From 1e4a197e4c60e461b8068b0619692ea083e30b8b Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 25 Mar 2003 06:35:27 +0000 Subject: [PATCH] Merged wxPython 2.4.x to the 2.5 branch (Finally!!!) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/.cvsignore | 4 + wxPython/BUILD.osx.txt | 58 +- wxPython/BUILD.unix.txt | 188 +- wxPython/BUILD.win32.txt | 133 +- wxPython/CHANGES.txt | 244 +- wxPython/MANIFEST.in | 5 - wxPython/README.txt | 86 +- wxPython/b | 8 +- wxPython/b.bat | 35 +- wxPython/contrib/gizmos/gizmos.cpp | 14 +- wxPython/contrib/gizmos/gizmos.i | 4 +- wxPython/contrib/glcanvas/glcanvas.i | 4 +- wxPython/contrib/glcanvas/msw/myglcanvas.cpp | 25 +- wxPython/contrib/glcanvas/msw/myglcanvas.h | 16 +- wxPython/contrib/iewin/IEHtmlWin.cpp | 66 +- wxPython/contrib/iewin/iewin.cpp | 23 +- wxPython/contrib/iewin/iewin.i | 2 +- wxPython/contrib/iewin/iewin.py | 4 +- wxPython/contrib/iewin/wxactivex.cpp | 204 +- wxPython/contrib/ogl/ogl.cpp | 26 +- wxPython/contrib/ogl/oglbasic.cpp | 140 +- wxPython/contrib/ogl/oglbasic.i | 2 +- wxPython/contrib/ogl/oglcanvas.cpp | 214 +- wxPython/contrib/ogl/oglcanvas.i | 11 +- wxPython/contrib/ogl/oglcanvas.py | 15 - wxPython/contrib/ogl/oglshapes.cpp | 401 +- wxPython/contrib/ogl/oglshapes.i | 7 +- wxPython/contrib/ogl/oglshapes.py | 15 +- wxPython/contrib/ogl/oglshapes2.cpp | 220 +- wxPython/contrib/ogl/oglshapes2.i | 2 +- wxPython/contrib/ogl/oglshapes2.py | 11 +- wxPython/contrib/stc/_stcextras.py | 4 +- wxPython/contrib/xrc/_xrcextras.py | 32 + wxPython/contrib/xrc/xrc.cpp | 248 +- wxPython/contrib/xrc/xrc.i | 72 +- wxPython/contrib/xrc/xrc.py | 85 +- wxPython/demo/.cvsignore | 3 + wxPython/demo/About.py | 6 +- wxPython/demo/ActiveXWrapper_Acrobat.py | 4 +- wxPython/demo/ActiveXWrapper_IE.py | 10 +- wxPython/demo/ColourSelect.py | 5 +- wxPython/demo/ContextHelp.py | 2 +- wxPython/demo/CustomDragAndDrop.py | 49 +- wxPython/demo/DialogUnits.py | 6 +- wxPython/demo/DragAndDrop.py | 14 +- wxPython/demo/DrawXXXList.py | 353 +- wxPython/demo/ErrorDialogs.py | 33 +- wxPython/demo/EventManager.py | 287 ++ wxPython/demo/FancyText.py | 3 +- wxPython/demo/FontEnumerator.py | 39 +- wxPython/demo/GenericButtons.py | 23 +- wxPython/demo/GridCustEditor.py | 14 +- wxPython/demo/GridCustTable.py | 31 +- wxPython/demo/GridDragable.py | 193 + wxPython/demo/GridEnterHandler.py | 2 +- wxPython/demo/GridHugeTable.py | 16 +- wxPython/demo/GridSimple.py | 22 +- wxPython/demo/GridStdEdRend.py | 12 +- wxPython/demo/LayoutAnchors.py | 20 +- wxPython/demo/Layoutf.py | 2 +- wxPython/demo/MDIDemo.py | 33 +- wxPython/demo/MDISashDemo.py | 16 +- wxPython/demo/Main.py | 175 +- wxPython/demo/OOR.py | 2 +- wxPython/demo/PrintFramework.py | 12 +- wxPython/demo/RowColSizer.py | 8 +- wxPython/demo/ScrolledPanel.py | 97 - wxPython/demo/Sizers.py | 28 +- wxPython/demo/SlashDot.py | 138 +- wxPython/demo/SplitTree.py | 11 +- wxPython/demo/TablePrint.py | 6 +- wxPython/demo/Threads.py | 12 +- wxPython/demo/Throbber.py | 180 + wxPython/demo/URLDragAndDrop.py | 6 +- wxPython/demo/Unicode.py | 4 +- wxPython/demo/XMLtreeview.py | 8 +- wxPython/demo/bmp_source/001.png | Bin 0 -> 2220 bytes wxPython/demo/bmp_source/002.png | Bin 0 -> 2234 bytes wxPython/demo/bmp_source/003.png | Bin 0 -> 2220 bytes wxPython/demo/bmp_source/004.png | Bin 0 -> 2339 bytes wxPython/demo/bmp_source/005.png | Bin 0 -> 2505 bytes wxPython/demo/bmp_source/006.png | Bin 0 -> 2230 bytes wxPython/demo/bmp_source/007.png | Bin 0 -> 2241 bytes wxPython/demo/bmp_source/008.png | Bin 0 -> 2291 bytes wxPython/demo/bmp_source/009.png | Bin 0 -> 2235 bytes wxPython/demo/bmp_source/010.png | Bin 0 -> 2306 bytes wxPython/demo/bmp_source/011.png | Bin 0 -> 2250 bytes wxPython/demo/bmp_source/012.png | Bin 0 -> 2266 bytes wxPython/demo/bmp_source/013.png | Bin 0 -> 2313 bytes wxPython/demo/bmp_source/014.png | Bin 0 -> 2226 bytes wxPython/demo/bmp_source/015.png | Bin 0 -> 2326 bytes wxPython/demo/bmp_source/016.png | Bin 0 -> 2230 bytes wxPython/demo/bmp_source/017.png | Bin 0 -> 2241 bytes wxPython/demo/bmp_source/018.png | Bin 0 -> 2291 bytes wxPython/demo/bmp_source/019.png | Bin 0 -> 2235 bytes wxPython/demo/bmp_source/020.png | Bin 0 -> 2306 bytes wxPython/demo/bmp_source/021.png | Bin 0 -> 2250 bytes wxPython/demo/bmp_source/022.png | Bin 0 -> 2266 bytes wxPython/demo/bmp_source/023.png | Bin 0 -> 2313 bytes wxPython/demo/bmp_source/024.png | Bin 0 -> 2226 bytes wxPython/demo/bmp_source/025.png | Bin 0 -> 2326 bytes wxPython/demo/bmp_source/026.png | Bin 0 -> 2221 bytes wxPython/demo/bmp_source/027.png | Bin 0 -> 2222 bytes wxPython/demo/bmp_source/028.png | Bin 0 -> 2464 bytes wxPython/demo/bmp_source/029.png | Bin 0 -> 2349 bytes wxPython/demo/bmp_source/030.png | Bin 0 -> 2220 bytes wxPython/demo/bmp_source/eclouds.png | Bin 0 -> 16502 bytes wxPython/demo/bmp_source/logo.png | Bin 0 -> 1092 bytes wxPython/demo/bmp_source/rest.png | Bin 0 -> 2234 bytes wxPython/demo/data/tips.txt | 4 +- wxPython/demo/data/widgetTest.htm | 12 +- wxPython/demo/demoMainLoop.py | 8 +- wxPython/demo/encode_bitmaps.py | 40 +- wxPython/demo/hangman.py | 14 +- wxPython/demo/images.py | 2 +- wxPython/demo/infoframe.py | 4 +- wxPython/demo/pyTree.py | 8 +- wxPython/demo/run.py | 26 +- wxPython/demo/simple.py | 4 +- wxPython/demo/throbImages.py | 4362 +++++++++++++++++ wxPython/demo/viewer_basics.py | 4 +- wxPython/demo/widgetTest.py | 4 +- wxPython/demo/wxButton.py | 44 +- wxPython/demo/wxCalendar.py | 30 +- wxPython/demo/wxCalendarCtrl.py | 10 + wxPython/demo/wxCheckBox.py | 2 +- wxPython/demo/wxCheckListBox.py | 5 +- wxPython/demo/wxColourDialog.py | 2 +- wxPython/demo/wxComboBox.py | 3 +- wxPython/demo/wxDialog.py | 115 +- wxPython/demo/wxDragImage.py | 33 +- wxPython/demo/wxDynamicSashWindow.py | 11 + wxPython/demo/wxEditor.py | 2 +- wxPython/demo/wxFileDialog.py | 7 +- wxPython/demo/wxFileHistory.py | 10 +- wxPython/demo/wxFindReplaceDialog.py | 6 +- wxPython/demo/wxFloatBar.py | 2 +- wxPython/demo/wxFontDialog.py | 128 +- wxPython/demo/wxFrame.py | 4 +- wxPython/demo/wxGLCanvas.py | 22 +- wxPython/demo/wxGenericDirCtrl.py | 2 +- wxPython/demo/wxGrid.py | 17 +- wxPython/demo/wxHtmlWindow.py | 48 +- wxPython/demo/wxIEHtmlWin.py | 10 +- wxPython/demo/wxImage.py | 8 + wxPython/demo/wxImageFromStream.py | 5 +- wxPython/demo/wxIntCtrl.py | 337 ++ wxPython/demo/wxJoystick.py | 2 +- wxPython/demo/wxKeyEvents.py | 20 +- wxPython/demo/wxLEDNumberCtrl.py | 2 +- wxPython/demo/wxLayoutConstraints.py | 2 +- wxPython/demo/wxListBox.py | 41 +- wxPython/demo/wxListCtrl.py | 63 +- wxPython/demo/wxListCtrl_virtual.py | 3 +- wxPython/demo/wxMDIWindows.py | 2 +- wxPython/demo/wxMVCTree.py | 6 +- wxPython/demo/wxMask.py | 13 +- wxPython/demo/wxMenu.py | 10 +- wxPython/demo/wxMimeTypesManager.py | 6 +- wxPython/demo/wxMiniFrame.py | 5 +- wxPython/demo/wxMultiSash.py | 90 + wxPython/demo/wxNotebook.py | 50 +- wxPython/demo/wxOGL.py | 86 +- wxPython/demo/wxPopupControl.py | 94 + wxPython/demo/wxPopupWindow.py | 8 +- wxPython/demo/wxPrintDialog.py | 6 +- wxPython/demo/wxProcess.py | 38 +- wxPython/demo/wxProgressDialog.py | 2 +- wxPython/demo/wxPyColourChooser.py | 58 + wxPython/demo/wxRadioBox.py | 38 +- wxPython/demo/wxRadioButton.py | 119 + wxPython/demo/wxRightTextCtrl.py | 2 +- wxPython/demo/wxSashWindow.py | 8 +- wxPython/demo/wxScrolledPanel.py | 112 + wxPython/demo/wxScrolledWindow.py | 9 +- wxPython/demo/wxSlider.py | 12 +- wxPython/demo/wxSpinButton.py | 2 - wxPython/demo/wxSpinCtrl.py | 4 +- wxPython/demo/wxSplitterWindow.py | 8 +- wxPython/demo/wxStaticBitmap.py | 2 - wxPython/demo/wxStaticText.py | 4 +- wxPython/demo/wxStatusBar.py | 10 +- wxPython/demo/wxStyledTextCtrl_1.py | 8 +- wxPython/demo/wxStyledTextCtrl_2.py | 54 +- wxPython/demo/wxTextCtrl.py | 70 +- wxPython/demo/wxTimeCtrl.py | 213 + wxPython/demo/wxToggleButton.py | 4 +- wxPython/demo/wxToolBar.py | 32 +- wxPython/demo/wxTreeCtrl.py | 57 +- wxPython/demo/wxValidator.py | 40 +- wxPython/demo/wxXmlResource.py | 2 +- wxPython/demo/wxXmlResourceHandler.py | 4 +- wxPython/distrib/.rpmrc | 5 - wxPython/distrib/README.1st.txt | 117 + wxPython/distrib/README.dbg.txt | 30 - wxPython/distrib/README.viewdocs.txt | 17 + wxPython/distrib/autobuild.py | 139 - wxPython/distrib/genfilelist.py | 51 + wxPython/distrib/mac/.cvsignore | 1 + wxPython/distrib/mac/MacPython/.cvsignore | 1 + wxPython/distrib/mac/MacPython/README.txt | 3 + wxPython/distrib/mac/MacPython/build | 129 + .../mac/MacPython/resources/Welcome.txt | 6 + .../mac/MacPython/resources/postflight | 67 + wxPython/distrib/mac/MachoPython.info | 15 - wxPython/distrib/mac/_build | 264 - wxPython/distrib/mac/_buildPython | 162 - wxPython/distrib/mac/build | 11 - wxPython/distrib/mac/buildPython | 8 - wxPython/distrib/mac/buildapp.py | 4 + wxPython/distrib/mac/buildpkg.py | 470 ++ wxPython/distrib/mac/bundlebuilder.py | 816 +++ wxPython/distrib/mac/makepkg | 283 -- wxPython/distrib/mac/resources/Welcome.txt | 2 - wxPython/distrib/mac/resources/preflight | 11 - .../distrib/mac/resourcesPython/License.rtf | 25 - .../distrib/mac/resourcesPython/ReadMe.rtf | 91 - .../distrib/mac/resourcesPython/Welcome.txt | 2 - wxPython/distrib/mac/wxPythonOSX.info | 15 - wxPython/distrib/mac/wxPythonOSX/.cvsignore | 1 + .../distrib/mac/wxPythonOSX/PieShell.icns | Bin 0 -> 55621 bytes wxPython/distrib/mac/wxPythonOSX/RunDemo.icns | Bin 0 -> 41898 bytes wxPython/distrib/mac/wxPythonOSX/XRCed.icns | Bin 0 -> 37830 bytes wxPython/distrib/mac/wxPythonOSX/build | 390 ++ .../{ => wxPythonOSX}/resources/License.rtf | 0 .../{ => wxPythonOSX}/resources/ReadMe.rtf | 35 +- .../mac/wxPythonOSX/resources/Welcome.txt | 5 + .../mac/wxPythonOSX/resources/postflight | 18 + .../mac/wxPythonOSX/resources/preflight | 4 + wxPython/distrib/mac/zappycfiles.py | 38 + wxPython/distrib/make_installer.py | 93 +- wxPython/distrib/makedbg.bat | 33 - wxPython/distrib/makedemo | 10 +- wxPython/distrib/makedev.bat | 4 +- wxPython/distrib/makedocs | 63 + wxPython/distrib/makedocs.bat | 26 - wxPython/distrib/makerpm | 123 +- wxPython/distrib/maketgz | 62 - wxPython/distrib/maketools | 38 - wxPython/distrib/makexferzip | 10 - wxPython/distrib/makexferzip.bat | 9 - wxPython/distrib/viewdocs.py | 31 + wxPython/distrib/wise.aut | 7 - wxPython/distrib/wxPython.WSM | Bin 33 -> 0 bytes wxPython/distrib/wxPython.bmp | Bin 131190 -> 0 bytes wxPython/distrib/wxPython.rsp | 106 - wxPython/distrib/wxPython.wse | 1364 ------ wxPython/distrib/wxPythonFull.spec.in | 192 +- wxPython/distrib/zipall.bat | 4 - wxPython/distrib/zipit.bat | 44 - wxPython/distutils/README | 22 + wxPython/distutils/README_1st.txt | 19 + wxPython/distutils/__init__.py | 15 + wxPython/distutils/archive_util.py | 173 + wxPython/distutils/bcppcompiler.py | 394 ++ wxPython/distutils/ccompiler.py | 1215 +++++ wxPython/distutils/cmd.py | 478 ++ wxPython/distutils/command/__init__.py | 32 + wxPython/distutils/command/bdist.py | 150 + wxPython/distutils/command/bdist_dumb.py | 128 + wxPython/distutils/command/bdist_rpm.py | 493 ++ wxPython/distutils/command/bdist_wininst.py | 242 + wxPython/distutils/command/build.py | 131 + wxPython/distutils/command/build_clib.py | 238 + wxPython/distutils/command/build_ext.py | 674 +++ wxPython/distutils/command/build_py.py | 396 ++ wxPython/distutils/command/build_scripts.py | 126 + wxPython/distutils/command/clean.py | 82 + wxPython/distutils/command/command_template | 45 + wxPython/distutils/command/config.py | 368 ++ wxPython/distutils/command/install.py | 601 +++ wxPython/distutils/command/install_data.py | 85 + wxPython/distutils/command/install_headers.py | 53 + wxPython/distutils/command/install_lib.py | 210 + wxPython/distutils/command/install_scripts.py | 66 + wxPython/distutils/command/register.py | 292 ++ wxPython/distutils/command/sdist.py | 460 ++ wxPython/distutils/core.py | 241 + wxPython/distutils/cygwinccompiler.py | 397 ++ wxPython/distutils/debug.py | 10 + wxPython/distutils/dep_util.py | 95 + wxPython/distutils/dir_util.py | 228 + wxPython/distutils/dist.py | 1095 +++++ wxPython/distutils/emxccompiler.py | 315 ++ wxPython/distutils/errors.py | 99 + wxPython/distutils/extension.py | 241 + wxPython/distutils/fancy_getopt.py | 501 ++ wxPython/distutils/file_util.py | 253 + wxPython/distutils/filelist.py | 355 ++ wxPython/distutils/log.py | 61 + wxPython/distutils/msvccompiler.py | 503 ++ wxPython/distutils/mwerkscompiler.py | 248 + wxPython/distutils/spawn.py | 194 + wxPython/distutils/sysconfig.py | 495 ++ wxPython/distutils/text_file.py | 382 ++ wxPython/distutils/unixccompiler.py | 233 + wxPython/distutils/util.py | 460 ++ wxPython/distutils/version.py | 299 ++ wxPython/my_distutils.py | 488 -- .../samples/StyleEditor/STCStyleEditor.py | 903 ++-- wxPython/samples/doodle/.cvsignore | 1 + wxPython/samples/doodle/doodle.py | 16 +- wxPython/samples/doodle/superdoodle.py | 10 +- wxPython/samples/frogedit/FrogEdit.py | 28 +- wxPython/samples/pySketch/pySketch.py | 3802 +++++++------- wxPython/samples/stxview/README.txt | 3 - .../StructuredText/ClassicDocumentClass.py | 684 --- .../StructuredText/ClassicStructuredText.py | 625 --- .../stxview/StructuredText/DocBookClass.py | 332 -- .../stxview/StructuredText/DocumentClass.py | 998 ---- .../StructuredText/DocumentWithImages.py | 134 - .../stxview/StructuredText/HTMLClass.py | 307 -- .../stxview/StructuredText/HTMLWithImages.py | 128 - wxPython/samples/stxview/StructuredText/ST.py | 283 -- .../samples/stxview/StructuredText/STDOM.py | 736 --- .../samples/stxview/StructuredText/STNG.txt | 116 - .../stxview/StructuredText/STletters.py | 15 - .../stxview/StructuredText/StructuredText.py | 148 - .../samples/stxview/StructuredText/Zwiki.py | 158 - .../stxview/StructuredText/__init__.py | 112 - wxPython/samples/stxview/stxview.py | 201 - wxPython/samples/stxview/test.stx | 127 - wxPython/samples/wxProject/wxProject.py | 32 +- wxPython/scripts/CreateBatchFiles.py | 4 +- wxPython/scripts/CreateMacScripts.py | 21 +- wxPython/scripts/helpviewer | 4 + wxPython/scripts/helpviewer.bat | 3 + wxPython/scripts/img2png.bat | 2 +- wxPython/scripts/img2py.bat | 2 +- wxPython/scripts/img2xpm.bat | 2 +- wxPython/scripts/pycrust.bat | 2 +- wxPython/scripts/pycwrap | 7 + wxPython/scripts/pycwrap.bat | 3 + wxPython/scripts/pyshell.bat | 2 +- wxPython/scripts/xrced.bat | 2 +- wxPython/setup.py | 729 ++- wxPython/src/__version__.py | 2 +- wxPython/src/_calextras.py | 1 + wxPython/src/_defs.i | 18 +- wxPython/src/_extras.py | 104 +- wxPython/src/_helpextras.py | 1 + wxPython/src/_htmlextras.py | 1 + wxPython/src/_wizardextras.py | 4 + wxPython/src/clip_dnd.i | 35 +- wxPython/src/controls.i | 8 +- wxPython/src/controls2.i | 50 +- wxPython/src/drawlist.cpp | 350 ++ wxPython/src/events.i | 4 +- wxPython/src/filesys.i | 11 +- wxPython/src/fonts.i | 93 +- wxPython/src/frames.i | 4 +- wxPython/src/gdi.i | 469 +- wxPython/src/grid.i | 87 +- wxPython/src/helpers.cpp | 428 +- wxPython/src/helpers.h | 189 +- wxPython/src/html.i | 137 +- wxPython/src/image.i | 15 + wxPython/src/misc.i | 263 +- wxPython/src/misc2.i | 41 +- wxPython/src/my_typemaps.i | 43 +- wxPython/src/pyistream.h | 13 + wxPython/src/sizers.i | 231 +- wxPython/src/stattool.i | 4 +- wxPython/src/streams.i | 19 +- wxPython/src/utils.i | 26 +- wxPython/src/windows.i | 17 + wxPython/src/windows2.i | 34 +- .../src/{wxc.pyd.manifest => winxp.manifest} | 2 +- wxPython/src/wizard.i | 9 +- wxPython/src/wx.i | 39 +- wxPython/src/wxPython.h | 1 + wxPython/src/wxc.rc | 2 +- wxPython/tests/gridtest.py | 2 +- wxPython/tests/hangman.py | 618 +-- wxPython/tests/tabs.py | 1 - wxPython/tests/test7.py | 19 +- wxPython/tests/test8.py | 58 +- wxPython/tests/testDlg.py | 44 +- wxPython/tests/testTree.py | 188 +- wxPython/tests/txml.py | 4 +- wxPython/tests/val.py | 3 +- wxPython/tests/wxPlotCanvas.py | 533 +- wxPython/tests/wxSlash.py | 126 +- wxPython/wxPython/.cvsignore | 1 + wxPython/wxPython/lib/CDate.py | 10 +- wxPython/wxPython/lib/ErrorDialogs.py | 42 +- wxPython/wxPython/lib/PyCrust/CHANGES.txt | 512 ++ wxPython/wxPython/lib/PyCrust/PyCrustApp.py | 67 +- wxPython/wxPython/lib/PyCrust/PyFillingApp.py | 38 +- wxPython/wxPython/lib/PyCrust/PyShellApp.py | 69 +- wxPython/wxPython/lib/PyCrust/README.txt | 43 +- wxPython/wxPython/lib/PyCrust/crust.py | 157 +- wxPython/wxPython/lib/PyCrust/dispatcher.py | 266 + wxPython/wxPython/lib/PyCrust/filling.py | 424 +- wxPython/wxPython/lib/PyCrust/interpreter.py | 52 +- wxPython/wxPython/lib/PyCrust/introspect.py | 199 +- wxPython/wxPython/lib/PyCrust/pseudo.py | 64 +- wxPython/wxPython/lib/PyCrust/shell.py | 845 ++-- wxPython/wxPython/lib/PyCrust/shellmenu.py | 226 + wxPython/wxPython/lib/PyCrust/version.py | 9 +- wxPython/wxPython/lib/PyCrust/wrap.py | 56 + .../wxPython/lib/PyCrust/wxd/Accelerators.py | 58 + wxPython/wxPython/lib/PyCrust/wxd/App.py | 358 ++ wxPython/wxPython/lib/PyCrust/wxd/Base.py | 206 + .../wxPython/lib/PyCrust/wxd/ClipDragDrop.py | 485 ++ wxPython/wxPython/lib/PyCrust/wxd/Config.py | 199 + wxPython/wxPython/lib/PyCrust/wxd/Controls.py | 1846 +++++++ .../lib/PyCrust/wxd/DataStructures.py | 485 ++ wxPython/wxPython/lib/PyCrust/wxd/DateTime.py | 553 +++ wxPython/wxPython/lib/PyCrust/wxd/Dialogs.py | 471 ++ wxPython/wxPython/lib/PyCrust/wxd/Drawing.py | 1466 ++++++ wxPython/wxPython/lib/PyCrust/wxd/Errors.py | 25 + .../lib/PyCrust/wxd/EventFunctions.py | 794 +++ wxPython/wxPython/lib/PyCrust/wxd/Events.py | 1275 +++++ .../wxPython/lib/PyCrust/wxd/FileSystem.py | 193 + wxPython/wxPython/lib/PyCrust/wxd/Frames.py | 440 ++ .../wxPython/lib/PyCrust/wxd/Functions.py | 1262 +++++ wxPython/wxPython/lib/PyCrust/wxd/Help.py | 127 + .../wxPython/lib/PyCrust/wxd/ImageHandlers.py | 142 + wxPython/wxPython/lib/PyCrust/wxd/Joystick.py | 197 + .../lib/PyCrust/wxd/LayoutConstraints.py | 80 + wxPython/wxPython/lib/PyCrust/wxd/Logging.py | 145 + wxPython/wxPython/lib/PyCrust/wxd/Menus.py | 477 ++ .../wxPython/lib/PyCrust/wxd/MimeTypes.py | 185 + wxPython/wxPython/lib/PyCrust/wxd/Misc.py | 558 +++ wxPython/wxPython/lib/PyCrust/wxd/Panel.py | 240 + .../wxPython/lib/PyCrust/wxd/Parameters.py | 68 + wxPython/wxPython/lib/PyCrust/wxd/Printing.py | 651 +++ wxPython/wxPython/lib/PyCrust/wxd/Process.py | 77 + .../wxPython/lib/PyCrust/wxd/SashSplitter.py | 226 + wxPython/wxPython/lib/PyCrust/wxd/Sizers.py | 488 ++ wxPython/wxPython/lib/PyCrust/wxd/Streams.py | 96 + .../lib/PyCrust/wxd/StyledTextConstants.py | 643 +++ .../wxPython/lib/PyCrust/wxd/Threading.py | 26 + wxPython/wxPython/lib/PyCrust/wxd/ToolBar.py | 403 ++ wxPython/wxPython/lib/PyCrust/wxd/Tree.py | 402 ++ .../wxPython/lib/PyCrust/wxd/Validators.py | 56 + wxPython/wxPython/lib/PyCrust/wxd/Window.py | 850 ++++ wxPython/wxPython/lib/PyCrust/wxd/__init__.py | 1 + wxPython/wxPython/lib/PyCrust/wxd/d_stc.py | 17 + wxPython/wxPython/lib/PyCrust/wxd/d_wx.py | 17 + .../wxPython/lib/PyCrust/wxd/decorator.py | 92 + wxPython/wxPython/lib/PyCrust/wxd/gen.py | 71 + wxPython/wxPython/lib/PyCrust/wxd/stc_.py | 1409 ++++++ wxPython/wxPython/lib/PyCrust/wxd/wx_.py | 62 + wxPython/wxPython/lib/PythonBitmaps.py | 2 +- wxPython/wxPython/lib/buttons.py | 110 +- wxPython/wxPython/lib/calendar.py | 45 +- .../wxPython/lib/colourchooser/__init__.py | 26 + wxPython/wxPython/lib/colourchooser/canvas.py | 120 + wxPython/wxPython/lib/colourchooser/intl.py | 24 + .../wxPython/lib/colourchooser/pycolourbox.py | 79 + .../lib/colourchooser/pycolourchooser.py | 385 ++ .../lib/colourchooser/pycolourslider.py | 82 + .../wxPython/lib/colourchooser/pypalette.py | 214 + wxPython/wxPython/lib/colourselect.py | 2 +- wxPython/wxPython/lib/dialogs.py | 397 +- wxPython/wxPython/lib/editor/editor.py | 57 +- wxPython/wxPython/lib/editor/selection.py | 18 +- wxPython/wxPython/lib/evtmgr.py | 519 ++ wxPython/wxPython/lib/fancytext.py | 2 +- wxPython/wxPython/lib/filebrowsebutton.py | 16 +- wxPython/wxPython/lib/floatbar.py | 12 +- wxPython/wxPython/lib/gridmovers.py | 419 ++ wxPython/wxPython/lib/grids.py | 4 +- wxPython/wxPython/lib/imagebrowser.py | 84 +- wxPython/wxPython/lib/imageutils.py | 45 + wxPython/wxPython/lib/infoframe.py | 8 +- wxPython/wxPython/lib/intctrl.py | 866 ++++ wxPython/wxPython/lib/layoutf.py | 14 +- wxPython/wxPython/lib/mixins/listctrl.py | 173 +- wxPython/wxPython/lib/mixins/rubberband.py | 389 ++ wxPython/wxPython/lib/multisash.py | 726 +++ wxPython/wxPython/lib/mvctree.py | 90 +- wxPython/wxPython/lib/popupctl.py | 243 + wxPython/wxPython/lib/printout.py | 112 +- wxPython/wxPython/lib/pubsub.py | 382 ++ wxPython/wxPython/lib/pyshell.py | 6 +- wxPython/wxPython/lib/rpcMixin.py | 7 +- wxPython/wxPython/lib/scrolledpanel.py | 85 + wxPython/wxPython/lib/sheet.py | 92 +- wxPython/wxPython/lib/shell.py | 24 +- wxPython/wxPython/lib/splashscreen.py | 14 +- wxPython/wxPython/lib/stattext.py | 12 +- wxPython/wxPython/lib/throbber.py | 253 + wxPython/wxPython/lib/timectrl.py | 843 ++++ wxPython/wxPython/lib/vtk.py | 4 +- wxPython/wxPython/lib/wxPlotCanvas.py | 15 +- wxPython/wxPython/lib/wxpTag.py | 67 +- wxPython/wxPython/tools/XRCed/CHANGES.txt | 162 + .../tools/XRCed/{README => README.txt} | 7 +- .../wxPython/tools/XRCed/{TODO => TODO.txt} | 8 +- .../wxPython/tools/XRCed/encode_bitmaps.py | 27 + wxPython/wxPython/tools/XRCed/globals.py | 39 + wxPython/wxPython/tools/XRCed/images.py | 1803 ++++++- wxPython/wxPython/tools/XRCed/license.txt | 23 + wxPython/wxPython/tools/XRCed/panel.py | 365 ++ wxPython/wxPython/tools/XRCed/params.py | 349 +- wxPython/wxPython/tools/XRCed/sawfishrc | 24 + .../tools/XRCed/src-images/AutoRefresh.png | Bin 0 -> 316 bytes .../wxPython/tools/XRCed/src-images/Copy.png | Bin 0 -> 273 bytes .../wxPython/tools/XRCed/src-images/Cut.png | Bin 0 -> 255 bytes .../wxPython/tools/XRCed/src-images/Icon.png | Bin 0 -> 1111 bytes .../wxPython/tools/XRCed/src-images/New.png | Bin 0 -> 190 bytes .../wxPython/tools/XRCed/src-images/Open.png | Bin 0 -> 274 bytes .../wxPython/tools/XRCed/src-images/Paste.png | Bin 0 -> 280 bytes .../wxPython/tools/XRCed/src-images/Redo.png | Bin 0 -> 252 bytes .../tools/XRCed/src-images/Refresh.png | Bin 0 -> 275 bytes .../wxPython/tools/XRCed/src-images/Save.png | Bin 0 -> 207 bytes .../wxPython/tools/XRCed/src-images/Test.png | Bin 0 -> 350 bytes .../XRCed/src-images/ToolBitmapButton.png | Bin 0 -> 616 bytes .../tools/XRCed/src-images/ToolBoxSizer.png | Bin 0 -> 141 bytes .../tools/XRCed/src-images/ToolButton.png | Bin 0 -> 182 bytes .../tools/XRCed/src-images/ToolCheckBox.png | Bin 0 -> 117 bytes .../tools/XRCed/src-images/ToolCheckList.png | Bin 0 -> 233 bytes .../tools/XRCed/src-images/ToolChoice.png | Bin 0 -> 193 bytes .../tools/XRCed/src-images/ToolComboBox.png | Bin 0 -> 233 bytes .../tools/XRCed/src-images/ToolDefault.png | Bin 0 -> 154 bytes .../tools/XRCed/src-images/ToolDialog.png | Bin 0 -> 146 bytes .../XRCed/src-images/ToolFlexGridSizer.png | Bin 0 -> 139 bytes .../tools/XRCed/src-images/ToolFrame.png | Bin 0 -> 131 bytes .../tools/XRCed/src-images/ToolGauge.png | Bin 0 -> 141 bytes .../tools/XRCed/src-images/ToolGridSizer.png | Bin 0 -> 133 bytes .../tools/XRCed/src-images/ToolListBox.png | Bin 0 -> 184 bytes .../tools/XRCed/src-images/ToolListCtrl.png | Bin 0 -> 167 bytes .../tools/XRCed/src-images/ToolMenu.png | Bin 0 -> 166 bytes .../tools/XRCed/src-images/ToolMenuBar.png | Bin 0 -> 171 bytes .../tools/XRCed/src-images/ToolMenuItem.png | Bin 0 -> 135 bytes .../tools/XRCed/src-images/ToolNotebook.png | Bin 0 -> 253 bytes .../tools/XRCed/src-images/ToolPanel.png | Bin 0 -> 140 bytes .../tools/XRCed/src-images/ToolRadioBox.png | Bin 0 -> 296 bytes .../XRCed/src-images/ToolRadioButton.png | Bin 0 -> 200 bytes .../tools/XRCed/src-images/ToolRoot.png | Bin 0 -> 170 bytes .../tools/XRCed/src-images/ToolScrollBar.png | Bin 0 -> 254 bytes .../tools/XRCed/src-images/ToolSeparator.png | Bin 0 -> 80 bytes .../tools/XRCed/src-images/ToolSlider.png | Bin 0 -> 185 bytes .../tools/XRCed/src-images/ToolSpacer.png | Bin 0 -> 229 bytes .../tools/XRCed/src-images/ToolSpinButton.png | Bin 0 -> 161 bytes .../tools/XRCed/src-images/ToolSpinCtrl.png | Bin 0 -> 308 bytes .../XRCed/src-images/ToolStaticBitmap.png | Bin 0 -> 576 bytes .../tools/XRCed/src-images/ToolStaticBox.png | Bin 0 -> 189 bytes .../XRCed/src-images/ToolStaticBoxSizer.png | Bin 0 -> 173 bytes .../tools/XRCed/src-images/ToolStaticLine.png | Bin 0 -> 82 bytes .../tools/XRCed/src-images/ToolStaticText.png | Bin 0 -> 166 bytes .../tools/XRCed/src-images/ToolTextCtrl.png | Bin 0 -> 129 bytes .../tools/XRCed/src-images/ToolTool.png | Bin 0 -> 119 bytes .../tools/XRCed/src-images/ToolToolBar.png | Bin 0 -> 165 bytes .../tools/XRCed/src-images/ToolTreeCtrl.png | Bin 0 -> 154 bytes .../tools/XRCed/src-images/ToolUnknown.png | Bin 0 -> 145 bytes .../tools/XRCed/src-images/TreeDefault.png | Bin 0 -> 154 bytes .../tools/XRCed/src-images/TreeDialog.png | Bin 0 -> 146 bytes .../tools/XRCed/src-images/TreeFrame.png | Bin 0 -> 131 bytes .../tools/XRCed/src-images/TreeMenu.png | Bin 0 -> 166 bytes .../tools/XRCed/src-images/TreeMenuBar.png | Bin 0 -> 171 bytes .../tools/XRCed/src-images/TreeMenuItem.png | Bin 0 -> 139 bytes .../tools/XRCed/src-images/TreePanel.png | Bin 0 -> 140 bytes .../tools/XRCed/src-images/TreeRoot.png | Bin 0 -> 170 bytes .../tools/XRCed/src-images/TreeSeparator.png | Bin 0 -> 103 bytes .../XRCed/src-images/TreeSizerFlexGrid.png | Bin 0 -> 139 bytes .../tools/XRCed/src-images/TreeSizerGrid.png | Bin 0 -> 133 bytes .../tools/XRCed/src-images/TreeSizerH.png | Bin 0 -> 141 bytes .../tools/XRCed/src-images/TreeSizerV.png | Bin 0 -> 136 bytes .../XRCed/src-images/TreeStaticBoxSizerH.png | Bin 0 -> 173 bytes .../XRCed/src-images/TreeStaticBoxSizerV.png | Bin 0 -> 177 bytes .../tools/XRCed/src-images/TreeTool.png | Bin 0 -> 141 bytes .../tools/XRCed/src-images/TreeToolBar.png | Bin 0 -> 194 bytes .../wxPython/tools/XRCed/src-images/Undo.png | Bin 0 -> 240 bytes wxPython/wxPython/tools/XRCed/tools.py | 279 ++ wxPython/wxPython/tools/XRCed/tree.py | 839 ++++ wxPython/wxPython/tools/XRCed/undo.py | 151 + wxPython/wxPython/tools/XRCed/xrced.py | 1587 ++---- wxPython/wxPython/tools/XRCed/xrced.xrc | 101 +- wxPython/wxPython/tools/XRCed/xxx.py | 234 +- wxPython/wxPython/tools/dbg.py | 256 + wxPython/wxPython/tools/helpviewer.py | 80 + wxPython/wxPython/tools/img2img.py | 19 +- wxPython/wxPython/tools/img2png.py | 12 +- wxPython/wxPython/tools/img2py.py | 76 +- wxPython/wxPython/tools/img2xpm.py | 12 +- wxPython/wxSWIG/Modules/pycpp.cxx | 11 +- wxPython/wxSWIG/Modules/python.cxx | 10 +- wxPython/wxSWIG/swig_lib/perl5/.cvsignore | 1 + wxPython/wxSWIG/swig_lib/python/.cvsignore | 1 + wxPython/wxSWIG/swig_lib/python/pyexp.swg | 5 +- wxPython/wxSWIG/swig_lib/python/python.swg | 4 +- wxPython/wxSWIG/swig_lib/tcl/.cvsignore | 1 + 586 files changed, 62842 insertions(+), 17891 deletions(-) create mode 100644 wxPython/demo/EventManager.py create mode 100644 wxPython/demo/GridDragable.py delete mode 100644 wxPython/demo/ScrolledPanel.py create mode 100644 wxPython/demo/Throbber.py create mode 100644 wxPython/demo/bmp_source/001.png create mode 100644 wxPython/demo/bmp_source/002.png create mode 100644 wxPython/demo/bmp_source/003.png create mode 100644 wxPython/demo/bmp_source/004.png create mode 100644 wxPython/demo/bmp_source/005.png create mode 100644 wxPython/demo/bmp_source/006.png create mode 100644 wxPython/demo/bmp_source/007.png create mode 100644 wxPython/demo/bmp_source/008.png create mode 100644 wxPython/demo/bmp_source/009.png create mode 100644 wxPython/demo/bmp_source/010.png create mode 100644 wxPython/demo/bmp_source/011.png create mode 100644 wxPython/demo/bmp_source/012.png create mode 100644 wxPython/demo/bmp_source/013.png create mode 100644 wxPython/demo/bmp_source/014.png create mode 100644 wxPython/demo/bmp_source/015.png create mode 100644 wxPython/demo/bmp_source/016.png create mode 100644 wxPython/demo/bmp_source/017.png create mode 100644 wxPython/demo/bmp_source/018.png create mode 100644 wxPython/demo/bmp_source/019.png create mode 100644 wxPython/demo/bmp_source/020.png create mode 100644 wxPython/demo/bmp_source/021.png create mode 100644 wxPython/demo/bmp_source/022.png create mode 100644 wxPython/demo/bmp_source/023.png create mode 100644 wxPython/demo/bmp_source/024.png create mode 100644 wxPython/demo/bmp_source/025.png create mode 100644 wxPython/demo/bmp_source/026.png create mode 100644 wxPython/demo/bmp_source/027.png create mode 100644 wxPython/demo/bmp_source/028.png create mode 100644 wxPython/demo/bmp_source/029.png create mode 100644 wxPython/demo/bmp_source/030.png create mode 100644 wxPython/demo/bmp_source/eclouds.png create mode 100644 wxPython/demo/bmp_source/logo.png create mode 100644 wxPython/demo/bmp_source/rest.png create mode 100644 wxPython/demo/throbImages.py create mode 100644 wxPython/demo/wxIntCtrl.py create mode 100644 wxPython/demo/wxMultiSash.py create mode 100644 wxPython/demo/wxPopupControl.py create mode 100644 wxPython/demo/wxPyColourChooser.py create mode 100644 wxPython/demo/wxRadioButton.py create mode 100644 wxPython/demo/wxScrolledPanel.py create mode 100644 wxPython/demo/wxTimeCtrl.py delete mode 100644 wxPython/distrib/.rpmrc create mode 100644 wxPython/distrib/README.1st.txt delete mode 100644 wxPython/distrib/README.dbg.txt create mode 100644 wxPython/distrib/README.viewdocs.txt delete mode 100755 wxPython/distrib/autobuild.py create mode 100644 wxPython/distrib/genfilelist.py create mode 100644 wxPython/distrib/mac/.cvsignore create mode 100644 wxPython/distrib/mac/MacPython/.cvsignore create mode 100644 wxPython/distrib/mac/MacPython/README.txt create mode 100755 wxPython/distrib/mac/MacPython/build create mode 100644 wxPython/distrib/mac/MacPython/resources/Welcome.txt create mode 100755 wxPython/distrib/mac/MacPython/resources/postflight delete mode 100644 wxPython/distrib/mac/MachoPython.info delete mode 100755 wxPython/distrib/mac/_build delete mode 100755 wxPython/distrib/mac/_buildPython delete mode 100755 wxPython/distrib/mac/build delete mode 100755 wxPython/distrib/mac/buildPython create mode 100644 wxPython/distrib/mac/buildapp.py create mode 100644 wxPython/distrib/mac/buildpkg.py create mode 100644 wxPython/distrib/mac/bundlebuilder.py delete mode 100755 wxPython/distrib/mac/makepkg delete mode 100644 wxPython/distrib/mac/resources/Welcome.txt delete mode 100755 wxPython/distrib/mac/resources/preflight delete mode 100644 wxPython/distrib/mac/resourcesPython/License.rtf delete mode 100644 wxPython/distrib/mac/resourcesPython/ReadMe.rtf delete mode 100644 wxPython/distrib/mac/resourcesPython/Welcome.txt delete mode 100644 wxPython/distrib/mac/wxPythonOSX.info create mode 100644 wxPython/distrib/mac/wxPythonOSX/.cvsignore create mode 100644 wxPython/distrib/mac/wxPythonOSX/PieShell.icns create mode 100644 wxPython/distrib/mac/wxPythonOSX/RunDemo.icns create mode 100644 wxPython/distrib/mac/wxPythonOSX/XRCed.icns create mode 100755 wxPython/distrib/mac/wxPythonOSX/build rename wxPython/distrib/mac/{ => wxPythonOSX}/resources/License.rtf (100%) rename wxPython/distrib/mac/{ => wxPythonOSX}/resources/ReadMe.rtf (70%) create mode 100644 wxPython/distrib/mac/wxPythonOSX/resources/Welcome.txt create mode 100755 wxPython/distrib/mac/wxPythonOSX/resources/postflight create mode 100755 wxPython/distrib/mac/wxPythonOSX/resources/preflight create mode 100644 wxPython/distrib/mac/zappycfiles.py delete mode 100755 wxPython/distrib/makedbg.bat create mode 100755 wxPython/distrib/makedocs delete mode 100755 wxPython/distrib/makedocs.bat delete mode 100755 wxPython/distrib/maketgz delete mode 100755 wxPython/distrib/maketools delete mode 100755 wxPython/distrib/makexferzip delete mode 100755 wxPython/distrib/makexferzip.bat create mode 100755 wxPython/distrib/viewdocs.py delete mode 100644 wxPython/distrib/wise.aut delete mode 100644 wxPython/distrib/wxPython.WSM delete mode 100644 wxPython/distrib/wxPython.bmp delete mode 100644 wxPython/distrib/wxPython.rsp delete mode 100644 wxPython/distrib/wxPython.wse delete mode 100755 wxPython/distrib/zipall.bat delete mode 100755 wxPython/distrib/zipit.bat create mode 100644 wxPython/distutils/README create mode 100644 wxPython/distutils/README_1st.txt create mode 100644 wxPython/distutils/__init__.py create mode 100644 wxPython/distutils/archive_util.py create mode 100644 wxPython/distutils/bcppcompiler.py create mode 100644 wxPython/distutils/ccompiler.py create mode 100644 wxPython/distutils/cmd.py create mode 100644 wxPython/distutils/command/__init__.py create mode 100644 wxPython/distutils/command/bdist.py create mode 100644 wxPython/distutils/command/bdist_dumb.py create mode 100644 wxPython/distutils/command/bdist_rpm.py create mode 100644 wxPython/distutils/command/bdist_wininst.py create mode 100644 wxPython/distutils/command/build.py create mode 100644 wxPython/distutils/command/build_clib.py create mode 100644 wxPython/distutils/command/build_ext.py create mode 100644 wxPython/distutils/command/build_py.py create mode 100644 wxPython/distutils/command/build_scripts.py create mode 100644 wxPython/distutils/command/clean.py create mode 100644 wxPython/distutils/command/command_template create mode 100644 wxPython/distutils/command/config.py create mode 100644 wxPython/distutils/command/install.py create mode 100644 wxPython/distutils/command/install_data.py create mode 100644 wxPython/distutils/command/install_headers.py create mode 100644 wxPython/distutils/command/install_lib.py create mode 100644 wxPython/distutils/command/install_scripts.py create mode 100644 wxPython/distutils/command/register.py create mode 100644 wxPython/distutils/command/sdist.py create mode 100644 wxPython/distutils/core.py create mode 100644 wxPython/distutils/cygwinccompiler.py create mode 100644 wxPython/distutils/debug.py create mode 100644 wxPython/distutils/dep_util.py create mode 100644 wxPython/distutils/dir_util.py create mode 100644 wxPython/distutils/dist.py create mode 100644 wxPython/distutils/emxccompiler.py create mode 100644 wxPython/distutils/errors.py create mode 100644 wxPython/distutils/extension.py create mode 100644 wxPython/distutils/fancy_getopt.py create mode 100644 wxPython/distutils/file_util.py create mode 100644 wxPython/distutils/filelist.py create mode 100644 wxPython/distutils/log.py create mode 100644 wxPython/distutils/msvccompiler.py create mode 100644 wxPython/distutils/mwerkscompiler.py create mode 100644 wxPython/distutils/spawn.py create mode 100644 wxPython/distutils/sysconfig.py create mode 100644 wxPython/distutils/text_file.py create mode 100644 wxPython/distutils/unixccompiler.py create mode 100644 wxPython/distutils/util.py create mode 100644 wxPython/distutils/version.py delete mode 100644 wxPython/my_distutils.py delete mode 100644 wxPython/samples/stxview/README.txt delete mode 100644 wxPython/samples/stxview/StructuredText/ClassicDocumentClass.py delete mode 100644 wxPython/samples/stxview/StructuredText/ClassicStructuredText.py delete mode 100644 wxPython/samples/stxview/StructuredText/DocBookClass.py delete mode 100644 wxPython/samples/stxview/StructuredText/DocumentClass.py delete mode 100644 wxPython/samples/stxview/StructuredText/DocumentWithImages.py delete mode 100644 wxPython/samples/stxview/StructuredText/HTMLClass.py delete mode 100644 wxPython/samples/stxview/StructuredText/HTMLWithImages.py delete mode 100644 wxPython/samples/stxview/StructuredText/ST.py delete mode 100644 wxPython/samples/stxview/StructuredText/STDOM.py delete mode 100644 wxPython/samples/stxview/StructuredText/STNG.txt delete mode 100644 wxPython/samples/stxview/StructuredText/STletters.py delete mode 100644 wxPython/samples/stxview/StructuredText/StructuredText.py delete mode 100644 wxPython/samples/stxview/StructuredText/Zwiki.py delete mode 100644 wxPython/samples/stxview/StructuredText/__init__.py delete mode 100644 wxPython/samples/stxview/stxview.py delete mode 100644 wxPython/samples/stxview/test.stx create mode 100755 wxPython/scripts/helpviewer create mode 100755 wxPython/scripts/helpviewer.bat create mode 100755 wxPython/scripts/pycwrap create mode 100755 wxPython/scripts/pycwrap.bat create mode 100644 wxPython/src/drawlist.cpp rename wxPython/src/{wxc.pyd.manifest => winxp.manifest} (90%) create mode 100644 wxPython/wxPython/lib/PyCrust/CHANGES.txt create mode 100644 wxPython/wxPython/lib/PyCrust/dispatcher.py create mode 100644 wxPython/wxPython/lib/PyCrust/shellmenu.py create mode 100644 wxPython/wxPython/lib/PyCrust/wrap.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Accelerators.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/App.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Base.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/ClipDragDrop.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Config.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Controls.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/DataStructures.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/DateTime.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Dialogs.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Drawing.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Errors.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/EventFunctions.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Events.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/FileSystem.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Frames.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Functions.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Help.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/ImageHandlers.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Joystick.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/LayoutConstraints.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Logging.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Menus.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/MimeTypes.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Misc.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Panel.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Parameters.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Printing.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Process.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/SashSplitter.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Sizers.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Streams.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/StyledTextConstants.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Threading.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/ToolBar.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Tree.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Validators.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/Window.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/__init__.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/d_stc.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/d_wx.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/decorator.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/gen.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/stc_.py create mode 100644 wxPython/wxPython/lib/PyCrust/wxd/wx_.py create mode 100644 wxPython/wxPython/lib/colourchooser/__init__.py create mode 100644 wxPython/wxPython/lib/colourchooser/canvas.py create mode 100644 wxPython/wxPython/lib/colourchooser/intl.py create mode 100644 wxPython/wxPython/lib/colourchooser/pycolourbox.py create mode 100644 wxPython/wxPython/lib/colourchooser/pycolourchooser.py create mode 100644 wxPython/wxPython/lib/colourchooser/pycolourslider.py create mode 100644 wxPython/wxPython/lib/colourchooser/pypalette.py create mode 100644 wxPython/wxPython/lib/evtmgr.py create mode 100644 wxPython/wxPython/lib/gridmovers.py create mode 100644 wxPython/wxPython/lib/imageutils.py create mode 100644 wxPython/wxPython/lib/intctrl.py create mode 100644 wxPython/wxPython/lib/mixins/rubberband.py create mode 100644 wxPython/wxPython/lib/multisash.py create mode 100644 wxPython/wxPython/lib/popupctl.py create mode 100644 wxPython/wxPython/lib/pubsub.py create mode 100644 wxPython/wxPython/lib/scrolledpanel.py create mode 100644 wxPython/wxPython/lib/throbber.py create mode 100644 wxPython/wxPython/lib/timectrl.py create mode 100644 wxPython/wxPython/tools/XRCed/CHANGES.txt rename wxPython/wxPython/tools/XRCed/{README => README.txt} (92%) rename wxPython/wxPython/tools/XRCed/{TODO => TODO.txt} (76%) create mode 100644 wxPython/wxPython/tools/XRCed/encode_bitmaps.py create mode 100644 wxPython/wxPython/tools/XRCed/globals.py create mode 100644 wxPython/wxPython/tools/XRCed/license.txt create mode 100644 wxPython/wxPython/tools/XRCed/panel.py create mode 100644 wxPython/wxPython/tools/XRCed/sawfishrc create mode 100644 wxPython/wxPython/tools/XRCed/src-images/AutoRefresh.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Copy.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Cut.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Icon.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/New.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Open.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Paste.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Redo.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Refresh.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Save.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Test.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolBitmapButton.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolBoxSizer.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolButton.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolCheckBox.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolCheckList.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolChoice.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolComboBox.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolDefault.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolDialog.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolFlexGridSizer.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolFrame.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolGauge.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolGridSizer.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolListBox.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolListCtrl.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolMenu.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolMenuBar.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolMenuItem.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolNotebook.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolPanel.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolRadioBox.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolRadioButton.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolRoot.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolScrollBar.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolSeparator.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolSlider.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolSpacer.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolSpinButton.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolSpinCtrl.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolStaticBitmap.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolStaticBox.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolStaticBoxSizer.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolStaticLine.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolStaticText.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolTextCtrl.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolTool.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolToolBar.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolTreeCtrl.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/ToolUnknown.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeDefault.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeDialog.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeFrame.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeMenu.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeMenuBar.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeMenuItem.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreePanel.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeRoot.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeSeparator.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeSizerFlexGrid.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeSizerGrid.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeSizerH.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeSizerV.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeStaticBoxSizerH.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeStaticBoxSizerV.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeTool.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png create mode 100644 wxPython/wxPython/tools/XRCed/src-images/Undo.png create mode 100644 wxPython/wxPython/tools/XRCed/tools.py create mode 100644 wxPython/wxPython/tools/XRCed/tree.py create mode 100644 wxPython/wxPython/tools/XRCed/undo.py create mode 100644 wxPython/wxPython/tools/dbg.py create mode 100644 wxPython/wxPython/tools/helpviewer.py create mode 100644 wxPython/wxSWIG/swig_lib/perl5/.cvsignore create mode 100644 wxPython/wxSWIG/swig_lib/python/.cvsignore create mode 100644 wxPython/wxSWIG/swig_lib/tcl/.cvsignore diff --git a/wxPython/.cvsignore b/wxPython/.cvsignore index 611f71ef4c..38dfbf734e 100644 --- a/wxPython/.cvsignore +++ b/wxPython/.cvsignore @@ -2,8 +2,12 @@ .emacs.desktop .gdb_history MANIFEST +_build_dmg _build_rpm build +build-gtk +build-gtk2 +build-gtk2.unicode build-pkg build-pkg-debug build.local diff --git a/wxPython/BUILD.osx.txt b/wxPython/BUILD.osx.txt index 1af6b0d189..14bee6102d 100644 --- a/wxPython/BUILD.osx.txt +++ b/wxPython/BUILD.osx.txt @@ -1,57 +1,32 @@ Building wxPython on Mac OS X ----------------------------- -NOTE: OS X support is HIGHLY EXPERIMENTAL at this time. Most things - are working now, but a few still don't. I know about most of - them and am addressing them as I have time. If you have any - ideas about a fix for the stuff that's still broken then - please persue them and send the fixes to me. - -These are the steps I have used for building wxPython on Mac OS X 10.1 +These are the steps I have used for building wxPython on Mac OS X 10.x with the Apple Developer Tools, a.k.a the Darwin version. I assume that you know your way around a command line and that you know how to get things from various CVS repositories as needed. -1. Python 2.2 is required. There is a disk image with an installer - package in the wxPython Sourceforge download area, in this group: +1. "MacPython-OSX" 2.3 is required. There is a disk image with an + installer package in the wxPython Sourceforge download area, in + this group: http://sourceforge.net/project/showfiles.php?group_id=10718&release_id=84730 If, for some reason you need to build your own Python, get the - source from www.python.org and follow theinstructions in the - Mac/OSX/README file to build and install Python.app and the - Python.framework. - - If you build your own Python then you may want to make a symlink or - two in /usr/local/bin so that this version of Python can be found - from the command line. For example: - - cd /usr/local/bin - sudo ln -s /Library/Frameworks/Python.framework/Versions/2.2/bin/python2.2 python2.2 - sudo ln -s python2.2 python - - Also, if you create a /usr/local/bin/pythonw script like the - following then you can run Python GUI apps (like wxPython) directly - from the command line: - - #!/bin/sh - exec /Applications/Python.app/Contents/MacOS/python $@ - - Be sure to give this script execute permissions: - - sudo chmod +x /usr/local/bin/pythonw - - If you would like to make a MachoPython installer from what you - built then you may want to look at the scripts I use to do it - located in wxPython/distrib/mac/buildPython. + source from www.python.org and follow the instructions in the + Mac/OSX/README file to build and install the Python.framework and + Python tools. One last thing, make sure that /usr/local/bin is in your PATH - environment variable. + environment variable since that is where the new python and pythonw + commands will be located. -2. In a wxWindows CVS tree make a build directory. +2. In a wxWindows CVS tree make a build directory. (You can also use + a CVS snapshot located in http://wxwindows.org/snapshots/ or the + released wxPythonSrc-*.tr.gz archive.) cd ~/proj/wxWindows # or wherever you put it mkdir build @@ -69,7 +44,14 @@ get things from various CVS repositories as needed. 5. Build and install wxPython. cd ../wxPython - python setup.py IN_CVS_TREE=1 build install + python setup.py build install + + If you would like to install to someplace besides the Python + site-packages directory (such as to your home directory) then you + can add "--root=" after the "install" command. To use + wxPython like this you'll need to ensure that the directory + containing wxPyrthon is contained in in the PYTHONPATH environment + variable. 6. Test. Just navigate in the Finder to the demo directory and double click demo.py, or simple.py, or whatever you want to run. Or from diff --git a/wxPython/BUILD.unix.txt b/wxPython/BUILD.unix.txt index 32bc8aeee6..a2abfebb32 100644 --- a/wxPython/BUILD.unix.txt +++ b/wxPython/BUILD.unix.txt @@ -1,23 +1,27 @@ Building wxPython on Unix or Unix-like Systems ---------------------------------------------- -The basic steps for building wxPython for Unix or Unix-like systems -are: - - 1. Compile and/or install glib and gtk+ - 2. Compile and/or install wxGTK - 3. Compile and install wxPython - -We'll go into more detail of each of these steps below, but first a -few bits of background information on tools. - -I use a tool called SWIG (http://www.swig.org) to help generate the -C++ sources used in the wxPython extension module. However you don't -need to have SWIG unless you want to modify the *.i files. I've made -several modifications to SWIG specific to wxPython's needs and so the -modified sources are included in the wx CVS at .../wxPython/wxSWIG. -If you need to modify the *.i files for wxPython then change to this -directory and run: +NOTE: You should probably look at the ../ README.1st.txt file for +directions for how to build wxPython the "new way." This files +describes the "old way" to build on unix-like systems. The difference +is very simple: The new way uses a private copy of wxGTK while the +old way uses either an existing wxGTK that may be installed and used +by other apps, or you can build a wxGTK that will be accissible by +other apps. + + +NOTE 2: I use a tool called SWIG (http://www.swig.org) to help +generate the C++ sources used in the wxPython extension module. +However you don't need to have SWIG unless you want to modify the *.i +files. I've made several modifications to and older version of SWIG +that are specific to wxPython's needs and so the modified sources are +included in the wx CVS at .../wxPython/wxSWIG. But because of the +size and since most people won't need it my SWIG is not included in +the wxPythonSrc tarball. You'll need to get it from CVS or a CVS +snapshot. + +If you need to modify the *.i files for wxPython then you will need to +build wxswig. Change to the .../wxPython/wxSWIG directory and run: configure make @@ -46,29 +50,13 @@ A. First of all, check and see if you've already got glib/gtk+ on your gtk-config --version - If you have version 1.2.5 or better then you're all set. You can - skip to step #2. + If you have version 1.2.7 or better then you're all set. Otherwise + either get the pacakges for your unix distribution and install them + or get the sources from www.gtk.org and build and install them. -B. If your system has a binary package mechanism, (RPMs, debs, - whatever...) check and see if binaries for glib abd gtk+ are - available. Be sure to get the runtime library package as well as - the development package, if they are separate. Install them with - your package tool, and skip to step #2. - -C. If all else fails, you can get the source code for glib and gtk+ at - http://www.gtk.org/. Fetch the latest of each in the 1.2.x - series. Compile and install each of them like this: - - gzip -d [package].tar.gz | tar xvf - - cd [package] - ./configure - make - make install - - The last step will probably have to be done as root. Also, if your - system needs anything done to update the dynamic loader for shared - libraries, (such as running ldconfig on Linux) then do it after - each library is installed. + The best version to get is the latest 1.2.x release as the + wxWindows support for GTK 2.x is still beta-level. (Most tings + work great though, and it looks real nice.) @@ -77,30 +65,40 @@ C. If all else fails, you can get the source code for glib and gtk+ at A. You can find the sources and RPMs for wxGTK at http://wxwindows.org/, just follow the download links from the - nevigation panel. You can also check out a current snapshot of the - sources from the CVS server. (Some information about annonymous - CVS access is at http://wxwindows.org/cvs.htm.) The advantage of - using CVS is that you can easily update as soon as the developers - check in new sources or fixes. The advantage of using a released - version is that it usually has had more thorough testing done. You - can decide which method is best for you. + navigation panel. + + Source code for wxGTK is now included with the wxPythonSrc tarball, + and is the recommended way to get released wxGTK source code if you + plan on building both. + + You can also check out a current snapshot of the sources from the + CVS server. (Some information about annonymous CVS access is at + http://wxwindows.org/cvs.htm.) The advantage of using CVS is that + you can easily update as soon as the developers check in new + sources or fixes. The advantage of using a released version is + that it usually has had more thorough testing done. You can decide + which method is best for you. + B. You'll usually want to use a version of wxGTK that has the same version number as the wxPython sources you are using. (Another - advantage of using CVS is that you'll get both at the same time.) + advantage of using wxPythonSrc or CVS is that you'll get both at + the same time.) + C. If using the RPMs be sure to get both the wxGTK and wxGTK-devel RPMs (at a minimum) and then install them as root. rpm -Uhv wxGTK-2.2.2-0.i386.rpm wxGTK-devel-2.2.2-0.i386.rpm + D. If using the sources (either from the tarball or from CVS) then configure it like this: cd wxWindows # or whatever your top-level directory is called mkdir build cd build - ../configure --with-gtk + ../configure --with-gtk --enable-geometry There are gobs and gobs of options for the configure script, run ../configure --help to see them all. I'll describe some that I find @@ -118,32 +116,9 @@ D. If using the sources (either from the tarball or from CVS) then special debugging code in wxWindows by defining the __WXDEBUG__ macro. You'll get some extra asserts, failure logging, etc. - To make a static library and not make a shared library, use the - --disable-shared and --enable-static flags. - - NOTE: There is a potential type mismatch between Python and wxGTK. - This happens if Python defines some flags that turn on 64-bit file - offset support and wxGTK does not. This causes some basic types, - like off_t, to be typedef'd differently causing the C++ method - signatures to be incompatible and giving link errors at runtime. - If you get errors upon running a wxPython script that looks - something like this: - - SeekI_13wxInputStream10wxSeekMode: referenced symbol not found - - then that is probably the issue. This can be fixed in the current - code by predefining these flags before wxGTK's configure is run, - for example: - - export CFLAGS="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DHAVE_LARGEFILE_SUPPORT" - export CXXFLAGS=$CFLAGS - ../configure --with-gtk --with-opengl --enable-debug + If you are using GTK 2.x then you'll want to add --enable-gtk2 and + probably also --enable-unicode. - In the 2.3.3 final release there will be a real configure flag for - it, and it should be enabled by default. You will be able to use - --enable-largefile or --disable-largefile to control it. If you - still get this or a similar error with 2.3.3 then try disabling - largefile support in wxGTK. E. Now just compile and install. You need to use GNU make, so if your system has something else get GNU make and build and install it and @@ -156,6 +131,7 @@ E. Now just compile and install. You need to use GNU make, so if your system needs anything done to update the dynamic loader for shared libraries, (such as running ldconfig on Linux) then do it now. + F. You can test your build by changing to one of the directories under build/samples or build/demos, running make and then running the executable that is built. @@ -167,33 +143,24 @@ F. You can test your build by changing to one of the directories under A. You have the same options (and same advantages/disadvantages) for getting the wxPython source, either a released snapshot or from - CVS. The released version file is named wxPython-[version].tar.gz + CVS. The released version file is named wxPythonSrc-[version].tar.gz and is available at http://wxpython.org/download.php. If you want to use CVS you'll find wxPython in the wxWindows CVS tree (see above) in the wxWindows/wxPython directory. -B. As mentioned previouslly, wxPython is built with the standard - Python Distutils tool. If you are using Python 2.0 or later you - are all set, otherwise you need to download and install Distutils - 1.0 from http://www.python.org/sigs/distutils-sig/. + +B. wxPython is built with the standard Python Distutils tool and + currently includes it's own snapshot of the latest version of + distutils which can also be used with previous versions of Python On Unix systems Distutils figures out what commands and flags to use for the compiler and linker by looking in the Makefile that was used to build Python itself. Most of the time this works okay. If it doesn't, there doesn't seem to be a way to override the values that Distutils uses without hacking either Distutils itself, or - Python's Makefile. (Complain to the distutils-sig about this - please.) For example, on a Solaris system I had to edit - /usr/local/lib/python1.5/config/Makefile and replace - - LDSHARED=ld -G - - with - - LDSHARED=gcc -G - - This particular problem has been fixed in Python 1.6 and beyond, - but there may be similar issues on other platforms. + Python's Makefile. (NOTE: This has been changed with the + distutilsincluded with Python 2.3 but I havn't yet looked into how + best to utilize this in wxPython...) While we're on the subject of how Python was built... Since wxPython is a C++ extension some platforms and/or compilers will @@ -215,13 +182,14 @@ B. As mentioned previouslly, wxPython is built with the standard make install I recently built Python 2.1.3 and Python 2.2.1 on Solaris and did - not have to resort to this workaround so apparently thigns are + not have to resort to this workaround so apparently things are getting better there. I will leave this note here though in case there are similar issues elsewhere. However I did run into a Python build issue that affects the wxPython build when attempting to use SunCC instead of GNU gcc. See the note below titled "Building with non-GNU compilers" if you are interested. + C. Change to the root wxPython directory and look at the setup.py file. This is the script that configures and defines all the information that Distutils needs to build wxPython. There are some @@ -248,18 +216,7 @@ C. Change to the root wxPython directory and look at the setup.py will be executed to regenerate the wrapper C++ and shadow python files. - IN_CVS_TREE If you are using the CVS version of the - wxWindows and wxPython sources then you will - need to set this flag to non-zero. This is - needed because some source files from the - wxWindows tree are copied to be under the - wxPython tree in order to keep Distutils happy. - With this flag set then setup.py will - automatically keep these copied sources up to - date if the original version is ever updated. - If you are using the tar.gz version of the - Python sources then these copied sources are - already present in your source tree. + etc. D. To build and install wxPython you simply need to execute the @@ -269,15 +226,32 @@ D. To build and install wxPython you simply need to execute the site-packages directory you may need to be root to run the install command. - python setup.py build - python setup.py install + python setup.py build install + + If you need to change any of the build flags that can also be done + on the setup.py command line, like this: + + python setup.py BUILD_GLCANVAS=0 build install + + If you are using GTK 2.x then you'll want to add these flags: + + python setup.py WXPORT=gtk2 UNICODE=1 build install + + If you would like to install to someplace besides the Python + site-packages directory (such as to your home directory) then you + can add "--root=" after the "install" command. To use + wxPython like this you'll need to ensure that the directory + containing wxPyrthon is contained in in the PYTHONPATH environment + variable. + E. At this point you should be able to change into the wxPython/demo directory and run the demo: python demo.py -F. If you would like to make a test build that doesn't overwrite the + +F. If you would like to make a test build that doesn't overwrite any installed version of wxPython you can do so with this command instead of the install command above: @@ -360,5 +334,7 @@ before running configure, like this in bash: After making and installing Python with this configuration you should be able to build wxPython as described in the steps above. + + ----------------- robin@alldunn.com diff --git a/wxPython/BUILD.win32.txt b/wxPython/BUILD.win32.txt index 163cc1664c..f0cde57a6b 100644 --- a/wxPython/BUILD.win32.txt +++ b/wxPython/BUILD.win32.txt @@ -8,10 +8,9 @@ your sources from and what your desired end result is, there are several permutations of those steps. At a high level the basic steps are: - 1. Get the wxWindows sources + 1. Get the sources 2. Build the wxWindows DLL - 3. Get the wxPython sources - 4. Build and Install wxPython + 3. Build and Install wxPython We'll go into more detail of each of these steps below, but first a few bits of background information on tools. @@ -20,7 +19,11 @@ I use a tool called SWIG (http://www.swig.org) to help generate the C++ sources used in the wxPython extension module. However you don't need to have SWIG unless you want to modify the *.i files. I've made several modifications to SWIG specific to wxPython's needs and so the -modified sources are included in the wx CVS at .../wxPython/wxSWIG. +modified sources are included in the wx CVS at.../wxPython/wxSWIG. +But because of the size and since most people won't need it my SWIG is +not included in the wxPythonSrc tarball. You'll need to get it from +CVS or a CVS snapshot. + If you need to modify the *.i files for wxPython then change to this directory and run: @@ -42,6 +45,7 @@ If anybody wants to try it I'll take any required patches for the setup script and for these instructions. + UNICODE ------- @@ -69,44 +73,44 @@ And now on to the fun stuff... -1. Get the wxWindows sources ----------------------------- +1. Get the sources +------------------ -A. There are a few possible ways to get sources for wxWindows. You - can download a released version from http://wxwindows.org/ or you - can get current development sources from the CVS server. (Some - information about annonymous CVS access is at the - http://wxwindows.org/cvs.htm site.) The advantage of using CVS is - that you can easily update as soon as the developers check in new - sources or fixes. The advantage of using a released version is - that it usually has had more thorough testing done. You can decide - which method is best for you. +A. You can either use a tarball with the released version of the + source code for wxWindows/wxPython, or you can get current + development sources from the CVS repository. (Some information + about annonymous CVS access is at the http://wxwindows.org/cvs.htm + site.) The advantage of using CVS is that you can easily update as + soon as the developers check in new sources or fixes. The + advantage of using a released version is that it usually has had + more thorough testing done. You can decide which method is best + for you. The released version file is named + wxPythonSrc-[version].tar.gz and is available from the wxPython + website at http://wxpython.org/download.php. You can use WinZip to + unpack it if you don't have tar and gzip. -B. You'll usually want to use wxWindows sources that have the same - version number as the wxPython sources you are using. (Another - advantage of using CVS is that you'll get both at the same time.) -C. Once you get the sources be sure to put them in a path without a +B. Once you get the sources be sure to put them in a path without a space in it (i.e., NOT c:\Program Files\wx) and set an environment - variable named WXWIN to this directory. For example: + variable named WXWIN to the top level directory. For example: - mkdir \wx2 - cd \wx2 - unzip wxMSW-2.2.2.zip - set WXWIN=c:\wx2 + set WXWIN=c:\wx\wxPythonSrc-2.4.0.4 - You'll probably want to add that last line to your autoexec.bat or + You'll probably want to add that line to your autoexec.bat or System Properties depending on the type of system you are on. -D. Change to the wx2\include\wx\msw directory and copy setup0.h to + +C. Change to the %WXWIN%\include\wx\msw directory and copy setup0.h to setup.h and then edit setup.h. This is how you control which parts of wxWindows are compiled into or left out of the build, simply by turning options on or off. I have the following differences from the default setup0.h in my setup.h, but you can experiment with other settings if you like: + WXWIN_COMPATIBILITY_2_2 0 wxDIALOG_UNIT_COMPATIBILITY 0 + wxUSE_DEBUG_CONTEXT 1 wxUSE_MEMORY_TRACING 1 wxUSE_CMDLINE_PARSER 0 wxUSE_FSVOLUME 0 @@ -134,6 +138,7 @@ A. Although MSVC project files are provided I always use the makefiles Python, (and I make sure they stay that way.) You would have to edit the project files a bit to make it work otherwise. + B. There are three different types of wxWindows DLLs that can be produced by the VC makefile simply by providing a flag on the nmake command-line, I call the three types DEBUG, FINAL, and HYBRID. @@ -157,43 +162,41 @@ B. There are three different types of wxWindows DLLs that can be wxmsw[version].dll. This DLL is compiled with optimizations turned on and without debugging information and without __WXDEBUG__. The /MD flag is used which means that you - can use this version with the standard python.exe. This - is the version that I use when making the binary installer - for win32. + can use this version with the standard python.exe. HYBRID Specified with "FINAL=hybrid" and produces a DLL named wxmsw[version]h.dll. This DLL is almost the same as the - DEBUG version except the /MD flag is used which means that - you can use the standard python.exe but you still get the - debugging info and the __WXDEBUG__ code enabled. With the - debugger you can trace through the the code for the - wxPython extension and the wxWindows DLL, but not the - Python interpreter. You might use this version when you - want to deploy a wxPython app with the __WXDEBUG__ code - enabled. I use this mode most of the time during - development simply because it's easier than having to - remember to type python_d all the time. + FINAL version except the __WXDEBUG__ is used which means + that you will get extra runtime assertions and validations + from wxWindows. If any of these fail then they are turned + into a Python exception that you can catch and deal with + in your code. This is the version that I use when making + the binary installer for win32. + Since different DLL names and object file directories are used you can build all three types if you like. -C. Change to the wx2\src\msw directory and type the following command, + +C. Change to the %WXWIN%\src\msw directory and type the following command, using the value for FINAL that you want: - nmake -f makefile.vc dll pch FINAL=hybrid + nmake -f makefile.vc dll FINAL=hybrid Your machine will then crunch away for possibly a long time, depending on your hardware, and when it's done you should have a - DLL and some library files in \wx2\lib. + DLL and some library files in %WXWIN%\lib. + -D. You'll either need to add \wx2\lib to the PATH or copy the DLL file - to a directory already on the PATH so the DLL can be found at +D. You'll either need to add %WXWIN%\lib to the PATH or copy the DLL + file to a directory already on the PATH so the DLL can be found at runtime. Another option is to copy the DLL to the directory that the wxPython pacakge is installed to, for example, c:\Python22\lib\site-packages\wxPython. + E. You can test your build by changing to one of the directories under - \wx2\samples or \wx2\demos and typing (using the right FINAL flag): + %WXWIN%\samples or %WXWIN\demos and typing (using the right FINAL flag): nmake -f makefile.vc FINAL=hybrid WXUSINGDLL=1 @@ -201,20 +204,8 @@ E. You can test your build by changing to one of the directories under -3. Get the wxPython sources ---------------------------- - -A. You have the same options (and same advantages/disadvantages) for - getting the wxPython source, either a released snapshot or from - CVS. The released version file is named wxPython-[version].tar.gz - and is available at http://wxpython.org/download.php. You can use - WinZip to unpack it if you don't have tar and gzip. If you want to - use CVS you'll find wxPython in the wxWindows CVS tree (see above) - in the wxWindows/wxPython directory. - - -4. Build and Install wxPython +3. Build and Install wxPython ----------------------------- A. As mentioned previouslly, wxPython is built with the standard @@ -222,6 +213,7 @@ A. As mentioned previouslly, wxPython is built with the standard are all set, otherwise you need to download and install Distutils 1.0 from http://www.python.org/sigs/distutils-sig/. + B. Change to the root wxPython directory and look at the setup.py file. This is the script that configures and defines all the information that Distutils needs to build wxPython. There are some @@ -246,18 +238,7 @@ B. Change to the root wxPython directory and look at the setup.py will be executed to regenerate the wrapper C++ and shadow python files. - IN_CVS_TREE If you are using the CVS version of the - wxWindows and wxPython sources then you will - need to set this flag to non-zero. This is - needed because some source files from the - wxWindows tree are copied to be under the - wxPython tree in order to keep Distutils happy. - With this flag set then setup.py will - automatically keep these copied sources up to - date if the original version is ever updated. - If you are using the tar.gz version of the - Python sources then these copied sources are - already present in your source tree. + etc. C. To build and install wxPython you simply need to execute the @@ -280,12 +261,20 @@ C. To build and install wxPython you simply need to execute the commented out. Just search for "GX-" and uncomment it so it is put into the cflags list. + If you would like to install to someplace besides the Python + site-packages directory (such as to your home directory) then you + can add "--root=" after the "install" command. To use + wxPython like this you'll need to ensure that the directory + containing wxPyrthon is contained in in the PYTHONPATH environment + variable. + D. At this point you should be able to change into the wxPython\demo directory and run the demo: python demo.py + E. If you would like to make a test build that doesn't overwrite the installed version of wxPython you can do so with one of these commands instead of the install command above: @@ -301,8 +290,8 @@ E. If you would like to make a test build that doesn't overwrite the To run using this test version just add the base wxPython source directory to the PYTHONPATH: - set PYTHONPATH=c:\wx2\wxPython - cd c:\wx2\wxPython\demo + set PYTHONPATH=%WXDIR%\wxPython + cd %WXDIR%\wxPython\demo python demo.py diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index eefa6256aa..1f94276ec2 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -2,8 +2,239 @@ CHANGES.txt for wxPython ---------------------------------------------------------------------- -2.3.3 ------ +????? +------- + +Added wxScrolledPanel from Wil Sadkin + + + +2.4.0.7 +------- +Gave up on generating a warning upon the use of the old true/false or +TRUE/FALSE values. + +Fixed wxGenericTreeCtrl (used on wxGTK and wxMac for wxTreeCtrl) so +that it can successfully handle lots of nodes instead of overflowing +when the virtual height of the widget overflowed a 16-bit value. + +Fixed the typemap that converts strings to wxColours to also accept +unicode. + +Fixed problem where the wrong class name could sometimes be used for +OOR. + +Fixed an interpreter lock problem in the __eq__ and __ne__ methods in +wxSize and etc. + +Updated PyCrust to version 0.9 + +Instead of always logging C++ assertions, added wxPYAPP_ASSERT_LOG +flag to turn it on. In most cases turning it into an exception (the +default behavior) is enough. See below in the 2.3.4.1 notes for more +details. + + + + +2.4.0.6 (a.k.a. the I'm so stupid release) +------- +The new deprecation class for the old true/false symbols can now be +returned from OnInit. And I promise to be sure I am testing what I +think I am testing in the future... + + + +2.4.0.5 (a.k.a. the blame it on Kevin release) +------- +A few little but annoying bug fixes. + +Updated pycolourchooser. + +Updated to 0.9b of PyCrust. + + + +2.4.0.4 +------- +Added missing wxRect methods + +Add OOR support for wxApp objects too. + +Added wxCursorFromImage, which works on wxMSW and wxGTK so far. + +All platforms now send EVT_DESTROY_WINDOW. Be warned that at the time +the event is sent the window is in the process of being deconstructed, +and so calling some (most?) methods of the window itself may cause +problems. + +Fixed SF Bug #689481, a method in the OGL wrappers was using the wrong +return type. + +Fixed SF Bug #689958, an endless loop in printout.py. + +Added EVT_WINDOW_CREATE_ID and EVT_WINDOW_DESTROY_ID so these events +can be associated with a specific window ID and more easily caught by +the parent window. + +Fixed copy-paste error in wxListCtrl.GetFirstSelected. + +Added missing Init method (and an overloading wrapper) to wxLocale +wrapper. + +Added a wxBitmap.SetMaskColour convenience method. + +Changed how the dynamic event tables (used for all Python wx classes, +C++ wx classes typically use static event tables) are searched such +that they behave from a Python perspective more like the static tables +in C++. Namely that if there are identical event bindings in a base +Python class and a derived Python class that the one in the derived +class will be found first and that if Skip is called that the one in +the base class will still be found instead of skipping directly to the +static stable in the C++ class. + +Switched to using True/False in the wxPython lib and demo instead of +true/false or TRUE/FALSE to prepare for the new boolean type and +constants being added to Python. Added code to wx.py to test for the +existence of the new constants and to create suitable values if not +present. + +Added some static wxApp functions that help with integration with the +Mac UI. They are no-ops on other platforms so it doesn't hurt to +always call them. The functions are: + + wxApp_GetMacDefaultEncodingIsPC + wxApp_GetMacSupportPCMenuShortcuts + wxApp_GetMacAboutMenuItemId + wxApp_GetMacPreferencesMenuItemId + wxApp_GetMacExitMenuItemId + wxApp_GetMacHelpMenuTitleName + wxApp_SetMacDefaultEncodingIsPC + wxApp_SetMacSupportPCMenuShortcuts + wxApp_SetMacAboutMenuItemId + wxApp_SetMacPreferencesMenuItemId + wxApp_SetMacExitMenuItemId + wxApp_SetMacHelpMenuTitleName + +Refactored, enhanced and added capabilities for the DrawXXXList +functions, inspired by code from Chris Barker. + +The wxWindows .mo language catalog files are now installed in a +subdirectory of the wxPython package dir on MSW since that platform +doesn't have a standard place for them. + +Added missing deselect methods for wxGrid. + +Fixed typemaps for wxGridCellCoordsArray. + +Updated to the 0.9a version of PyCrust + + + +2.4.0.2 +------- +Several bug fixes. + +Added wxIntCtrl from Will Sadkin. + +Added wxPyColourChooser by Michael Gilfix. + + + + +2.4.0.1 +------- +No major new features since 2.3.4.2, mostly bug fixes and minor +enhancements. + +Added function wrappers for the common dialogs from Kevin Altis. See +wxPython/lib/dialogs.py for more details. + + + +2.3.4.2 +------- +Various bug fixes. + + + +2.3.4.1 +------- +Updated XRCed and wxTimeCtrl contribs. + +Show a couple new wxGrid features in the demo. + +Several bug fixes in wxWindows. + +Added wxHtmlFilter. + +wxASSERT and related C++ runtime diagnostics are now converted to +Python exceptions. When an assert happens a wxPyAssertionError +(which derives from AssertionError) exception is created and when +control returns back to the Python code that invoked the C++ API it +will be raised. The same exception restrictions are in place as +before, namely that exceptions can't cross from one Python layer +through C++ to another Python layer. That simply means that if you +want to catch wxPyAssertionError or any other exception that you need +to do it before control returns to C++ at the end of your event +handler or callback code. There is some test code in demo/wxButton.py +you can use to play with this new feature. + +Added some methods to wxApp (SetAssertMode and GetAssertMode) that let +you control how C++ assertions are processed. Valid modes are: +wxPYAPP_ASSERT_SUPPRESS, wxPYAPP_ASSERT_EXCEPTION, and +wxPYAPP_ASSERT_DIALOG. Using _SUPPRESS will give you behavior like +the old "final" builds and the assert will be ignored, _EXCEPTION is +the new default described above, and _DIALOG is like the default in +2.3.3.1 and prior "hybrid" builds. You can also combine _EXCEPTION +and _DIALOG if you wish, although I don't know why you would. + +You can now overload OnInitGui, OnExit and OnAssert in your classes +derived from wxApp. + +Added GetSelectedCells, GetSelectionBlockTopLeft, +GetSelectionBlockBottomRight, GetSelectedRows, GetSelectedCols nethods +to wxGrid. + +Added Python == and != operators for some basic classes + +Fixed the Python wrappers for wxInputStream so they no longer block +when reading from a wxProcess on wxGTK. They now work more or less as +they did before 2.3.3.1 but the dual meaning of eof() has been +removed. There is now a CanRead() method that lets you know if there +is data waiting to be read from the pipe. + +Fixed method name clash in wxIEHtmlWin, renamed Refresh to RefreshPage. + +Added Throbber from Cliff Wells to the library and the demo. + +Windows installer prompts to uninstall old version first. + +Added wxPython.lib.evtmgr by Robb Shecter, which is an easier, more +"Pythonic" and more OO method of registering handlers for wxWindows +events using the Publish/Subscribe pattern. + +Added wxPython.lib.popupctl by Gerrit van Dyk which is a combobox-like +gizmo for poping up arbitrary controls. It is currently using +wxDialog because of some issues with wxPopupWindow... + +Added wxPython.lib.gridmovers by Gerrit van Dyk which facilitates the +dragging of columns and/or rows in a wxGrid. + +Added wxPython.lib.multisash by Gerrit van Dyk which is a nice +implementation of allowing the user to split a window any number of +times either horizontally or vertically, and to close the split off +windows when desired. + +Added helpviewer tool that displays HTML books similarly to how MS +HTMLHelp viewer does. Changed how the wxPythonDocs tarball is built +and added a script to launch the doc viewer. + + + + +2.3.3.1 +------- Added wxSplashScreen. Added wxGenericDirCtrl. @@ -174,6 +405,9 @@ Added wxXmlResourceHandler which allows you to create custom handlers for nonstandard class types in XRC resources. See the demo for an example. +Added wxPython.lib.mixins.rubberband module from Robb Shecter. + +Added wxTimeCtrl from Will Sadkin. @@ -205,8 +439,8 @@ Added XRCed to the wxPython Tools directory, contributed by Roman Rolinsky. Added a new "constructor" to most of the window classes that calls the -default C++ contructor, (the one with no parameters) and also added the -coresponding Create(...) method. This allows you to do a 2-step +default C++ constructor, (the one with no parameters) and also added the +corresponding Create(...) method. This allows you to do a 2-step creation of windows which is sometimes required for doing things such as setting extended style flags before the window is created, or for passing the object to the XRC resource system to be created from the @@ -742,7 +976,7 @@ methods look like this: toggle=FALSE) -There are also coresponding InsertTool and InsertSimpleTool methods +There are also corresponding InsertTool and InsertSimpleTool methods that additionally take an integer position as the first parameter. Added a wrapper for the new PCX and TIFF ImageHandlers. diff --git a/wxPython/MANIFEST.in b/wxPython/MANIFEST.in index 11ad108fbd..0dbd7d830c 100644 --- a/wxPython/MANIFEST.in +++ b/wxPython/MANIFEST.in @@ -44,11 +44,6 @@ include samples/doodle/*.txt include samples/doodle/*.py include samples/doodle/*.iss include samples/doodle/sample.ddl -include samples/stxview/*.txt -include samples/stxview/*.py -include samples/stxview/*.stx -include samples/stxview/StructuredText/*.py -include samples/stxview/StructuredText/*.txt include samples/wxProject/*.txt include samples/wxProject/*.py include samples/StyleEditor/*.py diff --git a/wxPython/README.txt b/wxPython/README.txt index 278202e0f8..5e3c5b2f0a 100644 --- a/wxPython/README.txt +++ b/wxPython/README.txt @@ -3,58 +3,34 @@ wxPython README Welcome to the wonderful world of wxPython! -Once you have installed the wxPython extension module, you can try it -out by going to the [install dir]\wxPython\demo directory and typing: +So where do you go from here? The best thing to do is to run the demo +and use its source code to help you learn how to use wxPython. Most +of the classes available are demonstrated there, and you can view the +sources directly in the demo so it is designed to help you learn. If +you are on Windows or OS X then you can run the demo just by double +clicking it's icon. If you are on Linux/Unix then change to the +directory containing the demo and type: python demo.py -There are also some other sample files there for you to play with and -learn from. +There are also some sample mini applications available for you to run +and to play with as a learning exercise. -If you selected to install the documentation then point your browser -to [install dir]\wxPython\docs\index.htm and you will then be looking -at the docs for wxWindows. For the most part you can use the C++ docs -as most classes and methods are used identically. Where there are -differences they are documented with a "wxPython Note." +The next thing you should do is join the wxPython-users maillist where +you can interact with a community of other users and developers who +are willing to help you learn, answer questions and solve problems. +To join the mail list just send an email message to the following +address from the account you want to receive the mail messages from +the list: -On Win32 systems the binary self-installer creates a program group on -the Start Menu that contains a link to running the demo and a link to -the help file. To help you save disk space I'm now using Microsoft's -HTML Help format. If your system doesn't know what to do with the help -file, you can install the HTML Help Viewer as part of IE 4+, NT -Service Pack 4+, or the HTML Workshop at + wxPython-users-subscribe@lists.wxwindows.org -http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp - -For some features, the latest common controls library from microsoft -is required. You can get this by installing IE 5.0 or Office 2000. -You can also get it independently from here: - -http://download.microsoft.com/download/platformsdk/Comctl32/5.80.2614.3600/W9XNT4/EN-US/50comupd.exe - -Windows 95 users may also need the WinSock 2.0 and OpenGL libraries. -These can be found at these sites: - - -http://www.microsoft.com/windows95/downloads/contents/wuadmintools/s_wunetworkingtools/w95sockets2/default.asp - -http://www.opengl.org/Downloads/Downloads.html - - - -Getting Help ------------- - -Since wxPython is a blending of multiple technologies, help comes from -multiple sources. See the http://wxPython.org/ for details on various -sources of help, but probably the best source is the wxPython-users -mail list. You can view the archive or subscribe by going to - - http://lists.wxwindows.org/mailman/listinfo/wxpython-users - -Or you can send mail directly to the list using this address: - - wxpython-users@lists.wxwindows.org +There is also a good set of class reference documentation available +for wxPython, but currently it is geared for the C++ user. This may +be a little daunting at first, but with a little practice you'll +easily be able to "translate" from the C++ shown there to Python. Not +all classes documented are available in Python, but most of the GUI +related classes are. Other Info @@ -62,17 +38,21 @@ Other Info Please also see the following files in this directory: - CHANGES.txt Information about new features, fixes, etc. in - each release. + CHANGES.txt Information about new features, fixes, + etc. in each release. + + ../README.1st.txt Instructions for building wxGTK and + wxPython on Unix-like platforms the + "new way." - BUILD.unix.txt Instructions for building wxPython on various - Unix-like platforms. + BUILD.unix.txt Instructions for building wxPython on + various Unix-like platforms the "old way." - BUILD.win32.txt Instructions for building wxPython on Windows. + BUILD.win32.txt Instructions for building wxPython on Windows. - BUILD.osx.txt Instructions for building wxPython on Mac OS X. + BUILD.osx.txt Instructions for building wxPython on Mac OS X. - licence/* Text of the wxWindows license. + licence/* Text of the wxWindows license. diff --git a/wxPython/b b/wxPython/b index 4f6136fb0a..b66448d124 100755 --- a/wxPython/b +++ b/wxPython/b @@ -9,6 +9,8 @@ function getpyver { PYVER=2.1 elif [ "$1" = "22" ]; then PYVER=2.2 + elif [ "$1" = "23" ]; then + PYVER=2.3 else echo You must specify Python version as first parameter. exit @@ -30,7 +32,7 @@ OTHERFLAGS="" # "c" --> clean if [ "$1" = "c" ]; then shift - CMD="$SETUP $FLAGS $OTHERFLAGS clean" + CMD="$SETUP $FLAGS $OTHERFLAGS clean $*" OTHERCMD="rm -f wxPython/*.so" # "d" --> clean extension modules only @@ -47,12 +49,12 @@ elif [ "$1" = "t" ]; then # "i" --> install elif [ "$1" = "i" ]; then shift - CMD="$SETUP $FLAGS $OTHERFLAGS install" + CMD="$SETUP $FLAGS $OTHERFLAGS build_ext install $*" # "s" --> source dist elif [ "$1" = "s" ]; then shift - CMD="$SETUP $OTHERFLAGS sdist" + CMD="$SETUP $OTHERFLAGS sdist $*" # "r" --> rpm dist elif [ "$1" = "r" ]; then diff --git a/wxPython/b.bat b/wxPython/b.bat index 22f0042c1e..79c75bddc0 100755 --- a/wxPython/b.bat +++ b/wxPython/b.bat @@ -8,7 +8,7 @@ set FLAGS=USE_SWIG=1 IN_CVS_TREE=1 rem Use non-default python? -iff "%1" == "15" .or. "%1" == "20" .or. "%1" == "21" .or. "%1" == "22" then +iff "%1" == "15" .or. "%1" == "20" .or. "%1" == "21" .or. "%1" == "22" .or. "%1" == "23" then set VER=%1 set PYTHON=%TOOLS%\python%1%\python.exe shift @@ -71,29 +71,26 @@ elseiff "%1" == "a" then shift set CMD=echo Finished! - call b.bat 15 c - call b.bat 15 f - cd demo - p15 encode_bitmaps.py - cd - - call b.bat 15 r - call b.bat 15 c - call b.bat 15 h - call b.bat 15 r - - call b.bat 21 c - call b.bat 21 f - call b.bat 21 r - call b.bat 21 c + call b.bat 21 d call b.bat 21 h call b.bat 21 r + call b.bat 21 d UNICODE=1 + call b.bat 21 h UNICODE=1 + call b.bat 21 r UNICODE=1 - call b.bat 22 c - call b.bat 22 f - call b.bat 22 r - call b.bat 22 c + call b.bat 22 d call b.bat 22 h call b.bat 22 r + call b.bat 22 d UNICODE=1 + call b.bat 22 h UNICODE=1 + call b.bat 22 r UNICODE=1 + + call b.bat 23 d + call b.bat 23 h + call b.bat 23 r + call b.bat 23 d UNICODE=1 + call b.bat 23 h UNICODE=1 + call b.bat 23 r UNICODE=1 rem "b" --> both debug and hybrid builds diff --git a/wxPython/contrib/gizmos/gizmos.cpp b/wxPython/contrib/gizmos/gizmos.cpp index f92d609908..0abd1ec076 100644 --- a/wxPython/contrib/gizmos/gizmos.cpp +++ b/wxPython/contrib/gizmos/gizmos.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -110,8 +109,8 @@ public: wxPyBeginBlockThreads(); if ((found = wxPyCBH_findCallback(m_myInst, "DrawItem"))) { PyObject* dcobj = wxPyMake_wxObject(&dc); - PyObject* idobj = wxPyConstructObject((void*)&id, "wxTreeItemId", FALSE); - PyObject* recobj= wxPyConstructObject((void*)&rect, "wxRect", FALSE); + PyObject* idobj = wxPyConstructObject((void*)&id, wxT("wxTreeItemId"), FALSE); + PyObject* recobj= wxPyConstructObject((void*)&rect, wxT("wxRect"), FALSE); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OOO)", dcobj, idobj, recobj)); Py_DECREF(dcobj); Py_DECREF(idobj); @@ -659,11 +658,10 @@ static PyObject *_wrap_wxEditableListBox_SetStrings(PyObject *self, PyObject *ar PyObject* item = PySequence_GetItem(_obj1, i); #if wxUSE_UNICODE PyObject* str = PyObject_Unicode(item); - _arg1->Add(PyUnicode_AsUnicode(str)); #else PyObject* str = PyObject_Str(item); - _arg1->Add(PyString_AsString(str)); #endif + _arg1->Add(Py2wxString(str)); Py_DECREF(item); Py_DECREF(str); } @@ -1790,7 +1788,7 @@ static PyObject *_wrap_wxLEDNumberCtrl_GetValue(PyObject *self, PyObject *args, if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif diff --git a/wxPython/contrib/gizmos/gizmos.i b/wxPython/contrib/gizmos/gizmos.i index 48b33f4e7c..1af639a5b7 100644 --- a/wxPython/contrib/gizmos/gizmos.i +++ b/wxPython/contrib/gizmos/gizmos.i @@ -272,8 +272,8 @@ public: wxPyBeginBlockThreads(); if ((found = wxPyCBH_findCallback(m_myInst, "DrawItem"))) { PyObject* dcobj = wxPyMake_wxObject(&dc); - PyObject* idobj = wxPyConstructObject((void*)&id, "wxTreeItemId", FALSE); - PyObject* recobj= wxPyConstructObject((void*)&rect, "wxRect", FALSE); + PyObject* idobj = wxPyConstructObject((void*)&id, wxT("wxTreeItemId"), FALSE); + PyObject* recobj= wxPyConstructObject((void*)&rect, wxT("wxRect"), FALSE); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OOO)", dcobj, idobj, recobj)); Py_DECREF(dcobj); Py_DECREF(idobj); diff --git a/wxPython/contrib/glcanvas/glcanvas.i b/wxPython/contrib/glcanvas/glcanvas.i index 3b15de59f9..cdd8e7fbff 100644 --- a/wxPython/contrib/glcanvas/glcanvas.i +++ b/wxPython/contrib/glcanvas/glcanvas.i @@ -69,7 +69,7 @@ public: ~wxGLContext(); void SetCurrent(); - void SetColour(const char *colour); + void SetColour(const wxString& colour); void SwapBuffers(); #ifdef __WXGTK__ @@ -151,7 +151,7 @@ public: %pragma(python) addtomethod = "wxGLCanvasWithContext:val._setOORInfo(self)" void SetCurrent(); - void SetColour(const char *colour); + void SetColour(const wxString& colour); void SwapBuffers(); wxGLContext* GetContext(); diff --git a/wxPython/contrib/glcanvas/msw/myglcanvas.cpp b/wxPython/contrib/glcanvas/msw/myglcanvas.cpp index 13bab4a35f..59157560fa 100644 --- a/wxPython/contrib/glcanvas/msw/myglcanvas.cpp +++ b/wxPython/contrib/glcanvas/msw/myglcanvas.cpp @@ -27,15 +27,17 @@ #if wxUSE_GLCANVAS #ifndef WX_PRECOMP -#include + #include "wx/frame.h" + #include "wx/settings.h" + #include "wx/intl.h" + #include "wx/log.h" #endif -#include -#include -#include +#include "wx/msw/private.h" #include "myglcanvas.h" +const wxChar* wxGLCanvasName = wxT("GLcanvas"); static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass"); static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR"); @@ -108,7 +110,7 @@ void wxGLContext::SetCurrent() */ } -void wxGLContext::SetColour(const char *colour) +void wxGLContext::SetColour(const wxChar *colour) { float r = 0.0; float g = 0.0; @@ -403,7 +405,6 @@ static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList) void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) { - int pixelFormat; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size */ 1, /* version */ @@ -427,13 +428,13 @@ void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) AdjustPFDForAttributes(pfd, attribList); - pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); + int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); if (pixelFormat == 0) { - wxLogWarning(_("ChoosePixelFormat failed.")); + wxLogLastError(_T("ChoosePixelFormat")); } else { - if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) { - wxLogWarning(_("SetPixelFormat failed.")); + if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) { + wxLogLastError(_T("SetPixelFormat")); } } } @@ -527,7 +528,7 @@ void wxGLCanvas::SetCurrent() } } -void wxGLCanvas::SetColour(const char *colour) +void wxGLCanvas::SetColour(const wxChar *colour) { if (m_glContext) m_glContext->SetColour(colour); @@ -728,7 +729,7 @@ bool wxGLApp::InitGLVisual(int *attribList) AdjustPFDForAttributes(pfd, attribList); // use DC for whole (root) screen, since no windows have yet been created - pixelFormat = ChoosePixelFormat((HDC) ::GetDC(NULL), &pfd); + pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd); if (pixelFormat == 0) { wxLogError(_("Failed to initialize OpenGL")); diff --git a/wxPython/contrib/glcanvas/msw/myglcanvas.h b/wxPython/contrib/glcanvas/msw/myglcanvas.h index 5dd269da72..2fe7404e2a 100644 --- a/wxPython/contrib/glcanvas/msw/myglcanvas.h +++ b/wxPython/contrib/glcanvas/msw/myglcanvas.h @@ -24,6 +24,7 @@ #include #include +#include "wx/msw/winundef.h" #include @@ -69,7 +70,7 @@ public: ~wxGLContext(); void SetCurrent(); - void SetColour(const char *colour); + void SetColour(const wxChar *colour); void SwapBuffers(); @@ -83,21 +84,26 @@ public: wxWindow* m_window; }; + +extern const wxChar* wxGLCanvasName; + + class wxGLCanvas: public wxWindow { DECLARE_CLASS(wxGLCanvas) public: wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, - const wxString& name = "GLCanvas", int *attribList = 0, const wxPalette& palette = wxNullPalette); + const wxString& name = wxGLCanvasName, int *attribList = 0, const wxPalette& palette = wxNullPalette); wxGLCanvas( wxWindow *parent, const wxGLContext *shared = (wxGLContext *)NULL, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "GLCanvas", + const wxSize& size = wxDefaultSize, long style = 0, const wxString& + name = wxGLCanvasName, int *attribList = (int*) NULL, const wxPalette& palette = wxNullPalette ); wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared = (wxGLCanvas *)NULL, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, - const wxString& name = "GLCanvas", int *attribList = 0, const wxPalette& palette = wxNullPalette ); + const wxString& name = wxGLCanvasName, int *attribList = 0, const wxPalette& palette = wxNullPalette ); ~wxGLCanvas(); @@ -106,7 +112,7 @@ class wxGLCanvas: public wxWindow const wxPoint& pos, const wxSize& size, long style, const wxString& name); void SetCurrent(); - void SetColour(const char *colour); + void SetColour(const wxChar *colour); void SwapBuffers(); void OnSize(wxSizeEvent& event); diff --git a/wxPython/contrib/iewin/IEHtmlWin.cpp b/wxPython/contrib/iewin/IEHtmlWin.cpp index 6214694d96..ad35820d51 100644 --- a/wxPython/contrib/iewin/IEHtmlWin.cpp +++ b/wxPython/contrib/iewin/IEHtmlWin.cpp @@ -37,23 +37,23 @@ private: public: FS_DWebBrowserEvents2(wxIEHtmlWin *iewin) : m_iewin(iewin) {} - virtual ~FS_DWebBrowserEvents2() + virtual ~FS_DWebBrowserEvents2() { } //IDispatch STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d) - { + { return E_NOTIMPL; }; STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t) - { + { return E_NOTIMPL; }; STDMETHODIMP GetTypeInfoCount(unsigned int* i) - { + { return E_NOTIMPL; }; @@ -72,7 +72,7 @@ public: m_iewin->GetParent()->AddPendingEvent(event); }; - bool Process(WXTYPE etype, wxString text = "", long l1 = 0, long l2 = 0) + bool Process(WXTYPE etype, wxString text = wxEmptyString, long l1 = 0, long l2 = 0) { if (! m_iewin || ! m_iewin->GetParent()) return true; @@ -103,7 +103,7 @@ public: return v.bstrVal; } else - return ""; + return wxEmptyString; }; #define STR_ARG(arg) GetStrArg(pDispParams->rgvarg[arg]) @@ -116,7 +116,7 @@ public: WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, unsigned int * puArgErr) - { + { if (wFlags & DISPATCH_PROPERTYGET) return E_NOTIMPL; @@ -125,21 +125,21 @@ public: case DISPID_BEFORENAVIGATE2: if (Process(wxEVT_COMMAND_MSHTML_BEFORENAVIGATE2, STR_ARG(5))) *pDispParams->rgvarg->pboolVal = VARIANT_FALSE; - else + else *pDispParams->rgvarg->pboolVal = VARIANT_TRUE; break; case DISPID_NEWWINDOW2: if (Process(wxEVT_COMMAND_MSHTML_NEWWINDOW2)) *pDispParams->rgvarg->pboolVal = VARIANT_FALSE; - else + else *pDispParams->rgvarg->pboolVal = VARIANT_TRUE; break; case DISPID_PROGRESSCHANGE: - Post(wxEVT_COMMAND_MSHTML_PROGRESSCHANGE, "", LONG_ARG(1), LONG_ARG(0)); + Post(wxEVT_COMMAND_MSHTML_PROGRESSCHANGE, wxEmptyString, LONG_ARG(1), LONG_ARG(0)); break; - + case DISPID_DOCUMENTCOMPLETE: Post(wxEVT_COMMAND_MSHTML_DOCUMENTCOMPLETE, STR_ARG(0)); break; @@ -183,7 +183,7 @@ wxIEHtmlWin::wxIEHtmlWin(wxWindow * parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, - const wxString& name) : + const wxString& name) : wxActiveX(parent, PROGID, id, pos, size, style, name) { SetupBrowser(); @@ -287,12 +287,12 @@ private: istream *m_is; public: - - IStreamAdaptor(istream *is) : IStreamAdaptorBase(), m_is(is) + + IStreamAdaptor(istream *is) : IStreamAdaptorBase(), m_is(is) { wxASSERT(m_is != NULL); } - ~IStreamAdaptor() + ~IStreamAdaptor() { delete m_is; } @@ -314,12 +314,12 @@ private: wxInputStream *m_is; public: - - IwxStreamAdaptor(wxInputStream *is) : IStreamAdaptorBase(), m_is(is) + + IwxStreamAdaptor(wxInputStream *is) : IStreamAdaptorBase(), m_is(is) { wxASSERT(m_is != NULL); } - ~IwxStreamAdaptor() + ~IwxStreamAdaptor() { delete m_is; } @@ -338,7 +338,7 @@ public: void wxIEHtmlWin::LoadUrl(const wxString& url) { VARIANTARG navFlag, targetFrame, postData, headers; - navFlag.vt = VT_EMPTY; + navFlag.vt = VT_EMPTY; navFlag.vt = VT_I2; navFlag.iVal = navNoReadFromCache; targetFrame.vt = VT_EMPTY; @@ -346,8 +346,8 @@ void wxIEHtmlWin::LoadUrl(const wxString& url) headers.vt = VT_EMPTY; HRESULT hret = 0; - hret = m_webBrowser->Navigate((BSTR) (const wchar_t *) url.wc_str(wxConvUTF8), - &navFlag, &targetFrame, &postData, &headers); + hret = m_webBrowser->Navigate((BSTR) (const wchar_t *) url.wc_str(wxConvUTF8), + &navFlag, &targetFrame, &postData, &headers); }; class wxOwnedMemInputStream : public wxMemoryInputStream @@ -358,7 +358,7 @@ public: wxOwnedMemInputStream(char *data, size_t len) : wxMemoryInputStream(data, len), m_data(data) {} - ~wxOwnedMemInputStream() + ~wxOwnedMemInputStream() { free(m_data); } @@ -524,17 +524,17 @@ wxString wxIEHtmlWin::GetStringSelection(bool asHTML) { wxAutoOleInterface tr(GetSelRange(m_oleObject)); if (! tr) - return ""; + return wxEmptyString; BSTR text = NULL; HRESULT hr = E_FAIL; - + if (asHTML) hr = tr->get_htmlText(&text); else hr = tr->get_text(&text); if (hr != S_OK) - return ""; + return wxEmptyString; wxString s = text; SysFreeString(text); @@ -545,41 +545,41 @@ wxString wxIEHtmlWin::GetStringSelection(bool asHTML) wxString wxIEHtmlWin::GetText(bool asHTML) { if (! m_webBrowser.Ok()) - return ""; + return wxEmptyString; // get document dispatch interface IDispatch *iDisp = NULL; HRESULT hr = m_webBrowser->get_Document(&iDisp); if (hr != S_OK) - return ""; + return wxEmptyString; // Query for Document Interface wxAutoOleInterface hd(IID_IHTMLDocument2, iDisp); iDisp->Release(); if (! hd.Ok()) - return ""; + return wxEmptyString; // get body element IHTMLElement *_body = NULL; hd->get_body(&_body); if (! _body) - return ""; + return wxEmptyString; wxAutoOleInterface body(_body); // get inner text BSTR text = NULL; hr = E_FAIL; - + if (asHTML) hr = body->get_innerHTML(&text); else hr = body->get_innerText(&text); if (hr != S_OK) - return ""; + return wxEmptyString; wxString s = text; SysFreeString(text); - return s; -}; \ No newline at end of file + return s; +}; diff --git a/wxPython/contrib/iewin/iewin.cpp b/wxPython/contrib/iewin/iewin.cpp index 11fb5ef617..9bd052c734 100644 --- a/wxPython/contrib/iewin/iewin.cpp +++ b/wxPython/contrib/iewin/iewin.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -177,7 +176,7 @@ static PyObject *_wrap_wxMSHTMLEvent_GetText1(PyObject *self, PyObject *args, Py if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -589,7 +588,7 @@ static PyObject *_wrap_wxIEHtmlWin_GetStringSelection(PyObject *self, PyObject * if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -629,7 +628,7 @@ static PyObject *_wrap_wxIEHtmlWin_GetText(PyObject *self, PyObject *args, PyObj if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -752,8 +751,8 @@ static PyObject *_wrap_wxIEHtmlWin_GoSearch(PyObject *self, PyObject *args, PyOb return _resultobj; } -#define wxIEHtmlWin_Refresh(_swigobj,_swigarg0) (_swigobj->Refresh(_swigarg0)) -static PyObject *_wrap_wxIEHtmlWin_Refresh(PyObject *self, PyObject *args, PyObject *kwargs) { +#define wxIEHtmlWin_RefreshPage(_swigobj,_swigarg0) (_swigobj->Refresh(_swigarg0)) +static PyObject *_wrap_wxIEHtmlWin_RefreshPage(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; bool _result; wxIEHtmlWin * _arg0; @@ -762,18 +761,18 @@ static PyObject *_wrap_wxIEHtmlWin_Refresh(PyObject *self, PyObject *args, PyObj char *_kwnames[] = { "self","level", NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxIEHtmlWin_Refresh",_kwnames,&_argo0,&_arg1)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxIEHtmlWin_RefreshPage",_kwnames,&_argo0,&_arg1)) return NULL; if (_argo0) { if (_argo0 == Py_None) { _arg0 = NULL; } else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxIEHtmlWin_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxIEHtmlWin_Refresh. Expected _wxIEHtmlWin_p."); + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxIEHtmlWin_RefreshPage. Expected _wxIEHtmlWin_p."); return NULL; } } { PyThreadState* __tstate = wxPyBeginAllowThreads(); - _result = (bool )wxIEHtmlWin_Refresh(_arg0,_arg1); + _result = (bool )wxIEHtmlWin_RefreshPage(_arg0,_arg1); wxPyEndAllowThreads(__tstate); if (PyErr_Occurred()) return NULL; @@ -811,7 +810,7 @@ static PyObject *_wrap_wxIEHtmlWin_Stop(PyObject *self, PyObject *args, PyObject static PyMethodDef iewincMethods[] = { { "wxIEHtmlWin_Stop", (PyCFunction) _wrap_wxIEHtmlWin_Stop, METH_VARARGS | METH_KEYWORDS }, - { "wxIEHtmlWin_Refresh", (PyCFunction) _wrap_wxIEHtmlWin_Refresh, METH_VARARGS | METH_KEYWORDS }, + { "wxIEHtmlWin_RefreshPage", (PyCFunction) _wrap_wxIEHtmlWin_RefreshPage, METH_VARARGS | METH_KEYWORDS }, { "wxIEHtmlWin_GoSearch", (PyCFunction) _wrap_wxIEHtmlWin_GoSearch, METH_VARARGS | METH_KEYWORDS }, { "wxIEHtmlWin_GoHome", (PyCFunction) _wrap_wxIEHtmlWin_GoHome, METH_VARARGS | METH_KEYWORDS }, { "wxIEHtmlWin_GoForward", (PyCFunction) _wrap_wxIEHtmlWin_GoForward, METH_VARARGS | METH_KEYWORDS }, diff --git a/wxPython/contrib/iewin/iewin.i b/wxPython/contrib/iewin/iewin.i index 8a90a95c0c..76384ee1d0 100644 --- a/wxPython/contrib/iewin/iewin.i +++ b/wxPython/contrib/iewin/iewin.i @@ -117,7 +117,7 @@ public: bool GoForward(); bool GoHome(); bool GoSearch(); - bool Refresh(wxIEHtmlRefreshLevel level); + %name(RefreshPage)bool Refresh(wxIEHtmlRefreshLevel level); bool Stop(); }; diff --git a/wxPython/contrib/iewin/iewin.py b/wxPython/contrib/iewin/iewin.py index 9c3f24f122..1bc59d7e3a 100644 --- a/wxPython/contrib/iewin/iewin.py +++ b/wxPython/contrib/iewin/iewin.py @@ -125,8 +125,8 @@ class wxIEHtmlWinPtr(wxWindowPtr): def GoSearch(self, *_args, **_kwargs): val = apply(iewinc.wxIEHtmlWin_GoSearch,(self,) + _args, _kwargs) return val - def Refresh(self, *_args, **_kwargs): - val = apply(iewinc.wxIEHtmlWin_Refresh,(self,) + _args, _kwargs) + def RefreshPage(self, *_args, **_kwargs): + val = apply(iewinc.wxIEHtmlWin_RefreshPage,(self,) + _args, _kwargs) return val def Stop(self, *_args, **_kwargs): val = apply(iewinc.wxIEHtmlWin_Stop,(self,) + _args, _kwargs) diff --git a/wxPython/contrib/iewin/wxactivex.cpp b/wxPython/contrib/iewin/wxactivex.cpp index 779042ed0b..34fd2b1e2f 100644 --- a/wxPython/contrib/iewin/wxactivex.cpp +++ b/wxPython/contrib/iewin/wxactivex.cpp @@ -33,7 +33,7 @@ END_EVENT_TABLE() class wxActiveX; -class FrameSite : +class FrameSite : public IOleClientSite, public IOleInPlaceSiteEx, public IOleInPlaceFrame, @@ -60,7 +60,7 @@ public: STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS); STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS); STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*, LPCOLESTR); - + //IOleInPlaceFrame STDMETHODIMP InsertMenus(HMENU, LPOLEMENUGROUPWIDTHS); STDMETHODIMP SetMenu(HMENU, HOLEMENU, HWND); @@ -73,7 +73,7 @@ public: STDMETHODIMP CanInPlaceActivate(); STDMETHODIMP OnInPlaceActivate(); STDMETHODIMP OnUIActivate(); - STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**, + STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**, LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO); STDMETHODIMP Scroll(SIZE); STDMETHODIMP OnUIDeactivate(BOOL); @@ -119,7 +119,7 @@ public: STDMETHODIMP GetObject(LPOLESTR, DWORD, IBindCtx*, REFIID, void**); STDMETHODIMP GetObjectStorage(LPOLESTR, IBindCtx*, REFIID, void**); STDMETHODIMP IsRunning(LPOLESTR); - + //IDispatch STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*); STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**); @@ -148,7 +148,7 @@ protected: bool m_bInPlaceActive; bool m_bUIActive; bool m_bWindowless; - + LCID m_nAmbientLocale; @@ -225,14 +225,14 @@ wxActiveX::~wxActiveX() }; m_connections.clear(); - if (m_oleInPlaceObject.Ok()) + if (m_oleInPlaceObject.Ok()) { m_oleInPlaceObject->InPlaceDeactivate(); m_oleInPlaceObject->UIDeactivate(); } - if (m_oleObject.Ok()) + if (m_oleObject.Ok()) { if (m_docAdviseCookie != 0) m_oleObject->Unadvise(m_docAdviseCookie); @@ -268,11 +268,11 @@ void wxActiveX::CreateActiveX(REFCLSID clsid) GetTypeInfo(); // Get IOleObject interface - hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); + hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX); wxASSERT(SUCCEEDED(hret)); // get IViewObject Interface - hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX); + hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX); wxASSERT(SUCCEEDED(hret)); // document advise @@ -529,23 +529,23 @@ private: public: wxActiveXEvents(wxActiveX *ax) : m_activeX(ax) {} - virtual ~wxActiveXEvents() + virtual ~wxActiveXEvents() { } //IDispatch STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d) - { + { return E_NOTIMPL; }; STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t) - { + { return E_NOTIMPL; }; STDMETHODIMP GetTypeInfoCount(unsigned int* i) - { + { return E_NOTIMPL; }; @@ -591,7 +591,7 @@ public: if (px.IsOut()) { wxVariant& vx = event.m_params[nArg - i - 1]; - + VariantToMSWVariant(vx, va); }; }; @@ -605,7 +605,7 @@ public: WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, unsigned int * puArgErr) - { + { if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF)) return E_NOTIMPL; @@ -616,7 +616,7 @@ public: if (mid == m_activeX->m_eventsIdx.end()) return S_OK; - int funcIdx = mid->second; + int funcIdx = mid->second; wxActiveX::FuncX &func = m_activeX->m_events[funcIdx]; @@ -697,12 +697,12 @@ wxVariant& wxActiveXEvent::operator[] (wxString name) return m_params[i]; }; - wxString err = "wxActiveXEvent::operator[] invalid name <" + name + ">"; - err += "\r\nValid Names = :\r\n"; + wxString err = wxT("wxActiveXEvent::operator[] invalid name <") + name + wxT(">"); + err += wxT("\r\nValid Names = :\r\n"); for (i = 0; i < m_params.GetCount(); i++) { err += m_params[i].GetName(); - err += "\r\n"; + err += wxT("\r\n"); }; wxASSERT_MSG(false, err); @@ -713,15 +713,15 @@ wxVariant& wxActiveXEvent::operator[] (wxString name) void wxActiveX::GetTypeInfo() { /* - We are currently only interested in the IDispatch interface + We are currently only interested in the IDispatch interface to the control. For dual interfaces (TypeKind = TKIND_INTERFACE) - we should drill down through the inheritance + we should drill down through the inheritance (using TYPEATTR->cImplTypes) and GetRefTypeOfImplType(n) - and retrieve all the func names etc that way, then generate a C++ + and retrieve all the func names etc that way, then generate a C++ header file for it. - But we don't do this and probably never will, so if we have a DUAL - interface then we query for the IDispatch + But we don't do this and probably never will, so if we have a DUAL + interface then we query for the IDispatch via GetRefTypeOfImplType(-1). */ @@ -772,12 +772,12 @@ void wxActiveX::GetTypeInfo() { if (impTypeFlags & IMPLTYPEFLAG_FSOURCE) { - WXOLE_TRACEOUT("Default Event Sink"); + WXOLE_TRACEOUT(wxT("Default Event Sink")); defEventSink = true; } else { - WXOLE_TRACEOUT("Default Interface"); + WXOLE_TRACEOUT(wxT("Default Interface")); } }; @@ -804,7 +804,7 @@ void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink) if (ta->typekind == TKIND_DISPATCH) { - WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str()); + WXOLE_TRACEOUT(wxT("GUID = ") << GetIIDName(ta->guid).c_str()); if (defEventSink) { @@ -831,7 +831,7 @@ void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink) { wxString name = anames[0]; - WXOLE_TRACEOUT("Name " << i << " = " << name.c_str()); + WXOLE_TRACEOUT(wxT("Name ") << i << wxT(" = ") << name.c_str()); SysFreeString(anames[0]); if (defEventSink) @@ -901,11 +901,11 @@ HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events) wxAutoOleInterface cpContainer(IID_IConnectionPointContainer, m_ActiveX); if (! cpContainer.Ok()) return E_FAIL; - + HRESULT hret = cpContainer->FindConnectionPoint(riid, cp.GetRef()); if (! SUCCEEDED(hret)) return hret; - + hret = cp->Advise(events, &adviseCookie); if (SUCCEEDED(hret)) @@ -979,7 +979,7 @@ void wxActiveX::OnSize(wxSizeEvent& event) m_oleObject->SetExtent(DVASPECT_CONTENT, &sz); }; - if (m_oleInPlaceObject.Ok()) + if (m_oleInPlaceObject.Ok()) m_oleInPlaceObject->SetObjectRects(&posRect, &posRect); } @@ -1002,7 +1002,7 @@ void wxActiveX::OnPaint(wxPaintEvent& event) ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT); { RECTL *prcBounds = (RECTL *) &posRect; - m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, + m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0); } } @@ -1018,11 +1018,11 @@ void wxActiveX::OnPaint(wxPaintEvent& event) void wxActiveX::OnMouse(wxMouseEvent& event) { - if (m_oleObjectHWND == NULL) - { - wxLogTrace(wxT("no oleInPlaceObject")); - event.Skip(); - return; + if (m_oleObjectHWND == NULL) + { + wxLogTrace(wxT("no oleInPlaceObject")); + event.Skip(); + return; } wxLogTrace(wxT("mouse event")); @@ -1031,52 +1031,52 @@ void wxActiveX::OnMouse(wxMouseEvent& event) LPARAM lParam = 0; LRESULT lResult = 0; - if (event.m_metaDown) + if (event.m_metaDown) wParam |= MK_CONTROL; - if (event.m_shiftDown) + if (event.m_shiftDown) wParam |= MK_SHIFT; - if (event.m_leftDown) + if (event.m_leftDown) wParam |= MK_LBUTTON; - if (event.m_middleDown) + if (event.m_middleDown) wParam |= MK_MBUTTON; - if (event.m_rightDown) + if (event.m_rightDown) wParam |= MK_RBUTTON; lParam = event.m_x << 16; lParam |= event.m_y; - if (event.LeftDown()) + if (event.LeftDown()) msg = WM_LBUTTONDOWN; - else if (event.LeftDClick()) + else if (event.LeftDClick()) msg = WM_LBUTTONDBLCLK; - else if (event.LeftUp()) + else if (event.LeftUp()) msg = WM_LBUTTONUP; - else if (event.MiddleDown()) + else if (event.MiddleDown()) msg = WM_MBUTTONDOWN; - else if (event.MiddleDClick()) + else if (event.MiddleDClick()) msg = WM_MBUTTONDBLCLK; - else if (event.MiddleUp()) + else if (event.MiddleUp()) msg = WM_MBUTTONUP; - else if (event.RightDown()) + else if (event.RightDown()) msg = WM_RBUTTONDOWN; - else if (event.RightDClick()) + else if (event.RightDClick()) msg = WM_RBUTTONDBLCLK; - else if (event.RightUp()) + else if (event.RightUp()) msg = WM_RBUTTONUP; - else if (event.Moving() || event.Dragging()) + else if (event.Moving() || event.Dragging()) msg = WM_MOUSEMOVE; wxString log; - if (msg == 0) - { + if (msg == 0) + { wxLogTrace(wxT("no message")); - event.Skip(); return; + event.Skip(); return; }; - if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam)) - { + if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam)) + { wxLogTrace(wxT("msg not delivered")); - event.Skip(); - return; + event.Skip(); + return; }; wxLogTrace(wxT("msg sent")); @@ -1106,13 +1106,13 @@ long wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) void wxActiveX::OnSetFocus(wxFocusEvent& event) { - if (m_oleInPlaceActiveObject.Ok()) + if (m_oleInPlaceActiveObject.Ok()) m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE); } void wxActiveX::OnKillFocus(wxFocusEvent& event) { - if (m_oleInPlaceActiveObject.Ok()) + if (m_oleInPlaceActiveObject.Ok()) m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE); } @@ -1132,7 +1132,7 @@ FrameSite::FrameSite(wxActiveX * win) m_bAmbientShowHatching = true; m_bAmbientShowGrabHandles = true; m_bAmbientAppearance = true; - + m_hDCBuffer = NULL; m_hWndParent = (HWND)m_window->GetHWND(); } @@ -1175,7 +1175,7 @@ HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, HRESULT hr; - if (pVarResult == NULL) + if (pVarResult == NULL) return E_INVALIDARG; //The most common case is boolean, use as an initial type @@ -1251,7 +1251,7 @@ HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, HRESULT FrameSite::GetWindow(HWND * phwnd) { WXOLE_TRACE("IOleWindow::GetWindow"); - if (phwnd == NULL) + if (phwnd == NULL) return E_INVALIDARG; (*phwnd) = m_hWndParent; return S_OK; @@ -1268,7 +1268,7 @@ HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode) HRESULT FrameSite::GetBorder(LPRECT lprectBorder) { WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder"); - if (lprectBorder == NULL) + if (lprectBorder == NULL) return E_INVALIDARG; return INPLACE_E_NOTOOLSPACE; } @@ -1276,7 +1276,7 @@ HRESULT FrameSite::GetBorder(LPRECT lprectBorder) HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths) { WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace"); - if (pborderwidths == NULL) + if (pborderwidths == NULL) return E_INVALIDARG; return INPLACE_E_NOTOOLSPACE; } @@ -1373,9 +1373,9 @@ HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame, if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL || lprcClipRect == NULL || lpFrameInfo == NULL) { - if (ppFrame != NULL) + if (ppFrame != NULL) (*ppFrame) = NULL; - if (ppDoc != NULL) + if (ppDoc != NULL) (*ppDoc) = NULL; return E_INVALIDARG; } @@ -1465,7 +1465,7 @@ HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags) { WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx"); OleLockRunning(m_window->m_ActiveX, TRUE, FALSE); - if (pfNoRedraw) + if (pfNoRedraw) (*pfNoRedraw) = FALSE; return S_OK; } @@ -1502,9 +1502,9 @@ HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer) { WXOLE_TRACE("IOleClientSite::GetContainer"); - if (ppContainer == NULL) + if (ppContainer == NULL) return E_INVALIDARG; - + HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer)); wxASSERT(SUCCEEDED(hr)); @@ -1557,26 +1557,26 @@ HRESULT FrameSite::LockContainer(BOOL fLock) //IOleItemContainer -HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded, +HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded, IBindCtx * pbc, REFIID riid, void ** ppvObject) { WXOLE_TRACE("IOleItemContainer::GetObject"); - if (pszItem == NULL) + if (pszItem == NULL) return E_INVALIDARG; - if (ppvObject == NULL) + if (ppvObject == NULL) return E_INVALIDARG; *ppvObject = NULL; return MK_E_NOOBJECT; } -HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc, +HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc, REFIID riid, void ** ppvStorage) { WXOLE_TRACE("IOleItemContainer::GetObjectStorage"); - if (pszItem == NULL) + if (pszItem == NULL) return E_INVALIDARG; - if (ppvStorage == NULL) + if (ppvStorage == NULL) return E_INVALIDARG; *ppvStorage = NULL; @@ -1586,7 +1586,7 @@ HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc, HRESULT FrameSite::IsRunning(LPOLESTR pszItem) { WXOLE_TRACE("IOleItemContainer::IsRunning"); - if (pszItem == NULL) + if (pszItem == NULL) return E_INVALIDARG; return MK_E_NOOBJECT; @@ -1651,7 +1651,7 @@ HRESULT FrameSite::ShowPropertyFrame() //IOleCommandTarget -HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, +HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, OLECMD * prgCmds, OLECMDTEXT * pCmdTet) { WXOLE_TRACE("IOleCommandTarget::QueryStatus"); @@ -1670,8 +1670,8 @@ HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds, return S_OK; } -HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, - DWORD nCmdExecOpt, VARIANTARG * pVaIn, +HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID, + DWORD nCmdExecOpt, VARIANTARG * pVaIn, VARIANTARG * pVaOut) { WXOLE_TRACE("IOleCommandTarget::Exec"); @@ -1775,49 +1775,49 @@ wxString OLEHResultToString(HRESULT hr) switch (hr) { case S_OK: - return ""; + return wxEmptyString; case OLECMDERR_E_UNKNOWNGROUP: - return "The pguidCmdGroup parameter is not NULL but does not specify a recognized command group."; + return wxT("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group."); case OLECMDERR_E_NOTSUPPORTED: - return "The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup."; + return wxT("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup."); case OLECMDERR_E_DISABLED: - return "The command identified by nCmdID is currently disabled and cannot be executed."; + return wxT("The command identified by nCmdID is currently disabled and cannot be executed."); case OLECMDERR_E_NOHELP: - return "The caller has asked for help on the command identified by nCmdID, but no help is available."; + return wxT("The caller has asked for help on the command identified by nCmdID, but no help is available."); case OLECMDERR_E_CANCELED: - return "The user canceled the execution of the command."; + return wxT("The user canceled the execution of the command."); case E_INVALIDARG: - return "E_INVALIDARG"; + return wxT("E_INVALIDARG"); case E_OUTOFMEMORY: - return "E_OUTOFMEMORY"; + return wxT("E_OUTOFMEMORY"); case E_NOINTERFACE: - return "E_NOINTERFACE"; + return wxT("E_NOINTERFACE"); case E_UNEXPECTED: - return "E_UNEXPECTED"; + return wxT("E_UNEXPECTED"); case STG_E_INVALIDFLAG: - return "STG_E_INVALIDFLAG"; + return wxT("STG_E_INVALIDFLAG"); case E_FAIL: - return "E_FAIL"; + return wxT("E_FAIL"); case E_NOTIMPL: - return "E_NOTIMPL"; + return wxT("E_NOTIMPL"); default: { - char buf[64]; - sprintf(buf, "Unknown - 0x%X", hr); - return wxString(buf); + wxString buf; + buf.Printf(wxT("Unknown - 0x%X"), hr); + return buf; } }; }; @@ -1826,7 +1826,7 @@ wxString OLEHResultToString(HRESULT hr) wxString GetIIDName(REFIID riid) { // an association between symbolic name and numeric value of an IID - struct KNOWN_IID + struct KNOWN_IID { const IID *pIid; const wxChar *szName; @@ -1836,7 +1836,7 @@ wxString GetIIDName(REFIID riid) #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) } #define ADD_KNOWN_GUID(name) { &name, _T(#name) } - static const KNOWN_IID aKnownIids[] = + static const KNOWN_IID aKnownIids[] = { ADD_KNOWN_IID(AdviseSink), ADD_KNOWN_IID(AdviseSink2), @@ -1930,9 +1930,9 @@ wxString GetIIDName(REFIID riid) #undef ADD_KNOWN_GUID // try to find the interface in the table - for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ ) + for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ ) { - if ( riid == *aKnownIids[ui].pIid ) + if ( riid == *aKnownIids[ui].pIid ) { return aKnownIids[ui].szName; } @@ -1948,5 +1948,5 @@ wxString GetIIDName(REFIID riid) return s; } else - return "StringFromIID() error"; + return wxT("StringFromIID() error"); } diff --git a/wxPython/contrib/ogl/ogl.cpp b/wxPython/contrib/ogl/ogl.cpp index da700b564f..cb54c18b03 100644 --- a/wxPython/contrib/ogl/ogl.cpp +++ b/wxPython/contrib/ogl/ogl.cpp @@ -1,15 +1,15 @@ /* * FILE : contrib/ogl/ogl.cpp - * + * * This file was automatically generated by : * Simplified Wrapper and Interface Generator (SWIG) * Version 1.1 (Build 883) - * + * * Portions Copyright (c) 1995-1998 * The University of Utah and The Regents of the University of California. * Permission is granted to distribute this file in any manner provided * this notice remains intact. - * + * * Do not make changes to this file--changes will be lost! * */ @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -188,19 +187,20 @@ PyObject* wxPyMake_wxShapeEvtHandler(wxShapeEvtHandler* source) { //--------------------------------------------------------------------------- -PyObject* wxPy_ConvertShapeList(wxListBase* list, const char* className) { +PyObject* wxPy_ConvertShapeList(wxListBase* listbase, const char* className) { + wxList* list = (wxList*)listbase; PyObject* pyList; PyObject* pyObj; wxObject* wxObj; - wxNode* node = list->First(); + wxNode* node = list->GetFirst(); wxPyBeginBlockThreads(); pyList = PyList_New(0); while (node) { - wxObj = node->Data(); + wxObj = node->GetData(); pyObj = wxPyMake_wxShapeEvtHandler((wxShapeEvtHandler*)wxObj); PyList_Append(pyList, pyObj); - node = node->Next(); + node = node->GetNext(); } wxPyEndBlockThreads(); return pyList; @@ -239,7 +239,7 @@ static PyObject *_wrap_wxOGLInitialize(PyObject *self, PyObject *args, PyObject char *_kwnames[] = { NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxOGLInitialize",_kwnames)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxOGLInitialize",_kwnames)) return NULL; { PyThreadState* __tstate = wxPyBeginAllowThreads(); @@ -257,7 +257,7 @@ static PyObject *_wrap_wxOGLCleanUp(PyObject *self, PyObject *args, PyObject *kw char *_kwnames[] = { NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxOGLCleanUp",_kwnames)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,":wxOGLCleanUp",_kwnames)) return NULL; { PyThreadState* __tstate = wxPyBeginAllowThreads(); @@ -386,7 +386,7 @@ static struct { char *n1; char *n2; void *(*pcnv)(void *); } _swig_mapping[] = { static PyObject *SWIG_globals; #ifdef __cplusplus -extern "C" +extern "C" #endif SWIGEXPORT(void) initoglc() { PyObject *m, *d; diff --git a/wxPython/contrib/ogl/oglbasic.cpp b/wxPython/contrib/ogl/oglbasic.cpp index ab32951076..a328db00e5 100644 --- a/wxPython/contrib/ogl/oglbasic.cpp +++ b/wxPython/contrib/ogl/oglbasic.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -467,7 +466,7 @@ static PyObject *_wrap_wxShapeRegion_GetText(PyObject *self, PyObject *args, PyO if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -759,7 +758,7 @@ static PyObject *_wrap_wxShapeRegion_GetName(PyObject *self, PyObject *args, PyO if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -796,7 +795,7 @@ static PyObject *_wrap_wxShapeRegion_GetColour(PyObject *self, PyObject *args, P if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -904,7 +903,7 @@ static PyObject *_wrap_wxShapeRegion_GetPenColour(PyObject *self, PyObject *args if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -1489,8 +1488,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnDraw(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -1526,8 +1524,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnDrawContents(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -1565,8 +1562,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnDrawBranches(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -1603,8 +1599,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnMoveLinks(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -1640,8 +1635,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnErase(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -1677,8 +1671,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnEraseContents(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -1714,8 +1707,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnHighlight(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -1884,8 +1876,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnMovePre(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -1927,8 +1918,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnMovePost(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -2167,8 +2157,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnDrawOutline(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -2204,8 +2193,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnDrawControlPoints(PyObject *se } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -2241,8 +2229,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnEraseControlPoints(PyObject *s } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -2280,8 +2267,7 @@ static PyObject *_wrap_wxPyShapeEvtHandler_base_OnMoveLink(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeEvtHandler_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -4524,8 +4510,7 @@ static PyObject *_wrap_wxPyShape_Move(PyObject *self, PyObject *args, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_Move. Expected _wxDC_p."); return NULL; } @@ -4562,8 +4547,7 @@ static PyObject *_wrap_wxPyShape_Erase(PyObject *self, PyObject *args, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_Erase. Expected _wxDC_p."); return NULL; } @@ -4599,8 +4583,7 @@ static PyObject *_wrap_wxPyShape_EraseContents(PyObject *self, PyObject *args, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_EraseContents. Expected _wxDC_p."); return NULL; } @@ -4636,8 +4619,7 @@ static PyObject *_wrap_wxPyShape_Draw(PyObject *self, PyObject *args, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_Draw. Expected _wxDC_p."); return NULL; } @@ -4701,8 +4683,7 @@ static PyObject *_wrap_wxPyShape_MoveLinks(PyObject *self, PyObject *args, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_MoveLinks. Expected _wxDC_p."); return NULL; } @@ -4738,8 +4719,7 @@ static PyObject *_wrap_wxPyShape_DrawContents(PyObject *self, PyObject *args, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_DrawContents. Expected _wxDC_p."); return NULL; } @@ -5158,8 +5138,7 @@ static PyObject *_wrap_wxPyShape_FormatText(PyObject *self, PyObject *args, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_FormatText. Expected _wxDC_p."); return NULL; } @@ -5397,7 +5376,7 @@ static PyObject *_wrap_wxPyShape_GetTextColour(PyObject *self, PyObject *args, P if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -5503,7 +5482,7 @@ static PyObject *_wrap_wxPyShape_GetRegionName(PyObject *self, PyObject *args, P if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -5788,8 +5767,7 @@ static PyObject *_wrap_wxPyShape_FindRegionNames(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxStringList_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxStringList_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_FindRegionNames. Expected _wxStringList_p."); return NULL; } @@ -6173,8 +6151,7 @@ static PyObject *_wrap_wxPyShape_EraseLinks(PyObject *self, PyObject *args, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_EraseLinks. Expected _wxDC_p."); return NULL; } @@ -6214,8 +6191,7 @@ static PyObject *_wrap_wxPyShape_DrawLinks(PyObject *self, PyObject *args, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_DrawLinks. Expected _wxDC_p."); return NULL; } @@ -6257,8 +6233,7 @@ static PyObject *_wrap_wxPyShape_MoveLineToNewAttachment(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_MoveLineToNewAttachment. Expected _wxDC_p."); return NULL; } @@ -6889,8 +6864,7 @@ static PyObject *_wrap_wxPyShape_Copy(PyObject *self, PyObject *args, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxPyShape_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxPyShape_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_Copy. Expected _wxPyShape_p."); return NULL; } @@ -6926,8 +6900,7 @@ static PyObject *_wrap_wxPyShape_CopyWithHandler(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxPyShape_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxPyShape_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_CopyWithHandler. Expected _wxPyShape_p."); return NULL; } @@ -7050,8 +7023,7 @@ static PyObject *_wrap_wxPyShape_Recentre(PyObject *self, PyObject *args, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_Recentre. Expected _wxDC_p."); return NULL; } @@ -7087,8 +7059,7 @@ static PyObject *_wrap_wxPyShape_ClearPointList(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxList_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxList_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_ClearPointList. Expected _wxList_p."); return NULL; } @@ -7212,8 +7183,7 @@ static PyObject *_wrap_wxPyShape_base_OnDraw(PyObject *self, PyObject *args, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -7249,8 +7219,7 @@ static PyObject *_wrap_wxPyShape_base_OnDrawContents(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -7288,8 +7257,7 @@ static PyObject *_wrap_wxPyShape_base_OnDrawBranches(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -7326,8 +7294,7 @@ static PyObject *_wrap_wxPyShape_base_OnMoveLinks(PyObject *self, PyObject *args } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -7363,8 +7330,7 @@ static PyObject *_wrap_wxPyShape_base_OnErase(PyObject *self, PyObject *args, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -7400,8 +7366,7 @@ static PyObject *_wrap_wxPyShape_base_OnEraseContents(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -7437,8 +7402,7 @@ static PyObject *_wrap_wxPyShape_base_OnHighlight(PyObject *self, PyObject *args } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -7607,8 +7571,7 @@ static PyObject *_wrap_wxPyShape_base_OnMovePre(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -7650,8 +7613,7 @@ static PyObject *_wrap_wxPyShape_base_OnMovePost(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -7890,8 +7852,7 @@ static PyObject *_wrap_wxPyShape_base_OnDrawOutline(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -7927,8 +7888,7 @@ static PyObject *_wrap_wxPyShape_base_OnDrawControlPoints(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -7964,8 +7924,7 @@ static PyObject *_wrap_wxPyShape_base_OnEraseControlPoints(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -8003,8 +7962,7 @@ static PyObject *_wrap_wxPyShape_base_OnMoveLink(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } diff --git a/wxPython/contrib/ogl/oglbasic.i b/wxPython/contrib/ogl/oglbasic.i index 806c6b32ec..7220270323 100644 --- a/wxPython/contrib/ogl/oglbasic.i +++ b/wxPython/contrib/ogl/oglbasic.i @@ -303,7 +303,7 @@ public: void ClearText(int regionId = 0); void RemoveLine(wxPyLineShape *line); -#ifdef PROLOGIO +#ifdef wxUSE_PROLOGIO void WriteAttributes(wxExpr *clause); void ReadAttributes(wxExpr *clause); void ReadConstraints(wxExpr *clause, wxExprDatabase *database); diff --git a/wxPython/contrib/ogl/oglcanvas.cpp b/wxPython/contrib/ogl/oglcanvas.cpp index 23965c2fc8..83ff03ea0d 100644 --- a/wxPython/contrib/ogl/oglcanvas.cpp +++ b/wxPython/contrib/ogl/oglcanvas.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -199,8 +198,7 @@ static PyObject *_wrap_wxDiagram_Clear(PyObject *self, PyObject *args, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_Clear. Expected _wxDC_p."); return NULL; } @@ -268,8 +266,7 @@ static PyObject *_wrap_wxDiagram_DrawOutline(PyObject *self, PyObject *args, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_DrawOutline. Expected _wxDC_p."); return NULL; } @@ -552,156 +549,6 @@ static PyObject *_wrap_wxDiagram_InsertShape(PyObject *self, PyObject *args, PyO return _resultobj; } -#define wxDiagram_LoadFile(_swigobj,_swigarg0) (_swigobj->LoadFile(_swigarg0)) -static PyObject *_wrap_wxDiagram_LoadFile(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - bool _result; - wxDiagram * _arg0; - wxString * _arg1; - PyObject * _argo0 = 0; - PyObject * _obj1 = 0; - char *_kwnames[] = { "self","filename", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxDiagram_LoadFile",_kwnames,&_argo0,&_obj1)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxDiagram_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxDiagram_LoadFile. Expected _wxDiagram_p."); - return NULL; - } - } -{ - _arg1 = wxString_in_helper(_obj1); - if (_arg1 == NULL) - return NULL; -} -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - _result = (bool )wxDiagram_LoadFile(_arg0,*_arg1); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} _resultobj = Py_BuildValue("i",_result); -{ - if (_obj1) - delete _arg1; -} - return _resultobj; -} - -#define wxDiagram_ReadContainerGeometry(_swigobj,_swigarg0) (_swigobj->ReadContainerGeometry(_swigarg0)) -static PyObject *_wrap_wxDiagram_ReadContainerGeometry(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - wxDiagram * _arg0; - wxExprDatabase * _arg1; - PyObject * _argo0 = 0; - PyObject * _argo1 = 0; - char *_kwnames[] = { "self","database", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxDiagram_ReadContainerGeometry",_kwnames,&_argo0,&_argo1)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxDiagram_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxDiagram_ReadContainerGeometry. Expected _wxDiagram_p."); - return NULL; - } - } - if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxExprDatabase_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_ReadContainerGeometry. Expected _wxExprDatabase_p."); - return NULL; - } - } -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - wxDiagram_ReadContainerGeometry(_arg0,*_arg1); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} Py_INCREF(Py_None); - _resultobj = Py_None; - return _resultobj; -} - -#define wxDiagram_ReadLines(_swigobj,_swigarg0) (_swigobj->ReadLines(_swigarg0)) -static PyObject *_wrap_wxDiagram_ReadLines(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - wxDiagram * _arg0; - wxExprDatabase * _arg1; - PyObject * _argo0 = 0; - PyObject * _argo1 = 0; - char *_kwnames[] = { "self","database", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxDiagram_ReadLines",_kwnames,&_argo0,&_argo1)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxDiagram_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxDiagram_ReadLines. Expected _wxDiagram_p."); - return NULL; - } - } - if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxExprDatabase_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_ReadLines. Expected _wxExprDatabase_p."); - return NULL; - } - } -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - wxDiagram_ReadLines(_arg0,*_arg1); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} Py_INCREF(Py_None); - _resultobj = Py_None; - return _resultobj; -} - -#define wxDiagram_ReadNodes(_swigobj,_swigarg0) (_swigobj->ReadNodes(_swigarg0)) -static PyObject *_wrap_wxDiagram_ReadNodes(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - wxDiagram * _arg0; - wxExprDatabase * _arg1; - PyObject * _argo0 = 0; - PyObject * _argo1 = 0; - char *_kwnames[] = { "self","database", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxDiagram_ReadNodes",_kwnames,&_argo0,&_argo1)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxDiagram_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxDiagram_ReadNodes. Expected _wxDiagram_p."); - return NULL; - } - } - if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxExprDatabase_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_ReadNodes. Expected _wxExprDatabase_p."); - return NULL; - } - } -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - wxDiagram_ReadNodes(_arg0,*_arg1); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} Py_INCREF(Py_None); - _resultobj = Py_None; - return _resultobj; -} - #define wxDiagram_RecentreAll(_swigobj,_swigarg0) (_swigobj->RecentreAll(_swigarg0)) static PyObject *_wrap_wxDiagram_RecentreAll(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -722,8 +569,7 @@ static PyObject *_wrap_wxDiagram_RecentreAll(PyObject *self, PyObject *args, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_RecentreAll. Expected _wxDC_p."); return NULL; } @@ -759,8 +605,7 @@ static PyObject *_wrap_wxDiagram_Redraw(PyObject *self, PyObject *args, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxDiagram_Redraw. Expected _wxDC_p."); return NULL; } @@ -841,45 +686,6 @@ static PyObject *_wrap_wxDiagram_RemoveShape(PyObject *self, PyObject *args, PyO return _resultobj; } -#define wxDiagram_SaveFile(_swigobj,_swigarg0) (_swigobj->SaveFile(_swigarg0)) -static PyObject *_wrap_wxDiagram_SaveFile(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - bool _result; - wxDiagram * _arg0; - wxString * _arg1; - PyObject * _argo0 = 0; - PyObject * _obj1 = 0; - char *_kwnames[] = { "self","filename", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxDiagram_SaveFile",_kwnames,&_argo0,&_obj1)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxDiagram_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxDiagram_SaveFile. Expected _wxDiagram_p."); - return NULL; - } - } -{ - _arg1 = wxString_in_helper(_obj1); - if (_arg1 == NULL) - return NULL; -} -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - _result = (bool )wxDiagram_SaveFile(_arg0,*_arg1); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} _resultobj = Py_BuildValue("i",_result); -{ - if (_obj1) - delete _arg1; -} - return _resultobj; -} - #define wxDiagram_SetCanvas(_swigobj,_swigarg0) (_swigobj->SetCanvas(_swigarg0)) static PyObject *_wrap_wxDiagram_SetCanvas(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -1777,8 +1583,7 @@ static PyObject *_wrap_wxPyShapeCanvas_Redraw(PyObject *self, PyObject *args, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyShapeCanvas_Redraw. Expected _wxDC_p."); return NULL; } @@ -1948,15 +1753,10 @@ static PyMethodDef oglcanvascMethods[] = { { "wxDiagram_SetMouseTolerance", (PyCFunction) _wrap_wxDiagram_SetMouseTolerance, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_SetGridSpacing", (PyCFunction) _wrap_wxDiagram_SetGridSpacing, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_SetCanvas", (PyCFunction) _wrap_wxDiagram_SetCanvas, METH_VARARGS | METH_KEYWORDS }, - { "wxDiagram_SaveFile", (PyCFunction) _wrap_wxDiagram_SaveFile, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_RemoveShape", (PyCFunction) _wrap_wxDiagram_RemoveShape, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_RemoveAllShapes", (PyCFunction) _wrap_wxDiagram_RemoveAllShapes, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_Redraw", (PyCFunction) _wrap_wxDiagram_Redraw, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_RecentreAll", (PyCFunction) _wrap_wxDiagram_RecentreAll, METH_VARARGS | METH_KEYWORDS }, - { "wxDiagram_ReadNodes", (PyCFunction) _wrap_wxDiagram_ReadNodes, METH_VARARGS | METH_KEYWORDS }, - { "wxDiagram_ReadLines", (PyCFunction) _wrap_wxDiagram_ReadLines, METH_VARARGS | METH_KEYWORDS }, - { "wxDiagram_ReadContainerGeometry", (PyCFunction) _wrap_wxDiagram_ReadContainerGeometry, METH_VARARGS | METH_KEYWORDS }, - { "wxDiagram_LoadFile", (PyCFunction) _wrap_wxDiagram_LoadFile, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_InsertShape", (PyCFunction) _wrap_wxDiagram_InsertShape, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_GetSnapToGrid", (PyCFunction) _wrap_wxDiagram_GetSnapToGrid, METH_VARARGS | METH_KEYWORDS }, { "wxDiagram_GetQuickEditMode", (PyCFunction) _wrap_wxDiagram_GetQuickEditMode, METH_VARARGS | METH_KEYWORDS }, diff --git a/wxPython/contrib/ogl/oglcanvas.i b/wxPython/contrib/ogl/oglcanvas.i index 451ce9a7f1..1845651b65 100644 --- a/wxPython/contrib/ogl/oglcanvas.i +++ b/wxPython/contrib/ogl/oglcanvas.i @@ -71,8 +71,13 @@ public: bool GetQuickEditMode(); bool GetSnapToGrid(); void InsertShape(wxPyShape *shape); + +#ifdef wxUSE_PROLOGIO bool LoadFile(const wxString& filename); + bool SaveFile(const wxString& filename); +#endif +#ifdef wxUSE_PROLOGIO // **** Have to deal with wxExpr and wxExprDatabase first... //void OnDatabaseLoad(wxExprDatabase& database); //void OnDatabaseSave(wxExprDatabase& database); @@ -80,16 +85,18 @@ public: //bool OnHeaderSave(wxExprDatabase& database, wxExpr& expr); //bool OnShapeLoad(wxExprDatabase& database, wxPyShape& shape, wxExpr& expr); //bool OnShapeSave(wxExprDatabase& database, wxPyShape& shape, wxExpr& expr); +#endif - +#ifdef wxUSE_PROLOGIO void ReadContainerGeometry(wxExprDatabase& database); void ReadLines(wxExprDatabase& database); void ReadNodes(wxExprDatabase& database); +#endif + void RecentreAll(wxDC& dc); void Redraw(wxDC& dc); void RemoveAllShapes(); void RemoveShape(wxPyShape* shape); - bool SaveFile(const wxString& filename); void SetCanvas(wxPyShapeCanvas* canvas); void SetGridSpacing(double spacing); void SetMouseTolerance(int tolerance); diff --git a/wxPython/contrib/ogl/oglcanvas.py b/wxPython/contrib/ogl/oglcanvas.py index d0126a265a..6a6a7459bd 100644 --- a/wxPython/contrib/ogl/oglcanvas.py +++ b/wxPython/contrib/ogl/oglcanvas.py @@ -88,18 +88,6 @@ class wxDiagramPtr(wxObjectPtr): def InsertShape(self, *_args, **_kwargs): val = apply(oglcanvasc.wxDiagram_InsertShape,(self,) + _args, _kwargs) return val - def LoadFile(self, *_args, **_kwargs): - val = apply(oglcanvasc.wxDiagram_LoadFile,(self,) + _args, _kwargs) - return val - def ReadContainerGeometry(self, *_args, **_kwargs): - val = apply(oglcanvasc.wxDiagram_ReadContainerGeometry,(self,) + _args, _kwargs) - return val - def ReadLines(self, *_args, **_kwargs): - val = apply(oglcanvasc.wxDiagram_ReadLines,(self,) + _args, _kwargs) - return val - def ReadNodes(self, *_args, **_kwargs): - val = apply(oglcanvasc.wxDiagram_ReadNodes,(self,) + _args, _kwargs) - return val def RecentreAll(self, *_args, **_kwargs): val = apply(oglcanvasc.wxDiagram_RecentreAll,(self,) + _args, _kwargs) return val @@ -112,9 +100,6 @@ class wxDiagramPtr(wxObjectPtr): def RemoveShape(self, *_args, **_kwargs): val = apply(oglcanvasc.wxDiagram_RemoveShape,(self,) + _args, _kwargs) return val - def SaveFile(self, *_args, **_kwargs): - val = apply(oglcanvasc.wxDiagram_SaveFile,(self,) + _args, _kwargs) - return val def SetCanvas(self, *_args, **_kwargs): val = apply(oglcanvasc.wxDiagram_SetCanvas,(self,) + _args, _kwargs) return val diff --git a/wxPython/contrib/ogl/oglshapes.cpp b/wxPython/contrib/ogl/oglshapes.cpp index 7e4c39f2d5..4da8d8a782 100644 --- a/wxPython/contrib/ogl/oglshapes.cpp +++ b/wxPython/contrib/ogl/oglshapes.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -185,8 +184,7 @@ static PyObject *_wrap_wxPseudoMetaFile_Draw(PyObject *self, PyObject *args, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPseudoMetaFile_Draw. Expected _wxDC_p."); return NULL; } @@ -202,82 +200,6 @@ static PyObject *_wrap_wxPseudoMetaFile_Draw(PyObject *self, PyObject *args, PyO return _resultobj; } -#define wxPseudoMetaFile_WriteAttributes(_swigobj,_swigarg0,_swigarg1) (_swigobj->WriteAttributes(_swigarg0,_swigarg1)) -static PyObject *_wrap_wxPseudoMetaFile_WriteAttributes(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - wxPseudoMetaFile * _arg0; - wxExpr * _arg1; - int _arg2; - PyObject * _argo0 = 0; - PyObject * _argo1 = 0; - char *_kwnames[] = { "self","clause","whichAngle", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OOi:wxPseudoMetaFile_WriteAttributes",_kwnames,&_argo0,&_argo1,&_arg2)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPseudoMetaFile_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxPseudoMetaFile_WriteAttributes. Expected _wxPseudoMetaFile_p."); - return NULL; - } - } - if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxExpr_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPseudoMetaFile_WriteAttributes. Expected _wxExpr_p."); - return NULL; - } - } -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - wxPseudoMetaFile_WriteAttributes(_arg0,_arg1,_arg2); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} Py_INCREF(Py_None); - _resultobj = Py_None; - return _resultobj; -} - -#define wxPseudoMetaFile_ReadAttributes(_swigobj,_swigarg0,_swigarg1) (_swigobj->ReadAttributes(_swigarg0,_swigarg1)) -static PyObject *_wrap_wxPseudoMetaFile_ReadAttributes(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject * _resultobj; - wxPseudoMetaFile * _arg0; - wxExpr * _arg1; - int _arg2; - PyObject * _argo0 = 0; - PyObject * _argo1 = 0; - char *_kwnames[] = { "self","clause","whichAngle", NULL }; - - self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OOi:wxPseudoMetaFile_ReadAttributes",_kwnames,&_argo0,&_argo1,&_arg2)) - return NULL; - if (_argo0) { - if (_argo0 == Py_None) { _arg0 = NULL; } - else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPseudoMetaFile_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxPseudoMetaFile_ReadAttributes. Expected _wxPseudoMetaFile_p."); - return NULL; - } - } - if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxExpr_p")) { - PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPseudoMetaFile_ReadAttributes. Expected _wxExpr_p."); - return NULL; - } - } -{ - PyThreadState* __tstate = wxPyBeginAllowThreads(); - wxPseudoMetaFile_ReadAttributes(_arg0,_arg1,_arg2); - - wxPyEndAllowThreads(__tstate); - if (PyErr_Occurred()) return NULL; -} Py_INCREF(Py_None); - _resultobj = Py_None; - return _resultobj; -} - #define wxPseudoMetaFile_Clear(_swigobj) (_swigobj->Clear()) static PyObject *_wrap_wxPseudoMetaFile_Clear(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -326,8 +248,7 @@ static PyObject *_wrap_wxPseudoMetaFile_Copy(PyObject *self, PyObject *args, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxPseudoMetaFile_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxPseudoMetaFile_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPseudoMetaFile_Copy. Expected _wxPseudoMetaFile_p."); return NULL; } @@ -469,16 +390,17 @@ static PyObject *_wrap_wxPseudoMetaFile_LoadFromMetaFile(PyObject *self, PyObjec PyObject * _resultobj; bool _result; wxPseudoMetaFile * _arg0; - char * _arg1; + wxString * _arg1; double * _arg2; double * _arg3; PyObject * _argo0 = 0; + PyObject * _obj1 = 0; PyObject * _argo2 = 0; PyObject * _argo3 = 0; char *_kwnames[] = { "self","filename","width","height", NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OsOO:wxPseudoMetaFile_LoadFromMetaFile",_kwnames,&_argo0,&_arg1,&_argo2,&_argo3)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OOOO:wxPseudoMetaFile_LoadFromMetaFile",_kwnames,&_argo0,&_obj1,&_argo2,&_argo3)) return NULL; if (_argo0) { if (_argo0 == Py_None) { _arg0 = NULL; } @@ -487,6 +409,11 @@ static PyObject *_wrap_wxPseudoMetaFile_LoadFromMetaFile(PyObject *self, PyObjec return NULL; } } +{ + _arg1 = wxString_in_helper(_obj1); + if (_arg1 == NULL) + return NULL; +} if (_argo2) { if (_argo2 == Py_None) { _arg2 = NULL; } else if (SWIG_GetPtrObj(_argo2,(void **) &_arg2,"_double_p")) { @@ -503,11 +430,15 @@ static PyObject *_wrap_wxPseudoMetaFile_LoadFromMetaFile(PyObject *self, PyObjec } { PyThreadState* __tstate = wxPyBeginAllowThreads(); - _result = (bool )wxPseudoMetaFile_LoadFromMetaFile(_arg0,_arg1,_arg2,_arg3); + _result = (bool )wxPseudoMetaFile_LoadFromMetaFile(_arg0,*_arg1,_arg2,_arg3); wxPyEndAllowThreads(__tstate); if (PyErr_Occurred()) return NULL; } _resultobj = Py_BuildValue("i",_result); +{ + if (_obj1) + delete _arg1; +} return _resultobj; } @@ -1886,8 +1817,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnDraw(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -1923,8 +1853,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnDrawContents(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -1962,8 +1891,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnDrawBranches(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -2000,8 +1928,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnMoveLinks(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -2037,8 +1964,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnErase(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -2074,8 +2000,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnEraseContents(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -2111,8 +2036,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnHighlight(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -2281,8 +2205,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnMovePre(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -2324,8 +2247,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnMovePost(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -2564,8 +2486,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnDrawOutline(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -2601,8 +2522,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnDrawControlPoints(PyObject *sel } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -2638,8 +2558,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnEraseControlPoints(PyObject *se } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -2677,8 +2596,7 @@ static PyObject *_wrap_wxPyRectangleShape_base_OnMoveLink(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyRectangleShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -3076,8 +2994,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnDraw(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -3113,8 +3030,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnDrawContents(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -3152,8 +3068,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnDrawBranches(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -3190,8 +3105,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnMoveLinks(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -3227,8 +3141,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnErase(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -3264,8 +3177,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnEraseContents(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -3301,8 +3213,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnHighlight(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -3471,8 +3382,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnMovePre(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -3514,8 +3424,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnMovePost(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -3754,8 +3663,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnDrawOutline(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -3791,8 +3699,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnDrawControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -3828,8 +3735,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnEraseControlPoints(PyObject *self } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -3867,8 +3773,7 @@ static PyObject *_wrap_wxPyControlPoint_base_OnMoveLink(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyControlPoint_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -4229,7 +4134,7 @@ static PyObject *_wrap_wxPyBitmapShape_GetFilename(PyObject *self, PyObject *arg if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -4260,8 +4165,7 @@ static PyObject *_wrap_wxPyBitmapShape_SetBitmap(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxBitmap_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxBitmap_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_SetBitmap. Expected _wxBitmap_p."); return NULL; } @@ -4364,8 +4268,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnDraw(PyObject *self, PyObject *arg } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -4401,8 +4304,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnDrawContents(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -4440,8 +4342,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnDrawBranches(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -4478,8 +4379,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnMoveLinks(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -4515,8 +4415,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnErase(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -4552,8 +4451,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnEraseContents(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -4589,8 +4487,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnHighlight(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -4759,8 +4656,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnMovePre(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -4802,8 +4698,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnMovePost(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -5042,8 +4937,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnDrawOutline(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -5079,8 +4973,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnDrawControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -5116,8 +5009,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnEraseControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -5155,8 +5047,7 @@ static PyObject *_wrap_wxPyBitmapShape_base_OnMoveLink(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyBitmapShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -6056,12 +5947,13 @@ static PyObject *_wrap_wxPyDrawnShape_LoadFromMetaFile(PyObject *self, PyObject PyObject * _resultobj; bool _result; wxPyDrawnShape * _arg0; - char * _arg1; + wxString * _arg1; PyObject * _argo0 = 0; + PyObject * _obj1 = 0; char *_kwnames[] = { "self","filename", NULL }; self = self; - if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Os:wxPyDrawnShape_LoadFromMetaFile",_kwnames,&_argo0,&_arg1)) + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxPyDrawnShape_LoadFromMetaFile",_kwnames,&_argo0,&_obj1)) return NULL; if (_argo0) { if (_argo0 == Py_None) { _arg0 = NULL; } @@ -6070,13 +5962,22 @@ static PyObject *_wrap_wxPyDrawnShape_LoadFromMetaFile(PyObject *self, PyObject return NULL; } } +{ + _arg1 = wxString_in_helper(_obj1); + if (_arg1 == NULL) + return NULL; +} { PyThreadState* __tstate = wxPyBeginAllowThreads(); - _result = (bool )wxPyDrawnShape_LoadFromMetaFile(_arg0,_arg1); + _result = (bool )wxPyDrawnShape_LoadFromMetaFile(_arg0,*_arg1); wxPyEndAllowThreads(__tstate); if (PyErr_Occurred()) return NULL; } _resultobj = Py_BuildValue("i",_result); +{ + if (_obj1) + delete _arg1; +} return _resultobj; } @@ -6533,8 +6434,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnDraw(PyObject *self, PyObject *args } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -6570,8 +6470,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnDrawContents(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -6609,8 +6508,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnDrawBranches(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -6647,8 +6545,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnMoveLinks(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -6684,8 +6581,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnErase(PyObject *self, PyObject *arg } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -6721,8 +6617,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnEraseContents(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -6758,8 +6653,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnHighlight(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -6928,8 +6822,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnMovePre(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -6971,8 +6864,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnMovePost(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -7211,8 +7103,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnDrawOutline(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -7248,8 +7139,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnDrawControlPoints(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -7285,8 +7175,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnEraseControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -7324,8 +7213,7 @@ static PyObject *_wrap_wxPyDrawnShape_base_OnMoveLink(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDrawnShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -8319,8 +8207,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnDraw(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -8356,8 +8243,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnDrawContents(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -8395,8 +8281,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnDrawBranches(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -8433,8 +8318,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnMoveLinks(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -8470,8 +8354,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnErase(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -8507,8 +8390,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnEraseContents(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -8544,8 +8426,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnHighlight(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -8714,8 +8595,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnMovePre(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -8757,8 +8637,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnMovePost(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -8997,8 +8876,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnDrawOutline(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -9034,8 +8912,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnDrawControlPoints(PyObject *sel } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -9071,8 +8948,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnEraseControlPoints(PyObject *se } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -9110,8 +8986,7 @@ static PyObject *_wrap_wxPyCompositeShape_base_OnMoveLink(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCompositeShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -9516,8 +9391,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnDraw(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -9553,8 +9427,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnDrawContents(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -9592,8 +9465,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnDrawBranches(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -9630,8 +9502,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnMoveLinks(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -9667,8 +9538,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnErase(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -9704,8 +9574,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnEraseContents(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -9741,8 +9610,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnHighlight(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -9911,8 +9779,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnMovePre(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -9954,8 +9821,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnMovePost(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -10194,8 +10060,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnDrawOutline(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -10231,8 +10096,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnDrawControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -10268,8 +10132,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnEraseControlPoints(PyObject *self } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -10307,8 +10170,7 @@ static PyObject *_wrap_wxPyDividedShape_base_OnMoveLink(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDividedShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -10911,7 +10773,7 @@ static PyObject *_wrap_wxPyDivisionShape_GetLeftSideColour(PyObject *self, PyObj if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -11506,8 +11368,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnDraw(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -11543,8 +11404,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnDrawContents(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -11582,8 +11442,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnDrawBranches(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -11620,8 +11479,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnMoveLinks(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -11657,8 +11515,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnErase(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -11694,8 +11551,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnEraseContents(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -11731,8 +11587,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnHighlight(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -11901,8 +11756,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnMovePre(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -11944,8 +11798,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnMovePost(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -12184,8 +12037,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnDrawOutline(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -12221,8 +12073,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnDrawControlPoints(PyObject *self } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -12258,8 +12109,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnEraseControlPoints(PyObject *sel } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -12297,8 +12147,7 @@ static PyObject *_wrap_wxPyDivisionShape_base_OnMoveLink(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyDivisionShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -12836,8 +12685,6 @@ static PyMethodDef oglshapescMethods[] = { { "wxPseudoMetaFile_Scale", (PyCFunction) _wrap_wxPseudoMetaFile_Scale, METH_VARARGS | METH_KEYWORDS }, { "wxPseudoMetaFile_Copy", (PyCFunction) _wrap_wxPseudoMetaFile_Copy, METH_VARARGS | METH_KEYWORDS }, { "wxPseudoMetaFile_Clear", (PyCFunction) _wrap_wxPseudoMetaFile_Clear, METH_VARARGS | METH_KEYWORDS }, - { "wxPseudoMetaFile_ReadAttributes", (PyCFunction) _wrap_wxPseudoMetaFile_ReadAttributes, METH_VARARGS | METH_KEYWORDS }, - { "wxPseudoMetaFile_WriteAttributes", (PyCFunction) _wrap_wxPseudoMetaFile_WriteAttributes, METH_VARARGS | METH_KEYWORDS }, { "wxPseudoMetaFile_Draw", (PyCFunction) _wrap_wxPseudoMetaFile_Draw, METH_VARARGS | METH_KEYWORDS }, { "delete_wxPseudoMetaFile", (PyCFunction) _wrap_delete_wxPseudoMetaFile, METH_VARARGS | METH_KEYWORDS }, { "new_wxPseudoMetaFile", (PyCFunction) _wrap_new_wxPseudoMetaFile, METH_VARARGS | METH_KEYWORDS }, diff --git a/wxPython/contrib/ogl/oglshapes.i b/wxPython/contrib/ogl/oglshapes.i index 38fd4dab8a..e3e3c114d5 100644 --- a/wxPython/contrib/ogl/oglshapes.i +++ b/wxPython/contrib/ogl/oglshapes.i @@ -46,16 +46,17 @@ public: ~wxPseudoMetaFile(); void Draw(wxDC& dc, double xoffset, double yoffset); - +#ifdef wxUSE_PROLOGIO void WriteAttributes(wxExpr *clause, int whichAngle); void ReadAttributes(wxExpr *clause, int whichAngle); +#endif void Clear(); void Copy(wxPseudoMetaFile& copy); void Scale(double sx, double sy); void ScaleTo(double w, double h); void Translate(double x, double y); void Rotate(double x, double y, double theta); - bool LoadFromMetaFile(char* filename, double *width, double *height); + bool LoadFromMetaFile(const wxString& filename, double *width, double *height); void GetBounds(double *minX, double *minY, double *maxX, double *maxY); void CalculateSize(wxPyDrawnShape* shape); @@ -280,7 +281,7 @@ public: wxPseudoMetaFile& GetMetaFile(); double GetRotation(); - bool LoadFromMetaFile(char * filename); + bool LoadFromMetaFile(const wxString& filename); void Rotate(double x, double y, double theta); void SetClippingRect(const wxRect& rect); void SetDrawnBackgroundColour(const wxColour& colour); diff --git a/wxPython/contrib/ogl/oglshapes.py b/wxPython/contrib/ogl/oglshapes.py index 9f6d7e260f..4090867d08 100644 --- a/wxPython/contrib/ogl/oglshapes.py +++ b/wxPython/contrib/ogl/oglshapes.py @@ -49,18 +49,15 @@ class wxPseudoMetaFilePtr(wxObjectPtr): def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,oglshapesc=oglshapesc): - if self.thisown == 1 : - oglshapesc.delete_wxPseudoMetaFile(self) + def __del__(self, delfunc=oglshapesc.delete_wxPseudoMetaFile): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def Draw(self, *_args, **_kwargs): val = apply(oglshapesc.wxPseudoMetaFile_Draw,(self,) + _args, _kwargs) return val - def WriteAttributes(self, *_args, **_kwargs): - val = apply(oglshapesc.wxPseudoMetaFile_WriteAttributes,(self,) + _args, _kwargs) - return val - def ReadAttributes(self, *_args, **_kwargs): - val = apply(oglshapesc.wxPseudoMetaFile_ReadAttributes,(self,) + _args, _kwargs) - return val def Clear(self, *_args, **_kwargs): val = apply(oglshapesc.wxPseudoMetaFile_Clear,(self,) + _args, _kwargs) return val diff --git a/wxPython/contrib/ogl/oglshapes2.cpp b/wxPython/contrib/ogl/oglshapes2.cpp index d23ae73f62..52c6257339 100644 --- a/wxPython/contrib/ogl/oglshapes2.cpp +++ b/wxPython/contrib/ogl/oglshapes2.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -210,8 +209,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnDraw(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -247,8 +245,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnDrawContents(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -286,8 +283,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnDrawBranches(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -324,8 +320,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnMoveLinks(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -361,8 +356,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnErase(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -398,8 +392,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnEraseContents(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -435,8 +428,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnHighlight(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -605,8 +597,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnMovePre(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -648,8 +639,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnMovePost(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -888,8 +878,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnDrawOutline(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -925,8 +914,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnDrawControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -962,8 +950,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnEraseControlPoints(PyObject *self } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -1001,8 +988,7 @@ static PyObject *_wrap_wxPyEllipseShape_base_OnMoveLink(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyEllipseShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -1322,8 +1308,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnDraw(PyObject *self, PyObject *arg } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -1359,8 +1344,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnDrawContents(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -1398,8 +1382,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnDrawBranches(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -1436,8 +1419,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnMoveLinks(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -1473,8 +1455,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnErase(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -1510,8 +1491,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnEraseContents(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -1547,8 +1527,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnHighlight(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -1717,8 +1696,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnMovePre(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -1760,8 +1738,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnMovePost(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -2000,8 +1977,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnDrawOutline(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -2037,8 +2013,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnDrawControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -2074,8 +2049,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnEraseControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -2113,8 +2087,7 @@ static PyObject *_wrap_wxPyCircleShape_base_OnMoveLink(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyCircleShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -2628,7 +2601,7 @@ static PyObject *_wrap_wxArrowHead_GetName(PyObject *self, PyObject *args, PyObj if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -3149,8 +3122,7 @@ static PyObject *_wrap_wxPyLineShape_DrawArrow(PyObject *self, PyObject *args, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_DrawArrow. Expected _wxDC_p."); return NULL; } @@ -3291,8 +3263,7 @@ static PyObject *_wrap_wxPyLineShape_DrawArrows(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_DrawArrows. Expected _wxDC_p."); return NULL; } @@ -3332,8 +3303,7 @@ static PyObject *_wrap_wxPyLineShape_DrawRegion(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_DrawRegion. Expected _wxDC_p."); return NULL; } @@ -3380,8 +3350,7 @@ static PyObject *_wrap_wxPyLineShape_EraseRegion(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_EraseRegion. Expected _wxDC_p."); return NULL; } @@ -3863,7 +3832,7 @@ static PyObject *_wrap_wxPyLineShape_GetLabelPosition(PyObject *self, PyObject * #define wxPyLineShape_GetNextControlPoint(_swigobj,_swigarg0) (_swigobj->GetNextControlPoint(_swigarg0)) static PyObject *_wrap_wxPyLineShape_GetNextControlPoint(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; - wxPoint * _result; + wxRealPoint * _result; wxPyLineShape * _arg0; wxPyShape * _arg1; PyObject * _argo0 = 0; @@ -3890,12 +3859,12 @@ static PyObject *_wrap_wxPyLineShape_GetNextControlPoint(PyObject *self, PyObjec } { PyThreadState* __tstate = wxPyBeginAllowThreads(); - _result = (wxPoint *)wxPyLineShape_GetNextControlPoint(_arg0,_arg1); + _result = (wxRealPoint *)wxPyLineShape_GetNextControlPoint(_arg0,_arg1); wxPyEndAllowThreads(__tstate); if (PyErr_Occurred()) return NULL; } if (_result) { - SWIG_MakePtr(_ptemp, (char *) _result,"_wxPoint_p"); + SWIG_MakePtr(_ptemp, (char *) _result,"_wxRealPoint_p"); _resultobj = Py_BuildValue("s",_ptemp); } else { Py_INCREF(Py_None); @@ -4465,8 +4434,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnDraw(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -4502,8 +4470,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnDrawContents(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -4541,8 +4508,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnDrawBranches(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -4579,8 +4545,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnMoveLinks(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -4616,8 +4581,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnErase(PyObject *self, PyObject *args } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -4653,8 +4617,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnEraseContents(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -4690,8 +4653,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnHighlight(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -4860,8 +4822,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnMovePre(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -4903,8 +4864,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnMovePost(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -5143,8 +5103,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnDrawOutline(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -5180,8 +5139,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnDrawControlPoints(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -5217,8 +5175,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnEraseControlPoints(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -5256,8 +5213,7 @@ static PyObject *_wrap_wxPyLineShape_base_OnMoveLink(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyLineShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -5758,8 +5714,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnDraw(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -5795,8 +5750,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnDrawContents(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -5834,8 +5788,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnDrawBranches(PyObject *self, PyOb } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -5872,8 +5825,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnMoveLinks(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -5909,8 +5861,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnErase(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -5946,8 +5897,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnEraseContents(PyObject *self, PyO } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -5983,8 +5933,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnHighlight(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -6153,8 +6102,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnMovePre(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -6196,8 +6144,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnMovePost(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -6436,8 +6383,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnDrawOutline(PyObject *self, PyObj } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -6473,8 +6419,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnDrawControlPoints(PyObject *self, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -6510,8 +6455,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnEraseControlPoints(PyObject *self } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -6549,8 +6493,7 @@ static PyObject *_wrap_wxPyPolygonShape_base_OnMoveLink(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyPolygonShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } @@ -6899,8 +6842,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnDraw(PyObject *self, PyObject *args, } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnDraw. Expected _wxDC_p."); return NULL; } @@ -6936,8 +6878,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnDrawContents(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnDrawContents. Expected _wxDC_p."); return NULL; } @@ -6975,8 +6916,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnDrawBranches(PyObject *self, PyObjec } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnDrawBranches. Expected _wxDC_p."); return NULL; } @@ -7013,8 +6953,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnMoveLinks(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnMoveLinks. Expected _wxDC_p."); return NULL; } @@ -7050,8 +6989,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnErase(PyObject *self, PyObject *args } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnErase. Expected _wxDC_p."); return NULL; } @@ -7087,8 +7025,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnEraseContents(PyObject *self, PyObje } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnEraseContents. Expected _wxDC_p."); return NULL; } @@ -7124,8 +7061,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnHighlight(PyObject *self, PyObject * } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnHighlight. Expected _wxDC_p."); return NULL; } @@ -7294,8 +7230,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnMovePre(PyObject *self, PyObject *ar } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnMovePre. Expected _wxDC_p."); return NULL; } @@ -7337,8 +7272,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnMovePost(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnMovePost. Expected _wxDC_p."); return NULL; } @@ -7577,8 +7511,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnDrawOutline(PyObject *self, PyObject } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnDrawOutline. Expected _wxDC_p."); return NULL; } @@ -7614,8 +7547,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnDrawControlPoints(PyObject *self, Py } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnDrawControlPoints. Expected _wxDC_p."); return NULL; } @@ -7651,8 +7583,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnEraseControlPoints(PyObject *self, P } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnEraseControlPoints. Expected _wxDC_p."); return NULL; } @@ -7690,8 +7621,7 @@ static PyObject *_wrap_wxPyTextShape_base_OnMoveLink(PyObject *self, PyObject *a } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxDC_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxPyTextShape_base_OnMoveLink. Expected _wxDC_p."); return NULL; } diff --git a/wxPython/contrib/ogl/oglshapes2.i b/wxPython/contrib/ogl/oglshapes2.i index 2cb69e5a43..108a423acd 100644 --- a/wxPython/contrib/ogl/oglshapes2.i +++ b/wxPython/contrib/ogl/oglshapes2.i @@ -209,7 +209,7 @@ public: void GetEnds(double *OUTPUT, double *OUTPUT, double *OUTPUT, double *OUTPUT); wxPyShape * GetFrom(); void GetLabelPosition(int position, double *OUTPUT, double *OUTPUT); - wxPoint * GetNextControlPoint(wxPyShape *shape); + wxRealPoint * GetNextControlPoint(wxPyShape *shape); wxPyShape * GetTo(); void Initialise(); void InsertLineControlPoint(wxDC* dc); diff --git a/wxPython/contrib/ogl/oglshapes2.py b/wxPython/contrib/ogl/oglshapes2.py index 25c6516237..60d4c2947e 100644 --- a/wxPython/contrib/ogl/oglshapes2.py +++ b/wxPython/contrib/ogl/oglshapes2.py @@ -257,9 +257,12 @@ class wxArrowHeadPtr(wxObjectPtr): def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,oglshapes2c=oglshapes2c): - if self.thisown == 1 : - oglshapes2c.delete_wxArrowHead(self) + def __del__(self, delfunc=oglshapes2c.delete_wxArrowHead): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def _GetType(self, *_args, **_kwargs): val = apply(oglshapes2c.wxArrowHead__GetType,(self,) + _args, _kwargs) return val @@ -393,7 +396,7 @@ class wxPyLineShapePtr(wxPyShapePtr): return val def GetNextControlPoint(self, *_args, **_kwargs): val = apply(oglshapes2c.wxPyLineShape_GetNextControlPoint,(self,) + _args, _kwargs) - if val: val = wxPointPtr(val) + if val: val = wxRealPointPtr(val) return val def GetTo(self, *_args, **_kwargs): val = apply(oglshapes2c.wxPyLineShape_GetTo,(self,) + _args, _kwargs) diff --git a/wxPython/contrib/stc/_stcextras.py b/wxPython/contrib/stc/_stcextras.py index eefe2c4547..dc8f3456ef 100644 --- a/wxPython/contrib/stc/_stcextras.py +++ b/wxPython/contrib/stc/_stcextras.py @@ -3,5 +3,5 @@ wx.wxStyledTextEventPtr = wxStyledTextEventPtr wx.wxStyledTextCtrlPtr = wxStyledTextCtrlPtr - -wxSTC_CARET_CENTER = wxSTC_CARET_STRICT +# This constant no longer exists in Scintilla, but I'll put it here for a while to avoid disrupting user code... +wxSTC_CARET_CENTER = 0 diff --git a/wxPython/contrib/xrc/_xrcextras.py b/wxPython/contrib/xrc/_xrcextras.py index e4cd16f562..9562aea2eb 100644 --- a/wxPython/contrib/xrc/_xrcextras.py +++ b/wxPython/contrib/xrc/_xrcextras.py @@ -4,3 +4,35 @@ wxTheXmlResource = wxXmlResource_Get() wx.wxXmlNodePtr = wxXmlNodePtr + + + + +#---------------------------------------------------------------------- +# Create a factory for handling the subclass property of the object tag. + + +def _my_import(name): + mod = __import__(name) + components = name.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + return mod + + +class wxXmlSubclassFactory_Python(wxXmlSubclassFactory): + def __init__(self): + wxXmlSubclassFactory.__init__(self) + + def Create(self, className): + assert className.find('.') != -1, "Module name must be specified!" + mname = className[:className.rfind('.')] + cname = className[className.rfind('.')+1:] + module = _my_import(mname) + klass = getattr(module, cname) + inst = klass() + return inst + + +wxXmlResource_AddSubclassFactory(wxXmlSubclassFactory_Python()) + diff --git a/wxPython/contrib/xrc/xrc.cpp b/wxPython/contrib/xrc/xrc.cpp index e42e2572b8..c9b4c7caba 100644 --- a/wxPython/contrib/xrc/xrc.cpp +++ b/wxPython/contrib/xrc/xrc.cpp @@ -19,6 +19,8 @@ /* Implementation : PYTHON */ #define SWIGPYTHON +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -36,12 +38,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); @@ -98,6 +97,16 @@ static PyObject* t_output_helper(PyObject* target, PyObject* o) { static const wxString wxPyBitmapString(wxT("bitmap")); static const wxString wxPyIconString(wxT("icon")); static const wxString wxPyFontString(wxT("font")); + +class wxPyXmlSubclassFactory : public wxXmlSubclassFactory +{ +public: + wxPyXmlSubclassFactory() {} + DEC_PYCALLBACK_OBJECT_STRING_pure(Create); + PYPRIVATE; +}; + +IMP_PYCALLBACK_OBJECT_STRING_pure(wxPyXmlSubclassFactory, wxXmlSubclassFactory, Create); // C++ version of Python aware wxXmlResourceHandler, for the pure virtual // callbacks, as well as to make some protected things public so they can // be wrapped. @@ -111,34 +120,6 @@ public: DEC_PYCALLBACK_OBJECT__pure(DoCreateResource); DEC_PYCALLBACK_BOOL_NODE_pure(CanHandle); -// wxObject* DoCreateResource() { -// wxObject* rv = NULL; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "DoCreateResource")) { -// PyObject* ro; -// ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); -// if (ro) { -// SWIG_GetPtrObj(ro, (void **)&rv, "_wxObject_p"); -// Py_DECREF(ro); -// } -// } -// wxPyEndBlockThreads(); -// return rv; -// } - -// bool CanHandle(wxXmlNode* a) { -// bool rv=FALSE; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "CanHandle")) { -// PyObject* obj = wxPyConstructObject((void*)a, "wxXmlNode", 0); -// rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); -// Py_DECREF(obj); -// } -// wxPyEndBlockThreads(); -// return rv; -// } - - // accessors for protected members @@ -576,6 +557,33 @@ static PyObject *_wrap_wxXmlResource_ClearHandlers(PyObject *self, PyObject *arg return _resultobj; } +static PyObject *_wrap_wxXmlResource_AddSubclassFactory(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyXmlSubclassFactory * _arg0; + PyObject * _argo0 = 0; + char *_kwnames[] = { "factory", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"O:wxXmlResource_AddSubclassFactory",_kwnames,&_argo0)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyXmlSubclassFactory_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxXmlResource_AddSubclassFactory. Expected _wxPyXmlSubclassFactory_p."); + return NULL; + } + } +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxXmlResource::AddSubclassFactory(_arg0); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + #define wxXmlResource_LoadMenu(_swigobj,_swigarg0) (_swigobj->LoadMenu(_swigarg0)) static PyObject *_wrap_wxXmlResource_LoadMenu(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -1521,6 +1529,99 @@ static PyObject *_wrap_wxXmlResource_GetFlags(PyObject *self, PyObject *args, Py return _resultobj; } +#define wxXmlResource_SetFlags(_swigobj,_swigarg0) (_swigobj->SetFlags(_swigarg0)) +static PyObject *_wrap_wxXmlResource_SetFlags(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxXmlResource * _arg0; + int _arg1; + PyObject * _argo0 = 0; + char *_kwnames[] = { "self","flags", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"Oi:wxXmlResource_SetFlags",_kwnames,&_argo0,&_arg1)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxXmlResource_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxXmlResource_SetFlags. Expected _wxXmlResource_p."); + return NULL; + } + } +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxXmlResource_SetFlags(_arg0,_arg1); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + +#define new_wxXmlSubclassFactory() (new wxPyXmlSubclassFactory()) +static PyObject *_wrap_new_wxXmlSubclassFactory(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyXmlSubclassFactory * _result; + char *_kwnames[] = { NULL }; + char _ptemp[128]; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,":new_wxXmlSubclassFactory",_kwnames)) + return NULL; +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + _result = (wxPyXmlSubclassFactory *)new_wxXmlSubclassFactory(); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} if (_result) { + SWIG_MakePtr(_ptemp, (char *) _result,"_wxPyXmlSubclassFactory_p"); + _resultobj = Py_BuildValue("s",_ptemp); + } else { + Py_INCREF(Py_None); + _resultobj = Py_None; + } + return _resultobj; +} + +#define wxXmlSubclassFactory__setCallbackInfo(_swigobj,_swigarg0,_swigarg1) (_swigobj->_setCallbackInfo(_swigarg0,_swigarg1)) +static PyObject *_wrap_wxXmlSubclassFactory__setCallbackInfo(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxPyXmlSubclassFactory * _arg0; + PyObject * _arg1; + PyObject * _arg2; + PyObject * _argo0 = 0; + PyObject * _obj1 = 0; + PyObject * _obj2 = 0; + char *_kwnames[] = { "self","self","_class", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OOO:wxXmlSubclassFactory__setCallbackInfo",_kwnames,&_argo0,&_obj1,&_obj2)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxPyXmlSubclassFactory_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxXmlSubclassFactory__setCallbackInfo. Expected _wxPyXmlSubclassFactory_p."); + return NULL; + } + } +{ + _arg1 = _obj1; +} +{ + _arg2 = _obj2; +} +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxXmlSubclassFactory__setCallbackInfo(_arg0,_arg1,_arg2); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; + return _resultobj; +} + #define new_wxXmlProperty(_swigarg0,_swigarg1,_swigarg2) (new wxXmlProperty(_swigarg0,_swigarg1,_swigarg2)) static PyObject *_wrap_new_wxXmlProperty(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject * _resultobj; @@ -1606,7 +1707,7 @@ static PyObject *_wrap_wxXmlProperty_GetName(PyObject *self, PyObject *args, PyO if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -1643,7 +1744,7 @@ static PyObject *_wrap_wxXmlProperty_GetValue(PyObject *self, PyObject *args, Py if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -2260,7 +2361,7 @@ static PyObject *_wrap_wxXmlNode_GetName(PyObject *self, PyObject *args, PyObjec if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -2297,7 +2398,7 @@ static PyObject *_wrap_wxXmlNode_GetContent(PyObject *self, PyObject *args, PyOb if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -2488,7 +2589,7 @@ static PyObject *_wrap_wxXmlNode_GetPropVal(PyObject *self, PyObject *args, PyOb if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -3143,8 +3244,7 @@ static PyObject *_wrap_wxXmlDocument_SaveToStream(PyObject *self, PyObject *args } } if (_argo1) { - if (_argo1 == Py_None) { _arg1 = NULL; } - else if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxOutputStream_p")) { + if (SWIG_GetPtrObj(_argo1,(void **) &_arg1,"_wxOutputStream_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 2 of wxXmlDocument_SaveToStream. Expected _wxOutputStream_p."); return NULL; } @@ -3248,7 +3348,7 @@ static PyObject *_wrap_wxXmlDocument_GetVersion(PyObject *self, PyObject *args, if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -3285,7 +3385,7 @@ static PyObject *_wrap_wxXmlDocument_GetFileEncoding(PyObject *self, PyObject *a if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -3443,7 +3543,7 @@ static PyObject *_wrap_wxXmlDocument_GetEncoding(PyObject *self, PyObject *args, if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -3454,6 +3554,51 @@ static PyObject *_wrap_wxXmlDocument_GetEncoding(PyObject *self, PyObject *args, return _resultobj; } +static void wxXmlDocument_SetEncoding(wxXmlDocument *self,const wxString & enc) { + #if wxUSE_UNICODE + // do nothing + #else + self->SetEncoding(enc); + #endif + } +static PyObject *_wrap_wxXmlDocument_SetEncoding(PyObject *self, PyObject *args, PyObject *kwargs) { + PyObject * _resultobj; + wxXmlDocument * _arg0; + wxString * _arg1; + PyObject * _argo0 = 0; + PyObject * _obj1 = 0; + char *_kwnames[] = { "self","enc", NULL }; + + self = self; + if(!PyArg_ParseTupleAndKeywords(args,kwargs,"OO:wxXmlDocument_SetEncoding",_kwnames,&_argo0,&_obj1)) + return NULL; + if (_argo0) { + if (_argo0 == Py_None) { _arg0 = NULL; } + else if (SWIG_GetPtrObj(_argo0,(void **) &_arg0,"_wxXmlDocument_p")) { + PyErr_SetString(PyExc_TypeError,"Type error in argument 1 of wxXmlDocument_SetEncoding. Expected _wxXmlDocument_p."); + return NULL; + } + } +{ + _arg1 = wxString_in_helper(_obj1); + if (_arg1 == NULL) + return NULL; +} +{ + PyThreadState* __tstate = wxPyBeginAllowThreads(); + wxXmlDocument_SetEncoding(_arg0,*_arg1); + + wxPyEndAllowThreads(__tstate); + if (PyErr_Occurred()) return NULL; +} Py_INCREF(Py_None); + _resultobj = Py_None; +{ + if (_obj1) + delete _arg1; +} + return _resultobj; +} + static void *SwigwxPyXmlResourceHandlerTowxObject(void *ptr) { wxPyXmlResourceHandler *src; wxObject *dest; @@ -3714,7 +3859,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetClass(PyObject *self, PyObject *a if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -3920,7 +4065,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetNodeContent(PyObject *self, PyObj if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -4049,7 +4194,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetParamValue(PyObject *self, PyObje if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -4209,7 +4354,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetText(PyObject *self, PyObject *ar if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -4278,7 +4423,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetName(PyObject *self, PyObject *ar if (PyErr_Occurred()) return NULL; }{ #if wxUSE_UNICODE - _resultobj = PyUnicode_FromUnicode(_result->c_str(), _result->Len()); + _resultobj = PyUnicode_FromWideChar(_result->c_str(), _result->Len()); #else _resultobj = PyString_FromStringAndSize(_result->c_str(), _result->Len()); #endif @@ -4569,8 +4714,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetBitmap(PyObject *self, PyObject * return NULL; } if (_argo2) { - if (_argo2 == Py_None) { _arg2 = NULL; } - else if (SWIG_GetPtrObj(_argo2,(void **) &_arg2,"_wxArtClient_p")) { + if (SWIG_GetPtrObj(_argo2,(void **) &_arg2,"_wxArtClient_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 3 of wxXmlResourceHandler_GetBitmap. Expected _wxArtClient_p."); return NULL; } @@ -4629,8 +4773,7 @@ static PyObject *_wrap_wxXmlResourceHandler_GetIcon(PyObject *self, PyObject *ar return NULL; } if (_argo2) { - if (_argo2 == Py_None) { _arg2 = NULL; } - else if (SWIG_GetPtrObj(_argo2,(void **) &_arg2,"_wxArtClient_p")) { + if (SWIG_GetPtrObj(_argo2,(void **) &_arg2,"_wxArtClient_p")) { PyErr_SetString(PyExc_TypeError,"Type error in argument 3 of wxXmlResourceHandler_GetIcon. Expected _wxArtClient_p."); return NULL; } @@ -4942,6 +5085,7 @@ static PyMethodDef xrccMethods[] = { { "wxXmlResourceHandler_CreateResource", (PyCFunction) _wrap_wxXmlResourceHandler_CreateResource, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResourceHandler__setCallbackInfo", (PyCFunction) _wrap_wxXmlResourceHandler__setCallbackInfo, METH_VARARGS | METH_KEYWORDS }, { "new_wxXmlResourceHandler", (PyCFunction) _wrap_new_wxXmlResourceHandler, METH_VARARGS | METH_KEYWORDS }, + { "wxXmlDocument_SetEncoding", (PyCFunction) _wrap_wxXmlDocument_SetEncoding, METH_VARARGS | METH_KEYWORDS }, { "wxXmlDocument_GetEncoding", (PyCFunction) _wrap_wxXmlDocument_GetEncoding, METH_VARARGS | METH_KEYWORDS }, { "wxXmlDocument_SetFileEncoding", (PyCFunction) _wrap_wxXmlDocument_SetFileEncoding, METH_VARARGS | METH_KEYWORDS }, { "wxXmlDocument_SetVersion", (PyCFunction) _wrap_wxXmlDocument_SetVersion, METH_VARARGS | METH_KEYWORDS }, @@ -4990,6 +5134,9 @@ static PyMethodDef xrccMethods[] = { { "wxXmlProperty_GetValue", (PyCFunction) _wrap_wxXmlProperty_GetValue, METH_VARARGS | METH_KEYWORDS }, { "wxXmlProperty_GetName", (PyCFunction) _wrap_wxXmlProperty_GetName, METH_VARARGS | METH_KEYWORDS }, { "new_wxXmlProperty", (PyCFunction) _wrap_new_wxXmlProperty, METH_VARARGS | METH_KEYWORDS }, + { "wxXmlSubclassFactory__setCallbackInfo", (PyCFunction) _wrap_wxXmlSubclassFactory__setCallbackInfo, METH_VARARGS | METH_KEYWORDS }, + { "new_wxXmlSubclassFactory", (PyCFunction) _wrap_new_wxXmlSubclassFactory, METH_VARARGS | METH_KEYWORDS }, + { "wxXmlResource_SetFlags", (PyCFunction) _wrap_wxXmlResource_SetFlags, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_GetFlags", (PyCFunction) _wrap_wxXmlResource_GetFlags, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_Set", (PyCFunction) _wrap_wxXmlResource_Set, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_Get", (PyCFunction) _wrap_wxXmlResource_Get, METH_VARARGS | METH_KEYWORDS }, @@ -5011,6 +5158,7 @@ static PyMethodDef xrccMethods[] = { { "wxXmlResource_LoadMenuBarOnFrame", (PyCFunction) _wrap_wxXmlResource_LoadMenuBarOnFrame, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_LoadMenuBar", (PyCFunction) _wrap_wxXmlResource_LoadMenuBar, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_LoadMenu", (PyCFunction) _wrap_wxXmlResource_LoadMenu, METH_VARARGS | METH_KEYWORDS }, + { "wxXmlResource_AddSubclassFactory", (PyCFunction) _wrap_wxXmlResource_AddSubclassFactory, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_ClearHandlers", (PyCFunction) _wrap_wxXmlResource_ClearHandlers, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_InsertHandler", (PyCFunction) _wrap_wxXmlResource_InsertHandler, METH_VARARGS | METH_KEYWORDS }, { "wxXmlResource_AddHandler", (PyCFunction) _wrap_wxXmlResource_AddHandler, METH_VARARGS | METH_KEYWORDS }, diff --git a/wxPython/contrib/xrc/xrc.i b/wxPython/contrib/xrc/xrc.i index 037e1eb214..8676043657 100644 --- a/wxPython/contrib/xrc/xrc.i +++ b/wxPython/contrib/xrc/xrc.i @@ -48,6 +48,9 @@ static const wxString wxPyIconString(wxT("icon")); static const wxString wxPyFontString(wxT("font")); %} + +class wxPyXmlSubclassFactory; + //--------------------------------------------------------------------------- enum wxXmlResourceFlags @@ -128,6 +131,12 @@ public: // Removes all handlers void ClearHandlers(); + // Registers subclasses factory for use in XRC. This function is not meant + // for public use, please see the comment above wxXmlSubclassFactory + // definition. + static void AddSubclassFactory(wxPyXmlSubclassFactory *factory); + + // Loads menu from resource. Returns NULL on failure. wxMenu *LoadMenu(const wxString& name); @@ -199,6 +208,9 @@ public: // Returns flags, which may be a bitlist of wxXRC_USE_LOCALE and wxXRC_NO_SUBCLASSING. int GetFlags(); + // Set flags after construction. + void SetFlags(int flags) { m_flags = flags; } + }; //---------------------------------------------------------------------- @@ -215,6 +227,31 @@ XMLCTRL = XRCCTRL " //---------------------------------------------------------------------- +// wxXmlSubclassFactory + + +%{ +class wxPyXmlSubclassFactory : public wxXmlSubclassFactory +{ +public: + wxPyXmlSubclassFactory() {} + DEC_PYCALLBACK_OBJECT_STRING_pure(Create); + PYPRIVATE; +}; + +IMP_PYCALLBACK_OBJECT_STRING_pure(wxPyXmlSubclassFactory, wxXmlSubclassFactory, Create); +%} + + +%name(wxXmlSubclassFactory)class wxPyXmlSubclassFactory { +public: + wxPyXmlSubclassFactory(); + + void _setCallbackInfo(PyObject* self, PyObject* _class); + %pragma(python) addtomethod = "__init__:self._setCallbackInfo(self, wxXmlSubclassFactory)" +}; + + //---------------------------------------------------------------------- // In order to provide wrappers for wxXmlResourceHandler we need to also // provide the classes for representing and parsing XML. @@ -374,6 +411,13 @@ public: return self->GetEncoding(); #endif } + void SetEncoding(const wxString& enc) { + #if wxUSE_UNICODE + // do nothing + #else + self->SetEncoding(enc); + #endif + } } }; @@ -396,34 +440,6 @@ public: DEC_PYCALLBACK_OBJECT__pure(DoCreateResource); DEC_PYCALLBACK_BOOL_NODE_pure(CanHandle); -// wxObject* DoCreateResource() { -// wxObject* rv = NULL; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "DoCreateResource")) { -// PyObject* ro; -// ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); -// if (ro) { -// SWIG_GetPtrObj(ro, (void **)&rv, "_wxObject_p"); -// Py_DECREF(ro); -// } -// } -// wxPyEndBlockThreads(); -// return rv; -// } - -// bool CanHandle(wxXmlNode* a) { -// bool rv=FALSE; -// wxPyBeginBlockThreads(); -// if (wxPyCBH_findCallback(m_myInst, "CanHandle")) { -// PyObject* obj = wxPyConstructObject((void*)a, "wxXmlNode", 0); -// rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); -// Py_DECREF(obj); -// } -// wxPyEndBlockThreads(); -// return rv; -// } - - // accessors for protected members diff --git a/wxPython/contrib/xrc/xrc.py b/wxPython/contrib/xrc/xrc.py index 9a10422a35..79f0b6a62c 100644 --- a/wxPython/contrib/xrc/xrc.py +++ b/wxPython/contrib/xrc/xrc.py @@ -56,9 +56,12 @@ class wxXmlResourcePtr(wxObjectPtr): def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,xrcc=xrcc): - if self.thisown == 1 : - xrcc.delete_wxXmlResource(self) + def __del__(self, delfunc=xrcc.delete_wxXmlResource): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def Load(self, *_args, **_kwargs): val = apply(xrcc.wxXmlResource_Load,(self,) + _args, _kwargs) return val @@ -135,6 +138,9 @@ class wxXmlResourcePtr(wxObjectPtr): def GetFlags(self, *_args, **_kwargs): val = apply(xrcc.wxXmlResource_GetFlags,(self,) + _args, _kwargs) return val + def SetFlags(self, *_args, **_kwargs): + val = apply(xrcc.wxXmlResource_SetFlags,(self,) + _args, _kwargs) + return val def __repr__(self): return "" % (self.this,) class wxXmlResource(wxXmlResourcePtr): @@ -152,6 +158,24 @@ def wxEmptyXmlResource(*_args,**_kwargs): return val +class wxXmlSubclassFactoryPtr : + def __init__(self,this): + self.this = this + self.thisown = 0 + def _setCallbackInfo(self, *_args, **_kwargs): + val = apply(xrcc.wxXmlSubclassFactory__setCallbackInfo,(self,) + _args, _kwargs) + return val + def __repr__(self): + return "" % (self.this,) +class wxXmlSubclassFactory(wxXmlSubclassFactoryPtr): + def __init__(self,*_args,**_kwargs): + self.this = apply(xrcc.new_wxXmlSubclassFactory,_args,_kwargs) + self.thisown = 1 + self._setCallbackInfo(self, wxXmlSubclassFactory) + + + + class wxXmlPropertyPtr : def __init__(self,this): self.this = this @@ -189,9 +213,12 @@ class wxXmlNodePtr : def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,xrcc=xrcc): - if self.thisown == 1 : - xrcc.delete_wxXmlNode(self) + def __del__(self, delfunc=xrcc.delete_wxXmlNode): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def AddChild(self, *_args, **_kwargs): val = apply(xrcc.wxXmlNode_AddChild,(self,) + _args, _kwargs) return val @@ -281,9 +308,12 @@ class wxXmlDocumentPtr(wxObjectPtr): def __init__(self,this): self.this = this self.thisown = 0 - def __del__(self,xrcc=xrcc): - if self.thisown == 1 : - xrcc.delete_wxXmlDocument(self) + def __del__(self, delfunc=xrcc.delete_wxXmlDocument): + if self.thisown == 1: + try: + delfunc(self) + except: + pass def Load(self, *_args, **_kwargs): val = apply(xrcc.wxXmlDocument_Load,(self,) + _args, _kwargs) return val @@ -321,6 +351,9 @@ class wxXmlDocumentPtr(wxObjectPtr): def GetEncoding(self, *_args, **_kwargs): val = apply(xrcc.wxXmlDocument_GetEncoding,(self,) + _args, _kwargs) return val + def SetEncoding(self, *_args, **_kwargs): + val = apply(xrcc.wxXmlDocument_SetEncoding,(self,) + _args, _kwargs) + return val def __repr__(self): return "" % (self.this,) class wxXmlDocument(wxXmlDocumentPtr): @@ -474,6 +507,8 @@ class wxXmlResourceHandler(wxXmlResourceHandlerPtr): #-------------- FUNCTION WRAPPERS ------------------ +wxXmlResource_AddSubclassFactory = xrcc.wxXmlResource_AddSubclassFactory + wxXmlResource_GetXRCID = xrcc.wxXmlResource_GetXRCID def wxXmlResource_Get(*_args, **_kwargs): @@ -515,3 +550,35 @@ wxXML_HTML_DOCUMENT_NODE = xrcc.wxXML_HTML_DOCUMENT_NODE wxTheXmlResource = wxXmlResource_Get() wx.wxXmlNodePtr = wxXmlNodePtr + + + + +#---------------------------------------------------------------------- +# Create a factory for handling the subclass property of the object tag. + + +def _my_import(name): + mod = __import__(name) + components = name.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + return mod + + +class wxXmlSubclassFactory_Python(wxXmlSubclassFactory): + def __init__(self): + wxXmlSubclassFactory.__init__(self) + + def Create(self, className): + assert className.find('.') != -1, "Module name must be specified!" + mname = className[:className.rfind('.')] + cname = className[className.rfind('.')+1:] + module = _my_import(mname) + klass = getattr(module, cname) + inst = klass() + return inst + + +wxXmlResource_AddSubclassFactory(wxXmlSubclassFactory_Python()) + diff --git a/wxPython/demo/.cvsignore b/wxPython/demo/.cvsignore index b4a758e078..3648f08aa4 100644 --- a/wxPython/demo/.cvsignore +++ b/wxPython/demo/.cvsignore @@ -1,6 +1,9 @@ *.pyc .DS_Store +._demo.py .emacs.desktop +.gdb_history +.setup.sh b.bat hangman_dict.txt mimetypes_wdr diff --git a/wxPython/demo/About.py b/wxPython/demo/About.py index 0605fa36fa..3e22739553 100644 --- a/wxPython/demo/About.py +++ b/wxPython/demo/About.py @@ -1,4 +1,4 @@ -import sys, string +import sys from wxPython.wx import * from wxPython.html import * @@ -46,12 +46,12 @@ demo item so you can learn how to use the classes yourself.

def __init__(self, parent): wxDialog.__init__(self, parent, -1, 'About the wxPython demo',) html = wxHtmlWindow(self, -1, size=(420, -1)) - py_version = string.split(sys.version)[0] + py_version = sys.version.split()[0] html.SetPage(self.text % (wx.__version__, py_version)) btn = html.FindWindowById(wxID_OK) btn.SetDefault() ir = html.GetInternalRepresentation() - html.SetSize( (ir.GetWidth()+5, ir.GetHeight()+5) ) + html.SetSize( (ir.GetWidth()+25, ir.GetHeight()+25) ) self.SetClientSize(html.GetSize()) self.CentreOnParent(wxBOTH) diff --git a/wxPython/demo/ActiveXWrapper_Acrobat.py b/wxPython/demo/ActiveXWrapper_Acrobat.py index 6eb972d109..694f875463 100644 --- a/wxPython/demo/ActiveXWrapper_Acrobat.py +++ b/wxPython/demo/ActiveXWrapper_Acrobat.py @@ -62,7 +62,7 @@ class TestPanel(wxPanel): sizer.Add(btnSizer, 0, wxEXPAND) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_WINDOW_DESTROY(self, self.OnDestroy) @@ -121,7 +121,7 @@ if __name__ == '__main__': app = wxPySimpleApp() frame = TestFrame() - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/ActiveXWrapper_IE.py b/wxPython/demo/ActiveXWrapper_IE.py index 2e23f54545..2e08c8e1a4 100644 --- a/wxPython/demo/ActiveXWrapper_IE.py +++ b/wxPython/demo/ActiveXWrapper_IE.py @@ -101,12 +101,18 @@ class TestPanel(wxWindow): self.location.Append(self.current) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_SIZE(self, self.OnSize) EVT_WINDOW_DESTROY(self, self.OnDestroy) + def ShutdownDemo(self): + # put the frame title back + if self.frame: + self.frame.SetTitle(self.titleBase) + + def OnDestroy(self, evt): if self.ie: self.ie.Cleanup() @@ -224,7 +230,7 @@ if __name__ == '__main__': app = wxPySimpleApp() frame = TestFrame() - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/ColourSelect.py b/wxPython/demo/ColourSelect.py index 0e044e0671..18cdf015a5 100644 --- a/wxPython/demo/ColourSelect.py +++ b/wxPython/demo/ColourSelect.py @@ -18,7 +18,6 @@ from wxPython.wx import * from wxPython.lib.colourselect import * -import string #---------------------------------------------------------------------------- @@ -26,7 +25,7 @@ class TestColourSelect(wxPanel): def __init__(self, parent, log): self.log = log wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) mainSizer = wxBoxSizer(wxVERTICAL) self.SetSizer(mainSizer) t = wxStaticText(self, -1, @@ -86,7 +85,7 @@ class TestColourSelect(wxPanel): colour = button.GetColour() # get the colour selection button result result.append(name + ": " + str(colour)) # create string list for easy viewing of results - out_result = string.joinfields(result, ', ') + out_result = ', '.join(result) self.log.WriteText("Colour Results: " + out_result + "\n") #--------------------------------------------------------------------------- diff --git a/wxPython/demo/ContextHelp.py b/wxPython/demo/ContextHelp.py index 2c2a567ab7..c115f22c44 100644 --- a/wxPython/demo/ContextHelp.py +++ b/wxPython/demo/ContextHelp.py @@ -53,7 +53,7 @@ class TestPanel(wxPanel): border = wxBoxSizer(wxVERTICAL) border.Add(sizer, 0, wxALL, 25) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(border) self.Layout() diff --git a/wxPython/demo/CustomDragAndDrop.py b/wxPython/demo/CustomDragAndDrop.py index 46c3ed5240..3fb49e5d02 100644 --- a/wxPython/demo/CustomDragAndDrop.py +++ b/wxPython/demo/CustomDragAndDrop.py @@ -124,7 +124,8 @@ class DoodleDropTarget(wxPyDropTarget): self.dv = window # specify the type of data we will accept - self.data = wxCustomDataObject(wxCustomDataFormat("DoodleLines")) + self.df = wxCustomDataFormat("DoodleLines") + self.data = wxCustomDataObject(self.df) self.SetDataObject(self.data) @@ -138,7 +139,7 @@ class DoodleDropTarget(wxPyDropTarget): def OnDrop(self, x, y): self.log.WriteText("OnDrop: %d %d\n" % (x, y)) - return true + return True def OnDragOver(self, x, y, d): #self.log.WriteText("OnDragOver: %d, %d, %d\n" % (x, y, d)) @@ -153,7 +154,7 @@ class DoodleDropTarget(wxPyDropTarget): - # Called when OnDrop returns true. We need to get the data and + # Called when OnDrop returns True. We need to get the data and # do something with it. def OnData(self, x, y, d): self.log.WriteText("OnData: %d, %d, %d\n" % (x, y, d)) @@ -205,7 +206,7 @@ class CustomDnDPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) - self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, false)) + self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, False)) # Make the controls text1 = wxStaticText(self, -1, @@ -217,9 +218,9 @@ class CustomDnDPanel(wxPanel): ) rb1 = wxRadioButton(self, -1, "Draw", style=wxRB_GROUP) - rb1.SetValue(true) + rb1.SetValue(True) rb2 = wxRadioButton(self, -1, "Drag") - rb2.SetValue(false) + rb2.SetValue(False) text2 = wxStaticText(self, -1, "The lower window is accepting a\n" @@ -249,7 +250,7 @@ class CustomDnDPanel(wxPanel): sizer.Add(dndsizer, 1, wxEXPAND) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) # Events @@ -269,12 +270,12 @@ class TestPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) sizer = wxBoxSizer(wxVERTICAL) msg = "Custom Drag-And-Drop" text = wxStaticText(self, -1, "", style=wxALIGN_CENTRE) - text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, false)) + text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, False)) text.SetLabel(msg) w,h = text.GetTextExtent(msg) text.SetSize(wxSize(w,h+1)) @@ -303,8 +304,9 @@ if __name__ == '__main__': class TestApp(wxApp): def OnInit(self): + wxInitAllImageHandlers() self.MakeFrame() - return true + return True def MakeFrame(self, event=None): frame = wxFrame(None, -1, "Custom Drag and Drop", size=(550,400)) @@ -315,7 +317,7 @@ if __name__ == '__main__': frame.SetMenuBar(mb) EVT_MENU(frame, 6543, self.MakeFrame) panel = TestPanel(frame, DummyLog()) - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) @@ -326,21 +328,20 @@ if __name__ == '__main__': #---------------------------------------------------------------------- +overview = """ +This demo shows Drag and Drop using a custom data type and a custom +data object. A type called "DoodleLines" is created and a Python +Pickle of a list is actually transfered in the drag and drop +opperation. +A second data object is also created containing a bitmap of the image +and is made available to any drop target that accepts bitmaps, such as +MS Word. +The two data objects are combined in a wxDataObjectComposite and the +rest is handled by the framework. + +""" - - - - - -overview = """\ -This demo shows Drag and Drop using a custom data type and a custom data object. A type called "DoodleLines" is created and a Python Pickle of a list is actually transfered in the drag and drop opperation. - -A second data object is also created containing a bitmap of the image and is made available to any drop target that accepts bitmaps, such as MS Word. - -The two data objects are combined in a wxDataObjectComposite and the rest is handled by the framework. -""" - diff --git a/wxPython/demo/DialogUnits.py b/wxPython/demo/DialogUnits.py index eca857897a..78974eb676 100644 --- a/wxPython/demo/DialogUnits.py +++ b/wxPython/demo/DialogUnits.py @@ -88,13 +88,13 @@ if __name__ == "__main__": # Create an instance of our customized Frame class frame = MyFrame(None, -1, "This is a test") - frame.Show(true) + frame.Show(True) # Tell wxWindows that this is our main window self.SetTopWindow(frame) # Return a success flag - return true + return True app = MyApp(0) # Create an instance of the application class @@ -107,7 +107,7 @@ if __name__ == "__main__": def runTest(frame, nb, log): win = MyFrame(frame, -1, "This is a test") frame.otherWin = win - win.Show(true) + win.Show(True) overview = """\ diff --git a/wxPython/demo/DragAndDrop.py b/wxPython/demo/DragAndDrop.py index da17b09299..e99abc3660 100644 --- a/wxPython/demo/DragAndDrop.py +++ b/wxPython/demo/DragAndDrop.py @@ -8,7 +8,7 @@ class ClipTextPanel(wxPanel): wxPanel.__init__(self, parent, -1) self.log = log - #self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, false)) + #self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, False)) sizer = wxBoxSizer(wxVERTICAL) sizer.Add(wxStaticText(self, -1, @@ -28,7 +28,7 @@ class ClipTextPanel(wxPanel): EVT_BUTTON(self, 6051, self.OnPaste) EVT_BUTTON(self, 6052, self.OnCopyBitmap) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) @@ -86,7 +86,7 @@ class OtherDropTarget(wxPyDropTarget): def OnDrop(self, x, y): self.log.WriteText("OnDrop: %d %d\n" % (x, y)) - return true + return True def OnData(self, x, y, d): self.log.WriteText("OnData: %d, %d, %d\n" % (x, y, d)) @@ -128,7 +128,7 @@ class FileDropPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) - #self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, false)) + #self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, False)) sizer = wxBoxSizer(wxVERTICAL) sizer.Add(wxStaticText(self, -1, " \nDrag some files here:"), @@ -148,7 +148,7 @@ class FileDropPanel(wxPanel): self.text2.SetDropTarget(dt) sizer.Add(self.text2, 1, wxEXPAND) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) @@ -166,12 +166,12 @@ class TestPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) outsideSizer = wxBoxSizer(wxVERTICAL) msg = "Clipboard / Drag-And-Drop" text = wxStaticText(self, -1, "", style=wxALIGN_CENTRE) - text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, false)) + text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, False)) text.SetLabel(msg) w,h = text.GetTextExtent(msg) text.SetSize(wxSize(w,h+1)) diff --git a/wxPython/demo/DrawXXXList.py b/wxPython/demo/DrawXXXList.py index 1783ef76e9..776201aa1a 100644 --- a/wxPython/demo/DrawXXXList.py +++ b/wxPython/demo/DrawXXXList.py @@ -46,6 +46,43 @@ def makeRandomLines(num, w, h): return pnts +def makeRandomRectangles(num, W, H): + rects = [] + for i in range(num): + w = whrandom.randint(10, W/2) + h = whrandom.randint(10, H/2) + x = whrandom.randint(0, W - w) + y = whrandom.randint(0, H - h) + rects.append( (x, y, w, h) ) + return rects + + +def makeRandomText(num): + Np = 8 # number of charcters in text + text = [] + for i in range(num): + word = [] + for i in range(Np): + c = chr( whrandom.randint(48, 122) ) + word.append( c ) + text.append( "".join(word) ) + return text + + +def makeRandomPolygons(num, W, H): + Np = 8 # number of points per polygon + polys = [] + for i in range(num): + poly = [] + for i in range(Np): + x = whrandom.randint(0, W) + y = whrandom.randint(0, H) + poly.append( (x,y) ) + polys.append( poly ) + return polys + + + def makeRandomPens(num, cache): pens = [] for i in range(num): @@ -57,62 +94,278 @@ def makeRandomPens(num, cache): return pens -class TestPanel(wxPanel): - def __init__(self, parent, size, log): - wxPanel.__init__(self, parent, -1, size=size) - self.log = log - self.SetBackgroundColour(wxWHITE) +def makeRandomBrushes(num, cache): + brushes = [] + for i in range(num): + c = whrandom.choice(colours) + if not cache.has_key(c): + cache[c] = wxBrush(c) + brushes.append( cache[c] ) + return brushes - w = size.width - h = size.height - pencache = {} - # make some lists of random points - self.pnts1 = makeRandomPoints(1000, w, h) - self.pnts2 = makeRandomPoints(1000, w, h) - self.pnts3 = makeRandomPoints(1000, w, h) - self.pens1 = makeRandomPens(1000, pencache) +def makeRandomColors(num): + colors = [] + for i in range(num): + c = whrandom.choice(colours) + colors.append(wxNamedColor(c)) + return colors - # and now some lines - self.lines1 = makeRandomLines(500, w, h) - self.lines2 = makeRandomLines(500, w, h) - self.lines3 = makeRandomLines(500, w, h) - self.pens2 = makeRandomPens(500, pencache) - EVT_PAINT(self, self.OnPaint) +pencache = {} +brushcache = {} +points = None +lines = None +rectangles = None +polygons = None +text = None +pens = None +brushes = None +colors1 = None +colors2 = None + + +def Init(w, h, n): + global pencache + global brushcache + global points + global lines + global rectangles + global polygons + global text + global pens + global brushes + global colors1 + global colors2 + + # make some lists of random shapes + points = makeRandomPoints(n, w, h) + try: + import Numeric + Apoints = Numeric.array(points) + except: + pass + lines = makeRandomLines(n, w, h) + rectangles = makeRandomRectangles(n, w, h) + polygons = makeRandomPolygons(n, w, h) + text = makeRandomText(n) + + # make some random pens and brushes + pens = makeRandomPens(n, pencache) + brushes = makeRandomBrushes(n, brushcache) + # make some random color lists + colors1 = makeRandomColors(n) + colors2 = makeRandomColors(n) + + + +def TestPoints(dc,log): + dc.BeginDrawing() + start = time.time() + dc.SetPen(wxPen("BLACK", 4)) + + dc.DrawPointList(points) + dc.DrawPointList(points, wxPen("RED", 2)) + dc.DrawPointList(points, pens) + + dc.EndDrawing() + log.write("DrawTime: %s seconds with DrawPointList\n" % (time.time() - start)) + + +def TestArrayPoints(dc,log): + try: + import Numeric - def OnPaint(self, evt): - dc = wxPaintDC(self) dc.BeginDrawing() start = time.time() - dc.SetPen(wxPen("BLACK", 1)) - dc.DrawPointList(self.pnts1) - dc.DrawPointList(self.pnts2, wxPen("RED", 2)) - dc.DrawPointList(self.pnts3, self.pens1) + for i in range(1): + dc.DrawPointList(Apoints) + #dc.DrawPointList(Apoints, wxPen("RED", 2)) + #dc.DrawPointList(Apoints, pens) + dc.EndDrawing() + log.write("DrawTime: %s seconds with DrawPointList an Numpy Array\n" % (time.time() - start)) + except ImportError: + log.write("Couldn't import Numeric") + pass + + +def TestLines(dc,log): + dc.BeginDrawing() + start = time.time() + + dc.SetPen(wxPen("BLACK", 2)) + dc.DrawLineList(lines) + dc.DrawLineList(lines, wxPen("RED", 2)) + dc.DrawLineList(lines, pens) + + dc.EndDrawing() + log.write("DrawTime: %s seconds with DrawLineList\n" % (time.time() - start)) + + +def TestRectangles(dc,log): + dc.BeginDrawing() + start = time.time() + + dc.SetPen( wxPen("BLACK",1) ) + dc.SetBrush( wxBrush("RED") ) + dc.DrawRectangleList(rectangles) + dc.DrawRectangleList(rectangles,pens) + dc.DrawRectangleList(rectangles,pens[0],brushes) + dc.DrawRectangleList(rectangles,pens,brushes[0]) + dc.DrawRectangleList(rectangles,None,brushes) +## for i in range(10): +## #dc.DrawRectangleList(rectangles,pens,brushes) +## dc.DrawRectangleList(rectangles) + + dc.EndDrawing() + log.write("DrawTime: %s seconds with DrawRectanglesList\n" % (time.time() - start)) + + +def TestEllipses(dc,log): + dc.BeginDrawing() + start = time.time() + + dc.SetPen( wxPen("BLACK",1) ) + dc.SetBrush( wxBrush("RED") ) + + dc.DrawEllipseList(rectangles) + dc.DrawEllipseList(rectangles,pens) + dc.DrawEllipseList(rectangles,pens[0],brushes) + dc.DrawEllipseList(rectangles,pens,brushes[0]) + dc.DrawEllipseList(rectangles,None,brushes) + dc.DrawEllipseList(rectangles,pens,brushes) + + dc.EndDrawing() + log.write("DrawTime: %s seconds with DrawEllipsesList\n" % (time.time() - start)) + + +def TestRectanglesArray(dc,log): + try: + import Numeric + Apoints = Numeric.array(rectangles) + + dc.BeginDrawing() + start = time.time() dc.SetPen(wxPen("BLACK", 1)) - dc.DrawLineList(self.lines1) - dc.DrawLineList(self.lines2, wxPen("RED", 2)) - dc.DrawLineList(self.lines3, self.pens2) + dc.DrawRectangleList(rectangles) + dc.DrawRectangleList(rectangles,pens) + dc.DrawRectangleList(rectangles,pens[0],brushes) + dc.DrawRectangleList(rectangles,pens,brushes[0]) + dc.DrawRectangleList(rectangles,None,brushes) +## for i in range(10): +## #dc.DrawRectangleList(rectangles,pens,brushes) +## dc.DrawRectangleList(rectangles) dc.EndDrawing() - self.log.write("DrawTime: %s seconds\n" % (time.time() - start)) - self.log.write("GetBoundingBox: %s\n" % (dc.GetBoundingBox(), )) + log.write("DrawTime: %s seconds with DrawRectangleList and Numpy Array\n" % (time.time() - start)) + except ImportError: + log.write("Couldn't import Numeric") + pass + + +def TestRectanglesLoop(dc,log): + dc.BeginDrawing() + + start = time.time() + dc.DrawRectangleList(rectangles,pens,brushes) + log.write("DrawTime: %s seconds with DrawRectanglesList\n" % (time.time() - start)) + + start = time.time() + for i in range(len(rectangles)): + dc.SetPen( pens[i] ) + dc.SetBrush( brushes[i] ) + dc.DrawRectangle(rectangles[i][0],rectangles[i][1],rectangles[i][2],rectangles[i][3]) + dc.EndDrawing() + log.write("DrawTime: %s seconds with Python loop\n" % (time.time() - start)) + + +def TestPolygons(dc,log): + dc.BeginDrawing() + + start = time.time() + dc.SetPen(wxPen("BLACK", 1)) + dc.DrawPolygonList(polygons) + dc.DrawPolygonList(polygons,pens) + dc.DrawPolygonList(polygons,pens[0],brushes) + dc.DrawPolygonList(polygons,pens,brushes[0]) + dc.DrawPolygonList(polygons,None,brushes) + log.write("DrawTime: %s seconds with DrawPolygonList\n" % (time.time() - start)) + + dc.EndDrawing() + + +def TestText(dc,log): + dc.BeginDrawing() + + start = time.time() + + # NOTE: you need to set BackgroundMode for the background colors to be used. + dc.SetBackgroundMode(wxSOLID) + foreground = colors1 + background = colors2 + dc.DrawTextList(text, points, foreground, background) + + log.write("DrawTime: %s seconds with DrawTextList\n" % (time.time() - start)) + + dc.EndDrawing() + + + +class TestNB(wxNotebook): + def __init__(self, parent, id, log): + style = wxNB_BOTTOM + if wxPlatform == "__WXMAC__": + style = 0 + wxNotebook.__init__(self, parent, id, style=style) + self.log = log + + win = DrawPanel(self, TestEllipses, log) + self.AddPage(win, 'Ellipses') + + win = DrawPanel(self, TestText, log) + self.AddPage(win, 'Text') + + win = DrawPanel(self, TestPolygons, log) + self.AddPage(win, 'Polygons') + + win = DrawPanel(self, TestPoints, log) + self.AddPage(win, 'Points') + + win = DrawPanel(self, TestLines, log) + self.AddPage(win, 'Lines') + + win = DrawPanel(self, TestRectangles, log) + self.AddPage(win, 'Rectangles') + + +class DrawPanel(wxPanel): + def __init__(self, parent, drawFun, log): + wxPanel.__init__(self, parent, -1) + self.SetBackgroundColour(wxWHITE) + + self.log = log + self.drawFun = drawFun + EVT_PAINT(self, self.OnPaint) + + + def OnPaint(self, evt): + dc = wxPaintDC(self) + dc.Clear() + self.drawFun(dc,self.log) + #---------------------------------------------------------------------- def runTest(frame, nb, log): w = nb.GetClientSize().width h = nb.GetClientSize().height - if w < 300: w = 300 - if h < 300: h = 300 - win = wxPanel(nb, -1) - tp = TestPanel(win, wxSize(w, h), log) - def OnPanelSize(evt, tp=tp): - tp.SetSize(evt.GetSize()) - EVT_SIZE(win, OnPanelSize) + if w < 600: w = 600 + if h < 400: h = 400 + Init(w, h, 200) + win = TestNB(nb, -1, log) return win #---------------------------------------------------------------------- @@ -136,4 +389,30 @@ drawing routines. Currently they are: (x1,y1, x2,y2) andd pens is either None, a single pen or a list of pens. +
+    DrawRectangleList(rectangles, pens=None, brushes=None)
+
+ + +
+    DrawEllipseList(ellipses, pens=None, brushes=None)
+
+ + +
+    DrawPolygonList(polygons, pens=None, brushes=None)
+
+ + +
+    DrawTextList(textList, coords, foregrounds = None, backgrounds = None)
+
+ """ + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/ErrorDialogs.py b/wxPython/demo/ErrorDialogs.py index 18076f8bc1..db24853b82 100644 --- a/wxPython/demo/ErrorDialogs.py +++ b/wxPython/demo/ErrorDialogs.py @@ -14,14 +14,14 @@ ID_BUTTON_wxPyNonFatalErrorDialog = 10004 ID_BUTTON_wxPyFatalErrorDialogWithTraceback = 10005 ID_BUTTON_wxPyNonFatalErrorDialogWithTraceback = 10006 -def ErrorDialogsDemoPanelFunc( parent, call_fit = true, set_sizer = true ): +def ErrorDialogsDemoPanelFunc( parent, call_fit = True, set_sizer = True ): item0 = wxBoxSizer( wxVERTICAL ) - + item1 = wxStaticText( parent, ID_TEXT, "Please select one of the buttons below for an example using explicit errors...", wxDefaultPosition, wxDefaultSize, 0 ) item0.AddWindow( item1, 0, wxALIGN_CENTRE|wxALL, 5 ) item2 = wxFlexGridSizer( 0, 2, 0, 0 ) - + item3 = wxButton( parent, ID_BUTTON_wxPyNonFatalError, "wxPyNonFatalError", wxDefaultPosition, wxDefaultSize, 0 ) item2.AddWindow( item3, 0, wxALIGN_CENTRE|wxALL, 5 ) @@ -34,7 +34,7 @@ def ErrorDialogsDemoPanelFunc( parent, call_fit = true, set_sizer = true ): item0.AddWindow( item5, 0, wxALIGN_CENTRE|wxALL, 5 ) item6 = wxFlexGridSizer( 0, 2, 0, 0 ) - + item7 = wxButton( parent, ID_BUTTON_wxPyFatalErrorDialog, "wxPyFatalErrorDialog", wxDefaultPosition, wxDefaultSize, 0 ) item6.AddWindow( item7, 0, wxALIGN_CENTRE|wxALL, 5 ) @@ -51,16 +51,16 @@ def ErrorDialogsDemoPanelFunc( parent, call_fit = true, set_sizer = true ): item0.AddSizer( item6, 0, wxALIGN_CENTRE|wxALL, 5 ) item11 = wxFlexGridSizer( 0, 2, 0, 0 ) - + item0.AddSizer( item11, 0, wxALIGN_CENTRE|wxALL, 5 ) - if set_sizer == true: - parent.SetAutoLayout( true ) + if set_sizer == True: + parent.SetAutoLayout( True ) parent.SetSizer( item0 ) - if call_fit == true: + if call_fit == True: item0.Fit( parent ) item0.SetSizeHints( parent ) - + return item0 # Menu bar functions @@ -105,8 +105,8 @@ class MyPanel(wxPanel): EVT_BUTTON(self, ID_BUTTON_wxPyNonFatalErrorDialogWithTraceback, self.DoDialog) - EVT_CLOSE(self,self.OnClose) - + + IndexFromID = { ID_BUTTON_wxPyFatalErrorDialog: 3, ID_BUTTON_wxPyFatalErrorDialogWithTraceback: 2, @@ -138,10 +138,11 @@ class MyPanel(wxPanel): print "%s.DoDialog(): testing %s..." % (self,sys.stderr) this_will_generate_a_NameError_exception - def OnClose(self,evt): + def ShutdownDemo(self): for d in self.dialogs: - d.Destroy () - self.Destroy () + d.Destroy() + + class MyFrame(wxFrame): def __init__(self,parent=None): @@ -158,9 +159,9 @@ class MyFrame(wxFrame): class MyApp(wxApp): def OnInit(self): frame = MyFrame() - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True def runTest(pframe, nb, log): panel = MyPanel(nb) diff --git a/wxPython/demo/EventManager.py b/wxPython/demo/EventManager.py new file mode 100644 index 0000000000..2966b930ff --- /dev/null +++ b/wxPython/demo/EventManager.py @@ -0,0 +1,287 @@ +#--------------------------------------------------------------------------- +# Name: EventManager.py +# Purpose: A module to demonstrate wxPython.lib.evtmgr.EventManager. +# +# Author: Robb Shecter (robb@acm.org) +# +# Created: 16-December-2002 +# Copyright: (c) 2002 by Robb Shecter (robb@acm.org) +# Licence: wxWindows license +#--------------------------------------------------------------------------- + +from wxPython.wx import * +from wxPython.lib.evtmgr import eventManager + +#---------------------------------------------------------------------- + +class TestPanel(wxPanel): + def __init__(self, parent, log): + wxPanel.__init__(self, parent, -1) + self.log = log + + fsize = self.GetFont().GetPointSize() + f1 = wxFont(fsize+0, wxSWISS, wxNORMAL, wxNORMAL) + f2 = wxFont(fsize+2, wxSWISS, wxNORMAL, wxBOLD) + f3 = wxFont(fsize+6, wxSWISS, wxNORMAL, wxBOLD) + + title1 = wxStaticText(self, -1, 'EventManager') + title1.SetFont(f3) + txt = """\ + This demo shows (1) basic uses and features of the EventManager, as well + as (2) how it helps with a real-world task: creating independent, object- + oriented components.""" + message0 = wxStaticText(self, -1, txt) + message0.SetFont(f1) + + title2 = wxStaticText(self, -1, 'Event Listeners') + title2.SetFont(f2) + + txt = """\ + These objects listen to motion events from the target window, using the ability + to register one event with multiple listeners. They also register for mouse events + on themselves to implement toggle-button functionality.""" + message1 = wxStaticText(self, -1, txt) + message1.SetFont(f1) + + title3 = wxStaticText(self, -1, 'Target Window') + title3.SetFont(f2) + + txt = """\ + A passive window that's used as an event generator. Move the mouse over it to + send events to the listeners above.""" + message2 = wxStaticText(self, -1, txt) + message2.SetFont(f1) + + targetPanel = Tile(self, log, bgColor=wxColor(80,10,10), active=0) + buttonPanel = wxPanel(self ,-1) + sizer = wxBoxSizer(wxHORIZONTAL) + target = targetPanel.tile + + sizer.Add(0,0,1) + for factor in [0.2, 0.3, 0.4, 0.5, 0.6, 0.7]: + sizer.Add(Tile(buttonPanel, log, factor-0.05, target), 0, wxALIGN_CENTER) + sizer.Add(0,0,1) + sizer.Add(Tile(buttonPanel, log, factor, target), 0, wxALIGN_CENTER) + sizer.Add(0,0,1) + + buttonPanel.SetAutoLayout(1) + buttonPanel.SetSizer(sizer) + sizer.Fit(buttonPanel) + + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(title1, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, 6) + sizer.Add(message0, 0, wxALIGN_CENTER | wxALL, 6) + sizer.Add(title2, 0, wxALIGN_CENTER | wxLEFT | wxTOP | wxRIGHT, 16) + sizer.Add(message1, 0, wxALIGN_CENTER | wxALL, 6) + sizer.Add(buttonPanel, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 16) + sizer.Add(title3, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 16) + sizer.Add(message2, 0, wxALIGN_CENTER | wxALL, 6) + sizer.Add(targetPanel, 2, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 16) + self.SetAutoLayout(1) + self.SetSizer(sizer) + + + +class Tile(wxPanel): + """ + This outer class is responsible for changing + its border color in response to certain mouse + events over its contained 'InnerTile'. + """ + normal = wxColor(150,150,150) + active = wxColor(250,245,245) + hover = wxColor(210,220,210) + + def __init__(self, parent, log, factor=1, thingToWatch=None, bgColor=None, active=1, size=(38,38), borderWidth=3): + wxPanel.__init__(self, parent, -1, size=size, style=wxCLIP_CHILDREN) + self.tile = InnerTile(self, log, factor, thingToWatch, bgColor) + self.log = log + sizer = wxBoxSizer(wxHORIZONTAL) + sizer.Add(self.tile, 1, wxEXPAND | wxALL, borderWidth) + self.SetAutoLayout(1) + self.SetSizer(sizer) + self.Layout() + self.SetBackgroundColour(Tile.normal) + if active: + # Register myself for mouse events over self.tile in order to + # create typical button/hyperlink visual effects. + eventManager.Register(self.setHover, EVT_ENTER_WINDOW, self.tile) + eventManager.Register(self.setNormal, EVT_LEAVE_WINDOW, self.tile) + eventManager.Register(self.setActive, EVT_LEFT_DOWN, self.tile) + eventManager.Register(self.setHover, EVT_LEFT_UP, self.tile) + + + def setHover(self, event): + self.SetBackgroundColour(Tile.hover) + self.Refresh() + + + def setActive(self, event): + self.SetBackgroundColour(Tile.active) + self.Refresh() + + + def setNormal(self, event): + self.SetBackgroundColour(Tile.normal) + self.Refresh() + + + +class InnerTile(wxPanel): + IDLE_COLOR = wxColor( 80, 10, 10) + START_COLOR = wxColor(200, 70, 50) + FINAL_COLOR = wxColor( 20, 80,240) + OFF_COLOR = wxColor(185,190,185) + # Some pre-computation. + DELTAS = map(lambda a,b: b-a, START_COLOR.Get(), FINAL_COLOR.Get()) + START_COLOR_TUPLE = START_COLOR.Get() + + """ + This inner panel changes its color in reaction to mouse + events over the 'thingToWatch'. + """ + def __init__(self, parent, log, factor, thingToWatch=None, bgColor=None): + wxPanel.__init__(self, parent, -1) + self.log=log + if bgColor: + self.SetBackgroundColour(bgColor) + if thingToWatch: + self.factor = factor + self.thingToWatch = thingToWatch + self.state = 0 + self.toggleOnOff() + # Watch for the mouse click to enable/disable myself. + eventManager.Register(self.toggleOnOff, EVT_LEFT_UP, self) + + + def toggleOnOff(self, event=None): + # Implement being on or off by registering and + # de-registering self.makeColor() from the event manager. + if self.state: + eventManager.DeregisterListener(self.makeColor) + else: + eventManager.Register(self.makeColor, EVT_MOTION, self.thingToWatch) + self.state = 1 - self.state + self.resetColor() + + + def resetColor(self, event=None): + if self.state: + self.setColor(InnerTile.IDLE_COLOR) + else: + self.setColor(InnerTile.OFF_COLOR) + + + def setColor(self, color): + self.SetBackgroundColour(color) + self.Refresh() + + + def makeColor(self, mouseEvent): + self.makeColorFromTuple(mouseEvent.GetPositionTuple()) + + + def makeColorFromTuple(self, (x, y)): + MAX = 180.0 + scaled = min((x + y) * self.factor, MAX) # In range [0..MAX] + percent = scaled / MAX + r = InnerTile.START_COLOR_TUPLE[0] + (InnerTile.DELTAS[0] * percent) + g = InnerTile.START_COLOR_TUPLE[1] + (InnerTile.DELTAS[1] * percent) + b = InnerTile.START_COLOR_TUPLE[2] + (InnerTile.DELTAS[2] * percent) + self.setColor(wxColor(r,g,b)) + + + + +#---------------------------------------------------------------------- + +def runTest(frame, nb, log): + win = TestPanel(nb, log) + return win + +#---------------------------------------------------------------------- + + + +overview = """ +

EventManager

+ +

The goal of the EventManager is to make wxWindows events more +'Pythonic' (ie. object-oriented) and easier to work with, without +impacting performance. It offers these features: + +

+

    + +
  • Allows any number of listeners to register for a single + event. (In addition to the standard wxPython feature of a single + listener being able to respond to many events.) + +
  • Makes it easy to disconnect and reconnect listeners. This + has the effect of reducing the need for case-based branching in + application code. + +
  • Has an object-oriented API. Programmers register to get + events directly from the objects that generate them, instead of + using ID numbers. + +
+ +

Usage

+ +

The EventManager class has three public methods. First get a +reference to it: + +

+  from wxPython.lib.evtmgr import eventManager
+
+ +

...and then invoke any of the following methods. These methods are +'safe'; duplicate registrations or de-registrations will have no +effect. + +

Registering a listener: + +

+  eventManager.Register(listener, event, event-source)
+
+ + +

De-registering by window: + +

+  eventManager.DeregisterWindow(event-source)
+
+ + +

De-registering by listener: + +

+  eventManager.DeregisterListener(listener)
+
+ +

Simple Example: + +

+  from wxPython.lib.evtmgr import eventManager
+
+  aButton = wxButton(somePanel, -1, 'Click me')
+  eventManager.Register(self.someMethod, EVT_BUTTON, aButton)
+
+ +

See the demo code as well as the documentation in the source of +wxPython.lib.evtmgr for more details. + + +

+by Robb Shecter (robb@acm.org) + +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/FancyText.py b/wxPython/demo/FancyText.py index edda6ce178..f504ccc21c 100644 --- a/wxPython/demo/FancyText.py +++ b/wxPython/demo/FancyText.py @@ -36,6 +36,5 @@ def runTest(frame, nb, log): -import string -overview = string.replace(fancytext.__doc__, "<", "<") +overview = fancytext.__doc__.replace("<", "<") diff --git a/wxPython/demo/FontEnumerator.py b/wxPython/demo/FontEnumerator.py index 27a1466d94..67b5f6ef10 100644 --- a/wxPython/demo/FontEnumerator.py +++ b/wxPython/demo/FontEnumerator.py @@ -3,44 +3,40 @@ from wxPython.wx import * #---------------------------------------------------------------------- -## class MyFontEnumerator(wxFontEnumerator): -## def __init__(self, list): -## wxFontEnumerator.__init__(self) -## self.list = list - -## def OnFacename(self, face): -## self.list.append(face) -## return true - - class TestPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) -## list = [] -## e = MyFontEnumerator(list) -## e.EnumerateFacenames() - e = wxFontEnumerator() e.EnumerateFacenames() list = e.GetFacenames() list.sort() - wxStaticText(self, -1, "Face names:", (15, 50), (65, 18)) - self.lb1 = wxListBox(self, -1, (80, 50), (200, 250), + s1 = wxStaticText(self, -1, "Face names:") + self.lb1 = wxListBox(self, -1, wxDefaultPosition, (200, 250), list, wxLB_SINGLE) EVT_LISTBOX(self, self.lb1.GetId(), self.OnSelect) self.txt = wxStaticText(self, -1, "Sample text...", (285, 50)) + row = wxBoxSizer(wxHORIZONTAL) + row.Add(s1, 0, wxALL, 5) + row.Add(self.lb1, 0, wxALL, 5) + row.Add(self.txt, 0, wxALL, 5) + + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(row, 0, wxALL, 30) + self.SetSizer(sizer) + self.Layout() + self.lb1.SetSelection(0) def OnSelect(self, evt): face = self.lb1.GetStringSelection() - font = wxFont(28, wxDEFAULT, wxNORMAL, wxNORMAL, false, face) + font = wxFont(28, wxDEFAULT, wxNORMAL, wxNORMAL, False, face) self.txt.SetFont(font) self.txt.SetSize(self.txt.GetBestSize()) @@ -64,9 +60,12 @@ def runTest(frame, nb, log): -overview = """\ -wxFontEnumerator enumerates either all available fonts on the system or only the ones with given attributes - either only fixed-width (suited for use in programs such as terminal emulators and the like) or the fonts available in the given encoding. - +overview = """ +wxFontEnumerator enumerates either all available fonts on the system or only +the ones with given attributes - either only fixed-width (suited for use in +programs such as terminal emulators and the like) or the fonts available in +the given encoding. + """ diff --git a/wxPython/demo/GenericButtons.py b/wxPython/demo/GenericButtons.py index ad30e9752c..c3e7ff4039 100644 --- a/wxPython/demo/GenericButtons.py +++ b/wxPython/demo/GenericButtons.py @@ -28,12 +28,12 @@ class TestPanel(wxPanel): b = wxGenButton(self, -1, 'disabled') EVT_BUTTON(self, b.GetId(), self.OnButton) - b.Enable(false) + b.Enable(False) sizer.Add(b) b = wxGenButton(self, -1, 'bigger') EVT_BUTTON(self, b.GetId(), self.OnBiggerButton) - b.SetFont(wxFont(20, wxSWISS, wxNORMAL, wxBOLD, false)) + b.SetFont(wxFont(20, wxSWISS, wxNORMAL, wxBOLD, False)) b.SetBezelWidth(5) ###b.SetBestSize() b.SetBackgroundColour("Navy") @@ -46,6 +46,12 @@ class TestPanel(wxPanel): EVT_BUTTON(self, b.GetId(), self.OnButton) sizer.Add(b) + bmp = images.getTest2Bitmap() + b = wxGenBitmapButton(self, -1, bmp) + EVT_BUTTON(self, b.GetId(), self.OnButton) + sizer.Add(b) + b.Enable(False) + b = wxGenBitmapButton(self, -1, None) EVT_BUTTON(self, b.GetId(), self.OnButton) bmp = images.getBulb1Bitmap() @@ -58,7 +64,6 @@ class TestPanel(wxPanel): b.SetBitmapSelected(bmp) b.SetBestSize() sizer.Add(b) - sizer.Add(10,10) b = wxGenToggleButton(self, -1, "Toggle Button") EVT_BUTTON(self, b.GetId(), self.OnToggleButton) @@ -74,7 +79,7 @@ class TestPanel(wxPanel): mask = wxMaskColour(bmp, wxBLUE) bmp.SetMask(mask) b.SetBitmapSelected(bmp) - b.SetToggle(true) + b.SetToggle(True) b.SetBestSize() sizer.Add(b) @@ -88,7 +93,7 @@ class TestPanel(wxPanel): mask = wxMaskColour(bmp, wxBLUE) bmp.SetMask(mask) b.SetBitmapSelected(bmp) - b.SetUseFocusIndicator(false) + b.SetUseFocusIndicator(False) b.SetBestSize() sizer.Add(b) @@ -128,3 +133,11 @@ def runTest(frame, nb, log): import wxPython.lib.buttons overview = wxPython.lib.buttons.__doc__ + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/GridCustEditor.py b/wxPython/demo/GridCustEditor.py index 27bba1562d..50101e4b60 100644 --- a/wxPython/demo/GridCustEditor.py +++ b/wxPython/demo/GridCustEditor.py @@ -2,6 +2,7 @@ from wxPython.wx import * from wxPython.grid import * +import string #--------------------------------------------------------------------------- class MyCellEditor(wxPyGridCellEditor): """ @@ -86,16 +87,16 @@ class MyCellEditor(wxPyGridCellEditor): def EndEdit(self, row, col, grid): """ - Complete the editing of the current cell. Returns true if the value + Complete the editing of the current cell. Returns True if the value has changed. If necessary, the control may be destroyed. *Must Override* """ self.log.write("MyCellEditor: EndEdit (%d,%d)\n" % (row, col)) - changed = false + changed = False val = self._tc.GetValue() if val != self.startValue: - changed = true + changed = True grid.GetTable().SetValue(row, col, val) # update the table self.startValue = '' @@ -115,7 +116,7 @@ class MyCellEditor(wxPyGridCellEditor): def IsAcceptedKey(self, evt): """ - Return TRUE to allow the given key to start editing: the base class + Return True to allow the given key to start editing: the base class version only checks that the event has no modifiers. F2 is special and will always start the editor. """ @@ -143,12 +144,13 @@ class MyCellEditor(wxPyGridCellEditor): elif key < 256 and key >= 0 and chr(key) in string.printable: ch = chr(key) if not evt.ShiftDown(): - ch = string.lower(ch) + ch = ch.lower() if ch is not None: # For this example, replace the text. Normally we would append it. #self._tc.AppendText(ch) self._tc.SetValue(ch) + self._tc.SetInsertionPointEnd() else: evt.Skip() @@ -226,7 +228,7 @@ if __name__ == '__main__': import sys app = wxPySimpleApp() frame = TestFrame(None, sys.stdout) - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/GridCustTable.py b/wxPython/demo/GridCustTable.py index ff78201fcb..3d4b6b3011 100644 --- a/wxPython/demo/GridCustTable.py +++ b/wxPython/demo/GridCustTable.py @@ -1,8 +1,6 @@ from wxPython.wx import * from wxPython.grid import * -import string - #--------------------------------------------------------------------------- class CustomDataTable(wxPyGridTableBase): @@ -45,7 +43,10 @@ class CustomDataTable(wxPyGridTableBase): return len(self.data[0]) def IsEmptyCell(self, row, col): - return not self.data[row][col] + try: + return not self.data[row][col] + except IndexError: + return true # Get/Set values in the table. The Python version of these # methods can handle any data-type, (as long as the Editor and @@ -90,11 +91,11 @@ class CustomDataTable(wxPyGridTableBase): # editor and renderer. This allows you to enforce some type-safety # in the grid. def CanGetValueAs(self, row, col, typeName): - colType = string.split(self.dataTypes[col], ':')[0] + colType = self.dataTypes[col].split(':')[0] if typeName == colType: return true else: - return false + return False def CanSetValueAs(self, row, col, typeName): return self.CanGetValueAs(row, col, typeName) @@ -120,7 +121,7 @@ class CustTableGrid(wxGrid): self.SetRowLabelSize(0) self.SetMargins(0,0) - self.AutoSizeColumns(false) + self.AutoSizeColumns(False) EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick) @@ -138,8 +139,22 @@ class CustTableGrid(wxGrid): class TestFrame(wxFrame): def __init__(self, parent, log): wxFrame.__init__(self, parent, -1, "Custom Table, data driven Grid Demo", size=(640,480)) - grid = CustTableGrid(self, log) - + p = wxPanel(self, -1, style=0) + grid = CustTableGrid(p, log) + b = wxButton(p, -1, "Another Control...") + b.SetDefault() + EVT_BUTTON(self, b.GetId(), self.OnButton) + EVT_SET_FOCUS(b, self.OnButtonFocus) + bs = wxBoxSizer(wxVERTICAL) + bs.Add(grid, 1, wxGROW|wxALL, 5) + bs.Add(b) + p.SetSizer(bs) + + def OnButton(self, evt): + print "button selected" + + def OnButtonFocus(self, evt): + print "button focus" #--------------------------------------------------------------------------- diff --git a/wxPython/demo/GridDragable.py b/wxPython/demo/GridDragable.py new file mode 100644 index 0000000000..ea989c6116 --- /dev/null +++ b/wxPython/demo/GridDragable.py @@ -0,0 +1,193 @@ +from wxPython.wx import * +from wxPython.grid import * +from wxPython.lib.gridmovers import wxGridColMover, EVT_GRID_COL_MOVE +from wxPython.lib.gridmovers import wxGridRowMover, EVT_GRID_ROW_MOVE + +#--------------------------------------------------------------------------- + +class CustomDataTable(wxPyGridTableBase): + """ + """ + + def __init__(self, log): + wxPyGridTableBase.__init__(self) + self.log = log + + self.identifiers = ['id','ds','sv','pr','pl','op','fx','ts'] + + self.rowLabels = ['Row1','Row2','Row3'] + + self.colLabels = {'id':'ID','ds':'Description','sv':'Severity', + 'pr':'Priority','pl':'Platform','op':'Opened?', + 'fx':'Fixed?','ts':'Tested?'} + + self.data = [{'id':1010, + 'ds':"The foo doesn't bar", + 'sv':"major", + 'pr':1, + 'pl':'MSW', + 'op':1, + 'fx':1, + 'ts':1 + }, + {'id':1011, + 'ds':"I've got a wicket in my wocket", + 'sv':"wish list", + 'pr':2, + 'pl':'other', + 'op':0, + 'fx':0, + 'ts':0 + }, + {'id':1012, + 'ds':"Rectangle() returns a triangle", + 'sv':"critical", + 'pr':5, + 'pl':'all', + 'op':0, + 'fx':0, + 'ts':0 + } + ] + + #-------------------------------------------------- + # required methods for the wxPyGridTableBase interface + + def GetNumberRows(self): + return len(self.data) + + def GetNumberCols(self): + return len(self.identifiers) + + def IsEmptyCell(self, row, col): + id = self.identifiers[col] + return not self.data[row][id] + + def GetValue(self, row, col): + id = self.identifiers[col] + return self.data[row][id] + + def SetValue(self, row, col, value): + id = self.identifiers[col] + self.data[row][id] = value + + #-------------------------------------------------- + # Some optional methods + + # Called when the grid needs to display column labels + def GetColLabelValue(self, col): + id = self.identifiers[col] + return self.colLabels[id] + + # Called when the grid needs to display row labels + def GetRowLabelValue(self,row): + return self.rowLabels[row] + + #-------------------------------------------------- + # Methods added for demo purposes. + + # The physical moving of the cols/rows is left to the implementer. + # Because of the dynamic nature of a wxGrid the physical moving of + # columns differs from implementation to implementation + + # Move the column + def MoveColumn(self,frm,to): + grid = self.GetView() + if grid: + # Move the identifiers + old = self.identifiers[frm] + del self.identifiers[frm] + if to > frm: + self.identifiers.insert(to-1,old) + else: + self.identifiers.insert(to,old) + + # Notify the grid + grid.BeginBatch() + msg = wxGridTableMessage(self,wxGRIDTABLE_NOTIFY_COLS_DELETED, + frm,1) + grid.ProcessTableMessage(msg) + msg = wxGridTableMessage(self,wxGRIDTABLE_NOTIFY_COLS_INSERTED, + to,1) + grid.ProcessTableMessage(msg) + grid.EndBatch() + + # Move the row + def MoveRow(self,frm,to): + grid = self.GetView() + if grid: + # Move the rowLabels and data rows + oldLabel = self.rowLabels[frm] + oldData = self.data[frm] + del self.rowLabels[frm] + del self.data[frm] + if to > frm: + self.rowLabels.insert(to-1,oldLabel) + self.data.insert(to-1,oldData) + else: + self.rowLabels.insert(to,oldLabel) + self.data.insert(to,oldData) + + # Notify the grid + grid.BeginBatch() + msg = wxGridTableMessage(self,wxGRIDTABLE_NOTIFY_ROWS_DELETED, + frm,1) + grid.ProcessTableMessage(msg) + msg = wxGridTableMessage(self,wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + to,1) + grid.ProcessTableMessage(msg) + grid.EndBatch() + + +#--------------------------------------------------------------------------- + + +class DragableGrid(wxGrid): + def __init__(self, parent, log): + wxGrid.__init__(self, parent, -1) + + table = CustomDataTable(log) + + # The second parameter means that the grid is to take ownership of the + # table and will destroy it when done. Otherwise you would need to keep + # a reference to it and call it's Destroy method later. + self.SetTable(table, True) + + # Enable Column moving + wxGridColMover(self) + EVT_GRID_COL_MOVE(self,self.GetId(),self.OnColMove) + + # Enable Row moving + wxGridRowMover(self) + EVT_GRID_ROW_MOVE(self,self.GetId(),self.OnRowMove) + + # Event method called when a column move needs to take place + def OnColMove(self,evt): + frm = evt.GetMoveColumn() # Column being moved + to = evt.GetBeforeColumn() # Before which column to insert + self.GetTable().MoveColumn(frm,to) + + # Event method called when a row move needs to take place + def OnRowMove(self,evt): + frm = evt.GetMoveRow() # Row being moved + to = evt.GetBeforeRow() # Before which row to insert + self.GetTable().MoveRow(frm,to) + +#--------------------------------------------------------------------------- + +class TestFrame(wxFrame): + def __init__(self, parent, log): + wxFrame.__init__(self, parent, -1, "Custom Table, data driven Grid Demo", size=(640,480)) + grid = DragableGrid(self, log) + + +#--------------------------------------------------------------------------- + +if __name__ == '__main__': + import sys + app = wxPySimpleApp() + frame = TestFrame(None, sys.stdout) + frame.Show(True) + app.MainLoop() + +#--------------------------------------------------------------------------- diff --git a/wxPython/demo/GridEnterHandler.py b/wxPython/demo/GridEnterHandler.py index 719c622ef0..d6989fbcfe 100644 --- a/wxPython/demo/GridEnterHandler.py +++ b/wxPython/demo/GridEnterHandler.py @@ -55,7 +55,7 @@ if __name__ == '__main__': import sys app = wxPySimpleApp() frame = TestFrame(None, sys.stdout) - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/GridHugeTable.py b/wxPython/demo/GridHugeTable.py index 6c450ec5d7..a2084fb6e3 100644 --- a/wxPython/demo/GridHugeTable.py +++ b/wxPython/demo/GridHugeTable.py @@ -23,7 +23,7 @@ class HugeTable(wxPyGridTableBase): return 10000 def IsEmptyCell(self, row, col): - return false + return False def GetValue(self, row, col): return str( (row, col) ) @@ -45,7 +45,15 @@ class HugeTableGrid(wxGrid): # The second parameter means that the grid is to take ownership of the # table and will destroy it when done. Otherwise you would need to keep # a reference to it and call it's Destroy method later. - self.SetTable(table, true) + self.SetTable(table, True) + + EVT_GRID_CELL_RIGHT_CLICK(self, self.OnRightDown) #added + + def OnRightDown(self, event): #added + print "hello" + print self.GetSelectedRows() #added + + @@ -56,7 +64,7 @@ class TestFrame(wxFrame): wxFrame.__init__(self, parent, -1, "Huge (virtual) Table Demo", size=(640,480)) grid = HugeTableGrid(self, log) - grid.SetReadOnly(5,5, true) + grid.SetReadOnly(5,5, True) #--------------------------------------------------------------------------- @@ -64,7 +72,7 @@ if __name__ == '__main__': import sys app = wxPySimpleApp() frame = TestFrame(None, sys.stdout) - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/GridSimple.py b/wxPython/demo/GridSimple.py index 9857e22ae0..89c2ec6e07 100644 --- a/wxPython/demo/GridSimple.py +++ b/wxPython/demo/GridSimple.py @@ -13,8 +13,8 @@ class SimpleGrid(wxGrid): ##, wxGridAutoEditMixin): EVT_IDLE(self, self.OnIdle) - self.CreateGrid(25, 25) - ##self.EnableEditing(false) + self.CreateGrid(25, 25) #, wxGrid.wxGridSelectRows) + ##self.EnableEditing(False) # simple cell formatting self.SetColSize(3, 200) @@ -26,9 +26,9 @@ class SimpleGrid(wxGrid): ##, wxGridAutoEditMixin): self.SetCellFont(0, 0, wxFont(12, wxROMAN, wxITALIC, wxNORMAL)) self.SetCellTextColour(1, 1, wxRED) self.SetCellBackgroundColour(2, 2, wxCYAN) - self.SetReadOnly(3, 3, true) + self.SetReadOnly(3, 3, True) - self.SetCellEditor(5, 0, wxGridCellNumberEditor()) + self.SetCellEditor(5, 0, wxGridCellNumberEditor(1,1000)) self.SetCellValue(5, 0, "123") self.SetCellEditor(6, 0, wxGridCellFloatEditor()) self.SetCellValue(6, 0, "123.34") @@ -53,6 +53,18 @@ class SimpleGrid(wxGrid): ##, wxGridAutoEditMixin): self.SetColLabelAlignment(wxALIGN_LEFT, wxALIGN_BOTTOM) + #self.SetDefaultCellOverflow(False) + #r = wxGridCellAutoWrapStringRenderer() + #self.SetCellRenderer(9, 1, r) + + # overflow cells + self.SetCellValue( 9, 1, "This default cell will overflow into neighboring cells, but not if you turn overflow off."); + self.SetCellSize(11, 1, 3, 3); + self.SetCellAlignment(11, 1, wxALIGN_CENTRE, wxALIGN_CENTRE); + self.SetCellValue(11, 1, "This cell is set to span 3 rows and 3 columns"); + + + # test all the events EVT_GRID_CELL_LEFT_CLICK(self, self.OnCellLeftClick) EVT_GRID_CELL_RIGHT_CLICK(self, self.OnCellRightClick) @@ -216,7 +228,7 @@ if __name__ == '__main__': import sys app = wxPySimpleApp() frame = TestFrame(None, sys.stdout) - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/GridStdEdRend.py b/wxPython/demo/GridStdEdRend.py index b4a3db3c36..8e43b41729 100644 --- a/wxPython/demo/GridStdEdRend.py +++ b/wxPython/demo/GridStdEdRend.py @@ -1,7 +1,7 @@ from wxPython.wx import * from wxPython.grid import * -import string, random +import random #--------------------------------------------------------------------------- @@ -60,7 +60,7 @@ editorDemoData = [ ('wxGridCellBoolEditor', '1', wxGridCellBoolEditor, ()), ('wxGridCellChoiceEditor', 'one', wxGridCellChoiceEditor, (['one', 'two', 'three', 'four', 'kick', 'Microsoft', 'out the', - 'door'], false)), + 'door'], False)), ] @@ -139,15 +139,15 @@ Renderers used together. attr = wxGridCellAttr() attr.SetFont(font) attr.SetBackgroundColour(wxLIGHT_GREY) - attr.SetReadOnly(true) + attr.SetReadOnly(True) attr.SetAlignment(wxRIGHT, -1) self.SetColAttr(renCol, attr) attr.IncRef() self.SetColAttr(edCol, attr) # There is a bug in wxGTK for this method... - self.AutoSizeColumns(true) - self.AutoSizeRows(true) + self.AutoSizeColumns(True) + self.AutoSizeRows(True) EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick) @@ -174,7 +174,7 @@ if __name__ == '__main__': import sys app = wxPySimpleApp() frame = TestFrame(None, sys.stdout) - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/LayoutAnchors.py b/wxPython/demo/LayoutAnchors.py index b201372a7e..04b0c3f92c 100644 --- a/wxPython/demo/LayoutAnchors.py +++ b/wxPython/demo/LayoutAnchors.py @@ -21,38 +21,38 @@ class AnchorsDemoFrame(wxFrame): self._init_utils() self.mainPanel = wxPanel(size = wxSize(320, 160), parent = self, id = wxID_ANCHORSDEMOFRAMEMAINPANEL, name = 'panel1', style = wxTAB_TRAVERSAL | wxCLIP_CHILDREN, pos = wxPoint(0, 0)) - self.mainPanel.SetAutoLayout(true) + self.mainPanel.SetAutoLayout(True) self.okButton = wxButton(label = 'OK', id = wxID_ANCHORSDEMOFRAMEOKBUTTON, parent = self.mainPanel, name = 'okButton', size = wxSize(72, 24), style = 0, pos = wxPoint(240, 128)) - self.okButton.SetConstraints(LayoutAnchors(self.okButton, false, false, true, true)) + self.okButton.SetConstraints(LayoutAnchors(self.okButton, False, False, True, True)) EVT_BUTTON(self.okButton, wxID_ANCHORSDEMOFRAMEOKBUTTON, self.OnOkButtonButton) self.backgroundPanel = wxPanel(size = wxSize(304, 80), parent = self.mainPanel, id = wxID_ANCHORSDEMOFRAMEBACKGROUNDPANEL, name = 'backgroundPanel', style = wxSIMPLE_BORDER | wxCLIP_CHILDREN, pos = wxPoint(8, 40)) self.backgroundPanel.SetBackgroundColour(wxColour(255, 255, 255)) - self.backgroundPanel.SetConstraints(LayoutAnchors(self.backgroundPanel, true, true, true, true)) + self.backgroundPanel.SetConstraints(LayoutAnchors(self.backgroundPanel, True, True, True, True)) self.anchoredPanel = wxPanel(size = wxSize(88, 48), id = wxID_ANCHORSDEMOFRAMEANCHOREDPANEL, parent = self.backgroundPanel, name = 'anchoredPanel', style = wxSIMPLE_BORDER, pos = wxPoint(104, 16)) self.anchoredPanel.SetBackgroundColour(wxColour(0, 0, 222)) - self.anchoredPanel.SetConstraints(LayoutAnchors(self.anchoredPanel, false, false, false, false)) + self.anchoredPanel.SetConstraints(LayoutAnchors(self.anchoredPanel, False, False, False, False)) self.leftCheckBox = wxCheckBox(label = 'Left', id = wxID_ANCHORSDEMOFRAMELEFTCHECKBOX, parent = self.mainPanel, name = 'leftCheckBox', size = wxSize(40, 16), style = 0, pos = wxPoint(8, 8)) - self.leftCheckBox.SetConstraints(LayoutAnchors(self.leftCheckBox, false, true, false, false)) + self.leftCheckBox.SetConstraints(LayoutAnchors(self.leftCheckBox, False, True, False, False)) EVT_CHECKBOX(self.leftCheckBox, wxID_ANCHORSDEMOFRAMELEFTCHECKBOX, self.OnCheckboxCheckbox) self.topCheckBox = wxCheckBox(label = 'Top', id = wxID_ANCHORSDEMOFRAMETOPCHECKBOX, parent = self.mainPanel, name = 'topCheckBox', size = wxSize(40, 16), style = 0, pos = wxPoint(88, 8)) - self.topCheckBox.SetConstraints(LayoutAnchors(self.topCheckBox, false, true, false, false)) + self.topCheckBox.SetConstraints(LayoutAnchors(self.topCheckBox, False, True, False, False)) EVT_CHECKBOX(self.topCheckBox, wxID_ANCHORSDEMOFRAMETOPCHECKBOX, self.OnCheckboxCheckbox) self.rightCheckBox = wxCheckBox(label = 'Right', id = wxID_ANCHORSDEMOFRAMERIGHTCHECKBOX, parent = self.mainPanel, name = 'rightCheckBox', size = wxSize(48, 16), style = 0, pos = wxPoint(168, 8)) - self.rightCheckBox.SetConstraints(LayoutAnchors(self.rightCheckBox, false, true, false, false)) + self.rightCheckBox.SetConstraints(LayoutAnchors(self.rightCheckBox, False, True, False, False)) EVT_CHECKBOX(self.rightCheckBox, wxID_ANCHORSDEMOFRAMERIGHTCHECKBOX, self.OnCheckboxCheckbox) self.bottomCheckBox = wxCheckBox(label = 'Bottom', id = wxID_ANCHORSDEMOFRAMEBOTTOMCHECKBOX, parent = self.mainPanel, name = 'bottomCheckBox', size = wxSize(56, 16), style = 0, pos = wxPoint(248, 8)) - self.bottomCheckBox.SetConstraints(LayoutAnchors(self.bottomCheckBox, false, true, false, false)) + self.bottomCheckBox.SetConstraints(LayoutAnchors(self.bottomCheckBox, False, True, False, False)) EVT_CHECKBOX(self.bottomCheckBox, wxID_ANCHORSDEMOFRAMEBOTTOMCHECKBOX, self.OnCheckboxCheckbox) self.helpStaticText = wxStaticText(label = 'Select anchor options above, then resize window to see the effect', id = wxID_ANCHORSDEMOFRAMEHELPSTATICTEXT, parent = self.mainPanel, name = 'helpStaticText', size = wxSize(224, 24), style = wxST_NO_AUTORESIZE, pos = wxPoint(8, 128)) - self.helpStaticText.SetConstraints(LayoutAnchors(self.helpStaticText, true, false, true, true)) + self.helpStaticText.SetConstraints(LayoutAnchors(self.helpStaticText, True, False, True, True)) def __init__(self, parent): self._init_ctrls(parent) @@ -71,7 +71,7 @@ class AnchorsDemoFrame(wxFrame): def runTest(frame, nb, log): win = AnchorsDemoFrame(frame) frame.otherWin = win - win.Show(true) + win.Show(True) diff --git a/wxPython/demo/Layoutf.py b/wxPython/demo/Layoutf.py index e5809b60c5..cde4ad405f 100644 --- a/wxPython/demo/Layoutf.py +++ b/wxPython/demo/Layoutf.py @@ -8,7 +8,7 @@ class TestLayoutf(wxPanel): def __init__(self, parent): wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_BUTTON(self, 100, self.OnButton) self.panelA = wxWindow(self, -1, wxPyDefaultPosition, wxPyDefaultSize, wxSIMPLE_BORDER) diff --git a/wxPython/demo/MDIDemo.py b/wxPython/demo/MDIDemo.py index 3ae510ea7c..c5298129c1 100644 --- a/wxPython/demo/MDIDemo.py +++ b/wxPython/demo/MDIDemo.py @@ -3,6 +3,9 @@ from wxPython.wx import * from wxScrolledWindow import MyCanvas +import images +SHOW_BACKGROUND = 1 + #---------------------------------------------------------------------- class MyParentFrame(wxMDIParentFrame): @@ -24,16 +27,38 @@ class MyParentFrame(wxMDIParentFrame): EVT_MENU(self, 5000, self.OnNewWindow) EVT_MENU(self, 5001, self.OnExit) + if SHOW_BACKGROUND: + self.bg_bmp = images.getGridBGBitmap() + EVT_ERASE_BACKGROUND(self.GetClientWindow(), self.OnEraseBackground) + def OnExit(self, evt): - self.Close(true) + self.Close(True) def OnNewWindow(self, evt): self.winCount = self.winCount + 1 win = wxMDIChildFrame(self, -1, "Child Window: %d" % self.winCount) canvas = MyCanvas(win) - win.Show(true) + win.Show(True) + + + def OnEraseBackground(self, evt): + dc = evt.GetDC() + if not dc: + dc = wxClientDC(self.GetClientWindow()) + + # tile the background bitmap + sz = self.GetClientSize() + w = self.bg_bmp.GetWidth() + h = self.bg_bmp.GetHeight() + x = 0 + while x < sz.width: + y = 0 + while y < sz.height: + dc.DrawBitmap(self.bg_bmp, x, y) + y = y + h + x = x + w #---------------------------------------------------------------------- @@ -43,9 +68,9 @@ if __name__ == '__main__': def OnInit(self): wxInitAllImageHandlers() frame = MyParentFrame() - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True app = MyApp(0) diff --git a/wxPython/demo/MDISashDemo.py b/wxPython/demo/MDISashDemo.py index dca6516f6a..a5fe68b915 100644 --- a/wxPython/demo/MDISashDemo.py +++ b/wxPython/demo/MDISashDemo.py @@ -44,7 +44,7 @@ class MyParentFrame(wxMDIParentFrame): win.SetOrientation(wxLAYOUT_HORIZONTAL) win.SetAlignment(wxLAYOUT_TOP) win.SetBackgroundColour(wxColour(255, 0, 0)) - win.SetSashVisible(wxSASH_BOTTOM, true) + win.SetSashVisible(wxSASH_BOTTOM, True) self.topWindow = win @@ -55,7 +55,7 @@ class MyParentFrame(wxMDIParentFrame): win.SetOrientation(wxLAYOUT_HORIZONTAL) win.SetAlignment(wxLAYOUT_BOTTOM) win.SetBackgroundColour(wxColour(0, 0, 255)) - win.SetSashVisible(wxSASH_TOP, true) + win.SetSashVisible(wxSASH_TOP, True) self.bottomWindow = win @@ -66,7 +66,7 @@ class MyParentFrame(wxMDIParentFrame): win.SetOrientation(wxLAYOUT_VERTICAL) win.SetAlignment(wxLAYOUT_LEFT) win.SetBackgroundColour(wxColour(0, 255, 0)) - win.SetSashVisible(wxSASH_RIGHT, TRUE) + win.SetSashVisible(wxSASH_RIGHT, True) win.SetExtraBorderSize(10) textWindow = wxTextCtrl(win, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxSUNKEN_BORDER) @@ -81,7 +81,7 @@ class MyParentFrame(wxMDIParentFrame): win.SetOrientation(wxLAYOUT_VERTICAL) win.SetAlignment(wxLAYOUT_LEFT) win.SetBackgroundColour(wxColour(0, 255, 255)) - win.SetSashVisible(wxSASH_RIGHT, TRUE) + win.SetSashVisible(wxSASH_RIGHT, True) self.leftWindow2 = win @@ -113,14 +113,14 @@ class MyParentFrame(wxMDIParentFrame): def OnExit(self, evt): - self.Close(true) + self.Close(True) def OnNewWindow(self, evt): self.winCount = self.winCount + 1 win = wxMDIChildFrame(self, -1, "Child Window: %d" % self.winCount) canvas = MyCanvas(win) - win.Show(true) + win.Show(True) #---------------------------------------------------------------------- @@ -130,9 +130,9 @@ if __name__ == '__main__': def OnInit(self): wxInitAllImageHandlers() frame = MyParentFrame() - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True app = MyApp(0) diff --git a/wxPython/demo/Main.py b/wxPython/demo/Main.py index 82736b72fe..40f9425b84 100644 --- a/wxPython/demo/Main.py +++ b/wxPython/demo/Main.py @@ -11,7 +11,7 @@ # Licence: wxWindows license #---------------------------------------------------------------------------- -import sys, os, time, string +import sys, os, time from wxPython.wx import * from wxPython.html import wxHtmlWindow @@ -19,27 +19,19 @@ from wxPython.html import wxHtmlWindow import images + #--------------------------------------------------------------------------- _treeList = [ # new stuff - ('New since last release', [ - 'RowColSizer', - 'Unicode', - 'wxFileHistory', - 'wxGenericDirCtrl', - 'wxImageFromStream', - 'wxArtProvider', - 'ScrolledPanel', - 'wxMenu', - 'wxIEHtmlWin', - 'wxKeyEvents', - 'wxWizard', - 'wxXmlResourceHandler', + ('Recent Additions', [ + 'wxIntCtrl', + 'wxPyColourChooser', + 'wxScrolledPanel', ]), - # managed windows == things with a caption you can close + # managed windows == things with a (optional) caption you can close ('Base Frames and Dialogs', [ 'wxDialog', 'wxFrame', @@ -88,14 +80,15 @@ _treeList = [ 'wxNotebook', 'wxPopupWindow', 'wxRadioBox', + 'wxRadioButton', 'wxSashWindow', - 'wxSlider', 'wxScrolledWindow', - 'wxSplitterWindow', + 'wxSlider', 'wxSpinButton', 'wxSpinCtrl', - 'wxStaticText', + 'wxSplitterWindow', 'wxStaticBitmap', + 'wxStaticText', 'wxStatusBar', 'wxTextCtrl', 'wxToggleButton', @@ -106,6 +99,9 @@ _treeList = [ # controls coming from other librairies ('More Windows/Controls', [ + #'wxFloatBar', deprecated + #'wxMVCTree', deprecated + #'wxRightTextCtrl', deprecated as we have wxTE_RIGHT now. 'ColourSelect', 'ContextHelp', 'FancyText', @@ -115,20 +111,23 @@ _treeList = [ 'PyCrustWithFilling', 'SplitTree', 'TablePrint', + 'Throbber', 'wxCalendar', 'wxCalendarCtrl', + 'wxPyColourChooser', 'wxDynamicSashWindow', 'wxEditableListBox', 'wxEditor', - #'wxFloatBar', deprecated 'wxHtmlWindow', 'wxIEHtmlWin', + 'wxIntCtrl', 'wxLEDNumberCtrl', 'wxMimeTypesManager', - #'wxMVCTree', deprecated - 'wxRightTextCtrl', + 'wxMultiSash', + 'wxPopupControl', 'wxStyledTextCtrl_1', 'wxStyledTextCtrl_2', + 'wxTimeCtrl', ]), # How to lay out the controls in a frame/dialog @@ -136,22 +135,23 @@ _treeList = [ 'LayoutAnchors', 'Layoutf', 'RowColSizer', - 'ScrolledPanel', 'Sizers', 'wxLayoutConstraints', + 'wxScrolledPanel', 'wxXmlResource', 'wxXmlResourceHandler', ]), # ditto ('Process and Events', [ + 'EventManager', 'infoframe', 'OOR', 'PythonEvents', 'Threads', + 'wxKeyEvents', 'wxProcess', 'wxTimer', - 'wxKeyEvents', ]), # Clipboard and DnD @@ -162,12 +162,13 @@ _treeList = [ ]), # Images - ('Images', [ + ('Using Images', [ + 'Throbber', + 'wxArtProvider', 'wxDragImage', 'wxImage', 'wxImageFromStream', 'wxMask', - 'wxArtProvider', ]), # Other stuff @@ -177,6 +178,7 @@ _treeList = [ 'DrawXXXList', 'FontEnumerator', 'PrintFramework', + 'Throbber', 'Unicode', 'wxFileHistory', 'wxJoystick', @@ -212,7 +214,8 @@ class MyLog(wxPyLog): if self.logTime: message = time.strftime("%X", time.localtime(timeStamp)) + \ ": " + message - self.tc.AppendText(message + '\n') + if self.tc: + self.tc.AppendText(message + '\n') class MyTP(wxPyTipProvider): @@ -223,7 +226,7 @@ class MyTP(wxPyTipProvider): def opj(path): """Convert paths to the platform-specific separator""" - return apply(os.path.join, tuple(string.split(path, '/'))) + return apply(os.path.join, tuple(path.split('/'))) #--------------------------------------------------------------------------- @@ -237,6 +240,7 @@ class wxPythonDemo(wxFrame): self.cwd = os.getcwd() self.curOverview = "" + self.window = None icon = images.getMondrianIcon() self.SetIcon(icon) @@ -250,9 +254,9 @@ class wxPythonDemo(wxFrame): EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate) EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose) + wxCallAfter(self.ShowTip) self.otherWin = None - self.showTip = true EVT_IDLE(self, self.OnIdle) EVT_CLOSE(self, self.OnCloseWindow) EVT_ICONIZE(self, self.OnIconfiy) @@ -268,8 +272,8 @@ class wxPythonDemo(wxFrame): EVT_ERASE_BACKGROUND(splitter, EmptyHandler) EVT_ERASE_BACKGROUND(splitter2, EmptyHandler) - # Prevent TreeCtrl from displaying all items after destruction when true - self.dying = false + # Prevent TreeCtrl from displaying all items after destruction when True + self.dying = False # Make a File menu self.mainmenu = wxMenuBar() @@ -277,6 +281,7 @@ class wxPythonDemo(wxFrame): exitID = wxNewId() menu.Append(exitID, 'E&xit\tAlt-X', 'Get the heck outta here!') EVT_MENU(self, exitID, self.OnFileExit) + wxApp_SetMacExitMenuItemId(exitID) self.mainmenu.Append(menu, '&File') # Make a Demo menu @@ -293,16 +298,33 @@ class wxPythonDemo(wxFrame): # Make a Help menu helpID = wxNewId() + findID = wxNewId() + findnextID = wxNewId() menu = wxMenu() + menu.Append(findID, '&Find\tCtrl-F', 'Find in the Demo Code') + menu.Append(findnextID, 'Find &Next\tF3', 'Find Next') + menu.AppendSeparator() menu.Append(helpID, '&About\tCtrl-H', 'wxPython RULES!!!') + wxApp_SetMacAboutMenuItemId(helpID) EVT_MENU(self, helpID, self.OnHelpAbout) + EVT_MENU(self, findID, self.OnHelpFind) + EVT_MENU(self, findnextID, self.OnFindNext) + EVT_COMMAND_FIND(self, -1, self.OnFind) + EVT_COMMAND_FIND_NEXT(self, -1, self.OnFind) + EVT_COMMAND_FIND_CLOSE(self, -1 , self.OnFindClose) self.mainmenu.Append(menu, '&Help') self.SetMenuBar(self.mainmenu) - # set the menu accellerator table... - aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID), - (wxACCEL_CTRL, ord('H'), helpID)]) - self.SetAcceleratorTable(aTable) + self.finddata = wxFindReplaceData() + + if 0: + # This is another way to set Accelerators, in addition to + # using the '\t' syntax in the menu items. + aTable = wxAcceleratorTable([(wxACCEL_ALT, ord('X'), exitID), + (wxACCEL_CTRL, ord('H'), helpID), + (wxACCEL_CTRL, ord('F'), findID), + (wxACCEL_NORMAL, WXK_F3, findnextID)]) + self.SetAcceleratorTable(aTable) # Create a TreeCtrl @@ -358,7 +380,8 @@ class wxPythonDemo(wxFrame): # Set up a TextCtrl on the Demo Code Notebook page self.txt = wxTextCtrl(self.nb, -1, - style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL) + style = wxTE_MULTILINE|wxTE_READONLY| + wxHSCROLL|wxTE_RICH2|wxTE_NOHIDESEL) self.nb.AddPage(self.txt, "Demo Code") @@ -376,16 +399,14 @@ class wxPythonDemo(wxFrame): #wxLog_SetActiveTarget(wxLogStderr()) #wxLog_SetTraceMask(wxTraceMessages) - self.Show(true) + self.Show(True) # add the windows to the splitter and split it. - splitter2.SplitHorizontally(self.nb, self.log) - splitter.SplitVertically(self.tree, splitter2) + splitter2.SplitHorizontally(self.nb, self.log, 450) + splitter.SplitVertically(self.tree, splitter2, 180) - splitter.SetSashPosition(180, true) splitter.SetMinimumPaneSize(20) - splitter2.SetSashPosition(450, true) splitter2.SetMinimumPaneSize(20) @@ -453,6 +474,11 @@ class wxPythonDemo(wxFrame): if self.nb.GetPageCount() == 3: if self.nb.GetSelection() == 2: self.nb.SetSelection(0) + # inform the window that it's time to quit if it cares + if self.window is not None: + if hasattr(self.window, "ShutdownDemo"): + self.window.ShutdownDemo() + wxSafeYield() # in case the page has pending events self.nb.DeletePage(2) if itemText == self.overviewText: @@ -478,7 +504,7 @@ class wxPythonDemo(wxFrame): wxSafeYield() self.window = module.runTest(self, self.nb, self) ### - if self.window: + if self.window is not None: self.nb.AddPage(self.window, 'Demo') self.nb.SetSelection(2) self.nb.Refresh() # without this wxMac has troubles showing the just added page @@ -507,7 +533,7 @@ class wxPythonDemo(wxFrame): self.curOverview = text lead = text[:6] if lead != '' and lead != '': - text = string.join(string.split(text, '\n'), '
') + text = '
'.join(text.split('\n')) self.ovr.SetPage(text) self.nb.SetPageText(0, name) @@ -516,17 +542,61 @@ class wxPythonDemo(wxFrame): def OnFileExit(self, *event): self.Close() - def OnHelpAbout(self, event): from About import MyAboutBox about = MyAboutBox(self) about.ShowModal() about.Destroy() + def OnHelpFind(self, event): + self.nb.SetSelection(1) + self.finddlg = wxFindReplaceDialog(self, self.finddata, "Find", + wxFR_NOUPDOWN | + wxFR_NOMATCHCASE | + wxFR_NOWHOLEWORD) + self.finddlg.Show(True) + + def OnFind(self, event): + self.nb.SetSelection(1) + end = self.txt.GetLastPosition() + textstring = self.txt.GetRange(0, end).lower() + start = self.txt.GetSelection()[1] + findstring = self.finddata.GetFindString().lower() + loc = textstring.find(findstring, start) + if loc == -1 and start != 0: + # string not found, start at beginning + start = 0 + loc = textstring.find(findstring, start) + if loc == -1: + dlg = wxMessageDialog(self, 'Find String Not Found', + 'Find String Not Found in Demo File', + wxOK | wxICON_INFORMATION) + dlg.ShowModal() + dlg.Destroy() + if self.finddlg: + if loc == -1: + self.finddlg.SetFocus() + return + else: + self.finddlg.Destroy() + self.txt.SetSelection(loc, loc + len(findstring)) + self.txt.ShowPosition(loc) + + + + def OnFindNext(self, event): + if self.finddata.GetFindString(): + self.OnFind(event) + else: + self.OnHelpFind(event) + + def OnFindClose(self, event): + event.GetDialog().Destroy() + #--------------------------------------------- def OnCloseWindow(self, event): - self.dying = true + self.dying = True self.window = None self.mainmenu = None if hasattr(self, "tbicon"): @@ -541,10 +611,6 @@ class wxPythonDemo(wxFrame): self.window = self.otherWin self.otherWin = None - if self.showTip: - self.ShowTip() - self.showTip = false - #--------------------------------------------- def ShowTip(self): @@ -575,9 +641,9 @@ class wxPythonDemo(wxFrame): #--------------------------------------------- def OnTaskBarActivate(self, evt): if self.IsIconized(): - self.Iconize(false) + self.Iconize(False) if not self.IsShown(): - self.Show(true) + self.Show(True) self.Raise() #--------------------------------------------- @@ -628,7 +694,7 @@ class MySplashScreen(wxSplashScreen): def OnClose(self, evt): frame = wxPythonDemo(None, -1, "wxPython: (A Demonstration)") - frame.Show(true) + frame.Show() evt.Skip() # Make sure the default handler runs too... @@ -638,10 +704,15 @@ class MyApp(wxApp): Create and show the splash screen. It will then create and show the main frame when it is time to do so. """ + + #import locale + #self.locale = wxLocale(wxLANGUAGE_FRENCH) + #locale.setlocale(locale.LC_ALL, 'fr') + wxInitAllImageHandlers() splash = MySplashScreen() splash.Show() - return true + return True diff --git a/wxPython/demo/OOR.py b/wxPython/demo/OOR.py index 9b4088fb8d..e0e84b0112 100644 --- a/wxPython/demo/OOR.py +++ b/wxPython/demo/OOR.py @@ -30,7 +30,7 @@ class TestPanel(wxPanel): sizer.Add(btns, 0, wxEXPAND|wxALL, 15) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.sizer = sizer # save it for testing later diff --git a/wxPython/demo/PrintFramework.py b/wxPython/demo/PrintFramework.py index faa33469d0..36c3ea5a2b 100644 --- a/wxPython/demo/PrintFramework.py +++ b/wxPython/demo/PrintFramework.py @@ -33,9 +33,9 @@ class MyPrintout(wxPrintout): def HasPage(self, page): self.log.WriteText("wxPrintout.HasPage: %d\n" % page) if page <= 2: - return true + return True else: - return false + return False def GetPageInfo(self): self.log.WriteText("wxPrintout.GetPageInfo\n") @@ -82,7 +82,7 @@ class MyPrintout(wxPrintout): self.canvas.DoDrawing(dc) dc.DrawText("Page: %d" % page, marginX/2, maxY-marginY) - return true + return True #---------------------------------------------------------------------- @@ -117,14 +117,14 @@ class TestPrintPanel(wxPanel): self.box.Add(subbox, 0, wxGROW) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(self.box) def OnPrintSetup(self, event): printerDialog = wxPrintDialog(self) printerDialog.GetPrintDialogData().SetPrintData(self.printData) - printerDialog.GetPrintDialogData().SetSetupDialog(true) + printerDialog.GetPrintDialogData().SetSetupDialog(True) printerDialog.ShowModal(); self.printData = printerDialog.GetPrintDialogData().GetPrintData() printerDialog.Destroy() @@ -144,7 +144,7 @@ class TestPrintPanel(wxPanel): frame.Initialize() frame.SetPosition(self.frame.GetPosition()) frame.SetSize(self.frame.GetSize()) - frame.Show(true) + frame.Show(True) diff --git a/wxPython/demo/RowColSizer.py b/wxPython/demo/RowColSizer.py index 24921ca057..1a5ac5119e 100644 --- a/wxPython/demo/RowColSizer.py +++ b/wxPython/demo/RowColSizer.py @@ -50,7 +50,7 @@ class TestPanel(wxPanel): sizer.AddSpacer(10,10, pos=(13,1)) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) #---------------------------------------------------------------------- @@ -67,3 +67,9 @@ import wxPython.lib.rcsizer overview = wxPython.lib.rcsizer.__doc__ + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/ScrolledPanel.py b/wxPython/demo/ScrolledPanel.py deleted file mode 100644 index 2ff349b8f3..0000000000 --- a/wxPython/demo/ScrolledPanel.py +++ /dev/null @@ -1,97 +0,0 @@ - -from wxPython.wx import * - -#---------------------------------------------------------------------- - -text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen" - - -class ScrolledPanel(wxScrolledWindow): - def __init__(self, parent, log): - self.log = log - wxScrolledWindow.__init__(self, parent, -1, - style = wxTAB_TRAVERSAL) - - box = wxBoxSizer(wxVERTICAL) - box.Add(wxStaticText(self, -1, - "This sample shows how to make a scrollable data entry \n" - "form by using a wxSizer in a wxScrolledWindow."), - 0, wxCENTER|wxALL, 5) - box.Add(wxStaticLine(self, -1), 0, wxEXPAND|wxALL, 5) - - fgs = wxFlexGridSizer(cols=2, vgap=4, hgap=4) - fgs.AddGrowableCol(1) - - # Add some spacers - fgs.Add(75, 10) - fgs.Add(150, 10) - - for word in text.split(): - label = wxStaticText(self, -1, word+":") - tc = wxTextCtrl(self, -1, word) - fgs.Add(label, flag=wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL) - fgs.Add(tc, flag=wxEXPAND) - - box.Add(fgs, 1) - box.Add(10, 40) # some more empty space at the bottom - self.SetSizer(box) - - - # The following is all that is needed to integrate the sizer and the - # scrolled window. In this case we will only support vertical scrolling. - self.EnableScrolling(false, true) - self.SetScrollRate(0, 20) - box.SetVirtualSizeHints(self) - EVT_CHILD_FOCUS(self, self.OnChildFocus) - - wxCallAfter(self.Scroll, 0, 0) # scroll back to top after initial events - - - def OnChildFocus(self, evt): - # If the child window that gets the focus is not visible, - # this handler will try to scroll enough to see it. If you - # need to handle horizontal auto-scrolling too then this will - # need adapted. - evt.Skip() - child = evt.GetWindow() - - sppu_y = self.GetScrollPixelsPerUnit()[1] - vs_y = self.GetViewStart()[1] - cpos = child.GetPosition() - csz = child.GetSize() - - # is it above the top? - if cpos.y < 0: - new_vs = cpos.y / sppu_y - self.Scroll(-1, new_vs) - - # is it below the bottom ? - if cpos.y + csz.height > self.GetClientSize().height: - diff = (cpos.y + csz.height - self.GetClientSize().height) / sppu_y - self.Scroll(-1, vs_y + diff + 1) - - -#---------------------------------------------------------------------- - - -def runTest(frame, nb, log): - win = ScrolledPanel(nb, log) - return win - -#---------------------------------------------------------------------- - - - -overview = """ -This sample shows how to make a scrollable data entry form by -using a wxSizer in a wxScrolledWindow. - -""" - - - -if __name__ == '__main__': - import sys,os - import run - run.main(['', os.path.basename(sys.argv[0])]) - diff --git a/wxPython/demo/Sizers.py b/wxPython/demo/Sizers.py index 8278bd0db4..ab95d06fd7 100644 --- a/wxPython/demo/Sizers.py +++ b/wxPython/demo/Sizers.py @@ -479,16 +479,16 @@ class TestFrame(wxFrame): self.SetStatusText("Resize this frame to see how the sizers respond...") self.sizer.Fit(self) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(self.sizer) EVT_CLOSE(self, self.OnCloseWindow) def OnCloseWindow(self, event): - self.MakeModal(false) + self.MakeModal(False) self.Destroy() def OnButton(self, event): - self.Close(true) + self.Close(True) #---------------------------------------------------------------------- @@ -531,8 +531,8 @@ class TestSelectionPanel(wxPanel): if func: win = TestFrame(self, title, func) win.CentreOnParent(wxBOTH) - win.Show(true) - win.MakeModal(true) + win.Show(True) + win.MakeModal(True) #---------------------------------------------------------------------- @@ -555,12 +555,12 @@ if __name__ == '__main__': def __init__(self): wxFrame.__init__(self, None, -1, "Testing...") - self.CreateStatusBar() - mainmenu = wxMenuBar() - menu = wxMenu() - menu.Append(200, 'E&xit', 'Get the heck outta here!') - mainmenu.Append(menu, "&File") - self.SetMenuBar(mainmenu) + self.CreateStatusBar() + mainmenu = wxMenuBar() + menu = wxMenu() + menu.Append(200, 'E&xit', 'Get the heck outta here!') + mainmenu.Append(menu, "&File") + self.SetMenuBar(mainmenu) EVT_MENU(self, 200, self.OnExit) self.panel = TestSelectionPanel(self, self) self.SetSize(wxSize(400, 380)) @@ -570,15 +570,15 @@ if __name__ == '__main__': self.Destroy() def OnExit(self, event): - self.Close(true) + self.Close(True) class TestApp(wxApp): def OnInit(self): frame = MainFrame() - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True app = TestApp(0) app.MainLoop() diff --git a/wxPython/demo/SlashDot.py b/wxPython/demo/SlashDot.py index 03fc98011f..eb0ded644e 100644 --- a/wxPython/demo/SlashDot.py +++ b/wxPython/demo/SlashDot.py @@ -170,22 +170,22 @@ class AppStatusBar(wxStatusBar): # This is a simple timer class to start a function after a short delay; class QuickTimer(wxTimer): def __init__(self, func, wait=100): - wxTimer.__init__(self) - self.callback = func - self.Start(wait); # wait .1 second (.001 second doesn't work. why?) + wxTimer.__init__(self) + self.callback = func + self.Start(wait); # wait .1 second (.001 second doesn't work. why?) def Notify(self): - self.Stop(); - apply(self.callback, ()); + self.Stop(); + apply(self.callback, ()); class AppFrame(wxFrame): def __init__(self, parent, id, title): wxFrame.__init__(self, parent, id, title, wxPyDefaultPosition, wxSize(650, 250)) - # if the window manager closes the window: - EVT_CLOSE(self, self.OnCloseWindow); + # if the window manager closes the window: + EVT_CLOSE(self, self.OnCloseWindow); - # Now Create the menu bar and items + # Now Create the menu bar and items self.mainmenu = wxMenuBar() menu = wxMenu() @@ -201,52 +201,52 @@ class AppFrame(wxFrame): EVT_MENU(self, 212, self.OnViewArticle) self.mainmenu.Append(menu, '&View') menu = wxMenu() - menu.Append(220, '&Internal', 'Use internal text browser',TRUE) - menu.Check(220, true) + menu.Append(220, '&Internal', 'Use internal text browser',True) + menu.Check(220, True) self.UseInternal = 1; EVT_MENU(self, 220, self.OnBrowserInternal) menu.Append(222, '&Settings...', 'External browser Settings') EVT_MENU(self, 222, self.OnBrowserSettings) self.mainmenu.Append(menu, '&Browser') - menu = wxMenu() - menu.Append(230, '&About', 'Some documentation'); - EVT_MENU(self, 230, self.OnAbout) - self.mainmenu.Append(menu, '&Help') + menu = wxMenu() + menu.Append(230, '&About', 'Some documentation'); + EVT_MENU(self, 230, self.OnAbout) + self.mainmenu.Append(menu, '&Help') self.SetMenuBar(self.mainmenu) - if wxPlatform == '__WXGTK__': - # I like lynx. Also Netscape 4.5 doesn't react to my cmdline opts - self.BrowserSettings = "xterm -e lynx %s &" - elif wxPlatform == '__WXMSW__': - # netscape 4.x likes to hang out here... - self.BrowserSettings = '\\progra~1\\Netscape\\Communicator\\Program\\netscape.exe %s' - else: - # a wild guess... - self.BrowserSettings = 'netscape %s' - - # A status bar to tell people what's happening - self.sb = AppStatusBar(self) + if wxPlatform == '__WXGTK__': + # I like lynx. Also Netscape 4.5 doesn't react to my cmdline opts + self.BrowserSettings = "xterm -e lynx %s &" + elif wxPlatform == '__WXMSW__': + # netscape 4.x likes to hang out here... + self.BrowserSettings = '\\progra~1\\Netscape\\Communicator\\Program\\netscape.exe %s' + else: + # a wild guess... + self.BrowserSettings = 'netscape %s' + + # A status bar to tell people what's happening + self.sb = AppStatusBar(self) self.SetStatusBar(self.sb) self.list = wxListCtrl(self, 1100, style=wxLC_REPORT) - self.list.InsertColumn(0, 'Subject') - self.list.InsertColumn(1, 'Date') - self.list.InsertColumn(2, 'Posted by') - self.list.InsertColumn(3, 'Comments') + self.list.InsertColumn(0, 'Subject') + self.list.InsertColumn(1, 'Date') + self.list.InsertColumn(2, 'Posted by') + self.list.InsertColumn(3, 'Comments') self.list.SetColumnWidth(0, 300) self.list.SetColumnWidth(1, 150) self.list.SetColumnWidth(2, 100) self.list.SetColumnWidth(3, 100) EVT_LIST_ITEM_SELECTED(self, 1100, self.OnItemSelected) - EVT_LEFT_DCLICK(self.list, self.OnLeftDClick) + EVT_LEFT_DCLICK(self.list, self.OnLeftDClick) - self.logprint("Connecting to slashdot... Please wait.") - # wxYield doesn't yet work here. That's why we use a timer - # to make sure that we see some GUI stuff before the slashdot - # file is transfered. - self.timer = QuickTimer(self.DoRefresh, 1000) + self.logprint("Connecting to slashdot... Please wait.") + # wxYield doesn't yet work here. That's why we use a timer + # to make sure that we see some GUI stuff before the slashdot + # file is transfered. + self.timer = QuickTimer(self.DoRefresh, 1000) def logprint(self, x): self.sb.logprint(x) @@ -268,44 +268,44 @@ class AppFrame(wxFrame): self.list.SetStringItem(i, 3, article[6]) self.url.append(article[1]) i = i + 1 - self.logprint("File retrieved OK.") + self.logprint("File retrieved OK.") def OnViewRefresh(self, event): - self.logprint("Connecting to slashdot... Please wait."); - wxYield() - self.DoRefresh() + self.logprint("Connecting to slashdot... Please wait."); + wxYield() + self.DoRefresh() def DoViewIndex(self): if self.UseInternal: self.view = HTMLTextView(self, -1, 'slashdot.org', 'http://slashdot.org') - self.view.Show(true) + self.view.Show(True) else: self.logprint(self.BrowserSettings % ('http://slashdot.org')) #os.system(self.BrowserSettings % ('http://slashdot.org')) wxExecute(self.BrowserSettings % ('http://slashdot.org')) - self.logprint("OK") + self.logprint("OK") def OnViewIndex(self, event): - self.logprint("Starting browser... Please wait.") - wxYield() - self.DoViewIndex() + self.logprint("Starting browser... Please wait.") + wxYield() + self.DoViewIndex() def DoViewArticle(self): if self.current<0: return url = self.url[self.current] if self.UseInternal: self.view = HTMLTextView(self, -1, url, url) - self.view.Show(true) + self.view.Show(True) else: self.logprint(self.BrowserSettings % (url)) os.system(self.BrowserSettings % (url)) - self.logprint("OK") + self.logprint("OK") def OnViewArticle(self, event): - self.logprint("Starting browser... Please wait.") - wxYield() - self.DoViewArticle() + self.logprint("Starting browser... Please wait.") + wxYield() + self.DoViewArticle() def OnBrowserInternal(self, event): if self.mainmenu.Checked(220): @@ -319,28 +319,28 @@ class AppFrame(wxFrame): self.BrowserSettings = dlg.GetValue() def OnAbout(self, event): - dlg = wxMessageDialog(self, __doc__, "wxSlash", wxOK | wxICON_INFORMATION) - dlg.ShowModal() + dlg = wxMessageDialog(self, __doc__, "wxSlash", wxOK | wxICON_INFORMATION) + dlg.ShowModal() def OnItemSelected(self, event): self.current = event.m_itemIndex self.logprint("URL: %s" % (self.url[self.current])) def OnLeftDClick(self, event): - (x,y) = event.Position(); - # Actually, we should convert x,y to logical coords using - # a dc, but only for a wxScrolledWindow widget. - # Now wxGTK derives wxListCtrl from wxScrolledWindow, - # and wxMSW from wxControl... So that doesn't work. - #dc = wxClientDC(self.list) - ##self.list.PrepareDC(dc) - #x = dc.DeviceToLogicalX( event.GetX() ) - #y = dc.DeviceToLogicalY( event.GetY() ) - id = self.list.HitTest(wxPoint(x,y)) - #print "Double click at %d %d" % (x,y), id - # Okay, we got a double click. Let's assume it's the current selection - wxYield() - self.OnViewArticle(event) + (x,y) = event.Position(); + # Actually, we should convert x,y to logical coords using + # a dc, but only for a wxScrolledWindow widget. + # Now wxGTK derives wxListCtrl from wxScrolledWindow, + # and wxMSW from wxControl... So that doesn't work. + #dc = wxClientDC(self.list) + ##self.list.PrepareDC(dc) + #x = dc.DeviceToLogicalX( event.GetX() ) + #y = dc.DeviceToLogicalY( event.GetY() ) + id = self.list.HitTest(wxPoint(x,y)) + #print "Double click at %d %d" % (x,y), id + # Okay, we got a double click. Let's assume it's the current selection + wxYield() + self.OnViewArticle(event) def OnCloseWindow(self, event): self.Destroy() @@ -353,9 +353,9 @@ if __name__ == '__main__': class MyApp(wxApp): def OnInit(self): frame = AppFrame(None, -1, "Slashdot Breaking News") - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True app = MyApp(0) app.MainLoop() @@ -368,7 +368,7 @@ if __name__ == '__main__': def runTest(frame, nb, log): win = AppFrame(None, -1, "Slashdot Breaking News") frame.otherWin = win - win.Show(true) + win.Show(True) overview = __doc__ diff --git a/wxPython/demo/SplitTree.py b/wxPython/demo/SplitTree.py index fddd44f7dc..698d2f639d 100644 --- a/wxPython/demo/SplitTree.py +++ b/wxPython/demo/SplitTree.py @@ -76,23 +76,26 @@ class TestPanel(wxPanel): wxNO_BORDER ) valueWindow = TestValueWindow(splitter, -1, style=wxNO_BORDER) - splitter.SplitVertically(tree, valueWindow) - splitter.SetSashPosition(150) + splitter.SplitVertically(tree, valueWindow, 150) scroller.SetTargetWindow(tree) - scroller.EnableScrolling(FALSE, FALSE) + scroller.EnableScrolling(False, False) valueWindow.SetTreeCtrl(tree) tree.SetCompanionWindow(valueWindow) sizer = wxBoxSizer(wxVERTICAL) sizer.Add(scroller, 1, wxEXPAND|wxALL, 25) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) #---------------------------------------------------------------------- def runTest(frame, nb, log): + if wxPlatform == "__WXMAC__": + wxMessageBox("This demo currently fails on the Mac. The problem is being looked into...", "Sorry") + return + win = TestPanel(nb, log) return win diff --git a/wxPython/demo/TablePrint.py b/wxPython/demo/TablePrint.py index 615222c812..51b075c3da 100644 --- a/wxPython/demo/TablePrint.py +++ b/wxPython/demo/TablePrint.py @@ -31,7 +31,7 @@ class TablePanel(wxPanel): box.Add(btn, 0, wxALIGN_CENTER|wxALL, 15) EVT_BUTTON(self, k, self.OnButton) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(box) def OnButton(self, evt): @@ -47,11 +47,11 @@ class TablePanel(wxPanel): data = [] while 1: text = file.readline() - text = string.strip(text) + text = text.strip() if not text: break - list_val = string.splitfields(text,'\t') + list_val = text.split('\t') data.append(list_val) file.close() diff --git a/wxPython/demo/Threads.py b/wxPython/demo/Threads.py index 0476647c38..4c165eeb89 100644 --- a/wxPython/demo/Threads.py +++ b/wxPython/demo/Threads.py @@ -30,11 +30,11 @@ class CalcBarThread: self.val = val def Start(self): - self.keepGoing = self.running = true + self.keepGoing = self.running = True thread.start_new_thread(self.Run, ()) def Stop(self): - self.keepGoing = false + self.keepGoing = False def IsRunning(self): return self.running @@ -57,7 +57,7 @@ class CalcBarThread: if self.val < 0: self.val = 0 if self.val > 300: self.val = 300 - self.running = false + self.running = False #---------------------------------------------------------------------- @@ -172,7 +172,7 @@ class TestFrame(wxFrame): sizer.Add(self.graph, 1, wxEXPAND) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) sizer.Fit(self) EVT_UPDATE_BARGRAPH(self, self.OnUpdate) @@ -194,7 +194,7 @@ class TestFrame(wxFrame): def OnUpdate(self, evt): self.graph.SetValue(evt.barNum, evt.value) - self.graph.Refresh(false) + self.graph.Refresh(False) def OnCloseWindow(self, evt): @@ -217,7 +217,7 @@ class TestFrame(wxFrame): def runTest(frame, nb, log): win = TestFrame(frame, log) frame.otherWin = win - win.Show(true) + win.Show(True) return None #---------------------------------------------------------------------- diff --git a/wxPython/demo/Throbber.py b/wxPython/demo/Throbber.py new file mode 100644 index 0000000000..2aadab2f90 --- /dev/null +++ b/wxPython/demo/Throbber.py @@ -0,0 +1,180 @@ +# +# Throbber.py - Cliff Wells +# + +from wxPython.wx import * +from wxPython.lib.rcsizer import RowColSizer +from wxPython.lib.throbber import Throbber, __doc__ as docString +import throbImages # this was created using a modified version of img2py + +#---------------------------------------------------------------------- + +class TestPanel(wxPanel): + def __init__(self, parent, log): + wxPanel.__init__(self, parent, -1) + self.log = log + + # create the throbbers + self.throbbers = { + 'plain': { 'throbber': None, + 'text': "Plain throbber." }, + 'reverse': { 'throbber': None, + 'text': "This throbber runs in reverse and faster." }, + 'autoreverse': { 'throbber': None, + 'text': "This throbber switches direction." }, + 'label': { 'throbber': None, + 'text': "With a label." }, + 'overlay': { 'throbber': None, + 'text': "With an overlayed image." }, + 'overlay+text': { 'throbber': None, + 'text': "With a label and an overlayed image." }, + } + + images = [throbImages.catalog[i].getBitmap() + for i in throbImages.index + if i not in ['eclouds', 'logo']] + + self.throbbers['plain']['throbber'] = Throbber(self, -1, + images, size=(36, 36), + frameDelay = 0.1) + self.throbbers['reverse']['throbber'] = Throbber(self, -1, images, #size=(36, 36), + frameDelay = 0.07) + self.throbbers['reverse']['throbber'].Reverse() + self.throbbers['autoreverse']['throbber'] = Throbber(self, -1, + images, #size=(36, 36), + frameDelay = 0.1, + reverse = True) + self.throbbers['autoreverse']['throbber'].sequence.append(0) + self.throbbers['label']['throbber'] = Throbber(self, -1, + images, #size=(36, 36), + frameDelay = 0.1, + label = 'Label') + self.throbbers['label']['throbber'].SetFont(wxFont(pointSize = 10, + family = wxDEFAULT, + style = wxNORMAL, + weight = wxBOLD)) + self.throbbers['overlay']['throbber'] = Throbber(self, -1, + images, #size=(36, 36), + frameDelay = 0.1, + overlay = throbImages.catalog['logo'].getBitmap()) + self.throbbers['overlay+text']['throbber'] = Throbber(self, -1, + images, #size=(36, 36), + frameDelay = 0.1, + overlay = throbImages.catalog['logo'].getBitmap(), + label = "Python!") + self.throbbers['overlay+text']['throbber'].SetFont(wxFont(pointSize = 8, + family = wxDEFAULT, + style = wxNORMAL, + weight = wxBOLD)) + + + # this throbber is created using a single, composite image + self.otherThrobber = Throbber(self, -1, + throbImages.catalog['eclouds'].getBitmap(), #size=(48, 48), + frameDelay = 0.15, + frames = 12, + frameWidth = 48, + label = "Stop") + + + EVT_LEFT_DOWN(self.otherThrobber, self.OnClickThrobber) + + box = wxBoxSizer(wxVERTICAL) + sizer = RowColSizer() + box.Add(sizer, 1, wxEXPAND|wxALL, 5) + sizer.AddGrowableCol(1) + + sizer.Add(self.otherThrobber, row = 0, col = 2, rowspan = 4, flag = wxALIGN_CENTER_VERTICAL) + + row = 2 + # use a list so we can keep our order + for t in ['plain', 'reverse', 'autoreverse', 'label', 'overlay', 'overlay+text']: + sizer.Add(self.throbbers[t]['throbber'], row = row, col = 0, flag = wxALIGN_CENTER|wxALL, border=2) + sizer.Add(wxStaticText(self, -1, self.throbbers[t]['text']), row = row, col = 1, + flag = wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT) + row += 1 + + # start and stop buttons + startButton = wxButton(self, -1, "Start") + EVT_BUTTON(self, startButton.GetId(), self.OnStartAnimation) + stopButton = wxButton(self, -1, "Stop") + EVT_BUTTON(self, stopButton.GetId(), self.OnStopAnimation) + + buttonBox = wxBoxSizer(wxHORIZONTAL) + buttonBox.AddMany([ + (startButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5), + (stopButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5), + ]) + + sizer.Add(buttonBox, + row = len(self.throbbers) + 3, + col = 0, + colspan = 3, + flag = wxALIGN_CENTER) + + self.SetSizer(box) + self.SetAutoLayout(True) + self.Layout() + sizer.SetSizeHints(self) + sizer.Fit(self) + + for t in self.throbbers.keys(): + self.throbbers[t]['throbber'].Start() + self.otherThrobber.Start() + self.otherThrobber.Reverse() + + EVT_WINDOW_DESTROY(self, self.OnDestroy) + + def OnDestroy(self, event): + self.log.write("got destroy event") + event.Skip() + + def OnStartAnimation(self, event): + for t in self.throbbers.keys(): + self.throbbers[t]['throbber'].Start() + + def OnStopAnimation(self, event): + for t in self.throbbers.keys(): + self.throbbers[t]['throbber'].Rest() + + def OnClickThrobber(self, event): + if self.otherThrobber.Running(): + self.otherThrobber.Rest() + self.otherThrobber.SetLabel("Start") + else: + self.otherThrobber.Start() + self.otherThrobber.SetLabel("Stop") + + def ShutdownDemo(self): + self.otherThrobber.Rest() + for t in self.throbbers.keys(): + self.throbbers[t]['throbber'].Rest() + + +#---------------------------------------------------------------------- + +def runTest(frame, nb, log): + if wxPlatform == "__WXMAC__": + wxMessageBox("This demo currently fails on the Mac.", + "Sorry") + return + else: + win = TestPanel(nb, log) + return win + +#---------------------------------------------------------------------- + + + +overview = """ +

Throbber

+

%s

+ +""" % docString + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) diff --git a/wxPython/demo/URLDragAndDrop.py b/wxPython/demo/URLDragAndDrop.py index d8c934ece2..16b3b96006 100644 --- a/wxPython/demo/URLDragAndDrop.py +++ b/wxPython/demo/URLDragAndDrop.py @@ -30,12 +30,12 @@ class TestPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) outsideSizer = wxBoxSizer(wxVERTICAL) msg = "Drag-And-Drop of URLs" text = wxStaticText(self, -1, "", style=wxALIGN_CENTRE) - text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, false)) + text.SetFont(wxFont(24, wxSWISS, wxNORMAL, wxBOLD, False)) text.SetLabel(msg) w,h = text.GetTextExtent(msg) text.SetSize(wxSize(w,h+1)) @@ -44,7 +44,7 @@ class TestPanel(wxPanel): outsideSizer.Add(wxStaticLine(self, -1), 0, wxEXPAND) outsideSizer.Add(20,20) - self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, false)) + self.SetFont(wxFont(10, wxSWISS, wxNORMAL, wxBOLD, False)) inSizer = wxFlexGridSizer(2, 2, 5, 5) inSizer.AddGrowableCol(0) diff --git a/wxPython/demo/Unicode.py b/wxPython/demo/Unicode.py index 2e654b6efd..c6910a05c4 100644 --- a/wxPython/demo/Unicode.py +++ b/wxPython/demo/Unicode.py @@ -56,7 +56,7 @@ class TestPanel(wxPanel): else: f = self.GetFont() - font = wxFont(14, f.GetFamily(), f.GetStyle(), wxBOLD, false, + font = wxFont(14, f.GetFamily(), f.GetStyle(), wxBOLD, False, f.GetFaceName(), f.GetEncoding()) self.AddLine(box) @@ -79,7 +79,7 @@ class TestPanel(wxPanel): border = wxBoxSizer(wxVERTICAL) border.Add(box, 1, wxEXPAND|wxALL, 10) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(border) diff --git a/wxPython/demo/XMLtreeview.py b/wxPython/demo/XMLtreeview.py index ce14928ce8..d57642958e 100644 --- a/wxPython/demo/XMLtreeview.py +++ b/wxPython/demo/XMLtreeview.py @@ -1,5 +1,5 @@ -import string, sys +import sys py2 = sys.version[0] == '2' @@ -11,9 +11,9 @@ try: else: from xml.parsers import pyexpat parsermodule = pyexpat - haveXML = true + haveXML = True except ImportError: - haveXML = false + haveXML = False #---------------------------------------------------------------------- @@ -76,7 +76,7 @@ else: self.nodeStack = self.nodeStack[:-1] def CharacterData(self, data ): - if string.strip(data): + if data.strip(): if py2: data = data.encode() self.AppendItem(self.nodeStack[-1], data) diff --git a/wxPython/demo/bmp_source/001.png b/wxPython/demo/bmp_source/001.png new file mode 100644 index 0000000000000000000000000000000000000000..01cbaae2ff0fd6c4ec77cf8f477a1cf8d32f32ff GIT binary patch literal 2220 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/003.png b/wxPython/demo/bmp_source/003.png new file mode 100644 index 0000000000000000000000000000000000000000..e118e993a33a20d0e50029fe5b37593f7f4caa6b GIT binary patch literal 2220 zcmYk8X;f257RT$omz|JA*&>KMc4!z3-~w(*Y(-GSXww)N(1azRqT)JA19=IcX+?>O zEXqi5p_M@dMZo2d2P%$&617D}Y(ZRz0wO|-5XkG$pXNi=J#|j~>(;INyZ6+uqOcX_ z3|j^Oz&s>)**cSTni@3NG+%cuK4~(fMB!>70M%!tp~6wq8jTBHw;F(L8US`j0x(no zK(-kG@lOF5Cjk)hCjhfH{~|tQ+Dn@svP>AhuQ*nwF#|Nz8g2KlO^Az2Oh|~6Nu{z_ z8ObTAnIH&%-o(N3akiuJ$3S9+^lXm)gRhgGkiaz7KqQ-kHSd1_aVU_7_!HaC<~5;- z(qQUlb(Li3Kzx%Rxw7pRxAxW7E^^bbUu zMLgQ;2O+-aE_si}tbFY02n$9YZ~R=-Qv3N}(bk_bj{e-AuJ=fTY4PSds^B!Xx2jsP z_--pRd}N@{pw%|)+*Qpm3#qQY>gRtAq>m1^b#=+H2n^_s4t8nN4GdCAS3}15hv)tw zGZF&HdxG55Wb_u+Fh&dxI;gh;n3imAq2r(uB(nJ-WzOdpqq+U9^5w3s`}Xa>5ukWO zXPn^6jT7VaIYciToiM&N9n;{N5^fm)U(tr+KjPp0}FK)75om&NL`9P zXnokke99Psoq1`qy0moWs>N}3K0X^#7L4B?DWE5j1)y5cG(C2{nm$6+vFP*=PtQ&J z_mk=LU$t_gA$`9ydah;}HLMc<4h~r990UvJ%)OrXb2v8iMgQcSDXjFdaWdBiM-hs>C{ULyxhjo~ zkA)DKEJ7p$hGQp>OgOnHRy*q+%deku`%?f()Y`fygr-XXn2oWc=sK zM#Wx%pPfhZoADd?L|vd|x?~CU2l%RD zlTBe|19p6NK!q{W-?m0%VEfwl1Ox>oeUkw9D6x?ImBITZ-SBOoH}{IV9-`qt7IgxU z$*T$p`R3ry>{b(3{eI!cm~a)=l+^Spuy8CNM6Eu%@s6?ua>`g=>9=UfsVw==VFc0Rui zSXbg_3+=->*Lc`vh=vAFmyq%Ym*#XG$~4QTpwaDJ z+Qxg%7X``y3lx*kZ3`DSzW1pLC6#4JB4O4+IX=;-iiKL&cNanjxz6<($UQM4LiF(~ z!LLXHj;g8ZwN1hoFxJUION_<>bHcBZq9Y~~m!0L$yJ zT(OI=hk{~gI}h#?22VoXor(r2aG#apCdn$I=c0w24!Fh%co5X^MxGI|lF4Tjm6noC z`D2J*m?RPzsoep;YOl9eH}Eybk-RpcG?QmvtSr69{C!_U$|lOuwHhalwS;UID#FiN z_1Ixk@Kv-a_WYx27U{)WRTI+FL3DpWT;zgsYjIv?(;;(Ghr&_>#|Kn>Lu7|b_=;(u zh7!9(0EC{J1(I}D#g@hkv(KN3BX^Q6ug1n^=JRnYvw+7%jtPDpEYwE4Qn{1KJFX}t zCi_aXgd>@)OPeD0Hz&zyNL+&SMWw*ml=*q23tOy%F~wWEX}y{(vs$G1zP#}iwS=Gc z{rjMUMLh?Grc{Y@B)3Q%GSJ?OtFr?Nva_wu_y{YBHn_DnR5MQ5MpebbC!gV;7~-_F z$%!#%U8#fVgfYWx#KQmfTGK;$tNL*qBo}~ACO$qhiR%@x2;&}iMUO$=tBn4rpSw$e zpa+>MKK$wXNkiS>Yq>K2ryObLIgc;9ew%Zk4`0CpGLy-_9CfGupT+ zg<`z1V~Zg=61{N1l^(i%HMif5y;qt$_RhbQdD=qY%~Yi_)}`^_&Lt+#Rgb{m+3HYs zb zGJ^bpeofiDi$zfQI6L|xGEC(SD4$vR2P~27;Z)?ounCU*O}O=3E`ijQ8HGKp4j-s? z2KHxQRVBGS(*!p6j+#UZ%SbkHT?h$P(~j?*A+?%zHV!& literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/004.png b/wxPython/demo/bmp_source/004.png new file mode 100644 index 0000000000000000000000000000000000000000..0b78a351029b956489a66bf0fbe028a4ffd54daf GIT binary patch literal 2339 zcmXX|Ygki98lH231QL>f3k0wvqTB>A7!F zi#Are32H4`ga|5F1r8Ds3n)djcqvfQ3Kg{=pahbfjl26}=6mLOX6Ak8{oa{xiq@=J zVQ1@V3jnZ-iH=xni5~A86}I$OJoQ@HRm^#6}f>>UyF(oFscT z+WY8&7UcA`GVUH0>Fif5EVwJ!hwzUrtzVwg=&??A;i3z6;Zn(}&R>6!1%7Tdykhquy8W(U44DROl~-8ohXMCbJrzJEIo!&GP&?!Z<#vWF=tP8I3~sE#u72^;Hor<%7%Quh%4fFhZUaU_fLf!FaJ0<3w#+% zZOQhof{=|dpWl^*UNdDrv0YEg_;}ThO9qtH=jxTJiNoZ$f3gg5c{j=r_CAZ_bRmZm z9L%J6d(WApZ*G>i^iNMs8h+#m57u6mC(HDbwB)oTS#naUd3wC{)o7Yx*~N6%-Mh!} zMzprzm`#cu1{76Ln}8Qau>VNO7bZ>{`XVD!bUIx`M1)~FTXEiKG)z3L-yv+0TRH3y z<|a#0l2Xw8MSN8Xe2lIn*g3{AFP{IDa(hF={+7Q+I1dsv|3ENs8N1~m4KB5rq;xZU zeYYhfBzSs8`o{QbdRD8$BD7aX`a_6T?QAmlo%N7(V09K7oO<(E(5*BWQvz3ce2rddwTn4Z?Fg}Cpl z;BGHXx|f$E*GxHek3PAud*d2{e`vl7TUnDBc2hoFe5RNYaw!kCE7rt5U@-~ES(g2jnph~9YrZy}b5bRqwAi#A$4=R0Yac2>o5IknKbWh~_O zme3p@e~*?{zcEgE4}i6?Z6N^XviLfSGmo&W9~VvSB@W-6{GwAX4;=|;yd?;0w`G{A zUUljE{B&sxH!!rS_=RGVgQFAg`n$2)F`o}ez5@PVi);xV6|E5Y++IhLcQliwE5ENR zVU{NC`>t(JV{FLUm$v6jkE5?7#ag*&^Nk;Re6y7D+}(3$)<39sWk24$BeL_Vd)?P( zSHDjHU3FiP%~A>b1R;tS_%4Q$DG`f|isM&X5{85!UxiEE*&8$fm8M3s^BiDaBjAty zdY@xJMFNzIYnq^wogeNolGOOX zo*DThp}XHYF?HwkK4Pt1CF6hCMP!T2rcz}zJF3z}+niO^Dz?2 zH_@1Epj>kow;6|q;FBMa^Rj7{r8cgcUYntlp9`1u}*JNg9OJC7Hm(9dnWnTDS@ z#-$N1b5zF&&j6&58GBuRFz;t+ypy$dDS*%zm|)M+_RiKMHexMnXL{)W@%Y5^9v zQvHjY4$RtK8JhTJab{*F_JFA9f{Q+jZYjCV*!s3$ni>H;aO_r-_%5VssbZM+Gdbg-w?F_Wpgs)ae5ZsMW0;0a3QLCXU)4BD3Yt#Rb} znk>gs{oaIhoT?eX|3q}T7Ty~X{{+R9KwE7UuV$seF8+f~R39JAYYFZ#*TK2;oRzKb z&QtVj$VjNh8M`|0sboYxJM(8p%>aoB;Fl3NkSfw($!SQeMpmwj+BuKuOKGv8{?SO5 zzERpQU{pUOz7K5o%w&Ct7fsC8bJRk)VbY)@KD!y5bUN~<2Zn5@Hw)K+U>g!5^8Z@^PJF*7&Csnb=HP`cZB{R%jN6jzjlOR{E3CfnlwX`9T~xzH0(WkJt2y?OYd zq)>6%rj(a#DT@&rg&s-#to%P}(TG zs{c}%G<56`n)9Sq-$Gavf@&_W$^t;dEpFStWHPbJSx;Mu&_~C9*k-q!HaqChIjD9X zDO4`GONjaiNj{ii+tmjlMgds~(dxMqQ ze2**Fsq3Ntt72@WNH)_t(Zv1Pin#CqNrv0A-c;)oqn2Ab!R5(89OeB!hxEt=hrB2c zO92seTp_huO8t3rAg*UvWJ&$3)KRVIQq%~yH0R8|UF6r01jUXK=j{AfVuraYN(CeB z@Wb%JqtJp31eIJ?ZU+Eky(ND+<5>9Pg4pk;f~e;Tbc1J}nWf6moL$y$%P*a{5j4E^ r?)kJn*OU7)CNk;-P=q(ik^tk~rF*(Ac4S(9IUpu-RYdhilDz)_lS~I9 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/005.png b/wxPython/demo/bmp_source/005.png new file mode 100644 index 0000000000000000000000000000000000000000..8221ef89f4c98e836f5edbd420278281a45c3adf GIT binary patch literal 2505 zcmW+&eKeG58-G4#jA6!1WQ@X0yCq+5zSDNnJa$VInH<|nEsu{uQK@Y=mGL}7k|=5` zD!by1kI#gn-WD4*NeoK~G3M)e-s%10y03GcbDis4_kI0-zx&D)Z{NZ; zTV@6T06REnQ@GK8@!3ov7WETL; zR02SbIRGR)2LLS%0D|WMz+vBs$TP-VW<>C&fQau zLn>5~^5ClH$|7Xr?DfhHr<>1t&hFi%`FtNDdP}zNClkNi`&&96Ok|d-zZJBX@-((y z?m=e)zPc6$$ST3B7I#i(|9t6}?3|plSMr!|OE4_cU@*K_mQ4>0A%hy^H+|BgZdy65 zY{U#&&4{kBDn^85QuD%nXEj?6J=Ak|6MddpZaRu%ire7;ve*wx-?5~{|dDR|RMGD43O6d+6FbT^^eQ)*b4R5nu6uQxUxn=g>%`HN}g&;=I|GEHDR zJ(Kah`zrGH}dTCmyd&6{^QI$m~<*+}Ws>ggEqMLkImiN|FBVT`+>so*>a+wq5x zTN|XByxcI;4kN}ewf3=Lu-N+BADi}CFHHu(R;bI2l1-TX|Nc>5u3o*`eKot_R#@4_ z?B)p-2aUiqv-7GR0nq_!X~{kw6|#4NK9O6co4Yb27L8Ml4JXlWMy*A+VusoCijt)q z4uz#{g-wOLWKzfY)ai#lcsn{`&Er{GSM|_4QTOz58+*pa+(`vyPmT_L7gkrdh&P$~2!uG=r>Ed{M z4Z1>6W`;yUAKilkak7)P9%b;Ha9!~o*ca20a7ij&3;2H;owSkL%Wp74SIW~F3_>KF z)4nP;LY96U8b2X~tiKZiA)T1)fPO&(SIM2ko(K>ih26H5TsbD&ho{OXh-AiZ&&ouZ znT7@H@zrvX@F!#g=p2q;_Lt5Nzsl_)rhs>z-ufhxQ3EfH>z2pSN*Wua)I8hL@AGJa z0b=&d`SYBTH#l=bS2#VT9LO{zkj#({VsUYj^4J8ud4X#B;A?Q3uRIP1va}|Vj#*}&=sx(W!SKj$=T3PP>O~q2F46uHltQ^Ja%~0!^NLiMxuoF5{GT9%IIbF}Rn-Zzk z2v|fcbjZE=+~m=i49$Z5yX3&4k$}AAsaCKP`|F1bI!<{yDgk!GT%>3vVd^%xVswoY zi0MF9eA+JNnoQCg$v53}vw4vm@e53z0IQi1YrJG#kmFb*65~lG>EP~~)Jlq24?w4x zS7{{4xD}1cKH2l%8|8@6F6!MEM1#PUr-$1f-j`jkIqA{rU4U*A-UMA;JvL`M^VSN@ zFaAk<){RJKq7|wX;nCpBX3Zu0@#Sd~bApQu(lfgr4t>HE0j{g0|JvnzsHyATui2gH zs2O~xlvTEAnvDxW$N|pPA^0Sd%N{s#=5D1oGB&7>Mjx*wLf_)-1kS>Yk!@7 z)SIzdkr+?U@m9P@04F4%gw7RQxIuVYobyQwIy77TU~ux)3H^r;E&WIeu}1S~v3SO& zyvATC1E2qf8cUV?5?Z^+{!CK8Br+8bNrZN{n3+j-iqAfR4j}l*Rof86Pm@bw04LI3w%Rbg3!c45T5@)_u5E5x}nliPpWes0J?IyYvk*b2OC zVLcvvbB7x-ZeaL*L{?3S`a~Fh82JY0Ne$ZfExDYk==$TD*|vH{m?(o}cI^`@0UFn> zSI%|_LtaknbQ|CG-F@%wslU3TZ6W%52Ng+F`<6q`j_LisGTZDzRTk>A1B zfB~!-5jC3x205D=zZMot@dBtdKaKAfNaO!x9KHQ8Q}dCcY={LDMX5<&DiQv6vcIad zY@Li9v6F}To7{2W@8PCIKg^h$@m8$Uo2MM{lI>nA28@){o?6l;KB+q5NVm3Mu_G8w zJU+JoE0#h$PMK&9bWKxyH_&7)9EnNG(@o6vS1B=SQ8PV_1*Y$%IlJ)Dob^V?boq$! z?2n?fp)9Mn6h-{RR6GGHdm1s#;=Jl!mAlf*yI#V$7uxinPkN%y)@wO}9-<#EC4rUPJwiS=3exR&#*3;4mi r?inlCRqR>hRyR&F6|P@_12AB-^GK^-XfDIJivhu#w{N=rHJbH5ktURr literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/006.png b/wxPython/demo/bmp_source/006.png new file mode 100644 index 0000000000000000000000000000000000000000..d00538469e1b82a5e7e022996d24e4d639d3fc2e GIT binary patch literal 2230 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/010.png b/wxPython/demo/bmp_source/010.png new file mode 100644 index 0000000000000000000000000000000000000000..f99a5719944446402bd8441365cedd8c6effb97b GIT binary patch literal 2306 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 D8wDLu literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/011.png b/wxPython/demo/bmp_source/011.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ea809f68e58069e4fbf42d575cc8c0130acac3 GIT binary patch literal 2250 zcmXX|dpMNa9$w!!cQeE6LgX?tg(xS3L?`i0E)BU%?JjgNgGg5uN$t^mBZ{&$TP3=} zhiBu`GXj+FU?zOox`vUR8+{G#{nsw~^?xoRI{ z4d6Xw2j73SG5m%0?+uB9pop|>Yp?z5ue6}Yam5$DP*_qQgb5D7Z(BNuGmNKxp&fET zX{qtABkIG4^1MCk%>GhyJUyXlgKnCd@H*Z`cvc=b_ZG zOU%HNiiz3Tsl~p&zDt%Yv9o)3)i-tWy+1ZGM6!wuidybia~YZ8cuA@tvI(rhk3{sg z!BIlZi^~&Qo3gW8claCJt9HmSPqB7p{7GO&Y;3HIAZQjrMaT`w&s{HGnAd|bL>4N$ zC&r9fGs80)X8&}-fyTznmQQ2MmjV}=6@c1c%KE(bh>Mb$u(l~7p-2R`+W(PV;J!m3 z$F#cf$B%ESu2nTkh=&g!hJJ^FRDm|2H-ZCJ;Cam_rVTUq(-i-v4ny>u%5W6GvA8Yf z*@{_k`jSk_@sM-mQcF^UvK(_~${*arEUCtSxJM<}mEHKKb#E_I46& zCu;!O#e(XB!Rw!+~VRHrUfYd>b=l3W}pwv~J`vl;z%aaKwuvRd(-xmm2t=X3Zx zsT0UQB=f;qN*ROf%pzQ}hp+-OPA~Q?C-c`JfSZMLUtdxpdF3U>rbqi#9&*eGI#zK4 z(0D>&S_&mYZ(K%PcWbK+|A_zMHebeec2e6Cp`S<#<=dekLE;32$J_B;JX3k-XVjzp zm>lym%udZuA=L;aR#yrJiaw4`kg7LXwGH%wvMcO3{5G7E#FkoeoPfs%WMyeBEGK9H z!cWurfyzpO{3JG~9@47>3V2YHDzlOsxoTp?*rT}tXXV0B8+4sT+jeBRQX>+HnwpyY z{r#)Ds#!V+&ZAsWA|sRKf;6Eog3vD}h6YQ-<9*9A5%x`(R|pla zQ5dLh5`{Ct4)NG}cnfE}1=(k; ztEs)?7Jh5#+2>)D!!>n_^f>ZBspV7RX`4zv)H*$)izY^zO$tqM164QB5J&xa6;^74 z858iVte4|DjwS+`d0>(6;HT_d)Ne>1sA;d);8&4_5gFmds7vyP@+dC zUPu4-@OWmMRy(|_U9x8bUrH@$XR*yY)4$X|r{SdT6t^cRs34~Jx%x=<1q#pR&JtOu z>=hVK6YkWHsF%b!P99VBL7RjAAUjD8<}8?fYK>Gl%=;aQ4q8MkDMTeRbXuQymXxou9hKFGYd`WglBm!Tkq)aGU)S;{1%_xmrW%CWiKIV;YYEOAS^ z7YDqfDRlNRuh&N8SUO637zwUUCzOApe$)g~<(@CbxgS{Cuf2CX`i%-YiOjOj{0hHw zR;-$QU|q~rI3{Q)p3tb;E1Y#lX|s9+(%DfQq&PHy#Mn5 z5{=mnH|DORIB`BuC^ntQcf1%V3)By_pIhJ|Xl~McX}{?qkN?qJ+6kZ>@(O8pM1dlM z!ofk~X_;%tVJ*@g$BV%&T64Qf$47t z;_(l%(204%t58h&x7*>G_+t~7 zO3$CmemBTgp_VWW%*TyxNL7lS`3vGZ)xDv zJ`~ZjYMhJqG~7DRuhlS5Rn1tT9bP;L5aZu`!J^C3Zy)vDV3sYcEj!(yZ!H1EZ=9ct z&hMsPRHVJGdw!|+S%0MQ`{*SKWy0b$(NFf5fr|MsnFID;IL17^W|PX)jDWC^sNlP6 Hh1vfBPgCn~ literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/012.png b/wxPython/demo/bmp_source/012.png new file mode 100644 index 0000000000000000000000000000000000000000..b9b85b65b09e07c3a3d68f40903a328a25c95a46 GIT binary patch literal 2266 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/013.png b/wxPython/demo/bmp_source/013.png new file mode 100644 index 0000000000000000000000000000000000000000..457e7a0e7bcd72597b7d9480a859a080712865c3 GIT binary patch literal 2313 zcmXX|dpK0<8voW>V~jD(ie%iEOWM@VL{xisX4VuMqU4k)u~0+0s7UP-W({&FJhUq+ zJFBVP?wmNGQtfJ6 zE&#y5N9q}5g~eyIffX(BmjF<4F~UzWrLD0jX`nv<`zZhtLI4;k1>m?o z06Sj+pk@K!GXa2g?6Kez+OwR~KAw`zM~fq6ls@2K-dLMk)vl2xwWepvj}C*+ox%-m>L#p`R=AQ26Ce)7(;7YavpqCGEC6!zx?y& zdp5l7^vdSle0MD6wdJv?LfbVHo4uM!QV&v! zN2yp<+t9Z4PVM)sX3QhE1sWb4YJRc1CakCXlQH?n4_hHLU3jMDbs24PR9Re`jgFQIufl$3Qc?St{)N1kyGrjoxA;3Rd3)i( ziy4(e=c_j2pyF`BFcuX%}A=GiD5u+}O-I9UUoyVwvGN&BF_Q)k(9Ia(C0?dSue5$=cg7 z-yJ|J9gbN7i7;c-)GOz1k;*AF^dYk_GN@6S4Mf}54n zB_HqUyCJSlX6F8Ae9LQI)nvFu-x-`7E2n&KDNDjxrscGBl`u1Wvx_8T_hyT`mF zA-csu5(OK@mz0+RKjZ3l)Dl?se0GZO_DD>SH!G239bezlxNy+|qk@m!-3))jZlIOonH-<&`kb^H z#xX}n_AR}h^~8Y-e`b}eK5QPNE3{>hW32h-D5Ab!6K5N-)cQGd zBdk)xFaw$k(V?M9%$&m2UArOl=(G(XjE|2W8ySK2!Li8IBa~I#hX)Z6>L}&nJIq^? z^7?!~=y?#Gj-1$(Z$jlX*Tqn_3%_lcP*3ckmIr)3Ss0fxH``nbH{bipQO}JK>3%XN zBIx@1=4Q18Pn0tIWll5W68@VY=J5ylZ10E5eX6I8b({)Afql+XsI!hx*D z_TXM-EiE?U6tD%9LC!kgaRuMt?!}gSCDs|&tBT3OllZCJGp`#%HvZF#t7Km@jp5|a z&S}1H*-q2U_{1l1z%4hxLR(j$(eM_qgSDA8?p`O7ZZdGX^6}^6-{!u_D|x6>;o}|H z+87cpB{R)JGw@dOb!|Ao8XFxQ9Ud-st%eK7c>rShx2O(H@mmJ*%ZdUh=TbERmYNn} zc{;J>9zpjGGjBSN*euC?Gx)R>3qK$+fe(1>mc-$0gvQS?lh6P5-!ctF_o~U z1V7_s{C+X2k45NIAVVfu?lh)w*eY#>^+TjF5DQ)2LLMHBCjRlI8xc;D=D3kcm65*E zq0FrYxbeU)$#H>DSp$^pn3WFhP#G&|H`?{}Ld=O|!_qy9Hek>0L9#4tty918x(Rv= zrJIq%5<7NL9;ui#;C+yP;bqG)tpr7J!5xZ;>6s}PY+3eRgZ%XQEXvi0t%7t|Xd(0y z{P<;wRFxX*ek18seH7uNXgYF|vDw^2$<*(dN?Za+du40_n%*V4jp>uPl;PwVvFUvGvBqwF9KUz^Mbfx^{F`05`Bl;>s1e zk`X%Ntd_j(M{KG!!&dM8qS9yB7)dDD`-X*Zr-)9}D}OfJQy+C8&0t&Rnr04hj^j6i zo8p1?b-vPDNHTJZ-Os12=%UOHnzI}IO7}r%=35<4x{Ck*QR9gn`v1O6%AmD2!9%I~ zp4Z$DI1!a_!z!Uji@qnpRk7V80H9=p`Yr^31PG?W-kmN2LWHR_RhAGKFN&g@eP V{eoU+h4wE4e7rVz{&x+L`adSK`L+N6 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/014.png b/wxPython/demo/bmp_source/014.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb6d8b3c1589d1ad0ebea519569c0d75593949e GIT binary patch literal 2226 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/020.png b/wxPython/demo/bmp_source/020.png new file mode 100644 index 0000000000000000000000000000000000000000..f99a5719944446402bd8441365cedd8c6effb97b GIT binary patch literal 2306 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 D8wDLu literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/021.png b/wxPython/demo/bmp_source/021.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ea809f68e58069e4fbf42d575cc8c0130acac3 GIT binary patch literal 2250 zcmXX|dpMNa9$w!!cQeE6LgX?tg(xS3L?`i0E)BU%?JjgNgGg5uN$t^mBZ{&$TP3=} zhiBu`GXj+FU?zOox`vUR8+{G#{nsw~^?xoRI{ z4d6Xw2j73SG5m%0?+uB9pop|>Yp?z5ue6}Yam5$DP*_qQgb5D7Z(BNuGmNKxp&fET zX{qtABkIG4^1MCk%>GhyJUyXlgKnCd@H*Z`cvc=b_ZG zOU%HNiiz3Tsl~p&zDt%Yv9o)3)i-tWy+1ZGM6!wuidybia~YZ8cuA@tvI(rhk3{sg z!BIlZi^~&Qo3gW8claCJt9HmSPqB7p{7GO&Y;3HIAZQjrMaT`w&s{HGnAd|bL>4N$ zC&r9fGs80)X8&}-fyTznmQQ2MmjV}=6@c1c%KE(bh>Mb$u(l~7p-2R`+W(PV;J!m3 z$F#cf$B%ESu2nTkh=&g!hJJ^FRDm|2H-ZCJ;Cam_rVTUq(-i-v4ny>u%5W6GvA8Yf z*@{_k`jSk_@sM-mQcF^UvK(_~${*arEUCtSxJM<}mEHKKb#E_I46& zCu;!O#e(XB!Rw!+~VRHrUfYd>b=l3W}pwv~J`vl;z%aaKwuvRd(-xmm2t=X3Zx zsT0UQB=f;qN*ROf%pzQ}hp+-OPA~Q?C-c`JfSZMLUtdxpdF3U>rbqi#9&*eGI#zK4 z(0D>&S_&mYZ(K%PcWbK+|A_zMHebeec2e6Cp`S<#<=dekLE;32$J_B;JX3k-XVjzp zm>lym%udZuA=L;aR#yrJiaw4`kg7LXwGH%wvMcO3{5G7E#FkoeoPfs%WMyeBEGK9H z!cWurfyzpO{3JG~9@47>3V2YHDzlOsxoTp?*rT}tXXV0B8+4sT+jeBRQX>+HnwpyY z{r#)Ds#!V+&ZAsWA|sRKf;6Eog3vD}h6YQ-<9*9A5%x`(R|pla zQ5dLh5`{Ct4)NG}cnfE}1=(k; ztEs)?7Jh5#+2>)D!!>n_^f>ZBspV7RX`4zv)H*$)izY^zO$tqM164QB5J&xa6;^74 z858iVte4|DjwS+`d0>(6;HT_d)Ne>1sA;d);8&4_5gFmds7vyP@+dC zUPu4-@OWmMRy(|_U9x8bUrH@$XR*yY)4$X|r{SdT6t^cRs34~Jx%x=<1q#pR&JtOu z>=hVK6YkWHsF%b!P99VBL7RjAAUjD8<}8?fYK>Gl%=;aQ4q8MkDMTeRbXuQymXxou9hKFGYd`WglBm!Tkq)aGU)S;{1%_xmrW%CWiKIV;YYEOAS^ z7YDqfDRlNRuh&N8SUO637zwUUCzOApe$)g~<(@CbxgS{Cuf2CX`i%-YiOjOj{0hHw zR;-$QU|q~rI3{Q)p3tb;E1Y#lX|s9+(%DfQq&PHy#Mn5 z5{=mnH|DORIB`BuC^ntQcf1%V3)By_pIhJ|Xl~McX}{?qkN?qJ+6kZ>@(O8pM1dlM z!ofk~X_;%tVJ*@g$BV%&T64Qf$47t z;_(l%(204%t58h&x7*>G_+t~7 zO3$CmemBTgp_VWW%*TyxNL7lS`3vGZ)xDv zJ`~ZjYMhJqG~7DRuhlS5Rn1tT9bP;L5aZu`!J^C3Zy)vDV3sYcEj!(yZ!H1EZ=9ct z&hMsPRHVJGdw!|+S%0MQ`{*SKWy0b$(NFf5fr|MsnFID;IL17^W|PX)jDWC^sNlP6 Hh1vfBPgCn~ literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/022.png b/wxPython/demo/bmp_source/022.png new file mode 100644 index 0000000000000000000000000000000000000000..b9b85b65b09e07c3a3d68f40903a328a25c95a46 GIT binary patch literal 2266 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/023.png b/wxPython/demo/bmp_source/023.png new file mode 100644 index 0000000000000000000000000000000000000000..457e7a0e7bcd72597b7d9480a859a080712865c3 GIT binary patch literal 2313 zcmXX|dpK0<8voW>V~jD(ie%iEOWM@VL{xisX4VuMqU4k)u~0+0s7UP-W({&FJhUq+ zJFBVP?wmNGQtfJ6 zE&#y5N9q}5g~eyIffX(BmjF<4F~UzWrLD0jX`nv<`zZhtLI4;k1>m?o z06Sj+pk@K!GXa2g?6Kez+OwR~KAw`zM~fq6ls@2K-dLMk)vl2xwWepvj}C*+ox%-m>L#p`R=AQ26Ce)7(;7YavpqCGEC6!zx?y& zdp5l7^vdSle0MD6wdJv?LfbVHo4uM!QV&v! zN2yp<+t9Z4PVM)sX3QhE1sWb4YJRc1CakCXlQH?n4_hHLU3jMDbs24PR9Re`jgFQIufl$3Qc?St{)N1kyGrjoxA;3Rd3)i( ziy4(e=c_j2pyF`BFcuX%}A=GiD5u+}O-I9UUoyVwvGN&BF_Q)k(9Ia(C0?dSue5$=cg7 z-yJ|J9gbN7i7;c-)GOz1k;*AF^dYk_GN@6S4Mf}54n zB_HqUyCJSlX6F8Ae9LQI)nvFu-x-`7E2n&KDNDjxrscGBl`u1Wvx_8T_hyT`mF zA-csu5(OK@mz0+RKjZ3l)Dl?se0GZO_DD>SH!G239bezlxNy+|qk@m!-3))jZlIOonH-<&`kb^H z#xX}n_AR}h^~8Y-e`b}eK5QPNE3{>hW32h-D5Ab!6K5N-)cQGd zBdk)xFaw$k(V?M9%$&m2UArOl=(G(XjE|2W8ySK2!Li8IBa~I#hX)Z6>L}&nJIq^? z^7?!~=y?#Gj-1$(Z$jlX*Tqn_3%_lcP*3ckmIr)3Ss0fxH``nbH{bipQO}JK>3%XN zBIx@1=4Q18Pn0tIWll5W68@VY=J5ylZ10E5eX6I8b({)Afql+XsI!hx*D z_TXM-EiE?U6tD%9LC!kgaRuMt?!}gSCDs|&tBT3OllZCJGp`#%HvZF#t7Km@jp5|a z&S}1H*-q2U_{1l1z%4hxLR(j$(eM_qgSDA8?p`O7ZZdGX^6}^6-{!u_D|x6>;o}|H z+87cpB{R)JGw@dOb!|Ao8XFxQ9Ud-st%eK7c>rShx2O(H@mmJ*%ZdUh=TbERmYNn} zc{;J>9zpjGGjBSN*euC?Gx)R>3qK$+fe(1>mc-$0gvQS?lh6P5-!ctF_o~U z1V7_s{C+X2k45NIAVVfu?lh)w*eY#>^+TjF5DQ)2LLMHBCjRlI8xc;D=D3kcm65*E zq0FrYxbeU)$#H>DSp$^pn3WFhP#G&|H`?{}Ld=O|!_qy9Hek>0L9#4tty918x(Rv= zrJIq%5<7NL9;ui#;C+yP;bqG)tpr7J!5xZ;>6s}PY+3eRgZ%XQEXvi0t%7t|Xd(0y z{P<;wRFxX*ek18seH7uNXgYF|vDw^2$<*(dN?Za+du40_n%*V4jp>uPl;PwVvFUvGvBqwF9KUz^Mbfx^{F`05`Bl;>s1e zk`X%Ntd_j(M{KG!!&dM8qS9yB7)dDD`-X*Zr-)9}D}OfJQy+C8&0t&Rnr04hj^j6i zo8p1?b-vPDNHTJZ-Os12=%UOHnzI}IO7}r%=35<4x{Ck*QR9gn`v1O6%AmD2!9%I~ zp4Z$DI1!a_!z!Uji@qnpRk7V80H9=p`Yr^31PG?W-kmN2LWHR_RhAGKFN&g@eP V{eoU+h4wE4e7rVz{&x+L`adSK`L+N6 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/024.png b/wxPython/demo/bmp_source/024.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb6d8b3c1589d1ad0ebea519569c0d75593949e GIT binary patch literal 2226 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 S<4*iHfbaGIuj?LY_WuBwDWv@X literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/027.png b/wxPython/demo/bmp_source/027.png new file mode 100644 index 0000000000000000000000000000000000000000..eb966316ed76967ac0cb1120c200b5db8e27da35 GIT binary patch literal 2222 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 NK>;EDmsVj}e*+s;ze)fA literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/028.png b/wxPython/demo/bmp_source/028.png new file mode 100644 index 0000000000000000000000000000000000000000..ba904b2f88c4b258b69234e81fb7ba2c3f234c54 GIT binary patch literal 2464 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 C`W%Y@ literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/030.png b/wxPython/demo/bmp_source/030.png new file mode 100644 index 0000000000000000000000000000000000000000..8448239d689c05e445c99faa5dcc404789f494a5 GIT binary patch literal 2220 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 P?*<579=fc0sYv!e+1Ihd literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/eclouds.png b/wxPython/demo/bmp_source/eclouds.png new file mode 100644 index 0000000000000000000000000000000000000000..54711b8ed5ecadc23fa46ef4289c17e434d716cf GIT binary patch literal 16502 zcmV)VK(D`vP)0Aikxze zq(WkRGA=Ck?&QwGw0f4LK2Ba!R#&B}tZasqKuT1XqNV=wRO zZheAIT4Rr*q-lPNYHDo$_UwL+l)A>mPI8PsMo(I2aYs^HLRxHsmYl-2te3L9R%UZx zYHy;Nl9H;lK3;s9s;o{{TI$-&QgV!TlAKOzd`L=6U}kD+a&-Rw{6bD#T6T=0w!C_d zl&YSTa*C8{f{asQYf@5Fj*5id+T31ZUv74EewwUGR$zdLj8JBIik_rKLOhnPyppD@ zc9yI{MoQYw#9CryPGWMZzQjgORd!7 ztfsoeqpq}aikwOkQ?`T6UDO!o-4lbV6QqQf`EAf{s&OWja1Y zQfhrZR&0`ngg`<>c5ZCm(!_d}tcHGkUV4{6ma4Q;PE3x5e2;Hq?(e9Zi<|4a&*eRwC38((#E`^w!}zUY*KEFilVGiN<_M{ zq;6_t{`%}nW`w@R%%-B0f|jI0UVL|gghD<%N@9C*hLl!vghEzoUUGz1bdRF4v|3V3 z>fY3HYGihDY-4(ic8Zj$y1aUhoHjBvMnXiAiiA#5ReEx4N@|3NnVf2doOY6=w!++I zf|P!CbY@~*zOt;wy0pT|%w%qJev+I@Mntx%q)J|I^5WF7rkwif+|I(hhMJ_3o}#Lv zlwMwBrka#GR&+WxH2&`7;?l%cT3lpucs@QvbA5nTYIw4~#Eyo9zRJw5qMT)Rg1)}I zut+ys00001VoOIv0Eh)0NB{r;32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RL2p<+B zIUnbmEC2u?07*naRCt{2ynj>^clJNr>NW)A!w=Ec5i_(-T~NAviw_;4$xi zaQqmPYR3iTc-{IT+iK&UHsc~^J@EINL8Vy`PDHY`J zhYy^@%Zn$ac6Z0c@bY^{GX#0r?=#>Zra-$On;5tV>Ie0y0sY}Y{gtS{JMn%zP%5Aw zPeVN2-7$GFh$lmo{~zM-1^v4dy8%xC(ftAWfPTc^!^Q zNEA=w#gRZU;qio9kT;%IZoEHnv|Dhy;K`tVupp1u?g zxSMte`v0f+|0F~Cm~N!c)W4}0tVfWBfQ1 z@Mm;SO)Z)dxql0uZukOu_pS0VQ?)U>6Q}+VVB78TkndeFT{H6c&D*;-H8F8_R}4?# z-2ooMcVHX*1PPfJm)D&~mZ?-tfeY*%O$F-aYY~3lgJwh+0I$R}�TkAkQ6b>TfO-Y;T|$N@3c#oETp``#GNfgLM+E)hqxkQm zqrB4EV0b~eHjrR&jFM$XTq1tnKQW`|&sz9O+#Ngt@CW2$xUxZ&Am0o2-k+G)g(VBr zFIqGsp2~}ZfAXY9R22fAUc{3K{=qtu8gL7ULv;f+$euj#Cs{V=65_QtycU3f{zR;R zwa%jw~D$<^O>H z9M`=Y;~((m6#SGZ_y;V=Q<}3>xdNX5IesKWY95|7C9s*t0`9HFdI$;DOMre656FYM zjj6k*x@$pbiccCmqqdu`pWsl?zi==&AYWUHGGH$#2FfIM3)k6=)gKO&?87q$1gP3#J0DLb~zwIS=#~9})3@|EH!>yHS7YqY}w=$-7fRdI210z)&H&lo2Va z3Y93&!;RrDlPdTgeo9>QqcF+SFC~I_o-!hbKY)uT<3-U2t8E!=uTtSfE z%?GwS4kWwzG~vJ1CW`)vfrepI1m)4=yAyYJBLEQW-VO3FI-vW}L0!PNQ3vQ(&6;;F z{E1Vw{~P?f`B@E=#v$VqgB;@fBhUvLungoEiuj)u&8#)n z)negH?dIc(s9|1A4d@4ZYj;BkMjg7KJTSC-cVKwr>o>%i|HXGw!QPl~Hz8M~LWf5{kR*=yFX`a2^sef3sXwfG^s|#Eu4*(JJ2eL%{ctD5(C&VQt zJpJpZ7YVf-$iw4tL@>52F~jb_pZaK+M6#$S?(X>G(4$B<;goI!IF<0DcM}!`q(MGD zLT9^8KCU*dmNzzzM~C_Q$tRx#+!T`+E+d!+Qf4wZm2bBJkEHU>;fGsH-WmL&ypVv; zE_!<1n@?|9^ynvlnCccW_ zbDO=j-8>z;@m$_Vi+*$_?2Nx8DzcURO-vW~M|VrSgjpw!9~n}4kAjE(u;|gJpFV4{ zYc?$c`3JPcB7tJ^pne9(5Es)UvLY^~7G}2|{1!8+G)f7^b|i3t7@l9X{9>Y~``JYa zZ!TG~BJ)W$sMQU zyD)9zcxS{3Gr%8y1ono7`TeJEtTAoj{X@$Y6+!u0fsQ=dR3y%Imi3zQqsCiLjEoI< zA2$x^bq}b51nLT;F1nka8M^tp88h0&Ck(9b!j6UK)(T-e^; z(UEiY>fyEh{U7xAADDP;W3_>fpal82je%N*2K1Cjq8b`T>QA(`&%$){_j7cN4Tvknh@<2aN%DC-Qbb3e*AKu$n5b z369uxtMa-8{60}Wu8a5m(FFUqp`imKHIc(@U*DLBUcJ42`Z%+7STQtPfr(S zVnWT~!~Ol2!GVWEu7+IgXumL7IPz^OfaUd<6Fx#G*o#@gU!ry{+c(j!VKuA-W+A}d zl?MY;46h&T7385QcMD4!3`9>)+>iXg9XP`LW6>A#x5Q)|>pc(t6y&?!4_E+e8<dboGG0Av_o%7#(n90|3GA8R6l| zMy}HB5FCVAhp7s`JzD?e#D&#gbaWgD2?73GzWl)<_|>srSwL16NyUnS`wU$?gC6yJ z8=4!&M(SI~TXw|8+D)caU8C=#{z`{I(BBO-fzV?)24wG+46GT@cp+l!rbTh1qcMOc zJR`h-JRQVy2mV_Bj^W|_qcQiuAA<`s$b0a0Pt2q5%?*>3NbqQ#V^0A2a5w?*khjR= zAhj_rW)V~!R#SJD^`1qicG{x`)&Zn&)KA{x9~{$S5~4y|2kIYe0RF7`>*U0RFWNii z=lpI-?Pz$$u?&!x-ioIuPI3Y01J3LJ;Di3PAvrnoJGQSr{^ba?cRZBUAny+9hb-bP z2=mq)%JFKj7?zaOb$5+ox@3TRl+~xnBKHjb9=`c^L8<{QO3wKG5}rZ+H90rz31~ny z8IB5Bv2*N3~XEi3?)IQ)35UBpoV-1nbu}2$8QivC}BxFMdUOWSS$L<9lfIk`o zaEx#m8Z$qwt`=JuUn)oQHja+kH$)%bj-JUmeE5UQhxh{+)Lc-InVH!r_Uw&NBr>|t z6~C?uZEJ4E5(ET72Ibo?84cy-&b^MY+wA(`3FJ{Z&;;lEH5{Jy}hEnG1zw!B^}_t%L}d?x_k&3bYOnR?^a)!*l-cr zsnGy}2_4V0b>HHI@ z&j$GdK|TZBGdg-K1}br8oJ8~W_7<-Ravp+r{V3#$fwEXEs6UA3HvDk(_*>d0V;{c< ze&7}O8U7`sR~cR+DFJVm_$6Tywtk|X%?odISS;Bb%8Ph_&ZsKyB@Og0Y#3ht=(Km* zhX)csKgV%WH>8YUZyw73!QL_s?#2RCxMA`*G_d(O;H8{(h=&7vjkgdkWArGy_|O&b zAABw!>hBK$2DP^zkDiQ-X_SGv6zBd_#2;|yXgG|H?|DP7_P4Uw!GJ*$zFTL?z@2FC zr$PLA7%VtNsjLp~>JIY@4D$Q!7y9c>&sZo5>}{+L>gSm@+6A3$BjySgpw7P79Z@Y% zQpX-_Zf@>-nUht2`l&!5C0+mvF?@P6GWZS_o&m}H6nu_7RbU|XdV-J|MMf(j9W$`( zjfN)-KNJlOEC*5x_yg8|v*4R=t}M8`W*^EIi1Lsbqj+l|<5|Bwa?LRGuu}uAtOJ$`@5bwBTaiR7#3HqCF8N;gUIcp7KqN3phr*Gc#S1P5P% zU@qvZ8Lr!F;Anz~xCIZ?|BTU3V#iMmj6esQ)3)KuiQ|}MIam8XxIB3lh89fHJj)osoE|SD)}r|x=B4v8I107 zp`!5i!dIQ9golC6lrKYl`K>oPdmv(zIvenpi~2EANAp8ZoEmE$s~;JGs$Wx66B!Lz z_Q9bwm#Pg?Cz1Vc{ybJUeC3;OmMv?G4GnD_8G|IiyzAI8C0hK{D%Pvf^mSqan@rv+jfr0qjA-_uKg$IIjfU^dP=4wrGkcF^ z8XA@0^T4l6{1jAI7l218hg&8NaR^AMlvNfed&VcBw|9)3t<#*Xg99AvJ+$nbZ~B+O zNGUS}<-76Nefq*cgKGWna1PEsQw8p37VZv}tBb0tM?`iOJrXA3NFdc%#uxa<|Dt9mxD_UFg86 znl`&egKmN2y1fIc^nx!wH#WLC&LIop*}E5}-pt2$Tmk+p8(Ei-0FH!_tZsY~hM*gN zE@*6wCn-`E)E~YV;6R;(_&lqzPkhkEvQJBZ51KQVV334SsWG0*zQv!Ikm0>LK4KYKIRL9wl0;|0&No3^Z5wW1q>1tYyE4+d95b;zu=a@ET6QcEWCCKI@tS)G|#4da+wCY5reg_BCf3uK~vd=}Su z^lez2{&ThW=rNG*&CD#wOgI5)^vyqC|=54+- zH#DauHuecA$#ImWQYy%gRzte)nggfmE^WTFIb*N#H{QS**s@BY88iLpG+W7 zCg(Q7NKGlEnMNs;?t)B%5iDwK1T=03%{-80O;J@G$i&r0%}kwEou0xS~#<{w!Ny;Wx|ww9?> z#f(Mh*`ym5K?cg^fCZ7H?(2}qPVWoK%q^OSCfS!cno(qBrJ#OB)PD#547T<7;<2Om z!e8nBtU43)OEVk)1O%Ei^#J|^$g;?e=DLq{puZ_)A?W7<@{JC6Iq2sUKLL?1+Dyn- zz~576hYs9aShX!JE30gwDoZZl&y>2$s|yU9$4`yb3=h0)%!CC_Z*O(x)D!$M%;$tA@e}UwgyqFTgTvc!kYc2Krqy`oTY+RhLsX zviE(7Y4~t7%kEcRZ@pURf8FSo>X|I`PesLyei+yb8qZS-hq78~F}xeraQMM>%FGPt zWE&0?df!o4i_6Luf`0^it1DrF(rBa}ATu{2ffhGxQbI-)6ciXYx8R~6GIn`Wg~}$^ z3j}I3=;tN9ykpB$4ux!~k&2Jr?p0#H>DDR`mN<)!@T*bB&u7MfoBA#G0{8sXIbgcb^ z^~hlEAczO$4YZo8EGm~tjhVldcqjTt)_M0AG;Z-uOtR0>L~+VO5TCVY&z>Xm?two; za^iSL!+zu4@f(Zi2q?kjGP0mLQ{o?+h}{S)sMn!Gjh72=jG8L9Zk~KQ^lVp}wJt+`++F(=&LAoO)`~xPL`urSg=p`LyxV6cNkh3?iaBmz z{gFBKpJz5g_x47IL~3R?RphEL03sfvQO~5Ken-J2nE3J!)E_M{LisTmWUtpFfoi-T z^7zq8bMJrO`*_&!hJ5=) zR6lr&e7Uibpk(I(kFl|bHEj=xHC4TN>HWH@3mYWY2%QZAjK}nz>3R3SzxR6U_MFK5 zhI`-#{hoNxZ!k1AZj#h*-|_m(8!v5w$!5HL!gNj1v=I1%1QO&MjU>T2K!0Nit7$vn zJ-RU??Hmn6`^qFRohc+3Ujvu5OthDw@q8}{ap!N57^&CQ!HT>{^1d=8w0W6u27 ziUH27SwTFFuuP;J##Q4;phu#P9)0}MW{}@_-Ma>c=rt#;K)BoVpFd4|Wak^vKkwN? z5B$!{*1di`e`0mjmUNPqE3%H{&f@(O#P0z7=Z&!HC@3f|nEPJj;@C|`UwY3kiCvvD zz@E%SQBb@B0?76{}vxGOnQ zhRXs2v?j=6_{E2UFhj#oq^K4G{M?`c?jkn~74Gu$&ox|F4Xe}PKMv1nYbz{V1IJ&X zjW5gjFVKIhysVO|lo`%vhS|q96t>NYY;DQ6+wG<*Z+)}9Z)?+$ii%l#pr#0f06Y$^ z(v8b3
  • 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/bmp_source/logo.png b/wxPython/demo/bmp_source/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4cca130f1404c7a21bdce0aa34fe21f207914d1e GIT binary patch literal 1092 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 literal 0 HcmV?d00001 diff --git a/wxPython/demo/data/tips.txt b/wxPython/demo/data/tips.txt index b56d78fb01..ca4a6e2d6c 100644 --- a/wxPython/demo/data/tips.txt +++ b/wxPython/demo/data/tips.txt @@ -2,6 +2,6 @@ Each of the leaf items in the tree is a separate demo. Click and learn! Use the source Luke! Many of the demos have some helpful overview text associated with them. Simply click on the first tab in the notebook control after selecting the demo. You can switch back and forth to the demo page as often as you like. You can also view the source code for each demo by clicking on the second notebook tab. -wxPython now has a company providing commercial support, consulting and training. Go to http://wxpros.com for details. You shouldn't pee on an electric fence! -Be sure to subscribe to the mail list. Go to http://wxwindows.org/mailman/listinfo/wxpython-users today! +Be sure to subscribe to the mail list. Go to http://wxpython.org/maillist.php today! +The wxPyWiki is a place where wxPython users can help other users, and is a colaborative documentation system. See http://wiki.wxpython.org. diff --git a/wxPython/demo/data/widgetTest.htm b/wxPython/demo/data/widgetTest.htm index 22d6398914..c88f019b7f 100644 --- a/wxPython/demo/data/widgetTest.htm +++ b/wxPython/demo/data/widgetTest.htm @@ -4,24 +4,30 @@

    Mixing wxPython and wxHTML

    -The widgets on this page were created dynamically on the fly by a custom -wxTagHandler found in wxPython.lib.wxpTag. You can look at the sources -and doc-string
    here. + +The widgets on this page were created dynamically on the fly by a +custom wxTagHandler found in wxPython.lib.wxpTag. You can look at the +sources and doc-string here. +

    The button below is added to the page like this: +

     <center><wxp class="wxButton" width="50%">
         <param name="label" value="It works!">
         <param name="id"    value="wxID_OK">
     </wxp></center>
     
    +
    +
    +

    Notice that the button click event is actually caught by the panel that contains this window, which then logs it in the window below. diff --git a/wxPython/demo/demoMainLoop.py b/wxPython/demo/demoMainLoop.py index 23067e9329..3d66c2ae4c 100755 --- a/wxPython/demo/demoMainLoop.py +++ b/wxPython/demo/demoMainLoop.py @@ -54,7 +54,7 @@ class MyFrame(wxFrame): def OnCloseWindow(self, event): - app.keepGoing = false + app.keepGoing = False self.Destroy() def OnIdle(self, event): @@ -104,12 +104,12 @@ class MyApp(wxApp): def OnInit(self): frame = MyFrame(None, -1, "This is a test") - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - self.keepGoing = true + self.keepGoing = True - return true + return True app = MyApp(0) diff --git a/wxPython/demo/encode_bitmaps.py b/wxPython/demo/encode_bitmaps.py index 489e6f6e64..b3d027eb11 100644 --- a/wxPython/demo/encode_bitmaps.py +++ b/wxPython/demo/encode_bitmaps.py @@ -6,7 +6,7 @@ This is a way to save the startup time when running img2py on lots of files... """ -import sys, string +import sys from wxPython.tools import img2py @@ -60,10 +60,46 @@ command_lines = [ "-a -u -n WizTest1 bmp_source/wiztest1.bmp images.py", "-a -u -n WizTest2 bmp_source/wiztest2.bmp images.py", + + + " -u -c bmp_source/001.png throbImages.py", + "-a -u -c bmp_source/002.png throbImages.py", + "-a -u -c bmp_source/003.png throbImages.py", + "-a -u -c bmp_source/004.png throbImages.py", + "-a -u -c bmp_source/005.png throbImages.py", + "-a -u -c bmp_source/006.png throbImages.py", + "-a -u -c bmp_source/007.png throbImages.py", + "-a -u -c bmp_source/008.png throbImages.py", + "-a -u -c bmp_source/009.png throbImages.py", + "-a -u -c bmp_source/010.png throbImages.py", + "-a -u -c bmp_source/011.png throbImages.py", + "-a -u -c bmp_source/012.png throbImages.py", + "-a -u -c bmp_source/013.png throbImages.py", + "-a -u -c bmp_source/014.png throbImages.py", + "-a -u -c bmp_source/015.png throbImages.py", + "-a -u -c bmp_source/016.png throbImages.py", + "-a -u -c bmp_source/017.png throbImages.py", + "-a -u -c bmp_source/018.png throbImages.py", + "-a -u -c bmp_source/019.png throbImages.py", + "-a -u -c bmp_source/020.png throbImages.py", + "-a -u -c bmp_source/021.png throbImages.py", + "-a -u -c bmp_source/022.png throbImages.py", + "-a -u -c bmp_source/023.png throbImages.py", + "-a -u -c bmp_source/024.png throbImages.py", + "-a -u -c bmp_source/025.png throbImages.py", + "-a -u -c bmp_source/026.png throbImages.py", + "-a -u -c bmp_source/027.png throbImages.py", + "-a -u -c bmp_source/028.png throbImages.py", + "-a -u -c bmp_source/029.png throbImages.py", + "-a -u -c bmp_source/030.png throbImages.py", + + "-a -u -c bmp_source/eclouds.png throbImages.py", + "-a -u -c bmp_source/logo.png throbImages.py", + "-a -u -c bmp_source/rest.png throbImages.py", ] for line in command_lines: - args = string.split(line) + args = line.split() img2py.main(args) diff --git a/wxPython/demo/hangman.py b/wxPython/demo/hangman.py index eb591471a8..f2e09b5bec 100644 --- a/wxPython/demo/hangman.py +++ b/wxPython/demo/hangman.py @@ -14,7 +14,7 @@ Have fun with it, Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)""" -import random,re,string +import random,re from wxPython.wx import * @@ -47,7 +47,7 @@ class WordFetcher: m = reg.search(self.words[index:]) if m and len(m.groups()[0]) >= self.min_length: break n = n - 1 - if n: return string.lower(m.groups()[0]) + if n: return m.groups()[0].lower() return "error" @@ -292,7 +292,7 @@ class MyFrame(wxFrame): menubar = wxMenuBar() menubar.Append(menu, "Game") menu = wxMenu() - #menu.Append(1010, "Internal", "Use internal dictionary", TRUE) + #menu.Append(1010, "Internal", "Use internal dictionary", True) menu.Append(1011, "ASCII File...") urls = [ 'wxPython home', 'http://wxPython.org/', 'slashdot.org', 'http://slashdot.org/', @@ -349,7 +349,7 @@ class MyFrame(wxFrame): def OnGameDemo(self, event): frame = HangmanDemoFrame(self.wf, self, -1, wxDefaultPosition, self.GetSize()) - frame.Show(TRUE) + frame.Show(True) def OnDictFile(self, event): fd = wxFileDialog(self) @@ -433,8 +433,8 @@ class MyApp(wxApp): wf = WordFetcher(defaultfile) frame = MyFrame(None, wf) self.SetTopWindow(frame) - frame.Show(TRUE) - return TRUE + frame.Show(True) + return True @@ -458,7 +458,7 @@ def runTest(frame, nb, log): wf = WordFetcher(defaultfile) win = MyFrame(frame, wf) frame.otherWin = win - win.Show(true) + win.Show(True) #---------------------------------------------------------------------- diff --git a/wxPython/demo/images.py b/wxPython/demo/images.py index 6c68ddafa1..8e35d1c1f2 100644 --- a/wxPython/demo/images.py +++ b/wxPython/demo/images.py @@ -1,5 +1,5 @@ #---------------------------------------------------------------------- -# This file was generated by C:\projects\wx\wxPython\demo\encode_bitmaps.py +# This file was generated by encode_bitmaps.py # from wxPython.wx import wxImageFromStream, wxBitmapFromImage from wxPython.wx import wxEmptyIcon diff --git a/wxPython/demo/infoframe.py b/wxPython/demo/infoframe.py index 99507a6547..7f19771460 100644 --- a/wxPython/demo/infoframe.py +++ b/wxPython/demo/infoframe.py @@ -82,14 +82,14 @@ if __name__ == "__main__": outputWindowClass = wxPyInformationalMessagesFrame def OnInit(self): frame = MyFrame(self.stdioWin) - frame.Show(TRUE) + frame.Show(True) self.SetTopWindow(frame) if isinstance(sys.stdout,wxPyInformationalMessagesFrame): sys.stdout.SetParent(frame) #self.redirectStdio(None)# this is done automatically # by the MyApp(1) call below print "Starting.\n", - return true + return True app = MyApp(1) app.MainLoop() diff --git a/wxPython/demo/pyTree.py b/wxPython/demo/pyTree.py index e463fffa10..72cb2ff317 100644 --- a/wxPython/demo/pyTree.py +++ b/wxPython/demo/pyTree.py @@ -78,7 +78,7 @@ class pyTree(wx.wxTreeCtrl): wx.wxTreeCtrl.__init__(self, parent, id) self.root = self.AddRoot(str(root), -1, -1, wx.wxTreeItemData(root)) if dir(root): - self.SetItemHasChildren(self.root, wx.TRUE) + self.SetItemHasChildren(self.root, wx.True) wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding) wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed) wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) @@ -121,7 +121,7 @@ class pyTree(wx.wxTreeCtrl): new_item = self.AppendItem( item, key, -1, -1, wx.wxTreeItemData(new_obj) ) if dir(new_obj): - self.SetItemHasChildren(new_item, wx.TRUE) + self.SetItemHasChildren(new_item, wx.True) def OnItemCollapsed(self, event): """ @@ -205,9 +205,9 @@ if __name__ == '__main__': def OnInit(self): """OnInit. Boring, boring, boring!""" frame = MyFrame() - frame.Show(wx.TRUE) + frame.Show(wx.True) self.SetTopWindow(frame) - return wx.TRUE + return wx.True app = MyApp(0) app.MainLoop() diff --git a/wxPython/demo/run.py b/wxPython/demo/run.py index 82d702bb43..fcf5bd9029 100755 --- a/wxPython/demo/run.py +++ b/wxPython/demo/run.py @@ -25,7 +25,9 @@ from wxPython.wx import * class Log: def WriteText(self, text): - sys.stdout.write(text) + if text[-1:] == '\n': + text = text[:-1] + wxLogMessage(text) write = WriteText @@ -38,7 +40,9 @@ class RunDemoApp(wxApp): def OnInit(self): wxInitAllImageHandlers() - frame = wxFrame(None, -1, "RunDemo: " + self.name, size=(0,0), + wxLog_SetActiveTarget(wxLogStderr()) + + frame = wxFrame(None, -1, "RunDemo: " + self.name, pos=(50,50), size=(0,0), style=wxNO_FULL_REPAINT_ON_RESIZE|wxDEFAULT_FRAME_STYLE) frame.CreateStatusBar() menuBar = wxMenuBar() @@ -47,7 +51,9 @@ class RunDemoApp(wxApp): EVT_MENU(self, 101, self.OnButton) menuBar.Append(menu, "&File") frame.SetMenuBar(menuBar) - frame.Show(true) + frame.Show(True) + EVT_CLOSE(frame, self.OnCloseFrame) + win = self.demoModule.runTest(frame, frame, Log()) # a window will be returned if the demo does not create @@ -56,6 +62,7 @@ class RunDemoApp(wxApp): # so set the frame to a good size for showing stuff frame.SetSize((640, 480)) win.SetFocus() + self.window = win else: # otherwise the demo made its own frame, so just put a @@ -68,17 +75,24 @@ class RunDemoApp(wxApp): # It was probably a dialog or something that is already # gone, so we're done. frame.Destroy() - return true + return True self.SetTopWindow(frame) self.frame = frame #wxLog_SetActiveTarget(wxLogStderr()) #wxLog_SetTraceMask(wxTraceMessages) - return true + return True def OnButton(self, evt): - self.frame.Close(true) + self.frame.Close(True) + + + def OnCloseFrame(self, evt): + if hasattr(self, "window") and hasattr(self.window, "ShutdownDemo"): + self.window.ShutdownDemo() + evt.Skip() + #---------------------------------------------------------------------------- diff --git a/wxPython/demo/simple.py b/wxPython/demo/simple.py index beed3ee0cd..6b28148228 100644 --- a/wxPython/demo/simple.py +++ b/wxPython/demo/simple.py @@ -33,7 +33,7 @@ class MyFrame(wxFrame): sizer.Add(text, 0, wxALL, 10) sizer.Add(btn, 0, wxALL, 10) panel.SetSizer(sizer) - panel.SetAutoLayout(true) + panel.SetAutoLayout(True) panel.Layout() EVT_BUTTON(self, btn.GetId(), self.OnButton) @@ -46,6 +46,6 @@ class MyFrame(wxFrame): app = wxPySimpleApp() frame = MyFrame(None, "Simple wxPython App") -frame.Show(true) +frame.Show(True) app.MainLoop() diff --git a/wxPython/demo/throbImages.py b/wxPython/demo/throbImages.py new file mode 100644 index 0000000000..54535e5bdc --- /dev/null +++ b/wxPython/demo/throbImages.py @@ -0,0 +1,4362 @@ +#---------------------------------------------------------------------- +# This file was generated by encode_bitmaps.py +# +from wxPython.wx import wxImageFromStream, wxBitmapFromImage +import cStringIO + + +catalog = {} +index = [] + +class ImageClass: pass + +def get001Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\x9fIDATx\x9c\xcd\x98_o\xdbF\x16\xc5\x7f\xf7\xce\x0c\xa5\xc8\xb2];N\xea4M\ +\x8a\xc2@\xb6[\xa0E\xd1\xa2o]\xf4#\xef\x17\xd8\xa7}\xeck\x8b\x16}\t\x908\x9b\ +\x7fnc\xc9\x96H\x0e\x87\x9c\xd9\x87\x19QR\xd2\xf7]\x02\xf4P\xb2L\x1e\x9d{\ +\xee9w,@\xe2\xff\xe0\xb0\x00_\x7f\xf7\x0f\xaaj\x82s\x15\xc6Z\x8c\x1aD\r"BJ\ +\x89=\xaci\xb3\xa4\xed\x1bIv~)\xfc\xe5!\xfb\x97\xa9\xfcL)\xf1\xef\x7f\xfd3\ +\x03\xa9\xaa\t\xd3\xe9\x8cj2\x1d\xc1\xe8\x06\x08\tR"E\xe8\x87@S\xaf\xf0M\x8d\ +ok|\xd7\xd2\x87\xc00\xf4\x88\x80\xb1\x15\x93\xc9\x94;\xb3C\xe6\x87\xc7T\x93i\ +~\xb0\xc8\x0e\x08\xc9p\x05RL\xc44l\x19q\xae\xa2\x9aL\x99N\xef\xe0&S\xac\xad0\ +\xaa\x1b\xe8\xf8\xb6aU/\xa9WKbJ\x18\xab\x1c\x1c\x1e2KG\xa4\xd8\x13\xfa\x9e>t\ +\x84\xae\xa3\xa9W,\xde]!\xc6pzz\x9f\xb3\xfb\x0f\x99\x1f\x1doa\xc8\x06\x8e\ +\x90R$\xc6\xb8\x05b\xac\xc5\xb9\n7\x99RU\x85\x15c\x00ay}\xc5\xeav\x811\xca\ +\xe9\xd9}\x9c\xadP\xa3\x00\x0c\xc3@\xdf\x07B\x08\x84\xae\xa3\xebZ|\xdb\xd04k\ +\xda\xa6\xe6\xcd\xabg\\\xbd}\xc9\xa7\x8f.x\xfc\xf9\x17\x88f\x00H\x06\x94Rd\ +\xe8w\x181j0\xd6bm\x95\x01\xb9\x8a\x18#\xcb\xc5\x1ft\xbe\xe6\xe4\xee\x19\xf3\ +\x839\xd3\xd9\x01UUA\x82\xbe\xef\t\x9d\xc7w\x1d\x9d\xf7t\xbe\xa5\xedZ|\xd3\ +\x94\x12OPU\xd6\xab\x1b~\xfd\xf9\'no\x17<\xf9\xf2[f\xb3y\x06\x82@J\x88\xee\ +\x00\x115\xa8\x1a\x8c*\xc6\x18b\x8c\xdc,\xffD$\xf2\xf1\xf9CN\xee\x9eqzr\xca\ +\xc1\xfc\x00\x11\xa1\xa9\x1b\xd6uMS\xd7\xb8\xb6\xc5\xbb\x16k-\xc6Y\xac1\x18c\ +QUT\x15\x11%\xa5\xc4\xb3\xa7\xbf\xd1\xf9\x96\xaf\xbf\xfb\x81\xd9\xec\xb04BD\ +\x07\xdd\x01"\x92\x05U\xea\xb7\\\xfc\x81H\xe4\xde\xd99\xe7\x0f>\xe1\xd1\xe3\ +\xcf8??\xa7\xef\x07\xae\xaf\xff$\x84\x01\xd5\x16U\xc5\x18\xc5ZK\xac\xaa\xd23\ +\x82\xaaA\x8d\xe6u\x04$\xbcy\xf5\x8c\xdf\x7f\x99\xf2\xcd\xf7?"\xa2\x80\x8c\r\ +g\x01RJ\xa5;`y}E\xe7k>>\x7f\xc8\xf9\x83O\xf8\xdb\x17\x7f\xe7\xe2\xe2\x82\x10\ +\x02\xcf\x9f?g\xb9\xbca\xbd^\xe1\xdb\x96\x10:\x86\xa1\xcf\xdfL\r\xceU\xa8Ha$\ +3c\xccf\xb5XW\xf1\x9f\x17O9<>\xe5\xe2\xc9W\xa5\x1bwJCiQ\xdf6\xacn\x17\x9c\ +\xdc=\xe3\xe4\xee\x19\x8f\x1e\x7f\xc6\xc5\xc5\x051&.//y\xfd\xfa5\xcb\xe5\x82\ +\xa6\xae\xf1\x9d\'\x0e\x03\tA\xd5"\x12\xcb\xc3\rj{\xd4\x18\xac\xb5\xa81\x18\ +\xeb\xb0\xd6\xe6\xd7\xaa\xbc|\xf1\x94\xbb\xf7\x1ept\xf4\x11i\xb7k\x00R\x84U\ +\xbd\xc4\x18e~0\xe7\xf4\xe4\x94\xf3\xf3sB\x08\\^^\xf2\xf2\xe5K\x16\x8bk\xea\ +\xba\xa6\x0f\x1d\xa9\x98\x81 \x88&\x12\x8ahD\x06AT1Ewj,\xd6d\x10\xa2\x86TJ\ +\xff\xf6\xd5%\xf3\xf911\xa6} \xfd\x10\xa8WKN\xcf\xee3\x9d\x1dp0?\xa0\xef\x07\ +\x9e?\x7f\xce\xeb\xd7\xaf3\x88\xf5\x9a\xd0\x07J\x15G\x8f\xcc\x80@0\x88U$\xc6\ +\xa2\x8d\xc2\x90\xc9\x806\xc2\x8di`q}E\xd3\xac\xa8\xaa\xe9\x0e\x90\x04M\xbd"\ +\xa6\x84\xb3\x15UU!"\\_\xff\xc9ry\xc3r\xb9\xa0\xae\xeb\x11\xc4\x9es\x8b\x94\ +\xf7\x12I\xb2X\x8d1\xa4\xa4\xa8\xa6\x11\x84)N\x1dcd\x18z\x82\xf7\xdc,\xdeqz\ +\xef|\x9f\x11\xdf\xd4\x18\xab\xd9\xac\x124uC\x08\x03\xeb\xf5\x8a\xa6\x94c\ +\x9b3\xec_\x8cn9\xc2C\x0b>c\x18\xbb\x07 \x0e\x03}\xe8\xf0mC]\xaf8\xd9\xd5H"\ +\xe1\xdb\x9a\x83\xc3\xc3\\\xa6\xbeg]\xd7\xa8\xb6\xf8\xb6\xc5w\x9e\x94> c\x07\ +\xc4\xf6\xc5h\xe1"\xa8\xe4\x98\xc8\x9dc\x80\xec\xc6]\xf0\xdci\x0eh\x9a51\xbd\ +\'V\xdf\xb5\xcc\xd2\x11\xc30\x10:OS\xd7\xa8*!t\xc4a\xc8)\xb5y\xea\x1e\x13\ +\xbbe\xda\x96KTQQD\x15\x01T-\xa9\x00\x99\xfa\x96\xc9d\xc6zuS\xd2}\xa7}\xfb\ +\x10H\xb1\xa7\xef\x03\xbe\xebpm\x8b1\x9a}\xa2\x84\x14\xa4m\x92\xfeU\xdao:I\ +\x04\x15\xc9\x825Y\x1b\xa6L\x08C\xdf\xe3\xaa\t\xd5\xa4B\xd4\xc0\x1e\x90$Y@}O\ +\x08\x81\xce\xfb\xd1\xb6\xb3YYDS\xc9\xee\xbf\x02\xb1_\x92|jq\xde\xdc\xc6\x1b\ +\xcaz\x17p\xae\xc2Z\x875n$w,\x8d\x08c\x94w\xbe\x1dm;\xcf%1\xfb\xc4\xf6k\x7fP\ +\x92m\xaanAh\x01a\xad\x1d\xebf\xac\xdd:\xaf\xb3\xef1B\xc2\xd8j\x8c\xf2\xb6k1\ +.\xd7\xd4\xb9\x02F#\x82)-\xba\xc3B*u\x92\x1d6TF6\xb2\xa3:\x10!\xc5T\xee\x95?\ +\xef\\\xf5\xbeF\x84\xc9d\x9a\xa7\xaf\xb6\xc17\r\xd6\x98\x1c`\x92}A\x06\xc9f\ +\xb5\x81![:d\xe7\xd4\x1dGU\xcd \xac\xcd\x8f\x19\x8c\x969$\x11\xe3\x80\xb5\ +\xd5\xc8\xeaX\x9a;\xb3C\x16\xef\xaeh\x9a5\xd5d\xba\x17\\j\xfb\xac\xfe\x18\ +\xc7\x81i_\x0f\xb9\x1c\x99\t3Z\xbas\x0e\xeb\x1c\xd6XbJ\x90|6\xb4\xbeg\x08=\ +\xce\xb9\xf7\x19\x81\xf9\xe11b\x0cmS\x8fC\xcd\x18\xe5\xc6\x94\xec\xd0\xec\ +\x98\xb2\xdb\xa2;\x9aP\xcd\xd9R@8W\xe1\xacCT\x89!\x14k\xe8\xe8:O\x08\x1d\xd5\ +t\xf6!#\xd5d\xca\xe9\xe9}\xde\xbcz\xb6\xbdia\xc4\x96a:\x9fy~W\xc9>\xb1\x05Pr\ +Ew@8\x87\xb1\x96\x18#\xfd\xd0\xd3u\x1e\xef\xf38\xb9\xf9\xfc\x07\x8c\x00\x9c\ +\xdd\x7f\xc8\xd5\xdb\x97\xacW7\xfb\xed\xb7\xc9\x8br\xbd\xa9\x8e\xec\x01\xd8\ +\n\xd3:\x87\xb3\x19\x04@\x1f\x02m\xd3\xd065M\xbd\xa2\xaeWY\xc0;\xc7N\xfb\n\ +\xf3\xa3c>}t\xc1\xaf?\xffDJ\xa9\x00\xb1y\x9e0v\x04\xb4IU)\x7f\xb7\x07\xc2\ +\xe6\xd8\x17\xd5\xccD\x08\xd4\xcd\x9a\xf5\xfa\x96\xd5\xed\x92\xd5\xed\x12\ +\x11\xc5X\xb7\xed\xbc\x11\xc8\x8e-<\xfe\xfc\x0bno\x17<{\xfa[v\xc4R\x9a<\xe4\ +\xd8Q+\x9b2\x98\xd1\xeeel\xa5\x98\x121\x04\xfa\xa1\xa7m\x1a\xd6\xeb[no\x16\ +\xdc\xdc,\xf0\xdec\xad\xdb\xe4\xe4\xc6F\xf6K\x03\xd9\x03\x9e|\xf9-\x9doy\xf3\ +\xea\x19\xd6U\xe3P#\xa2{\x9b\xa5\x8d\x85l\x00\xa4\x98\x18\x8cB\xf29\xdc:O\ +\xdb\xd4\xacn\x97\xdc\xdc,X\xafnP\x93\xc5\xbb\xc9\xae}F([\x9e\xe2\x90\xb3\ +\xd9\x9c\xaf\xbf\xfb\x81\xdf\x7f\x99\xf2\x9f\x17Os\xb7 \xa5\xff#q\x18\x186g\ +\xdf\xd3\xbb\xb0\xb3;\x84\x18#\xa1\xeb\xf0\xbe\xa5\xa9W\xacn\x97x\xefQ\xe3\ +\xf6JJ\xd9\xf5\x8d@F\x83,\x0e\x89\x08\xb3\xd9!\xdf|\xff#\x87\xc7\xa7\xbc|\ +\xf1\x94\xe5\xe2\x0fb\x1a\x18\x86\xbc\xab\xeb\x82g\xea[\xdcf\xcfl,\xa2\x19\ +\xec\xd0\x97\x0e)3\x87\x88\xe6r\x94$F\xb4L\xf1\xef\x895\xed\xb0\xb1]\xb3?\\<\ +\xf9\x8a\xbb\xf7\x1e\xf0\xf6\xd5%\x8b\xeb+\x82\xcf\x0f\xb8\xd3\x1c0\x99\xcc\ +\xa8&9\xc0T\r\x88\x10\xe3\xc0\x10zB\xe8\xca\x00\xed0\xa3&v\xccoS\x93}\x8d$RL\ +\xa4\x14I)\xe61?\xc5QMGG\x1f1\x9f\x1f\xd34+n\x16\xef\xa8\xeb\x15M\xb3\xcem\ +\xae\x06k\x1c\xc6\xd9\x92\xaa\xd9?\xaa\xe9l\x1c\x862\xd3\xa3\xa0v%\xb9\xef#\ +\x9b\x816\xdb\xef\x80\xe8\x80\x0eJ\x12Hq \xc5H\x8c\x89\xaa\x9arz\xef\x9c\x93\ +\x18\x89)\xe6\x9b\xa4\xf2\x0f\x8a\x94\xc6\x9b\xbe\xbfJ\xe9\x8eq\xbc-L\xa4\ +\x94 \xee\x8d\xe1\xff\xfb\xe3\xbfy1\xf7\xfe\xbevR\x90\x00\x00\x00\x00IEND\ +\xaeB`\x82' + +def get001Bitmap(): + return wxBitmapFromImage(get001Image()) + +def get001Image(): + stream = cStringIO.StringIO(get001Data()) + return wxImageFromStream(stream) + +index.append('001') +catalog['001'] = ImageClass() +catalog['001'].getData = get001Data +catalog['001'].getImage = get001Image +catalog['001'].getBitmap = get001Bitmap + + +#---------------------------------------------------------------------- +def get002Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\x9fIDATx\x9c\xcd\x98Ko\x1b\xc7\x12\x85\xbf~\rI\x89\x8c"?d\xc9Il\xc4N\x10{\ +\x11#\x88\xb3\xcc\xcd_\xbe\x7f\xe0\xae\xee6\xc8\xd2\x80\xb3q\x00\xc9q\x04\ +\xdb\x12\xc5\xd7L\xcf\xa3\xbb\xb2\xe8\xe6p\xa8\xf8\x07\x84\xc0L\x13$f\xe6T\ +\xd59\xa7\xaaG\x01\xc2\xbf\xe0c\x01^\xbc\xfc\x0fE1\xc2\xb9\x02c-F\x1b\x946(\ +\xa5\x10\x11\xf6\xb0\xcav\x91\xdd\x0f\xa2\x06\x7f*>\xf9Q\xfb_%\x9fE\x84\xff\ +\xff\xef\xbf\tHQ\x8c\x18\x8f\x0f(F\xe3\x1e\x8c\xde\x02A@\x04\x89\x10BK\xed7\ +\xd4\xbe\xa4\xae+\xda\xa6\xa6k\x1bB\x08\x08\x821\x0e7\x1a3\x99L9\x9c\x1eQ\ +\x8c\xc6\xe9\xc1J\r@\xa8\x04W\x81D!J\xd8e\xc4\xb9\x82b4f<\x9e\xe0Fc\xac-0Zo\ +\xa1\xd3\xd4\x15\x95_RU+\x140\x1a9&\xe3\x02A\x11\xba\x8e\xaek\xe9\xda\x96\ +\xba\xf1\xd4~\xc3j\xfe\x11\x94\xe6\xe8\xf8\x84{\x0f\x1e2\x9d\x1d\xed`\xa8-\ +\x1c\x85H$\xc6\xb8\x03b\xac\xc5\xb9\x027\x1aS\x149+\xc6\x00\x8a\xf5\xf2\n_-(\ +\n\xcbg\xb3S\\Q\xa0\xb5\x05\x84\x10:\xba\xae\xa3ik\xda\xba\xa1nj|UR\x96\x1b\ +\xca\xcd\x8a\x8f\xef/\xb8\xfa\xf0\x8e\x87_>\xe1\xd1\xd7\xcfP:\x01@%@"\x91\ +\xd0\r2b\xb4\xc1X\x8b\xb5E\x02\xe4\n\xa2\x08\xe5\xea\x1a\x895\'\xf7\x1fp8\ +\x9d1\x99L\x18\x8d\xc6 B\x17:\x9a\xa6\xa1\xaek\x9a\xba\xc6\xd7\x15\x8d\xf7T9\ +\x98\xa2(\xb0\xd6\xb2\\.x\xfd\xeaWV\xeb\x1b\xbe{\xfe#\x93\x83i\x02\x82\x02\ +\x11\x94\x1e\x00Q\xda\xa0\xb5\xc1h\x8d1\x86(B\xb5\xbe\xa6pp|\xf2\x15w\xee\ +\xde\xe3\xce\x9dc\xa6\x87S\x14\x8a\xd2W\x94\x9b\x92\xb2,\xf1\xbe\xc2;\x9f\ +\x03q\x89\xec\xd6a\xacA)\rJ\x03\x91\xf37\xafi\xbc\xe7\xc5\xcb\x9f98\x98e!Dt\ +\xd0\x03 J%B\xe5\xfa\x95\xab\x04\xe2\xe4\xe4\x8c\xb3\xb3/x\xf4\xf81\xa7\xa7\ +\xa7\x84.p}}E\x1b\x02Z{\xb4I\xc0\x9d\xb3\x88\x8czbj\xad1F\xa7L\x1b\x83V\x1a\ +\xd0\xbc\xbf<\xe7\xf7W\xbf\xf1\xc3O\xbf$\x90\xa8^p\x16@D\xb2:`\xbd\xbcBb\xcd\ +\xf1\xc9W\x9c\x9d}\xc1\xb3\xe7\xcfy\xfa\xf4\x1b\xda\xb6\xe1\xfc\xfc\x9c\xc5r\ +\xc9f\xbd\xc6{O\xdb4t]G\x8c\x82\xd6\x86\xa2(2\x08\x8b6\x16c,\xc6\x18\x8c\xb1\ +\xd8\xcc\xc3\xcb?\xdf\xf0\xe6\xe8\x98\'\xdf~\x9f\xd58(\rY\xa2M]\xe1\xab\x05\ +\'\xf7\x1fp\xe7\xee=\x1e=~\xcc\xd3\xa7\xdf \x12\xb9\xb8x\xcb\xe5\xe5%\x8b\ +\x9b\x1b\xca\xb2\xa4njb\x08\xa0T\x8aZ\xebt\xe4\x07\x1bc\xb06\x83\xb1\x0e\xeb\ +\xd2a\x8c\xe1\xaf\xb7\x7fp\xf7\xfe\x19\xb3\xd9\xe7\xc8P5\x00\x12\xa1\xf2K\ +\x8a\xc2r8\x9dq\xe7\xce1\xa7\xa7\xa7\xb4m\xc3\xc5\xc5[\xde\xbd\xfb\x93\x9b\ +\xf9\x9c\xb2\xdc\xd0\xb6m\xb23\xa5\xd0(\xc4(\x10P:\xa2\x82N|3\x99w\xc6f\xfeX\ +\xb4N\xe5\x98_\x7f\xe0\xfd\xe5\x05\x87\x87G\xc4(\xfb@Bh\xa9\xaa\x15\x9f\xcdN\ +\x99L&L\x0f\xa7\x84.p~~\xce\xe5\xe5%7\xf39\x9brC\xd7\xb6\x88\x0c\xcdI\xd2\ +\xaa@\xabd\x82:jb\xceN\xcaJ\x02\xa4\xb4\x06\x81\x18\x02\xcb\xf9\x15U\xb5\xa6\ +(\xc6\x03 \x02\xb5\xdf\xa0\x00W\x14\x8cFc\x14\x8a\xeb\xeb+\x16\xcbe.G\x06\ +\xb1\xf3hP\x03\xa7\xccg\x85\x06\x03Z\x0c\xa2c&l\xe2\xcc\xb6et]G\xddxV\x8b9\ +\xc7\xf7\x1e\xecg\xa4\xf6%\xa3\x91Kf%B\xe9+\xda\x10\xd8\xac\xd7\x94e\x99\xca\ +!\x03\x100\xc8\xcc\xee\x8c\xca\x86\x05\x80\xc6\x08hcPZ\xa3H\xd9h\x9b\x06\xef\ +7x\xbfF\xe2\xfd\x81j\x10\xea\xbab2.\x80dV\xe5\xa6Dk\x8f\xf7\x9e\xba\xa9wmO\ +\xf6\x96\xfd\x16\xb7\x05\x90\xed@\xab\xd4&\x8c\xa4\xf2(\x05!\x04\x9a\xa6\xe6\ +\xe0`\xc6j\xbd"\xca-\xb2\xb6M\x9dzGv\xcc\xb2,\xd1F\xd36M\xaf\x8ed\xcf\xb731\ +\xc0\xd1\xe3QYE\xa6\xf7\xa8\xd42 t\x1d~\x92\xadz\x04!J\xec%\xba\xe5DYmX-\x17,n\ +\xe6\xcco\xe6D\x92\xb2\xd2\rng\x84mTi\x9d\x1cLy\xf1\xf2g~\x7f\xf5\x1b\x97\ +\x7f\xbe\xe9\xf78i\xa2\x14b\x08\x84\x10ro\n\xb4\xaeI\x8e\x99\xeb\x1e%\xe6V_Q\ +n\xd6,\x977\xac\xd7\x9b\x0cb\xa7\xba\xadO\xf7@v#\x86\xea=\xe2\xe0`\xc6\x0f?\ +\xfd\xc2\x9b\xa3c\xfez\xfb\x07\xf3\xeb\x0f\xc4\x10\x92\x07d\t\xfa\xf1\x84\ +\xd1\xa8\xc2mm[+$\xa6\xc1\xa7ij\xaa\xaad\xbdZ\x12"\xa0\x92\xd1\xa5\x92\xe8<\ +\xc5\xdf"\xab\x0c\xb2\xb1[\x93Y=\xf9\xf6{\xee\xde?\xe3\xfd\xe5\x05\xcb\xf9\ +\x15u\xe3\xf1~\xc3\xc1\xc1\x8c\xf1d\x92w\x86.76\x12A\xbb\x96\xa6\xae\x89\xa2\ +\xd3\x9e\xc9\xd8[\xfdH\xef\xf6\xc3\xfb\x1c\x11$\n"\x11\x91\x98\xc6|\x89=\x9b\ +f\xb3\xcf9<<\xa2\xaa\xd6\xac\x16s\xbc_\xb3Z\xafX\xae\x16\x18\x9d\xe7R\xeb\ +\xd2\x9e\xd9\xbad\x82\xb6\xe8K\x95g\xca\x9c\xfb\xfd\xd7\x02{>"\x92v\xe51\xa6\ +\xbd\xa8\xd2\x01\x1d4\xa2@b@b$F\xa1(\xc6\x1c\xdf{\x80\xc4\xfbD\x89\xe9&\x92_\ +P\x88\xf47\xbd\xbd\xaa\xac\x0e\xa5\xd8\x9b\xf4D\x04bO\x8a\x7f\xc7\x8b\x9a\ +\xbf\x01\xfc\t\xfa\\\xad\xe0v?\x00\x00\x00\x00IEND\xaeB`\x82' + +def get002Bitmap(): + return wxBitmapFromImage(get002Image()) + +def get002Image(): + stream = cStringIO.StringIO(get002Data()) + return wxImageFromStream(stream) + +index.append('002') +catalog['002'] = ImageClass() +catalog['002'].getData = get002Data +catalog['002'].getImage = get002Image +catalog['002'].getBitmap = get002Bitmap + + +#---------------------------------------------------------------------- +def get003Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xabIDATx\x9c\xcd\x98\xddn\xdb\xc6\x16\x85\xbf=3$%YB\x0c9i\x1d\xb7hR$h\x91\ +\x83\xa2(\xda^\xf6\xf4\x95\xcf\x0b\x9c\xabs[\xf42\x17)\n\xa4H\x9c6\xfeQD\xc9\ +\xe2\xffp\xe6\\\xccP\xa2\xdc<@)P\xb4i\x8b\xb3\xb8\xd7\xdakmJ\x00\xcf?`3\x00\ +\xdf\xfe\xf0o\xd24#IR\xb41h\xa5\x11\xa5\x11\x11\xbc\xf7\x1ca\xf5\xc3\xc1\x1f\ +Nx\x19\xfdQ\xf8\xe8&\xc7?\xfa\xf8\xee\xbd\xe7\x7f\xff\xfdO\x00\x92\xa6\x19\ +\x93\xc9\x8c4\x9b\xec\xc1\xa8\x01\x08\x1e\xbc\xc7;\xe8\xfb\x8e\xb6)\xe9\xda\ +\x8a\xb6\xa9\xe9\xba\x06k\x1b\x9cu\xf4\xde\xa3\x95!I\'d\xd3\x19\xb3\xf9)i\ +\x9a\x85\x85EF $\xc0\x15\xf0\xce\xe3|\x7f\xa8H\x92\xa4\xa4\xd9\x84\xc9dJ\x92\ +M0&E+5@\xa7\xebj\x9aj\x87mv\x18\x05\xd9\xc9\x04\x99O\xc1\x83\xed{\xac\xed\ +\xe8\xda\x96\xa6\xa9\xa9\xeb\x8a\xd5\xd5\x8a\x9b\xabK\x1e\x9c>d\xf9\xe8\x82\ +\xf9\xe2\xc1\x01\x86\x0cp\x04\xef\x1d\xce\xb9\x03\x10m\x0cI\x92\x92d\x13\xd2\ +4VEk@(\x8b5}[p2K8[^\x90&\tZ\x1b<\x1eg{:\xdb\xd1\xb6-m\xdbR\xd7\x15UUR\x16\ +\x05Eq\xc7\xea\xe6\x1d\xb7\xd7\x7f\xf2\xf8\xf3g|\xf1\xf4kD\x05\x00H\x00\xe4\ +\xbd\xa3\xb7\xa3\x8ah\xa5\xd1\xc6`L\x1a\x00%)\x1eO[m\xc8t\xcf\xa3\xc7\xe7\ +\xcc\x17\x0bf\xd3\x19i\x16\xcam\xad\xa5mZ\xda\xb6\xa1nj\x9a\xaa\xa6\xaaK\xea\ +r\xcad2%\xcdR\xb46l79\xbf\xbd\xfc\x85\xdd\xdd\x9a\xaf^|\xcft6\x0f@\x10\xf0\ +\x1eQ# \xa24Ji\xb4Rh\xad\xf1xl\xbde61\x9c-?\xe5\xec\xe1#\xce\x96KN\xe6\xe1"U\ +UQ\x16;\xca\xb2\xa2\xae+\x92:\xc5\x98\x04\x93\x18\x8cI\xd0\x89Ak\x8dR\n\x11\ +\xc19\xc7\xdb\xd7\xafh\xea\x9ao\x7f\xf8\x89\xd9l\x11\x1b\xc1\xa1z5\x02"\x12\ +\x04\x15\xf9k\xab\r\xb3\x89\xe1\xfc\xfc1\x17\x17\x9f\xf1\xe4\xc9S\xce\xcf\ +\xcf\xe9\xfb\x9e\xd5\x87\x15\xbd\xed\xa9uXLk\x8d1\x86,\xcd\x82\xa0DP\xf1\x86\ +\xb4Rh\x15\x00)%\xdc^\xbf\xe5\xd5\xcb_\xf9\xee\xc7\x9f\x11Q\x80\xec\x1b\xce\ +\x00x\xefcw@Y\xac\xc9t\xcf\xd9\xf2S..>\xe3\xc5\x8b\x7f\xf1\xec\xf9s\xba\xb6\ +\xe5\xcd\x9b7l7[v\xc5\x8e\xba\xaah\xdb\x16k-\xde{\x94\xd6\xa4i\x86\x12\x851\ +\x06c\x0cZ\'\xc1\x0e\x8c!1\tI\x9aq\xfd\xd7\x1f\xbc\xfe}\xc9\x97\xcf\xbf\x89\ +\xdd8\xa2\x86\xd8\xa2]W\xd3\xb7\x05\x8f\x1e\x9fs\xf6\xf0\x11O\x9e<\xe5\xd9\ +\xf3\xe7x\xe7\xb8\xbc\xbc\xe4\xfd\xd5{\xf2uNY\x164M\x83s="\x82\xd6\x06\xa5\\\ +\xac\x90\xc1\xd8 \xe8\x01\x901\tI\x92b\x92\x04\xad5\xef\xdf\xbdf\xf9\xf0\x9c\ +\xc5\xe2\x14?\xee\x1a\x00\xef\xa0\xa9v\x9c\xcc\x12\xe6\x8b\x05g\xcb%\xe7\xe7\ +\xe7tm\xcb\xe5\xe5%\xef\xde\xbdc\x9d\xaf)\x8b\x82\xaek\xa3\x17(\xc0\xa35x\ +\xafP\xca#\x91\x1a\x15i\xd3\x11L\x92$Q3p{{\xc3\xed\xd5%\'\'\x0fp\xce\x1f\x03\ +\xe9\xfb\x0e\xdb\xec8[^0\x9b\xce8\x99\xcf\xe9\xfb\x9e7o\xde\xf0\xfe\xea=\xeb\ +|M\xb1\xdbE*\xa2\xc1\x8c\x8d3\xeal\x10\xe7X?Z\x07zD\x14x\xe8\xfb\x9e\xedvEU\ +\xefH\x93\xc9\x08\x88\x87\xb6)1\n\xd2$\t-*\xc2\xea\xc3\x8a\xedf\x1b\xe8(\n\ +\xac\xb5q\xd1`\xd122\xec\x11"\xb4(<>tb\xa4K\xeb\x00\xc4{\x8f\xb5\x1dM]\xb3\ +\xdb\xe6\x9c.?9\xaeH\xd7Vd\'\x13\xb4\x0e\xa7\xaa\xaa\xa2\xb7=\xbbbGYF:|4\xa2\ +AV\x03\x80\xc1\xc2C\xd3\x1c:P\x85%\x0e\x91\x11\xaa\xd1\xb6\reY\xd2\xd4\xc5\ +\xb1F<\x9e\xb6\xa9\x91\xf94x\x88\xb5\x94\xc5\x8eZ\x1b\xea\xaa\xa2i\x9a\xb8\ +\xa4\x0fa5 \x19\x83\xe0\x00`\xa0H\x89\n\x15\xf2\xa1\xd5E\xc0\xda\x9e\xb6\xa9\ +\x99\xcf\x17\xac\xf3\x1c\xe7\xef\x89\xb5\xeb\x1a\xf0\xe0lO\xdb\xb4\x94e\x85\ +\xd6\x9a\xb6mcw\xa8\x11\x11\x1f\x01\xb1\x7f\x0bI\xa2$\x08V)AP8\x13\x96\xb2\ +\xd6\xd2\xd43\xa6\xb3\x19y\xbe\x8e\xe9>j_k\x1bl?dGC]\x07 \xd6\xda\x98\x9e~\ +\xbc\xe4\x11\x88\xf1&"\x88R\xd1\xc4Thm\x91\xfd\x80\xd0[K6\x99\x90e\x13\x8c1p\ +\x04\xc4\x0b\xce:l\x0c\xb0\xba\xa9\xa3m\x1b\xbc\xf7Ql\xc3R\xfeo dH\xd5Q\xe7\ +\x88\xc8>2\x02-\xe1\\\xd2u1\xcfB$\x0c\xb7wh_\xef\xe9b\x8a6U\x8d1\tY\x9a\xc5\ +\xf2:\xbcWGs\xc5\xa86\x07\x10\xf1\xa5DPJ\xa3\xb4\xc1h\x8dI\x12 \x0cY\x07\xd7\ +\r;\xf7\xa9\xd1\xca\xec\xe7\x89\xaa.1\x89\x014\xa292\x04\xe0\x8b\xa7_\xb3\xbb[\xf3\xf6\xf5+\ +\x94\x920YE\x03\xd2\x83^\xa2\x1e\x9c1q.\x91xQ\xd9\xfb\xc5\xa0\x89\xaa\xaa\ +\xb8\xbb\xdb\x90\xe7k\xd6\xeb\x15\x1f\xd6[\\/\xc4Iq\xb0\x91cj@\x10%|\xf5\xe2\ +{\x9a\xba\xe6\xf6\xfa-I\x9aa\xf6C\xcd\xb0\x1f\xccU"\x10\xef=\xde;\xac\xedc\ +\xb8\x05M\x94e\xc1v\x93\xb3^\xaf\xb8\xbeY\xd1\xf6\x1eQjp\xc1{\x15\xe1`\xd3\ +\x820\x9d\xcd\xf9\xf6\x87\x9fx\xf5\xf2W\xae\xff\xfac\x9f\x9ca\xa2\xf4\xf4}\ +\x8f\xb5=\xd6ZzkI\xban\xa4\x9f0\x18\xb5m\x10fQ\xdc\xb1\xc9s>\xac\xb7\x01\x84\ +\xa8=x\xe2S\xdf\x1e\xc8!\xd2d\x18(\x98\xcd\x16|\xf7\xe3\xcf\xbc\xfe}\xc9\xfb\ +w\xaf\xb9\xbd\xbd\x89\x00\xba\xd8\x825M=#\x9bL\xf6^\xa1\x94\xc2y\x8f\xed:\ +\xda\xa6\xa1\xac\n\xf2|C\xd3\xf5\x91\x0e\x15SZ\xed\xd3\xfcH\xac~T\x8d\xc3Q\ +\x10Q|\xf9\xfc\x1b\x96\x0f\xcf\xb9\xbd\xbad\xbb]\xd1\xd45eY2\x9f/\x98\xcefd\ +\xd9$\xe8G\x1b\x10p1\xc1\xab\xaa\xc6\xf6>v\x87\x8e\x9a8\\w\x1c\x17#j<\xde\ +\x05\x8e\xbdwa\xcc\xf7n\xaf\xa6\xc5\xe2\x94\x93\x93\x07T\xf5\x8e\xdd6\xa7\ +\xa9\x0b\xd6yN\x9e\xaf\xa3\x8b\x0e\x1d\x95"\xda *\xee2\xb4\xe8\xe1\x99\xe9\ +\xfe\xd7\x02G>\xe2}x*w.<\x8b\x8a\xeaQ\xbd\xc2\x0bx\xd7\xe3\x9d\xc39O\x9aL8]~\ +\x12~\xf7.\\\xc4\xc71\xc9\xfb\xfdE\xef\x1f%v\xc7~\xcc\xe4\xa07\xdc^\x14\xff\ +\x8c/j\xfe\x0f\xd8\x1d\x10\x98\x84\xbe&\x9c\x00\x00\x00\x00IEND\xaeB`\x82' + +def get003Bitmap(): + return wxBitmapFromImage(get003Image()) + +def get003Image(): + stream = cStringIO.StringIO(get003Data()) + return wxImageFromStream(stream) + +index.append('003') +catalog['003'] = ImageClass() +catalog['003'].getData = get003Data +catalog['003'].getImage = get003Image +catalog['003'].getBitmap = get003Bitmap + + +#---------------------------------------------------------------------- +def get004Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +\x03IDATx\x9c\xcd\x98[\x8f\xe3D\x1a\x86\x9f:\xdaI:\xdd\xcdL\x0f\x9a\xe9\xa5%\ +\xa6\x01!\xa4\x11\x08\xc1%\xcb_\xde?\xb0W{?w \xc4AB#\x98\x81>\xc49\xda.\xbb\ +\xec\xaa\xbd(\xc7I\xf7\x1e\xae)\xc9q+I\xbb\xde|\xdf{\xf8l\x01D\xfe\x02K\x03|\ +\xfe\xd5\xdf\xb16\xc3\x18\x8b\xd2\x1a%\x15B*\x84\x10\xc4\x18y\x805\xeeO\xf1\ +\xf0F\x14G\x1f\n\xfe\xeb\x12\x0f\xff\x8c\xc3k\x8c\x91\x7f\xfd\xf3\x1f\t\x88\ +\xb5\x19y>\xc5f\xf9\x08F\xee\x81\x10!Fb\x80\x10<\xbeut\xbe\xa6k\x1b\xbcw\xf4\ +\xbe\xa5\xef{B\x00\xa4\xc2\x98\x0c\x9bO\x99\xce\xce06K\x1b\x0bq\x04B$\xb8\ +\x02b\x88\x84\xd8\x1f*b\x8c\xc5f9y>\xc1d9Z[\x94\x94{\xe8t\xbe\xc1\xb7%\xa1+\ +\x99X\x81\x99\xce\x10bN\x04\xfa\xbe\xa3m=m\xdb\xd08G]W\xac\xee\x0b\x167\xbf3\ +?\xbf\xe0\xc9\xc5\x0bf\xf3\xb3\x03\x0c\xb1\x87#\x881\x10B8\x00QZc\x8c\xc5d9\ +\xd6\x0eUQ\n\x10\xb4\xf5\nE\xcd\xc9i\xced\xfa\x84\xdc\xe6h\xa3\x00\x08}\xa4\ +\xf5\r\xdbmI\xdb68\xe7\xa8\xea\x8ai\xb9c\xbb\xdb\xb2Z\xbccq\xf7\x8e\xe7\x97\ +\xd7\\}\xf8)B&\x00\x88\x04(\xc6@\xdf\x1dUDI\x85\xd2\x1a\xadm\x02dl\xda\xa8\ +\xdd2\x9b\x08\xce\xcf?\xe0\xec\xf4\x94\xd9\xec\x84|2AJA\xe8{Z\xdf\xd26-o\xff\ +\xb8\xc5\xb9\x06\x9bU\x18\x9b\x93\xd9\x0cm,Z)\xd6\xeb\x15?\xff\xf0\x9a\xddv\ +\xc5\'\x9f}\xc9dz\x92\x80 F\x84<\x02"\xa4BJ\x85\x92r\xa8\x04\xd0\xed8;\xcdx\ +v\xf1\x01\xef\xbf\xff>\x17\x17\xcf8=\x9b\xa3\x95\xa2i\x1a\xaa\xaa\xc2\xd5%U\ +\xe5X\xac*\x10\x1a!$\x085\x9ce:#\xe8C\xe0\xb77?\xe2\\\xcd\xe7_}\xc3t:\x1f\ +\x84\x10\x90\xbd<\x02"D"\xd4\xd0\xbf\xd0n9;\xcd\xb8\xbc\xfc\x1bWWW\\_\xbf\ +\xe4\xf2\xc5%1\x066\x9b-\xab\xf5\x92\xbe\xef\xe8:\x8f\xb1\x01\xa9\x14\xdahB\ +\xc8\x06\x95\x1d\xae)\xa5@J\x89\x10\x82\xe2\xee-?}\xff\x9a/\xbe\xfev\x04\xb9\ +\x17\x9c\x06\x881\x0e\xea\x80\xb6^1\x9b\x08\x9e]|\xc0\xd5\xd5\x15\xaf^\xbd\ +\xe2\xa3\xeb\x97\xf4\xbd\xe7\xe6\xf6\x8e\xba.\xa9\xab\x8a\xc65x\xef\xe9:O\ +\x8c \xa5F\x9b\x986W\x1a\xa5\x14J+\xa4R(\xa5\xd1\xc6\x90\xd9\x8c\xbb\x9b7\ +\xfc\xfa\xcbw\xbc\xfc\xf8\xd5\xa0\xc6\xa3\xd60H\xb4\xf3\r\x8a\x9a\xf3\xf3\ +\xd4\x8e\xeb\xeb\x97|t\xfd\x92\x18#\xf7\xf7\x05\xcb\xe5\x92\xe5r\xc5n\xb7\ +\xc59G\xe7;\x04\x02\xa5\x14R\x08\x94\x92\xf4Z\'/R\n\xa5\x0cRi\x8c\xb6\x18\ +\x9ba\x8dEk\xc5\xed\xbb7<\xbdx\xce\xc9\xfc\x9cx\xac\x1a\x80\x18\xc0\xb7%\'\ +\xa79g\xa7\xa7\\\\<\xe3\xf2\xc5%}\xef\xb9\xbf/\xb8\xbf\xbf\xa7(\n\xb6\xdb\rM\ +\xd3\x10B@H\x81D"\xa5\x04)\x91! \x84D\n\x99\x04\xa0\x92\x08\x8c6\x18k\xd0*YB\ +\x8c\xb7\xdc\xdf\xbee:;#\x84\xf8\x10H\x08>\xf9\xc4\xf4\t\'\'\'\x9c\x9e\xcd\ +\x891ps{\xc7r\xb9\xa4(\n6\x9b5M\xd3\x8c\xc6\xb4\xb7\xc9\xd4\xef\x08R\xa1\x06\ +\x92J\xa5\x91J\xa3\xb5A\xeb\xd4\x1a\xad\x92I\x86>\xb0^/qn\x871\xf9\x11\x90\ +\x08\xbeuL\xac \xb79Y>A+\xc5f\xb3\xa5\xaeK\x96\xcb\xd5X\x89\xc3\xeeq4\xa8\ +\xe4\xc0\xc93\xf7\x04\x8d\x91\xd4*\xa5\x12g\xb4F\xa9D\xda\xbe\xefh\x1aG\xb9]\ +s\xfa\x9e}X\x91\xce\xd7\x98\xe9\x0cm\x14R\n\x9a\xa6a\xb5^RW\x15\xbb\xdd\xf6!\ +\x88q\xc5\xf1\xbd$\xb8!E\x84\x1c\xdeW(E\xaa\x88\x92(\x99\xc0v]K]W4MI\x0cO\ +\x8fTC\xa4k\x1b\x84\x98\x0f\x8e\xd9SUUB\xee\x92c\x86\x10\x06W<\x0e\xebC{\x88\ +\x1c\xec[\x08\x84\x90\x83%\x08bL\xca\x91R"\x88\xf4]\xc7\xc9I\x89\xbb/\x08\ +\xf1\x11Y\xbdwD\x92m{\xdf\xe2\xea\x92\xae\xf3I\xa2\xbeCH\xc1\x83]\x1f\xa7\ +\xac8\x00\x13"\x118\xf9\x87D\x08\x08:\x0c@\x03}\xd72\x9dN\x902\x8e\xbe3\xca7\ +\xa5hG\xeb\x1b\x9a\xa6\xa5\xaa\x1c\xc6\x06\xba\xce#H\xea\x18b\xe2\xff\xae\ +\xc4\x11\x99\x14%%Rk\xe4\x00P\x8aT\x91\xd05)`\x8d\x86\x07@\xa2\xa0\xef{:\xdf\ +\xd1\xb6-\xce\xd5\xd4.\xa7\x0f=1F\xb4\xd6C^\x1eWe\xbf1<9\x9f\x01"m$D22\xa9\ +\x06\xb5\xa4\xf9\x06\x04\xde\xb7\x94\xbb\rEh\xc7\xf9g\xdf\xe8#\xf9B\xd36\xb4\ +\x8d\xa3\xaak\xf2,\'\x84\x80\xd6z(\xb3\x1a<\xe0P\x95\xfd\xf9\xe9\xf9\xc9\xc8\ +\t)\xc5\xc1;L:\xb46@\xc4\xb9\x86BF\\\xb9\x1b\x00>\xae\xc8\xe0\x01\x8dK \xea\ +\xb2\xa4\xb2\x96H$\xcb2\x94R\xc4\x18\x06\x89\x8a\x11D\x1ax\xf6\xe4\x1crE\xa9\ +\xd1\xcc\xb46\x18c\xd1Z\x0f<\xec\x07\xf3K<\x93Z\x13\x1e\x02\x11\x18\x93QU%eY\ +\xb1\xdd\xed\xb0\xd6"\x04H)\xc7\xaa\x08!\xd9\x87\xf3\xff\x04\xa1\xf6 R[\x8cI\ +\xa6\x16br\xe2@$\x84\x98\xe6\x1016\xe4\xd0\x1a\x9bOY\xdd\x17\x94\xbb\r\xbb\ +\xe9\x04k\rR\xc9\xe1W\x99\x94\'R\r\xa6$\x8fZ!\x91R \xe4\xc1\xd6\x8d\xb1\x18k\ +\xb1\xc3Y+\x8d\xef:b\x08\xf4]G\xe7[\xbc\xf7D\xe4c\xd5\xc0tv\xc6\xe2\xe6w\xd6\ +\x9bM\x9a]\x87\xe02Z\x8f@\x94\xd6G1/Qj\xaf\x10\x85>\xaa\x84\xb1\x96\xccfdy\ +\x861\x86\x18\xa1\xef{\x9a\xd6\xe3\x9c\xa3v\x8e]Y\x11Q\xffY\x11c3\xe6\xe7\ +\x17\xac\x16\xef\xb0\xc6\x8c\xbf\xce\x1a\x83\x1e\x06j\xad\rA)\xb4&\x91R\xa9\ +\x91\x13z\xf8\\\x1b\x8d5v\x04!\xa5\xa2\xeb|\x1a\xa6\xca\x8a\xb2\xac(w;Z\x1f@\ +\xc8\xc7dM\xeb\xc9\xc5\x0b\x16w\xefX.\x8b$C%\xc7\xc02\xc6`\xb4Ak\x95\xfewpO\ +\xad5J\xe9\xa1r\x16cRE\xf6 B\x08\xd4\x95c\xbb\xdd\xb1\xd9\xae\xd9n6,\x8a%m\ +\xc7\x835\x02\x11B0\x9b\x9f\xf1\xfc\xf2\x9a\x9f\x7fxM\x08\x01)e\x02`m\x92\ +\xe3>EM\x87\x89z$\xaa\x1e\x142VEib\x84\xae\xf3\xd4\x95c\xb5^S\x14\x05E\xb1\ +\xa4X.(\xeb\xc4\x8f\xc3T\xbf\x07r\xe4\x96W\x1f~\xcan\xbb\xe2\xb77?\xa6M\x8e\ +\x80hm\xc6\x14U*UB\x073\x98Rz\r1\xe0\xbb.q\xa2i\xd8nw\x14E\x9ag\x16\xf7w\xdc\ +\xdc\x16\xb4>\x0cs\xed\xd8\x99\x87\xad\x01\x81\x90\x82O>\xfb\x12\xe7j\x8a\ +\xbb\xb7dY\x9a\xac\x94\x94\x88\xe1^\'\xc4H\x0c\xc3\x11\xd3\x11\xfa0\xf8\x84 \ +\x84@\xd3z\xaa\xb2b\xb3]S\x14K\x16\xf7w\xbc\xfd\xe3\x86\xca\xf5\x89\x1b\xa3\ +\xfc\x1f\xb7f?[ \x98LO\xf8\xfc\xabo\xf8\xe9\xfb\xd7\xdc\xdd\xbc\x19\'\xfb\ +\x10#}\x1fh\xbd\xa7m[fM\x8bs\x13\xb2,\x1b\xbcF\x11\x86tu\xb5\xa3\xac*\xb6\ +\x9b\r\xc5r\xc1\xcdm1\x82\x10G>\xf4\xc0\xe2\xf7y:\xa6\x9a\x10L\xa7s\xbe\xf8\ +\xfa[~\xfd\xe5;n\xdf\xbd\xe1\xf6\xf6O\xba\xae\xc3\xb7\x1e\xe7j\xaa\xb2f6\xdb\ +1\xc9\'\x98,\xc3(\rR\x10B\xa4\xf3-\xb5s\x94\xbb\x1d\x8bbIY\xfbQ%)\xa4\xf7\ +\xb7\x1a\x8f\xc8\x1a\x8f\xaaq8\'U\xbc\xfc\xf8\x15O/\x9es\x7f\xfb\x96\xd5j\ +\x89s\x8e]\xb9c>?e6\x9b\x92\xe7\xd3\xe1~Y\x01\xc91\xbd\xf7\xec\xca\x8a\xd6\ +\x07\xda\x0e"\xc3\xc6\xe2\xd1\xacr\xa0\xd6!kR\xbf\x031\x864\xe6\xc7\xc0\x9eM\ +\'\xf3s\xa6\xb33\x9c\xdbQn\xd74M\x89\xbb+X,\x16I\xae\xc6\xa2\xa4Fj\rB\'\xc7D\ +%.\x8c\x95\xde\xd7\xfe\xe1c\x81\x07\xce\x1ac\xba+\x0f!\xdd\x8b\n\xd9#{I\x14\ +\x10CO\x0c\x81\x10"\xc6\xe4\x9c\xbeg\x89\xe1)!\x86t\x918<\xa0\x88q\x0c\xb0\ +\xfd\xc5\x19]\xf8\x90\xda\xe3|\x17\x87\xef\x85\x91\x14\x7f\x8d\x075\xff\x06\ +\xd6\xc47q\xb1o)\xe8\x00\x00\x00\x00IEND\xaeB`\x82' + +def get004Bitmap(): + return wxBitmapFromImage(get004Image()) + +def get004Image(): + stream = cStringIO.StringIO(get004Data()) + return wxImageFromStream(stream) + +index.append('004') +catalog['004'] = ImageClass() +catalog['004'].getData = get004Data +catalog['004'].getImage = get004Image +catalog['004'].getBitmap = get004Bitmap + + +#---------------------------------------------------------------------- +def get005Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +\x92IDATx\x9c\xcd\x98[s\x1dG\x15\x85\xbf\xbd\xbb{\xe6\xdc$\xd9V\xe4$\xb6cc\ +\x8a\x90\x84\x82\x90TR\xc5\x0b\x81\'\x8aW\xfe)\x7f\x80\'\n\x9e \xf0\x90\x90\ +\x8b\xc1&\x89#\xcb\xbaKg\xce\xdc\xa7\xbby\xe89G\x92\xe1\x070U\xad9\xd7\xeeu\ +\xf6Z{\xaf\xbd%@\xe4\xff\xe0\xb2\x00\xef\x7f\xf4\tY\x96\xe3\\\x86\xb1\x16\ +\xa3\x06Q\x83\x88\x10c\xe4\x06\xd6\xb8\xbe\xc5\xab\x17\xa2\\{S\xf8\x9f\x97\ +\xdc|\x18\xc7\xbf1F\xfe\xf8\x87\xdf\' Y\x963\x99\xcc\xc8\xf2\xc9\x06\x8c\xae\ +\x81\x10!Fb\x80\x18\x07\x86\xbe\xc6\x0f-C\xdf2t-\x83\xef\xf1C\x8f\xf7\x11\ +\xd4b\xac#\xcb\xe7Lg\xdb\xb8,O\x07\x8b\\\x03!\t\xae@\x0c\x91\x10\xfdUD\x9c\ +\xcb\xc8\xf2\t\x93\xc9\x14\x97O\xb06\xc3\xa8\xae\xa1\x13\x86\x0e\xdfW\x84\ +\xa1f>7X\xbb\x9d6\x8f\xe0C\xa0\xef{\xba\xae\xa5\xa9\x1b\xca\xb2\xa08?\xe0\ +\xecx\x9f\xc5\xf6.\xb7w\xdf`\xbe\xb5s\x05C\xd6p\x84\x18\x03!\x84+ \xc6Z\x9c\ +\xcbp\xf9\x84,\x1b\xa3b\x0c \xf8\xbe@\xe8X\xec,\x98\xcd\xee\x92\xe79\xce9D\ +\x84\x10\x02\xc30\xd0u\x1dm[SU\r\xe5\xaa`\xb9\\r\xb9\xbc\xe0\xfc\xec%\xa7\ +\xc7/x\xfd\xdec\xdez\xf4\x0e\xa2\t\x00\x92\x00\xc5\x18\xf0\xc3\xb5\x88\x185\ +\x18k\xb16K\x80\\\x86\x08H(\xd9\xd9\xb2\xdc\xba\xf5\x90\xed\x9dm\x16\xf3\x05\ +\xb3\xd9t\x04\t\xc300\x0c\x1dM\xd3\xd2\xd45\xab\xb2\xa4(\x96,/\x97\xcc\xce\ +\xe7dY\xce\xe9\xc9\t\xcf\xbe\xfe;\xab\xe5\x05o\xbf\xf7!\xd3\xd9"\x01A FD\xaf\ +\x01\x115\xa8\x1a\x8c*\xc6\x18D\xc0Rs\xe7\xf6\x9c\xbd\xbd=\xee\xee\xed\xb1\ +\xfb\xdak\xec\xdc\xda!w\x19!z\xba\xae\xa3i\x1a\x9a\xa6\xa6\xaa*\xaa\xaab6\ +\x9b2\x9dN\x99N\xa6\xe4\x93\x9c,s\x18c\x18\xbcg\xff\xbb\'4u\xc5\xfb\x1f\x7f\ +\xc2l\xb65&B@\xbd^\x03"\x928_\xf3\x17J\xee\xdc\x9es\xff\xfe}\x1e\xfc\x8e\xdd\xbb\xf7X,v\x88\xd7\xb3\x06 \x06\xf0}\xc5bg\ +\xc1\xd6\xf6\x16\xbb\xbbw\xb8{w\x0f5\x96\xe5\xe5\x92\xaa\xaei\x9a\x86\xf3\ +\xb3s\x8a\xa2\xa0\xeb:\x06? \x92h@\x15\x83!\xf8\x801\x96\xba\x1d8>\xab\x99\ +\xce\xe6)\x11\\\x86\xb5\x16U\x05\x0e9=\xfa\x9e\xd9l\x9b\x10\xe2+@\xe2@\x18j\ +\xa6\xd3=\xe6\xb39\xf3\xc5\x02b`\xb9\\\xa6\xf4l\x1a\xce\xcf\xcfY\x16\x05m\ +\xdb&\xa1\x89\x12\x89\xe8\xa8\r\x00\x15\xc5\x87\xc8W\xcf\x8e\xc9\xf3\x1cc\r\ +\xc6X\xacuXc1F!z\xce\xcf/i\x9a\x12\xe7\xf2k@"\x0c}*V\xa9\xca\xe6\xa8(U\xdd0x\ +O\xd7\xb5,/\x97\xac\xca\x15m\xdb\xa6\xb4\x1bk\xb6\x88 \xaacT\x03"\xc2\x97O\ +\x0f\x19\x06\x8fu\x19j,jl\xb2\x0ec0F z\xba\xb6\xa1*.\xd8\xba\xbdw3"~h1f\x0bk\ +S\x8d\xe8\xba\x96\xd5\xaa \xcb\x1cm\xd3RV%]\xd7\x11c\xd8\x80XGa]\xc0E\x95\ +\xfd\xa3\x0b\xce.\n\xd4\xa4\xac0DL\xb0\x18\x93h1\n\xc2@\xd7T\xd4]uS#\x91\xc8\ +\xd0\xb7\x88l\x13#x\xef\xa9\x9b\x9a\xbc\xca\xe8ZC\xdb\xb5I\x13\x83G\xe5\x15\ +\x10\xa3\r\x00,W\r_=}\x99\xa2\x84n*i4\x11c\x0c\xaa\x8a*\x88x\x16[\xdb\xd4\'g\ +\x84\xf8\x8aX\x87\xaeM\xbe\x12\x06\xba\xb6\xa3\xad\x1b*\xe7PU\x82\xf7\xf4\ +\xc3\xb01\xc1+Z\xb8a\xcc\x9f?\xd9\'x\x9f\x9cD%\x19\xa7j\xfa^\x88\xa8(*\x11\ +\xc53\xcc\xe6\x18=\x1b\xdd\xfdZ\xfa\x0e\xbe\x1f\xf5\xd0\xd3\xf5-u[c\xabT\x0f\ +bLv\x9d\xc2\xbd\xfe\xa57A|\xf9\xf4%\xab\xaaF\x11D\x14\xd5\xf49;\x82\xc1\x90^\ +\x13\x90\xd83\xe4\x13\xf2\xcc\xc1\r Q\xf0C\xbfq\xd1\xbanh\xaa\x06k\xcchpc\ +\xe9\x8f)\n\xff\xd5q\x88p~Y\xa5H\xc8z)\xaa\x065i\x89(j<"\x11\x89\x19\x83\xcb\ +p\x99#\x8c[\xe8F\xac>&+o\x1a\xea\xaa\xa6\xacJ\xea\xba\xa6mZ\x86\xbe\xdf\x88\ +\n\xd8\xf0\xba\x06!\xc0/>x\xcc\xfd7v\xd3sUD\x15\xa3\x06\x1dS\xd79\x8b\xb3\ +\x16\xe7\x1c\xd6fX\x97z\x1e^\xa5\x06\xb54uC]7Tu\xc9\xb4\xcc\xb1\xc6\xa4\xa2K\ +L\xf5 \x981$W\xa9\xcb\x18\x81\xcc(?\xff\xc9[\xdc{\xfd6\x9f=9\x00H~\xe3,\xd6\ +\x8cZS\x0fxpI7\xaa\x8ex\xb3\xa0\t\xc6:\xaajEU\x96\xacV+\xb2,G\x8d\x01I\xdc\ +\x0ev\xd8(_HM\xd3\x86\x06\x95qc\xc3\xfd7\xef\xb0\xb7{\x8b\xbf}\xf1=M\xdbc\ +\x8dM\xbf^\x14\xef\x81`\x88*\xc4\xe0\t\x98M`7Y\x93\xe5s\x96g/(V\x05\x93\xe9\ +\x04\xe7\x1c\xc6(F\x15kSA\xb2\xc6\x8e\xbc+")\xfc\xaa\x8a\x8a\xa0\xc6\x8c\x9f\ +7L\xb7\x1d\xbf\xfd\xf5\xfb<{~\xc6\xd3o\x8f\xb1\xce\x8e\xfa\t\x88\x17\xba\xe0\ +\xf1\xbe\'"\xaff\rLg\xdb\x9c\x1d\xefS\x14\x97\xe4y\x9e\x0e\xd7\x11\x88K\xdc:\ +k\xb1\xd6BL\xcd\x9e\xaabL\x12\xa51)\xc3\xec\xa8\x83I\x9e\xf3\xe1O\x1f\xf3\ +\xc3\x1f\xdc\xe7\xcf\x9f>\xc5\x0f]\xf23<\xc1w\xacV\x15>\xe8\x7fG\xc4e9\x8b\ +\xed].\xce\x0e\xb0\xd6\x8d\x07$CK \xd2\xb2\xceacDT\xc6F\xcab\xad\x19)p\x1b\ +\x97\xcd\xf3\x9cI\x9e3\x9f\xcf\xf9\xddo>\xe0O\x7f\xf9\x8a\x83\x83\x15\xd1\ +\xb7\xb4ME\xd5\x0e\x9bN\xfe\x06\x10\x80\xdb\xbbopz\xfc\x82\xf3\xb3\xf3\r\xff\ +FM: \xcb\xc8\xf2,\x81\x1a\xfb\x0eDF\xeaR\xb4\\\x96\x91\xad\x97K\xddY\x8c\x11\ +\xef=?~t\x87\xae<\xe5\x9b\xd3\x92\x93\x933\xda6p\xbd\x10l\x80\x88\x08\xf3\ +\xad\x1d^\xbf\xf7\x98\xa7_\xfd\r\x1f<"2\x86:m\xee\x9c#s\xd9x\xe0\x15\x18U\ +\x1d{\xdeq\x19\x8b\x88\xe2C\xa0m;../9<:\xa4\xa9.\xa9\xab\x82\xa2l\xf1Q\xb8\ +\xea\xea\xd7@\xaeU\xa8\xb7\x1e\xbd\xc3jy\xc1\xfewOP\x91\x11DN\x9e\xe7\t\x84s\ +\xe8\xd8\x06Z\xe3\xb0\xd6\x10C\xaa\x901F\xc28^\xf4CO\xd7\xf5\x14E\xc1\xf1\ +\xc9\t\x07/\x0ex\xf1\xe2\x80\xe7\xfbGT\x8d\xdf\xb4\xa6\xa3VoR\xc3\xe8\x11o\ +\xbf\xf7!MSsr\xf2\x82|2!\xcb\xd2x\xa1f,\xd7\xe3L\x13b$\xc40\x1ae\xc0\r\x03F\ +\r\x11\xe8\xfb\x9e\xb2\xac\xb8\xb8\xb8\xe0\xe8\xe8\x88\xc3\xc3\x97<\xfbf\x9f\ +\x8b\xa2\xbdV\x8b^\x8d\x08\xe3\xc8#\xe9>\x9d-x\xff\xa3_\xf2\xe4\x8bO9>z\xbe\ +\x99qdL7\xef=}\xd7\xd3\xb6i\x94\x98N\xa7\x1b\xb0\x820xO]\xd7\xacV\x05\x17\ +\x17\x97\x9c\x9c\x9c\xf0|\xff\x88\x8b\xa2\xddX\xa6\x8c@\xd6ve\xd7\xcc\xc45G#\ +\xda\xd9l\x8b\x9f\x7f\xf4+\xbe\xf9\xd7\xe7\x1c\x1f~K\x8c/\t!\xb9p\xdb\xb6\ +\xd4MMY\x96L\x97S&\x93\t\xcef\xa8I@\xbb\xae\xdf\x00yyx\xc2e\xd1P5~c\x07\x88\ +\x8e]\xfc\xd55\xf6#W\xd1\xb8\xba\'\xe3\xfa\xc1\x8f~\xca\x9d\xbd79;\xde\xe7\ +\xe4\xf4\x82\xa6\xae)W+\x8ab\x9b\xf9|1F#\x1f\x1b*\xc1\xfb\x81\xbe\xefY\x16%e\ +\xdd\xd3\xb4\x01\x1f\xe5\x86\x1d\x88\xe8\xd5<|S#\x91\x18"1\x06b\x9a\xb6\xd3}\ +T\xd3b\xb1\xc3l\xb6M\xd3\x94\xd4\xabK\xca\xb6\xa2<<\xc5\xe8)y\xe6p\x99K\x15W\ +\x1d\x01C\x88\x82\x0f:\xd6\x89q\tW\x8f\xaf\xf4p\xb3\xb2\xc6\x98\xa6\xf2\x10\ +\xd2,*\xeaQ\xafD\x81\x18\xfc8DE\x9c\xcb1\xb7^K\xcfcH\x9b\xc4\x88\x07|\x8cD\ +\x9f6]o\xbe!|\xcc\x8eQ\xe3\x9b\xb7b\x8c\x106\xa2\xf8\xff\xf8G\xcd\x7f\x00\ +\xa5^v\xc7\xab\xa1\x84<\x00\x00\x00\x00IEND\xaeB`\x82' + +def get005Bitmap(): + return wxBitmapFromImage(get005Image()) + +def get005Image(): + stream = cStringIO.StringIO(get005Data()) + return wxImageFromStream(stream) + +index.append('005') +catalog['005'] = ImageClass() +catalog['005'].getData = get005Data +catalog['005'].getImage = get005Image +catalog['005'].getBitmap = get005Bitmap + + +#---------------------------------------------------------------------- +def get006Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xd6IDATx\x9c\xcd\x98Yo\xe4\xc6\x15\x85\xbfZ\xb9\xb4\xa4n\x0b\xd2\xb4&\xb05\ +\x8b\xed\x186&\x13\x18\xf3j\xff\xd2\xfc\x81\xbc\xe5\x0f\x04\x08\x92<8O\xf6\ +\x8ba\xc0\x19{4\x98\x99h\x19\xb4\xd4\x8b\x9aM6\xc9\xaa\xca\x03\x17\xb1e\x07y\ +5\x81\xea\xea\x85d\x9d\xbe\xf7\x9csoQ\x00\x81\xdf\xc0\xa1\x01\x9e\xbf\xf8\ +\x1ak#\x8c\xb1(\xadQR!\xa4B\x08A\x08\x81\x1d\xac\xa1\x9b\xc2\xdd\x17A\x0c~\ +\x14\xfc\xea!v\xdf\x86\xf65\x84\xc0?\xfe\xfa\x97\x06\x88\xb5\x11q\x9cb\xa3\ +\xb8\x07#; \x04\x08\x81\xe0\x81P\xe3\xdc\x16_oq\xf5\x96\xba\xde\xe2\xeb\x9a\ +\xba\xae\xa8] \x91\xcablJ<\xda\xc7\x98\xa8YX\x88\x01\x08\xd1\xc0\x15\x10|\ +\xc0\x07w\x17\x11c,6\x8a\x89\xe3\x04\x13\xc5hmQRv\xd0\xf1\xbe\x02\x97#BMl-J%\ +(\xa5\x00\xa8\xeb\x9a\xaa\xaa\xd8n\xb7l6\x1b\xb2,\xe3vu\xc1\xe2\xfa\x9ct\xff\ +\x90\x0f\x0e\xa7\xa4\xfb\xe3;\x18\xa2\x83#\x08\xc1\xe3\xbd\xbf\x03\xa2\xb4\ +\xc6\x18\x8b\x89b\xacm\xa3\xa2Ts\x81\xcb0\xcas\xb07a4\x1a\x11\xc71\xc6\x18\ +\xa4\x948\xe7(\xcb\x92\xb2,\xef@\xdc\xde\xb2\\.Y,\x16\xcc\xe7\x97\xdc\xcc\ +\xcey\xf0\xf01\x1f\x9e~\x86\x90\r\x00D\x03(\x04\x8f\xab\x07\x11QR\xa1\xb4Fk\ +\xdb\x002\x16)\x05F\xe4\x8c\'\x11\x87\x87\x0f\x99L&\x8c\xc7c\x92\xa4\x89F\ +\x08\x81\xaa\xaa(\x8a\x82<\xcf\xc9\xb2\x8c\xf5z\xcdr\xb9doo\x8f$I\xb0\xd62\ +\x9b\xcdx\xf5\xe3w\xac\x97\x0b>\xf9\xfcK\x92t\xaf\x01\x82\x80\x10\x10r\x00DH\ +\x85\x94\n%%J)\xa4\x14\xc4z\xcb\xc9\xd1\x01\xd3\xe9\xb4\x1f\xe3\xf1\x18cL\ +\x0f\xa0\x8bB\x9e\xe7$IB\x1c\xc7DQ\x84\xb5\x16\xad5RJ\x84\x108\xe78\x7f\xf7\ +\x92\xbc\xc8y\xfe\xe2+\xd2t\xbf\x15\x82G:9\x00"DC\xa86\x7fF\xe4\x9c\x1c\x1d\ +\xf0\xd1G\x1fqzz\xca\xd3\xa7O999A\x08AY\x96\xac\xd7kV\xab\x15\xce9\xbc\xf7\ +\x84\x10p\xce\x11BhU\x06RJd\xfb\xc7\x84\x10H)y\xff\xfe\x82\x97?|\xcb\xf3\x17\ +_#\x84\x04D/8\r47 @\x00\xe12\xc6\x93\x88\xe9t\xca\xa3G\x8fx\xf6\xec\x19\xc7\ +\xc7\xc7\x00TUE\x08\x81\xb2,\xa9\xaa\n\xe7\\\x0f@kM\x14E\x08!\xd0Zc\x8c\xe9G\ +\xf7[\x1c\xc7\\^\xbe\xe5\xf5\xcf\xdf\xf3\xf8\xe3g\xad\x1a\x07\xa9\xa1\x95\ +\xa8\xf7\x15Fy\x0e\x0f\x1f2\x9dNy\xf2\xe4\t\xc7\xc7\xc7}x\xeb\xbaf\xb1X\xb0Z\ +\xad\xc8\xf3\x9c\xa2(\xf0\xde\xa3\xb5\xfe\x05\x00k-\xd6Z\xa2(\xeaAX\xdb\x88\ +\xe0\xfa\xea-\x87G\x0f\xd9\xdb\x1b\x13\x86\xaa\x01\x1a\x9fp9\x07{\x13&\x93\t\ +\xd3\xe9\x94\x93\x93\x13\x80^\x1d\xb3\xd9\x8c\xf9|N\x9e\xe7\x94e\x89\x10\xa2\ +\xe5\x94Dk\xdd\x83\x1aF#\x8a\xa2\x1eX\'\xf9\x10\xce\x99\xcf\xceI\xd3\x03\xbc\ +\x0f\xbb@\x085"\xd4\x8cF#\xc6\xe31\xe3\xf1\x18!\x04UUQ\xd75\xb3\xd9\x8c\xeb\ +\xebk\xb2,\xc3{\x8f\x94\xb2\xe7CgX\x1d\x17\x94Rh\xad\xfb\xa8t\xa3\xbb\xc69\ +\xc7\xe5\xd5\x8c\xed6C\xebh\x00$\x80s[bk\x89\xe3\x98$I0\xc6P\x96%!\x84\xd6\ +\x13\xe6dYF\x08\xe1\x17\x0b\x03x\xef\xfb\xef\xa5\x94\x18c\xf0\xde\xf7Q\xe9H\ +\xdbE7\xcb2\xf2l\xc9\xe8\xe0h7"\xbe\xde\xa2T\x03@)EUU\xac\xd7k\xca\xb2\xec91\ +\\lh\xdb\xdd\xe2\xdd1`\xbe\xb8E\x1b\xd3\x02\xd0\ +\x18-\x19\xc50\x8a\x05Zl\xd9\x14\x1b..g\xac7\xf5\x8e\r\xf4@\x84\x10\xa4\xfbc\ +\x1e<|\xcc\xab\x1f\xbf\xc39\xd7/4,\xe5\x1d\xa0\xae\xfb\xee\x00k\xady\xf1\x87\ +\xc7\xfc\xed\x9b\x1f\x9a\xcfJb4\x8cb\xd8K$VV\x14\x9b5\xcb\xc5\x9c\xf9jC\xed\ +\x1b\x91\x88a\x876\xdc\xfc|x\xfa\x19\xeb\xe5\x82\xf3w/\x91R\xee45]\xf1\xea\ +\x16\xee"\xd69\xf0\xef\x9f\x1c\xf3\xf7\x7f\x81Q\x81\xd84\xe9\x18\xc5\x02++\ +\xcab\xcdb~\xc3\xd9\x9b+V\xeb\xce\xfc\xa0\x13\xe2Nj@ \xa4\xe0\x93\xcf\xbf$/r\ +\xde\xbf\xbf\xd8\xe9\xac:\xc5\x84\x10v\xec\xdf9\xd7\x9fsr\xb4OU\x16\xa4\t$6\ +\xa0\xc5\x96b\xb3f\xb1\xb8\xe1\xa7\xb3w\\/\xf2fw%\xc4\xafD\x84v\xcb#\x9a9I\ +\xf7x\xfe\xe2+^\xfe\xf0-\x97\x97o\x07\x9dU\xd3\xd4l\xb7\xdb~\x1b\x91\xa6)I\ +\x92\xf4e\xe0\xc1D\xb1\xba\r\x18U\xe2\xca\x92M\xb1a\xb9\x98s\xf6\xe6\x8a\xeb\ +E\x8e\x0f\x02A\xe7\xca\xa2\xdf\xb8\xea.3\xa1\xcbQ\x8b6M\xf7y\xfe\xe2k^\xff\ +\xfc=\xd7Wo\t\xe1\xbcoj:\x07^\xadV$I\xd2sH\x08\x81\xabj\xaabMQ5\xea\xb8\xb8\ +\x9c1_mX\xad\xabv?\x03\x08\xd9v\xf1\xf7\xc8\x1a\x06\xd1\xb8\x9b\x1b\xcb~\xfc\ +\xf13\x0e\x8f\x1e2\x9f\x9dsy5#\xcb2V\xab\x15\x93\xc9\xa4\xdfH\xdd\xef\xc0\ +\x8a\xa2`\xbeX\x93\xe5\x15\xebMM\xed\xe9\x0bbw\xdf\xbe\x80\xeer$\x10| \x04O\ +\x08\xbei\xf3\x83\xa7c\xd3\xde\xde\x984=`\xbbm\xda\xbb\xe5\xba`\x95]a\xd4{\ +\xe2\xb8\xa9\xa2B*\x84\xd48/\xa9\x1dT\x8e\xd6\'\xbaHw\xb1\xdf},\xb0\xd3\x8f\ +\x84\xd0\xec\xca\xbdo\xf6\xa2B:\xa4\x93\x04\x01\xc1;\x82\xf7x\x1f\xd0:btp\ +\xd4|\x0eM\x11\xacCh\x1c\xb2\xbe\xdb\\\xdd\xd5\xa4\xae\xb9n\xd4!\xc4\xe0\x01\ +Gh\xcf\xf3=)~\x1b\x0fj\xfe\x0bA\xd9\\\x8cd\xf1*\x82\x00\x00\x00\x00IEND\xaeB\ +`\x82' + +def get006Bitmap(): + return wxBitmapFromImage(get006Image()) + +def get006Image(): + stream = cStringIO.StringIO(get006Data()) + return wxImageFromStream(stream) + +index.append('006') +catalog['006'] = ImageClass() +catalog['006'].getData = get006Data +catalog['006'].getImage = get006Image +catalog['006'].getBitmap = get006Bitmap + + +#---------------------------------------------------------------------- +def get007Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xddIDATx\x9c\xcd\x98Yo\x1b\xd7\x19\x86\x9f\xb3\xceB\x8ablK\xb4\x03[u\x15\ +\xa3\x8e[\xd7@\xea\xdb\xe47\x17\xbdk\xd1^\xb4E/\xdb\x18H\xd2\xa0\xa9\x1d/Q*K\ +\x0ee."9$\xe7,\xbd\x98EC5@o3\x005\xa28\xc3\xf3\xe8\xfd\xdeo9#\x80\xc8O\xe0\ +\xd0\x00O\x9e~\x86\xb5\t\xc6X\x94\xd6(\xa9\x10R!\x84 \xc6\xc8\x0eklN\xf1\xea\ +\x0fQt>\x14\xfc\xe8!v\x7f\x8d\xf5\xcf\x18#\x7f\xfd\xd3o+\x10k\x13\xd24\xc7&i\ +\x0b#\x1b\x10"\xc4H\x0c@tx\xbf!\xb8\r\xdempnCp\x0e\xe7J\x9c\x8fD$RY\x8c\xcdI\ +{{\x18\x93T\x0b\x0b\xd1\x81\x10\x15\xae\x80\x18"!\xfa+E\x8c\xb1\xd8$%M3L\x92\ +\xa2\xb5EI\xd9\xa0\x13B\t\xbe@DGj-Je(\xa5\x00p\xceQ\x96%\x9b\xcd\x86\xd5j\ +\xc5r\xb9\xe4r\xfe\x96\xe9\xc5)\xf9\xde\r>\xb81"\xdf\xdb\xbf\xc2\x10\r\x8e \ +\xc6@\x08\xe1\nDi\x8d1\x16\x93\xa4X[\xab\xa2Tu\x83_bT`\xd0\x1f\xd2\xeb\xf5H\ +\xd3\x14k-B\x08B\x08l\xb7[6\x9b\rEQT\x10\x97\x97L\xa7S\xa6\xd3)\x93\xc9\x19\ +\xef\xc7\xa7\x1c\xde\xb9\xcf\xdd\xa3\x87\x08Y\x01 *\xa0\x18\x03\xdeu\x14QR\ +\xa1\xb4Fk[\x01\x19\x8b\x94\x02#\n\xf6\x87\t7o~\xc8p8d0\x18\x90\xe79ZkB\x088\ +\xe7X\xaf\xd7;\x10\xb3\xd9\x8c^\xafG\x96eXk\x19\x8f\xc7\xbc\xfc\xe6\x19\x8b\ +\xd9\x94\x07\x8f>!\xcb\xfb\x15\x08\x02bD\xc8\x0e\x88\x90\n)\x15JJ\x94RH)H\ +\xf5\x86\xdb\xb7\x06\xdc\xbe}\x9b\xd1h\xc4\xe1\xe1!\xc3\xe1\x10c\xcc\x0e\xc0\ +b\xb1\xa0(\n\xb2,#MS\x92$\xc1Z\x8b\xd6\x1a\xa5*\x9fy\xef9\xfd\xfe9\xc5\xba\ +\xe0\xc9\xd3O\xc9\xf3\xbd:\x11\x02\xd2\xcb\x0e\x88\x10\x95\xa1\xea\xf8\x19Qp\ +\xe7`\x9f{\xf7\xeeqtt\xc4\xf1\xf11\xa3\xd1\x08)%eY\xb2\\.\x99\xcf\xe7x\xef\ +\xc9\xf3\x1c\x80\x10\x021\xc6:\xcb@J\xd9\xbe\x84\x10H)y\xf7\xee-\xcf\xbf\xfe\ +\x9c\'O?C\x08\t\x886\xe14P}\x01\x11"\x08\xbfd\x7f\x980\x1a\x8d8::\xe2\xf1\ +\xe3\xc7\x1c\x1c\x1c\xb4\x8b\x95e\xd9\xbeB\x08x\xef\x891\xa2\x94"I\x12\x84\ +\x10h\xad1\xc6`\x8ci\xd5I\x92\x844M9;;\xe1\xf5\xb7_q\xff\xa3\xc7u6vBC\x9d\ +\xa2!\x94\x18\x15\xb8y\xf3CF\xa3\x11\xc7\xc7\xc7\x1c\x1c\x1c\xb4\xf5\xc4{\ +\xcfl6c>\x9f\xb3Z\xadX\xaf\xd7x\xef[\x88\xeb\x00\xd6\xda6T\x8d\xc9\x95R\\\ +\x9c\x9fp\xe3\xd6\x1d\xfa\xfd}b7k\x80\xaaN\xf8\x82A\x7f\xc8p8\xe4\xf0\xf0\ +\x90\xd1hD\xa3\x98\xf7\x9e\xf1x\xccd2a\xb5Z\xb1\xddn\x11B\xd4\x9e\x92\xad\ +\x81\xbb0\xc6\x18\x92$i\xc1\x9a\x94\x8f\xf1\x94\xc9\xf8\x94<\x1f\x10B\xdc\ +\x05!:Dt\xf4z=\x06\x83\x01\xc3\xe1\x10)e+\xffx<\xe6\xe2\xe2\x82\xc5bA\x08\ +\x01)%1F\xa4\x94\xedW4\x9ePJ\xa1\xb5\xfe\x1fU\x9a{\xbc\xf7\x9c\x9d\x8f\xd9l\ +\x96h\x9dt@"x\xbf!\xad%\xcc\xf3\x1ccL\xeb\x85\xd9l\xc6d2a\xb1X\x10cl+ec\xc2\ +\xc6?\xcd{\xa5\x141FB\x08\xad*\xdd\x0c\xdan\xb7,\x97K\x8a\xe5\x8c\xde\xe0\ +\xd6\xae"\xc1mP*k\xcd\xe5\x9cc\xb9\\R\x96e\xeb\x89f\xb1\xebe\xbbQ\xa39\xba\ +\xd74\x8a4pM\x05\x9e\xcf\xe7\xcc\x16\xeb]\x8fD"\xdemZ\xea\x10\x02\xeb\xf5\ +\x9a\xf9|NY\x96\xad\'\x9a\xc5\xba\x0b5\xe9\xda-\x03\xdd\xd4m\xd4RJ\x11B\xa0(\ +\n.//\x19\x0e\x87\xcc\x97\xe7\x84x\xcd\xac\xcem\xda\x9b\x9cs\x14E\x81\xf7\ +\xbe\x85j\x16\xfd\x7f\x10\xdd\xf0h\xad\xdb\xeb\xa5\x94x\xef\x19\x0c\x06\xec\ +\xed\xed\xd1\xef\xf71\xea]\xfb\x1dm\xfaV]\xd4\xb1\xddnY\xaf\xd7,\x16\x0b\xf2\ +<\xc7{\xdf\xa6h\xf7\xbf\xbc\x0e\xd1\xf5L\x17\xa4\x811\xc6\x10Bh\xcb\x7fU\x89\ +-n\x07$\n\x9c+\xdb.Z\x14\x05EQ\xb4\x0b6\x10?v\xbc\xbb\xb8\xe4o\x7f\x7f\xc1\ +\xc3\xe3\xdb<<\xbeM\x9eU~h@\x8c1mX\x9cs\xa4iz\xd5\n\x8c\xa5\xac\xeaY\'4>\xee\ +t\xd1,\xcb\xf0\xde\xb7UQk\xdd\x86\xae\xeb\x95/\xff\xf5\x1f^\xbd9\xe3\xf5w\ +\xe7\xfc\xe1/_\xf0\xe0\xf8.\x8f\x7fq\x97_\x7f|\x8f^\xa7~x\xef\xdbDh\xfb\x90T\ +\xe0\xae\x85&"\xaf\xe6\x89\xcbK\xd24%\xc6\xd8B4\x00\xdd0\x08!89\x9b\xd6}J \ +\x84\xe4\xe5\x9b3^\x9f\xfc\xc0\xef\xff\xfc%\xbf|t\xcco~\xf5s\x9e<\xbaG\x92$\ +\xac\xd7\xeb\x9d\xfe#\xa4\xbe\xee\x11\x81Tv\xa7\x95\'I\xd2\x9a\xd3\x18\x83\ +\xd6z\xc7#B\x08\xe6\x8b5\x17\xef\xa75\x94DH\x89\x14u\xc6(\xc5\x8bWoy}2\xe6w\ +\x7f\xfc\x07\x1f?\xb8\xc7\xcf\xee\xf4\xe8\'\xbe\xf5\x9d\x0fW\xe1nCcl^MV\xd3)\ +\xbd^\x0fkmuA\xa7d7\xb1oL\xf9\xe2\xf5\x0f\xedH)\xa4D\xd4\x10Z\x1b\x94\xb6\ +\xf5Y\xa3\x95\xe2\xcd\xc9\x19\x93\xf7\x92\x0f\xfa\x80[\xb2\xdelp\x9e\xeb\x8a\ +@\xda\xdbczq\xcat:%\xcb\xb2V\x81\xa6O4\xaat\xdb\xfc\x97\xff>m!\xaayF!\x95B\ +\xe9\xfazS{B\t\xf2D\xb0\x97K\xacv,W\x1b&\x93\xcb\xd6\xa8\xbb\x8a\x98\x84|\ +\xef\x06\x93\xc9Yk\xb0\xeb \xd6\xda\xb6\xbaVa\x99#\xeb\xc5\xa5\xd4(\xadPJ\ +\xa3u\x03\xa10Z\x91\x18A?\x97\xf4RAt\x05\xebb\xc5\xb2(\t\xb1\x1e\x8a\xbb \ +\x00\x1f\xdc\x18\xf1~|\xcax\xa1X\x17\xbc{\xf7vg\xb2j\xf2\x7f<\xddb\x94\xaf\xa6\ +\x7f\x19\xd02`4$&\x92\xa6\x82^&\xd9\xcb%y\nV\x96l\x8a\n\xe2\xc5\xab\xef\xb9\ +\x98\x16\x15\xad\x10?\xa2\x08\xf5\x96GT\xe7,\xef\xf3\xe4\xe9\xa7<\xff\xfas\ +\xce\xceN:\x93U=\xa9\xcdJ\xf63\x814\x12\xad\x05\xc6H\x12\xabH3E\x96H\xf2T`\ +\xb5#\xba\xca\x13\xb3\xd9\x84W\xdf\x9ds1-\x08Q h\xfa\x93h7\xae\xba\x89LlbT\ +\xd3\xe6\xf9\x1eO\x9e~\xc6\xebo\xbf\xe2\xe2\xfc\x84\x18O\xdb\xa1F\xdb\x8c,\ +\xeb\x91\xa4\x06k#\xc6F\x12\x1b0\xc6\xa3U\xc4o\x0b\x16\xab\x92uQ\x19s2_1_\ +\x94\xf5~\x06\x10\xb2\x9e\xe2\xaf\x995v\xd4\xb8:W\xd5\xf2\xfeG\x8f\xb9q\xeb\ +\x0e\x93\xf1)g\xe7c\x96\xcb%\xfb\xfb\xd5f\xab\xd7\xeb\xe3\xb3\x94\xe0\x12\ +\xdcF!\x85$DOY\x96L\xa7\x0b\x96E\xc9b\xe5p\x81N\x1b\xa8\xabp\x13\x93]\x8fDb\ +\x88\xc4\x18\x881Tc~\x0c4n\xea\xf7\xf7\xc9\xf3\x01\x9bM5\xde]\xae\xd6,\x8a1F\ +]\x90\xa6\x16kl\xf5\xf4@j|\x908\x0f\xa5\xa7\xae\x13\x8d\xd2\x8d\xf6\xbb\x8f\ +\x05v*k\x8c\xd5\xae<\x84j/*\xa4GzI\x14\x10\x83\'\x86@\x08\x11\xad\x13z\x83[\ +\xd5\xfbXm\xa8\\\x8cU\x85tW\x9b\xab\xabY\xa5\x0ex\x9d\x1dBt\x1ep\xc4\xfa\xba\ +\xd0\x9a\xe2\xa7\xf1\xa0\xe6\xbf\xf1o."\xb9\t8\x10\x00\x00\x00\x00IEND\xaeB`\ +\x82' + +def get007Bitmap(): + return wxBitmapFromImage(get007Image()) + +def get007Image(): + stream = cStringIO.StringIO(get007Data()) + return wxImageFromStream(stream) + +index.append('007') +catalog['007'] = ImageClass() +catalog['007'].getData = get007Data +catalog['007'].getImage = get007Image +catalog['007'].getBitmap = get007Bitmap + + +#---------------------------------------------------------------------- +def get008Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +&IDATx\x9c\xcd\x98K\x8f\xdb\xe6\x19\x85\x9f\xefFR\xd4H\xa3\xd8\x9e\x91\x1d\ +\xd8\x03\xd7\t\x90\x04p\r\x04\xde&\x7f\xa0\x7f\xa4\xcb\xae\xba\xee\xef\xe8\ +\xbe(\xba)R\xf4\x024h\x82\x02A\x03\x14mjo\x8c4\xf1%q\xeazF\x9a\xa1"J#\x89\ +\x92\xf8]\xba\xa0HIN\x80nC@w\x91\xdf\xd1y\xcf9\xef\xfbI\x00\x81\x1f\xc0\xa1\ +\x01\xee\xdd\x7f\x9f(\x8a1&Bi\x8d\x92\n!\x15B\x08B\x08\xeca\r\xf5C\xd8\xbe\ +\x11\xc4\xce\x87\x82\xef=\xc4\xfe\xd3\xb0\xb9\x0f!\xf0\xc9G\x1fT@\xa2(&IR\ +\xa28i\xc0\xc8\x1a\x08\x01B x X\x9c[\xe1\xed\ngWX\xbb\xc2[\x8b\xb5%\xd6\x05\ +\x02\x12\xa9"L\x94\x92\xb4;\x18\x13W\x0b\x0b\xb1\x03BTp\x05\x04\x1f\xf0\xc1m\ +\x191&"\x8a\x13\x92\xa4\x85\x89\x13\xb4\x8ePR\xd6\xd0\xf1\xbe\x04W \x82%\x89\ +"\x94j\xa1\x94\x02\xc0ZKY\x96\xacV+\x16\x8b\x05\xf3\xf9\x9c\xcb\xe9\x19\xf9\ +\xe8\x94\xb4s\x85\xd7\xae\xf4I;\x87[\x18\xa2\x86#\x08\xc1\xe3\xbd\xdf\x02QZc\ +L\x84\x89\x13\xa2h\xc3\x8aR\xd5\tn\x8eQ\x9e\xeeA\x8fv\xbbM\x92$DQ\x84\x10\ +\x02\xef=\xeb\xf5\x9a\xd5jEQ\x14\x15\x88\xcbK\xf2<\'\xcfs\xc6\xe3\x01\xdff\ +\xa7\x1c\xdf\xb8\xcd\xcd\x93\xb7\x10\xb2\x02\x80\xa8\x00\x85\xe0qv\x87\x11%\ +\x15Jk\xb4\x8e*@&BJ\x81\x11\x05\x87\xbd\x98\xabW_\xa7\xd7\xeb\xd1\xedvI\xd3\ +\x14\xad5\xde{\xac\xb5,\x97\xcb=\x10\x93\xc9\x84v\xbbM\xab\xd5"\x8a"\xb2,\ +\xe3\xab/\x1f2\x9b\xe4\xbc\xf9\xce\xbb\xb4\xd2\x83\n\x08\x02B@\xc8\x1d B*\ +\xa4T()QJ!\xa5 \xd1+\xae_\xebr\xfd\xfau\xfa\xfd>\xc7\xc7\xc7\xf4z=\x8c1{\x00\ +f\xb3\x19EQ\xd0j\xb5H\x92\x848\x8e\x89\xa2\x08\xad5JU:s\xceq\xfa\xdf\'\x14\ +\xcb\x82{\xf7\xdf#M;\x1b#x\xa4\x93;@\x84\xa8\x04\xb5\xa9\x9f\x11\x057\x8e\ +\x0e\xb9u\xeb\x16\'\'\'\xdc\xb9s\x87~\xbf\x8f\x94\x92\xb2,\x99\xcf\xe7L\xa7S\ +\x9cs\xa4i\n\x80\xf7\x9e\x10\xc2\xc6e \xa5lnB\x08\xa4\x94\x9c\x9f\x9f\xf1\ +\xe4\xf3\x07\xdc\xbb\xff>BH@4\x86\xd3@u\x01\x02\x04\x10n\xcea/\xa6\xdf\xefsr\ +r\xc2\xdd\xbbw9::j\x16+\xcb\xb2\xb9y\xefq\xce\x11B@)E\x1c\xc7\x08!\xd0Zc\x8c\ +\xc1\x18\xd3\xb0\x13\xc71I\x920\x18\xbc\xe0\xf9\xb3G\xdc~\xe3\xee\xc6\x8d;\ +\xa5acQ\xefK\x8c\xf2\\\xbd\xfa:\xfd~\x9f;w\xeeptt\xd4\xe4\x89s\x8e\xc9d\xc2t\ +:e\xb1X\xb0\\.q\xce5 ^\x05\x10EQS\xaaZ\xe4J)F\xc3\x17\\\xb9v\x83\x83\x83C\ +\xc2\xaek\x80*\'\\A\xf7\xa0G\xaf\xd7\xe3\xf8\xf8\x98~\xbfO\xcd\x98s\x8e,\xcb\ +\x18\x8f\xc7,\x16\x0b\xd6\xeb5B\x88\x8d\xa6d#\xe0]0\xc6\x18\xe28n\x80\xd5\ +\x96\x0f\xe1\x94qvJ\x9av\xf1>\xec\x03!XD\xb0\xb4\xdbm\xba\xdd.\xbd^\x0f)eC\ +\x7f\x96e\x8cF#f\xb3\x19\xde{\xa4\x94\x84\x10\x90R6\x97\xa85\xa1\x94Bk\xfd\ +\x1dV\xeas\x9cs\x0c\x86\x19\xab\xd5\x1c\xad\xe3\x1d \x01\x9c[\x91l(L\xd3\x14\ +cL\xa3\x85\xc9d\xc2x\x9fS\x96e\xa3\x89z\xb1Wc\xbbf\xa3>v\xbfS3R\x83\xab\x13x:\x9d2\x99-\xf75\ +\x12\x088\xbbjP{\xefY.\x97L\xa7S\xca\xb2l4Q/\xb6\xbbPm\xd7\xdd\x18\xd8\xb5n\ +\xcd\x96R\n\xef=EQpyyI\xaf\xd7c:\x1f\xe2\xc3+b\xb5v\xd5\x9cd\xad\xa5(\n\x9cs\ +\r\xa8z\xd1\xff\x07b\xb7\x9dN\x99\xcdf\xac\xd7k\xca\xb2\xc4Z\x8b\xf7\x9e\x8f?\ +\xfd7\xbf\xfb\xf0\x9f\x94\xe5\xaa\x16\x08\x08\xc1\xe8\xdb\t\x7f\xf9\xdb\x17\ +\xdfa\xa3\xbe\xd5\x8b\xd7\x01\xe9\x9c\xc3\xf9m\xb9\x9b\xd2\x98(\xad&\xab<\ +\xa7\xddn\x13EQ\xf5\x85M\x9d\xf3\xcb%\x7f\xfd\xfbS\xf2\xc9\x0c!e5c\tY=\x17\ +\x02!%\x0f\x1e}\xcd\xbbwo\xf3\xf6\x9b7\x9b\xdeR\x0fQ\xb5kjC\xacV+\xac\xe3U\ +\xd7@\xd2\xee\x90\x8fN\xc9\xf3\x9cV\xab\x85\xd6\x1a)%\xc6\x18\x1e\x7f}\xc1\ +\xa3\xa7\x17\x08@i\x83D\xc0+ \xaayF\xf1\x9b?>\xe0\x17?;!\x8ecZ\xadV\xa3\x8f\ +\xb2,Y.\x97,\x16\x0b\x16\x8b\x05\xe3\xfc\xb2\x11\xea>#&&\xed\\a<\x1e4\x02\ +\x0b\xc0\xa3\xc7g\x8c&kL\x94`\xa2V5D\xa9\x80\x04\x84\xd8\x04\x97RH\xa9QZ\x11\ +\x82\xe7W\xbf\xff\x8c\x9f\xff\xf4\'h]i\xa0\x0e\xc5\xe9t\xda\x94|\xb6(\xf1a3\ +\x14o5R\x1d\xaf]\xe9\xb3*=Y\x961\x1c\x0e\xf9\xf2\xc97\x8cF\x19\xf85\xceY\x9c\ ++\xab\xf9\xc3o6\x13bg\xbaS\n\xa5\x0cZ\x1b^\x9c^\xf0\xc9?\x9e6 \xea9v<\x1e\ +\x93\xe79/O\xcf\x99-\xec^\x0c4@\x84\x10\xa4\x9dC\x8eo\xdc\xe6\xfc\xfc\x9c\ +\xc1`H1\x9f"\xc3\x1a-\x1d2\x94\x04\xef\x08\xc1\xe2\xbd\xab\xa29\xd4\xe7\xcaM\ +y$JI\xb4R\xfc\xe9\xe3\xcfx\xfe\x9f\x01y\x9e\x93e\x19\xe7\xe7\xe7dYF\x96e|;Y`\ +}\xf5K\x9a\xe4\xdd\x98\xa69n\x9e\xbc\xc5\xf1\xf5\x1fqqqN\x9e\x8fp\xb6\xc0HK\ +\x12\x05\x8crH*0\x04O\x08\x0e6\x1b0A@V\x06\xc2(Hc\xc1\x1f>\xfa\x8c\x97/O9;;c\ +0\x180\x1c\x0e\xf9\xea\x9b\x01\xd3Y\x89\xd8\x18\xee;\x1a\xa9m,\xa4\xe0\xcdw\ +\xde\xa5X\x16\x8c\xb23\x928!\x8eb\xe28\xc2D1B\x01* \x94\xab\xa6\x7f\xe9\xd1\ +\xd2c4\xc4&\x90$\x82vK\xd2I%\x91X\xf0\xc5\xe3g\x94\xab9\xc3\xe1\x90\xc7\xcf^\ +0\xca\x8b\xc6\xf2\xdb}\xce\x0e\x10\xb1yS h\xa5\x07\xdc\xbb\xff\x1eO>\x7f\xc0\ +\xc5\xc5\x8bMHI\x92\xd8\x90\xc4\x11J\x83\xd2\x02i$Z\x0b\x8c\x91\xc4\x91"i)Z\ +\xb1$M\x04\x91\xb6\x04[r1\\0\x9d\xe6|\xf5\xcd\x80Q^\xe0\x83\xd8\xb0Q\x01\t\ +\xbb\x8cl\xb5+\x1a\xb4i\xda\xe1\xde\xfd\xf7y\xfe\xec\x11\xa3\xe1\x0b\xe0|C\ +\x7f\xe0\xa0\x03-\xa3\x88\x13C\x14\x05L\x14\x88#\x8f1\x0e\xad\x02n]0[\x94,\ +\x8b\x05g\x83\x8c\xf1t\xc1tVn\xf63T\xd6\x17\xfb\xbdk3\x8fl\xd9\xd8>V\x81u\ +\xfb\x8d\xbb\\\xb9v\x83qvJ6\x1a\xb3\\\x16\xf4\x8a\x05\xddn\x97v\xfb\x00\xd7J\ +\xf06\xc6\xae\x14RH|\xa82#\xcfg\xcc\x8b\x92\xd9\xc2b\xfd\x86\x01\xb1\xbdn3X\ +\x85\xbd\xd2\x84\xca\x92\xc1\x13\x82\xaf\xc6\xfc\xe0+\x86B\xe0\xe0\xe0\x904\ +\xed\xb2ZU\xe3\xdd\xe5b\xc9\xac\xc80jD\x92DD&\xaa\xfe=\x90\x1a\xe7%\xd6A\xe9\ +\xd8\xe4D\xcdt\xcd\xfd\xfe\xdf\x02{\xc9\x1aB\xb5+\xf7\xbe\xda\x8b\n\xe9\x90N\ +\x12\x04\x95e\xbd\xc7\xfb\x80\xd61\xed\xee\xb5\xeau\xa8\x9a\xa0\r\xa1JH\xbb\ +\xdd\\mg\x95M\xc1\xab\xdfS=\xb2\xfd(\x84\x00\xbe\x11\xc5\x0f\xe3\x8f\x9a\xff\ +\x01k)\xae\n\xd5\xf2\r\xdb\x00\x00\x00\x00IEND\xaeB`\x82' + +def get008Bitmap(): + return wxBitmapFromImage(get008Image()) + +def get008Image(): + stream = cStringIO.StringIO(get008Data()) + return wxImageFromStream(stream) + +index.append('008') +catalog['008'] = ImageClass() +catalog['008'].getData = get008Data +catalog['008'].getImage = get008Image +catalog['008'].getBitmap = get008Bitmap + + +#---------------------------------------------------------------------- +def get009Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xb7IDATx\x9c\xcd\x98\xdbn\xdbV\x16\x86\xbf}")\xca\x96\xd5$\xb6\x92\xa25\x82\ +\xb4@Q \x08P\xe4r\xda\xbby\xdfy\x81\xb9\x9a\x07\xe8\xdc\x14\x05f\x82\x16-2ud\ +\x97\x8a$\x8a\xe2A\xdc\x87\xb9\xe0A\x92;\xc0\xdc\x96\x00MK"\xb9?\xae\xf5\xaf\ +\x7f\xafM\x01\x04\xfe\x04\x9b\x06x\xf3\xf6;\xa2(\xc6\x98\x08\xa55J*\x84T\x08\ +!\x08!p\xc6\x1a\x86C8~\x11\xc4\xc9\x8f\x82\xff\xb9\x89\xf3\x7fC\xff7\x84\xc0\ +?\xfe\xfe\xb7\x0e$\x8ab\x92$%\x8a\x93\x11F\x0e \x04\x08\x81\xe0\x81`q\xae\ +\xc1\xdb\x06g\x1b\xacm\xf0\xd6bm\x8bu\x81\x80D\xaa\x08\x13\xa5$\xd3K\x8c\x89\ +\xbb\x81\x858\x81\x10\x1d\xae\x80\xe0\x03>\xb8cD\x8c\x89\x88\xe2\x84$\x99`\ +\xe2\x04\xad#\x94\x94\x03:\xde\xb7\xe0*D\xb0$Q\x84R\x13\x94R\x00Xki\xdb\x96\ +\xa6i(\xcb\x92\xfd~\xcf.\xff\xc0fuGz\xf9\x84O\x9e,H/\xaf\x8e\x18b\xc0\x11\ +\x84\xe0\xf1\xde\x1fA\x94\xd6\x18\x13a\xe2\x84(\xea\xa3\xa2Tw\x81\xdbc\x94gv\ +1g:\x9d\x92$\tQ\x14!\x84\xc0{\xcf\xe1p\xa0i\x1a\xaa\xaa\xea v;6\x9b\r\x9b\ +\xcd\x86\xf5z\xc9\xc7\xec\x8e\x9b\x17/\xf9\xec\xf6+\x84\xec\x00\x10\x1dP\x08\ +\x1egO"\xa2\xa4Bi\x8d\xd6Q\x07d"\xa4\x14\x18Qq5\x8fy\xfa\xf4S\xe6\xf39\xb3\ +\xd9\x8c4M\xd1Z\xe3\xbd\xc7ZK]\xd7g\x10\xdb\xed\x96\xe9t\xcad2!\x8a"\xb2,\ +\xe3\xe7\x7f\xfd\x93b\xbb\xe1\xcb\xaf\xbfa\x92^t \x08\x08\x01!O@\x84TH\xa9PR\ +\xa2\x94BJA\xa2\x1b\x9e?\x9b\xf1\xfc\xf9s\x16\x8b\x05777\xcc\xe7s\x8c1g\x00E\ +QPU\x15\x93\xc9\x84$I\x88\xe3\x98(\x8a\xd0Z\xa3T\xa73\xe7\x1cw\xffyGUW\xbcy\ +\xfb-iz\xd9\x17\x82G:y\x02"D\'\xa8>\x7fFT\xbc\xb8\xbe\xe2\xf3\xcf?\xe7\xf6\ +\xf6\x96W\xaf^\xb1X,\x90R\xd2\xb6-\xfb\xfd\x9e<\xcfq\xce\x91\xa6)\x00\xde{B\ +\x08}\x95\x81\x94r\xdc\x85\x10H)yx\xf8\xc0\xbb\x1f\xbf\xe7\xcd\xdb\xef\x10B\ +\x02b,8\rt7 @\x00\xe1\xf6\\\xcdc\x16\x8b\x05\xb7\xb7\xb7\xbc~\xfd\x9a\xeb\ +\xeb\xebq\xb0\xb6m\xc7\xdd{\x8fs\x8e\x10\x02J)\xe28F\x08\x81\xd6\x1ac\x0c\ +\xc6\x981:q\x1c\x93$\t\xcb\xe5{~\xf9\xe9\x07^~\xf1\xba\xaf\xc6\x93\xd4\xd0\ +\x97\xa8\xf7-Fy\x9e>\xfd\x94\xc5b\xc1\xabW\xaf\xb8\xbe\xbe\x1e\xfd\xc49\xc7v\ +\xbb%\xcfs\xca\xb2\xa4\xaek\x9cs#\xc4c\x80(\x8a\xc6T\r"WJ\xb1\xba\x7f\xcf\ +\x93g/\xb8\xb8\xb8"\x9cV\r\xd0\xf9\x84\xab\x98]\xcc\x99\xcf\xe7\xdc\xdc\xdc\ +\xb0X,\x18"\xe6\x9c#\xcb2\xd6\xeb5eYr8\x1c\x10B\xf4\x9a\x92\xa3\x80Oa\x8c1\ +\xc4q<\x82\r%\x1f\xc2\x1d\xeb\xec\x8e4\x9d\xe1}8\x07!XD\xb0L\xa7Sf\xb3\x19\ +\xf3\xf9\x1c)\xe5\x18\xfe,\xcbX\xadV\x14E\x81\xf7\x1e)%!\x04\xa4\x94\xe3-\ +\x06M(\xa5\xd0Z\xff!*\xc35\xce9\x96\xf7\x19M\xb3G\xeb\xf8\x04$\x80s\rI\x1f\ +\xc24M1\xc6\x8cZ\xd8n\xb7\xac\xd7k\x8a\xa2 \x840:\xe5 \xc2A?\xc3g\xa5\x14!\ +\x04\xbc\xf7cTN+\xe8p8\xb0\xdf\xef\xa9\xf6[\xa6\xb3g\xe7\x11\xf1\xb6A\xa9\ +\xc9(.k-\xfb\xfd\x9e\xb6mGM\x0c\x83=\xb6\xed!\x1a\xc3vz\xce\x10\x91\x01np\ +\xe0<\xcf\xd9\x16\xf5\xb9F\x02\x01g\x9b\x91\xda{O]\xd7\xe4yN\xdb\xb6\xa3&\ +\x86\xc1N\x07\x1a\xca\xf5\xd4\x06NKw\x88\x96R\n\xef=UU\xb1\xdb\xed\x98\xcf\ +\xe7\xe4\xfb{|x$Vk\x9b\xf1"k-UU\xe1\x9c\x1b\xa1\x86A\xff\x1f\xc4iz\xb4\xd6\ +\xe3\xf9RJ\x9cs\xccf3.//\xb9\xb8\xb8\xc0\xa8\x87\xf1\x1ec\xf9v\xb3\xa8\xe5p8\ +P\xd75EQ\x90\xa6)\xce\xb9\xb1DO\x9f\xf21\xc4\xa9fNA\x06\x18c\x0c\xde\xfb\xd1\ +\xfe;\'\x8e\xb0g A`mKU7\xdc-?\xb2\\[<\xbf\x10\x84\xecLN\x88\xbe?\x91\xc7\x89\ +\xebd\xfb\xeb_\xbefq}5FD)5\x82\x18c\xc6\xb4XkI\x92\xe48\x15\x98\x88\xb6\xf3\ +\xb3\x93\xd4\xb8@S\xd7\x14\xfb\x82vg)[\x81\xf3\x02\x10H\xa5Q\xaa\x0f\xb3\x90\ +G\x90\xfe\xd0\xb4\xee,\x12J\xa93cSJ\xe1\x9c\x1b\x0ba\x9c\x87\xa4\x02\xfb(5\ +\x01IUW\xc4uE\x90\x02w\x10X/@*\xb4\x90H\xe1A\xaa\xae\xad\xe9\xe7\xa5\x01\xe8\ +q:\x1e\xfb\x88\xd6\x1a\xe7\x1cu]\x9f\xcd?B\xea\xe3\xdc4<\x9aT\x11\xe5\xbe\ +\xa4\xa9+l[\xe3\xdd\x81\xd66xg\xbb\xdd{B\xaf\xf0p\xda:\n\x81\xec\xd31@<\xb6\ +\xf9\xc1\xcc\x86\x8a\x1ct\xe7\xfc\xb1\xe4\xc7\xd4\x98(\xa5\xc8?\x90LR&S\x85w\ +\x9a`%6\xf4\xe9\x10\xb2?v\x95#\x10\xbdf$\xba\x1fx\x80\x18&\xb8\x01b\x10\xb1s\ +n,\x88\xa6i\xb0\x8e\xc7U\x03\xc9\xf4\x92\xcd\xea\x8eb\x97#\x95\x06\x99\x10\ +\xbc\xc2\x07\x10B!\xa5FJG\x90\x12I\x0f\xd7?\xa5VzL\x811f\x14\xe3d2\x19\xf5\ +\xd1\xb6-u]S\x96%eY\xb2\xde\xecF\xa1\x9eG\xc4\xc4\xa4\x97O\xd8n\x96(\xad\x89\ +\x13\x0f"&\x08pv(\xddN`R\x05$ D\x97o\xfd(\rQ\x141\x99L\xd0\xba\xd3\xc0`\x8ay\ +\x9e\x93\xe79EQP\x94->\xf4M\xf1Q#\xdd\xf6\xc9\x93\x05\x07\xeb\xd9\xac\xd7T\ +\xe5\x0e\\\x83\x0c-\xf8\x03\xceY\x9ck\xbb\xfe\xc3\xf7*\x11]wg\x8c\xfe\x03\ +\xc8`\xe9m\xdb\x8e}\xecz\xbdf\xb3\xd9\xf0\xdb\xdd\x03Ei\xcf,`\x04\x11B\x90^^\ +q\xf3\xe2%Y\xf6;\xeb\x8f+\x9a\xba@\x86\x03Z:dh\t\xde\x11\x82\xc5{\xd7Ys\xafY\ +)\xd5\x1f\x0cl\xa8\x92\xcdfC\x96e<<<\x90e\x19Y\x96\xf1q[b}\xf7$\x83\x19\xeaS\ +?\x00\xf8\xec\xf6+\x8a\xed\x86\xbb\xff\xbcCH\xc1u\xd4\xcf\x9eQ H\x87\xa0\x83\ +!hBp\x104\xde\xbb\xb1\x12\x9a\xa6\x19[\xca\xb2,\xd9l6<<<\xb0\\.\xb9\xbf\xbf\ +\xe7\xe7_\x97\xe4E;\xb6\xa6\x83A\x1f\xfb\x91\x9eHH\xc1\x97_\x7fCUW\xac\xb2\ +\x0f$qB\x1c\xc5\xc4q\x84\x89b\x84\x02T@(\xd7u\xff\xd2\xd3\xf4]\xfc0\'\r\xd1\ +\xc8\xf3\x9c\xf5zM\x96e\xdc\xdf\xdf\xf3\xef\x9f\xde\xb3\xdaT\xbd\x0f\t\x8e\ +\xeb\x9c\x13\x10\xd1\x7f)\x10L\xd2\x0b\xde\xbc\xfd\x96w?~\xcf\xef\xbf\xbf\ +\xef\xfdA\x92\xc4\x86$\x8eP\x1a\x94\x16H#\xd1Z\xb0\xdbmX.\xc5\xd8HYkGq\x0e\ +\xa9\xf9\xf9\xd7%\xabM\x85\x0f\x9d\r\x8a\x1edp$=d&\x0c9\xeai\xd3\xf4\x927o\ +\xbf\xe3\x97\x9f~`u\xff\x1ex@\x10\x90"pq\t\x13\xa3\x88\x13C\x14\x05V\xd9=M\ +\x95\x8f^q8\x1c(\xcb\x92\xa2(\xf8\xed\xee\x81\x8f\xdb\x92\xbch\xfb\xf5\x0cG_\ +:\xd9\xfa~\xe4\x18\x8d\xe3\xb13\xac\x97_\xbc\xe6\xc9\xb3\x17\xac\xb3;\xb2\ +\xd5\x9a\xba\xae\x98W%\xb3\xd9\x8c\xe9\xf4\x027I\xb8\xfb\xad9\x13i\xd34\xac7\ +;\x8a\xb2\xa5(-\xd6\xf7\x11\x10\xc7\xfb\x8e\x8d\xd5\xb9FBW\x92\xa1\xb7\xf1\ +\x10z;\xef\xd4tqqE\x9a\xceh\x9a\xae\xbd\xdb\x955E\x95a\xd4\x8a$\x89\x88L\xd4\ +\xcd\xceR\xe3\xbc\xc4:h\x1d\xbdO\x0c\x91\x1eb\x7f\xfeZ\xe0\xccYC\xe8V\xe5\ +\xdewkQ!\x1d\xd2I\x82\xa0+Y\xef\xf1>\xa0u\xcct\xf6\xac\xfb\x1c\xba\x05\x95\r\ +\xa1sH{\\\\\x1d{\x95>\xe1}u\x08q\xf2\x82#\xf4\xe7\xf9Q\x14\x7f\x8e\x175\xff\ +\x05g\'\x93\xa3\xa4\x98\xbd\xac\x00\x00\x00\x00IEND\xaeB`\x82' + +def get009Bitmap(): + return wxBitmapFromImage(get009Image()) + +def get009Image(): + stream = cStringIO.StringIO(get009Data()) + return wxImageFromStream(stream) + +index.append('009') +catalog['009'] = ImageClass() +catalog['009'].getData = get009Data +catalog['009'].getImage = get009Image +catalog['009'].getBitmap = get009Bitmap + + +#---------------------------------------------------------------------- +def get010Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +\x1eIDATx\x9c\xcd\x98[\x8f\x1c\xc5\x19\x86\x9f:\xf4az\x0e;\x18\xef\x8e\x1d\ +\xf0b\xd6D\x80p6A\x86(R\xec\x08\t)\x8a\x14\xfe_~\x00\xcae\x84r\x97\x8b\\D(\ +\x17\x91"\xf0\rB"\x96-\xc0\xb0\xde\xd9\x9d\xf5\x9cz\xfa\\U\xb9\xe8\xc3\xcc\ +\xd8\xfc\x00J\xaa\x9d\x9d\xd9\xe9\xaeg\xbfz\xbf\xf7\xfb\xaa\x05\xe0\xf8\x19\ +\x0c\rpz\xef\x01\xbe\x1f\xe0y>Jk\x94T\x08\xa9\x10B\xe0\x9cc\x8f\xd5\xb5/n\ +\xfb\x81\x13;\x7f\x14\xfc\xe4\x10\xfb\xbf\xba\xe6\xa7s\x8e\xcf\xff\xf9Y\r\ +\xe2\xfb\x01a\x18\xe1\x07a\x07#[\x10\x1c8\x87\xb3\x80\xab0&\xc7V9\xa6\xca\ +\xa9\xaa\x1c[UTUIe\x1c\x0e\x89T>\x9e\x1f\x11\xf6\x87x^P/,\xc4\x0e\x84\xa8q\ +\x058\xeb\xb0\xcel#\xe2y>~\x10\x12\x86=\xbc Dk\x1f%e\x8b\x8e\xb5%\x98\x14\ +\xe1*B\xdfG\xa9\x1eJ)\x00\xaa\xaa\xa2,K\xf2<\'I\x126\x9b\r\xeb\xd53\x16WgD\ +\xc3k\xbcrmB4<\xd8b\x88\x16G\xe0\x9c\xc5Z\xbb\x05QZ\xe3y>^\x10\xe2\xfbMT\x94\ +\xaa/0\x1baR\x86\xfd\x11a\xafO^)\xbe\xf9~\xcd\x1bo\xd0A\xccf3\xe6\xf39I\x92P\ +\x14\x05B\x88FS\xb2\x13\xf0.\x8c\xe7y\x04A\xd0\x81\xb5)\xef\xdc\x19\xf3\xd9\ +\x19Q4\xc2Z\xb7\x0f\x82\xab\xc0\x96\x84\xe1\x04\xe5\x05\x94V1\xbd\\\xf2\xe9\ +\xdf\x1fr\xef\xbd\t\xaf\xf4\x05WWW\xc4q\x8c\xb5\x16)%\xce9\xa4\x94\xdd-ZM(\ +\xa5\xd0Z\xbf\x14\x95\xf6\x1ac\x0c\xe7\xd3\x19y\xbeA\xeb`\x07\xc4\x8119\x81\ +\xe7!\x95\xa62\x828)\xd8\x14\x0b\xd6\x9b)_|\xf1_^\x9f\x1c\xf0\xe1\xaf^\xc3\ +\xf7T\xe7\x94\xad\x08[\xfd\xb4\xef\x95R8\xe7\xb0\xd6vQ\xd9\xcd\xa0\xa2(\xd8l\ +6\xa4\x9b%\xfd\xd1\xf5\xfd\x88\xd8*G\xaa\x00P\xa4E\x85-cJ\x93\x91\xa4)\xf1z\ +\xcd\xc3\x8b)\x8f\xbf\xfd\x91?\xfd\xe1=\x8e\xae\x8f\xf6l\xbb\x8dF;vA\xdb\x88\ +\xb4p\xad\x03\xafV+\x96q\xb6\xaf\x11\x87\xc3T9RH\x8c\xb5$INn\x1c\xa5\x81,\ +\xcb\xc9\xb2\x94\xaa,\xb9z\xbe\xe0\xd3\xcf\xfe\xcdG\xbf{\x8f\x0fNo\xef\x14\ +\xc5-@\x1b\x95v\xb6\xd1RJa\xad%MS\xd6\xeb5\xe3\xf1\x98\xd5f\x8au/\x88\xb5\ +\xaar\x1cP\x14%\xa6\xcaH\xcb\x82\xca@YV\x94e\x81u\x8ev\xcd\x7f\xfd\xe7k\xbe\ +\x7f6\xe7\xcf\x1f\xdd%\x08\xbc=\x88\xdd\xed\xd1Zw\xd1\x91Rb\x8ca4\x1a1\x1c\ +\x0e\x19\x0c\x06x\xeab\xeb;m\xfa\xd6U\xb4\xa2\xc8\x0b\xd24%I\x12\xd24\xa3(rL\ +U5\xc5\xc9\xd1T-\x9e|\xf7\x8c\xbf\xfc\xf5s\x9e\x9e=\x7fI3\xbb \xad\x7f\xf4\ +\xfb}\xa2(\xea\xec\xbfvb\x1f\xf6@\x9c\xa0\xaaj\x93*\xca\x82"\xcf)\xf2\x8c"\ +\xcf(\x8bb\xc75\xa9/t\xdb(\xfe\xed\x1f\x0f\xc9\xf2r/"J\xa9\x0e\xa4\x15k\x18\ +\x86]\x19\xe8J\x81\xe7w]\xcdvk\x8c\xab\x01\x8a\x9c\xd2\n\xcaR`\xac\x00\x04Ri\ +\x94\x92\x8d\x9aD]\t\x9a\x1e\xe8\xc1\x87o\xd1\x0b\xfd\xbdH(\xa5\xf6\x8cM)\ +\x851\xa6s\xd9\xae\x0eI\x05\xd5\x9e\x8f\xd4MM\x9a\xa5\x04Y\x8a\x93\x02S\x08*\ ++@*\xb4\x90HaA\xaa\xba\xadi\xea\xd2\x9d7n\xf2\xdb\xdf\x9c\xbc\xa4\x8b\x17}Dk\ +\x8d1\x86,\xcb\xf6\xea\x8f\x90\xba\xd3H\x03"\x90\xca\'\xd9$\xf4z)\xd2\x93X\ +\xa3(\r(\xe5c\xa5\xc2\n\x89\x14\x02!\x14\x0e\xc7h0\xe2\x93\x8f\x7f\xdd\xddt\ +\x17\xe2E\x9b\xd7Z\x93\xe7y\xd7\xc3\x18c\xeai\xb7)\xdfm\x8d\xe7G\xc4\xabg\ +\x84\xbd\x88^_a\x8d\xc6U\x92\xca\t\x10\xb2\xae\x96B"\x84C\x08\xc1\'\x1f\x9f\ +\xd2\x8f\xc2\xbd\xedh!ZM\xb4 m\xc4\x8c1uB4\xcdTex1"\x10\xf6\x87,\xae\xce\x88\ +\xd7+\xa4\xd2 C\x9cUX\x07B(\xa4\xd4HipR\xf2\xfb\x0f\xde\xe1\xcd[\x87/\x01\ +\xb4\xe2l\xc5\xd8\xeb\xf5:}\x94eI\x96e$IB\x92$\xcc\x17kJ\xc3OD\xc4\x0b\x88\ +\x86\xd7X.\xceQZ\x13\x84\x16D\x80\x13`*\xd5\xec\xad\xe2\xb5\xd7&<\xf8\xf0\ +\x97]\xa1k\xe7\xeeV\xf8\xbeO\xaf\xd7C\xebZ\x03eYvn\xbaZ\xad\x88\xe3\x988)\ +\xb1\xaei\x8a\xb7>R\x8fW\xaeM(*\xcbb>\'M\xd6`r\xa4+\xc1\x16\x18S!\xa4\xe0\ +\x8f\xf7\xdf\xe9\x1a\xde\xdd\xdec\x17\xa2\xcd\x94\x16\xa2\xedc\xe7\xf39\x8b\ +\xc5\x82\x1f\xcf.\x88\x93jw\xe9-\x88\x10\x82hx\xc0\xd1\xcd\xdb\xccf\x97\xcc\ +\x9f_\x91g1\xd2\x15hi\x90\xae\xe4\xfe\x07o\x12\xfa\x8a\xaa38^\xf2\x8d\xd6M\ +\xdb,Y,\x16\xccf3...\x98\xcdf\xccf3\x9e/\x13*[\'Ik\x86\xbaI\x9an\xbc~\xfc6\ +\xf1r\xc1\xd9\x0f\x8f\x10Rp\xe8\xd7\xe2\xbbqs\xc4A\xa4X\xaf\xd7\xdd\xc2RJ<\ +\xcf\xdb\xcb\x84<\xcf\xbb\x962I\x12\x16\x8b\x05\x17\x17\x17\x9c\x9f\x9f3\x9d\ +Ny\xf2\xdd9\xab\xb8\xecZ\xd3\xb6ll\xfb\x91\x86HH\xc1[\xef\xbeO\x9a\xa5\\\xcd\ +\x9e\x11\x06!\xbd0\xc4W%\x97\x97\x97]\xa1k\x17o\xbby\xdf\xf7\xc9\xb2l/\x1a\ +\xab\xd5\x8a\xf9|\xcel6c:\x9d\xf2\xbf\xc7O\xb9Z\xa4\x8d\x0f\t\xb6\xe7\x9c\ +\x1d\x10\xd1|(\x10\xf4\xa2\x01\xa7\xf7\xee\xf3\xe8\xeb/\xb9\xbc|\x8a\xef{\ +\xf4B\x1f\x01\xdd\x7f\x9d\xa6)\xa3\xd1\xa8;\xebh\xad\x91Rv`\xad8\xdb\xady\ +\xf2\xdd9W\x8b\x14\xebjg\x16\r\xc8\x9e\xc5o\xb5+:\xda(\x1arz\xef\x01\xdf>\ +\xfe\x8a\xab\xe9S\x9c;\xeb\x9a\x9a$IX\xaf\xd7\x0c\x87\xc3\xae~\xb4 \xbb\xdf\ +\x89\xe3\x98\x1f\xcf.x\xbeLX\xc5es\x9ea\xebK;\xa3\xe9G\xb6\xd1\xd8\xbe\n\x84\ +\x90\xdc\xbes\x97k\xd7o2\x9f\x9dq>\x9duG\x89\xf1x\xcc`0\xa0\xd7\xeb\xbd\xd4\ +\x81\xe5y\xce|\xb1&NJ\xe2\xa4\xa2\xb2M\x04\xc4\xf6\xbe]c\xb5\xaf\x11\x87\xb3\ +\x0e\xe7,\xce\xd9\xba\xcdw\x96VM\x83\xc1\x01Q4"\xcf\xeb\xf6n\x19g\xac6S#\x19\x1e\xdd`\x88\x16G\xe0\xbd\xc39w\x03\xa2\ +\xb4&\x08B\x82(&\x0c\x9b\xa8(U\xff\x83\xdd\xa1\xa4e\xd8\x1f\x11\xc7gH\x15pr4\ +@J\x89s\x8e\xb2,)\x8a\x82,\xcbj\x88\xcd\x86\xe5r\xc9r\xb9d\xb1\x98p=\xbf\xe0\ +\xf4\xfe#>y\xf8\x1c!k\x00D\r\xe4\xbd\xc3\x9a\xbd\x88(\xa9PZ\xa3uX\x03\x05!R\ +\n\x02\x911:\n\x19\x8dN\x89{}T\x10a\x9c\xe0\xec\xee\t\xe3\xe3\x04c\x0cy\x9e\ +\x1f@\xacV+\xfa\xfd>\xbd^\x8f0\x0c\x99\xcf\xe7\xbc\xfa\xefwlWK\x9e~\xfe%\xbd\ +dP\x83 \xc0{\x84\xdc\x03\x11R!\xa5BI\x89R\n)\x05\xb1.8\xbd3\xe4\xe4\xe4\x0e\ +\xc9\xe0\x08\x1d$TN\xb1MKr\x17\xf1\xe9\xa7\x9f\x92e\x19\xdb\xed\x96,\xcb\xe8\ +\xf5z\xc4qL\x14E\x84a\x88\xd6\x1a\xa5j\x9dYk\xb9\xf8\xed\x9c,\xcfx\xf1\xf2+\ +\x92d\xd8\x14\x82CZ\xb9\x07"D-\xa8&\x7f\x81\xc88\x1d\x0f9=\xbd\xcf\xe8\xf8\ +\x0eq\xff\x04\xa1\x13v\x99aW.y\xf3\xee\x9a\x7f\xfc\xbd\x8f\xb5\x96$I\x00p\ +\xce\xe1\xbdo\xaa\x0c\xa4\x94\xdd&\x84@J\xc9lv\xc9\xf9\x0f\xdf\xf2\xe2\xe5\ +\xd7\x08!\x01\xd1\x15\x9c\x06\xea\x13\xe0\xc1\x83\xb0;FG!\'\xe3;\x0c\x8f\xee\ +p4~@\xdc\x1fc\xbcf\x95\xce\xd8\xec\n\xd2,\xe3\x87\xf3w<\xf8\xa8\x86\xf1\xde\ +\xa3\x94"\x8a"\x84\x10h\xad\t\x82\x80 \x08\xba\xe8DQD\x1c\xc7L&oy\xfd\xcb\ +\xf7C\ +\x05\x11\x95S\xec2\xc3*\x9dqy9\xe1\xfd\xfb\x19\xeb\xf5\x8a,K\xb1\xb6\x0e\xe7\ +\xcfo\xde\xf3\xf4O\x1fu\xa7h5\xa1\x94Bk\xfdAT\xa4\x94x\xef\xb1\xd62\x99\xce)\ +\x8a\x1dZG{ \x1e\xac-\x88\x82\x00\xa94\xc6\n\xb6i\xc9\xae\\\xb2\xd9\x15\\]\ +\xcd\xd9l\xd6dY\xda\x88\xb2\xb6\xf8\x9f\xdf\xbc\xe7\xf9\x9f\xefubmE\xa9\x94\ +\xc2{\x8fs\xae\x8b\xca~\x05\x95e\xc9n\xb7#\xdb\xad\xe8\x8f\xee\x1eF\xc4\x99\ +\x02\xa9"@\x91\x95\x06Wm\xa9lN\x9ael7\x1b\xf2{|\xaf\xeb\x1f\xffO\x17\xb7}Dk\x8d\xb5\x96<\xcf\x0f\xfa\x8f\ +\x90\xba\xd3\x88n\xd5\'UH\xbaK\xe9\xf52d \x81\x88\x07\xf7\xc6<{\xfc\t\x7f}\ +\xfe\xb0k\xeb\xfb%\xda\x02\xb4\xe9h!n\xdb\xbc\xd6\x9a\xa2(\x10B\xe0\x9c\xc3Z\ +[o\xee\xa6\xe4\xbb\xd4\x04a\xc2n}I\x7f0\xe0\xech\xc4\xc3O\xcf8>>\xe6\xe4$\ +\xa1,\xcb.\xd7\xad1\xed\x97h\xfb}\x0b\xd1\n\xb4\x05i\x8f\xb7\xd6\xd6\x05\xd1\ +\x0cS\xc6r;"\x10\xf7\x87,\xaf.\xd8n\xd6\x0c\x07}\xae\xaf\xaf\x91Rvw\x16\x04\ +\x01Z\xeb\x836\x7f\x1b\xa0\x15g+\xc6^\xaf\xd7\xe9\xa3\xaa*\xf2<\'MS\xd24e\ +\xb1\xdctB=\x8cH\x10\x91\x0c\xc7,\x16\x93N`\xb7A\xc20<\xb0\xf2Vx-@\x1b\x810\ +\x0c\xe9\xf5z\x1dxUU\x9d\x9b\xae\xd7k\xb6\xdb-\xdb\xb4\xc2\xf9f(\xde\x07\x01\ +8\x19\x9fq=\xbf`>\x9fw\x17k-\xbam\\\xed\x05[\x9d\xfc\x1eD{#-D;\xc7.\x16\x0b\ +\x96\xcb%\xef.flSs\xe0G\x1d\x88\x10\x82dx\xc4\xe9\xfdG\xbc\xfa\xefwXk\xbb\ +\x0b\xb5\x00-P\x14E\xdd\xf4}\xdb7Z7m\xd3\xb1\xd9l\x98\xcf\xe7\xccf3\xe6\xf39\ +\xf3\xf9\x9c\xebU\x8aqu\x91\x88\xfd\tm\xdf\xb2?y\xf8\x9c\xedj\xc9\xc5o\xe7H)\ +?\x10\xde\xbe.\xda\xd4\xedWBQ\x14H)\xbbt,\x97Kf\xb3\x19\x93\xc9\x84\xe9t\xca\ +\xab7\x13\xd6\xdb\xaa\x1bM\xdb\xb6q\x90\x1a\x10\x08)x\xfa\xf9\x97dy\xc6lvy0Y\ +\xb5\xa5\xda\xb6xkm\xe7\x98a\x18\x92\xe7y\x17\x8d<\xcfY\xaf\xd7,\x16\x0b\xe6\ +\xf39\xd3\xe9\x94\x9f~y\xcb\xd52\xab\xdb\x84\x10\xbf\x13\x11\x9a%\x8f\xa8\ +\xf7\xbdd\xc0\x8b\x97_q\xfe\xc3\xb7L&o\xf7&+\xdf\xddu\x96e\x8cF#\xfa\xfd>q\ +\x1c\xa3\xb5\xee\xd6:\xc6\x98N\x9c\xcb\xe5\xb2^R\xbc\x99p\xb5\xccp^ hG\x05\ +\xd1-\\u\x9b\x19\xdf\xe6\xa8\xa1M\x92!/^~\xcd\xeb_\xbe\xe7j\xfa\x16\xef/\xba\ +\xa1&MS6\x9b\r\xc3\xe1\xb0[F\xb4 \xfb\xc7l\xb7[\xde]\xcc\xb8^\xa5\xac\xb7U\ +\xb3\x9e\x01\x84l\xa6\xf8[b\xf5{\xd1\xb8\xd9\x0b\x84\x90\xc0\xc5\xcb\x1fQ\xaaG\x10(<\xdf\xc7\x93\x1eBz\x08!\ +\xb0\xd6r\xc0j\xdd\xce\xde\xbdaE\xe7\x9f\x82?}\x89\xc3_\xed\xfe\xa7\xb5\x96\ +\x7f\xff\xeb\x9f\r\x88R=\xc20F\xf5\xc2\x16F:\x10,X\x8b5\x80\xad\xd1\xba\xc0\ +\xd4\x05\xba.\xa8\xeb\x02S\xd7\xd4uE\xad-\x16\x89\xf4\x14\x81\x8a\t\xfbC\x82\ +\xa0\xd7\x9cX\x88\x0e\x84hp\x05Xc1V\xdf)\x12\x04\n\xd5\x0b\t\xc3\x88\xa0\x17\ +\xe2\xfb\nOJ\x87\x8e1\x15\xe8\x0cLE/\x08\x90^\x0f)$\x16\xa8\xeb\x9a\xaa\xaa(\ +\x8a\x82<\xcbH\xd3\x94\xdd\xfa\x9a\xe4\xf6\x8ax8\xe1xrJ<<\xba\xc3\x10\x0eG`\ +\xad\xc1\x18s\x07\xe2\xf9>A\xa0\x08z!J\xedU\xf1\xbc\xe6\x03z\x87\'5\xc3\xfe\ +\x880.\ +\xae8y\xf4\x94\'_\x9e#d\x03\x80h\x80\xac5\xe8\xba\xa3\x88\'=<\xdf\xc7\xf7U\ +\x03\x14(\xa4\x14\x04"ct\xa4\x18\x8dN\x08\xa3>^\xd0\xa36\x82\xac\xa8I\xd3\ +\x02]\xe7\x94d\x94FR[\x81\x95\x02\x19H\x9e|6a\xb9\x8cQJ\xb1X,x\xf3\xdb\xcflW\ +\t\xcf\xbf\xfd\x9e(\x1e4 \x08\xb0\x16!; BzH\xe9\xe1I\x89\xe7yH)\x08\xfd\x82\ +\x93\x07C\x8e\x8f\x1f\x10\x0f\x8e\xf0\x83\x98\xcaxl\xd3\x12]l)\xb4%\xabJ\xd2\ +RP\x96PU\x02]\n\x8e\x8f\xc6\x9c\x9e\x8e\x08\x82\x00\xcfk\xfaLk\xcd\xd5\x1f\ +\xaf\xc8\xf2\x8c\x8b\x97?\x10\xc7\xc3\xbd\x11\x0cR\xcb\x0e\x88\x10MC\xed\xeb\ +\x17\x88\x8c\x93\xc9\x90\x93\x93G\x8c\xc6\x0f\x08\xfb\xc7\x08?f\x97\xd5\xec\ +\xca\x84\xda\xe4T\x1a\xea\x1a\xb4\x91\xcd\xa6\x05\xb5\x11<9;e<\xee!\xa5l7!\ +\x04RJ\xe6\xf3k^\xfd\xfa\x13\x17/\x7fD\x08\t\x88\xd6p>\x80\xb5v\xef\x0e\x10z\ +\xc7\xe8Hq\\s}=\xe5\xf6v\xc1v\xb3!\xcf3\xaa\xaa\xc4h\xdd\\\xb1\xe7\xf3\xc5\xe9C&\ +\xc7G\x94e\x89R\n\xa5\x14\xbd^\x0f\xa5\x14a\x18\xa2Tc\x82\xdb\xd9{&\x0f\x1f1\ +\x18\x1ca\xbb\xae\x01\x9a\x9c\xd0Y\xe3\x8e\xa8\x8f\x1f\xc4\x08?\xa6\xb6>\xb3\ +\x0f\xd7\xbc{{\xc9\xcd\xcd\x9c\xcdfM\x9eg\xd4U\x85\xb1\xb6\t&!\xf1<\xc97\xcf\ +\x1f\x13EQ\xabF\x10\x04\xf4z\xbdV\x99\xc6\x89`\xed\x15\xcb\xc5\x15q<\xc2\x18\ +{\x08\x82\xad\xc1T\x84\xe1)^\xd0\xa32\x1e\xbb\xacf\x95\xce\xb9\xbe\x9ers3g\ +\xbd^\x91e)Z\xeb\xfd\x17\xba\xb0j\x02\xe7\x9b\xe7g\xed\t}\xdf\xffD\x15)%\xd6\ +Z\xb4\xd6Lg\x0b\x8ab\x87\xef\xf7: \x16\xb4.\xf6a\xe5Sk\xc16-\xd9\x95\t\x9b]\ +\xc1\xed\xed\x82\xcdfM\x96\xa5\x18c\xb0\xb6\x13\xf1B"\xb0L&\xc7\x8cG}\x00<\ +\xcf\xc3Z\x8b1\xa6U\xa5\xeb\xa0\xb2,\xd9\xedvd\xbb\x15\xfd\xd1\xc3CEL]\x10\ +\x04\x11q\x14\x81\xf4X\xad\xb7T:\'\xcd\xb2\xb6\'\xb4\xd6X\xbb\'Gt\xd6\x0f\ +\xc1\xc5\xf9\x13\xa4\x94\x07\x91.\x84h\x15qpEQ\x90\xa6)\xeb\xf5\x9a\xd56?\ +\xec\x11\x8bE\xd7\x05\x9e\xe7\x11\x85\x8a\xf3g\x9f3\x9e|\xc6mR\xf0\x9f\xdf\ +\xff\xe0\xe6fN]U\xb8c?Y\xd8\x04|\xf5\xb7\x936\x06\xba\xd6\x050\xc6\xe0y\x1e\ +\xc6\x18\xb2,c\xb3\xd90\x1e\x8fY\xeff\x18{\xafY\xeb\xbah?T\xd75\xbe\xb4|\xf1\ +\xf9\x80\xc7\'_\xf3\x8f\x8b3^\xff\xef\x86W\xef\xe6\xbc\xbd\x9c~\xc2\xf1`2f<\ +\x8c\x0f@\\\x9f8u\xa4\x94h\xad\x19\x8dF\x0c\x87C\x06\x83\x01\x817\xdf\xaf\ +\xee\x1d\xfb6\xabhMY\x96\xe4y\xcev\xbb%\x8ec\xb4\xd6x\x12\xbe}\xf69\x7f\xff\ +\xea\x8c\xaa6\xfc\xf7\xf2\x86\xdf\xdfNys9\x05\x0b\xdf\x9d?nK\xe1\x94p \x0e&\ +\x08\x02\x8c1\xf4\xfb}\xa2("\x8a"\xc2PQ\x1f\x80XA]W\xed*\x9ae\x19Y\x96\xed\ +\x9da\xf7\xb1\xdf\xc8\x1c\xf6\x02^|}\xc6\x8b\xaf\xcf(\x8a\x8aW\x977|\xf9x\ +\xd2\xaa!\x84\xc0\xf3\xbc\x16\xc4E\xbdS:\x0cC\xc20l\x9c\x14(\xaa\xc6\x80\x9d\ +\xd2h\xdbB\xecv;\xa2(Bk\xdd\xa6\xa2\xef\xfbm\xe9Z\xa8P\xf1\xdd\xf9\xe3O\x94\ +\xf0<\xef Y=\xcfCk\xdd\xa6\xac\xef\xfb\x8d\x8b\xa4\x07\xf5\xbd\xd2Xd3K\xecvl\ +6\x1b\xc20\xc4Z\xdbB8\x80\xae#\xba[\xb7\x1c\xf7s\xc4\xf7}\xb4\xd6\xe4y~\xb0\ +\xfe\x08\xe9\xdf\xef\x11\x81\xf4T\x0b\xb1Z\xad\xe8\xf5zXk\xdb\xfa\xfa\xbe\ +\x7f\xe0\x84.\x80+\x87\x83\xe8\xaa\xe1@\x8a\xa2@\x08\x811\x06\xadu\xb3\x19\ +\xd96|[\x9a@\xc5l\xd6\xd7$IB\xbf\xdfG)\xd5\x1c\xb0\xaf\xb3\xab\xb5\x0b\xa6\ +\xaeE\xdd\xfb\x0e\xc2-p\x0e\xc4\x1d\xaf\xb5n\rQ\x14\x05\xb5\xe6\xbe"\x10\xf6\ +\x87$\xb7W$IB\x14E\xad\x02\xee\xca\x9c*\xee\x83\x7f\x06\xe0\xa0]3FQ\xd4\xf6G\ +UU\xe4yN\x9a\xa6\xa4i\xca2\xd9\xb4\x8dz\xa8H\xd0#\x1eNX.\xa7m\x83\xdd\x07QJa\ +\x8ci\xaf\xd05\x9e\x03p\n(\xa5\xda\x8b\xb1\xd6RUU\x9b\xa6\xeb\xf5\x9a\xedv\ +\xcb6\xad0v?\x14wA\x00\x8e\'\xa7|\\\\\xb1X,\xda\x93\xb9\x88v\x0b\x97;\xa1\ +\xeb\x93?\x83p\x17\xe2 6\x9b\rI\x92\xb0\\.I\x92\x84\x0fWs\xb6i\xdd=\xf5\x1d\ +\x88\x10\x82xx\xc4\xc9\xa3\xa7\xbc\xf9\xedg\xf4~\xcep\xdd\xefj\xef67}\xdf\ +\xcf\r\x17`\xae\x1c\x9b\xcd\x86\xc5b\xc1|>g\xb1X\xb0X,\xf8\xb8J\xa9Mc\x12\ +\xd1\x9d\xd0\xba\x91\xfd\xe4\xcbs\xb6\xab\x84\xab?^!\xa5\xfc\xa4\xf1\xba}\ +\xe1J\xd7uBQ\x14H)\xdbr$I\xc2|>g:\x9d2\x9b\xcdxs9e\xbd\xad\xda\xd1t\xdfr\x87\ +\xa5\x01\x81\x90\x82\xe7\xdf~O\x96g\xcc\xe7\xd7\x07\x93\x95\xb3\xaa[\xe2\xb5\ +\xd6mb*\xa5\xc8\xf3\xbcU#\xcfs\xd6\xeb5\xcb\xe5\x92\xc5b\xc1l6\xe3\xf7\xd7\ +\xef\xb9M\xb2f\xac\xdc\xcf1\x87\x8a\xb0\xbf\xe5\x11\xcd>\x8a\x07\\\xbc\xfc\ +\x81W\xbf\xfe\xc4t\xfa\xbe3Y\xd9\xf6\xaa\xb3,c4\x1a\xd1\xef\xf7\t\xc3\xb0u\ +\x99\x03s\xcd\x99$IsKq9\xe56\xc90V \xb8\x1b\xa8\xdc\x8d\xab\xef*c]\x8d\xf6\ +\xb4q<\xe4\xe2\xe5\x8f\xbc{\xfd\x0b\xb7\xb3\xf7X{\xd5\x0e5i\x9a\xb2\xd9l\x18\ +\x0e\x87\xfb\xc5\xeb\x0e\xa4{\xccv\xbb\xe5\xc3\xd5\x9c\x8f\xab\x94\xf5\xb6\ +\xda\xdf\xcf\xd0\x0cS\xe2.\xccZ\x10\xdbQ\xe3n/\x10B\xf2\xf4\xd9\x0b&\x0f\x1f\ +\xb1\\\\1\x9d-\xd8\xedv\xac\xd7k\xc6\xe31\x83\xc1\x80(\x8a>\x99\xc0\x8a\xa2`\ +\x99l\xd8\xa6\x15\xdb\xb4\xa66{\x05\xc4\xdd\xf7\xb6\xf7\xc3\x87=b\xb1\xc6b\ +\xad\xc1Z\xd3\x8c\xf9\xd6\xe0\xbai08"\x8eG\x14E3\xde\xad\xb69\xeb\xdd\x8c\ +\xc0\x9b\x13\x86\n\x15\xa8\xe6\xe9\x81\xf4\xd1FRk\xa84\xfb\x9cpJ;\xed\x0f\ +\x1f\x0b\x1c$\xab\xb5\xcd]\xb91\xcd\xbd\xa8\x90\x1a\xa9%V\x805\x1ak\x0c\xc6X\ +|\xbfG\x7f\xf4\xb0\xf9\xdb\x1a\xac\xb5\xd4\xd66\tY\xdb\xf6K\xdd\xbe-\xb8p\ +\x83v\xe7\x01\x87\xdd\x1fg\xda\xa6\xf8k<\xa8\xf9?\xa2\xcax\xb9\xd2zv\x8b\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def get012Bitmap(): + return wxBitmapFromImage(get012Image()) + +def get012Image(): + stream = cStringIO.StringIO(get012Data()) + return wxImageFromStream(stream) + +index.append('012') +catalog['012'] = ImageClass() +catalog['012'].getData = get012Data +catalog['012'].getImage = get012Image +catalog['012'].getBitmap = get012Bitmap + + +#---------------------------------------------------------------------- +def get013Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +HIDATx\x9c\xcd\x98\xdbn\x1b\xd7\x15\x86\xbf\xbd\xf7\x1cy\x12-Kf\x9c\xc4\xaa\ +\xe1\xb8qS\xa8nR\x15\x01\x82\xc6E\x81\xa0@\n\xe4\xaa}\xba\xbe@/z\xd3\x9b^\ +\x16\x08P\xa0g4A\x81 @b\xc4I\xeaD\x96\xe4\x919\x1c\x923\x1c\xce>\xf4b\xb8G\ +\xa4\xeb\x07\x08\x81\xd1H\xe2&\xe7\x9b\xb5\xfe\xf5\xaf\xb5G\x00\x8e\xef\xc0+\ +\x00\xb8\x7f\xf2\x80(\x8a\t\xc3\x08\x15\x04(\xa9\x10R!\x84\xc09\xc7\x0e\xab\ +\xf3\'w\xf5\x0f\'\xb6\xde\x14\xbc\xf0%v\x7fu\x9b\x9f\xce9\xfe\xfc\xa7?\xb4 Q\ +\x14\x93$=\xa28\xe9`\xa4\x07\xc1\x81s8\x0b8\x8d15V\xd7\x18]\xa3u\x8d\xd5\x1a\ +\xad\x1b\xb4q8$RE\x84Q\x8f\xa4?$\x0c\xe3\xf6\xc2BlA\x88\x16W\x80\xb3\x0e\xeb\ +\xccUD\xc20"\x8a\x13\x92$%\x8c\x13\x82 BI\xe9\xd1\xb1\xb6\x01S\x81m\x88\xc3\ +\x10\xa9b\xa4\x908@kM\xd34\xd4u\xcd\xaa\xaa(\xcb\x92E\xf1\x84\xfc\xf2\x94\ +\xdep\x9fk\xfb\x13z\xc3\xbd+\x0c\xe1q\x04\xceY\xac\xb5W *\x08\x08\xc3\x880N\ +\x88\xa2MT\x94j?`\x96(i\x18\xf6G$\xc9\x04\xa9B@b\xace\xbdnX\xd7k\xd6\xcd\x9a\ +\xf5\xba&I+\xd2^E\x92\xf6X\xcc\x0bf\xf9\x19\xcf\xb2Sn\xdc\xbc\xcd\xabG\xf7\ +\x10\xb2\x05@\xb4@\xceY\x8c\xde\x8a\x88\x92\n\x15\x04\x04A\xd4\x02\x85\x11R\ +\nBQ1\xda\x8b\x19\x8dn\x90\xa4}T\x18\xa3\xad\xa0\xaa5eYc\xf4\x8a5\x15k+\xd1N\ +\xe0\xa4@\x86\x92\xb4\xaf\x90*@\x05\x01\xf9t\xca\xa3\xcf>f1\xcb\xb9\xfb\xc6[\ +\xa4\xbdA\x0b\x82\x00\xe7\x10r\x0bDH\x85\x94\n%%J)\xa4\x14$A\xcdK\x07#&\x93\ +\t*\xea\xa3\x82\x94\xc6*\x16\xe5\x1aS/\xa8\x8d\xa3j\xd6\x94k\xc1z\rM#0k\x811\ +\x12g\x02\x90\tqb\x19\xed9\x8c1\x9c~\xf3\x90jUq\xff\xe4]z\xbd\xe1\xa6\x10,\ +\xd2\xc8-\x10!ZAm\xf2\x17\x8a\x8a\x9b\x87{\xdc\xbau\x8b\xa3\xa3#\xae\x1d\xbc\ +\xc4\xa3o\n\x96\x95f\xb9\xce\xd1vEc@k0V\xb6\x87\x11h+h\x8c\xc0i\x89\xb3\nDL\ +\x9c\xc0\xb5}\x81\x90\x82\xcb\xec\t\x0f?\xfd\x88\xfb\'\x0f\x10B\x02\xa2+\xb8\ +\x00\xc09\xb7\xa9\x0e\x10f\xc9\xde8f2\x99ptt\xc4\xf1\xf11\x87\x87\x87\x8c\ +\x0f+>\xfc\xcb\x7f\x98/k\xca\xaab\xb5\xaai\xb4\xc6Z\xd3\x96\xb8\x10 \x15JEh\ +\'\xb0\x9b\xaa\x96J\x90\xf4$\x87QH\x12\'<}\xfa\x98\xaf\xbe\xf8\x84\xdb\xaf\ +\x1do\xaaq+5lJ\xd4\xda\x86PY\xae_\x7f\x99\xc9d\xc2\x9d;w8<b\xc6\x18\xde>\x9e\xf0\x8f\x7f\xfe\x8b\ +\xd5\xaaB7\r\xd6\xb9\xd6\x98\x84D)\x89\x14\x16+$BH\xa4\x0c\x90RbL\x00\xaea\ +\xffz\x8fA\xea\xb88\x8fp\xee\x94ivJ\xaf7\xc2Z\xb7\x0b\x82\xd3\x08\xa7\xe9\ +\xf7\xfb\x8cF#\xc6\xe31RJ\xac\xb5\x18c\xc8\xb2\x8c@j~\xfa\xa3#>\xfc\xeb\'\ +\x1b@oV\x1b\xc3\x91\n)Z0)\rR*")x\xf3\x07/\xf3\xca\x8d\x1eO\x9f>E\x00\xc6\x18\ +\xce\xce3\xeazI\x10\xc4[ \x0e\x8c\xa9I\xa2\x88$I\xe8\xf5z\x84aH\xd344M\xc3l6\ +c:\x9d\xb2X,x\xf3\x87\xb7\xf8\xf2q\xc6\xa3\xff>\xd9x\x94\xa4\xf5\xdf\xd63\ +\x85P\x08\xe1pRrpp\x9d_\xbe{\x8f\xf10a>\x9f#\x84\xc0\x18\xc3z\xbdf\xb9\\R-g\ +\xf4G\x07\xbb\x11\xb1\xbaF\xa9\x94(\x8a\x08\x82\x00\xad5\xcb\xe5\x92\xa6i(\ +\x8a\x82\xb2,\xb1\xd6"\x84\xe0W\xbf8\xe6\xb7\xbf\x9b\xa2u\xbde\xdc\xado;\x1c\ +B\x08N\x8e_\xe3\xc1\xdb\xdf\'\n\x15Zk\x94R8\xe7\xa8\xeb\x9a\xb2,)\x8a\x82\ +\xd9b\xb5\xab\x11\x87\xc3\xe8\x1a\xa5\xda\xfeb\xade\xb5ZQ\x14\x05M\xd3P\x96%\ +\xeb\xf5\x1a)\xdb\x9aO\x93\x88_\xbf\xff\x16\xbf\xff\xe3\xdf=G\xd7\xef\xa20\ +\xe5\x83\xf7\xee\xf3\xc6\xdd\x97\xbb\xf5\xd6Z\x94RXk\xa9\xaa\x8a\xf9|\xcex<\ +\xa6X\x9ec\xddsb\xf5wg\xadEkMUU\x18c:(\xdf\x89}\x03\xfb\xde+\xd7y\xe7\xe4u\ +\xfe\xf6\xef\xcf;\x98Wo\x1e\xf2\xc1{?f\x7f<@)E\x10\x04\xdd\xfaV\xb8\x86\xd1h\ +\xc4p8d0\x18\x10\xaa\x8bMw\xdf*\xdf\xb6\x8bj\xd6\xeb5\xab\xd5\x8a\xc5bA\xaf\ +\xd7\xc3\x18\x831f\xe3\xb8\xb2\xbbK\xe7\x1c?;\xb9\xcb\xe7_^p\xf9,\xe7\x9d\ +\x93{\xfc\xfc\xed\xd7\xbb5\x1e\xc4\xc3\x84a\x88\xb5\x96~\xbfO\x9a\xa6\xa4iJ\ +\x92D\xe8\x1d\x10\'\xd0\xba\xe9\xbahUUTU\xd5]\xd0C\xbc\xe8\xf5\x9b\xf7\x7fB1\ +\xaf8z\xe5z\xe7\xd0J\xa9\x0e$\x0c\xc3.-Zk\x92$!I\x12\xe28&\n#\x9a\xd6\xcf\ +\xb6Rc\\\x07\xb1\\.I\xd3\x14c\x0cA\x10\x10\xc71A\x10t\xa9\xf3PB\x08\xf6\x86)\ +\xe3Qo\'\x12J)\xc20$\x0cC\xa2\xa8\xed\xe4\xc6\x98\xae\x10\x82 h\xf5(\x15\xe8\ +\xe7R\xe3\x90\x94e\xc9r\xb9d>\x9f\x93$\t\xce\xb9\x0e\xc2\x03\xf8\x9c\xfb\xbb\ +\xf7\xc7v:\xfc9\x8a\xa2\xee\xe2\xc6\x18V\xabU\x07,\x84@\xc8\xe0y\x8d\x08\xa4\ +\x8a:\x88\xd9lF\x1c\xc7\x9d8\xc30$\x08\x82\x1d\x8dl\x03\xf8tx\x88\xedhx\x90\ +\xba\xae\xbb\x8a\xf4\xba3\xf6*\xdd]j\xc2\xa8\xc7\xbcxB\x9e\xe7\xf4\xfb}\xa2(\ +j\x17l\xf2\xecs\xedK\xdcCm\xa7\xc3C\xc4qL\x92$\x1d\x88_o\x8c\xe9\n\xa2\xaek\ +\xb4\xe1\xf9\x88@\xd2\x1f\x92_\x9e\x92\xe79i\x9av\x11\xf0w\xe6\xa3\xe2?\xf8"\ +\x00\x0f\xed\xc5\x98\xa6i\xa7\x8f\xa6iX\xadV\x94eIY\x96L\xf3y\'\xd4\xdd\x88\ +\x841\xbd\xe1>\xd3\xe9Y\'\xb0\xe7A\xa2(\xea\xdcUJ\xd9\t\xcf\x03\xf8\x08DQ\ +\xd4\xdd\x8cs\xae3\xc5\xa2((\x8a\x82\xc5b\xc1\xa2l\xb0\xce;\xe1v\xd3\x03\xae\ +\xedOx\x96\x9d\x92eYw\xb1(\x8a\x88\xe3\xb8-\xb7- \xaf\x93\x17A\xf8\x1b\xf1\ +\x10\xf3\xf9\x9c<\xcf\x99N\xa7\xe4y\xce\xb7\xa7\x17,J\xbdc\x03\x1d\x88\x10\ +\x82\xdep\x8f\x1b7o\xf3\xe8\xb3\x8f1\x9b9\xc3\xab\xdf\xe7\xde\x1f~\xfa~\xde7\ +\xbc\x81\xf9t\xcc\xe7s\xb2,\xe3\xe2\xe2\x82,\xcb\xc8\xb2\x8cg\xb3\x12m\xdb"\ +\x11\xdb\x13\xda\xf6\xe6\xe7\xd5\xa3{,f9\xa7\xdf\xa3X4\xddh\ +\xba\x91\xdcnj\xa0\x9d-\xef\xbe\xf1\x16\xd5\xaa\xe2\xe2\xe2I\x07\xe1/\xec{\ +\x8e\xbf\xb8w\xcc(\x8a\xba\x9e\xe4=\xa3(\n\xa6\xd3)Y\x96q~~\xce\xe7_<\xe62\ +\xaf\xda\xb1r3\xc7\xecF\x84\xcd\x96G\xb4\xe7\xb47\xe0\xfe\xc9\xbb<\xfc\xf4#\ +\xce\xce\x1eo\xf68W\x93\x9aw\xe0\xd1hD\xbf\xdf\'I\x92\xae\xca<\x98\x17g\x9e\ +\xe7dY\xc6\xa3\xaf\xcf\xb8\xcc+\xackG\x06?P\xf9\x8dk\xe03\xe3|\x8e6\xb4\xbd\ +\xde\x90\xfb\'\x0f\xf8\xea\x8bO\xb8<\x7f\x8cs\xa7\xddPS\x96%\xf3\xf9\x9c\xe1\ +p\xb8i^W \xdbk\x16\x8b\x05\xdf\x9e^\xf0lVR,\x9a\xcd~\x86\xcdL\xbb\xdb\xbb6\ +\xf3\xc8U4\xae\xce\x02!$\xb7_;f\xff\xe0&\xd3\xec\x94\xb3\xf3\x8c\xe5rIQ\x14\ +\x8c\xc7c\x06\x83\x01i\x9a\x12\xc7qgt>b\xd3|\xce\xa2lX\x94\x1am7\x11\x10W\ +\xdf\xdb\xed\x87w5\xe2p\xd6\xe1\x9c\xc59\xdb\x8e\xf9\xce\xe2\xd54\x18\xec\ +\xd1\xeb\x8d\xa8\xebv\xbc\x9b-V\x14\xcbsBuA\x92DDa\xd4>=\x90\x01\xc6J\xb4\ +\x81\xc6\xb0\xf1\t\x1fi\x1f\xfb\xdd\xc7\x02;\xce\xea\\\xbb+\xb7\xb6\xdd\x8b\ +\ni\x90F\xe2\x048kp\xd6b\xad#\x08b\xfa\xa3\x83\xf6ogq\xce\xa1\x9dk\x1dR\xbb\ +\xeeK\xfd\xb9K\xb8\xf0\x83\xf6\xd6\x03\x0e\xb7Yg;Q|7\x1e\xd4\xfc\x0fU+\x93#\ +\x1a\xd9\x15\x96\x00\x00\x00\x00IEND\xaeB`\x82' + +def get013Bitmap(): + return wxBitmapFromImage(get013Image()) + +def get013Image(): + stream = cStringIO.StringIO(get013Data()) + return wxImageFromStream(stream) + +index.append('013') +catalog['013'] = ImageClass() +catalog['013'].getData = get013Data +catalog['013'].getImage = get013Image +catalog['013'].getBitmap = get013Bitmap + + +#---------------------------------------------------------------------- +def get014Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xc7IDATx\x9c\xcd\x98\xdfn\xdb\xc6\x12\x87\xbf\xd9].)\xca\x96\xd5$\xb6\x92\ +\xa25\x82\xb4\x07E\x81 @\x91^\x1d\xb4\xcf|^\xe0\\\x9d\x07ho\x8a\x02m\xd0\xa0\ +AZ\xc7v\xe9\x88\x92(R\x14\xb9\xbb\xe7\x82\x7f,\xa5y\x80\x12\xa0i[\x12\xf7\ +\xe3\xcco~3+\x01\x02\xff\x80\xc3\x00\xbcx\xf9=\xd6\xc6D\x91E\x1b\x83V\x1aQ\ +\x1a\x11!\x84\xc0\x11k\x18.\xe1\xfe\x1fA\x0e^\x14>z\xc8\xf1\xaf\xa1\xff\x19B\ +\xe0\x7f\xff\xfdO\x07bmL\x92\xa4\xd88\x19a\xd4\x00B\x80\x10\x08\x1e\x08-\xce\ +\xd5\xf8\xb6\xc6\xb55m[\xe3\xdb\x96\xb6mh] \xa0P\xda\x12\xd9\x94dzJ\x14\xc5\ +\xdd\xc2"\x07\x10\xd2\xe1\n\x04\x1f\xf0\xc1\xddG$\x8a,6NH\x92\tQ\x9c`\x8cE+5\ +\xa0\xe3}\x03\xaeBBKb-ZO\xd0Z\x03\xd0\xb6-e\xb5\xa3\xaekvUEY\x96\x14\xebw\ +\xe4wW\xa4\xa7\x0f\xf8\xe4\xc1\x82\xf4\xf4\xec\x1eC\x06\x1c!\x04\x8f\xf7\xfe\ +\x1eD\x1bC\x14Y\xa28\xc1\xda>*Zw\x1fp["\xed\x99\x9d\xcc\x99N\xa7$I\x82\xb5\ +\x16\x11\xc1{\xcf~\xbf\xe7\xf7\xb77\xec\xf75\xc9\xa4b\x92V$\x93\x94b\xb3f\ +\x95_\xf3>\xbb\xe2\xe2\xc9S>\xbb\xfc\nQ\x1d\x00\xd2\x01\x85\xe0q\xedAD\xb4\ +\xd2hc0\xc6v@\x91E)!\x92\x8a\xb3y\xcc\xc3\x87\x9f2\x9f\xcf\x99\xcdf\xa4i\x8a\ +1\x06\xef=m\xdb\xb2\xdb\xed\xf8\xf5\xcd\x8a6\x08A\t*RL\xa6\x1a\xa5\r\xda\x18\ +\xf2\xe5\x92\xd7\xbf\xfcH\xb1\xca\xf9\xf2\xebo\x98\xa4\'\x1d\x08\x02! \xea\ +\x00D\x94F)\x8dV\n\xad5J\t\x89\xa9y\xfch\xc6\xe3\xc7\x8fY,\x16\\\\\\0\x9f\ +\xcf\x89\xa2h\x04\xa8\xaa\x8a\xa2((\xf7\xd04\x82\xdb\x0b\xce)\x823\xa0\x12\ +\xe2\xc43;\x0b8\xe7\xb8\xfa\xe3\x15\xd5\xae\xe2\xc5\xcb\xefH\xd3\xd3\xbe\x10\ +<\xca\xa9\x03\x10\x91NP}\xfe"\xa9xr~\xc6\xe7\x9f\x7f\xce\xe5\xe5%\xcf\x9e=c\ +\xb1X\xa0\x94\xa2i\x1a\xb6\xdb-\xeb\xf5\x1a\xe7\x1ci\x9a\xe2\xbc\xc29\xa1\ +\xf5B\xe3\x84\xd0*\x82\xd7 1q\x02\x9f<\x10D\tw\xd9;^\xfd\xfc\x03/^~\x8f\x88\ +\x02d,8\x03\x10B\xe8\xab\x03\xc4m9\x9b\xc7,\x16\x0b.//y\xfe\xfc9\xe7\xe7\xe7\ +\x00x\xefi\x9af<\xbd\xf78\xe7\xba\x12\x17\x01\xa5\xd1\xda\xd2\x06\xc1\xf7U\ +\xad\xb4\x90\xa4\x8as\x1b\x91\xc4\t\x7f\xfd\xf5\x96\xdf\x7f\xfb\x89\xa7_<\ +\xef\xab\xf1 5\xf4%\xea}C\xa4=\x0f\x1f~\xcab\xb1\xe0\xd9\xb3g\x9c\x9f\x9f\ +\x8f~\xe2\x9cc\xb5Z\xb1^\xaf)\xcb\x92\xddn\x87s\x0e\x11Ai\x83\x11\x85W\x1aD!\ +\xa2q\xad\x06\xafQ*"\x8ecb\x1bc\x8c\xe1\xee\xe6-\x0f\x1e=\xe1\xe4\xe4\x8cpX5\ +@\xe7\x13\xaebv2g>\x9fsqq\xc1b\xb1`\x88\x98s\x8e,\xcbX.\x97\x94e\xc9~\xbfGD\ +\xba\xea\x12\x85\xd6\n%\x1e/\n\x11\x85R\x06\xa5\x14\xce\x19\x08\r\xda\x06\ +\xe2\xd8\xa2\xb5\x02nYfW\xa4\xe9\x0c\xef\xc31\x08\xa1EB\xcbt:e6\x9b1\x9f\xcf\ +QJ\x8d\xe1\xcf\xb2\x8c\xbb\xbb;\x8a\xa2\xc0{\x8fR\x8a\x10\x02J\xa9>\xdf\x01\ +\x94F\x89\x80(\x94r(\xa5Q\xae!\xf8\x88\xa0\x1c\x91\x8d\x89\xadA\x08dwK\xeaz\ +\x8b1\xf1\x01H\x00\xe7j\x12kI\x92\x844M\x89\xa2h\xd4\xc2j\xb5b\xb9\\R\x14\ +\x05!\x84\xd1)E\xa4\x07\x11B\xef\x99"\x1a\x91@P\xaak\x13J\x13B\x8b\xe0\x10\r\ +\x13k\xd1\nv\xbb\x8aj\xbbb:{t\x1c\x11\xdf\xd6h=\xc1Z\x8b1\x86\xb6m\xd9n\xb74\ +M3j\xc2{\x7f\x04q\xd8=\xba\x82\xebZ\x82\x88\xa0\x10\x94\x0ehm\xf0\xdet0:\xa0\ +#8\x89`^\x95l\xca\xdd\xb1F\x02\x01\xd7\xd6h\xadG\xc7\xdc\xedv\xac\xd7k\x9a\ +\xa6\x195\xa1\x94:\x82\x18\x9bb\xdf\n\x90\xc1\xbc\xfb\xf4\x00A\x81\x04\r\xc1\ +\x80vh#L"\xcdl6\xa3\xa82|\xf8@\xacm[\x8f%\xda\xb6-UU\xe1\x9c\x1b\xa1\x86E\ +\xff\x06q\x1f\x94!.\x88(d\xd0\x8e\x80\x0e\x10\x82C+\x8d\x8a\x14q\x121=9!\xca\ +\xee\xc6{\x8c\xe5\xdbu\xd1\x96\xfd~\xcfn\xb7\xa3(\x8a\xce\xac\x9c\xc39\xd7;\ +\xae\x1a\xa3r\x04qx\x88\xf4\x10\xbd~\x94\xee\x970h\xe51F\xb06\xe0\x92\x84$\ +\xb1\xb4G Ah\xdbN\x98u]SU\x15UU\x8d\x0b\x0e\x10\x1f_W\xf8\xf7\xb7_\x01\xf7\ +\xc2\xd5\xc6\xa0\xb5\xc1\x98\xee\x14Q\x10\xe7\xe4\xe4\x84\xc9dB\x1c\ +\xc7\xa3\xd1\r\x11[\xe6\x1b\x8a\xb2\xa1([Z\xdfG@\xee\xef;\x0eV\xc7\x1a\t\x04\ +\x1f\x08\xc1\x13\x82\xef\xc6\xfc\xe0\x19\xd4trrF\x9a\xce\xa8\xeb-\xd5v\xc5\ +\xaa\xd8\xb1\xde\xde\x10\xe9[\x92\xc4b#\xdb\x8f\x85\x06\xe7\x15\xad\x83\xc6\ +\xd1\xfb\xc4\x10\xe9!\xf6\xc7_\x0b\x1c9k\x08\xdd\xae\xdc\xfbn/*\xca\xa1\x9c"\ +\x08\x04\xef\x08\xde\xe3}\xc0\x98\x98\xe9\xecQ\xf7w\xf0\x84\x10hC\xe8\x1c\ +\xb2\r\xe3M\xefg\x95>\xe1}u\x88\x1c|\xc1\x11\xfa\xf7\xf9Q\x14\xff\x8c/j\xfe\ +\x0f\x14\xf5q\xf5\x0b9\xe5)\x00\x00\x00\x00IEND\xaeB`\x82' + +def get014Bitmap(): + return wxBitmapFromImage(get014Image()) + +def get014Image(): + stream = cStringIO.StringIO(get014Data()) + return wxImageFromStream(stream) + +index.append('014') +catalog['014'] = ImageClass() +catalog['014'].getData = get014Data +catalog['014'].getImage = get014Image +catalog['014'].getBitmap = get014Bitmap + + +#---------------------------------------------------------------------- +def get015Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +9IDATx\x9c\xcd\x98M\x8f\x1cG\x19\xc7\x7fU\xd5U\xfd2\xb3\xb3\x93\xf5\xee\x8e\ +\x1d\x92\xc5r\x0c\xc1\x8ae\x11|\x80C"q\xc8\x05E\x90\x0b\'\xee|\x02\xf8\x08|\ +\r\xce\x08q@\x1c@\x08\x11\t\x82\x02HH\x8e\x90,\xe7\xc58\tl\xb2\xde]\xf7zzfz\ +\xa6g\xa6\xbb\xaa8\xf4\xcb\xceX\xfe\x00\x19\xa9\xb6w\xb7{\xba~\xfd\xbc\xfd\ +\x9f\xa7\x05\xe0\xf9\n|\x02\x80;w\xdf\xc4\x98\x10\xad\r*\x08PR!\xa4B\x08\x81\ +\xf7\x9e-V\xdf\x1e\xfc\xe5?\xbc\xd88)x\xeeGl\xff\xea\x9b\x9f\xde{\xde\xfb\ +\xf3ok\x10cB\xa2(\xc1\x84Q\x07#[\x10x\xf0\x05N\x86D\x89\xe0\xc0h\xa20\xe2\ +\xc9\x93c>\x7ft\x9f\xeb\xaf\xdcn\xb2q\xc354)\xea\\\x89V\x8e+W^d4\x1aq\xe3\ +\xc6\r\x0e\x0e\x0e\xbazb\xade2\x990\x9dNY,\x16,\x97K\xac\xb5\x1dD\x0b\xa0\ +\xb5\xe6\xfe\'\x8f\x99\xce-\xc8\x08)5a\x18\x12\x9a\xfa\x9a\x8b\xb3c\xf6\xf6\ +\xaf\xd1\xef\xef\xe27\xb3\x06\xa8\xeb\x84-\x18\xf4\x87\x0c\x87C\x0e\x0f\x0f\ +\x19\x8dF\xb4\x16\xb3\xd6\x92\xa6)\xe3\xf1\x98\xc5b\xc1z\xbdF\x08\xd1\xc4\ +\x94\xec\x028\x08\x02\xb2\xd9\x92\x07\xff9C\x9b\x08k\x03\xf0%\xcax\xc2\xd0\ +\xa0\x94\x04\xce\x19\xa7\'$\xc9\x00\xe7\xfc6\x08\xbeB\xf8\x8a^\xaf\xc7`0`8\ +\x1c"\xa5\xec\xcc\x9f\xa6)\x17\x17\x17\xe4y\x8es\xae\x8e\x01\xef\x91Rv\xb7\ +\x90R\xb2.-\x7f|\xef\xa3&\xf3\x14\xd2\x96x\xa7\xf1\xd2\xa2MHh\x02\x04\x9e\ +\xf4b\xccj5\'\x08\xc2\r\x10\x0f\xd6\xae\x88\x8c!\x8a"\x92$Ak\xdd\xc5\xc2d2a<\ +\x1e\x93\xe79\xde\xfb\xaeR\n!:\x10\xe7\x1cB\x08\xfe\xf4\xb7\x0f)\x8a%*\xd0\ +\xb5LH\x85\xf7\x15\x02\x8bP\x10\x1b\x83\x92\xb0\\\x16\x14\xf3\t\xbd\xc1\xfe\ +\xb6E\\\xb5B\xa9\xb8K\xbd\xaa\xaa\x98\xcf\xe7\x94e\xd9\xc5D\xbb\xd9\xb3e\xbb\ +\xb5\xc6\xfdON\xf8\xec\xf8\x0c!%\x12\x81T\x1e\xa5\x02\x9c\x0bj\x18\xe5Q\x1a\ +\xfa\x1a\x86\xc5\x82\xd9b\xb9\x1d#\x1e\x8f\xadV(\xa5\xba\x8a\xb9\\.\x99N\xa7\ +\x94e\xd9\xc5D\xfb\xf4\x9b0m\xba\x9e\xa7S\xde}\xff\xc3\xba\x14 @H$\xe0%\x08\ +\xaf\xc0\x07\xa0,*\x10\xc4Z1\x18\x0c\xc8\x8b\x14\xe7\x9f\t\xd6\xaaZu&\xae\ +\xaa\x8a\xa2(\xb0\xd6vP\xed\xa6\xcf\x83\x00\xf8\xfd_\xeeS\x95\xebZE\x84DHY\ +\xd7\n\x01\xca\x83\xf7\x16%\x15RK\xc2H\xd3\xeb\xf7\xd1\xe9Ew\x8f.}k\x15\xadX\ +\xaf\xd7,\x97K\xf2<\'I\x12\xac\xb5]\x8aJ);\xablB\xbc\xfb\xfeG\\<\xcd.uD\xca.\ +~\x84T\xcd\x16\x01J:\x82@`\x8c\xc7F\x11Qd\xa8\xb6@\xbc\xa0\xaa\xcaNE\x8b\xa2\ +\xa0(\x8an\xc3\x16\xe2y\x1f!\x04\xc7\x8f\x9f6\x96h\x05\xad\x86\x91J5\xed\x84\ +\x04<\x81th-\xd1\xc6\xe3\xaa\x10\xa3\r\xa5mb\xacs\x8d\xf5[*:\x9f\xcf\xc9\xf3\ +\x9c\xd5j\x85\xb5\xb6\xdb\xb8\x95\xed\xcdX\xf9\xc9;\xdf\xe5\xb5o}\xbd\x81\ +\xa8\xdd"\xa5B\xca\x00\xa5\x82FP\x03\xb41\x98f)Ug\x14\xad$\xb4\xae\xf1\xc8\ +\xcb~b6\xeb\xc4l\xbd^w\xb1\xb2\xe9\x8eV\x9f\xa4\x94$q\xc8\x8f\xde\xfa6?~\xfb\ +{\x980F\x08\xd9(\xbaB\x05\x9a \xd0hm\x08\x8d&\x8e\rF\x07\x8d\xdb\x82gcD \x95\ +\xd9\x92\xf20\x0c\xbb\xe0\xd4Z\x13\x04\xc1V\x8cl\x82\xb4\x15\xf6\xb5o\xbe\ +\xc4\xd1\xd7\x0e\xf8\xf5\x1f\xee1\x1e\xcfP*hTX"\x04\xc4\x91$\x0e\x05\x81\xf2\ +8g\xb1\xee\xd2\xdd]\xd6h\x93\xd4\x9dU\x96\xd1\xeb\xf50\xc6\xd4\x17l\xe8\x87R\ +\xaaK\xf1\x16J6\xadC\xbb\x0e\xf7c~\xfe\xd3\x1f\xf0\xde\xbf\x1e\xf1\xd7\x7f~T\ +\xbbE)\xb4\x82$\x96\xc4\x11\xb8uAY\x96T\x96g-\x02Qo\x87\xec\xe2\x84,\xcb\x88\ +\xe3\xb8\xb3\x80\xd6\x1acLg\x95M\x99\xdf\x04h\xcfk\xad\x89\xa2\x88\x1f\xbe\ +\xf5\x1d^\xbf}\x93_\xfe\xe6\x1fx\xbb$\t\x05;\x89\xc4\x04\x15\xf3EI\x96\xe5]\ +\xa0n[D\x87$;{\x8c\xc7\xa7]0=\x0bb\x8c\xe9\xaak+t\xedj\xcf\xb7+\x8ecn}c\x87_\ +\xfc\xec\x1d~\xf5\xbb\xbfs~~J/\x12\xf8\xaa`Y,\x98\x17%\xce7M\xf1&\x08\xc0\ +\x0b{#\x9e\xa6\'\xa4i\xdamf\x8c\xa9%\xbc\xe9\xbc\xda\r\xdb8y\x1eD\xfb \xde{\ +\xa4\xf0\xbc\xfd\xfd[\xdc\xfb\xb7\xe0\xe4\xcb/\xc9\x97\x0b\x1e\x9f\xa6\xe4\ +\x8bj\xab\x0ct B\x08\x92\x9d]\x0e\xaf]\xe7\xd3\x8f?\xc0Z\xdbm\xd4\x02\xb4@a\ +\x18vi\xdc\x06\xaaR\xaa\xb3\x8e\x10\x02k-eY2\x9b\xcdH\xd3\x14-K$k&\x931\xe3\ +\xe9\x82\xca\xd5I"6;\xb4\xcd\xe1\xe7\xa5\xa3W\xc9\'\x19\'_i\xbbZ\xd7\xb5\xad\x82\xb5\x96\xd5j\xd5\xb5\x94\x8b\xc5\x82,\xcb8??\xe7\ +\xf4\xf4\x94\'O\xce\xf9\xec\x7fgL\xf3\xb2kM\xdb\x8a\xb0\xe5\x1a\x10\x08)\xb8\ +y\xebu\x8ae\xc1\xf9\xf9\xe3\x0e\xa2\xdd\xb8\xd5\x98v\xf3V\x9b\x8c1\x9d&Yk;\ +\xd1\x1c\x8f\xc7\xa4i\xca\xd9\xd9\x19\x9f<:\xe6"+\xea\xe9J\x88\xe7X\x84f\xe4\ +\x11\xf51N\xfa\xdc\xb9\xfb\x06\x0f\x1f\xdc\xe3\xf4\xf4\xb8\x1b\xa6\xdaN\xad\ +\xad\xc0\x83\xc1\xa0\x9bu\xda,k\xc1\x16\x8b\x05\xd3\xe9\x94,\xcb\xea\x91\xe2\ +\xbf\xa7\\d\x05\xce\x0b\x04mU\x16\xdd\xe0\x1a\xb4\x9e\xf1\xad\x8f\x1a\xda$\ +\xd9\xe1\xce\xdd7\xf9\xfc\xd1}.\xce\x8e\xf1\xfe\x04k-\xeb\xf5\x9a\xc5b\xc1l6\ +cgg\xa7\x1b#Z\x90\xcdk\xf2<\xe7\xcb\x93s\x9eN\x16L\xf3\xb2\x99g\x00\xd1(\xf3\ +\xb3\xc1\xea7\xacqy\xacu\xe3\xfa+\xb7\xd9\xdb\xbf\xc68=\xe1\xf4,\xedF\x89\ +\xe1pH\xbf\xdf\'\x8ec\xc20\xec\n]k\xb1q6#_\x94\xe4\x8b\x8a\xca\xb1-\x88B^6V\ +\xdb1\xe2\xf1\xce\xe3\xbd\xc3{W\xb7\xf9\xde\xd1FS\xbf\xbfK\x92\x0cX\xad\xe6\ +\x14\xf3\t\x93|\xc9t~\x86V\xe7D\x91\xc1h\xd3\xb4\x85\x01\xd6I*\x0b\xa5\xa5\ +\xa9\x13\xad\xa5[\xdbo\xbf\x16\xd8\xaa\xac\xde\xd7S\xb9s\xf5,*\xa4EZ\x89\x17\ +\xe0\x9d\xc5;\x87s\x9e \x08\xe9\r\xf6\xeb\xbf}-\x82\x95\xf7u\x85\xac.\x87\ +\xabKql\x1c\xded\x87\x10\x1b/8|s\x9d\xeb\x82\xe2\xab\xf1\xa2\xe6\xff\x11%\ +\x81E\xc4\xf0\x00\x1c\x00\x00\x00\x00IEND\xaeB`\x82' + +def get015Bitmap(): + return wxBitmapFromImage(get015Image()) + +def get015Image(): + stream = cStringIO.StringIO(get015Data()) + return wxImageFromStream(stream) + +index.append('015') +catalog['015'] = ImageClass() +catalog['015'].getData = get015Data +catalog['015'].getImage = get015Image +catalog['015'].getBitmap = get015Bitmap + + +#---------------------------------------------------------------------- +def get016Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xd6IDATx\x9c\xcd\x98Yo\xe4\xc6\x15\x85\xbfZ\xb9\xb4\xa4n\x0b\xd2\xb4&\xb05\ +\x8b\xed\x186&\x13\x18\xf3j\xff\xd2\xfc\x81\xbc\xe5\x0f\x04\x08\x92<8O\xf6\ +\x8ba\xc0\x19{4\x98\x99h\x19\xb4\xd4\x8b\x9aM6\xc9\xaa\xca\x03\x17\xb1e\x07y\ +5\x81\xea\xea\x85d\x9d\xbe\xf7\x9csoQ\x00\x81\xdf\xc0\xa1\x01\x9e\xbf\xf8\ +\x1ak#\x8c\xb1(\xadQR!\xa4B\x08A\x08\x81\x1d\xac\xa1\x9b\xc2\xdd\x17A\x0c~\ +\x14\xfc\xea!v\xdf\x86\xf65\x84\xc0?\xfe\xfa\x97\x06\x88\xb5\x11q\x9cb\xa3\ +\xb8\x07#; \x04\x08\x81\xe0\x81P\xe3\xdc\x16_oq\xf5\x96\xba\xde\xe2\xeb\x9a\ +\xba\xae\xa8] \x91\xcablJ<\xda\xc7\x98\xa8YX\x88\x01\x08\xd1\xc0\x15\x10|\ +\xc0\x07w\x17\x11c,6\x8a\x89\xe3\x04\x13\xc5hmQRv\xd0\xf1\xbe\x02\x97#BMl-J%\ +(\xa5\x00\xa8\xeb\x9a\xaa\xaa\xd8n\xb7l6\x1b\xb2,\xe3vu\xc1\xe2\xfa\x9ct\xff\ +\x90\x0f\x0e\xa7\xa4\xfb\xe3;\x18\xa2\x83#\x08\xc1\xe3\xbd\xbf\x03\xa2\xb4\ +\xc6\x18\x8b\x89b\xacm\xa3\xa2Ts\x81\xcb0\xcas\xb07a4\x1a\x11\xc71\xc6\x18\ +\xa4\x948\xe7(\xcb\x92\xb2,\xef@\xdc\xde\xb2\\.Y,\x16\xcc\xe7\x97\xdc\xcc\ +\xcey\xf0\xf01\x1f\x9e~\x86\x90\r\x00D\x03(\x04\x8f\xab\x07\x11QR\xa1\xb4Fk\ +\xdb\x002\x16)\x05F\xe4\x8c\'\x11\x87\x87\x0f\x99L&\x8c\xc7c\x92\xa4\x89F\ +\x08\x81\xaa\xaa(\x8a\x82<\xcf\xc9\xb2\x8c\xf5z\xcdr\xb9doo\x8f$I\xb0\xd62\ +\x9b\xcdx\xf5\xe3w\xac\x97\x0b>\xf9\xfcK\x92t\xaf\x01\x82\x80\x10\x10r\x00DH\ +\x85\x94\n%%J)\xa4\x14\xc4z\xcb\xc9\xd1\x01\xd3\xe9\xb4\x1f\xe3\xf1\x18cL\ +\x0f\xa0\x8bB\x9e\xe7$IB\x1c\xc7DQ\x84\xb5\x16\xad5RJ\x84\x108\xe78\x7f\xf7\ +\x92\xbc\xc8y\xfe\xe2+\xd2t\xbf\x15\x82G:9\x00"DC\xa86\x7fF\xe4\x9c\x1c\x1d\ +\xf0\xd1G\x1fqzz\xca\xd3\xa7O999A\x08AY\x96\xac\xd7kV\xab\x15\xce9\xbc\xf7\ +\x84\x10p\xce\x11BhU\x06RJd\xfb\xc7\x84\x10H)y\xff\xfe\x82\x97?|\xcb\xf3\x17\ +_#\x84\x04D/8\r47 @\x00\xe12\xc6\x93\x88\xe9t\xca\xa3G\x8fx\xf6\xec\x19\xc7\ +\xc7\xc7\x00TUE\x08\x81\xb2,\xa9\xaa\n\xe7\\\x0f@kM\x14E\x08!\xd0Zc\x8c\xe9G\ +\xf7[\x1c\xc7\\^\xbe\xe5\xf5\xcf\xdf\xf3\xf8\xe3g\xad\x1a\x07\xa9\xa1\x95\ +\xa8\xf7\x15Fy\x0e\x0f\x1f2\x9dNy\xf2\xe4\t\xc7\xc7\xc7}x\xeb\xbaf\xb1X\xb0Z\ +\xad\xc8\xf3\x9c\xa2(\xf0\xde\xa3\xb5\xfe\x05\x00k-\xd6Z\xa2(\xeaAX\xdb\x88\ +\xe0\xfa\xea-\x87G\x0f\xd9\xdb\x1b\x13\x86\xaa\x01\x1a\x9fp9\x07{\x13&\x93\t\ +\xd3\xe9\x94\x93\x93\x13\x80^\x1d\xb3\xd9\x8c\xf9|N\x9e\xe7\x94e\x89\x10\xa2\ +\xe5\x94Dk\xdd\x83\x1aF#\x8a\xa2\x1eX\'\xf9\x10\xce\x99\xcf\xceI\xd3\x03\xbc\ +\x0f\xbb@\x085"\xd4\x8cF#\xc6\xe31\xe3\xf1\x18!\x04UUQ\xd75\xb3\xd9\x8c\xeb\ +\xebk\xb2,\xc3{\x8f\x94\xb2\xe7CgX\x1d\x17\x94Rh\xad\xfb\xa8t\xa3\xbb\xc69\ +\xc7\xe5\xd5\x8c\xed6C\xebh\x00$\x80s[bk\x89\xe3\x98$I0\xc6P\x96%!\x84\xd6\ +\x13\xe6dYF\x08\xe1\x17\x0b\x03x\xef\xfb\xef\xa5\x94\x18c\xf0\xde\xf7Q\xe9H\ +\xdbE7\xcb2\xf2l\xc9\xe8\xe0h7"\xbe\xde\xa2T\x03@)EUU\xac\xd7k\xca\xb2\xec91\ +\\lh\xdb\xdd\xe2\xdd1`\xbe\xb8E\x1b\xd3\x02\xd0\ +\x18-\x19\xc50\x8a\x05Zl\xd9\x14\x1b..g\xac7\xf5\x8e\r\xf4@\x84\x10\xa4\xfbc\ +\x1e<|\xcc\xab\x1f\xbf\xc39\xd7/4,\xe5\x1d\xa0\xae\xfb\xee\x00k\xady\xf1\x87\ +\xc7\xfc\xed\x9b\x1f\x9a\xcfJb4\x8cb\xd8K$VV\x14\x9b5\xcb\xc5\x9c\xf9jC\xed\ +\x1b\x91\x88a\x876\xdc\xfc|x\xfa\x19\xeb\xe5\x82\xf3w/\x91R\xee45]\xf1\xea\ +\x16\xee"\xd69\xf0\xef\x9f\x1c\xf3\xf7\x7f\x81Q\x81\xd84\xe9\x18\xc5\x02++\ +\xcab\xcdb~\xc3\xd9\x9b+V\xeb\xce\xfc\xa0\x13\xe2Nj@ \xa4\xe0\x93\xcf\xbf$/r\ +\xde\xbf\xbf\xd8\xe9\xac:\xc5\x84\x10v\xec\xdf9\xd7\x9fsr\xb4OU\x16\xa4\t$6\ +\xa0\xc5\x96b\xb3f\xb1\xb8\xe1\xa7\xb3w\\/\xf2fw%\xc4\xafD\x84v\xcb#\x9a9I\ +\xf7x\xfe\xe2+^\xfe\xf0-\x97\x97o\x07\x9dU\xd3\xd4l\xb7\xdb~\x1b\x91\xa6)I\ +\x92\xf4e\xe0\xc1D\xb1\xba\r\x18U\xe2\xca\x92M\xb1a\xb9\x98s\xf6\xe6\x8a\xeb\ +E\x8e\x0f\x02A\xe7\xca\xa2\xdf\xb8\xea.3\xa1\xcbQ\x8b6M\xf7y\xfe\xe2k^\xff\ +\xfc=\xd7Wo\t\xe1\xbcoj:\x07^\xadV$I\xd2sH\x08\x81\xabj\xaabMQ5\xea\xb8\xb8\ +\x9c1_mX\xad\xabv?\x03\x08\xd9v\xf1\xf7\xc8\x1a\x06\xd1\xb8\x9b\x1b\xcb~\xfc\ +\xf13\x0e\x8f\x1e2\x9f\x9dsy5#\xcb2V\xab\x15\x93\xc9\xa4\xdfH\xdd\xef\xc0\ +\x8a\xa2`\xbeX\x93\xe5\x15\xebMM\xed\xe9\x0bbw\xdf\xbe\x80\xeer$\x10| \x04O\ +\x08\xbei\xf3\x83\xa7c\xd3\xde\xde\x984=`\xbbm\xda\xbb\xe5\xba`\x95]a\xd4{\ +\xe2\xb8\xa9\xa2B*\x84\xd48/\xa9\x1dT\x8e\xd6\'\xbaHw\xb1\xdf},\xb0\xd3\x8f\ +\x84\xd0\xec\xca\xbdo\xf6\xa2B:\xa4\x93\x04\x01\xc1;\x82\xf7x\x1f\xd0:btp\ +\xd4|\x0eM\x11\xacCh\x1c\xb2\xbe\xdb\\\xdd\xd5\xa4\xae\xb9n\xd4!\xc4\xe0\x01\ +Gh\xcf\xf3=)~\x1b\x0fj\xfe\x0bA\xd9\\\x8cd\xf1*\x82\x00\x00\x00\x00IEND\xaeB\ +`\x82' + +def get016Bitmap(): + return wxBitmapFromImage(get016Image()) + +def get016Image(): + stream = cStringIO.StringIO(get016Data()) + return wxImageFromStream(stream) + +index.append('016') +catalog['016'] = ImageClass() +catalog['016'].getData = get016Data +catalog['016'].getImage = get016Image +catalog['016'].getBitmap = get016Bitmap + + +#---------------------------------------------------------------------- +def get017Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xddIDATx\x9c\xcd\x98Yo\x1b\xd7\x19\x86\x9f\xb3\xceB\x8ablK\xb4\x03[u\x15\ +\xa3\x8e[\xd7@\xea\xdb\xe47\x17\xbdk\xd1^\xb4E/\xdb\x18H\xd2\xa0\xa9\x1d/Q*K\ +\x0ee."9$\xe7,\xbd\x98EC5@o3\x005\xa28\xc3\xf3\xe8\xfd\xdeo9#\x80\xc8O\xe0\ +\xd0\x00O\x9e~\x86\xb5\t\xc6X\x94\xd6(\xa9\x10R!\x84 \xc6\xc8\x0eklN\xf1\xea\ +\x0fQt>\x14\xfc\xe8!v\x7f\x8d\xf5\xcf\x18#\x7f\xfd\xd3o+\x10k\x13\xd24\xc7&i\ +\x0b#\x1b\x10"\xc4H\x0c@tx\xbf!\xb8\r\xdempnCp\x0e\xe7J\x9c\x8fD$RY\x8c\xcdI\ +{{\x18\x93T\x0b\x0b\xd1\x81\x10\x15\xae\x80\x18"!\xfa+E\x8c\xb1\xd8$%M3L\x92\ +\xa2\xb5EI\xd9\xa0\x13B\t\xbe@DGj-Je(\xa5\x00p\xceQ\x96%\x9b\xcd\x86\xd5j\ +\xc5r\xb9\xe4r\xfe\x96\xe9\xc5)\xf9\xde\r>\xb81"\xdf\xdb\xbf\xc2\x10\r\x8e \ +\xc6@\x08\xe1\nDi\x8d1\x16\x93\xa4X[\xab\xa2Tu\x83_bT`\xd0\x1f\xd2\xeb\xf5H\ +\xd3\x14k-B\x08B\x08l\xb7[6\x9b\rEQT\x10\x97\x97L\xa7S\xa6\xd3)\x93\xc9\x19\ +\xef\xc7\xa7\x1c\xde\xb9\xcf\xdd\xa3\x87\x08Y\x01 *\xa0\x18\x03\xdeu\x14QR\ +\xa1\xb4Fk[\x01\x19\x8b\x94\x02#\n\xf6\x87\t7o~\xc8p8d0\x18\x90\xe79ZkB\x088\ +\xe7X\xaf\xd7;\x10\xb3\xd9\x8c^\xafG\x96eXk\x19\x8f\xc7\xbc\xfc\xe6\x19\x8b\ +\xd9\x94\x07\x8f>!\xcb\xfb\x15\x08\x02bD\xc8\x0e\x88\x90\n)\x15JJ\x94RH)H\ +\xf5\x86\xdb\xb7\x06\xdc\xbe}\x9b\xd1h\xc4\xe1\xe1!\xc3\xe1\x10c\xcc\x0e\xc0\ +b\xb1\xa0(\n\xb2,#MS\x92$\xc1Z\x8b\xd6\x1a\xa5*\x9fy\xef9\xfd\xfe9\xc5\xba\ +\xe0\xc9\xd3O\xc9\xf3\xbd:\x11\x02\xd2\xcb\x0e\x88\x10\x95\xa1\xea\xf8\x19Qp\ +\xe7`\x9f{\xf7\xeeqtt\xc4\xf1\xf11\xa3\xd1\x08)%eY\xb2\\.\x99\xcf\xe7x\xef\ +\xc9\xf3\x1c\x80\x10\x021\xc6:\xcb@J\xd9\xbe\x84\x10H)y\xf7\xee-\xcf\xbf\xfe\ +\x9c\'O?C\x08\t\x886\xe14P}\x01\x11"\x08\xbfd\x7f\x980\x1a\x8d8::\xe2\xf1\ +\xe3\xc7\x1c\x1c\x1c\xb4\x8b\x95e\xd9\xbeB\x08x\xef\x891\xa2\x94"I\x12\x84\ +\x10h\xad1\xc6`\x8ci\xd5I\x92\x844M9;;\xe1\xf5\xb7_q\xff\xa3\xc7u6vBC\x9d\ +\xa2!\x94\x18\x15\xb8y\xf3CF\xa3\x11\xc7\xc7\xc7\x1c\x1c\x1c\xb4\xf5\xc4{\ +\xcfl6c>\x9f\xb3Z\xadX\xaf\xd7x\xef[\x88\xeb\x00\xd6\xda6T\x8d\xc9\x95R\\\ +\x9c\x9fp\xe3\xd6\x1d\xfa\xfd}b7k\x80\xaaN\xf8\x82A\x7f\xc8p8\xe4\xf0\xf0\ +\x90\xd1hD\xa3\x98\xf7\x9e\xf1x\xccd2a\xb5Z\xb1\xddn\x11B\xd4\x9e\x92\xad\ +\x81\xbb0\xc6\x18\x92$i\xc1\x9a\x94\x8f\xf1\x94\xc9\xf8\x94<\x1f\x10B\xdc\ +\x05!:Dt\xf4z=\x06\x83\x01\xc3\xe1\x10)e+\xffx<\xe6\xe2\xe2\x82\xc5bA\x08\ +\x01)%1F\xa4\x94\xedW4\x9ePJ\xa1\xb5\xfe\x1fU\x9a{\xbc\xf7\x9c\x9d\x8f\xd9l\ +\x96h\x9dt@"x\xbf!\xad%\xcc\xf3\x1ccL\xeb\x85\xd9l\xc6d2a\xb1X\x10cl+ec\xc2\ +\xc6?\xcd{\xa5\x141FB\x08\xad*\xdd\x0c\xdan\xb7,\x97K\x8a\xe5\x8c\xde\xe0\ +\xd6\xae"\xc1mP*k\xcd\xe5\x9cc\xb9\\R\x96e\xeb\x89f\xb1\xebe\xbbQ\xa39\xba\ +\xd74\x8a4pM\x05\x9e\xcf\xe7\xcc\x16\xeb]\x8fD"\xdemZ\xea\x10\x02\xeb\xf5\ +\x9a\xf9|NY\x96\xad\'\x9a\xc5\xba\x0b5\xe9\xda-\x03\xdd\xd4m\xd4RJ\x11B\xa0(\ +\n.//\x19\x0e\x87\xcc\x97\xe7\x84x\xcd\xac\xcem\xda\x9b\x9cs\x14E\x81\xf7\ +\xbe\x85j\x16\xfd\x7f\x10\xdd\xf0h\xad\xdb\xeb\xa5\x94x\xef\x19\x0c\x06\xec\ +\xed\xed\xd1\xef\xf71\xea]\xfb\x1dm\xfaV]\xd4\xb1\xddnY\xaf\xd7,\x16\x0b\xf2\ +<\xc7{\xdf\xa6h\xf7\xbf\xbc\x0e\xd1\xf5L\x17\xa4\x811\xc6\x10Bh\xcb\x7fU\x89\ +-n\x07$\n\x9c+\xdb.Z\x14\x05EQ\xb4\x0b6\x10?v\xbc\xbb\xb8\xe4o\x7f\x7f\xc1\ +\xc3\xe3\xdb<<\xbeM\x9eU~h@\x8c1mX\x9cs\xa4iz\xd5\n\x8c\xa5\xac\xeaY\'4>\xee\ +t\xd1,\xcb\xf0\xde\xb7UQk\xdd\x86\xae\xeb\x95/\xff\xf5\x1f^\xbd9\xe3\xf5w\ +\xe7\xfc\xe1/_\xf0\xe0\xf8.\x8f\x7fq\x97_\x7f|\x8f^\xa7~x\xef\xdbDh\xfb\x90T\ +\xe0\xae\x85&"\xaf\xe6\x89\xcbK\xd24%\xc6\xd8B4\x00\xdd0\x08!89\x9b\xd6}J \ +\x84\xe4\xe5\x9b3^\x9f\xfc\xc0\xef\xff\xfc%\xbf|t\xcco~\xf5s\x9e<\xbaG\x92$\ +\xac\xd7\xeb\x9d\xfe#\xa4\xbe\xee\x11\x81Tv\xa7\x95\'I\xd2\x9a\xd3\x18\x83\ +\xd6z\xc7#B\x08\xe6\x8b5\x17\xef\xa75\x94DH\x89\x14u\xc6(\xc5\x8bWoy}2\xe6w\ +\x7f\xfc\x07\x1f?\xb8\xc7\xcf\xee\xf4\xe8\'\xbe\xf5\x9d\x0fW\xe1nCcl^MV\xd3)\ +\xbd^\x0fkmuA\xa7d7\xb1oL\xf9\xe2\xf5\x0f\xedH)\xa4D\xd4\x10Z\x1b\x94\xb6\ +\xf5Y\xa3\x95\xe2\xcd\xc9\x19\x93\xf7\x92\x0f\xfa\x80[\xb2\xdelp\x9e\xeb\x8a\ +@\xda\xdbczq\xcat:%\xcb\xb2V\x81\xa6O4\xaat\xdb\xfc\x97\xff>m!\xaayF!\x95B\ +\xe9\xfazS{B\t\xf2D\xb0\x97K\xacv,W\x1b&\x93\xcb\xd6\xa8\xbb\x8a\x98\x84|\ +\xef\x06\x93\xc9Yk\xb0\xeb \xd6\xda\xb6\xbaVa\x99#\xeb\xc5\xa5\xd4(\xadPJ\ +\xa3u\x03\xa10Z\x91\x18A?\x97\xf4RAt\x05\xebb\xc5\xb2(\t\xb1\x1e\x8a\xbb \ +\x00\x1f\xdc\x18\xf1~|\xcax\xa1X\x17\xbc{\xf7vg\xb2j\xf2\x7f<\xddb\x94\xaf\xa6\ +\x7f\x19\xd02`4$&\x92\xa6\x82^&\xd9\xcb%y\nV\x96l\x8a\n\xe2\xc5\xab\xef\xb9\ +\x98\x16\x15\xad\x10?\xa2\x08\xf5\x96GT\xe7,\xef\xf3\xe4\xe9\xa7<\xff\xfas\ +\xce\xceN:\x93U=\xa9\xcdJ\xf63\x814\x12\xad\x05\xc6H\x12\xabH3E\x96H\xf2T`\ +\xb5#\xba\xca\x13\xb3\xd9\x84W\xdf\x9ds1-\x08Q h\xfa\x93h7\xae\xba\x89LlbT\ +\xd3\xe6\xf9\x1eO\x9e~\xc6\xebo\xbf\xe2\xe2\xfc\x84\x18O\xdb\xa1F\xdb\x8c,\ +\xeb\x91\xa4\x06k#\xc6F\x12\x1b0\xc6\xa3U\xc4o\x0b\x16\xab\x92uQ\x19s2_1_\ +\x94\xf5~\x06\x10\xb2\x9e\xe2\xaf\x995v\xd4\xb8:W\xd5\xf2\xfeG\x8f\xb9q\xeb\ +\x0e\x93\xf1)g\xe7c\x96\xcb%\xfb\xfb\xd5f\xab\xd7\xeb\xe3\xb3\x94\xe0\x12\ +\xdcF!\x85$DOY\x96L\xa7\x0b\x96E\xc9b\xe5p\x81N\x1b\xa8\xabp\x13\x93]\x8fDb\ +\x88\xc4\x18\x881Tc~\x0c4n\xea\xf7\xf7\xc9\xf3\x01\x9bM5\xde]\xae\xd6,\x8a1F\ +]\x90\xa6\x16kl\xf5\xf4@j|\x908\x0f\xa5\xa7\xae\x13\x8d\xd2\x8d\xf6\xbb\x8f\ +\x05v*k\x8c\xd5\xae<\x84j/*\xa4GzI\x14\x10\x83\'\x86@\x08\x11\xad\x13z\x83[\ +\xd5\xfbXm\xa8\\\x8cU\x85tW\x9b\xab\xabY\xa5\x0ex\x9d\x1dBt\x1ep\xc4\xfa\xba\ +\xd0\x9a\xe2\xa7\xf1\xa0\xe6\xbf\xf1o."\xb9\t8\x10\x00\x00\x00\x00IEND\xaeB`\ +\x82' + +def get017Bitmap(): + return wxBitmapFromImage(get017Image()) + +def get017Image(): + stream = cStringIO.StringIO(get017Data()) + return wxImageFromStream(stream) + +index.append('017') +catalog['017'] = ImageClass() +catalog['017'].getData = get017Data +catalog['017'].getImage = get017Image +catalog['017'].getBitmap = get017Bitmap + + +#---------------------------------------------------------------------- +def get018Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +&IDATx\x9c\xcd\x98K\x8f\xdb\xe6\x19\x85\x9f\xefFR\xd4H\xa3\xd8\x9e\x91\x1d\ +\xd8\x03\xd7\t\x90\x04p\r\x04\xde&\x7f\xa0\x7f\xa4\xcb\xae\xba\xee\xef\xe8\ +\xbe(\xba)R\xf4\x024h\x82\x02A\x03\x14mjo\x8c4\xf1%q\xeazF\x9a\xa1"J#\x89\ +\x92\xf8]\xba\xa0HIN\x80nC@w\x91\xdf\xd1y\xcf9\xef\xfbI\x00\x81\x1f\xc0\xa1\ +\x01\xee\xdd\x7f\x9f(\x8a1&Bi\x8d\x92\n!\x15B\x08B\x08\xeca\r\xf5C\xd8\xbe\ +\x11\xc4\xce\x87\x82\xef=\xc4\xfe\xd3\xb0\xb9\x0f!\xf0\xc9G\x1fT@\xa2(&IR\ +\xa28i\xc0\xc8\x1a\x08\x01B x X\x9c[\xe1\xed\ngWX\xbb\xc2[\x8b\xb5%\xd6\x05\ +\x02\x12\xa9"L\x94\x92\xb4;\x18\x13W\x0b\x0b\xb1\x03BTp\x05\x04\x1f\xf0\xc1m\ +\x191&"\x8a\x13\x92\xa4\x85\x89\x13\xb4\x8ePR\xd6\xd0\xf1\xbe\x04W \x82%\x89\ +"\x94j\xa1\x94\x02\xc0ZKY\x96\xacV+\x16\x8b\x05\xf3\xf9\x9c\xcb\xe9\x19\xf9\ +\xe8\x94\xb4s\x85\xd7\xae\xf4I;\x87[\x18\xa2\x86#\x08\xc1\xe3\xbd\xdf\x02QZc\ +L\x84\x89\x13\xa2h\xc3\x8aR\xd5\tn\x8eQ\x9e\xeeA\x8fv\xbbM\x92$DQ\x84\x10\ +\x02\xef=\xeb\xf5\x9a\xd5jEQ\x14\x15\x88\xcbK\xf2<\'\xcfs\xc6\xe3\x01\xdff\ +\xa7\x1c\xdf\xb8\xcd\xcd\x93\xb7\x10\xb2\x02\x80\xa8\x00\x85\xe0qv\x87\x11%\ +\x15Jk\xb4\x8e*@&BJ\x81\x11\x05\x87\xbd\x98\xabW_\xa7\xd7\xeb\xd1\xedvI\xd3\ +\x14\xad5\xde{\xac\xb5,\x97\xcb=\x10\x93\xc9\x84v\xbbM\xab\xd5"\x8a"\xb2,\ +\xe3\xab/\x1f2\x9b\xe4\xbc\xf9\xce\xbb\xb4\xd2\x83\n\x08\x02B@\xc8\x1d B*\ +\xa4T()QJ!\xa5 \xd1+\xae_\xebr\xfd\xfau\xfa\xfd>\xc7\xc7\xc7\xf4z=\x8c1{\x00\ +f\xb3\x19EQ\xd0j\xb5H\x92\x848\x8e\x89\xa2\x08\xad5JU:s\xceq\xfa\xdf\'\x14\ +\xcb\x82{\xf7\xdf#M;\x1b#x\xa4\x93;@\x84\xa8\x04\xb5\xa9\x9f\x11\x057\x8e\ +\x0e\xb9u\xeb\x16\'\'\'\xdc\xb9s\x87~\xbf\x8f\x94\x92\xb2,\x99\xcf\xe7L\xa7S\ +\x9cs\xa4i\n\x80\xf7\x9e\x10\xc2\xc6e \xa5lnB\x08\xa4\x94\x9c\x9f\x9f\xf1\ +\xe4\xf3\x07\xdc\xbb\xff>BH@4\x86\xd3@u\x01\x02\x04\x10n\xcea/\xa6\xdf\xefsr\ +r\xc2\xdd\xbbw9::j\x16+\xcb\xb2\xb9y\xefq\xce\x11B@)E\x1c\xc7\x08!\xd0Zc\x8c\ +\xc1\x18\xd3\xb0\x13\xc71I\x920\x18\xbc\xe0\xf9\xb3G\xdc~\xe3\xee\xc6\x8d;\ +\xa5acQ\xefK\x8c\xf2\\\xbd\xfa:\xfd~\x9f;w\xeeptt\xd4\xe4\x89s\x8e\xc9d\xc2t\ +:e\xb1X\xb0\\.q\xce5 ^\x05\x10EQS\xaaZ\xe4J)F\xc3\x17\\\xb9v\x83\x83\x83C\ +\xc2\xaek\x80*\'\\A\xf7\xa0G\xaf\xd7\xe3\xf8\xf8\x98~\xbfO\xcd\x98s\x8e,\xcb\ +\x18\x8f\xc7,\x16\x0b\xd6\xeb5B\x88\x8d\xa6d#\xe0]0\xc6\x18\xe28n\x80\xd5\ +\x96\x0f\xe1\x94qvJ\x9av\xf1>\xec\x03!XD\xb0\xb4\xdbm\xba\xdd.\xbd^\x0f)eC\ +\x7f\x96e\x8cF#f\xb3\x19\xde{\xa4\x94\x84\x10\x90R6\x97\xa85\xa1\x94Bk\xfd\ +\x1dV\xeas\x9cs\x0c\x86\x19\xab\xd5\x1c\xad\xe3\x1d \x01\x9c[\x91l(L\xd3\x14\ +cL\xa3\x85\xc9d\xc2x\x9fS\x96e\xa3\x89z\xb1Wc\xbbf\xa3>v\xbfS3R\x83\xab\x13x:\x9d2\x99-\xf75\ +\x12\x088\xbbjP{\xefY.\x97L\xa7S\xca\xb2l4Q/\xb6\xbbPm\xd7\xdd\x18\xd8\xb5n\ +\xcd\x96R\n\xef=EQpyyI\xaf\xd7c:\x1f\xe2\xc3+b\xb5v\xd5\x9cd\xad\xa5(\n\x9cs\ +\r\xa8z\xd1\xff\x07b\xb7\x9dN\x99\xcdf\xac\xd7k\xca\xb2\xc4Z\x8b\xf7\x9e\x8f?\ +\xfd7\xbf\xfb\xf0\x9f\x94\xe5\xaa\x16\x08\x08\xc1\xe8\xdb\t\x7f\xf9\xdb\x17\ +\xdfa\xa3\xbe\xd5\x8b\xd7\x01\xe9\x9c\xc3\xf9m\xb9\x9b\xd2\x98(\xad&\xab<\ +\xa7\xddn\x13EQ\xf5\x85M\x9d\xf3\xcb%\x7f\xfd\xfbS\xf2\xc9\x0c!e5c\tY=\x17\ +\x02!%\x0f\x1e}\xcd\xbbwo\xf3\xf6\x9b7\x9b\xdeR\x0fQ\xb5kjC\xacV+\xac\xe3U\ +\xd7@\xd2\xee\x90\x8fN\xc9\xf3\x9cV\xab\x85\xd6\x1a)%\xc6\x18\x1e\x7f}\xc1\ +\xa3\xa7\x17\x08@i\x83D\xc0+ \xaayF\xf1\x9b?>\xe0\x17?;!\x8ecZ\xadV\xa3\x8f\ +\xb2,Y.\x97,\x16\x0b\x16\x8b\x05\xe3\xfc\xb2\x11\xea>#&&\xed\\a<\x1e4\x02\ +\x0b\xc0\xa3\xc7g\x8c&kL\x94`\xa2V5D\xa9\x80\x04\x84\xd8\x04\x97RH\xa9QZ\x11\ +\x82\xe7W\xbf\xff\x8c\x9f\xff\xf4\'h]i\xa0\x0e\xc5\xe9t\xda\x94|\xb6(\xf1a3\ +\x14o5R\x1d\xaf]\xe9\xb3*=Y\x961\x1c\x0e\xf9\xf2\xc97\x8cF\x19\xf85\xceY\x9c\ ++\xab\xf9\xc3o6\x13bg\xbaS\n\xa5\x0cZ\x1b^\x9c^\xf0\xc9?\x9e6 \xea9v<\x1e\ +\x93\xe79/O\xcf\x99-\xec^\x0c4@\x84\x10\xa4\x9dC\x8eo\xdc\xe6\xfc\xfc\x9c\ +\xc1`H1\x9f"\xc3\x1a-\x1d2\x94\x04\xef\x08\xc1\xe2\xbd\xab\xa29\xd4\xe7\xcaM\ +y$JI\xb4R\xfc\xe9\xe3\xcfx\xfe\x9f\x01y\x9e\x93e\x19\xe7\xe7\xe7dYF\x96e|;Y`\ +}\xf5K\x9a\xe4\xdd\x98\xa69n\x9e\xbc\xc5\xf1\xf5\x1fqqqN\x9e\x8fp\xb6\xc0HK\ +\x12\x05\x8crH*0\x04O\x08\x0e6\x1b0A@V\x06\xc2(Hc\xc1\x1f>\xfa\x8c\x97/O9;;c\ +0\x180\x1c\x0e\xf9\xea\x9b\x01\xd3Y\x89\xd8\x18\xee;\x1a\xa9m,\xa4\xe0\xcdw\ +\xde\xa5X\x16\x8c\xb23\x928!\x8eb\xe28\xc2D1B\x01* \x94\xab\xa6\x7f\xe9\xd1\ +\xd2c4\xc4&\x90$\x82vK\xd2I%\x91X\xf0\xc5\xe3g\x94\xab9\xc3\xe1\x90\xc7\xcf^\ +0\xca\x8b\xc6\xf2\xdb}\xce\x0e\x10\xb1yS h\xa5\x07\xdc\xbb\xff\x1eO>\x7f\xc0\ +\xc5\xc5\x8bMHI\x92\xd8\x90\xc4\x11J\x83\xd2\x02i$Z\x0b\x8c\x91\xc4\x91"i)Z\ +\xb1$M\x04\x91\xb6\x04[r1\\0\x9d\xe6|\xf5\xcd\x80Q^\xe0\x83\xd8\xb0Q\x01\t\ +\xbb\x8cl\xb5+\x1a\xb4i\xda\xe1\xde\xfd\xf7y\xfe\xec\x11\xa3\xe1\x0b\xe0|C\ +\x7f\xe0\xa0\x03-\xa3\x88\x13C\x14\x05L\x14\x88#\x8f1\x0e\xad\x02n]0[\x94,\ +\x8b\x05g\x83\x8c\xf1t\xc1tVn\xf63T\xd6\x17\xfb\xbdk3\x8fl\xd9\xd8>V\x81u\ +\xfb\x8d\xbb\\\xb9v\x83qvJ6\x1a\xb3\\\x16\xf4\x8a\x05\xddn\x97v\xfb\x00\xd7J\ +\xf06\xc6\xae\x14RH|\xa82#\xcfg\xcc\x8b\x92\xd9\xc2b\xfd\x86\x01\xb1\xbdn3X\ +\x85\xbd\xd2\x84\xca\x92\xc1\x13\x82\xaf\xc6\xfc\xe0+\x86B\xe0\xe0\xe0\x904\ +\xed\xb2ZU\xe3\xdd\xe5b\xc9\xac\xc80jD\x92DD&\xaa\xfe=\x90\x1a\xe7%\xd6A\xe9\ +\xd8\xe4D\xcdt\xcd\xfd\xfe\xdf\x02{\xc9\x1aB\xb5+\xf7\xbe\xda\x8b\n\xe9\x90N\ +\x12\x04\x95e\xbd\xc7\xfb\x80\xd61\xed\xee\xb5\xeau\xa8\x9a\xa0\r\xa1JH\xbb\ +\xdd\\mg\x95M\xc1\xab\xdfS=\xb2\xfd(\x84\x00\xbe\x11\xc5\x0f\xe3\x8f\x9a\xff\ +\x01k)\xae\n\xd5\xf2\r\xdb\x00\x00\x00\x00IEND\xaeB`\x82' + +def get018Bitmap(): + return wxBitmapFromImage(get018Image()) + +def get018Image(): + stream = cStringIO.StringIO(get018Data()) + return wxImageFromStream(stream) + +index.append('018') +catalog['018'] = ImageClass() +catalog['018'].getData = get018Data +catalog['018'].getImage = get018Image +catalog['018'].getBitmap = get018Bitmap + + +#---------------------------------------------------------------------- +def get019Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xb7IDATx\x9c\xcd\x98\xdbn\xdbV\x16\x86\xbf}")\xca\x96\xd5$\xb6\x92\xa25\x82\ +\xb4@Q \x08P\xe4r\xda\xbby\xdfy\x81\xb9\x9a\x07\xe8\xdc\x14\x05f\x82\x16-2ud\ +\x97\x8a$\x8a\xe2A\xdc\x87\xb9\xe0A\x92;\xc0\xdc\x96\x00MK"\xb9?\xae\xf5\xaf\ +\x7f\xafM\x01\x04\xfe\x04\x9b\x06x\xf3\xf6;\xa2(\xc6\x98\x08\xa55J*\x84T\x08\ +!\x08!p\xc6\x1a\x86C8~\x11\xc4\xc9\x8f\x82\xff\xb9\x89\xf3\x7fC\xff7\x84\xc0\ +?\xfe\xfe\xb7\x0e$\x8ab\x92$%\x8a\x93\x11F\x0e \x04\x08\x81\xe0\x81`q\xae\ +\xc1\xdb\x06g\x1b\xacm\xf0\xd6bm\x8bu\x81\x80D\xaa\x08\x13\xa5$\xd3K\x8c\x89\ +\xbb\x81\x858\x81\x10\x1d\xae\x80\xe0\x03>\xb8cD\x8c\x89\x88\xe2\x84$\x99`\ +\xe2\x04\xad#\x94\x94\x03:\xde\xb7\xe0*D\xb0$Q\x84R\x13\x94R\x00Xki\xdb\x96\ +\xa6i(\xcb\x92\xfd~\xcf.\xff\xc0fuGz\xf9\x84O\x9e,H/\xaf\x8e\x18b\xc0\x11\ +\x84\xe0\xf1\xde\x1fA\x94\xd6\x18\x13a\xe2\x84(\xea\xa3\xa2Tw\x81\xdbc\x94gv\ +1g:\x9d\x92$\tQ\x14!\x84\xc0{\xcf\xe1p\xa0i\x1a\xaa\xaa\xea v;6\x9b\r\x9b\ +\xcd\x86\xf5z\xc9\xc7\xec\x8e\x9b\x17/\xf9\xec\xf6+\x84\xec\x00\x10\x1dP\x08\ +\x1egO"\xa2\xa4Bi\x8d\xd6Q\x07d"\xa4\x14\x18Qq5\x8fy\xfa\xf4S\xe6\xf39\xb3\ +\xd9\x8c4M\xd1Z\xe3\xbd\xc7ZK]\xd7g\x10\xdb\xed\x96\xe9t\xcad2!\x8a"\xb2,\ +\xe3\xe7\x7f\xfd\x93b\xbb\xe1\xcb\xaf\xbfa\x92^t \x08\x08\x01!O@\x84TH\xa9PR\ +\xa2\x94BJA\xa2\x1b\x9e?\x9b\xf1\xfc\xf9s\x16\x8b\x05777\xcc\xe7s\x8c1g\x00E\ +QPU\x15\x93\xc9\x84$I\x88\xe3\x98(\x8a\xd0Z\xa3T\xa73\xe7\x1cw\xffyGUW\xbcy\ +\xfb-iz\xd9\x17\x82G:y\x02"D\'\xa8>\x7fFT\xbc\xb8\xbe\xe2\xf3\xcf?\xe7\xf6\ +\xf6\x96W\xaf^\xb1X,\x90R\xd2\xb6-\xfb\xfd\x9e<\xcfq\xce\x91\xa6)\x00\xde{B\ +\x08}\x95\x81\x94r\xdc\x85\x10H)yx\xf8\xc0\xbb\x1f\xbf\xe7\xcd\xdb\xef\x10B\ +\x02b,8\rt7 @\x00\xe1\xf6\\\xcdc\x16\x8b\x05\xb7\xb7\xb7\xbc~\xfd\x9a\xeb\ +\xeb\xebq\xb0\xb6m\xc7\xdd{\x8fs\x8e\x10\x02J)\xe28F\x08\x81\xd6\x1ac\x0c\ +\xc6\x981:q\x1c\x93$\t\xcb\xe5{~\xf9\xe9\x07^~\xf1\xba\xaf\xc6\x93\xd4\xd0\ +\x97\xa8\xf7-Fy\x9e>\xfd\x94\xc5b\xc1\xabW\xaf\xb8\xbe\xbe\x1e\xfd\xc49\xc7v\ +\xbb%\xcfs\xca\xb2\xa4\xaek\x9cs#\xc4c\x80(\x8a\xc6T\r"WJ\xb1\xba\x7f\xcf\ +\x93g/\xb8\xb8\xb8"\x9cV\r\xd0\xf9\x84\xab\x98]\xcc\x99\xcf\xe7\xdc\xdc\xdc\ +\xb0X,\x18"\xe6\x9c#\xcb2\xd6\xeb5eYr8\x1c\x10B\xf4\x9a\x92\xa3\x80Oa\x8c1\ +\xc4q<\x82\r%\x1f\xc2\x1d\xeb\xec\x8e4\x9d\xe1}8\x07!XD\xb0L\xa7Sf\xb3\x19\ +\xf3\xf9\x1c)\xe5\x18\xfe,\xcbX\xadV\x14E\x81\xf7\x1e)%!\x04\xa4\x94\xe3-\ +\x06M(\xa5\xd0Z\xff!*\xc35\xce9\x96\xf7\x19M\xb3G\xeb\xf8\x04$\x80s\rI\x1f\ +\xc24M1\xc6\x8cZ\xd8n\xb7\xac\xd7k\x8a\xa2 \x840:\xe5 \xc2A?\xc3g\xa5\x14!\ +\x04\xbc\xf7cTN+\xe8p8\xb0\xdf\xef\xa9\xf6[\xa6\xb3g\xe7\x11\xf1\xb6A\xa9\ +\xc9(.k-\xfb\xfd\x9e\xb6mGM\x0c\x83=\xb6\xed!\x1a\xc3vz\xce\x10\x91\x01np\ +\xe0<\xcf\xd9\x16\xf5\xb9F\x02\x01g\x9b\x91\xda{O]\xd7\xe4yN\xdb\xb6\xa3&\ +\x86\xc1N\x07\x1a\xca\xf5\xd4\x06NKw\x88\x96R\n\xef=UU\xb1\xdb\xed\x98\xcf\ +\xe7\xe4\xfb{|x$Vk\x9b\xf1"k-UU\xe1\x9c\x1b\xa1\x86A\xff\x1f\xc4iz\xb4\xd6\ +\xe3\xf9RJ\x9cs\xccf3.//\xb9\xb8\xb8\xc0\xa8\x87\xf1\x1ec\xf9v\xb3\xa8\xe5p8\ +P\xd75EQ\x90\xa6)\xce\xb9\xb1DO\x9f\xf21\xc4\xa9fNA\x06\x18c\x0c\xde\xfb\xd1\ +\xfe;\'\x8e\xb0g A`mKU7\xdc-?\xb2\\[<\xbf\x10\x84\xecLN\x88\xbe?\x91\xc7\x89\ +\xebd\xfb\xeb_\xbefq}5FD)5\x82\x18c\xc6\xb4XkI\x92\xe48\x15\x98\x88\xb6\xf3\ +\xb3\x93\xd4\xb8@S\xd7\x14\xfb\x82vg)[\x81\xf3\x02\x10H\xa5Q\xaa\x0f\xb3\x90\ +G\x90\xfe\xd0\xb4\xee,\x12J\xa93cSJ\xe1\x9c\x1b\x0ba\x9c\x87\xa4\x02\xfb(5\ +\x01IUW\xc4uE\x90\x02w\x10X/@*\xb4\x90H\xe1A\xaa\xae\xad\xe9\xe7\xa5\x01\xe8\ +q:\x1e\xfb\x88\xd6\x1a\xe7\x1cu]\x9f\xcd?B\xea\xe3\xdc4<\x9aT\x11\xe5\xbe\ +\xa4\xa9+l[\xe3\xdd\x81\xd66xg\xbb\xdd{B\xaf\xf0p\xda:\n\x81\xec\xd31@<\xb6\ +\xf9\xc1\xcc\x86\x8a\x1ct\xe7\xfc\xb1\xe4\xc7\xd4\x98(\xa5\xc8?\x90LR&S\x85w\ +\x9a`%6\xf4\xe9\x10\xb2?v\x95#\x10\xbdf$\xba\x1fx\x80\x18&\xb8\x01b\x10\xb1s\ +n,\x88\xa6i\xb0\x8e\xc7U\x03\xc9\xf4\x92\xcd\xea\x8eb\x97#\x95\x06\x99\x10\ +\xbc\xc2\x07\x10B!\xa5FJG\x90\x12I\x0f\xd7?\xa5VzL\x811f\x14\xe3d2\x19\xf5\ +\xd1\xb6-u]S\x96%eY\xb2\xde\xecF\xa1\x9eG\xc4\xc4\xa4\x97O\xd8n\x96(\xad\x89\ +\x13\x0f"&\x08pv(\xddN`R\x05$ D\x97o\xfd(\rQ\x141\x99L\xd0\xba\xd3\xc0`\x8ay\ +\x9e\x93\xe79EQP\x94->\xf4M\xf1Q#\xdd\xf6\xc9\x93\x05\x07\xeb\xd9\xac\xd7T\ +\xe5\x0e\\\x83\x0c-\xf8\x03\xceY\x9ck\xbb\xfe\xc3\xf7*\x11]wg\x8c\xfe\x03\ +\xc8`\xe9m\xdb\x8e}\xecz\xbdf\xb3\xd9\xf0\xdb\xdd\x03Ei\xcf,`\x04\x11B\x90^^\ +q\xf3\xe2%Y\xf6;\xeb\x8f+\x9a\xba@\x86\x03Z:dh\t\xde\x11\x82\xc5{\xd7Ys\xafY\ +)\xd5\x1f\x0cl\xa8\x92\xcdfC\x96e<<<\x90e\x19Y\x96\xf1q[b}\xf7$\x83\x19\xeaS\ +?\x00\xf8\xec\xf6+\x8a\xed\x86\xbb\xff\xbcCH\xc1u\xd4\xcf\x9eQ H\x87\xa0\x83\ +!hBp\x104\xde\xbb\xb1\x12\x9a\xa6\x19[\xca\xb2,\xd9l6<<<\xb0\\.\xb9\xbf\xbf\ +\xe7\xe7_\x97\xe4E;\xb6\xa6\x83A\x1f\xfb\x91\x9eHH\xc1\x97_\x7fCUW\xac\xb2\ +\x0f$qB\x1c\xc5\xc4q\x84\x89b\x84\x02T@(\xd7u\xff\xd2\xd3\xf4]\xfc0\'\r\xd1\ +\xc8\xf3\x9c\xf5zM\x96e\xdc\xdf\xdf\xf3\xef\x9f\xde\xb3\xdaT\xbd\x0f\t\x8e\ +\xeb\x9c\x13\x10\xd1\x7f)\x10L\xd2\x0b\xde\xbc\xfd\x96w?~\xcf\xef\xbf\xbf\ +\xef\xfdA\x92\xc4\x86$\x8eP\x1a\x94\x16H#\xd1Z\xb0\xdbmX.\xc5\xd8HYkGq\x0e\ +\xa9\xf9\xf9\xd7%\xabM\x85\x0f\x9d\r\x8a\x1edp$=d&\x0c9\xeai\xd3\xf4\x927o\ +\xbf\xe3\x97\x9f~`u\xff\x1ex@\x10\x90"pq\t\x13\xa3\x88\x13C\x14\x05V\xd9=M\ +\x95\x8f^q8\x1c(\xcb\x92\xa2(\xf8\xed\xee\x81\x8f\xdb\x92\xbch\xfb\xf5\x0cG_\ +:\xd9\xfa~\xe4\x18\x8d\xe3\xb13\xac\x97_\xbc\xe6\xc9\xb3\x17\xac\xb3;\xb2\ +\xd5\x9a\xba\xae\x98W%\xb3\xd9\x8c\xe9\xf4\x027I\xb8\xfb\xad9\x13i\xd34\xac7\ +;\x8a\xb2\xa5(-\xd6\xf7\x11\x10\xc7\xfb\x8e\x8d\xd5\xb9FBW\x92\xa1\xb7\xf1\ +\x10z;\xef\xd4tqqE\x9a\xceh\x9a\xae\xbd\xdb\x955E\x95a\xd4\x8a$\x89\x88L\xd4\ +\xcd\xceR\xe3\xbc\xc4:h\x1d\xbdO\x0c\x91\x1eb\x7f\xfeZ\xe0\xccYC\xe8V\xe5\ +\xdewkQ!\x1d\xd2I\x82\xa0+Y\xef\xf1>\xa0u\xcct\xf6\xac\xfb\x1c\xba\x05\x95\r\ +\xa1sH{\\\\\x1d{\x95>\xe1}u\x08q\xf2\x82#\xf4\xe7\xf9Q\x14\x7f\x8e\x175\xff\ +\x05g\'\x93\xa3\xa4\x98\xbd\xac\x00\x00\x00\x00IEND\xaeB`\x82' + +def get019Bitmap(): + return wxBitmapFromImage(get019Image()) + +def get019Image(): + stream = cStringIO.StringIO(get019Data()) + return wxImageFromStream(stream) + +index.append('019') +catalog['019'] = ImageClass() +catalog['019'].getData = get019Data +catalog['019'].getImage = get019Image +catalog['019'].getBitmap = get019Bitmap + + +#---------------------------------------------------------------------- +def get020Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +\x1eIDATx\x9c\xcd\x98[\x8f\x1c\xc5\x19\x86\x9f:\xf4az\x0e;\x18\xef\x8e\x1d\ +\xf0b\xd6D\x80p6A\x86(R\xec\x08\t)\x8a\x14\xfe_~\x00\xcae\x84r\x97\x8b\\D(\ +\x17\x91"\xf0\rB"\x96-\xc0\xb0\xde\xd9\x9d\xf5\x9cz\xfa\\U\xb9\xe8\xc3\xcc\ +\xd8\xfc\x00J\xaa\x9d\x9d\xd9\xe9\xaeg\xbfz\xbf\xf7\xfb\xaa\x05\xe0\xf8\x19\ +\x0c\rpz\xef\x01\xbe\x1f\xe0y>Jk\x94T\x08\xa9\x10B\xe0\x9cc\x8f\xd5\xb5/n\ +\xfb\x81\x13;\x7f\x14\xfc\xe4\x10\xfb\xbf\xba\xe6\xa7s\x8e\xcf\xff\xf9Y\r\ +\xe2\xfb\x01a\x18\xe1\x07a\x07#[\x10\x1c8\x87\xb3\x80\xab0&\xc7V9\xa6\xca\ +\xa9\xaa\x1c[UTUIe\x1c\x0e\x89T>\x9e\x1f\x11\xf6\x87x^P/,\xc4\x0e\x84\xa8q\ +\x058\xeb\xb0\xcel#\xe2y>~\x10\x12\x86=\xbc Dk\x1f%e\x8b\x8e\xb5%\x98\x14\ +\xe1*B\xdfG\xa9\x1eJ)\x00\xaa\xaa\xa2,K\xf2<\'I\x126\x9b\r\xeb\xd53\x16WgD\ +\xc3k\xbcrmB4<\xd8b\x88\x16G\xe0\x9c\xc5Z\xbb\x05QZ\xe3y>^\x10\xe2\xfbMT\x94\ +\xaa/0\x1baR\x86\xfd\x11a\xafO^)\xbe\xf9~\xcd\x1bo\xd0A\xccf3\xe6\xf39I\x92P\ +\x14\x05B\x88FS\xb2\x13\xf0.\x8c\xe7y\x04A\xd0\x81\xb5)\xef\xdc\x19\xf3\xd9\ +\x19Q4\xc2Z\xb7\x0f\x82\xab\xc0\x96\x84\xe1\x04\xe5\x05\x94V1\xbd\\\xf2\xe9\ +\xdf\x1fr\xef\xbd\t\xaf\xf4\x05WWW\xc4q\x8c\xb5\x16)%\xce9\xa4\x94\xdd-ZM(\ +\xa5\xd0Z\xbf\x14\x95\xf6\x1ac\x0c\xe7\xd3\x19y\xbeA\xeb`\x07\xc4\x8119\x81\ +\xe7!\x95\xa62\x828)\xd8\x14\x0b\xd6\x9b)_|\xf1_^\x9f\x1c\xf0\xe1\xaf^\xc3\ +\xf7T\xe7\x94\xad\x08[\xfd\xb4\xef\x95R8\xe7\xb0\xd6vQ\xd9\xcd\xa0\xa2(\xd8l\ +6\xa4\x9b%\xfd\xd1\xf5\xfd\x88\xd8*G\xaa\x00P\xa4E\x85-cJ\x93\x91\xa4)\xf1z\ +\xcd\xc3\x8b)\x8f\xbf\xfd\x91?\xfd\xe1=\x8e\xae\x8f\xf6l\xbb\x8dF;vA\xdb\x88\ +\xb4p\xad\x03\xafV+\x96q\xb6\xaf\x11\x87\xc3T9RH\x8c\xb5$INn\x1c\xa5\x81,\ +\xcb\xc9\xb2\x94\xaa,\xb9z\xbe\xe0\xd3\xcf\xfe\xcdG\xbf{\x8f\x0fNo\xef\x14\ +\xc5-@\x1b\x95v\xb6\xd1RJa\xad%MS\xd6\xeb5\xe3\xf1\x98\xd5f\x8au/\x88\xb5\ +\xaar\x1cP\x14%\xa6\xcaH\xcb\x82\xca@YV\x94e\x81u\x8ev\xcd\x7f\xfd\xe7k\xbe\ +\x7f6\xe7\xcf\x1f\xdd%\x08\xbc=\x88\xdd\xed\xd1Zw\xd1\x91Rb\x8ca4\x1a1\x1c\ +\x0e\x19\x0c\x06x\xeab\xeb;m\xfa\xd6U\xb4\xa2\xc8\x0b\xd24%I\x12\xd24\xa3(rL\ +U5\xc5\xc9\xd1T-\x9e|\xf7\x8c\xbf\xfc\xf5s\x9e\x9e=\x7fI3\xbb \xad\x7f\xf4\ +\xfb}\xa2(\xea\xec\xbfvb\x1f\xf6@\x9c\xa0\xaaj\x93*\xca\x82"\xcf)\xf2\x8c"\ +\xcf(\x8bb\xc75\xa9/t\xdb(\xfe\xed\x1f\x0f\xc9\xf2r/"J\xa9\x0e\xa4\x15k\x18\ +\x86]\x19\xe8J\x81\xe7w]\xcdvk\x8c\xab\x01\x8a\x9c\xd2\n\xcaR`\xac\x00\x04Ri\ +\x94\x92\x8d\x9aD]\t\x9a\x1e\xe8\xc1\x87o\xd1\x0b\xfd\xbdH(\xa5\xf6\x8cM)\ +\x851\xa6s\xd9\xae\x0eI\x05\xd5\x9e\x8f\xd4MM\x9a\xa5\x04Y\x8a\x93\x02S\x08*\ ++@*\xb4\x90HaA\xaa\xba\xadi\xea\xd2\x9d7n\xf2\xdb\xdf\x9c\xbc\xa4\x8b\x17}Dk\ +\x8d1\x86,\xcb\xf6\xea\x8f\x90\xba\xd3H\x03"\x90\xca\'\xd9$\xf4z)\xd2\x93X\ +\xa3(\r(\xe5c\xa5\xc2\n\x89\x14\x02!\x14\x0e\xc7h0\xe2\x93\x8f\x7f\xdd\xddt\ +\x17\xe2E\x9b\xd7Z\x93\xe7y\xd7\xc3\x18c\xeai\xb7)\xdfm\x8d\xe7G\xc4\xabg\ +\x84\xbd\x88^_a\x8d\xc6U\x92\xca\t\x10\xb2\xae\x96B"\x84C\x08\xc1\'\x1f\x9f\ +\xd2\x8f\xc2\xbd\xedh!ZM\xb4 m\xc4\x8c1uB4\xcdTex1"\x10\xf6\x87,\xae\xce\x88\ +\xd7+\xa4\xd2 C\x9cUX\x07B(\xa4\xd4HipR\xf2\xfb\x0f\xde\xe1\xcd[\x87/\x01\ +\xb4\xe2l\xc5\xd8\xeb\xf5:}\x94eI\x96e$IB\x92$\xcc\x17kJ\xc3OD\xc4\x0b\x88\ +\x86\xd7X.\xceQZ\x13\x84\x16D\x80\x13`*\xd5\xec\xad\xe2\xb5\xd7&<\xf8\xf0\ +\x97]\xa1k\xe7\xeeV\xf8\xbeO\xaf\xd7C\xebZ\x03eYvn\xbaZ\xad\x88\xe3\x988)\ +\xb1\xaei\x8a\xb7>R\x8fW\xaeM(*\xcbb>\'M\xd6`r\xa4+\xc1\x16\x18S!\xa4\xe0\ +\x8f\xf7\xdf\xe9\x1a\xde\xdd\xdec\x17\xa2\xcd\x94\x16\xa2\xedc\xe7\xf39\x8b\ +\xc5\x82\x1f\xcf.\x88\x93jw\xe9-\x88\x10\x82hx\xc0\xd1\xcd\xdb\xccf\x97\xcc\ +\x9f_\x91g1\xd2\x15hi\x90\xae\xe4\xfe\x07o\x12\xfa\x8a\xaa38^\xf2\x8d\xd6M\ +\xdb,Y,\x16\xccf3...\x98\xcdf\xccf3\x9e/\x13*[\'Ik\x86\xbaI\x9an\xbc~\xfc6\ +\xf1r\xc1\xd9\x0f\x8f\x10Rp\xe8\xd7\xe2\xbbqs\xc4A\xa4X\xaf\xd7\xdd\xc2RJ<\ +\xcf\xdb\xcb\x84<\xcf\xbb\x962I\x12\x16\x8b\x05\x17\x17\x17\x9c\x9f\x9f3\x9d\ +Ny\xf2\xdd9\xab\xb8\xecZ\xd3\xb6ll\xfb\x91\x86HH\xc1[\xef\xbeO\x9a\xa5\\\xcd\ +\x9e\x11\x06!\xbd0\xc4W%\x97\x97\x97]\xa1k\x17o\xbby\xdf\xf7\xc9\xb2l/\x1a\ +\xab\xd5\x8a\xf9|\xcel6c:\x9d\xf2\xbf\xc7O\xb9Z\xa4\x8d\x0f\t\xb6\xe7\x9c\ +\x1d\x10\xd1|(\x10\xf4\xa2\x01\xa7\xf7\xee\xf3\xe8\xeb/\xb9\xbc|\x8a\xef{\ +\xf4B\x1f\x01\xdd\x7f\x9d\xa6)\xa3\xd1\xa8;\xebh\xad\x91Rv`\xad8\xdb\xady\ +\xf2\xdd9W\x8b\x14\xebjg\x16\r\xc8\x9e\xc5o\xb5+:\xda(\x1arz\xef\x01\xdf>\ +\xfe\x8a\xab\xe9S\x9c;\xeb\x9a\x9a$IX\xaf\xd7\x0c\x87\xc3\xae~\xb4 \xbb\xdf\ +\x89\xe3\x98\x1f\xcf.x\xbeLX\xc5es\x9ea\xebK;\xa3\xe9G\xb6\xd1\xd8\xbe\n\x84\ +\x90\xdc\xbes\x97k\xd7o2\x9f\x9dq>\x9duG\x89\xf1x\xcc`0\xa0\xd7\xeb\xbd\xd4\ +\x81\xe5y\xce|\xb1&NJ\xe2\xa4\xa2\xb2M\x04\xc4\xf6\xbe]c\xb5\xaf\x11\x87\xb3\ +\x0e\xe7,\xce\xd9\xba\xcdw\x96VM\x83\xc1\x01Q4"\xcf\xeb\xf6n\x19g\xac6S#\x19\x1e\xdd`\x88\x16G\xe0\xbd\xc39w\x03\xa2\ +\xb4&\x08B\x82(&\x0c\x9b\xa8(U\xff\x83\xdd\xa1\xa4e\xd8\x1f\x11\xc7gH\x15pr4\ +@J\x89s\x8e\xb2,)\x8a\x82,\xcbj\x88\xcd\x86\xe5r\xc9r\xb9d\xb1\x98p=\xbf\xe0\ +\xf4\xfe#>y\xf8\x1c!k\x00D\r\xe4\xbd\xc3\x9a\xbd\x88(\xa9PZ\xa3uX\x03\x05!R\ +\n\x02\x911:\n\x19\x8dN\x89{}T\x10a\x9c\xe0\xec\xee\t\xe3\xe3\x04c\x0cy\x9e\ +\x1f@\xacV+\xfa\xfd>\xbd^\x8f0\x0c\x99\xcf\xe7\xbc\xfa\xefwlWK\x9e~\xfe%\xbd\ +dP\x83 \xc0{\x84\xdc\x03\x11R!\xa5BI\x89R\n)\x05\xb1.8\xbd3\xe4\xe4\xe4\x0e\ +\xc9\xe0\x08\x1d$TN\xb1MKr\x17\xf1\xe9\xa7\x9f\x92e\x19\xdb\xed\x96,\xcb\xe8\ +\xf5z\xc4qL\x14E\x84a\x88\xd6\x1a\xa5j\x9dYk\xb9\xf8\xed\x9c,\xcfx\xf1\xf2+\ +\x92d\xd8\x14\x82CZ\xb9\x07"D-\xa8&\x7f\x81\xc88\x1d\x0f9=\xbd\xcf\xe8\xf8\ +\x0eq\xff\x04\xa1\x13v\x99aW.y\xf3\xee\x9a\x7f\xfc\xbd\x8f\xb5\x96$I\x00p\ +\xce\xe1\xbdo\xaa\x0c\xa4\x94\xdd&\x84@J\xc9lv\xc9\xf9\x0f\xdf\xf2\xe2\xe5\ +\xd7\x08!\x01\xd1\x15\x9c\x06\xea\x13\xe0\xc1\x83\xb0;FG!\'\xe3;\x0c\x8f\xee\ +p4~@\xdc\x1fc\xbcf\x95\xce\xd8\xec\n\xd2,\xe3\x87\xf3w<\xf8\xa8\x86\xf1\xde\ +\xa3\x94"\x8a"\x84\x10h\xad\t\x82\x80 \x08\xba\xe8DQD\x1c\xc7L&oy\xfd\xcb\ +\xf7C\ +\x05\x11\x95S\xec2\xc3*\x9dqy9\xe1\xfd\xfb\x19\xeb\xf5\x8a,K\xb1\xb6\x0e\xe7\ +\xcfo\xde\xf3\xf4O\x1fu\xa7h5\xa1\x94Bk\xfdAT\xa4\x94x\xef\xb1\xd62\x99\xce)\ +\x8a\x1dZG{ \x1e\xac-\x88\x82\x00\xa94\xc6\n\xb6i\xc9\xae\\\xb2\xd9\x15\\]\ +\xcd\xd9l\xd6dY\xda\x88\xb2\xb6\xf8\x9f\xdf\xbc\xe7\xf9\x9f\xefubmE\xa9\x94\ +\xc2{\x8fs\xae\x8b\xca~\x05\x95e\xc9n\xb7#\xdb\xad\xe8\x8f\xee\x1eF\xc4\x99\ +\x02\xa9"@\x91\x95\x06Wm\xa9lN\x9ael7\x1b\xf2{|\xaf\xeb\x1f\xffO\x17\xb7}Dk\x8d\xb5\x96<\xcf\x0f\xfa\x8f\ +\x90\xba\xd3\x88n\xd5\'UH\xbaK\xe9\xf52d \x81\x88\x07\xf7\xc6<{\xfc\t\x7f}\ +\xfe\xb0k\xeb\xfb%\xda\x02\xb4\xe9h!n\xdb\xbc\xd6\x9a\xa2(\x10B\xe0\x9c\xc3Z\ +[o\xee\xa6\xe4\xbb\xd4\x04a\xc2n}I\x7f0\xe0\xech\xc4\xc3O\xcf8>>\xe6\xe4$\ +\xa1,\xcb.\xd7\xad1\xed\x97h\xfb}\x0b\xd1\n\xb4\x05i\x8f\xb7\xd6\xd6\x05\xd1\ +\x0cS\xc6r;"\x10\xf7\x87,\xaf.\xd8n\xd6\x0c\x07}\xae\xaf\xaf\x91Rvw\x16\x04\ +\x01Z\xeb\x836\x7f\x1b\xa0\x15g+\xc6^\xaf\xd7\xe9\xa3\xaa*\xf2<\'MS\xd24e\ +\xb1\xdctB=\x8cH\x10\x91\x0c\xc7,\x16\x93N`\xb7A\xc20<\xb0\xf2Vx-@\x1b\x810\ +\x0c\xe9\xf5z\x1dxUU\x9d\x9b\xae\xd7k\xb6\xdb-\xdb\xb4\xc2\xf9f(\xde\x07\x01\ +8\x19\x9fq=\xbf`>\x9fw\x17k-\xbam\\\xed\x05[\x9d\xfc\x1eD{#-D;\xc7.\x16\x0b\ +\x96\xcb%\xef.flSs\xe0G\x1d\x88\x10\x82dx\xc4\xe9\xfdG\xbc\xfa\xefwXk\xbb\ +\x0b\xb5\x00-P\x14E\xdd\xf4}\xdb7Z7m\xd3\xb1\xd9l\x98\xcf\xe7\xccf3\xe6\xf39\ +\xf3\xf9\x9c\xebU\x8aqu\x91\x88\xfd\tm\xdf\xb2?y\xf8\x9c\xedj\xc9\xc5o\xe7H)\ +?\x10\xde\xbe.\xda\xd4\xedWBQ\x14H)\xbbt,\x97Kf\xb3\x19\x93\xc9\x84\xe9t\xca\ +\xab7\x13\xd6\xdb\xaa\x1bM\xdb\xb6q\x90\x1a\x10\x08)x\xfa\xf9\x97dy\xc6lvy0Y\ +\xb5\xa5\xda\xb6xkm\xe7\x98a\x18\x92\xe7y\x17\x8d<\xcfY\xaf\xd7,\x16\x0b\xe6\ +\xf39\xd3\xe9\x94\x9f~y\xcb\xd52\xab\xdb\x84\x10\xbf\x13\x11\x9a%\x8f\xa8\ +\xf7\xbdd\xc0\x8b\x97_q\xfe\xc3\xb7L&o\xf7&+\xdf\xddu\x96e\x8cF#\xfa\xfd>q\ +\x1c\xa3\xb5\xee\xd6:\xc6\x98N\x9c\xcb\xe5\xb2^R\xbc\x99p\xb5\xccp^ hG\x05\ +\xd1-\\u\x9b\x19\xdf\xe6\xa8\xa1M\x92!/^~\xcd\xeb_\xbe\xe7j\xfa\x16\xef/\xba\ +\xa1&MS6\x9b\r\xc3\xe1\xb0[F\xb4 \xfb\xc7l\xb7[\xde]\xcc\xb8^\xa5\xac\xb7U\ +\xb3\x9e\x01\x84l\xa6\xf8[b\xf5{\xd1\xb8\xd9\x0b\x84\x90\xc0\xc5\xcb\x1fQ\xaaG\x10(<\xdf\xc7\x93\x1eBz\x08!\ +\xb0\xd6r\xc0j\xdd\xce\xde\xbdaE\xe7\x9f\x82?}\x89\xc3_\xed\xfe\xa7\xb5\x96\ +\x7f\xff\xeb\x9f\r\x88R=\xc20F\xf5\xc2\x16F:\x10,X\x8b5\x80\xad\xd1\xba\xc0\ +\xd4\x05\xba.\xa8\xeb\x02S\xd7\xd4uE\xad-\x16\x89\xf4\x14\x81\x8a\t\xfbC\x82\ +\xa0\xd7\x9cX\x88\x0e\x84hp\x05Xc1V\xdf)\x12\x04\n\xd5\x0b\t\xc3\x88\xa0\x17\ +\xe2\xfb\nOJ\x87\x8e1\x15\xe8\x0cLE/\x08\x90^\x0f)$\x16\xa8\xeb\x9a\xaa\xaa(\ +\x8a\x82<\xcbH\xd3\x94\xdd\xfa\x9a\xe4\xf6\x8ax8\xe1xrJ<<\xba\xc3\x10\x0eG`\ +\xad\xc1\x18s\x07\xe2\xf9>A\xa0\x08z!J\xedU\xf1\xbc\xe6\x03z\x87\'5\xc3\xfe\ +\x880.\ +\xae8y\xf4\x94\'_\x9e#d\x03\x80h\x80\xac5\xe8\xba\xa3\x88\'=<\xdf\xc7\xf7U\ +\x03\x14(\xa4\x14\x04"ct\xa4\x18\x8dN\x08\xa3>^\xd0\xa36\x82\xac\xa8I\xd3\ +\x02]\xe7\x94d\x94FR[\x81\x95\x02\x19H\x9e|6a\xb9\x8cQJ\xb1X,x\xf3\xdb\xcflW\ +\t\xcf\xbf\xfd\x9e(\x1e4 \x08\xb0\x16!; BzH\xe9\xe1I\x89\xe7yH)\x08\xfd\x82\ +\x93\x07C\x8e\x8f\x1f\x10\x0f\x8e\xf0\x83\x98\xcaxl\xd3\x12]l)\xb4%\xabJ\xd2\ +RP\x96PU\x02]\n\x8e\x8f\xc6\x9c\x9e\x8e\x08\x82\x00\xcfk\xfaLk\xcd\xd5\x1f\ +\xaf\xc8\xf2\x8c\x8b\x97?\x10\xc7\xc3\xbd\x11\x0cR\xcb\x0e\x88\x10MC\xed\xeb\ +\x17\x88\x8c\x93\xc9\x90\x93\x93G\x8c\xc6\x0f\x08\xfb\xc7\x08?f\x97\xd5\xec\ +\xca\x84\xda\xe4T\x1a\xea\x1a\xb4\x91\xcd\xa6\x05\xb5\x11<9;e<\xee!\xa5l7!\ +\x04RJ\xe6\xf3k^\xfd\xfa\x13\x17/\x7fD\x08\t\x88\xd6p>\x80\xb5v\xef\x0e\x10z\ +\xc7\xe8Hq\\s}=\xe5\xf6v\xc1v\xb3!\xcf3\xaa\xaa\xc4h\xdd\\\xb1\xe7\xf3\xc5\xe9C&\ +\xc7G\x94e\x89R\n\xa5\x14\xbd^\x0f\xa5\x14a\x18\xa2Tc\x82\xdb\xd9{&\x0f\x1f1\ +\x18\x1ca\xbb\xae\x01\x9a\x9c\xd0Y\xe3\x8e\xa8\x8f\x1f\xc4\x08?\xa6\xb6>\xb3\ +\x0f\xd7\xbc{{\xc9\xcd\xcd\x9c\xcdfM\x9eg\xd4U\x85\xb1\xb6\t&!\xf1<\xc97\xcf\ +\x1f\x13EQ\xabF\x10\x04\xf4z\xbdV\x99\xc6\x89`\xed\x15\xcb\xc5\x15q<\xc2\x18\ +{\x08\x82\xad\xc1T\x84\xe1)^\xd0\xa32\x1e\xbb\xacf\x95\xce\xb9\xbe\x9ers3g\ +\xbd^\x91e)Z\xeb\xfd\x17\xba\xb0j\x02\xe7\x9b\xe7g\xed\t}\xdf\xffD\x15)%\xd6\ +Z\xb4\xd6Lg\x0b\x8ab\x87\xef\xf7: \x16\xb4.\xf6a\xe5Sk\xc16-\xd9\x95\t\x9b]\ +\xc1\xed\xed\x82\xcdfM\x96\xa5\x18c\xb0\xb6\x13\xf1B"\xb0L&\xc7\x8cG}\x00<\ +\xcf\xc3Z\x8b1\xa6U\xa5\xeb\xa0\xb2,\xd9\xedvd\xbb\x15\xfd\xd1\xc3CEL]\x10\ +\x04\x11q\x14\x81\xf4X\xad\xb7T:\'\xcd\xb2\xb6\'\xb4\xd6X\xbb\'Gt\xd6\x0f\ +\xc1\xc5\xf9\x13\xa4\x94\x07\x91.\x84h\x15qpEQ\x90\xa6)\xeb\xf5\x9a\xd56?\ +\xec\x11\x8bE\xd7\x05\x9e\xe7\x11\x85\x8a\xf3g\x9f3\x9e|\xc6mR\xf0\x9f\xdf\ +\xff\xe0\xe6fN]U\xb8c?Y\xd8\x04|\xf5\xb7\x936\x06\xba\xd6\x050\xc6\xe0y\x1e\ +\xc6\x18\xb2,c\xb3\xd90\x1e\x8fY\xeff\x18{\xafY\xeb\xbah?T\xd75\xbe\xb4|\xf1\ +\xf9\x80\xc7\'_\xf3\x8f\x8b3^\xff\xef\x86W\xef\xe6\xbc\xbd\x9c~\xc2\xf1`2f<\ +\x8c\x0f@\\\x9f8u\xa4\x94h\xad\x19\x8dF\x0c\x87C\x06\x83\x01\x817\xdf\xaf\ +\xee\x1d\xfb6\xabhMY\x96\xe4y\xcev\xbb%\x8ec\xb4\xd6x\x12\xbe}\xf69\x7f\xff\ +\xea\x8c\xaa6\xfc\xf7\xf2\x86\xdf\xdfNys9\x05\x0b\xdf\x9d?nK\xe1\x94p \x0e&\ +\x08\x02\x8c1\xf4\xfb}\xa2("\x8a"\xc2PQ\x1f\x80XA]W\xed*\x9ae\x19Y\x96\xed\ +\x9da\xf7\xb1\xdf\xc8\x1c\xf6\x02^|}\xc6\x8b\xaf\xcf(\x8a\x8aW\x977|\xf9x\ +\xd2\xaa!\x84\xc0\xf3\xbc\x16\xc4E\xbdS:\x0cC\xc20l\x9c\x14(\xaa\xc6\x80\x9d\ +\xd2h\xdbB\xecv;\xa2(Bk\xdd\xa6\xa2\xef\xfbm\xe9Z\xa8P\xf1\xdd\xf9\xe3O\x94\ +\xf0<\xef Y=\xcfCk\xdd\xa6\xac\xef\xfb\x8d\x8b\xa4\x07\xf5\xbd\xd2Xd3K\xecvl\ +6\x1b\xc20\xc4Z\xdbB8\x80\xae#\xba[\xb7\x1c\xf7s\xc4\xf7}\xb4\xd6\xe4y~\xb0\ +\xfe\x08\xe9\xdf\xef\x11\x81\xf4T\x0b\xb1Z\xad\xe8\xf5zXk\xdb\xfa\xfa\xbe\ +\x7f\xe0\x84.\x80+\x87\x83\xe8\xaa\xe1@\x8a\xa2@\x08\x811\x06\xadu\xb3\x19\ +\xd96|[\x9a@\xc5l\xd6\xd7$IB\xbf\xdfG)\xd5\x1c\xb0\xaf\xb3\xab\xb5\x0b\xa6\ +\xaeE\xdd\xfb\x0e\xc2-p\x0e\xc4\x1d\xaf\xb5n\rQ\x14\x05\xb5\xe6\xbe"\x10\xf6\ +\x87$\xb7W$IB\x14E\xad\x02\xee\xca\x9c*\xee\x83\x7f\x06\xe0\xa0]3FQ\xd4\xf6G\ +UU\xe4yN\x9a\xa6\xa4i\xca2\xd9\xb4\x8dz\xa8H\xd0#\x1eNX.\xa7m\x83\xdd\x07QJa\ +\x8ci\xaf\xd05\x9e\x03p\n(\xa5\xda\x8b\xb1\xd6RUU\x9b\xa6\xeb\xf5\x9a\xedv\ +\xcb6\xad0v?\x14wA\x00\x8e\'\xa7|\\\\\xb1X,\xda\x93\xb9\x88v\x0b\x97;\xa1\ +\xeb\x93?\x83p\x17\xe2 6\x9b\rI\x92\xb0\\.I\x92\x84\x0fWs\xb6i\xdd=\xf5\x1d\ +\x88\x10\x82xx\xc4\xc9\xa3\xa7\xbc\xf9\xedg\xf4~\xcep\xdd\xefj\xef67}\xdf\ +\xcf\r\x17`\xae\x1c\x9b\xcd\x86\xc5b\xc1|>g\xb1X\xb0X,\xf8\xb8J\xa9Mc\x12\ +\xd1\x9d\xd0\xba\x91\xfd\xe4\xcbs\xb6\xab\x84\xab?^!\xa5\xfc\xa4\xf1\xba}\ +\xe1J\xd7uBQ\x14H)\xdbr$I\xc2|>g:\x9d2\x9b\xcdxs9e\xbd\xad\xda\xd1t\xdfr\x87\ +\xa5\x01\x81\x90\x82\xe7\xdf~O\x96g\xcc\xe7\xd7\x07\x93\x95\xb3\xaa[\xe2\xb5\ +\xd6mb*\xa5\xc8\xf3\xbcU#\xcfs\xd6\xeb5\xcb\xe5\x92\xc5b\xc1l6\xe3\xf7\xd7\ +\xef\xb9M\xb2f\xac\xdc\xcf1\x87\x8a\xb0\xbf\xe5\x11\xcd>\x8a\x07\\\xbc\xfc\ +\x81W\xbf\xfe\xc4t\xfa\xbe3Y\xd9\xf6\xaa\xb3,c4\x1a\xd1\xef\xf7\t\xc3\xb0u\ +\x99\x03s\xcd\x99$IsKq9\xe56\xc90V \xb8\x1b\xa8\xdc\x8d\xab\xef*c]\x8d\xf6\ +\xb4q<\xe4\xe2\xe5\x8f\xbc{\xfd\x0b\xb7\xb3\xf7X{\xd5\x0e5i\x9a\xb2\xd9l\x18\ +\x0e\x87\xfb\xc5\xeb\x0e\xa4{\xccv\xbb\xe5\xc3\xd5\x9c\x8f\xab\x94\xf5\xb6\ +\xda\xdf\xcf\xd0\x0cS\xe2.\xccZ\x10\xdbQ\xe3n/\x10B\xf2\xf4\xd9\x0b&\x0f\x1f\ +\xb1\\\\1\x9d-\xd8\xedv\xac\xd7k\xc6\xe31\x83\xc1\x80(\x8a>\x99\xc0\x8a\xa2`\ +\x99l\xd8\xa6\x15\xdb\xb4\xa66{\x05\xc4\xdd\xf7\xb6\xf7\xc3\x87=b\xb1\xc6b\ +\xad\xc1Z\xd3\x8c\xf9\xd6\xe0\xbai08"\x8eG\x14E3\xde\xad\xb69\xeb\xdd\x8c\ +\xc0\x9b\x13\x86\n\x15\xa8\xe6\xe9\x81\xf4\xd1FRk\xa84\xfb\x9cpJ;\xed\x0f\ +\x1f\x0b\x1c$\xab\xb5\xcd]\xb91\xcd\xbd\xa8\x90\x1a\xa9%V\x805\x1ak\x0c\xc6X\ +|\xbfG\x7f\xf4\xb0\xf9\xdb\x1a\xac\xb5\xd4\xd66\tY\xdb\xf6K\xdd\xbe-\xb8p\ +\x83v\xe7\x01\x87\xdd\x1fg\xda\xa6\xf8k<\xa8\xf9?\xa2\xcax\xb9\xd2zv\x8b\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def get022Bitmap(): + return wxBitmapFromImage(get022Image()) + +def get022Image(): + stream = cStringIO.StringIO(get022Data()) + return wxImageFromStream(stream) + +index.append('022') +catalog['022'] = ImageClass() +catalog['022'].getData = get022Data +catalog['022'].getImage = get022Image +catalog['022'].getBitmap = get022Bitmap + + +#---------------------------------------------------------------------- +def get023Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +HIDATx\x9c\xcd\x98\xdbn\x1b\xd7\x15\x86\xbf\xbd\xf7\x1cy\x12-Kf\x9c\xc4\xaa\ +\xe1\xb8qS\xa8nR\x15\x01\x82\xc6E\x81\xa0@\n\xe4\xaa}\xba\xbe@/z\xd3\x9b^\ +\x16\x08P\xa0g4A\x81 @b\xc4I\xeaD\x96\xe4\x919\x1c\x923\x1c\xce>\xf4b\xb8G\ +\xa4\xeb\x07\x08\x81\xd1H\xe2&\xe7\x9b\xb5\xfe\xf5\xaf\xb5G\x00\x8e\xef\xc0+\ +\x00\xb8\x7f\xf2\x80(\x8a\t\xc3\x08\x15\x04(\xa9\x10R!\x84\xc09\xc7\x0e\xab\ +\xf3\'w\xf5\x0f\'\xb6\xde\x14\xbc\xf0%v\x7fu\x9b\x9f\xce9\xfe\xfc\xa7?\xb4 Q\ +\x14\x93$=\xa28\xe9`\xa4\x07\xc1\x81s8\x0b8\x8d15V\xd7\x18]\xa3u\x8d\xd5\x1a\ +\xad\x1b\xb4q8$RE\x84Q\x8f\xa4?$\x0c\xe3\xf6\xc2BlA\x88\x16W\x80\xb3\x0e\xeb\ +\xccUD\xc20"\x8a\x13\x92$%\x8c\x13\x82 BI\xe9\xd1\xb1\xb6\x01S\x81m\x88\xc3\ +\x10\xa9b\xa4\x908@kM\xd34\xd4u\xcd\xaa\xaa(\xcb\x92E\xf1\x84\xfc\xf2\x94\ +\xdep\x9fk\xfb\x13z\xc3\xbd+\x0c\xe1q\x04\xceY\xac\xb5W *\x08\x08\xc3\x880N\ +\x88\xa2MT\x94j?`\x96(i\x18\xf6G$\xc9\x04\xa9B@b\xace\xbdnX\xd7k\xd6\xcd\x9a\ +\xf5\xba&I+\xd2^E\x92\xf6X\xcc\x0bf\xf9\x19\xcf\xb2Sn\xdc\xbc\xcd\xabG\xf7\ +\x10\xb2\x05@\xb4@\xceY\x8c\xde\x8a\x88\x92\n\x15\x04\x04A\xd4\x02\x85\x11R\ +\nBQ1\xda\x8b\x19\x8dn\x90\xa4}T\x18\xa3\xad\xa0\xaa5eYc\xf4\x8a5\x15k+\xd1N\ +\xe0\xa4@\x86\x92\xb4\xaf\x90*@\x05\x01\xf9t\xca\xa3\xcf>f1\xcb\xb9\xfb\xc6[\ +\xa4\xbdA\x0b\x82\x00\xe7\x10r\x0bDH\x85\x94\n%%J)\xa4\x14$A\xcdK\x07#&\x93\ +\t*\xea\xa3\x82\x94\xc6*\x16\xe5\x1aS/\xa8\x8d\xa3j\xd6\x94k\xc1z\rM#0k\x811\ +\x12g\x02\x90\tqb\x19\xed9\x8c1\x9c~\xf3\x90jUq\xff\xe4]z\xbd\xe1\xa6\x10,\ +\xd2\xc8-\x10!ZAm\xf2\x17\x8a\x8a\x9b\x87{\xdc\xbau\x8b\xa3\xa3#\xae\x1d\xbc\ +\xc4\xa3o\n\x96\x95f\xb9\xce\xd1vEc@k0V\xb6\x87\x11h+h\x8c\xc0i\x89\xb3\nDL\ +\x9c\xc0\xb5}\x81\x90\x82\xcb\xec\t\x0f?\xfd\x88\xfb\'\x0f\x10B\x02\xa2+\xb8\ +\x00\xc09\xb7\xa9\x0e\x10f\xc9\xde8f2\x99ptt\xc4\xf1\xf11\x87\x87\x87\x8c\ +\x0f+>\xfc\xcb\x7f\x98/k\xca\xaab\xb5\xaai\xb4\xc6Z\xd3\x96\xb8\x10 \x15JEh\ +\'\xb0\x9b\xaa\x96J\x90\xf4$\x87QH\x12\'<}\xfa\x98\xaf\xbe\xf8\x84\xdb\xaf\ +\x1do\xaaq+5lJ\xd4\xda\x86PY\xae_\x7f\x99\xc9d\xc2\x9d;w8<b\xc6\x18\xde>\x9e\xf0\x8f\x7f\xfe\x8b\ +\xd5\xaaB7\r\xd6\xb9\xd6\x98\x84D)\x89\x14\x16+$BH\xa4\x0c\x90RbL\x00\xaea\ +\xffz\x8fA\xea\xb88\x8fp\xee\x94ivJ\xaf7\xc2Z\xb7\x0b\x82\xd3\x08\xa7\xe9\ +\xf7\xfb\x8cF#\xc6\xe31RJ\xac\xb5\x18c\xc8\xb2\x8c@j~\xfa\xa3#>\xfc\xeb\'\ +\x1b@oV\x1b\xc3\x91\n)Z0)\rR*")x\xf3\x07/\xf3\xca\x8d\x1eO\x9f>E\x00\xc6\x18\ +\xce\xce3\xeazI\x10\xc4[ \x0e\x8c\xa9I\xa2\x88$I\xe8\xf5z\x84aH\xd344M\xc3l6\ +c:\x9d\xb2X,x\xf3\x87\xb7\xf8\xf2q\xc6\xa3\xff>\xd9x\x94\xa4\xf5\xdf\xd63\ +\x85P\x08\xe1pRrpp\x9d_\xbe{\x8f\xf10a>\x9f#\x84\xc0\x18\xc3z\xbdf\xb9\\R-g\ +\xf4G\x07\xbb\x11\xb1\xbaF\xa9\x94(\x8a\x08\x82\x00\xad5\xcb\xe5\x92\xa6i(\ +\x8a\x82\xb2,\xb1\xd6"\x84\xe0W\xbf8\xe6\xb7\xbf\x9b\xa2u\xbde\xdc\xado;\x1c\ +B\x08N\x8e_\xe3\xc1\xdb\xdf\'\n\x15Zk\x94R8\xe7\xa8\xeb\x9a\xb2,)\x8a\x82\ +\xd9b\xb5\xab\x11\x87\xc3\xe8\x1a\xa5\xda\xfeb\xade\xb5ZQ\x14\x05M\xd3P\x96%\ +\xeb\xf5\x1a)\xdb\x9aO\x93\x88_\xbf\xff\x16\xbf\xff\xe3\xdf=G\xd7\xef\xa20\ +\xe5\x83\xf7\xee\xf3\xc6\xdd\x97\xbb\xf5\xd6Z\x94RXk\xa9\xaa\x8a\xf9|\xcex<\ +\xa6X\x9ec\xddsb\xf5wg\xadEkMUU\x18c:(\xdf\x89}\x03\xfb\xde+\xd7y\xe7\xe4u\ +\xfe\xf6\xef\xcf;\x98Wo\x1e\xf2\xc1{?f\x7f<@)E\x10\x04\xdd\xfaV\xb8\x86\xd1h\ +\xc4p8d0\x18\x10\xaa\x8bMw\xdf*\xdf\xb6\x8bj\xd6\xeb5\xab\xd5\x8a\xc5bA\xaf\ +\xd7\xc3\x18\x831f\xe3\xb8\xb2\xbbK\xe7\x1c?;\xb9\xcb\xe7_^p\xf9,\xe7\x9d\ +\x93{\xfc\xfc\xed\xd7\xbb5\x1e\xc4\xc3\x84a\x88\xb5\x96~\xbfO\x9a\xa6\xa4iJ\ +\x92D\xe8\x1d\x10\'\xd0\xba\xe9\xbahUUTU\xd5]\xd0C\xbc\xe8\xf5\x9b\xf7\x7fB1\ +\xaf8z\xe5z\xe7\xd0J\xa9\x0e$\x0c\xc3.-Zk\x92$!I\x12\xe28&\n#\x9a\xd6\xcf\ +\xb6Rc\\\x07\xb1\\.I\xd3\x14c\x0cA\x10\x10\xc71A\x10t\xa9\xf3PB\x08\xf6\x86)\ +\xe3Qo\'\x12J)\xc20$\x0cC\xa2\xa8\xed\xe4\xc6\x98\xae\x10\x82 h\xf5(\x15\xe8\ +\xe7R\xe3\x90\x94e\xc9r\xb9d>\x9f\x93$\t\xce\xb9\x0e\xc2\x03\xf8\x9c\xfb\xbb\ +\xf7\xc7v:\xfc9\x8a\xa2\xee\xe2\xc6\x18V\xabU\x07,\x84@\xc8\xe0y\x8d\x08\xa4\ +\x8a:\x88\xd9lF\x1c\xc7\x9d8\xc30$\x08\x82\x1d\x8dl\x03\xf8tx\x88\xedhx\x90\ +\xba\xae\xbb\x8a\xf4\xba3\xf6*\xdd]j\xc2\xa8\xc7\xbcxB\x9e\xe7\xf4\xfb}\xa2(\ +j\x17l\xf2\xecs\xedK\xdcCm\xa7\xc3C\xc4qL\x92$\x1d\x88_o\x8c\xe9\n\xa2\xaek\ +\xb4\xe1\xf9\x88@\xd2\x1f\x92_\x9e\x92\xe79i\x9av\x11\xf0w\xe6\xa3\xe2?\xf8"\ +\x00\x0f\xed\xc5\x98\xa6i\xa7\x8f\xa6iX\xadV\x94eIY\x96L\xf3y\'\xd4\xdd\x88\ +\x841\xbd\xe1>\xd3\xe9Y\'\xb0\xe7A\xa2(\xea\xdcUJ\xd9\t\xcf\x03\xf8\x08DQ\ +\xd4\xdd\x8cs\xae3\xc5\xa2((\x8a\x82\xc5b\xc1\xa2l\xb0\xce;\xe1v\xd3\x03\xae\ +\xedOx\x96\x9d\x92eYw\xb1(\x8a\x88\xe3\xb8-\xb7- \xaf\x93\x17A\xf8\x1b\xf1\ +\x10\xf3\xf9\x9c<\xcf\x99N\xa7\xe4y\xce\xb7\xa7\x17,J\xbdc\x03\x1d\x88\x10\ +\x82\xdep\x8f\x1b7o\xf3\xe8\xb3\x8f1\x9b9\xc3\xab\xdf\xe7\xde\x1f~\xfa~\xde7\ +\xbc\x81\xf9t\xcc\xe7s\xb2,\xe3\xe2\xe2\x82,\xcb\xc8\xb2\x8cg\xb3\x12m\xdb"\ +\x11\xdb\x13\xda\xf6\xe6\xe7\xd5\xa3{,f9\xa7\xdf\xa3X4\xddh\ +\xba\x91\xdcnj\xa0\x9d-\xef\xbe\xf1\x16\xd5\xaa\xe2\xe2\xe2I\x07\xe1/\xec{\ +\x8e\xbf\xb8w\xcc(\x8a\xba\x9e\xe4=\xa3(\n\xa6\xd3)Y\x96q~~\xce\xe7_<\xe62\ +\xaf\xda\xb1r3\xc7\xecF\x84\xcd\x96G\xb4\xe7\xb47\xe0\xfe\xc9\xbb<\xfc\xf4#\ +\xce\xce\x1eo\xf68W\x93\x9aw\xe0\xd1hD\xbf\xdf\'I\x92\xae\xca<\x98\x17g\x9e\ +\xe7dY\xc6\xa3\xaf\xcf\xb8\xcc+\xackG\x06?P\xf9\x8dk\xe03\xe3|\x8e6\xb4\xbd\ +\xde\x90\xfb\'\x0f\xf8\xea\x8bO\xb8<\x7f\x8cs\xa7\xddPS\x96%\xf3\xf9\x9c\xe1\ +p\xb8i^W \xdbk\x16\x8b\x05\xdf\x9e^\xf0lVR,\x9a\xcd~\x86\xcdL\xbb\xdb\xbb6\ +\xf3\xc8U4\xae\xce\x02!$\xb7_;f\xff\xe0&\xd3\xec\x94\xb3\xf3\x8c\xe5rIQ\x14\ +\x8c\xc7c\x06\x83\x01i\x9a\x12\xc7qgt>b\xd3|\xce\xa2lX\x94\x1am7\x11\x10W\ +\xdf\xdb\xed\x87w5\xe2p\xd6\xe1\x9c\xc59\xdb\x8e\xf9\xce\xe2\xd54\x18\xec\ +\xd1\xeb\x8d\xa8\xebv\xbc\x9b-V\x14\xcbsBuA\x92DDa\xd4>=\x90\x01\xc6J\xb4\ +\x81\xc6\xb0\xf1\t\x1fi\x1f\xfb\xdd\xc7\x02;\xce\xea\\\xbb+\xb7\xb6\xdd\x8b\ +\ni\x90F\xe2\x048kp\xd6b\xad#\x08b\xfa\xa3\x83\xf6ogq\xce\xa1\x9dk\x1dR\xbb\ +\xeeK\xfd\xb9K\xb8\xf0\x83\xf6\xd6\x03\x0e\xb7Yg;Q|7\x1e\xd4\xfc\x0fU+\x93#\ +\x1a\xd9\x15\x96\x00\x00\x00\x00IEND\xaeB`\x82' + +def get023Bitmap(): + return wxBitmapFromImage(get023Image()) + +def get023Image(): + stream = cStringIO.StringIO(get023Data()) + return wxImageFromStream(stream) + +index.append('023') +catalog['023'] = ImageClass() +catalog['023'].getData = get023Data +catalog['023'].getImage = get023Image +catalog['023'].getBitmap = get023Bitmap + + +#---------------------------------------------------------------------- +def get024Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xc7IDATx\x9c\xcd\x98\xdfn\xdb\xc6\x12\x87\xbf\xd9].)\xca\x96\xd5$\xb6\x92\ +\xa25\x82\xb4\x07E\x81 @\x91^\x1d\xb4\xcf|^\xe0\\\x9d\x07ho\x8a\x02m\xd0\xa0\ +AZ\xc7v\xe9\x88\x92(R\x14\xb9\xbb\xe7\x82\x7f,\xa5y\x80\x12\xa0i[\x12\xf7\ +\xe3\xcco~3+\x01\x02\xff\x80\xc3\x00\xbcx\xf9=\xd6\xc6D\x91E\x1b\x83V\x1aQ\ +\x1a\x11!\x84\xc0\x11k\x18.\xe1\xfe\x1fA\x0e^\x14>z\xc8\xf1\xaf\xa1\xff\x19B\ +\xe0\x7f\xff\xfdO\x07bmL\x92\xa4\xd88\x19a\xd4\x00B\x80\x10\x08\x1e\x08-\xce\ +\xd5\xf8\xb6\xc6\xb55m[\xe3\xdb\x96\xb6mh] \xa0P\xda\x12\xd9\x94dzJ\x14\xc5\ +\xdd\xc2"\x07\x10\xd2\xe1\n\x04\x1f\xf0\xc1\xddG$\x8a,6NH\x92\tQ\x9c`\x8cE+5\ +\xa0\xe3}\x03\xaeBBKb-ZO\xd0Z\x03\xd0\xb6-e\xb5\xa3\xaekvUEY\x96\x14\xebw\ +\xe4wW\xa4\xa7\x0f\xf8\xe4\xc1\x82\xf4\xf4\xec\x1eC\x06\x1c!\x04\x8f\xf7\xfe\ +\x1eD\x1bC\x14Y\xa28\xc1\xda>*Zw\x1fp["\xed\x99\x9d\xcc\x99N\xa7$I\x82\xb5\ +\x16\x11\xc1{\xcf~\xbf\xe7\xf7\xb77\xec\xf75\xc9\xa4b\x92V$\x93\x94b\xb3f\ +\x95_\xf3>\xbb\xe2\xe2\xc9S>\xbb\xfc\nQ\x1d\x00\xd2\x01\x85\xe0q\xedAD\xb4\ +\xd2hc0\xc6v@\x91E)!\x92\x8a\xb3y\xcc\xc3\x87\x9f2\x9f\xcf\x99\xcdf\xa4i\x8a\ +1\x06\xef=m\xdb\xb2\xdb\xed\xf8\xf5\xcd\x8a6\x08A\t*RL\xa6\x1a\xa5\r\xda\x18\ +\xf2\xe5\x92\xd7\xbf\xfcH\xb1\xca\xf9\xf2\xebo\x98\xa4\'\x1d\x08\x02! \xea\ +\x00D\x94F)\x8dV\n\xad5J\t\x89\xa9y\xfch\xc6\xe3\xc7\x8fY,\x16\\\\\\0\x9f\ +\xcf\x89\xa2h\x04\xa8\xaa\x8a\xa2((\xf7\xd04\x82\xdb\x0b\xce)\x823\xa0\x12\ +\xe2\xc43;\x0b8\xe7\xb8\xfa\xe3\x15\xd5\xae\xe2\xc5\xcb\xefH\xd3\xd3\xbe\x10\ +<\xca\xa9\x03\x10\x91NP}\xfe"\xa9xr~\xc6\xe7\x9f\x7f\xce\xe5\xe5%\xcf\x9e=c\ +\xb1X\xa0\x94\xa2i\x1a\xb6\xdb-\xeb\xf5\x1a\xe7\x1ci\x9a\xe2\xbc\xc29\xa1\ +\xf5B\xe3\x84\xd0*\x82\xd7 1q\x02\x9f<\x10D\tw\xd9;^\xfd\xfc\x03/^~\x8f\x88\ +\x02d,8\x03\x10B\xe8\xab\x03\xc4m9\x9b\xc7,\x16\x0b.//y\xfe\xfc9\xe7\xe7\xe7\ +\x00x\xefi\x9af<\xbd\xf78\xe7\xba\x12\x17\x01\xa5\xd1\xda\xd2\x06\xc1\xf7U\ +\xad\xb4\x90\xa4\x8as\x1b\x91\xc4\t\x7f\xfd\xf5\x96\xdf\x7f\xfb\x89\xa7_<\ +\xef\xab\xf1 5\xf4%\xea}C\xa4=\x0f\x1f~\xcab\xb1\xe0\xd9\xb3g\x9c\x9f\x9f\ +\x8f~\xe2\x9cc\xb5Z\xb1^\xaf)\xcb\x92\xddn\x87s\x0e\x11Ai\x83\x11\x85W\x1aD!\ +\xa2q\xad\x06\xafQ*"\x8ecb\x1bc\x8c\xe1\xee\xe6-\x0f\x1e=\xe1\xe4\xe4\x8cpX5\ +@\xe7\x13\xaebv2g>\x9fsqq\xc1b\xb1`\x88\x98s\x8e,\xcbX.\x97\x94e\xc9~\xbfGD\ +\xba\xea\x12\x85\xd6\n%\x1e/\n\x11\x85R\x06\xa5\x14\xce\x19\x08\r\xda\x06\ +\xe2\xd8\xa2\xb5\x02nYfW\xa4\xe9\x0c\xef\xc31\x08\xa1EB\xcbt:e6\x9b1\x9f\xcf\ +QJ\x8d\xe1\xcf\xb2\x8c\xbb\xbb;\x8a\xa2\xc0{\x8fR\x8a\x10\x02J\xa9>\xdf\x01\ +\x94F\x89\x80(\x94r(\xa5Q\xae!\xf8\x88\xa0\x1c\x91\x8d\x89\xadA\x08dwK\xeaz\ +\x8b1\xf1\x01H\x00\xe7j\x12kI\x92\x844M\x89\xa2h\xd4\xc2j\xb5b\xb9\\R\x14\ +\x05!\x84\xd1)E\xa4\x07\x11B\xef\x99"\x1a\x91@P\xaak\x13J\x13B\x8b\xe0\x10\r\ +\x13k\xd1\nv\xbb\x8aj\xbbb:{t\x1c\x11\xdf\xd6h=\xc1Z\x8b1\x86\xb6m\xd9n\xb74\ +M3j\xc2{\x7f\x04q\xd8=\xba\x82\xebZ\x82\x88\xa0\x10\x94\x0ehm\xf0\xdet0:\xa0\ +#8\x89`^\x95l\xca\xdd\xb1F\x02\x01\xd7\xd6h\xadG\xc7\xdc\xedv\xac\xd7k\x9a\ +\xa6\x195\xa1\x94:\x82\x18\x9bb\xdf\n\x90\xc1\xbc\xfb\xf4\x00A\x81\x04\r\xc1\ +\x80vh#L"\xcdl6\xa3\xa82|\xf8@\xacm[\x8f%\xda\xb6-UU\xe1\x9c\x1b\xa1\x86E\ +\xff\x06q\x1f\x94!.\x88(d\xd0\x8e\x80\x0e\x10\x82C+\x8d\x8a\x14q\x121=9!\xca\ +\xee\xc6{\x8c\xe5\xdbu\xd1\x96\xfd~\xcfn\xb7\xa3(\x8a\xce\xac\x9c\xc39\xd7;\ +\xae\x1a\xa3r\x04qx\x88\xf4\x10\xbd~\x94\xee\x970h\xe51F\xb06\xe0\x92\x84$\ +\xb1\xb4G Ah\xdbN\x98u]SU\x15UU\x8d\x0b\x0e\x10\x1f_W\xf8\xf7\xb7_\x01\xf7\ +\xc2\xd5\xc6\xa0\xb5\xc1\x98\xee\x14Q\x10\xe7\xe4\xe4\x84\xc9dB\x1c\ +\xc7\xa3\xd1\r\x11[\xe6\x1b\x8a\xb2\xa1([Z\xdfG@\xee\xef;\x0eV\xc7\x1a\t\x04\ +\x1f\x08\xc1\x13\x82\xef\xc6\xfc\xe0\x19\xd4trrF\x9a\xce\xa8\xeb-\xd5v\xc5\ +\xaa\xd8\xb1\xde\xde\x10\xe9[\x92\xc4b#\xdb\x8f\x85\x06\xe7\x15\xad\x83\xc6\ +\xd1\xfb\xc4\x10\xe9!\xf6\xc7_\x0b\x1c9k\x08\xdd\xae\xdc\xfbn/*\xca\xa1\x9c"\ +\x08\x04\xef\x08\xde\xe3}\xc0\x98\x98\xe9\xecQ\xf7w\xf0\x84\x10hC\xe8\x1c\ +\xb2\r\xe3M\xefg\x95>\xe1}u\x88\x1c|\xc1\x11\xfa\xf7\xf9Q\x14\xff\x8c/j\xfe\ +\x0f\x14\xf5q\xf5\x0b9\xe5)\x00\x00\x00\x00IEND\xaeB`\x82' + +def get024Bitmap(): + return wxBitmapFromImage(get024Image()) + +def get024Image(): + stream = cStringIO.StringIO(get024Data()) + return wxImageFromStream(stream) + +index.append('024') +catalog['024'] = ImageClass() +catalog['024'].getData = get024Data +catalog['024'].getImage = get024Image +catalog['024'].getBitmap = get024Bitmap + + +#---------------------------------------------------------------------- +def get025Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +9IDATx\x9c\xcd\x98M\x8f\x1cG\x19\xc7\x7fU\xd5U\xfd2\xb3\xb3\x93\xf5\xee\x8e\ +\x1d\x92\xc5r\x0c\xc1\x8ae\x11|\x80C"q\xc8\x05E\x90\x0b\'\xee|\x02\xf8\x08|\ +\r\xce\x08q@\x1c@\x08\x11\t\x82\x02HH\x8e\x90,\xe7\xc58\tl\xb2\xde]\xf7zzfz\ +\xa6g\xa6\xbb\xaa8\xf4\xcb\xceX\xfe\x00\x19\xa9\xb6w\xb7{\xba~\xfd\xbc\xfd\ +\x9f\xa7\x05\xe0\xf9\n|\x02\x80;w\xdf\xc4\x98\x10\xad\r*\x08PR!\xa4B\x08\x81\ +\xf7\x9e-V\xdf\x1e\xfc\xe5?\xbc\xd88)x\xeeGl\xff\xea\x9b\x9f\xde{\xde\xfb\ +\xf3ok\x10cB\xa2(\xc1\x84Q\x07#[\x10x\xf0\x05N\x86D\x89\xe0\xc0h\xa20\xe2\ +\xc9\x93c>\x7ft\x9f\xeb\xaf\xdcn\xb2q\xc354)\xea\\\x89V\x8e+W^d4\x1aq\xe3\ +\xc6\r\x0e\x0e\x0e\xbazb\xade2\x990\x9dNY,\x16,\x97K\xac\xb5\x1dD\x0b\xa0\ +\xb5\xe6\xfe\'\x8f\x99\xce-\xc8\x08)5a\x18\x12\x9a\xfa\x9a\x8b\xb3c\xf6\xf6\ +\xaf\xd1\xef\xef\xe27\xb3\x06\xa8\xeb\x84-\x18\xf4\x87\x0c\x87C\x0e\x0f\x0f\ +\x19\x8dF\xb4\x16\xb3\xd6\x92\xa6)\xe3\xf1\x98\xc5b\xc1z\xbdF\x08\xd1\xc4\ +\x94\xec\x028\x08\x02\xb2\xd9\x92\x07\xff9C\x9b\x08k\x03\xf0%\xcax\xc2\xd0\ +\xa0\x94\x04\xce\x19\xa7\'$\xc9\x00\xe7\xfc6\x08\xbeB\xf8\x8a^\xaf\xc7`0`8\ +\x1c"\xa5\xec\xcc\x9f\xa6)\x17\x17\x17\xe4y\x8es\xae\x8e\x01\xef\x91Rv\xb7\ +\x90R\xb2.-\x7f|\xef\xa3&\xf3\x14\xd2\x96x\xa7\xf1\xd2\xa2MHh\x02\x04\x9e\ +\xf4b\xccj5\'\x08\xc2\r\x10\x0f\xd6\xae\x88\x8c!\x8a"\x92$Ak\xdd\xc5\xc2d2a<\ +\x1e\x93\xe79\xde\xfb\xaeR\n!:\x10\xe7\x1cB\x08\xfe\xf4\xb7\x0f)\x8a%*\xd0\ +\xb5LH\x85\xf7\x15\x02\x8bP\x10\x1b\x83\x92\xb0\\\x16\x14\xf3\t\xbd\xc1\xfe\ +\xb6E\\\xb5B\xa9\xb8K\xbd\xaa\xaa\x98\xcf\xe7\x94e\xd9\xc5D\xbb\xd9\xb3e\xbb\ +\xb5\xc6\xfdON\xf8\xec\xf8\x0c!%\x12\x81T\x1e\xa5\x02\x9c\x0bj\x18\xe5Q\x1a\ +\xfa\x1a\x86\xc5\x82\xd9b\xb9\x1d#\x1e\x8f\xadV(\xa5\xba\x8a\xb9\\.\x99N\xa7\ +\x94e\xd9\xc5D\xfb\xf4\x9b0m\xba\x9e\xa7S\xde}\xff\xc3\xba\x14 @H$\xe0%\x08\ +\xaf\xc0\x07\xa0,*\x10\xc4Z1\x18\x0c\xc8\x8b\x14\xe7\x9f\t\xd6\xaaZu&\xae\ +\xaa\x8a\xa2(\xb0\xd6vP\xed\xa6\xcf\x83\x00\xf8\xfd_\xeeS\x95\xebZE\x84DHY\ +\xd7\n\x01\xca\x83\xf7\x16%\x15RK\xc2H\xd3\xeb\xf7\xd1\xe9Ew\x8f.}k\x15\xadX\ +\xaf\xd7,\x97K\xf2<\'I\x12\xac\xb5]\x8aJ);\xablB\xbc\xfb\xfeG\\<\xcd.uD\xca.\ +~\x84T\xcd\x16\x01J:\x82@`\x8c\xc7F\x11Qd\xa8\xb6@\xbc\xa0\xaa\xcaNE\x8b\xa2\ +\xa0(\x8an\xc3\x16\xe2y\x1f!\x04\xc7\x8f\x9f6\x96h\x05\xad\x86\x91J5\xed\x84\ +\x04<\x81th-\xd1\xc6\xe3\xaa\x10\xa3\r\xa5mb\xacs\x8d\xf5[*:\x9f\xcf\xc9\xf3\ +\x9c\xd5j\x85\xb5\xb6\xdb\xb8\x95\xed\xcdX\xf9\xc9;\xdf\xe5\xb5o}\xbd\x81\ +\xa8\xdd"\xa5B\xca\x00\xa5\x82FP\x03\xb41\x98f)Ug\x14\xad$\xb4\xae\xf1\xc8\ +\xcb~b6\xeb\xc4l\xbd^w\xb1\xb2\xe9\x8eV\x9f\xa4\x94$q\xc8\x8f\xde\xfa6?~\xfb\ +{\x980F\x08\xd9(\xbaB\x05\x9a \xd0hm\x08\x8d&\x8e\rF\x07\x8d\xdb\x82gcD \x95\ +\xd9\x92\xf20\x0c\xbb\xe0\xd4Z\x13\x04\xc1V\x8cl\x82\xb4\x15\xf6\xb5o\xbe\ +\xc4\xd1\xd7\x0e\xf8\xf5\x1f\xee1\x1e\xcfP*hTX"\x04\xc4\x91$\x0e\x05\x81\xf2\ +8g\xb1\xee\xd2\xdd]\xd6h\x93\xd4\x9dU\x96\xd1\xeb\xf50\xc6\xd4\x17l\xe8\x87R\ +\xaaK\xf1\x16J6\xadC\xbb\x0e\xf7c~\xfe\xd3\x1f\xf0\xde\xbf\x1e\xf1\xd7\x7f~T\ +\xbbE)\xb4\x82$\x96\xc4\x11\xb8uAY\x96T\x96g-\x02Qo\x87\xec\xe2\x84,\xcb\x88\ +\xe3\xb8\xb3\x80\xd6\x1acLg\x95M\x99\xdf\x04h\xcfk\xad\x89\xa2\x88\x1f\xbe\ +\xf5\x1d^\xbf}\x93_\xfe\xe6\x1fx\xbb$\t\x05;\x89\xc4\x04\x15\xf3EI\x96\xe5]\ +\xa0n[D\x87$;{\x8c\xc7\xa7]0=\x0bb\x8c\xe9\xaak+t\xedj\xcf\xb7+\x8ecn}c\x87_\ +\xfc\xec\x1d~\xf5\xbb\xbfs~~J/\x12\xf8\xaa`Y,\x98\x17%\xce7M\xf1&\x08\xc0\ +\x0b{#\x9e\xa6\'\xa4i\xdamf\x8c\xa9%\xbc\xe9\xbc\xda\r\xdb8y\x1eD\xfb \xde{\ +\xa4\xf0\xbc\xfd\xfd[\xdc\xfb\xb7\xe0\xe4\xcb/\xc9\x97\x0b\x1e\x9f\xa6\xe4\ +\x8bj\xab\x0ct B\x08\x92\x9d]\x0e\xaf]\xe7\xd3\x8f?\xc0Z\xdbm\xd4\x02\xb4@a\ +\x18vi\xdc\x06\xaaR\xaa\xb3\x8e\x10\x02k-eY2\x9b\xcdH\xd3\x14-K$k&\x931\xe3\ +\xe9\x82\xca\xd5I"6;\xb4\xcd\xe1\xe7\xa5\xa3W\xc9\'\x19\'_i\xbbZ\xd7\xb5\xad\x82\xb5\x96\xd5j\xd5\xb5\x94\x8b\xc5\x82,\xcb8??\xe7\ +\xf4\xf4\x94\'O\xce\xf9\xec\x7fgL\xf3\xb2kM\xdb\x8a\xb0\xe5\x1a\x10\x08)\xb8\ +y\xebu\x8ae\xc1\xf9\xf9\xe3\x0e\xa2\xdd\xb8\xd5\x98v\xf3V\x9b\x8c1\x9d&Yk;\ +\xd1\x1c\x8f\xc7\xa4i\xca\xd9\xd9\x19\x9f<:\xe6"+\xea\xe9J\x88\xe7X\x84f\xe4\ +\x11\xf51N\xfa\xdc\xb9\xfb\x06\x0f\x1f\xdc\xe3\xf4\xf4\xb8\x1b\xa6\xdaN\xad\ +\xad\xc0\x83\xc1\xa0\x9bu\xda,k\xc1\x16\x8b\x05\xd3\xe9\x94,\xcb\xea\x91\xe2\ +\xbf\xa7\\d\x05\xce\x0b\x04mU\x16\xdd\xe0\x1a\xb4\x9e\xf1\xad\x8f\x1a\xda$\ +\xd9\xe1\xce\xdd7\xf9\xfc\xd1}.\xce\x8e\xf1\xfe\x04k-\xeb\xf5\x9a\xc5b\xc1l6\ +cgg\xa7\x1b#Z\x90\xcdk\xf2<\xe7\xcb\x93s\x9eN\x16L\xf3\xb2\x99g\x00\xd1(\xf3\ +\xb3\xc1\xea7\xacqy\xacu\xe3\xfa+\xb7\xd9\xdb\xbf\xc68=\xe1\xf4,\xedF\x89\ +\xe1pH\xbf\xdf\'\x8ec\xc20\xec\n]k\xb1q6#_\x94\xe4\x8b\x8a\xca\xb1-\x88B^6V\ +\xdb1\xe2\xf1\xce\xe3\xbd\xc3{W\xb7\xf9\xde\xd1FS\xbf\xbfK\x92\x0cX\xad\xe6\ +\x14\xf3\t\x93|\xc9t~\x86V\xe7D\x91\xc1h\xd3\xb4\x85\x01\xd6I*\x0b\xa5\xa5\ +\xa9\x13\xad\xa5[\xdbo\xbf\x16\xd8\xaa\xac\xde\xd7S\xb9s\xf5,*\xa4EZ\x89\x17\ +\xe0\x9d\xc5;\x87s\x9e \x08\xe9\r\xf6\xeb\xbf}-\x82\x95\xf7u\x85\xac.\x87\ +\xabKql\x1c\xded\x87\x10\x1b/8|s\x9d\xeb\x82\xe2\xab\xf1\xa2\xe6\xff\x11%\ +\x81E\xc4\xf0\x00\x1c\x00\x00\x00\x00IEND\xaeB`\x82' + +def get025Bitmap(): + return wxBitmapFromImage(get025Image()) + +def get025Image(): + stream = cStringIO.StringIO(get025Data()) + return wxImageFromStream(stream) + +index.append('025') +catalog['025'] = ImageClass() +catalog['025'].getData = get025Data +catalog['025'].getImage = get025Image +catalog['025'].getBitmap = get025Bitmap + + +#---------------------------------------------------------------------- +def get026Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xdaIDATx\x9c\xcd\x98Ks\xdb\xd6\x19\x86\x9fs\x03@\x90\xa2\x18[\x12\xed4\xd6\ +\xb8vf\xd2LE\x08\t\x88.\xe14\xd0<\x80\x00\x01\x84[s8I\x99N\xa7\x9c\ +\x9e\x9e\xf2\xe8\xd1#\x8e\x8f\x8f\xbb\xc5\xea\xba\xeeN\xef=\xce9B\x08(\xa5H\ +\xd3\x14!\x04Zk\x8c1\x18c:u\xd24%\xcb2\xce\xcf_\xf2\xe2\x9b/\xb9\xff\xf0Q\ +\x9b\x8d\xbd\xd0\xd0\xa6\xa8\xf75Fyn\xdf~\x97\xe9t\xca\x83\x07\x0f8>>\xee\ +\xea\x89s\x8e\xe5r\xc9j\xb5b\xb3\xd9PU\x15\xce\xb9\x0e\xe2m\x80$I\xbaPE\x93+\ +\xa5\xb8|\xf3\x92[Gw\x19\x8d\x0e\t\xfd\xac\x01\x9a:\xe1J\xc6\xa3\t\x93\xc9\ +\x84\x93\x93\x13\xa6\xd3)Q1\xe7\x1c\xb3\xd9\x8c\xf9|\xcef\xb3a\xb7\xdb!\x84h\ +=%;\x03\xf7a\x8c1\xa4i\xda\x81\xc5\x94\x0f\xe1\x8c\xf9\xec\x8c<\x1f\xe3}\xd8\ +\x07!XD\xb0\x0c\x87C\xc6\xe31\x93\xc9\x04)e\'\xffl6\xe3\xf2\xf2\x92\xa2(\xf0\ +\xde#\xa5$\x84\x80\x94\xb2{D\xf4\x84R\n\xad\xf5\x8fT\x89\xefq\xceq\xfef\xc6v\ +\xbbF\xeb\xb4\x07\x12\xc0\xb9-Y+a\x9e\xe7\x18c:/,\x97K\xe6\xf39EQ\x10B\xe8*e\ +4a\xf4O|\xad\x94"\x84\x80\xf7\xbeS\xa5\x9fA\xbb\xdd\x8e\xf5zM\xb9^2\x1c\x1f\ +\xed+\xe2\xed\x16\xa5\x06\x9d\xb9\xac\xb5\xac\xd7k\xea\xba\xee<\x11\x17{\xbb\ +lG5\xe2\xd1\xbf\'*\xa2\x94b\xbe\\S\xd5\x12\x93\xe6\x1c\x1eN\xb8\xdeT\xfb\x1e\ +\t\x04\x9c\xddv\xd4\xde{\xaa\xaab\xb5ZQ\xd7u\xe7\x89\xb8X\x7f\xa1\x98\xae\ +\xfd2\xd0O\xdd\xef^]\xf2\xd5\xb33\xfe\xf5\xec?l\xab\x15\x87\x03\xc1 \xcb\x19\ +\x8f\xc7\x14\xe5\x0c\x1f\xde2\xab\xb5\xdbNbk-eY\xe2\x9c\xeb\xa0\xe2\xa2\xff\ +\x0fB\x08\xc1\xd3\x17?\xf0\xec\xbb\x1f\xf8\xf7\xf3\x0b\xeaz\xdb&\xa5C\xab\ +\x04i$if\x18\x8eF\x98\xd9e\xf7\x8c.}\x9b.j\xd9\xedvTUEQ\x14\xe4y\x8es\xaeK\ +\xd1\xf8)c&\xf5!\x9e\xbe\xb8h\xce\xe7\x178g[e\x14J\x99v\t\x8d\x92\x1e\xad\ +\x05I\x12pYF\x96%\xd8=\x90 \xb0\xb6\xee\xbahY\x96\x94e\xd9-\x18!~\xea\x10B\ +\xf0\xfb?|\x86\xadwmun\x00\x84\x94H\xa5\xdaqB\x02\x01-=\xc6HL\x12\xf06%1\t\ +\xb5k=\xd6\x85\xc6\x85\xbd.\xba^\xaf)\x8a\x82\xedv\x8bs\xae[8\xb6\xed\xbeW\ +\x0e\xc7y\x07!\x84l \xa4BJ\x8dR\xbam\xa8\x1a\xd3\xa6s\xac)B*\x88-!\x86& o\ +\xe6\x89\xeb\xeb\xae\x99\xedv\xbb\xce+\xff\xcb\x98\xbf\xfe\xf0\xde\x1e\x84\ +\x10\xb2\xed\xe8\n\xa5\rZ\x1b\x8cIH\x13\xc3`\x90\x90\x18\xdd\xf4 \xa9ozS\xfb\ +X\xa4J\xf6Z\xf9j\xb5\xa2(\nv\xbb\x1du]c\xad\xfd\x91\x1a\x11\xe4W\x0f\xef\xde\ +(!\xda\x8cQ\n\xa5Z%\x8cF\x1b\xcd K\x19\xa4\x06\xad$\xde;\x9c\xbf\tw\x975&\ +\xc9\x9b\xc9j\xb1`8\x1c\x92$IsC\xafd+\xa5\xba\x14\xef\xa7\xe8\xd1\xad1\xd3\ +\x93#fW\xcb\xb6\xdc\x1b\x94N\xda\xabF+\x85Q\x90\x0f$\x83\x0c\xfc\xael>\x9c\ +\xe3mE \x1b\x1e\xb0\xab\x03\x8b\xc5\x82\xab\xab+\xae\xae\xae:U\xaa\xaa\xeaB\ +\xd4o\xf3\xb1\x94k\xad\xf9\xed\xe3_\xa2\x95\xee \x8c1h\x13\x07-M>0\x1c\xe4\ +\x86D\x0b\x9c\xadY,\x8a\xce\xa8\xfb\x8a\x98\x94\xfc\xe0\x16\xf3\xf9yg&)e\xd7\ +\xb0\xe2\xb5_\xca#\x84\xd6\x9a\xdf|t\x9f\xbf\xfc\xe3\xeb6\x1c\r\x84\xd6\n\ +\xa3\x15\xa9\x11\x8cr\xc90\x13\x04[R\x95\x1b\xd6e\x8d\x0f\xedP\xdc\x07\x01x\ +\xe7\xd6\x94\xab\xd9\x19\xb3\xd9\xac[,\x96\xe8\xd8\xb8"P\xf4I\x0c\xdd\xc9p\ +\xc8\xbbw\xefpy\xb5\xbc\xc9\x12\xadH\x8cd4\x90\x8c\x07\x12#k\x8aj\xc3\xeb\ +\xf3\x19\xc5\xc6\xee\x95\x81\x0eD\x08A~p\xc8\xc9\xdd\xfb|\xfb\xf5\x178\xe7\ +\xba\x85"@\x04J\xd3\xb43n\x1c\x05\x94R\xfc\xee\xe3\x87\xfc\xe9\xaf\xffD+\x85\ +V\xa2Qb 9\x1c*Rc\xd9\x95k\x96\xcb9\xf3\xd5\x06\xeb\x9b$\x11\xfd\t\xad\xbf\ +\xf9y\xef\xf4\x03\x8a\xe5\x82\xb3WO\x91Rv\x93U?\xff\xe3\x19C\x17G\x85\x8f\ +\xde\x9f\xf2\xe7\xbf\xd1\x183m\xc21\x1eH2\xe3\xa8wk\x96\x8b+\x9e\x7f\xff\x86\ +UQw\xa3i\xac\x08{\xa1\x01\x81\x90\x82\xf7?\xfc\x98\xb2*\xb9\xb8x\xbd7Y\xc5\ +\xf93\xb6\xf8X_\xac\xb5\xdd=\xef\xdd\x99\xb0\xdb\x96\x1c\xe4\x92<\x83D\xd6l\ +\xcb\x06\xe2\xd9\xf3W\\.\xcafw%\xc4O(B\xbb\xe5\x11\xcdu\x90\x8fx\xfc\xe4\x13\ +\x9e~\xf59\xe7\xe7/{\x93U3\xd4\xc4\n<\x1e\x8f\xbb\xbd\x8e\xd6M\x91\xfa\xc5m\ +\xc3rU\x91hK\xb0\x8d\'\x96\xcb9\xcf\xbf\x7f\xc3\xe5\xa2\xc4\x07\x81 Ve\xd1m\ +\\u\x8cL\x881ji\xf3\xfc\x80\xc7O>\xe5\xc57_r\xf9\xe6%!\x9cuC\xcdf\xb3\xe1\ +\xfa\xfa\x9a\x83\x83\x83n\x1b\x11AB]\xe3v\xd7\x14\x9b\x9a\xaal\x8c9_mX\x15u\ +\xbb\x9f\x01\x84l\xfb\xcf[f\r=5n\xaeM\xc9\xbe\xff\xf0\x11\xb7\x8e\xee2\x9f\ +\x9dq\xfef\xd6m%&\x93\t\xa3\xd1\x88\xc1`\xf0\xa3\t\xac\xaa*\xe6\x8b\x82uYSl,\ +\xd6\xd3\xebEm+\x881\xd9\xf7H \xf8@\x08\x9e\x10|3\xe6\x07Ot\xd3htH\x9e\x8f\ +\xd9n\x9b\xf1nYT\xac\xd6o0\xea\x82,KHL\xd2|{ 5\xceK\xac\x83\xda\xd1\xd6\x89\ +\xa8t\xd4~\xffk\x81\xbdy$\x84fW\xee}\xb3\x17\x15\xd2!\x9d$\x08\x08\xde\x11\ +\xbc\xc7\xfb\x80\xd6)\xc3\xf1Q\xf3:4M\xd0\x86\xd0TH{\xb3\xb9\xbai\x8em\xc0\ +\xdb\xec\x10\xa2\xf7\x05Gh\xef\xf3\x9d)~\x1e_\xd4\xfc\x17K\x9fQTS\xbe,\xc2\ +\x00\x00\x00\x00IEND\xaeB`\x82' + +def get026Bitmap(): + return wxBitmapFromImage(get026Image()) + +def get026Image(): + stream = cStringIO.StringIO(get026Data()) + return wxImageFromStream(stream) + +index.append('026') +catalog['026'] = ImageClass() +catalog['026'].getData = get026Data +catalog['026'].getImage = get026Image +catalog['026'].getBitmap = get026Bitmap + + +#---------------------------------------------------------------------- +def get027Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xe0IDATx\x9c\xcd\x98\xdbo\xdbF\x1a\xc5\x7fs%)\xc9\x96j\xc4\xb1\xddm\xe3\xa4\ +I\xd1v\x91\rP\xe4\xb5\xfd\x9b\xf7}\xb1\x0f\xc5\xeeC\x81}h\xb1@\xd0m\x90\xb6\ +\xe96\xae/\x89l\xc92)^gf\x1f(\xd2\x94[`_K\x80\xa6,\x91\x9c\xc3\xf3\x9ds\xe6\ +\x1b\n \xf0\x07\xd84\xc0\xb3\xe7_bm\x841\x16\xa55J*\x84T\x08!\x08!\xb0\x855t\ +\x87p\xfbE\x10\x83\x1f\x05\xbf\xbb\x89\xed\x8fa\xf37\x84\xc0?\xfe\xfe\xd7\ +\x16\x88\xb5\x11q<\xc2Fq\x0fFv@\x08\x10\x02\xc1\x03\xa1\xc1\xb9\x12\xdf\x94\ +\xb8\xa6\xa4iJ|\xd3\xd045\x8d\x0b\x04$RY\x8c\x1d\x11\x8fw0&j\x07\x16b\x00B\ +\xb4p\x05\x04\x1f\xf0\xc1\xdd2b\x8c\xc5F1q\x9c`\xa2\x18\xad-J\xca\x0e:\xde\ +\xd7\xe0rDh\x88\xadE\xa9\x04\xa5\x14\x00M\xd3P\xd75eY\xb2^\xaf\xc9\xb2\x8c\ +\x9b\xd5\x19\xcb\xcbSF;{\xbc\xb7w\xc0hgz\x0bCtp\x04!x\xbc\xf7\xb7@\x94\xd6\ +\x18c1Q\x8c\xb5\x1bV\x94j/p\x19Fyv\'3\xc6\xe31q\x1cc\x8cAJ\x89s\x8e\xaa\xaa\ +\xa8\xaa\xea\x16\xc4\xcd\r\xd7\xd7\xd7,\x97K\x16\x8bs\xae\xe6\xa7\xdc?z\xc8\ +\x07\x0f>A\xc8\x16\x00\xa2\x05\x14\x82\xc75\x03F\x94T(\xad\xd1\xda\xb6\x80\ +\x8cEJ\x81\x119\xd3Y\xc4\xde\xde\x11\xb3\xd9\x8c\xe9tJ\x92\xb4l\x84\x10\xa8\ +\xeb\x9a\xa2(\xc8\xf3\x9c,\xcbH\xd3\x94\xeb\xebk&\x93\tI\x92`\xade>\x9f\xf3\ +\xd3\xcboI\xaf\x97<\xf9\xecs\x92\xd1\xa4\x05\x82\x80\x10\x10r\x00DH\x85\x94\ +\n%%J)\xa4\x14\xc4\xba\xe4\xf0\xde.\x07\x07\x07\xfd>\x9dN1\xc6\xf4\x00:\x16\ +\xf2<\'I\x12\xe28&\x8a"\xac\xb5h\xad\x91R"\x84\xc09\xc7\xe9\xc9+\xf2"\xe7\ +\xd9\xf3/\x18\x8dv6F\xf0H\'\x07@\x84h\x05\xb5\xa9\x9f\x119\x87\xf7v\xf9\xf0\ +\xc3\x0fy\xf0\xe0\x01\x1f}\xf4\x11\x87\x87\x87\x08!\xa8\xaa\x8a4MY\xadV8\xe7\ +\xf0\xde\x13B\xc09G\x08a\xe32\x90R"7\x0f&\x84@J\xc9\xdb\xb7g\xbc\xfa\xee\x1b\ +\x9e=\xff\x12!$ z\xc3i\xa0\xbd\x01\x01\x02\x08\x971\x9dE\x1c\x1c\x1cp||\xcc\ +\xd3\xa7O\xd9\xdf\xdf\x07\xa0\xaekB\x08TUE]\xd78\xe7z\x00Zk\xa2(B\x08\x81\ +\xd6\x1acL\xbfw\xbf\xc5q\xcc\xf9\xf9\x1b~\xfe\xf1\x05\x0f\x1f?\xdd\xb8qP\x1a\ +6\x16\xf5\xbe\xc6(\xcf\xde\xde\x11\x07\x07\x07g\xb1X\x90\xe79UU!\x84\xd8hJ\xa2\xb5\ +\xeeA\r\xd9\x88\xa2\xa8\x07\xd6Y>\x84S\x16\xf3SF\xa3]\xbc\x0f\xdb@\x08\r"4\ +\x8c\xc7c\xa6\xd3)\xd3\xe9\x14!\x04u]\xd34\r\xf3\xf9\x9c\xcb\xcbK\xb2,\xc3{\ +\x8f\x94\xb2\xd7C\x17X\x9d\x16\x94Rh\xad{V\xba\xbd\xbb\xc69\xc7\xf9\xc5\x9c\ +\xb2\xcc\xd0:\x1a\x00\t\xe0\\Il-q\x1c\x93$\t\xc6\x18\xaa\xaa"\x84\xb0\xc9\ +\x84\x05Y\x96\x11B\xf8\xcd\xc0\x00\xde\xfb\xfe{)%\xc6\x18\xbc\xf7=+\x9dh;v\ +\xb3,#\xcf\xae\x19\xef\xde\xdbf\xc47%J\xb5\x00\x94R\xd4uM\x9a\xa6TU\xd5kb8\ +\xd80\xb6\xbb\xc1\xbbmx\xce\xb0,!\x84>\x81W\xab\x15\xd7i\xb1\xad\x91@\xc05e_\ +\xef\x10\x02EQ\xb0Z\xad\xa8\xeb\xba\xd7D7\xd8p\xa0\xae<\xc3\x18\xe8\xac;d\ +\xab\xd3PQ\x14\xa4i\xcal6c\x95]\xe0\xc3\x1d\xb16M\xd9\x0b\xb3\xaek\xd6\xebuo\ +\xcf\xa2(\xfaA\xff\x1f\x88\xbb:\xe9\xceWJ\xe1\x9c#\xcfsV\xab\x15\x93\xc9\x04\ +\xa3\xde\xf6\xf7\xe8\xed\xdb\xce\xa2\rUUQ\x14E/\xca.\xb4:\xc5wOy\x17\xc4P3C \ +\x1d\x98N3\xa3\xd1\x88$I6Ili\xb6\x80\x04A\xd3\xd4\xd4uMUU\xe4yN\x9e\xe7}R\ +\x0e\xe3\xfa\xee6_d\xfc\xeb\xdf\xafyr|\x9f\xc7\xc7\xf7Ib\x85R\xaa\x07\xd2i\ +\xae{\xa8$I\xfal\xb1\xc6R\xb7y6(\x8dk\x85\xd4M`I\x92\xe0\x9c\xdb\n\xab\xae\ +\xdeC\xad|\xff\xc3\x19oN\xdeq\xf2\xeb\x9c\xaf\xbe\xfe\x0f\x0f\x8f\x8f\xf8\ +\xf4\xf1\xfb|\xf6\xe4}\xc6\x83du\xce\xf5sP\x07NH\x05\xcd\x9d\xd2\x04$\xeb\ +\xf5\x9a4MI\xd3\x948\x8e\t!\x10EQ/\xb4~N\x1ah\xe2\xf4\xddj3O\t\x84\x90\xfcr\ +\xf2\x8e\x93\xb3+\xbe\xfa\xfa{>\xf9\xf8\x98\xbf|\xfa\x80?\x7f\xfc\'\xa2(\xa2\ +,\xcb\x9eY!\x04B\xea\xbb\x1a\x11He\xb7\xfa\x89(\x8azqvOu\xd7\xa2iV\xb2X\xac6\ +7\x96\x88\x81[\xa4R\xfc\xfc\xe6-\'g\x0b\xfe\xf6\xcf\x17|\xfc\xe8\x88\xf7\xf7\ +G$\xa6\xee\xcb\xe4\xfc\xed\xfd\xfa\xd2\x18;\xe2fu\xd6\xf7\x13\xd6\xda\xf6\ +\x84Adw\xf6\xeeD\xf9\xfa\xe4\x12\xb9\t*!%B\xc8M\xdc\x1b\xb4\xb6\xedqs\xdd\ +\xc9\xe9;\x96W\x82\x9d$\xe0\xca\x1b\xca\xb2\xa4q\xdce\x04\xe2\xf1\x0e\xcb\ +\xcbS\x96\xcb%I\x92\xf4\x0ct\x81\xd4\xb1b\x8c\xe9\xdd\xf3\xfdO\x17=\x88\xb6\ +\x9fQH\xa56\r\x96A[\x8b\xd1\x1a\xad$\xb1\x81Q\x02ZU\x14U\xc9\xd5\xe2\xa6\x17\ +\xea6#&b\xb4\xb3\xc7bq\xde\xcf\x0bw\x81Xk{\xad\xa4\xeb\x92\xc52En\x06WR\xa3\ +\xb4B)\xdd2\xd1\tSk\x8c\x86Q,Hl\xc0U\x15y\xbe&\xcbk|\xd84\xc5C \x00\xef\xed\ +\x1dp5?e>\x9f\xf73k7Wt\x9dWW\xa6\x1f\xff\xfb\x0e\x04=\x13\xade[\xd6\xb41\x1b\ +\x00\x1a\xa3%\xe3\x18\xc6\xb1@\x8b\x92u\xb1\xe6\xec|N\xban\xb6b\xa0\x07"\x84\ +`\xb43\xe5\xfe\xd1C~z\xf9-\xce\xb9\xde\xb6\xc3\xa9\xbc\x03\xf4\xe2\xe5\xaf\ +\x88\xd0]+\x11\xaa\r\xb1\x96\x15\x85V\x12\xa3a\x1c\xc3$\x91XYS\xacS\xae\x97\ +\x0b\x16\xab5\x8doM"\x86\x1d\xdap\xf1\xf3\xc1\x83OH\xaf\x97\x9c\x9e\xbcBJ\ +\xb9\xd5\xd4t\x93\xd7\xba\xa8\x99_^a\x8c!\xa0A\xb4\xcb%!@\n0*\xb4\x9a\x88\ +\x05\xe3X`eMU\xa4,\x17W\xbc\xfe\xe5\x82UZ\xf7\xadi\x17\xd0[\xa5\x01\x81\x90\ +\x82\'\x9f}N^\xe4\xbc}{\xb6\xd5Yu\x8eY\xdc4h\xe9\x90B\xa1h\x8fZ\x06\xac\xf2D\ +\xb6-\xc3(\x81\xc4\x06\xb4()\xd6)\xcb\xe5\x15?\xbc>\xe1r\x99\xb7\x88\x85\xf8\ +\x1dF\xd8,yD{LF\x13\x9e=\xff\x82W\xdf}\xc3\xf9\xf9\x9bAg\xd565\x8b\xb4a\x1c)\ +\xb4\x05\xad\xc1\x18\x88"A\x1c\t\xe2\x08\xe2(`T\x85\xab*\xd6\xc5\x9a\xeb\xe5\ +\x82\xd7\xbf\\p\xb9\xcc\xf1Al\xd8k\x81t3\x96\xee*\x13\xba\x1am\xd0\x8eF;<{\ +\xfe%?\xff\xf8\x82\xcb\x8b7\x84p\xda75&\x1a\x91\x8c\xc6$Fc\xac\xc3Z\x8f\xb5\ +\x0ec@\xe1\xa8\x0bGQ\xb7\xee8;\x9f\xb3X\xadY\xa5\xf5f=\x03\x08\xb9\xe9\xe2\ +\xef\x885\x0c\xd8\xb8=\xb6i\xf9\xf0\xf1S\xf6\xee\x1d\xb1\x98\x9fr~1\'\xcb2\ +\xa6\xb3\x19\xbb;\xbb\xd4\x93\tI\x9c\xd0D\x96Ji\x84\x14x\xefi\xea\x8a\xc52%\ +\xcbk\xd2uC\xe3\x19L\x03\x9b\x14\xeej\xb2\xad\x91@\xf0\x81\x10\xa0u\xc4x\xf7^\xfb\x7fh\ +\x17VM\x08mB6\xb7\x8b\xab\xdb^\xa5k\xae[w\x081x\xc1\x116\xe7\xf9^\x14\x7f\ +\x8c\x175\xff\x03\x89\xa8;\xfaX\x82\xde\xe7\x00\x00\x00\x00IEND\xaeB`\x82' + +def get027Bitmap(): + return wxBitmapFromImage(get027Image()) + +def get027Image(): + stream = cStringIO.StringIO(get027Data()) + return wxImageFromStream(stream) + +index.append('027') +catalog['027'] = ImageClass() +catalog['027'].getData = get027Data +catalog['027'].getImage = get027Image +catalog['027'].getBitmap = get027Bitmap + + +#---------------------------------------------------------------------- +def get028Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +\x83IDATx\x9c\xcd\x98[o[\xc7\x15\x85\xbf\xb9\x9eCJ\xd4\xc5\x8e-_b91\x12\x04)\ +\x92\x18\x81_\xd3\x00}\xec\xaf\xed\x1f\xe8S\x1e[8E\xd145\x9c\x18\xf1U\xb1E\ +\x91\xe2\xf5\xdcgv\x1f\xe6\x90\x92\x9c\xfc\x80\x1c\xe0h(\x92\x18.\xee\xbd\ +\xf6Zk\xa8\x00\xe1\x0fpY\x80\xaf\x1e\xfd\x19\xef3\x9c\xf3\x18k1\xda\xa0\xb4A\ +)\x85\x88p\x05\xabl\x16\xb9xB\xd4\xa5\x17\x15\xbf{\xa9\xab\x0f\xa5\xff+"|\ +\xf7\xf7\xbf% \xdeg\xe4\xf9\x10\x9f\xe5[0z\x03\x04\x01\x11$\x82HG\xd7\x96\ +\x84\xae\xa6kk\xba\xa6\xa6\x0b-\xa1k\tA@[\x8cu\xf8l\x87\xc1p\x0f\xe7\xb3\xf4\ +\xc1J]\x02\xa1\x12\\\x05\x12\x85(\xe1\xa2"\xcey|\x96\x93\xe7\x03\\\x96c\xad\ +\xc7h\xbd\x81N\xec\x1aB[\x10\xbb\x92\xdd]\x8b1\x19J)\x14\x8a.\x04\xda\xb6\ +\xa5\xae+\xaa\xb2\xa2(V,\xa6\'L\xc7o\xd8\xdd\xbb\xce\xe1\xf5[\xec\x8c\xf6/`\ +\xa8\r\x1c\x85H$\xc6x\x01\xc4X\x8bs\x1e\x97\xe5x\xdfW\xc5\x18@\x11\xda%\x8a\ +\x86\xd1\xc1\x88\xe1\xf0\x88,\xcb\xf1\xde\x02\x8a\x18\x03M\xd3\xd245UUR\xacK\ +V\xab\x15\x8b\xe5\x82\xc5b\xc6\xf9\xf4W&\xe3\x13\x8e\xee|\xcc\xbd\xfb\x9f\ +\xa1t\x02\x80J\x80D"\xa1\xbbT\x11\xa3\r\xc6Z\xac\xf5\t\x90\xf3(\x05*\xae\xd9\ +\x1fY\x0e\x0f\xef\xb3\x7f\xb0\xcf\xde\xee\x88\xe1\xce\x00\xad\r1\x06\xda\xa6\ +\xa5ik\xca\xa2\xa2(\xd6[\x10\xc3\xf9\x90<\xcf\xb0\xd61\x9dLy\xf6\xe4{V\x8b\ +\x19\x9f~\xfe5\x83\xe1n\x02\x82\x02\x11\x94\xbe\x04Di\x83\xd6\x06\xa35\xc6\ +\x18\x94\x02K\xc9\xb5\xc3\x1d\x8e\x8enrtt\xc4\xcd\x1b7\xd8?8\xc0YK\xd36\x94e\ +IY\x14\x14eA9(\xc9\x079y\x9e\x93\xe5\x19\xde{\x9c\xb3\xfd^\x9a\x10\x03o^>\ +\xa5\xaaJ\xbez\xf4\r\xc3\xe1\xa8\x1f\x84\x88\x0e\xfa\x12\x10\xa5\x12\xa16\ +\xfd\x8bk\xae\x1d\xeep\xef\xde\x87\x1c\x1f\x1f\xf3\xe0\xc1\x03\xee\xde\xb9\r\ +@Q\x96,\x16\x0b\x00B\x08\xc4\x18{\xd2\xc5\x9e\x86\xa0U\xfaB\xc6\x18\xb4\xd6h\ +\xad\xd0Jqvv\xc2\xd3\x1f\x1f\xf3\xf0\xd1\xb7(\xa5\x01\xb5\x1d8\x0b "\xfdt@h\ +\x97\xec\x8f,GG79>>\xe6\xcb/\xbe\xe4\xf8\xf8.!\n\xcb\xe5\x92\xb6i\xa8\xab\ +\x8a\xa6\xae\xe9\xba\x96.t\x88\x08\xd6X|\x96\xa1\x94\xc6:\x8bs\x16\xe7\x1c\ +\xce\xbam\xbb\xb3\xdc9\xbc\xf38\xef\ +\xf1\xde\xe33O\x96\xa5\xc7\xc6\x18\xc6\xef^p\xed\xc6mvw\xf7\x91\xcbS\x03 \ +\x11B[0:\x18\xb1\x7f\xb0\xcf\x8d\x1b7\xb8{\xe76!\nE\xb1f\xb9\\19\x9b0\x9b\ +\xcd\xa8\xaa\x8a.t(\xad0\x18\xb4\x160\x86(\x11c,\xd6Z\xacKk\xe2\x8b\xc7;\x8f\ +\xd6i\x12\xe5m\x1a\xef\xe1p\x8f\x18\xe5= \xd2\x11\xbb\x92\xe1\xf0\x88\xbd\ +\xdd\x11\x07\x07\x07\x00,\x97K\x8ab\xcd\xe4l\xc2\xf9\xec\x9c\xb2\xac\x12\xc9\ +\x94N\xed\xd4\xa0$\xf1K\xa1\xd1J\x13\x8c\xc1\x9a\xbe5\xbe\xaf\x8es\xa04"B\ +\x08\x1d\xe3\xb3s\xaaj\x8ds\xd9% \x02]\x9b\xc4*\xcbr\x86;\x03\x9c\xb5\x14eI\ +\xdb4\xccf3f\xb3\x19eY\xa5\x91\xeb\xf5Z\xa1PZ\xf7\x15\x8d\xe9Yc\xd0F#\xd6b\ +\xa3\xc3\xda\x04$\xe9R"x]7\x94EA\xb9\x9ac\x0e>\xb8Z\x91\xd0\xd5\x18\x93\xe1}\ +\x92\xf7\xa6mX,\x16\xd4U\xc5b\xb9\xa0\xaaR%6 \xb8"\xdbl\x01m\xa6p\xf3\x1e\ +\xef\x1d\x9d\xf7hc\x88"4uCQ\x14\xac\x96K\xd6uq\x95#\x82\xd0\xb5u\xbfAR\xcc\ +\xb2,\x01h\xea\x9a\xb2L\x9c\xd0J_\x01\xf1\x1b{\xebe \x8d\xabF\xf76\xe1\\\xc4\ +\x1a\x83D\xa1\xaa*\x96\xeb5\xfb\x07\xfb\xac\xdf\x9e\x11\xe5=\xb2vM\x8d\xeaA\ +\xb4mKY\x14\x84\xd0\xd1u\x1dM\xdd\xa0t2\xc0\x8b\xb6\xfc\x1e\x08\xfa[\xa3\x8d\ +\xc6\x1a\xbb\xad\x941\x96\x10"\xa3r\xc4hg\xc9\xce\xce.F\x9f\xf5\xee~i|\xbb\ +\xd0\xd2\x85\x0b\xef(\xca\x82\x18\xe3V\'\x0c&\x11\xf3R\x0b\xae\xf4\xa6o\xc9\ +\xa6\x12\xc96\x0c\xd6:\x94R8\xe7\x8812\x1c\x0e{\x15\x1e\x90y\x07W\x80\x88"t-\ +m\x9b@\x94EE9(\x91([\x9d\xd0Z\xd2t\xbcW\x8d\x9f_\x8c\x19\x0e\x1cwo]K\xe4U\n\ +\xa35\xda\x98\xed(\x1bc\x10\x11b\x08\xc9\x06\xb2\xde\x06\xbc#\xf4\xfb\\\x905\ +H\xb2\xf2\xaa\xa4(\xd6\xe4\x83\x9c(1\x95W)0\x06T?\x1dZ\xd3v\x81\x7f\xfd\xf8\ +\x8a\xd9|\x85\xb1\x8e\x0f\xae\xed1\x1c\xf8$\xe9\xc6`\xad\xc5\xd94\xc2\xd6Z$F\ +:\xef{suX\x9b\xfc-\xf4\x15\xd1\x9b\xd6\xa0m\xca\x13\xbd\x95\x17\xeb5UY\xd2\ +\xb4\r!\x06\xa2\xc4m&{7Y\xf0\xdd?~b>_%\xf3\n\x81\xef\xff\xfb2\xb5\xc3\x18\ +\x8c\xd1Xc.\x94\xd5oT\xd5&\xa0\xfdPh\xed\xde\xe7\x88\xc2XGQ\xac\xb6V\xee\xb3\ +M\xba\xd28\xe7\xd2&J\xf3\xe4\xf9)\xaf\xdeN\xb7F\xb9\xb9\xd7E\xc5\xff\x9e\xbd\ +\xe3\xe1\x9f\xeea\x8d\xc5\xf6R\x9f\xfc\xc6\xd2v]\xcaYQ\x881\x12BG\xc4l[\xbcm\ +\x8d\xcfvXLO\xb6y\xc2\xfb\x94\xd2lo^e\x1d\xf8\xe9\xf9\x19U\xdd\xa0\xb5\xee\ +\xf9\x90\x88\xa9T\x12\xb6\xd7\xbfN\xf9\xe8\xdeM\xee\xdc\xda\xdd\xf2 \xedc\ +\x081\x12Dh\xbb\x8e\xbaih\x9a\x86(\xea\xfd\x8a\xc0`\xb8\xc7t\xfc\x86\xc5bF\ +\x9eg\xdb<\xe1\x9c\xe5lZ\xf0nZb\x8c\xc6X\x07\xef\x81HV\x9f\xda\xf2\xf8\xbf\ +\xaf\xf9\xf0\xf6M2\xef\xc9\xf3\x1ckm\x9a\xbe.PU\x15EQP\x96%\x8b\xe5\x9a\x10\ +\xf5o+\xe2|\xc6\xee\xdeu\xce\xa7\xbfb\xad\xdb\x86\x9a\xb7\xe3%m4\xe4\xf9\x90\ +,\x1f\xa0\xb4\xc1\x18A+z\x00\xfd\x84h\x8b\xb1\x06\xad\x15\xff\xfc\xe15\x7f\ +\xfd\xcb\xc3\xe4/$Y/\xcb\x92\xe5r\xc5j\xb5d\xbd^RT\xdd6\xc9_"k\xba\x0e\xaf\ +\xdf\xa2\r\xc2t2e<>\xe3\xe5\xab\x13\xce\xa7\xe7\xb4MM\xdb\xb6t]K\x0c\x11\x91\ +\xfe8\xa0\x14\xdaX\x8c\xb1W\xa2\xe6bU\xf0\xec\xe5d\x0bb\xb5*\x98\xcd\xe7\xcc\ +gs\xe6\xf3\x05o\xdfM\xa8\xeaxE\x8a\xb6\x15QJ\xb13\xda\xe7\xe8\xce\xc7<{\xf2=\ +]\xe8\xb8~=\xa2\xb4\xc1:Gp\x96\xaeM\xba\x10\x83E\x8c\xe9\xb3\xf8E"\xb36\xb9\ +\xae5\x96\xff\x02l\x92\xa6\xa0\xfayx\xfc\xef\x9f8\xbe=\ +b:\x99pz:\xe6\xf4t\xcc\xeb\x931E\x15\xb6\xd1\xb4\xe7\xeaEE6c\xac\xb4\xe2\xd3\ +\xcf\xbf\xa6\xaaJ&\x93\x13\xb2<\'\xcb|\x12\'\xeb Z$\x1ab0\x88\xd1H\xd4 \xba\ +\xef\xb2\xc6\xa0\x12\x7fP\xd4e\xc5/\xbf\x9cS\xac\xe7\x9c\x9e\x8ey\xfe\xf2\ +\x84\xf9\xaaakJ\xbf\xa9\x08}\xb6Pi\x1d\x0cw\xf9\xea\xd17<\xfd\xf11g\xa7\xafR\ +\x08V\x1ak\r\xcei\x9c\xd5\xe8\xa8Q\xa2\xd1\xa2\xd1\xa2\xd0(\x0c\x82\x96\x80\ +\n\x8a\xae\x0b\xb4MEY\xae\x99\xcff\xbc>\x193_5[\xdb\xdc8\xfdF$\xed\xa63\xb2\ +\xe9Q\x8fv8\x1c\xf1\xf0\xd1\xb7<\xff\xf9\x07\xc6\xef^ g\xef\x88\x12\x881\x80\ +th\x15\xb1F@\x070\x01i;\x82hb\x0be\x08\xb4MMY\xae9\x1dOY\xacj\x8a*\xf4\xe7\ +\x19@\xe9>\xc5\xbfGV\xb9T\x8d\x8b5i\xc5G\x9f|\xc1\xb5\x1b\xb7\x99\x8e\xdf0\ +\x9d\xce\xa8\xab\x8a\xaaX3\xda_\xb33\xdc%\xcb\x07x\x9f\xfc$\xc5\x88\x8e\xb6m\ +Y\xae\n\x8a\xaa\xa3\xaa#A6\xc7\x95\x8b}\xb7\xe1\xe9*G\xa4w\xda\x88\xa4\xd3vZ\ +{6\xed\xee\xee3\x1c\xeeQUk\xca\xd5\x9c\xa2)(N\xa7\x18=%\xf3)\x97jm\xd0\xda\ +\x111DQ\x84\xa8{\x9d\xe8o\x05\x97(\xbd\xe1\xc3Ue\x15\x91\xbe\xec\xe9,\xaat@\ +\x07\x8d(\x90\x18\x90\x18\x89Qp.\xc3\x1c|\x90\xfe\x97\x986\x11!\x00A\x04\ti\ +\xd3\xcd\xe6\xdb\x86\xf7\xd3\xa1\xd4\xa5\x1f8\xa4\x7f_\xdc\x92\xe2\x8f\xf1C\ +\xcd\xff\x01,2\x98\xdb\x10\x8a7\xe1\x00\x00\x00\x00IEND\xaeB`\x82' + +def get028Bitmap(): + return wxBitmapFromImage(get028Image()) + +def get028Image(): + stream = cStringIO.StringIO(get028Data()) + return wxImageFromStream(stream) + +index.append('028') +catalog['028'] = ImageClass() +catalog['028'].getData = get028Data +catalog['028'].getImage = get028Image +catalog['028'].getBitmap = get028Bitmap + + +#---------------------------------------------------------------------- +def get029Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x08\ +\rIDATx\x9c\xcd\x98[\x8f\xe3T\x16\x85\xbfs\xb5\x93\xd4\x8d\xee\xeaVSCI\xd3\ +\x05\x08!\xb5@\x08\x1e\x19\xfe\xf2\xfc\x81y\x9a\xf7~\x03!.\x12jA\xf7LU%\xce\ +\xd5w\xfb\xecy8\x8e\x934\xf3\x038R*)\'\xf2Y\xdek\xaf\xb5\xb6\xad\x00\xe1/\ +\xb0,\xc0\x17_\xff\x03\xef\x13\x9c\xf3\x18k1\xda\xa0\xb4A)\x85\x88p\x82U\xf6\ +or8 \xea\xe8K\xc5\xff]\xea\xf4\xa3\x0c\x7fE\x84\x7f\xff\xeb\x9f\x11\x88\xf7\ +\ti:\xc5\'\xe9\x08F\xef\x81 \x82\x04\x08\xa1\xa5m*\xba\xb6\xa4kj\xda\xb6\ +\xa2o\x1b\xfa\xbe\'\x04@\x1b\x9cK\xf0\xe9\x94\xe9\xec\x12\xe7\x93\xb8\xb1RG \ +T\x84\xab@\x82\x10\xa4?T\xc49\x8fOR\xd2t\x82KR\xac\xf5\x18\xad\xf7\xd0\xe9\ +\xda\x9a\xb6\xc9\t]\xce\xc4+\xdct\x86R\xe7\x08\xd0\xf7\x1d]\xdbQ75uUQ\x149\ +\xaby\xc6\xe2\xfe\x0f\xce\xaf\xaeyr\xfd!\xb3\xf3\xcb\x03\x0c\xb5\x87\xa3\x10\ +\t\x84\x10\x0e@\x8c\xb58\xe7qI\x8a\xf7CU\x8c\x01\x14M\xb9\xc2Prv\x912\x99>!\ +\xf5)\xd6\x19\x00B/4mM\xd344uEQ\x96\xe4yA\xbe\xdb\xb0\xdelX-\xde\xb1x|\xc7\ +\x8b\x9b;n\xff\xfe\x19JG\x00\xa8\x08H$\xd0wG\x151\xda`\xac\xc5Z\x1f\x019\x1f\ +7j\xb6\xcc&\x8a\xab\xab\x8f\xb8\xbc\xb8`6;#\x9dL\xd0Z\x11\xfa\x9e\xa6mh\xea\ +\x86\xaa*)\xca\x922\xcf\xd9\xeev\xec\xa6\x13|\x92\xe0\x9dc\xb9\xcc\xf8\xe5\ +\xc7\xd7\xec\xb6+>\xfd\xfc+&\xd3\xb3\x08\x04\x05"(}\x04Di\x83\xd6\x06\xa3\ +\xf5P\t\xa0\xdbqy\x91\xf0\xec\xfa#\x9e?\x7f\xce\xf5\xf53..\xcf\xb1\xc6P\xd75\ +EQP\x959EQQV)i\x92Rx\x8f\xf7\x1e\xef\x1d\xceZ\x8c\xb6(\xa5\x08!\xf0\xfb\x9b\ +\x9f\xa8\xaa\x92/\xbe\xfe\x96\xe9\xf4|\x10B@\xf7\xfa\x08\x88R\xb1\xa1\x06\ +\xfeB\xb3\xe5\xf2"\xe1\xe6\xe6o\xdc\xde\xderw\xf7\x92\x9b\x0fo\x10\tl6[V\xeb\ +e\xec\x8d\xae\xc5\xf9@\x1fzB\x08\x08\x82R\xa0M\xbc\xa0\xf8\xd2h\xadQJ\x91=\ +\xbe\xe5\xe7\x1f^\xf3\xe57\xdf\xa1\x94\x06\xd4(8\x0b "\x83:\xa0)W\xcc&\x8ag\ +\xd7\x1fq{{\xcb\xabW\xaf\xf8\xf8\xee%}\xdfr\xff\xf0HY\xe6\x94EA]\xd5\xb4mK\ +\xd7\xb5\x88\x08\xd6Z\x92$Ak\x8d\xb5\xb1"\xde9\xac\xb58\xe7\xb0\xce\x91$\t\ +\x8f\xf7o\xf8\xed\xd7\xefy\xf9\xc9\xabA\x8dG\xd40H\xb4kk\x0c%WW\x91\x8e\xbb\ +\xbb\x97||\xf7\x12\x11a>\xcfX.\x97,\x97+v\xbb-UU\xd1\xb5\x1d\n\x85\xb5\x16=\ +\xd0\xba\xdf8n\xee\xb1\xce\xe1\xbc\xc7y\x8f\x1fD\xf0\xf0\xee\rO\xaf_pv~\x85\ +\x1c\xab\x06@\x02\xb4M\xce\xd9E\xca\xe5\xc5\x05\xd7\xd7\xcf\xb8\xf9\xf0\x86\ +\xbeo\x99\xcf3\xe6\xf39Y\x96\xb1\xddn\xa8\xeb\x9a\x10\x02J+4\x1a\x85Bk\x139\ +\xd7G\xb4\xecA\xd9\xf82:\xf6\xc3\xc3\xc3\x7f\x99?\xbce:\xbb$\x049\x05\x12B\ +\x1b}b\xfa\x84\xb3\xb33..\xcf\x11\t\xdc?<\xb2\\.\xc9\xb2\x8c\xcdfM]\xd7\xa31\ +\xedm2J2\xba\xa5R:6\xbe\xb5\x03E\x91&k\x1dJk\x82\x08]\xd7\xb1Z-\xa9\xaa\x1d\ +\xce\xa5G@\x04\xda\xa6b\xe2\x15\xa9OI\xd2\t\xd6\x186\x9b-e\x99\xb3\\\xae\xc6\ +J\x1cv\x97#\x83\x02\x91\x08\xc8\x180F#"\x04c\xb0\xd6`\x9d\xc3X\x0b\n\xfa>\ +\xd06-UU\x91o\xd7\\|\xe0O+\xd2\xb5%n:\xc3:\x83\xd6\x8a\xba\xaeY\xad\x97\x94E\ +\xc1n\xb7=\x051.\x19\x8f\xa9\xe3,Q\x83$m\x04h]\x871\x9a\x10\x84\xa6m\xa9\xaa\ +\x92]\xbe\xa3\xaes$<=R\rB\xd7\xd4(u\x1ei\xea{\x8a\xa2\xa0\xef;\xea\xaa\xa6\ +\xaa\xaa\xd8\x13c%\xc6-9^J\xed\xad@\x0f\x14E\x17ub1\xc6"Ah\xda\x86"/9?\xbf\ +\xa0z\xcc\x08\xf2^\xb3\xb6m\x85\x10m\xbbm\x1b\xaa2\xa7\xeb\xda(\xd1\xb6Ciu\ +\xb4\xf9\x9fSv\x0f"VGa\x8c\xc2\x183\x80R#\x90Y\xdd0\x9b\xed\x98\xcd\xa6,\x16\ +\x8b!\xdd\x8f\xe4\x1bS\xb4\xa3ik\xea\xba\xa1(*\x9c\x0ft]\x1bUA\x0cAu\xba\xff\ +\x08\xe2@\x91B\xebhbz\x90\xb3R\n\x1b\x1c"BUM\x98\xa4\x13\xd2t\x8as\x03w#\x10\ +Q\xf4}O\xdb\xb4\xec\xf2\x82\xfb\xc7\x8cm\xd1\xc6\x06\x13\xc1\x18\x836\x06\ +\x85\x1e\x1c\xf8\x14\xcd\xf3\'g$\x89\x1b\x1dZk\x85\xd2&f\x98\xb1Xc\x10\xa2q&\ +I\x82K\x921\xd3\xf6D\x1f\xc9\x971\xcaw\xbb\x1d]\x0f\xd6Y\xb4\xb617\x86+C\xe9\ +\x13\xe9\x02\x04a\xa4 \x82\xd0\xd8\xbd\xb9\r\xd2\x05!\xf4!J\xdaX\x8c5\x18\ +\xfd~E\x10\xd0\x86\xba\xaa\xa8\xaa\n\x9f\x94(e\x08!\xc1:\x89y\x11\x02h\x13\ +\xc7\x1au\x98+"5\x87Jh\xb3\xaf\x84\x89\x9b:\x8f\xb5v\xe8\xc3\x1e\xad5\xe8\ +\xd8g\xdaZ\xc2)\x10\x85s\teYP\x94\x05\xce\xa7(m\x10\x11\x94R\xf4\xd6\xa2\x94\ +\xc6\x0cW}\xdc\xac\x7f\x02a\xcch\xf5\xd6Y\x9c\x8b\x15\t\x12\x9d8 \x84 q\x0eQ\ +#!\x07j|:e5\xcf\x98\xe6;\x12\x9f\xa0\x94F\x04\xb4\x89\xb4\xe8#I\xeei\x88\xff\ +\xeb8\xe7\x0e\xb3\xae1&\xf2?d\x8b\xf3\x1ek,m\xd7!!\xd0w\x1d]\xdb\xd0\xb6-\ +\x82~_50\x9d]\xb2\xb8\xff\x83\xedn\x8bu>\xf6\x82R\x87\xdc\xd0\x06m\xec\x9e\ +\xd2\x11\x84\xd2\n\xa3M\xcc\x92}_xO\xe2\x13\x924\xc19\x87\x08\xf4}O=8jYU\xec\ +\xf2\x02\xc1\xfc\xb9"\xce\'\x9c_]\xb3Z\xbc\xc3\x1e\xeb\xdf\x1a\x8cq\x83r,\ +\xc6h\xc0\x9c\xc8t\x8cz\xeb\xb0\xce\xe2\x9d\x1fAhm\xe8\xba6\x0eSy1\x8c\x92;\ +\x9a6\x80\xd2\xef7k\\O\xae?d\xf1\xf8\x8e\xf5z\x05\x1cx\xdf\xd3c\xad\xa37\x86\ +8\xce\x0e\xd4\x8c\xbd\xe0\x06I\xc6\x8a\xecA\x84\x10(\x8b\x8a\xedv\xc7f\xbbf\ +\xbb\xd9\xb0\xc8\x964\xdd\x89\x03\x1c\x80(\xa5\x98\x9d_\xf2\xe2\xe6\x8e_~|M\ +\x1f\xf6\x91nq\xd6\xe3l\x1cr\xb4\xb1Xk\x111q\x1aC\rR\x8d\xdf[\xeb\xb0\x03\ +\x85]\xd7R\x16\x15\xab\xf5\x9a,\xcb\xc8\xb2%\xd9rA^\xc6\xfe8\xce({\xec\x07\ +\x00\xb7\x7f\xff\x8c\xddv\xc5\xefo~\x8a\x8e\xe8\x1c\xce\'8\xef\xc6\x14\xb5&\ +\x02\x0c6\x0c\xe2\xdf+\t\x82\x04\xda\xae\x8b=Q\xd7l\xb7;\xb2,\xce3\x8b\xf9#\ +\xf7\x0f\x19M\x1bb0\xaa\x91\x99Sj@\xa1\xb4\xe2\xd3\xcf\xbf\xa2\xaaJ\xb2\xc7\ +\xb7$>\xc1;\x8f5\xd1\xa4\x8c\xd1\x18\xad\x869\x14\xb4\xd24uMU\xd9\xc1\'\xe2\ +\xb0\\7-E^\xb0\xd9\xae\xc9\xb2%\x8b\xf9#o\xffsOQ\xf5\xb17\xc6\\z\x9f\x9a\xe1\ +\xa0B1\x99\x9e\xf1\xc5\xd7\xdf\xf2\xf3\x0f\xafy\xbc\x7f\x83\xb5f\xc8\x99\xe8\ +\x19\n\x19\xee\xd7\x02\na\xb3Y\xd3\xb5u\xec\t\x84\xbe\xeb\xa8\xca\x8a\xbc(\ +\xd8n6d\xcb\x05\xf7\x0f\xd9\x08Bq\x08\xc8\x13\x8b?\x14V\xedc\x94\xe9\xf4\x9c\ +/\xbf\xf9\x8e\xdf~\xfd\x9e\x87wo\x10y \xf4\x81\xd0wt]C\xdfu\xf4]C\xe8j\x1e\ +\x1eZR\xefA+B\x10\xba\xb6\xa1\xac*\xf2\xdd\x8eE\xb6$/\xdbQ%\xd1\x90\xf58\xb3\ +\x9c4\xab\x1cU\xe3\xf0\x1eU\xf1\xf2\x93W<\xbd~\xc1\xfc\xe1-\xeb\xf5\x92\xba\ +\xae\xb8(\x0b\xce\xcer\xa6\xd3\ti:a\xb3N\xb0\xce\x02\xd11\xdb6\x86g\xd3\x06\ +\x9a\x0e\x84acu8\xefx?|\xda#\x82\x04A$ \x12\xe2\x98/\x81}7\x9d\x9d_1\x9d]RU;\ +\xf2\xed\x9a\xba\xce\xa9\xe6\x19ZK\x94\xab\xf3\x18m\xd1\xd6\x82\xb2\xd111\ +\xb1\x17\xc6J\xefk\x7f\xfaX\xe0\xc4YE\xe2]y\x08\xf1^T\xe9\x1e\xddkD\x81\x84\ +\x1e\t\x81\x10\x04\xe7R.>\xf0HxJ\x90\x10O"\xc3\x03\n\x911\xc0\xf6\'\xdfKB\r\ +\xeaP\xea\xe8\x01\x87\x0c\xbf\x0bcS\xfc5\x1e\xd4\xfc\x0f`\xfc9\x8a\xcf\x1b\ +\xf5\x97\x00\x00\x00\x00IEND\xaeB`\x82' + +def get029Bitmap(): + return wxBitmapFromImage(get029Image()) + +def get029Image(): + stream = cStringIO.StringIO(get029Data()) + return wxImageFromStream(stream) + +index.append('029') +catalog['029'] = ImageClass() +catalog['029'].getData = get029Data +catalog['029'].getImage = get029Image +catalog['029'].getBitmap = get029Bitmap + + +#---------------------------------------------------------------------- +def get030Data(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00"\x00\x00\x00"\x08\x06\x00\ +\x00\x00:G\x0b\xc2\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x07\ +\xabIDATx\x9c\xcd\x98\xddn\xdb\xc6\x16\x85\xbf=3$%YB\x0c9i\x1d\xb7hR$h\x91\ +\x83\xa2(\xda^\xf6\xf4\x95\xcf\x0b\x9c\xabs[\xf42\x17)\n\xa4H\x9c6\xfeQD\xc9\ +\xe2\xffp\xe6\\\xccP\xa2\xdc<@)P\xb4i\x8b\xb3\xb8\xd7\xdakmJ\x00\xcf?`3\x00\ +\xdf\xfe\xf0o\xd24#IR\xb41h\xa5\x11\xa5\x11\x11\xbc\xf7\x1ca\xf5\xc3\xc1\x1f\ +Nx\x19\xfdQ\xf8\xe8&\xc7?\xfa\xf8\xee\xbd\xe7\x7f\xff\xfdO\x00\x92\xa6\x19\ +\x93\xc9\x8c4\x9b\xec\xc1\xa8\x01\x08\x1e\xbc\xc7;\xe8\xfb\x8e\xb6)\xe9\xda\ +\x8a\xb6\xa9\xe9\xba\x06k\x1b\x9cu\xf4\xde\xa3\x95!I\'d\xd3\x19\xb3\xf9)i\ +\x9a\x85\x85EF $\xc0\x15\xf0\xce\xe3|\x7f\xa8H\x92\xa4\xa4\xd9\x84\xc9dJ\x92\ +M0&E+5@\xa7\xebj\x9aj\x87mv\x18\x05\xd9\xc9\x04\x99O\xc1\x83\xed{\xac\xed\ +\xe8\xda\x96\xa6\xa9\xa9\xeb\x8a\xd5\xd5\x8a\x9b\xabK\x1e\x9c>d\xf9\xe8\x82\ +\xf9\xe2\xc1\x01\x86\x0cp\x04\xef\x1d\xce\xb9\x03\x10m\x0cI\x92\x92d\x13\xd2\ +4VEk@(\x8b5}[p2K8[^\x90&\tZ\x1b<\x1eg{:\xdb\xd1\xb6-m\xdbR\xd7\x15UUR\x16\ +\x05Eq\xc7\xea\xe6\x1d\xb7\xd7\x7f\xf2\xf8\xf3g|\xf1\xf4kD\x05\x00H\x00\xe4\ +\xbd\xa3\xb7\xa3\x8ah\xa5\xd1\xc6`L\x1a\x00%)\x1eO[m\xc8t\xcf\xa3\xc7\xe7\ +\xcc\x17\x0bf\xd3\x19i\x16\xcam\xad\xa5mZ\xda\xb6\xa1nj\x9a\xaa\xa6\xaaK\xea\ +r\xcad2%\xcdR\xb46l79\xbf\xbd\xfc\x85\xdd\xdd\x9a\xaf^|\xcft6\x0f@\x10\xf0\ +\x1eQ# \xa24Ji\xb4Rh\xad\xf1xl\xbde61\x9c-?\xe5\xec\xe1#\xce\x96KN\xe6\xe1"U\ +UQ\x16;\xca\xb2\xa2\xae+\x92:\xc5\x98\x04\x93\x18\x8cI\xd0\x89Ak\x8dR\n\x11\ +\xc19\xc7\xdb\xd7\xafh\xea\x9ao\x7f\xf8\x89\xd9l\x11\x1b\xc1\xa1z5\x02"\x12\ +\x04\x15\xf9k\xab\r\xb3\x89\xe1\xfc\xfc1\x17\x17\x9f\xf1\xe4\xc9S\xce\xcf\ +\xcf\xe9\xfb\x9e\xd5\x87\x15\xbd\xed\xa9uXLk\x8d1\x86,\xcd\x82\xa0DP\xf1\x86\ +\xb4Rh\x15\x00)%\xdc^\xbf\xe5\xd5\xcb_\xf9\xee\xc7\x9f\x11Q\x80\xec\x1b\xce\ +\x00x\xefcw@Y\xac\xc9t\xcf\xd9\xf2S..>\xe3\xc5\x8b\x7f\xf1\xec\xf9s\xba\xb6\ +\xe5\xcd\x9b7l7[v\xc5\x8e\xba\xaah\xdb\x16k-\xde{\x94\xd6\xa4i\x86\x12\x851\ +\x06c\x0cZ\'\xc1\x0e\x8c!1\tI\x9aq\xfd\xd7\x1f\xbc\xfe}\xc9\x97\xcf\xbf\x89\ +\xdd8\xa2\x86\xd8\xa2]W\xd3\xb7\x05\x8f\x1e\x9fs\xf6\xf0\x11O\x9e<\xe5\xd9\ +\xf3\xe7x\xe7\xb8\xbc\xbc\xe4\xfd\xd5{\xf2uNY\x164M\x83s="\x82\xd6\x06\xa5\\\ +\xac\x90\xc1\xd8 \xe8\x01\x901\tI\x92b\x92\x04\xad5\xef\xdf\xbdf\xf9\xf0\x9c\ +\xc5\xe2\x14?\xee\x1a\x00\xef\xa0\xa9v\x9c\xcc\x12\xe6\x8b\x05g\xcb%\xe7\xe7\ +\xe7tm\xcb\xe5\xe5%\xef\xde\xbdc\x9d\xaf)\x8b\x82\xaek\xa3\x17(\xc0\xa35x\ +\xafP\xca#\x91\x1a\x15i\xd3\x11L\x92$Q3p{{\xc3\xed\xd5%\'\'\x0fp\xce\x1f\x03\ +\xe9\xfb\x0e\xdb\xec8[^0\x9b\xce8\x99\xcf\xe9\xfb\x9e7o\xde\xf0\xfe\xea=\xeb\ +|M\xb1\xdbE*\xa2\xc1\x8c\x8d3\xeal\x10\xe7X?Z\x07zD\x14x\xe8\xfb\x9e\xedvEU\ +\xefH\x93\xc9\x08\x88\x87\xb6)1\n\xd2$\t-*\xc2\xea\xc3\x8a\xedf\x1b\xe8(\n\ +\xac\xb5q\xd1`\xd122\xec\x11"\xb4(<>tb\xa4K\xeb\x00\xc4{\x8f\xb5\x1dM]\xb3\ +\xdb\xe6\x9c.?9\xaeH\xd7Vd\'\x13\xb4\x0e\xa7\xaa\xaa\xa2\xb7=\xbbbGYF:|4\xa2\ +AV\x03\x80\xc1\xc2C\xd3\x1c:P\x85%\x0e\x91\x11\xaa\xd1\xb6\reY\xd2\xd4\xc5\ +\xb1F<\x9e\xb6\xa9\x91\xf94x\x88\xb5\x94\xc5\x8eZ\x1b\xea\xaa\xa2i\x9a\xb8\ +\xa4\x0fa5 \x19\x83\xe0\x00`\xa0H\x89\n\x15\xf2\xa1\xd5E\xc0\xda\x9e\xb6\xa9\ +\x99\xcf\x17\xac\xf3\x1c\xe7\xef\x89\xb5\xeb\x1a\xf0\xe0lO\xdb\xb4\x94e\x85\ +\xd6\x9a\xb6mcw\xa8\x11\x11\x1f\x01\xb1\x7f\x0bI\xa2$\x08V)AP8\x13\x96\xb2\ +\xd6\xd2\xd43\xa6\xb3\x19y\xbe\x8e\xe9>j_k\x1bl?dGC]\x07 \xd6\xda\x98\x9e~\ +\xbc\xe4\x11\x88\xf1&"\x88R\xd1\xc4Thm\x91\xfd\x80\xd0[K6\x99\x90e\x13\x8c1p\ +\x04\xc4\x0b\xce:l\x0c\xb0\xba\xa9\xa3m\x1b\xbc\xf7Ql\xc3R\xfeo dH\xd5Q\xe7\ +\x88\xc8>2\x02-\xe1\\\xd2u1\xcfB$\x0c\xb7wh_\xef\xe9b\x8a6U\x8d1\tY\x9a\xc5\ +\xf2:\xbcWGs\xc5\xa86\x07\x10\xf1\xa5DPJ\xa3\xb4\xc1h\x8dI\x12 \x0cY\x07\xd7\ +\r;\xf7\xa9\xd1\xca\xec\xe7\x89\xaa.1\x89\x014\xa292\x04\xe0\x8b\xa7_\xb3\xbb[\xf3\xf6\xf5+\ +\x94\x920YE\x03\xd2\x83^\xa2\x1e\x9c1q.\x91xQ\xd9\xfb\xc5\xa0\x89\xaa\xaa\ +\xb8\xbb\xdb\x90\xe7k\xd6\xeb\x15\x1f\xd6[\\/\xc4Iq\xb0\x91cj@\x10%|\xf5\xe2\ +{\x9a\xba\xe6\xf6\xfa-I\x9aa\xf6C\xcd\xb0\x1f\xccU"\x10\xef=\xde;\xac\xedc\ +\xb8\x05M\x94e\xc1v\x93\xb3^\xaf\xb8\xbeY\xd1\xf6\x1eQjp\xc1{\x15\xe1`\xd3\ +\x820\x9d\xcd\xf9\xf6\x87\x9fx\xf5\xf2W\xae\xff\xfac\x9f\x9ca\xa2\xf4\xf4}\ +\x8f\xb5=\xd6ZzkI\xban\xa4\x9f0\x18\xb5m\x10fQ\xdc\xb1\xc9s>\xac\xb7\x01\x84\ +\xa8=x\xe2S\xdf\x1e\xc8!\xd2d\x18(\x98\xcd\x16|\xf7\xe3\xcf\xbc\xfe}\xc9\xfb\ +w\xaf\xb9\xbd\xbd\x89\x00\xba\xd8\x825M=#\x9bL\xf6^\xa1\x94\xc2y\x8f\xed:\ +\xda\xa6\xa1\xac\n\xf2|C\xd3\xf5\x91\x0e\x15SZ\xed\xd3\xfcH\xac~T\x8d\xc3Q\ +\x10Q|\xf9\xfc\x1b\x96\x0f\xcf\xb9\xbd\xbad\xbb]\xd1\xd45eY2\x9f/\x98\xcefd\ +\xd9$\xe8G\x1b\x10p1\xc1\xab\xaa\xc6\xf6>v\x87\x8e\x9a8\\w\x1c\x17#j<\xde\ +\x05\x8e\xbdwa\xcc\xf7n\xaf\xa6\xc5\xe2\x94\x93\x93\x07T\xf5\x8e\xdd6\xa7\ +\xa9\x0b\xd6yN\x9e\xaf\xa3\x8b\x0e\x1d\x95"\xda *\xee2\xb4\xe8\xe1\x99\xe9\ +\xfe\xd7\x02G>\xe2}x*w.<\x8b\x8a\xeaQ\xbd\xc2\x0bx\xd7\xe3\x9d\xc39O\x9aL8]~\ +\x12~\xf7.\\\xc4\xc71\xc9\xfb\xfdE\xef\x1f%v\xc7~\xcc\xe4\xa07\xdc^\x14\xff\ +\x8c/j\xfe\x0f\xd8\x1d\x10\x98\x84\xbe&\x9c\x00\x00\x00\x00IEND\xaeB`\x82' + +def get030Bitmap(): + return wxBitmapFromImage(get030Image()) + +def get030Image(): + stream = cStringIO.StringIO(get030Data()) + return wxImageFromStream(stream) + +index.append('030') +catalog['030'] = ImageClass() +catalog['030'].getData = get030Data +catalog['030'].getImage = get030Image +catalog['030'].getBitmap = get030Bitmap + + +#---------------------------------------------------------------------- +def getecloudsData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x02@\x00\x00\x000\x08\x06\x00\ +\x00\x00\xf9\'\xc5\xde\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ + \x00IDATx\x9c\xec\xbd_\x8cf\xc9u\xd8\xf7\xeb\xee\xea\xee33wfjf\xbf\xdd\xbd\ +\xcb\xfd\xb4\xfcH5\xc9&=\xb6F6e\x0f\xe0\xb5\xb2N\x14\x87qdX\x01\x04D\x08\x04\ +\xc4\x0fy\x08\xf2\xe4G?&oF\xfc\xa2\x87 \xf0\x83\x03\x08\x89\x1f(\xc0\x0fr $\ +\x1b\x98A\x18\x84A\xd6\x0e\x15\x8f\x95\x11\xd5\x14G\xe4G\xb2\xb9{w\xf9\xedL\ +\xcd\xcc\x9d\xee\xd3\xdd\xd5\xddy8Uu\xeb~\xfdg\xd6\xe0\xae\x05%[\xc0L\x7f\ +\xff\xee\xbd\xa7N\x9d:\xff\xcf\xa9\x95\xd5Uw\xca\xa7\xe3\xd3\xf1\xe9\xf8t|:>\ +\x1d\x9f\x8eO\xc7\xff\x8f\xc6\xea\x9f6\x00\x9f\x8eO\xc7\xa7\xe3\xd3\xf1\xe9\ +\xf8t|:>\x1d\xff\xa6\x87\xcb/\xfe\xfeo\xfd\xd6\x9f&\x1c\xff\xda\xe3\xef\xfd\ +\xdd\xbf;z\xff)\xfc\xfff\xc7\xa7\xf0\xff\xe9\x8eO\xe1\xff\xd3\x1d\x9f\xc2\ +\xff\xa7;>\x85\xffOw\xfc\x7f\x05~W\x7f\xf8\xce\\i[\x8f\xf6J\xb7\x08\x84\x10\ +\x00\x10\x11\xb4W"\xe0\x1c\xc4\xb8t\xa1\x03\xfbr\xe9o\xfd=\xc3w1\xda}\x9c\ +\x13bT\x9c\x13\xfbY\xfa]\xfe<\xbfvK\xd7\xbf\xb5\xed\xcf\x9d\xd4;se:m\xe9C\ +\xb8\x10\xfe\x1a\xdc\x02^\x05\xd3\x19\xf8_0\'\xe7d\xc0E\x9a\x13p\x06~q\xa0\ +\x11\x1c\xca\x9b\xdb\xed\x85\xf0\xb7\xad\xa7_t\x84^Y\x84\xe1\x1eQ\xb5\x80QPq\ +\x11\xbc\xd4?:\xfb\xb7\xc6\xffy88\x0f\xff\x19\x86\x17\xe1\x7f\xd6z\xc22\xfd8\ +A\xa3\x12\xe3\xd9k\xdc2\\y\x0e\xe7-\x96[\xbev\xa0\x9f\xfc\x95\x13\xc1\xa1D\ +\xaa\xef\xf2Z\xa5\xcf/\x83\xff\xcf2\xfd\x7f{\x1e\x98\xb6m\xc1\xbf\x86\x80\ +\x92\xf0_\xd1\xcfEtT>?\x0f\xfe\xfa\xa2\xfcq\x86\xbb\xfa\x9dpJtW\xce\xa1\x7f\ +\xa3\x01\xb8\x9c~\xda\xd6s\x1c\xde\xe3\xc7ae\x8c\x7f=K?\xe7\xed\xe32.\xa0\ +\x99z\x1e5\xfd\xe7\xd18\x83\x1f8C?y\\\x86\xffv:;\x9f\xff\xa8\x8ep|\xdeZd\xda\ +\x18\xcdey]\x96F\xa6\xfd\xc8\x8b\xe9\xe7\xa3\xd0\xffg&\xc2\x93^\xf90\xe8\x85\ +\xf8?\x0f\xa5\xd5\x14.\xdc\x0f\xf5y\xbc\x08\ +\xff\xcfC\xe0\xbdK\xe8g\x04s\xf5A\x86\xfb\x8c\x1c\xa8>\xcb\xd78Y\xe2\x9d\xf5\ +T\xd3w\xf9\xc7\x99\xce\xce\xa3\xff\xd1\xfa\xb7\x1eV\xa3\xa6\xcd\xaa\x05\x19\ +\xe2\x00I\x8bp\x0eRG\x80\xbb\xf3\xee<\xfelD\xf8K\x0cf\x10\x06y\x820\x9b\xb5\ +\xb4\x13O\xb7\x08\xf4\xe1bB\xf89\xbf\xcaQTb\x1f\x0c\xd9K\xf0g!p\x06\xbcK\xe0\ +?wn#8/\x04\x07\xe7\x04\x11\xe1\x8dVx\xa5m\xe9\xba@\xdf_\x0c\xbfo\x84\x06\xa5\ +\x8b\xc2j|^\x9e\xd94\x82\x82\t\x90e\x06\x99\xe1\\\x9eS=\xc9\xa5\xbf5\xfe\xcb\ +\xbd\xaa\xf99\x8c\xd1,\xe3\x7f\xb1\x08?\xf5\xc6\xff_@?\xbe\x11$*!\ +\xf3\x99\x04K\xd3\x18n4\xed\xdf\xf5\xf8\x98#wk\xac\xb4\x9c\x07\xcf%\ +\xe8{\xe5\xb6\x1c\x17\x1a\xd7\xc2<\xd3~\xcf\xc6NE\xc3\xb5B\xe6\x9c\x8c\xe6)E\ +1\x19po\x02+3\xe2\xbc\xce\x9eI\xc6?\xf6=\xe2/\x84\xbf\x0f\xe6]\x89\x99\xf9\'\ +\x18\xb4\x1f\xf6/\x0c\xfb3\xf3\x0b\xe7\x06:/J\xfc\xd2\xfade\xda\xc0\x951\x8e\ +\xd2\x18\xf4;\xbbO\x93\xf6o\xa1}1\x0f\xdbG\xa6\xff\x1a\x87\xf1\xb4\x08\xc8\ +\xac4h\xc2\x8b\xf1Y\x19\xc0\xd11\xcf\xcc\xf3\xa9\xffJ\xbdN\x19\xea\x8c\x8f\ +\xb4\xc6M#4\x8d\xc1\xaf\xd1\xf8\x91D\xbd\x10\xfe\xc5b\xe0\xff\xd9+b{p`G#\xa5\ +9\xfc\x08\xb7\xf8\x0e\x00\xa7\xceC\x0c\xacJ\xcb\xc9d\xfb\xcc\xbe\x88Q\x0b\ +\xff\x1a\xd1N6^8EY)\xf8\xcf\xfc\xa7\x9d\x08\xcf\xa3r\xad\xdaw\x17\x8d\x02\ +\x7fe\xbc;g\x9e\xe7\x12Fc\xbcW\xeb\xb1\xbc\x8f\xa9\xee%i>\xeb\xfa\x98\xb8\ +\xf8!h0\xbak^\xc7\xc9u\xb4ii\x9a\xda\xa0T\xa4\x11&\x13\xdb\xbf\x82\x94\xf4\ +\x82\x8bFH\x8a[\xcc\xf2+\xd1HT\x92\xec0\xba,Fc\xc6+I\x11]\x92\xb3\x19\xf6\ +\xb1\xd1U\xf1\xa6Z\x9b\xcd8H{\xa3\xe0\xbf\xf5\x89\x7f\x1a\xfd\x17#\xe4\xec\ +\xa5\xc9mU\x8db\xb5$\x86o\x0bk\x0c\xae0\xfe\xfafK\xcc\x1f\xd2f\xcf\x1b9\xbb\ +\xa5\xe2\xc0$a\xcc\xcc\xf2\xfd\xc5)\xd3\xb6e\xd2\x08kQy\xa2p\xf3\x05\x0bP[\ +\x0e\x9a\x14\x17M\xd6V=\xf1\xe8$q\xa9\xe5\xf9&\xc6\xe7d\xb4a\x97\xbd=\x83\ +\xf5&E0R\xb9\xf5\x1c\xc6p\xda\x89G\x1aO\x04\x9e\xc7\xe1^\x97\r\x01b%`m^\x02i\ +\x13\xc4X\xc1\t\x05\xde\xac\xf1\x9a\xa7KGs\x89Q\x0bS\xc9a\xb9\x8c0e\xa5R\xde\ +j\x1c\xc2$\xe1\xffH\x95\xe7\x027\xf3\xc6\xbf\x08\xff\xf9\xb9\xd5\\\x14\n\xed\ +D(\xd6\xf0 x\x0c\xc6\xac\x08\x917\x89\x13\xa2\x1b\xeb\x07#k\xb1\xfe\xc2\x8d\ +\xbf\xcb\xb45m=\x92$\xff\xf3\x08\xa8\xa6M~\x11\xfcKk\xf13\xd0\xbfMGm=\xfe\r\ +\xd2\xbf\x8bZ\x98I\x8d\xaa\xd0k\xb9wv\x19K\x93,\xc3%Z\xc9s8O\xe9/L\xb0R\xe2j\ +\xc5\xa7V8&\xadg\xd2\xd8\xef\x9fG\xc3\xe1e\x02\x00\xc0\xc5`\xde\xab\x0cx\x1a\ +\x8ft\xcd\xe0r\x82\xb8l\xc9\x8f\x85i\xac\x98\xa5\xc1I\xc1k\x11`\xf5\xa2U\x8c\ +\xda\x0c\xe1\x016\x11\xe13\x13\xc1\'\xfa\x7f\x82\x18\xfe\xcf\xe1\x1b\xf5\xa8\ +q\x9f\x951\x8d\xe0j\xfeQ\xbc\x97\x03\xbe2\xfd\xd6\xca\xfe\xa0(\r\xcaE\x1d\ +\x9e\x18\xe1\xcd\x8dC/\x8d\xe4\xfdk\xd7=Q\xe5Z\xc2\xdd\xc5\xc0\xe7<7\x9bg\ +\xe1C\x9ax\x92\xcb\x9eI\xa1\x0e\xfb\x92\x14\xb4B/\xb5\xd2\xe6\x96\xe8\xa2\ +\x0e\x7f0\xe0j\xa0A[\x87F,\x9f\xc47B\x9f\x8c\xaa\x18\xfd\x99\xf0\xfd\x18\xf7\ +c\xc5\xad(\x94N\xa0\x0f\x88\x13\x84g\xf4\x08+\xfd{\xec\xef\xfe\xdf\x88\x08\ +\x13\xefq",\xfaW8\x89\xcaj\xf7\x0e\'M\x0b~v\x86\xaf\x14\xe5\xb3\xdec\x11\xa2\ +\\)x\xc8\xe1\x97i\xebiD8\x8d\xf0\x1c\xb8\xe9^\xc0\x7f2\x9e\x96rpr\xfeg\xc6SL\ +x\xabq\x99=R\xf9\x1e\xf5>\x00 \xfc\x88\x18\xdeECW\x94@\x11\xa1q\xcf\xe9\xf59\ +\xa2\x8f\x88\xf2\x17\rv\xbb\xb0\xc0\x0f\xc6?r\x8a\xc3\x85\xf0\xc7\x0cS\x82U\ +\x06\xcf`M\x9c5\xef,\xf3\xa9\x0c\x80\x9c\xb38\xec\xe1\n?\x19\xff\x95\x81\x91\ +=c$\x051{]\xa7\xadG\x9c\xe1?\xc3\x7f&\xfd\xe3\xbc7\x8e\x1c\xef5K\xd4>\x1f\ +\xb4\xde\xe5\xa4\xcc\xc1RH\x1a62~\xdf\xc8\x88\xf1\xc5\xda\xcac \xac\x11\x9e\ +\\\n\xb7\xf4\xcau\xa7\xac\x89\xe7\t\xf0\xd2%\x044\x12\x96\t\xd1g~\x93\x99\ +\x13KL\xa4h\xf2\xe7\x08\xd98(;#.\x935V\x86\xb9\x96[9o\xd6\xab*W\x08\xac\x89\ +\'D\x984\x17\x82_6?\x9c#`3\xee\xd3\xeb\xc20\xb3\xc5\x1d\x95\x15}\xcc1\xb0\ +\x0e\xe06\xc1]\x1dY<2\xba\xe1\x00\x7f\x869[\xa5T\x8a\\\xc6\x7f\xc4<)\x13\x7f\ +1\xfe\x97\x99x\xbe\x87\x8dD\x98\x95\xd5T\xffVU\xd9\x08sN\xe2\x11\xb1\x7fNl\ +\xae\xb1\xd2LP\xb9uVp\xe5\xe7I\x05\xfb\xf2\xd4\xd2}{5\xe5\xaf\x11\xa1\xcf^\ +\x8b\x0b\xc6\xc7E\xff \x10~\x84v\xdf)J\xdcJ\xfb\x0b\\\xf3mQ8?\x11\xfa/\xf4\ +\xb3$l+\xc5-3\xef\x1c\xda\xcd8\xcct\xef\x92p\xab\x81[\r;\xec\xf5\x81\x8d\xa4\ +\xd8\x1c\xcbM\xd6\xfckc\xab\xbf\xc00\xc0\xb7\x1a-\x9fA\x92\xe0}\x82\xf0\xd2\ +\x0b\xe9\xdfC\\26\xb2\x10+\x9e\xc5\xf3\x85P\xb6\xf8\xf3W\x19\xaf\xd9\xf2\xc5\ +m\x0e\xd3\x92\xdb\x03/\x10Y\xda\xd6\x8as\x9e\x13\'Iq\x1c\xe6\xf8\xd2e\xfa[\ +\x16BK\xca\xe4(d\x9b\x18u\x0e\xa3\x16\xe5\xa6\xda\xdb\x85\xdf\xa4{\xd6\x86n\ +\x1d\xc6\xab\x85\xdeYX\xbc)\xbe\n\x8e@#\xc2s9\x87\x07,\xc1\x9f\r\xc3\xcc;c2\ +\xaa\xd0\xc0q\xbf\x8f\xeb\x17l\xb8c\xc4\xad\xd3\xeb\t"\x1b\x1c\xb8\x1b\x9c\ +\xc6#\x9c4\xc0j\to\x0c\x82\xba\xa6\x0b)\xefk/\x98\xc6%\xe58\xd1\xbf\xed_\x08\ +\x08~In,\x8f!\x9c\xa3g\xf6A6>\x94\xeb\xb8\x08\x87\xe1}\x9c\x13V\xc5s\xef\xde\ +=\xbc\xf7\xfc\xee\xef\xbd\x8dF\xe5\xc4\t\xab}\xc7\x86\x06trwH\xa2=\x8f\x07U\ +\x86Z\xde\x7f1*"5\xfcf\xbc>\xe1r\x038\xf3\x8e\xa2\x14\x17\x94e\xbe%\x03\xef\ +\xa8\xe9h\xa4\x08\x8d\xe5\xefJ\xff\x1e\xfb\x8b\x1fB\n?e#\xdc9\xa1m_\xe3\xce\ +\xf6\x97\xd8\xdd\xedx\xb0\xb3\x83\xeb?\x00\xffF\xba\x8f\xf1\x81\x90\xbc\xc7\ +\xce\x99\x87\xf6\x85\xf2+\x0ex\xcf\xc6V\x9d\xa3SB\xfe\x95\x11P\xf8+\x83r-\ +\xc9\xf3W\xf4\xa7\x84\xc7\x95\xb8O\x8cG\xa0O\xec\xf7\xf1y\xc93\xea\xfb@t7x\ +\xde\xbc\xc6\xcd\xe9\x97\x0b\xfeq&\x1f{<~I~\x8del\xb2\xeezM.\xbc\xda\xad\x17\ +\xcf^a\xa1\x80}\xd4\xad\x8c\xbfrg~\x9a&\x11\x86\x8d\xc1\xf8\xfe\xc3wR\x90\ +\xa6\x9a*\xa1\xbc i#\xe8%\x1a\xa83s\xdb\x16\xbf&\xb6*$S\x87\xb5\x84\x1c\xfe\ +\t\x1c\xeb>+\xfa\x84\xab\xee\x98+\xb2Q\xeey\xcd\x9d\xa0l"Nx\xde?\xe3\x9a\\7\ +\xe4\xcbUT\x8f\xd3\x82>a\xd3m\xf2\xa3p\xca\x91\xbb\t\xcdm\x9a\x14s\xee\xba\ +\xc0d\xe2i\x12\x01|x\x89\x01f\xde\x13\x1d\x08\xa4\x12\xba\xe7\xe1\x1f\x92\ +\xa5\xb8\xf8\x1eN?\xc4{\xcfdr\x8b\xd3x\xcaA|J\xdf\xef\xb3\x17\xe00\x87\xfa\ +\x9a\x16\xea\x8d\xb5\xc4xj\x0fA#\xd0\xf7\x80\x1b\xf0\x1f\x05>\xec/\x86?o\xb0\ +\x1c_\x1e+\x0bKV}Q8\xd3\x1a\xec\xde\xe7$Y\x80\x93FP\xfd\x10\xf4C6EP\xf9\x0c\ +\xaey\x05D*\xe5j\xb04\x96\xf3\x9b\x9a\xb2!\x06\xfck\xaf\xf8\x06\x9e\xc7\xcb\ +\xe9\xe7\xe3\xa0\x7f\x87\xd2w\xdfA\x1c\xac\x8ag\x03%.\xbe\x8b\xca-*\x8d\xeac\ +\xa7\xff\x9c\x10\xaey\x8e\x89I\x16x#\xdc\x90c\x9e\xc6\xb53s){6\xef\x8f\xf0#N\ +\xfaG\xc40/\xc2pC\x84\x13\x15N\xfb\xc0\x89>\x81\xe9\xdd\xea\xde\x96p\x9a\x13\ +\x9f\x9d\x83\xa7=\xacv\x81\xa6\x91\x94\xe0\x0f\x1f^\x08\xfd@\xffg\\\xdcd\x8f\ +\xc3\xd2\xe7n\x807&\xbc\xa3{\x1c\xc7\x03V\xf5\t\'\xf1\x08\xfa\x9f\xe0\x10\ +\xd6\xaa\xb9\xc6\xa8\xac\x8a\xc7M>\x8f\xf3\xaf\x14\xe5\xbf\xccELa\xd3\x1e\ +\x16NKr\'\xc0\x87\\\x8e\xff\x98\x04\xc7\xa8\xca)\xda\x1c\x006b@\x17\x1d\'\ +\xee*\xabq\x0f\xc0\xe0\x04N\xdc:\'\xf1\x88FV\x13\x1cWX\xe7\x985\xb7\x8e\x97\ +\x15\x94U\x9e\xf7\xcaO\x83\xb2\xd2L\x90\xa6!\xca\xcbeN\x05\x8e\x04\x7f\xdfS\ +\xe8\xdf%/\xd4e\xf0;\x11\x1a\x84\xa8\xc1\xe8F\x03\xa4\xb0\x81\xdb\xdd\xe1ko\ +\xdd\xe3\x97\xdf\xfc\xf7yc:\x03\x8c>\x1f\xf5\x81\xc3\xderJB\x08\x84^S.\x8e\ +\xfd]\xe8\x11!\xec\xf1TO9\x95\x9b\xac\xb9M\x90\xab\xc5\xd34R<\xe3>\xcaJ\n\ +\x95\x1ao\xda\xed\x82y\xd2UI5E\x97\xe0?\xf1O\xa4\xe0|\xa4pTt\xb3\xaa\x1d\x1b\ +btyg{\xbb\x84\x88\xc0\x14\xf7\x1cF\x93\xee\x1d\xf03\x98\xccF\xeb\x9c\xfd\xdb\ +c\x07G\n\xbf\x88\xf1O\xd5\x81\xff\xa0\x99~.\x1e#\xfa\x8f\x83\x0csY\xd9\xa1\ +\xe2\x19\x95\xe15\n\x89\xa6\xf9\xc5>\xa0\xdd\x0e\xf4\xdd\x88\xe7\xe4\xbf1*m\ +\xfb*[\xb3\x19m\xfb\n\xf3\xdd9\xaa\x8f\x817\xd2\xbe\x1a\xf8Ol\xe0\x96X\xf87r\ +~\x05\xd8Y\xf8s\x804=v\x89\xd7\xb8\x9c{[xwR\xd8\xc2{\x10\x8f\x88I\xc1A\x9f\ +\x9bA\x02%\x8dED\x90\xc9\x95D\xe7/\x83\x83&\x85\x08\xfb>\xb0\xf3p\x0e\x0bP\ +\xff\x8bh\x08\xc4(\xf8\xc6\xd3GE\x96\xe4\xef\xb9\xfah&>eele\xe5\x89V\x8c\xbb\ +\xfe\x8d\xa4\xeb\x96\xdf\x0f\xe10\x9f\x84\xdeYy\x92\xbf+\xf21i\x9f\xa0L\xbc\ +\xd0\xab\t\xfb^\xbb\x0b\x17\x00\x8c\xc1\x9f\xb85z3\xe1\x93\x1bNF0g\xa6\xa9\ +\xacp\xb2\xd8\xe1\x8b\xed\x15\xee\xdc\xfd\x12\xed\xc43\x99\xb4l\x08l\xb8\xc1\ +]f\x88\xcep\x0e.\xc2z\xe1\xc0\x92\xd8vv\xe6|\xfd\xed\x7f\xc6\xd3p\x0c\xfeup\ +\x8a\x8f\x06\xfb\xa2\x0b\xe6F\xbc`hTn\xb8c\xf6\xdc5\xb2%0B\xd2\x12\xee\x85S\ +\xe2\xfc\x1d@\x99\xce>\xc7\xf6\xd6\x97\n\x1c1\x82z[\x8b}U\x9e\xf4\x81~\xd1\ +\xb1\x17aO<\x1bn\xc5\x98\xa7\xdc\xc6\xf2\x0f\x06\x0b\xc4`\x11\xe8;\x9ck!\xe5\ +q\x90\x18\xddE#\xbb\xb83\xfd\xd4B\xd5\xb9!\xdc\xe5\xa0l\x14U%\x86\x1f\x15\ +\x05`6m\x01\xcb\x87\xca\xa1\xf0F\xdf%\xf6\xefr\xe0?\x8b6\xaf%+x\x08\x07\xd9\ +\xbd\x07K3W \x84~lU.\x82rK.)CJ\xe3g\xa6\x7f\xec\xf9MRH\x01\x16\x8b\xc7\x9c`\ +\x827}m\xb0\xe7\xbf\x1f\x03\xfdk4\xc6\xeb\x96\x92yK\xee\x0c\xb0\xc75\xf3\xb0\ +$\x86\xdf\xb0G\xcf\xd5t\x03\xe50\xec\xa0\x8by1\x1a\xea\xb0\xadsCNI\xdfw\x10~\ +T,\xc6\xe8\xae\x98\xa5\xebr\x0b\x02\xb3\xbe\x9ah\xfb\xa8WS\xf2j\x0f\xc6y\xe3\ +\x86;\xe6\x90\xb5\xe2:\x1f\xc2p\x83\x02\xe4\x9cZBk\xf8\x80\x93\xb8W\x14\x9d\ +\\\xb9\xb8*\x9e\xd5\xa8l8\xa0\xf1\xc5:\xafW\xb0i<\x8f\xfaw9\x8e\xcfq\x93\xcf\ +\x91\xf3[\xe29\xf4\xef|\n\x05\x05\x0b\x0b]\x86\xff\xec-\x1a%h\x8ay\x14t\xd1q\ +\xd5)7\xbcg"\'\x80\xe1\xe6\xbc\x7fM\xf5:3\xfdUg|\xe90*\xefv\x1d\xff\xec\x1b\ +\xef\xf0\xc3\xb0\x8f\xf3\xaf\x0c\x96v\x05\x7f\xec\x03.yR\xb4\x0f\xe6\xcd\xb9\ +l\xff\xc6}pWL\xd0E\x13x\xc2)\'a\xce\xbf\xfd\xe6]\xfe\xceo\xfeZY\x13\xb0\xaa\ +\x1f\xef}\xe1\x81%\xff\xa3\xf2\xd8\x85\xc43\xfa^y\xd6[i\xf7w\x1f\xcey\xd8utn\ +V\x8c-\xcd9\x86\x0c\x9e\xdb\x18\xd5\x8c\xb6\x89y\x00J\xb2\xf8\x05#2\xecM\x91\ +\xa4\xc8-y\xf4-\xb7$\xa0)\x1c\x9e\xf9z\x1d\x9a\xaa=11\x02\x8b\x1d\x08\x1d\ +\xd2~\x1e\xfc\x1b#\x96\x90\xc3P%\x1c\x95\xd6 \xef\xd7\xc1\x13m\xef\x9bK\xe0\ +\xcfa\xa0\xac\x90_T\xcdu^~\x9ep\x9a\xee\xb0B\xff\xf0\x1d\x9c\x86\xf1o\x97\ +\xf0\xe40\x85\xa5Ikh\xbck\x98\x13\xd1\x94\t\xe7\xc0\xf9\x96gQ\x88A\x89\xf1r\ +\xfe\xe9e\x85\xa0\xa7\x88\xf8\x81\x17\xa6Q\xb7\xc8pq\xdf\x0c_\x8c/\xac\xf6\ +\x1d\xf4\x81M\xb7\xd4\xba\xc4\'^_\xed\xffk"\xac\xb8\x15$yt%\xf1)\xdb/-w\x9c\ +\xf0\x07\x0f\xe7,\x16\x1d\xb8\x96i\xe3\x8b\'k\xb1\x84\xff\x11j-W\xe4\xd4\\z\ +\xce\xac[d\xc5\x18ZNF\x8d\xfbDwe\xa4\xc4dE!\xc7\xef\xf2]\xcb\xfb\xca\xdd\x95\ +\x9f\x9a]w\xb52Q\x90_%\'\xc7\xa8\xa5\xaa+\xe7\xf3L/\xe0A1*\x87n\xad\xb8\xe1\ +\x8a\'(\x19\x04\x12\xf7G9>\xda\xfd1\xf7\xb6Z\xbe\xfa\xd5m\x1a\xf1\x85\xd9\ +\xac2(?M\x15\xbe+\xa5\x9cn\xd88\x11\xb8"\xc2iT\xc4{\xee\xdd\xbb\xcbt\xda\xf2\ +_\xfe\xc3\xdfA\xe3K\xac\xa9%q\xf6A\xe9\xd56\xc2\xf4\\\xb5\xd3\xc6\x1e\xd7\ +\xaa\t\x19\xae\xea\xe4He\xa5l\xf2~\xf1cbT\xbc\xf7lo}\x89\xe2\x00K8\x97\xe4\ +\xe1Yq+\xdcl<\x8d\x0c\xe5\xa5\xaa\xfb\xc4\xfe\x8f\xa1\x87\x03y\x15&_N\x0c\ +\xe4\x80\xe8n\xa6\xc7\x9b\x82\x12\x16\x96\\\xdb\xab)7\x17\xe2?\xe7\xcb0\x84\ +\xd2\xf2f\x1b*\xb4\x06Fe\x86\x8dp\xd8?B\x9cp\xf7\xce6w\xef\xfe\x05\xee\xdf\ +\xff\x03v\xbb\xae\xf2\xd6\xa5D\xd1\xc5w\xa1\x7f\x8f\x83\xe65\x0b\xc1\xe4\x10\ +X\x84F\x96h,\x06"\x9e}\r\x84 \xb8\x18\xe8\xa3\x10^@?\x1f\x07\xfd\xe7\\\x86v\ +\xe2\xb9{\xf7\x17\x00\xf8\xd6;\xef\xf04/\xe9\'D\xff\x06\xc3\x10ZP\x06\x81\ +\x1c\x11\x88f\xd9\xe7H\x81p\x8a\xba\xdb\xc4\xee\x8f\x89\xe1]b\xb2\x16\xcd\ +\x93\xe4Y\x0e\x17\xaa*\xed\xa4\xe5\xce\xf6\x8c\xb7\xbf\xf9\x0e\x8f\xfaG\\\ +\xf5\xafT\xc6\x80/\xf9fY\xf0XO\x16{\xeeB\x15\xe7\xf4B\xf85*\xd1]\xab\xf2uR^\ +\x94\x08\x1b<\xe7i\xda\xbb\xcf\x17\xef\xb1\xb6\xf8na^\xab$:\xca\xa1\xbe8\xe4\ +\xcb\xd5\xde_\xc3/\x89\x9eV\xf8\xca\xac\xe5;\xf3.%Ug\x8b{\xf8m\xa1\xff\xa0\ +\x94\xb6\x02\x97\xc0\x9ffqN\xde\x08h\xe8x\xc3\xaf\xd0\x88\x1f\x85!\xa4\x91\ +\xc4\xc0\xa9\x14\xa0\r\x10\x8a\xd7*\xf3\xab\xfc\x9b\xc6]\xe1\x95I\xcb\x1b\ +\xb3\x19\xff\xe0\xbf\xfe\xefy\xac7\x90\xc6\xdb\xbcbVz\x028_\x94\x8f@R@/\xa1\ +\x1fe\xa5\x84\xf0,O\xcf\xf8\xccI\x98\xf3\xe6\xbd\xdf\xa8<\xc5\xb0\xe2\x12\ +\xcf\xcb\xc6G\xf1\xc6\xd9\xa45\xfd3\x9ej\n\xc9\x86\xc0-\xefym\xdar7\x04\xee\ +\xdf\xdf\xe1~\xef\x891\'\x82Wx\x8bZ\n\x10JqK\x12\xea\xb3\x0b\xc20\xa64\xac$%\ +JS\xbeX\xce+\x19\xdf\x9f$0\xb7\xb7\xb7\xf9ko\xde\xe3\xbd\xc4o\xa0\xeaw\x94\ +\xf9\x0f\xa6\xcc\x1d.\xbe\xcf\xaa\xbcb\xfb\xdd\xe5p\xcf\xa00I\xde\xbbqP\xbc\ +\xfa^\xe9\x17\x1d\xd1Y\x7f"\xe7.\x86?\xe31\xd3/\xd9#\x96\xc3x\xd4\xf6\xd8\ +\x90WY+\x16q\xe7\x9bC\x12:c\x03\xbdL=\xfd\xdd\xdaz\x83\xd9l\xc6\x83\x07;\xc4\ +\x08\x87\xf1\x94\xabi\xef\x9b\x12&\xf4=\xa5uH\xdf+\x8b\xcb\xe0W\x05w\x8a\xb8\ ++#^X\xf3\xcd:/\xcc\xb9\xe4\xf9^\xec\x00\x9a\xc2^\x95\xf2\x93\xee\x9b\xdb`\ +\x80)?\xf5\x10\x91\x91Q\xe2\x1c\xb4\xadg\xb7\x13\x1e\x85@\xf4mi=\xb3\xdb\x85\ +3\xf2k\xec9\xab\xc3\x17$\xab.\xee#\xa2\xc5\xb5Kvq\'\xe6]\\\xbe\x9a\x93\x8e\ +\x07+\x7f\x14\xc7N\x8b0m=\xbb\xddX;\xcdL\xffL~\x893\xfe\xb5\xbb\xdb\x11O\xd6\ +p\xab\xebv\x8f\xe9\xf9\x0b\x90\xe1\x17\x19\xaaT\x8a\xa5\xed\x00V\xb8\xc11\ +\x87i~\x13\x1e\xf1\xd5\xbb\x7f\x19\xdf\x98\xf5]{~\x9c[\xc1\xb9Mr\x05EF\xb6\ +\xc36\x7f\x1e\xeb\xe9of\x08\x0e\x98N[\xfe\xea\xf6\xab\xfc\xcb\x14.\xea\xba\ +\xc1jW\x15\x92\x93\xe3\xdc\x11U\xb9!\xc7\xecq-=wl\x19\r\xe1\x13X,\xde\xc5{\ +\xcfl\xda2\x99x\xfa>\x94kJ\xbf\xa1\xacq\xa4QJW%UG8p\xf1\t\xaa?\xa5\x9d}!\xfd\ +\xbe^\x07e\xde\x85a\x13\xaa^\x0e\x7f%p2#un\xc81\x81\xf4L\xb9eBE\x95U\xedX\ +\x15\xcfl6c{\xeb\xf3\x8c\xd7\x8ca\x86wM\xf9\xa98W\xe6-\x1b\xe9\xb7\xc5\ +pN\x82)\x8f\xc3\xcak\x18u\x9f\xd9\xec\x17\xe8\x16\x81E\xff\x01\xd2|q)? )`ja\ +\xa4z\\\xc6\x7fF!\x9d\x84\xc3\xd5\xbe\xe3\xb6S6\xeb\xaa\xd3\xac\x04\xe5\xa7%\ +\xfa\xddt\xe0X\xe5\x9a\x13V\x12]o\x08\x15/XAd\x13\xe7\x847\x9a\x96\xff\xe8k\ +\x7f\x8d\xff\xf6\xf7\xfeOd\xd2\xa60\xc0,=@\xd2>V\xe6\xbb\x1d9\xaf\xc9\x92s/\ +\x86\xbf\xf4\x00\xb3\tX\x05\x1b0\x99\xf8\xa2\xf8\x00\xc6\xeb2?\x8c\xf6~\xa5\ +\xf0\xdc\xa4\x0cH\xe5E!\x1b;\x8aCh\xc4s\xf7\xce6\x1f\xdc\xff\x01\xef\xc6\xc1\ +\xeb\x95+um\x91\x12\xfd$\xfe\x19O\xd6\x90\x8du\xeb\x9fq\xce\x18\x0c\xc5\x94w\ +\x96\xfa\x005b\xc2\xdc\xa1\xb8\xb8\x87\xca\xedb\x18d>i\xdeMo^\x83\xfc\xf8\ +\x92\x8f\x93\xaa\xe3zE\xba\xff\x878\xfb%\x84\x94\xb0]\xede\xdf\xf8D\xf7y\r\ +\x8c~v\x17\x00\x1dk\x0eV\x90\x0b\xe1\x87\xe5\xfd{\xa5P\xafs\xe6\x95\x89\xe5G\ +\xd9\xd0L<\x0b8\x9c\xdf\xe70\x87/\xd3(^\xc9\xbc\xb72\xaeDh\'\xb7\x99L<;\x0f\ +\xe7\xc4\xa8\xdc\x90+\x16\xae\x03V\xa2\xb2\x96d\xc4\xee\xee\xbc(\x83"\xfeb\ +\xf8]6\xd0\x07\xde6L\xea\xca`\xece\xe5\x0c\xa5OI\xd99l<\xda\xd7\x0c\xe2k\xd9\ +g n\xb3|\xd80\\\x97\xff^\x13\xe1\x00k\xe5P\xcb\xdf\xa41\x8eA\x1b\xded\x0b\ +\xbe\xfa\xc6])%\xa2\xa5\xc4,\x85 \xc4A\x1f\x81\x94\xb1\x9d\xc3_\xe7x\xdd\n`\ +\xdd"\x8c\xdd\xc3i\xc3\xf8\xc4@\x1b\xef\x07w"@\xb2\x80M\x0bU\xe2\xc9\x1a\x83\ +\xda\xb1\xf4\x8c\xbc\xe9\xca\xf3\xa4 \xda\xee\'\x1c&\xa6\xd2\xef\xfe1w\xeel\ +\xb3\x99\x13\xdc\x10V\x97b\xc6\xe2*\xa1\xe0\xc6\xca\xcf\xe6\xd2\x8a\x1cD\xdb\ +\xe0\xc7\xd1\xa0\x9b\xb6-\xf3\x1f<\xc2\xdd\xfa|\xb1\xc2jfp\xde\xc8Bi/\xa3\ +\xdfe\xcf\x82\x14\xfc\x13A\x1a\xe1\xa4\xff\x10\x17\x03\xe2,lg8\x1e\x9aee\x06\ +\x1b\xfb\xec\xd5Xa\r\xe1yn\xf2\xc7\xa0\x0c\xe1\x04Y\xfc!\xb2\xf5\x05\xfc\xc4\ +\x8f-\xb1\xa4P\xf6\xbdr\x8a\x96\r\x7f\xdeh\x9a\xc4\x10\x92+=[\xd5\xd9\x8a\ +\xcf\xe5\xf0\x19\xb6F\x84.\xc1\xbb\x812\xf1\x9e\xc3\xa8<\x0e\xa1l\x86\xbc1`\ +\xa0\xa1\x18a\xafW\xae\xf6\x1d\x1b)6o\x95G\xe6u\xa9)\\U\xc7\xf8?Y\xbb\x10\ +\xfe\x9f\x85\xfeG\xa3\x82\xf9 Z\xd8\x08\'l\xb0O\xa4\xfd\xc4\xe8\xbf\x91\xa1\ +\xeaB\x9c\xad\x95yF@\x92E\x9c\x132\xedgB\xdc\xfd\x83\x91\xcb?\x81_<)9\xbc\ +\x98\xf7B\x8c\xb0\xee\x84i\xdb\x16\xc6\x92\xdd\xcf\xde[h)\xdf#\xe7\x01\x18\ +\xfc\x00\xca\xf1\x0b\xe8Gc\xe5\x818\xe35V\xa2>\xc59SfVKhl`\x9e\xb1\xeaw2Z\ +\x92\x08W\xdd\x10\x9a\xc9\x95f\xed\xc4\xf3\xee\xfc\x11R\xe1\x7f\xa8\x10\xb5\ +\xb0@T\x0b\xdf\x1c\x97\xbd{\x91\x02M\xf1\x14e\xf8\x1dF#W3\x1c\xacT\xccz\x1cb\ +\x1c\xdd\x87!\xe7!\xc3\xdf4f\x94\x99\xb2m\x9f\xdf\xbd{\x97\x95\x7f\xf26\xe2R\ +\xd9x\xa6\x9fh4\x97\xf7\xaf\xed\x83\xb3\xde\x803x"+\xf1F\x837P\x0e\x13-\xac8\ +S\xd0\x0e\xe2\xc0\x17\x0fb\xe2\x85\x89\xf7\xacW^\xdb\x9c\xccn\x9e\xe9\x03V\ +\xd5\xae\x0b)\xb4\xb2)\xc2\x17\'W\xf8\xd1\xae\xf1\x82\xc6\x9b\x121\x0cM^\x08\ +e\xf1\xe8\x19n\xf5\x18=\x84\x8b\xe8?f\x9cB\x92\xb0W\xd2|m\x1f\xa8\x02b{m7%\ +\x89\xf7}\xe0\xf1\xa2\xa3i<\x13\xef\x07e+)R5m\x99\xc6\xf4\x13\xe0\x97\x86\ +\xfd\x99\xf8Y#\xd0T\xf4?\x00\xa5\x85\xfe\x0f\x0e\x8fp\x97\x9c\xbe\x99\xf7\ +\xaf\xcb\xcf\xcd\xb9Ln\xe0\xa3\xd9\xd8\xb35\xf2V"\xef\x8c\xcf\x1d\xf6\x83\ +\xd7<\x17\xd18\xc6JPyV\xe3\x8b\xc7.wln^\x9e\xd2\xb6-\xb5\xc1\x03\xd0\xf7\xd9\ +\xa0\x16\xf4\xf0\xe8B\xfc\xd7\x05\x08\x99n\x9b\xa4hfM\xc6ZMx\x9cS\x0e\xfbc\\\ +?\'\x87\xdaG\xf7\x82\x11\r\xd9|\xe1 \x1e\xb0\x99B_\xf5\xb6\x89\t\x7fy<\xef\ +\x03\xf8\x9bv\xb2\x82*a\xa1\xc4\x93#\xfa\xbd1\xfc\xa3\xe5\x90\xb2x\xd9\x8d\ +\x9d\'\x068_\xb9\xfe\xf2?\x05\r\x96_\x90\\[\xa5\xeb\xa6\x0ee\x8f\xae\xba_\ +\xddK\xc0\x89\x182\xc4\x92\x145jiH(\xcebvMc\xc4+\xc9%,\x1b\xe7#?\xc3?zV\x9e\ +\x83Kn\xe7*dr\xd8?b\xe2=+K\x9a\xe3\x10K\xdc\xac,!)\xd6O\xad\xf8\x0c\x99\xee\ +\xc2\xb5$8\xd7\x9cYC\x1aOXYo\xf0^\xd2<\xed\xbb\xb5K\xcaP\xa5\xc6\x8d\xab\xe6\ +\xe1 \'\x8d\x99W \xf0\xb4\x7fV`h\x9a\xe46\xaf\xe6\x01U\xd8)\x11\xd0\xba\x03\ +\'\x1e\'W\x92&\x9e\x92}\xb3R\x98\xf2n\n\xee\x85\x11\xfcp9\xfc%l\xe2\xae\x94M\ +\x9bG\x8c\xa1J\n\xb5\x18|>L\xfdl\x06<\x17\x0c\rt\x07l\xe8\xfb\ +EHg\xb8b\nS8g\x02U\x84\x11\xfe77\x8e/\xc6\xff\xcf@\xff\xb9?\x85\xed\x85\x83\ +\x02\xb3o\x92%\xef\xe0\x90+g\xf7\xc2\xc7I\xffYy+\x80\x0f/Ku!\x82&k8\xf6\x8f\ +\x97,t\x9b\xbf\t\xd7\x81\xf9\x97poT\xba`\x9fom\xcd\x92G\xe6\x03\x9c\xcb9\x1b\ +\xc9\r\xce\x00{\r\xffy\xc2\xfe<\xf8s\x19\xabM\xa1\xc6\x97\xe7\xa4\xef\xacb\ +\xb0\x82\xaf\xac\x11Y\x19:K\xa3.3b\xbb\x11\xe2\x8c\xf1\xcff3H9!f\xc0\xa5~E\t\ +\xf6vb\xf0\xaf;I\xfb\xf7r\xf8\x07\xe5\xa8\xda\xcb\x9c 9oA6Kh\xa2^\x9f\x8c\ +\xe3+\x89\xc6\xd6\xf3\xfc\x9dpU\xce\x96\xef\x92\xf8Y;\xf1|e\xd6\xa6\xbc?M\ +\x02\x83\x94xn\xfb7_\xbb\xe6\xf4\xc5\xfc\xa7R\xb8\x00\x0e\x13M,\x16\xa1\xf0\ +\xbeM7\xb6\xf0C\xaf)_\x8d\x12\x16\xcb\xff\xf2\xbd\x9c\xdb\xac\x04\xd9p\xed\ +\xab\x13\x8f\xc4Gh^\x83D?\x99^\xb2W\xb1\xb9\xba\x8esr\xe9\xfe\xf5\xcdYO\xc1\ +\xc8\xd8H\xaf5\n\x1b\x8d\x85k\xb3\xc1(\xce\xbc\\\x85\xa6\x92\xcc\xb0\xeb\x06\ +\xc1n\xd1\x8e\xc1#^W\xb7\xe5\x0e\xec\xe2\xf4\xec\xfem\x8c\xf7\xbc\x88\xfe\ +\xed9g]\x14\xce\x99\x11\xec\x18:\x8d\xc7hk\xeeDp\xfaA\xe5\xf9\x94\x81\xc6\ +\xd2\x18\x0cc\xfb\xd7N}\x1f,d\xb9\xf9\x121\x0e\xfc\xb8\xde\xbf\x99\xc7^\ +\xc6\x7fr\xb5X\xcd;\x97\xe7\x92\x15\xb9\x88p\x18\xde;\xa3\xf8\x80\x197\xe5\ +\x12\x19xA\x1e+n\x05M\x8d:3O\x96\xec\x89w\xa6\xe8\xf6\xaa\xdc\xf2\xd7\xcd\ +\xb0IJ\xf8\xe6\xc61\xcd\xd51\xfc\xa3\xe5\x88\x95\xa5\x9b\xad\xc0:10?\xa0\x94\ +y\x92\x80s \x95\xf5\xe8\xa8\xc3_\x83F\xdcl\xac\x11O\x8e\x89\xceW\xaf\xed\xa2\ +\'\n7Q\xd4\x99\x17\xa9\xf1\xbe<\xb3O%|\xeb\xe7 k4\x96\xe2\xfd8\x9fb\xd9u\x8f\ +\x1e#\x1eA\xad\xba\xa0(<\xb6\xc8!X\x16y\x08\x83\xc0>[>n\x9a\xe9\xa6\x08\x9f\ +\x9b\xcdx\xf3\xde\xbd\xb2\xe4\xceV\x85\xf9\xfcG\\\x9bl\x9b\x801\xd3\x83\xf5\ +\x17\x82\x9f\x1a\xa6\xa9\x96|\x84\xa6\xc2\x7f.!\x8c\x08\'a\xc7\xac\xee\x94\ +\xc4v\x1a\x0f\xcb}N\x9d\x9d\xa3dy4\x0c.\xe9\x1a\xfe\xa5\xb9\x98\x05\xd7\x13\ +\xfa\x00x\xbc\xa8\xad\r|d\xf8\xcd\x83\xe2G\x02h\xe8k3\x1c\xc5\x80\xb3\x86l\ +\xf1\xe4\x98}\xdd\xe74*M\xd3r\xb5\x11\xf6\xfa\xccD\xa8\x04\xea \xd8\x86\xb0\ +\x86\xf2TO\xb9\x91\xe6\xf2\\A",b\xc0{O\xd3hr\xcc\x88%\xec:\xb8~Nb\xde\x08\ +\xff?\x03\xfd\xdb\x0f\xd2\xdc\xdccr\xb1\xdc\xa6H\n\xfd\x08\xd78\xe04\x95\xc7\ +~\x12\xf4\xafQ\xc0).\xe65?\xc0]\xbdM<9\x1e,\xc98\xfc\xd6\xf1\xa8\xe0\x16\xb4\ +xO\xf2\xfa\xa9\xda5.\xe1\xdb9A\xfbn\x94#\x01\x87\xe4\xc6g\xc31/\x86\xb7\xecU\ +\xea\xfbda6\xc9\n\xe7\xfc5\xe8\xcb\xf3\x86\xfbg+\xb5\xb6`\xeb\xf0m\xbdv\xb5\ +\xf0^\xae.\xa9\xbb\xce\xfa\xc6\xd6w\xb1\x08\xdc\xd9\xde\xe6\xb6\x80\xf6\xfb\ +\xa8x\x16\x04\xeb\x0b\xe3\xc0\x0b,z\x19\xd3\x7f\xce/{u\xf4$}_{\xf5\x81\xe3x\xc4\xd1\ +\x12\xcf\xf1M\xca[K2:\xf3\x0b\xe7\xa0g\xb86\x1b*w\xb6\xb7\xcf\xe4\xd0u\x9d\ +\x19I\xd7\xfc+\x80\x10\x12\xff_wr\x06\xffK\n\x90\xb9\xa7\x84\xa1\xa1\x13\xab\ +\xd7ho_/7\x8eI\x99\x10\xb1PLL\xda\x96kr?\x9a\x8a\x11\xa5\xff\x8au\xb6zL;\xb9k\x8d8\x00iH\xde\x95\x8b7@V\x16\x87\ +\xae\xd4\x0c\xf8w\x16>\xd4\x84\xd3\xbd\x10\x984R6[\xe8\x8d \xfa^9\xd6}v\x1e\ +\xee\xd0GK\x8a,\xb7\xaf\x84\xb7s\xf0\xe6\xbd{<\x9c\xff\x90\x92,\n\xac\xa8\ +\x12\xb0DJ\xc7p\x08\xdfG\x81?\x87\x88\x06/\x8cm2?\xb1\xf8~\xd7\x85\xe2)\xc0\ +\xd9\xd9O}|\nb\xcd\xc8n\xfb[|\xb8\xf8\xc1\xe8\x9e\xb5\x02D\xb9\xb7\xe1y\xc3\ +\xadX|\xffd\r\xb7z\\6W_U\x7f\xf5\xd9Z\x1b\xd1\xcf\xf9\xe3g\xa1\x7f\xa0(3}\\\ +\x19\xddWD\xb8"\xc2\xbe^e\x92C\x81\x9f\x00\xfd;(\n\x99\xb9\xc1o\xe2H\r9+\xfa\ +\x89\x1ah\x9a\x96\x187\x96\x94\x88\x14&\x81B\x0f\xa4}\xa4\x98w5\x979\xcf\xa6\ +-\xd2x\xf6\xfaEi;p\x8a\x95^k\x1c\xf2M\xfaL3.\xe3\xe2b\xfc\x0fM\xd1\xc6^\x9c7\ +Z\xe1j\xe3\xd9\xdd\xed8Ly$\x999\xff\xea\xd7\xde\xe2\xf7\xde\xfefQ\x96\xcfS\ +\x8aN\xa4%\xf6]\xaaX\x1a\x9a\xac-B`\xcd\xc1K\x93\x96\xf7\xb5\xc3\xb9\xd7l\ +\xfd\xd2^Z\xc4\xc1\x8bjp\xcb\x12\xc7<\x1f\xff5\x8d:\'\xbc>\x9b\xf1\x93\xfbs&\ +P)w\x16\x86\xf8\xd6;\xdf,\nb\x0e\xeb\x9d7"\xc2;\xdf\xbe\xcf\x7f\xf1\xf7\xfe.\ +m\xdb\x16\x8f\xf4\x9a\x83\xad\xd9\xe7qo\xff\xef\x88|\xc1z\xc29\xb5\x9eW\xa9\ +\x02k\\\x8e\x0f\x17\xf2\x1f\x18\x92\x85S"\xaf\x08\xdch?\xcb\xfd\xfb\xf7\x81\ +\xdf\xa8&jc>\x9f\xf3\xa8W\xde\xcd\x1a\x7f\xaaR\\-\x9eE{\xd6\xaax\xbe8{\x8d\ +\xff\xe0W\xfe-ny\xe3-\xeb\x0e\x8e#L\x9b\xc8O\x1d\xac`dw\xe8\x02=>\x85\xce\ +\xecy\xcb\xc2\xf4\xe25\xd0\xe2\xb1\xcd\xc6_;\xf1\x83`\xcc8h<\xae7\x9a\xd9\ +\xdd\xed\x98N\xdbd\x04\xa7u\xf3\xafC\xff\x13\xb4*\x0c\x10\x91JQ\x85\xec\x95w\ +)4-\x1b\x06\xff\x89\x0b\xa8\xf3\xe4\xb0 T\xfc\xf3\x12\xfa/\x878\x17o-\xc3\ +\xfeM\xfc\xd3\x1a\xe0*\xe2\xac\xa7M\xdf\xab\xf1\x1f}\x8a\x83\xd29;\xd3\x14\ +\x08\xcd\xe4\x156&\x9f\xe7p\xf7~Y\x0fS\xf2W\x8aa)"\xb8f\xc2Q\xcc\xc7d\xa8\ +\x85\xbeF\xf43\xf0\xa9\x8bFq4\x14\xcf\x0c\xdcNg\xccu\x8bPB|\xe2\x84C}RynM\ +\x99\xb9s\xe7\x8b|\xfd\x9f\xfc\x0f\xa5j\xb1\x0c\xb9\x81\x93k\xac\xb2\xcf\x8a\ +X\x91\x8e\xf6\xef\x17#\xa9\xde\xf7}o\xbc{\xady\xa54\x80-\xfcs\x89~Fo\xb37\ +\xa4nm\xeeV\x8f\x11\x07\xdb3#\xa8\xdd\xdd@\xc4\x92\xa1\xeen\xb5tA\x99\xa7\ +\xb35r\x17\xd4rx\x9e\x0e{.W\x05\r\x9dH\xa5X\r\xeb\x92\x81\x1cW\\\xa9\x1a\x93\ +\x88q\xe8n\x1b\xf5b\xe4C\x8e\xa3\xfa21q\xb6\x19\xb7\xb6\xb7q\xbb\x1d]\x17\ +\xd8\xd3\'|v{\xc6\x15\xa9\x11\'\x84\x10\xb8\xff`\x87\xd5v\x9b\xdb)\xb7$b\x16\ +]\xdd\x82{-m\xdcw\x1f\xbc\xc3\xd6\xcc[fzFn\xb4\xa4\xd5\xeb\xfe%\xdb$"\xb8\ +\xc4\x9c\xcf\xcbMX\x1e5<5\xfe\xb7\xb6fH\xd3\xf1\xe3\xdd\x8e\'!\x94j\x8f\xc9\ +\xc4\xa3\xf1\xc4b\xf3Y\x10Gp[o\xd1\xa6\xb5\xcc\xc2\xcc\xc5=b\xaeB\x85!\x04>7\x9b\xf1\'\xf7\xe7L\xd3z\x0c%\xd1i]\ +\x9a\xa1D\xf8#\xc1\x9fs\x10\xec\xba\r\'\x162\ +\x97.\xf1\x7f\xfb\xeeD\xc7\xc5\x05\xf7\xbez7\xb5?Q\xfc\xf6/\xb3\xea69t\xd7,\ +\x04\xea\xcc\xd0\xcd!\xd0g\x8b\x0f\xd9\xe0I\xc2QZ\xfb\xe41\x0c\xfd\x13V\x9aW\ +)E\x06\x8d\x14X\x96\xf7\xefX\x01\x12\x98N\xad\\o\x88\xc7\x9a\x8bp\xde\x05\ +\xa6\xadG#,\xba\x0eP\x1ev\xc1\xaa?\x1aS\x00\xd6\xa2r\x1c\x87\xf7\xf9\xb8\x06\ +\x19m\xcaA\xe9\xb08/xo\x87\xad\xb9\x14.p(\xc7N\xb8\xe6\x86\xc5\xe8\x13<\xa1\ +\xd7be,\x8fFL\x90fk0F8E\xd9\x8b\xb0\xdbu\x05\xfe\x1f\xdd\xefx\xd9\xcf\x8c\ +\xc9:h\x92\x06\xb9X\x04\xf6"\xdc\x9e\xb4\x053\x03\xfcu\x05\x07\x80r\xd2\x07\ +\xeel\xdf+\xbf\xcd\x82\xe7\xc7\xbbs^\xd9\xfaJ\xdat6\x87\xdc\x0f\xe3E\xf0\xb7\ +\x13\x83\xd1\x12w\x03k\xe9\xda\xf9\xae\xc1\x1f#\xfcd>/.\xbf\xf3Z\xab\x9b\xb2\ +\xe5\x07\xcb%Y\x8a+\xb4\xa0\x81\xe0l\x03t]\xc7\x93>\x94\xb5\xf9\xc2\xf6W\x12\ +\xad\x98\x97\xa7\xd6\xacU=\xa1\x0f\x84^ ^\x02\x7f\xebQ\x95\x94piI\x8cA\x95\ +\xddE`\xd6\x9a{S;kN\xf5\xe0\xe1\x1c\xed\x03\xab\xe2\xd9\x9a\xcd\x92\x95\xf3\ +\x01W\xd3F\x13Yg\xb5y\x89\xdb\xfe%N\xfa\xf7\xa1W\xde|\xf3.\xa7\x95\x1bw\x92\ +\xac\xa3R\x85\x94\xe6\xb2\xe2`\x13*\xfc[\x95\\\xafr!\xfe?.\xfa\x8f\xb2b\xae\ +\xeaT\xa9\x90\xd7\xea\xb0\x82\'?\xef\xe3\xa6\xffL?\x07}`?\xb9{\x83\xc2\xbcK\ +\xf8O\xf0\x0f}\x86\x86\xf1\xef\xbcu\x8f\xf9\xee\x9c\xd8~\t\xf1\xc3\xa1\x90\ +\x8f\xa4\xe5$\xcc\x0b\xdc!\x18\xcd|y{\xc6\xf7\xbe\xf1\x0e^`Z\xd1:\x98"p\x80p\ +3\xd1S\xc6\xff"%C\x9f7r8\xd7\xf6/\x16\x86\x00\xfa\x10\x98\xefZ\x05i\xf7\xdak\ +\xf4\xbb\x0f\xc8\xc9\xf8]\x17\xd8\x9a\xcd\xd8\xd9\xd9\xa1i\xbfPx\xceh]\x1dh\ +\xf32{\x8b\xef\x8fh\x04,\xdf\xec\xf5\xd6\xe3\xb4c6\x15\xbcH9#\xd0\xac\xfe\ +\xe4UT8\xe8;~\xda\xfbK\xe9\x7f\xd2\xce\xace\x81\xda>\\sf\xa1\xab\xff"\x1a\ +\x7f\x8aon\x8e\x9e?m[~\xa8\x91+\xbee%\xf1\xacq\xc2\xaa\x16\xdes\xa3\xfd,?\ +\xdc\xed\xf8\xebi\x82kI\x91\xf3^\xf8\xea\xf6\xcf\xe3\x9aS&\xd3\xcf\x01\x83\ +\xc1\x96\x13\xd7U\r\x8eE\xd0\xcb\xe1\xaf\xf8\xa7*\xc4\x93#hn\x11\xa3yJf[\xdb\ +\xa3k~~k\xc6\xda\xb7\x7f\xc0\x15\xf7\x12\xa4\xa4\xf1\xba\x05\x83U\x9c\xde\ +\xe4\xf6\xd6]v\xdf\xf9]B\x08\x1c*8\xa4(dM#L\x9c\xd2Ng\x85\x86\x86\xc4{S\xba\ +\xfb(\t\xff\x1f\x85\xff\x18\xec+1\xb0\x1f={*\x89\xfe[b\x14\x0ev\xe7 \xd7\x8a\ +77\x9f\xc1xE\x06es\xdd\xad\x1a-\x8a7\x05\xe8\xad{\xfc\xaf\xdfz\xa7g{v\x97&\xfd6:\x98\x8a@\xb4sm.\ +\x83\xbfW\x98\xb5\x82\xe2\xe9{\xb3f\x82j\xca\x15\xb0,\x7fk\xeb/\xdclY\ +\xb1\xc9\x92\xca\xd6\xb2@\xeb\xdbK\xe1\x171%i\xda\xb64NK\xfeD\xaf\xd0u\t\xff\ +\xce\x18\x85\xaar\x94\xca\xa8\xaf:J3\xae\x10\x82y\x80P\xd6\xe5\x1aW%\x95\x8e\ +\x92\xbd;\xc2Q\xda\x80k\x99\t9\xdb|\xc7\xceBJ.\xadG}\xb8k#\x02\x93\x96\xd0C\ +\xf7\xf0b\xfc\x7f\x1c\xf4\xdf\xf7\xc9\xd2\xa8\xdc\xbb"\xc25g.\xdf\xac0}\xdc\ +\xf4/)\xe7\xa3m=2\xf5\xa3\xc3\x153\xfe\xb32\\+@Y\xd1[Ok\xb3\xe7N\xb8&\x94\ +\xaa\xa7\xabMC\x1f(\x0c-3\xd3i\xdbr\xd5\xc1q<\xe4J\xa2\xb7k\x99\xe6\xa3Ym`\ +\x82,\xe3\xbfW\xd8\xdd\xb9\x7f.\xfc`p\xe5d\xd4\x10,$f\x89\x9a\xca\xce\xc3\ +\x8e\xf5k/\x8d\x14\xf3\x10l\x0f\xfen2\xb82c\xcf\n\xc4i\xa2\x95\xc6_\xa1\xd7\ +\x80\xf3m\x15\x06^1\x05jk\xc6\xa4\x11\xc2B\x99\xde1!\\\xbc\xa6\xc9\x83\xeb\ +\x1b`2\xe3\xa5\x17\xd0\x8f\xf6\xcatb{^u\xa8"[\x8f\xcfFn\xf8\xac\x04M\xa7-\ +\x7f\xf8\xed\x1fps\x9a\xf7\xa9\xf1\x1b\x11_\xf1i\xf3\xb2\xed5\xaf\xb0\xb3\ +\xb3\x83F\xcbO\xaa\x9d9w\xee\xcc\xf8?\xe6\xcf\x98me%;U\xb39\xf3`\x9b\x17Kh\'\ +\x97\xf3\x9f\x18s\xe2t2\x04"\xf4a\x9d\x13i\xd9y8\xe7\xcd\xb7\x18I\x8d/nms\ +\x14~\x87\xd3\xd9\x97YS;\xf4s\x05\xe1\x9aS\x0e\x0e\xd7\x10wL\xae\x04\x13\x07\ +\x8fC\xe0Y\x1f\n\xbd\xe0\xe0f#\xfc$\x1c\xb0"\x92\xce\x9eR\x9a\xac$F\xa5\xf1\ +\xde\xfc\xc9\x93\x19\xaf\xab2\xbf\x04\xfe\xd0[\xe7h\xdb+\x03\xfe\xbb\xce\xba\ +SKRT\x16\x95\x87-WA\xe5\\\x14\x11\xe1y\xdc\xe4e\x81Gi\xae\x8b\xa0\xdcJ\xc6\ +\xd6\x89kF\xca\x8f\x88p=\xf1\xe1\x9b\xc3\xb4F\xfb\xb7I\x1e\xd2\xe9\xe4r\xf8U\ +\x8d~\x9c\xf3t!\x1b`\xc1\xf6o\xe8\xcc\x1b\x92\xf8ZX\x04\xfa\xc4\xd77b\xe0\ +\x04[\xfb\xbe\xb7F\xa1\x1br\xa58\x1f\x84X\xf6L\xd3\xf8\x12\x0e~\x7fa\xca\xdf\ +\xf5\xe9\xac\xf0\xff\x9c{er:\xe5G\x15\xfa\x11vw\xceo\x86(b\x93\xa2\x11\xa6l\x1b_\xb0\x8a\xb0\x1a\xfe3\n\x10\x11+\x9dnd8\t\ +;Y\x92\x9ab\xef\xeb\xce\x03!\t\xa6\xe1\xb4\xec#\xb5.\x00\xf9\xfdr\xc5\x84%/&\ +\xb7f30TI\xd7\x9e:\xe1@\x07"\xca\x08r.\x05\x84"e\xf1\xcf\' s\xa9\xf6}\x12\ +\xe4BI2<\x8a\xca\x8a\x1a\x81\xcf\xa6\xb3Q8*3\xc3\xf9\xc39\x8a\xf0la\xda\xe9Z\ +|\xca\x9e\xbb1z\xc6\x06\x87\xf4n\x9d\xe3\xfeC\x9c\x13s\tWe\x9f}\x1f\xf8\x83\ +\xf9#\xfe\xe6WS\x0c\x98:\xf5\xee#\xc0\x1fM\xd9i&m\xc9\xe9\xc9\x9d}C\xb0\xca\ +\xa6\xe7\xe1\t\x1b\xc0\xf5F\xb8\xd2\x08\xaa\'#|\xed\x85@\xbf\x08\xa5\xaaI\ +\xddU\x1cG \r\xbax\x0f\x8dp]6\x93\xeb\xd76\xd9\x9e\xbb\xc9\xf1R,\xb5\xc6\x7f\ +f\xde\x97\xc3\x9fp\x10\x02nb\xa10K\rH\x82\xb6\x1fb\xe0\xce\t\x8b>\x9f0\r7\ +\xbc\xd1\xc6|\xb7c#y\x80\xf6\xc3\x82}\xae"\xcd\r\x0e\xfb\xc7E\xf9\xec\xd3\ +\xa6\xbd\xd1\xac\xe3\x92p\xcde\xba\x03\xbc\x83\x1b>\xe65p&8\xceg?\x1f\x1f\ +\xfd\x9b5\xe2!R*xj\x05\xfa\x93\xa2\x7f\xfb\xfd\x80\xff\xc6)\x8f\xfa\xa1\xcaK\ +{P\xa7\xac\x8b\xb0\xa2\x00bG\x8c\xf4\x1f\xa0\xaa\xdc\xf0\xb9:\xea=\xf6\xe2S\ +\x8e\xdd\r\x0eu\x0f\r\x1f\x8c\xee\xdf-\xde\x07(\x0c\xe6y\xf8\x80#\x1d\x8e Y\ +\xee\xe7Q\x8fK\x1a\xa1\x1b\x8cj\xd6\x9a\xf7)i3\xe1?\xe7\xe2\xd4\xe1\x15\xe7\ +\xcc\xb3\xfb+o\xdd\x03`\xaf\x9bs\xd2\\\xe7\xc4Y\xab\x83u}\xcc>\x9e+\xf1\x03\ +\xf6K!\xfa\x98\xe9=N\xc5\x0e\x93\xb6%ts\xe2V\x8bKM\x05\xcf\xbb\xc07\x97\xd1\ +\x8f\xf1\x9f\xd0\xe7$\xf6\xdc\xc0R9\xf5\x9f%\xec\xbeC;I\xae\xf9,\x8cDX\x8b{,\ +v\xbf\x9f\xf0k\xcc~C\x0c\xde\r\x0e9d\x83\xc8!k\xfa\x94\x9d\xf9\xdc\xe8\xad\ +\x91B\xd3\x00w\xb6\xbf\xcc\xef}\xf3\xbfC\xef\xfc\x05S\xd6\xa0\x08\xe0\x08\ +\xb8\x98h\xe8\x05\xf4\xa3QQ\xb5\xe4[g\xee\x02\x00\xae\xf9\x9b|\xfb\xfe\xbf\ +\xe2?]\xfa}\xe3=^\xe0\xdd\x9d\x9d\x04\xef>\xd158\xb7\xc6\xaa\xdb\x04\x0e\xd9\ +#\x1d-\xe4e-\x19\xab\xa3\xca\xad%x/K#\ +\xc8\xcaF\xecM\xd1\x15,\x996\x1b\xc1uR\xb0o\x84\x85\xcba\xf9TY\xd8\x0c\xc6\ +\xd9I\xb7\xc3\x87\xb1\xe7$B\xb7\xe8\xe8\xba.\xf5\xf9\x11N\xfa\xf7\xd3\xfe\ +\x05\x10\xae\xa0\x1c%\xb9\x16c\xaex\x84R-\xca\xc0\x7f^\x94\x06\xa1\xaat\xc1\ +\x8c\xf8\xac\x88\x18\xebM\xed\x15\x92\xa89*s\xf1\x1c\xa9Ur\xb9\xa6\x05\xcc`\ +\xd8\xed:\xfa~\x8f\xc3\xdd9\x87}@CG\xce\xc7-\x9d\x9fUS^\xa3up\xd6(\xd6AZ|\te\ +\xe1$5m\xe5lk\x8a\x0b\xd6\xa0\xefA\x92\x072\xf6Z\x14\xf9\xacT\xad;!\x86w\x13\ +\x9f\xb45\xdb\x9a\xcd\x88\x11\xe6\xbbsV\xdd\x84\x83\xc5{\x83\x88p\x14O\x98x+?\xfd\xe4\xe8\xdf\xd6\ +\xd8\xe8_\xd8\x10\xcb\xa7\xea\xfbA@CVT\x14\xe461|\xc0|w\xce\x7f\xf5[\xffp\ +\xdc4,\xff\x8e\xe1\xf9\xe6\x01\xdaGUi[O\xd3x\x1e\x07k\xc9p@V\xe0L\xed\xcfL_\ +\xe3 \x00.\xa3\x9f\x1b\r\xecE8\xd4@\x08\xa6@\xe3\x04\xc9\x1d\xcc\xa3\xe0DY\ +\xf5-N\x8dq?|8/\xe1b\xfaw\xac\x87\x96\x93\xc1\x82\x85\xd2\xd9\xdb\xf2aH\xeb\ +\nkn\x93\x15\xb7B\x1f\x94\xad\xd9\x8co\xdd\xdf!\xf2V\xa2\xbfa\rF\xf8\xbf\x94\ +\xfe\xcd\x03\xad\x11$U^eo\xb7\xf7\x9e0\xe7\x8c\x10\xecU\xd9j_\xc2\xb9\xa7\ +\xc5Sh\xfcg-\xdd\xf3JR\x92\xaf\x81{\x8d\xcd{_*Fd=f[_\xb2C\x84\xa3\xe5\xdf9\ +\x06\xa59\xe5\x11\xbf\x10\xffM\xcaUQ\xd5\x92\x7f\xe3\\*\xe1\xf6\xaf2\x9f\xff\ +\x0b\x16]\xc7\xa4\xea\xa4(\x8d\xf0\x9f\xffg\xff\tO\x17\x81}U\x0e\x92R\xb3\ +\xdf+\x07%\x94\x96\x14\x10\x7f7)X\x87\x03\x1c\x89\x7f]\xd30\xf0\xaa\xd4\r\ +\xb8\x86\xff\xa3\xd2\xbf\xaa\xf5]\x8a\xc9[\xdb\x88\xbdw\xa2%-#\xf3\x9f\x8d\ +\xc6\x93\xcb\xef\xfb\xde\xc2-\xaf\xb7-\xdf}\xb8c\x86\xdc\xae\t\xd3\xae\x83\ +\xbf\xff[\xbf\xc5\xdd;w\x0b\n\x07\xef\x02\x9c&Ej\xc5\x81s\x9a\x92\x9d\xa5\ +\xe4\xe1\xa5i\x14E\xe22\xfc\xe7\xd1/:Hi\x0c\xf5\xbe\xcd\x86\xc0\xba\x08Gja\ +\xa6\xe7)\xe9WP\xbe\xf7p\xce\xef\xbd\xfd\xf6\xa0\xec-~4\xc2\x0f\x18\xff_u\ +\x10\xe3\x01\xcfRD`\xd3\xdb\x9aZ+\x8c\xd4\xac5.\xe5\xad\xbe\x00~\xf3\x84\xdb\ +z/\x18\xf8\x1en\x89\x7f\x02\xe8c\xbb\xa5j\xa9\x8a\xfcG\xbf\xfdu\xba\xaeC$\ +\xf0\xc1b\x97\x8d\x84_\xe7\xe0\xaa\x13\xe8\xb3\'|\x85\xd9\xec3E^\xda3\x84\ +\x83\x94\xff3\x99\xbe\x8e4~\xc8E\xae\x15\xb8\xa51\xfah2\x11\x16\x01\xbc\xa3\ +\x9c\x9e+"H\x14\xfa\xdcg%\xcf\xc4\x81\xa2D5A`\x0c\xde\x18_.\xa7=\x8afm.\x0b\ +\x8a\x1c\xe7m\x122\x8e\xd5NK_\x8b\x89X\xa1\xb8"s?\t\x13\xe0\x97o\x84\xb6\xf5\ +,\x16\xa1 \xadh\x87\x92sR\xe0\xc9\xa2\xe3\xf5\xbb\xbf\x08\xc0jmi\xb8M~\xedW\ +\xbfV\x04R\xee\xf9\x93\xb5\xd4\xa2\xe4\x9c\xf7|\x8b3@\xd2`o\xbfbn\xf6\xacm\ +\xbe\xc0\xe8-c:\xb5.\xd9uY\x1f"4\x1a\xe8S{\xf2g\x8b\x9d\x12\x12\x19u\xae\x8d\ +Z*\xacr\x1c\xff\x96\xfa\xd2[\xe6(Z\x13\xa9\x18O\x89Qy8\x9f\xb3\xbbk\x97j\x84\ +5\xd9\x1c\x88\xde\r\xcaX\xd6\xdbrI\xfce\nD\xdbz\xba\xc5\xd0#\xc3\xc2\x7f\xb6\ +1{\x1d\x12`\x05\x01\x81\xa8\xcf\x01\xc177\x99L<\xdf\x9f\xcf\x8b\xb0\xe9\x13\ +\x93\xcf\xe1\xb0\x8c\x8fo\xbd\xf3\x8eyN\x80k\xcd\x06\xeb\x85\xe1\xd8Z=\x8f\ +\xe6\x86\xef\x97\x84\xc4G\x11\xc0\x1f\x1b\xfd\xe7\x90\x1d\xa7\xe5\x1e\xd6\ +\x11z\xb5X\xff\x9f\x04\xfdO&\xe6v^\x8dCO\xaeA\x01N\x8a\x0fR\xb4A\xc3\x9b#\ +\xba\xa1[vfx\xb5\xd0\xcfM\x11Ip-B \xf4\x81\xd9\xec.\xbe\x11\xbe\xdf\xfd\xd0\ +\x14\x0e\'\x1c\xbb\xc1\xea\xca\xdeO\x81rb\xf6e\xf4s{\xd2\xb2\x11r\x97\xf8\ +\x84##vBO\xaa\x1cQ6e\x93\xa3Tut\xff\xc1}\xee?\x80\\\xf2l\xc7a\x0c\xcc\xfe\ +\xc4\r\x95UE)\x8eJtWXKk\xb4\x08\x01\xefo\xa0\xa1c\xb1\xb0\xf0x)\x19N\x82\xf8\ +\xa3(\xa1\xb3V\x98w\xa9?Q\xa1\x1f\x90h\x87D.\xe4\x06Q-\xc9\xd5zw\x19v\xde\ +\xbc\xd7\x16\xc5\xa8\x11\xcf\x86d\xcf\xe1\x15\x9c\xdb\xa4n\xd3\xb1\x9e\xf8\ +\xd2\xc8\xb3\x9c\xbc\x88w\xefl\xd3u])C/\xa7\x94\xf3\xd1\x0c\x80\xcc\x7fl\xd1\ +\x87s\x1b]\x14^n?\xc3\xf7v,\xe1\x7f\xb2\xd4J\xfa/\x7f\xf5^\xc1kV2\x8e#\xec\ +\xa7\xfe20(BO{\xcb\x01:/\x99\xdcZ\x8f\xb4\x80\xb5\xe2\xc8\xf0K\\R\xa2_\x00\ +\xbfT\xb8\x8fQ\xf0\xde\xc2\x91\xd9\x08$\xc2\xaa3:\xa2\xb7{\x87`\xed3\xae\xc8\ +\x90#\x16\x91r|\x08\xc0\xb7\xef\xdf\'\x02\xde\x0f\x86m\xed\xad:\x8d\xa9\x9d\ +\x85$oS\xa5\x0c\x95L04\x01\xcd\xfc\'dok6\xf8\\\ +\x85\xf7\xcb\x0c\x18o\xa5\xedu\x98\xfb\xe5&\x1d\xda\x9a<\x1a\x85\x7f:\xe3=\ +\xe2\x84\x8d\x94\x1c\\wr/2?\x0e4\x94\xe7\xd2\xa4\xbc\xc3\x9c\xcb\'\xfe\xe5"\ +\xf7N5\xc9\xac8\xec#U\xfdH\xf0\xb7)\x8f\'7N\xd4\x94\x0e\xd0$\xb9\xe6\x93\xd2\ +\xaf\xe9\xe0\xeb\xdc#\xaf\xdc\xba\x00=\xe6\x9f6\';t\xba\xce\xebtnx\xbf\xe9,\ +\xdd%j\xc0O\xbfd^@\xccp\xca\xf0\x9fG?\xa3\xe9\xe4\xa4\xc8\xd6\x0f\x89\xd2\ +\xeb)!-\xb7y\xb0\x06Ou\xb3\xb4\xe1\xd0\xb3\xac\x91\xc2P~\t\xd9\x93A\xd9\xfc@\ +\x89\xcd\xf6X\xc2r\xbdX\xc6\xf4\xed\xb3F(\xb9\x12\xfd\x0b\x84p^\xb8l-E(q\xef\ +&\xc2{\xf3wK\xbf\x87\x82\xd88\xd8R5?qP\xda\x89\x17\xefO\\\xfa\xd1\x92@UU\xe6\ +\xf3\x8e\xcfM\xb7\x8d`J\xec3\xcd\xf9r\xf0y\x9e*\xb22\x81\x16aU1\x8d\x0f\x17\ +\x8f\x0bc\x12\xd9\x185@\xccL&\xff6\x8f\x15g\xc4\x13\xe3)\xa5\xb9T\xce[J\xf3[\ +\xbd\xe29N\x04Ir\xdb;\x02\xc3\xc1\x98\xd9\x15}\xd6r\xcb#\xf49\xec5\x94r\xae\ +\xa7d\xde(B\x1f\xc5\x0e-\x05\x9e\x06\xe50\xfd~\xdazV\x9c\xb0\x08\x8f\x12}d\ +\xe6/\xecEr\x06A\xa1\x8f\xc2\x90\\\xa2\xbf\xc6*\xa7\xb2u\xd14\xe6-{\xa2)\xa4\ +T[j\x97\xd0\xd0\xc7E\xffC(\xe4\xa0(k\x9b"\x9c\xc6\xe3\xe4\xb2\xfd\x84\xe8?\ +\x0c\x8c\xa3\xf6\\K\xe3!%t7\xde\x97\x92v\x10\xfa\xeb7\x86p\x98\xcd\xc8\xfe\ +\xb8|\xa4\xc2\xe0\xf9\xc9\x89\xd9\xf6\xact0\xe5\xd4\x8c\x89\xe7\x8b\xae\x1c\ +\xc8)\xa2\xac\x01O\xd4*\xd9\x9e\xabVV\xe5\x8b\xf0o\xd7g\xaf\x0b\x8e*\xb7\xc8\ +\xe0\xbc\xe5\xaf\xb1`L\xe3\xa3\xbc\x91\xf4:Fe\xcfy\xae\x16\x85t\xd8\xaek\xce\ +\xfa\xd08\xb7Y\x94\xcf\xd9l\xc6\xbb\xbb\xbbL\xa63\xa2\x0e-;\xcc\x93p9\xec0\ +\xf4^\x111\x85\xcfE-\x9dl{Un\xbd\xf42\xcf\x1e\xfe\x986\xad\x11NXq\x1bDg\x15C\ +\xe7\t\x97\xa2\xe7$\xbc\xdb\x19\\~\xe0=\x95\x90\xd8\xda\x9a\xf1\xc1?\xfe\xa7\ +\xc4{o\x02\xf0\xa1\x0e\x95HQ\x93\'\xe1\x1c\xcfK\xc1\xbf\x0e\xbc\xa6\xc9\xe5\ +\xfc\x11\x9cx\xbcW^\x9a~\x8eo\xdf\xff\x03~\x93\xffx|a\xbd\x0e\xe9\xfe\x9b\ +\xa7\xc7\xc5ki\xc2j\x05U8\x8c:\x0e\x87\xd7\x13\xd5\xfdRn\x8d\n\xc7NK%\xe7e\ +\x8ag\x1e}\x95\xcc\\\xe7>9\x07Q\x92\xf2\xef}\nE\t7\xfdM\x16\xaa\xa8X\x88>2x\ +\x0ec\x9awV\x822\x88y\x8d4t\xb8\xa6%:\xe3\x0f\x83\x1c\xb1\xb9\x85~\xe8\xdc\ +\x1cS\xf3\xd3\x17\xcd\xc1\xe07\xfa\xcf\xebp\x94\x8d\x91\xe4\xcdrq\xec=\x8b\ +\xce\xf2\xc4H-(\xb2\xa2\\\x9cD\x95\xd1\x91\x8d\xfc\xece\xf9\xf1\xee\x0e\x11\ +\x98\xf8\xdb\xe4N\xca\x19\xfe\xe7Q\xd8L\xb2"\x97\xf7\x8f\xfa\xf2\x9c3\xac\ +\x89\xee \x7f\xc5\x19\xff<\x8af\xbch\x9a\xdbU\xfd)\xd9\xd4.y[\x8c\xc9\x7f9\ +\xc4+n\xb3\xf2\nU\x06\x02\x8cx\x92F\x10o\xc7\x17\xc5\xdc/,y\xbd\xcf3\xe2GK\ +\xd2-\x94\xa6\x01\xc8\xda\xa5!}\xcda\x823y\x0fr\xd3\xbd\xd2\x1f\xc0\x81d\xd5\ +?\x01s\xa1\xa0Hk\xd7\xb8A\xab\x0c\xbd\x9d\xd2\x9a\xddm\x96\x8cj\xc4P[_+\x0e\ +\xd6.\x11\x02\x8b`\x13\xf6Y f\xa2\xb0Wt\xfa\xd4\xfa\x89@i~hn\xe6\x04\xb7\x1b\ +\x8e\xbc\xc8\xd7\xd8\xc3\x13\xe3\x1fQV\xf57\x01\xb8\xbb\xdb\xd1q\x93)\xc2Z\ +\xb4\x04z\xf7\xab\x883\xe5\xd4\x89\xed_\x1b\x97\x0b\x80EP\xab\xfc\xcc\x9d\x90\ +\xdd\xc0&\x9c\x13\x9a\x19\xdc\x7fpv\xfe\x92xC\xe9\x14\x9d\xe7\\\x1d\xc7\xd3\ +\xb8\xa1\xf1\xe1\x99\x91h\xa2\x9d\xce\x10\xd9d\xd1\xbd\x87\x9f\xdc\x02\x84S\ +\xb1\xca4q\xca\xf3K\xcea\x03\xa3\x7f\x11I\x87\xf2\x0e\xf0G\x8c\xffL\xa6o\xf0\ +\xe0[\xff3\xef\xbf\xffS^}\xf5\xe5\x0b\xe18\xc8\xde\xb3\xca\xeb\xfcT\xf7Y\x05\ +N\xa2\xcdS\xb1P\xcfi<,\xfd\xcb\xf6C \xaa\xb2\xe2\x94>\xf5\xbf\xc9\xde\xf3\ +\xdc\x1a\xe2\xb2\x11\xd4x\xd4\xcb\x8d\x16\xfa7\x84f\x85N8V\xb5Rh\xac\xba1\ +\x1b\x8d;;s\xeelo\xd3x_\x8c\xe8\x98\x9a\xc8.+\xbf1\xc2\x81\x1e\xe2Rn\xa0\xcb\ +Gp\xe8\xd0=_2\xed;\x81\x10X\x11aM/7 \x17\x89\xafd\xfa_\x0e\xc3f\xde\xd8+\xa5\ +\'\x92"\xf4\xc9\xda\x8e:\xa6}8\x0b7$\xf9\xe8V\xf80\x04\x88\xcaF\xd3\xd0\xc7|\ +BB\x12\xe1\xbdr\xe4@\xc8M\x85\x07\x85\xf4\xa2\xd1-\xcc\xc1\xd1N\xa4(\x8b1\ +\xe59F\'\x89\xff(\x0f\xc3\x87#\x9c\x0e\x9e\xab\xaa`$\xc9\\\xc7)\xeb.\xfd\xc6\ +\xc9H\xf4\xd6s;\x88\x10\xfa\'\\\xf7\xd6\x8e!\xa6\xb5\x88\x9a\xdb\x8a\x98\xec\ +=\xe3\xd9\x1e\xbd\x8bIH\xf8\xb1\x0b\xd6\x80\xf14@Te\xd2\xa4d\'rUJ\xa5\x1d:s\ +\x99^$(\xfa\xde\\z\x8a\x11e>M;7\xba*^\x82\xa50\x8dsp\xca\xd0)\xf6\xbc\xa1i\ +\x03\x88O\x84\xb0\xc4\xb0\xde\xef\xde\xe7\xde\xd6\x9f\x07`\x95\xac\xe9\x9fV\ +\x8bp\xc9\x06\xab=&\x95\xd2S3\xf4\x07\x0fv\xb8\x95\x9aI\r\xde\x8a\x1c\xd60Mx\ +\xed\x12\x15"\xf6\xc1\x8e\tIZka\xde\x0e\x88\x1e]\xcc\x81\xe4\xd2m\x84\xa8\'%\ +\xd10FX\x89\xa7#\x8d?\x8f\xe3X\x9d\xf7T{P\x12\x9cWs\xc5J\x14\x9e%\xa1\xd9\ +\xa4\xe7\xe6PXo;\xfc\x8cf\xbe<4[,\xaef\xe6\xf9:\xc1Ee\xe2\x85ww\xf6\n\x0c/M,\ +i\xf3{)\xa15\x13\xb6\x9d\xeem0\x9a%\x9278\\k\xae\x15\x9asQy\x96\xaa\x83\xfah\ +VF\x93\x84]Lk\x97\x1b\xc1-\xd3\xc4x\x01>\x1e\xfa\xa7\n%:\xb7\xb9\xd4p3\xe3\ +\xe9\x13\xa0\xffd\xb5n&\xaf\x03\x98\xe0\x18\x8e\xa5\x81\xa8\x9eI\xf2p9\x85\ +\xeb\x93\xdb\xd4\x96k\x1df\x1c\xf0\x9b\x05\x81Z\x8f\x9c\x18\x08!\xd0\xf7`\ +\x06\xba\xd4\x00\x00 \x00IDATO\x98L,\x11z\xd1uL\xd5\x94\x86[)i\xd9\x8aosW\ +\xed\xb1\xb5v.\xfcj=o\x9a\n~\x03;@:\xbcR\xa3g\xd2\x0e%\xb3\x03\x13\x1d\xe8#\ +\xc3_\x7f\x9e\r\x1c\xa2r\x10W\x12\xa3\xdd,\xd7\x84`\xb9?%\xbc\xd7X\xf83\xd3\ +\x8e\xfb\x08\xf4\x9f\x0b\x18\xda\xba\x82&\xe1\xcd\n\n|\xea\xa9C\xa9Z\x11\xb7\ +j\xc9\xf3\x89.s^\xa2\xc8\xd0M<\x93\xcei<\xe7\xf9\x99\xff8\x13\x1e\xf7\xeen\ +\xf30<\xe1\xba\xbfbtP)!0\x84g\xcf\x1b\x92\xc2\x88M\xce\x1d\xcb\x1e\xf0\xa8H\ +\xe3y}\xfa\x1a\x7f\x14\x95?\xf9\xa3?\xe4\xd5W\xdfJ\xcf\xaf\xe7?\xdc\xfbx}\r\ +\no:`\xa3\xfai\xaf\xc10I!\xff\x9c\xf7\x93\x8f\xaeu1p,\ +\xe3\x14\x81z\x98l\x81\xb5\xd4\xfbf|\x0e\x95)\x06\x9b\xe2\x99$\x8f^\x9c\xbc2\ +2\xac\x16\x8bPr\xfc\xca!\xa3x\xc4\x852\xd5,xO\x8fz\xe0\x15\x1aGI\xb8\xb7\x1e\ +T\xc33s\x18;Fp\xaa\x1c\xd5\xebu\xce\xc8B\xbb\x11?\x84\x85\x8aG*\x97\xa5\x07c\ +1\xc9\x1b\xe4\x9cr\xdc/\xec\xb7\x89F\xcb\xfd\x12\xbc\xb5\xb2\x91\xbd?}\xbfO\ +\x97\x8c\x98\xab\xcdur\x18\xbc\x07\x9a\x9c\x98\x8c\xe10{\x86b\x84\xd3K\xe8_R\ +\xf2t\x96_9\x89z\xb0\xe3\xad\xc2p\xb1x4*\xf2(\xb8\xaao\xe6LI\xb3\xf9\x9f\x0e\ +\x05A\xd5\x1a\xe4\xf4\x95M\x07?\xe9\x02!<\xe6\xf6\xec\xcf\r\x99&\x15\xdc9\'q\ +\x99\xff\x8f\xd8r\xe8\x15\x89`\x07W&K,\xc7\xb1\x93\xf0(\xc74\x907\x97)\x0e%V\ +\x8d\x9d\xeb\xf4"A1\xfc?(I8\xf3\x12\xc0\xe0R4\xa6\x87!\xf3\xb2\x8381\xa6~\ +\x12\x03\xf3.\xe7o\x84\xc4L=Q\x03\xa7\xe1=\xbc\xff+\x15\xac\xf6\xbb\xc5"X\ +\x87O\x06\xc6y\xc6\xed\xed\x06f2(B&\xa8\xfa\xd4\x18\xee\xf7w\xbe\xc7\xcf\xbf\ +\xf9\xb7\x92\x12\x92\x98U\xa4\x08\x03\xdb\xd4\x17\x13\xd0\xa2\x17\xaeJ\xe0\ +\xe1\xae\x85q\x04c<9\x8c\xb2Hg{\xe5\x85?\x8d\x87\xa3\ree\xe4?Du\x7fd\x81\r9A\ +\x832\x92\xbf{y\xfa\xf3\xbc2\xfb2}\x1cp.\xc01\x815\xe7)\xa7s/\xe3\xe0\x9c\ +\x11B\xe0\xaa\xc0\xeebp%\xe7\x1c\x8e2\x9c)A{\xcf\xed0\xbbF\x84W&-!\x04\xde_t\ +EA\xcb\xc9\xabq4?\xbb\xef\xcb\xd3\xd7\xf9\xecW\xff\xdd\x14\xde4\x9cJ4\xfal\ +\xdc\x10\x8arH\x81?[\xe4\x97\xc2\xff1\xd1\xbf\xa4\x1c\x9c\xa3\xb4\xa3\xf7\ +\x93\x82\xea\xe2~y\xd6\'A\xff}\x08D\x19Jq\x1bg95\xf5yHN*o\x08\x8a4-_z\xf3o\ +\xf0\xdd\xfb\xbf\x8f\x86\x9f@\xa1\x9b\xda\xcd>\xe4\x04ee\xa8[t\xf4\xfd>\x93\ +\xc9\xabL\xdb\x96\x87\xf3yR>\xe1(\x0e\xd5L\x03\xfdg\xa6t~\x0f\x11[_\xe5$v\ +\xec\xe2S^\x9e\xf1\x92QWbgJ\xd5\x17\xee\xfdu\xfe\xf97\xfe\xa7*\xec$\xe9\x08\ +\x8bs\xf0\x92B\xcby\xef\xbc\xdex\xcb\x01JL\xb7\x11\xeb\x87\xf2\xd5\xe9]&\x93\ +[|\xb8\xf8\x80\x9f\xf7_,!8C\x82\x16!z\xd1\x08\xbd%\xe0>\xdc\r\xa9\xd2/\xd0\ +\xf8v\xc4\xdc\xa7w\xff\n\xdf\xfe\xc6\xef\x96j\x96|\xb2u>\x045{\x8b\xc6\xca\ +\xdc\xf0Y\xde\xc3\xbf\xfa\xb5\xb7\xb8{\xe7.\xcba\xb0;[3\xbe\xf3\xcd\x7f\xc9\ +\xda\xd6\xf6\x88\xf6\xcb4.\x11`]oB\x7f\xdeYh\xfa\xba\x0bl\x8a/\xfc\xc2OZ\xa6\ +\xdb\xbf\xc8\x7f\xf3\x8f\xbe\xcewv\xe6%\x04\x7f\x90s,\x12\x9e\xac\xe0DG|\xc7\ +\xaa\x83\x0e\x88)\xccu\xf7\xce6m\xfb\x8a\xad{\x1cx\xedq\xff\x04\x92\x17&\xb7\ +\xb7\xb0\xf0Q2h\xfb\x8b\xf1\x9f\x9f\xebb\x87k<\xd7\x9d\x15\x17\x8c<\x81iI5%7\ +\xbf\xbc\xf5\x8b\xfc\xf4\xe1\xbf\xe4\xc7\xbb\x1d\xef|\xfb>\xf7\x1f\xec\x00Yy\ +\x01q\xa1\x18\x95V\xaam\r!\xf7\x9e\xef1\xc1p\ +\xda\x01.\xcd!\xa7Alo\x7f\x19\x80\x07\x0f\xfe\x88\xbc\x7f#\x8c\xf8\xaf\xaar\ +\xff\xc1\x0e\x0fvv\xb8\x9f\x12\xa6};3\xc57\x85\xa9\x92;\xcb^\xc7\xe1\xba\xac\ +\x80]H?\xc9\x83\xbb\xbbk\xf0\xdf\x12\x0b\xffe\xc3\xc7\xaa3;\\|\x9a\xe6bp\xdd\ +\xbd\xb3\xcd"\xff\x01Ya\x19\xb7\xa9\x19\xdeg>\xbe\x96\xae\xcd\x07\x0c[U3|\ +f\xeb\xcf\x17\xaf\x99\xa5E$\x15:V\x9e\xa5j\x9cq\xa8jT\xe8)\xe1\xab\x06J\x12\ +\xa1\xab\x91\nx\x114m\xce\x95\x188u~\xf04\\"(|\xf2\x10]\x89Ox\x167\xed\xbb\ +\xca\x82.\xee?\x06o\x85\xc1\xc6`\xcd\x9e3\xf2f\x81\x80\xc6\xd4H\xac\x01\'\ +\xca\xa2\xeb\xec\xfc"\'\xa9\x040{\x13\x0e\xd8\xdd\xed\xf8\xd6;\xef\xb0\xfdW\ +\xff\x06+\xaeA\xd8\xa3\xdb?a\xff\x00V\xdd\n\'\xf1\x148a\xd5m\xb2\x16\x0f\xb8\ +\xde\x80r\x95\xd3\xa3\x13\xe0\x84\x03n\xe2\xe5*\x7f\xe5k\x7f\x8bug\x1dZ\xf38\ +\xce\xa1\x8c\xb4A\xd6/\x0b"9eO\r>\x8d\xe94a\xa7X\xb1\x97\xb2;\xff\xbe\x11lcU\ +E9\xf9\xb9f6\xab\xfe3\xb4\xcd:\x11\xe10F\x0ei\xb8"\xa7l\xae\x9d\xb2\xb2\xde\ +\xb0\x96\x8e\x8fpMnT7x\x07\xd61\xc2\x8a\xe9ov7\x82\xe5\x074\t\x8e\xcb\xc6\ +\x9e\xc2jo\t\xbe\x8d\x80:J\xdeO\x16d\x11\xe8\x7f\xba\x0b\x0c\xdd\x7f\xcd\xa3\ +0x\x7fn7B\xf3\xb9_\xe2\xca\xb5\xab\x86w\xb9\xcaUg\xa1\x9c\xa6(%\xb61\xd7E9\ +\xc2,"I\xd5+\xf99@a\xe0\x8a\x9c%\xf8\xa5\xf1q\xd0\xff\xb2\x97\xa6v\xbbf\xc5\ +\xea\x93\xa0\xff\x0c\xbfS\x83_\x9d\xf2\x9a\xd3t\xcc\x80\x8e\xacbGn[\xaf\xf8;\ +_\xe1\xe7\xb6\xbfb\x81\t\x05T9\xd6\'\x84~\x8f\xe3>\xf0T\xadz\xf2h\xf1\xc3"P\ +\xbb\xae+\x87\x9fN&\x9e\x07;\x8a\x8b\x01/m\x11\xe4\xc5\x12\xcbx]blg`W\x13(\ +\x84P\x1aL\x12\x83\xf5\\AF\x82\xec\xf5\xd9g\xf9\x9b\xbf\xf9wJ\xa2l\xbaC\xf2\ +\x84\x1e\xa0q\x05\xd5\xe7\xac\xc5\x03\x0e\x13\x12\x9f*\xe8\xe2G<\xd7\x94\x90\ +\x8f\xad]\x0f\xe9\x88\x14h\'\xaf\xf2(|\x80so\x00\xc3YN\n\\Ik|\xe1\x88&6reQ#\ +\xa0!\x94\x04n\xe7`6\x9d\xe1\x7f\xfd\xef\x10\xba\x8e\x03=D\xd8\xe3\x19\xc2J\ +\xaeGq\x1b\x1c\xc4C\xf4\xa8\xe7\xe08\xf1\x9e\x08\xebI\xc8\x1d\xbbM\x9e\xed\ +\xbeG\xfb\xed\xfb\xdc\xbd{\xb7z\xb6\xc1\xb9\xb55\xe3\x83\xaf\xff\x8f\x89\xd9\ +\xa75H\x9e\x85u\x945^\x00\x7fL\xb9dN\xd1\xc6\xe3\xb1\xa2\x16\xc1\xd6\xf4\xde\ +\xd7\xfe6?y\xf8]\xee\xef>\xe6(e\xe7\xad\xc7\xa7\x1c\xb9\x1b\\\xd9\x04\xd8\ +\xe0hE8a3)g79\x89f\xc1\xaf\x01\x87\x8b\x9f\xb0{\xff\xf7\xb9{g\xbb\xc0]\xdaq\ +\x88\xf0a\\!\x9f\xdd\xa41\x85<3\xff\xe4\xa3\xf0\x7fa\x81yS\xa3S\xc4k\xf2H\ +\x0c\xc6lVb}\xe3\xf9so\xfe{\xdc\xef\x03?\xec:~\xb8;\xe7\x10\xc1O\xbf\xc8zs\ +\x8b5\xb9\x8e\xac\xaf0\xff\xbf\xfe\x19w\xb6\xbf\xcco\xfe\xfa\xdf\xe6\x1f\xff\ +\x93\x7f\xca\xeen\xc7\xd5kW\xad\xa1i\x19V\x0cQ{[\xedYF\xbbGY\x11\xbd\xcc\x85\ +\x9b\xaa\x05\x83\x9aB\xa5\xd9H\xcfG\xe68\x0b\xe3\xd4\xde!\xc1\x8aI\x00&\xfe&\ +\xbf\xfa\xb5\xaf\xf1\xdb_\xff\x1dBx\xcc\xabw~\x99\'\xfd\x1e\xee\xf8\x80\xfe\ +\xf1\xfb\x10\x8fx\x14\xf6y\xe7\xfe}3\xee&o\xf0\xe5\xbb\x7f\t\x9f\xba\xc7\xaf\ +W\x8av\xf6\x1c\xc5\xa8If\xc9\x88\x17\x9d\x8f\x7f\xdb\xc3\x0b0\x834\x82\x8f\ +\xa1\xe4\x03;\'<\x0fOF\x068X\x18\xdd\x87\xc0\xc3\x87?\xe0\x97\xbe\xf6\x1fB\ +\xdcg\xff\xe8\x84\x83\xe3\x15\x8e\xf5y\xba\xf9\x111F\\Z\xc4u\xb7\xc2a<\xe5H\ +\xf79\x8c\xd0n\xdfe2\x9d1i[\xf2\xa1\xbe\x19\xe6\x18a\x1dk\xca\xb8L?g\xe5Aj:\ +\xa6Q\xb1\xfe\x9b\xca\x95\xc6\x0eF\xcb\x0c\xb4\xb8\xda\x9c\x14\xcb.3\x86|\ +\x1eG!:,~\x1c\x93 \x14\xf1U\x17\xd3WK\xef\x99\xbaV_#\x1ch\xe0h9\\\x91,\x89\ +\x17\x8d\xbd\x08W5\xa0\xe2\xe9\xa3\xd2D\xf8`w\x97\xafL[\x9c\x13N"l\xc8\xb0!\ +\xe6]\xc7\xf5\xc9\xeb\xcc\xbe\xfc\x17\x8b\xa5\x0f\x10\xd5\x12G\xaf;\xe5q\x12\ +\xe8c\xf8\x93W+r\x06\xfe\xe3\x02\x7f5\x87\xc8\xd99\xd5\xd3Ssi\xf6=\xffo{\xe7\ +\xf3d\xd7q\xdd\xf7\xcf\x0cz0=\x83\x0b\xa2\x07x\x04/\xa9G\xe1\x91\x1cYC\x19\ +\xb4 \x85)Q*9f\xa5\x14[r\\\x159\xe5\x85w\xd1"\x8b,\xb3\xc8"\x7f\x8e\x97^d\ +\xe1\x85\x92\x92SJB\xdbL\x15\x1c3\x11d\xd2"\x14C\xd4P\x1c\t\x97\xc4\x05\xa6\ +\x07s1\xef\x0c\xa6g&\x8b\xd3\xa7\xef}\x83\xf9AYT\x16.\xde\xaa\x01\xe6\xc7}\ +\xf7v\x9f>}\xfa\xfc\xfc\x1e\xf5`$\x0bA\xe8\x9c\xdb\xf5\xff\x9b;\x9dgkBdF\xf9\ +\xe9Dx\xf1\xfak\n\xe1\x8e\xb9d\x07\xf91\xa8g\xc9\xf6\xad$_b\xa3:\xfe|\xc8\ +\x98\xd5\x86Z/\xce\x05.\x12\x15w\xe2\x8c<\x08\x1b\x97\xcd\xd7\x04\xb1\xb3\ +\x1e=Ni\xf30n2\x0f\xa5\xb1\xe3Gm\xa3\x1f\xc9\x9fy\xfa\xfaWxi\xf5\x85\xa2\xa8\ +J\xa6m\xa9P1\x01S\xe9\xe6=\x97\x95\x15\xb3\x92Uxj\xfcz\x01\xeb\xca\x1c\x9f\ +\x00\xc2zr\x11\xfe\xe1\xfco\x96\xce\x8c\xe7\xddi\xee\x866)T\xaf\xa8\xb5{pN\ +\xf3\x02t-r\x08*?\xef\xb8\xbe5Iz\xa1x\xec\xd0\x93\x86R\x94\x7f"\xa1\n\xdc\ +\xeb\xd4;Vy\x9fs\xd2\x0c\xfb\xa9W\x00\xd4\xfa\xd3\xc3\xa6\x0e\xea1\xdd\x17\ +\xcf\x85l5-!\xac\xaf\x7f\xc4\x0f\xbe\xf7\xe3l\xc5\xa95\x18\xa3&\xc9\x8f\xf3\ +\x1a\xeev[\xb8\xf1\x84\xa3}\xbfT&(\xcdf:T\x1f\xb9l\xedv\xccc\x94\xd4*\xd6=\ +\x18s\x15Zo\x11\xbb\xca\x132\xe6\x905\xe25\x05}?\xe9\x9e\xd5RbS\xc0\xa1m\xc6\ +l\xbc\xf5\x86\xce;\xd3\xbbBi-"\xd4\xe3\x9a\x9f\xbc\xf56\xbbr]=x\xe6\x89Iy\ +\x0f\x9db\x01[\xc2o\x02\xe6E\x1bz:g\x85\x05\nI\x81\xd3\xf2\xe0*\'\x8fK\xf2\\\ +I\xbdr:7P\xb2\x92\xc4\\\x88!Y\xb9\xd2\xf4\x82\x8d\xd1\no\xbd\xf3\xd7\xfc\xdb\ +r \xf54\xad\xc7\x13*\x1e\xd3d\xc5\x0bT\xe9\x96D\x1e\xff\xe9\xf2\xd3p\xa4|V\ +\xfe\xccw!y\x1c\xcey>\xb3\xfa\xf9^\xc9\xcf^\x8f\x94\xbd\x96\x0b\x08\xe7|P\ +\xf9\x97\x94\xe7\xb4\xc2Z=#\xdd\xf8E~\xf4\xd6\xff\xcc\xd0\x03\xe6a\xee\xe9\ +\xbf(\xef\x01\x9f\x854\xa0\x85HQ\x88N\r!%5vSR\x00\xbe\xae\xf2\xa4N\xbd\x96\ +\x96\xd0la=S\xb2B\xe5y\xfd\x8f\xfeM\x19{\xc1\xf4I6~\xa1y\xfb\xafp\x1c\xe6\\\ +\xbdE\xe5\x9b\xdd\x87\xd4\xa3:\xf3z\x1f\xa2\xcf$\x81"S{\x03,v\xb1(\x92\'\xd1\ +\xde\xf6\xafs\nd\xdb%QQ\xe3\xbb\xf2\xf3\x9b\xed@\x96\xdc\x08\xee\x84\x05\xd0I\xeb!\xf0\x18]\ +\xac\x18A<|\xb0\xfe\x01\xbf\xbd\xfa\xa5B\xf4\xe1\xb5\xb1\xbe\xce\xc5QM\x92X\ +\xc6\xaf\xf1_\xbd\xefB\xf5\xffo\xfcz\x19\xfd\x95\xec-\x9e\xed\xe6=\xacD\xfa\ +\xd2h\xa5\xc4\xce\x01\xf6\x98+\xef:\x7f.+F\xce\xac OU\xd5\\@\xb1x\x86\xeeD_B\ +Zz\x80$\x89\xda\xe1<\xe5RN]=\x9d\x83\x04\x8d\xdd\'9\xd1\x86,yO\xf4.\xe4\xd8\ +\xa9\x17\x88\xae)\xb8\'\xa9\x13\x0e$r\xde\xfb\x82Jz\xbf\xedKN{\xab[C*\xc1Cr\ +\x8aq\xb3\x10\x1b\\\x08\xb8\xaa.\x02G7o`K\xfa$\xb7\xb9\x04\xe7R_\xe6\xaa\xe5\ +\xa9\x82t\x9bg\xa8p\xffp\xfe/U~\xd9"\x1b^\xa1\x94\xa6\xf7I\x81\xba\x16:\xbe\ +\x84\x82\xb2Y2\xb4\xe5\xb3\x81\xc7I\xa4\xc3\xd3e\x05\xe2\xcc\xf1;T\x91\xb3\ +\x04\xf8\x04\x88uW\xf6%\xbc\x0b*\xd8\xa2x\xb0\xd2T\xa7J\x92\xa3W\xee\x16}\ +\xe0\xca\xa8\xdf7\xc6?m\xae\xbaX]\x9d\xe8{\xa6\xdb\x8c*\x90\x14\xa8R\x9f\xf8\ +\x9c\xf0,\xb8\xc8v\xa7\xd5o\xa7\xf1\xbf\x85\xe6La\xea\xb3@\x00bI\x924|\x14\ +\xefr\xc7j\xa7\xf7X~\xcdBy\x16\xc5 H\x12y\xa1^\xe1v\x17\xb5\x1b6\xfd\xa1U\ +\xf2\x80B`\xaf\xbb\x8fg\x8e\x0b\xa1\xa7\x7f\xcc\x82\\8\x99\xfe\xbde\xab\xfb}\ +\x19U\x82\xc4I\tW@\x8f\x86\x9d\xb2\xf2`r2!\x19.@\x8a\xfc\xf1)\xb7!@\x95\x17\ +\xef=\x93q\xcd\xcd?\xfb)M\xdbP\xd7uq\xb3\t\xba\xe7_{\xf5\x06m\x17yv4aj4Asob\ +\xe2\xd4\xfd\x9b\x07\x82\xe4\xb1\xa4\xe4\xb5\x7f\x95\xd3\x04\xde\x92:\x90)\ +\xe1\x1d\xcc\xe5\xf5YB\x13\x8cC\x1e\xbb\xed\x95P\xf5\xf2pT{.\x8fj\x9a\xe6CVs\ +A\x8aY\xe9\t2\xda\xbag\xdfy\xbc\xf8bP\xc4N\xc1\x19\x0b\x1e\xd0Is\x10\xb0J\ +\xe4\xe2\x91H=\xfd\xed\xabO\xf8\xed\xbdK\x86\x84\x9c\xb2\x17V\xc8}"\xab\xa7\ +\x8b\xd2_g\x84\xe1\xb9\xc5\n\x8f@\x86\x96H\t\xb6D\xb8\x92\x8dc\x11S6s\x18\ +\x8f>\x1f\xee,\x05"/\x81BedE\xd4\x93\xf3C\xf3\xdc\\\xce\xad\x91\xb8\x99\rM\ +\x1d\xb3\xb5\x189_Ue\x8d*\x9f\x1b\xca\x8ap\xd1\xc1b\x96E)yB6\xe4D\xd4\xdb\ +\xaa\xb2)\x03D\xa6\xbax\x82,\xf1\xfa\xb4\xf3\xab\xa4\x8c\x0c\x1c\x15\t\x95\ +\xff.\xcb\x97\xbbM;\x08\xed*\xff,U\xba\x87\x97\xab\xa7t/g\x99\n\xd9@\t\xb5*C\ +\x89\xa2\xfcX\xa5m\xc8\xf8EJ\xf3\x9c\xb6\x90\xe5\xe7\xbe\x0b\x9c\x93\xa8\xfb\ +\x02\xe5\xa1\xa3\xf2\xe7\x84\xb5\x90\x19f\x8a\xf9\t>\x0b\xa7\x0ec"\xc9\x0c\ +\x95\xb1>2\xc3w\xa9\xdf\x1c\x9246X\x87\xdc$M\xa0\xf2\x11\x91\xc0\x9c\x8eX\ +\xc3\t\x95\x96\x0e\x0eC:&\xf8\xc9\xcc\x90\x92\x1e\x86\'Fa\\\xbf\x00)\t\xa9S\ +\xcc\x83\xb6\x8d\\H[\x83Ch0S\x99j\xcc\xfb\xe9\x8b\xfc|\xa3\x87\xfc\xdf\xe3\ +\x80\x05sKw\x179\xbf8\xc7\xce#\xa1A1s\x00\x0e\xe6<+~\x0e\xe1\x90KN\x0f\x0f\ +\xd5T\xe3\x8c\x02H\x92\x82\'r\xda\xf8\x87%\xe0\x90\x99(3\xdeG\x1b\xef\x97\ +\xc5_r\x87\xc5\x12\x12\x81]\x99\xa2%\xbf\x97x\xb0\x1f`7\xe38t\x91}\xd9d\xabZ\ +\x864\xe5~\xbb\xc9\xf9\xb4K\'\xdb\x90\x16h\xe3}\xae\xd6\xcf\xf2\xfb\xdf\xfe\ +\xd7T^\xe1\xc7b\x94\\\xbe\xd9\x1f\xc2\xfbI\x9b\x97\xfaL\xe3\x932q\x9d\x9d\ +\x986w\'\xba\xe0\xf9\xc04$\xf0\x9d\x8d;\xc5\xf3`\xb8\x11\xef\xe7\x18\xee0\ +\x19\xfd\xfe\xc6\xcf\xd8\xe9:\x16\xd2C\xda\xa6\xa1\xc9]\xd7\x01\xfe\xf0;\xdf\ +\xe1\xc2h\x82\xf79\xdf\xcb\x19\x8f\xa8\xe0-^-\xa3S\',\x1f\n;~\td\xf7\xf8\t\ +\xf4\x94\xb7e\xfb\xa5\xf9_\xd7}\xa9<)\xa5\x1eS\xca\x01;\xdb\r\xd1\xd7x\x0f\ +\xfb\x9dp\xcepn\x1c\xc5\x13\xaa\x07\x91)>\xfa\xbd%\xba\xbb3\xe9\xaf\x15\x10\ +\x86HKV\x16\xcc\xfb\xe3\xc9{\xca\xf5\x89\xd9?\xb9\xf5?\xf8\xe0\xd6_\x03\x10F\ +\x01\x17\xc6T\xe1\n\x97\xc2%.\x86\xcb\xb8:p\xb1\x9au[;\xa7\xfbJ\xa4\xef\xe3\ +\xb3\xb5\xb5\x9d\xd78\x1b\x01\xf4\x87\xaa\x95\xc2\x06\xc7\xc9\xfb\x17\xaf\x15A\xe2\x03|xN\x07\ +\x95"\xb13\nr*\x16V\x91?y\x0e\xc3\x9c\xb0y"\xf3\xc6\xf3){\xa3t\xd1\x07\x07r/\ +3\xba\x04;]d7>\xa0k?`=zn\xde\xcc=\xec\x92p\xff\xc3\x8f\x88\x02\xc1\x14\x12\ +\xe7\xb9@Ok\xf58\x03\xc4\xfew\x90\x93\xa4\xcf\x88b\x98\x01\x93=\x7f\x08H\xce\ +\xdd3#\xcb\xe5\xf0\xf34n\x169t\xb7i\xb8y\xf3\x16\x1f\xb4\x91\xc7\xcd\x03\x9c\ +_b\xa1\xba\xcc\xc5\xd5\xe7\xb8\x90\xc3Pw;\x08\xa9a\xc9\xa9w\xe6J\xa6O\xa8PgA\ +\x12=\xaf\x12\x05\xa3\xc7\xc2\xd7\xf01\xce/\xe3\x9f\xfc9\xd7\xa9\x92x\xd0E\ +\x1e\x02{\xed\xfb,\x0eB\x87\xa3\xfaY\xd6V\xd7\xf8\x1eop\xb7\xdd\xc2\xbd\xf3\ +\x16\xe7\xfc\x05\x00\xbc\xbf\xc09w\x9e p\xb1\xd2\xa3D\xfb\xfd\xf5\x10;\xca\ +\x14&?\x85\xdd\xc1ys\x98\xe1D\x16\xd2\x16\xf7\xd2b\x81\xa7\x18\x8e\x7fF\x01\ +\xeaQ`{\rZ\xdd\xb4\x02\xe2I.f\xeb\xfe\x88\x0e\x9e\x0f\x87:PJ\xbf\x87\xe0O\ +\xa6\xfc\x80az\x84\x02\xb9\x1ft\xfc\x19?F\x95\xa5\xfd\x14\xd9N9\x0e\x8a\xf4\ +\xb9*iJb\xe9D\r\xba\xe0\xb1\x98\x10E7q\x8c\xda\xa0s\xe1\x98\xf0\x87s\x9e\x1b\ +k\x13n\xbeu\x8b\xe6\xdd\xbf9\xe1\xc9\xbdr\xd2WQ\x99\x1b\x8fbQ\xbf\xf2\xfa\ +\xb7\xf8\xcc\xaa\xf5\x8fb\xe6\xc0XBCZ\xb6?\x8f\x1d\xff\x90\xfev\x08\xe4\xaa\ +\xa8G\xcd\xfbJ\xaf|`\xf6\xee\xd5\xfe\xf3\x0f7~\xcc\x9d;\xef3\xdf5\xe5\xddV\r\ +g(\xb9\xd6]\xd7\xe6\xb0\xd3](v\xb6\xd2Kx4p\xffZO\x17\x80$Sp\xa7\xd3\x1f\xd7o\ +"\xab\x88\xb0\x03\xcc,\xdb\x8f\xe2c\xac\xaaa5\x97Q\xdfY_\x1f\xb8F\xe1\xef\ +\xdf\xfcs\x0c\xf2\xbf\xb7\xd2{\x05\xa9i\x1a\xae\xf8@H\xe0]\x86\x8c\xf7AA\xca\ +:\xe3\xdf\x9e\x06\x00\x8f\xf7\xfdL"\xf2\xa9\xf4\xe7\x97\xe7\x7f-m\xf7H\xa7\ +\xca\x9c\x81OjCZ\xad\xeay\xb0%<\xde\x8f}\x928\x9f,\xff3\xd8w$_\xfa\xafIV\xe6\ +J\x12\xec\x807\xf7D\nO\xc46\xe2b\xa4\x85"\xf4\xbc\xf7\xcc\x0f\x92\x10\x8d\ +\xb6e\x0f\xe7\x1eJm\xf3>\xf7\xa3\xf2N)\x81\x86\x99\\3\x11\rU\x1eO\x7f\xbd\ +\xaf\x08~\xb2\xef\xa7\xe0\x8b\xd9\xf8\xf5\xa0\x8a\xcdOq\xces\xaf\xed-m\xf3 1\ +8h\xde\xd1\xa7\xe3=\xcc\xfb\xc0A\x12F#\xb3\x82%\xe7\xeb\xf4\x95`U\x15X\x7f\ +\xef=\x0e.+\xd4\x82\xed}\xdb3\']\xb3\xfb\x972_[0\xdd\xff\x91\xf7\xde\xf9[\ +\xe6\xbb\xe6\x89\xcf\x0fQ\xab\x87\xf3(\x15@\xf4<\x9d\x12T\xd5\xd2\x8c\x8c\ +\xd9MZY6\x99L\xd8\xf8\x93?\xa5^\xebs\x84l_\x91\xa6g\xcb\x1fL~\xf9\xbe\xba\ +\xc9\x8cJ\x89\xfc\xec\x9d[,\xbb}\x12\x0ekiP\x8c\xce\x1c\xaa8\x9a\xc4:\x1cG\ +\xe5=\xe3\xbc\xef\x87WJ\xda\x91\xfd\xfd\x9f\xbe\xc73/,\x0f\xf6o\x1e\x1fg\xf0\ +\x8f\xf1\xbf\x958B\x81u\xd8\xc9\x8a\x8d79\x94\xc7\xac\xcfW\x83o_\x1e\xb2\xd3\ +u\xe0\xde\xfaO\x91\\\xcdi\xde\xec\xef\xbfq\xb3\xcca;\xde\xe7Q\xd7 \x12\ +\xa8\x83a\xf5x\x9a(\x19$4j\xf8\xcf\xd9\xdc\xf2\xe1{\x86\xfcQ\x19\xd9\xef\x01\ +\xe92\xffd/\x9c5\xef\xb6-\x1e\xe3\xc3\xf2\xfc\x1f\xbes\x8b\xff=\xe83\xfc\xb7\ +\xedG\x80\xf0wUM\x15.\x12\x9e\x9d\x10.]\xa0\x1ai\x1b\xa5\x8b\x15\xc4\xaa&TR\ +\xbc^M\x94\x9c\x02@\t\x1d\x0fsvN\xf3`\xcd\xf0\x0f\xa81F6\xfeM\xb6\x1c\xf9p\ +\xdb\xdc\xe5O\xff\xd3\x9fq\xfb\xce:{"\xbc\xd7\xbe\xdf\xbfg gM\xee\x87\xe0y\ +\x8c\xe7Bu\x81sn\x81\xe5\xea)\x9e\n\xcb,,V<=\x1esii\t\xe94\xfd\xa4\xcb\x06\ +\xfc\nS\xbc[,\x8a\xe8p\x083\xc3\x19\x8d4I\xab\xedr\x19`\x11\x9c\xa8\xf0,\x87\ +\xb2\xc5\x95\xf5\x89>\xe7\x9b\xac7\xbd\x1bO\xad\xac\x9c0\x19\xa5\x1cf-\x80\ +\xdc\xc6*\x1b\xf6\xbb]\\\xa5\xf1\xf16#S\xea\xf3m\x11\xa6\x88S\xac\x92\x8e%\ +\xdc \xccq\xf4\xaaC\x0e\xdf\x88Y\xe2\xaa\xc1\xee\xb4\r\xcf\xac=\xab.f\xf3(\ +\xe5\r\xeb\xfd\x12\xbf\xfb\xcd\xd7\xb5\xab{\xbe\x16\x07\x9bw\xc9\xf7\xf7\x0f\ +K\xc8\x81\xd2\xcc\x0f\xe0?\x7f\xff/X\xb9r\t\xe9\xfa\xca\xa5.\x81O\xaa4\xdc\ +\xa3\xcf\xad9y\xfc\xea~\xecb\xd4\x8a\x80\xac\xe8L%\xb2\x135\x844ldg_\x90\x05\ +\x83\xf7Z\x15\x93=E\x8f\xf1,#\xd9\x12?\x9a\x00\xac\xcc\xb1\x1c\xae0\x8c\xa5J\ +\xce\xb9\xf0\x80\x93)\xc2\x1c\x8e)\x899\x14\xcc\xect\xfa\x0b\x1a\xf6\x1aZi\ +\x16\x02\xb4\xef\xb7r"\\U\x05m\xdb!\xc2\xc6\xfa:\xb8@J\xb1l\xb8\xe3\x84~\x89\ +3\xb3L\x12a\x9f9\x1dw\x07\xd25\xd9\xa2\xd4\xfb\x8c\xfe\x05\x80,M\xe9X\xc2s\ +\xbc\x07\xe8W\xe5\x7f\xf5\x02i3L-\xffT\xa5G[\xaah\xee\xc0\\\xda\xc5\xf2\x1d>\ +i\xfe\x1f\x8drI}\x1e\xbf\xcbc\x14\xf1%\x0f\xe4h\x0e\x9dw>W\x1a2\x108Y\xc8\ +\xb9~\x9f\xa4NJ\xfe\x15\xe8\xbd\x1bMC\x8c\xdaM=\x84\xc0F\xd3\xb0\x99\x9b\xf0\ +\x1a\xfd\x9d\xe8\xf85\xa4\x92\xf9\xe0\x0c\xfeQ\x14\xef\x9e_t(*L\xcb\xf8\x1d\ +\xb8\xea*.=\xd4\xc4\xf7\xbc\x12\xf6\xff\x81\xf3\x9cGf\xf6m\x02\x0e$*\x86V\ +\xbe\xd3*vJ\xfe\x86hRws\xfb6N\xbe\x94\xf9\xffP\xed\xa93\xf6\xefh\xa4\x0c\x13\ +S\xc8\xe5\xd4v\x90)\xdf$tO_\x19\xad\xf0\xd2j\xcd(w\x17\xd7u\x00\x9c\x9f\xe9;\ +\xe8\x9dz\x83\x16\xbdg?\xd3\xe3\x9cS\x04\xe5\xc9x\xc2\xf3\xe3k3\xce\x90\xc3\ +\xbc\x8fC\x08\\\t\x81\x0f\x9b\x8f\xb8\x12.\x92\x98+\x9e\x90\x98\x96\xa8\xdd\ +\xf1\xfc?\x1ey\xa2\x08N\x06\xe1{\xe9K\xbc\xc1\xe3|\xcd\xf9\xa4\xa1\xdazt\x85\ +\xaaz\x06\xc3\xf3*m\x072\x1f\xd9\\J\xb8>\x8f\xcf\x0e7\x93]]1\x18\xf5o;[\xdb\ +\\IR\x0c.\xfb\xbf3%\xe24\xfe\xef\x84\xce\x07\xba\\\x91\'(\xff\x0f\xbd*~\xf0\ +\xee$\xf0\xa8y\x97i\xfb\x0b\x90\xed\x99\xce\xf0\xd5@\xf6[X\xd3\xae\xbd\xee>\ +\x9b\x02\xa3\x8ab\xf4\xc5\xdc\x85\xbd(nI#\x0c\xfa\x83z\x85M&\x1cwik\xa3\x80\ +\xc4&;6\xfa\xd2\xfada\xbd\xc1\x19\x060\x15E\x816\x1e\x1fz MY\xefbC\x17\x1b\ +\x9a\xf5\xbf\xcfr7\x7f\x8d\xae\xf1\xfc\xea\x0b\xfc\xe6\x8d\x1b\xf8\xa48DQt\ +\x9fz\x87\xa6\x83\xa4\xde\xab\x99\xce<\xbf\xb2\xd1\x9cB\x06\xc5\x9d\x959\x12\ +\xef\x95\x10\xbf\x8d\x19\xe7\xb9\xf9\xd6\xad>\xb4]\xbcq\xb3\xf3\x19\x1a^N\ +\x84\xbdN\xd8N\xda3\xed\x17\x99o\xfe\xd9\xef\x7f\x9b\xc7\x0b!+n\x82\x93)0\ +\xe5\x9e[\xcaI\xd9\x19(y\xa8\x90\x0f\'0\x88`\xe8\x80\xcd"\x87^+\x05\xb4\xddE\ +`\xe4|\xb1\xb6\xed2&ym\xad&\x8ap\xbfm\n\xf0\x94\xb9\xaf\xad\x82\xc79\xcf\x9e\ +\xa3t%\xefr\x8c\xce\xa7)\xd2\x01n\x0eIs\x18\x08\xdf\x10<\xee\xb8\xab\x100Q\ +\xb4w}m\xc3\xd3a\x92\x9be\xea\xef\x0e\xc8\xc9\xd72\xe5)\xbf\xc4\x8d\x1b7zat\ +\xc4z9\xea92pA\x9d\xb0\xd0\xc6-\xe4\xbb\x7f\xce\xce\x9c\x82\x8eUy\xbc*\xf0w5\ +\x8e\xe9\x97N\x1d\xbb\xbd\xb7\x1b\x1cP\x964\xf9(\xe6\xd8\xb7\xeb\xbb\x15\xf7\ +\xc9\xcf*\xa4R\xfe\xfcx\xfcl\xfe\xfb!V\x15\xa1S\xee\x0f\xdd\x1ekGxf\xfcY\xba\ +\xe4\x89\xad2\xbf5B\xd4\x06\xa6y\xb3\xba\xa5"\xfcO\x1f?\xc5@.\x96\xcc0l\x927\ +\xeea\xd7\x16\x05\'\x04\xcd\xedi3\x94\x00\xce\xf0\x9b\x0c?\xc6\xfa2\xd9s\xf4\ +o+\xe7\x0f\xb27`W+\x81R\xa4\x8b\x9a\x00\xe72z\xabZ\xad\xbb\xd9\xfb\x927V\x92\ +\x13\x05\xe8\'\xc9\xff\xc3\xcb\x1a\xd5\x16\x85\xee\xd7\xc4\xff+\x08\x9b.\x14\ +\xc5\x7f8\xcd\xa1"\xe1\x1c=\xbe\x88\x08T+v\x17\x86\xb7c\xb4\xaf\xbc\xf2\xc4y\ +\x1fJB\xa2\xc1!\x88\x88\x8e]\x84\xf1\xb8\xe6\xad[\xb7\x88\x9b\x0f\x18\xb9E\ +\xf0K\xaa\xfc\xa49\x0c\x8bh\x18\xde<\xeerN\x13\x92\xc5y\r\xbd\xd8\xba\x98\ +\xd3*\xf5\xde7\xe7=\xa3\xc9\xcbt\xeb?,\xcaNQ\xe0L\x00z_\x12\xd3\xbd\x03\xe7\ +\x97p\x19SD\xd7\x14\x86\x842\xc5\xbb\xaekn\xbeu\x8bG\xddC\xce\xf9K=/\x9dLz \ +\x87\xff1\xaf\x92y\xa1U\xf9\xb1\xbd IX\xac\xbf\x88t\xb7\xa8\xeb\xabx7\xcf\ +\xa2\xf7\xa5\x07\x95\xb5b\xb02y\xeb\x056<\x08L\x80\xef%\xed\xf17\x94O\xc6\ +\x1f\xaf\xac\xadq;> \x85\xa70|+\xd2\xf4D\xe5\xff\xe8\x1cd\xb0\xdfl/\xdbA\xef\ +G\xd7\xf0<\xe4?\xfe\x87\x7f\x87%\xa3&(aZk.z\x80\xb0\x93\x95\x9b\xd8EH^\x1b\ +\xa6J\xdf>\xa2\x18p\xf9}{\t\xe6\xe2\x87Oz\x1c\xd2\x14\xcf\xdc\xa9kP9\x8f\xf8\ +\x1e\xd1]\x1f0\xe07\xd7\xbf\xcbZ\x0e\xb5\xdd:\xf7\xee\xfc\x98\xca\xc37\xbf\ +\xf1:\x1bM\xc3;\xef\xdc.2\xd6\xc0I\x87\xfb:\x81\xf6\x9c\xd3\xa7i\xea\x86(\ +\x86\x91\xe5\x16\xa9\xb7v\x0e\xb2\x0c\xb5\xe2\xa0\xd3\x0c\x80\xa7+\xd8\x94\ +\xec\x8d\x19\xd0\xc4e\xe5\xcd\xbc\xd1\x92\xa4\x84q\xe73cJh\x82-\xe8\xb8\x9b\xa6a\\\xd7\xd4\xa3P\xd6\xc11\x08)\xd3\ +/\xd9\xd5\xfaJ\xf1\xe0i\xf3\xd7\xa8I\xbai\x9ai2W\x0cT\xf5\xcaj2\xeei\x06\xcc\ +\xbdVhc/\xbff\xa2\x15\x03\x0f\x94\xc9\x1f\x00_]\x9ay\x86*X\xc6\xfby\xbc\xd9\ +\xc39\n\x81Wo|\xb1x\xa0S\x12FO?;\xf0pI\xa9\xb4L\x12\xcb\x1c\xf4\xb9\x1f\x97\ +\xff\x97\xe8\xba\x98C\x8e\x19\xfe!\xd3\xfb\x82\xcf\xfbo\xb0O\xcb\xf7\xc9\x8c\ +v\xbdg\xce\x99\xf1=\xfb\x8er4\x0f\x0c\xca\xae\x13\xae\xae\xfe\xa6\x1a\xf7\ +\xe6x\xb0\xf1\xe3\xe9XR\xf9\x93\x9e\x94\xff3\n\x90\x88z\x01\xd2`\x03\x94\xcb\ +\xd1\'\x99\xd1\xbb\xa4\xbc#{8\xe0\xd5\xd5\x9a\xd7\xd6j\xd6&\xb5\x82 \x15SZ\ +\x93%\xdb\xa8\x16\xe0\xf3\xb5\n\xa8\xd8\t\x1bQ\x81\xcab\xa7\x15R\xc6\xe4\x96\ +\xab 9\xf6\xee8\xd4\xefO\xd9\x04\x96{\xa3\xe3\xeb\x05\xbfZ\x7f\xf3eN\xe6\n+\ +\xee\xfd\x82\x06=xX\x92\x99\xc51%\xc2\x0e\xbe\x84md\xe1\x07\xb7\x7f\x8c\x1bM\ +\xfa\xf0\x91\xef\xc79\xdc\xb4\xdd\xa0\xdc\xff\xd8\xf1\'\x83s\xb7\x03H7\xeb\ +\xe3\xae\xef\x90\xed\xbdZO{\xd9\x1a*\xcc,R\x80\xf7L\x83\xd7\x0f\xcd\xba\x16\ +\xfby\xfa\x9cA\x7f\xc8F\x14\x9a\xa8\xde\x07q+\xc8\x00\xcf\xc9J\nE\xd4\xbbr\ +\x9a\x10\x92,\xf0\xac\rB\xe9\xcal\xbc\xe2=\xc3\xee\xca\nb\xe5\x0b\x98\xddp\ +\x93\xf5k\xe1\xcb\x97mTC3}\xd454\xad\xb0\xde\xaa\xfb\xb6K\x94\xea\xaa\x94\ +\xc3\x87\xc9)\xa2q\xc7RY\xbf\x13\xc7\xff+\xf2\xff\xa8RE\xe0Z}\xa9X\\\xd0;\ +\x19\xf6\xdd\x05\xae\x8d\xeb_+\xffw\x03\xe5\xdd;?\xb3\x06\xd6!\xde\x9a\xba\ +\xea\xb8\x07e\xa56\xd5\x81\xc5;\xcc\xbfZ\xce_:\xc0\x1c\xd2\xce\n\xd7x\\SUKD\ +\xd9\xd5}5\x18\xbf\x1e\x12\xb9\r\xc8i\xfc\x8f/\xa1\xdf\xa1\xd7df\x1e^\xbd\ +\xa0\x0eX\t\xcb\x18J\xf3\x8e\xd1e\xb8\xbe\xe66\x97)\xbbi\xb7\x17\xaa\'X\xe1\ +\x0e\xd8\xea\x04\xef\xe6\xa9\xc2\n;\x8fv\x07\xf9T\x92\x930O\x1e\x7f\x97\xf7\ +\xe1\xd1^W\xdee\x8c\x98\x01\xcd\x1f\xb9\xa7i\xdb\x8f iHk\x98\xdc\x9e\x12\xcc\ +\'\xf2\x81\xb0;3\x17\x1b\x8b)\x1e\x0c\xe4\x91\xfd\xce\x94\xd6]Q[89\xdf\x97\ +\x06\xff\x12\xfc3\xf4\xdeZ3\xe0\xf9$\xd4\xa3\x00\xfe)\xed\x8e^\x94\xf3\xddA8\ +\x1e\x9c\xc4bl\xee&A\xe4\xa0\xbc#\xc1@\xf6\x0e\x0c\xb4\xdc\xa0\x16wI\r\x99\ +\xe1\x1e6E\xe24\xfe\x11\xd1\x83\x17\x9e\xe0\x1f\x18\x9c\x07\x03\x12T\x15\xf8\ +\xa0\x1e\xd0{Y\x99w\xbe/b\xb0\x8a\xe0a\xde\x8d\xf7\x9e\xf1\xf5\xdf&vB\xd3\ +\xa8\xf7zSTaO~\xa5(\x1c\xc5\xf0\xf0\x06k\xc0\xec:\x1e\xb9L\xf94\xc5\xad\xec=\ +?\xe0!\xd7GP\x00Fu\xcd\xf8\xfaWf\xe6g\xfc\x01\xccx\xb4-}\xa2-\xf3\xf4\x88[\ +\xa2\xed\xfa\xf0\xbb=\xe3\xa8\xb1R\xe8\x7f\x86\xfc\xef\xba\x81\xd1\xab\xc1\ +\x18\xbcW\xb9q\xce_,\x13*42\xd9S\xd6H\xf7\xe8\xd0X\xd1\xdf\x1f\xff\xde\xb6U\ +\x03\xf9\xca\x95\x15:<>m\xe6yg\x8f\x99&(\x9c(\x7f\xdc\xd1\x9f\n\xb3\x98\xeb\ +\xd0\x1ds\x10\xe4\x0fN\xc65\xa3\xa0\xc8\xa7\xa1R\x81n\x1b\xa5\x0e\xfas\x8c\ +\x91.\x05\xed\xb2\x0c\xbc4\xf2\xac\xd47\xf0.\xd2\x89(\xa2l\ntQ\xab\x0b\\v\ +\xb5:\x11\xf0u\xc6)\x07\xb0\x08\x00\x00\x19\xbdIDAT\xe8\xd0\xd0\x90K\xf1\xd4\ +\x05(%\xd8\x06B\x94\t\x17\xa9\xf4\xf9\x01\xa6\xa2\xae\xb5\x94`>\x87\x16z\xd7\ +\xfc\xee\x8c\x86iU\'.\xdf_\x0e\x86"hvI\xe9\x90\xbf{\xe7]&\xaf\x7f^\x89\x9e\ +\x14\x8d\xd7:\xb8\xa7N2\x8a)\xb9:g\xd6\x05wt\xfc\x86S\x93\xf2?\xbeR\x05\xe8\ +\xa9*0\xce%\x98)\xc1\xbeL!\xf5\xf7\x1d\xed\xf55\xcc\r\xb2\xcb\xe6\xa9X0B=\ +\xb9A=~\x96\x18suA\xde\x00\xc9\x9b\xd2\x81"#\x13\xca\xdfv\xba\xc8\x89Y\x88\ +\x03!\xee\x8d\xfb\x07\xbfs\xce+\x96PR\x17\xf2\xeaDs\x18\xee6\r\x96\xac\x9d\ +\x06\xde\x9f\xa3\x157\x1a3\x0e\xbc\xf6\x8do\xf2\xea\xda\x84N\x84\x0b\xb93\ +\xb3\xf2\x0fz\xbf\xd72lF\xb5\xaeW\x0e\x87vN-\xbb\xd1\x89e\x0c\xbf\x1a\xff\ +\x87\n$y|\xb54C\xf7\xfd\xa4\x1b}1=\xfa\xb5\xf2\xbf\xd1=\xc9\x80\xfe\xc7\xadO\ +>\x88\'\xe3\x9aP\xc1\x9d&\xb22y\x99{w~@J\xc2\x81\x0b\x9c?\x82:=\xab \xf5\xdf\ +7M\x93\x1b\xd0z\x16\xdd"]\xdc\xc4U\xa1 Z\x93t\x05\x93\xf3\xa5\x12\xf2\xa4+\ +\xe5\xf1\xf7\xa8\xb3\x03E~\xc0K\t\x953\xa3:\xb0y{\x85\x8f\xe2T\x1b\x9e\xbaA\ +\xa8\x08\x8a2\xe4\xfc\x12\x8a\x9c\x9e!\xf5\xdd\xec\xf3\x18\x1eV\xc0\xfaFC\ +\xd3\xdc\xe5\xf2\xf8"~\xd0\xd6"\r\x9ey\xdcU\xba\xd8;?\xbb\x0fl<\x83\xd7>=\ +\x99\xd0\xb4\xeb\x8cFW\xb9\xe4\x97\x99\x8a\x94\x12\xe6B\x8f\x81\xcc\x11\xd9\ +\xc2\xfb\xc5\x99\xf5\xb7\x12\xfa\xa1G\x17t\xcfO;a\xa5\x1e\xab"\x9a\xef9K\x81\ +#\xcb\x9f\x84\xf2\xbf-\xb3\x1f(\xf3.7\x15\xadF\xcfr\xf3\xad[\xbc\xfe\xf5\xd7\ +\xca\xa1\x05\x94\xd0W\xca\'\xaf\xe5I\x0e{~iR\xac\x1a\xab}\xae\xd7.\x87\t\xb6\ +\xba\xc8\x0b7^S\x1eM\xe0C(\x89\xe4C\xc8\x80\x93\xc6\xefsh\xc4\xd6\xe0(\xf0\ +\xa6y\xc15\x87)(\xae\xd2\xb3c6\xe2&\x8f\x06\x8aX\x9f\xf8.3<5Y\xfb"\xdf\xfa\ +\xf6\x1f\xf2L\xad@\xbbM\x14\x1eu\r\x9bB\xc1\xc8\xd1j\xe00\xa3\xd4v(@\xebc9Y~\ +\x9a\x815\x947\x85\x97\x8a2\xd4{`\xc7#\xed\xdb\xe6\xfd\xb7xf|\x8d\x9f\xdc\ +\xfc\xaf\xbd\x078{WzY\n\x17\xf2\xde\xea:U\x14\xbf\xb0\xb6\xc6\xa4\x0e\xc4\ +\xa8\xdee\xb1\xcfd\xf9iM\\-\x15\xa3\x84,O\x92\xff6\x07t\x1dJc\xea|\xee\x8d\ +\xc6\xabl\xb4?C\xe2G\x18\xfa\xbd\xb5\x0bq\xd9Sk\xe1/3V,\xf4\xda\x9f]\x83\x97\ +%\xed|\xe0\x9cgqe\x9c\x1d\x7f9\x9c\x9fiV\xd1\xe7qZ2\xf6\x11\x96\x99\xfd!\x1d\ +\xf9\xcbPV\x0c\xa1\xe0W\'uA8\x1d\x8fBF+\xa6X\x10[1\xb2\xe74\xc1\xd2\x03\xa30\ +A\xba\xc8\xfdn\x87\x8b\xa9\xd1\xe4C\x0f\xab\xe3\t\xcei\xe8\xe1\xd4\x9c\xa1$\ +\xd93q\xba+\xae,\xb8\xe5\x04$\xc1\xd7\xab\xbc\xf3\xcem\xae\xafM\x18\xd9\xa18\ +\xa8\xca\xd2\xcf\xa9\xc5U4\xe0\xa4\xe1\x14\xe8\x95\x9e\xe3\xdc\xc7?]_\xe77\ +\xbe\xfc\x1a_^\x9b\xe4\xf1\x0b\xdb\xb9\xa9\xa9$-\xcf\x13\xcc\x15\x98\x17\xf2\ +\x18\xeb\xb3\x9f\xc0\x90qUQ\x99\xaf.\x93\xba\xf7\x9e8\xcf\xccz\x9aY\xb8\xec\ +\xda=z\x1f\xf4\xcaP\x08\x9e\xf1d\x8dW^\xfb*\xab\xe3\x1a7V\xcfS\xec\x02\xf7\ +\xdb\x86\xa9do\xca@qIy\x03\x1c\x9c\xa2\xc0\xe9\xcd\xfdg\x8cq\r\x15<%a\xab;\ +\xd4\xdc\x1f\x0f\xaf\xbdz\x03\x11\xe1\'\x1bM\x114f\xc9&\xa7\x02\xa3\x07\xb1\ +\x0b\\\xbf\xaec~i\xf5\x9a&\x94zX\xad\xeb\xcc?\x81\xad\x18i\xbb\xc8f\xfeH\xd7\ +\r\x12\xa9\x8dwN\xa1\xfd\xaf\xca\xff\xf6\xae[\xcd0\xcc\xb8\x9b\xff\xd7\xe7\ +\xfcZ\xf9\xdf,\xdc\xca\x84^>8\x06\xe3\xb6{\xd6&!{R\x84\xd5:0\xf9\xa3\x7f\xc5\ +V\xf3\x15~\xf8\xd6\xff\xe1\xbdw\xfe\x17\x98\x80\x1a\xb8\xdb\xcbk\x0644D\xe8\ +\xf5\xf5u\xee\xb7\x8d\x86oS\x86\nH\x02.h\x88\xd5\x85\'<#\'\x0c\xbf\xe47\xd8\ +\xfd\xc6K\x99(\xe0|Q\xdev~\xeb+\xc4\xbf\xfc\x9e\x86#3\xbfUU(\xf3\xb6\xeb0\ +\x1d2\xe7\xe6JH\xc8\x1dy\xe90\xe1Rs\xb2`\xc7=uD\xe0\xc2\xc1i\n\x10\xf4}\xfce\xc3\xa6\x9e\xf6\xa1Z\xa0\x8b\xd06=\xee\xc7P\xe8%Q\ +\xa0\xbfG\xe6^\xce\x9an\xd7E\xe6}\xe0j=a9\\\xe1\x99\xfai\x16C\xcdd\x14\xf0\ +\xa3\x90\xab\xc6\xec\x90\xa9\xa9CC\xa8&H\xd7\'D\xb7\xdd@\xd1\xe2\x0c\xddm&\ +\xcc\xd6\x1f^C!\x14\x16v\xd8\xc8VFJ\xea\xc2\xb4^jv_\xca\xde\x0e\xfb|\xfd\xf2\ +?e\xf2\xf9\x97\x08!\xb0\xe7\x16\xb9\xbd~\x84\x7fR\x0e\xe5\xd4\x81\xcfP\xd3vQ\ +A\xafD7Ir\x8a\x1b3[%q<\xfd?\t\xfe\xb7{\xcccw\xb7ix\xe3\xcd\x9bt\x9d\xf0\xe0\ +\xa3\x8f\xc0/\xffZ\xf8\x7fX)\xa1\xd3\xe9\x7f\x9eI\x10N\xea\xba\xf7>\xceT\xef\ +\xbc\xb4\xb6\xc6g&\x13n\xdf\xf82?\xbb\xfd.\x0f\xd6\x7fL\xdb6\xf8\x01\x94\xfd\ +Qo\xc3^\xe6\xb3\xf5\x8d\x86.\xc1\xc5\xd1\x15n\xac\xd6e\xfc\xb1S4n\x0bs\xce\ +\x9f6\x87\xa3\xe3\xcf\xbf\x1b&L\x9a\x17\xa6\xd9Xg7x.\x7fv\xc27\xbf\xf3\xef\ +\xf1I\xd8M\xbb|\xf8\x8b\xbbl\xfc\xe2.;1\xd2\xb5\xef\xcf\x1ch\x1a>[\xd2d\xf7\ +\xb2\xcf\xa0W\x82\xf4w\x1b\xcd\x87\x00\\_{\td\x8a\xb0D\x12\xe1 \t\xf3\xa7\ +\x19\x00\xc3\xb1\x0e\xf8\xd9e\x9a\x0f\xadw\xe9\x84\x83\xf0\x19\xdex\xeb]p\ +\xf3\xd9c\xd6_\x16\x028\xda#\xac$\x81\x0eC\x08\xf93\xdeA\xd3F\xda6R\xad\xdd \ +\x8cj\xa4\xd3\x03\xb9\xc7\x91:y\xfc3\xfbo8\x07\x1b;\xbdA\xd2\x12p\xd5Un\xbeu\ +\x8b\x7f\x92\xd6\xd8\xeav\x10y\\Z\xda\xc4.2\xed\x84G"\xbd\x87\xc8]\xa2\xaa\x94\xfd[\xaa\xaa\xe8Cg\ +\xa7]3c\xf7\xb3\xb24%\xa3\x95\xd2\x7f\xa3i\xe8\xb2\x11r\xa5Z,\xf3\x8fQ=\xfe\ +\xce{mN\x9d`u\xed\x1a\x93\x1b_%\x04\xcf\xa6\x08\x9b\xeb\x91PA=\n\xc5\xe0\xf7\ +^\x7f\xaeG\x8a\xa5f!m\x00$\x12\xb37\xfb4\xf1S\xe8=\xdc\xb7%\x95a\xb8P\xa2 \ +\xa4]\xcc\xca\xbe\xc7\x89P\x85\xc0\x17\xbe|\x83\xe5\xe7j\xd6\xdf\xb9\xcd\x8f\ +\xde\xba\xc9cK\xcc\xf6=\x84\xcb\xfd\x8c\xba\x7f\xf9\xea\xd5A\xca\x05\x8c}\ +\xcdx\x84\xd2?\xe6\x90|\xdc$\xb9\xa5\x9e\xfeg\x9c_@.\xfe\x91c\xe5QJ\xc2x\xf5\ +:\xc1K\x89\xd4,\xe4\xbfov\xc2n\x17\xf9p\xe3\x17<\x88\xf7\xd9k\x1b\xadj\xac<\ +\xde/\x11\xaaK%\x11\xda{5\xbeD\x84\xf1\xf3cpF\xffP\xe4g\xec\xa0#cN\x15\xfe?2\ +\xe4\x99\x9f\x86\xde\x83A\x9c.a\x1b/\xc7ds>H\xea\xb2;\xac\x13\x16:\x14-\xd5\ +\x1e\xa5\xbf\xc6\x12\xf8p\x91\xe0\xb5\xc4\xd4\x12\xce\xa2\xefA\xc8\xf4\xf2,!\ +\xc7z\x8e6"\x84Df\xaa\xd3\x85\xa8mR\x8b\x01\x07\x07~<\xc1O\xeaRf\x0c\xaa\x95\ +\x9b\xb5\t\xb0\xe2\xe7\xd8\x94C\xe6\x0f\x85\x87\x8f\xf4=\xde-\xa2%\xe0>\xbbe\ +s%\x15\x1a$z\xfe5}\xd8\xfaF\x03.\xb0Dd\xcf\xa90\xf2!p\x05u\xc1md\xc1\xd3ug\ +\x8c\x7f@\xbf|\xb62\xbe\xf1U~\x14\xb7\x88]\xe4\xce\x9d\xdb\xd4u]6{\x17\xe3\ +\x8c\x80\xabF5O\xd5W\xa8\xab\x8b,T\x97\xb9\x12.\x82[\xd2V$N\xe9\xd3t\x92\x91\ +9\x07\x1bC\xb4\xcc~\xae\xb8\xee\x03\xc1\x0b\xa1\x12$\x056\xda\x88\x93M\xa2\ +\x9c\x92H\\\xbc\x0cz\x98[G\xe5>\x0f\tv\xaf\\\x06\xb4/\xd3F\xf3\x8b\x99R~\x06\ +\xee\xfdy\x1fx\xees\xafP_{\x89\x10<\xe7\xcf\xe9\xe6\xddO\xda\xf7\xeb~\xdb\ +\x10\x9dW\xf6\xa3\xf7\xbe,\x01\x87N\xfbty\x97\x1b\xf2f\xfa\xfbd\x18\x1d\'\ +\x8f\xff\x93\xe0\x7fK~N\tb\x9c\xe2\xdc\x94\xae\xeb\x93\xb9\x7f]\xfc\xdf+)=\ +\x0eWO\x7f\x13\xae*\xb4\xa3(\xb5\x03\xb6\x1f\x84Gq\x0b\xe1\x10\xe7<\x97W_\ +\xe6\xb9\xc9\x0b\xc4\xcd\x07\xb4?\xff\x80v\xfd]m1\xc3P\x98\xea8\xde\xb9\xfd\ +\x1ew\xee\xac\x93D\xb8\x18\xae\xe8{+\xc5\xd0\x19U\n\x8b\xd0:\xed\x89\xd7\xc5\ +\xf8\xb1\xc7_\x04V\xce\xa10\xa3$\x89\xd0\x8a\x80h|\xdf\x80\xf9\xbc_\xe4\xf2g\ +\',_\xb5}\xfeUR\x12\xe6$2\xed"\x0f\xe3\x0e\x9d\xec\xd24[ \x9bY\xf9[b\x14.\ +\x95\xea\xca\x8d\x8du\xda\x18\xf9\xda\xef~\x9b\xc9\xea\x0bh\xb8\xdb\xb3\xd1\ +\xeaAb\x8a\xdcIW\xf1\xa20\x08\xbfXC\xc8\xcc\x13\x92T1\xbf<\xb9\xceo\\\xa7?8\ +\x9c\xcf-\x18\x18\xe4\xc50P\xbe\x17\xe9s\x82\x16y\xbc\xb3\xc5\xbc\xbf\x84g\ +\x17a\x11\xcf.~u\xc2\xab\xaf\x05\xaci&#}V\xdb\xaa7\xb1\x8b\xa7\x8f\xdf\xc6a\ +\xb4\xb6R\xf0\xde\xb8\xf1\xa5\x82\xeb\xc5\xeb\xbf\xc5\xcf\xe2C~\xf6\xe6\xdb,\ +W\x17\xb9Xy\xf6\\\r\x01\x96\xc2.\x95_\xe4\xd9\x12\x13\xc9\xbd\x07\x87\'\x8eS\ +\x84hI\xc2\xe1\x0e4\t\x96h\xfa\xfd\xeb=s\x950E\xe9oH\xc4\xa7\xc9\xcf\xa1\x12\ +T\xe0\r|\x8f\xfa-\x19(T\x04"\x19\xd5>7\x9c~\x8cg\xbb\x13V\x9cg\xdey\xaa\xd1\ +\xf3\xac~\xf1K\x8c\x9e}\xae\xe4\xe2Y\xbf\xc2\xfbI\xe1.\xf6S\xe4\xaa\xf74.p!E\ +\xf6\xbd\x07\xa7\xc0\xa0!\xe9H\xbb\xce\xe3\xdaX N\xce\xba,D\xd7\r\xf6\xaf/\ +\xf0\x1b\xda*\xa3\xeb\xc0y\x01\xb4\xbdG\x97\x84\xfbQ\x1bX\x93\xa0\x9eL\x08u\ +\xcd\xbd\xe6\x01\xef\xdf\xfaK\x8d\x84x5DL\xc6ui^\xb1\xbc\xf2\xd8w\xbd\xc7\ +\x1a)\xfb*0\t\xb0[y\xa6x\xda\xb69\x93\x7f\x8a\xd2\xe3|12\xbc\xd7\x9f\xd5\xb8\ +\xec+\x97\xdb\x0e|R\xf9\xbc\xe7<\x0b\x0eV\xbc\xe7\\]\xb3\xf2L\xcd\xe3\xfd\ +\xde\xeb\xf4P`~\xfa\x00v\x1f\xf2@\x0ei\x9a{\x88\xec\x93:m\xa7r\xae\ne\x1e\ +\xd60Z\x01v\xa1v\x9a\x80\xdeF\x95\xcbG\xcf\xaf\'<@\xd5\xe07C\x97\x96\x1d\xb0\ +\x9e\\Y\x93T\x005\x9d\x14w\x97\xc1t\x1b\x0e\x8f\xb7\xb8\xbc\xefq%\xdaN\xa8CM\ +\xec\x14!\xb3\xed"\xa3\xcaJ;\x85\xbb\xc2\xb1\x9e\xa3\xd5Z\x98K\x9e\xb77Nq\ +\xe1\x02.w\xb4\xb5RQ\x8bi\xf7y;\x1e\x97a\xc5\x85A\xc5\x06\x825I8\x98\xf3\xb8\ +\n*\x1fX@\xd8K\x9e\x85|\x98\x1e\xe6\r\xad\x80o\x8ap\x1b\x0b\xdd\x84\xbb\xf9\ +\x805\xc8\xf6P)]?7\xd2\xb7\xbc-\xa7\x8f\xdfJv\x8f&\xcb}\xf9\xf5\xd7y\xb0\xfe\ +\xf7l\xdc\xf9;n\xdfY\xd7\x9e.\xd5\xd3,\x8d\x9ec\xa5\xbe\xc8\x0b\xa1\xe2BxF\ +\x11\xab\xe7<\xcb\x87\xc2\xf9\x8b5\x0e\xf5>y\xa7 R\xba\xa6\x81\xad\xd8h\xdcw\ +`!w\xd2\x870\x89\xeb\x90\x13XW\xbc0\xc9\xae^\xd9\x88\x90\x9ac\xc7\xaf\xc9\ +\xae\x14\xda\x9b\xd0\xecD7\xb4\x08,\x8e^`\xde\x07\x1e\xb6\ro\xbc\xf1\x97\x8c\ +\xea\x9a\xc6\x92\xf2\x1cA\ +\x13\x8d\xde\xbd\xc5,\xe8\xfc\xea\x1cj\xd9\xd9\x8e,\x8f\xeaA\t\xb0\xe6\x9e\ +\xa4\xb0BJ\xca\'\xc1[\x0e\x9d\xd0\xb4BJ\xeb8\xe73\xff\x07\xeaZ=\xaew\xce\xa0\ +\x7f\t\xfb\xa4\xfep\x18\xa6\x03\xb8\x14q\x04\x12\xb0<\xbe\x0e)\x03u\xe6\xb9\ +\rk\x92,i]D\xc7x)\x84\x99s`g;\xa2\x18U\xbeT\xb6\x19\x08\x9fU\x9eV\x95\xf6b\ +\x1c\x8f<\xce\x05d\xa39\xd1\x0bQ\x94\x9c\x81\xfc\xb7uQe"\xc3\x01\x90\xf7t\'\ +\xb4I\xe7\xbc2y\x99\xcd\xf5w\xb9\x1f#+!\xf0\x1b\xd7\xd7\xa8WoPU\xea%\xaf+\ +\xcfJ\xe6\xb5C\xa7\xeb\xb6\'\xbac\xee\xe7u\xbe\x8f\x87\x0e\xf6\xd3:{\xb9\x8a\ +1x]\x83j\xac}\xcf\xd6\xd3\xc9\xfcc\x8aOO\xbf\x9c\xfcm=\xe1\x9c\x15\x9a\xe8\ +\xf9\xd5\x8a\xc7\x89\x9ey\xde{*\x84\xa9\xf4\x9e\xf3\x10\xb4u\xc7\xb3\xab/\ +\xf2\xe8\x83;\xb8\xdd\x8e\xaeS\x0f\xddx\xf5%]\x87(,\xf9\x06\xf1\x01\x9fs\xb3\ +\x86:\x8e\xcf\xfc_\xd75\x0bIx7\xf9\xde\xd0=\x86\x7fJ\xb51}>\x9fsZ\xfc\xe2+m\ +\xe5\x11\x13\xd9\xdb\xa5|`\xe3\xad\xfd\x01\xad\x08\xcb\xf6\xbc\xca\xab!.\xc2\ +\x82Sl\xab\x84*\xb1\xbb]\xc34\xeb\x19\x0bi\x17\xbcr\x9e\x01\xb1\x1a\x8f\xdb3\ +F#\xc1\xb9\x9a\xd44\x0c\x85\xc4\x8c\x02dU\nC\x85\xc1\x92\x94,\t\xd0\x92\x19\ +\xcbf\xf1}\x86\xbeb`P\x18,\xb9AB#\n\x8c\x16\x92\n\x93\xd8\xa9\xabj\xc1\xb0O|\ +\xc6\xb7AN\xf4\x1ci)\x9f\xd7\x9e\r\xc7\\\x96\xb8V\x14\x88\xdc\x94q\xe6\x1e\ +\xc8\xc9\xca9\xacA\xc6\x03r\xbd\xf0\xf4\x08+\x1e.T\xda\xb2`N\x84)\x81K\xa1/\ +\x0b\xb5\xdeBQL\xf3\r\n\xc2\'\xaa\x80\x89h\x1eD\x14\x8fs\xdac\xe8\xe3\x8c\ +\xbf\xb8\x9es\xacZ\x92W,\x96\x14\xb8\xba\xf6\n\xcb\x93W\x98O\xc2\x81\xcb\xd6\ +o\xd6\xda\xf7Pw\x1f\xfb\x9a\xd71\xef\xbd6ou\xbe\xe4z\x84J\xc3^\t\xa1r\x8a\ +\xd3d\tp\xa3\x91Z\x15\xd6\xd8\x0f\xf2\xbawB\xeb=\x93J\x90\xec\x15\xea\x9b^\ +\x1d\x9d@/x\x92y\x7f\xe87\xb2\xd1\xff\xe5\xaf\xff.?\xb9\xf57\xdcY\xff)\xeb\ +\x96\xffS]e4y\x99\xf1\xea\x0b8\xaf\x87f\x08\xd9C\x92\xadpE\xc1\xaeq\xae\xa1\ +\xf2\x1afy$R:-[o*\xd1\xa8\x18M\xa7\x16c\xe5\xd4=\xecQ%\xf6\xa4\xf1\x7fR\xfc\ +\xef\x9c\xe7r]\xb3\xb1q\x97\xef~\xff\x8d\xe2Z\xff\xecx\x8d/|n\r\xef\xf9\xa5\ +\xf9_\x0fC\xe1\xd9\x00{\'\xf0\xcfp\xfc\xce\xf5s(\xcbcss\xbe\x1c\x16%\xa9?\ +\xdf#N]\xd8U\x15\xb8P\xa9E\x95P\x87\xc2\x17^^\xc3\x7f\xe3u>l"\xb7~\xf0\x16o\ +\xff\xf5\x9b\xb4MC\x97\xce\xf3\xe2\xf5W\xb9>\x1e3\x1fj\xeeu\x0c*J"m\xa7\xfd\ +\x00\xdd\x19\xf4W\xcfa\xff}o\xb4\xccbJY\x92h\x1a\xf0\x95\xb5jIh\xc3R\xef=\ +\xe7\xfc"\x8b\xd9e\xee\x80\xb0\xec\xf1\xcb\xd6\xa0\xd3s9F\x1eI`\x0f\xed\x0c.\ +9t\x1c\xbb\xec\xe5\xebT\xb1*\x00\xa4)\x97U\x9f0\xfea\xd7k\xe8\xc3E\xa5\xd7W\ +\xe6\x13]\x9fYoy\x14S\x8e\x04W\xf5\x95\x9bU>x\xa7\xc08w\xed\xae\x9c\xc7{\r\ +\x13=\xea"S<\x97|\xe0Ql\x98f\xe5\\2\x0f\xb5\xb9\xb1\xe6\xa4Vz\x9eF\xffax\xcc\ +\x94h\xf5\xe2\xf6\x8aiLj\xc9k~\x87\xcf\x95Z\x92A\xff\x80l\x80\x8e\x82\xeeW\ +\xef`\xce\xc3\x14\xcf(\x84"\x13B\xa7\x07m\x14\xfd\xaau\xf1z\x10\xdb\xec\xe9\ +\x89\xa2\nV])\x18`\xa8\xce\x90\xffY.\x0eeh1\xea\x8c\xe6\xa9?\xa4M\x99\xbav\ +\xfd\x8b|\xe6\xda\xf3Lw\xc1\xd5\x97\x19\x87@\x15\x14\xb6e\xc5\xab\x97\xe2R0e\ +\xdb\xe3+\x0b\xb3(\xadC%\xd9\xa0Q\xa5\xc8\x0c\xa6.7\xb7\x1e\x8dj@x\xba\x92\ +\x13\xf7o\xa8B\xaf\xdb\r\x95\x0c\x93=\t-\xca9\xa6BKDJ\x9e\xa6s\xda\xb2BCG\ +\xba\x0e\xa9~\x95\x10\x02\x8f\xda\xc8\x97\xbe\xa1\xe0\x9aQ\x94\x7f\xf6\xacR\ +\xb3ScY\xf0\xc5\xd3E\xce\xa3\x1c\x8f\x94T\xc1\x9f\xb1\x7f\xab\xc1\xf9:\x1c{\ +\x9eS#\xbdQ\xe0\xbc\x9eo.\xcf\xa1\x91\xc7\xe0\xb5\x8f\xa7U{V\x1e\xa8\xf4\x19\ +\xa1\n\xe5\xfc\x8d]]\xc2\xa4\xdb\tFNS\x07\xac`\xc4x\xa8\xca\xc0\xc0\xe3Q\xe0\ +\xb8f\xd8\xb3\n\x90\xcb\tw@\'\x1e,\xac2\xb0\xec\xfb\xc4\xc8\xdeB3A:\xb4\x1eN\ +\xbc7k\xa8Z5\xe3iZ%\xc2\x12\xba\x802\x08\x11\x95\xf8\'\xcaX\x1e\xc1W\xe1D\ +\x07h\x957\x9c\xcb\xc4\xe8\xc4\x17\x10\xb9aF\xbaY\x1c\x0eJ\x92\xe1\x0cC\xb9\ +\xc0\xb6\x83\x0b\x08\xf7\xdb\xc8\xb9\xec\x82\xc4\xd5\xa4TS\xf9\xc8d\xa4\x01\ +\x84\x8d\x9c0\x99D]\x91z@\x0e\x08,\rT\xf5\xc7\x1a\xff\xa8\xa2\x80\xe4\x89\ +\xf7\xc4\xd8\xdf\xa9L\x92C\x03N[Z$,\x93^\xe7\x98\xb2v\xae\x8d!Cf\x14)\xf4\ +\x0c\x83\xec\xfd\x10<\x01O\xe3\r\x12\xc0\xa3\x1d\xe8\xf3;E=\x1d*\x94#m\n\x10\ +\x1b\xaa*\x9c\x18\x06\x08\xb9\xd5\xc2E\'l\xba\xec\xa6u\xbdg\xce\xac\xaf\x8b\ +\xa3\xe7X\xfd\xfa\xef\xe1\x80\xd86Zu0\x10\x8e\xa6\xc8\x92\x84G\xed\x16\x00\ +\xe7\xbc\xd2\xdfgK\x7fT\xf8\'2\x97`\x9a\xf4\xf0\x94N\x0fs;\x80m}\xf5\xf7\x92\ +\xc7\x7f<\xfd?)\xfe\x07\xf8\xad\xd7\xbf\xc9\x9d7\xbfG\xd348\xa7x#\xbf\xf7\ +\x07\xdf\xd4\xc6\x96I~i\xfe\x7f\xd4\xa9e\xe3\xbd\x9f\xe9\x08}\x94\xfe\x960l\ +\x15?\xa6\xe8\x0c\xf9\xc8\xae\xd9\xa4Z\x06\xf4\xb2\x83P\xdd\xea\x00\xe7\x9c\ +\',\xab\xa2\xffL\x1d\xf8\x97\xdf\xfa\x03~\xe7w\xbeN\xf3@\xf9~\t\xd8\xce\x07\ +\xee0y2\xaf$\xbb\x12i\x93\xa7\xce!\xb1\xe3.U~4|j9\\Co\xe8Px\xe9>\xce\x1e]S\ +\xbaMQu}i\xad\xe5\xb8y\x07){\x80*\xa7/\xf3\xae\xc6\x10|A-\xe8v\x10b1o\x82\ +\x93\xa9\x82\xf7\x9d1~\xef{\xe5\xac\x13U&\x8d\xc6\x95\xef\x8d-\xf3\xf6\xd9~\ +\x98Y\x93,?\xaa\xac\x04\x15d\xe2\xbc6O\xf0O\x0c\xa5\xf5\xca9\x1f \xaagQ\xbd|\ +\xe6I\xeb\xad\xfap\xc6\xf85\xfc\xe8\xf3\xc1.\x85\xe6V\xdal{A\xf9%\x97<\xbba\ +\xc2\xb0\xd2^\x128\x11\xbab\xc4\x01\x8f\xa5\x1c\xde\xa1\x82P\xd54Qz\x0f_V\ +\x00;\x19\x18\xd2\t\\\xe5i\x93.\x8by*\x8f\xbb\xccCVy5.\x8c\xfeC\xf4a \x1f\ +\xbc\x83\x10e\xfe\xa5\xab\xbe\xa0\x88\xc1\xe8;\ +\x94?*\xc35\x14\xf7(~\xc8\x9e\x81i&\xf8L]\x97\xe2\x02\x9f<1{\xe8e~Mh8;\xff>v\xc2~\x12.Xa\x03j\xc0\x8f\xaa\x80\xf7\ +\x82\xf7\x83\xfcTG\xa9f\x16\x03\x8e\xc4S%\x95\x9f\xdbI\x8bo\x86\xe3?J\xc7\ +\x92l\x17*U\xb4\rkB-\xf1\x1e\xad\xd7\xa1\x95\x1dn ,l\x91Be\x07\x902\xce\xf2\ +\xa1\xf0`?\xf0B\xb5\xcb\x85\xd1\x9an\xd0l\xc9\x8fG\xb5\xe6\xa4\x00\x8bN\xbd%\ +M\xec\x17\xd5:\x9a\x1bc\x9e\x9aD\x8cj\x9a\x0b\xc9\xbaj\xfb\x9cs\x98\x85N\x8a\ +\x1a.I1\x97\xd7\xf9\x0c\xad\xde\xc7\'-\xc4\x81h\x8c\xf7"slv\x92\xd1Q\x1b\xea\ +0\xb0\xf0\xe8\x93V\xf1\x01\xef<\x8d\xd3Lz\xabZX\xbe\xe0y\xec(a\x87\xd3\xc6\ +\xdf\xe5\xaa1c\x1a\x9f\x99E\xe9\x9dA\x0b\xf4a\xb2\x94\x02[I\xd3\x07\x92\ +D=t\x92\'\x1c\x98\x12\xa7\xcf\x19\x07Mz&A\x18\xf9\xe2u0\xc5qhT\xe7\x11\x9dJ\ +\x7f\x0b\xe4\x9a\'\xd1r~\xca\xfe\xf5\x9a#c\x8au\xd9\x13\x99w\x86\xde\xbb(\ +\x1eC\xaf6\x9c\x9c\xd1(\xa8\x17\r\x95\xcf\x93\xaa\xa6\x89\x91\xc5\xec\xc5]\'\ +\x12\t\x19\xbe\xc2\xc6#\x19\x87\xc9J%\x8e\xbfR"\xe7jz\xf0R\xd6\xa4\xa7o,s.\xd8\ +\xff\xd2\xff<\x18\xbf\xe1\xc9l\xb4\r\x1bg\x8c\xff8\x15\xc1\xe8\xf8q\xe4\x8f-\ +Q\x19\xff\x8c|\x1f\xf2\xbe\xc3C\ +\xeaY\xb2\xd9\x1c\xe3\xae\xcb[\xdb\x9d\x19\x81p\x9bz\xcf\x7f\x9e\x97\x9a\x06\ +\x86\tB@.\x80\r{=V\xae\xddA_\xdfQL\xd3\x9c\xe6`h\xe82\xa1\xdf:\xf8\xf1\x97\ +\x0c\xc7\xbf\x97\xb4,\x15\xbc\xf3\xaa\xc6#/W\xcd\xa8\xde)\xe9\r\x85@\x0fM\ +\xbaW\xe0\xc3\xd75\x9e{\xfb\x0b\x92\xc9$\x87\x0f\x1f\x9a\xe6\xc0\xcb\xe5\xc8\ +\x8e\xe5y\xba]\xa5\xfd1I<.\xa8\x0e\x0b\x86N\x14d\xe3\x0e\xb5,xJz\xcb\to]\x8b\ +\xc2\xa17\x96\xb1u\xeb\x96i\xcfl\xdb\xe6\xe0\x81\xf7\xc8f]\xe25\n\x0b\x17\ +\xa9TG\x8b.u]\xf2\xf7W\x85\xb2\xaa*AO\xbd\x9f\x95\xe5ZL\t`\xdb\xda\xab\xd8\ +\xe9\xa1R;8\x8e\xc3\xc9\x93_\x93Ju\xf0\xc3\xe9o\x10\x14\xcb1Yg^\x0e\xd2\xd7\ +\xca!\'\xa5\xd7\xcd\xc1\xd5\x91\x80HD`\x9a\x02=\x04%\xddd}>>\xf2\x12[.E1\x0c\ +\x93\xd1\xd1Q|\xbf\xf8\x81\xd6X\x0b\xbe/\t$\x08\t\xe3\x0e\xa4\xd3\x01\x1d\ +\xef\xeas\xd7\xf4\xf9\x8f\x8c\xd2\xa4Ov\x8eK\xc3\x104,T\x08\x9b0\xf0G\x81\ +\xcc8H\x19\x08\xd7u0\xcd\x10\xa6Y,\xbe\xa6\x8e\xcb\xf3\x83\x01\x86^\xc0\xf3\ +\xe1\xaf+\x92\xd7>3f=\xe2\xe6\xf9Q\xfb_%\x9fE\x84\xff\ +\xff\xef\xbf\tHQ\x8c\x18\x8f\x0f(F\xe3\x1e\x8c\xde\x02A@\x04\x89\x10BK\xed7\ +\xd4\xbe\xa4\xae+\xda\xa6\xa6k\x1bB\x08\x08\x821\x0e7\x1a3\x99L9\x9c\x1eQ\ +\x8c\xc6\xe9\xc1J\r@\xa8\x04W\x81D!J\xd8e\xc4\xb9\x82b4f<\x9e\xe0Fc\xac-0Zo\ +\xa1\xd3\xd4\x15\x95_RU+\x140\x1a9&\xe3\x02A\x11\xba\x8e\xaek\xe9\xda\x96\ +\xba\xf1\xd4~\xc3j\xfe\x11\x94\xe6\xe8\xf8\x84{\x0f\x1e2\x9d\x1d\xed`\xa8-\ +\x1c\x85H$\xc6\xb8\x03b\xac\xc5\xb9\x027\x1aS\x149+\xc6\x00\x8a\xf5\xf2\n_-(\ +\n\xcbg\xb3S\\Q\xa0\xb5\x05\x84\x10:\xba\xae\xa3ik\xda\xba\xa1nj|UR\x96\x1b\ +\xca\xcd\x8a\x8f\xef/\xb8\xfa\xf0\x8e\x87_>\xe1\xd1\xd7\xcfP:\x01@%@"\x91\ +\xd0\r2b\xb4\xc1X\x8b\xb5E\x02\xe4\n\xa2\x08\xe5\xea\x1a\x895\'\xf7\x1fp8\ +\x9d1\x99L\x18\x8d\xc6 B\x17:\x9a\xa6\xa1\xaek\x9a\xba\xc6\xd7\x15\x8d\xf7T9\ +\x98\xa2(\xb0\xd6\xb2\\.x\xfd\xeaWV\xeb\x1b\xbe{\xfe#\x93\x83i\x02\x82\x02\ +\x11\x94\x1e\x00Q\xda\xa0\xb5\xc1h\x8d1\x86(B\xb5\xbe\xa6pp|\xf2\x15w\xee\ +\xde\xe3\xce\x9dc\xa6\x87S\x14\x8a\xd2W\x94\x9b\x92\xb2,\xf1\xbe\xc2;\x9f\ +\x03q\x89\xec\xd6a\xacA)\rJ\x03\x91\xf37\xafi\xbc\xe7\xc5\xcb\x9f98\x98e!Dt\ +\xd0\x03 J%B\xe5\xfa\x95\xab\x04\xe2\xe4\xe4\x8c\xb3\xb3/x\xf4\xf81\xa7\xa7\ +\xa7\x84.p}}E\x1b\x02Z{\xb4I\xc0\x9d\xb3\x88\x8czbj\xad1F\xa7L\x1b\x83V\x1a\ +\xd0\xbc\xbf<\xe7\xf7W\xbf\xf1\xc3O\xbf$\x90\xa8^p\x16@D\xb2:`\xbd\xbcBb\xcd\ +\xf1\xc9W\x9c\x9d}\xc1\xb3\xe7\xcfy\xfa\xf4\x1b\xda\xb6\xe1\xfc\xfc\x9c\xc5r\ +\xc9f\xbd\xc6{O\xdb4t]G\x8c\x82\xd6\x86\xa2(2\x08\x8b6\x16c,\xc6\x18\x8c\xb1\ +\xd8\xcc\xc3\xcb?\xdf\xf0\xe6\xe8\x98\'\xdf~\x9f\xd58(\rY\xa2M]\xe1\xab\x05\ +\'\xf7\x1fp\xe7\xee=\x1e=~\xcc\xd3\xa7\xdf \x12\xb9\xb8x\xcb\xe5\xe5%\x8b\ +\x9b\x1b\xca\xb2\xa4njb\x08\xa0T\x8aZ\xebt\xe4\x07\x1bc\xb06\x83\xb1\x0e\xeb\ +\xd2a\x8c\xe1\xaf\xb7\x7fp\xf7\xfe\x19\xb3\xd9\xe7\xc8P5\x00\x12\xa1\xf2K\ +\x8a\xc2r8\x9dq\xe7\xce1\xa7\xa7\xa7\xb4m\xc3\xc5\xc5[\xde\xbd\xfb\x93\x9b\ +\xf9\x9c\xb2\xdc\xd0\xb6m\xb23\xa5\xd0(\xc4(\x10P:\xa2\x82N|3\x99w\xc6f\xfeX\ +\xb4N\xe5\x98_\x7f\xe0\xfd\xe5\x05\x87\x87G\xc4(\xfb@Bh\xa9\xaa\x15\x9f\xcdN\ +\x99L&L\x0f\xa7\x84.p~~\xce\xe5\xe5%7\xf39\x9brC\xd7\xb6\x88\x0c\xcdI\xd2\ +\xaa@\xabd\x82:jb\xceN\xcaJ\x02\xa4\xb4\x06\x81\x18\x02\xcb\xf9\x15U\xb5\xa6\ +(\xc6\x03 \x02\xb5\xdf\xa0\x00W\x14\x8cFc\x14\x8a\xeb\xeb+\x16\xcbe.G\x06\ +\xb1\xf3hP\x03\xa7\xccg\x85\x06\x03Z\x0c\xa2c&l\xe2\xcc\xb6et]G\xddxV\x8b9\ +\xc7\xf7\x1e\xecg\xa4\xf6%\xa3\x91Kf%B\xe9+\xda\x10\xd8\xac\xd7\x94e\x99\xca\ +!\x03\x100\xc8\xcc\xee\x8c\xca\x86\x05\x80\xc6\x08hcPZ\xa3H\xd9h\x9b\x06\xef\ +7x\xbfF\xe2\xfd\x81j\x10\xea\xbab2.\x80dV\xe5\xa6Dk\x8f\xf7\x9e\xba\xa9wmO\ +\xf6\x96\xfd\x16\xb7\x05\x90\xed@\xab\xd4&\x8c\xa4\xf2(\x05!\x04\x9a\xa6\xe6\ +\xe0`\xc6j\xbd"\xca-\xb2\xb6M\x9dzGv\xcc\xb2,\xd1F\xd36M\xaf\x8ed\xcf\xb731\ +\xc0\xd1\xe3QYE\xa6\xf7\xa8\xd42 t\x1d~\x92\xadz\x04!J\xec%\xba\xe5DYmX-\x17,n\ +\xe6\xcco\xe6D\x92\xb2\xd2\rng\x84mTi\x9d\x1cLy\xf1\xf2g~\x7f\xf5\x1b\x97\ +\x7f\xbe\xe9\xf78i\xa2\x14b\x08\x84\x10ro\n\xb4\xaeI\x8e\x99\xeb\x1e%\xe6V_Q\ +n\xd6,\x977\xac\xd7\x9b\x0cb\xa7\xba\xadO\xf7@v#\x86\xea=\xe2\xe0`\xc6\x0f?\ +\xfd\xc2\x9b\xa3c\xfez\xfb\x07\xf3\xeb\x0f\xc4\x10\x92\x07d\t\xfa\xf1\x84\ +\xd1\xa8\xc2mm[+$\xa6\xc1\xa7ij\xaa\xaad\xbdZ\x12"\xa0\x92\xd1\xa5\x92\xe8<\ +\xc5\xdf"\xab\x0c\xb2\xb1[\x93Y=\xf9\xf6{\xee\xde?\xe3\xfd\xe5\x05\xcb\xf9\ +\x15u\xe3\xf1~\xc3\xc1\xc1\x8c\xf1d\x92w\x86.76\x12A\xbb\x96\xa6\xae\x89\xa2\ +\xd3\x9e\xc9\xd8[\xfdH\xef\xf6\xc3\xfb\x1c\x11$\n"\x11\x91\x98\xc6|\x89=\x9b\ +f\xb3\xcf9<<\xa2\xaa\xd6\xac\x16s\xbc_\xb3Z\xafX\xae\x16\x18\x9d\xe7R\xeb\ +\xd2\x9e\xd9\xbad\x82\xb6\xe8K\x95g\xca\x9c\xfb\xfd\xd7\x02{>"\x92v\xe51\xa6\ +\xbd\xa8\xd2\x01\x1d4\xa2@b@b$F\xa1(\xc6\x1c\xdf{\x80\xc4\xfbD\x89\xe9&\x92_\ +P\x88\xf47\xbd\xbd\xaa\xac\x0e\xa5\xd8\x9b\xf4D\x04bO\x8a\x7f\xc7\x8b\x9a\ +\xbf\x01\xfc\t\xfa\\\xad\xe0v?\x00\x00\x00\x00IEND\xaeB`\x82' + +def getrestBitmap(): + return wxBitmapFromImage(getrestImage()) + +def getrestImage(): + stream = cStringIO.StringIO(getrestData()) + return wxImageFromStream(stream) + +index.append('rest') +catalog['rest'] = ImageClass() +catalog['rest'].getData = getrestData +catalog['rest'].getImage = getrestImage +catalog['rest'].getBitmap = getrestBitmap + + diff --git a/wxPython/demo/viewer_basics.py b/wxPython/demo/viewer_basics.py index 1dca97130d..7916c1bce2 100644 --- a/wxPython/demo/viewer_basics.py +++ b/wxPython/demo/viewer_basics.py @@ -59,11 +59,11 @@ class SecondThreadApp(wxApp): catcher = HiddenCatcher() #self.SetTopWindow(catcher) self.catcher =catcher - return true + return True #--------------------------------------------------------------------------- def add_cone(): frame = VtkFrame(None, -1, "Cone") - frame.Show(true) + frame.Show(True) diff --git a/wxPython/demo/widgetTest.py b/wxPython/demo/widgetTest.py index ee940e89f4..3ca627c6ab 100644 --- a/wxPython/demo/widgetTest.py +++ b/wxPython/demo/widgetTest.py @@ -1,6 +1,6 @@ -import sys, string +import sys from wxPython.wx import * from wxPython.html import * @@ -43,7 +43,7 @@ class TestHtmlPanel(wxPanel): import About wxPanel.__init__(self, parent, id, size=size) self.html = wxHtmlWindow(self, -1, wxPoint(5,5), wxSize(400, 350)) - py_version = string.split(sys.version)[0] + py_version = sys.version.split()[0] self.html.SetPage(About.MyAboutBox.text % (wx.__version__, py_version)) ir = self.html.GetInternalRepresentation() self.html.SetSize( (ir.GetWidth()+5, ir.GetHeight()+5) ) diff --git a/wxPython/demo/wxButton.py b/wxPython/demo/wxButton.py index 2a92effc12..159d06b328 100644 --- a/wxPython/demo/wxButton.py +++ b/wxPython/demo/wxButton.py @@ -19,20 +19,38 @@ class TestPanel(wxPanel): b = wxButton(self, 20, "HELLO AGAIN!", wxPoint(20, 60), wxSize(120, 45)) EVT_BUTTON(self, 20, self.OnClick) - b.SetToolTipString("This is a Hello button...") - bmp = images.getTest2Bitmap() - mask = wxMaskColour(bmp, wxBLUE) - bmp.SetMask(mask) + if 0: # a test case for catching wxPyAssertionError + + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_SUPPRESS) + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_EXCEPTION) + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_DIALOG) + #wxGetApp().SetAssertMode(wxPYAPP_ASSERT_EXCEPTION | wxPYAPP_ASSERT_DIALOG) + + try: + bmp = wxBitmap("nosuchfile.bmp", wxBITMAP_TYPE_BMP) + mask = wxMaskColour(bmp, wxBLUE) + except wxPyAssertionError: + self.log.write("Caught wxPyAssertionError! I will fix the problem.\n") + bmp = images.getTest2Bitmap() + mask = wxMaskColour(bmp, wxBLUE) + else: + bmp = images.getTest2Bitmap() + mask = wxMaskColour(bmp, wxBLUE) + bmp.SetMask(mask) wxBitmapButton(self, 30, bmp, wxPoint(160, 20), wxSize(bmp.GetWidth()+10, bmp.GetHeight()+10)) EVT_BUTTON(self, 30, self.OnClick) + def OnClick(self, event): - self.log.WriteText("Click! (%d)\n" % event.GetId()) + self.log.write("Click! (%d)\n" % event.GetId()) + ##wxLogDebug("debug message") + +## wxLog_SetLogLevel(wxLOG_Message) # ignore everything above wxLOG_Message #---------------------------------------------------------------------- @@ -43,15 +61,19 @@ def runTest(frame, nb, log): #---------------------------------------------------------------------- +overview = """ +

    wxButton

    +A button is a control that contains a text string or a bitmap and cab be +placed on nearly any kind of window. + +""" - - - -overview = """\ -""" - +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) diff --git a/wxPython/demo/wxCalendar.py b/wxPython/demo/wxCalendar.py index 487eeb39c1..5c14011608 100644 --- a/wxPython/demo/wxCalendar.py +++ b/wxPython/demo/wxCalendar.py @@ -75,7 +75,7 @@ class TestPanel(wxPanel): # set attributes of calendar - self.calend.hide_title = TRUE + self.calend.hide_title = True self.calend.HideGrid() self.calend.SetWeekColor('WHITE', 'BLACK') @@ -91,7 +91,7 @@ class TestPanel(wxPanel): mID = NewId() self.scroll = wxScrollBar(self, mID, wxPoint(100, 240), wxSize(200, 20), wxSB_HORIZONTAL) - self.scroll.SetScrollbar(start_month-1, 1, 12, 1, TRUE) + self.scroll.SetScrollbar(start_month-1, 1, 12, 1, True) EVT_COMMAND_SCROLL(self, mID, self.Scroll) # spin control for year selection @@ -147,8 +147,8 @@ class TestPanel(wxPanel): def TestFrame(self, event): frame = CalendFrame(self, -1, "Test Calendar", self.log) - frame.Show(true) - return true + frame.Show(True) + return True # calendar print preview @@ -171,7 +171,7 @@ class TestPanel(wxPanel): name = event.GetString() self.log.WriteText('EvtComboBox: %s\n' % name) monthval = self.date.FindString(name) - self.scroll.SetScrollbar(monthval, 1, 12, 1, TRUE) + self.scroll.SetScrollbar(monthval, 1, 12, 1, True) self.calend.SetMonth(monthval+1) self.ResetDisplay() @@ -366,8 +366,8 @@ class PrintCalend: self.sel_lst = [] # highlighted selected days self.size = None - self.hide_title = FALSE - self.hide_grid = FALSE + self.hide_title = False + self.hide_grid = False self.set_day = None def SetParms(self): @@ -416,7 +416,7 @@ class PrintCalend: frame.Initialize() frame.SetPosition(self.frame.GetPosition()) frame.SetSize(self.frame.GetSize()) - frame.Show(true) + frame.Show(True) def Print(self): pdd = wxPrintDialogData() @@ -438,7 +438,7 @@ class PrintCalend: if self.preview is None: cal.SetPSize(size[0]/self.pagew, size[1]/self.pageh) - cal.SetPreview(FALSE) + cal.SetPreview(False) else: if self.preview == 1: @@ -454,7 +454,7 @@ class PrintCalend: cal.grid_color = self.grid_color cal.high_color = self.high_color cal.back_color = self.back_color - cal.outer_border = FALSE + cal.outer_border = False cal.font = self.font cal.bold = self.bold @@ -534,9 +534,9 @@ class SetPrintout(wxPrintout): def HasPage(self, page): if page <= self.end_pg: - return true + return True else: - return false + return False def GetPageInfo(self): self.end_pg = self.canvas.GetTotalPages() @@ -594,14 +594,14 @@ class SetPrintout(wxPrintout): self.canvas.SetPageSize(self.psizew, self.psizeh) self.canvas.DoDrawing(dc) - return true + return True class MyApp(wxApp): def OnInit(self): frame = CalendFrame(None, -1, "Test Calendar") - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxCalendarCtrl.py b/wxPython/demo/wxCalendarCtrl.py index 02c771ad33..7afc4c37d7 100644 --- a/wxPython/demo/wxCalendarCtrl.py +++ b/wxPython/demo/wxCalendarCtrl.py @@ -19,6 +19,11 @@ class TestPanel(wxPanel): EVT_BUTTON(self, b.GetId(), self.OnButton) self.cal = cal + # Set up control to display a set of holidays: + EVT_CALENDAR_MONTH(self, cal.GetId(), self.OnChangeMonth) + self.holidays = [(1,1), (10,31), (12,25) ] # (these don't move around) + self.OnChangeMonth() + def OnButton(self, evt): self.cal.Destroy() self.cal = None @@ -26,6 +31,11 @@ class TestPanel(wxPanel): def OnCalSelected(self, evt): self.log.write('OnCalSelected: %s\n' % evt.GetDate()) + def OnChangeMonth(self, evt=None): + cur_month = self.cal.GetDate().GetMonth() + 1 # convert wxDateTime 0-11 => 1-12 + for month, day in self.holidays: + if month == cur_month: + self.cal.SetHoliday(day) #---------------------------------------------------------------------- diff --git a/wxPython/demo/wxCheckBox.py b/wxPython/demo/wxCheckBox.py index 45f82e2f48..e2e81e3f28 100644 --- a/wxPython/demo/wxCheckBox.py +++ b/wxPython/demo/wxCheckBox.py @@ -14,7 +14,7 @@ class TestCheckBox(wxPanel): cID = NewId() cb1 = wxCheckBox(self, cID, " Apples", wxPoint(65, 40), wxSize(150, 20), wxNO_BORDER) cb2 = wxCheckBox(self, cID+1, " Oranges", wxPoint(65, 60), wxSize(150, 20), wxNO_BORDER) - cb2.SetValue(true) + cb2.SetValue(True) cb3 = wxCheckBox(self, cID+2, " Pears", wxPoint(65, 80), wxSize(150, 20), wxNO_BORDER) EVT_CHECKBOX(self, cID, self.EvtCheckBox) diff --git a/wxPython/demo/wxCheckListBox.py b/wxPython/demo/wxCheckListBox.py index 4a0fd024c7..434ecf2e06 100644 --- a/wxPython/demo/wxCheckListBox.py +++ b/wxPython/demo/wxCheckListBox.py @@ -22,7 +22,8 @@ class TestPanel(wxPanel): lb.SetSelection(0) self.lb = lb - btn = wxButton(self, -1, "Test SetString", (180, 50)) + pos = lb.GetPosition().x + lb.GetSize().width + 25 + btn = wxButton(self, -1, "Test SetString", (pos, 50)) EVT_BUTTON(self, btn.GetId(), self.OnTestButton) EVT_RIGHT_UP(self, self.OnDoPopup) @@ -44,7 +45,7 @@ class TestPanel(wxPanel): item = wxMenuItem(menu, wxNewId(), "If supported, this is bold") df = wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT) nf = wxFont(df.GetPointSize(), df.GetFamily(), df.GetStyle(), wxBOLD, - false, df.GetFaceName()) + False, df.GetFaceName()) item.SetFont(nf) menu.AppendItem(item) diff --git a/wxPython/demo/wxColourDialog.py b/wxPython/demo/wxColourDialog.py index a949731ff1..c4d42aebbf 100644 --- a/wxPython/demo/wxColourDialog.py +++ b/wxPython/demo/wxColourDialog.py @@ -5,7 +5,7 @@ from wxPython.wx import * def runTest(frame, nb, log): dlg = wxColourDialog(frame) - dlg.GetColourData().SetChooseFull(true) + dlg.GetColourData().SetChooseFull(True) if dlg.ShowModal() == wxID_OK: data = dlg.GetColourData() log.WriteText('You selected: %s\n' % str(data.GetColour().Get())) diff --git a/wxPython/demo/wxComboBox.py b/wxPython/demo/wxComboBox.py index b3dfc92739..37e52cbb37 100644 --- a/wxPython/demo/wxComboBox.py +++ b/wxPython/demo/wxComboBox.py @@ -1,4 +1,3 @@ -import string from wxPython.wx import * #--------------------------------------------------------------------------- @@ -35,7 +34,7 @@ class TestComboBox(wxPanel): cb = wxComboBox(self, 501, "default value", wxPoint(90, 80), wxSize(95, -1), [], wxCB_SIMPLE) for item in sampleList: - cb.Append(item, string.upper(item)) + cb.Append(item, item.upper()) EVT_COMBOBOX(self, 501, self.EvtComboBox) EVT_TEXT(self, 501, self.EvtText) diff --git a/wxPython/demo/wxDialog.py b/wxPython/demo/wxDialog.py index 8d614756e1..615539add3 100644 --- a/wxPython/demo/wxDialog.py +++ b/wxPython/demo/wxDialog.py @@ -1,54 +1,102 @@ from wxPython.wx import * +from wxPython.help import * #--------------------------------------------------------------------------- +# Create and set a help provider. Normally you would do this in +# the app's OnInit as it must be done before any SetHelpText calls. +provider = wxSimpleHelpProvider() +wxHelpProvider_Set(provider) -def runTest(frame, nb, log): - win = wxDialog(frame, -1, "This is a wxDialog", size=wxSize(350, 200), style=wxCAPTION) - sizer = wxBoxSizer(wxVERTICAL) - label = wxStaticText(win, -1, "This is a wxDialog") - sizer.Add(label, 0, wxALIGN_CENTRE|wxALL, 5) +#--------------------------------------------------------------------------- + +class TestDialog(wxDialog): + def __init__(self, parent, ID, title, + pos=wxDefaultPosition, size=wxDefaultSize, + style=wxDEFAULT_DIALOG_STYLE): + + # Instead of calling wxDialog.__init__ we precreate the dialog + # so we can set an extra style that must be set before + # creation, and then we create the GUI dialog using the Create + # method. + pre = wxPreDialog() + pre.SetExtraStyle(wxDIALOG_EX_CONTEXTHELP) + pre.Create(parent, ID, title, pos, size, style) + + # This next step is the most important, it turns this Python + # object into the real wrapper of the dialog (instead of pre) + # as far as the wxPython extension is concerned. + self.this = pre.this + + + # Now continue with the normal construction of the dialog + # contents + sizer = wxBoxSizer(wxVERTICAL) + + label = wxStaticText(self, -1, "This is a wxDialog") + label.SetHelpText("This is the help text for the label") + sizer.Add(label, 0, wxALIGN_CENTRE|wxALL, 5) + + box = wxBoxSizer(wxHORIZONTAL) + + label = wxStaticText(self, -1, "Field #1:") + label.SetHelpText("This is the help text for the label") + box.Add(label, 0, wxALIGN_CENTRE|wxALL, 5) - box = wxBoxSizer(wxHORIZONTAL) + text = wxTextCtrl(self, -1, "", size=(80,-1)) + text.SetHelpText("Here's some help text for field #1") + box.Add(text, 1, wxALIGN_CENTRE|wxALL, 5) - label = wxStaticText(win, -1, "Field #1:") - box.Add(label, 0, wxALIGN_CENTRE|wxALL, 5) + sizer.AddSizer(box, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5) - text = wxTextCtrl(win, -1, "", size=(80,-1)) - box.Add(text, 1, wxALIGN_CENTRE|wxALL, 5) + box = wxBoxSizer(wxHORIZONTAL) - sizer.AddSizer(box, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5) + label = wxStaticText(self, -1, "Field #2:") + label.SetHelpText("This is the help text for the label") + box.Add(label, 0, wxALIGN_CENTRE|wxALL, 5) - box = wxBoxSizer(wxHORIZONTAL) + text = wxTextCtrl(self, -1, "", size=(80,-1)) + text.SetHelpText("Here's some help text for field #2") + box.Add(text, 1, wxALIGN_CENTRE|wxALL, 5) - label = wxStaticText(win, -1, "Field #2:") - box.Add(label, 0, wxALIGN_CENTRE|wxALL, 5) + sizer.AddSizer(box, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5) - text = wxTextCtrl(win, -1, "", size=(80,-1)) - box.Add(text, 1, wxALIGN_CENTRE|wxALL, 5) + line = wxStaticLine(self, -1, size=(20,-1), style=wxLI_HORIZONTAL) + sizer.Add(line, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP, 5) - sizer.AddSizer(box, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5) + box = wxBoxSizer(wxHORIZONTAL) - line = wxStaticLine(win, -1, size=(20,-1), style=wxLI_HORIZONTAL) - sizer.Add(line, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP, 5) + if wxPlatform != "__WXMSW__": + btn = wxContextHelpButton(self) + box.Add(btn, 0, wxALIGN_CENTRE|wxALL, 5) - box = wxBoxSizer(wxHORIZONTAL) + btn = wxButton(self, wxID_OK, " OK ") + btn.SetDefault() + btn.SetHelpText("The OK button completes the dialog") + box.Add(btn, 0, wxALIGN_CENTRE|wxALL, 5) - btn = wxButton(win, wxID_OK, " OK ") - btn.SetDefault() - box.Add(btn, 0, wxALIGN_CENTRE|wxALL, 5) + btn = wxButton(self, wxID_CANCEL, " Cancel ") + btn.SetHelpText("The Cancel button cnacels the dialog. (Duh!)") + box.Add(btn, 0, wxALIGN_CENTRE|wxALL, 5) - btn = wxButton(win, wxID_CANCEL, " Cancel ") - box.Add(btn, 0, wxALIGN_CENTRE|wxALL, 5) + sizer.AddSizer(box, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5) - sizer.AddSizer(box, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5) + self.SetSizer(sizer) + self.SetAutoLayout(True) + sizer.Fit(self) - win.SetSizer(sizer) - win.SetAutoLayout(true) - sizer.Fit(win) + +#--------------------------------------------------------------------------- + +def runTest(frame, nb, log): + win = TestDialog(frame, -1, "This is a wxDialog", size=wxSize(350, 200), + #style = wxCAPTION | wxSYSTEM_MENU | wxTHICK_FRAME + style = wxDEFAULT_DIALOG_STYLE + ) + win.CenterOnScreen() val = win.ShowModal() if val == wxID_OK: log.WriteText("You pressed OK\n") @@ -63,10 +111,13 @@ def runTest(frame, nb, log): +overview = """\ +""" +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) - -overview = """\ -""" diff --git a/wxPython/demo/wxDragImage.py b/wxPython/demo/wxDragImage.py index 7ab24df8b9..5fcecb0d53 100644 --- a/wxPython/demo/wxDragImage.py +++ b/wxPython/demo/wxDragImage.py @@ -9,14 +9,14 @@ class DragShape: def __init__(self, bmp): self.bmp = bmp self.pos = wxPoint(0,0) - self.shown = true + self.shown = True self.text = None - self.fullscreen = false + self.fullscreen = False def HitTest(self, pt): rect = self.GetRect() - return rect.Inside(pt.x, pt.y) + return rect.InsideXY(pt.x, pt.y) def GetRect(self): @@ -31,11 +31,11 @@ class DragShape: dc.Blit(self.pos.x, self.pos.y, self.bmp.GetWidth(), self.bmp.GetHeight(), - memDC, 0, 0, op, true) + memDC, 0, 0, op, True) - return true + return True else: - return false + return False @@ -58,7 +58,7 @@ class DragCanvas(wxScrolledWindow): bmp = images.getTestStarBitmap() shape = DragShape(bmp) shape.pos = wxPoint(5, 5) - shape.fullscreen = true + shape.fullscreen = True self.shapes.append(shape) @@ -185,7 +185,7 @@ class DragCanvas(wxScrolledWindow): # reposition and draw the shape self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos - self.dragShape.shown = true + self.dragShape.shown = True self.dragShape.Draw(dc) self.dragShape = None @@ -207,7 +207,7 @@ class DragCanvas(wxScrolledWindow): # erase the shape since it will be drawn independently now dc = wxClientDC(self) - self.dragShape.shown = false + self.dragShape.shown = False self.EraseShape(self.dragShape, dc) @@ -228,16 +228,16 @@ class DragCanvas(wxScrolledWindow): # if we have shape and image then move it, posibly highlighting another shape. elif self.dragShape and self.dragImage: onShape = self.FindShape(evt.GetPosition()) - unhiliteOld = false - hiliteNew = false + unhiliteOld = False + hiliteNew = False # figure out what to hilite and what to unhilite if self.hiliteShape: if onShape is None or self.hiliteShape is not onShape: - unhiliteOld = true + unhiliteOld = True if onShape and onShape is not self.hiliteShape and onShape.shown: - hiliteNew = TRUE + hiliteNew = True # if needed, hide the drag image so we can update the window if unhiliteOld or hiliteNew: @@ -274,3 +274,10 @@ def runTest(frame, nb, log): overview = """\ """ + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxDynamicSashWindow.py b/wxPython/demo/wxDynamicSashWindow.py index dd9652791d..9c9d1fa5b7 100644 --- a/wxPython/demo/wxDynamicSashWindow.py +++ b/wxPython/demo/wxDynamicSashWindow.py @@ -89,6 +89,10 @@ class SimpleView(wxPanel): #---------------------------------------------------------------------- def runTest(frame, nb, log): + if wxPlatform == "__WXMAC__": + wxMessageBox("This demo currently fails on the Mac. The problem is being looked into...", "Sorry") + return + if 1: win = wxDynamicSashWindow(nb, -1, style = 0 | wxCLIP_CHILDREN @@ -149,3 +153,10 @@ You will need to set the scrollbars' event handler at three times: """ + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxEditor.py b/wxPython/demo/wxEditor.py index 2ee5c23c6b..0ae5f8f741 100644 --- a/wxPython/demo/wxEditor.py +++ b/wxPython/demo/wxEditor.py @@ -10,7 +10,7 @@ def runTest(frame, nb, log): box = wxBoxSizer(wxVERTICAL) box.Add(ed, 1, wxALL|wxGROW, 1) win.SetSizer(box) - win.SetAutoLayout(true) + win.SetAutoLayout(True) ed.SetText(["", "This is a simple text editor, the class name is", diff --git a/wxPython/demo/wxFileDialog.py b/wxPython/demo/wxFileDialog.py index a3c753e45b..a73dc06970 100644 --- a/wxPython/demo/wxFileDialog.py +++ b/wxPython/demo/wxFileDialog.py @@ -1,6 +1,5 @@ from wxPython.wx import * -import string #--------------------------------------------------------------------------- @@ -11,8 +10,10 @@ wildcard = "Python source (*.py)|*.py|" \ def runTest(frame, nb, log): dlg = wxFileDialog(frame, "Choose a file", "", "", wildcard, wxOPEN|wxMULTIPLE) if dlg.ShowModal() == wxID_OK: - for path in dlg.GetPaths(): - log.WriteText('You selected: %s\n' % path) + paths = dlg.GetPaths() + log.WriteText('You selected %d files:' % len(paths)) + for path in paths: + log.WriteText(' %s\n' % path) dlg.Destroy() #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxFileHistory.py b/wxPython/demo/wxFileHistory.py index 8847e2f679..0da510cf4d 100644 --- a/wxPython/demo/wxFileHistory.py +++ b/wxPython/demo/wxFileHistory.py @@ -37,7 +37,7 @@ class TestPanel(wxPanel): box.Add(t, 0, wxCENTER|wxALL, 5) self.SetSizer(box) - self.SetAutoLayout(true) + self.SetAutoLayout(True) # Make a menu self.menu = m = wxMenu() @@ -46,10 +46,10 @@ class TestPanel(wxPanel): m.Append(wxID_CLOSE, "&Close") m.Append(wxID_SAVE, "&Save") m.Append(wxID_SAVEAS, "Save &as...") - m.Enable(wxID_NEW, false) - m.Enable(wxID_CLOSE, false) - m.Enable(wxID_SAVE, false) - m.Enable(wxID_SAVEAS, false) + m.Enable(wxID_NEW, False) + m.Enable(wxID_CLOSE, False) + m.Enable(wxID_SAVE, False) + m.Enable(wxID_SAVEAS, False) # and a file history self.filehistory = wxFileHistory() diff --git a/wxPython/demo/wxFindReplaceDialog.py b/wxPython/demo/wxFindReplaceDialog.py index 14b0e32df8..c0217aedec 100644 --- a/wxPython/demo/wxFindReplaceDialog.py +++ b/wxPython/demo/wxFindReplaceDialog.py @@ -25,21 +25,21 @@ class TestPanel(wxPanel): data = wxFindReplaceData() dlg = wxFindReplaceDialog(self, data, "Find") dlg.data = data # save a reference to it... - dlg.Show(true) + dlg.Show(True) def OnShowFindReplace(self, evt): data = wxFindReplaceData() dlg = wxFindReplaceDialog(self, data, "Find & Replace", wxFR_REPLACEDIALOG) dlg.data = data # save a reference to it... - dlg.Show(true) + dlg.Show(True) def OnFind(self, evt): map = { wxEVT_COMMAND_FIND : "FIND", wxEVT_COMMAND_FIND_NEXT : "FIND_NEXT", - wxEVT_COMMAND_FIND_REPLACE : "REPALCE", + wxEVT_COMMAND_FIND_REPLACE : "REPLACE", wxEVT_COMMAND_FIND_REPLACE_ALL : "REPLACE_ALL", } et = evt.GetEventType() diff --git a/wxPython/demo/wxFloatBar.py b/wxPython/demo/wxFloatBar.py index 593e3b0ab8..ff323abe7e 100644 --- a/wxPython/demo/wxFloatBar.py +++ b/wxPython/demo/wxFloatBar.py @@ -70,7 +70,7 @@ class TestFloatBar(wxFrame): def runTest(frame, nb, log): win = TestFloatBar(frame, log) frame.otherWin = win - win.Show(true) + win.Show(True) #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxFontDialog.py b/wxPython/demo/wxFontDialog.py index 509ebfbb3a..e27ad38d74 100644 --- a/wxPython/demo/wxFontDialog.py +++ b/wxPython/demo/wxFontDialog.py @@ -3,43 +3,127 @@ from wxPython.wx import * #--------------------------------------------------------------------------- -def runTest(frame, nb, log): - data = wxFontData() - data.EnableEffects(true) - font_colour = wxColour(255, 0, 0) # colour of font (red) - data.SetColour(font_colour) # set colour - ##print data.GetColour() - dlg = wxFontDialog(frame, data) - dlg.SetSize((250,250)) - if dlg.ShowModal() == wxID_OK: - data = dlg.GetFontData() - font = data.GetChosenFont() - log.WriteText('You selected: "%s", %d points, color %s\n' % - (font.GetFaceName(), font.GetPointSize(), - data.GetColour().Get())) - dlg.Destroy() +class TestPanel(wxPanel): + def __init__(self, parent, log): + wxPanel.__init__(self, parent, -1) + self.log = log -#--------------------------------------------------------------------------- + btn = wxButton(self, -1, "Select Font") + EVT_BUTTON(self, btn.GetId(), self.OnSelectFont) + self.sampleText = wxTextCtrl(self, -1, "Sample Text") + #from wxPython.lib.stattext import wxGenStaticText + #self.sampleText = wxGenStaticText(self, -1, "Sample Text") + self.curFont = self.sampleText.GetFont() + self.curClr = wxBLACK + fgs = wxFlexGridSizer(cols=2, vgap=5, hgap=5) + fgs.AddGrowableCol(1) + fgs.AddGrowableRow(0) + fgs.Add(btn) + fgs.Add(self.sampleText, 0, wxADJUST_MINSIZE|wxGROW) + fgs.Add(15,15); fgs.Add(15,15) # an empty row + fgs.Add(wxStaticText(self, -1, "PointSize:")) + self.ps = wxStaticText(self, -1, "") + font = self.ps.GetFont() + font.SetWeight(wxBOLD) + self.ps.SetFont(font) + fgs.Add(self.ps, 0, wxADJUST_MINSIZE) + fgs.Add(wxStaticText(self, -1, "Family:")) + self.family = wxStaticText(self, -1, "") + self.family.SetFont(font) + fgs.Add(self.family, 0, wxADJUST_MINSIZE) + fgs.Add(wxStaticText(self, -1, "Style:")) + self.style = wxStaticText(self, -1, "") + self.style.SetFont(font) + fgs.Add(self.style, 0, wxADJUST_MINSIZE) + fgs.Add(wxStaticText(self, -1, "Weight:")) + self.weight = wxStaticText(self, -1, "") + self.weight.SetFont(font) + fgs.Add(self.weight, 0, wxADJUST_MINSIZE) + fgs.Add(wxStaticText(self, -1, "Face:")) + self.face = wxStaticText(self, -1, "") + self.face.SetFont(font) + fgs.Add(self.face, 0, wxADJUST_MINSIZE) + fgs.Add(15,15); fgs.Add(15,15) # an empty row + fgs.Add(wxStaticText(self, -1, "wxNativeFontInfo:")) + self.nfi = wxStaticText(self, -1, "") + self.nfi.SetFont(font) + fgs.Add(self.nfi, 0, wxADJUST_MINSIZE) + + # give it some border space + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(fgs, 0, wxGROW|wxADJUST_MINSIZE|wxALL, 25) + + self.SetSizer(sizer) + self.UpdateUI() + + + def UpdateUI(self): + self.sampleText.SetFont(self.curFont) + self.ps.SetLabel(str(self.curFont.GetPointSize())) + self.family.SetLabel(self.curFont.GetFamilyString()) + self.style.SetLabel(self.curFont.GetStyleString()) + self.weight.SetLabel(self.curFont.GetWeightString()) + self.face.SetLabel(self.curFont.GetFaceName()) + self.nfi.SetLabel(self.curFont.GetNativeFontInfo().ToString()) + self.Layout() -overview = """\ -This class represents the font chooser dialog. -wxFontDialog() ----------------------------- + def OnSelectFont(self, evt): + data = wxFontData() + data.EnableEffects(True) + data.SetColour(self.curClr) # set colour + data.SetInitialFont(self.curFont) -wxFontDialog(wxWindow* parent, wxFontData* data) + dlg = wxFontDialog(self, data) + if dlg.ShowModal() == wxID_OK: + data = dlg.GetFontData() + font = data.GetChosenFont() + colour = data.GetColour() + self.log.WriteText('You selected: "%s", %d points, color %s\n' % + (font.GetFaceName(), font.GetPointSize(), + colour.Get())) + self.curFont = font + self.curClr = colour + self.UpdateUI() + dlg.Destroy() + + + + + +#--------------------------------------------------------------------------- + +def runTest(frame, nb, log): + win = TestPanel(nb, log) + return win + + +#--------------------------------------------------------------------------- + + + + +overview = """\ +This class allows you to use the system font chooser dialog. -Constructor. Pass a parent window and a font data object, which will be copied to the font dialog's font data. """ + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxFrame.py b/wxPython/demo/wxFrame.py index 3eac8d119c..428859beec 100644 --- a/wxPython/demo/wxFrame.py +++ b/wxPython/demo/wxFrame.py @@ -16,7 +16,7 @@ class MyFrame(wxFrame): def OnCloseMe(self, event): - self.Close(true) + self.Close(True) def OnCloseWindow(self, event): self.Destroy() @@ -27,7 +27,7 @@ def runTest(frame, nb, log): win = MyFrame(frame, -1, "This is a wxFrame", size=(350, 200), style = wxDEFAULT_FRAME_STYLE)# | wxFRAME_TOOL_WINDOW ) frame.otherWin = win - win.Show(true) + win.Show(True) #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxGLCanvas.py b/wxPython/demo/wxGLCanvas.py index d1e2c025b5..a4d0194cb0 100644 --- a/wxPython/demo/wxGLCanvas.py +++ b/wxPython/demo/wxGLCanvas.py @@ -1,18 +1,18 @@ from wxPython.wx import * try: from wxPython.glcanvas import * - haveGLCanvas = true + haveGLCanvas = True except ImportError: - haveGLCanvas = false + haveGLCanvas = False try: # The Python OpenGL package can be found at # http://PyOpenGL.sourceforge.net/ from OpenGL.GL import * from OpenGL.GLUT import * - haveOpenGL = true + haveOpenGL = True except ImportError: - haveOpenGL = false + haveOpenGL = False #---------------------------------------------------------------------- @@ -62,7 +62,7 @@ else: c.SetSize((200, 200)) box.Add(c, 0, wxALIGN_CENTER|wxALL, 15) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(box) @@ -71,7 +71,7 @@ else: canvasClass = eval(canvasClassName) frame = wxFrame(None, -1, canvasClassName, size=(400,400)) canvas = canvasClass(frame) - frame.Show(true) + frame.Show(True) @@ -85,7 +85,7 @@ else: class MyCanvasBase(wxGLCanvas): def __init__(self, parent): wxGLCanvas.__init__(self, parent, -1) - self.init = false + self.init = False # initial mouse position self.lastx = self.x = 30 self.lasty = self.y = 30 @@ -110,7 +110,7 @@ else: self.SetCurrent() if not self.init: self.InitGL() - self.init = true + self.init = True self.OnDraw() def OnMouseDown(self, evt): @@ -123,7 +123,7 @@ else: if evt.Dragging() and evt.LeftIsDown(): self.x, self.y = self.lastx, self.lasty self.x, self.y = evt.GetPosition() - self.Refresh(false) + self.Refresh(False) @@ -268,9 +268,9 @@ def _test(): frame = wxFrame(None, -1, "GL Demos", wxDefaultPosition, wxSize(600,300)) #win = ConeCanvas(frame) MySplitter(frame) - frame.Show(TRUE) + frame.Show(True) self.SetTopWindow(frame) - return TRUE + return True app = MyApp(0) app.MainLoop() diff --git a/wxPython/demo/wxGenericDirCtrl.py b/wxPython/demo/wxGenericDirCtrl.py index 6799b1f93f..7f338e67df 100644 --- a/wxPython/demo/wxGenericDirCtrl.py +++ b/wxPython/demo/wxGenericDirCtrl.py @@ -37,7 +37,7 @@ class TestPanel(wxPanel): sz.AddGrowableCol(1) sz.AddGrowableCol(2) self.SetSizer(sz) - self.SetAutoLayout(true) + self.SetAutoLayout(True) #---------------------------------------------------------------------- diff --git a/wxPython/demo/wxGrid.py b/wxPython/demo/wxGrid.py index a95ed9bacc..365e0125e6 100644 --- a/wxPython/demo/wxGrid.py +++ b/wxPython/demo/wxGrid.py @@ -4,12 +4,13 @@ from wxPython.wx import * #--------------------------------------------------------------------------- buttonDefs = { - 814 : ('GridSimple', 'Simple wxGrid, catching all events'), - 815 : ('GridStdEdRend', 'wxGrid showing Editors and Renderers'), - 818 : ('GridHugeTable', 'A wxGrid with a HUGE table (100 MILLION cells!)'), - 817 : ('GridCustTable', 'wxGrid using a custom Table, with non-string data'), - 819 : ('GridEnterHandler','Remapping keys to behave differently'), - 820 : ('GridCustEditor', 'Shows how to create a custom Cell Editor'), + 814 : ('GridSimple', ' Simple wxGrid, catching all events '), + 815 : ('GridStdEdRend', ' wxGrid showing Editors and Renderers '), + 818 : ('GridHugeTable', ' A wxGrid with a HUGE table (100 MILLION cells!) '), + 817 : ('GridCustTable', ' wxGrid using a custom Table, with non-string data '), + 819 : ('GridEnterHandler',' Remapping keys to behave differently '), + 820 : ('GridCustEditor', ' Shows how to create a custom Cell Editor '), + 821 : ('GridDragable', ' A wxGrid with dragable rows and columns '), } @@ -28,7 +29,7 @@ class ButtonPanel(wxPanel): box.Add(btn, 0, wxALIGN_CENTER|wxALL, 15) EVT_BUTTON(self, k, self.OnButton) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(box) @@ -36,7 +37,7 @@ class ButtonPanel(wxPanel): modName = buttonDefs[evt.GetId()][0] module = __import__(modName) frame = module.TestFrame(None, self.log) - frame.Show(true) + frame.Show(True) #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxHtmlWindow.py b/wxPython/demo/wxHtmlWindow.py index 5692a76b0b..dc87749b14 100644 --- a/wxPython/demo/wxHtmlWindow.py +++ b/wxPython/demo/wxHtmlWindow.py @@ -43,6 +43,23 @@ class MyHtmlWindow(wxHtmlWindow): self.base_OnCellClicked(cell, x, y, evt) +# This filter doesn't really do anything but show how to use filters +class MyHtmlFilter(wxHtmlFilter): + def __init__(self, log): + wxHtmlFilter.__init__(self) + self.log = log + + # This method decides if this filter is able to read the file + def CanRead(self, fsfile): + self.log.write("CanRead: %s\n" % fsfile.GetMimeType()) + return False + + # If CanRead returns True then this method is called to actually + # read the file and return the contents. + def ReadFile(self, fsfile): + return "" + + class TestHtmlPanel(wxPanel): def __init__(self, parent, frame, log): wxPanel.__init__(self, parent, -1, style=wxNO_FULL_REPAINT_ON_RESIZE) @@ -51,9 +68,13 @@ class TestHtmlPanel(wxPanel): self.cwd = os.path.split(sys.argv[0])[0] if not self.cwd: self.cwd = os.getcwd() + if frame: + self.titleBase = frame.GetTitle() + + wxHtmlWindow_AddFilter(MyHtmlFilter(log)) self.html = MyHtmlWindow(self, -1, log) - self.html.SetRelatedFrame(frame, "wxPython: (A Demonstration) -- %s") + self.html.SetRelatedFrame(frame, self.titleBase + " -- %s") self.html.SetRelatedStatusBar(0) self.printer = wxHtmlEasyPrinting() @@ -93,7 +114,7 @@ class TestHtmlPanel(wxPanel): self.box.Add(subbox, 0, wxGROW) self.SetSizer(self.box) - self.SetAutoLayout(true) + self.SetAutoLayout(True) # A button with this ID is created on the widget test page. EVT_BUTTON(self, wxID_OK, self.OnOk) @@ -101,6 +122,11 @@ class TestHtmlPanel(wxPanel): self.OnShowDefault(None) + def ShutdownDemo(self): + # put the frame title back + if self.frame: + self.frame.SetTitle(self.titleBase) + def OnShowDefault(self, event): name = os.path.join(self.cwd, opj('data/test.htm')) @@ -168,15 +194,27 @@ def runTest(frame, nb, log): -overview = """\ -wxHtmlWindow is capable of parsing and rendering most simple HTML tags. +overview = """ +

    wxHtmlWindow

    -It is not intended to be a high-end HTML browser. If you're looking for something like that try http://www.mozilla.org - there's a chance you'll be able to make their widget wxWindows-compatible. I'm sure everyone will enjoy your work in that case... +

    wxHtmlWindow is capable of parsing and rendering most +simple HTML tags. +

    It is not intended to be a high-end HTML browser. If you're +looking for something like that try http://www.mozilla.org - there's a +chance you'll be able to make their widget wxWindows-compatible. I'm +sure everyone will enjoy your work in that case... + + """ +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxIEHtmlWin.py b/wxPython/demo/wxIEHtmlWin.py index a09476159b..1604da40cc 100644 --- a/wxPython/demo/wxIEHtmlWin.py +++ b/wxPython/demo/wxIEHtmlWin.py @@ -9,7 +9,7 @@ if wxPlatform == '__WXMSW__': class TestPanel(wxWindow): def __init__(self, parent, log, frame=None): wxWindow.__init__(self, parent, -1, - style=wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE) + style=wxTAB_TRAVERSAL|wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE) self.log = log self.current = "http://wxWindows.org/" self.frame = frame @@ -68,7 +68,7 @@ class TestPanel(wxWindow): self.location.Append(self.current) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_SIZE(self, self.OnSize) # Hook up the event handlers for the IE window @@ -80,6 +80,12 @@ class TestPanel(wxWindow): EVT_MSHTML_TITLECHANGE(self, -1, self.OnTitleChange) + def ShutdownDemo(self): + # put the frame title back + if self.frame: + self.frame.SetTitle(self.titleBase) + + def OnSize(self, evt): self.Layout() diff --git a/wxPython/demo/wxImage.py b/wxPython/demo/wxImage.py index 6a15003e85..23d3ee7eee 100644 --- a/wxPython/demo/wxImage.py +++ b/wxPython/demo/wxImage.py @@ -39,3 +39,11 @@ def runTest(frame, nb, log): overview = """\ """ + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxImageFromStream.py b/wxPython/demo/wxImageFromStream.py index 19e6f28f21..6953a2ca4c 100644 --- a/wxPython/demo/wxImageFromStream.py +++ b/wxPython/demo/wxImageFromStream.py @@ -10,7 +10,7 @@ class TestPanel(wxPanel): def __init__(self, parent, log): wxPanel.__init__(self, parent, -1) - data = open(opj('bitmaps/image.gif'), "rb").read() + data = open(opj('bitmaps/image.png'), "rb").read() stream = StringIO(data) bmp = wxBitmapFromImage( wxImageFromStream( stream )) @@ -18,8 +18,7 @@ class TestPanel(wxPanel): wxStaticText(self, -1, "This image was loaded from a Python file-like object:", (15, 15)) - wxStaticBitmap(self, -1, bmp, (15, 45)) - + wxStaticBitmap(self, -1, bmp, (15, 45))#, (bmp.GetWidth(), bmp.GetHeight())) diff --git a/wxPython/demo/wxIntCtrl.py b/wxPython/demo/wxIntCtrl.py new file mode 100644 index 0000000000..fb1bcb5ff0 --- /dev/null +++ b/wxPython/demo/wxIntCtrl.py @@ -0,0 +1,337 @@ +from wxPython.wx import * +from wxPython.lib.intctrl import * + +#---------------------------------------------------------------------- + +class TestPanel( wxPanel ): + def __init__( self, parent, log ): + + wxPanel.__init__( self, parent, -1 ) + self.log = log + panel = wxPanel( self, -1 ) + + self.set_min = wxCheckBox( panel, -1, "Set minimum value:" ) + self.min = wxIntCtrl( panel, size=wxSize( 50, -1 ) ) + self.min.Enable( False ) + + self.set_max = wxCheckBox( panel, -1, "Set maximum value:" ) + self.max = wxIntCtrl( panel, size=wxSize( 50, -1 ) ) + self.max.Enable( False ) + + self.limit_target = wxCheckBox( panel, -1, "Limit control" ) + self.allow_none = wxCheckBox( panel, -1, "Allow empty control" ) + self.allow_long = wxCheckBox( panel, -1, "Allow long integers" ) + + label = wxStaticText( panel, -1, "Resulting integer control:" ) + self.target_ctl = wxIntCtrl( panel ) + + grid = wxFlexGridSizer( 0, 2, 0, 0 ) + grid.AddWindow( self.set_min, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + grid.AddWindow( self.min, 0, wxALIGN_LEFT|wxALL, 5 ) + + grid.AddWindow( self.set_max, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + grid.AddWindow( self.max, 0, wxALIGN_LEFT|wxALL, 5 ) + + grid.AddWindow( self.limit_target, 0, wxALIGN_LEFT|wxALL, 5 ) + grid.AddSpacer( 20, 0, 0, wxALIGN_LEFT|wxALL, 5 ) + grid.AddWindow( self.allow_none, 0, wxALIGN_LEFT|wxALL, 5 ) + grid.AddSpacer( 20, 0, 0, wxALIGN_LEFT|wxALL, 5 ) + grid.AddWindow( self.allow_long, 0, wxALIGN_LEFT|wxALL, 5 ) + grid.AddSpacer( 20, 0, 0, wxALIGN_LEFT|wxALL, 5 ) + + grid.AddSpacer( 20, 0, 0, wxALIGN_LEFT|wxALL, 5 ) + grid.AddSpacer( 20, 0, 0, wxALIGN_LEFT|wxALL, 5 ) + + grid.AddWindow( label, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + grid.AddWindow( self.target_ctl, 0, wxALIGN_LEFT|wxALL, 5 ) + + outer_box = wxBoxSizer( wxVERTICAL ) + outer_box.AddSizer( grid, 0, wxALIGN_CENTRE|wxALL, 20 ) + + panel.SetAutoLayout( True ) + panel.SetSizer( outer_box ) + outer_box.Fit( panel ) + panel.Move( (50,50) ) + self.panel = panel + + EVT_CHECKBOX( self, self.set_min.GetId(), self.OnSetMin ) + EVT_CHECKBOX( self, self.set_max.GetId(), self.OnSetMax ) + EVT_CHECKBOX( self, self.limit_target.GetId(), self.SetTargetMinMax ) + EVT_CHECKBOX( self, self.allow_none.GetId(), self.OnSetAllowNone ) + EVT_CHECKBOX( self, self.allow_long.GetId(), self.OnSetAllowLong ) + EVT_INT( self, self.min.GetId(), self.SetTargetMinMax ) + EVT_INT( self, self.max.GetId(), self.SetTargetMinMax ) + EVT_INT( self, self.target_ctl.GetId(), self.OnTargetChange ) + + + def OnSetMin( self, event ): + self.min.Enable( self.set_min.GetValue() ) + self.SetTargetMinMax() + + def OnSetMax( self, event ): + self.max.Enable( self.set_max.GetValue() ) + self.SetTargetMinMax() + + + def SetTargetMinMax( self, event=None ): + min = max = None + self.target_ctl.SetLimited( self.limit_target.GetValue() ) + + if self.set_min.GetValue(): + min = self.min.GetValue() + if self.set_max.GetValue(): + max = self.max.GetValue() + + cur_min, cur_max = self.target_ctl.GetBounds() + + if min != cur_min and not self.target_ctl.SetMin( min ): + self.log.write( "min (%d) > current max (%d) -- bound not set\n" % ( min, self.target_ctl.GetMax() ) ) + self.min.SetForegroundColour( wxRED ) + else: + self.min.SetForegroundColour( wxBLACK ) + self.min.Refresh() + + if max != cur_max and not self.target_ctl.SetMax( max ): + self.log.write( "max (%d) < current min (%d) -- bound not set\n" % ( max, self.target_ctl.GetMin() ) ) + self.max.SetForegroundColour( wxRED ) + else: + self.max.SetForegroundColour( wxBLACK ) + self.max.Refresh() + + if min != cur_min or max != cur_max: + new_min, new_max = self.target_ctl.GetBounds() + self.log.write( "current min, max: (%s, %s)\n" % ( str(new_min), str(new_max) ) ) + + + def OnSetAllowNone( self, event ): + self.target_ctl.SetNoneAllowed( self.allow_none.GetValue() ) + + + def OnSetAllowLong( self, event ): + self.target_ctl.SetLongAllowed( self.allow_long.GetValue() ) + + + def OnTargetChange( self, event ): + ctl = event.GetEventObject() + value = ctl.GetValue() + ib_str = [ " (out of bounds)", "" ] + self.log.write( "integer value = %s%s\n" % ( str(value), ib_str[ ctl.IsInBounds(value) ] ) ) + + +#---------------------------------------------------------------------- + +def runTest( frame, nb, log ): + win = TestPanel( nb, log ) + return win + +#---------------------------------------------------------------------- + +overview = """ +

    +wxIntCtrl provides a control that takes and returns integers as +value, and provides bounds support and optional value limiting. +

    +

    +Here's the API for wxIntCtrl: +

    +    wxIntCtrl(
    +         parent, id = -1,
    +         value = 0,
    +         min = None,
    +         max = None,
    +         limited = False,
    +         allow_none = False,
    +         allow_long = False,
    +         default_color = wxBLACK,
    +         oob_color = wxRED,
    +         pos = wxDefaultPosition,
    +         size = wxDefaultSize,
    +         style = 0,
    +         name = "integer")
    +
    +
      +
      value +
      If no initial value is set, the default will be zero, or + the minimum value, if specified. If an illegal string is specified, + a ValueError will result. (You can always later set the initial + value with SetValue() after instantiation of the control.) +
      +
      min +
      The minimum value that the control should allow. This can be + adjusted with SetMin(). If the control is not limited, any value + below this bound will be colored with the current out-of-bounds color. +
      +
      max +
      The maximum value that the control should allow. This can be + adjusted with SetMax(). If the control is not limited, any value + above this bound will be colored with the current out-of-bounds color. +
      +
      limited +
      Boolean indicating whether the control prevents values from + exceeding the currently set minimum and maximum values (bounds). + If False and bounds are set, out-of-bounds values will + be colored with the current out-of-bounds color. +
      +
      allow_none +
      Boolean indicating whether or not the control is allowed to be + empty, representing a value of None for the control. +
      +
      allow_long +
      Boolean indicating whether or not the control is allowed to hold + and return a value of type long as well as int. If False, the + control will be implicitly limited to have a value such that + -sys.maxint-1 <= n <= sys.maxint. +
      +
      default_color +
      Color value used for in-bounds values of the control. +
      +
      oob_color +
      Color value used for out-of-bounds values of the control + when the bounds are set but the control is not limited. +
    +
    +
    +
    EVT_INT(win, id, func) +
    Respond to a wxEVT_COMMAND_INT_UPDATED event, generated when the +value changes. Notice that this event will always be sent when the +control's contents changes - whether this is due to user input or +comes from the program itself (for example, if SetValue() is called.) +
    +
    +
    SetValue(int) +
    Sets the value of the control to the integer value specified. +The resulting actual value of the control may be altered to +conform with the bounds set on the control if limited, +or colored if not limited but the value is out-of-bounds. +A ValueError exception will be raised if an invalid value +is specified. +
    +
    GetValue() +
    Retrieves the integer value from the control. The value +retrieved will be sized as an int if possible or a long, +if necessary. +
    +
    +
    SetMin(min=None) +
    Sets the expected minimum value, or lower bound, of the control. +(The lower bound will only be enforced if the control is +configured to limit its values to the set bounds.) +If a value of None is provided, then the control will have +no explicit lower bound. If the value specified is greater than +the current lower bound, then the function returns 0 and the +lower bound will not change from its current setting. On success, +the function returns 1. +
    If successful and the current value is +lower than the new lower bound, if the control is limited, the +value will be automatically adjusted to the new minimum value; +if not limited, the value in the control will be colored with +the current out-of-bounds color. +
    +
    GetMin() +
    Gets the current lower bound value for the control. +It will return None if no lower bound is currently specified. +
    +
    +
    SetMax(max=None) +
    Sets the expected maximum value, or upper bound, of the control. +(The upper bound will only be enforced if the control is +configured to limit its values to the set bounds.) +If a value of None is provided, then the control will +have no explicit upper bound. If the value specified is less +than the current lower bound, then the function returns 0 and +the maximum will not change from its current setting. On success, +the function returns 1. +
    If successful and the current value +is greater than the new upper bound, if the control is limited +the value will be automatically adjusted to the new maximum value; +if not limited, the value in the control will be colored with the +current out-of-bounds color. +
    +
    GetMax() +
    Gets the current upper bound value for the control. +It will return None if no upper bound is currently specified. +
    +
    +
    SetBounds(min=None,max=None) +
    This function is a convenience function for setting the min and max +values at the same time. The function only applies the maximum bound +if setting the minimum bound is successful, and returns True +only if both operations succeed. Note: leaving out an argument +will remove the corresponding bound. +
    GetBounds() +
    This function returns a two-tuple (min,max), indicating the +current bounds of the control. Each value can be None if +that bound is not set. +
    +
    +
    IsInBounds(value=None) +
    Returns True if no value is specified and the current value +of the control falls within the current bounds. This function can also +be called with a value to see if that value would fall within the current +bounds of the given control. +
    +
    +
    SetLimited(bool) +
    If called with a value of True, this function will cause the control +to limit the value to fall within the bounds currently specified. +If the control's value currently exceeds the bounds, it will then +be limited accordingly. +If called with a value of 0, this function will disable value +limiting, but coloring of out-of-bounds values will still take +place if bounds have been set for the control. +
    IsLimited() +
    Returns True if the control is currently limiting the +value to fall within the current bounds. +
    +
    +
    SetNoneAllowed(bool) +
    If called with a value of True, this function will cause the control +to allow the value to be empty, representing a value of None. +If called with a value of fakse, this function will prevent the value +from being None. If the value of the control is currently None, +ie. the control is empty, then the value will be changed to that +of the lower bound of the control, or 0 if no lower bound is set. +
    IsNoneAllowed() +
    Returns True if the control currently allows its +value to be None. +
    +
    +
    SetLongAllowed(bool) +
    If called with a value of True, this function will cause the +control to allow the value to be a long. If called with a value +of False, and the value of the control is currently a long value, +the value of the control will be adjusted to fall within the +size of an integer type, at either the sys.maxint or -sys.maxint-1, +for positive and negative values, respectively. +
    IsLongAllowed() +
    Returns True if the control currently allows its +value to be of type long. +
    +
    +
    SetColors(default_color=wxBLACK, oob_color=wxRED) +
    Tells the control what colors to use for normal and out-of-bounds +values. If the value currently exceeds the bounds, it will be +recolored accordingly. +
    GetColors() +
    Returns a tuple of (default_color, oob_color) indicating +the current color settings for the control. +
    +
    +
    Cut() +
    Will allow cuts to the clipboard of the text portion of the value, +leaving the value of zero if the entire contents are "cut." +
    Paste() +
    Will paste the contents of the clipboard to the selected portion +of the value; if the resulting string does not represent a legal +value, a ValueError will result. If the result is out-of bounds, +it will either be adjusted or colored as appropriate. +
    + +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) diff --git a/wxPython/demo/wxJoystick.py b/wxPython/demo/wxJoystick.py index 2e13d81010..1c4882f40e 100644 --- a/wxPython/demo/wxJoystick.py +++ b/wxPython/demo/wxJoystick.py @@ -11,7 +11,7 @@ class JoystickTestPanel(wxPanel): style = wxTAB_TRAVERSAL ): wxPanel.__init__(self, parent, id, pos, size, style) - MakeJoystickTestPanel( self, true ) + MakeJoystickTestPanel( self, True ) try: self.stick = wxJoystick() diff --git a/wxPython/demo/wxKeyEvents.py b/wxPython/demo/wxKeyEvents.py index e7574a702a..7e214089f5 100644 --- a/wxPython/demo/wxKeyEvents.py +++ b/wxPython/demo/wxKeyEvents.py @@ -120,11 +120,11 @@ class KeySink(wxWindow): #| wxSUNKEN_BORDER ) self.SetBackgroundColour(wxBLUE) - self.haveFocus = false - self.callSkip = false - self.logKeyDn = true - self.logKeyUp = true - self.logChar = true + self.haveFocus = False + self.callSkip = False + self.logKeyDn = True + self.logKeyUp = True + self.logChar = True EVT_PAINT(self, self.OnPaint) EVT_SET_FOCUS(self, self.OnSetFocus) @@ -164,11 +164,11 @@ class KeySink(wxWindow): def OnSetFocus(self, evt): - self.haveFocus = true + self.haveFocus = True self.Refresh() def OnKillFocus(self, evt): - self.haveFocus = false + self.haveFocus = False self.Refresh() def OnMouse(self, evt): @@ -277,15 +277,15 @@ class TestPanel(wxPanel): cb2 = wxCheckBox(self, -1, "EVT_KEY_UP") EVT_CHECKBOX(self, cb2.GetId(), self.OnKeyUpCB) - cb2.SetValue(true) + cb2.SetValue(True) cb3 = wxCheckBox(self, -1, "EVT_KEY_DOWN") EVT_CHECKBOX(self, cb3.GetId(), self.OnKeyDnCB) - cb3.SetValue(true) + cb3.SetValue(True) cb4 = wxCheckBox(self, -1, "EVT_CHAR") EVT_CHECKBOX(self, cb4.GetId(), self.OnCharCB) - cb4.SetValue(true) + cb4.SetValue(True) buttons = wxBoxSizer(wxHORIZONTAL) buttons.Add(btn, 0, wxALL, 4) diff --git a/wxPython/demo/wxLEDNumberCtrl.py b/wxPython/demo/wxLEDNumberCtrl.py index 22be241dbb..d8907a35c1 100644 --- a/wxPython/demo/wxLEDNumberCtrl.py +++ b/wxPython/demo/wxLEDNumberCtrl.py @@ -17,7 +17,7 @@ class TestPanel(wxPanel): led = wxLEDNumberCtrl(self, -1, (25,100), (280, 50)) led.SetValue("56789") led.SetAlignment(wxLED_ALIGN_RIGHT) - led.SetDrawFaded(false) + led.SetDrawFaded(False) led = wxLEDNumberCtrl(self, -1, (25,175), (280, 50), wxLED_ALIGN_CENTER)# | wxLED_DRAW_FADED) diff --git a/wxPython/demo/wxLayoutConstraints.py b/wxPython/demo/wxLayoutConstraints.py index 8e63a12af2..4ffa033924 100644 --- a/wxPython/demo/wxLayoutConstraints.py +++ b/wxPython/demo/wxLayoutConstraints.py @@ -6,7 +6,7 @@ from wxPython.wx import * class TestLayoutConstraints(wxPanel): def __init__(self, parent): wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_BUTTON(self, 100, self.OnButton) self.SetBackgroundColour(wxNamedColour("MEDIUM ORCHID")) diff --git a/wxPython/demo/wxListBox.py b/wxPython/demo/wxListBox.py index f2f8bf7056..074f2de5ae 100644 --- a/wxPython/demo/wxListBox.py +++ b/wxPython/demo/wxListBox.py @@ -1,8 +1,6 @@ from wxPython.wx import * -import string - #--------------------------------------------------------------------------- class wxFindPrefixListBox(wxListBox): @@ -10,18 +8,22 @@ class wxFindPrefixListBox(wxListBox): choices=[], style=0, validator=wxDefaultValidator): wxListBox.__init__(self, parent, id, pos, size, choices, style, validator) self.typedText = '' - EVT_KEY_UP(self, self.OnKey) + self.log = parent.log + EVT_KEY_DOWN(self, self.OnKey) def FindPrefix(self, prefix): + self.log.WriteText('Looking for prefix: %s\n' % prefix) if prefix: - prefix = string.lower(prefix) + prefix = prefix.lower() length = len(prefix) for x in range(self.Number()): text = self.GetString(x) - text = string.lower(text) + text = text.lower() if text[:length] == prefix: + self.log.WriteText('Prefix %s is found.\n' % prefix) return x + self.log.WriteText('Prefix %s is not found.\n' % prefix) return -1 @@ -43,8 +45,12 @@ class wxFindPrefixListBox(wxListBox): self.SetSelection(item) else: + self.typedText = '' evt.Skip() + def OnKeyDown(self, evt): + pass + #--------------------------------------------------------------------------- @@ -90,7 +96,9 @@ class TestListBox(wxPanel): def EvtListBox(self, event): - self.log.WriteText('EvtListBox: %s\n' % event.GetString()) + self.log.WriteText('EvtListBox: %s, %s, %s\n' % + (event.GetString(), event.IsSelection(), event.GetSelection())) + lb = event.GetEventObject() data = lb.GetClientData(lb.GetSelection()) if data is not None: @@ -127,14 +135,19 @@ def runTest(frame, nb, log): +overview = """ +A listbox is used to select one or more of a list of +strings. The strings are displayed in a scrolling box, with the +selected string(s) marked in reverse video. A listbox can be single +selection (if an item is selected, the previous selection is removed) +or multiple selection (clicking an item toggles the item on or off +independently of other selections). + +""" +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) - - - - -overview = """\ -A listbox is used to select one or more of a list of strings. The strings are displayed in a scrolling box, with the selected string(s) marked in reverse video. A listbox can be single selection (if an item is selected, the previous selection is removed) or multiple selection (clicking an item toggles the item on or off independently of other selections). - -""" diff --git a/wxPython/demo/wxListCtrl.py b/wxPython/demo/wxListCtrl.py index 0979a5c738..d640ecddb6 100644 --- a/wxPython/demo/wxListCtrl.py +++ b/wxPython/demo/wxListCtrl.py @@ -97,7 +97,10 @@ class TestListCtrlPanel(wxPanel, wxColumnSorterMixin): self.sm_dn = self.il.Add(images.getSmallDnArrowBitmap()) self.list = TestListCtrl(self, tID, - style=wxLC_REPORT|wxSUNKEN_BORDER)#|wxLC_VRULES|wxLC_HRULES) + style=wxLC_REPORT | wxSUNKEN_BORDER + #| wxLC_NO_HEADER + #| wxLC_VRULES | wxLC_HRULES + ) self.list.SetImageList(self.il, wxIMAGE_LIST_SMALL) self.PopulateList() @@ -106,7 +109,7 @@ class TestListCtrlPanel(wxPanel, wxColumnSorterMixin): # see wxPython/lib/mixins/listctrl.py self.itemDataMap = musicdata wxColumnSorterMixin.__init__(self, 3) - #self.SortListItems(0, true) + #self.SortListItems(0, True) EVT_SIZE(self, self.OnSize) EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected) @@ -191,7 +194,9 @@ class TestListCtrlPanel(wxPanel, wxColumnSorterMixin): self.x = event.GetX() self.y = event.GetY() self.log.WriteText("x, y = %s\n" % str((self.x, self.y))) - print event.GetEventObject() + item, flags = self.list.HitTest((self.x, self.y)) + if flags & wxLIST_HITTEST_ONITEM: + self.list.Select(item) event.Skip() @@ -201,6 +206,7 @@ class TestListCtrlPanel(wxPanel, wxColumnSorterMixin): def OnItemSelected(self, event): + ##print event.GetItem().GetTextColour() self.currentItem = event.m_itemIndex self.log.WriteText("OnItemSelected: %s, %s, %s, %s\n" % (self.currentItem, @@ -213,17 +219,19 @@ class TestListCtrlPanel(wxPanel, wxColumnSorterMixin): # this does self.list.SetItemState(10, 0, wxLIST_STATE_SELECTED) - # Show how to reselect something we don't want deselected def OnItemDeselected(self, evt): item = evt.GetItem() - print evt.m_itemIndex + self.log.WriteText("OnItemDeselected: %d" % evt.m_itemIndex) + + # Show how to reselect something we don't want deselected if evt.m_itemIndex == 11: wxCallAfter(self.list.SetItemState, 11, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED) def OnItemActivated(self, event): self.currentItem = event.m_itemIndex - self.log.WriteText("OnItemActivated: %s\n" % self.list.GetItemText(self.currentItem)) + self.log.WriteText("OnItemActivated: %s\nTopItem: %s" % + (self.list.GetItemText(self.currentItem), self.list.GetTopItem())) def OnItemDelete(self, event): self.log.WriteText("OnItemDelete\n") @@ -256,30 +264,37 @@ class TestListCtrlPanel(wxPanel, wxColumnSorterMixin): def OnRightClick(self, event): self.log.WriteText("OnRightClick %s\n" % self.list.GetItemText(self.currentItem)) - menu = wxMenu() - tPopupID1 = 0 - tPopupID2 = 1 - tPopupID3 = 2 - tPopupID4 = 3 - tPopupID5 = 5 + # only do this part the first time + if not hasattr(self, "popupID1"): + self.popupID1 = wxNewId() + self.popupID2 = wxNewId() + self.popupID3 = wxNewId() + self.popupID4 = wxNewId() + self.popupID5 = wxNewId() + EVT_MENU(self, self.popupID1, self.OnPopupOne) + EVT_MENU(self, self.popupID2, self.OnPopupTwo) + EVT_MENU(self, self.popupID3, self.OnPopupThree) + EVT_MENU(self, self.popupID4, self.OnPopupFour) + EVT_MENU(self, self.popupID5, self.OnPopupFive) + + # make a menu + menu = wxMenu() # Show how to put an icon in the menu - item = wxMenuItem(menu, tPopupID1,"One") + item = wxMenuItem(menu, self.popupID1,"One") item.SetBitmap(images.getSmilesBitmap()) - menu.AppendItem(item) - menu.Append(tPopupID2, "Two") - menu.Append(tPopupID3, "ClearAll and repopulate") - menu.Append(tPopupID4, "DeleteAllItems") - menu.Append(tPopupID5, "GetItem") - EVT_MENU(self, tPopupID1, self.OnPopupOne) - EVT_MENU(self, tPopupID2, self.OnPopupTwo) - EVT_MENU(self, tPopupID3, self.OnPopupThree) - EVT_MENU(self, tPopupID4, self.OnPopupFour) - EVT_MENU(self, tPopupID5, self.OnPopupFive) + # add some other items + menu.Append(self.popupID2, "Two") + menu.Append(self.popupID3, "ClearAll and repopulate") + menu.Append(self.popupID4, "DeleteAllItems") + menu.Append(self.popupID5, "GetItem") + + # Popup the menu. If an item is selected then its handler + # will be called before PopupMenu returns. self.PopupMenu(menu, wxPoint(self.x, self.y)) menu.Destroy() - event.Skip() + def OnPopupOne(self, event): self.log.WriteText("Popup one\n") diff --git a/wxPython/demo/wxListCtrl_virtual.py b/wxPython/demo/wxListCtrl_virtual.py index f7489db1c8..7dffd52fdd 100644 --- a/wxPython/demo/wxListCtrl_virtual.py +++ b/wxPython/demo/wxListCtrl_virtual.py @@ -45,7 +45,8 @@ class TestVirtualList(wxListCtrl): def OnItemActivated(self, event): self.currentItem = event.m_itemIndex - self.log.WriteText("OnItemActivated: %s\n" % self.GetItemText(self.currentItem)) + self.log.WriteText("OnItemActivated: %s\nTopItem: %s\n" % + (self.GetItemText(self.currentItem), self.GetTopItem())) def getColumnText(self, index, col): item = self.GetItem(index, col) diff --git a/wxPython/demo/wxMDIWindows.py b/wxPython/demo/wxMDIWindows.py index 91d7a55eb0..7eef8a39c9 100644 --- a/wxPython/demo/wxMDIWindows.py +++ b/wxPython/demo/wxMDIWindows.py @@ -18,7 +18,7 @@ class TestPanel(wxPanel): box.Add(20, 30) box.Add(b1, 0, wxALIGN_CENTER|wxALL, 15) box.Add(b2, 0, wxALIGN_CENTER|wxALL, 15) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(box) diff --git a/wxPython/demo/wxMVCTree.py b/wxPython/demo/wxMVCTree.py index af7760cb9d..808f8870b3 100644 --- a/wxPython/demo/wxMVCTree.py +++ b/wxPython/demo/wxMVCTree.py @@ -29,11 +29,11 @@ def runTest(frame, nb, log): p = wxMVCTree(nb, -1) #f = wxFrame(frame, -1, "wxMVCTree") #p = wxMVCTree(f, -1) - p.SetAssumeChildren(true) + p.SetAssumeChildren(True) p.SetModel(LateFSTreeModel(os.path.normpath(os.getcwd() + os.sep +'..'))) #Uncomment this to enable live filename editing! # p.AddEditor(FileEditor(p)) - p.SetMultiSelect(true) + p.SetMultiSelect(True) EVT_MVCTREE_SEL_CHANGING(p, p.GetId(), selchanging) EVT_MVCTREE_SEL_CHANGED(p, p.GetId(), selchanged) EVT_MVCTREE_ITEM_EXPANDED(p, p.GetId(), expanded) @@ -44,7 +44,7 @@ def runTest(frame, nb, log): return p #frame.otherWin = f - #f.Show(true) + #f.Show(True) #return None diff --git a/wxPython/demo/wxMask.py b/wxPython/demo/wxMask.py index 7c1f7ccfc6..68b8468a86 100644 --- a/wxPython/demo/wxMask.py +++ b/wxPython/demo/wxMask.py @@ -40,8 +40,7 @@ class TestMaskWindow(wxScrolledWindow): self.bmp_withmask = images.getTestStar2Bitmap() # this mask comes from a monochrome bitmap - self.bmp_themask = images.getTestMaskBitmap() - self.bmp_themask.SetDepth(1) + self.bmp_themask = wxBitmapFromImage(images.getTestMaskImage(), 1) mask = wxMask(self.bmp_themask) # set the mask on our bitmap @@ -87,7 +86,7 @@ class TestMaskWindow(wxScrolledWindow): x,y = 120+150*(i%4), 20+100*(i/4) dc.DrawText(text, x, y-20) mdc.SelectObject(self.bmp_withcolourmask) - dc.Blit(x,y, cx,cy, mdc, 0,0, code, true) + dc.Blit(x,y, cx,cy, mdc, 0,0, code, True) i = i + 1 @@ -115,3 +114,11 @@ def runTest(frame, nb, log): overview = """\ """ + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxMenu.py b/wxPython/demo/wxMenu.py index 87758ff783..bdbf93489b 100644 --- a/wxPython/demo/wxMenu.py +++ b/wxPython/demo/wxMenu.py @@ -30,11 +30,11 @@ check the source for this sample to see how to implement them. # 1st menu from left menu1 = wxMenu() - menu1.Append(101, "Mercury", "This the text in the Statusbar") - menu1.Append(102, "Venus", "") - menu1.Append(103, "Earth", "You may select Earth too") + menu1.Append(101, "&Mercury", "This the text in the Statusbar") + menu1.Append(102, "&Venus", "") + menu1.Append(103, "&Earth", "You may select Earth too") menu1.AppendSeparator() - menu1.Append(104, "Close", "Close this frame") + menu1.Append(104, "&Close", "Close this frame") # Add menu to the menu bar menuBar.Append(menu1, "&Planets") @@ -151,7 +151,7 @@ check the source for this sample to see how to implement them. def runTest(frame, nb, log): win = MyFrame(frame, -1, log) frame.otherWin = win - win.Show(true) + win.Show(True) #------------------------------------------------------------------- diff --git a/wxPython/demo/wxMimeTypesManager.py b/wxPython/demo/wxMimeTypesManager.py index 5768ba2592..39ba2074dc 100644 --- a/wxPython/demo/wxMimeTypesManager.py +++ b/wxPython/demo/wxMimeTypesManager.py @@ -14,7 +14,7 @@ class MimeTypesTestPanel(wxPanel): style = wxTAB_TRAVERSAL ): wxPanel.__init__(self, parent, id, pos, size, style) - MakeMimeTypesTestPanel( self, true ) + MakeMimeTypesTestPanel( self, True ) # WDR: handler declarations for MimeTypesTestPanel EVT_LISTBOX(self, ID_LISTBOX, self.OnListbox) @@ -34,8 +34,8 @@ class MimeTypesTestPanel(wxPanel): def OnListbox(self, event): mimetype = event.GetString() self.GetInputText().SetValue(mimetype) - self.GetMimeBtn().SetValue(TRUE) - self.GetExtensionBtn().SetValue(FALSE) + self.GetMimeBtn().SetValue(True) + self.GetExtensionBtn().SetValue(False) self.OnLookup() diff --git a/wxPython/demo/wxMiniFrame.py b/wxPython/demo/wxMiniFrame.py index 2e947486e8..fd7c6c7f45 100644 --- a/wxPython/demo/wxMiniFrame.py +++ b/wxPython/demo/wxMiniFrame.py @@ -14,9 +14,10 @@ class MyMiniFrame(wxMiniFrame): EVT_CLOSE(self, self.OnCloseWindow) def OnCloseMe(self, event): - self.Close(true) + self.Close(True) def OnCloseWindow(self, event): + print "OnCloseWindow" self.Destroy() #--------------------------------------------------------------------------- @@ -28,7 +29,7 @@ def runTest(frame, nb, log): win.SetSize((200, 200)) win.CenterOnParent(wxBOTH) frame.otherWin = win - win.Show(true) + win.Show(True) #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxMultiSash.py b/wxPython/demo/wxMultiSash.py new file mode 100644 index 0000000000..6308121201 --- /dev/null +++ b/wxPython/demo/wxMultiSash.py @@ -0,0 +1,90 @@ +from wxPython.wx import * +from wxPython.lib.multisash import wxMultiSash +from wxPython.stc import * + +#--------------------------------------------------------------------------- + +sampleText="""\ +You can drag the little tab on the vertical sash left to create another view, +or you can drag the tab on the horizontal sash to the top to create another +horizontal view. + +The red blocks on the sashes will destroy the view (bottom,left) this block +belongs to. + +A yellow rectangle also highlights the current selected view. + +By calling GetSaveData on the multiSash control the control will return its +contents and the positions of each sash as a dictionary. +Calling SetSaveData with such a dictionary will restore the control to the +state it was in when it was saved. + +If the class, that is used as a view, has GetSaveData/SetSaveData implemented, +these will also be called to save/restore their state. Any object can be +returned by GetSaveData, as it is just another object in the dictionary. +""" + +#--------------------------------------------------------------------------- + +class TestWindow(wxStyledTextCtrl): + def __init__(self, parent): + wxStyledTextCtrl.__init__(self, parent, -1, style=wxNO_BORDER) + self.SetMarginWidth(1,0) + if wxPlatform == '__WXMSW__': + fSize = 10 + else: + fSize = 12 + self.StyleSetFont(wxSTC_STYLE_DEFAULT, + wxFont(fSize, wxMODERN, wxNORMAL, wxNORMAL)) + self.SetText(sampleText) + +class TestFrame(wxFrame): + def __init__(self, parent, log): + wxFrame.__init__(self, parent, -1, "Multi Sash Demo", + size=(640,480)) + self.multi = wxMultiSash(self,-1,pos = wxPoint(0,0), + size = (640,480)) + + # Use this method to set the default class that will be created when + # a new sash is created. The class's constructor needs 1 parameter + # which is the parent of the window + self.multi.SetDefaultChildClass(TestWindow) + + +#--------------------------------------------------------------------------- + + +def runTest(frame, nb, log): + multi = wxMultiSash(nb, -1, pos = (0,0), size = (640,480)) + + # Use this method to set the default class that will be created when + # a new sash is created. The class's constructor needs 1 parameter + # which is the parent of the window + multi.SetDefaultChildClass(TestWindow) + + return multi + +# win = TestPanel(nb, log) +# return win + +#---------------------------------------------------------------------- + + + +overview = """ +

    wxMultiSash

    + +wxMultiSash allows the user to split a window any number of times +either horizontally or vertically, and to close the split off windows +when desired. + + +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxNotebook.py b/wxPython/demo/wxNotebook.py index 4af4007dcd..ced491b69d 100644 --- a/wxPython/demo/wxNotebook.py +++ b/wxPython/demo/wxNotebook.py @@ -5,6 +5,7 @@ import ColorPanel import GridSimple import wxListCtrl import wxScrolledWindow +import images import sys @@ -12,10 +13,14 @@ import sys class TestNB(wxNotebook): def __init__(self, parent, id, log): - wxNotebook.__init__(self, parent, id, style=wxNB_BOTTOM) + wxNotebook.__init__(self, parent, id, style= + #0 + wxNB_BOTTOM + #wxNB_LEFT + #wxNB_RIGHT + ) self.log = log - win = self.makeColorPanel(wxBLUE) self.AddPage(win, "Blue") st = wxStaticText(win.win, -1, @@ -26,6 +31,16 @@ class TestNB(wxNotebook): st.SetForegroundColour(wxWHITE) st.SetBackgroundColour(wxBLUE) + # Show how to put an image on one of the notebook tabs, + # first make the image list: + il = wxImageList(16, 16) + idx1 = il.Add(images.getSmilesBitmap()) + self.AssignImageList(il) + + # now put an image on the first tab we just created: + self.SetPageImage(0, idx1) + + win = self.makeColorPanel(wxRED) self.AddPage(win, "Red") @@ -94,28 +109,27 @@ def runTest(frame, nb, log): +overview = """\ + +

    wxNotebook

    +

    +This class represents a notebook control, which manages multiple +windows with associated tabs. +

    +To use the class, create a wxNotebook object and call AddPage or +InsertPage, passing a window to be used as the page. Do not explicitly +delete the window for a page that is currently managed by wxNotebook. +""" +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) -overview = """\ -This class represents a notebook control, which manages multiple windows with associated tabs. - -To use the class, create a wxNotebook object and call AddPage or InsertPage, passing a window to be used as the page. Do not explicitly delete the window for a page that is currently managed by wxNotebook. - -""" - - -if __name__ == "__main__": - app = wxPySimpleApp() - frame = wxFrame(None, -1, "Test Notebook", size=(600, 400)) - win = TestNB(frame, -1, sys.stdout) - frame.Show(true) - app.MainLoop() - - diff --git a/wxPython/demo/wxOGL.py b/wxPython/demo/wxOGL.py index 0b2af68b53..17f0015899 100644 --- a/wxPython/demo/wxOGL.py +++ b/wxPython/demo/wxOGL.py @@ -43,6 +43,52 @@ class RoundedRectangleShape(wxRectangleShape): self.SetCornerRadius(-0.3) +#---------------------------------------------------------------------- + +class DividedShape(wxDividedShape): + def __init__(self, width, height, canvas): + wxDividedShape.__init__(self, width, height) + + region1 = wxShapeRegion() + region1.SetText('wxDividedShape') + region1.SetProportions(0.0, 0.2) + region1.SetFormatMode(FORMAT_CENTRE_HORIZ) + self.AddRegion(region1) + + region2 = wxShapeRegion() + region2.SetText('This is Region number two.') + region2.SetProportions(0.0, 0.3) + region2.SetFormatMode(FORMAT_CENTRE_HORIZ|FORMAT_CENTRE_VERT) + self.AddRegion(region2) + + region3 = wxShapeRegion() + region3.SetText('Region 3\nwith embedded\nline breaks') + region3.SetProportions(0.0, 0.5) + region3.SetFormatMode(FORMAT_NONE) + self.AddRegion(region3) + + self.SetRegionSizes() + self.ReformatRegions(canvas) + + + def ReformatRegions(self, canvas=None): + rnum = 0 + if canvas is None: + canvas = self.GetCanvas() + dc = wxClientDC(canvas) # used for measuring + for region in self.GetRegions(): + text = region.GetText() + self.FormatText(dc, text, rnum) + rnum += 1 + + + def OnSizingEndDragLeft(self, pt, x, y, keys, attch): + self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) + self.SetRegionSizes() + self.ReformatRegions() + self.GetCanvas().Refresh() + + #---------------------------------------------------------------------- class MyEvtHandler(wxShapeEvtHandler): @@ -66,10 +112,10 @@ class MyEvtHandler(wxShapeEvtHandler): canvas.PrepareDC(dc) if shape.Selected(): - shape.Select(false, dc) + shape.Select(False, dc) canvas.Redraw(dc) else: - redraw = false + redraw = False shapeList = canvas.GetDiagram().GetShapeList() toUnselect = [] for s in shapeList: @@ -79,11 +125,11 @@ class MyEvtHandler(wxShapeEvtHandler): # shapes too!) and bad things will happen... toUnselect.append(s) - shape.Select(true, dc) + shape.Select(True, dc) if toUnselect: for s in toUnselect: - s.Select(false, dc) + s.Select(False, dc) canvas.Redraw(dc) self.UpdateStatusBar(shape) @@ -97,14 +143,14 @@ class MyEvtHandler(wxShapeEvtHandler): self.UpdateStatusBar(shape) - def OnSize(self, x, y): - self.base_OnSize(x, y) + def OnSizingEndDragLeft(self, pt, x, y, keys, attch): + self.base_OnSizingEndDragLeft(pt, x, y, keys, attch) self.UpdateStatusBar(self.GetShape()) -# def OnMovePost(self, dc, x, y, oldX, oldY, display): -# self.base_OnMovePost(dc, x, y, oldX, oldY, display) -# self.UpdateStatusBar(self.GetShape()) + def OnMovePost(self, dc, x, y, oldX, oldY, display): + self.base_OnMovePost(dc, x, y, oldX, oldY, display) + self.UpdateStatusBar(self.GetShape()) def OnRightClick(self, *dontcare): @@ -130,12 +176,14 @@ class TestWindow(wxShapeCanvas): self.shapes = [] self.save_gdi = [] - rRectBrush = wxBrush(wxNamedColour("MEDIUM TURQUOISE"), wxSOLID) + rRectBrush = wxBrush("MEDIUM TURQUOISE", wxSOLID) + dsBrush = wxBrush("WHEAT", wxSOLID) self.MyAddShape(wxCircleShape(80), 100, 100, wxPen(wxBLUE, 3), wxGREEN_BRUSH, "Circle") self.MyAddShape(wxRectangleShape(85, 50), 305, 60, wxBLACK_PEN, wxLIGHT_GREY_BRUSH, "Rectangle") + ds = self.MyAddShape(DividedShape(140, 150, self), 495, 145, wxBLACK_PEN, dsBrush, '') self.MyAddShape(DiamondShape(90, 90), 345, 235, wxPen(wxBLUE, 3, wxDOT), wxRED_BRUSH, "Polygon") - self.MyAddShape(RoundedRectangleShape(95,70), 140, 255, wxPen(wxRED, 1), rRectBrush, "Rounded Rect") + self.MyAddShape(RoundedRectangleShape(95,70), 140, 255, wxPen(wxRED, 2), rRectBrush, "Rounded Rect") bmp = images.getTest2Bitmap() mask = wxMaskColour(bmp, wxBLUE) @@ -161,16 +209,16 @@ class TestWindow(wxShapeCanvas): line.MakeLineControlPoints(2) fromShape.AddLine(line, toShape) self.diagram.AddShape(line) - line.Show(true) + line.Show(True) # for some reason, the shapes have to be moved for the line to show up... fromShape.Move(dc, fromShape.GetX(), fromShape.GetY()) - EVT_WINDOW_DESTROY(self, self.OnDestroy) + EVT_WINDOW_DESTROY(self, self.OnDestroy) def MyAddShape(self, shape, x, y, pen, brush, text): - shape.SetDraggable(true, true) + shape.SetDraggable(True, True) shape.SetCanvas(self) shape.SetX(x) shape.SetY(y) @@ -179,7 +227,7 @@ class TestWindow(wxShapeCanvas): if text: shape.AddText(text) #shape.SetShadowMode(SHADOW_RIGHT) self.diagram.AddShape(shape) - shape.Show(true) + shape.Show(True) evthandler = MyEvtHandler(self.log, self.frame) evthandler.SetShape(shape) @@ -187,7 +235,7 @@ class TestWindow(wxShapeCanvas): shape.SetEventHandler(evthandler) self.shapes.append(shape) - + return shape def OnDestroy(self, evt): @@ -236,3 +284,9 @@ manipulation of simple and complex graphic images on a canvas. """ + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxPopupControl.py b/wxPython/demo/wxPopupControl.py new file mode 100644 index 0000000000..b3b7ad2b7d --- /dev/null +++ b/wxPython/demo/wxPopupControl.py @@ -0,0 +1,94 @@ +from wxPython.wx import * +from wxPython.lib.popupctl import wxPopupControl +from wxPython.calendar import * + +class TestDateControl(wxPopupControl): + def __init__(self,*_args,**_kwargs): + apply(wxPopupControl.__init__,(self,) + _args,_kwargs) + + self.win = wxWindow(self,-1,pos = (0,0),style = 0) + self.cal = wxCalendarCtrl(self.win,-1,pos = (0,0)) + + bz = self.cal.GetBestSize() + self.win.SetSize(bz) + + # This method is needed to set the contents that will be displayed + # in the popup + self.SetPopupContent(self.win) + + # Event registration for date selection + EVT_CALENDAR_DAY(self.cal,self.cal.GetId(),self.OnCalSelected) + + # Method called when a day is selected in the calendar + def OnCalSelected(self,evt): + self.PopDown() + date = self.cal.GetDate() + + # Format the date that was selected for the text part of the control + self.SetValue('%02d/%02d/%04d' % (date.GetDay(), + date.GetMonth()+1, + date.GetYear())) + evt.Skip() + + # Method overridden from wxPopupControl + # This method is called just before the popup is displayed + # Use this method to format any controls in the popup + def FormatContent(self): + # I parse the value in the text part to resemble the correct date in + # the calendar control + txtValue = self.GetValue() + dmy = txtValue.split('/') + didSet = False + if len(dmy) == 3: + date = self.cal.GetDate() + d = int(dmy[0]) + m = int(dmy[1]) - 1 + y = int(dmy[2]) + if d > 0 and d < 31: + if m >= 0 and m < 12: + if y > 1000: + self.cal.SetDate(wxDateTimeFromDMY(d,m,y)) + didSet = True + if not didSet: + self.cal.SetDate(wxDateTime_Today()) + + +#--------------------------------------------------------------------------- + +class TestPanel(wxPanel): + def __init__(self, parent, log): + self.log = log + wxPanel.__init__(self, parent, -1) + date = TestDateControl(self, -1, pos = (30,30), size = (100,22)) + +#---------------------------------------------------------------------- + +def runTest(frame, nb, log): + win = TestPanel(nb, log) + return win + +#---------------------------------------------------------------------- + + + +overview = """ +

    wxPopupControl

    + +wxPopupControl is a class that can display a value and has a button +that will popup another window similar to how a wxComboBox works. The +popup window can contain whatever is needed to edit the value. This +example uses a wxCalendarCtrl. + +

    Currently a wxDialog is used for the popup. Eventually a +wxPopupWindow should be used... + + +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxPopupWindow.py b/wxPython/demo/wxPopupWindow.py index 014e21c8a2..0ee3df748c 100644 --- a/wxPython/demo/wxPopupWindow.py +++ b/wxPython/demo/wxPopupWindow.py @@ -55,7 +55,7 @@ class TestPopup(wxPopupWindow): self.ReleaseMouse() def OnRightUp(self, evt): - self.Show(false) + self.Show(False) self.Destroy() @@ -80,7 +80,7 @@ class TestTransientPopup(wxPopupTransientWindow): def ProcessLeftDown(self, evt): self.log.write("ProcessLeftDown\n") - return false + return False def OnDismiss(self): self.log.write("OnDismiss\n") @@ -113,7 +113,7 @@ class TestPanel(wxPanel): sz = btn.GetSize() win.Position(pos, (0, sz.height)) - win.Show(true) + win.Show(True) def OnShowPopupTransient(self, evt): @@ -139,7 +139,7 @@ class TestPanel(wxPanel): sz = btn.GetSize() win.Position(pos, (0, sz.height)) - win.Show(true) + win.Show(True) class TestPopupWithListbox(wxPopupWindow): def __init__(self, parent, style, log): diff --git a/wxPython/demo/wxPrintDialog.py b/wxPython/demo/wxPrintDialog.py index 50da750bd2..183cbe801c 100644 --- a/wxPython/demo/wxPrintDialog.py +++ b/wxPython/demo/wxPrintDialog.py @@ -5,9 +5,9 @@ from wxPython.wx import * def runTest(frame, nb, log): data = wxPrintDialogData() - data.EnablePrintToFile(true) - data.EnablePageNumbers(true) - data.EnableSelection(true) + data.EnablePrintToFile(True) + data.EnablePageNumbers(True) + data.EnableSelection(True) dlg = wxPrintDialog(frame, data) if dlg.ShowModal() == wxID_OK: log.WriteText('\n') diff --git a/wxPython/demo/wxProcess.py b/wxPython/demo/wxProcess.py index c2ba5ba1ec..d8104e5e75 100644 --- a/wxPython/demo/wxProcess.py +++ b/wxPython/demo/wxProcess.py @@ -27,9 +27,9 @@ class TestPanel(wxPanel): self.inp = wxTextCtrl(self, -1, '', style=wxTE_PROCESS_ENTER) self.sndBtn = wxButton(self, -1, 'Send') self.termBtn = wxButton(self, -1, 'Close Stream') - self.inp.Enable(false) - self.sndBtn.Enable(false) - self.termBtn.Enable(false) + self.inp.Enable(False) + self.sndBtn.Enable(False) + self.termBtn.Enable(False) # Hook up the events EVT_BUTTON(self, self.exBtn.GetId(), self.OnExecuteBtn) @@ -55,7 +55,7 @@ class TestPanel(wxPanel): sizer.Add(box2, 0, wxEXPAND|wxALL, 10) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) def __del__(self): @@ -70,14 +70,14 @@ class TestPanel(wxPanel): self.process = wxProcess(self) self.process.Redirect(); - pid = wxExecute(cmd, false, self.process) + pid = wxExecute(cmd, wxEXEC_ASYNC, self.process) self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid)) - self.inp.Enable(true) - self.sndBtn.Enable(true) - self.termBtn.Enable(true) - self.cmd.Enable(false) - self.exBtn.Enable(false) + self.inp.Enable(True) + self.sndBtn.Enable(True) + self.termBtn.Enable(True) + self.cmd.Enable(False) + self.exBtn.Enable(False) self.inp.SetFocus() @@ -99,11 +99,7 @@ class TestPanel(wxPanel): if self.process is not None: stream = self.process.GetInputStream() - # Yes, this is weird. For this particular stream, EOF - # simply means that there is no data available to be read, - # not truly the end of file. Also, read() just reads all - # the currently available data, not until the real EOF... - if not stream.eof(): + if stream.CanRead(): text = stream.read() self.out.AppendText(text) @@ -113,17 +109,17 @@ class TestPanel(wxPanel): (evt.GetPid(), evt.GetExitCode())) stream = self.process.GetInputStream() - if not stream.eof(): + if stream.CanRead(): text = stream.read() self.out.AppendText(text) self.process.Destroy() self.process = None - self.inp.Enable(false) - self.sndBtn.Enable(false) - self.termBtn.Enable(false) - self.cmd.Enable(true) - self.exBtn.Enable(true) + self.inp.Enable(False) + self.sndBtn.Enable(False) + self.termBtn.Enable(False) + self.cmd.Enable(True) + self.exBtn.Enable(True) #---------------------------------------------------------------------- diff --git a/wxPython/demo/wxProgressDialog.py b/wxPython/demo/wxProgressDialog.py index 7e097c0150..09f6c08b56 100644 --- a/wxPython/demo/wxProgressDialog.py +++ b/wxPython/demo/wxProgressDialog.py @@ -11,7 +11,7 @@ def runTest(frame, nb, log): frame, wxPD_CAN_ABORT | wxPD_APP_MODAL) - keepGoing = true + keepGoing = True count = 0 while keepGoing and count < max: count = count + 1 diff --git a/wxPython/demo/wxPyColourChooser.py b/wxPython/demo/wxPyColourChooser.py new file mode 100644 index 0000000000..c213042aa3 --- /dev/null +++ b/wxPython/demo/wxPyColourChooser.py @@ -0,0 +1,58 @@ +from wxPython.wx import * +from wxPython.lib.colourchooser import wxPyColourChooser + +#--------------------------------------------------------------- + +class TestColourChooser(wxPanel): + def __init__(self, parent, log): + wxPanel.__init__(self, parent, -1) + self.log = log + + chooser = wxPyColourChooser(self, -1) + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(chooser, 0, wxALL, 25) + + self.SetAutoLayout(True) + self.SetSizer(sizer) + +#--------------------------------------------------------------- + +def runTest(frame, nb, log): + win = TestColourChooser(nb, log) + return win + +#--------------------------------------------------------------- + +overview = """ +The wxPyColourChooser component creates a colour chooser window +that is similar to the Microsoft Windows colour chooser dialog. +This dialog component is drawn in a panel, and thus can be +embedded inside any widget (although it cannot be resized). +This colour chooser may also be substituted for the colour +chooser on any platform that might have an ugly one :) + +How to use it +------------------------------ + +The demo (demo/wxPyColourChooser.py code shows how to display +a colour chooser and retrieve its options. + +Contact and Author Info +------------------------------ + +wxPyColourChooser was written and is maintained by: + + Michael Gilfix + +You can find the latest wxPyColourChooser code at +http://www.sourceforge.net/wxcolourchooser. If you have +any suggestions or want to submit a patch, please send +it my way at: mgilfix@eecs.tufts.edu +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) diff --git a/wxPython/demo/wxRadioBox.py b/wxPython/demo/wxRadioBox.py index 78921edaa9..9a31860855 100644 --- a/wxPython/demo/wxRadioBox.py +++ b/wxPython/demo/wxRadioBox.py @@ -3,10 +3,13 @@ from wxPython.wx import * #--------------------------------------------------------------------------- -RBOX1 = wxNewId() -RBOX2 = wxNewId() RBUT1 = wxNewId() RBUT2 = wxNewId() +RBUT3 = wxNewId() +RBUT4 = wxNewId() + +RBOX1 = wxNewId() +RBOX2 = wxNewId() class TestRadioButtons(wxPanel): def __init__(self, parent, log): @@ -33,15 +36,6 @@ class TestRadioButtons(wxPanel): rb.SetToolTip(wxToolTip("This box has no label")) sizer.Add(rb, 0, wxLEFT|wxRIGHT|wxBOTTOM, 20) - sizer.Add(wxStaticText(self, -1, "These are plain wxRadioButtons"), - 0, wxLEFT|wxRIGHT, 20) - sizer.Add(wxRadioButton(self, RBUT1, "wxRadioButton 1"), - 0, wxLEFT|wxRIGHT, 20) - sizer.Add(wxRadioButton(self, RBUT2, "wxRadioButton 2"), - 0, wxLEFT|wxRIGHT, 20) - EVT_RADIOBUTTON(self, RBUT1, self.EvtRadioButton) - EVT_RADIOBUTTON(self, RBUT2, self.EvtRadioButton) - self.SetSizer(sizer) @@ -49,7 +43,7 @@ class TestRadioButtons(wxPanel): self.log.WriteText('EvtRadioBox: %d\n' % event.GetInt()) def EvtRadioButton(self, event): - self.log.write('EvtRadioButton:%d\n' % event.GetInt()) + self.log.write('EvtRadioButton:%d\n' % event.GetId()) #--------------------------------------------------------------------------- @@ -57,21 +51,19 @@ def runTest(frame, nb, log): win = TestRadioButtons(nb, log) return win -#--------------------------------------------------------------------------- - - - - - - - - - overview = """\ -A radio box item is used to select one of number of mutually exclusive choices. It is displayed as a vertical column or horizontal row of labelled buttons. +A radio box item is used to select one of number of mutually exclusive +choices. It is displayed as a vertical column or horizontal row of +labelled buttons. """ + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxRadioButton.py b/wxPython/demo/wxRadioButton.py new file mode 100644 index 0000000000..2993cec800 --- /dev/null +++ b/wxPython/demo/wxRadioButton.py @@ -0,0 +1,119 @@ +from wxPython.wx import * +#---------------------------------------------------------------------- + +class TestPanel( wxPanel ): + def __init__( self, parent, log ): + + wxPanel.__init__( self, parent, -1 ) + self.log = log + panel = wxPanel( self, -1 ) + + # 1st group of controls: + self.group1_ctrls = [] + radio1 = wxRadioButton( panel, -1, " Radio1 ", style = wxRB_GROUP ) + text1 = wxTextCtrl( panel, -1, "" ) + radio2 = wxRadioButton( panel, -1, " Radio2 " ) + text2 = wxTextCtrl( panel, -1, "" ) + radio3 = wxRadioButton( panel, -1, " Radio3 " ) + text3 = wxTextCtrl( panel, -1, "" ) + self.group1_ctrls.append((radio1, text1)) + self.group1_ctrls.append((radio2, text2)) + self.group1_ctrls.append((radio3, text3)) + + # 2nd group of controls: + self.group2_ctrls = [] + radio4 = wxRadioButton( panel, -1, " Radio1 ", style = wxRB_GROUP ) + text4 = wxTextCtrl( panel, -1, "" ) + radio5 = wxRadioButton( panel, -1, " Radio2 " ) + text5 = wxTextCtrl( panel, -1, "" ) + radio6 = wxRadioButton( panel, -1, " Radio3 " ) + text6 = wxTextCtrl( panel, -1, "" ) + self.group2_ctrls.append((radio4, text4)) + self.group2_ctrls.append((radio5, text5)) + self.group2_ctrls.append((radio6, text6)) + + # Layout controls on panel: + vs = wxBoxSizer( wxVERTICAL ) + + box1_title = wxStaticBox( panel, -1, "Group 1" ) + box1 = wxStaticBoxSizer( box1_title, wxVERTICAL ) + grid1 = wxFlexGridSizer( 0, 2, 0, 0 ) + for radio, text in self.group1_ctrls: + grid1.AddWindow( radio, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 ) + grid1.AddWindow( text, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 ) + box1.AddSizer( grid1, 0, wxALIGN_CENTRE|wxALL, 5 ) + vs.AddSizer( box1, 0, wxALIGN_CENTRE|wxALL, 5 ) + + box2_title = wxStaticBox( panel, -1, "Group 2" ) + box2 = wxStaticBoxSizer( box2_title, wxVERTICAL ) + grid2 = wxFlexGridSizer( 0, 2, 0, 0 ) + for radio, text in self.group2_ctrls: + grid2.AddWindow( radio, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 ) + grid2.AddWindow( text, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxTOP, 5 ) + box2.AddSizer( grid2, 0, wxALIGN_CENTRE|wxALL, 5 ) + vs.AddSizer( box2, 0, wxALIGN_CENTRE|wxALL, 5 ) + + panel.SetSizer( vs ) + vs.Fit( panel ) + panel.Move( (50,50) ) + self.panel = panel + + # Setup event handling and initial state for controls: + for radio, text in self.group1_ctrls: + EVT_RADIOBUTTON( self, radio.GetId(), self.OnGroup1Select ) + + for radio, text in self.group2_ctrls: + EVT_RADIOBUTTON( self, radio.GetId(), self.OnGroup2Select ) + + for radio, text in self.group1_ctrls + self.group2_ctrls: + radio.SetValue(0) + text.Enable(False) + + + def OnGroup1Select( self, event ): + radio_selected = event.GetEventObject() + self.log.write('Group1 %s selected\n' % radio_selected.GetLabel() ) + for radio, text in self.group1_ctrls: + if radio is radio_selected: + text.Enable(True) + else: + text.Enable(False) + + def OnGroup2Select( self, event ): + radio_selected = event.GetEventObject() + self.log.write('Group2 %s selected\n' % radio_selected.GetLabel() ) + for radio, text in self.group2_ctrls: + if radio is radio_selected: + text.Enable(True) + else: + text.Enable(False) + +#---------------------------------------------------------------------- + +def runTest( frame, nb, log ): + win = TestPanel( nb, log ) + return win + +#---------------------------------------------------------------------- + + +overview = """\ + +

    +This demo shows how individual radio buttons can be used to build +more complicated selection mechanisms... +

    +It uses 2 groups of wxRadioButtons, where the groups are defined by +instantiation. When a wxRadioButton is created with the wxRB_GROUP +style, all subsequent wxRadioButtons created without it are implicitly +added to that group by the framework. + +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxRightTextCtrl.py b/wxPython/demo/wxRightTextCtrl.py index c6ef3b9d2f..7fe10cef6f 100644 --- a/wxPython/demo/wxRightTextCtrl.py +++ b/wxPython/demo/wxRightTextCtrl.py @@ -33,7 +33,7 @@ class TestPanel(wxPanel): sizer.Add(fgs, 0, wxALL, 25) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) diff --git a/wxPython/demo/wxSashWindow.py b/wxPython/demo/wxSashWindow.py index be6a46d7c5..a8b472c2c1 100644 --- a/wxPython/demo/wxSashWindow.py +++ b/wxPython/demo/wxSashWindow.py @@ -31,7 +31,7 @@ class TestSashWindow(wxPanel): win.SetOrientation(wxLAYOUT_HORIZONTAL) win.SetAlignment(wxLAYOUT_TOP) win.SetBackgroundColour(wxColour(255, 0, 0)) - win.SetSashVisible(wxSASH_BOTTOM, true) + win.SetSashVisible(wxSASH_BOTTOM, True) self.topWindow = win @@ -44,7 +44,7 @@ class TestSashWindow(wxPanel): win.SetOrientation(wxLAYOUT_HORIZONTAL) win.SetAlignment(wxLAYOUT_BOTTOM) win.SetBackgroundColour(wxColour(0, 0, 255)) - win.SetSashVisible(wxSASH_TOP, true) + win.SetSashVisible(wxSASH_TOP, True) self.bottomWindow = win @@ -57,7 +57,7 @@ class TestSashWindow(wxPanel): win.SetOrientation(wxLAYOUT_VERTICAL) win.SetAlignment(wxLAYOUT_LEFT) win.SetBackgroundColour(wxColour(0, 255, 0)) - win.SetSashVisible(wxSASH_RIGHT, TRUE) + win.SetSashVisible(wxSASH_RIGHT, True) win.SetExtraBorderSize(10) textWindow = wxTextCtrl(win, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxSUNKEN_BORDER) @@ -74,7 +74,7 @@ class TestSashWindow(wxPanel): win.SetOrientation(wxLAYOUT_VERTICAL) win.SetAlignment(wxLAYOUT_LEFT) win.SetBackgroundColour(wxColour(0, 255, 255)) - win.SetSashVisible(wxSASH_RIGHT, TRUE) + win.SetSashVisible(wxSASH_RIGHT, True) self.leftWindow2 = win diff --git a/wxPython/demo/wxScrolledPanel.py b/wxPython/demo/wxScrolledPanel.py new file mode 100644 index 0000000000..079f878dc6 --- /dev/null +++ b/wxPython/demo/wxScrolledPanel.py @@ -0,0 +1,112 @@ +from wxPython.wx import * +from wxPython.lib.scrolledpanel import wxScrolledPanel + +#---------------------------------------------------------------------- + +text = "one two buckle my shoe three four shut the door five six pick up sticks seven eight lay them straight nine ten big fat hen" + + +class TestPanel(wxScrolledPanel): + def __init__(self, parent, log): + self.log = log + wxScrolledPanel.__init__(self, parent, -1) + + vbox = wxBoxSizer(wxVERTICAL) + desc = wxStaticText(self, -1, + "wxScrolledPanel extends wxScrolledWindow, adding all " + "the necessary bits to set up scroll handling for you.\n\n" + "Here are three fixed size examples of its use, and the " + "mail demo panel is also using it." + ) + desc.SetForegroundColour("Blue") + vbox.Add(desc, 0, wxALIGN_LEFT|wxALL, 5) + vbox.Add(wxStaticLine(self, -1), 0, wxEXPAND|wxALL, 5) + vbox.AddSpacer(20,20) + + words = text.split() + + panel1 = wxScrolledPanel(self, -1, size=(120,300), + style = wxTAB_TRAVERSAL|wxSUNKEN_BORDER ) + fgs1 = wxFlexGridSizer(cols=2, vgap=4, hgap=4) + + for word in words: + label = wxStaticText(panel1, -1, word+":") + tc = wxTextCtrl(panel1, -1, word, size=(50,-1)) + fgs1.Add(label, flag=wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL) + fgs1.Add(tc, flag=wxEXPAND|wxRIGHT, border=25) + + panel1.SetSizer( fgs1 ) + panel1.SetAutoLayout(1) + panel1.SetupScrolling( scroll_x=False ) + + panel2 = wxScrolledPanel(self, -1, size=(350, 40), + style = wxTAB_TRAVERSAL|wxSUNKEN_BORDER) + panel3 = wxScrolledPanel(self, -1, size=(200,100), + style = wxTAB_TRAVERSAL|wxSUNKEN_BORDER) + + fgs2 = wxFlexGridSizer(cols=25, vgap=4, hgap=4) + fgs3 = wxFlexGridSizer(cols=5, vgap=4, hgap=4) + + for i in range(len(words)): + word = words[i] + if i % 5 != 4: + label2 = wxStaticText(panel2, -1, word) + fgs2.Add(label2, flag=wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL) + label3 = wxStaticText(panel3, -1, word) + fgs3.Add(label3, flag=wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL) + else: + tc2 = wxTextCtrl(panel2, -1, word, size=(50,-1)) + fgs2.Add(tc2, flag=wxLEFT, border=5) + tc3 = wxTextCtrl(panel3, -1, word ) + fgs3.Add(tc3, flag=wxLEFT, border=5) + + panel2.SetSizer( fgs2 ) + panel2.SetAutoLayout(1) + panel2.SetupScrolling(scroll_y = False) + + panel3.SetSizer( fgs3 ) + panel3.SetAutoLayout(1) + panel3.SetupScrolling() + + hbox = wxBoxSizer(wxHORIZONTAL) + hbox.AddSpacer(20,20) + hbox.Add(panel1, 0) + hbox.AddSpacer(40, 10) + + vbox2 = wxBoxSizer(wxVERTICAL) + vbox2.Add(panel2, 0) + vbox2.AddSpacer(20, 50) + + vbox2.Add(panel3, 0) + vbox2.AddSpacer(20, 10) + hbox.Add(vbox2) + + vbox.AddSizer(hbox, 0) + self.SetSizer(vbox) + self.SetAutoLayout(1) + self.SetupScrolling() + + +#---------------------------------------------------------------------- + + +def runTest(frame, nb, log): + win = TestPanel(nb, log) + return win + +#---------------------------------------------------------------------- + + + +overview = """ +wxScrolledPanel fills a "hole" in the implementation of wxScrolledWindow, +providing automatic scrollbar and scrolling behavior and the tab traversal +mangement that wxScrolledWindow lacks. + +""" + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) diff --git a/wxPython/demo/wxScrolledWindow.py b/wxPython/demo/wxScrolledWindow.py index e0ad207b73..53d8b4a130 100644 --- a/wxPython/demo/wxScrolledWindow.py +++ b/wxPython/demo/wxScrolledWindow.py @@ -16,7 +16,7 @@ class MyCanvas(wxScrolledWindow): self.maxHeight = 1000 self.x = self.y = 0 self.curLine = [] - self.drawing = false + self.drawing = False self.SetBackgroundColour("WHITE") self.SetCursor(wxStockCursor(wxCURSOR_PENCIL)) @@ -88,7 +88,7 @@ class MyCanvas(wxScrolledWindow): dc.SetPen(wxGREEN_PEN) dc.DrawSpline(lst+[(100,100)]) - dc.DrawBitmap(self.bmp, 200, 20, true) + dc.DrawBitmap(self.bmp, 200, 20, True) dc.SetTextForeground(wxColour(0, 0xFF, 0x80)) dc.DrawText("a bitmap", 200, 85) @@ -149,10 +149,11 @@ class MyCanvas(wxScrolledWindow): def OnLeftButtonEvent(self, event): if event.LeftDown(): + self.SetFocus() self.SetXY(event) self.curLine = [] self.CaptureMouse() - self.drawing = true + self.drawing = True elif event.Dragging() and self.drawing: if BUFFERED: @@ -178,7 +179,7 @@ class MyCanvas(wxScrolledWindow): self.lines.append(self.curLine) self.curLine = [] self.ReleaseMouse() - self.drawing = false + self.drawing = False ## This is an example of what to do for the EVT_MOUSEWHEEL event, diff --git a/wxPython/demo/wxSlider.py b/wxPython/demo/wxSlider.py index 731486ee2b..8cce5b131e 100644 --- a/wxPython/demo/wxSlider.py +++ b/wxPython/demo/wxSlider.py @@ -1,8 +1,6 @@ from wxPython.wx import * -import string - #---------------------------------------------------------------------- class TestPanel(wxPanel): @@ -31,11 +29,13 @@ def runTest(frame, nb, log): +overview = """\ +""" +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) - - -overview = """\ -""" diff --git a/wxPython/demo/wxSpinButton.py b/wxPython/demo/wxSpinButton.py index 67308b41d0..0095fbad77 100644 --- a/wxPython/demo/wxSpinButton.py +++ b/wxPython/demo/wxSpinButton.py @@ -1,8 +1,6 @@ from wxPython.wx import * -import string - #---------------------------------------------------------------------- class TestPanel(wxPanel): diff --git a/wxPython/demo/wxSpinCtrl.py b/wxPython/demo/wxSpinCtrl.py index f373c82aa0..164397d1a0 100644 --- a/wxPython/demo/wxSpinCtrl.py +++ b/wxPython/demo/wxSpinCtrl.py @@ -1,8 +1,6 @@ from wxPython.wx import * -import string - #---------------------------------------------------------------------- class TestPanel(wxPanel): @@ -17,7 +15,7 @@ class TestPanel(wxPanel): sc = wxSpinCtrl(self, -1, "", wxPoint(30, 50), wxSize(80, -1)) sc.SetRange(1,100) sc.SetValue(5) - #sc.Enable(false) + #sc.Enable(False) #---------------------------------------------------------------------- diff --git a/wxPython/demo/wxSplitterWindow.py b/wxPython/demo/wxSplitterWindow.py index fac9cbee57..206244f6c0 100644 --- a/wxPython/demo/wxSplitterWindow.py +++ b/wxPython/demo/wxSplitterWindow.py @@ -35,8 +35,12 @@ def runTest(frame, nb, log): wxStaticText(p2, -1, "Panel Two", wxPoint(5,5)).SetBackgroundColour(wxBLUE) splitter.SetMinimumPaneSize(20) - splitter.SplitVertically(p1, p2) - splitter.SetSashPosition(100) + splitter.SplitVertically(p1, p2, 100) + +## splitter.SetSize((300,300)) +## print splitter.GetSashPosition() +## splitter.SetSashPosition(100) +## print splitter.GetSashPosition() return splitter diff --git a/wxPython/demo/wxStaticBitmap.py b/wxPython/demo/wxStaticBitmap.py index 1b057913ef..d281d60237 100644 --- a/wxPython/demo/wxStaticBitmap.py +++ b/wxPython/demo/wxStaticBitmap.py @@ -1,8 +1,6 @@ from wxPython.wx import * -from Main import opj -import string import images #---------------------------------------------------------------------- diff --git a/wxPython/demo/wxStaticText.py b/wxPython/demo/wxStaticText.py index dc558eed08..f143ddb5cb 100644 --- a/wxPython/demo/wxStaticText.py +++ b/wxPython/demo/wxStaticText.py @@ -1,7 +1,7 @@ from wxPython.wx import * -USE_GENERIC = 1 +USE_GENERIC = 0 if USE_GENERIC: from wxPython.lib.stattext import wxGenStaticText as wxStaticText @@ -24,7 +24,7 @@ class TestPanel(wxPanel): str = "This is a different font." text = wxStaticText(self, -1, str, (20, 100)) - font = wxFont(18, wxSWISS, wxNORMAL, wxNORMAL, false, "Arial") + font = wxFont(18, wxSWISS, wxNORMAL, wxNORMAL, False, "Arial") w, h, d, e = self.GetFullTextExtent(str, font) text.SetFont(font) text.SetSize(wxSize(w, h)) diff --git a/wxPython/demo/wxStatusBar.py b/wxPython/demo/wxStatusBar.py index 1c9b45655f..d7241a1b5b 100644 --- a/wxPython/demo/wxStatusBar.py +++ b/wxPython/demo/wxStatusBar.py @@ -10,7 +10,7 @@ class CustomStatusBar(wxStatusBar): wxStatusBar.__init__(self, parent, -1) self.SetFieldsCount(3) self.log = log - self.sizeChanged = false + self.sizeChanged = False EVT_SIZE(self, self.OnSize) EVT_IDLE(self, self.OnIdle) @@ -18,7 +18,7 @@ class CustomStatusBar(wxStatusBar): self.cb = wxCheckBox(self, 1001, "toggle clock") EVT_CHECKBOX(self, 1001, self.OnToggleClock) - self.cb.SetValue(true) + self.cb.SetValue(True) # set the initial position of the checkbox self.Reposition() @@ -52,7 +52,7 @@ class CustomStatusBar(wxStatusBar): # Set a flag so the idle time handler will also do the repositioning. # It is done this way to get around a buglet where GetFieldRect is not # accurate during the EVT_SIZE resulting from a frame maximize. - self.sizeChanged = true + self.sizeChanged = True def OnIdle(self, evt): @@ -65,7 +65,7 @@ class CustomStatusBar(wxStatusBar): rect = self.GetFieldRect(1) self.cb.SetPosition(wxPoint(rect.x+2, rect.y+2)) self.cb.SetSize(wxSize(rect.width-4, rect.height-4)) - self.sizeChanged = false + self.sizeChanged = False @@ -91,7 +91,7 @@ class TestCustomStatusBar(wxFrame): def runTest(frame, nb, log): win = TestCustomStatusBar(frame, log) frame.otherWin = win - win.Show(true) + win.Show(True) #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxStyledTextCtrl_1.py b/wxPython/demo/wxStyledTextCtrl_1.py index 83530d2ece..d23c1a6636 100644 --- a/wxPython/demo/wxStyledTextCtrl_1.py +++ b/wxPython/demo/wxStyledTextCtrl_1.py @@ -74,7 +74,7 @@ class MySTC(wxStyledTextCtrl): % (evt.GetDragAllowMove(), evt.GetDragText())) if debug and evt.GetPosition() < 250: - evt.SetDragAllowMove(false) # you can prevent moving of text (only copy) + evt.SetDragAllowMove(False) # you can prevent moving of text (only copy) evt.SetDragText("DRAGGED TEXT") # you can change what is dragged #evt.SetDragText("") # or prevent the drag with empty text @@ -159,13 +159,13 @@ def runTest(frame, nb, log): s = wxBoxSizer(wxHORIZONTAL) s.Add(ed, 1, wxEXPAND) p.SetSizer(s) - p.SetAutoLayout(true) + p.SetAutoLayout(True) - #ed.SetBufferedDraw(false) + #ed.SetBufferedDraw(False) #ed.StyleClearAll() #ed.SetScrollWidth(800) - #ed.SetWrapMode(true) + #ed.SetWrapMode(True) ed.SetText(demoText) if wxUSE_UNICODE: diff --git a/wxPython/demo/wxStyledTextCtrl_2.py b/wxPython/demo/wxStyledTextCtrl_2.py index 325c4ea6ae..516383f50f 100644 --- a/wxPython/demo/wxStyledTextCtrl_2.py +++ b/wxPython/demo/wxStyledTextCtrl_2.py @@ -45,14 +45,14 @@ class PythonSTC(wxStyledTextCtrl): self.CmdKeyAssign(ord('N'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT) self.SetLexer(wxSTC_LEX_PYTHON) - self.SetKeyWords(0, string.join(keyword.kwlist)) + self.SetKeyWords(0, " ".join(keyword.kwlist)) self.SetProperty("fold", "1") self.SetProperty("tab.timmy.whinge.level", "1") self.SetMargins(0,0) - self.SetViewWhiteSpace(false) - #self.SetBufferedDraw(false) + self.SetViewWhiteSpace(False) + #self.SetBufferedDraw(False) self.SetEdgeMode(wxSTC_EDGE_BACKGROUND) self.SetEdgeColumn(78) @@ -61,7 +61,7 @@ class PythonSTC(wxStyledTextCtrl): #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER? self.SetMarginType(2, wxSTC_MARGIN_SYMBOL) self.SetMarginMask(2, wxSTC_MASK_FOLDERS) - self.SetMarginSensitive(2, true) + self.SetMarginSensitive(2, True) self.SetMarginWidth(2, 12) if 0: # simple folder marks, like the old version @@ -151,7 +151,7 @@ class PythonSTC(wxStyledTextCtrl): #lst = [] #for x in range(50000): # lst.append('%05d' % x) - #st = string.join(lst) + #st = " ".join(lst) #print len(st) #self.AutoCompShow(0, st) @@ -165,9 +165,9 @@ class PythonSTC(wxStyledTextCtrl): kw.append("this_is_a_much_much_much_much_much_much_much_longer_value") kw.sort() # Python sorts are case sensitive - self.AutoCompSetIgnoreCase(false) # so this needs to match + self.AutoCompSetIgnoreCase(False) # so this needs to match - self.AutoCompShow(0, string.join(kw)) + self.AutoCompShow(0, " ".join(kw)) else: event.Skip() @@ -175,7 +175,7 @@ class PythonSTC(wxStyledTextCtrl): def OnUpdateUI(self, evt): # check for matching braces braceAtCaret = -1 - braceOpposite = -1 + braceOpposite = -1 charBefore = None caretPos = self.GetCurrentPos() if caretPos > 0: @@ -201,9 +201,9 @@ class PythonSTC(wxStyledTextCtrl): else: self.BraceHighlight(braceAtCaret, braceOpposite) #pt = self.PointFromPosition(braceOpposite) - #self.Refresh(true, wxRect(pt.x, pt.y, 5,5)) + #self.Refresh(True, wxRect(pt.x, pt.y, 5,5)) #print pt - #self.Refresh(false) + #self.Refresh(False) def OnMarginClick(self, evt): @@ -215,22 +215,22 @@ class PythonSTC(wxStyledTextCtrl): lineClicked = self.LineFromPosition(evt.GetPosition()) if self.GetFoldLevel(lineClicked) & wxSTC_FOLDLEVELHEADERFLAG: if evt.GetShift(): - self.SetFoldExpanded(lineClicked, true) - self.Expand(lineClicked, true, true, 1) + self.SetFoldExpanded(lineClicked, True) + self.Expand(lineClicked, True, True, 1) elif evt.GetControl(): if self.GetFoldExpanded(lineClicked): - self.SetFoldExpanded(lineClicked, false) - self.Expand(lineClicked, false, true, 0) + self.SetFoldExpanded(lineClicked, False) + self.Expand(lineClicked, False, True, 0) else: - self.SetFoldExpanded(lineClicked, true) - self.Expand(lineClicked, true, true, 100) + self.SetFoldExpanded(lineClicked, True) + self.Expand(lineClicked, True, True, 100) else: self.ToggleFold(lineClicked) def FoldAll(self): lineCount = self.GetLineCount() - expanding = true + expanding = True # find out if we are folding or unfolding for lineNum in range(lineCount): @@ -245,12 +245,12 @@ class PythonSTC(wxStyledTextCtrl): (level & wxSTC_FOLDLEVELNUMBERMASK) == wxSTC_FOLDLEVELBASE: if expanding: - self.SetFoldExpanded(lineNum, true) - lineNum = self.Expand(lineNum, true) + self.SetFoldExpanded(lineNum, True) + lineNum = self.Expand(lineNum, True) lineNum = lineNum - 1 else: lastChild = self.GetLastChild(lineNum, -1) - self.SetFoldExpanded(lineNum, false) + self.SetFoldExpanded(lineNum, False) if lastChild > lineNum: self.HideLines(lineNum+1, lastChild) @@ -258,9 +258,9 @@ class PythonSTC(wxStyledTextCtrl): - def Expand(self, line, doExpand, force=false, visLevels=0, level=-1): + def Expand(self, line, doExpand, force=False, visLevels=0, level=-1): lastChild = self.GetLastChild(line, level) - line = line + 1 + line = line + 1 while line <= lastChild: if force: if visLevels > 0: @@ -277,16 +277,16 @@ class PythonSTC(wxStyledTextCtrl): if level & wxSTC_FOLDLEVELHEADERFLAG: if force: if visLevels > 1: - self.SetFoldExpanded(line, true) + self.SetFoldExpanded(line, True) else: - self.SetFoldExpanded(line, false) + self.SetFoldExpanded(line, False) line = self.Expand(line, doExpand, force, visLevels-1) else: if doExpand and self.GetFoldExpanded(line): - line = self.Expand(line, true, force, visLevels-1) + line = self.Expand(line, True, force, visLevels-1) else: - line = self.Expand(line, false, force, visLevels-1) + line = self.Expand(line, False, force, visLevels-1) else: line = line + 1; @@ -306,7 +306,7 @@ def runTest(frame, nb, log): s = wxBoxSizer(wxHORIZONTAL) s.Add(ed, 1, wxEXPAND) p.SetSizer(s) - p.SetAutoLayout(true) + p.SetAutoLayout(True) ed.SetText(demoText + open('Main.py').read()) diff --git a/wxPython/demo/wxTextCtrl.py b/wxPython/demo/wxTextCtrl.py index 7b55456399..1045efe3d0 100644 --- a/wxPython/demo/wxTextCtrl.py +++ b/wxPython/demo/wxTextCtrl.py @@ -20,55 +20,73 @@ class TestPanel(wxPanel): self.log = log l1 = wxStaticText(self, -1, "wxTextCtrl") - t1 = wxTextCtrl(self, 10, "Test it out and see", size=(125, -1)) + t1 = wxTextCtrl(self, -1, "Test it out and see", size=(125, -1)) t1.SetInsertionPoint(0) - EVT_TEXT(self, 10, self.EvtText) + self.tc1 = t1 + EVT_TEXT(self, t1.GetId(), self.EvtText) EVT_CHAR(t1, self.EvtChar) EVT_SET_FOCUS(t1, self.OnSetFocus) EVT_KILL_FOCUS(t1, self.OnKillFocus) EVT_WINDOW_DESTROY(t1, self.OnWindowDestroy) l2 = wxStaticText(self, -1, "Passsword") - t2 = wxTextCtrl(self, 20, "", size=(125, -1), style=wxTE_PASSWORD) - EVT_TEXT(self, 20, self.EvtText) + t2 = wxTextCtrl(self, -1, "", size=(125, -1), style=wxTE_PASSWORD) + EVT_TEXT(self, t2.GetId(), self.EvtText) l3 = wxStaticText(self, -1, "Multi-line") - t3 = wxTextCtrl(self, 30, + t3 = wxTextCtrl(self, -1, "Here is a looooooooooooooong line of text set in the control.\n\n" "The quick brown fox jumped over the lazy dog...", size=(200, 100), style=wxTE_MULTILINE) t3.SetInsertionPoint(0) - EVT_TEXT(self, 30, self.EvtText) + EVT_TEXT(self, t3.GetId(), self.EvtText) b = wxButton(self, -1, "Test Replace") EVT_BUTTON(self, b.GetId(), self.OnTestReplace) b2 = wxButton(self, -1, "Test GetSelection") EVT_BUTTON(self, b2.GetId(), self.OnTestGetSelection) + b3 = wxButton(self, -1, "Test WriteText") + EVT_BUTTON(self, b3.GetId(), self.OnTestWriteText) self.tc = t3 + b4 = wxButton(self, -1, "Test Simulated Event") + EVT_BUTTON(self, b4.GetId(), self.OnTestEvent) + l4 = wxStaticText(self, -1, "Rich Text") - t4 = wxTextCtrl(self, 40, "If supported by the native control, this is red, and this is a different font.", + t4 = wxTextCtrl(self, -1, "If supported by the native control, this is red, and this is a different font.", size=(200, 100), style=wxTE_MULTILINE|wxTE_RICH2) t4.SetInsertionPoint(0) t4.SetStyle(44, 47, wxTextAttr("RED", "YELLOW")) - points = t4.GetFont().GetPointSize() # get the current size - f = wxFont(points+3, wxROMAN, wxITALIC, wxBOLD, true) + f = wxFont(points+3, wxROMAN, wxITALIC, wxBOLD, True) t4.SetStyle(63, 77, wxTextAttr("BLUE", wxNullColour, f)) + l5 = wxStaticText(self, -1, "Test Positions") + t5 = wxTextCtrl(self, -1, "0123456789\n" * 5, size=(200, 100), + style = wxTE_MULTILINE + #| wxTE_RICH + | wxTE_RICH2 + ) + EVT_LEFT_DOWN(t5, self.OnT5LeftDown) + self.t5 = t5 + + bsizer = wxBoxSizer(wxVERTICAL) - bsizer.Add(b, 0, wxGROW) - bsizer.Add(b2, 0, wxGROW) + bsizer.Add(b, 0, wxGROW|wxALL, 4) + bsizer.Add(b2, 0, wxGROW|wxALL, 4) + bsizer.Add(b3, 0, wxGROW|wxALL, 4) + bsizer.Add(b4, 0, wxGROW|wxALL, 4) sizer = wxFlexGridSizer(cols=3, hgap=6, vgap=6) sizer.AddMany([ l1, t1, (0,0), l2, t2, (0,0), l3, t3, bsizer, l4, t4, (0,0), + l5, t5, (0,0), ]) border = wxBoxSizer(wxVERTICAL) border.Add(sizer, 0, wxALL, 25) self.SetSizer(border) - self.SetAutoLayout(true) + self.SetAutoLayout(True) def EvtText(self, event): @@ -84,11 +102,14 @@ class TestPanel(wxPanel): self.tc.Replace(5, 9, "IS A") #self.tc.Remove(5, 9) + def OnTestWriteText(self, evt): + self.tc.WriteText("TEXT") + def OnTestGetSelection(self, evt): start, end = self.tc.GetSelection() text = self.tc.GetValue() if wxPlatform == "__WXMSW__": # This is why GetStringSelection was added - text = string.replace(text, '\n', '\r\n') + text = text.replace('\n', '\r\n') self.log.write("GetSelection(): (%d, %d)\n" "\tGetStringSelection(): %s\n" "\tSelectedText: %s\n" % @@ -96,6 +117,29 @@ class TestPanel(wxPanel): self.tc.GetStringSelection(), repr(text[start:end]))) + def OnT5LeftDown(self, evt): + evt.Skip() + wxCallAfter(self.LogT5Position, evt) + + def LogT5Position(self, evt): + text = self.t5.GetValue() + ip = self.t5.GetInsertionPoint() + lp = self.t5.GetLastPosition() + self.log.write("LogT5Position:\n" + "\tGetInsertionPoint:\t%d\n" + "\ttext[insertionpoint]:\t%s\n" + "\tGetLastPosition:\t%d\n" + "\tlen(text):\t\t%d\n" + % (ip, text[ip], lp, len(text))) + + + def OnTestEvent(self, evt): + ke = wxKeyEvent(wxEVT_CHAR) + ke.SetEventObject(self.tc1) + ke.SetId(self.tc1.GetId()) + ke.m_keyCode = ord('A') + self.tc1.GetEventHandler().ProcessEvent(ke) + #--------------------------------------------------------------------------- diff --git a/wxPython/demo/wxTimeCtrl.py b/wxPython/demo/wxTimeCtrl.py new file mode 100644 index 0000000000..09465642dd --- /dev/null +++ b/wxPython/demo/wxTimeCtrl.py @@ -0,0 +1,213 @@ +from wxPython.wx import * +from wxPython.lib.timectrl import * + +#---------------------------------------------------------------------- + +class TestPanel( wxPanel ): + def __init__( self, parent, log ): + + wxPanel.__init__( self, parent, -1 ) + self.log = log + panel = wxPanel( self, -1 ) + + grid = wxFlexGridSizer( 0, 2, 20, 0 ) + + text1 = wxStaticText( panel, 10, "A 12-hour format wxTimeCtrl:") + self.time12 = wxTimeCtrl( panel, 20, name="12 hour control" ) + spin1 = wxSpinButton( panel, 30, wxDefaultPosition, wxSize(-1,20), 0 ) + self.time12.BindSpinButton( spin1 ) + + grid.AddWindow( text1, 0, wxALIGN_RIGHT, 5 ) + hbox1 = wxBoxSizer( wxHORIZONTAL ) + hbox1.AddWindow( self.time12, 0, wxALIGN_CENTRE, 5 ) + hbox1.AddWindow( spin1, 0, wxALIGN_CENTRE, 5 ) + grid.AddSizer( hbox1, 0, wxLEFT, 5 ) + + + text2 = wxStaticText( panel, 40, "A 24-hour format wxTimeCtrl:") + self.time24 = wxTimeCtrl( panel, 50, fmt24hr=True, name="24 hour control" ) + spin2 = wxSpinButton( panel, 60, wxDefaultPosition, wxSize(-1,20), 0 ) + self.time24.BindSpinButton( spin2 ) + + grid.AddWindow( text2, 0, wxALIGN_RIGHT|wxTOP|wxBOTTOM, 5 ) + hbox2 = wxBoxSizer( wxHORIZONTAL ) + hbox2.AddWindow( self.time24, 0, wxALIGN_CENTRE, 5 ) + hbox2.AddWindow( spin2, 0, wxALIGN_CENTRE, 5 ) + grid.AddSizer( hbox2, 0, wxLEFT, 5 ) + + + text3 = wxStaticText( panel, 70, "A wxTimeCtrl without a spin button:") + self.spinless_ctrl = wxTimeCtrl( panel, 80, name="spinless control" ) + + grid.AddWindow( text3, 0, wxALIGN_RIGHT|wxTOP|wxBOTTOM, 5 ) + grid.AddWindow( self.spinless_ctrl, 0, wxLEFT, 5 ) + + + buttonChange = wxButton( panel, 100, "Change Controls") + self.radio12to24 = wxRadioButton( panel, 110, "Copy 12-hour time to 24-hour control", wxDefaultPosition, wxDefaultSize, wxRB_GROUP ) + self.radio24to12 = wxRadioButton( panel, 120, "Copy 24-hour time to 12-hour control") + self.radioWx = wxRadioButton( panel, 130, "Set controls to 'now' using wxDateTime") + self.radioMx = wxRadioButton( panel, 140, "Set controls to 'now' using mxDateTime") + + radio_vbox = wxBoxSizer( wxVERTICAL ) + radio_vbox.AddWindow( self.radio12to24, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + radio_vbox.AddWindow( self.radio24to12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + radio_vbox.AddWindow( self.radioWx, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + radio_vbox.AddWindow( self.radioMx, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ) + + box_label = wxStaticBox( panel, 90, "Change Controls through API" ) + buttonbox = wxStaticBoxSizer( box_label, wxHORIZONTAL ) + buttonbox.AddWindow( buttonChange, 0, wxALIGN_CENTRE|wxALL, 5 ) + buttonbox.AddSizer( radio_vbox, 0, wxALIGN_CENTRE|wxALL, 5 ) + + outer_box = wxBoxSizer( wxVERTICAL ) + outer_box.AddSizer( grid, 0, wxALIGN_CENTRE|wxBOTTOM, 20 ) + outer_box.AddSizer( buttonbox, 0, wxALIGN_CENTRE|wxALL, 5 ) + + + # Turn on mxDateTime option only if we can import the module: + try: + from mx import DateTime + except ImportError: + self.radioMx.Enable( False ) + + + panel.SetAutoLayout( True ) + panel.SetSizer( outer_box ) + outer_box.Fit( panel ) + panel.Move( (50,50) ) + self.panel = panel + + + EVT_TIMEUPDATE( self, self.time12.GetId(), self.OnTimeChange ) + EVT_TIMEUPDATE( self, self.time24.GetId(), self.OnTimeChange ) + EVT_TIMEUPDATE( self, self.spinless_ctrl.GetId(), self.OnTimeChange ) + + EVT_BUTTON( self, buttonChange.GetId(), self.OnButtonClick ) + + + def OnTimeChange( self, event ): + timectrl = self.panel.FindWindowById( event.GetId() ) + self.log.write('%s time = %s\n' % ( timectrl.GetName(), timectrl.GetValue() ) ) + + def OnButtonClick( self, event ): + if self.radio12to24.GetValue(): + self.time24.SetValue( self.time12.GetValue() ) + + elif self.radio24to12.GetValue(): + self.time12.SetValue( self.time24.GetValue() ) + + elif self.radioWx.GetValue(): + now = wxDateTime_Now() + self.time12.SetWxDateTime( now ) + self.time24.SetWxDateTime( now ) + self.spinless_ctrl.SetWxDateTime( now ) + + elif self.radioMx.GetValue(): + from mx import DateTime + now = DateTime.now() + self.time12.SetMxDateTime( now ) + self.time24.SetMxDateTime( now ) + self.spinless_ctrl.SetMxDateTime( now ) + +#---------------------------------------------------------------------- + +def runTest( frame, nb, log ): + win = TestPanel( nb, log ) + return win + +#---------------------------------------------------------------------- + +overview = """ +

    +wxTimeCtrl provides a multi-cell control that allows manipulation of a time +value. It supports 12 or 24 hour format, and you can use wxDateTime or mxDateTime +to get/set values from the control. +

    +Left/right/tab keys to switch cells within a wxTimeCtrl, and the up/down arrows act +like a spin control. wxTimeCtrl also allows for an actual spin button to be attached +to the control, so that it acts like the up/down arrow keys. +

    +The ! or c key sets the value of the control to now. +

    +Here's the API for wxTimeCtrl: +

    +    wxTimeCtrl(
    +         parent, id = -1,
    +         value = '12:00:00 AM',
    +         pos = wxDefaultPosition,
    +         size = wxDefaultSize,
    +         fmt24hr = False,
    +         spinButton = None,
    +         style = wxTE_PROCESS_TAB,
    +         name = "time")
    +
    +
      +
      value +
      If no initial value is set, the default will be midnight; if an illegal string + is specified, a ValueError will result. (You can always later set the initial time + with SetValue() after instantiation of the control.) +
      size +
      The size of the control will be automatically adjusted for 12/24 hour format + if wxDefaultSize is specified. +
      +
      fmt24hr +
      If True, control will display time in 24 hour time format; if False, it will + use 12 hour AM/PM format. SetValue() will adjust values accordingly for the + control, based on the format specified. +
      +
      spinButton +
      If specified, this button's events will be bound to the behavior of the + wxTimeCtrl, working like up/down cursor key events. (See BindSpinButton.) +
      +
      style +
      By default, wxTimeCtrl will process TAB events, by allowing tab to the + different cells within the control. +
      +
    +
    +
    +
    SetValue(time_string) +
    Sets the value of the control to a particular time, given a valid time string; +raises ValueError on invalid value +
    +
    GetValue() +
    Retrieves the string value of the time from the control +
    +
    SetWxDateTime(wxDateTime) +
    Uses the time portion of a wxDateTime to construct a value for the control. +
    +
    GetWxDateTime() +
    Retrieves the value of the control, and applies it to the wxDateTimeFromHMS() +constructor, and returns the resulting value. (This returns the date portion as +"today".) +
    +
    SetMxDateTime(mxDateTime) +
    Uses the time portion of an mxDateTime to construct a value for the control. +NOTE: This imports mx.DateTime at runtime only if this or the Get function +is called. +
    +
    GetMxDateTime() +
    Retrieves the value of the control and applies it to the DateTime.Time() +constructor, and returns the resulting value. (mxDateTime is smart enough to +know this is just a time value.) +
    +
    BindSpinButton(wxSpinBtton) +
    Binds an externally created spin button to the control, so that up/down spin +events change the active cell or selection in the control (in addition to the +up/down cursor keys.) (This is primarily to allow you to create a "standard" +interface to time controls, as seen in Windows.) +
    +
    EVT_TIMEUPDATE(win, id, func) +
    func is fired whenever the value of the control changes. +
    + +""" + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxToggleButton.py b/wxPython/demo/wxToggleButton.py index b184437ab7..74d34d3f77 100644 --- a/wxPython/demo/wxToggleButton.py +++ b/wxPython/demo/wxToggleButton.py @@ -15,12 +15,12 @@ class TestPanel(wxPanel): self.log = log panel = wxPanel(self, -1) buttons = wxBoxSizer(wxHORIZONTAL) - for word in string.split("These are toggle buttons"): + for word in "These are toggle buttons".split(): b = wxToggleButton(panel, -1, word) EVT_TOGGLEBUTTON(self, b.GetId(), self.OnToggle) buttons.Add(b, flag=wxALL, border=5) - panel.SetAutoLayout(true) + panel.SetAutoLayout(True) panel.SetSizer(buttons) buttons.Fit(panel) panel.Move((50,50)) diff --git a/wxPython/demo/wxToolBar.py b/wxPython/demo/wxToolBar.py index ad4bfe5ea9..9867b98f05 100644 --- a/wxPython/demo/wxToolBar.py +++ b/wxPython/demo/wxToolBar.py @@ -7,16 +7,18 @@ import images class TestToolBar(wxFrame): def __init__(self, parent, log): - wxFrame.__init__(self, parent, -1, 'Test ToolBar', - wxPoint(0,0), wxSize(500, 300)) + wxFrame.__init__(self, parent, -1, 'Test ToolBar', size=(500, 300)) self.log = log self.timer = None EVT_CLOSE(self, self.OnCloseWindow) wxWindow(self, -1).SetBackgroundColour(wxNamedColour("WHITE")) - tb = self.CreateToolBar(wxTB_HORIZONTAL|wxNO_BORDER|wxTB_FLAT) - # wxTB_VERTICAL + tb = self.CreateToolBar( wxTB_HORIZONTAL + | wxNO_BORDER + | wxTB_FLAT + | wxTB_TEXT + ) #tb = wxToolBarSimple(self, -1, wxDefaultPosition, wxDefaultSize, # wxTB_HORIZONTAL | wxNO_BORDER | wxTB_FLAT) #self.SetToolBar(tb) @@ -24,6 +26,7 @@ class TestToolBar(wxFrame): self.CreateStatusBar() tb.AddSimpleTool(10, images.getNewBitmap(), "New", "Long help for 'New'") + #tb.AddLabelTool(10, "New", images.getNewBitmap(), shortHelp="New", longHelp="Long help for 'New'") EVT_TOOL(self, 10, self.OnToolClick) EVT_TOOL_RCLICKED(self, 10, self.OnToolRClick) @@ -46,9 +49,9 @@ class TestToolBar(wxFrame): shortHelp="Toggle this") EVT_TOOL(self, 50, self.OnToolClick) - #tb.AddCheckTool(60, '', images.getTog1Bitmap(), images.getTog2Bitmap(), - # shortHelp="Toggle with 2 bitmaps") - #EVT_TOOL(self, 60, self.OnToolClick) +## tb.AddCheckTool(60, images.getTog1Bitmap(), images.getTog2Bitmap(), +## shortHelp="Toggle with 2 bitmaps") +## EVT_TOOL(self, 60, self.OnToolClick) EVT_TOOL_ENTER(self, -1, self.OnToolEnter) EVT_TOOL_RCLICKED(self, -1, self.OnToolRClick) # Match all @@ -100,7 +103,7 @@ class TestToolBar(wxFrame): def runTest(frame, nb, log): win = TestToolBar(frame, log) frame.otherWin = win - win.Show(true) + win.Show(True) #--------------------------------------------------------------------------- @@ -109,16 +112,15 @@ def runTest(frame, nb, log): +overview = """\ +""" +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) - - - - -overview = """\ - -""" diff --git a/wxPython/demo/wxTreeCtrl.py b/wxPython/demo/wxTreeCtrl.py index ed5adc05e6..9a6a24f468 100644 --- a/wxPython/demo/wxTreeCtrl.py +++ b/wxPython/demo/wxTreeCtrl.py @@ -1,6 +1,6 @@ from wxPython.wx import * - +import images import string #--------------------------------------------------------------------------- @@ -27,46 +27,51 @@ class TestTreeCtrlPanel(wxPanel): EVT_SIZE(self, self.OnSize) self.log = log - tID = NewId() + tID = wxNewId() self.tree = MyTreeCtrl(self, tID, wxDefaultPosition, wxDefaultSize, - wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS# | wxTR_MULTIPLE + wxTR_HAS_BUTTONS + | wxTR_EDIT_LABELS + #| wxTR_MULTIPLE #| wxTR_HIDE_ROOT , self.log) + isz = (16,16) + il = wxImageList(isz[0], isz[1]) + fldridx = il.Add(wxArtProvider_GetBitmap(wxART_FOLDER, wxART_OTHER, isz)) + fldropenidx = il.Add(wxArtProvider_GetBitmap(wxART_FILE_OPEN, wxART_OTHER, isz)) + fileidx = il.Add(wxArtProvider_GetBitmap(wxART_REPORT_VIEW, wxART_OTHER, isz)) + smileidx = il.Add(images.getSmilesBitmap()) - ##import images - ##il = wxImageList(16, 16) - ##idx1 = il.Add(images.getSmilesBitmap()) - ##idx2 = il.Add(images.getOpenBitmap()) - ##idx3 = il.Add(images.getNewBitmap()) - ##idx4 = il.Add(images.getCopyBitmap()) - ##idx5 = il.Add(images.getPasteBitmap()) - - ##self.tree.SetImageList(il) - ##self.il = il + self.tree.SetImageList(il) + self.il = il # NOTE: For some reason tree items have to have a data object in # order to be sorted. Since our compare just uses the labels - # we don't need any real data, so we'll just use None. + # we don't need any real data, so we'll just use None below for + # the item data. self.root = self.tree.AddRoot("The Root Item") self.tree.SetPyData(self.root, None) - ##self.tree.SetItemImage(self.root, idx1) + self.tree.SetItemImage(self.root, fldridx, wxTreeItemIcon_Normal) + self.tree.SetItemImage(self.root, fldropenidx, wxTreeItemIcon_Expanded) + for x in range(15): child = self.tree.AppendItem(self.root, "Item %d" % x) self.tree.SetPyData(child, None) - ##self.tree.SetItemImage(child, idx2, wxTreeItemIcon_Expanded) - ##self.tree.SetItemSelectedImage(child, idx3) + self.tree.SetItemImage(child, fldridx, wxTreeItemIcon_Normal) + self.tree.SetItemImage(child, fldropenidx, wxTreeItemIcon_Expanded) for y in range(5): last = self.tree.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y))) self.tree.SetPyData(last, None) - ##self.tree.SetItemImage(last, idx4) - ##self.tree.SetItemSelectedImage(last, idx5) + self.tree.SetItemImage(last, fldridx, wxTreeItemIcon_Normal) + self.tree.SetItemImage(last, fldropenidx, wxTreeItemIcon_Expanded) for z in range(5): item = self.tree.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z)) self.tree.SetPyData(item, None) + self.tree.SetItemImage(item, fileidx, wxTreeItemIcon_Normal) + self.tree.SetItemImage(item, smileidx, wxTreeItemIcon_Selected) self.tree.Expand(self.root) EVT_TREE_ITEM_EXPANDED (self, tID, self.OnItemExpanded) @@ -105,8 +110,20 @@ class TestTreeCtrlPanel(wxPanel): if self.tree.GetItemText(event.GetItem()) == "The Root Item": wxBell() self.log.WriteText("You can't edit this one...\n") + + # Lets just see what's visible of its children + cookie = 0 + root = event.GetItem() + (child, cookie) = self.tree.GetFirstChild(root, cookie) + while child.IsOk(): + self.log.WriteText("Child [%s] visible = %d" % + (self.tree.GetItemText(child), + self.tree.IsVisible(child))) + (child, cookie) = self.tree.GetNextChild(root, cookie) + event.Veto() + def OnEndEdit(self, event): self.log.WriteText("OnEndEdit\n") # show how to reject edit, we'll not allow any digits @@ -144,7 +161,7 @@ class TestTreeCtrlPanel(wxPanel): self.log.WriteText("OnSelChanged: %s\n" % self.tree.GetItemText(self.item)) if wxPlatform == '__WXMSW__': self.log.WriteText("BoundingRect: %s\n" % - self.tree.GetBoundingRect(self.item, true)) + self.tree.GetBoundingRect(self.item, True)) #items = self.tree.GetSelections() #print map(self.tree.GetItemText, items) event.Skip() diff --git a/wxPython/demo/wxValidator.py b/wxPython/demo/wxValidator.py index 91192b2b80..fc1300229e 100644 --- a/wxPython/demo/wxValidator.py +++ b/wxPython/demo/wxValidator.py @@ -24,14 +24,14 @@ class MyValidator(wxPyValidator): if self.flag == ALPHA_ONLY: for x in val: if x not in string.letters: - return false + return False elif self.flag == DIGIT_ONLY: for x in val: if x not in string.digits: - return false + return False - return true + return True def OnChar(self, event): @@ -58,7 +58,7 @@ class MyValidator(wxPyValidator): class TestValidatorPanel(wxPanel): def __init__(self, parent): wxPanel.__init__(self, parent, -1) - self.SetAutoLayout(true) + self.SetAutoLayout(True) VSPACE = 10 fgs = wxFlexGridSizer(0, 2) @@ -130,30 +130,30 @@ class TextObjectValidator(wxPyValidator): textCtrl.SetBackgroundColour("pink") textCtrl.SetFocus() textCtrl.Refresh() - return false + return False else: textCtrl.SetBackgroundColour( wxSystemSettings_GetColour(wxSYS_COLOUR_WINDOW)) textCtrl.Refresh() - return true + return True def TransferToWindow(self): """ Transfer data from validator to window. - The default implementation returns false, indicating that an error - occurred. We simply return true, as we don't do any data transfer. + The default implementation returns False, indicating that an error + occurred. We simply return True, as we don't do any data transfer. """ - return true # Prevent wxDialog from complaining. + return True # Prevent wxDialog from complaining. def TransferFromWindow(self): """ Transfer data from window to validator. - The default implementation returns false, indicating that an error - occurred. We simply return true, as we don't do any data transfer. + The default implementation returns False, indicating that an error + occurred. We simply return True, as we don't do any data transfer. """ - return true # Prevent wxDialog from complaining. + return True # Prevent wxDialog from complaining. #---------------------------------------------------------------------- @@ -161,7 +161,7 @@ class TestValidateDialog(wxDialog): def __init__(self, parent): wxDialog.__init__(self, parent, -1, "Validated Dialog") - self.SetAutoLayout(true) + self.SetAutoLayout(True) VSPACE = 10 fgs = wxFlexGridSizer(0, 2) @@ -210,12 +210,6 @@ def runTest(frame, nb, log): - - - - - - overview = """\ wxValidator is the base class for a family of validator classes that mediate between a class of control, and application data. @@ -230,3 +224,11 @@ A validator has three major roles: Validators can be plugged into controls dynamically. """ + + + +if __name__ == '__main__': + import sys,os + import run + run.main(['', os.path.basename(sys.argv[0])]) + diff --git a/wxPython/demo/wxXmlResource.py b/wxPython/demo/wxXmlResource.py index 2d0aa94768..839a9cff1d 100644 --- a/wxPython/demo/wxXmlResource.py +++ b/wxPython/demo/wxXmlResource.py @@ -51,7 +51,7 @@ class TestPanel(wxPanel): sizer.Add(panel, 1, wxEXPAND|wxALL, 5) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) #---------------------------------------------------------------------- diff --git a/wxPython/demo/wxXmlResourceHandler.py b/wxPython/demo/wxXmlResourceHandler.py index dda5005d4e..531457c651 100644 --- a/wxPython/demo/wxXmlResourceHandler.py +++ b/wxPython/demo/wxXmlResourceHandler.py @@ -11,7 +11,7 @@ resourceText = r''' 200,100 - + 10,10 @@ -153,7 +153,7 @@ class TestPanel(wxPanel): sizer.Add(panel, 1, wxEXPAND|wxALL, 5) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) #---------------------------------------------------------------------- diff --git a/wxPython/distrib/.rpmrc b/wxPython/distrib/.rpmrc deleted file mode 100644 index 46a92a2043..0000000000 --- a/wxPython/distrib/.rpmrc +++ /dev/null @@ -1,5 +0,0 @@ -sourcedir: . -builddir: . -rpmdir: . -srcrpmdir: . - diff --git a/wxPython/distrib/README.1st.txt b/wxPython/distrib/README.1st.txt new file mode 100644 index 0000000000..4b55d30398 --- /dev/null +++ b/wxPython/distrib/README.1st.txt @@ -0,0 +1,117 @@ +README for wxPythonSrc-*.tar.gz +------------------------------- + +Prior to version 2.3.3 of wxPython I had always made my Linux/Unix +binaries based on the released binary of wxGTK and wxGTK-gl. This +imposed a few restrictions and so starting with 2.3.3 I have decided +to do a combined binary that inlcudes wxGTK as well as wxPython. This +allows me a bit more flexibility and is consistent with how the +Windows and Mac OS X binaries are built. + +If you are reading this file then you are probably interested in +building your own copy of wxPython from the sources contained in this +archive. If you wish to use the released wxGTK binary as has been +done in the past then you can still follow the old build directions in +wxPython/BUILD.unix.txt. If you are building for Windows or Mac OS X +then you should look at wxPython/BUILD.win32.txt or +wxPython/BUILD.osx.txt respectivly. + +If, on the other hand, you would like to build Linux/Unix binaries +with a private copy of wxGTK like what I am now distributing then +you'll want to follow the instructions in this file. (You should +probably still read wxPython/BUILD.unix.txt though since there are +other details there that you may need to be aware of. + +Clear as mud? Good. Let's get started. + + +1. We'll be making a private copy of wxGTK so it doesn't conflict with + one used by wxGTK C++ apps that expect to have the default binary + installed from RPM or whatever. I put it in /usr/lib/wxPython, but + you can use whatever you like. I'll just set a variable to our wx + prefix to reference later: + + export WXPREF=/usr/lib/wxPython + + +2. Make a build directory and configure wxGTK. + + cd wxPythonGTK-2.3.3 # or whatever the top-level dir is + mkdir build + cd build + ../configure --with-gtk \ + --prefix=$WXPREF \ + --enable-rpath=$WXPREF/lib \ + --with-opengl \ + --enable-geometry \ + --enable-optimise \ + --enable-debug_flag \ + + You may want to use --enable-debug instead of --enable-optimise if + you need to run though a debugger and want full debugging symbols. + + if you want to use the image and zlib libraries included with + wxWindows instead of those already installed on your system, (for + example, to reduce dependencies on 3rd party libraries) then you + can add these flags to the configure command: + + --with-libjpeg=builtin \ + --with-libpng=builtin \ + --with-libtiff=builtin \ + --with-zlib=builtin \ + + If you would like to use GTK 2.x and unicode, then add the + following flags. Please note that this is still beta-level + quality, but does look and work quite nice for the most part: + + --enable-gtk2 \ + --enable-unicode \ + + +3. Build and install wxGTK. (You may need to be root for the last + step, depending on where your WXPREF is.) + + make + cd ../build + make install + + +4. Build and install wxPython. If you want to use a different version + of Python than is found by default on the PATH then specify the + whole pathname in these steps. The version of Python that runs + setup.py is the version wxPython will be built and installed for. + (You will need to be root for the install step unless your Python + is not in a system location.) + + cd ../wxPython + python setup.py \ + WX_CONFIG=$WXPREF/bin/wx-config \ + build install + + If you are using GTK 2.x and unicode then do it this way instead: + + python setup.py \ + WX_CONFIG=$WXPREF/bin/wx-config \ + WXPORT=gtk2 UNICODE=1 \ + build install + + If you get errors about wxGLCanvas or being unable to find libGLU + or something like that then you can add BUILD_GLCANVAS=0 to the + setup.py command line to disable the building of the glcanvas + module. + + If you would like to install to someplace besides the Python + site-packages directory (such as to your home directory) then you + can add "--root=" after the "install" command. To use + wxPython like this you'll need to ensure that the directory + containing wxPyrthon is contained in in the PYTHONPATH environment + variable. + + +5. That's all, except for the having fun part! + +-- +Robin Dunn +Software Craftsman +http://wxPython.org Java give you jitters? Relax with wxPython! + diff --git a/wxPython/distrib/README.dbg.txt b/wxPython/distrib/README.dbg.txt deleted file mode 100644 index ba829d4443..0000000000 --- a/wxPython/distrib/README.dbg.txt +++ /dev/null @@ -1,30 +0,0 @@ -This zip file contains versions of the wxWindows and wxPython binaries -that have been compiled with __WXDEBUG__ defined. This adds code to -wxWindows that is a bit more agressive about checking parameter -values, return values, and etc. When the debugging library senses -something is wrong it will popup a message dialog telling you so. -Unfortunately the message is specific to the C++ code but it might -give you a hint about what went wrong and how to fix it. - -Another debugging feature is when the wxPython program exits, it will -print to stdout information about any wxWindows C++ objects that -havn't been properly cleaned up. - -This archive contains a new wxWindows DLL named wx[version]d.dll and a -debugging version of the core wxPython module, wxc_d.pyd. These -should be put into your wxPython package directory. Also included are -the debuging version of Python, python_d.exe and python[VER]_d.dll -which can be put wherever you like. - -In order to run the debugging version of wxPython sumply run you -program with python_d.exe instead of python.exe. This lets the -debugging version sit side by side with the production version, with -no need for swapping this around. You will also need _d versions of -any other extension modules you are using. If you need _d's for any -of the other standard Python extensions you can get them here, for 2.0 -at least: - -http://www.pythonlabs.com/products/python2.0/downloads/BeOpen-Python-2.0-Debug.zip - - -Robin diff --git a/wxPython/distrib/README.viewdocs.txt b/wxPython/distrib/README.viewdocs.txt new file mode 100644 index 0000000000..de7b3f7ee9 --- /dev/null +++ b/wxPython/distrib/README.viewdocs.txt @@ -0,0 +1,17 @@ +wxPythonDocs +------------ + +The wxWindows docs can now be viewed on non-Win32 platforms with a +nice viewer modeled after the MS HTMLHelp viewer. Simply execute the +viewdocs.py script located in this directory and you're all set. +(You'll need to first have wxPython installed and accessible via the +PYTHONPATH.) + +You can also add other HTML books to be displayed by the viewer simply +by dropping their .zip file here, viewdocs.py will find them +automatically and add them to the list. The zip file just needs to +contain a .hhp file that defines the contents of the book. See the +docs on wxHtmlHelpController for details. + +If you'd still ike to view these docs in your regular browser you can +simply unzip each of the books into their own directory. \ No newline at end of file diff --git a/wxPython/distrib/autobuild.py b/wxPython/distrib/autobuild.py deleted file mode 100755 index e5434e669e..0000000000 --- a/wxPython/distrib/autobuild.py +++ /dev/null @@ -1,139 +0,0 @@ - - -import sys, os, string, time -from ftplib import FTP - -cwd = os.getcwd() - -logfile = 'c:\\temp\\autobuild.log' -WXDIR = os.environ['WXWIN'] -dllVer = '23_0' -wxpVer = '2.3b1' -dateSt = time.strftime("%Y%m%d", time.localtime(time.time())) - -base = os.path.split(sys.argv[0])[0] -base = os.path.join(base, '..') -WXPYDIR = os.path.abspath(base) - -#---------------------------------------------------------------------- - -def do(cmd): - st = " " + cmd + " >> " + logfile - print st - f = open(logfile, "at") - f.write(st + '\n') - f.close() - os.system(cmd + " >>& " + logfile) - -#---------------------------------------------------------------------- - -def logTruncate(): - f = open(logfile, "wt") - f.close() - - -def logSeparator(msg=None, f=None, recurse=1): - if not f: - f = open(logfile, "at") - f.write('\n') - f.write('--' * 35) - f.write('\n') - if msg: - f.write(msg) - f.write('\n') - f.write('--' * 35) - f.write('\n') - if recurse: - logSeparator(msg, sys.stdout, 0) - -#---------------------------------------------------------------------- - -def validateFile(file): - if not os.path.exists(file): - logSeparator("***** %s does not exist, exiting! *****" % file) - raise SystemExit - else: - logSeparator("%s found, continuing..." % file, recurse=0) - - -#---------------------------------------------------------------------- - -def main(): - logTruncate() - - try: - logSeparator("Cleanup") - os.chdir(WXDIR + '/src/msw') - do('make cleandll FINAL=1') - - logSeparator("Building Documentation...") - os.chdir(WXDIR + '/src/msw') - do('make touchmanual htmlhelp') - validateFile(WXDIR + '/docs/htmlhelp/wx.chm') - - logSeparator("Building wxWindows...") - os.chdir(WXDIR + '/src/msw') - do('make dll pch FINAL=1') - validateFile(WXDIR + '/lib/wx'+dllVer+'.dll') - - - - logSeparator("Cleaning wxPython build directory...") - os.chdir(WXPYDIR) - do('b.bat c') - - logSeparator("Building wxPython...") - os.chdir(WXPYDIR + '\\src') - do("b.bat f") - validateFile(WXPYDIR+'\\wxPython\\wxc.pyd') - - - logSeparator("Building installer executable...") - os.chdir(WXPYDIR+'\\distrib') - do("autoit2 wise.aut") - srcName = WXPYDIR+'\\distrib\\wxPython-'+wxpVer+'.EXE' - destName = WXPYDIR+'\\distrib\\wxPython-'+wxpVer+'-'+dateSt+'.EXE' - validateFile(srcName) - try: - time.sleep(5) - os.rename(srcName, destName) - validateFile(destName) - except: - logSeparator("****** UNABLE TO RENAME FILE ******") - - - logSeparator("Building docs zip file...") - os.chdir(WXPYDIR) - do("distrib\\zipit.bat %s" % wxpVer) - - srcDName = WXPYDIR+'\\distrib\\wxPython-docs-'+wxpVer+'.tar.gz' - destDName = WXPYDIR+'\\distrib\\wxPython-docs-'+wxpVer+'-'+dateSt+'.tar.gz' - validateFile(srcDName) - try: - os.rename(srcDName, destDName) - except: - pass - - - - # #*#*#*#*#* Comment this out to allow upload... - #return - - logSeparator("Uploading to website...") - do('python c:\\utils\\sendwxp.py %s' % destName) - #do('python c:\\utils\\sendwxp.py %s' % destDName) - - - logSeparator("Finished!!!") - - finally: - os.system("list " + logfile) - pass - - - - - - -if __name__ == '__main__': - main() diff --git a/wxPython/distrib/genfilelist.py b/wxPython/distrib/genfilelist.py new file mode 100644 index 0000000000..20760b36d9 --- /dev/null +++ b/wxPython/distrib/genfilelist.py @@ -0,0 +1,51 @@ +""" +Walk a directory tree and output a filename list suitable for use +in an RPM spec. + +Usage: genfilelist.py [-r] build_root filespec(s) + +""" + + +import sys, os, glob, stat + + +def walktree(names, buildroot, recurse): + for name in names: + isdir = os.path.isdir(name) + printfilename(name, buildroot, isdir) + if isdir and recurse: + walktree([os.path.join(name, x) for x in os.listdir(name)], buildroot, recurse) + + +def printfilename(name, buildroot, isdir): + s = os.lstat(name) + realname = name[len(buildroot):] + if isdir: + fmt = "%%dir %%attr(%o, root, root) %s" + else: + fmt = "%%attr(%o, root, root) %s" + print fmt % (s[stat.ST_MODE] & 0777, realname) + + +def main(args): + if args[0] == '-r': + recurse = 1 + args = args[1:] + else: + recurse = 0 + + if len(args) < 2: + print __str__ + sys.exit(1) + + buildroot = args[0] + for arg in args[1:]: + if arg[0] == '/': + arg = arg[1:] + walktree(glob.glob(os.path.join(buildroot, arg)), buildroot, recurse) + +if __name__ == "__main__": + main(sys.argv[1:]) + + diff --git a/wxPython/distrib/mac/.cvsignore b/wxPython/distrib/mac/.cvsignore new file mode 100644 index 0000000000..e43b0f9889 --- /dev/null +++ b/wxPython/distrib/mac/.cvsignore @@ -0,0 +1 @@ +.DS_Store diff --git a/wxPython/distrib/mac/MacPython/.cvsignore b/wxPython/distrib/mac/MacPython/.cvsignore new file mode 100644 index 0000000000..e43b0f9889 --- /dev/null +++ b/wxPython/distrib/mac/MacPython/.cvsignore @@ -0,0 +1 @@ +.DS_Store diff --git a/wxPython/distrib/mac/MacPython/README.txt b/wxPython/distrib/mac/MacPython/README.txt new file mode 100644 index 0000000000..89ecd2b9b4 --- /dev/null +++ b/wxPython/distrib/mac/MacPython/README.txt @@ -0,0 +1,3 @@ +This is a set of build scripts and such for MacPython-OSX 2.3 that I +will use until there are standard distributions from Jack. + diff --git a/wxPython/distrib/mac/MacPython/build b/wxPython/distrib/mac/MacPython/build new file mode 100755 index 0000000000..f684d4363c --- /dev/null +++ b/wxPython/distrib/mac/MacPython/build @@ -0,0 +1,129 @@ +#!/bin/sh -e +#---------------------------------------------------------------------- +# Build MacPython 2.3 and make an Installer package of it + +# TODO: Parameterize the versions, builddirs, etc... + +# Script configs +PYVERSION=2.3a2 +PYVER=2.3 +BUILDNUM=3 +DOCLEANUP=no + +PROGDIR="`dirname \"$0\"`" +TMPDIR=/tmp/_py +#TMPDIR=/projects/_py + +BUILDROOT=$TMPDIR/build +INSTALLROOT=$TMPDIR/install +DMGDIR=$TMPDIR/dmg +RESOURCEDIR=$PROGDIR/resources +DESTDIR=/projects/wx/wxPython/dist +PYTHONSRC=/projects/Python-$PYVERSION +WASTEDIR=/projects/waste + +# Setup +mkdir -p $BUILDROOT +mkdir -p $INSTALLROOT +rm -rf $DMGDIR +mkdir -p $DMGDIR/root + + +# Configure and build Python +pushd $BUILDROOT + +# Check if we should build and install the docs, but only if it +# doesn't appear to be done already. TODO: fix this path to be version independent +if [ ! -e "build/temp.darwin-6.3-Power Macintosh-2.3/build-html/build-html idx" ]; then + read -p "Build the Python docs? (y/N)? " builddocs +fi + +# If the filesystem is case-sensitive then "python" will be built, but +# some parts of the install expect "python.exe which is what is built +# on a case-insensitive filesystem. Make a link just in case it is +# needed. +if [ ! -e python.exe ]; then + ln -s python python.exe +fi + +# Make a link to the waste dir so that lib can be found. This allows +# the PythonIDE to be built +if [ ! -e waste ]; then + ln -s $WASTEDIR waste +fi + +$PYTHONSRC/configure --enable-framework=$INSTALLROOT/Library/Frameworks LDFLAGS=-Wl,-x +make +make frameworkinstall + +if [ "$builddocs" = "y" -o "$builddocs" = "Y" ]; then + ./python.exe $PYTHONSRC/Mac/OSX/setupDocs.py build + echo "" + read -p "When the help indexer is done press Enter..." ans + ./python.exe $PYTHONSRC/Mac/OSX/setupDocs.py install \ + --prefix=$INSTALLROOT/Library/Frameworks/Python.framework/Versions/$PYVER +fi + +popd + + + +# Make the Installer package: +# First, remove the unix tools as their paths will be wrong. We'll recreate +# them in the postinstall. +rm -r $INSTALLROOT/usr + +# Next, remove the .pyc/.pyo files +python $PROGDIR/../zappycfiles.py $INSTALLROOT/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER + +# Make the welcome message +cat > $RESOURCEDIR/Welcome.txt < $TOOLDIR/pythonw <&2 - echo usage: `basename $0` '[-s dir] [-d dir] [--cvs-update] [--force] [--debug]' 1>&2 - exit 1 -} - -quotemeta() { - # probably not quite correct, but seems to work - echo "$1" | sed -e 's/\([^a-zA-z0-9.,--;_/]\)/\\\1/g' -} - -msg() -{ - echo "---------------------------------------------" - echo $@ -} - -msgdo() { - echo "--> " $@ - $@ -} - - -user=$1 -shift - -update= -force= -debug= -srcPath= -dstPath= - -while :; do - case "$1" in - --cvs-update) update=1;; - --force) force=1;; - --debug) debug=1;; - -s) shift; srcPath="$1";; - -d) shift; dstPath="$1";; - -*) usage "bad argument $1";; - *) break;; - esac - shift -done - - -#----------------------------------- -msg check and prepare build directories - -if ! test "$srcPath"; then - srcPath=$defSrcPath -fi -if ! test -d "$srcPath"; then - echo "no such directory: '$srcPath'" 1>&2 - exit -fi - -if ! test "$dstPath"; then - dstPath=$defDstPath -fi -if ! test -d "$dstPath"; then - msgdo mkdir -p -m 775 "$dstPath" - msgdo chown ${user}:staff "$dstPath" -fi - -temp="tmp$$" -if test -e "$dstPath/$temp"; then - msgdo rm -rf "$dstPath/$temp" -fi -msgdo mkdir -m 775 "$dstPath/$temp" - -if test -e "$dstPath/$temp/$pkgRoot"; then - msgdo rm -rf "$dstPath/$temp/$pkgRoot" -fi -msgdo mkdir -m 1775 "$dstPath/$temp/$pkgRoot" -msgdo chown root:admin "$dstPath/$temp/$pkgRoot" - -if test -e "$dstPath/$temp/$dmgRoot"; then - msgdo rm -rf "$dstPath/$temp/$dmgRoot" -fi -msgdo mkdir -p -m 775 "$dstPath/$temp/$dmgRoot" -msgdo chown $user:staff "$dstPath/$temp/$dmgRoot" - - -#----------------------------------- -# update cvs -if [ $update ]; then - msg Updating from CVS - msgdo cd "$srcPath" - msgdo cvs update -dP -A -fi - - -#----------------------------------- -msg configuring wxWindows - -buildDir="$srcPath/build-pkg" -dFlag="--enable-debug_flag --enable-optimise" -if [ $debug ]; then - buildDir="$srcPath/build-pkg-debug" - dFlag="--enable-debug" -fi -if ! test -e "$buildDir"; then - force=1 -fi -if [ $force ]; then - if test -e "$buildDir"; then - rm -rf "$buildDir" - fi - msgdo mkdir -m 775 "$buildDir" - msgdo cd "$buildDir" - msgdo ../configure --with-mac --with-opengl --enable-precomp=no $dFlag - cd $curDir - -else - echo wxWindows already configured -fi - - -#----------------------------------- -msg building wxWindows -msgdo cd $buildDir -msgdo make -msgdo cd ../locale -msgdo make allmo -cd $curDir - - -#----------------------------------- -msg installing wxWindows -msgdo mkdir -p -m 1755 "$dstPath/$temp/$wxWindowsInst" -msgdo cd "$buildDir" - -# install once to the package directory, and once to the -# local machine so the wxPython build will get the right wxMac -msgdo make install "prefix=`quotemeta \"$dstPath/$temp/$wxWindowsInst\"`" -msgdo make install - -msgdo chown -R root:wheel "$dstPath/$temp/$pkgRoot/usr" -cd $curDir - - -#----------------------------------- -msg building wxPython -if [ $force ]; then - fFlag="--force" -else - fFlag= -fi -if [ $debug ]; then - dFlag="--debug" - wxpBuildDir="build-pkg-debug" -else - dFlag= - wxpBuildDir="build-pkg" -fi -bbFlag="BUILD_BASE=$wxpBuildDir" - -msgdo cd "$srcPath/wxPython" -msgdo $pythonExec setup.py build 'IN_CVS_TREE=1' $bbFlag $fFlag $dFlag -cd $curDir - - -#----------------------------------- -msg installing wxPython -msgdo mkdir -p -m 775 "$dstPath/$temp/$wxPythonInst" -msgdo cd "$srcPath/wxPython" -msgdo $pythonExec setup.py install $bbFlag --install-lib="$dstPath/$temp/$wxPythonInst" -cd $curDir - -msgdo chown -R root:admin "$dstPath/$temp/$pkgRoot/Library" -msgdo chmod -R g+w "$dstPath/$temp/$pkgRoot/Library" - - -#----------------------------------- -msg copying additional wxPython files -msgdo cp -pR "$srcPath/wxPython/samples" "$dstPath/$temp/$dmgRoot" -msgdo cp -pR "$srcPath/wxPython/demo" "$dstPath/$temp/$dmgRoot" -msgdo cp -pR "$srcPath/wxPython/licence" "$dstPath/$temp/$dmgRoot" -find "$dstPath/$temp/$dmgRoot" -name "CVS" -type d -print0 | xargs -0 rm -rf -find "$dstPath/$temp/$dmgRoot" -name ".DS_Store" -type f -print0 | xargs -0 rm -find "$dstPath/$temp/$dmgRoot" -name ".cvsignore" -type f -print0 | xargs -0 rm -find "$dstPath/$temp/$dmgRoot" -name ".#*" -type f -print0 | xargs -0 rm -find "$dstPath/$temp/$dmgRoot" -name "b" -type f -print0 | xargs -0 rm -find "$dstPath/$temp/$dmgRoot" -name "*~*~" -type f -print0 | xargs -0 rm - -msgdo cd "$srcPath/wxPython/scripts" -sFiles=`$pythonExec CreateMacScripts.py` -for f in $sFiles; do - msgdo cp $f "$dstPath/$temp/$wxWindowsInst/bin" -done -cd $curDir - -msgdo chown -R ${user}:staff "$dstPath/$temp/$dmgRoot" - - -#----------------------------------- -msg making installer package -msgdo cp -pR "$progDir/resources" "$dstPath/$temp" -msgdo cp $progDir/$pkgName.info $progDir/$pkgName-$version.info -if [ $debug ]; then - echo "__WXDEBUG__ version." >> "$dstPath/$temp/resources/Welcome.txt" - echo "" >> "$dstPath/$temp/resources/Welcome.txt" -fi -echo "Build date: `date`" >> "$dstPath/$temp/resources/Welcome.txt" -msgdo cd "$progDir" -msgdo "$makePkgExec" $dstPath/$temp/$pkgRoot $pkgName-$version.info -d $dstPath/$temp/$dmgRoot -r $dstPath/$temp/resources -msgdo chown -R ${user}:staff $dstPath/$temp/$dmgRoot/$pkgName-$version.pkg -cd $curDir - - -#----------------------------------- -msg making disk image -msgdo cd "$progDir" -msgdo "$makeDmgExec" $dstPath/$temp/$dmgRoot $dstPath/$temp $pkgName-$version -if [ $debug ]; then - dmgName="$pkgName-$version-debug" -else - dmgName="$pkgName-$version" -fi -msgdo mv "$dstPath/$temp/$pkgName-$version.dmg" "$dstPath/$dmgName.dmg" -msgdo chown ${user}:staff "$dstPath/$dmgName.dmg" -cd $curDir - - -#----------------------------------- -msg cleaning up -msgdo chown -R ${user}:staff "$buildDir" -msgdo chown -R ${user}:staff "$srcPath/wxPython/$wxpBuildDir" -msgdo rm $progDir/$pkgName-$version.info -msgdo rm -rf "$dstPath/$temp" diff --git a/wxPython/distrib/mac/_buildPython b/wxPython/distrib/mac/_buildPython deleted file mode 100755 index 57774d1bb6..0000000000 --- a/wxPython/distrib/mac/_buildPython +++ /dev/null @@ -1,162 +0,0 @@ -#!/bin/sh -e -# -# Create a MachoPython package from the currently installed verison -# and put it on a disk image -# - - -PYVER=2.2 - -curDir=`pwd` -progDir="`dirname \"$0\"`" - -defDstPath="/projects/wx/wxPython/dist" - -pkgName="MachoPython" -version=2.2.1-4 -dmgRoot="dmg-root" -pkgRoot="pkg-root" -sitePkgDir="$pkgRoot/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/site-packages" - -pythonExec="python$PYVER" -makePkgExec="./makepkg" -makeDmgExec="./makedmg" - - -usage() { - echo `basename $0`: ERROR: $* 1>&2 - echo usage: `basename $0` '[-d dir]' 1>&2 - exit 1 -} - -quotemeta() { - # probably not quite correct, but seems to work - echo "$1" | sed -e 's/\([^a-zA-z0-9.,--;_/]\)/\\\1/g' -} - -msg() -{ - echo "---------------------------------------------" - echo $@ -} - -msgdo() { - echo "--> " $@ - $@ -} - - -user=$1 -shift - -dstPath= - -while :; do - case "$1" in - -d) shift; dstPath="$1";; - -*) usage "bad argument $1";; - *) break;; - esac - shift -done - - -#----------------------------------- -msg check and prepare build directories - -if ! test "$dstPath"; then - dstPath=$defDstPath -fi -if ! test -d "$dstPath"; then - msgdo mkdir -p -m 775 "$dstPath" - msgdo chown ${user}:staff "$dstPath" -fi - -temp="tmp$$" -if test -e "$dstPath/$temp"; then - msgdo rm -rf "$dstPath/$temp" -fi -msgdo mkdir -m 775 "$dstPath/$temp" - -if test -e "$dstPath/$temp/$pkgRoot"; then - msgdo rm -rf "$dstPath/$temp/$pkgRoot" -fi -msgdo mkdir -m 1775 "$dstPath/$temp/$pkgRoot" -msgdo chown root:admin "$dstPath/$temp/$pkgRoot" - -if test -e "$dstPath/$temp/$dmgRoot"; then - msgdo rm -rf "$dstPath/$temp/$dmgRoot" -fi -msgdo mkdir -p -m 775 "$dstPath/$temp/$dmgRoot" -msgdo chown $user:staff "$dstPath/$temp/$dmgRoot" - -#----------------------------------- -msg Copying files to package build dir - -for d in Applications/Python.app Library/Frameworks/Python.framework; do - msgdo mkdir -p -m 755 $dstPath/$temp/$pkgRoot/$d - msgdo cp -pR /$d/* $dstPath/$temp/$pkgRoot/$d -done - -msgdo mkdir -p -m 755 $dstPath/$temp/$pkgRoot/usr/local/bin -msgdo cd $dstPath/$temp/$pkgRoot/usr/local/bin -for f in pydoc python python$PYVER; do - msgdo ln -s ../../../Library/Frameworks/Python.framework/Versions/Current/bin/$f . -done - -cat > pythonw <) + +""" + + +__all__ = ["BundleBuilder", "BundleBuilderError", "AppBuilder", "buildapp"] + + +import sys +import os, errno, shutil +import imp, marshal +import re +from copy import deepcopy +import getopt +from plistlib import Plist +from types import FunctionType as function + +class BundleBuilderError(Exception): pass + + +class Defaults: + + """Class attributes that don't start with an underscore and are + not functions or classmethods are (deep)copied to self.__dict__. + This allows for mutable default values. + """ + + def __init__(self, **kwargs): + defaults = self._getDefaults() + defaults.update(kwargs) + self.__dict__.update(defaults) + + def _getDefaults(cls): + defaults = {} + for name, value in cls.__dict__.items(): + if name[0] != "_" and not isinstance(value, + (function, classmethod)): + defaults[name] = deepcopy(value) + for base in cls.__bases__: + if hasattr(base, "_getDefaults"): + defaults.update(base._getDefaults()) + return defaults + _getDefaults = classmethod(_getDefaults) + + +class BundleBuilder(Defaults): + + """BundleBuilder is a barebones class for assembling bundles. It + knows nothing about executables or icons, it only copies files + and creates the PkgInfo and Info.plist files. + """ + + # (Note that Defaults.__init__ (deep)copies these values to + # instance variables. Mutable defaults are therefore safe.) + + # Name of the bundle, with or without extension. + name = None + + # The property list ("plist") + plist = Plist(CFBundleDevelopmentRegion = "English", + CFBundleInfoDictionaryVersion = "6.0") + + # The type of the bundle. + type = "BNDL" + # The creator code of the bundle. + creator = None + + # List of files that have to be copied to /Contents/Resources. + resources = [] + + # List of (src, dest) tuples; dest should be a path relative to the bundle + # (eg. "Contents/Resources/MyStuff/SomeFile.ext). + files = [] + + # List of shared libraries (dylibs, Frameworks) to bundle with the app + # will be placed in Contents/Frameworks + libs = [] + + # Directory where the bundle will be assembled. + builddir = "build" + + # Make symlinks instead copying files. This is handy during debugging, but + # makes the bundle non-distributable. + symlink = 0 + + # Verbosity level. + verbosity = 1 + + def setup(self): + # XXX rethink self.name munging, this is brittle. + self.name, ext = os.path.splitext(self.name) + if not ext: + ext = ".bundle" + bundleextension = ext + # misc (derived) attributes + self.bundlepath = pathjoin(self.builddir, self.name + bundleextension) + + plist = self.plist + plist.CFBundleName = self.name + plist.CFBundlePackageType = self.type + if self.creator is None: + if hasattr(plist, "CFBundleSignature"): + self.creator = plist.CFBundleSignature + else: + self.creator = "????" + plist.CFBundleSignature = self.creator + if not hasattr(plist, "CFBundleIdentifier"): + plist.CFBundleIdentifier = self.name + + def build(self): + """Build the bundle.""" + builddir = self.builddir + if builddir and not os.path.exists(builddir): + os.mkdir(builddir) + self.message("Building %s" % repr(self.bundlepath), 1) + if os.path.exists(self.bundlepath): + shutil.rmtree(self.bundlepath) + os.mkdir(self.bundlepath) + self.preProcess() + self._copyFiles() + self._addMetaFiles() + self.postProcess() + self.message("Done.", 1) + + def preProcess(self): + """Hook for subclasses.""" + pass + def postProcess(self): + """Hook for subclasses.""" + pass + + def _addMetaFiles(self): + contents = pathjoin(self.bundlepath, "Contents") + makedirs(contents) + # + # Write Contents/PkgInfo + assert len(self.type) == len(self.creator) == 4, \ + "type and creator must be 4-byte strings." + pkginfo = pathjoin(contents, "PkgInfo") + f = open(pkginfo, "wb") + f.write(self.type + self.creator) + f.close() + # + # Write Contents/Info.plist + infoplist = pathjoin(contents, "Info.plist") + self.plist.write(infoplist) + + def _copyFiles(self): + files = self.files[:] + for path in self.resources: + files.append((path, pathjoin("Contents", "Resources", + os.path.basename(path)))) + for path in self.libs: + files.append((path, pathjoin("Contents", "Frameworks", + os.path.basename(path)))) + if self.symlink: + self.message("Making symbolic links", 1) + msg = "Making symlink from" + else: + self.message("Copying files", 1) + msg = "Copying" + files.sort() + for src, dst in files: + if os.path.isdir(src): + self.message("%s %s/ to %s/" % (msg, src, dst), 2) + else: + self.message("%s %s to %s" % (msg, src, dst), 2) + dst = pathjoin(self.bundlepath, dst) + if self.symlink: + symlink(src, dst, mkdirs=1) + else: + copy(src, dst, mkdirs=1) + + def message(self, msg, level=0): + if level <= self.verbosity: + indent = "" + if level > 1: + indent = (level - 1) * " " + sys.stderr.write(indent + msg + "\n") + + def report(self): + # XXX something decent + pass + + +if __debug__: + PYC_EXT = ".pyc" +else: + PYC_EXT = ".pyo" + +MAGIC = imp.get_magic() +USE_ZIPIMPORT = "zipimport" in sys.builtin_module_names + +# For standalone apps, we have our own minimal site.py. We don't need +# all the cruft of the real site.py. +SITE_PY = """\ +import sys +del sys.path[1:] # sys.path[0] is Contents/Resources/ +""" + +if USE_ZIPIMPORT: + ZIP_ARCHIVE = "Modules.zip" + SITE_PY += "sys.path.append(sys.path[0] + '/%s')\n" % ZIP_ARCHIVE + def getPycData(fullname, code, ispkg): + if ispkg: + fullname += ".__init__" + path = fullname.replace(".", os.sep) + PYC_EXT + return path, MAGIC + '\0\0\0\0' + marshal.dumps(code) + +SITE_CO = compile(SITE_PY, "<-bundlebuilder.py->", "exec") + +# +# Extension modules can't be in the modules zip archive, so a placeholder +# is added instead, that loads the extension from a specified location. +# +EXT_LOADER = """\ +def __load(): + import imp, sys, os + for p in sys.path: + path = os.path.join(p, "%(filename)s") + if os.path.exists(path): + break + else: + assert 0, "file not found: %(filename)s" + mod = imp.load_dynamic("%(name)s", path) + +__load() +del __load +""" + +MAYMISS_MODULES = ['mac', 'os2', 'nt', 'ntpath', 'dos', 'dospath', + 'win32api', 'ce', '_winreg', 'nturl2path', 'sitecustomize', + 'org.python.core', 'riscos', 'riscosenviron', 'riscospath' +] + +STRIP_EXEC = "/usr/bin/strip" + +# +# We're using a stock interpreter to run the app, yet we need +# a way to pass the Python main program to the interpreter. The +# bootstrapping script fires up the interpreter with the right +# arguments. os.execve() is used as OSX doesn't like us to +# start a real new process. Also, the executable name must match +# the CFBundleExecutable value in the Info.plist, so we lie +# deliberately with argv[0]. The actual Python executable is +# passed in an environment variable so we can "repair" +# sys.executable later. +# +BOOTSTRAP_SCRIPT = """\ +#!%(hashbang)s + +import sys, os +execdir = os.path.dirname(sys.argv[0]) +executable = os.path.join(execdir, "%(executable)s") +resdir = os.path.join(os.path.dirname(execdir), "Resources") +libdir = os.path.join(os.path.dirname(execdir), "Frameworks") +mainprogram = os.path.join(resdir, "%(mainprogram)s") + +sys.argv.insert(1, mainprogram) +os.environ["PYTHONPATH"] = resdir +%(pythonhome)s +os.environ["PYTHONEXECUTABLE"] = executable +os.environ["DYLD_LIBRARY_PATH"] = libdir +os.execve(executable, sys.argv, os.environ) +""" + + +# +# Optional wrapper that converts "dropped files" into sys.argv values. +# +ARGV_EMULATOR = """\ +import argvemulator, os + +argvemulator.ArgvCollector().mainloop() +execfile(os.path.join(os.path.split(__file__)[0], "%(realmainprogram)s")) +""" + + +class AppBuilder(BundleBuilder): + + # Override type of the bundle. + type = "APPL" + + # platform, name of the subfolder of Contents that contains the executable. + platform = "MacOS" + + # A Python main program. If this argument is given, the main + # executable in the bundle will be a small wrapper that invokes + # the main program. (XXX Discuss why.) + mainprogram = None + + # The main executable. If a Python main program is specified + # the executable will be copied to Resources and be invoked + # by the wrapper program mentioned above. Otherwise it will + # simply be used as the main executable. + executable = None + + # The name of the main nib, for Cocoa apps. *Must* be specified + # when building a Cocoa app. + nibname = None + + # The name of the icon file to be copied to Resources and used for + # the Finder icon. + iconfile = None + + # Symlink the executable instead of copying it. + symlink_exec = 0 + + # If True, build standalone app. + standalone = 0 + + # If True, add a real main program that emulates sys.argv before calling + # mainprogram + argv_emulation = 0 + + # The following attributes are only used when building a standalone app. + + # Exclude these modules. + excludeModules = [] + + # Include these modules. + includeModules = [] + + # Include these packages. + includePackages = [] + + # Strip binaries. + strip = 0 + + # Found Python modules: [(name, codeobject, ispkg), ...] + pymodules = [] + + # Modules that modulefinder couldn't find: + missingModules = [] + maybeMissingModules = [] + + # List of all binaries (executables or shared libs), for stripping purposes + binaries = [] + + def setup(self): + if self.standalone and self.mainprogram is None: + raise BundleBuilderError, ("must specify 'mainprogram' when " + "building a standalone application.") + if self.mainprogram is None and self.executable is None: + raise BundleBuilderError, ("must specify either or both of " + "'executable' and 'mainprogram'") + + self.execdir = pathjoin("Contents", self.platform) + + if self.name is not None: + pass + elif self.mainprogram is not None: + self.name = os.path.splitext(os.path.basename(self.mainprogram))[0] + elif executable is not None: + self.name = os.path.splitext(os.path.basename(self.executable))[0] + if self.name[-4:] != ".app": + self.name += ".app" + + if self.executable is None: + if not self.standalone: + self.symlink_exec = 1 + self.executable = sys.executable + + if self.nibname: + self.plist.NSMainNibFile = self.nibname + if not hasattr(self.plist, "NSPrincipalClass"): + self.plist.NSPrincipalClass = "NSApplication" + + BundleBuilder.setup(self) + + self.plist.CFBundleExecutable = self.name + + if self.standalone: + self.findDependencies() + + def preProcess(self): + resdir = "Contents/Resources" + if self.executable is not None: + if self.mainprogram is None: + execname = self.name + else: + execname = os.path.basename(self.executable) + execpath = pathjoin(self.execdir, execname) + if not self.symlink_exec: + self.files.append((self.executable, execpath)) + self.binaries.append(execpath) + self.execpath = execpath + + if self.mainprogram is not None: + mainprogram = os.path.basename(self.mainprogram) + self.files.append((self.mainprogram, pathjoin(resdir, mainprogram))) + if self.argv_emulation: + # Change the main program, and create the helper main program (which + # does argv collection and then calls the real main). + # Also update the included modules (if we're creating a standalone + # program) and the plist + realmainprogram = mainprogram + mainprogram = '__argvemulator_' + mainprogram + resdirpath = pathjoin(self.bundlepath, resdir) + mainprogrampath = pathjoin(resdirpath, mainprogram) + makedirs(resdirpath) + open(mainprogrampath, "w").write(ARGV_EMULATOR % locals()) + if self.standalone: + self.includeModules.append("argvemulator") + self.includeModules.append("os") + if not self.plist.has_key("CFBundleDocumentTypes"): + self.plist["CFBundleDocumentTypes"] = [ + { "CFBundleTypeOSTypes" : [ + "****", + "fold", + "disk"], + "CFBundleTypeRole": "Viewer"}] + # Write bootstrap script + executable = os.path.basename(self.executable) + execdir = pathjoin(self.bundlepath, self.execdir) + bootstrappath = pathjoin(execdir, self.name) + makedirs(execdir) + if self.standalone: + # XXX we're screwed when the end user has deleted + # /usr/bin/python + hashbang = "/usr/bin/python" + pythonhome = 'os.environ["PYTHONHOME"] = resdir' + else: + hashbang = sys.executable + while os.path.islink(hashbang): + hashbang = os.readlink(hashbang) + pythonhome = '' + open(bootstrappath, "w").write(BOOTSTRAP_SCRIPT % locals()) + os.chmod(bootstrappath, 0775) + + if self.iconfile is not None: + iconbase = os.path.basename(self.iconfile) + self.plist.CFBundleIconFile = iconbase + self.files.append((self.iconfile, pathjoin(resdir, iconbase))) + + def postProcess(self): + if self.standalone: + self.addPythonModules() + if self.strip and not self.symlink: + self.stripBinaries() + + if self.symlink_exec and self.executable: + self.message("Symlinking executable %s to %s" % (self.executable, + self.execpath), 2) + dst = pathjoin(self.bundlepath, self.execpath) + makedirs(os.path.dirname(dst)) + os.symlink(os.path.abspath(self.executable), dst) + + if self.missingModules or self.maybeMissingModules: + self.reportMissing() + + def addPythonModules(self): + self.message("Adding Python modules", 1) + + if USE_ZIPIMPORT: + # Create a zip file containing all modules as pyc. + import zipfile + relpath = pathjoin("Contents", "Resources", ZIP_ARCHIVE) + abspath = pathjoin(self.bundlepath, relpath) + zf = zipfile.ZipFile(abspath, "w", zipfile.ZIP_DEFLATED) + for name, code, ispkg in self.pymodules: + self.message("Adding Python module %s" % name, 2) + path, pyc = getPycData(name, code, ispkg) + zf.writestr(path, pyc) + zf.close() + # add site.pyc + sitepath = pathjoin(self.bundlepath, "Contents", "Resources", + "site" + PYC_EXT) + writePyc(SITE_CO, sitepath) + else: + # Create individual .pyc files. + for name, code, ispkg in self.pymodules: + if ispkg: + name += ".__init__" + path = name.split(".") + path = pathjoin("Contents", "Resources", *path) + PYC_EXT + + if ispkg: + self.message("Adding Python package %s" % path, 2) + else: + self.message("Adding Python module %s" % path, 2) + + abspath = pathjoin(self.bundlepath, path) + makedirs(os.path.dirname(abspath)) + writePyc(code, abspath) + + def stripBinaries(self): + if not os.path.exists(STRIP_EXEC): + self.message("Error: can't strip binaries: no strip program at " + "%s" % STRIP_EXEC, 0) + else: + self.message("Stripping binaries", 1) + for relpath in self.binaries: + self.message("Stripping %s" % relpath, 2) + abspath = pathjoin(self.bundlepath, relpath) + assert not os.path.islink(abspath) + rv = os.system("%s -S \"%s\"" % (STRIP_EXEC, abspath)) + + def findDependencies(self): + self.message("Finding module dependencies", 1) + import modulefinder + mf = modulefinder.ModuleFinder(excludes=self.excludeModules) + if USE_ZIPIMPORT: + # zipimport imports zlib, must add it manually + mf.import_hook("zlib") + # manually add our own site.py + site = mf.add_module("site") + site.__code__ = SITE_CO + mf.scan_code(SITE_CO, site) + + # warnings.py gets imported implicitly from C + mf.import_hook("warnings") + + includeModules = self.includeModules[:] + for name in self.includePackages: + includeModules.extend(findPackageContents(name).keys()) + for name in includeModules: + try: + mf.import_hook(name) + except ImportError: + self.missingModules.append(name) + + mf.run_script(self.mainprogram) + modules = mf.modules.items() + modules.sort() + for name, mod in modules: + if mod.__file__ and mod.__code__ is None: + # C extension + path = mod.__file__ + filename = os.path.basename(path) + if USE_ZIPIMPORT: + # Python modules are stored in a Zip archive, but put + # extensions in Contents/Resources/.a and add a tiny "loader" + # program in the Zip archive. Due to Thomas Heller. + dstpath = pathjoin("Contents", "Resources", filename) + source = EXT_LOADER % {"name": name, "filename": filename} + code = compile(source, "" % name, "exec") + mod.__code__ = code + else: + # just copy the file + dstpath = name.split(".")[:-1] + [filename] + dstpath = pathjoin("Contents", "Resources", *dstpath) + self.files.append((path, dstpath)) + self.binaries.append(dstpath) + if mod.__code__ is not None: + ispkg = mod.__path__ is not None + if not USE_ZIPIMPORT or name != "site": + # Our site.py is doing the bootstrapping, so we must + # include a real .pyc file if USE_ZIPIMPORT is True. + self.pymodules.append((name, mod.__code__, ispkg)) + + if hasattr(mf, "any_missing_maybe"): + missing, maybe = mf.any_missing_maybe() + else: + missing = mf.any_missing() + maybe = [] + self.missingModules.extend(missing) + self.maybeMissingModules.extend(maybe) + + def reportMissing(self): + missing = [name for name in self.missingModules + if name not in MAYMISS_MODULES] + if self.maybeMissingModules: + maybe = self.maybeMissingModules + else: + maybe = [name for name in missing if "." in name] + missing = [name for name in missing if "." not in name] + missing.sort() + maybe.sort() + if maybe: + self.message("Warning: couldn't find the following submodules:", 1) + self.message(" (Note that these could be false alarms -- " + "it's not always", 1) + self.message(" possible to distinguish between \"from package " + "import submodule\" ", 1) + self.message(" and \"from package import name\")", 1) + for name in maybe: + self.message(" ? " + name, 1) + if missing: + self.message("Warning: couldn't find the following modules:", 1) + for name in missing: + self.message(" ? " + name, 1) + + def report(self): + # XXX something decent + import pprint + pprint.pprint(self.__dict__) + if self.standalone: + self.reportMissing() + +# +# Utilities. +# + +SUFFIXES = [_suf for _suf, _mode, _tp in imp.get_suffixes()] +identifierRE = re.compile(r"[_a-zA-z][_a-zA-Z0-9]*$") + +def findPackageContents(name, searchpath=None): + head = name.split(".")[-1] + if identifierRE.match(head) is None: + return {} + try: + fp, path, (ext, mode, tp) = imp.find_module(head, searchpath) + except ImportError: + return {} + modules = {name: None} + if tp == imp.PKG_DIRECTORY and path: + files = os.listdir(path) + for sub in files: + sub, ext = os.path.splitext(sub) + fullname = name + "." + sub + if sub != "__init__" and fullname not in modules: + modules.update(findPackageContents(fullname, [path])) + return modules + +def writePyc(code, path): + f = open(path, "wb") + f.write(MAGIC) + f.write("\0" * 4) # don't bother about a time stamp + marshal.dump(code, f) + f.close() + +def copy(src, dst, mkdirs=0): + """Copy a file or a directory.""" + if mkdirs: + makedirs(os.path.dirname(dst)) + if os.path.isdir(src): + shutil.copytree(src, dst) + else: + shutil.copy2(src, dst) + +def copytodir(src, dstdir): + """Copy a file or a directory to an existing directory.""" + dst = pathjoin(dstdir, os.path.basename(src)) + copy(src, dst) + +def makedirs(dir): + """Make all directories leading up to 'dir' including the leaf + directory. Don't moan if any path element already exists.""" + try: + os.makedirs(dir) + except OSError, why: + if why.errno != errno.EEXIST: + raise + +def symlink(src, dst, mkdirs=0): + """Copy a file or a directory.""" + if not os.path.exists(src): + raise IOError, "No such file or directory: '%s'" % src + if mkdirs: + makedirs(os.path.dirname(dst)) + os.symlink(os.path.abspath(src), dst) + +def pathjoin(*args): + """Safe wrapper for os.path.join: asserts that all but the first + argument are relative paths.""" + for seg in args[1:]: + assert seg[0] != "/" + return os.path.join(*args) + + +cmdline_doc = """\ +Usage: + python bundlebuilder.py [options] command + python mybuildscript.py [options] command + +Commands: + build build the application + report print a report + +Options: + -b, --builddir=DIR the build directory; defaults to "build" + -n, --name=NAME application name + -r, --resource=FILE extra file or folder to be copied to Resources + -f, --file=SRC:DST extra file or folder to be copied into the bundle; + DST must be a path relative to the bundle root + -e, --executable=FILE the executable to be used + -m, --mainprogram=FILE the Python main program + -a, --argv add a wrapper main program to create sys.argv + -p, --plist=FILE .plist file (default: generate one) + --nib=NAME main nib name + -c, --creator=CCCC 4-char creator code (default: '????') + --iconfile=FILE filename of the icon (an .icns file) to be used + as the Finder icon + -l, --link symlink files/folder instead of copying them + --link-exec symlink the executable instead of copying it + --standalone build a standalone application, which is fully + independent of a Python installation + --lib=FILE shared library or framework to be copied into + the bundle + -x, --exclude=MODULE exclude module (with --standalone) + -i, --include=MODULE include module (with --standalone) + --package=PACKAGE include a whole package (with --standalone) + --strip strip binaries (remove debug info) + -v, --verbose increase verbosity level + -q, --quiet decrease verbosity level + -h, --help print this message +""" + +def usage(msg=None): + if msg: + print msg + print cmdline_doc + sys.exit(1) + +def main(builder=None): + if builder is None: + builder = AppBuilder(verbosity=1) + + shortopts = "b:n:r:f:e:m:c:p:lx:i:hvqa" + longopts = ("builddir=", "name=", "resource=", "file=", "executable=", + "mainprogram=", "creator=", "nib=", "plist=", "link", + "link-exec", "help", "verbose", "quiet", "argv", "standalone", + "exclude=", "include=", "package=", "strip", "iconfile=", + "lib=") + + try: + options, args = getopt.getopt(sys.argv[1:], shortopts, longopts) + except getopt.error: + usage() + + for opt, arg in options: + if opt in ('-b', '--builddir'): + builder.builddir = arg + elif opt in ('-n', '--name'): + builder.name = arg + elif opt in ('-r', '--resource'): + builder.resources.append(arg) + elif opt in ('-f', '--file'): + srcdst = arg.split(':') + if len(srcdst) != 2: + usage("-f or --file argument must be two paths, " + "separated by a colon") + builder.files.append(srcdst) + elif opt in ('-e', '--executable'): + builder.executable = arg + elif opt in ('-m', '--mainprogram'): + builder.mainprogram = arg + elif opt in ('-a', '--argv'): + builder.argv_emulation = 1 + elif opt in ('-c', '--creator'): + builder.creator = arg + elif opt == '--iconfile': + builder.iconfile = arg + elif opt == "--lib": + builder.libs.append(arg) + elif opt == "--nib": + builder.nibname = arg + elif opt in ('-p', '--plist'): + builder.plist = Plist.fromFile(arg) + elif opt in ('-l', '--link'): + builder.symlink = 1 + elif opt == '--link-exec': + builder.symlink_exec = 1 + elif opt in ('-h', '--help'): + usage() + elif opt in ('-v', '--verbose'): + builder.verbosity += 1 + elif opt in ('-q', '--quiet'): + builder.verbosity -= 1 + elif opt == '--standalone': + builder.standalone = 1 + elif opt in ('-x', '--exclude'): + builder.excludeModules.append(arg) + elif opt in ('-i', '--include'): + builder.includeModules.append(arg) + elif opt == '--package': + builder.includePackages.append(arg) + elif opt == '--strip': + builder.strip = 1 + + if len(args) != 1: + usage("Must specify one command ('build', 'report' or 'help')") + command = args[0] + + if command == "build": + builder.setup() + builder.build() + elif command == "report": + builder.setup() + builder.report() + elif command == "help": + usage() + else: + usage("Unknown command '%s'" % command) + + +def buildapp(**kwargs): + builder = AppBuilder(**kwargs) + main(builder) + + +if __name__ == "__main__": + main() diff --git a/wxPython/distrib/mac/makepkg b/wxPython/distrib/mac/makepkg deleted file mode 100755 index 97cbd89e9f..0000000000 --- a/wxPython/distrib/mac/makepkg +++ /dev/null @@ -1,283 +0,0 @@ -#! /bin/csh -ef -# -# original script by Chris Roberts (The OS X Package Manager) -# slightly modified by Frank Vercruesse (mainly fixed quoting issues) - -set prog = `/usr/bin/basename $0` -set usage = "Usage: $prog [-f] root-dir info-file [tiff-file] [-d dest-dir] [-r resource-dir] [-traditional | -gnutar]" -set noglob - -if (-x /usr/bin/mkbom) then - set mkbom=/usr/bin/mkbom - set lsbom=/usr/bin/lsbom -else - set mkbom=/usr/etc/mkbom - set lsbom=/usr/etc/lsbom -endif - -if (-x /usr/bin/awk) then - set awk=/usr/bin/awk -else - set awk=/bin/awk -endif - -set gnutar=/usr/bin/gnutar -set tar=/usr/bin/tar -set pax=/bin/pax - -# gather parameters -if ($#argv == 0) then - echo $usage - exit(1) -endif - -while ( $#argv > 0 ) - switch ( "$argv[1]" ) - case -d: - if ( $?destDir ) then - echo ${prog}: dest-dir parameter already set to ${destDir}. - echo $usage - exit(1) - else if ( $#argv < 2 ) then - echo ${prog}: -d option requires destination directory. - echo $usage - exit(1) - else - set destDir = "$argv[2]" - shift; shift - breaksw - endif - case -f: - if ( $?rootDir ) then - echo ${prog}: root-dir parameter already set to ${rootDir}. - echo $usage - exit(1) - else if ( $#argv < 2 ) then - echo ${prog}: -f option requires package root directory. - echo $usage - exit(1) - else - set rootDir = "$argv[2]" - set fflag - shift; shift - breaksw - endif - case -r: - if ( $?resDir ) then - echo ${prog}: resource-dir parameter already set to ${resDir}. - echo $usage - exit(1) - else if ( $#argv < 2 ) then - echo ${prog}: -r option requires package resource directory. - echo $usage - exit(1) - else - set resDir = "$argv[2]" - shift; shift - breaksw - endif - case -traditional: - set usetar - unset usegnutar - unset usepax - shift - breaksw - case -gnutar: - set usegnutar - unset usepax - unset usetar - shift - breaksw - case -B: - # We got long file names, better use bigtar instead - #set archiver = /NextAdmin/Installer.app/Resources/installer_bigtar - #echo 2>&1 ${prog}: -B flag is longer relevant. - shift - breaksw - case -*: - echo ${prog}: Unknown option: $argv[1] - echo $usage - exit(1) - case *.info: - if ( $?info ) then - echo ${prog}: info-file parameter already set to ${info}. - echo $usage - exit(1) - else - set info = "$argv[1]" - shift - breaksw - endif - case *.tiff: - if ( $?tiff ) then - echo ${prog}: tiff-file parameter already set to ${tiff}. - echo $usage - exit(1) - else - set tiff = "$argv[1]" - shift - breaksw - endif - default: - if ( $?rootDir ) then - echo ${prog}: unrecognized parameter: $argv[1] - echo $usage - exit(1) - else - set rootDir = "$argv[1]" - shift - breaksw - endif - endsw -end - -# check for mandatory parameters -if ( ! $?rootDir ) then - echo ${prog}: missing root-dir parameter. - echo $usage - exit(1) -else if ( ! $?info) then - echo ${prog}: missing info-file parameter. - echo $usage - exit(1) -endif - -# destDir gets default value if unset on command line -if ( $?destDir ) then - /bin/mkdir -p "$destDir" -else - set destDir = . -endif - -# derive the root name for the package from the root name of the info file -set root = `/usr/bin/basename $info .info` - -# create package directory -set pkg = "${destDir}/${root}.pkg" -echo Generating Installer package $pkg ... -if ( -e "$pkg" ) /bin/rm -rf "$pkg" -/bin/mkdir -p -m 755 "$pkg" -/bin/mkdir -p -m 755 "$pkg/Contents" -/bin/mkdir -p -m 755 "$pkg/Contents/Resources" -/bin/mkdir -p -m 755 "$pkg/Contents/Resources/English.lproj/" -echo -n "pmkrpkg1" >"$pkg/Contents/PkgInfo" -chmod 755 "$pkg/Contents/PkgInfo" -# (gnu)tar/pax and compress root directory to package archive -echo -n " creating package archive ... " -if ( $?fflag ) then - set pkgTop = "${rootDir:t}" - set parent = "${rootDir:h}" - if ( "$parent" == "$pkgTop" ) set parent = "." -else - set parent = "$rootDir" - set pkgTop = . -endif -if ( $?usetar ) then - set pkgArchive = "$pkg/Contents/Resources/$root.tar.Z" - (cd "$parent"; $tar -w "$pkgTop") | /usr/bin/tar -f -c > "$pkgArchive" -else if ( $?usegnutar ) then - set pkgArchive = "$pkg/Contents/Resources/$root.tar.gz" - (cd "$parent"; $gnutar zcf "$pkgArchive" "$pkgTop") -else - set pkgArchive = "$pkg/Contents/Resources/$root.pax.gz" - (cd "$parent"; $pax -w -z -x cpio "$pkgTop") > "$pkgArchive" -endif -/bin/chmod 755 "$pkgArchive" -echo done. - -# copy info file to package -set pkgInfo = "$pkg/Contents/Resources/English.lproj/$root.info" -echo -n " copying ${info:t} ... " -/bin/cp $info "$pkgInfo" -/bin/chmod 755 "$pkgInfo" -echo done. - -# copy tiff file to package -if ( $?tiff ) then - set pkgTiff = "$pkg/$root.tiff" - echo -n " copying ${tiff:t} ... " - /bin/cp $tiff "$pkgTiff" - /bin/chmod 444 "$pkgTiff" - echo done. -endif - -# copy resources to package -if ( $?resDir ) then - echo -n " copying ${resDir:t} ... " - - # don't want to see push/pop output - pushd "$resDir" > /dev/null - # get lists of resources. We'll want to change - # permissions on just these things later. - set directoriesInResDir = `find . -type d` - set filesInResDir = `find . -type f` - popd > /dev/null - - # copy the resource directory contents into the package directory - foreach resFile (`ls "$resDir"`) - cp -r "$resDir/$resFile" "$pkg/Contents/Resources" - end - - pushd "$pkg/Contents/Resources" > /dev/null - # Change all directories to +r+x, except the package - # directory itself - foreach resFileItem ($directoriesInResDir) - if ( "$resFileItem" != "." ) then - chmod 755 $resFileItem - endif - end - # change all flat files to read only - foreach resFileItem ($filesInResDir) - if ( "$resFileItem" != "./.DS_Store" ) then - chmod 755 $resFileItem - endif - end - popd > /dev/null - - echo done. -endif - -# generate bom file -set pkgBom = "$pkg/Contents/Resources/$root.bom" -echo -n " generating bom file ... " -/bin/rm -f "$pkgBom" -if ( $?fflag ) then - $mkbom "$parent" "$pkgBom" >& /dev/null -else - $mkbom "$rootDir" "$pkgBom" >& /dev/null -endif -/bin/chmod 444 "$pkgArchive" -echo done. - -# generate sizes file -set pkgSizes = "$pkg/Contents/Resources/$root.sizes" -echo -n " generating sizes file ... " - -# compute number of files in package -set numFiles = `$lsbom -s "$pkgBom" | /usr/bin/wc -l` - -# compute package size when compressed -@ compressedSize = `/usr/bin/du -k -s "$pkg" | $awk '{print $1}'` -@ compressedSize += 3 # add 1KB each for sizes, location, status files - -@ infoSize = `/bin/ls -s "$pkgInfo" | $awk '{print $1}'` -@ bomSize = `/bin/ls -s "$pkgBom" | $awk '{print $1}'` -if ( $?tiff ) then - @ tiffSize = `/bin/ls -s "$pkgTiff" | $awk '{print $1}'` -else - @ tiffSize = 0 -endif - -@ installedSize = `/usr/bin/du -k -s "$rootDir" | $awk '{print $1}'` -@ installedSize += $infoSize + $bomSize + $tiffSize + 3 - -# echo size parameters to sizes file -echo NumFiles $numFiles > "$pkgSizes" -echo InstalledSize $installedSize >> "$pkgSizes" -echo CompressedSize $compressedSize >> "$pkgSizes" -echo done. -echo " ... finished generating $pkg." - -exit(0) - -# end package diff --git a/wxPython/distrib/mac/resources/Welcome.txt b/wxPython/distrib/mac/resources/Welcome.txt deleted file mode 100644 index e981f01c24..0000000000 --- a/wxPython/distrib/mac/resources/Welcome.txt +++ /dev/null @@ -1,2 +0,0 @@ -You will be guided through the steps necessary to install wxPython 2.3.3pre (including wxMac) for MachoPython 2.2.x on Mac OS X 10.1 or later. - diff --git a/wxPython/distrib/mac/resources/preflight b/wxPython/distrib/mac/resources/preflight deleted file mode 100755 index bdb5d0110f..0000000000 --- a/wxPython/distrib/mac/resources/preflight +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -/usr/bin/sudo -u $USER /bin/rm -rf \ - $2/Library/Frameworks/Python.framework/Versions/2.2/lib/python2.2/site-packages/wxPython \ - -# $2/usr/local/bin/wx* \ -# $2/usr/local/include/wx \ -# $2/usr/local/lib/wx \ -# $2/usr/local/lib/libwx* - -exit 0 diff --git a/wxPython/distrib/mac/resourcesPython/License.rtf b/wxPython/distrib/mac/resourcesPython/License.rtf deleted file mode 100644 index 99731771f4..0000000000 --- a/wxPython/distrib/mac/resourcesPython/License.rtf +++ /dev/null @@ -1,25 +0,0 @@ -{\rtf1\mac\ansicpg10000\cocoartf100 -{\fonttbl\f0\fnil\fcharset77 Monaco;} -{\colortbl;\red255\green255\blue255;} -\margl1440\margr1440\vieww15640\viewh10560\viewkind0 -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f0\fs24 \cf0 PSF LICENSE AGREEMENT FOR PYTHON 2.2.1\ ---------------------------------------\ -\ -1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 2.2.1 software in source or binary form and its associated documentation.\ -\ -2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 2.2.1 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002 Python Software Foundation; All Rights Reserved" are retained in Python 2.2.1 alone or in any derivative version prepared by Licensee.\ -\ -3. In the event Licensee prepares a derivative work that is based on or incorporates Python 2.2.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 2.2.1.\ -\ -4. PSF is making Python 2.2.1 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.2.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\ -\ -5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.2.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.2.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\ -\ -6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.\ -\ -7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.\ -\ -8. By copying, installing or otherwise using Python 2.2.1, Licensee agrees to be bound by the terms and conditions of this License Agreement.\ -} \ No newline at end of file diff --git a/wxPython/distrib/mac/resourcesPython/ReadMe.rtf b/wxPython/distrib/mac/resourcesPython/ReadMe.rtf deleted file mode 100644 index 4e9c27c25d..0000000000 --- a/wxPython/distrib/mac/resourcesPython/ReadMe.rtf +++ /dev/null @@ -1,91 +0,0 @@ -{\rtf1\mac\ansicpg10000\cocoartf100 -{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fnil\fcharset77 Monaco; -} -{\colortbl;\red255\green255\blue255;\red0\green0\blue255;} -\margl1440\margr1440\vieww10820\viewh9000\viewkind0 -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f0\b\fs24 \cf0 About\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f1\b0 \cf0 \ -This is a Mach-O binary package of Python 2.2.1 (a.k.a. MachoPython) for Mac OS X 10.1 or later. \ -\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f0\b \cf0 What files will be installed and where?\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f1\b0 \cf0 \ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f2 \cf0 /Applications\ -\ - + Python.app -\fs20 (a double-clickable interpreter)\ -\ - -\fs24 /Library/Frameworks\ -\ - + Python.framework -\fs20 (library, headers, tools, etc.)\ -\ - -\fs24 /usr/local/bin\ - \ - + pydoc -\fs20 (symbolic link to the pydoc script) -\fs24 \ - + python -\fs20 (symbolic link to the actual binary inside the framework)\ - -\fs24 + python2.2 -\fs20 (symbolic link to the actual binary inside the framework)\ - -\fs24 + pythonw -\fs20 (a script that can run a GUI app from the command line)\ - -\f1\fs24 \ -\ -\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f0\b \cf0 Getting started with Python -\f1\b0 \ -\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f2 \cf2 http://www.python.org\cf0 \ -\cf2 \ - http://www.python.org/sigs/pythonmac-sig\cf0 \ -\cf2 \ - http://www.cwi.nl/~jack/macpython.html -\f1 \cf0 \ -\ -\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f0\b \cf0 Credits\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f1\b0 \cf0 \ -Python itself is\ -\ -Copyright (c) 2001, 2002 Python Software Foundation; All Rights Reserved\ -\ -This binary package was compiled using the build instructions from Jack Jansen and Tony Lownds as found on the net.\ -\ -\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f0\b \cf0 Disclaimer -\f1\b0 \ -\ -\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural - -\f2 \cf0 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -\f1 \ -\ -\ -Packaged by Robin Dunn\ -} \ No newline at end of file diff --git a/wxPython/distrib/mac/resourcesPython/Welcome.txt b/wxPython/distrib/mac/resourcesPython/Welcome.txt deleted file mode 100644 index 77b3eca84e..0000000000 --- a/wxPython/distrib/mac/resourcesPython/Welcome.txt +++ /dev/null @@ -1,2 +0,0 @@ -Mach-O Python 2.2.1 binary package for Mac OS X 10.1 or later. - diff --git a/wxPython/distrib/mac/wxPythonOSX.info b/wxPython/distrib/mac/wxPythonOSX.info deleted file mode 100644 index 662b153096..0000000000 --- a/wxPython/distrib/mac/wxPythonOSX.info +++ /dev/null @@ -1,15 +0,0 @@ -Title wxPythonOSX -Version 2.3.3 -Description wxMac and wxPython for OSX -DefaultLocation / -DeleteWarning - -### Package Flags - -NeedsAuthorization YES -Required NO -Relocatable NO -RequiresReboot NO -UseUserMask NO -OverwritePermissions NO -InstallFat NO diff --git a/wxPython/distrib/mac/wxPythonOSX/.cvsignore b/wxPython/distrib/mac/wxPythonOSX/.cvsignore new file mode 100644 index 0000000000..e43b0f9889 --- /dev/null +++ b/wxPython/distrib/mac/wxPythonOSX/.cvsignore @@ -0,0 +1 @@ +.DS_Store diff --git a/wxPython/distrib/mac/wxPythonOSX/PieShell.icns b/wxPython/distrib/mac/wxPythonOSX/PieShell.icns new file mode 100644 index 0000000000000000000000000000000000000000..afc8c3f5c3bd4b2d328bf97c4bf75c1c71df28f8 GIT binary patch literal 55621 zcmeFacX(UZl`jfXltjw3RqWW4SdL`JPU2YdyovnB{oZ@uy_uQZ?>dR&Se0^-dy_2} zbxI_~1F(q{yGiw^D-uQ0B$@ycfCzvT8-ylQq8Uv9Nudc%C<5?)2c&JeWis#0-0yue z1Cj@)?7i07Yp=cbI%}=Hx%sV+w^Jw+|MPeM{QS=-l$?CZ_k9YMQz+-!C^<`>CGz$^ zvAke8?Kew)_vrGui}IdbUfJBXAUAjU<1Y{oEFyll{PD*r`wJ+o&n{}EJU)-|yNw0U z=AD|ersFr1jtvB5$t4OU?>FCv;fL=ni%}?<3}sFxBb=YfSeIoof&Y=o#PE0LU;0DY z82Pslbx_|5I0R)``iF7h$>z7VJVT-6em@`nYR&I^SXfwi*X^8ZOCJ@9dWEyMaHW(y zvh?AlGdBvCh{a+h`76rapi7qGvwZ0zOIIvKjoe%%p5U`$#S*f>wWTW_$rccauaN~r zE0^HmHBsSG5q;?j3cgHBuc7)<(X~e&&Y@7GOGMWmy@nFFBYp(WS1etcgDX_Iw&D>A z1+d9S*Op#ev{bZ$LgAwTc?*A{YhnsTVw!ypq>u6`lzWvZNb0RtOb8;fz3oMeqqF~k23saqg`OLy+3Z8j-RY3v13h=#ZY9$^&16m+O_^d$rl?(8&pdi0s1&ZY34`iSK zi6XKR6&I}{ACvX-^Yed^kG4ERwuS^Sf8|1y#KZiR`33oN$S<6r0ND^ce_~-46oBF} z>Ss%>K>39rItw2Z19E;r!OwxZAQyE}5`>_UcuoQ8RpbNQ$}ji@K+nl9$X$_}j}~R0 z$7ie0$-*Y9MoP3;Q1@@M^Xt2UcF7ikH)hFaF?VJ2LK}Lui6-o zlFunC5(&_NUL%RipF@6wx@R^ein5O>kyue8zG?;9M&igPp*+2+h+4GiiJ9jV%I$bj zJiaQvdeus_W#y_>8#isD7A0n&XUjx36rseg@s}t{lq3>GC7U*U)xX&i(c7`2c+o2; zRlbBJ&Svqr)&^yy0{OZiQ~$3WaX@{k|J!i+)0{x7|!< zGVzHo3}1kP;BB8j5DZ0v0piv}(>F{8liq2>^J%@s_=R;UfNI`bMDXE&*YEWO0xqLL zYrUS%q`W4x+3ND#3f{UEpay?(E9eab175GqsIkdonbd8)+w4GHU?;-!B0&_3go)t2 zQzotJ+MP@$#lB&`5u^qvL28&1B_dD8!l7{RrpfG(0r{PS*8*;TFc=Bl!e1~FiN|h7 zLZPt7RMgb$Kku&1EJ<62E*@@gIe56CxvlxYfu_&(cN#K<>CpB5&(EE?#1V{}qwSfz zG#ZWHkxV92mANOK^iAJ%-n_}!PfFLV0_uSsRs zRjTU>#psnj4*fEVab=RoJQd~eJ9`;D{4tqKu28Df8m(5Nlk?b2R*zr|4f}#~xu=JI zMJkucq=fSSl3!P8RBF{V0gKVy$AUQA=;QVBQIN_Q36QedhjjCTi}g+5YaE zZ@>2D8=q_^PF=O$*`Imn&Yf}ETQ5HM+#mn=!kYD~UwY-GO>b{G{^_|t zJ->GChN2fYtXsWiUC~Rgyj41$tjrYXH^2M)=hm!W_tMM6YlW}8w6SRY+O=y|zxe6d zFctDV^~TG;|6ebx+pzJ~_lPaO`S63cU)i{B-I^CxZ`yJ)j^0Zjd3){i&u>__@r})& zY~8W5xU_8V?sqn>d!cCkn)gT1fWX!*>x$N{-uUUxPe0vJyoW|qEUW#j{PlHf);|As z3!aaE@aEd0HJi6?+qrYc?&9KdDnTQt50t&VX7wLm-*P9DmTY-%!%MGi-MPECj9UDE z@7-HYpg`HyO>2Mu`rFaWovHVBytrx0&Yi_2)UuM2(&FMhL`B8^=Ehy?{_xi8iA*N> z;f^<7-?n=<>Xi{CE6YktN~@}BTaVRkD0+Q2g!fL#+gsoLu(-H%Z}C0?omX1EZ(rG- zy%nFn^zNI7shNV4@4vZYYjH_wX$iIT-m-mY-0oe)yEni4`f3(6GuO1^qYpkPCQ9?m z_U8-V7k#9qWfpaPy7`^=KiXDOwr9`YeS6Ewit%*!YwKTqi-?ih z>h#uady2R1_^7gk*jKr4->w}yi(c9I^6NX45UrS?c+W1PWZ#EdKiT=o`|rH?O3@qd zyz%aCdAd6Dfc3N8yUQyN?A^U%>*gJA@A%;3Ejtfdpso^Xb}Mz?-qJnb#_kMG^G_WALqro-nt#G2q|8A`eWy*85B^4~uC@c(C)FhqU!^F7AKmyf>u{$`Oc@811= zSBblCe|`RCfv@j;>ujdLw{G5jnJsYljc=cm1-^an?(6>y&;JSovi$oOpZ{Qind(2t z!>=FX>~5}S&%g0BdvSM>?>_wxdS~-n@54is`|Q7_dHKIV>6|AX$1(TW{ii6DCm&z) z0)_J1)=C;B=gCJOTSv)j{p|y_zsddW;(vUMl2`j|-fv$h_)Q+|$>mEPXwJ|5P2QQu z{_*kV#rXw!EzjmtDgTteeD0FR_dojVqW#2j+M+g69fFP-q!>j4i_< z6I+HuCbkTROl%nrnbDBF?+aB_|0dy zD-w&YldiYBALPJU_wdpcE0!)1i|Aihfv0W7QvRbNu^8?sztnky#vtOGONkQY3|MEmx$ZiL5aKTUc__aWp1q~;S1w%+CmrdSobely&Op*l_%K;M_a4%9iSjwP17GA) zuxUjv>AB4M8W%0k`VL7S;nF1}q4z8&v5K#Oo|)o>0Ia}$vTE)kk{%K|T#C}AWP|U0 z7*~t%M}$MO9v?) z7$tC!ngk|+(QN#N#9iYXB|szP8^7f-Ei6P~sp%Vq0chqU{PN^K-#7FSJiG<@|M^<} z|GmXIln8$RCODBC_$=XXCY{bJ^H=cRz@|2?$jkdEGG0D0llE8*ZKD?GCR9&ykGxB2|9pw6DGAl=wc zFMJxsNtjPBEFc}i@N#E;=mjgI-ykXnU{*cz47|=OQ8N2Y79}gp)InqJ@|s3SKX}$5 z59c;cN#8eo?<*HBfOnll0kn711lT0>tW%uyEYCX2Nz$JtJ>hV;la2V2q!ple0oX$N z(6gnp&SlbhOcDrpJ6z^u%d`G%w3l>dufp9$Gah`>g$@@u4lDBUg$jT~GGmrYIjczb z`=adqEG2*pnn>3<4)9VxJzIP>0`OG9DiS&x2G=!!&p5gZeon$)nVa=!;~9|5INT}o z$uI;cA_E2_$t3s{D2t0ARD~MVj=tN>HLCcie}5-F4?qd72xKsL^DZ}XXuy>He{O* z-mThHG%KQ!4Tu3`=i{^pRa%o0deK=F-5)J?PT5wcRw1~SA^1i{0zYzQZx z#DbbD^D)qhHUWC#D|?Epv7snYw4rFzhE*{VV1B{VWXK1_G3+)K(Mo8W5~N9c*XJoz z0FolqLVvHs_(v402!#_M1&7#|js3DtdUq!=@6FlG}HwlDojqo<^REfm^^) zv|&T+*SDYetA)R+9*I&S-)`Yo5C7}rKQ0G0zfVTE?&FXze;sh+rtc)fiKssjj-`ln z&YkqJ%;LDmW0*2KT}FrAte={?8BHF{Je;}{cHFR-5bpW{KUSyN?snd=+uiuS5( z=uOiQ^|NW622gLgal`KR-ntbI`vZul-5>A;{r)Mt*<{fp8lf@TCCM}u1ncc~qv;Ei z%Vn|O3!kZJgMGM~V_aH*&@dbiDH{yyDT8mYd zqGs}(DyLzBu;#i$A!=}r-%FN#!s{WM==B5wx4!toq|unIGQ?$4Nte!HGNX?@HxaKx z46!o!&$q$>584^J>G8R&rU|wE#z>Sb8q|1hm~D2CA3;SjBpF6X4{_#;t%4s1ZjDN2!rHWN9LDUmT1K`NM9rQRi|DB0!aYr&Bt0 z!{!czskiP4+zN)G2q%Vb#}Hb~iN}f1f=J-@q{;ln4a*3c_>;tEy?Vdf;SC3apaMX{ zQJ@E>Q8reHs2`}iX`Hw*IXFto%ugR9hJ3-mO(HlKMG%uD!Z~F05s;~odk}aG-f}yp zTtjDt6`6b<(R59H%j*kOMsmVoYJ?i6#E1wH%)fQhG37CwYEsbgWcWFA$D~ zt0O28Uqr?#!+_<#Ib|O>UDX<@$Sg>WRhL)(#q4q1^b(PIw-L{bMPgKxjorCJqV?UB ziQD&3Psb}W_a_;&it4kYmK)Pk;XouDLsT?Ii{BSX+`i=v2W(1C^{(;*#_G(^Z(rD7 zT~~X2MCb7OT(M{*7RGNh>JQ(FL?*2EuEw&Gvi(<5)tM*K(ZAH!G#+ZM>ivA^i%IW< z|JE0G;;x$s`xjp2;DtlGc9d7tbR}yukEO=j8k?FwYi~Yu@)Bos9HD8Me2mveKiFDb zQ&n0KuXO>Mdn;Q-^A3S-i`(#U9E48ka)>2o}LZepKR#(*?)gp5KNZN6#x%J?o zBPZJq9qBs$*#W>jP+whLRbA7>^rc%eKTb|4SjP{xH#M~!X{&E+{;aLBzOJG1{1x|| zgPHqN$?5UW&m3%PZ9dp`^4ul1P#Z}78C<-R47qRI4kYiS+7Y}U)mbK^$R00dh;;s) zJE0iVS}+E!mP#E%#5L(KUy%$9T@?&p85_}Q4T(GLnWd>a3BO)4C=m8@*jxl$`>zaM z9TX3b=v;yHj9zmN33z=y9T&Sgx_Y`h==94x4u{9(imwQCAyTh-xcvUldpa+4b@dYL zoXeL9Mqy76<1&NY&l3s~O(9z3e(J%M)4+w=K(G>xY$KhV)FbL*+2BS|n?7ow(gl-F66$&n& z>g-~&E_3?@;;Un$qgRJS!hS@6c}zBw!T7w3cXhya2f8iE>tbIzbFQn0!Mc2zkD}LP zGO6^MbX3gi>u0hrGZ;NgM*o$en|CTQPfjp+Jr_DUdoFX>eFG!o5{XoK9l>G6HKlYI zOuEdW_aK0KS;R@AuvpCR?CSZP!(sEp5~%_)WTjHAQjw8jjao9;&t~^rzTEpcUu4Jl z2y~BfE_Krx%r4%DlqQ>}P%2SDLueO5S*k}7nnoPEyMJgnMP%;1qrWU-_I%z;XADSW zGOCm!rz(FWm!mvlts0GdT!1h)y^AgGNfMbQDIG&d@9FKO_m858QYn`zvc;949ONsd z(h)9~-QC3+qTi-w7MawxZ~;oz3-}2NhlV`8P58h&t=E6BFh!_GK==mrd%oWaDAxRYBj7417b-TPeRz(t-H3UQg)m#U0!ea(KhS z!$K7QQThapA-sB341XOcR-w2`eI3#89KD{Zp(^tgf-B>L#~R0=mJ8DSiki;u@oO?w zr6xzMrfLX%&cp-=Cgb*!!BO$&)J9EK#eG&@^=IxCiCm>s(=>T%^s^3SwOT?$mX%8+ z1Anfe9n7k^@%`nrKXZo$B~n5|)jovje!_qlydGVmxURT1@|WY(y;bL+|JmMcrHy7%&z-NTsIFQIR>3G#%AKVZUnMYHu-o^v9 z4WAuqI`dgwO+zVl+n(C$-3{gYXys)U`wwYS>Bh`b=c$IK&ptbN3@YwqW8?mYrq-I; ziV9jqWeY2->EfDe^dq0OHq`=|5){Pmgq$)qYY!{doJ! zr4<)Dn3Ksi=(M}v#%mvcvSnvkRrin~(U^HGok@E}O5T5C z)1Q9#hd=)Qx#!ocE-L!drq^HF^zv(OzqR$8HJwV=WeVddP4R25t$pE-zkmMu7pUtf z>xtF(J^!cG>sG(~+Nwf?H=aE{lZtcbm8(w<3X#KjiFRWd+ zy6DA?uWWjM`{%Ay4QwOJhabN8hu{5S^}6+I@L&`5)%h>K{Nju2i`K2Du9?4j^&2}s z8A~D=;g@M&<$JHa_|JcQe%<;F8((_mwKv~+`|USge|6JFq$Rw#X5E_AtN-}B*FM}S zPFG|Wr(=89zx3Sy{9n(%uy*~14KKg;-bcj8#7FmU+5E=K8&P)M3#(;GayXKFtebSD?g}lw%UtLpFw5I68 zPe0j8-I23vH&HyNoS>EywEN0wGy;LfVs~^6JqIXh;clUg}@uf|hKP7f8EZ$R2Ei2u#x3shv)sTcyQCQX7 zShxTE_0Rq8_4nS4gOKRkuas?i@r`ZUcW&Q-TnTDf8MTyJytuTqqPn8GwdLSBYSEh2 zZ@#`MM$J5w*t2oZdoR8DDPZj`*;ig(TDGSI18g6)l&C7Kfst^Yx?%l`Z*HuEDg2W- z_3c-;zWv7L?Zw5&T_`Rtqm}R3O{QFwmlOL6k(hyujSq`n-TdL|&Wg+f2R{CA>z*C& zZ6gb#bQuk)7ki1)obqyNDXn<^dz-er`TG|KV7=#G-v0I*FYVp2b8ls7P6^UC^2*Ei z?b$=@x(9u;d)vG3ezfsVJ0umEdnT(t`ry;e@9#hcM+s3{P_lO~aPQlP0iP|p^V2Qw z{O+aqXg4trrbhOB`tE!0zVX4<9Vk;)ylYo+>At;tkh?*i?%uQO+VJYfZP0f2 z#?Np2@Pqd^f3)S(Ps{e~qwe`p*}f7K-Meeoj$J!ScA{5b+w@+sj8t}i-ulV59Xt0F zZ`rnG%l;}fg+@cJN!hMFWyNbYzPj60(pYEm=zf}uTcb2}pd;1%W z_1m^rzq9e}^>4n80ki4tPmjc4)ZMwdZ#$T{Zx6BOy^pqkvc2M+*WZ0>!}_-Lk3pgZDrB=)+HU)Qmt|JQCM6 z?JeC`POT{|r#6=D-BDapwtdGZpM3nu)~XI)x+(K;Iu(%%Pu39o_UztMvUB^c-6bVE z@m1X1<-!Z){i&Ese7=Q-q#9~@U42XEW$9$ru8V~{Hj{rcbo=(*y6*jKTFQU9@Bf`0 z6IuKD?!#ZhcXzqF&%d|M-37jL{yjCmQ|22tzFpxP55Mo?n-#vV#JBI=RpZ-_zW@5G z3g7?uyLV?ReD}c*-I=NILr=eZ|G&zAmnV1M`OnFp@1{K6&6B&%XXW#Ia-{Ambl2&> zviw)Y|2717702maXn)}Jo8|wd3g0T7z5D^d%3MVV;ysp$W^ zsM_Z3WLPFAaVnFazU`lyob=v`;~gYy!^$C(al&MBCy2~rKBLa=Mo{90#i(~gGbxMF zI(Z9@@qiZ#gBJgcIq;_Y3!Hj=>W$I!~;2`)1kgSRrNE8TQ~gj`@E zy~1QjGPgLr0y!3xD6!x~0MAyE%^sJ_)oOBqiGs;Yr~fRtrY2NB*Xp&`$FFpyGb2qr z8J2HM=v0cndI6~9*PrORGB$dptG)CHNu|B}@Mj0AYO5QwR3;rt#l&=$%7T==@A#o3 z-B+jZ-gl3oeEsvQ*JHuL8^;4g=A+R~e^~e8TkpL2^7=JvciYp+-D}ru`f%$mybQjz zc1>;O#`_!I+JTqeGQ5Dl@%-C&VjsV{ZFhNT$==e+hPt)yrqX*p++MP`4B7i7#XH_8 z&t$HAxMgSQp3+jh$Gx?w2V^pK7vo)f*OvEQeXS;h5RCCeb$KzdEw_Yo8_Z0a$40N; zxI@ou&%W9GZ6n~z$zou+F~q3BDTvseGBug!0LL~1r@1Eh-* z`M+F~xBS_Hycd4Cpqacwe&$>6)@T1?R+ph3smb0aOU!->v)@RIe3aBZ$c7Y&AEx9& zFCm3bSSS+ZAggdW@(iynhDM|Cpt+VJb+1rr63nFJeLL$j3l4Zl+D5Y%-#K8h?$`H7 zC6P^_$*$g=Pp0NT6=7Lxc9|_S6q(0>+ze7zWmlxmCV-Hc5YR+WGSEx-h3ol0iX$uvBQsYEn_6ItfzB(Bm4i&CX?dQ5ty-e9yC)ds6c zhj^z^sne+({z$+Ri6v68U?P=3jkr^5@l2U)dZ)`b>C#Uk2I+fOD zvfHhCvoQ>E)56Su2aTz8CK*qYO$w+-C0J|evYT9p3QxJG+>=v|DYs+VGd($Fx48^9 z*Q5`Ctrn}^}CYXEr?)GdYqG!4y+pWPCLzJjoR!F##5<^G%NE{upsQVT1NCrquuUsxa+ub0lf_~%IVSBclg*;GTJ+PY zL?i@wKTRd$0XZD@_G!1p?Dd#T1}%amDy>p6E>lY7gz8uD_>U>E&=t#DK?@e(Au6uY z8Feb7+wO8&fdTDTP5R^U^rg&d^g6oOual^C&dDk7Gu`4B1D>!x&VJwEF4c5)E3jU*XgtwO;${r z20+uJ!C2R4G*OL(2EEy;Cle5~Kt<>uF{;&COs&X40B@~klLM&=V1vW0HJeQyD!?wo znoY@htwU=;NMEnkk?93GtbsIuYp7^6(=7jhFgdu5J_fNSy&gbSTCmq>u^Nn4v(aib z8?fBhHf43#j8bDL5lf%WJdh^Y;6oflYjQelcD+`mLC{A($AHuas%44UV7A&ILKchF z4lX(zRy|?r^F8?(lV^vTQ;08g0|ZmYrJ zw%g4HwL-0<8s=hYuij{(+U8n~7OZ0?EV)*zgX)^=w42NpGtKlU*p3sU4GWcZdW%M@ zRv7eZtzKjGxGV;#Eu2ms&(P9~f~HQX!C})|O=g``saEQ#=DDC2t);s19a-3*n{ZNH zgp&ZiIaZU&NZ6Nx^D}^TYK2y#&?zDCMyuOl5?NCjYWh&-p%li%ltQbNs7-!{70dyr z(Pvh|exJhu_~@FcNt4Cl0_0qm%T1m9wcF`(Vw@or#RfUUs%pfJzz_rE5hoBJ^sw16 z=?hMypQDJAq|yg73sdp5ZAhvzyAa?v>y&D$j$$ONG{*u!aJwg`C-GG~MR8}jV|O^w zj(KGNnJtzYV}+s6Vt4yIZii9{a0tjOO5w{pDwmmD4x81kl`CnwIb`|@&2f(nG*3-W zPdSl)LiOf)Jk!*#0Nd;Ud=CJln;oR=KuQZBuOT8=S^CbmOv5_pjIqDPbPzU z)8w?%VsYAyN{K>87;{ZlJJmsP(%kve(;lC9dTQEB1So#0kK(0e@hm2RgA|9wVzRo- z8gwyXe8{AS6d5#9i4MBN>9m{m8gnuoPmyR+Ho0Xo7;@>g2Bl0g_DwVeSu{wE2}Fnh zElBfGJk;sME(f|Gi^FWUoAj2iap*CuWn+4?!8SSRLN-w<3><%#n(iKhGPF4iD%sHJ zD71kI5(bq`Wv8%%|41xx@pb^s2p6(c!vdLXWr5r1jF^`z7Fq<7#s$(8#0 zljrvb!=V~)mFMZH$?2eP%I&h7(Im`05MS_4r^On1twybe{5m#OiQ3`bm@kK-4>1h|nx6?d}#cI;e zV$rDNMkr7|D4-BU6}kMz`A`3?-pw>oUJc zc!%{S2cTLEdJ}Y|No%x1k}%PmOvo{t#3l!Lf%5w6gOw3Vs50bGXxuF+uWxgpVX3^vG8T za)bU55qto-QUQ;D(rUa5ftfJgXVB|r5NL+%urq2hzeuN2(Gkpem=-KXC}$%Sz72Ra;7>pV>5X6%E}h|$;>Bm#t&7I@N& z4Kt7==<{Rmj39=Ko8&LL9Rdc0iK!3++G3JSrI1_rBXSLXuwP}Ga#`I*>>pqu4L8UK zAX~A^h3{_2d6B^Mq^~0I(_j#c@;XVdPj5b)hG+!R(m&s|u`)GFbM*_i!8yX#^hf%A+e2B@! z;&d3txC4n~6|x0DxEWa)3cK5?Mb}s=toas;-G#DQfUnU)r>ugS!)ed7tZ=qTjfOd@P5V`Tk z4ES7sC{zzbgg3|MtMvW?(2<5XH3ilq>oO9ac0fac`dRoUSkx8`(}g5}ALCUdl?se% zeIBRY2;yNK*zB;tY;NjwE_4Mom>&v}o0dRBQ2mrZV{mZ*9*|Hd;G3SB0)H^nG4z(9 zcfCFjc0qAKXt03_vPof?V_QngoT> zObzCRg2=O^1`Y=E!jW*$hj|3>!(m$FJ}5zF0IE0WaXG9O8`V$tevyo2Ou`U>f)Op?zps=nlKXjkMDc*%ER9`@#G`FiZ_0Jrnvb7mXtPIoSi02iZkHKnu+$vqQt7 z08%|4@IbRc9byhtTRk3|QYGZX;&qvyghWb}83u?$t0B7`T@LF2c#u6@3C%|Y=lMhE z@JO_F7EK=JK7XJxGAA03K_Ko6qO-ygAH*Z%vQJtGIjeJO zQZ5jul6A;ZW-?U6mMPyP5{%IZ*az4?hZ-mZrQ~!Mfb0ff#O0Ga>SS|_3GgH@8jT^r zHe88)bRLYyFmPanAqf~M&Y@U55^y`sM#5Z(4ToSjx!n@BH;c=2;xuzy36xkZCP8ZWr&+P}g`)v@6TA+*MQc>B7Tr^Rt)Qzvl|FzigxZ>$&WbcD zJ34b3Hu7JANQ=w^`O#=F4$<^SrtC1$R9dK?NvFr$eSwoC;rUKB)-;}zW1RcJF4)jh zo&cz#K_7%j8Keg1gHR*@havsBU@S>3$?eK026~v(eh)`NNNnbKF6M<`SR$Qz7I+ld&f$t+P5?^r zfq)mLmKAPlAKumVLyQw`eUU6!X=7E%o;HzY+HZCG{Lz5Z>m$MDf+!laTm%|uZWI^M zXw?kOS+IBnYm*wx4S1Y{<3328*XiJLE}cHy!Xe>4l%8&@*;i6}Xi#ZT%WZ*hzzN+0 zsilQ$&_xtT9Tl3a0!$!cpf^klQqYPAk$`SDS*Ku#`@IgA;B-@CW4oE`vWL>4&I8na zrPPZetyv;>Ba0Zh>PYHtjLd;pVe6~ftN@U(YJv~={cf8LG{MaCS>()fhnfzw$r>_0 zNu{*S)l@32?z9ju_s&2n9)-RQKnsNrMCJkzva<=0NQqU%E3$;u2AANKaLNPwY04^L zoH|n9)Yjz(sASS}q_MJsAS#Y_iQwh3S-ox#jJ{Af)Dp?X&;=>cYV`XSw++M0^;vhwCLJkzv6u5zlb z2g&WhrbBN3w9PCK@H=aew^o0|8zaHoAMa|arNLKDt3PvIZk@8)ydgAaE>hHCfIxX* zDxo1yKNsqRq-^Gl8YerO+;}Vy@?nbfdtDY=aMB{};~%dn+efXcKOTuTXO_l&Ep-*t zePy(Ys%pByJ?Zx1RS7dIej|{%Txi*<>=J-TZG0ZK3Bz_^Ng|b#gqSRaT>3DvW4VV* zJEG8!a5@i_>?qksr5!jil>+Q!qO-9YId8Oz3ZjiK*Q=a9_=MC>-;_N9M*daUP){N9 zWeO3PN#2lb;9?sx%}Vyss@sR-$!5&AY2W#lT3Q*B_9`ly&khR=c8kSjBTa7)R1!>} zC=Bx`Ek-V1fDR$OsgVdse=Hsics!GVP%=2>i6_IMX}e0zKUZFg_(K`3uKrLc4IjX~ zq^qO8il9*|9;&Imz!mFlE|<|Ajbfg$N5USr5AS{ee=z}aUGmHu*fH!>PR~54yVEq zBD4^@wLz=I6XdpQkr+vSwhd2WA2zHsfKa1LgRy`UGm9rYsTk)mE*zxo+_rVwu6M)z!5`-7jjZTh0#QmC$Tn$(2B5!5WMH{XHQAVj@>2HnyUJPy$Sea=E1Ej zZfmY1swu$qaBXF6>nWy8i?>R=1W$%SE|t;`YDmvB5uXzZKzJi?p%am(VT44&cx6iX z{D}~}-U+{0>+`#Vk!e}aiH6#JP&FmRCFNE1HO&HlJl%%D@b}5Y=;6k?YFc$&UCn{| z)+47b_VzH8TFa!zH3g@O)te555~+yOgE!JdIuRxkzm5fh@dSM1sh}?rn=&UtF{JUj z#)g$+BiPUDaOJ)|yGn_&vhvb$T6JSfHyq}0k@Z;o36V z=>e6rpRaICO<6qC-nd^muJhwPB5JWr8pj9uW1}bQn;L1QySDAzv7;17sw=7* z+8Mq?;uu~7UkY>ES`Hkjt7~m;Yieq!uRnb5d?T%?g?gf!qfoirCa2%yz?-{U?+Cb5 z7RQuDB6r}eNTZVJ^mfD8xbWiHqjhBj4dO)IQ@pDfJ8cma=!3SNY0?o|kP7#mJ$Rs@ zp}B!*{zYqB+mWMfb@d0^>rb4m*hV|a95cD#f5EGr4n}}dA|D?aRhZ4h*v|&BDaVlD z;=#&>gKY;YD-c<%rj=p+3{q<=>l#{GIWTxnLz+{`&_H`jGuEm!QJeqJ)ZSd*aIn4o z61R<3O)L5I)7`bL$Io{#2IO$8jE;%~Bcoz2tK-nYh9k$Ct9O6$>8`2O?4$f zlp(jX@<4Ozp@BH8>2sNXPQ_%Wu@0ubv8B1Ov7x1@p}GCwk#)~V`nRxj~*!BQ-0zot>RE+Y31qe z_Ub)5O52XKR#%i0P|4M`wRQNbsfNO6J8>=$OQt(B_eQ0Mnp^4{FajEp$V(jk)$tRD zPh4Vj96xocx#`r&)(-BOw(82$Cn~Gj8!IZ>&!23lsH#NY)K*tkQmYo%R##M3(5h<= zG_{{p2Vm@{yRb*uw3yY_+Jr>;7Jxjo{P5v}$IqTW(R%nud;77&$GVtjPPDfkX|6fY z)>Kp7dh%!!QJV`ADytV()>P5Z^aBkCPxHbEi}aA%ClwyQbfm4Nt*w=4|L<+>?T1gC zI&rYE{ovvDg9ndXxN!XV;e%jHBldf&Z#{ab1tQr{Uq>!fs;;U6!0NgK_3bBm9nk~; zvakfnbAf*9cw76ycEFo^=;)EQ)^=)ZVf*2;CyoMAGbFEtXnwfuV9UYAhK8nk$Wc}O z0g`=9&8>$IjYLDKzRcsv$Y?4s&182TZf$RGZ99ZzP|Zz^IJ6x-cnBK;Hq>Ro4-sEYKV2K5YD#hAv6PVlDyu{Lw>44})p7)cPkHTR>BD6IyYg8FJJN z@CRF)n;L4-bq892?g-x+NfF81R3u# zrTxeesGLJ>O$`mLtzGN^gAdWYQ7pfrrWPdQld7{vTicEvYNNHxBO6iQ*iN+OwI4Zt z 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

    x!!Plm2nKGmH$`s-VfY& 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 eW3{!B_hg9mKK~!Dx%5K- literal 0 HcmV?d00001 diff --git a/wxPython/distrib/mac/wxPythonOSX/XRCed.icns b/wxPython/distrib/mac/wxPythonOSX/XRCed.icns new file mode 100644 index 0000000000000000000000000000000000000000..ffe1737dae490aab27996a64644311221d6b059e GIT binary patch literal 37830 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 literal 0 HcmV?d00001 diff --git a/wxPython/distrib/mac/wxPythonOSX/build b/wxPython/distrib/mac/wxPythonOSX/build new file mode 100755 index 0000000000..6fca6f4226 --- /dev/null +++ b/wxPython/distrib/mac/wxPythonOSX/build @@ -0,0 +1,390 @@ +#!/bin/sh -e +#---------------------------------------------------------------------- +# Build wxMac and wxPythonOSX from the tarball and then make an +# Installer package out of it. + +spectemplate=distrib/wxPythonFull.spec.in + +if [ ! -d wxPython -o ! -e ${spectemplate} ]; then + echo "Please run this script from the root wxPython directory." + exit 1 +fi + +#---------------------------------------------------------------------- +# Check Parameters + +function usage { + echo "" + echo "Usage: $0 wx_version py_version [command flags...]" + echo " wx_version String to use for version in filenames, etc." + echo " py_version String to append to python (which python version to use.)" + echo "" + echo "command flags:" + echo " skiptar Don't unpack the tarball" + echo " use_cvs Use the CVS workspace instead of a tarfile" + echo " skipconfig Don't run configure" + echo " skipbuild Don't build wxWindows or wxPython" + echo " skipinstall Don't do the installation step" + echo " skipdmg Don't make the package or diskimage" + echo " skipclean Don't do the cleanup at the end" +} + + +if [ $# -lt 2 ]; then + usage + exit 1 +fi + +VERSION=$1 +PYVER=$2 +shift;shift + + +for flag in $*; do + case ${flag} in + skiptar) skiptar=1 ;; + use_cvs) skiptar=1; use_cvs=1 ;; + skipconfig) skipconfig=1; skiptar=1 ;; + skipbuild) skipbuild=1; skipconfig=1; skiptar=1 ;; + skipinstall) skipinstall=1 ;; + skipdmg) skipdmg=1 ;; + skipclean) skipclean=1 ;; + + *) echo "Unknown flag \"${flag}\"" + usage + exit 1 + esac +done + + +SRCDIR=/Volumes/Gate.Stuff/Development/wxPython/dist/$VERSION +TARBALL=$SRCDIR/wxPythonSrc-$VERSION.tar.gz +SITEPACKAGES=/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/site-packages + +# TODO: Should I change the prefix to /usr? +PREFIX=/usr/local + +PROGDIR="`dirname \"$0\"`" +TMPDIR=$PWD/_build_dmg + +BUILDROOT=$TMPDIR/build +INSTALLROOT=$TMPDIR/install +INSTALLDEVEL=$TMPDIR/install-devel +DMGDIR=$TMPDIR/dmg +RESOURCEDIR=$PROGDIR/resources +DESTDIR=$PWD/dist + + + +#---------------------------------------------------------------------- +# Setup builddirs + +mkdir -p $BUILDROOT +mkdir -p $INSTALLROOT +mkdir -p $INSTALLDEVEL +rm -rf $DMGDIR +mkdir -p $DMGDIR/root + +pushd $BUILDROOT + + +#---------------------------------------------------------------------- +# Unpack the tarball + +if [ -z "$skiptar" ]; then + tar xzvf $TARBALL +fi + +if [ "$use_cvs" = 1 ]; then + # copy the cvs workspace, except for build dirs + + mkdir -p wxPythonSrc-$VERSION + + echo Finding updated files... + if [ -e .last_copy ]; then + FEXPR="-cnewer .last_copy" + fi + find /projects/wx $FEXPR -print \ + | grep -v wx/build \ + | grep -v wxPython/build \ + | grep -v wxPython/_build \ + | grep -v CVS \ + | cut -b 14- > filelist + + for x in `cat filelist`; do + if [ -d "/projects/wx/$x" ]; then + mkdir -p "wxPythonSrc-$VERSION/$x" + else + echo $x + cp -p "/projects/wx/$x" "wxPythonSrc-$VERSION/$x" + fi + done + + touch .last_copy +fi + + +cd wxPythonSrc-$VERSION +WXDIR=`pwd` +mkdir -p $WXDIR/build +cd $WXDIR/build + +#---------------------------------------------------------------------- + + +# Configure wxWindows +if [ -z "$skipconfig" ]; then + ../configure --with-mac --prefix=$PREFIX \ + --with-opengl \ + --enable-precomp=no \ + --enable-geometry \ + --enable-optimise \ + --enable-debug_flag \ + --with-libjpeg=builtin \ + --with-libpng=builtin \ + --with-libtiff=builtin \ + --with-zlib=builtin + +fi + +# Build wxWindows and wxPython +if [ -z "$skipbuild" ]; then + make + + cd $WXDIR/wxPython + python$PYVER setup.py \ + IN_CVS_TREE=1 \ + WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" \ + build + + + # Build wxrc (XRC resource tool) but don't use the makefiles since they expect + # a shared version of the xrc lib to have been built... + cd $WXDIR/contrib/utils/wxrc + WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" + wCC=`$WX_CONFIG --cc` + wCXX=`$WX_CONFIG --cxx` + + for f in wxrc.cpp ../../src/xrc/*.cpp; do + echo $f + $wCXX `$WX_CONFIG --cxxflags` -I ../../include -I ../../src/xrc/expat/xmlparse -I ../../src/xrc/expat/xmltok -c $f + done + for f in ../../src/xrc/expat/xmlparse/xmlparse.c ../../src/xrc/expat/xmltok/xmlrole.c ../../src/xrc/expat/xmltok/xmltok.c; do + echo $f + $wCC `$WX_CONFIG --cxxflags` -I ../../include -I ../../src/xrc/expat/xmlparse -I ../../src/xrc/expat/xmltok -c $f + done + + # the handlers are not needed + rm xh_*.o xmlrsall.o + + $wCXX `$WX_CONFIG --libs` *.o -o wxrc + strip wxrc + +fi + +#---------------------------------------------------------------------- +# Install wxWindows + +if [ -z "$skipinstall" ]; then + cd $WXDIR/build + make prefix=$INSTALLROOT/$PREFIX install + + + # and wxPython + cd $WXDIR/wxPython + python$PYVER setup.py \ + IN_CVS_TREE=1 \ + WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" \ + install \ + --root=$INSTALLROOT + + # install wxPython's tool scripts + cd $WXDIR/wxPython/scripts + python$PYVER CreateMacScripts.py $INSTALLROOT $PREFIX/bin + + # Install wxrc + cp $WXDIR/contrib/utils/wxrc/wxrc $INSTALLROOT$PREFIX/bin + + + # Move wxWindows devel files and save for a separate installer package + mkdir -p $INSTALLDEVEL$PREFIX + mkdir -p $INSTALLDEVEL$PREFIX/bin + mkdir -p $INSTALLDEVEL$PREFIX/lib + mv -f $INSTALLROOT$PREFIX/include $INSTALLDEVEL$PREFIX + mv -f $INSTALLROOT$PREFIX/lib/wx $INSTALLDEVEL$PREFIX/lib + mv -f $INSTALLROOT$PREFIX/bin/wx* $INSTALLDEVEL$PREFIX/bin + +fi + +popd + +#---------------------------------------------------------------------- + +# Make the Installer packages and disk image +if [ -z "$skipdmg" ]; then + + # Remove the .pyc/.pyo files they just take up space and can be recreated + # during the install. + python $PROGDIR/../zappycfiles.py $INSTALLROOT/Library/Frameworks/Python.framework + + # Copy the demo, samples, and such to the Applications dir + APPDIR=$INSTALLROOT/Applications/wxPythonOSX-$VERSION + mkdir -p $APPDIR + cp -pR $WXDIR/wxPython/demo $APPDIR + cp -pR $WXDIR/wxPython/samples $APPDIR + + # Move sample launchers to .pyw files. + # TODO: A better, more automated way to do this!!! + pushd $APPDIR/samples + for x in StyleEditor/STCStyleEditor \ + doodle/superdoodle \ + frogedit/FrogEdit \ + pySketch/pySketch \ + wxProject/wxProject; do + mv $x.py $x.pyw + done + popd + + # Make an app to launch the demo + cat > $APPDIR/demo/RunDemo.pyw < $RESOURCEDIR/Welcome.txt < $RESOURCEDIR/preflight < $RESOURCEDIR/postflight < $DMGDIR/root/README.txt < wpSelectDir then Exit; + FileName := WizardDirValue() + '\wxPython\unins000.exe'; + if FileExists(FileName) then begin + ResultCode := MsgBox('A prior wxPython installation was found in this directory. It' + #13 + + 'is recommended that it be uninstalled first.' + #13#13 + + 'Should I do it?', + mbConfirmation, MB_YESNO); + if ResultCode = IDYES then begin + InstExec(FileName, '/SILENT', WizardDirValue()+'\wxPython', True, False, SW_SHOWNORMAL, ResultCode); + + end; + end; +end; + + begin end. """ - #---------------------------------------------------------------------- def find_DLLs(): @@ -317,7 +347,7 @@ def find_DLLs(): proc.close() for line in lines: if line[:6] == " wx": - WXDLL = string.strip(line) + WXDLL = line.strip() if line[:10] == " python": PYTHONVER = line[10] + '.' + line[11] @@ -326,6 +356,23 @@ def find_DLLs(): return WXDLL, PYTHONVER +#---------------------------------------------------------------------- + +locale_template = 'Source: "%s"; DestDir: "{app}\%s"; Components: core' + +def build_locale_string(): + stringlst = [] + + def walk_helper(lst, dirname, files): + for f in files: + filename = os.path.join(dirname, f) + if not os.path.isdir(filename): + lst.append( locale_template % (filename, dirname) ) + + os.path.walk('wxPython\\locale', walk_helper, stringlst) + return '\n'.join(stringlst) + + #---------------------------------------------------------------------- def main(): @@ -344,6 +391,7 @@ def main(): SYSDIR = r"C:\WINNT\SYSTEM32" ISSFILE = "__wxPython.iss" IFSFILE = "__wxPython.ifs" + LOCALE = build_locale_string() if PYTHONVER >= "2.2": IF22 = r"InstallDir := InstallDir + '\Lib\site-packages';" @@ -352,7 +400,7 @@ def main(): # Starting with 2.3.3 the hybrid build is the release build too, so # no need to label it that way. - ##if string.find(WXDLL, "h") != -1: + ##if WXDLL.find("h") != -1: ## PYVER = PYVER + "-hybrid" MSLU='' @@ -370,6 +418,7 @@ def main(): os.system(ISCC % (os.environ['TOOLS'], ISSFILE)) if not KEEP_TEMPS: + time.sleep(1) os.remove(ISSFILE) os.remove(IFSFILE) diff --git a/wxPython/distrib/makedbg.bat b/wxPython/distrib/makedbg.bat deleted file mode 100755 index f738789ffa..0000000000 --- a/wxPython/distrib/makedbg.bat +++ /dev/null @@ -1,33 +0,0 @@ -@echo off -rem Builds a zip containing debugging versions of wxWindows and wxPython -rem that could be unziped over a wxPython installation. - -setlocal - -iff "%1" == "15" then - set PCBUILD=c:\projects\Python-1.5.2\PCBuild -elseiff "%1" == "20" then - set PCBUILD=c:\projects\Python-2.0\PCBuild -else - echo Specivy Python version!!! - goto end -endiff - -iff "%2" == "" then - echo Specify wxPython version!!! - goto end -endiff - - -mkdir wxPython-dbg -copy README.dbg.txt wxPython-dbg -copy %WXWIN%\lib\wx*d.dll wxPython-dbg -copy %WXWIN%\wxPython\wxPython\*_d.pyd wxPython-dbg -copy %PCBUILD%\python_d.exe wxPython-dbg -copy %PCBUILD%\python%1_d.dll wxPython-dbg - -zip -r wxPython-dbg-%2-Py%1.zip wxPython-dbg - -del /sx wxPython-dbg - -:end \ No newline at end of file diff --git a/wxPython/distrib/makedemo b/wxPython/distrib/makedemo index bf340d4335..af2983ee31 100755 --- a/wxPython/distrib/makedemo +++ b/wxPython/distrib/makedemo @@ -21,15 +21,17 @@ cp -R samples _distrib_tgz/wxPython-$1 rm -rf `find _distrib_tgz/wxPython-$1 -name CVS` rm -f `find _distrib_tgz/wxPython-$1 -name "*.pyc"` rm -f `find _distrib_tgz/wxPython-$1 -name .cvsignore` -rm -f `find _distrib_tgz/wxPython-$1 -name core` +rm -f `find _distrib_tgz/wxPython-$1 -name "core*"` rm -f `find _distrib_tgz/wxPython-$1 -name wxPython` -rm -f `find _distrib_tgz/wxPython-$1 -name *.o` -rm -f `find _distrib_tgz/wxPython-$1 -name *.so` +rm -f `find _distrib_tgz/wxPython-$1 -name "*.o"` +rm -f `find _distrib_tgz/wxPython-$1 -name "*.so"` +rm -f `find _distrib_tgz/wxPython-$1 -name "*~"` +rm -f `find _distrib_tgz/wxPython-$1 -name ".#*"` cd _distrib_tgz tar cvf ../dist/wxPythonDemo-$1.tar wxPython-$1 -gzip ../dist/wxPythonDemo-$1.tar +gzip -9 ../dist/wxPythonDemo-$1.tar cd .. rm -r _distrib_tgz diff --git a/wxPython/distrib/makedev.bat b/wxPython/distrib/makedev.bat index 03368b9732..252606a81f 100755 --- a/wxPython/distrib/makedev.bat +++ b/wxPython/distrib/makedev.bat @@ -59,8 +59,8 @@ del /sxzy %BASE%\include\wx\x11\nanox\X11\CVS rem *** bundle it all up cd _distrib_zip -tar cvf ..\dist\wxPythonWIN32-devel-%1.tar wxPython-%1 -gzip -9 ..\dist\wxPythonWIN32-devel-%1.tar +tar cvf ../dist/wxPythonWIN32-devel-%1.tar wxPython-%1 +gzip -9 ../dist/wxPythonWIN32-devel-%1.tar rem *** cleanup cd .. diff --git a/wxPython/distrib/makedocs b/wxPython/distrib/makedocs new file mode 100755 index 0000000000..f158caa190 --- /dev/null +++ b/wxPython/distrib/makedocs @@ -0,0 +1,63 @@ +#!/bin/bash + +#---------------------------------------------------------------------- + +if [ -z $1 ]; then + echo "Please specify a version number on the command line." + exit 1 +fi + +if [ ! -d wxPython ]; then # TODO: make this test more robust + echo "Please run this script from the root wxPython directory." + exit 1 +fi + + +# **** Make a directory to build up a distribution tree + +DEST=wxPython-$1/docs + +mkdir -p _build_docs/$DEST +cd _build_docs +mkdir $DEST/wx +mkdir $DEST/ogl + +WXDIR=../.. + +# **** Build the docs using tex2rtf +cp $WXDIR/docs/latex/wx/*.gif $DEST/wx +$WXDIR/utils/tex2rtf/src/tex2rtf $WXDIR/docs/latex/wx/manual.tex $DEST/wx/wx.htm -twice -html +cp $DEST/wx/wx.htm $DEST/wx/index.htm + +cp $WXDIR/contrib/docs/latex/ogl/*.gif $DEST/ogl +cp $WXDIR/contrib/docs/latex/ogl/*.bmp $DEST/ogl +$WXDIR/utils/tex2rtf/src/tex2rtf $WXDIR/contrib/docs/latex/ogl/ogl.tex $DEST/ogl/ogl.htm -twice -html +cp $DEST/ogl/ogl.htm $DEST/ogl/index.htm + + +# **** zip the docs into "books" +pushd $DEST +pushd wx +zip ../wx.zip * +popd +rm -r wx + +pushd ogl +zip ../ogl.zip * +popd +rm -r ogl + +popd +cp ../distrib/viewdocs.py $DEST +cp ../distrib/README.viewdocs.txt $DEST/README.txt + +rm -f ../dist/wxPythonDocs-$1.tar.gz +tar cvf ../dist/wxPythonDocs-$1.tar $DEST +gzip -9 ../dist/wxPythonDocs-$1.tar + + +# **** Cleanup +cd .. +rm -r _build_docs + + diff --git a/wxPython/distrib/makedocs.bat b/wxPython/distrib/makedocs.bat deleted file mode 100755 index 4e353fb32c..0000000000 --- a/wxPython/distrib/makedocs.bat +++ /dev/null @@ -1,26 +0,0 @@ -@echo off - -rem **** Make a directory to build up a distribution tree -md _distrib_zip -md _distrib_zip\wxPython-%1 - -cd _distrib_zip - -rem **** copy the docs into the tree -md wxPython-%1\docs -md wxPython-%1\docs\wx -md wxPython-%1\docs\ogl -copy %WXWIN%\docs\html\wx\*.* wxPython-%1\docs\wx -copy wxPython-%1\docs\wx\wx.htm wxPython-%1\docs\wx\index.htm -copy %WXWIN%\docs\html\ogl\*.* wxPython-%1\docs\ogl -copy wxPython-%1\docs\ogl\ogl.htm wxPython-%1\docs\ogl\index.htm - -rem **** zip up the docs -rem zip -r ..\distrib\wxPython-docs-%1.zip wxPython-%1\docs -tar cvf ..\dist\wxPythonDocs-%1.tar wxPython-%1 -gzip -9 ..\dist\wxPythonDocs-%1.tar - - -rem **** Cleanup -cd .. -del /sxzy _distrib_zip diff --git a/wxPython/distrib/makerpm b/wxPython/distrib/makerpm index ccb1f5bb9e..f9e7604374 100755 --- a/wxPython/distrib/makerpm +++ b/wxPython/distrib/makerpm @@ -13,51 +13,52 @@ fi #---------------------------------------------------------------------- # Initialization -distdir=`pwd`/dist -builddir=`pwd`/_build_rpm +wxpdir=`pwd` +wxdir=${wxpdir}/.. +distdir=${wxpdir}/dist +builddir=${wxpdir}/_build_rpm rpmtop=${builddir}/rpmtop -cvsroot=:pserver:anoncvs@cvs.wxwindows.org:/home/wxcvs +cvsroot=:pserver:anoncvs@cvs.wxwindows.org:/pack/cvsroots/wxwindows pythonbin=/usr/bin/python port=GTK lcport=gtk +unicode=0 tarname=wxPythonSrc -debug=0 - +rpmflag=-ba #---------------------------------------------------------------------- # Check parameters function useage { - echo "Usage: $0 cvs_tag wx_version py_version [command flags...]" - echo " cvs_tag Tag to use for CVS export" + echo "Usage: $0 wx_version py_version [command flags...]" echo " wx_version String to use for version in filenames, etc." echo " py_version String to append to $pythonbin (which python" echo " version to use.)" echo "" echo "command flags:" - echo " skipcvs Don't do the CVS export" + echo " skipcopy Don't copy the files for the tarball from the workspace" echo " skiptar Don't build the tarball" echo " skiprpm Don't build the RPM (but why?)" echo " skipclean Don't do the cleanup at the end" + echo " gtk2 Build using wxGTK2 and Unicode" + echo " x11 Build using wxX11" echo " speconly Do nothing but write the RPM spec file" - echo " debug Make a __WXDEBUG__ version" - echo " smp Add SMP=2 to the envivonment to speed wxGTK build" + echo " srpm Only make the SRPM" +# echo " smp Add SMP=2 to the envivonment to speed wxGTK build" } -if [ $# -lt 3 ]; then +if [ $# -lt 2 ]; then useage exit 1 fi -cvs_tag=$1 -version=$2 -pyver=$3 -shift;shift;shift +version=$1 +pyver=$2 +shift;shift ver2=`echo ${version} | cut -c 1,2,3` tarver=${tarname}-${version} - python=${pythonbin}${pyver} if [ ! -e ${python} ]; then echo "${python} not found!" @@ -70,12 +71,12 @@ function makespec { cat ${spectemplate} \ | sed s:@PYTHON@:${python}:g \ | sed s:@PYVER@:${pyver}:g \ - | sed s:@DEBUG@:${debug}:g \ | sed s:@PORT@:${port}:g \ | sed s:@LCPORT@:${lcport}:g \ | sed s:@TARNAME@:${tarname}:g \ | sed s:@VERSION@:${version}:g \ | sed s:@VER2@:${ver2}:g \ + | sed s:@UNICODE@:${unicode}:g \ > ${distdir}/wxPython${port}.spec } @@ -83,13 +84,15 @@ function makespec { for flag in $*; do case ${flag} in - skipcvs) skipcvs=1 ;; - skipclean) skipclean=1 ;; - skiptar) skiptar=1 ;; - skiprpm) skiprpm=1 ;; - smp) export SMP=2 ;; - debug) debug=1 ;; - speconly) makespec; exit 0 ;; + skipcopy) skipcopy=1 ;; + skipclean) skipclean=1 ;; + skiptar) skiptar=1 ;; + skiprpm) skiprpm=1 ;; + gtk2) unicode=1; port=GTK2; lcport=gtk2 ;; + x11) port=X11; lcport=x11 ;; + smp) export SMP=2 ;; + speconly) makespec; exit 0 ;; + srpm) rpmflag=-bs; ;; *) echo "Unknown flag \"${flag}\"" useage @@ -119,38 +122,57 @@ done #---------------------------------------------------------------------- -# Get the sources from CVS +# Copy the sources from my CVS workspace -if [ -z "${skipcvs}" ]; then - echo "*** Exporting CVS archive..." +if [ -z "${skipcopy}" ]; then + echo "*** Copying CVS tree" pushd ${builddir} > /dev/null if [ -e ${tarver} ]; then - rm -rf ${tarver} - fi - cvs -d ${cvsroot} export -r ${cvs_tag} -d ${tarver} wxWindows > /dev/null 2>&1 - if [ "$?" != "0" ]; then - echo "*** CVS failure, exiting." - exit 1 + rm -rf ${tarver} fi + mkdir -p ${tarver} + + # copy root dir contents + cp -pf --link ${wxdir}/* ${tarver} > /dev/null 2>&1 - echo "*** Removing unneeded stuff from CVS tree" + # copy all top dirs except CVS, build, demos, utils, samples, and wxPython + for d in art contrib debian distrib docs include lib locale misc src; do + cp -Rpf --link ${wxdir}/$d ${tarver} #> /dev/null 2>&1 + done + + # now do the same thing for wxPython, skipping it's build dirs and such + mkdir ${tarver}/wxPython + cp -pf --link ${wxdir}/wxPython/* ${tarver}/wxPython > /dev/null 2>&1 + for d in contrib demo distrib distutils samples scripts src wxPython; do + cp -Rpf --link ${wxdir}/wxPython/$d ${tarver}/wxPython #> /dev/null 2>&1 + done + + + echo "*** Removing uneeded stuff from copy of CVS tree" pushd ${tarver} > /dev/null rm `find . -name .cvsignore` + rm -rf `find . -name CVS` rm *.spec - rm -rf demos -# rm -rf docs rm -rf docs/html rm -rf docs/latex - rm -rf samples - rm -rf utils -# rm -rf include/wx/mgl -# rm -rf include/wx/motif -# rm -rf include/wx/os2 -# rm -rf src/mgl -# rm -rf src/motif -# rm -rf src/os2 - rm -rf wxPython/wxSWIG - rm -rf wxPython/tests + rm -rf contrib/docs + rm -rf contrib/samples + rm locale/*.mo + rm `find . -name ".#*"` + rm `find . -name "*~"` + rm `find . -name "*.pyc"` + rm `find . -name "core"` + rm `find . -name "core.[0-9]*"` + + rm -f wxPython/wxPython/* > /dev/null 2>&1 + rm wxPython/demo/.setup.sh + rm -rf wxPython/contrib/art2d + rm -rf wxPython/contrib/canvas + rm -rf wxPython/contrib/canvas2 + rm -rf wxPython/contrib/gizmos/contrib + rm -rf wxPython/contrib/ogl/contrib + rm -rf wxPython/contrib/stc/contrib + rm -rf wxPython/contrib/xrc/contrib popd > /dev/null popd > /dev/null @@ -171,9 +193,16 @@ cp ${distdir}/wxPython${port}.spec ${builddir}/${tarver}/wxPython${port}.spec # Build the tar file if [ -z "${skiptar}" ]; then + echo "*** Creating language catalogs..." + pushd ${builddir}/${tarver}/locale > /dev/null + make allmo + popd > /dev/null + echo "*** Creating tarball..." + cp distrib/README.1st.txt ${builddir}/${tarver} pushd ${builddir} > /dev/null tar cvf ${distdir}/${tarver}.tar ${tarver} > /dev/null + echo "*** Compressing..." if [ -e ${distdir}/${tarver}.tar.gz ]; then rm ${distdir}/${tarver}.tar.gz @@ -189,7 +218,7 @@ fi if [ -z "${skiprpm}" ]; then echo "*** Building RPMs..." cp ${distdir}/${tarver}.tar.gz ${rpmtop}/SOURCES - rpm -ba \ + rpmbuild ${rpmflag} \ --define "_topdir ${rpmtop}" \ --define "_tmppath ${builddir}" \ ${distdir}/wxPython${port}.spec diff --git a/wxPython/distrib/maketgz b/wxPython/distrib/maketgz deleted file mode 100755 index bb34859cd8..0000000000 --- a/wxPython/distrib/maketgz +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -#---------------------------------------------------------------------- -# Make a source distribution as a tar.gz file. This script should be -# run from the directory that holds the wxPython dir (../..) and be -# given a version number as an parameter. The best way to do this is -# run "make dist" in the wxPython/src/ directory. -#---------------------------------------------------------------------- - -if [ -z $1 ]; then - echo "Please specify a version number on the command line." - exit 1 -fi - -if [ ! -d wxPython ]; then - echo "Please run this script from the root wxPython directory." - exit 1 -fi - -mkdir _distrib_tgz -mkdir _distrib_tgz/wxPython-$1 - -# Copy license files -cp $WXWIN/docs/gpl.txt _distrib_tgz/wxPython-$1 -cp $WXWIN/docs/lgpl.txt _distrib_tgz/wxPython-$1 -cp $WXWIN/docs/licence.txt _distrib_tgz/wxPython-$1 -cp $WXWIN/docs/licendoc.txt _distrib_tgz/wxPython-$1 -cp $WXWIN/docs/preamble.txt _distrib_tgz/wxPython-$1 - -# Copy files from the live dirs -# first, get a list of files -for x in `cat distrib/wxPython.rsp`; do - ls $x >> _distrib_tgz/filelist -done - -# and make a tar file containing those files -tar cf _distrib_tgz/dist-temp.tar -T _distrib_tgz/filelist - -# now untar it in the right place -cd _distrib_tgz/wxPython-$1 -tar xf ../dist-temp.tar -cd .. - -# update a few things -rm wxPython-$1/src/gtk/helpers.cpp -touch `find wxPython-$1 -name "*.cpp"` -touch `find wxPython-$1 -name "*.py"` - -# Finally, make the finished tar file -tar cvf ../distrib/wxPython-$1.tar wxPython-$1 -gzip ../distrib/wxPython-$1.tar - -cd .. -rm -rf _distrib_tgz - - - - - - - - - diff --git a/wxPython/distrib/maketools b/wxPython/distrib/maketools deleted file mode 100755 index bc47f63dcc..0000000000 --- a/wxPython/distrib/maketools +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -#---------------------------------------------------------------------- - -if [ -z $1 ]; then - echo "Please specify a version number on the command line." - exit 1 -fi - -if [ ! -d wxPython ]; then - echo "Please run this script from the root wxPython directory." - exit 1 -fi - -mkdir _distrib_tgz -mkdir _distrib_tgz/wxPython-$1 - -cp -R tools _distrib_tgz/wxPython-$1 - -# do some cleanup -rm -rf `find _distrib_tgz/wxPython-$1 -name CVS` -rm -f `find _distrib_tgz/wxPython-$1 -name "*.pyc"` -rm -f `find _distrib_tgz/wxPython-$1 -name .cvsignore` -rm -f `find _distrib_tgz/wxPython-$1 -name core` -rm -f `find _distrib_tgz/wxPython-$1 -name wxPython` -rm -f `find _distrib_tgz/wxPython-$1 -name *.o` -rm -f `find _distrib_tgz/wxPython-$1 -name *.so` - -cd _distrib_tgz - -tar cvf ../dist/wxPython-tools-$1.tar wxPython-$1 -gzip ../dist/wxPython-tools-$1.tar - -cd .. -rm -r _distrib_tgz - - - - diff --git a/wxPython/distrib/makexferzip b/wxPython/distrib/makexferzip deleted file mode 100755 index 88e06f3ab0..0000000000 --- a/wxPython/distrib/makexferzip +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -cd ~/wx/utils/wxPython - -find . -name "*.py" > filelist -find . -name "*.i" >> filelist -find . -name "*.h" >> filelist -find . -name "*.cpp" >> filelist - -cat filelist | zip -r -u -@ xfer.zip diff --git a/wxPython/distrib/makexferzip.bat b/wxPython/distrib/makexferzip.bat deleted file mode 100755 index 133ecb15d9..0000000000 --- a/wxPython/distrib/makexferzip.bat +++ /dev/null @@ -1,9 +0,0 @@ - - -cd %WXWIN%\utils\wxPython -find . -name "*.py" > filelist -find . -name "*.i" >> filelist -find . -name "*.h" >> filelist -find . -name "*.cpp" >> filelist - -cat filelist | zip -r -u -@ xfer.zip diff --git a/wxPython/distrib/viewdocs.py b/wxPython/distrib/viewdocs.py new file mode 100755 index 0000000000..efcd59b523 --- /dev/null +++ b/wxPython/distrib/viewdocs.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +#--------------------------------------------------------------------------- + +import sys, os, glob +from wxPython.tools import helpviewer + + +# Figure out the path where this app is located +if __name__ == '__main__': + basePath = os.path.dirname(sys.argv[0]) +else: + basePath = os.path.dirname(__file__) + + +# setup the args +args = ['', + '--cache='+basePath, + os.path.join(basePath, 'wx.zip'), + os.path.join(basePath, 'ogl.zip'), + ] + +# add any other .zip files found +for file in glob.glob(os.path.join(basePath, "*.zip")): + if file not in args: + args.append(file) + +# launch helpviewer +helpviewer.main(args) + +#--------------------------------------------------------------------------- + diff --git a/wxPython/distrib/wise.aut b/wxPython/distrib/wise.aut deleted file mode 100644 index 8f97040c2d..0000000000 --- a/wxPython/distrib/wise.aut +++ /dev/null @@ -1,7 +0,0 @@ - -run, c:\\Tools\\Wise\\WISE32.EXE wxPython.wse -winwaitactive, wxPython.wse - Wise Installation System -send, !ic -sleep, 1000 -winwaitactive, wxPython.wse - Wise Installation System -send, !fx diff --git a/wxPython/distrib/wxPython.WSM b/wxPython/distrib/wxPython.WSM deleted file mode 100644 index 075f558178800d97840ee9f539f9099908b334cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33 lcmWF!_BE?9V_;xpu+w7PtsCjhP^HSm00NAmZ1owyxLLFwh6^(0`!~7!n6vB4FU2k>Qbg;3Nwmla14o+5;br>Q1OW2AOP> zn7jkgvmUV^fUE{YW};P0PQ>2c-H40q580oxU$B2>t^!%p&_k_NVL@>>t^!;3E4& z_NVL@>>t^!^dkF1_NVL@>>t@}$Rhhg_NVL@>>t@}+#>r!_NVL@>>t@FfYKl4?>t_fghlp;>`&P**gvw{F^lXE*`KmsuzzH?vliJOvOi_NVE@Q&2QIQdWPi$j!Tyom zPF-Yw$o`c5g8d^q8Brf=@-%-Je12rN^B374vOi_NVE@RjKo;2_vOi_NVE@RjkQUh= zvOi_NVE@Rj;1<~*vOi_NVE@RjFc;Y$vOi_NVE@QY0_tP0Sd)wVedJT2FS0*mf69Kr z{*hfEEV4gjf69Kr{*hg9EV4gjf69Kr{*hh4EV4gjf69Kr{*j#z>O(mDQ}zq?kL+Ba zK1#@5u_hn$M`Y?lIQvuf3-*ufWI%lgXMf6m!Tyn*OsNmy>`&P**gvvU5cMIP{VDqe z`$u*PrwGE?pR!-DfBgT!-o3N5{MGX9<=frc-KDkevIomuw%bd5FE8C$T5#_!cbB?L z3#(jST3z6LtLx#yDpyt)R=dk&LwqhYk+`x-K3n&QNZ8Vy-d1;Yc{LgGy|6^^?XD@w zVEGPl?kscg)pGYMGxQ=MrZAgcpR9UYeG+(Wi$A`Wtfv{V8!K7fCN_V$VD4@ekg$9# zd%elqgv+a(cgddkUP|tL6ZgDE(6Uvf2fCL36{lP!rGJ)WCCp~IYfjc{;5Eu6&+cGg zFrgG_#1z--Rjrb}1=*t2?rJaDRwm{_`qiE#)MoXJH#sMl9QV3Q=F#mnc`S7wb-RC9 z{R8nWh-+JIfu7V>SNQC0ZEtP&`h5h*tdE0dIy-27&bKZQ8aFbadBx-2xLJ6fHy$6A2Rr1oX+i z#|NDSu9o{-cZ{`UMnpv#BqK@AITfry3g5)ARuxEXtBw6Zb-3-|lAXM~nvp?VT11xq z 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�D>c^=Rh80UsBo-hpLBm8B=q*0Qo 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 XyRW6}l|AgWgi~OJh-azJNa+6o;FcWO diff --git a/wxPython/distrib/wxPython.rsp b/wxPython/distrib/wxPython.rsp deleted file mode 100644 index bfc9cdf462..0000000000 --- a/wxPython/distrib/wxPython.rsp +++ /dev/null @@ -1,106 +0,0 @@ -*.txt - -demo/*.py -demo/bitmaps/*.bmp -demo/bitmaps/*.ico -demo/bitmaps/*.gif -demo/bitmaps/*.png -demo/bitmaps/*.jpg -demo/README.txt -demo/*.xml -demo/data/*.png -demo/data/*.htm -demo/data/*.html -demo/data/*.bmp -demo/data/*.txt -demo/data/*.i -demo/data/*.h - -distrib/build.py -distrib/wxPython.spec - -wxPython/lib/*.py -wxPython/lib/*.txt -wxPython/lib/sizers/*.py -wxPython/lib/sizers/*.txt -wxPython/lib/editor/*.py -wxPython/lib/editor/*.txt - - -src/build.cfg -src/*.i -src/*.py -src/*.cpp -src/*.c -src/*.h -src/*.ico -src/*.def -src/*.rc - -src/msw/*.cpp -src/msw/*.h -src/msw/*.py - -src/gtk/*.cpp -src/gtk/*.h -src/gtk/*.py - -src/motif/*.cpp -src/motif/*.h -src/motif/*.py - - -contrib/glcanvas/build.cfg -contrib/glcanvas/*.i -contrib/glcanvas/*.py -contrib/glcanvas/*.cpp -contrib/glcanvas/*.c -contrib/glcanvas/*.h -contrib/glcanvas/*.def -contrib/glcanvas/*.rc -contrib/glcanvas/msw/*.cpp -contrib/glcanvas/msw/*.h -contrib/glcanvas/msw/*.py -contrib/glcanvas/gtk/*.cpp -contrib/glcanvas/gtk/*.h -contrib/glcanvas/gtk/*.py - -contrib/ogl/build.cfg -contrib/ogl/*.txt -contrib/ogl/*.i -contrib/ogl/*.py -contrib/ogl/*.cpp -contrib/ogl/*.c -contrib/ogl/*.h -contrib/ogl/*.def -contrib/ogl/*.rc -contrib/ogl/contrib/include/wx/ogl/*.h -contrib/ogl/contrib/src/ogl/*.cpp - -contrib/stc/build.cfg -contrib/stc/*.txt -contrib/stc/*.i -contrib/stc/*.py -contrib/stc/*.cpp -contrib/stc/*.c -contrib/stc/*.h -contrib/stc/*.def -contrib/stc/*.rc -contrib/stc/*.cpp -contrib/stc/*.h -contrib/stc/*.py -contrib/stc/contrib/include/wx/stc/*.h -contrib/stc/contrib/src/stc/*.h -contrib/stc/contrib/src/stc/*.cpp -contrib/stc/contrib/src/stc/*.txt -contrib/stc/contrib/src/stc/*.py -contrib/stc/contrib/src/stc/scintilla/include/*.h -contrib/stc/contrib/src/stc/scintilla/include/*.iface -contrib/stc/contrib/src/stc/scintilla/src/*.h -contrib/stc/contrib/src/stc/scintilla/src/*.cxx - - - - - - diff --git a/wxPython/distrib/wxPython.wse b/wxPython/distrib/wxPython.wse deleted file mode 100644 index bf3321be82..0000000000 --- a/wxPython/distrib/wxPython.wse +++ /dev/null @@ -1,1364 +0,0 @@ -Document Type: WSE -item: Global - Version=6.01 - Title=wxPython 2.2 Installation - Flags=10010111 - Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - Japanese Font Name=MS Gothic - Japanese Font Size=10 - Progress Bar DLL=%_WISE_%\Progress\WIZ%_EXE_OS_TYPE_%.DLL - Start Gradient=128 128 255 - End Gradient=64 0 128 - Windows Flags=00000100000000010010110000011000 - Log Pathname=%MAINDIR%\INSTALL.LOG - Message Font=MS Sans Serif - Font Size=8 - Disk Filename=SETUP - Patch Flags=0000000000001001 - Patch Threshold=85 - Patch Memory=4000 - EXE Filename=wxPython-2.2.5-PyXX.exe - FTP Cluster Size=20 - Per-User Version ID=1 - Dialogs Version=6 - Variable Name1=_SYS_ - Variable Default1=C:\WINNT\System32 - Variable Flags1=00001000 - Variable Name2=_WISE_ - Variable Default2=C:\Tools\Wise - Variable Flags2=00001000 - Variable Name3=_ODBC16_ - Variable Default3=C:\WINNT\System32 - Variable Flags3=00001000 - Variable Name4=_ODBC32_ - Variable Default4=C:\WINNT\System32 - Variable Flags4=00001000 - Variable Name5=_ALIASNAME_ - Variable Flags5=00001000 - Variable Name6=_ALIASPATH_ - Variable Flags6=00001000 - Variable Name7=_ALIASTYPE_ - Variable Flags7=00001000 -end -item: Open/Close INSTALL.LOG - Flags=00000001 -end -item: Check if File/Dir Exists - Pathname=%SYS% - Flags=10000100 -end -item: Set Variable - Variable=SYS - Value=%WIN% -end -item: End Block -end -item: Set Variable - Variable=APPTITLE - Value=wxPython 2.2 - Flags=10000000 -end -item: Set Variable - Variable=GROUP - Value=wxPython 2.2 - Flags=10000000 -end -item: Set Variable - Variable=DISABLED - Value=! -end -item: Set Variable - Variable=MAINDIR - Value=wxPython - Flags=10000000 -end -item: Remark -end -item: Set Variable - Variable=PYTHONVER - Value=1.5 -end -item: Remark -end -item: Check Configuration - Flags=10111011 -end -item: Get Registry Key Value - Variable=PYTHONDIR - Key=SOFTWARE\Python\PythonCore\%PYTHONVER%\InstallPath - Flags=00000100 -end -remarked item: If/While Statement - Variable=PYTHONDIR - Value=None -end -remarked item: Get Registry Key Value - Variable=PYTHONDIR - Key=SOFTWARE\Python\PythonCore\%PYTHONVER%\InstallPath - Flags=00000010 -end -remarked item: End Block -end -item: If/While Statement - Variable=PYTHONDIR - Value=None -end -item: Display Message - Title=Installation Error - Text=An existing Python installation was not found, wxPython installation can not proceed. Please download and install the Python core interpreter and library (version 1.5.1 or greater) from http://www.python.org/download/ - Flags=00001000 -end -item: Exit Installation -end -item: End Block -end -item: Set Variable - Variable=MAINDIR - Value=%PYTHONDIR% -end -item: Remark -end -item: Set Variable - Variable=EXPLORER - Value=1 -end -item: Get Registry Key Value - Variable=COMMON - Key=SOFTWARE\Microsoft\Windows\CurrentVersion - Default=C:\Program Files\Common Files - Value Name=CommonFilesDir - Flags=00000100 -end -item: Get Registry Key Value - Variable=PROGRAM_FILES - Key=SOFTWARE\Microsoft\Windows\CurrentVersion - Default=C:\Program Files - Value Name=ProgramFilesDir - Flags=00000100 -end -item: Else Statement -end -item: Set Variable - Variable=MAINDIR - Value=C:\%MAINDIR% -end -item: End Block -end -item: Set Variable - Variable=BACKUP - Value=%MAINDIR%\wxPython\BACKUP - Flags=10000000 -end -item: Set Variable - Variable=DOBACKUP - Value=B - Flags=10000000 -end -item: Set Variable - Variable=COMPONENTS - Flags=10000000 -end -item: Set Variable - Variable=BRANDING - Value=0 -end -item: If/While Statement - Variable=BRANDING - Value=1 -end -item: Read INI Value - Variable=NAME - Pathname=%INST%\CUSTDATA.INI - Section=Registration - Item=Name -end -item: Read INI Value - Variable=COMPANY - Pathname=%INST%\CUSTDATA.INI - Section=Registration - Item=Company -end -item: If/While Statement - Variable=NAME -end -item: Set Variable - Variable=DOBRAND - Value=1 -end -item: End Block -end -item: End Block -end -item: Display Graphic - Pathname=C:\PROJECTS\wx\wxPython\distrib\wxPython.bmp - X Position=32784 - Y Position=16 - Flags=0000001010000000 -end -item: Wizard Block - Direction Variable=DIRECTION - Display Variable=DISPLAY - Bitmap Pathname=%_WISE_%\DIALOGS\TEMPLATE\WIZARD.BMP - X Position=9 - Y Position=10 - Filler Color=8421440 - Dialog=Select Program Manager Group - Dialog=Select Backup Directory - Dialog=Display Registration Information - Dialog=Get Registration Information - Variable=EXPLORER - Variable=DOBACKUP - Variable=DOBRAND - Variable=DOBRAND - Value=1 - Value=A - Value=1 - Value=1 - Compare=0 - Compare=1 - Compare=0 - Compare=1 - Flags=00000011 -end -item: Custom Dialog Set - Name=Welcome - Display Variable=DISPLAY - item: Dialog - Title=Welcome - Title French=Bienvenue - Title German=Willkommen - Title Portuguese=Bem-vindo - Title Spanish=Bienvenido - Title Italian=Benvenuto - Title Danish=Velkommen - Title Dutch=Welkom - Title Norwegian=Velkommen - Title Swedish=Välkommen - Width=280 - Height=224 - Font Name=Helv - Font Size=8 - item: Push Button - Rectangle=172 185 214 199 - Variable=DIRECTION - Value=N - Create Flags=01010000000000010000000000000001 - Text=&Next > - Text French=&Suivant> - Text German=&Weiter> - Text Portuguese=&Próximo> - Text Spanish=&Siguiente > - Text Italian=&Avanti > - Text Danish=&Næste> - Text Dutch=&Volgende> - Text Norwegian=&Neste> - Text Swedish=&Nästa > - end - item: Push Button - Rectangle=222 185 264 199 - Action=3 - Create Flags=01010000000000010000000000000000 - Text=Cancel - Text French=Annuler - Text German=Abbrechen - Text Portuguese=Cancelar - Text Spanish=Cancelar - Text Italian=Annulla - Text Danish=Annuller - Text Dutch=Annuleren - Text Norwegian=Avbryt - Text Swedish=Avbryt - end - item: Static - Rectangle=9 177 263 178 - Action=3 - Create Flags=01010000000000000000000000000111 - end - item: Static - Rectangle=83 8 121 33 - Action=2 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000001011 - Pathname=%_WISE_%\dialogs\template\install.grf - Pathname French=%_WISE_%\dialogs\template\install.grf - Pathname German=%_WISE_%\dialogs\template\install.grf - Pathname Portuguese=%_WISE_%\dialogs\template\install.grf - Pathname Spanish=%_WISE_%\dialogs\template\install.grf - Pathname Italian=%_WISE_%\dialogs\template\install.grf - Pathname Danish=%_WISE_%\dialogs\template\install.grf - Pathname Dutch=%_WISE_%\dialogs\template\install.grf - Pathname Norwegian=%_WISE_%\dialogs\template\install.grf - Pathname Swedish=%_WISE_%\dialogs\template\install.grf - end - item: Static - Rectangle=121 10 258 44 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000000000 - Text=Welcome to %APPTITLE% Setup program. This program will install %APPTITLE% on your computer. - Text French=Bienvenue sur le programme d'installation %APPTITLE%. Ce programme va installer %APPTITLE% sur votre ordinateur. - Text German=Willkommen im Installationsprogramm für %APPTITLE%. Dieses Programm installiert %APPTITLE% auf Ihrem Computer. - Text Portuguese=Bem-vindo ao programa de configuração %APPTITLE%. Este programa instalará %APPTITLE% no seu computador - Text Spanish=Bienvenido al programa de Configuración %APPTITLE%. Este programa instalará %APPTITLE en su ordenador - Text Italian=Benvenuto nel programma di installazione di %APPTITLE%. Con questo programma puoi installare %APPTITLE% sul tuo computer. - Text Danish=Velkommen til %APPTITLE% installationsprogrammet. Dette program installerer %APPTITLE% på computeren. - Text Dutch=Welkom bij het %APPTITLE% installatieprogramma. Dit programma installeert %APPTITLE% op uw computer. - Text Norwegian=Velkommen til %APPTITLE% Oppsett-program. Dette programmet vil installere %APPTITLE% på datamaskinen din. - Text Swedish=Välkommen till installationsprogrammet för %APPTITLE%. Detta program installerar %APPTITLE% på din dator. - end - item: Static - Rectangle=90 45 260 175 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000000000 - Text=It is strongly recommended that you exit all Windows programs before running this Setup Program. - Text= - Text=Click Cancel to quit Setup and close any programs you have running. Click Next to continue with the Setup program . - Text= - Text=WARNING: Although this program is OpenSource, it is still protected by copyright law and international treaties. See wxWindows Library Licence, Version 3 for details. - Text= - Text= - Text French=Il vous est fortement recommandé de fermer tous les programmes Windows avant d'exécuter le Programme d'Installation - Text French= - Text French=Cliquez sur Annuler pour quitter l'Installation et fermez tous les programmes actuellement utilisés. Cliquez sur Suivant pour continuer l'installation - Text French= - Text French=ATTENTION : Ce programme est protégé par la loi sur les droits d'exploitation et par les traités internationaux - Text French= - Text French=Toute reproduction ou distribution, même partielle, de ce programme qui n'aura pas reçu d'autorisation préalable fera l'objet de poursuites et sera sévèrement sanctionnée par le droit civil et pénal - Text German=Wir empfehlen nachdrücklich, vor Ausführen dieses Installationsprogramms alle Windows-Programme zu beenden. - Text German= - Text German=Auf Abbrechen klicken, um die Installation zu beenden und alle laufenden Programme zu schließen. Auf Weiter klicken, um mit dem Installationsprogramm beginnen. - Text German= - Text German=WARNUNG: Dieses Programm ist urheberrechtlich sowie durch internationale Verträge geschützt. - Text German= - Text German=Die unzulässige Vervielfältigung oder Verbreitung dieses Programms, ob ganz oder auszugsweise, kann schwere zivil- und strafrechtliche Konsequenzen nach sich ziehen und wird unter voller Ausschöpfung der Rechtsmittel geahndet. - Text Portuguese=Recomenda-se insistentemente que saia de todos os programas do Windows antes de executar este Programa de Configuração. - Text Portuguese= - Text Portuguese=Faça um clique sobre Cancelar para sair da Configuração e feche todos os programas que estiver a executar. Faça um clique sobre Próximo para continuar com o programa de configuração - Text Portuguese= - Text Portuguese=AVISO: Este programa está protegido pela lei de direitos do autor e tratados internacionais - Text Portuguese= - Text Portuguese=A reprodução e a distribuição sem autorização deste programa, ou qualquer parte dele, pode dar lugar à aplicação de severas sanções civis e criminais, e serão perseguidas à extensão máxima permitida pela lei. - Text Spanish=Se recomienda encarecidamente que salga de todos los programas Windows antes de ejecutar este programa de Configuración. - Text Spanish= - Text Spanish=Haga un clic en Cancelar para abandonar la Configuración y cerrar cualquier programa que haya estado ejecutando. Haga un clic en Siguiente para continuar con el programa de Configuración. - Text Spanish= - Text Spanish=AVISO: Este programa está protegido por las leyes de derechos de autor y tratados internacionales. - Text Spanish= - Text Spanish=La reproducción o distribución no autorizadas de este programa, o cualquier parte de él, podría dar como resultado rigurosas multas civiles y penales, y se entablará la máxima acción judicial que permita la ley. - Text Italian=Ti consigliamo di uscire da tutti i programmi Windows prima di eseguire questo programma di installazione. - Text Italian= - Text Italian=Fai clic su Annulla per uscire dal programma di installazione e chiudi tutti i programmi aperti. Fai clic su Avanti per continuare con il programma di Installazione. - Text Italian= - Text Italian=AVVERTENZA: Questo programma è protetto ai sensi delle norme di legge e delle convenzioni internazionali in materia di diritti di copyright. - Text Italian= - Text Italian=La riproduzione o la distribuzione totale o parziale non autorizzata di questo programma potrà essere soggetta a penalità civili e penali, e sarà punita con la massima severità possibile a norma di legge. - Text Danish=Det anbefales kraftigt at afslutte alle Windows programmer, inden man kører dette installationsprogram. - Text Danish= - Text Danish=Klik på Annuller for at forlade installationsprogrammet og lukke alle igangværende programmer. Klik på Næste for at fortsætte med installationsprogrammet. - Text Danish= - Text Danish=ADVARSEL: Dette program er beskyttet af copyright og internationale traktater. - Text Danish= - Text Danish=Uautoriseret gengivelse eller videresalg af dette program eller dele heraf kan føre til streng civil- og/eller kriminel stra. Retsforfølgning heraf vil finde sted i det videste omfang der hjemles muligt. - Text Dutch=Het wordt aangeraden om alle Windows programma's af te sluiten voordat u met de installatie van dit programma begint. - Text Dutch= - Text Dutch=Klik op Annuleren om de installatie te verlaten en eventueel nog lopende programma's af te sluiten. Klik op Volgende om verder te gaan met het Installatieprogramma. - Text Dutch= - Text Dutch=WAARSCHUWING: dit computerprogramma is auteursrechtelijk beschermd. - Text Dutch= - Text Dutch=Onrechtmatige verveelvoudiging of distributie van dit programma of een gedeelte ervan is verboden en strafbaar en zal met alle beschikbare juridische middelen worden bestreden. - Text Norwegian=Det anbefales på det sterkeste at du avslutter alle Windows-programmer før du kjører dette Oppsett-programmet. - Text Norwegian= - Text Norwegian=Velg Avbryt for å avbryte Oppsett og lukk alle programmer som er i bruk. Velg Neste for å fortsette med Oppsett-programmet. - Text Norwegian= - Text Norwegian=ADVARSEL: Dette programmet er beskyttet i henhold til lover om opphavsrett og internasjonale konvensjoner. - Text Norwegian= - Text Norwegian=Uautorisert kopiering eller distribuering av dette programmet eller deler av det, vil resultere i alvorlig sivil og kriminell straff og vil føre til saksmål i høyest mulig utstrekning i henhold til loven. - Text Swedish=Du tillråds bestämt att gå ur alla Windows-program innan du kör installationsprogrammet. - Text Swedish= - Text Swedish=Klicka på Avbryt för att gå ur installationsprogrammet och stäng eventuella program som du har laddade. Klicka på Nästa för att fortsätta med installationen. - Text Swedish= - Text Swedish=VARNING: Detta program är skyddat av upphovsrätten och internationella avtal. - Text Swedish= - Text Swedish=Om du utan tillstånd kopierar eller distribuerar detta program eller delar av det kan det bli allvarliga civilrättsliga och brottsrättliga straffpåföljder. Vi beivrar sådana överträdelser i den allra högsta utsträckning som lagen tillåter. - end - end -end -item: Custom Dialog Set - Name=Select Destination Directory - Display Variable=DISPLAY - item: Dialog - Title=Choose Destination Location - Title French=Choisissez la localisation de destination - Title German=Zielpfad wählen - Title Portuguese=Escolher Local de Destino - Title Spanish=Elegir una localización de destino - Title Italian=Scegli Posizione di Destinazione - Title Danish=Vælg destinationsmappe - Title Dutch=Kies doellocatie - Title Norwegian=Velg målplassering - Title Swedish=Välj ställe för installationen - Width=280 - Height=224 - Font Name=Helv - Font Size=8 - item: Push Button - Rectangle=172 185 214 199 - Variable=DIRECTION - Value=N - Create Flags=01010000000000010000000000000001 - Text=&Next > - Text French=&Suivant> - Text German=&Weiter> - Text Portuguese=&Próximo> - Text Spanish=&Siguiente > - Text Italian=&Avanti > - Text Danish=&Næste> - Text Dutch=&Volgende> - Text Norwegian=&Neste> - Text Swedish=&Nästa > - end - item: Push Button - Rectangle=130 185 172 199 - Variable=DIRECTION - Value=B - Create Flags=01010000000000010000000000000000 - Flags=0000000000000001 - Text=< &Back - Text French=<&Retour - Text German=<&Zurück - Text Portuguese=<&Retornar - Text Spanish=<&Retroceder - Text Italian=< &Indietro - Text Danish=<&Tilbage - Text Dutch=<&Terug - Text Norwegian=<&Tilbake - Text Swedish=< &Tillbaka - end - item: Push Button - Rectangle=222 185 264 199 - Action=3 - Create Flags=01010000000000010000000000000000 - Text=Cancel - Text French=Annuler - Text German=Abbrechen - Text Portuguese=Cancelar - Text Spanish=Cancelar - Text Italian=Annulla - Text Danish=Annuller - Text Dutch=Annuleren - Text Norwegian=Avbryt - Text Swedish=Avbryt - end - item: Static - Rectangle=9 177 263 178 - Action=3 - Create Flags=01010000000000000000000000000111 - end - item: Static - Rectangle=89 10 260 74 - Create Flags=01010000000000000000000000000000 - Text=Setup will install %APPTITLE% in the following folder. - Text= - Text=To install into a different folder, click Browse, and select another folder. - Text= - Text=You can choose not to install %APPTITLE% by clicking Cancel to exit Setup. - Text French=%APPTITLE% va être installé dans le répertoire ci-dessous - Text French= - Text French=Pour l'installer dans un répertoire différent, cliquez sur Parcourir et sélectionnez un autre répertoire - Text French= - Text French=Vous pouvez choisir de ne pas installer %APPTITLE% en cliquant sur Annuler pour quitter l'Installation - Text German=Installation speichert %APPTITLE% im unten angegebenen Ordner: - Text German= - Text German=Zur Installation in einem anderen Ordner auf Blättern klicken und einen anderen Ordner wählen. - Text German= - Text German=Wenn Sie %APPTITLE% nicht installieren möchten, können Sie durch Klicken auf Abbrechen die Installation beenden. - Text Portuguese=Configuração instalará %APPTITLE% na seguinte pasta - Text Portuguese= - Text Portuguese=Para instalar numa pasta diferente, faça um clique sobre Procurar, e seleccione uma outra pasta. - Text Portuguese= - Text Portuguese=Pode escolher não instalar %APPTITLE% clicando no botão Cancelar para sair da Configuração - Text Spanish=El programa de Configuración instalará %APPTITLE% en la siguiente carpeta. - Text Spanish= - Text Spanish=Para instalar en una carpeta diferente, haga un clic en Visualizar, y seleccione otra carpeta. - Text Spanish= - Text Spanish=Puede elegir no instalar %APPTITLE% haciendo un clic en Cancelar para salir de Configuración. - Text Italian=Il programma di installazione installerà %APPTITLE% nella seguente cartella. - Text Italian= - Text Italian=Per effettuare l’installazione in una cartella diversa, fai clic su Sfoglia, e scegli un’altra cartella. - Text Italian= - Text Italian=Puoi scegliere di non installare %APPTITLE% facendo clic su Annulla per uscire dal programma di installazione - Text Danish=Installationsprogrammet installerer %APPTITLE% i denne mappe. - Text Danish= - Text Danish=Man installerer i en anden mappe ved at klikke på Browse og vælge en anden mappe. - Text Danish= - Text Danish=Man kan vælge ikke at installere %APPTITLE% ved at klikke på Slet og forlade installationsprogrammet. - Text Dutch=Het installatieprogramma installeert %APPTITLE% in de volgende directory. - Text Dutch= - Text Dutch=Als u het in een andere directory wilt installeren, klik dan op Bladeren en kies een andere locatie. - Text Dutch= - Text Dutch=U kunt ervoor kiezen om %APPTITLE% niet te installeren: klik op Annuleren om het installatieprogramma te verlaten. - Text Norwegian=Oppsett vil installere %APPTITLE% i følgende mappe. - Text Norwegian= - Text Norwegian=For å installere i en annen mappe, klikk Bla igjennom og velg en annen mappe. - Text Norwegian= - Text Norwegian=Du kan velge å ikke installere %APPTITLE% ved å velge Avbryt for å gå ut av Oppsett. - Text Swedish=Installationsprogrammet installerar %APPTITLE% i följande mapp. - Text Swedish= - Text Swedish=Om du vill att installationen ska göras i en annan mapp, klickar du på Bläddra och väljer en annan mapp. - Text Swedish= - Text Swedish=Du kan välja att inte installera %APPTITLE% genom att klicka på Avbryt för att lämna installationsprogrammet. - end - item: Static - Rectangle=90 134 260 162 - Action=1 - Create Flags=01010000000000000000000000000111 - Text=Destination Folder - Text French=Répertoire de destination - Text German=Zielordner - Text Portuguese=Pasta de Destino - Text Spanish=Carpeta de Destino - Text Italian=Cartella di destinazione - Text Danish=Destinationsmappe - Text Dutch=Doeldirectory - Text Norwegian=Målmappe - Text Swedish=Destinationsmapp - end - item: Push Button - Rectangle=213 143 255 157 - Variable=MAINDIR_SAVE - Value=%MAINDIR% - Destination Dialog=1 - Action=2 - Create Flags=01010000000000010000000000000000 - Text=B&rowse... - Text French=P&arcourir - Text German=B&lättern... - Text Portuguese=P&rocurar - Text Spanish=V&isualizar... - Text Italian=Sfoglia... - Text Danish=&Gennemse... - Text Dutch=B&laderen... - Text Norwegian=Bla igjennom - Text Swedish=&Bläddra - end - item: Static - Rectangle=95 146 211 157 - Destination Dialog=2 - Create Flags=01010000000000000000000000000000 - Text=%MAINDIR% - Text French=%MAINDIR% - Text German=%MAINDIR% - Text Portuguese=%MAINDIR% - Text Spanish=%MAINDIR% - Text Italian=%MAINDIR% - Text Danish=%MAINDIR% - Text Dutch=%MAINDIR% - Text Norwegian=%MAINDIR% - Text Swedish=%MAINDIR% - end - item: Static - Rectangle=94 81 138 96 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000000000 - Flags=0000000000000001 - Name=MS Sans Serif - Font Style=-11 0 0 0 700 0 0 0 0 1 2 1 34 - Text=Please note: - end - item: Static - Rectangle=138 82 254 106 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000000000 - Text=wxPython will be installed in a subdirectory of the path specfied below. - end - item: Static - Rectangle=91 74 259 113 - Action=1 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000000111 - end - end - item: Dialog - Title=Select Destination Directory - Title French=Choisissez le répertoire de destination - Title German=Zielverzeichnis wählen - Title Portuguese=Seleccionar Directório de Destino - Title Spanish=Seleccione el Directorio de Destino - Title Italian=Seleziona Directory di destinazione - Title Danish=Vælg Destinationsbibliotek - Title Dutch=Kies doeldirectory - Title Norwegian=Velg målkatalog - Title Swedish=Välj destinationskalatog - Width=221 - Height=173 - Font Name=Helv - Font Size=8 - item: Listbox - Rectangle=5 2 160 149 - Variable=MAINDIR - Create Flags=01010000100000010000000101000000 - Flags=0000110000100010 - Text=%MAINDIR% - Text French=%MAINDIR% - Text German=%MAINDIR% - Text Portuguese=%MAINDIR% - Text Spanish=%MAINDIR% - Text Italian=%MAINDIR% - Text Danish=%MAINDIR% - Text Dutch=%MAINDIR% - Text Norwegian=%MAINDIR% - Text Swedish=%MAINDIR% - end - item: Push Button - Rectangle=167 6 212 21 - Create Flags=01010000000000010000000000000001 - Text=OK - Text French=OK - Text German=OK - Text Portuguese=OK - Text Spanish=ACEPTAR - Text Italian=OK - Text Danish=OK - Text Dutch=OK - Text Norwegian=OK - Text Swedish=OK - end - item: Push Button - Rectangle=167 25 212 40 - Variable=MAINDIR - Value=%MAINDIR_SAVE% - Create Flags=01010000000000010000000000000000 - Flags=0000000000000001 - Text=Cancel - Text French=Annuler - Text German=Abbrechen - Text Portuguese=Cancelar - Text Spanish=Cancelar - Text Italian=Annulla - Text Danish=Slet - Text Dutch=Annuleren - Text Norwegian=Avbryt - Text Swedish=Avbryt - end - end -end -item: Custom Dialog Set - Name=Start Installation - Display Variable=DISPLAY - item: Dialog - Title=Start Installation - Title French=Commencer l'installation - Title German=Installation beginnen - Title Portuguese=Iniciar Instalação - Title Spanish=Comenzar la Instalación - Title Italian=Avvia Installazione - Title Danish=Start installationen - Title Dutch=Start de installatie - Title Norwegian=Start installeringen - Title Swedish=Starta installationen - Width=280 - Height=224 - Font Name=Helv - Font Size=8 - item: Push Button - Rectangle=172 185 214 199 - Variable=DIRECTION - Value=N - Create Flags=01010000000000010000000000000001 - Text=&Next > - Text French=&Suivant> - Text German=&Weiter> - Text Portuguese=&Próximo> - Text Spanish=&Siguiente > - Text Italian=&Avanti > - Text Danish=&Næste> - Text Dutch=&Volgende> - Text Norwegian=&Neste> - Text Swedish=&Nästa > - end - item: Push Button - Rectangle=130 185 172 199 - Variable=DIRECTION - Value=B - Create Flags=01010000000000010000000000000000 - Text=< &Back - Text French=<&Retour - Text German=<&Zurück - Text Portuguese=<&Retornar - Text Spanish=<&Retroceder - Text Italian=< &Indietro - Text Danish=<&Tilbage - Text Dutch=<&Terug - Text Norwegian=<&Tilbake - Text Swedish=< &Tillbaka - end - item: Push Button - Rectangle=222 185 264 199 - Action=3 - Create Flags=01010000000000010000000000000000 - Text=Cancel - Text French=Annuler - Text German=Abbrechen - Text Portuguese=Cancelar - Text Spanish=Cancelar - Text Italian=Annulla - Text Danish=Annuller - Text Dutch=Annuleren - Text Norwegian=Avbryt - Text Swedish=Avbryt - end - item: Static - Rectangle=9 177 263 178 - Action=3 - Create Flags=01010000000000000000000000000111 - end - item: Static - Rectangle=90 10 260 70 - Create Flags=01010000000000000000000000000000 - Text=You are now ready to install %APPTITLE%. - Text= - Text=Press the Next button to begin the installation or the Back button to reenter the installation information. - Text French=Vous êtes maintenant prêt à installer %APPTITLE% - Text French= - Text French=Cliquez sur Suivant pour commencer l'installation ou Retour pour entrer à nouveau les informations d'installation - Text German=Sie sind jetzt zur Installation von %APPTITLE% bereit. - Text German= - Text German=Auf die Schaltfläche Weiter klicken, um mit dem Start der Installation zu beginnen, oder auf die Schaltfläche Zurück, um die Installationsinformationen nochmals aufzurufen. - Text Portuguese=Está agora pronto para instalar %APPTITLE% - Text Portuguese= - Text Portuguese=Pressione o botão Próximo para começar a instalação ou o botão Retornar para introduzir novamente a informação sobre a instalação - Text Spanish=Ahora estará listo para instalar %APPTITLE%. - Text Spanish= - Text Spanish=Pulse el botón de Siguiente para comenzar la instalación o el botón Retroceder para volver a introducir la información sobre la instalación. - Text Italian=Sei pronto ad installare %APPTITLE%. - Text Italian= - Text Italian=Premi il tasto Avanti per iniziare l’installazione o il tasto Indietro per rientrare nuovamente nei dati sull’installazione - Text Danish=Du er nu klar til at installere %APPTITLE%. - Text Danish= - Text Danish=Klik på Næste for at starte installationen eller på Tilbage for at ændre installationsoplysningerne. - Text Dutch=U bent nu klaar om %APPTITLE% te installeren. - Text Dutch= - Text Dutch=Druk op Volgende om met de installatie te beginnen of op Terug om de installatie-informatie opnieuw in te voeren. - Text Norwegian=Du er nå klar til å installere %APPTITLE% - Text Norwegian= - Text Norwegian=Trykk på Neste-tasten for å starte installeringen, eller Tilbake-tasten for å taste inn installasjonsinformasjonen på nytt. - Text Swedish=Du är nu redo att installera %APPTITLE%. - Text Swedish= - Text Swedish=Tryck på Nästa för att starta installationen eller på Tillbaka för att skriva in installationsinformationen på nytt. - end - end -end -item: If/While Statement - Variable=DISPLAY - Value=Select Destination Directory -end -item: Set Variable - Variable=BACKUP - Value=%MAINDIR%\wxPython\BACKUP -end -item: End Block -end -item: End Block -end -item: If/While Statement - Variable=DOBACKUP - Value=A -end -item: Set Variable - Variable=BACKUPDIR - Value=%BACKUP% -end -item: End Block -end -item: If/While Statement - Variable=BRANDING - Value=1 -end -item: If/While Statement - Variable=DOBRAND - Value=1 -end -item: Edit INI File - Pathname=%INST%\CUSTDATA.INI - Settings=[Registration] - Settings=NAME=%NAME% - Settings=COMPANY=%COMPANY% - Settings= -end -item: End Block -end -item: End Block -end -item: Remark -end -item: Set Variable - Variable=INST_LOG_PATH - Value=%MAINDIR%\wxPython\install.log -end -item: Open/Close INSTALL.LOG - Pathname=%INST_LOG_PATH% - Flags=00000010 -end -item: Check Disk Space - Component=COMPONENTS -end -item: Remark -end -item: Install File - Source=c:\WINNT\System32\Msvcirt.dll - Destination=%SYS%\Msvcirt.dll - Flags=0000001010000011 -end -item: Install File - Source=c:\WINNT\System32\Msvcrt.dll - Destination=%SYS%\Msvcrt.dll - Flags=0000001010000011 -end -item: Install File - Source=c:\projects\wx\lib\wx22_5.dll - Destination=%MAINDIR%\wxPython\wx22_5.dll - Flags=0000000010010010 -end -item: Install File - Source=c:\Projects\wx\wxPython\wxPython\*.py - Destination=%MAINDIR%\wxPython - Description=wxPython shadow class modules - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\wxPython\*.pyd - Destination=%MAINDIR%\wxPython - Description=wxPython extension modules - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\wxPython\*.txt - Destination=%MAINDIR%\wxPython - Description=README file - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\wxPython\lib\*.py - Destination=%MAINDIR%\wxPython\lib - Description=wxPython Standard Library - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\wxPython\lib\editor\*.py - Destination=%MAINDIR%\wxPython\lib\editor - Description=wxPython Standard Library - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\wxPython\lib\editor\*.txt - Destination=%MAINDIR%\wxPython\lib\editor - Description=wxPython Standard Library - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\*.py - Destination=%MAINDIR%\wxPython\demo - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\README.txt - Destination=%MAINDIR%\wxPython\demo\README.txt - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\*.xml - Destination=%MAINDIR%\wxPython\demo - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\bitmaps\*.bmp - Destination=%MAINDIR%\wxPython\demo\bitmaps - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\bitmaps\*.gif - Destination=%MAINDIR%\wxPython\demo\bitmaps - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\bitmaps\*.jpg - Destination=%MAINDIR%\wxPython\demo\bitmaps - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\bitmaps\*.png - Destination=%MAINDIR%\wxPython\demo\bitmaps - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\bitmaps\*.ico - Destination=%MAINDIR%\wxPython\demo\bitmaps - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\*.htm - Destination=%MAINDIR%\wxPython\demo\data - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\*.html - Destination=%MAINDIR%\wxPython\demo\data - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\*.py - Destination=%MAINDIR%\wxPython\demo\data - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\*.png - Destination=%MAINDIR%\wxPython\demo\data - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\grid.i - Destination=%MAINDIR%\wxPython\demo\data\grid.i - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\stc.h - Destination=%MAINDIR%\wxPython\demo\data\stc.h - Description=Demos - Flags=0000000010000010 -end -item: Install File - Source=c:\Projects\wx\wxPython\demo\data\tips.txt - Destination=%MAINDIR%\wxPython\demo\data\tips.txt - Description=Demos - Flags=0000000010000010 -end -item: Remark -end -item: Install File - Source=C:\PROJECTS\wx\wxPython\*.txt - Destination=%MAINDIR%\wxPython\docs\ - Flags=0000000010000010 -end -item: Install File - Source=C:\PROJECTS\wx\wxPython\licence\*.txt - Destination=%MAINDIR%\wxPython\docs\licence\ - Flags=0000000010000010 -end -item: Remark -end -item: Install File - Source=C:\PROJECTS\wx\docs\htmlhelp\wx.chm - Destination=%MAINDIR%\wxPython\docs\wx.chm - Description=wxPython documentation - Flags=0000000010000010 -end -item: Install File - Source=c:\PROJECTS\wx\docs\htmlhelp\ogl.chm - Destination=%MAINDIR%\wxPython\docs\ogl.chm - Description=wxPython documentation - Flags=0000000010000010 -end -item: Remark -end -item: Remark -end -item: Remark - Text= Install Support for uninstalling the application. -end -item: Set Variable - Variable=UNINSTALL_PATH - Value=%MAINDIR%\wxPython\UNWISE.EXE -end -item: Compiler Variable If - Variable=_EXE_OS_TYPE_ - Value=WIN32 -end -item: Install File - Source=%_WISE_%\UNWISE32.EXE - Destination=%UNINSTALL_PATH% - Flags=0000000000000010 -end -item: Compiler Variable Else -end -item: Install File - Source=%_WISE_%\UNWISE.EXE - Destination=%UNINSTALL_PATH% - Flags=0000000000000010 -end -item: Compiler Variable End -end -item: Remark -end -item: Remark - Text= Install the add/remove or uninstall icon -end -item: Set Variable - Variable=UNINSTALL_PATH - Value=%UNINSTALL_PATH% - Flags=00010100 -end -item: Set Variable - Variable=INST_LOG_PATH - Value=%INST_LOG_PATH% - Flags=00010100 -end -item: Check Configuration - Flags=10111011 -end -item: Edit Registry - Total Keys=1 - Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE% - New Value=%APPTITLE% - Value Name=DisplayName - Root=2 -end -item: Edit Registry - Total Keys=1 - Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\%APPTITLE% - New Value=%UNINSTALL_PATH% /A %INST_LOG_PATH% - New Value= - Value Name=UninstallString - Root=2 -end -item: Else Statement -end -item: End Block -end -item: Remark -end -item: Remark -end -item: Add Text to INSTALL.LOG - Text=File Tree: %MAINDIR%\wxPython\*.* -end -item: Remark -end -item: Set Variable - Variable=COMMON - Value=%COMMON% - Flags=00010100 -end -item: Set Variable - Variable=MAINDIR - Value=%MAINDIR% - Flags=00010100 -end -item: Check Configuration - Flags=10111011 -end -item: Get Registry Key Value - Variable=STARTUPDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%WIN%\Start Menu\Programs\StartUp - Value Name=StartUp - Flags=00000010 -end -item: Get Registry Key Value - Variable=DESKTOPDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%WIN%\Desktop - Value Name=Desktop - Flags=00000010 -end -item: Get Registry Key Value - Variable=STARTMENUDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%WIN%\Start Menu - Value Name=Start Menu - Flags=00000010 -end -item: Get Registry Key Value - Variable=GROUPDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%WIN%\Start Menu\Programs - Value Name=Programs - Flags=00000010 -end -item: Get Registry Key Value - Variable=CSTARTUPDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%STARTUPDIR% - Value Name=Common Startup - Flags=00000100 -end -item: Get Registry Key Value - Variable=CDESKTOPDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%DESKTOPDIR% - Value Name=Common Desktop - Flags=00000100 -end -item: Get Registry Key Value - Variable=CSTARTMENUDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%STARTMENUDIR% - Value Name=Common Start Menu - Flags=00000100 -end -item: Get Registry Key Value - Variable=CGROUPDIR - Key=Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders - Default=%GROUPDIR% - Value Name=Common Programs - Flags=00000100 -end -item: Set Variable - Variable=CGROUP_SAVE - Value=%GROUP% -end -item: Set Variable - Variable=GROUP - Value=%GROUPDIR%\%GROUP% -end -item: Create Shortcut - Source=%PYTHONDIR%\pythonw.exe - Destination=%CGROUPDIR%\%CGROUP_SAVE%\Run the DEMO.lnk - Command Options=demo.py - Working Directory=%MAINDIR%\wxPython\demo - Icon Number=0 - Key Type=1536 - Flags=00000001 -end -item: Create Shortcut - Source=%MAINDIR%\wxPython\docs\wx.chm - Destination=%CGROUPDIR%\%CGROUP_SAVE%\wxWindows User Guide.lnk - Icon Number=0 -end -item: Create Shortcut - Source=%MAINDIR%\wxPython\docs\ogl.chm - Destination=%CGROUPDIR%\%CGROUP_SAVE%\wxOGL User Guide.lnk - Icon Number=0 - Key Type=1536 - Flags=00000001 -end -item: Create Shortcut - Source=%MAINDIR%\wxPython\docs\licence\licence.txt - Destination=%CGROUPDIR%\%CGROUP_SAVE%\License.lnk - Icon Number=0 - Key Type=1536 - Flags=00000001 -end -item: Create Shortcut - Source=%MAINDIR%\wxPython\docs\README.txt - Destination=%CGROUPDIR%\%CGROUP_SAVE%\ReadMe.lnk - Icon Number=0 - Key Type=1536 - Flags=00000001 -end -item: Create Shortcut - Source=%MAINDIR%\wxPython\docs\CHANGES.txt - Destination=%CGROUPDIR%\%CGROUP_SAVE%\Changes.lnk - Icon Number=0 - Key Type=1536 - Flags=00000001 -end -item: Create Shortcut - Source=%UNINSTALL_PATH% - Destination=%CGROUPDIR%\%CGROUP_SAVE%\Uninstall %APPTITLE%.lnk - Command Options=%INST_LOG_PATH% - Icon Number=0 -end -item: Else Statement -end -item: Add ProgMan Icon - Group=%GROUP% - Icon Name=Uninstall %APPTITLE% - Command Line=%UNINSTALL_PATH% %INST_LOG_PATH% -end -item: Add ProgMan Icon - Group=%GROUP% - Icon Name=Run the DEMO - Command Line=pythonw.exe demo.py - Default Directory=%MAINDIR%\wxPython\demo -end -item: Add ProgMan Icon - Group=%GROUP% - Icon Name=wxWindows User Guide - Command Line=%MAINDIR%\wxPython\docs\wx.chm -end -item: End Block -end -item: Self-Register OCXs/DLLs - Description=Updating System Configuration, Please Wait... -end -remarked item: Edit Registry - Total Keys=1 - Key=SOFTWARE\Python\PythonCore\%PYTHONVER%\PythonPath\wxPython - New Value=%MAINDIR% - New Value= - Root=2 -end -item: Wizard Block - Direction Variable=DIRECTION - Display Variable=DISPLAY - Bitmap Pathname=%_WISE_%\DIALOGS\TEMPLATE\WIZARD.BMP - X Position=9 - Y Position=10 - Filler Color=8421440 - Flags=00000011 -end -item: Custom Dialog Set - Name=Finished - Display Variable=DISPLAY - item: Dialog - Title=Installation Complete - Title French=Installation en cours - Title German=Installation abgeschlossen - Title Portuguese=Instalação Completa - Title Spanish=Se ha completado la Instalación - Title Italian=Installazione completata - Title Danish=Installation gennemført - Title Dutch=Installatie afgerond - Title Norwegian=Installasjonen er fullført - Title Swedish=Installationen klar - Width=280 - Height=224 - Font Name=Helv - Font Size=8 - item: Push Button - Rectangle=170 185 212 199 - Variable=DIRECTION - Value=N - Create Flags=01010000000000010000000000000001 - Text=&Finish > - Text French=&Terminer> - Text German=&Fertigstellen> - Text Portuguese=&Terminar > - Text Spanish=&Finalizar> - Text Italian=&Fine > - Text Danish=&Afslut > - Text Dutch=&Klaar> - Text Norwegian=&Avslutt> - Text Swedish=&Sluta> - end - item: Push Button - Control Name=CANCEL - Rectangle=222 185 264 199 - Action=3 - Create Flags=01010000000000010000000000000000 - Text=Cancel - Text French=Annuler - Text German=Abbrechen - Text Portuguese=Cancelar - Text Spanish=Cancelar - Text Italian=Annulla - Text Danish=Annuller - Text Dutch=Annuleren - Text Norwegian=Avbryt - Text Swedish=Avbryt - end - item: Static - Rectangle=9 177 263 178 - Action=3 - Create Flags=01010000000000000000000000000111 - end - item: Static - Rectangle=90 10 260 63 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000000000000000000000 - Text=%APPTITLE% has been successfully installed. - Text= - Text= - Text=Press the Finish button to exit this installation. - Text= - Text French=L'installation de %APPTITLE% est réussie - Text French= - Text French= - Text French=Cliquez sur Terminer pour quitter cette installation - Text French= - Text German=%APPTITLE% wurde erfolgreich installiert. - Text German= - Text German= - Text German=Zum Beenden dieser Installation Fertigstellen anklicken. - Text German= - Text Portuguese=%APPTITLE% foi instalado com êxito - Text Portuguese= - Text Portuguese= - Text Portuguese=Pressionar o botão Terminar para sair desta instalação - Text Portuguese= - Text Spanish=%APPTITLE% se ha instalado con éxito. - Text Spanish= - Text Spanish= - Text Spanish=Pulse el botón de Finalizar para salir de esta instalación. - Text Spanish= - Text Italian=%APPTITLE% è stato installato. - Text Italian= - Text Italian= - Text Italian=Premi il pulsante Fine per uscire dal programma di installazione - Text Italian= - Text Danish=%APPTITLE% er nu installeret korrekt. - Text Danish= - Text Danish= - Text Danish=Klik på Afslut for at afslutte installationen. - Text Danish= - Text Dutch=%APPTITLE% is met succes geïnstalleerd. - Text Dutch= - Text Dutch= - Text Dutch=Druk op Klaar om deze installatie af te ronden. - Text Dutch= - Text Norwegian=Installasjonen av %APPTITLE% er vellykket. - Text Norwegian= - Text Norwegian= - Text Norwegian=Trykk på Avslutt-tasten for å avslutte denne installasjonen. - Text Norwegian= - Text Swedish=Installationen av %APPTITLE% har lyckats. - Text Swedish= - Text Swedish= - Text Swedish=Tryck på Sluta för att gå ur installationsprogrammet. - Text Swedish= - end - item: Push Button - Control Name=BACK - Rectangle=128 185 170 199 - Variable=DIRECTION - Value=B - Create Flags=01010000000000010000000000000000 - Text=< &Back - Text French=<&Retour - Text German=<&Zurück - Text Portuguese=<&Retornar - Text Spanish=<&Retroceder - Text Italian=< &Indietro - Text Danish=<&Tilbage - Text Dutch=<&Terug - Text Norwegian=<&Tilbake - Text Swedish=< &Tillbaka - end - item: Push Button - Rectangle=90 68 153 82 - Alternate=0%MAINDIR%\wxPython\docs\README.txt - Action=6 - Enabled Color=00000000000000001111111111111111 - Create Flags=01010000000000010000000000000000 - Text=View README.txt - end - item: Set Control Attribute - Control Name=BACK - Operation=1 - end - item: Set Control Attribute - Control Name=CANCEL - Operation=1 - end - end -end -item: End Block -end -item: New Event - Name=Cancel -end -item: Include Script - Pathname=%_WISE_%\INCLUDE\rollback.wse -end diff --git a/wxPython/distrib/wxPythonFull.spec.in b/wxPython/distrib/wxPythonFull.spec.in index 8dbf5154b6..fa0745bb6f 100644 --- a/wxPython/distrib/wxPythonFull.spec.in +++ b/wxPython/distrib/wxPythonFull.spec.in @@ -1,33 +1,34 @@ %define pref %{_prefix} %define python @PYTHON@ %define pyver @PYVER@ -%define debug @DEBUG@ %define port @PORT@ %define lcport @LCPORT@ +%define unicode @UNICODE@ %define tarname @TARNAME@ %define version @VERSION@ %define ver2 @VER2@ %define release 1 %define wxpref %{pref}/lib/wxPython +%define name wxPython%{port}-py%{pyver} -# Should --enable-debug_flag be used in release builds? -%define debug_flag 1 +# Should the builtin image and etc. libs be used, or system libs? +# Distro specific RPMs should probably set this to 0, generic ones +# should use 1 +%define builtin_libs 1 -%if %{debug} - %define name wxPython%{port}-py%{pyver}-dbg - %define othername wxPython%{port}-py%{pyver} -%else - %define name wxPython%{port}-py%{pyver} - %define othername wxPython%{port}-py%{pyver}-dbg -%endif +# Should --enable-debug_flag be used in release builds? Using it +# defines __WXDEBUG__ and gives us runtime diagnostics that are turned +# into Python exceptions starting with 2.3.4. (So turning it on is a +# very helpful thing IMO and is recommended.) +%define debug_flag 1 -%if %{debug} || %{debug_flag} - %define wxconfigname %{wxpref}/bin/wx%{lcport}d-%{ver2}-config -%else - %define wxconfigname %{wxpref}/bin/wx%{lcport}-%{ver2}-config -%endif + +# build the name of the real wx-config from the port, flags, etc. +%define dbgflg %(if [ "%{debug_flag}" = "1" ]; then echo d; fi) +%define uniflg %(if [ "%{unicode}" = "1" ]; then echo u; fi) +%define wxconfigname %{wxpref}/bin/wx%{lcport}%{uniflg}%{dbgflg}-%{ver2}-config #---------------------------------------------------------------- @@ -44,13 +45,9 @@ BuildRoot: %{_tmppath}/%{name}-buildroot Prefix: %{pref} #BuildRequires: %{python} -Provides: wxwin -Provides: wx%{port} = %{version} Provides: wxPython = %{version} +Provides: wxPython%{port} = %{version} - -# They conflict with each other, so let them replace each other -Obsoletes: %{othername} # old wxPython packages Obsoletes: wxPython @@ -65,13 +62,13 @@ This package is implemented using the %{port} port of wxWindows, and includes the wx%{port} shared libs and etc. -%package devel +%package -n wxPython%{port}-devel Summary: wxPython%{port} development files Group: Development/Libraries Requires: wxPython%{port} = %{version} -%description devel +%description -n wxPython%{port}-devel This packages contains the headers and etc. for building apps or Python extension modules that use the same wx%{port} shared libraries that wxPython uses. @@ -89,129 +86,162 @@ else MAKE="make" fi +WXDIR=`pwd` mkdir build cd build -# Configure, trying to reduce dependencies -../configure --with-%{lcport} \ +# Configure, trying to reduce external dependencies +$WXDIR/configure --with-%{lcport} \ --prefix=%{wxpref} \ --disable-soname \ --enable-rpath=%{wxpref}/lib \ --with-opengl \ -%if %{debug} - --enable-debug \ -%else +%if %{unicode} + --enable-gtk2 \ + --enable-unicode \ +%endif + --enable-geometry \ --enable-optimise \ %if %{debug_flag} --enable-debug_flag \ %endif -%endif +%if %{builtin_libs} --with-libjpeg=builtin \ --with-libpng=builtin \ --with-libtiff=builtin \ --with-zlib=builtin \ - -## --enable-debug_flag \ -## --with-odbc \ +%endif # Build wxWindows $MAKE -cd ../locale -make allmo - - -# ** Unfortunately we have to do a bit of installation here so wxPython -# can be built. Perhaps wx-config should be changed to be able to be -# used from the build dir, maybe with an --inplace flag... Move these -# three lines to %install if/when that happens. -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT -cd ../build -make prefix=$RPM_BUILD_ROOT%{wxpref} install - # Now build wxPython -cd ../wxPython +cd $WXDIR/wxPython %{python} setup.py \ IN_CVS_TREE=1 \ NO_SCRIPTS=1 \ - WX_CONFIG="$RPM_BUILD_ROOT%{wxpref}/bin/wx-config --prefix=$RPM_BUILD_ROOT%{wxpref}" \ + WXPORT=%{lcport} \ + UNICODE=%{unicode} \ + WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" \ build +## WX_CONFIG="$WXDIR/build/wx-config --inplace --prefix=$RPM_BUILD_ROOT%{wxpref}" \ + + + +# Build wxrc (XRC resource tool) but don't use the makefiles since they expect +# a shared version of the xrc lib to have been built... +cd $WXDIR/contrib/utils/wxrc +WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" +wCC=`$WX_CONFIG --cc` +wCXX=`$WX_CONFIG --cxx` + +for f in wxrc.cpp ../../src/xrc/*.cpp; do + echo $f + $wCXX `$WX_CONFIG --cxxflags` -I ../../include -I ../../src/xrc/expat/xmlparse -I ../../src/xrc/expat/xmltok -c $f +done +for f in ../../src/xrc/expat/xmlparse/xmlparse.c ../../src/xrc/expat/xmltok/xmlrole.c ../../src/xrc/expat/xmltok/xmltok.c; do + echo $f + $wCC `$WX_CONFIG --cxxflags` -I ../../include -I ../../src/xrc/expat/xmlparse -I ../../src/xrc/expat/xmltok -c $f +done + +# the handlers are not needed +rm xh_*.o xmlrsall.o + +$wCXX `$WX_CONFIG --libs` *.o -o wxrc +strip wxrc + #---------------------------------------------------------------- %install -%find_lang wxstd -cd wxPython +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT + +# install wxWindows +WXDIR=`pwd` +cd build +make prefix=$RPM_BUILD_ROOT%{wxpref} install + +# install wxPython +cd $WXDIR/wxPython %{python} setup.py \ IN_CVS_TREE=1 \ NO_SCRIPTS=1 \ + WXPORT=%{lcport} \ + UNICODE=%{unicode} \ WX_CONFIG="$RPM_BUILD_ROOT%{wxpref}/bin/wx-config --prefix=$RPM_BUILD_ROOT%{wxpref}" \ install \ --root=$RPM_BUILD_ROOT # Since I want this RPM to be as generic as possible I won't let -# distutils copy the scripts, since it will mangle the #! line -# to use the real python pathname. Since some distros install -# python 2.2 as python2 and others as python, then I can't let -# it do that otherwise the dependencies will be fouled up. Copy -# them manually instead: +# distutils copy the scripts since it will mangle the #! line to use +# the real python pathname. Since some distros install python 2.2 as +# python2 and others as python, then I can't let distutils do that +# otherwise the dependencies will be fouled up. Copy them manually +# instead, leaving the #!/bin/env line intact. +# +# TODO: Should this be dependent on %{builtin_libs} or something like it? mkdir -p $RPM_BUILD_ROOT/usr/bin for s in \ + helpviewer \ img2png \ img2py \ img2xpm \ pycrust \ + pycwrap \ pyshell \ xrced; do - cp scripts/$s $RPM_BUILD_ROOT/usr/bin + cp scripts/$s $RPM_BUILD_ROOT/%{pref}/bin done +# Install wxrc +cp $WXDIR/contrib/utils/wxrc/wxrc $RPM_BUILD_ROOT/%{pref}/bin -#---------------------------------------------------------------- -%clean -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +# Generate the filelists. For some reason the %defattr below is still +# resulting in many (but not all) files not owned by root when just +# specifying directories and wildcards to be included in each package. +# So instead we'll build some explicit filelists here and use %attr on +# each entry. +cd $WXDIR +mkdir -p $RPM_BUILD_ROOT%{pref}/share/doc +GFL="%{python} wxPython/distrib/genfilelist.py" +$GFL $RPM_BUILD_ROOT %{pref} > FILELIST +$GFL -r $RPM_BUILD_ROOT %{pref}/bin >> FILELIST +$GFL $RPM_BUILD_ROOT %{pref}/lib >> FILELIST +$GFL -r $RPM_BUILD_ROOT %{pref}/lib/python%{pyver} >> FILELIST +$GFL -r $RPM_BUILD_ROOT %{pref}/share >> FILELIST +$GFL $RPM_BUILD_ROOT %{wxpref} >> FILELIST +$GFL $RPM_BUILD_ROOT %{wxpref}/lib >> FILELIST +$GFL $RPM_BUILD_ROOT "%{wxpref}/lib/libwx*" >> FILELIST +$GFL -r $RPM_BUILD_ROOT %{wxpref}/share >> FILELIST - -#---------------------------------------------------------------- -%post -/sbin/ldconfig +$GFL $RPM_BUILD_ROOT %{wxpref}/include > DEVELLIST +$GFL -r $RPM_BUILD_ROOT %{wxpref}/include/wx >> DEVELLIST +$GFL -r $RPM_BUILD_ROOT %{wxpref}/lib/wx >> DEVELLIST +$GFL $RPM_BUILD_ROOT %{wxconfigname} >> DEVELLIST +$GFL $RPM_BUILD_ROOT %{wxpref}/bin/wx-config >> DEVELLIST #---------------------------------------------------------------- -%postun -/sbin/ldconfig - +%clean +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT #---------------------------------------------------------------- -%files -%doc docs/preamble.txt -%doc docs/licence.txt -%doc docs/readme.txt -%doc docs/changes.txt -%doc wxPython/README.txt -%doc wxPython/CHANGES.txt + +%files -f FILELIST %defattr(-,root,root) -%{wxpref}/lib/libwx* -%{pref}/lib/python* -%{wxpref}/share/ -%{pref}/bin/* +%doc docs/preamble.txt docs/licence.txt docs/readme.txt docs/changes.txt +%doc wxPython/README.txt wxPython/CHANGES.txt -%files devel +%files -n wxPython%{port}-devel -f DEVELLIST %defattr(-,root,root) -%{wxpref}/include/wx -%{wxpref}/lib/wx -%{wxconfigname} -%{wxpref}/bin/wx-config #---------------------------------------------------------------- -%changelog - # end of file diff --git a/wxPython/distrib/zipall.bat b/wxPython/distrib/zipall.bat deleted file mode 100755 index c044043d11..0000000000 --- a/wxPython/distrib/zipall.bat +++ /dev/null @@ -1,4 +0,0 @@ - -find . | grep -v "/CVS" | grep -v "./build/" | grep -v "./distrib/" | grep -v ".pyd" | grep -v ".pdb" | grep -v "contrib/ogl/contrib" | grep -v "contrib/stc/contrib" | zip -@ wxPython.zip - - diff --git a/wxPython/distrib/zipit.bat b/wxPython/distrib/zipit.bat deleted file mode 100755 index ebb4928776..0000000000 --- a/wxPython/distrib/zipit.bat +++ /dev/null @@ -1,44 +0,0 @@ -@echo off - -rem **** Make a directory to build up a distribution tree -md _distrib_zip -md _distrib_zip\wxPython-%1 - -REM rem **** Copy the license files -REM copy %WXWIN%\docs\gpl.txt _distrib_zip\wxPython-%1 -REM copy %WXWIN%\docs\lgpl.txt _distrib_zip\wxPython-%1 -REM copy %WXWIN%\docs\licence.txt _distrib_zip\wxPython-%1 -REM copy %WXWIN%\docs\licendoc.txt _distrib_zip\wxPython-%1 -REM copy %WXWIN%\docs\preamble.txt _distrib_zip\wxPython-%1 - -REM rem **** Make a zip fron the live files -REM zip -@ -r _distrib_zip\temp.zip < distrib\wxPython.rsp - -REM rem **** Unzip it in our build dir -REM cd _distrib_zip\wxPython-%1 -REM unzip ..\temp.zip - -REM rem **** zip up the build dir -REM cd .. -REM zip -r ..\distrib\wxPython-src-%1.zip wxPython-%1 - -cd _distrib_zip - -rem **** copy the docs into the tree -md wxPython-%1\docs -md wxPython-%1\docs\wx -md wxPython-%1\docs\ogl -copy %WXWIN%\docs\html\wx\*.* wxPython-%1\docs\wx -copy wxPython-%1\docs\wx\wx.htm wxPython-%1\docs\wx\index.htm -copy %WXWIN%\docs\html\ogl\*.* wxPython-%1\docs\ogl -copy wxPython-%1\docs\ogl\ogl.htm wxPython-%1\docs\ogl\index.htm - -rem **** zip up the docs -rem zip -r ..\distrib\wxPython-docs-%1.zip wxPython-%1\docs -tar cvf ..\dist\wxPython-docs-%1.tar wxPython-%1 -gzip -9 ..\dist\wxPython-docs-%1.tar - - -rem **** Cleanup -cd .. -del /sxzy _distrib_zip diff --git a/wxPython/distutils/README b/wxPython/distutils/README new file mode 100644 index 0000000000..45c7ca8ca9 --- /dev/null +++ b/wxPython/distutils/README @@ -0,0 +1,22 @@ +This directory contains only a subset of the Distutils, specifically +the Python modules in the 'distutils' and 'distutils.command' +packages. This is all you need to distribute and install Python +modules using the Distutils. There is also a separately packaged +standalone version of the Distutils available for people who want to +upgrade the Distutils without upgrading Python, available from the +Distutils web page: + + http://www.python.org/sigs/distutils-sig/ + +The standalone version includes all of the code in this directory, +plus documentation, test scripts, examples, etc. + +The Distutils documentation is divided into two documents, "Installing +Python Modules", which explains how to install Python packages, and +"Distributing Python Modules", which explains how to write setup.py +files. Both documents are part of the standard Python documentation +set, and are available from http://www.python.org/doc/current/ . + + Greg Ward (gward@python.net) + +$Id$ diff --git a/wxPython/distutils/README_1st.txt b/wxPython/distutils/README_1st.txt new file mode 100644 index 0000000000..5a06b95c56 --- /dev/null +++ b/wxPython/distutils/README_1st.txt @@ -0,0 +1,19 @@ +This is a copy of the Distutils package from Python (currently version +2.3a2.) This newer copy of distutils is used for all versions of +Python to avoid some problems in the older versions that show up in +wxPython builds and to avoid having to make some ugly hacks in local +modules to work around them. + +There is one little 1-line customization (hack) in msvccompiler.py +that allows the CFLAGS to be given on the RC.EXE command line. This +is required so the wx.rc files can be found when it is #included. I've +submitted this patch to the Python project so if it gets into the main +Distutils distribution I can remove this code. (However, the newer +version of distutils should still always be used, at least on Windows, +so it will need to wait until there it a Distutils distribution that +can be installed on the older Pythons.) + +I have not yet applied any patches specifically for MSCV 7 yet. So +far it appears that if you have the PATH setup properly (like I +usually do) that distutils works as is. + diff --git a/wxPython/distutils/__init__.py b/wxPython/distutils/__init__.py new file mode 100644 index 0000000000..7873d297b3 --- /dev/null +++ b/wxPython/distutils/__init__.py @@ -0,0 +1,15 @@ +"""distutils + +The main package for the Python Module Distribution Utilities. Normally +used from a setup script as + + from distutils.core import setup + + setup (...) +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +__version__ = "1.0.3" diff --git a/wxPython/distutils/archive_util.py b/wxPython/distutils/archive_util.py new file mode 100644 index 0000000000..d5b3096617 --- /dev/null +++ b/wxPython/distutils/archive_util.py @@ -0,0 +1,173 @@ +"""distutils.archive_util + +Utility functions for creating archive files (tarballs, zip files, +that sort of thing).""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.errors import DistutilsExecError +from distutils.spawn import spawn +from distutils.dir_util import mkpath +from distutils import log + +def make_tarball (base_name, base_dir, compress="gzip", + verbose=0, dry_run=0): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. 'compress' must be "gzip" (the default), "compress", + "bzip2", or None. Both "tar" and the compression utility named by + 'compress' must be on the default program search path, so this is + probably Unix-specific. The output tar file will be named 'base_dir' + + ".tar", possibly plus the appropriate compression extension (".gz", + ".bz2" or ".Z"). Return the output filename. + """ + # XXX GNU tar 1.13 has a nifty option to add a prefix directory. + # It's pretty new, though, so we certainly can't require it -- + # but it would be nice to take advantage of it to skip the + # "create a tree of hardlinks" step! (Would also be nice to + # detect GNU tar to use its 'z' option and save a step.) + + compress_ext = { 'gzip': ".gz", + 'bzip2': '.bz2', + 'compress': ".Z" } + + # flags for compression program, each element of list will be an argument + compress_flags = {'gzip': ["-f9"], + 'compress': ["-f"], + 'bzip2': ['-f9']} + + if compress is not None and compress not in compress_ext.keys(): + raise ValueError, \ + "bad value for 'compress': must be None, 'gzip', or 'compress'" + + archive_name = base_name + ".tar" + mkpath(os.path.dirname(archive_name), dry_run=dry_run) + cmd = ["tar", "-cf", archive_name, base_dir] + spawn(cmd, dry_run=dry_run) + + if compress: + spawn([compress] + compress_flags[compress] + [archive_name], + dry_run=dry_run) + return archive_name + compress_ext[compress] + else: + return archive_name + +# make_tarball () + + +def make_zipfile (base_name, base_dir, verbose=0, dry_run=0): + """Create a zip file from all the files under 'base_dir'. The output + zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" + Python module (if available) or the InfoZIP "zip" utility (if installed + and found on the default search path). If neither tool is available, + raises DistutilsExecError. Returns the name of the output zip file. + """ + try: + import zipfile + except ImportError: + zipfile = None + + zip_filename = base_name + ".zip" + mkpath(os.path.dirname(zip_filename), dry_run=dry_run) + + # If zipfile module is not available, try spawning an external + # 'zip' command. + if zipfile is None: + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + + try: + spawn(["zip", zipoptions, zip_filename, base_dir], + dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise DistutilsExecError, \ + ("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + + else: + log.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + def visit (z, dirname, names): + for name in names: + path = os.path.normpath(os.path.join(dirname, name)) + if os.path.isfile(path): + z.write(path, path) + log.info("adding '%s'" % path) + + if not dry_run: + z = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + os.path.walk(base_dir, visit, z) + z.close() + + return zip_filename + +# make_zipfile () + + +ARCHIVE_FORMATS = { + 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"), + 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (make_zipfile, [],"ZIP file") + } + +def check_archive_formats (formats): + for format in formats: + if not ARCHIVE_FORMATS.has_key(format): + return format + else: + return None + +def make_archive (base_name, format, + root_dir=None, base_dir=None, + verbose=0, dry_run=0): + """Create an archive file (eg. zip or tar). 'base_name' is the name + of the file to create, minus any format-specific extension; 'format' + is the archive format: one of "zip", "tar", "ztar", or "gztar". + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + """ + save_cwd = os.getcwd() + if root_dir is not None: + log.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = { 'dry_run': dry_run } + + try: + format_info = ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError, "unknown archive format '%s'" % format + + func = format_info[0] + for (arg,val) in format_info[1]: + kwargs[arg] = val + filename = apply(func, (base_name, base_dir), kwargs) + + if root_dir is not None: + log.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + +# make_archive () diff --git a/wxPython/distutils/bcppcompiler.py b/wxPython/distutils/bcppcompiler.py new file mode 100644 index 0000000000..cfbe04ac01 --- /dev/null +++ b/wxPython/distutils/bcppcompiler.py @@ -0,0 +1,394 @@ +"""distutils.bcppcompiler + +Contains BorlandCCompiler, an implementation of the abstract CCompiler class +for the Borland C++ compiler. +""" + +# This implementation by Lyle Johnson, based on the original msvccompiler.py +# module and using the directions originally published by Gordon Williams. + +# XXX looks like there's a LOT of overlap between these two classes: +# someone should sit down and factor out the common code as +# WindowsCCompiler! --GPW + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + + +import sys, os +from distutils.errors import \ + DistutilsExecError, DistutilsPlatformError, \ + CompileError, LibError, LinkError, UnknownFileError +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options, gen_lib_options +from distutils.file_util import write_file +from distutils.dep_util import newer +from distutils import log + +class BCPPCompiler(CCompiler) : + """Concrete class that implements an interface to the Borland C/C++ + compiler, as defined by the CCompiler abstract class. + """ + + compiler_type = 'bcpp' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = _c_extensions + _cpp_extensions + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CCompiler.__init__ (self, verbose, dry_run, force) + + # These executables are assumed to all be in the path. + # Borland doesn't seem to use any special registry settings to + # indicate their installation locations. + + self.cc = "bcc32.exe" + self.linker = "ilink32.exe" + self.lib = "tlib.exe" + + self.preprocess_options = None + self.compile_options = ['/tWM', '/O2', '/q', '/g0'] + self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] + + self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] + self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] + self.ldflags_static = [] + self.ldflags_exe = ['/Gn', '/q', '/x'] + self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] + + + # -- Worker methods ------------------------------------------------ + + def compile(self, sources, + output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + compile_opts = extra_preargs or [] + compile_opts.append ('-c') + if debug: + compile_opts.extend (self.compile_options_debug) + else: + compile_opts.extend (self.compile_options) + + for obj, (src, ext) in build.items(): + # XXX why do the normpath here? + src = os.path.normpath(src) + obj = os.path.normpath(obj) + # XXX _setup_compile() did a mkpath() too but before the normpath. + # Is it possible to skip the normpath? + self.mkpath(os.path.dirname(obj)) + + if ext == '.res': + # This is already a binary file -- skip it. + continue # the 'for' loop + if ext == '.rc': + # This needs to be compiled to a .res file -- do it now. + try: + self.spawn (["brcc32", "-fo", obj, src]) + except DistutilsExecError, msg: + raise CompileError, msg + continue # the 'for' loop + + # The next two are both for the real compiler. + if ext in self._c_extensions: + input_opt = "" + elif ext in self._cpp_extensions: + input_opt = "-P" + else: + # Unknown file type -- no extra options. The compiler + # will probably fail, but let it just in case this is a + # file the compiler recognizes even if we don't. + input_opt = "" + + output_opt = "-o" + obj + + # Compiler command line syntax is: "bcc32 [options] file(s)". + # Note that the source file names must appear at the end of + # the command line. + try: + self.spawn ([self.cc] + compile_opts + pp_opts + + [input_opt, output_opt] + + extra_postargs + [src]) + except DistutilsExecError, msg: + raise CompileError, msg + + return objects + + # compile () + + + def create_static_lib (self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + + (objects, output_dir) = self._fix_object_args (objects, output_dir) + output_filename = \ + self.library_filename (output_libname, output_dir=output_dir) + + if self._need_link (objects, output_filename): + lib_args = [output_filename, '/u'] + objects + if debug: + pass # XXX what goes here? + try: + self.spawn ([self.lib] + lib_args) + except DistutilsExecError, msg: + raise LibError, msg + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # create_static_lib () + + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + # XXX this ignores 'build_temp'! should follow the lead of + # msvccompiler.py + + (objects, output_dir) = self._fix_object_args (objects, output_dir) + (libraries, library_dirs, runtime_library_dirs) = \ + self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) + + if runtime_library_dirs: + log.warn("I don't know what to do with 'runtime_library_dirs': %s", + str(runtime_library_dirs)) + + if output_dir is not None: + output_filename = os.path.join (output_dir, output_filename) + + if self._need_link (objects, output_filename): + + # Figure out linker args based on type of target. + if target_desc == CCompiler.EXECUTABLE: + startup_obj = 'c0w32' + if debug: + ld_args = self.ldflags_exe_debug[:] + else: + ld_args = self.ldflags_exe[:] + else: + startup_obj = 'c0d32' + if debug: + ld_args = self.ldflags_shared_debug[:] + else: + ld_args = self.ldflags_shared[:] + + + # Create a temporary exports file for use by the linker + if export_symbols is None: + def_file = '' + else: + head, tail = os.path.split (output_filename) + modname, ext = os.path.splitext (tail) + temp_dir = os.path.dirname(objects[0]) # preserve tree structure + def_file = os.path.join (temp_dir, '%s.def' % modname) + contents = ['EXPORTS'] + for sym in (export_symbols or []): + contents.append(' %s=_%s' % (sym, sym)) + self.execute(write_file, (def_file, contents), + "writing %s" % def_file) + + # Borland C++ has problems with '/' in paths + objects2 = map(os.path.normpath, objects) + # split objects in .obj and .res files + # Borland C++ needs them at different positions in the command line + objects = [startup_obj] + resources = [] + for file in objects2: + (base, ext) = os.path.splitext(os.path.normcase(file)) + if ext == '.res': + resources.append(file) + else: + objects.append(file) + + + for l in library_dirs: + ld_args.append("/L%s" % os.path.normpath(l)) + ld_args.append("/L.") # we sometimes use relative paths + + # list of object files + ld_args.extend(objects) + + # XXX the command-line syntax for Borland C++ is a bit wonky; + # certain filenames are jammed together in one big string, but + # comma-delimited. This doesn't mesh too well with the + # Unix-centric attitude (with a DOS/Windows quoting hack) of + # 'spawn()', so constructing the argument list is a bit + # awkward. Note that doing the obvious thing and jamming all + # the filenames and commas into one argument would be wrong, + # because 'spawn()' would quote any filenames with spaces in + # them. Arghghh!. Apparently it works fine as coded... + + # name of dll/exe file + ld_args.extend([',',output_filename]) + # no map file and start libraries + ld_args.append(',,') + + for lib in libraries: + # see if we find it and if there is a bcpp specific lib + # (xxx_bcpp.lib) + libfile = self.find_library_file(library_dirs, lib, debug) + if libfile is None: + ld_args.append(lib) + # probably a BCPP internal library -- don't warn + else: + # full name which prefers bcpp_xxx.lib over xxx.lib + ld_args.append(libfile) + + # some default libraries + ld_args.append ('import32') + ld_args.append ('cw32mt') + + # def file for export symbols + ld_args.extend([',',def_file]) + # add resource files + ld_args.append(',') + ld_args.extend(resources) + + + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + + self.mkpath (os.path.dirname (output_filename)) + try: + self.spawn ([self.linker] + ld_args) + except DistutilsExecError, msg: + raise LinkError, msg + + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # link () + + # -- Miscellaneous methods ----------------------------------------- + + + def find_library_file (self, dirs, lib, debug=0): + # List of effective library names to try, in order of preference: + # xxx_bcpp.lib is better than xxx.lib + # and xxx_d.lib is better than xxx.lib if debug is set + # + # The "_bcpp" suffix is to handle a Python installation for people + # with multiple compilers (primarily Distutils hackers, I suspect + # ;-). The idea is they'd have one static library for each + # compiler they care about, since (almost?) every Windows compiler + # seems to have a different format for static libraries. + if debug: + dlib = (lib + "_d") + try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib) + else: + try_names = (lib + "_bcpp", lib) + + for dir in dirs: + for name in try_names: + libfile = os.path.join(dir, self.library_filename(name)) + if os.path.exists(libfile): + return libfile + else: + # Oops, didn't find it in *any* of 'dirs' + return None + + # overwrite the one from CCompiler to support rc and res-files + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + if ext not in (self.src_extensions + ['.rc','.res']): + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % \ + (ext, src_name) + if strip_dir: + base = os.path.basename (base) + if ext == '.res': + # these can go unchanged + obj_names.append (os.path.join (output_dir, base + ext)) + elif ext == '.rc': + # these need to be compiled to .res-files + obj_names.append (os.path.join (output_dir, base + '.res')) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + def preprocess (self, + source, + output_file=None, + macros=None, + include_dirs=None, + extra_preargs=None, + extra_postargs=None): + + (_, macros, include_dirs) = \ + self._fix_compile_args(None, macros, include_dirs) + pp_opts = gen_preprocess_options(macros, include_dirs) + pp_args = ['cpp32.exe'] + pp_opts + if output_file is not None: + pp_args.append('-o' + output_file) + if extra_preargs: + pp_args[:0] = extra_preargs + if extra_postargs: + pp_args.extend(extra_postargs) + pp_args.append(source) + + # We need to preprocess: either we're being forced to, or the + # source file is newer than the target (or the target doesn't + # exist). + if self.force or output_file is None or newer(source, output_file): + if output_file: + self.mkpath(os.path.dirname(output_file)) + try: + self.spawn(pp_args) + except DistutilsExecError, msg: + print msg + raise CompileError, msg + + # preprocess() diff --git a/wxPython/distutils/ccompiler.py b/wxPython/distutils/ccompiler.py new file mode 100644 index 0000000000..bfcf1279f1 --- /dev/null +++ b/wxPython/distutils/ccompiler.py @@ -0,0 +1,1215 @@ +"""distutils.ccompiler + +Contains CCompiler, an abstract base class that defines the interface +for the Distutils compiler abstraction model.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, re +from types import * +from copy import copy +from distutils.errors import * +from distutils.spawn import spawn +from distutils.file_util import move_file +from distutils.dir_util import mkpath +from distutils.dep_util import newer_pairwise, newer_group +from distutils.sysconfig import python_build +from distutils.util import split_quoted, execute +from distutils import log + +class CCompiler: + """Abstract base class to define the interface that must be implemented + by real compiler classes. Also has some utility methods used by + several compiler classes. + + The basic idea behind a compiler abstraction class is that each + instance can be used for all the compile/link steps in building a + single project. Thus, attributes common to all of those compile and + link steps -- include directories, macros to define, libraries to link + against, etc. -- are attributes of the compiler instance. To allow for + variability in how individual files are treated, most of those + attributes may be varied on a per-compilation or per-link basis. + """ + + # 'compiler_type' is a class attribute that identifies this class. It + # keeps code that wants to know what kind of compiler it's dealing with + # from having to import all possible compiler classes just to do an + # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type' + # should really, really be one of the keys of the 'compiler_class' + # dictionary (see below -- used by the 'new_compiler()' factory + # function) -- authors of new compiler interface classes are + # responsible for updating 'compiler_class'! + compiler_type = None + + # XXX things not handled by this compiler abstraction model: + # * client can't provide additional options for a compiler, + # e.g. warning, optimization, debugging flags. Perhaps this + # should be the domain of concrete compiler abstraction classes + # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base + # class should have methods for the common ones. + # * can't completely override the include or library searchg + # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". + # I'm not sure how widely supported this is even by Unix + # compilers, much less on other platforms. And I'm even less + # sure how useful it is; maybe for cross-compiling, but + # support for that is a ways off. (And anyways, cross + # compilers probably have a dedicated binary with the + # right paths compiled in. I hope.) + # * can't do really freaky things with the library list/library + # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against + # different versions of libfoo.a in different locations. I + # think this is useless without the ability to null out the + # library search path anyways. + + + # Subclasses that rely on the standard filename generation methods + # implemented below should override these; see the comment near + # those methods ('object_filenames()' et. al.) for details: + src_extensions = None # list of strings + obj_extension = None # string + static_lib_extension = None + shared_lib_extension = None # string + static_lib_format = None # format string + shared_lib_format = None # prob. same as static_lib_format + exe_extension = None # string + + # Default language settings. language_map is used to detect a source + # file or Extension target language, checking source filenames. + # language_order is used to detect the language precedence, when deciding + # what language to use when mixing source types. For example, if some + # extension has two files with ".c" extension, and one with ".cpp", it + # is still linked as c++. + language_map = {".c" : "c", + ".cc" : "c++", + ".cpp" : "c++", + ".cxx" : "c++", + ".m" : "objc", + } + language_order = ["c++", "objc", "c"] + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + self.dry_run = dry_run + self.force = force + self.verbose = verbose + + # 'output_dir': a common output directory for object, library, + # shared object, and shared library files + self.output_dir = None + + # 'macros': a list of macro definitions (or undefinitions). A + # macro definition is a 2-tuple (name, value), where the value is + # either a string or None (no explicit value). A macro + # undefinition is a 1-tuple (name,). + self.macros = [] + + # 'include_dirs': a list of directories to search for include files + self.include_dirs = [] + + # 'libraries': a list of libraries to include in any link + # (library names, not filenames: eg. "foo" not "libfoo.a") + self.libraries = [] + + # 'library_dirs': a list of directories to search for libraries + self.library_dirs = [] + + # 'runtime_library_dirs': a list of directories to search for + # shared libraries/objects at runtime + self.runtime_library_dirs = [] + + # 'objects': a list of object files (or similar, such as explicitly + # named library files) to include on any link + self.objects = [] + + for key in self.executables.keys(): + self.set_executable(key, self.executables[key]) + + # __init__ () + + + def set_executables (self, **args): + + """Define the executables (and options for them) that will be run + to perform the various stages of compilation. The exact set of + executables that may be specified here depends on the compiler + class (via the 'executables' class attribute), but most will have: + compiler the C/C++ compiler + linker_so linker used to create shared objects and libraries + linker_exe linker used to create binary executables + archiver static library creator + + On platforms with a command-line (Unix, DOS/Windows), each of these + is a string that will be split into executable name and (optional) + list of arguments. (Splitting the string is done similarly to how + Unix shells operate: words are delimited by spaces, but quotes and + backslashes can override this. See + 'distutils.util.split_quoted()'.) + """ + + # Note that some CCompiler implementation classes will define class + # attributes 'cpp', 'cc', etc. with hard-coded executable names; + # this is appropriate when a compiler class is for exactly one + # compiler/OS combination (eg. MSVCCompiler). Other compiler + # classes (UnixCCompiler, in particular) are driven by information + # discovered at run-time, since there are many different ways to do + # basically the same things with Unix C compilers. + + for key in args.keys(): + if not self.executables.has_key(key): + raise ValueError, \ + "unknown executable '%s' for class %s" % \ + (key, self.__class__.__name__) + self.set_executable(key, args[key]) + + # set_executables () + + def set_executable(self, key, value): + if type(value) is StringType: + setattr(self, key, split_quoted(value)) + else: + setattr(self, key, value) + + + def _find_macro (self, name): + i = 0 + for defn in self.macros: + if defn[0] == name: + return i + i = i + 1 + + return None + + + def _check_macro_definitions (self, definitions): + """Ensures that every element of 'definitions' is a valid macro + definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do + nothing if all definitions are OK, raise TypeError otherwise. + """ + for defn in definitions: + if not (type (defn) is TupleType and + (len (defn) == 1 or + (len (defn) == 2 and + (type (defn[1]) is StringType or defn[1] is None))) and + type (defn[0]) is StringType): + raise TypeError, \ + ("invalid macro definition '%s': " % defn) + \ + "must be tuple (string,), (string, string), or " + \ + "(string, None)" + + + # -- Bookkeeping methods ------------------------------------------- + + def define_macro (self, name, value=None): + """Define a preprocessor macro for all compilations driven by this + compiler object. The optional parameter 'value' should be a + string; if it is not supplied, then the macro will be defined + without an explicit value and the exact outcome depends on the + compiler used (XXX true? does ANSI say anything about this?) + """ + # Delete from the list of macro definitions/undefinitions if + # already there (so that this one will take precedence). + i = self._find_macro (name) + if i is not None: + del self.macros[i] + + defn = (name, value) + self.macros.append (defn) + + + def undefine_macro (self, name): + """Undefine a preprocessor macro for all compilations driven by + this compiler object. If the same macro is defined by + 'define_macro()' and undefined by 'undefine_macro()' the last call + takes precedence (including multiple redefinitions or + undefinitions). If the macro is redefined/undefined on a + per-compilation basis (ie. in the call to 'compile()'), then that + takes precedence. + """ + # Delete from the list of macro definitions/undefinitions if + # already there (so that this one will take precedence). + i = self._find_macro (name) + if i is not None: + del self.macros[i] + + undefn = (name,) + self.macros.append (undefn) + + + def add_include_dir (self, dir): + """Add 'dir' to the list of directories that will be searched for + header files. The compiler is instructed to search directories in + the order in which they are supplied by successive calls to + 'add_include_dir()'. + """ + self.include_dirs.append (dir) + + def set_include_dirs (self, dirs): + """Set the list of directories that will be searched to 'dirs' (a + list of strings). Overrides any preceding calls to + 'add_include_dir()'; subsequence calls to 'add_include_dir()' add + to the list passed to 'set_include_dirs()'. This does not affect + any list of standard include directories that the compiler may + search by default. + """ + self.include_dirs = copy (dirs) + + + def add_library (self, libname): + """Add 'libname' to the list of libraries that will be included in + all links driven by this compiler object. Note that 'libname' + should *not* be the name of a file containing a library, but the + name of the library itself: the actual filename will be inferred by + the linker, the compiler, or the compiler class (depending on the + platform). + + The linker will be instructed to link against libraries in the + order they were supplied to 'add_library()' and/or + 'set_libraries()'. It is perfectly valid to duplicate library + names; the linker will be instructed to link against libraries as + many times as they are mentioned. + """ + self.libraries.append (libname) + + def set_libraries (self, libnames): + """Set the list of libraries to be included in all links driven by + this compiler object to 'libnames' (a list of strings). This does + not affect any standard system libraries that the linker may + include by default. + """ + self.libraries = copy (libnames) + + + def add_library_dir (self, dir): + """Add 'dir' to the list of directories that will be searched for + libraries specified to 'add_library()' and 'set_libraries()'. The + linker will be instructed to search for libraries in the order they + are supplied to 'add_library_dir()' and/or 'set_library_dirs()'. + """ + self.library_dirs.append (dir) + + def set_library_dirs (self, dirs): + """Set the list of library search directories to 'dirs' (a list of + strings). This does not affect any standard library search path + that the linker may search by default. + """ + self.library_dirs = copy (dirs) + + + def add_runtime_library_dir (self, dir): + """Add 'dir' to the list of directories that will be searched for + shared libraries at runtime. + """ + self.runtime_library_dirs.append (dir) + + def set_runtime_library_dirs (self, dirs): + """Set the list of directories to search for shared libraries at + runtime to 'dirs' (a list of strings). This does not affect any + standard search path that the runtime linker may search by + default. + """ + self.runtime_library_dirs = copy (dirs) + + + def add_link_object (self, object): + """Add 'object' to the list of object files (or analogues, such as + explicitly named library files or the output of "resource + compilers") to be included in every link driven by this compiler + object. + """ + self.objects.append (object) + + def set_link_objects (self, objects): + """Set the list of object files (or analogues) to be included in + every link to 'objects'. This does not affect any standard object + files that the linker may include by default (such as system + libraries). + """ + self.objects = copy (objects) + + + # -- Private utility methods -------------------------------------- + # (here for the convenience of subclasses) + + # Helper method to prep compiler in subclass compile() methods + + def _setup_compile(self, outdir, macros, incdirs, sources, depends, + extra): + """Process arguments and decide which source files to compile. + + Merges _fix_compile_args() and _prep_compile(). + """ + if outdir is None: + outdir = self.output_dir + elif type(outdir) is not StringType: + raise TypeError, "'output_dir' must be a string or None" + + if macros is None: + macros = self.macros + elif type(macros) is ListType: + macros = macros + (self.macros or []) + else: + raise TypeError, "'macros' (if supplied) must be a list of tuples" + + if incdirs is None: + incdirs = self.include_dirs + elif type(incdirs) in (ListType, TupleType): + incdirs = list(incdirs) + (self.include_dirs or []) + else: + raise TypeError, \ + "'include_dirs' (if supplied) must be a list of strings" + + if extra is None: + extra = [] + + # Get the list of expected output (object) files + objects = self.object_filenames(sources, + strip_dir=python_build, + output_dir=outdir) + assert len(objects) == len(sources) + + # XXX should redo this code to eliminate skip_source entirely. + # XXX instead create build and issue skip messages inline + + if self.force: + skip_source = {} # rebuild everything + for source in sources: + skip_source[source] = 0 + elif depends is None: + # If depends is None, figure out which source files we + # have to recompile according to a simplistic check. We + # just compare the source and object file, no deep + # dependency checking involving header files. + skip_source = {} # rebuild everything + for source in sources: # no wait, rebuild nothing + skip_source[source] = 1 + + n_sources, n_objects = newer_pairwise(sources, objects) + for source in n_sources: # no really, only rebuild what's + skip_source[source] = 0 # out-of-date + else: + # If depends is a list of files, then do a different + # simplistic check. Assume that each object depends on + # its source and all files in the depends list. + skip_source = {} + # L contains all the depends plus a spot at the end for a + # particular source file + L = depends[:] + [None] + for i in range(len(objects)): + source = sources[i] + L[-1] = source + if newer_group(L, objects[i]): + skip_source[source] = 0 + else: + skip_source[source] = 1 + + pp_opts = gen_preprocess_options(macros, incdirs) + + build = {} + for i in range(len(sources)): + src = sources[i] + obj = objects[i] + ext = os.path.splitext(src)[1] + self.mkpath(os.path.dirname(obj)) + if skip_source[src]: + log.debug("skipping %s (%s up-to-date)", src, obj) + else: + build[obj] = src, ext + + return macros, objects, extra, pp_opts, build + + def _get_cc_args(self, pp_opts, debug, before): + # works for unixccompiler, emxccompiler, cygwinccompiler + cc_args = pp_opts + ['-c'] + if debug: + cc_args[:0] = ['-g'] + if before: + cc_args[:0] = before + return cc_args + + def _fix_compile_args (self, output_dir, macros, include_dirs): + """Typecheck and fix-up some of the arguments to the 'compile()' + method, and return fixed-up values. Specifically: if 'output_dir' + is None, replaces it with 'self.output_dir'; ensures that 'macros' + is a list, and augments it with 'self.macros'; ensures that + 'include_dirs' is a list, and augments it with 'self.include_dirs'. + Guarantees that the returned values are of the correct type, + i.e. for 'output_dir' either string or None, and for 'macros' and + 'include_dirs' either list or None. + """ + if output_dir is None: + output_dir = self.output_dir + elif type (output_dir) is not StringType: + raise TypeError, "'output_dir' must be a string or None" + + if macros is None: + macros = self.macros + elif type (macros) is ListType: + macros = macros + (self.macros or []) + else: + raise TypeError, "'macros' (if supplied) must be a list of tuples" + + if include_dirs is None: + include_dirs = self.include_dirs + elif type (include_dirs) in (ListType, TupleType): + include_dirs = list (include_dirs) + (self.include_dirs or []) + else: + raise TypeError, \ + "'include_dirs' (if supplied) must be a list of strings" + + return output_dir, macros, include_dirs + + # _fix_compile_args () + + + def _prep_compile(self, sources, output_dir, depends=None): + """Decide which souce files must be recompiled. + + Determine the list of object files corresponding to 'sources', + and figure out which ones really need to be recompiled. + Return a list of all object files and a dictionary telling + which source files can be skipped. + """ + # Get the list of expected output (object) files + objects = self.object_filenames(sources, strip_dir=python_build, + output_dir=output_dir) + assert len(objects) == len(sources) + + if self.force: + skip_source = {} # rebuild everything + for source in sources: + skip_source[source] = 0 + elif depends is None: + # If depends is None, figure out which source files we + # have to recompile according to a simplistic check. We + # just compare the source and object file, no deep + # dependency checking involving header files. + skip_source = {} # rebuild everything + for source in sources: # no wait, rebuild nothing + skip_source[source] = 1 + + n_sources, n_objects = newer_pairwise(sources, objects) + for source in n_sources: # no really, only rebuild what's + skip_source[source] = 0 # out-of-date + else: + # If depends is a list of files, then do a different + # simplistic check. Assume that each object depends on + # its source and all files in the depends list. + skip_source = {} + # L contains all the depends plus a spot at the end for a + # particular source file + L = depends[:] + [None] + for i in range(len(objects)): + source = sources[i] + L[-1] = source + if newer_group(L, objects[i]): + skip_source[source] = 0 + else: + skip_source[source] = 1 + + return objects, skip_source + + # _prep_compile () + + + def _fix_object_args (self, objects, output_dir): + """Typecheck and fix up some arguments supplied to various methods. + Specifically: ensure that 'objects' is a list; if output_dir is + None, replace with self.output_dir. Return fixed versions of + 'objects' and 'output_dir'. + """ + if type (objects) not in (ListType, TupleType): + raise TypeError, \ + "'objects' must be a list or tuple of strings" + objects = list (objects) + + if output_dir is None: + output_dir = self.output_dir + elif type (output_dir) is not StringType: + raise TypeError, "'output_dir' must be a string or None" + + return (objects, output_dir) + + + def _fix_lib_args (self, libraries, library_dirs, runtime_library_dirs): + """Typecheck and fix up some of the arguments supplied to the + 'link_*' methods. Specifically: ensure that all arguments are + lists, and augment them with their permanent versions + (eg. 'self.libraries' augments 'libraries'). Return a tuple with + fixed versions of all arguments. + """ + if libraries is None: + libraries = self.libraries + elif type (libraries) in (ListType, TupleType): + libraries = list (libraries) + (self.libraries or []) + else: + raise TypeError, \ + "'libraries' (if supplied) must be a list of strings" + + if library_dirs is None: + library_dirs = self.library_dirs + elif type (library_dirs) in (ListType, TupleType): + library_dirs = list (library_dirs) + (self.library_dirs or []) + else: + raise TypeError, \ + "'library_dirs' (if supplied) must be a list of strings" + + if runtime_library_dirs is None: + runtime_library_dirs = self.runtime_library_dirs + elif type (runtime_library_dirs) in (ListType, TupleType): + runtime_library_dirs = (list (runtime_library_dirs) + + (self.runtime_library_dirs or [])) + else: + raise TypeError, \ + "'runtime_library_dirs' (if supplied) " + \ + "must be a list of strings" + + return (libraries, library_dirs, runtime_library_dirs) + + # _fix_lib_args () + + + def _need_link (self, objects, output_file): + """Return true if we need to relink the files listed in 'objects' + to recreate 'output_file'. + """ + if self.force: + return 1 + else: + if self.dry_run: + newer = newer_group (objects, output_file, missing='newer') + else: + newer = newer_group (objects, output_file) + return newer + + # _need_link () + + def detect_language (self, sources): + """Detect the language of a given file, or list of files. Uses + language_map, and language_order to do the job. + """ + if type(sources) is not ListType: + sources = [sources] + lang = None + index = len(self.language_order) + for source in sources: + base, ext = os.path.splitext(source) + extlang = self.language_map.get(ext) + try: + extindex = self.language_order.index(extlang) + if extindex < index: + lang = extlang + index = extindex + except ValueError: + pass + return lang + + # detect_language () + + # -- Worker methods ------------------------------------------------ + # (must be implemented by subclasses) + + def preprocess (self, + source, + output_file=None, + macros=None, + include_dirs=None, + extra_preargs=None, + extra_postargs=None): + """Preprocess a single C/C++ source file, named in 'source'. + Output will be written to file named 'output_file', or stdout if + 'output_file' not supplied. 'macros' is a list of macro + definitions as for 'compile()', which will augment the macros set + with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a + list of directory names that will be added to the default list. + + Raises PreprocessError on failure. + """ + pass + + def compile(self, sources, output_dir=None, macros=None, + include_dirs=None, debug=0, extra_preargs=None, + extra_postargs=None, depends=None): + """Compile one or more source files. + + 'sources' must be a list of filenames, most likely C/C++ + files, but in reality anything that can be handled by a + particular compiler and compiler class (eg. MSVCCompiler can + handle resource files in 'sources'). Return a list of object + filenames, one per source filename in 'sources'. Depending on + the implementation, not all source files will necessarily be + compiled, but all corresponding object filenames will be + returned. + + If 'output_dir' is given, object files will be put under it, while + retaining their original path component. That is, "foo/bar.c" + normally compiles to "foo/bar.o" (for a Unix implementation); if + 'output_dir' is "build", then it would compile to + "build/foo/bar.o". + + 'macros', if given, must be a list of macro definitions. A macro + definition is either a (name, value) 2-tuple or a (name,) 1-tuple. + The former defines a macro; if the value is None, the macro is + defined without an explicit value. The 1-tuple case undefines a + macro. Later definitions/redefinitions/ undefinitions take + precedence. + + 'include_dirs', if given, must be a list of strings, the + directories to add to the default include file search path for this + compilation only. + + 'debug' is a boolean; if true, the compiler will be instructed to + output debug symbols in (or alongside) the object file(s). + + 'extra_preargs' and 'extra_postargs' are implementation- dependent. + On platforms that have the notion of a command-line (e.g. Unix, + DOS/Windows), they are most likely lists of strings: extra + command-line arguments to prepand/append to the compiler command + line. On other platforms, consult the implementation class + documentation. In any event, they are intended as an escape hatch + for those occasions when the abstract compiler framework doesn't + cut the mustard. + + 'depends', if given, is a list of filenames that all targets + depend on. If a source file is older than any file in + depends, then the source file will be recompiled. This + supports dependency tracking, but only at a coarse + granularity. + + Raises CompileError on failure. + """ + + # A concrete compiler class can either override this method + # entirely or implement _compile(). + + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) + + for obj, (src, ext) in build.items(): + self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) + + # Return *all* object filenames, not just the ones we just built. + return objects + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + """Compile 'src' to product 'obj'.""" + + # A concrete compiler class that does not override compile() + # should implement _compile(). + pass + + def create_static_lib (self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + """Link a bunch of stuff together to create a static library file. + The "bunch of stuff" consists of the list of object files supplied + as 'objects', the extra object files supplied to + 'add_link_object()' and/or 'set_link_objects()', the libraries + supplied to 'add_library()' and/or 'set_libraries()', and the + libraries supplied as 'libraries' (if any). + + 'output_libname' should be a library name, not a filename; the + filename will be inferred from the library name. 'output_dir' is + the directory where the library file will be put. + + 'debug' is a boolean; if true, debugging information will be + included in the library (note that on most platforms, it is the + compile step where this matters: the 'debug' flag is included here + just for consistency). + + 'target_lang' is the target language for which the given objects + are being compiled. This allows specific linkage time treatment of + certain languages. + + Raises LibError on failure. + """ + pass + + + # values for target_desc parameter in link() + SHARED_OBJECT = "shared_object" + SHARED_LIBRARY = "shared_library" + EXECUTABLE = "executable" + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + """Link a bunch of stuff together to create an executable or + shared library file. + + The "bunch of stuff" consists of the list of object files supplied + as 'objects'. 'output_filename' should be a filename. If + 'output_dir' is supplied, 'output_filename' is relative to it + (i.e. 'output_filename' can provide directory components if + needed). + + 'libraries' is a list of libraries to link against. These are + library names, not filenames, since they're translated into + filenames in a platform-specific way (eg. "foo" becomes "libfoo.a" + on Unix and "foo.lib" on DOS/Windows). However, they can include a + directory component, which means the linker will look in that + specific directory rather than searching all the normal locations. + + 'library_dirs', if supplied, should be a list of directories to + search for libraries that were specified as bare library names + (ie. no directory component). These are on top of the system + default and those supplied to 'add_library_dir()' and/or + 'set_library_dirs()'. 'runtime_library_dirs' is a list of + directories that will be embedded into the shared library and used + to search for other shared libraries that *it* depends on at + run-time. (This may only be relevant on Unix.) + + 'export_symbols' is a list of symbols that the shared library will + export. (This appears to be relevant only on Windows.) + + 'debug' is as for 'compile()' and 'create_static_lib()', with the + slight distinction that it actually matters on most platforms (as + opposed to 'create_static_lib()', which includes a 'debug' flag + mostly for form's sake). + + 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except + of course that they supply command-line arguments for the + particular linker being used). + + 'target_lang' is the target language for which the given objects + are being compiled. This allows specific linkage time treatment of + certain languages. + + Raises LinkError on failure. + """ + raise NotImplementedError + + + # Old 'link_*()' methods, rewritten to use the new 'link()' method. + + def link_shared_lib (self, + objects, + output_libname, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + self.link(CCompiler.SHARED_LIBRARY, objects, + self.library_filename(output_libname, lib_type='shared'), + output_dir, + libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, + extra_preargs, extra_postargs, build_temp, target_lang) + + + def link_shared_object (self, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + self.link(CCompiler.SHARED_OBJECT, objects, + output_filename, output_dir, + libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, + extra_preargs, extra_postargs, build_temp, target_lang) + + + def link_executable (self, + objects, + output_progname, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + target_lang=None): + self.link(CCompiler.EXECUTABLE, objects, + self.executable_filename(output_progname), output_dir, + libraries, library_dirs, runtime_library_dirs, None, + debug, extra_preargs, extra_postargs, None, target_lang) + + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function; there is + # no appropriate default implementation so subclasses should + # implement all of these. + + def library_dir_option (self, dir): + """Return the compiler option to add 'dir' to the list of + directories searched for libraries. + """ + raise NotImplementedError + + def runtime_library_dir_option (self, dir): + """Return the compiler option to add 'dir' to the list of + directories searched for runtime libraries. + """ + raise NotImplementedError + + def library_option (self, lib): + """Return the compiler option to add 'dir' to the list of libraries + linked into the shared library or executable. + """ + raise NotImplementedError + + def find_library_file (self, dirs, lib, debug=0): + """Search the specified list of directories for a static or shared + library file 'lib' and return the full path to that file. If + 'debug' true, look for a debugging version (if that makes sense on + the current platform). Return None if 'lib' wasn't found in any of + the specified directories. + """ + raise NotImplementedError + + # -- Filename generation methods ----------------------------------- + + # The default implementation of the filename generating methods are + # prejudiced towards the Unix/DOS/Windows view of the world: + # * object files are named by replacing the source file extension + # (eg. .c/.cpp -> .o/.obj) + # * library files (shared or static) are named by plugging the + # library name and extension into a format string, eg. + # "lib%s.%s" % (lib_name, ".a") for Unix static libraries + # * executables are named by appending an extension (possibly + # empty) to the program name: eg. progname + ".exe" for + # Windows + # + # To reduce redundant code, these methods expect to find + # several attributes in the current object (presumably defined + # as class attributes): + # * src_extensions - + # list of C/C++ source file extensions, eg. ['.c', '.cpp'] + # * obj_extension - + # object file extension, eg. '.o' or '.obj' + # * static_lib_extension - + # extension for static library files, eg. '.a' or '.lib' + # * shared_lib_extension - + # extension for shared library/object files, eg. '.so', '.dll' + # * static_lib_format - + # format string for generating static library filenames, + # eg. 'lib%s.%s' or '%s.%s' + # * shared_lib_format + # format string for generating shared library filenames + # (probably same as static_lib_format, since the extension + # is one of the intended parameters to the format string) + # * exe_extension - + # extension for executable files, eg. '' or '.exe' + + def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): + if output_dir is None: + output_dir = '' + obj_names = [] + for src_name in source_filenames: + base, ext = os.path.splitext(src_name) + if ext not in self.src_extensions: + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % (ext, src_name) + if strip_dir: + base = os.path.basename(base) + obj_names.append(os.path.join(output_dir, + base + self.obj_extension)) + return obj_names + + def shared_object_filename(self, basename, strip_dir=0, output_dir=''): + assert output_dir is not None + if strip_dir: + basename = os.path.basename (basename) + return os.path.join(output_dir, basename + self.shared_lib_extension) + + def executable_filename(self, basename, strip_dir=0, output_dir=''): + assert output_dir is not None + if strip_dir: + basename = os.path.basename (basename) + return os.path.join(output_dir, basename + (self.exe_extension or '')) + + def library_filename(self, libname, lib_type='static', # or 'shared' + strip_dir=0, output_dir=''): + assert output_dir is not None + if lib_type not in ("static", "shared", "dylib"): + raise ValueError, "'lib_type' must be \"static\", \"shared\" or \"dylib\"" + fmt = getattr(self, lib_type + "_lib_format") + ext = getattr(self, lib_type + "_lib_extension") + + dir, base = os.path.split (libname) + filename = fmt % (base, ext) + if strip_dir: + dir = '' + + return os.path.join(output_dir, dir, filename) + + + # -- Utility methods ----------------------------------------------- + + def announce (self, msg, level=1): + log.debug(msg) + + def debug_print (self, msg): + from distutils.debug import DEBUG + if DEBUG: + print msg + + def warn (self, msg): + sys.stderr.write ("warning: %s\n" % msg) + + def execute (self, func, args, msg=None, level=1): + execute(func, args, msg, self.dry_run) + + def spawn (self, cmd): + spawn (cmd, dry_run=self.dry_run) + + def move_file (self, src, dst): + return move_file (src, dst, dry_run=self.dry_run) + + def mkpath (self, name, mode=0777): + mkpath (name, mode, self.dry_run) + + +# class CCompiler + + +# Map a sys.platform/os.name ('posix', 'nt') to the default compiler +# type for that platform. Keys are interpreted as re match +# patterns. Order is important; platform mappings are preferred over +# OS names. +_default_compilers = ( + + # Platform string mappings + + # on a cygwin built python we can use gcc like an ordinary UNIXish + # compiler + ('cygwin.*', 'unix'), + ('os2emx', 'emx'), + + # OS name mappings + ('posix', 'unix'), + ('nt', 'msvc'), + ('mac', 'mwerks'), + + ) + +def get_default_compiler(osname=None, platform=None): + + """ Determine the default compiler to use for the given platform. + + osname should be one of the standard Python OS names (i.e. the + ones returned by os.name) and platform the common value + returned by sys.platform for the platform in question. + + The default values are os.name and sys.platform in case the + parameters are not given. + + """ + if osname is None: + osname = os.name + if platform is None: + platform = sys.platform + for pattern, compiler in _default_compilers: + if re.match(pattern, platform) is not None or \ + re.match(pattern, osname) is not None: + return compiler + # Default to Unix compiler + return 'unix' + +# Map compiler types to (module_name, class_name) pairs -- ie. where to +# find the code that implements an interface to this compiler. (The module +# is assumed to be in the 'distutils' package.) +compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', + "standard UNIX-style compiler"), + 'msvc': ('msvccompiler', 'MSVCCompiler', + "Microsoft Visual C++"), + 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', + "Cygwin port of GNU C Compiler for Win32"), + 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', + "Mingw32 port of GNU C Compiler for Win32"), + 'bcpp': ('bcppcompiler', 'BCPPCompiler', + "Borland C++ Compiler"), + 'mwerks': ('mwerkscompiler', 'MWerksCompiler', + "MetroWerks CodeWarrior"), + 'emx': ('emxccompiler', 'EMXCCompiler', + "EMX port of GNU C Compiler for OS/2"), + } + +def show_compilers(): + """Print list of available compilers (used by the "--help-compiler" + options to "build", "build_ext", "build_clib"). + """ + # XXX this "knows" that the compiler option it's describing is + # "--compiler", which just happens to be the case for the three + # commands that use it. + from distutils.fancy_getopt import FancyGetopt + compilers = [] + for compiler in compiler_class.keys(): + compilers.append(("compiler="+compiler, None, + compiler_class[compiler][2])) + compilers.sort() + pretty_printer = FancyGetopt(compilers) + pretty_printer.print_help("List of available compilers:") + + +def new_compiler (plat=None, + compiler=None, + verbose=0, + dry_run=0, + force=0): + """Generate an instance of some CCompiler subclass for the supplied + platform/compiler combination. 'plat' defaults to 'os.name' + (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler + for that platform. Currently only 'posix' and 'nt' are supported, and + the default compilers are "traditional Unix interface" (UnixCCompiler + class) and Visual C++ (MSVCCompiler class). Note that it's perfectly + possible to ask for a Unix compiler object under Windows, and a + Microsoft compiler object under Unix -- if you supply a value for + 'compiler', 'plat' is ignored. + """ + if plat is None: + plat = os.name + + try: + if compiler is None: + compiler = get_default_compiler(plat) + + (module_name, class_name, long_description) = compiler_class[compiler] + except KeyError: + msg = "don't know how to compile C/C++ code on platform '%s'" % plat + if compiler is not None: + msg = msg + " with '%s' compiler" % compiler + raise DistutilsPlatformError, msg + + try: + module_name = "distutils." + module_name + __import__ (module_name) + module = sys.modules[module_name] + klass = vars(module)[class_name] + except ImportError: + raise DistutilsModuleError, \ + "can't compile C/C++ code: unable to load module '%s'" % \ + module_name + except KeyError: + raise DistutilsModuleError, \ + ("can't compile C/C++ code: unable to find class '%s' " + + "in module '%s'") % (class_name, module_name) + + # XXX The None is necessary to preserve backwards compatibility + # with classes that expect verbose to be the first positional + # argument. + return klass (None, dry_run, force) + + +def gen_preprocess_options (macros, include_dirs): + """Generate C pre-processor options (-D, -U, -I) as used by at least + two types of compilers: the typical Unix compiler and Visual C++. + 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) + means undefine (-U) macro 'name', and (name,value) means define (-D) + macro 'name' to 'value'. 'include_dirs' is just a list of directory + names to be added to the header file search path (-I). Returns a list + of command-line options suitable for either Unix compilers or Visual + C++. + """ + # XXX it would be nice (mainly aesthetic, and so we don't generate + # stupid-looking command lines) to go over 'macros' and eliminate + # redundant definitions/undefinitions (ie. ensure that only the + # latest mention of a particular macro winds up on the command + # line). I don't think it's essential, though, since most (all?) + # Unix C compilers only pay attention to the latest -D or -U + # mention of a macro on their command line. Similar situation for + # 'include_dirs'. I'm punting on both for now. Anyways, weeding out + # redundancies like this should probably be the province of + # CCompiler, since the data structures used are inherited from it + # and therefore common to all CCompiler classes. + + pp_opts = [] + for macro in macros: + + if not (type (macro) is TupleType and + 1 <= len (macro) <= 2): + raise TypeError, \ + ("bad macro definition '%s': " + + "each element of 'macros' list must be a 1- or 2-tuple") % \ + macro + + if len (macro) == 1: # undefine this macro + pp_opts.append ("-U%s" % macro[0]) + elif len (macro) == 2: + if macro[1] is None: # define with no explicit value + pp_opts.append ("-D%s" % macro[0]) + else: + # XXX *don't* need to be clever about quoting the + # macro value here, because we're going to avoid the + # shell at all costs when we spawn the command! + pp_opts.append ("-D%s=%s" % macro) + + for dir in include_dirs: + pp_opts.append ("-I%s" % dir) + + return pp_opts + +# gen_preprocess_options () + + +def gen_lib_options (compiler, library_dirs, runtime_library_dirs, libraries): + """Generate linker options for searching library directories and + linking with specific libraries. 'libraries' and 'library_dirs' are, + respectively, lists of library names (not filenames!) and search + directories. Returns a list of command-line options suitable for use + with some compiler (depending on the two format strings passed in). + """ + lib_opts = [] + + for dir in library_dirs: + lib_opts.append (compiler.library_dir_option (dir)) + + for dir in runtime_library_dirs: + lib_opts.append (compiler.runtime_library_dir_option (dir)) + + # XXX it's important that we *not* remove redundant library mentions! + # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to + # resolve all symbols. I just hope we never have to say "-lfoo obj.o + # -lbar" to get things to work -- that's certainly a possibility, but a + # pretty nasty way to arrange your C code. + + for lib in libraries: + (lib_dir, lib_name) = os.path.split (lib) + if lib_dir: + lib_file = compiler.find_library_file ([lib_dir], lib_name) + if lib_file: + lib_opts.append (lib_file) + else: + compiler.warn ("no library file corresponding to " + "'%s' found (skipping)" % lib) + else: + lib_opts.append (compiler.library_option (lib)) + + return lib_opts + +# gen_lib_options () diff --git a/wxPython/distutils/cmd.py b/wxPython/distutils/cmd.py new file mode 100644 index 0000000000..1165f95124 --- /dev/null +++ b/wxPython/distutils/cmd.py @@ -0,0 +1,478 @@ +"""distutils.cmd + +Provides the Command class, the base class for the command classes +in the distutils.command package. +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string, re +from types import * +from distutils.errors import * +from distutils import util, dir_util, file_util, archive_util, dep_util +from distutils import log + +class Command: + """Abstract base class for defining command classes, the "worker bees" + of the Distutils. A useful analogy for command classes is to think of + them as subroutines with local variables called "options". The options + are "declared" in 'initialize_options()' and "defined" (given their + final values, aka "finalized") in 'finalize_options()', both of which + must be defined by every command class. The distinction between the + two is necessary because option values might come from the outside + world (command line, config file, ...), and any options dependent on + other options must be computed *after* these outside influences have + been processed -- hence 'finalize_options()'. The "body" of the + subroutine, where it does all its work based on the values of its + options, is the 'run()' method, which must also be implemented by every + command class. + """ + + # 'sub_commands' formalizes the notion of a "family" of commands, + # eg. "install" as the parent with sub-commands "install_lib", + # "install_headers", etc. The parent of a family of commands + # defines 'sub_commands' as a class attribute; it's a list of + # (command_name : string, predicate : unbound_method | string | None) + # tuples, where 'predicate' is a method of the parent command that + # determines whether the corresponding command is applicable in the + # current situation. (Eg. we "install_headers" is only applicable if + # we have any C header files to install.) If 'predicate' is None, + # that command is always applicable. + # + # 'sub_commands' is usually defined at the *end* of a class, because + # predicates can be unbound methods, so they must already have been + # defined. The canonical example is the "install" command. + sub_commands = [] + + + # -- Creation/initialization methods ------------------------------- + + def __init__ (self, dist): + """Create and initialize a new Command object. Most importantly, + invokes the 'initialize_options()' method, which is the real + initializer and depends on the actual command being + instantiated. + """ + # late import because of mutual dependence between these classes + from distutils.dist import Distribution + + if not isinstance(dist, Distribution): + raise TypeError, "dist must be a Distribution instance" + if self.__class__ is Command: + raise RuntimeError, "Command is an abstract class" + + self.distribution = dist + self.initialize_options() + + # Per-command versions of the global flags, so that the user can + # customize Distutils' behaviour command-by-command and let some + # commands fallback on the Distribution's behaviour. None means + # "not defined, check self.distribution's copy", while 0 or 1 mean + # false and true (duh). Note that this means figuring out the real + # value of each flag is a touch complicated -- hence "self._dry_run" + # will be handled by __getattr__, below. + # XXX This needs to be fixed. + self._dry_run = None + + # verbose is largely ignored, but needs to be set for + # backwards compatibility (I think)? + self.verbose = dist.verbose + + # Some commands define a 'self.force' option to ignore file + # timestamps, but methods defined *here* assume that + # 'self.force' exists for all commands. So define it here + # just to be safe. + self.force = None + + # The 'help' flag is just used for command-line parsing, so + # none of that complicated bureaucracy is needed. + self.help = 0 + + # 'finalized' records whether or not 'finalize_options()' has been + # called. 'finalize_options()' itself should not pay attention to + # this flag: it is the business of 'ensure_finalized()', which + # always calls 'finalize_options()', to respect/update it. + self.finalized = 0 + + # __init__ () + + + # XXX A more explicit way to customize dry_run would be better. + + def __getattr__ (self, attr): + if attr == 'dry_run': + myval = getattr(self, "_" + attr) + if myval is None: + return getattr(self.distribution, attr) + else: + return myval + else: + raise AttributeError, attr + + + def ensure_finalized (self): + if not self.finalized: + self.finalize_options() + self.finalized = 1 + + + # Subclasses must define: + # initialize_options() + # provide default values for all options; may be customized by + # setup script, by options from config file(s), or by command-line + # options + # finalize_options() + # decide on the final values for all options; this is called + # after all possible intervention from the outside world + # (command-line, option file, etc.) has been processed + # run() + # run the command: do whatever it is we're here to do, + # controlled by the command's various option values + + def initialize_options (self): + """Set default values for all the options that this command + supports. Note that these defaults may be overridden by other + commands, by the setup script, by config files, or by the + command-line. Thus, this is not the place to code dependencies + between options; generally, 'initialize_options()' implementations + are just a bunch of "self.foo = None" assignments. + + This method must be implemented by all command classes. + """ + raise RuntimeError, \ + "abstract method -- subclass %s must override" % self.__class__ + + def finalize_options (self): + """Set final values for all the options that this command supports. + This is always called as late as possible, ie. after any option + assignments from the command-line or from other commands have been + done. Thus, this is the place to to code option dependencies: if + 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as + long as 'foo' still has the same value it was assigned in + 'initialize_options()'. + + This method must be implemented by all command classes. + """ + raise RuntimeError, \ + "abstract method -- subclass %s must override" % self.__class__ + + + def dump_options (self, header=None, indent=""): + from distutils.fancy_getopt import longopt_xlate + if header is None: + header = "command options for '%s':" % self.get_command_name() + print indent + header + indent = indent + " " + for (option, _, _) in self.user_options: + option = string.translate(option, longopt_xlate) + if option[-1] == "=": + option = option[:-1] + value = getattr(self, option) + print indent + "%s = %s" % (option, value) + + + def run (self): + """A command's raison d'etre: carry out the action it exists to + perform, controlled by the options initialized in + 'initialize_options()', customized by other commands, the setup + script, the command-line, and config files, and finalized in + 'finalize_options()'. All terminal output and filesystem + interaction should be done by 'run()'. + + This method must be implemented by all command classes. + """ + + raise RuntimeError, \ + "abstract method -- subclass %s must override" % self.__class__ + + def announce (self, msg, level=1): + """If the current verbosity level is of greater than or equal to + 'level' print 'msg' to stdout. + """ + log.debug(msg) + + def debug_print (self, msg): + """Print 'msg' to stdout if the global DEBUG (taken from the + DISTUTILS_DEBUG environment variable) flag is true. + """ + from distutils.debug import DEBUG + if DEBUG: + print msg + sys.stdout.flush() + + + + # -- Option validation methods ------------------------------------- + # (these are very handy in writing the 'finalize_options()' method) + # + # NB. the general philosophy here is to ensure that a particular option + # value meets certain type and value constraints. If not, we try to + # force it into conformance (eg. if we expect a list but have a string, + # split the string on comma and/or whitespace). If we can't force the + # option into conformance, raise DistutilsOptionError. Thus, command + # classes need do nothing more than (eg.) + # self.ensure_string_list('foo') + # and they can be guaranteed that thereafter, self.foo will be + # a list of strings. + + def _ensure_stringlike (self, option, what, default=None): + val = getattr(self, option) + if val is None: + setattr(self, option, default) + return default + elif type(val) is not StringType: + raise DistutilsOptionError, \ + "'%s' must be a %s (got `%s`)" % (option, what, val) + return val + + def ensure_string (self, option, default=None): + """Ensure that 'option' is a string; if not defined, set it to + 'default'. + """ + self._ensure_stringlike(option, "string", default) + + def ensure_string_list (self, option): + """Ensure that 'option' is a list of strings. If 'option' is + currently a string, we split it either on /,\s*/ or /\s+/, so + "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become + ["foo", "bar", "baz"]. + """ + val = getattr(self, option) + if val is None: + return + elif type(val) is StringType: + setattr(self, option, re.split(r',\s*|\s+', val)) + else: + if type(val) is ListType: + types = map(type, val) + ok = (types == [StringType] * len(val)) + else: + ok = 0 + + if not ok: + raise DistutilsOptionError, \ + "'%s' must be a list of strings (got %s)" % \ + (option, `val`) + + def _ensure_tested_string (self, option, tester, + what, error_fmt, default=None): + val = self._ensure_stringlike(option, what, default) + if val is not None and not tester(val): + raise DistutilsOptionError, \ + ("error in '%s' option: " + error_fmt) % (option, val) + + def ensure_filename (self, option): + """Ensure that 'option' is the name of an existing file.""" + self._ensure_tested_string(option, os.path.isfile, + "filename", + "'%s' does not exist or is not a file") + + def ensure_dirname (self, option): + self._ensure_tested_string(option, os.path.isdir, + "directory name", + "'%s' does not exist or is not a directory") + + + # -- Convenience methods for commands ------------------------------ + + def get_command_name (self): + if hasattr(self, 'command_name'): + return self.command_name + else: + return self.__class__.__name__ + + + def set_undefined_options (self, src_cmd, *option_pairs): + """Set the values of any "undefined" options from corresponding + option values in some other command object. "Undefined" here means + "is None", which is the convention used to indicate that an option + has not been changed between 'initialize_options()' and + 'finalize_options()'. Usually called from 'finalize_options()' for + options that depend on some other command rather than another + option of the same command. 'src_cmd' is the other command from + which option values will be taken (a command object will be created + for it if necessary); the remaining arguments are + '(src_option,dst_option)' tuples which mean "take the value of + 'src_option' in the 'src_cmd' command object, and copy it to + 'dst_option' in the current command object". + """ + + # Option_pairs: list of (src_option, dst_option) tuples + + src_cmd_obj = self.distribution.get_command_obj(src_cmd) + src_cmd_obj.ensure_finalized() + for (src_option, dst_option) in option_pairs: + if getattr(self, dst_option) is None: + setattr(self, dst_option, + getattr(src_cmd_obj, src_option)) + + + def get_finalized_command (self, command, create=1): + """Wrapper around Distribution's 'get_command_obj()' method: find + (create if necessary and 'create' is true) the command object for + 'command', call its 'ensure_finalized()' method, and return the + finalized command object. + """ + cmd_obj = self.distribution.get_command_obj(command, create) + cmd_obj.ensure_finalized() + return cmd_obj + + # XXX rename to 'get_reinitialized_command()'? (should do the + # same in dist.py, if so) + def reinitialize_command (self, command, reinit_subcommands=0): + return self.distribution.reinitialize_command( + command, reinit_subcommands) + + def run_command (self, command): + """Run some other command: uses the 'run_command()' method of + Distribution, which creates and finalizes the command object if + necessary and then invokes its 'run()' method. + """ + self.distribution.run_command(command) + + + def get_sub_commands (self): + """Determine the sub-commands that are relevant in the current + distribution (ie., that need to be run). This is based on the + 'sub_commands' class attribute: each tuple in that list may include + a method that we call to determine if the subcommand needs to be + run for the current distribution. Return a list of command names. + """ + commands = [] + for (cmd_name, method) in self.sub_commands: + if method is None or method(self): + commands.append(cmd_name) + return commands + + + # -- External world manipulation ----------------------------------- + + def warn (self, msg): + sys.stderr.write("warning: %s: %s\n" % + (self.get_command_name(), msg)) + + + def execute (self, func, args, msg=None, level=1): + util.execute(func, args, msg, dry_run=self.dry_run) + + + def mkpath (self, name, mode=0777): + dir_util.mkpath(name, mode, dry_run=self.dry_run) + + + def copy_file (self, infile, outfile, + preserve_mode=1, preserve_times=1, link=None, level=1): + """Copy a file respecting verbose, dry-run and force flags. (The + former two default to whatever is in the Distribution object, and + the latter defaults to false for commands that don't define it.)""" + + return file_util.copy_file( + infile, outfile, + preserve_mode, preserve_times, + not self.force, + link, + dry_run=self.dry_run) + + + def copy_tree (self, infile, outfile, + preserve_mode=1, preserve_times=1, preserve_symlinks=0, + level=1): + """Copy an entire directory tree respecting verbose, dry-run, + and force flags. + """ + return dir_util.copy_tree( + infile, outfile, + preserve_mode,preserve_times,preserve_symlinks, + not self.force, + dry_run=self.dry_run) + + def move_file (self, src, dst, level=1): + """Move a file respectin dry-run flag.""" + return file_util.move_file(src, dst, dry_run = self.dry_run) + + def spawn (self, cmd, search_path=1, level=1): + """Spawn an external command respecting dry-run flag.""" + from distutils.spawn import spawn + spawn(cmd, search_path, dry_run= self.dry_run) + + def make_archive (self, base_name, format, + root_dir=None, base_dir=None): + return archive_util.make_archive( + base_name, format, root_dir, base_dir, dry_run=self.dry_run) + + + def make_file (self, infiles, outfile, func, args, + exec_msg=None, skip_msg=None, level=1): + """Special case of 'execute()' for operations that process one or + more input files and generate one output file. Works just like + 'execute()', except the operation is skipped and a different + message printed if 'outfile' already exists and is newer than all + files listed in 'infiles'. If the command defined 'self.force', + and it is true, then the command is unconditionally run -- does no + timestamp checks. + """ + if exec_msg is None: + exec_msg = "generating %s from %s" % \ + (outfile, string.join(infiles, ', ')) + if skip_msg is None: + skip_msg = "skipping %s (inputs unchanged)" % outfile + + + # Allow 'infiles' to be a single string + if type(infiles) is StringType: + infiles = (infiles,) + elif type(infiles) not in (ListType, TupleType): + raise TypeError, \ + "'infiles' must be a string, or a list or tuple of strings" + + # If 'outfile' must be regenerated (either because it doesn't + # exist, is out-of-date, or the 'force' flag is true) then + # perform the action that presumably regenerates it + if self.force or dep_util.newer_group (infiles, outfile): + self.execute(func, args, exec_msg, level) + + # Otherwise, print the "skip" message + else: + log.debug(skip_msg) + + # make_file () + +# class Command + + +# XXX 'install_misc' class not currently used -- it was the base class for +# both 'install_scripts' and 'install_data', but they outgrew it. It might +# still be useful for 'install_headers', though, so I'm keeping it around +# for the time being. + +class install_misc (Command): + """Common base class for installing some files in a subdirectory. + Currently used by install_data and install_scripts. + """ + + user_options = [('install-dir=', 'd', "directory to install the files to")] + + def initialize_options (self): + self.install_dir = None + self.outfiles = [] + + def _install_dir_from (self, dirname): + self.set_undefined_options('install', (dirname, 'install_dir')) + + def _copy_files (self, filelist): + self.outfiles = [] + if not filelist: + return + self.mkpath(self.install_dir) + for f in filelist: + self.copy_file(f, self.install_dir) + self.outfiles.append(os.path.join(self.install_dir, f)) + + def get_outputs (self): + return self.outfiles + + +if __name__ == "__main__": + print "ok" diff --git a/wxPython/distutils/command/__init__.py b/wxPython/distutils/command/__init__.py new file mode 100644 index 0000000000..fc6117166b --- /dev/null +++ b/wxPython/distutils/command/__init__.py @@ -0,0 +1,32 @@ +"""distutils.command + +Package containing implementation of all the standard Distutils +commands.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +__all__ = ['build', + 'build_py', + 'build_ext', + 'build_clib', + 'build_scripts', + 'clean', + 'install', + 'install_lib', + 'install_headers', + 'install_scripts', + 'install_data', + 'sdist', + 'bdist', + 'bdist_dumb', + 'bdist_rpm', + 'bdist_wininst', + # These two are reserved for future use: + #'bdist_sdux', + #'bdist_pkgtool', + # Note: + # bdist_packager is not included because it only provides + # an abstract base class + ] diff --git a/wxPython/distutils/command/bdist.py b/wxPython/distutils/command/bdist.py new file mode 100644 index 0000000000..7c606ffc4d --- /dev/null +++ b/wxPython/distutils/command/bdist.py @@ -0,0 +1,150 @@ +"""distutils.command.bdist + +Implements the Distutils 'bdist' command (create a built [binary] +distribution).""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os, string +from types import * +from distutils.core import Command +from distutils.errors import * +from distutils.util import get_platform + + +def show_formats (): + """Print list of available formats (arguments to "--format" option). + """ + from distutils.fancy_getopt import FancyGetopt + formats=[] + for format in bdist.format_commands: + formats.append(("formats=" + format, None, + bdist.format_command[format][1])) + pretty_printer = FancyGetopt(formats) + pretty_printer.print_help("List of available distribution formats:") + + +class bdist (Command): + + description = "create a built (binary) distribution" + + user_options = [('bdist-base=', 'b', + "temporary directory for creating built distributions"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('formats=', None, + "formats for distribution (comma-separated list)"), + ('dist-dir=', 'd', + "directory to put final built distributions in " + "[default: dist]"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ] + + boolean_options = ['skip-build'] + + help_options = [ + ('help-formats', None, + "lists available distribution formats", show_formats), + ] + + # The following commands do not take a format option from bdist + no_format_option = ('bdist_rpm', + #'bdist_sdux', 'bdist_pkgtool' + ) + + # This won't do in reality: will need to distinguish RPM-ish Linux, + # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. + default_format = { 'posix': 'gztar', + 'nt': 'zip', + 'os2': 'zip', } + + # Establish the preferred order (for the --help-formats option). + format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', + 'wininst', 'zip', + #'pkgtool', 'sdux' + ] + + # And the real information. + format_command = { 'rpm': ('bdist_rpm', "RPM distribution"), + 'zip': ('bdist_dumb', "ZIP file"), + 'gztar': ('bdist_dumb', "gzip'ed tar file"), + 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'ztar': ('bdist_dumb', "compressed tar file"), + 'tar': ('bdist_dumb', "tar file"), + 'wininst': ('bdist_wininst', + "Windows executable installer"), + 'zip': ('bdist_dumb', "ZIP file"), + #'pkgtool': ('bdist_pkgtool', + # "Solaris pkgtool distribution"), + #'sdux': ('bdist_sdux', "HP-UX swinstall depot"), + } + + + def initialize_options (self): + self.bdist_base = None + self.plat_name = None + self.formats = None + self.dist_dir = None + self.skip_build = 0 + + # initialize_options() + + + def finalize_options (self): + # have to finalize 'plat_name' before 'bdist_base' + if self.plat_name is None: + self.plat_name = get_platform() + + # 'bdist_base' -- parent of per-built-distribution-format + # temporary directories (eg. we'll probably have + # "build/bdist./dumb", "build/bdist./rpm", etc.) + if self.bdist_base is None: + build_base = self.get_finalized_command('build').build_base + self.bdist_base = os.path.join(build_base, + 'bdist.' + self.plat_name) + + self.ensure_string_list('formats') + if self.formats is None: + try: + self.formats = [self.default_format[os.name]] + except KeyError: + raise DistutilsPlatformError, \ + "don't know how to create built distributions " + \ + "on platform %s" % os.name + + if self.dist_dir is None: + self.dist_dir = "dist" + + # finalize_options() + + + def run (self): + + # Figure out which sub-commands we need to run. + commands = [] + for format in self.formats: + try: + commands.append(self.format_command[format][0]) + except KeyError: + raise DistutilsOptionError, "invalid format '%s'" % format + + # Reinitialize and run each command. + for i in range(len(self.formats)): + cmd_name = commands[i] + sub_cmd = self.reinitialize_command(cmd_name) + if cmd_name not in self.no_format_option: + sub_cmd.format = self.formats[i] + + # If we're going to need to run this command again, tell it to + # keep its temporary files around so subsequent runs go faster. + if cmd_name in commands[i+1:]: + sub_cmd.keep_temp = 1 + self.run_command(cmd_name) + + # run() + +# class bdist diff --git a/wxPython/distutils/command/bdist_dumb.py b/wxPython/distutils/command/bdist_dumb.py new file mode 100644 index 0000000000..8ee3a5c5f7 --- /dev/null +++ b/wxPython/distutils/command/bdist_dumb.py @@ -0,0 +1,128 @@ +"""distutils.command.bdist_dumb + +Implements the Distutils 'bdist_dumb' command (create a "dumb" built +distribution -- i.e., just an archive to be unpacked under $prefix or +$exec_prefix).""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.core import Command +from distutils.util import get_platform +from distutils.dir_util import create_tree, remove_tree, ensure_relative +from distutils.errors import * +from distutils import log + +class bdist_dumb (Command): + + description = "create a \"dumb\" built distribution" + + user_options = [('bdist-dir=', 'd', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('format=', 'f', + "archive format to create (tar, ztar, gztar, zip)"), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('relative', None, + "build the archive using relative paths" + "(default: false)"), + ] + + boolean_options = ['keep-temp', 'skip-build', 'relative'] + + default_format = { 'posix': 'gztar', + 'nt': 'zip', + 'os2': 'zip' } + + + def initialize_options (self): + self.bdist_dir = None + self.plat_name = None + self.format = None + self.keep_temp = 0 + self.dist_dir = None + self.skip_build = 0 + self.relative = 0 + + # initialize_options() + + + def finalize_options (self): + + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'dumb') + + if self.format is None: + try: + self.format = self.default_format[os.name] + except KeyError: + raise DistutilsPlatformError, \ + ("don't know how to create dumb built distributions " + + "on platform %s") % os.name + + self.set_undefined_options('bdist', + ('dist_dir', 'dist_dir'), + ('plat_name', 'plat_name')) + + # finalize_options() + + + def run (self): + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', reinit_subcommands=1) + install.root = self.bdist_dir + install.skip_build = self.skip_build + install.warn_dir = 0 + + log.info("installing to %s" % self.bdist_dir) + self.run_command('install') + + # And make an archive relative to the root of the + # pseudo-installation tree. + archive_basename = "%s.%s" % (self.distribution.get_fullname(), + self.plat_name) + + # OS/2 objects to any ":" characters in a filename (such as when + # a timestamp is used in a version) so change them to hyphens. + if os.name == "os2": + archive_basename = archive_basename.replace(":", "-") + + pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) + if not self.relative: + archive_root = self.bdist_dir + else: + if (self.distribution.has_ext_modules() and + (install.install_base != install.install_platbase)): + raise DistutilsPlatformError, \ + ("can't make a dumb built distribution where " + "base and platbase are different (%s, %s)" + % (repr(install.install_base), + repr(install.install_platbase))) + else: + archive_root = os.path.join(self.bdist_dir, + ensure_relative(install.install_base)) + + # Make the archive + self.make_archive(pseudoinstall_root, + self.format, root_dir=archive_root) + + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) + + # run() + +# class bdist_dumb diff --git a/wxPython/distutils/command/bdist_rpm.py b/wxPython/distutils/command/bdist_rpm.py new file mode 100644 index 0000000000..237cc70d25 --- /dev/null +++ b/wxPython/distutils/command/bdist_rpm.py @@ -0,0 +1,493 @@ +"""distutils.command.bdist_rpm + +Implements the Distutils 'bdist_rpm' command (create RPM source and binary +distributions).""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +import glob +from types import * +from distutils.core import Command +from distutils.debug import DEBUG +from distutils.util import get_platform +from distutils.file_util import write_file +from distutils.errors import * +from distutils import log + +class bdist_rpm (Command): + + description = "create an RPM distribution" + + user_options = [ + ('bdist-base=', None, + "base directory for creating built distributions"), + ('rpm-base=', None, + "base directory for creating RPMs (defaults to \"rpm\" under " + "--bdist-base; must be specified for RPM 2)"), + ('dist-dir=', 'd', + "directory to put final RPM files in " + "(and .spec files if --spec-only)"), + ('python=', None, + "path to Python interpreter to hard-code in the .spec file " + "(default: \"python\")"), + ('fix-python', None, + "hard-code the exact path to the current Python interpreter in " + "the .spec file"), + ('spec-only', None, + "only regenerate spec file"), + ('source-only', None, + "only generate source RPM"), + ('binary-only', None, + "only generate binary RPM"), + ('use-bzip2', None, + "use bzip2 instead of gzip to create source distribution"), + + # More meta-data: too RPM-specific to put in the setup script, + # but needs to go in the .spec file -- so we make these options + # to "bdist_rpm". The idea is that packagers would put this + # info in setup.cfg, although they are of course free to + # supply it on the command line. + ('distribution-name=', None, + "name of the (Linux) distribution to which this " + "RPM applies (*not* the name of the module distribution!)"), + ('group=', None, + "package classification [default: \"Development/Libraries\"]"), + ('release=', None, + "RPM release number"), + ('serial=', None, + "RPM serial number"), + ('vendor=', None, + "RPM \"vendor\" (eg. \"Joe Blow \") " + "[default: maintainer or author from setup script]"), + ('packager=', None, + "RPM packager (eg. \"Jane Doe \")" + "[default: vendor]"), + ('doc-files=', None, + "list of documentation files (space or comma-separated)"), + ('changelog=', None, + "RPM changelog"), + ('icon=', None, + "name of icon file"), + ('provides=', None, + "capabilities provided by this package"), + ('requires=', None, + "capabilities required by this package"), + ('conflicts=', None, + "capabilities which conflict with this package"), + ('build-requires=', None, + "capabilities required to build this package"), + ('obsoletes=', None, + "capabilities made obsolete by this package"), + + # Actions to take when building RPM + ('keep-temp', 'k', + "don't clean up RPM build directory"), + ('no-keep-temp', None, + "clean up RPM build directory [default]"), + ('use-rpm-opt-flags', None, + "compile with RPM_OPT_FLAGS when building from source RPM"), + ('no-rpm-opt-flags', None, + "do not pass any RPM CFLAGS to compiler"), + ('rpm3-mode', None, + "RPM 3 compatibility mode (default)"), + ('rpm2-mode', None, + "RPM 2 compatibility mode"), + ] + + boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode'] + + negative_opt = {'no-keep-temp': 'keep-temp', + 'no-rpm-opt-flags': 'use-rpm-opt-flags', + 'rpm2-mode': 'rpm3-mode'} + + + def initialize_options (self): + self.bdist_base = None + self.rpm_base = None + self.dist_dir = None + self.python = None + self.fix_python = None + self.spec_only = None + self.binary_only = None + self.source_only = None + self.use_bzip2 = None + + self.distribution_name = None + self.group = None + self.release = None + self.serial = None + self.vendor = None + self.packager = None + self.doc_files = None + self.changelog = None + self.icon = None + + self.prep_script = None + self.build_script = None + self.install_script = None + self.clean_script = None + self.verify_script = None + self.pre_install = None + self.post_install = None + self.pre_uninstall = None + self.post_uninstall = None + self.prep = None + self.provides = None + self.requires = None + self.conflicts = None + self.build_requires = None + self.obsoletes = None + + self.keep_temp = 0 + self.use_rpm_opt_flags = 1 + self.rpm3_mode = 1 + + # initialize_options() + + + def finalize_options (self): + self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) + if self.rpm_base is None: + if not self.rpm3_mode: + raise DistutilsOptionError, \ + "you must specify --rpm-base in RPM 2 mode" + self.rpm_base = os.path.join(self.bdist_base, "rpm") + + if self.python is None: + if self.fix_python: + self.python = sys.executable + else: + self.python = "python" + elif self.fix_python: + raise DistutilsOptionError, \ + "--python and --fix-python are mutually exclusive options" + + if os.name != 'posix': + raise DistutilsPlatformError, \ + ("don't know how to create RPM " + "distributions on platform %s" % os.name) + if self.binary_only and self.source_only: + raise DistutilsOptionError, \ + "cannot supply both '--source-only' and '--binary-only'" + + # don't pass CFLAGS to pure python distributions + if not self.distribution.has_ext_modules(): + self.use_rpm_opt_flags = 0 + + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + self.finalize_package_data() + + # finalize_options() + + def finalize_package_data (self): + self.ensure_string('group', "Development/Libraries") + self.ensure_string('vendor', + "%s <%s>" % (self.distribution.get_contact(), + self.distribution.get_contact_email())) + self.ensure_string('packager') + self.ensure_string_list('doc_files') + if type(self.doc_files) is ListType: + for readme in ('README', 'README.txt'): + if os.path.exists(readme) and readme not in self.doc_files: + self.doc_files.append(readme) + + self.ensure_string('release', "1") + self.ensure_string('serial') # should it be an int? + + self.ensure_string('distribution_name') + + self.ensure_string('changelog') + # Format changelog correctly + self.changelog = self._format_changelog(self.changelog) + + self.ensure_filename('icon') + + self.ensure_filename('prep_script') + self.ensure_filename('build_script') + self.ensure_filename('install_script') + self.ensure_filename('clean_script') + self.ensure_filename('verify_script') + self.ensure_filename('pre_install') + self.ensure_filename('post_install') + self.ensure_filename('pre_uninstall') + self.ensure_filename('post_uninstall') + + # XXX don't forget we punted on summaries and descriptions -- they + # should be handled here eventually! + + # Now *this* is some meta-data that belongs in the setup script... + self.ensure_string_list('provides') + self.ensure_string_list('requires') + self.ensure_string_list('conflicts') + self.ensure_string_list('build_requires') + self.ensure_string_list('obsoletes') + + # finalize_package_data () + + + def run (self): + + if DEBUG: + print "before _get_package_data():" + print "vendor =", self.vendor + print "packager =", self.packager + print "doc_files =", self.doc_files + print "changelog =", self.changelog + + # make directories + if self.spec_only: + spec_dir = self.dist_dir + self.mkpath(spec_dir) + else: + rpm_dir = {} + for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): + rpm_dir[d] = os.path.join(self.rpm_base, d) + self.mkpath(rpm_dir[d]) + spec_dir = rpm_dir['SPECS'] + + # Spec file goes into 'dist_dir' if '--spec-only specified', + # build/rpm. otherwise. + spec_path = os.path.join(spec_dir, + "%s.spec" % self.distribution.get_name()) + self.execute(write_file, + (spec_path, + self._make_spec_file()), + "writing '%s'" % spec_path) + + if self.spec_only: # stop if requested + return + + # Make a source distribution and copy to SOURCES directory with + # optional icon. + sdist = self.reinitialize_command('sdist') + if self.use_bzip2: + sdist.formats = ['bztar'] + else: + sdist.formats = ['gztar'] + self.run_command('sdist') + + source = sdist.get_archive_files()[0] + source_dir = rpm_dir['SOURCES'] + self.copy_file(source, source_dir) + + if self.icon: + if os.path.exists(self.icon): + self.copy_file(self.icon, source_dir) + else: + raise DistutilsFileError, \ + "icon file '%s' does not exist" % self.icon + + + # build package + log.info("building RPMs") + rpm_cmd = ['rpm'] + if os.path.exists('/usr/bin/rpmbuild') or \ + os.path.exists('/bin/rpmbuild'): + rpm_cmd = ['rpmbuild'] + if self.source_only: # what kind of RPMs? + rpm_cmd.append('-bs') + elif self.binary_only: + rpm_cmd.append('-bb') + else: + rpm_cmd.append('-ba') + if self.rpm3_mode: + rpm_cmd.extend(['--define', + '_topdir %s/%s' % (os.getcwd(), self.rpm_base),]) + if not self.keep_temp: + rpm_cmd.append('--clean') + rpm_cmd.append(spec_path) + self.spawn(rpm_cmd) + + # XXX this is a nasty hack -- we really should have a proper way to + # find out the names of the RPM files created; also, this assumes + # that RPM creates exactly one source and one binary RPM. + if not self.dry_run: + if not self.binary_only: + srpms = glob.glob(os.path.join(rpm_dir['SRPMS'], "*.rpm")) + assert len(srpms) == 1, \ + "unexpected number of SRPM files found: %s" % srpms + self.move_file(srpms[0], self.dist_dir) + + if not self.source_only: + rpms = glob.glob(os.path.join(rpm_dir['RPMS'], "*/*.rpm")) + assert len(rpms) == 1, \ + "unexpected number of RPM files found: %s" % rpms + self.move_file(rpms[0], self.dist_dir) + + # run() + + + def _make_spec_file(self): + """Generate the text of an RPM spec file and return it as a + list of strings (one per line). + """ + # definitions and headers + spec_file = [ + '%define name ' + self.distribution.get_name(), + '%define version ' + self.distribution.get_version(), + '%define release ' + self.release, + '', + 'Summary: ' + self.distribution.get_description(), + ] + + # put locale summaries into spec file + # XXX not supported for now (hard to put a dictionary + # in a config file -- arg!) + #for locale in self.summaries.keys(): + # spec_file.append('Summary(%s): %s' % (locale, + # self.summaries[locale])) + + spec_file.extend([ + 'Name: %{name}', + 'Version: %{version}', + 'Release: %{release}',]) + + # XXX yuck! this filename is available from the "sdist" command, + # but only after it has run: and we create the spec file before + # running "sdist", in case of --spec-only. + if self.use_bzip2: + spec_file.append('Source0: %{name}-%{version}.tar.bz2') + else: + spec_file.append('Source0: %{name}-%{version}.tar.gz') + + spec_file.extend([ + 'License: ' + self.distribution.get_license(), + 'Group: ' + self.group, + 'BuildRoot: %{_tmppath}/%{name}-buildroot', + 'Prefix: %{_prefix}', ]) + + # noarch if no extension modules + if not self.distribution.has_ext_modules(): + spec_file.append('BuildArchitectures: noarch') + + for field in ('Vendor', + 'Packager', + 'Provides', + 'Requires', + 'Conflicts', + 'Obsoletes', + ): + val = getattr(self, string.lower(field)) + if type(val) is ListType: + spec_file.append('%s: %s' % (field, string.join(val))) + elif val is not None: + spec_file.append('%s: %s' % (field, val)) + + + if self.distribution.get_url() != 'UNKNOWN': + spec_file.append('Url: ' + self.distribution.get_url()) + + if self.distribution_name: + spec_file.append('Distribution: ' + self.distribution_name) + + if self.build_requires: + spec_file.append('BuildRequires: ' + + string.join(self.build_requires)) + + if self.icon: + spec_file.append('Icon: ' + os.path.basename(self.icon)) + + spec_file.extend([ + '', + '%description', + self.distribution.get_long_description() + ]) + + # put locale descriptions into spec file + # XXX again, suppressed because config file syntax doesn't + # easily support this ;-( + #for locale in self.descriptions.keys(): + # spec_file.extend([ + # '', + # '%description -l ' + locale, + # self.descriptions[locale], + # ]) + + # rpm scripts + # figure out default build script + def_build = "%s setup.py build" % self.python + if self.use_rpm_opt_flags: + def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build + + # insert contents of files + + # XXX this is kind of misleading: user-supplied options are files + # that we open and interpolate into the spec file, but the defaults + # are just text that we drop in as-is. Hmmm. + + script_options = [ + ('prep', 'prep_script', "%setup"), + ('build', 'build_script', def_build), + ('install', 'install_script', + ("%s setup.py install " + "--root=$RPM_BUILD_ROOT " + "--record=INSTALLED_FILES") % self.python), + ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), + ('verifyscript', 'verify_script', None), + ('pre', 'pre_install', None), + ('post', 'post_install', None), + ('preun', 'pre_uninstall', None), + ('postun', 'post_uninstall', None), + ] + + for (rpm_opt, attr, default) in script_options: + # Insert contents of file referred to, if no file is referred to + # use 'default' as contents of script + val = getattr(self, attr) + if val or default: + spec_file.extend([ + '', + '%' + rpm_opt,]) + if val: + spec_file.extend(string.split(open(val, 'r').read(), '\n')) + else: + spec_file.append(default) + + + # files section + spec_file.extend([ + '', + '%files -f INSTALLED_FILES', + '%defattr(-,root,root)', + ]) + + if self.doc_files: + spec_file.append('%doc ' + string.join(self.doc_files)) + + if self.changelog: + spec_file.extend([ + '', + '%changelog',]) + spec_file.extend(self.changelog) + + return spec_file + + # _make_spec_file () + + def _format_changelog(self, changelog): + """Format the changelog correctly and convert it to a list of strings + """ + if not changelog: + return changelog + new_changelog = [] + for line in string.split(string.strip(changelog), '\n'): + line = string.strip(line) + if line[0] == '*': + new_changelog.extend(['', line]) + elif line[0] == '-': + new_changelog.append(line) + else: + new_changelog.append(' ' + line) + + # strip trailing newline inserted by first changelog entry + if not new_changelog[0]: + del new_changelog[0] + + return new_changelog + + # _format_changelog() + +# class bdist_rpm diff --git a/wxPython/distutils/command/bdist_wininst.py b/wxPython/distutils/command/bdist_wininst.py new file mode 100644 index 0000000000..5acca11a62 --- /dev/null +++ b/wxPython/distutils/command/bdist_wininst.py @@ -0,0 +1,242 @@ +"""distutils.command.bdist_wininst + +Implements the Distutils 'bdist_wininst' command: create a windows installer +exe-program.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from distutils.core import Command +from distutils.util import get_platform +from distutils.dir_util import create_tree, remove_tree +from distutils.errors import * +from distutils.sysconfig import get_python_version +from distutils import log + +class bdist_wininst (Command): + + description = "create an executable installer for MS Windows" + + user_options = [('bdist-dir=', None, + "temporary directory for creating the distribution"), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('target-version=', 'v', + "require a specific python version" + + " on the target system"), + ('no-target-compile', 'c', + "do not compile .py to .pyc on the target system"), + ('no-target-optimize', 'o', + "do not compile .py to .pyo (optimized)" + "on the target system"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('bitmap=', 'b', + "bitmap to use for the installer instead of python-powered logo"), + ('title=', 't', + "title to display on the installer background instead of default"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('install-script=', None, + "basename of installation script to be run after" + "installation or before deinstallation"), + ] + + boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', + 'skip-build'] + + def initialize_options (self): + self.bdist_dir = None + self.keep_temp = 0 + self.no_target_compile = 0 + self.no_target_optimize = 0 + self.target_version = None + self.dist_dir = None + self.bitmap = None + self.title = None + self.skip_build = 0 + self.install_script = None + + # initialize_options() + + + def finalize_options (self): + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'wininst') + if not self.target_version: + self.target_version = "" + if self.distribution.has_ext_modules(): + short_version = get_python_version() + if self.target_version and self.target_version != short_version: + raise DistutilsOptionError, \ + "target version can only be" + short_version + self.target_version = short_version + + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + + if self.install_script: + for script in self.distribution.scripts: + if self.install_script == os.path.basename(script): + break + else: + raise DistutilsOptionError, \ + "install_script '%s' not found in scripts" % \ + self.install_script + # finalize_options() + + + def run (self): + if (sys.platform != "win32" and + (self.distribution.has_ext_modules() or + self.distribution.has_c_libraries())): + raise DistutilsPlatformError \ + ("distribution contains extensions and/or C libraries; " + "must be compiled on a Windows 32 platform") + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install') + install.root = self.bdist_dir + install.skip_build = self.skip_build + install.warn_dir = 0 + + install_lib = self.reinitialize_command('install_lib') + # we do not want to include pyc or pyo files + install_lib.compile = 0 + install_lib.optimize = 0 + + # Use a custom scheme for the zip-file, because we have to decide + # at installation time which scheme to use. + for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): + value = string.upper(key) + if key == 'headers': + value = value + '/Include/$dist_name' + setattr(install, + 'install_' + key, + value) + + log.info("installing to %s", self.bdist_dir) + install.ensure_finalized() + + # avoid warning of 'install_lib' about installing + # into a directory not in sys.path + sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) + + install.run() + + del sys.path[0] + + # And make an archive relative to the root of the + # pseudo-installation tree. + from tempfile import mktemp + archive_basename = mktemp() + fullname = self.distribution.get_fullname() + arcname = self.make_archive(archive_basename, "zip", + root_dir=self.bdist_dir) + # create an exe containing the zip-file + self.create_exe(arcname, fullname, self.bitmap) + # remove the zip-file again + log.debug("removing temporary file '%s'", arcname) + os.remove(arcname) + + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) + + # run() + + def get_inidata (self): + # Return data describing the installation. + + lines = [] + metadata = self.distribution.metadata + + # Write the [metadata] section. Values are written with + # repr()[1:-1], so they do not contain unprintable characters, and + # are not surrounded by quote chars. + lines.append("[metadata]") + + # 'info' will be displayed in the installer's dialog box, + # describing the items to be installed. + info = (metadata.long_description or '') + '\n' + + for name in ["author", "author_email", "description", "maintainer", + "maintainer_email", "name", "url", "version"]: + data = getattr(metadata, name, "") + if data: + info = info + ("\n %s: %s" % \ + (string.capitalize(name), data)) + lines.append("%s=%s" % (name, repr(data)[1:-1])) + + # The [setup] section contains entries controlling + # the installer runtime. + lines.append("\n[Setup]") + if self.install_script: + lines.append("install_script=%s" % self.install_script) + lines.append("info=%s" % repr(info)[1:-1]) + lines.append("target_compile=%d" % (not self.no_target_compile)) + lines.append("target_optimize=%d" % (not self.no_target_optimize)) + if self.target_version: + lines.append("target_version=%s" % self.target_version) + + title = self.title or self.distribution.get_fullname() + lines.append("title=%s" % repr(title)[1:-1]) + import time + import distutils + build_info = "Build %s with distutils-%s" % \ + (time.ctime(time.time()), distutils.__version__) + lines.append("build_info=%s" % build_info) + return string.join(lines, "\n") + + # get_inidata() + + def create_exe (self, arcname, fullname, bitmap=None): + import struct + + self.mkpath(self.dist_dir) + + cfgdata = self.get_inidata() + + if self.target_version: + # if we create an installer for a specific python version, + # it's better to include this in the name + installer_name = os.path.join(self.dist_dir, + "%s.win32-py%s.exe" % + (fullname, self.target_version)) + else: + installer_name = os.path.join(self.dist_dir, + "%s.win32.exe" % fullname) + self.announce("creating %s" % installer_name) + + if bitmap: + bitmapdata = open(bitmap, "rb").read() + bitmaplen = len(bitmapdata) + else: + bitmaplen = 0 + + file = open(installer_name, "wb") + file.write(self.get_exe_bytes()) + if bitmap: + file.write(bitmapdata) + + file.write(cfgdata) + header = struct.pack("' under the base build directory. We only use one of + # them for a given distribution, though -- + if self.build_purelib is None: + self.build_purelib = os.path.join(self.build_base, 'lib') + if self.build_platlib is None: + self.build_platlib = os.path.join(self.build_base, + 'lib' + plat_specifier) + + # 'build_lib' is the actual directory that we will use for this + # particular module distribution -- if user didn't supply it, pick + # one of 'build_purelib' or 'build_platlib'. + if self.build_lib is None: + if self.distribution.ext_modules: + self.build_lib = self.build_platlib + else: + self.build_lib = self.build_purelib + + # 'build_temp' -- temporary directory for compiler turds, + # "build/temp." + if self.build_temp is None: + self.build_temp = os.path.join(self.build_base, + 'temp' + plat_specifier) + if self.build_scripts is None: + self.build_scripts = os.path.join(self.build_base, + 'scripts-' + sys.version[0:3]) + + # finalize_options () + + + def run (self): + + # Run all relevant sub-commands. This will be some subset of: + # - build_py - pure Python modules + # - build_clib - standalone C libraries + # - build_ext - Python extensions + # - build_scripts - (Python) scripts + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + + # -- Predicates for the sub-command list --------------------------- + + def has_pure_modules (self): + return self.distribution.has_pure_modules() + + def has_c_libraries (self): + return self.distribution.has_c_libraries() + + def has_ext_modules (self): + return self.distribution.has_ext_modules() + + def has_scripts (self): + return self.distribution.has_scripts() + + + sub_commands = [('build_py', has_pure_modules), + ('build_clib', has_c_libraries), + ('build_ext', has_ext_modules), + ('build_scripts', has_scripts), + ] + +# class build diff --git a/wxPython/distutils/command/build_clib.py b/wxPython/distutils/command/build_clib.py new file mode 100644 index 0000000000..ef03ed7269 --- /dev/null +++ b/wxPython/distutils/command/build_clib.py @@ -0,0 +1,238 @@ +"""distutils.command.build_clib + +Implements the Distutils 'build_clib' command, to build a C/C++ library +that is included in the module distribution and needed by an extension +module.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + + +# XXX this module has *lots* of code ripped-off quite transparently from +# build_ext.py -- not surprisingly really, as the work required to build +# a static library from a collection of C source files is not really all +# that different from what's required to build a shared object file from +# a collection of C source files. Nevertheless, I haven't done the +# necessary refactoring to account for the overlap in code between the +# two modules, mainly because a number of subtle details changed in the +# cut 'n paste. Sigh. + +import os, string +from types import * +from distutils.core import Command +from distutils.errors import * +from distutils.sysconfig import customize_compiler +from distutils import log + +def show_compilers (): + from distutils.ccompiler import show_compilers + show_compilers() + + +class build_clib (Command): + + description = "build C/C++ libraries used by Python extensions" + + user_options = [ + ('build-clib', 'b', + "directory to build C/C++ libraries to"), + ('build-temp', 't', + "directory to put temporary build by-products"), + ('debug', 'g', + "compile with debugging information"), + ('force', 'f', + "forcibly build everything (ignore file timestamps)"), + ('compiler=', 'c', + "specify the compiler type"), + ] + + boolean_options = ['debug', 'force'] + + help_options = [ + ('help-compiler', None, + "list available compilers", show_compilers), + ] + + def initialize_options (self): + self.build_clib = None + self.build_temp = None + + # List of libraries to build + self.libraries = None + + # Compilation options for all libraries + self.include_dirs = None + self.define = None + self.undef = None + self.debug = None + self.force = 0 + self.compiler = None + + # initialize_options() + + + def finalize_options (self): + + # This might be confusing: both build-clib and build-temp default + # to build-temp as defined by the "build" command. This is because + # I think that C libraries are really just temporary build + # by-products, at least from the point of view of building Python + # extensions -- but I want to keep my options open. + self.set_undefined_options('build', + ('build_temp', 'build_clib'), + ('build_temp', 'build_temp'), + ('compiler', 'compiler'), + ('debug', 'debug'), + ('force', 'force')) + + self.libraries = self.distribution.libraries + if self.libraries: + self.check_library_list(self.libraries) + + if self.include_dirs is None: + self.include_dirs = self.distribution.include_dirs or [] + if type(self.include_dirs) is StringType: + self.include_dirs = string.split(self.include_dirs, + os.pathsep) + + # XXX same as for build_ext -- what about 'self.define' and + # 'self.undef' ? + + # finalize_options() + + + def run (self): + + if not self.libraries: + return + + # Yech -- this is cut 'n pasted from build_ext.py! + from distutils.ccompiler import new_compiler + self.compiler = new_compiler(compiler=self.compiler, + dry_run=self.dry_run, + force=self.force) + customize_compiler(self.compiler) + + if self.include_dirs is not None: + self.compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name,value) in self.define: + self.compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + self.compiler.undefine_macro(macro) + + self.build_libraries(self.libraries) + + # run() + + + def check_library_list (self, libraries): + """Ensure that the list of libraries (presumably provided as a + command option 'libraries') is valid, i.e. it is a list of + 2-tuples, where the tuples are (library_name, build_info_dict). + Raise DistutilsSetupError if the structure is invalid anywhere; + just returns otherwise.""" + + # Yechh, blecch, ackk: this is ripped straight out of build_ext.py, + # with only names changed to protect the innocent! + + if type(libraries) is not ListType: + raise DistutilsSetupError, \ + "'libraries' option must be a list of tuples" + + for lib in libraries: + if type(lib) is not TupleType and len(lib) != 2: + raise DistutilsSetupError, \ + "each element of 'libraries' must a 2-tuple" + + if type(lib[0]) is not StringType: + raise DistutilsSetupError, \ + "first element of each tuple in 'libraries' " + \ + "must be a string (the library name)" + if '/' in lib[0] or (os.sep != '/' and os.sep in lib[0]): + raise DistutilsSetupError, \ + ("bad library name '%s': " + + "may not contain directory separators") % \ + lib[0] + + if type(lib[1]) is not DictionaryType: + raise DistutilsSetupError, \ + "second element of each tuple in 'libraries' " + \ + "must be a dictionary (build info)" + # for lib + + # check_library_list () + + + def get_library_names (self): + # Assume the library list is valid -- 'check_library_list()' is + # called from 'finalize_options()', so it should be! + + if not self.libraries: + return None + + lib_names = [] + for (lib_name, build_info) in self.libraries: + lib_names.append(lib_name) + return lib_names + + # get_library_names () + + + def get_source_files (self): + self.check_library_list(self.libraries) + filenames = [] + for (lib_name, build_info) in self.libraries: + sources = build_info.get('sources') + if (sources is None or + type(sources) not in (ListType, TupleType) ): + raise DistutilsSetupError, \ + ("in 'libraries' option (library '%s'), " + "'sources' must be present and must be " + "a list of source filenames") % lib_name + + filenames.extend(sources) + + return filenames + # get_source_files () + + + def build_libraries (self, libraries): + + for (lib_name, build_info) in libraries: + sources = build_info.get('sources') + if sources is None or type(sources) not in (ListType, TupleType): + raise DistutilsSetupError, \ + ("in 'libraries' option (library '%s'), " + + "'sources' must be present and must be " + + "a list of source filenames") % lib_name + sources = list(sources) + + log.info("building '%s' library", lib_name) + + # First, compile the source code to object files in the library + # directory. (This should probably change to putting object + # files in a temporary build directory.) + macros = build_info.get('macros') + include_dirs = build_info.get('include_dirs') + objects = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug) + + # Now "link" the object files together into a static library. + # (On Unix at least, this isn't really linking -- it just + # builds an archive. Whatever.) + self.compiler.create_static_lib(objects, lib_name, + output_dir=self.build_clib, + debug=self.debug) + + # for libraries + + # build_libraries () + +# class build_lib diff --git a/wxPython/distutils/command/build_ext.py b/wxPython/distutils/command/build_ext.py new file mode 100644 index 0000000000..0c37768179 --- /dev/null +++ b/wxPython/distutils/command/build_ext.py @@ -0,0 +1,674 @@ +"""distutils.command.build_ext + +Implements the Distutils 'build_ext' command, for building extension +modules (currently limited to C extensions, should accommodate C++ +extensions ASAP).""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string, re +from types import * +from distutils.core import Command +from distutils.errors import * +from distutils.sysconfig import customize_compiler, get_python_version +from distutils.dep_util import newer_group +from distutils.extension import Extension +from distutils import log + +# An extension name is just a dot-separated list of Python NAMEs (ie. +# the same as a fully-qualified module name). +extension_name_re = re.compile \ + (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$') + + +def show_compilers (): + from distutils.ccompiler import show_compilers + show_compilers() + + +class build_ext (Command): + + description = "build C/C++ extensions (compile/link to build directory)" + + # XXX thoughts on how to deal with complex command-line options like + # these, i.e. how to make it so fancy_getopt can suck them off the + # command line and make it look like setup.py defined the appropriate + # lists of tuples of what-have-you. + # - each command needs a callback to process its command-line options + # - Command.__init__() needs access to its share of the whole + # command line (must ultimately come from + # Distribution.parse_command_line()) + # - it then calls the current command class' option-parsing + # callback to deal with weird options like -D, which have to + # parse the option text and churn out some custom data + # structure + # - that data structure (in this case, a list of 2-tuples) + # will then be present in the command object by the time + # we get to finalize_options() (i.e. the constructor + # takes care of both command-line and client options + # in between initialize_options() and finalize_options()) + + sep_by = " (separated by '%s')" % os.pathsep + user_options = [ + ('build-lib=', 'b', + "directory for compiled extension modules"), + ('build-temp=', 't', + "directory for temporary files (build by-products)"), + ('inplace', 'i', + "ignore build-lib and put compiled extensions into the source " + + "directory alongside your pure Python modules"), + ('include-dirs=', 'I', + "list of directories to search for header files" + sep_by), + ('define=', 'D', + "C preprocessor macros to define"), + ('undef=', 'U', + "C preprocessor macros to undefine"), + ('libraries=', 'l', + "external C libraries to link with"), + ('library-dirs=', 'L', + "directories to search for external C libraries" + sep_by), + ('rpath=', 'R', + "directories to search for shared C libraries at runtime"), + ('link-objects=', 'O', + "extra explicit link objects to include in the link"), + ('debug', 'g', + "compile/link with debugging information"), + ('force', 'f', + "forcibly build everything (ignore file timestamps)"), + ('compiler=', 'c', + "specify the compiler type"), + ('swig-cpp', None, + "make SWIG create C++ files (default is C)"), + ] + + boolean_options = ['inplace', 'debug', 'force', 'swig-cpp'] + + help_options = [ + ('help-compiler', None, + "list available compilers", show_compilers), + ] + + def initialize_options (self): + self.extensions = None + self.build_lib = None + self.build_temp = None + self.inplace = 0 + self.package = None + + self.include_dirs = None + self.define = None + self.undef = None + self.libraries = None + self.library_dirs = None + self.rpath = None + self.link_objects = None + self.debug = None + self.force = None + self.compiler = None + self.swig_cpp = None + + + def finalize_options (self): + from distutils import sysconfig + + self.set_undefined_options('build', + ('build_lib', 'build_lib'), + ('build_temp', 'build_temp'), + ('compiler', 'compiler'), + ('debug', 'debug'), + ('force', 'force')) + + if self.package is None: + self.package = self.distribution.ext_package + + self.extensions = self.distribution.ext_modules + + + # Make sure Python's include directories (for Python.h, pyconfig.h, + # etc.) are in the include search path. + py_include = sysconfig.get_python_inc() + plat_py_include = sysconfig.get_python_inc(plat_specific=1) + if self.include_dirs is None: + self.include_dirs = self.distribution.include_dirs or [] + if type(self.include_dirs) is StringType: + self.include_dirs = string.split(self.include_dirs, os.pathsep) + + # Put the Python "system" include dir at the end, so that + # any local include dirs take precedence. + self.include_dirs.append(py_include) + if plat_py_include != py_include: + self.include_dirs.append(plat_py_include) + + if type(self.libraries) is StringType: + self.libraries = [self.libraries] + + # Life is easier if we're not forever checking for None, so + # simplify these options to empty lists if unset + if self.libraries is None: + self.libraries = [] + if self.library_dirs is None: + self.library_dirs = [] + elif type(self.library_dirs) is StringType: + self.library_dirs = string.split(self.library_dirs, os.pathsep) + + if self.rpath is None: + self.rpath = [] + elif type(self.rpath) is StringType: + self.rpath = string.split(self.rpath, os.pathsep) + + # for extensions under windows use different directories + # for Release and Debug builds. + # also Python's library directory must be appended to library_dirs + if os.name == 'nt': + self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs')) + if self.debug: + self.build_temp = os.path.join(self.build_temp, "Debug") + else: + self.build_temp = os.path.join(self.build_temp, "Release") + + # Append the source distribution include and library directories, + # this allows distutils on windows to work in the source tree + self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC')) + self.library_dirs.append(os.path.join(sys.exec_prefix, 'PCBuild')) + + # OS/2 (EMX) doesn't support Debug vs Release builds, but has the + # import libraries in its "Config" subdirectory + if os.name == 'os2': + self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config')) + + # for extensions under Cygwin and AtheOS Python's library directory must be + # appended to library_dirs + if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos': + if string.find(sys.executable, sys.exec_prefix) != -1: + # building third party extensions + self.library_dirs.append(os.path.join(sys.prefix, "lib", + "python" + get_python_version(), + "config")) + else: + # building python standard extensions + self.library_dirs.append('.') + + # The argument parsing will result in self.define being a string, but + # it has to be a list of 2-tuples. All the preprocessor symbols + # specified by the 'define' option will be set to '1'. Multiple + # symbols can be separated with commas. + + if self.define: + defines = string.split(self.define, ',') + self.define = map(lambda symbol: (symbol, '1'), defines) + + # The option for macros to undefine is also a string from the + # option parsing, but has to be a list. Multiple symbols can also + # be separated with commas here. + if self.undef: + self.undef = string.split(self.undef, ',') + + # finalize_options () + + + def run (self): + + from distutils.ccompiler import new_compiler + + # 'self.extensions', as supplied by setup.py, is a list of + # Extension instances. See the documentation for Extension (in + # distutils.extension) for details. + # + # For backwards compatibility with Distutils 0.8.2 and earlier, we + # also allow the 'extensions' list to be a list of tuples: + # (ext_name, build_info) + # where build_info is a dictionary containing everything that + # Extension instances do except the name, with a few things being + # differently named. We convert these 2-tuples to Extension + # instances as needed. + + if not self.extensions: + return + + # If we were asked to build any C/C++ libraries, make sure that the + # directory where we put them is in the library search path for + # linking extensions. + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.libraries.extend(build_clib.get_library_names() or []) + self.library_dirs.append(build_clib.build_clib) + + # Setup the CCompiler object that we'll use to do all the + # compiling and linking + self.compiler = new_compiler(compiler=self.compiler, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force) + customize_compiler(self.compiler) + + # And make sure that any compile/link-related options (which might + # come from the command-line or from the setup script) are set in + # that CCompiler object -- that way, they automatically apply to + # all compiling and linking done here. + if self.include_dirs is not None: + self.compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name,value) in self.define: + self.compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + self.compiler.undefine_macro(macro) + if self.libraries is not None: + self.compiler.set_libraries(self.libraries) + if self.library_dirs is not None: + self.compiler.set_library_dirs(self.library_dirs) + if self.rpath is not None: + self.compiler.set_runtime_library_dirs(self.rpath) + if self.link_objects is not None: + self.compiler.set_link_objects(self.link_objects) + + # Now actually compile and link everything. + self.build_extensions() + + # run () + + + def check_extensions_list (self, extensions): + """Ensure that the list of extensions (presumably provided as a + command option 'extensions') is valid, i.e. it is a list of + Extension objects. We also support the old-style list of 2-tuples, + where the tuples are (ext_name, build_info), which are converted to + Extension instances here. + + Raise DistutilsSetupError if the structure is invalid anywhere; + just returns otherwise. + """ + if type(extensions) is not ListType: + raise DistutilsSetupError, \ + "'ext_modules' option must be a list of Extension instances" + + for i in range(len(extensions)): + ext = extensions[i] + if isinstance(ext, Extension): + continue # OK! (assume type-checking done + # by Extension constructor) + + (ext_name, build_info) = ext + log.warn(("old-style (ext_name, build_info) tuple found in " + "ext_modules for extension '%s'" + "-- please convert to Extension instance" % ext_name)) + if type(ext) is not TupleType and len(ext) != 2: + raise DistutilsSetupError, \ + ("each element of 'ext_modules' option must be an " + "Extension instance or 2-tuple") + + if not (type(ext_name) is StringType and + extension_name_re.match(ext_name)): + raise DistutilsSetupError, \ + ("first element of each tuple in 'ext_modules' " + "must be the extension name (a string)") + + if type(build_info) is not DictionaryType: + raise DistutilsSetupError, \ + ("second element of each tuple in 'ext_modules' " + "must be a dictionary (build info)") + + # OK, the (ext_name, build_info) dict is type-safe: convert it + # to an Extension instance. + ext = Extension(ext_name, build_info['sources']) + + # Easy stuff: one-to-one mapping from dict elements to + # instance attributes. + for key in ('include_dirs', + 'library_dirs', + 'libraries', + 'extra_objects', + 'extra_compile_args', + 'extra_link_args'): + val = build_info.get(key) + if val is not None: + setattr(ext, key, val) + + # Medium-easy stuff: same syntax/semantics, different names. + ext.runtime_library_dirs = build_info.get('rpath') + if build_info.has_key('def_file'): + log.warn("'def_file' element of build info dict " + "no longer supported") + + # Non-trivial stuff: 'macros' split into 'define_macros' + # and 'undef_macros'. + macros = build_info.get('macros') + if macros: + ext.define_macros = [] + ext.undef_macros = [] + for macro in macros: + if not (type(macro) is TupleType and + 1 <= len(macro) <= 2): + raise DistutilsSetupError, \ + ("'macros' element of build info dict " + "must be 1- or 2-tuple") + if len(macro) == 1: + ext.undef_macros.append(macro[0]) + elif len(macro) == 2: + ext.define_macros.append(macro) + + extensions[i] = ext + + # for extensions + + # check_extensions_list () + + + def get_source_files (self): + self.check_extensions_list(self.extensions) + filenames = [] + + # Wouldn't it be neat if we knew the names of header files too... + for ext in self.extensions: + filenames.extend(ext.sources) + + return filenames + + + def get_outputs (self): + + # Sanity check the 'extensions' list -- can't assume this is being + # done in the same run as a 'build_extensions()' call (in fact, we + # can probably assume that it *isn't*!). + self.check_extensions_list(self.extensions) + + # And build the list of output (built) filenames. Note that this + # ignores the 'inplace' flag, and assumes everything goes in the + # "build" tree. + outputs = [] + for ext in self.extensions: + fullname = self.get_ext_fullname(ext.name) + outputs.append(os.path.join(self.build_lib, + self.get_ext_filename(fullname))) + return outputs + + # get_outputs () + + def build_extensions(self): + # First, sanity-check the 'extensions' list + self.check_extensions_list(self.extensions) + + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + sources = ext.sources + if sources is None or type(sources) not in (ListType, TupleType): + raise DistutilsSetupError, \ + ("in 'ext_modules' option (extension '%s'), " + + "'sources' must be present and must be " + + "a list of source filenames") % ext.name + sources = list(sources) + + fullname = self.get_ext_fullname(ext.name) + if self.inplace: + # ignore build-lib -- put the compiled extension into + # the source tree along with pure Python modules + + modpath = string.split(fullname, '.') + package = string.join(modpath[0:-1], '.') + base = modpath[-1] + + build_py = self.get_finalized_command('build_py') + package_dir = build_py.get_package_dir(package) + ext_filename = os.path.join(package_dir, + self.get_ext_filename(base)) + else: + ext_filename = os.path.join(self.build_lib, + self.get_ext_filename(fullname)) + depends = sources + ext.depends + if not (self.force or newer_group(depends, ext_filename, 'newer')): + log.debug("skipping '%s' extension (up-to-date)", ext.name) + return + else: + log.info("building '%s' extension", ext.name) + + # First, scan the sources for SWIG definition files (.i), run + # SWIG on 'em to create .c files, and modify the sources list + # accordingly. + sources = self.swig_sources(sources) + + # Next, compile the source code to object files. + + # XXX not honouring 'define_macros' or 'undef_macros' -- the + # CCompiler API needs to change to accommodate this, and I + # want to do one thing at a time! + + # Two possible sources for extra compiler arguments: + # - 'extra_compile_args' in Extension object + # - CFLAGS environment variable (not particularly + # elegant, but people seem to expect it and I + # guess it's useful) + # The environment variable should take precedence, and + # any sensible compiler will give precedence to later + # command line args. Hence we combine them in order: + extra_args = ext.extra_compile_args or [] + + macros = ext.define_macros[:] + for undef in ext.undef_macros: + macros.append((undef,)) + + objects = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=ext.include_dirs, + debug=self.debug, + extra_postargs=extra_args, + depends=ext.depends) + + # XXX -- this is a Vile HACK! + # + # The setup.py script for Python on Unix needs to be able to + # get this list so it can perform all the clean up needed to + # avoid keeping object files around when cleaning out a failed + # build of an extension module. Since Distutils does not + # track dependencies, we have to get rid of intermediates to + # ensure all the intermediates will be properly re-built. + # + self._built_objects = objects[:] + + # Now link the object files together into a "shared object" -- + # of course, first we have to figure out all the other things + # that go into the mix. + if ext.extra_objects: + objects.extend(ext.extra_objects) + extra_args = ext.extra_link_args or [] + + # Detect target language, if not provided + language = ext.language or self.compiler.detect_language(sources) + + self.compiler.link_shared_object( + objects, ext_filename, + libraries=self.get_libraries(ext), + library_dirs=ext.library_dirs, + runtime_library_dirs=ext.runtime_library_dirs, + extra_postargs=extra_args, + export_symbols=self.get_export_symbols(ext), + debug=self.debug, + build_temp=self.build_temp, + target_lang=language) + + + def swig_sources (self, sources): + + """Walk the list of source files in 'sources', looking for SWIG + interface (.i) files. Run SWIG on all that are found, and + return a modified 'sources' list with SWIG source files replaced + by the generated C (or C++) files. + """ + + new_sources = [] + swig_sources = [] + swig_targets = {} + + # XXX this drops generated C/C++ files into the source tree, which + # is fine for developers who want to distribute the generated + # source -- but there should be an option to put SWIG output in + # the temp dir. + + if self.swig_cpp: + target_ext = '.cpp' + else: + target_ext = '.c' + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == ".i": # SWIG interface file + new_sources.append(base + '_wrap' + target_ext) + swig_sources.append(source) + swig_targets[source] = new_sources[-1] + else: + new_sources.append(source) + + if not swig_sources: + return new_sources + + swig = self.find_swig() + swig_cmd = [swig, "-python"] + if self.swig_cpp: + swig_cmd.append("-c++") + + for source in swig_sources: + target = swig_targets[source] + log.info("swigging %s to %s", source, target) + self.spawn(swig_cmd + ["-o", target, source]) + + return new_sources + + # swig_sources () + + def find_swig (self): + """Return the name of the SWIG executable. On Unix, this is + just "swig" -- it should be in the PATH. Tries a bit harder on + Windows. + """ + + if os.name == "posix": + return "swig" + elif os.name == "nt": + + # Look for SWIG in its standard installation directory on + # Windows (or so I presume!). If we find it there, great; + # if not, act like Unix and assume it's in the PATH. + for vers in ("1.3", "1.2", "1.1"): + fn = os.path.join("c:\\swig%s" % vers, "swig.exe") + if os.path.isfile(fn): + return fn + else: + return "swig.exe" + + elif os.name == "os2": + # assume swig available in the PATH. + return "swig.exe" + + else: + raise DistutilsPlatformError, \ + ("I don't know how to find (much less run) SWIG " + "on platform '%s'") % os.name + + # find_swig () + + # -- Name generators ----------------------------------------------- + # (extension names, filenames, whatever) + + def get_ext_fullname (self, ext_name): + if self.package is None: + return ext_name + else: + return self.package + '.' + ext_name + + def get_ext_filename (self, ext_name): + r"""Convert the name of an extension (eg. "foo.bar") into the name + of the file from which it will be loaded (eg. "foo/bar.so", or + "foo\bar.pyd"). + """ + + from distutils.sysconfig import get_config_var + ext_path = string.split(ext_name, '.') + # OS/2 has an 8 character module (extension) limit :-( + if os.name == "os2": + ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8] + # extensions in debug_mode are named 'module_d.pyd' under windows + so_ext = get_config_var('SO') + if os.name == 'nt' and self.debug: + return apply(os.path.join, ext_path) + '_d' + so_ext + return apply(os.path.join, ext_path) + so_ext + + def get_export_symbols (self, ext): + """Return the list of symbols that a shared extension has to + export. This either uses 'ext.export_symbols' or, if it's not + provided, "init" + module_name. Only relevant on Windows, where + the .pyd file (DLL) must export the module "init" function. + """ + + initfunc_name = "init" + string.split(ext.name,'.')[-1] + if initfunc_name not in ext.export_symbols: + ext.export_symbols.append(initfunc_name) + return ext.export_symbols + + def get_libraries (self, ext): + """Return the list of libraries to link against when building a + shared extension. On most platforms, this is just 'ext.libraries'; + on Windows and OS/2, we add the Python library (eg. python20.dll). + """ + # The python library is always needed on Windows. For MSVC, this + # is redundant, since the library is mentioned in a pragma in + # pyconfig.h that MSVC groks. The other Windows compilers all seem + # to need it mentioned explicitly, though, so that's what we do. + # Append '_d' to the python import library on debug builds. + if sys.platform == "win32": + from distutils.msvccompiler import MSVCCompiler + if not isinstance(self.compiler, MSVCCompiler): + template = "python%d%d" + if self.debug: + template = template + '_d' + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib] + else: + return ext.libraries + elif sys.platform == "os2emx": + # EMX/GCC requires the python library explicitly, and I + # believe VACPP does as well (though not confirmed) - AIM Apr01 + template = "python%d%d" + # debug versions of the main DLL aren't supported, at least + # not at this time - AIM Apr01 + #if self.debug: + # template = template + '_d' + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib] + elif sys.platform[:6] == "cygwin": + template = "python%d.%d" + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib] + elif sys.platform[:6] == "atheos": + from distutils import sysconfig + + template = "python%d.%d" + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # Get SHLIBS from Makefile + extra = [] + for lib in sysconfig.get_config_var('SHLIBS').split(): + if lib.startswith('-l'): + extra.append(lib[2:]) + else: + extra.append(lib) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib, "m"] + extra + else: + return ext.libraries + +# class build_ext diff --git a/wxPython/distutils/command/build_py.py b/wxPython/distutils/command/build_py.py new file mode 100644 index 0000000000..258d6d4ca0 --- /dev/null +++ b/wxPython/distutils/command/build_py.py @@ -0,0 +1,396 @@ +"""distutils.command.build_py + +Implements the Distutils 'build_py' command.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, string, os +from types import * +from glob import glob + +from distutils.core import Command +from distutils.errors import * +from distutils.util import convert_path +from distutils import log + +class build_py (Command): + + description = "\"build\" pure Python modules (copy to build directory)" + + user_options = [ + ('build-lib=', 'd', "directory to \"build\" (copy) to"), + ('compile', 'c', "compile .py to .pyc"), + ('no-compile', None, "don't compile .py files [default]"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('force', 'f', "forcibly build everything (ignore file timestamps)"), + ] + + boolean_options = ['compile', 'force'] + negative_opt = {'no-compile' : 'compile'} + + + def initialize_options (self): + self.build_lib = None + self.py_modules = None + self.package = None + self.package_dir = None + self.compile = 0 + self.optimize = 0 + self.force = None + + def finalize_options (self): + self.set_undefined_options('build', + ('build_lib', 'build_lib'), + ('force', 'force')) + + # Get the distribution options that are aliases for build_py + # options -- list of packages and list of modules. + self.packages = self.distribution.packages + self.py_modules = self.distribution.py_modules + self.package_dir = {} + if self.distribution.package_dir: + for name, path in self.distribution.package_dir.items(): + self.package_dir[name] = convert_path(path) + + # Ick, copied straight from install_lib.py (fancy_getopt needs a + # type system! Hell, *everything* needs a type system!!!) + if type(self.optimize) is not IntType: + try: + self.optimize = int(self.optimize) + assert 0 <= self.optimize <= 2 + except (ValueError, AssertionError): + raise DistutilsOptionError, "optimize must be 0, 1, or 2" + + def run (self): + + # XXX copy_file by default preserves atime and mtime. IMHO this is + # the right thing to do, but perhaps it should be an option -- in + # particular, a site administrator might want installed files to + # reflect the time of installation rather than the last + # modification time before the installed release. + + # XXX copy_file by default preserves mode, which appears to be the + # wrong thing to do: if a file is read-only in the working + # directory, we want it to be installed read/write so that the next + # installation of the same module distribution can overwrite it + # without problems. (This might be a Unix-specific issue.) Thus + # we turn off 'preserve_mode' when copying to the build directory, + # since the build directory is supposed to be exactly what the + # installation will look like (ie. we preserve mode when + # installing). + + # Two options control which modules will be installed: 'packages' + # and 'py_modules'. The former lets us work with whole packages, not + # specifying individual modules at all; the latter is for + # specifying modules one-at-a-time. Currently they are mutually + # exclusive: you can define one or the other (or neither), but not + # both. It remains to be seen how limiting this is. + + # Dispose of the two "unusual" cases first: no pure Python modules + # at all (no problem, just return silently), and over-specified + # 'packages' and 'py_modules' options. + + if not self.py_modules and not self.packages: + return + if self.py_modules and self.packages: + raise DistutilsOptionError, \ + "build_py: supplying both 'packages' and 'py_modules' " + \ + "options is not allowed" + + # Now we're down to two cases: 'py_modules' only and 'packages' only. + if self.py_modules: + self.build_modules() + else: + self.build_packages() + + self.byte_compile(self.get_outputs(include_bytecode=0)) + + # run () + + + def get_package_dir (self, package): + """Return the directory, relative to the top of the source + distribution, where package 'package' should be found + (at least according to the 'package_dir' option, if any).""" + + path = string.split(package, '.') + + if not self.package_dir: + if path: + return apply(os.path.join, path) + else: + return '' + else: + tail = [] + while path: + try: + pdir = self.package_dir[string.join(path, '.')] + except KeyError: + tail.insert(0, path[-1]) + del path[-1] + else: + tail.insert(0, pdir) + return apply(os.path.join, tail) + else: + # Oops, got all the way through 'path' without finding a + # match in package_dir. If package_dir defines a directory + # for the root (nameless) package, then fallback on it; + # otherwise, we might as well have not consulted + # package_dir at all, as we just use the directory implied + # by 'tail' (which should be the same as the original value + # of 'path' at this point). + pdir = self.package_dir.get('') + if pdir is not None: + tail.insert(0, pdir) + + if tail: + return apply(os.path.join, tail) + else: + return '' + + # get_package_dir () + + + def check_package (self, package, package_dir): + + # Empty dir name means current directory, which we can probably + # assume exists. Also, os.path.exists and isdir don't know about + # my "empty string means current dir" convention, so we have to + # circumvent them. + if package_dir != "": + if not os.path.exists(package_dir): + raise DistutilsFileError, \ + "package directory '%s' does not exist" % package_dir + if not os.path.isdir(package_dir): + raise DistutilsFileError, \ + ("supposed package directory '%s' exists, " + + "but is not a directory") % package_dir + + # Require __init__.py for all but the "root package" + if package: + init_py = os.path.join(package_dir, "__init__.py") + if os.path.isfile(init_py): + return init_py + else: + log.warn(("package init file '%s' not found " + + "(or not a regular file)"), init_py) + + # Either not in a package at all (__init__.py not expected), or + # __init__.py doesn't exist -- so don't return the filename. + return None + + # check_package () + + + def check_module (self, module, module_file): + if not os.path.isfile(module_file): + log.warn("file %s (for module %s) not found", module_file, module) + return 0 + else: + return 1 + + # check_module () + + + def find_package_modules (self, package, package_dir): + self.check_package(package, package_dir) + module_files = glob(os.path.join(package_dir, "*.py")) + modules = [] + setup_script = os.path.abspath(self.distribution.script_name) + + for f in module_files: + abs_f = os.path.abspath(f) + if abs_f != setup_script: + module = os.path.splitext(os.path.basename(f))[0] + modules.append((package, module, f)) + else: + self.debug_print("excluding %s" % setup_script) + return modules + + + def find_modules (self): + """Finds individually-specified Python modules, ie. those listed by + module name in 'self.py_modules'. Returns a list of tuples (package, + module_base, filename): 'package' is a tuple of the path through + package-space to the module; 'module_base' is the bare (no + packages, no dots) module name, and 'filename' is the path to the + ".py" file (relative to the distribution root) that implements the + module. + """ + + # Map package names to tuples of useful info about the package: + # (package_dir, checked) + # package_dir - the directory where we'll find source files for + # this package + # checked - true if we have checked that the package directory + # is valid (exists, contains __init__.py, ... ?) + packages = {} + + # List of (package, module, filename) tuples to return + modules = [] + + # We treat modules-in-packages almost the same as toplevel modules, + # just the "package" for a toplevel is empty (either an empty + # string or empty list, depending on context). Differences: + # - don't check for __init__.py in directory for empty package + + for module in self.py_modules: + path = string.split(module, '.') + package = string.join(path[0:-1], '.') + module_base = path[-1] + + try: + (package_dir, checked) = packages[package] + except KeyError: + package_dir = self.get_package_dir(package) + checked = 0 + + if not checked: + init_py = self.check_package(package, package_dir) + packages[package] = (package_dir, 1) + if init_py: + modules.append((package, "__init__", init_py)) + + # XXX perhaps we should also check for just .pyc files + # (so greedy closed-source bastards can distribute Python + # modules too) + module_file = os.path.join(package_dir, module_base + ".py") + if not self.check_module(module, module_file): + continue + + modules.append((package, module_base, module_file)) + + return modules + + # find_modules () + + + def find_all_modules (self): + """Compute the list of all modules that will be built, whether + they are specified one-module-at-a-time ('self.py_modules') or + by whole packages ('self.packages'). Return a list of tuples + (package, module, module_file), just like 'find_modules()' and + 'find_package_modules()' do.""" + + if self.py_modules: + modules = self.find_modules() + else: + modules = [] + for package in self.packages: + package_dir = self.get_package_dir(package) + m = self.find_package_modules(package, package_dir) + modules.extend(m) + + return modules + + # find_all_modules () + + + def get_source_files (self): + + modules = self.find_all_modules() + filenames = [] + for module in modules: + filenames.append(module[-1]) + + return filenames + + + def get_module_outfile (self, build_dir, package, module): + outfile_path = [build_dir] + list(package) + [module + ".py"] + return apply(os.path.join, outfile_path) + + + def get_outputs (self, include_bytecode=1): + modules = self.find_all_modules() + outputs = [] + for (package, module, module_file) in modules: + package = string.split(package, '.') + filename = self.get_module_outfile(self.build_lib, package, module) + outputs.append(filename) + if include_bytecode: + if self.compile: + outputs.append(filename + "c") + if self.optimize > 0: + outputs.append(filename + "o") + + return outputs + + + def build_module (self, module, module_file, package): + if type(package) is StringType: + package = string.split(package, '.') + elif type(package) not in (ListType, TupleType): + raise TypeError, \ + "'package' must be a string (dot-separated), list, or tuple" + + # Now put the module source file into the "build" area -- this is + # easy, we just copy it somewhere under self.build_lib (the build + # directory for Python source). + outfile = self.get_module_outfile(self.build_lib, package, module) + dir = os.path.dirname(outfile) + self.mkpath(dir) + return self.copy_file(module_file, outfile, preserve_mode=0) + + + def build_modules (self): + + modules = self.find_modules() + for (package, module, module_file) in modules: + + # Now "build" the module -- ie. copy the source file to + # self.build_lib (the build directory for Python source). + # (Actually, it gets copied to the directory for this package + # under self.build_lib.) + self.build_module(module, module_file, package) + + # build_modules () + + + def build_packages (self): + + for package in self.packages: + + # Get list of (package, module, module_file) tuples based on + # scanning the package directory. 'package' is only included + # in the tuple so that 'find_modules()' and + # 'find_package_tuples()' have a consistent interface; it's + # ignored here (apart from a sanity check). Also, 'module' is + # the *unqualified* module name (ie. no dots, no package -- we + # already know its package!), and 'module_file' is the path to + # the .py file, relative to the current directory + # (ie. including 'package_dir'). + package_dir = self.get_package_dir(package) + modules = self.find_package_modules(package, package_dir) + + # Now loop over the modules we found, "building" each one (just + # copy it to self.build_lib). + for (package_, module, module_file) in modules: + assert package == package_ + self.build_module(module, module_file, package) + + # build_packages () + + + def byte_compile (self, files): + from distutils.util import byte_compile + prefix = self.build_lib + if prefix[-1] != os.sep: + prefix = prefix + os.sep + + # XXX this code is essentially the same as the 'byte_compile() + # method of the "install_lib" command, except for the determination + # of the 'prefix' string. Hmmm. + + if self.compile: + byte_compile(files, optimize=0, + force=self.force, prefix=prefix, dry_run=self.dry_run) + if self.optimize > 0: + byte_compile(files, optimize=self.optimize, + force=self.force, prefix=prefix, dry_run=self.dry_run) + +# class build_py diff --git a/wxPython/distutils/command/build_scripts.py b/wxPython/distutils/command/build_scripts.py new file mode 100644 index 0000000000..f61ad37d03 --- /dev/null +++ b/wxPython/distutils/command/build_scripts.py @@ -0,0 +1,126 @@ +"""distutils.command.build_scripts + +Implements the Distutils 'build_scripts' command.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, re +from stat import ST_MODE +from distutils import sysconfig +from distutils.core import Command +from distutils.dep_util import newer +from distutils.util import convert_path +from distutils import log + +# check if Python is called on the first line with this expression +first_line_re = re.compile(r'^#!.*python[0-9.]*(\s+.*)?$') + +class build_scripts (Command): + + description = "\"build\" scripts (copy and fixup #! line)" + + user_options = [ + ('build-dir=', 'd', "directory to \"build\" (copy) to"), + ('force', 'f', "forcibly build everything (ignore file timestamps"), + ] + + boolean_options = ['force'] + + + def initialize_options (self): + self.build_dir = None + self.scripts = None + self.force = None + self.outfiles = None + + def finalize_options (self): + self.set_undefined_options('build', + ('build_scripts', 'build_dir'), + ('force', 'force')) + self.scripts = self.distribution.scripts + + + def run (self): + if not self.scripts: + return + self.copy_scripts() + + + def copy_scripts (self): + """Copy each script listed in 'self.scripts'; if it's marked as a + Python script in the Unix way (first line matches 'first_line_re', + ie. starts with "\#!" and contains "python"), then adjust the first + line to refer to the current Python interpreter as we copy. + """ + self.mkpath(self.build_dir) + outfiles = [] + for script in self.scripts: + adjust = 0 + script = convert_path(script) + outfile = os.path.join(self.build_dir, os.path.basename(script)) + outfiles.append(outfile) + + if not self.force and not newer(script, outfile): + log.debug("not copying %s (up-to-date)", script) + continue + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, "r") + except IOError: + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: + self.warn("%s is an empty file (skipping)" % script) + continue + + match = first_line_re.match(first_line) + if match: + adjust = 1 + post_interp = match.group(1) or '' + + if adjust: + log.info("copying and adjusting %s -> %s", script, + self.build_dir) + if not self.dry_run: + outf = open(outfile, "w") + if not sysconfig.python_build: + outf.write("#!%s%s\n" % + (os.path.normpath(sys.executable), + post_interp)) + else: + outf.write("#!%s%s" % + (os.path.join( + sysconfig.get_config_var("BINDIR"), + "python" + sysconfig.get_config_var("EXE")), + post_interp)) + outf.writelines(f.readlines()) + outf.close() + if f: + f.close() + else: + f.close() + self.copy_file(script, outfile) + + if os.name == 'posix': + for file in outfiles: + if self.dry_run: + log.info("changing mode of %s", file) + else: + oldmode = os.stat(file)[ST_MODE] & 07777 + newmode = (oldmode | 0555) & 07777 + if newmode != oldmode: + log.info("changing mode of %s from %o to %o", + file, oldmode, newmode) + os.chmod(file, newmode) + + # copy_scripts () + +# class build_scripts diff --git a/wxPython/distutils/command/clean.py b/wxPython/distutils/command/clean.py new file mode 100644 index 0000000000..41b22777bc --- /dev/null +++ b/wxPython/distutils/command/clean.py @@ -0,0 +1,82 @@ +"""distutils.command.clean + +Implements the Distutils 'clean' command.""" + +# contributed by Bastian Kleineidam , added 2000-03-18 + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.core import Command +from distutils.dir_util import remove_tree +from distutils import log + +class clean (Command): + + description = "clean up output of 'build' command" + user_options = [ + ('build-base=', 'b', + "base build directory (default: 'build.build-base')"), + ('build-lib=', None, + "build directory for all modules (default: 'build.build-lib')"), + ('build-temp=', 't', + "temporary build directory (default: 'build.build-temp')"), + ('build-scripts=', None, + "build directory for scripts (default: 'build.build-scripts')"), + ('bdist-base=', None, + "temporary directory for built distributions"), + ('all', 'a', + "remove all build output, not just temporary by-products") + ] + + boolean_options = ['all'] + + def initialize_options(self): + self.build_base = None + self.build_lib = None + self.build_temp = None + self.build_scripts = None + self.bdist_base = None + self.all = None + + def finalize_options(self): + self.set_undefined_options('build', + ('build_base', 'build_base'), + ('build_lib', 'build_lib'), + ('build_scripts', 'build_scripts'), + ('build_temp', 'build_temp')) + self.set_undefined_options('bdist', + ('bdist_base', 'bdist_base')) + + def run(self): + # remove the build/temp. directory (unless it's already + # gone) + if os.path.exists(self.build_temp): + remove_tree(self.build_temp, dry_run=self.dry_run) + else: + log.debug("'%s' does not exist -- can't clean it", + self.build_temp) + + if self.all: + # remove build directories + for directory in (self.build_lib, + self.bdist_base, + self.build_scripts): + if os.path.exists(directory): + remove_tree(directory, dry_run=self.dry_run) + else: + log.warn("'%s' does not exist -- can't clean it", + directory) + + # just for the heck of it, try to remove the base build directory: + # we might have emptied it right now, but if not we don't care + if not self.dry_run: + try: + os.rmdir(self.build_base) + log.info("removing '%s'", self.build_base) + except OSError: + pass + +# class clean diff --git a/wxPython/distutils/command/command_template b/wxPython/distutils/command/command_template new file mode 100644 index 0000000000..50bbab7b6e --- /dev/null +++ b/wxPython/distutils/command/command_template @@ -0,0 +1,45 @@ +"""distutils.command.x + +Implements the Distutils 'x' command. +""" + +# created 2000/mm/dd, John Doe + +__revision__ = "$Id$" + +from distutils.core import Command + + +class x (Command): + + # Brief (40-50 characters) description of the command + description = "" + + # List of option tuples: long name, short name (None if no short + # name), and help string. + user_options = [('', '', + ""), + ] + + + def initialize_options (self): + self. = None + self. = None + self. = None + + # initialize_options() + + + def finalize_options (self): + if self.x is None: + self.x = + + # finalize_options() + + + def run (self): + + + # run() + +# class x diff --git a/wxPython/distutils/command/config.py b/wxPython/distutils/command/config.py new file mode 100644 index 0000000000..f18c79ff43 --- /dev/null +++ b/wxPython/distutils/command/config.py @@ -0,0 +1,368 @@ +"""distutils.command.config + +Implements the Distutils 'config' command, a (mostly) empty command class +that exists mainly to be sub-classed by specific module distributions and +applications. The idea is that while every "config" command is different, +at least they're all named the same, and users always see "config" in the +list of standard commands. Also, this is a good place to put common +configure-like tasks: "try to compile this C code", or "figure out where +this header file lives". +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string, re +from types import * +from distutils.core import Command +from distutils.errors import DistutilsExecError +from distutils.sysconfig import customize_compiler +from distutils import log + +LANG_EXT = {'c': '.c', + 'c++': '.cxx'} + +class config (Command): + + description = "prepare to build" + + user_options = [ + ('compiler=', None, + "specify the compiler type"), + ('cc=', None, + "specify the compiler executable"), + ('include-dirs=', 'I', + "list of directories to search for header files"), + ('define=', 'D', + "C preprocessor macros to define"), + ('undef=', 'U', + "C preprocessor macros to undefine"), + ('libraries=', 'l', + "external C libraries to link with"), + ('library-dirs=', 'L', + "directories to search for external C libraries"), + + ('noisy', None, + "show every action (compile, link, run, ...) taken"), + ('dump-source', None, + "dump generated source files before attempting to compile them"), + ] + + + # The three standard command methods: since the "config" command + # does nothing by default, these are empty. + + def initialize_options (self): + self.compiler = None + self.cc = None + self.include_dirs = None + #self.define = None + #self.undef = None + self.libraries = None + self.library_dirs = None + + # maximal output for now + self.noisy = 1 + self.dump_source = 1 + + # list of temporary files generated along-the-way that we have + # to clean at some point + self.temp_files = [] + + def finalize_options (self): + if self.include_dirs is None: + self.include_dirs = self.distribution.include_dirs or [] + elif type(self.include_dirs) is StringType: + self.include_dirs = string.split(self.include_dirs, os.pathsep) + + if self.libraries is None: + self.libraries = [] + elif type(self.libraries) is StringType: + self.libraries = [self.libraries] + + if self.library_dirs is None: + self.library_dirs = [] + elif type(self.library_dirs) is StringType: + self.library_dirs = string.split(self.library_dirs, os.pathsep) + + + def run (self): + pass + + + # Utility methods for actual "config" commands. The interfaces are + # loosely based on Autoconf macros of similar names. Sub-classes + # may use these freely. + + def _check_compiler (self): + """Check that 'self.compiler' really is a CCompiler object; + if not, make it one. + """ + # We do this late, and only on-demand, because this is an expensive + # import. + from distutils.ccompiler import CCompiler, new_compiler + if not isinstance(self.compiler, CCompiler): + self.compiler = new_compiler(compiler=self.compiler, + dry_run=self.dry_run, force=1) + customize_compiler(self.compiler) + if self.include_dirs: + self.compiler.set_include_dirs(self.include_dirs) + if self.libraries: + self.compiler.set_libraries(self.libraries) + if self.library_dirs: + self.compiler.set_library_dirs(self.library_dirs) + + + def _gen_temp_sourcefile (self, body, headers, lang): + filename = "_configtest" + LANG_EXT[lang] + file = open(filename, "w") + if headers: + for header in headers: + file.write("#include <%s>\n" % header) + file.write("\n") + file.write(body) + if body[-1] != "\n": + file.write("\n") + file.close() + return filename + + def _preprocess (self, body, headers, include_dirs, lang): + src = self._gen_temp_sourcefile(body, headers, lang) + out = "_configtest.i" + self.temp_files.extend([src, out]) + self.compiler.preprocess(src, out, include_dirs=include_dirs) + return (src, out) + + def _compile (self, body, headers, include_dirs, lang): + src = self._gen_temp_sourcefile(body, headers, lang) + if self.dump_source: + dump_file(src, "compiling '%s':" % src) + (obj,) = self.compiler.object_filenames([src]) + self.temp_files.extend([src, obj]) + self.compiler.compile([src], include_dirs=include_dirs) + return (src, obj) + + def _link (self, body, + headers, include_dirs, + libraries, library_dirs, lang): + (src, obj) = self._compile(body, headers, include_dirs, lang) + prog = os.path.splitext(os.path.basename(src))[0] + self.compiler.link_executable([obj], prog, + libraries=libraries, + library_dirs=library_dirs, + target_lang=lang) + + if self.compiler.exe_extension is not None: + prog = prog + self.compiler.exe_extension + self.temp_files.append(prog) + + return (src, obj, prog) + + def _clean (self, *filenames): + if not filenames: + filenames = self.temp_files + self.temp_files = [] + log.info("removing: %s", string.join(filenames)) + for filename in filenames: + try: + os.remove(filename) + except OSError: + pass + + + # XXX these ignore the dry-run flag: what to do, what to do? even if + # you want a dry-run build, you still need some sort of configuration + # info. My inclination is to make it up to the real config command to + # consult 'dry_run', and assume a default (minimal) configuration if + # true. The problem with trying to do it here is that you'd have to + # return either true or false from all the 'try' methods, neither of + # which is correct. + + # XXX need access to the header search path and maybe default macros. + + def try_cpp (self, body=None, headers=None, include_dirs=None, lang="c"): + """Construct a source file from 'body' (a string containing lines + of C/C++ code) and 'headers' (a list of header files to include) + and run it through the preprocessor. Return true if the + preprocessor succeeded, false if there were any errors. + ('body' probably isn't of much use, but what the heck.) + """ + from distutils.ccompiler import CompileError + self._check_compiler() + ok = 1 + try: + self._preprocess(body, headers, include_dirs, lang) + except CompileError: + ok = 0 + + self._clean() + return ok + + def search_cpp (self, pattern, body=None, + headers=None, include_dirs=None, lang="c"): + """Construct a source file (just like 'try_cpp()'), run it through + the preprocessor, and return true if any line of the output matches + 'pattern'. 'pattern' should either be a compiled regex object or a + string containing a regex. If both 'body' and 'headers' are None, + preprocesses an empty file -- which can be useful to determine the + symbols the preprocessor and compiler set by default. + """ + + self._check_compiler() + (src, out) = self._preprocess(body, headers, include_dirs, lang) + + if type(pattern) is StringType: + pattern = re.compile(pattern) + + file = open(out) + match = 0 + while 1: + line = file.readline() + if line == '': + break + if pattern.search(line): + match = 1 + break + + file.close() + self._clean() + return match + + def try_compile (self, body, headers=None, include_dirs=None, lang="c"): + """Try to compile a source file built from 'body' and 'headers'. + Return true on success, false otherwise. + """ + from distutils.ccompiler import CompileError + self._check_compiler() + try: + self._compile(body, headers, include_dirs, lang) + ok = 1 + except CompileError: + ok = 0 + + log.info(ok and "success!" or "failure.") + self._clean() + return ok + + def try_link (self, body, + headers=None, include_dirs=None, + libraries=None, library_dirs=None, + lang="c"): + """Try to compile and link a source file, built from 'body' and + 'headers', to executable form. Return true on success, false + otherwise. + """ + from distutils.ccompiler import CompileError, LinkError + self._check_compiler() + try: + self._link(body, headers, include_dirs, + libraries, library_dirs, lang) + ok = 1 + except (CompileError, LinkError): + ok = 0 + + log.info(ok and "success!" or "failure.") + self._clean() + return ok + + def try_run (self, body, + headers=None, include_dirs=None, + libraries=None, library_dirs=None, + lang="c"): + """Try to compile, link to an executable, and run a program + built from 'body' and 'headers'. Return true on success, false + otherwise. + """ + from distutils.ccompiler import CompileError, LinkError + self._check_compiler() + try: + src, obj, exe = self._link(body, headers, include_dirs, + libraries, library_dirs, lang) + self.spawn([exe]) + ok = 1 + except (CompileError, LinkError, DistutilsExecError): + ok = 0 + + log.info(ok and "success!" or "failure.") + self._clean() + return ok + + + # -- High-level methods -------------------------------------------- + # (these are the ones that are actually likely to be useful + # when implementing a real-world config command!) + + def check_func (self, func, + headers=None, include_dirs=None, + libraries=None, library_dirs=None, + decl=0, call=0): + + """Determine if function 'func' is available by constructing a + source file that refers to 'func', and compiles and links it. + If everything succeeds, returns true; otherwise returns false. + + The constructed source file starts out by including the header + files listed in 'headers'. If 'decl' is true, it then declares + 'func' (as "int func()"); you probably shouldn't supply 'headers' + and set 'decl' true in the same call, or you might get errors about + a conflicting declarations for 'func'. Finally, the constructed + 'main()' function either references 'func' or (if 'call' is true) + calls it. 'libraries' and 'library_dirs' are used when + linking. + """ + + self._check_compiler() + body = [] + if decl: + body.append("int %s ();" % func) + body.append("int main () {") + if call: + body.append(" %s();" % func) + else: + body.append(" %s;" % func) + body.append("}") + body = string.join(body, "\n") + "\n" + + return self.try_link(body, headers, include_dirs, + libraries, library_dirs) + + # check_func () + + def check_lib (self, library, library_dirs=None, + headers=None, include_dirs=None, other_libraries=[]): + """Determine if 'library' is available to be linked against, + without actually checking that any particular symbols are provided + by it. 'headers' will be used in constructing the source file to + be compiled, but the only effect of this is to check if all the + header files listed are available. Any libraries listed in + 'other_libraries' will be included in the link, in case 'library' + has symbols that depend on other libraries. + """ + self._check_compiler() + return self.try_link("int main (void) { }", + headers, include_dirs, + [library]+other_libraries, library_dirs) + + def check_header (self, header, include_dirs=None, + library_dirs=None, lang="c"): + """Determine if the system header file named by 'header_file' + exists and can be found by the preprocessor; return true if so, + false otherwise. + """ + return self.try_cpp(body="/* No body */", headers=[header], + include_dirs=include_dirs) + + +# class config + + +def dump_file (filename, head=None): + if head is None: + print filename + ":" + else: + print head + + file = open(filename) + sys.stdout.write(file.read()) + file.close() diff --git a/wxPython/distutils/command/install.py b/wxPython/distutils/command/install.py new file mode 100644 index 0000000000..5d5bdaa77e --- /dev/null +++ b/wxPython/distutils/command/install.py @@ -0,0 +1,601 @@ +"""distutils.command.install + +Implements the Distutils 'install' command.""" + +from distutils import log + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from types import * +from distutils.core import Command +from distutils.debug import DEBUG +from distutils.sysconfig import get_config_vars +from distutils.errors import DistutilsPlatformError +from distutils.file_util import write_file +from distutils.util import convert_path, subst_vars, change_root +from distutils.errors import DistutilsOptionError +from glob import glob + +if sys.version < "2.2": + WINDOWS_SCHEME = { + 'purelib': '$base', + 'platlib': '$base', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } +else: + WINDOWS_SCHEME = { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } + +INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', + 'platlib': '$platbase/lib/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', + 'platlib': '$base/lib/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'nt': WINDOWS_SCHEME, + 'mac': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + 'os2': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } + } + +# The keys to an installation scheme; if any new types of files are to be +# installed, be sure to add an entry to every installation scheme above, +# and to SCHEME_KEYS here. +SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') + + +class install (Command): + + description = "install everything from build directory" + + user_options = [ + # Select installation scheme and set base director(y|ies) + ('prefix=', None, + "installation prefix"), + ('exec-prefix=', None, + "(Unix only) prefix for platform-specific files"), + ('home=', None, + "(Unix only) home directory to install under"), + + # Or, just set the base director(y|ies) + ('install-base=', None, + "base installation directory (instead of --prefix or --home)"), + ('install-platbase=', None, + "base installation directory for platform-specific files " + + "(instead of --exec-prefix or --home)"), + ('root=', None, + "install everything relative to this alternate root directory"), + + # Or, explicitly set the installation scheme + ('install-purelib=', None, + "installation directory for pure Python module distributions"), + ('install-platlib=', None, + "installation directory for non-pure module distributions"), + ('install-lib=', None, + "installation directory for all module distributions " + + "(overrides --install-purelib and --install-platlib)"), + + ('install-headers=', None, + "installation directory for C/C++ headers"), + ('install-scripts=', None, + "installation directory for Python scripts"), + ('install-data=', None, + "installation directory for data files"), + + # Byte-compilation options -- see install_lib.py for details, as + # these are duplicated from there (but only install_lib does + # anything with them). + ('compile', 'c', "compile .py to .pyc [default]"), + ('no-compile', None, "don't compile .py files"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + + # Miscellaneous control options + ('force', 'f', + "force installation (overwrite any existing files)"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + + # Where to install documentation (eventually!) + #('doc-format=', None, "format of documentation to generate"), + #('install-man=', None, "directory for Unix man pages"), + #('install-html=', None, "directory for HTML documentation"), + #('install-info=', None, "directory for GNU info files"), + + ('record=', None, + "filename in which to record list of installed files"), + ] + + boolean_options = ['compile', 'force', 'skip-build'] + negative_opt = {'no-compile' : 'compile'} + + + def initialize_options (self): + + # High-level options: these select both an installation base + # and scheme. + self.prefix = None + self.exec_prefix = None + self.home = None + + # These select only the installation base; it's up to the user to + # specify the installation scheme (currently, that means supplying + # the --install-{platlib,purelib,scripts,data} options). + self.install_base = None + self.install_platbase = None + self.root = None + + # These options are the actual installation directories; if not + # supplied by the user, they are filled in using the installation + # scheme implied by prefix/exec-prefix/home and the contents of + # that installation scheme. + self.install_purelib = None # for pure module distributions + self.install_platlib = None # non-pure (dists w/ extensions) + self.install_headers = None # for C/C++ headers + self.install_lib = None # set to either purelib or platlib + self.install_scripts = None + self.install_data = None + + self.compile = None + self.optimize = None + + # These two are for putting non-packagized distributions into their + # own directory and creating a .pth file if it makes sense. + # 'extra_path' comes from the setup file; 'install_path_file' can + # be turned off if it makes no sense to install a .pth file. (But + # better to install it uselessly than to guess wrong and not + # install it when it's necessary and would be used!) Currently, + # 'install_path_file' is always true unless some outsider meddles + # with it. + self.extra_path = None + self.install_path_file = 1 + + # 'force' forces installation, even if target files are not + # out-of-date. 'skip_build' skips running the "build" command, + # handy if you know it's not necessary. 'warn_dir' (which is *not* + # a user option, it's just there so the bdist_* commands can turn + # it off) determines whether we warn about installing to a + # directory not in sys.path. + self.force = 0 + self.skip_build = 0 + self.warn_dir = 1 + + # These are only here as a conduit from the 'build' command to the + # 'install_*' commands that do the real work. ('build_base' isn't + # actually used anywhere, but it might be useful in future.) They + # are not user options, because if the user told the install + # command where the build directory is, that wouldn't affect the + # build command. + self.build_base = None + self.build_lib = None + + # Not defined yet because we don't know anything about + # documentation yet. + #self.install_man = None + #self.install_html = None + #self.install_info = None + + self.record = None + + + # -- Option finalizing methods ------------------------------------- + # (This is rather more involved than for most commands, + # because this is where the policy for installing third- + # party Python modules on various platforms given a wide + # array of user input is decided. Yes, it's quite complex!) + + def finalize_options (self): + + # This method (and its pliant slaves, like 'finalize_unix()', + # 'finalize_other()', and 'select_scheme()') is where the default + # installation directories for modules, extension modules, and + # anything else we care to install from a Python module + # distribution. Thus, this code makes a pretty important policy + # statement about how third-party stuff is added to a Python + # installation! Note that the actual work of installation is done + # by the relatively simple 'install_*' commands; they just take + # their orders from the installation directory options determined + # here. + + # Check for errors/inconsistencies in the options; first, stuff + # that's wrong on any platform. + + if ((self.prefix or self.exec_prefix or self.home) and + (self.install_base or self.install_platbase)): + raise DistutilsOptionError, \ + ("must supply either prefix/exec-prefix/home or " + + "install-base/install-platbase -- not both") + + # Next, stuff that's wrong (or dubious) only on certain platforms. + if os.name == 'posix': + if self.home and (self.prefix or self.exec_prefix): + raise DistutilsOptionError, \ + ("must supply either home or prefix/exec-prefix -- " + + "not both") + else: + if self.exec_prefix: + self.warn("exec-prefix option ignored on this platform") + self.exec_prefix = None + if self.home: + self.warn("home option ignored on this platform") + self.home = None + + # Now the interesting logic -- so interesting that we farm it out + # to other methods. The goal of these methods is to set the final + # values for the install_{lib,scripts,data,...} options, using as + # input a heady brew of prefix, exec_prefix, home, install_base, + # install_platbase, user-supplied versions of + # install_{purelib,platlib,lib,scripts,data,...}, and the + # INSTALL_SCHEME dictionary above. Phew! + + self.dump_dirs("pre-finalize_{unix,other}") + + if os.name == 'posix': + self.finalize_unix() + else: + self.finalize_other() + + self.dump_dirs("post-finalize_{unix,other}()") + + # Expand configuration variables, tilde, etc. in self.install_base + # and self.install_platbase -- that way, we can use $base or + # $platbase in the other installation directories and not worry + # about needing recursive variable expansion (shudder). + + py_version = (string.split(sys.version))[0] + (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') + self.config_vars = {'dist_name': self.distribution.get_name(), + 'dist_version': self.distribution.get_version(), + 'dist_fullname': self.distribution.get_fullname(), + 'py_version': py_version, + 'py_version_short': py_version[0:3], + 'sys_prefix': prefix, + 'prefix': prefix, + 'sys_exec_prefix': exec_prefix, + 'exec_prefix': exec_prefix, + } + self.expand_basedirs() + + self.dump_dirs("post-expand_basedirs()") + + # Now define config vars for the base directories so we can expand + # everything else. + self.config_vars['base'] = self.install_base + self.config_vars['platbase'] = self.install_platbase + + if DEBUG: + from pprint import pprint + print "config vars:" + pprint(self.config_vars) + + # Expand "~" and configuration variables in the installation + # directories. + self.expand_dirs() + + self.dump_dirs("post-expand_dirs()") + + # Pick the actual directory to install all modules to: either + # install_purelib or install_platlib, depending on whether this + # module distribution is pure or not. Of course, if the user + # already specified install_lib, use their selection. + if self.install_lib is None: + if self.distribution.ext_modules: # has extensions: non-pure + self.install_lib = self.install_platlib + else: + self.install_lib = self.install_purelib + + + # Convert directories from Unix /-separated syntax to the local + # convention. + self.convert_paths('lib', 'purelib', 'platlib', + 'scripts', 'data', 'headers') + + # Well, we're not actually fully completely finalized yet: we still + # have to deal with 'extra_path', which is the hack for allowing + # non-packagized module distributions (hello, Numerical Python!) to + # get their own directories. + self.handle_extra_path() + self.install_libbase = self.install_lib # needed for .pth file + self.install_lib = os.path.join(self.install_lib, self.extra_dirs) + + # If a new root directory was supplied, make all the installation + # dirs relative to it. + if self.root is not None: + self.change_roots('libbase', 'lib', 'purelib', 'platlib', + 'scripts', 'data', 'headers') + + self.dump_dirs("after prepending root") + + # Find out the build directories, ie. where to install from. + self.set_undefined_options('build', + ('build_base', 'build_base'), + ('build_lib', 'build_lib')) + + # Punt on doc directories for now -- after all, we're punting on + # documentation completely! + + # finalize_options () + + + def dump_dirs (self, msg): + if DEBUG: + from distutils.fancy_getopt import longopt_xlate + print msg + ":" + for opt in self.user_options: + opt_name = opt[0] + if opt_name[-1] == "=": + opt_name = opt_name[0:-1] + opt_name = string.translate(opt_name, longopt_xlate) + val = getattr(self, opt_name) + print " %s: %s" % (opt_name, val) + + + def finalize_unix (self): + + if self.install_base is not None or self.install_platbase is not None: + if ((self.install_lib is None and + self.install_purelib is None and + self.install_platlib is None) or + self.install_headers is None or + self.install_scripts is None or + self.install_data is None): + raise DistutilsOptionError, \ + ("install-base or install-platbase supplied, but " + "installation scheme is incomplete") + return + + if self.home is not None: + self.install_base = self.install_platbase = self.home + self.select_scheme("unix_home") + else: + if self.prefix is None: + if self.exec_prefix is not None: + raise DistutilsOptionError, \ + "must not supply exec-prefix without prefix" + + self.prefix = os.path.normpath(sys.prefix) + self.exec_prefix = os.path.normpath(sys.exec_prefix) + + else: + if self.exec_prefix is None: + self.exec_prefix = self.prefix + + self.install_base = self.prefix + self.install_platbase = self.exec_prefix + self.select_scheme("unix_prefix") + + # finalize_unix () + + + def finalize_other (self): # Windows and Mac OS for now + + if self.prefix is None: + self.prefix = os.path.normpath(sys.prefix) + + self.install_base = self.install_platbase = self.prefix + try: + self.select_scheme(os.name) + except KeyError: + raise DistutilsPlatformError, \ + "I don't know how to install stuff on '%s'" % os.name + + # finalize_other () + + + def select_scheme (self, name): + # it's the caller's problem if they supply a bad name! + scheme = INSTALL_SCHEMES[name] + for key in SCHEME_KEYS: + attrname = 'install_' + key + if getattr(self, attrname) is None: + setattr(self, attrname, scheme[key]) + + + def _expand_attrs (self, attrs): + for attr in attrs: + val = getattr(self, attr) + if val is not None: + if os.name == 'posix': + val = os.path.expanduser(val) + val = subst_vars(val, self.config_vars) + setattr(self, attr, val) + + + def expand_basedirs (self): + self._expand_attrs(['install_base', + 'install_platbase', + 'root']) + + def expand_dirs (self): + self._expand_attrs(['install_purelib', + 'install_platlib', + 'install_lib', + 'install_headers', + 'install_scripts', + 'install_data',]) + + + def convert_paths (self, *names): + for name in names: + attr = "install_" + name + setattr(self, attr, convert_path(getattr(self, attr))) + + + def handle_extra_path (self): + + if self.extra_path is None: + self.extra_path = self.distribution.extra_path + + if self.extra_path is not None: + if type(self.extra_path) is StringType: + self.extra_path = string.split(self.extra_path, ',') + + if len(self.extra_path) == 1: + path_file = extra_dirs = self.extra_path[0] + elif len(self.extra_path) == 2: + (path_file, extra_dirs) = self.extra_path + else: + raise DistutilsOptionError, \ + ("'extra_path' option must be a list, tuple, or " + "comma-separated string with 1 or 2 elements") + + # convert to local form in case Unix notation used (as it + # should be in setup scripts) + extra_dirs = convert_path(extra_dirs) + + else: + path_file = None + extra_dirs = '' + + # XXX should we warn if path_file and not extra_dirs? (in which + # case the path file would be harmless but pointless) + self.path_file = path_file + self.extra_dirs = extra_dirs + + # handle_extra_path () + + + def change_roots (self, *names): + for name in names: + attr = "install_" + name + setattr(self, attr, change_root(self.root, getattr(self, attr))) + + + # -- Command execution methods ------------------------------------- + + def run (self): + + # Obviously have to build before we can install + if not self.skip_build: + self.run_command('build') + + # Run all sub-commands (at least those that need to be run) + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + if self.path_file: + self.create_path_file() + + # write list of installed files, if requested. + if self.record: + outputs = self.get_outputs() + if self.root: # strip any package prefix + root_len = len(self.root) + for counter in xrange(len(outputs)): + outputs[counter] = outputs[counter][root_len:] + self.execute(write_file, + (self.record, outputs), + "writing list of installed files to '%s'" % + self.record) + + sys_path = map(os.path.normpath, sys.path) + sys_path = map(os.path.normcase, sys_path) + install_lib = os.path.normcase(os.path.normpath(self.install_lib)) + if (self.warn_dir and + not (self.path_file and self.install_path_file) and + install_lib not in sys_path): + log.debug(("modules installed to '%s', which is not in " + "Python's module search path (sys.path) -- " + "you'll have to change the search path yourself"), + self.install_lib) + + # run () + + def create_path_file (self): + filename = os.path.join(self.install_libbase, + self.path_file + ".pth") + if self.install_path_file: + self.execute(write_file, + (filename, [self.extra_dirs]), + "creating %s" % filename) + else: + self.warn("path file '%s' not created" % filename) + + + # -- Reporting methods --------------------------------------------- + + def get_outputs (self): + # Assemble the outputs of all the sub-commands. + outputs = [] + for cmd_name in self.get_sub_commands(): + cmd = self.get_finalized_command(cmd_name) + # Add the contents of cmd.get_outputs(), ensuring + # that outputs doesn't contain duplicate entries + for filename in cmd.get_outputs(): + if filename not in outputs: + outputs.append(filename) + + if self.path_file and self.install_path_file: + outputs.append(os.path.join(self.install_libbase, + self.path_file + ".pth")) + + return outputs + + def get_inputs (self): + # XXX gee, this looks familiar ;-( + inputs = [] + for cmd_name in self.get_sub_commands(): + cmd = self.get_finalized_command(cmd_name) + inputs.extend(cmd.get_inputs()) + + return inputs + + + # -- Predicates for sub-command list ------------------------------- + + def has_lib (self): + """Return true if the current distribution has any Python + modules to install.""" + return (self.distribution.has_pure_modules() or + self.distribution.has_ext_modules()) + + def has_headers (self): + return self.distribution.has_headers() + + def has_scripts (self): + return self.distribution.has_scripts() + + def has_data (self): + return self.distribution.has_data_files() + + + # 'sub_commands': a list of commands this command might have to run to + # get its work done. See cmd.py for more info. + sub_commands = [('install_lib', has_lib), + ('install_headers', has_headers), + ('install_scripts', has_scripts), + ('install_data', has_data), + ] + +# class install diff --git a/wxPython/distutils/command/install_data.py b/wxPython/distutils/command/install_data.py new file mode 100644 index 0000000000..2fa0da29fe --- /dev/null +++ b/wxPython/distutils/command/install_data.py @@ -0,0 +1,85 @@ +"""distutils.command.install_data + +Implements the Distutils 'install_data' command, for installing +platform-independent data files.""" + +# contributed by Bastian Kleineidam + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from types import StringType +from distutils.core import Command +from distutils.util import change_root, convert_path + +class install_data (Command): + + description = "install data files" + + user_options = [ + ('install-dir=', 'd', + "base directory for installing data files " + "(default: installation base dir)"), + ('root=', None, + "install everything relative to this alternate root directory"), + ('force', 'f', "force installation (overwrite existing files)"), + ] + + boolean_options = ['force'] + + def initialize_options (self): + self.install_dir = None + self.outfiles = [] + self.root = None + self.force = 0 + + self.data_files = self.distribution.data_files + self.warn_dir = 1 + + def finalize_options (self): + self.set_undefined_options('install', + ('install_data', 'install_dir'), + ('root', 'root'), + ('force', 'force'), + ) + + def run (self): + self.mkpath(self.install_dir) + for f in self.data_files: + if type(f) is StringType: + # it's a simple file, so copy it + f = convert_path(f) + if self.warn_dir: + self.warn("setup script did not provide a directory for " + "'%s' -- installing right in '%s'" % + (f, self.install_dir)) + (out, _) = self.copy_file(f, self.install_dir) + self.outfiles.append(out) + else: + # it's a tuple with path to install to and a list of files + dir = convert_path(f[0]) + if not os.path.isabs(dir): + dir = os.path.join(self.install_dir, dir) + elif self.root: + dir = change_root(self.root, dir) + self.mkpath(dir) + + if f[1] == []: + # If there are no files listed, the user must be + # trying to create an empty directory, so add the + # directory to the list of output files. + self.outfiles.append(dir) + else: + # Copy files, adding them to the list of output files. + for data in f[1]: + data = convert_path(data) + (out, _) = self.copy_file(data, dir) + self.outfiles.append(out) + + def get_inputs (self): + return self.data_files or [] + + def get_outputs (self): + return self.outfiles diff --git a/wxPython/distutils/command/install_headers.py b/wxPython/distutils/command/install_headers.py new file mode 100644 index 0000000000..3a37d309f9 --- /dev/null +++ b/wxPython/distutils/command/install_headers.py @@ -0,0 +1,53 @@ +"""distutils.command.install_headers + +Implements the Distutils 'install_headers' command, to install C/C++ header +files to the Python include directory.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.core import Command + + +class install_headers (Command): + + description = "install C/C++ header files" + + user_options = [('install-dir=', 'd', + "directory to install header files to"), + ('force', 'f', + "force installation (overwrite existing files)"), + ] + + boolean_options = ['force'] + + def initialize_options (self): + self.install_dir = None + self.force = 0 + self.outfiles = [] + + def finalize_options (self): + self.set_undefined_options('install', + ('install_headers', 'install_dir'), + ('force', 'force')) + + + def run (self): + headers = self.distribution.headers + if not headers: + return + + self.mkpath(self.install_dir) + for header in headers: + (out, _) = self.copy_file(header, self.install_dir) + self.outfiles.append(out) + + def get_inputs (self): + return self.distribution.headers or [] + + def get_outputs (self): + return self.outfiles + +# class install_headers diff --git a/wxPython/distutils/command/install_lib.py b/wxPython/distutils/command/install_lib.py new file mode 100644 index 0000000000..daf3e010fd --- /dev/null +++ b/wxPython/distutils/command/install_lib.py @@ -0,0 +1,210 @@ +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from types import IntType +from distutils.core import Command +from distutils.errors import DistutilsOptionError + +class install_lib (Command): + + description = "install all Python modules (extensions and pure Python)" + + # The byte-compilation options are a tad confusing. Here are the + # possible scenarios: + # 1) no compilation at all (--no-compile --no-optimize) + # 2) compile .pyc only (--compile --no-optimize; default) + # 3) compile .pyc and "level 1" .pyo (--compile --optimize) + # 4) compile "level 1" .pyo only (--no-compile --optimize) + # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more) + # 6) compile "level 2" .pyo only (--no-compile --optimize-more) + # + # The UI for this is two option, 'compile' and 'optimize'. + # 'compile' is strictly boolean, and only decides whether to + # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and + # decides both whether to generate .pyo files and what level of + # optimization to use. + + user_options = [ + ('install-dir=', 'd', "directory to install to"), + ('build-dir=','b', "build directory (where to install from)"), + ('force', 'f', "force installation (overwrite existing files)"), + ('compile', 'c', "compile .py to .pyc [default]"), + ('no-compile', None, "don't compile .py files"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('skip-build', None, "skip the build steps"), + ] + + boolean_options = ['force', 'compile', 'skip-build'] + negative_opt = {'no-compile' : 'compile'} + + + def initialize_options (self): + # let the 'install' command dictate our installation directory + self.install_dir = None + self.build_dir = None + self.force = 0 + self.compile = None + self.optimize = None + self.skip_build = None + + def finalize_options (self): + + # Get all the information we need to install pure Python modules + # from the umbrella 'install' command -- build (source) directory, + # install (target) directory, and whether to compile .py files. + self.set_undefined_options('install', + ('build_lib', 'build_dir'), + ('install_lib', 'install_dir'), + ('force', 'force'), + ('compile', 'compile'), + ('optimize', 'optimize'), + ('skip_build', 'skip_build'), + ) + + if self.compile is None: + self.compile = 1 + if self.optimize is None: + self.optimize = 0 + + if type(self.optimize) is not IntType: + try: + self.optimize = int(self.optimize) + assert 0 <= self.optimize <= 2 + except (ValueError, AssertionError): + raise DistutilsOptionError, "optimize must be 0, 1, or 2" + + def run (self): + + # Make sure we have built everything we need first + self.build() + + # Install everything: simply dump the entire contents of the build + # directory to the installation directory (that's the beauty of + # having a build directory!) + outfiles = self.install() + + # (Optionally) compile .py to .pyc + if outfiles is not None and self.distribution.has_pure_modules(): + self.byte_compile(outfiles) + + # run () + + + # -- Top-level worker functions ------------------------------------ + # (called from 'run()') + + def build (self): + if not self.skip_build: + if self.distribution.has_pure_modules(): + self.run_command('build_py') + if self.distribution.has_ext_modules(): + self.run_command('build_ext') + + def install (self): + if os.path.isdir(self.build_dir): + outfiles = self.copy_tree(self.build_dir, self.install_dir) + else: + self.warn("'%s' does not exist -- no Python modules to install" % + self.build_dir) + return + return outfiles + + def byte_compile (self, files): + from distutils.util import byte_compile + + # Get the "--root" directory supplied to the "install" command, + # and use it as a prefix to strip off the purported filename + # encoded in bytecode files. This is far from complete, but it + # should at least generate usable bytecode in RPM distributions. + install_root = self.get_finalized_command('install').root + + if self.compile: + byte_compile(files, optimize=0, + force=self.force, prefix=install_root, + dry_run=self.dry_run) + if self.optimize > 0: + byte_compile(files, optimize=self.optimize, + force=self.force, prefix=install_root, + verbose=self.verbose, dry_run=self.dry_run) + + + # -- Utility methods ----------------------------------------------- + + def _mutate_outputs (self, has_any, build_cmd, cmd_option, output_dir): + + if not has_any: + return [] + + build_cmd = self.get_finalized_command(build_cmd) + build_files = build_cmd.get_outputs() + build_dir = getattr(build_cmd, cmd_option) + + prefix_len = len(build_dir) + len(os.sep) + outputs = [] + for file in build_files: + outputs.append(os.path.join(output_dir, file[prefix_len:])) + + return outputs + + # _mutate_outputs () + + def _bytecode_filenames (self, py_filenames): + bytecode_files = [] + for py_file in py_filenames: + if self.compile: + bytecode_files.append(py_file + "c") + if self.optimize > 0: + bytecode_files.append(py_file + "o") + + return bytecode_files + + + # -- External interface -------------------------------------------- + # (called by outsiders) + + def get_outputs (self): + """Return the list of files that would be installed if this command + were actually run. Not affected by the "dry-run" flag or whether + modules have actually been built yet. + """ + pure_outputs = \ + self._mutate_outputs(self.distribution.has_pure_modules(), + 'build_py', 'build_lib', + self.install_dir) + if self.compile: + bytecode_outputs = self._bytecode_filenames(pure_outputs) + else: + bytecode_outputs = [] + + ext_outputs = \ + self._mutate_outputs(self.distribution.has_ext_modules(), + 'build_ext', 'build_lib', + self.install_dir) + + return pure_outputs + bytecode_outputs + ext_outputs + + # get_outputs () + + def get_inputs (self): + """Get the list of files that are input to this command, ie. the + files that get installed as they are named in the build tree. + The files in this list correspond one-to-one to the output + filenames returned by 'get_outputs()'. + """ + inputs = [] + + if self.distribution.has_pure_modules(): + build_py = self.get_finalized_command('build_py') + inputs.extend(build_py.get_outputs()) + + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + inputs.extend(build_ext.get_outputs()) + + return inputs + +# class install_lib diff --git a/wxPython/distutils/command/install_scripts.py b/wxPython/distutils/command/install_scripts.py new file mode 100644 index 0000000000..abe10457b6 --- /dev/null +++ b/wxPython/distutils/command/install_scripts.py @@ -0,0 +1,66 @@ +"""distutils.command.install_scripts + +Implements the Distutils 'install_scripts' command, for installing +Python scripts.""" + +# contributed by Bastian Kleineidam + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.core import Command +from distutils import log +from stat import ST_MODE + +class install_scripts (Command): + + description = "install scripts (Python or otherwise)" + + user_options = [ + ('install-dir=', 'd', "directory to install scripts to"), + ('build-dir=','b', "build directory (where to install from)"), + ('force', 'f', "force installation (overwrite existing files)"), + ('skip-build', None, "skip the build steps"), + ] + + boolean_options = ['force', 'skip-build'] + + + def initialize_options (self): + self.install_dir = None + self.force = 0 + self.build_dir = None + self.skip_build = None + + def finalize_options (self): + self.set_undefined_options('build', ('build_scripts', 'build_dir')) + self.set_undefined_options('install', + ('install_scripts', 'install_dir'), + ('force', 'force'), + ('skip_build', 'skip_build'), + ) + + def run (self): + if not self.skip_build: + self.run_command('build_scripts') + self.outfiles = self.copy_tree(self.build_dir, self.install_dir) + if os.name == 'posix': + # Set the executable bits (owner, group, and world) on + # all the scripts we just installed. + for file in self.get_outputs(): + if self.dry_run: + log.info("changing mode of %s", file) + else: + mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777 + log.info("changing mode of %s to %o", file, mode) + os.chmod(file, mode) + + def get_inputs (self): + return self.distribution.scripts or [] + + def get_outputs(self): + return self.outfiles or [] + +# class install_scripts diff --git a/wxPython/distutils/command/register.py b/wxPython/distutils/command/register.py new file mode 100644 index 0000000000..29b76cbfd9 --- /dev/null +++ b/wxPython/distutils/command/register.py @@ -0,0 +1,292 @@ +"""distutils.command.register + +Implements the Distutils 'register' command (register with the repository). +""" + +# created 2002/10/21, Richard Jones + +__revision__ = "$Id$" + +import sys, os, string, urllib2, getpass, urlparse +import StringIO, ConfigParser + +from distutils.core import Command +from distutils.errors import * + +class register(Command): + + description = "register the distribution with the repository" + + DEFAULT_REPOSITORY = 'http://www.python.org/pypi' + + user_options = [ + ('repository=', 'r', + "url of repository [default: %s]"%DEFAULT_REPOSITORY), + ('verify', None, + 'verify the package metadata for correctness'), + ('list-classifiers', None, + 'list the valid Trove classifiers'), + ('show-response', None, + 'display full response text from server'), + ] + boolean_options = ['verify', 'show-response', 'list-classifiers'] + + def initialize_options(self): + self.repository = None + self.verify = 0 + self.show_response = 0 + self.list_classifiers = 0 + + def finalize_options(self): + if self.repository is None: + self.repository = self.DEFAULT_REPOSITORY + + def run(self): + self.check_metadata() + if self.verify: + self.verify_metadata() + elif self.list_classifiers: + self.classifiers() + else: + self.send_metadata() + + def check_metadata(self): + """Ensure that all required elements of meta-data (name, version, + URL, (author and author_email) or (maintainer and + maintainer_email)) are supplied by the Distribution object; warn if + any are missing. + """ + metadata = self.distribution.metadata + + missing = [] + for attr in ('name', 'version', 'url'): + if not (hasattr(metadata, attr) and getattr(metadata, attr)): + missing.append(attr) + + if missing: + self.warn("missing required meta-data: " + + string.join(missing, ", ")) + + if metadata.author: + if not metadata.author_email: + self.warn("missing meta-data: if 'author' supplied, " + + "'author_email' must be supplied too") + elif metadata.maintainer: + if not metadata.maintainer_email: + self.warn("missing meta-data: if 'maintainer' supplied, " + + "'maintainer_email' must be supplied too") + else: + self.warn("missing meta-data: either (author and author_email) " + + "or (maintainer and maintainer_email) " + + "must be supplied") + + def classifiers(self): + ''' Fetch the list of classifiers from the server. + ''' + response = urllib2.urlopen(self.repository+'?:action=list_classifiers') + print response.read() + + def verify_metadata(self): + ''' Send the metadata to the package index server to be checked. + ''' + # send the info to the server and report the result + (code, result) = self.post_to_server(self.build_post_data('verify')) + print 'Server response (%s): %s'%(code, result) + + def send_metadata(self): + ''' Send the metadata to the package index server. + + Well, do the following: + 1. figure who the user is, and then + 2. send the data as a Basic auth'ed POST. + + First we try to read the username/password from $HOME/.pypirc, + which is a ConfigParser-formatted file with a section + [server-login] containing username and password entries (both + in clear text). Eg: + + [server-login] + username: fred + password: sekrit + + Otherwise, to figure who the user is, we offer the user three + choices: + + 1. use existing login, + 2. register as a new user, or + 3. set the password to a random string and email the user. + + ''' + choice = 'x' + username = password = '' + + # see if we can short-cut and get the username/password from the + # config + config = None + if os.environ.has_key('HOME'): + rc = os.path.join(os.environ['HOME'], '.pypirc') + if os.path.exists(rc): + print 'Using PyPI login from %s'%rc + config = ConfigParser.ConfigParser() + config.read(rc) + username = config.get('server-login', 'username') + password = config.get('server-login', 'password') + choice = '1' + + # get the user's login info + choices = '1 2 3 4'.split() + while choice not in choices: + print '''We need to know who you are, so please choose either: + 1. use your existing login, + 2. register as a new user, + 3. have the server generate a new password for you (and email it to you), or + 4. quit +Your selection [default 1]: ''', + choice = raw_input() + if not choice: + choice = '1' + elif choice not in choices: + print 'Please choose one of the four options!' + + if choice == '1': + # get the username and password + while not username: + username = raw_input('Username: ') + while not password: + password = getpass.getpass('Password: ') + + # set up the authentication + auth = urllib2.HTTPPasswordMgr() + host = urlparse.urlparse(self.repository)[1] + auth.add_password('pypi', host, username, password) + + # send the info to the server and report the result + code, result = self.post_to_server(self.build_post_data('submit'), + auth) + print 'Server response (%s): %s'%(code, result) + + # possibly save the login + if os.environ.has_key('HOME') and config is None and code == 200: + rc = os.path.join(os.environ['HOME'], '.pypirc') + print 'I can store your PyPI login so future submissions will be faster.' + print '(the login will be stored in %s)'%rc + choice = 'X' + while choice.lower() not in 'yn': + choice = raw_input('Save your login (y/N)?') + if not choice: + choice = 'n' + if choice.lower() == 'y': + f = open(rc, 'w') + f.write('[server-login]\nusername:%s\npassword:%s\n'%( + username, password)) + f.close() + try: + os.chmod(rc, 0600) + except: + pass + elif choice == '2': + data = {':action': 'user'} + data['name'] = data['password'] = data['email'] = '' + data['confirm'] = None + while not data['name']: + data['name'] = raw_input('Username: ') + while data['password'] != data['confirm']: + while not data['password']: + data['password'] = getpass.getpass('Password: ') + while not data['confirm']: + data['confirm'] = getpass.getpass(' Confirm: ') + if data['password'] != data['confirm']: + data['password'] = '' + data['confirm'] = None + print "Password and confirm don't match!" + while not data['email']: + data['email'] = raw_input(' EMail: ') + code, result = self.post_to_server(data) + if code != 200: + print 'Server response (%s): %s'%(code, result) + else: + print 'You will receive an email shortly.' + print 'Follow the instructions in it to complete registration.' + elif choice == '3': + data = {':action': 'password_reset'} + data['email'] = '' + while not data['email']: + data['email'] = raw_input('Your email address: ') + code, result = self.post_to_server(data) + print 'Server response (%s): %s'%(code, result) + + def build_post_data(self, action): + # figure the data to send - the metadata plus some additional + # information used by the package server + meta = self.distribution.metadata + data = { + ':action': action, + 'metadata_version' : '1.0', + 'name': meta.get_name(), + 'version': meta.get_version(), + 'summary': meta.get_description(), + 'home_page': meta.get_url(), + 'author': meta.get_contact(), + 'author_email': meta.get_contact_email(), + 'license': meta.get_licence(), + 'description': meta.get_long_description(), + 'keywords': meta.get_keywords(), + 'platform': meta.get_platforms(), + 'classifiers': meta.get_classifiers(), + 'download_url': meta.get_download_url(), + } + return data + + def post_to_server(self, data, auth=None): + ''' Post a query to the server, and return a string response. + ''' + + # Build up the MIME payload for the urllib2 POST data + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = '\n--' + boundary + end_boundary = sep_boundary + '--' + body = StringIO.StringIO() + for key, value in data.items(): + # handle multiple entries for the same name + if type(value) != type([]): + value = [value] + for value in value: + value = str(value) + body.write(sep_boundary) + body.write('\nContent-Disposition: form-data; name="%s"'%key) + body.write("\n\n") + body.write(value) + if value and value[-1] == '\r': + body.write('\n') # write an extra newline (lurve Macs) + body.write(end_boundary) + body.write("\n") + body = body.getvalue() + + # build the Request + headers = { + 'Content-type': 'multipart/form-data; boundary=%s'%boundary, + 'Content-length': str(len(body)) + } + req = urllib2.Request(self.repository, body, headers) + + # handle HTTP and include the Basic Auth handler + opener = urllib2.build_opener( + urllib2.HTTPBasicAuthHandler(password_mgr=auth) + ) + data = '' + try: + result = opener.open(req) + except urllib2.HTTPError, e: + if self.show_response: + data = e.fp.read() + result = e.code, e.msg + except urllib2.URLError, e: + result = 500, str(e) + else: + if self.show_response: + data = result.read() + result = 200, 'OK' + if self.show_response: + print '-'*75, data, '-'*75 + return result + diff --git a/wxPython/distutils/command/sdist.py b/wxPython/distutils/command/sdist.py new file mode 100644 index 0000000000..c0b7dd45d9 --- /dev/null +++ b/wxPython/distutils/command/sdist.py @@ -0,0 +1,460 @@ +"""distutils.command.sdist + +Implements the Distutils 'sdist' command (create a source distribution).""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from types import * +from glob import glob +from distutils.core import Command +from distutils import dir_util, dep_util, file_util, archive_util +from distutils.text_file import TextFile +from distutils.errors import * +from distutils.filelist import FileList +from distutils import log + + +def show_formats (): + """Print all possible values for the 'formats' option (used by + the "--help-formats" command-line option). + """ + from distutils.fancy_getopt import FancyGetopt + from distutils.archive_util import ARCHIVE_FORMATS + formats=[] + for format in ARCHIVE_FORMATS.keys(): + formats.append(("formats=" + format, None, + ARCHIVE_FORMATS[format][2])) + formats.sort() + pretty_printer = FancyGetopt(formats) + pretty_printer.print_help( + "List of available source distribution formats:") + +class sdist (Command): + + description = "create a source distribution (tarball, zip file, etc.)" + + user_options = [ + ('template=', 't', + "name of manifest template file [default: MANIFEST.in]"), + ('manifest=', 'm', + "name of manifest file [default: MANIFEST]"), + ('use-defaults', None, + "include the default file set in the manifest " + "[default; disable with --no-defaults]"), + ('no-defaults', None, + "don't include the default file set"), + ('prune', None, + "specifically exclude files/directories that should not be " + "distributed (build tree, RCS/CVS dirs, etc.) " + "[default; disable with --no-prune]"), + ('no-prune', None, + "don't automatically exclude anything"), + ('manifest-only', 'o', + "just regenerate the manifest and then stop " + "(implies --force-manifest)"), + ('force-manifest', 'f', + "forcibly regenerate the manifest and carry on as usual"), + ('formats=', None, + "formats for source distribution (comma-separated list)"), + ('keep-temp', 'k', + "keep the distribution tree around after creating " + + "archive file(s)"), + ('dist-dir=', 'd', + "directory to put the source distribution archive(s) in " + "[default: dist]"), + ] + + boolean_options = ['use-defaults', 'prune', + 'manifest-only', 'force-manifest', + 'keep-temp'] + + help_options = [ + ('help-formats', None, + "list available distribution formats", show_formats), + ] + + negative_opt = {'no-defaults': 'use-defaults', + 'no-prune': 'prune' } + + default_format = { 'posix': 'gztar', + 'nt': 'zip' } + + def initialize_options (self): + # 'template' and 'manifest' are, respectively, the names of + # the manifest template and manifest file. + self.template = None + self.manifest = None + + # 'use_defaults': if true, we will include the default file set + # in the manifest + self.use_defaults = 1 + self.prune = 1 + + self.manifest_only = 0 + self.force_manifest = 0 + + self.formats = None + self.keep_temp = 0 + self.dist_dir = None + + self.archive_files = None + + + def finalize_options (self): + if self.manifest is None: + self.manifest = "MANIFEST" + if self.template is None: + self.template = "MANIFEST.in" + + self.ensure_string_list('formats') + if self.formats is None: + try: + self.formats = [self.default_format[os.name]] + except KeyError: + raise DistutilsPlatformError, \ + "don't know how to create source distributions " + \ + "on platform %s" % os.name + + bad_format = archive_util.check_archive_formats(self.formats) + if bad_format: + raise DistutilsOptionError, \ + "unknown archive format '%s'" % bad_format + + if self.dist_dir is None: + self.dist_dir = "dist" + + + def run (self): + + # 'filelist' contains the list of files that will make up the + # manifest + self.filelist = FileList() + + # Ensure that all required meta-data is given; warn if not (but + # don't die, it's not *that* serious!) + self.check_metadata() + + # Do whatever it takes to get the list of files to process + # (process the manifest template, read an existing manifest, + # whatever). File list is accumulated in 'self.filelist'. + self.get_file_list() + + # If user just wanted us to regenerate the manifest, stop now. + if self.manifest_only: + return + + # Otherwise, go ahead and create the source distribution tarball, + # or zipfile, or whatever. + self.make_distribution() + + + def check_metadata (self): + """Ensure that all required elements of meta-data (name, version, + URL, (author and author_email) or (maintainer and + maintainer_email)) are supplied by the Distribution object; warn if + any are missing. + """ + metadata = self.distribution.metadata + + missing = [] + for attr in ('name', 'version', 'url'): + if not (hasattr(metadata, attr) and getattr(metadata, attr)): + missing.append(attr) + + if missing: + self.warn("missing required meta-data: " + + string.join(missing, ", ")) + + if metadata.author: + if not metadata.author_email: + self.warn("missing meta-data: if 'author' supplied, " + + "'author_email' must be supplied too") + elif metadata.maintainer: + if not metadata.maintainer_email: + self.warn("missing meta-data: if 'maintainer' supplied, " + + "'maintainer_email' must be supplied too") + else: + self.warn("missing meta-data: either (author and author_email) " + + "or (maintainer and maintainer_email) " + + "must be supplied") + + # check_metadata () + + + def get_file_list (self): + """Figure out the list of files to include in the source + distribution, and put it in 'self.filelist'. This might involve + reading the manifest template (and writing the manifest), or just + reading the manifest, or just using the default file set -- it all + depends on the user's options and the state of the filesystem. + """ + + # If we have a manifest template, see if it's newer than the + # manifest; if so, we'll regenerate the manifest. + template_exists = os.path.isfile(self.template) + if template_exists: + template_newer = dep_util.newer(self.template, self.manifest) + + # The contents of the manifest file almost certainly depend on the + # setup script as well as the manifest template -- so if the setup + # script is newer than the manifest, we'll regenerate the manifest + # from the template. (Well, not quite: if we already have a + # manifest, but there's no template -- which will happen if the + # developer elects to generate a manifest some other way -- then we + # can't regenerate the manifest, so we don't.) + self.debug_print("checking if %s newer than %s" % + (self.distribution.script_name, self.manifest)) + setup_newer = dep_util.newer(self.distribution.script_name, + self.manifest) + + # cases: + # 1) no manifest, template exists: generate manifest + # (covered by 2a: no manifest == template newer) + # 2) manifest & template exist: + # 2a) template or setup script newer than manifest: + # regenerate manifest + # 2b) manifest newer than both: + # do nothing (unless --force or --manifest-only) + # 3) manifest exists, no template: + # do nothing (unless --force or --manifest-only) + # 4) no manifest, no template: generate w/ warning ("defaults only") + + manifest_outofdate = (template_exists and + (template_newer or setup_newer)) + force_regen = self.force_manifest or self.manifest_only + manifest_exists = os.path.isfile(self.manifest) + neither_exists = (not template_exists and not manifest_exists) + + # Regenerate the manifest if necessary (or if explicitly told to) + if manifest_outofdate or neither_exists or force_regen: + if not template_exists: + self.warn(("manifest template '%s' does not exist " + + "(using default file list)") % + self.template) + self.filelist.findall() + + if self.use_defaults: + self.add_defaults() + if template_exists: + self.read_template() + if self.prune: + self.prune_file_list() + + self.filelist.sort() + self.filelist.remove_duplicates() + self.write_manifest() + + # Don't regenerate the manifest, just read it in. + else: + self.read_manifest() + + # get_file_list () + + + def add_defaults (self): + """Add all the default files to self.filelist: + - README or README.txt + - setup.py + - test/test*.py + - all pure Python modules mentioned in setup script + - all C sources listed as part of extensions or C libraries + in the setup script (doesn't catch C headers!) + Warns if (README or README.txt) or setup.py are missing; everything + else is optional. + """ + + standards = [('README', 'README.txt'), self.distribution.script_name] + for fn in standards: + if type(fn) is TupleType: + alts = fn + got_it = 0 + for fn in alts: + if os.path.exists(fn): + got_it = 1 + self.filelist.append(fn) + break + + if not got_it: + self.warn("standard file not found: should have one of " + + string.join(alts, ', ')) + else: + if os.path.exists(fn): + self.filelist.append(fn) + else: + self.warn("standard file '%s' not found" % fn) + + optional = ['test/test*.py', 'setup.cfg'] + for pattern in optional: + files = filter(os.path.isfile, glob(pattern)) + if files: + self.filelist.extend(files) + + if self.distribution.has_pure_modules(): + build_py = self.get_finalized_command('build_py') + self.filelist.extend(build_py.get_source_files()) + + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + self.filelist.extend(build_ext.get_source_files()) + + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.filelist.extend(build_clib.get_source_files()) + + # add_defaults () + + + def read_template (self): + """Read and parse manifest template file named by self.template. + + (usually "MANIFEST.in") The parsing and processing is done by + 'self.filelist', which updates itself accordingly. + """ + log.info("reading manifest template '%s'", self.template) + template = TextFile(self.template, + strip_comments=1, + skip_blanks=1, + join_lines=1, + lstrip_ws=1, + rstrip_ws=1, + collapse_join=1) + + while 1: + line = template.readline() + if line is None: # end of file + break + + try: + self.filelist.process_template_line(line) + except DistutilsTemplateError, msg: + self.warn("%s, line %d: %s" % (template.filename, + template.current_line, + msg)) + + # read_template () + + + def prune_file_list (self): + """Prune off branches that might slip into the file list as created + by 'read_template()', but really don't belong there: + * the build tree (typically "build") + * the release tree itself (only an issue if we ran "sdist" + previously with --keep-temp, or it aborted) + * any RCS or CVS directories + """ + build = self.get_finalized_command('build') + base_dir = self.distribution.get_fullname() + + self.filelist.exclude_pattern(None, prefix=build.build_base) + self.filelist.exclude_pattern(None, prefix=base_dir) + self.filelist.exclude_pattern(r'/(RCS|CVS)/.*', is_regex=1) + + + def write_manifest (self): + """Write the file list in 'self.filelist' (presumably as filled in + by 'add_defaults()' and 'read_template()') to the manifest file + named by 'self.manifest'. + """ + self.execute(file_util.write_file, + (self.manifest, self.filelist.files), + "writing manifest file '%s'" % self.manifest) + + # write_manifest () + + + def read_manifest (self): + """Read the manifest file (named by 'self.manifest') and use it to + fill in 'self.filelist', the list of files to include in the source + distribution. + """ + log.info("reading manifest file '%s'", self.manifest) + manifest = open(self.manifest) + while 1: + line = manifest.readline() + if line == '': # end of file + break + if line[-1] == '\n': + line = line[0:-1] + self.filelist.append(line) + + # read_manifest () + + + def make_release_tree (self, base_dir, files): + """Create the directory tree that will become the source + distribution archive. All directories implied by the filenames in + 'files' are created under 'base_dir', and then we hard link or copy + (if hard linking is unavailable) those files into place. + Essentially, this duplicates the developer's source tree, but in a + directory named after the distribution, containing only the files + to be distributed. + """ + # Create all the directories under 'base_dir' necessary to + # put 'files' there; the 'mkpath()' is just so we don't die + # if the manifest happens to be empty. + self.mkpath(base_dir) + dir_util.create_tree(base_dir, files, dry_run=self.dry_run) + + # And walk over the list of files, either making a hard link (if + # os.link exists) to each one that doesn't already exist in its + # corresponding location under 'base_dir', or copying each file + # that's out-of-date in 'base_dir'. (Usually, all files will be + # out-of-date, because by default we blow away 'base_dir' when + # we're done making the distribution archives.) + + if hasattr(os, 'link'): # can make hard links on this system + link = 'hard' + msg = "making hard links in %s..." % base_dir + else: # nope, have to copy + link = None + msg = "copying files to %s..." % base_dir + + if not files: + log.warn("no files to distribute -- empty manifest?") + else: + log.info(msg) + for file in files: + if not os.path.isfile(file): + log.warn("'%s' not a regular file -- skipping" % file) + else: + dest = os.path.join(base_dir, file) + self.copy_file(file, dest, link=link) + + self.distribution.metadata.write_pkg_info(base_dir) + + # make_release_tree () + + def make_distribution (self): + """Create the source distribution(s). First, we create the release + tree with 'make_release_tree()'; then, we create all required + archive files (according to 'self.formats') from the release tree. + Finally, we clean up by blowing away the release tree (unless + 'self.keep_temp' is true). The list of archive files created is + stored so it can be retrieved later by 'get_archive_files()'. + """ + # Don't warn about missing meta-data here -- should be (and is!) + # done elsewhere. + base_dir = self.distribution.get_fullname() + base_name = os.path.join(self.dist_dir, base_dir) + + self.make_release_tree(base_dir, self.filelist.files) + archive_files = [] # remember names of files we create + for fmt in self.formats: + file = self.make_archive(base_name, fmt, base_dir=base_dir) + archive_files.append(file) + + self.archive_files = archive_files + + if not self.keep_temp: + dir_util.remove_tree(base_dir, dry_run=self.dry_run) + + def get_archive_files (self): + """Return the list of archive files created when the command + was run, or None if the command hasn't run yet. + """ + return self.archive_files + +# class sdist diff --git a/wxPython/distutils/core.py b/wxPython/distutils/core.py new file mode 100644 index 0000000000..a463272c2f --- /dev/null +++ b/wxPython/distutils/core.py @@ -0,0 +1,241 @@ +"""distutils.core + +The only module that needs to be imported to use the Distutils; provides +the 'setup' function (which is to be called from the setup script). Also +indirectly provides the Distribution and Command classes, although they are +really defined in distutils.dist and distutils.cmd. +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os +from types import * + +from distutils.debug import DEBUG +from distutils.errors import * +from distutils.util import grok_environment_error + +# Mainly import these so setup scripts can "from distutils.core import" them. +from distutils.dist import Distribution +from distutils.cmd import Command +from distutils.extension import Extension + +# This is a barebones help message generated displayed when the user +# runs the setup script with no arguments at all. More useful help +# is generated with various --help options: global help, list commands, +# and per-command help. +USAGE = """\ +usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] + or: %(script)s --help [cmd1 cmd2 ...] + or: %(script)s --help-commands + or: %(script)s cmd --help +""" + +def gen_usage (script_name): + script = os.path.basename(script_name) + return USAGE % vars() + + +# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'. +_setup_stop_after = None +_setup_distribution = None + +# Legal keyword arguments for the setup() function +setup_keywords = ('distclass', 'script_name', 'script_args', 'options', + 'name', 'version', 'author', 'author_email', + 'maintainer', 'maintainer_email', 'url', 'license', + 'description', 'long_description', 'keywords', + 'platforms', 'classifiers', 'download_url') + +# Legal keyword arguments for the Extension constructor +extension_keywords = ('name', 'sources', 'include_dirs', + 'define_macros', 'undef_macros', + 'library_dirs', 'libraries', 'runtime_library_dirs', + 'extra_objects', 'extra_compile_args', 'extra_link_args', + 'export_symbols', 'depends', 'language') + +def setup (**attrs): + """The gateway to the Distutils: do everything your setup script needs + to do, in a highly flexible and user-driven way. Briefly: create a + Distribution instance; find and parse config files; parse the command + line; run each Distutils command found there, customized by the options + supplied to 'setup()' (as keyword arguments), in config files, and on + the command line. + + The Distribution instance might be an instance of a class supplied via + the 'distclass' keyword argument to 'setup'; if no such class is + supplied, then the Distribution class (in dist.py) is instantiated. + All other arguments to 'setup' (except for 'cmdclass') are used to set + attributes of the Distribution instance. + + The 'cmdclass' argument, if supplied, is a dictionary mapping command + names to command classes. Each command encountered on the command line + will be turned into a command class, which is in turn instantiated; any + class found in 'cmdclass' is used in place of the default, which is + (for command 'foo_bar') class 'foo_bar' in module + 'distutils.command.foo_bar'. The command class must provide a + 'user_options' attribute which is a list of option specifiers for + 'distutils.fancy_getopt'. Any command-line options between the current + and the next command are used to set attributes of the current command + object. + + When the entire command-line has been successfully parsed, calls the + 'run()' method on each command object in turn. This method will be + driven entirely by the Distribution object (which each command object + has a reference to, thanks to its constructor), and the + command-specific options that became attributes of each command + object. + """ + + global _setup_stop_after, _setup_distribution + + # Determine the distribution class -- either caller-supplied or + # our Distribution (see below). + klass = attrs.get('distclass') + if klass: + del attrs['distclass'] + else: + klass = Distribution + + if not attrs.has_key('script_name'): + attrs['script_name'] = os.path.basename(sys.argv[0]) + if not attrs.has_key('script_args'): + attrs['script_args'] = sys.argv[1:] + + # Create the Distribution instance, using the remaining arguments + # (ie. everything except distclass) to initialize it + try: + _setup_distribution = dist = klass(attrs) + except DistutilsSetupError, msg: + if attrs.has_key('name'): + raise SystemExit, "error in %s setup command: %s" % \ + (attrs['name'], msg) + else: + raise SystemExit, "error in setup command: %s" % msg + + if _setup_stop_after == "init": + return dist + + # Find and parse the config file(s): they will override options from + # the setup script, but be overridden by the command line. + dist.parse_config_files() + + if DEBUG: + print "options (after parsing config files):" + dist.dump_option_dicts() + + if _setup_stop_after == "config": + return dist + + # Parse the command line; any command-line errors are the end user's + # fault, so turn them into SystemExit to suppress tracebacks. + try: + ok = dist.parse_command_line() + except DistutilsArgError, msg: + raise SystemExit, gen_usage(dist.script_name) + "\nerror: %s" % msg + + if DEBUG: + print "options (after parsing command line):" + dist.dump_option_dicts() + + if _setup_stop_after == "commandline": + return dist + + # And finally, run all the commands found on the command line. + if ok: + try: + dist.run_commands() + except KeyboardInterrupt: + raise SystemExit, "interrupted" + except (IOError, os.error), exc: + error = grok_environment_error(exc) + + if DEBUG: + sys.stderr.write(error + "\n") + raise + else: + raise SystemExit, error + + except (DistutilsError, + CCompilerError), msg: + if DEBUG: + raise + else: + raise SystemExit, "error: " + str(msg) + + return dist + +# setup () + + +def run_setup (script_name, script_args=None, stop_after="run"): + """Run a setup script in a somewhat controlled environment, and + return the Distribution instance that drives things. This is useful + if you need to find out the distribution meta-data (passed as + keyword args from 'script' to 'setup()', or the contents of the + config files or command-line. + + 'script_name' is a file that will be run with 'execfile()'; + 'sys.argv[0]' will be replaced with 'script' for the duration of the + call. 'script_args' is a list of strings; if supplied, + 'sys.argv[1:]' will be replaced by 'script_args' for the duration of + the call. + + 'stop_after' tells 'setup()' when to stop processing; possible + values: + init + stop after the Distribution instance has been created and + populated with the keyword arguments to 'setup()' + config + stop after config files have been parsed (and their data + stored in the Distribution instance) + commandline + stop after the command-line ('sys.argv[1:]' or 'script_args') + have been parsed (and the data stored in the Distribution) + run [default] + stop after all commands have been run (the same as if 'setup()' + had been called in the usual way + + Returns the Distribution instance, which provides all information + used to drive the Distutils. + """ + if stop_after not in ('init', 'config', 'commandline', 'run'): + raise ValueError, "invalid value for 'stop_after': %s" % `stop_after` + + global _setup_stop_after, _setup_distribution + _setup_stop_after = stop_after + + save_argv = sys.argv + g = {} + l = {} + try: + try: + sys.argv[0] = script_name + if script_args is not None: + sys.argv[1:] = script_args + execfile(script_name, g, l) + finally: + sys.argv = save_argv + _setup_stop_after = None + except SystemExit: + # Hmm, should we do something if exiting with a non-zero code + # (ie. error)? + pass + except: + raise + + if _setup_distribution is None: + raise RuntimeError, \ + ("'distutils.core.setup()' was never called -- " + "perhaps '%s' is not a Distutils setup script?") % \ + script_name + + # I wonder if the setup script's namespace -- g and l -- would be of + # any interest to callers? + #print "_setup_distribution:", _setup_distribution + return _setup_distribution + +# run_setup () + diff --git a/wxPython/distutils/cygwinccompiler.py b/wxPython/distutils/cygwinccompiler.py new file mode 100644 index 0000000000..18af388c3c --- /dev/null +++ b/wxPython/distutils/cygwinccompiler.py @@ -0,0 +1,397 @@ +"""distutils.cygwinccompiler + +Provides the CygwinCCompiler class, a subclass of UnixCCompiler that +handles the Cygwin port of the GNU C compiler to Windows. It also contains +the Mingw32CCompiler class which handles the mingw32 port of GCC (same as +cygwin in no-cygwin mode). +""" + +# problems: +# +# * if you use a msvc compiled python version (1.5.2) +# 1. you have to insert a __GNUC__ section in its config.h +# 2. you have to generate a import library for its dll +# - create a def-file for python??.dll +# - create a import library using +# dlltool --dllname python15.dll --def python15.def \ +# --output-lib libpython15.a +# +# see also http://starship.python.net/crew/kernr/mingw32/Notes.html +# +# * We put export_symbols in a def-file, and don't use +# --export-all-symbols because it doesn't worked reliable in some +# tested configurations. And because other windows compilers also +# need their symbols specified this no serious problem. +# +# tested configurations: +# +# * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works +# (after patching python's config.h and for C++ some other include files) +# see also http://starship.python.net/crew/kernr/mingw32/Notes.html +# * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works +# (ld doesn't support -shared, so we use dllwrap) +# * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now +# - its dllwrap doesn't work, there is a bug in binutils 2.10.90 +# see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html +# - using gcc -mdll instead dllwrap doesn't work without -static because +# it tries to link against dlls instead their import libraries. (If +# it finds the dll first.) +# By specifying -static we force ld to link against the import libraries, +# this is windows standard and there are normally not the necessary symbols +# in the dlls. +# *** only the version of June 2000 shows these problems + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os,sys,copy +from distutils.ccompiler import gen_preprocess_options, gen_lib_options +from distutils.unixccompiler import UnixCCompiler +from distutils.file_util import write_file +from distutils.errors import DistutilsExecError, CompileError, UnknownFileError +from distutils import log + +class CygwinCCompiler (UnixCCompiler): + + compiler_type = 'cygwin' + obj_extension = ".o" + static_lib_extension = ".a" + shared_lib_extension = ".dll" + static_lib_format = "lib%s%s" + shared_lib_format = "%s%s" + exe_extension = ".exe" + + def __init__ (self, verbose=0, dry_run=0, force=0): + + UnixCCompiler.__init__ (self, verbose, dry_run, force) + + (status, details) = check_config_h() + self.debug_print("Python's GCC status: %s (details: %s)" % + (status, details)) + if status is not CONFIG_H_OK: + self.warn( + "Python's pyconfig.h doesn't seem to support your compiler. " + "Reason: %s. " + "Compiling may fail because of undefined preprocessor macros." + % details) + + self.gcc_version, self.ld_version, self.dllwrap_version = \ + get_versions() + self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" % + (self.gcc_version, + self.ld_version, + self.dllwrap_version) ) + + # ld_version >= "2.10.90" should also be able to use + # gcc -mdll instead of dllwrap + # Older dllwraps had own version numbers, newer ones use the + # same as the rest of binutils ( also ld ) + # dllwrap 2.10.90 is buggy + if self.ld_version >= "2.10.90": + self.linker_dll = "gcc" + else: + self.linker_dll = "dllwrap" + + # Hard-code GCC because that's what this is all about. + # XXX optimization, warnings etc. should be customizable. + self.set_executables(compiler='gcc -mcygwin -O -Wall', + compiler_so='gcc -mcygwin -mdll -O -Wall', + linker_exe='gcc -mcygwin', + linker_so=('%s -mcygwin -mdll -static' % + self.linker_dll)) + + # cygwin and mingw32 need different sets of libraries + if self.gcc_version == "2.91.57": + # cygwin shouldn't need msvcrt, but without the dlls will crash + # (gcc version 2.91.57) -- perhaps something about initialization + self.dll_libraries=["msvcrt"] + self.warn( + "Consider upgrading to a newer version of gcc") + else: + self.dll_libraries=[] + + # __init__ () + + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + if ext == '.rc' or ext == '.res': + # gcc needs '.res' and '.rc' compiled to object files !!! + try: + self.spawn(["windres", "-i", src, "-o", obj]) + except DistutilsExecError, msg: + raise CompileError, msg + else: # for other files use the C-compiler + try: + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + # use separate copies, so we can modify the lists + extra_preargs = copy.copy(extra_preargs or []) + libraries = copy.copy(libraries or []) + objects = copy.copy(objects or []) + + # Additional libraries + libraries.extend(self.dll_libraries) + + # handle export symbols by creating a def-file + # with executables this only works with gcc/ld as linker + if ((export_symbols is not None) and + (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): + # (The linker doesn't do anything if output is up-to-date. + # So it would probably better to check if we really need this, + # but for this we had to insert some unchanged parts of + # UnixCCompiler, and this is not what we want.) + + # we want to put some files in the same directory as the + # object files are, build_temp doesn't help much + # where are the object files + temp_dir = os.path.dirname(objects[0]) + # name of dll to give the helper files the same base name + (dll_name, dll_extension) = os.path.splitext( + os.path.basename(output_filename)) + + # generate the filenames for these files + def_file = os.path.join(temp_dir, dll_name + ".def") + lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a") + + # Generate .def file + contents = [ + "LIBRARY %s" % os.path.basename(output_filename), + "EXPORTS"] + for sym in export_symbols: + contents.append(sym) + self.execute(write_file, (def_file, contents), + "writing %s" % def_file) + + # next add options for def-file and to creating import libraries + + # dllwrap uses different options than gcc/ld + if self.linker_dll == "dllwrap": + extra_preargs.extend(["--output-lib", lib_file]) + # for dllwrap we have to use a special option + extra_preargs.extend(["--def", def_file]) + # we use gcc/ld here and can be sure ld is >= 2.9.10 + else: + # doesn't work: bfd_close build\...\libfoo.a: Invalid operation + #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) + # for gcc/ld the def-file is specified as any object files + objects.append(def_file) + + #end: if ((export_symbols is not None) and + # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): + + # who wants symbols and a many times larger output file + # should explicitly switch the debug mode on + # otherwise we let dllwrap/ld strip the output file + # (On my machine: 10KB < stripped_file < ??100KB + # unstripped_file = stripped_file + XXX KB + # ( XXX=254 for a typical python extension)) + if not debug: + extra_preargs.append("-s") + + UnixCCompiler.link(self, + target_desc, + objects, + output_filename, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + None, # export_symbols, we do this in our def-file + debug, + extra_preargs, + extra_postargs, + build_temp, + target_lang) + + # link () + + # -- Miscellaneous methods ----------------------------------------- + + # overwrite the one from CCompiler to support rc and res-files + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + if ext not in (self.src_extensions + ['.rc','.res']): + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % \ + (ext, src_name) + if strip_dir: + base = os.path.basename (base) + if ext == '.res' or ext == '.rc': + # these need to be compiled to object files + obj_names.append (os.path.join (output_dir, + base + ext + self.obj_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + +# class CygwinCCompiler + + +# the same as cygwin plus some additional parameters +class Mingw32CCompiler (CygwinCCompiler): + + compiler_type = 'mingw32' + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CygwinCCompiler.__init__ (self, verbose, dry_run, force) + + # A real mingw32 doesn't need to specify a different entry point, + # but cygwin 2.91.57 in no-cygwin-mode needs it. + if self.gcc_version <= "2.91.57": + entry_point = '--entry _DllMain@12' + else: + entry_point = '' + + self.set_executables(compiler='gcc -mno-cygwin -O -Wall', + compiler_so='gcc -mno-cygwin -mdll -O -Wall', + linker_exe='gcc -mno-cygwin', + linker_so='%s -mno-cygwin -mdll -static %s' + % (self.linker_dll, entry_point)) + # Maybe we should also append -mthreads, but then the finished + # dlls need another dll (mingwm10.dll see Mingw32 docs) + # (-mthreads: Support thread-safe exception handling on `Mingw32') + + # no additional libraries needed + self.dll_libraries=[] + + # __init__ () + +# class Mingw32CCompiler + +# Because these compilers aren't configured in Python's pyconfig.h file by +# default, we should at least warn the user if he is using a unmodified +# version. + +CONFIG_H_OK = "ok" +CONFIG_H_NOTOK = "not ok" +CONFIG_H_UNCERTAIN = "uncertain" + +def check_config_h(): + + """Check if the current Python installation (specifically, pyconfig.h) + appears amenable to building extensions with GCC. Returns a tuple + (status, details), where 'status' is one of the following constants: + CONFIG_H_OK + all is well, go ahead and compile + CONFIG_H_NOTOK + doesn't look good + CONFIG_H_UNCERTAIN + not sure -- unable to read pyconfig.h + 'details' is a human-readable string explaining the situation. + + Note there are two ways to conclude "OK": either 'sys.version' contains + the string "GCC" (implying that this Python was built with GCC), or the + installed "pyconfig.h" contains the string "__GNUC__". + """ + + # XXX since this function also checks sys.version, it's not strictly a + # "pyconfig.h" check -- should probably be renamed... + + from distutils import sysconfig + import string + # if sys.version contains GCC then python was compiled with + # GCC, and the pyconfig.h file should be OK + if string.find(sys.version,"GCC") >= 0: + return (CONFIG_H_OK, "sys.version mentions 'GCC'") + + fn = sysconfig.get_config_h_filename() + try: + # It would probably better to read single lines to search. + # But we do this only once, and it is fast enough + f = open(fn) + s = f.read() + f.close() + + except IOError, exc: + # if we can't read this file, we cannot say it is wrong + # the compiler will complain later about this file as missing + return (CONFIG_H_UNCERTAIN, + "couldn't read '%s': %s" % (fn, exc.strerror)) + + else: + # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar + if string.find(s,"__GNUC__") >= 0: + return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn) + else: + return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn) + + + +def get_versions(): + """ Try to find out the versions of gcc, ld and dllwrap. + If not possible it returns None for it. + """ + from distutils.version import StrictVersion + from distutils.spawn import find_executable + import re + + gcc_exe = find_executable('gcc') + if gcc_exe: + out = os.popen(gcc_exe + ' -dumpversion','r') + out_string = out.read() + out.close() + result = re.search('(\d+\.\d+\.\d+)',out_string) + if result: + gcc_version = StrictVersion(result.group(1)) + else: + gcc_version = None + else: + gcc_version = None + ld_exe = find_executable('ld') + if ld_exe: + out = os.popen(ld_exe + ' -v','r') + out_string = out.read() + out.close() + result = re.search('(\d+\.\d+\.\d+)',out_string) + if result: + ld_version = StrictVersion(result.group(1)) + else: + ld_version = None + else: + ld_version = None + dllwrap_exe = find_executable('dllwrap') + if dllwrap_exe: + out = os.popen(dllwrap_exe + ' --version','r') + out_string = out.read() + out.close() + result = re.search(' (\d+\.\d+\.\d+)',out_string) + if result: + dllwrap_version = StrictVersion(result.group(1)) + else: + dllwrap_version = None + else: + dllwrap_version = None + return (gcc_version, ld_version, dllwrap_version) diff --git a/wxPython/distutils/debug.py b/wxPython/distutils/debug.py new file mode 100644 index 0000000000..e195ebdcdf --- /dev/null +++ b/wxPython/distutils/debug.py @@ -0,0 +1,10 @@ +import os + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +# If DISTUTILS_DEBUG is anything other than the empty string, we run in +# debug mode. +DEBUG = os.environ.get('DISTUTILS_DEBUG') + diff --git a/wxPython/distutils/dep_util.py b/wxPython/distutils/dep_util.py new file mode 100644 index 0000000000..0746633d23 --- /dev/null +++ b/wxPython/distutils/dep_util.py @@ -0,0 +1,95 @@ +"""distutils.dep_util + +Utility functions for simple, timestamp-based dependency of files +and groups of files; also, function based entirely on such +timestamp dependency analysis.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.errors import DistutilsFileError + + +def newer (source, target): + """Return true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. Return false if + both exist and 'target' is the same age or younger than 'source'. + Raise DistutilsFileError if 'source' does not exist. + """ + if not os.path.exists(source): + raise DistutilsFileError, "file '%s' does not exist" % source + if not os.path.exists(target): + return 1 + + from stat import ST_MTIME + mtime1 = os.stat(source)[ST_MTIME] + mtime2 = os.stat(target)[ST_MTIME] + + return mtime1 > mtime2 + +# newer () + + +def newer_pairwise (sources, targets): + """Walk two filename lists in parallel, testing if each source is newer + than its corresponding target. Return a pair of lists (sources, + targets) where source is newer than target, according to the semantics + of 'newer()'. + """ + if len(sources) != len(targets): + raise ValueError, "'sources' and 'targets' must be same length" + + # build a pair of lists (sources, targets) where source is newer + n_sources = [] + n_targets = [] + for i in range(len(sources)): + if newer(sources[i], targets[i]): + n_sources.append(sources[i]) + n_targets.append(targets[i]) + + return (n_sources, n_targets) + +# newer_pairwise () + + +def newer_group (sources, target, missing='error'): + """Return true if 'target' is out-of-date with respect to any file + listed in 'sources'. In other words, if 'target' exists and is newer + than every file in 'sources', return false; otherwise return true. + 'missing' controls what we do when a source file is missing; the + default ("error") is to blow up with an OSError from inside 'stat()'; + if it is "ignore", we silently drop any missing source files; if it is + "newer", any missing source files make us assume that 'target' is + out-of-date (this is handy in "dry-run" mode: it'll make you pretend to + carry out commands that wouldn't work because inputs are missing, but + that doesn't matter because you're not actually going to run the + commands). + """ + # If the target doesn't even exist, then it's definitely out-of-date. + if not os.path.exists(target): + return 1 + + # Otherwise we have to find out the hard way: if *any* source file + # is more recent than 'target', then 'target' is out-of-date and + # we can immediately return true. If we fall through to the end + # of the loop, then 'target' is up-to-date and we return false. + from stat import ST_MTIME + target_mtime = os.stat(target)[ST_MTIME] + for source in sources: + if not os.path.exists(source): + if missing == 'error': # blow up when we stat() the file + pass + elif missing == 'ignore': # missing source dropped from + continue # target's dependency list + elif missing == 'newer': # missing source means target is + return 1 # out-of-date + + source_mtime = os.stat(source)[ST_MTIME] + if source_mtime > target_mtime: + return 1 + else: + return 0 + +# newer_group () diff --git a/wxPython/distutils/dir_util.py b/wxPython/distutils/dir_util.py new file mode 100644 index 0000000000..bd1ea0f243 --- /dev/null +++ b/wxPython/distutils/dir_util.py @@ -0,0 +1,228 @@ +"""distutils.dir_util + +Utility functions for manipulating directories and directory trees.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os, sys +from types import * +from distutils.errors import DistutilsFileError, DistutilsInternalError +from distutils import log + +# cache for by mkpath() -- in addition to cheapening redundant calls, +# eliminates redundant "creating /foo/bar/baz" messages in dry-run mode +_path_created = {} + +# I don't use os.makedirs because a) it's new to Python 1.5.2, and +# b) it blows up if the directory already exists (I want to silently +# succeed in that case). +def mkpath (name, mode=0777, verbose=0, dry_run=0): + """Create a directory and any missing ancestor directories. If the + directory already exists (or if 'name' is the empty string, which + means the current directory, which of course exists), then do + nothing. Raise DistutilsFileError if unable to create some + directory along the way (eg. some sub-path exists, but is a file + rather than a directory). If 'verbose' is true, print a one-line + summary of each mkdir to stdout. Return the list of directories + actually created.""" + + global _path_created + + # Detect a common bug -- name is None + if type(name) is not StringType: + raise DistutilsInternalError, \ + "mkpath: 'name' must be a string (got %s)" % `name` + + # XXX what's the better way to handle verbosity? print as we create + # each directory in the path (the current behaviour), or only announce + # the creation of the whole path? (quite easy to do the latter since + # we're not using a recursive algorithm) + + name = os.path.normpath(name) + created_dirs = [] + if os.path.isdir(name) or name == '': + return created_dirs + if _path_created.get(os.path.abspath(name)): + return created_dirs + + (head, tail) = os.path.split(name) + tails = [tail] # stack of lone dirs to create + + while head and tail and not os.path.isdir(head): + #print "splitting '%s': " % head, + (head, tail) = os.path.split(head) + #print "to ('%s','%s')" % (head, tail) + tails.insert(0, tail) # push next higher dir onto stack + + #print "stack of tails:", tails + + # now 'head' contains the deepest directory that already exists + # (that is, the child of 'head' in 'name' is the highest directory + # that does *not* exist) + for d in tails: + #print "head = %s, d = %s: " % (head, d), + head = os.path.join(head, d) + abs_head = os.path.abspath(head) + + if _path_created.get(abs_head): + continue + + log.info("creating %s", head) + + if not dry_run: + try: + os.mkdir(head) + created_dirs.append(head) + except OSError, exc: + raise DistutilsFileError, \ + "could not create '%s': %s" % (head, exc[-1]) + + _path_created[abs_head] = 1 + return created_dirs + +# mkpath () + + +def create_tree (base_dir, files, mode=0777, verbose=0, dry_run=0): + + """Create all the empty directories under 'base_dir' needed to + put 'files' there. 'base_dir' is just the a name of a directory + which doesn't necessarily exist yet; 'files' is a list of filenames + to be interpreted relative to 'base_dir'. 'base_dir' + the + directory portion of every file in 'files' will be created if it + doesn't already exist. 'mode', 'verbose' and 'dry_run' flags are as + for 'mkpath()'.""" + + # First get the list of directories to create + need_dir = {} + for file in files: + need_dir[os.path.join(base_dir, os.path.dirname(file))] = 1 + need_dirs = need_dir.keys() + need_dirs.sort() + + # Now create them + for dir in need_dirs: + mkpath(dir, mode, dry_run=dry_run) + +# create_tree () + + +def copy_tree (src, dst, + preserve_mode=1, + preserve_times=1, + preserve_symlinks=0, + update=0, + verbose=0, + dry_run=0): + + """Copy an entire directory tree 'src' to a new location 'dst'. Both + 'src' and 'dst' must be directory names. If 'src' is not a + directory, raise DistutilsFileError. If 'dst' does not exist, it is + created with 'mkpath()'. The end result of the copy is that every + file in 'src' is copied to 'dst', and directories under 'src' are + recursively copied to 'dst'. Return the list of files that were + copied or might have been copied, using their output name. The + return value is unaffected by 'update' or 'dry_run': it is simply + the list of all files under 'src', with the names changed to be + under 'dst'. + + 'preserve_mode' and 'preserve_times' are the same as for + 'copy_file'; note that they only apply to regular files, not to + directories. If 'preserve_symlinks' is true, symlinks will be + copied as symlinks (on platforms that support them!); otherwise + (the default), the destination of the symlink will be copied. + 'update' and 'verbose' are the same as for 'copy_file'.""" + + from distutils.file_util import copy_file + + if not dry_run and not os.path.isdir(src): + raise DistutilsFileError, \ + "cannot copy tree '%s': not a directory" % src + try: + names = os.listdir(src) + except os.error, (errno, errstr): + if dry_run: + names = [] + else: + raise DistutilsFileError, \ + "error listing files in '%s': %s" % (src, errstr) + + if not dry_run: + mkpath(dst) + + outputs = [] + + for n in names: + src_name = os.path.join(src, n) + dst_name = os.path.join(dst, n) + + if preserve_symlinks and os.path.islink(src_name): + link_dest = os.readlink(src_name) + log.info("linking %s -> %s", dst_name, link_dest) + if not dry_run: + os.symlink(link_dest, dst_name) + outputs.append(dst_name) + + elif os.path.isdir(src_name): + outputs.extend( + copy_tree(src_name, dst_name, preserve_mode, + preserve_times, preserve_symlinks, update, + dry_run=dry_run)) + else: + copy_file(src_name, dst_name, preserve_mode, + preserve_times, update, dry_run=dry_run) + outputs.append(dst_name) + + return outputs + +# copy_tree () + +# Helper for remove_tree() +def _build_cmdtuple(path, cmdtuples): + for f in os.listdir(path): + real_f = os.path.join(path,f) + if os.path.isdir(real_f) and not os.path.islink(real_f): + _build_cmdtuple(real_f, cmdtuples) + else: + cmdtuples.append((os.remove, real_f)) + cmdtuples.append((os.rmdir, path)) + + +def remove_tree (directory, verbose=0, dry_run=0): + """Recursively remove an entire directory tree. Any errors are ignored + (apart from being reported to stdout if 'verbose' is true). + """ + from distutils.util import grok_environment_error + global _path_created + + log.info("removing '%s' (and everything under it)", directory) + if dry_run: + return + cmdtuples = [] + _build_cmdtuple(directory, cmdtuples) + for cmd in cmdtuples: + try: + apply(cmd[0], (cmd[1],)) + # remove dir from cache if it's already there + abspath = os.path.abspath(cmd[1]) + if _path_created.has_key(abspath): + del _path_created[abspath] + except (IOError, OSError), exc: + log.warn(grok_environment_error( + exc, "error removing %s: " % directory)) + + +def ensure_relative (path): + """Take the full path 'path', and make it a relative path so + it can be the second argument to os.path.join(). + """ + drive, path = os.path.splitdrive(path) + if sys.platform == 'mac': + return os.sep + path + else: + if path[0:1] == os.sep: + path = drive + path[1:] + return path + diff --git a/wxPython/distutils/dist.py b/wxPython/distutils/dist.py new file mode 100644 index 0000000000..08e2a4f7d8 --- /dev/null +++ b/wxPython/distutils/dist.py @@ -0,0 +1,1095 @@ +"""distutils.dist + +Provides the Distribution class, which represents the module distribution +being built/installed/distributed. +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string, re +from types import * +from copy import copy + +try: + import warnings +except ImportError: + warnings = None + +from distutils.errors import * +from distutils.fancy_getopt import FancyGetopt, translate_longopt +from distutils.util import check_environ, strtobool, rfc822_escape +from distutils import log +from distutils.debug import DEBUG + +# Regex to define acceptable Distutils command names. This is not *quite* +# the same as a Python NAME -- I don't allow leading underscores. The fact +# that they're very similar is no coincidence; the default naming scheme is +# to look for a Python module named after the command. +command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$') + + +class Distribution: + """The core of the Distutils. Most of the work hiding behind 'setup' + is really done within a Distribution instance, which farms the work out + to the Distutils commands specified on the command line. + + Setup scripts will almost never instantiate Distribution directly, + unless the 'setup()' function is totally inadequate to their needs. + However, it is conceivable that a setup script might wish to subclass + Distribution for some specialized purpose, and then pass the subclass + to 'setup()' as the 'distclass' keyword argument. If so, it is + necessary to respect the expectations that 'setup' has of Distribution. + See the code for 'setup()', in core.py, for details. + """ + + + # 'global_options' describes the command-line options that may be + # supplied to the setup script prior to any actual commands. + # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of + # these global options. This list should be kept to a bare minimum, + # since every global option is also valid as a command option -- and we + # don't want to pollute the commands with too many options that they + # have minimal control over. + # The fourth entry for verbose means that it can be repeated. + global_options = [('verbose', 'v', "run verbosely (default)", 1), + ('quiet', 'q', "run quietly (turns verbosity off)"), + ('dry-run', 'n', "don't actually do anything"), + ('help', 'h', "show detailed help message"), + ] + + # options that are not propagated to the commands + display_options = [ + ('help-commands', None, + "list all available commands"), + ('name', None, + "print package name"), + ('version', 'V', + "print package version"), + ('fullname', None, + "print -"), + ('author', None, + "print the author's name"), + ('author-email', None, + "print the author's email address"), + ('maintainer', None, + "print the maintainer's name"), + ('maintainer-email', None, + "print the maintainer's email address"), + ('contact', None, + "print the maintainer's name if known, else the author's"), + ('contact-email', None, + "print the maintainer's email address if known, else the author's"), + ('url', None, + "print the URL for this package"), + ('license', None, + "print the license of the package"), + ('licence', None, + "alias for --license"), + ('description', None, + "print the package description"), + ('long-description', None, + "print the long package description"), + ('platforms', None, + "print the list of platforms"), + ('classifiers', None, + "print the list of classifiers"), + ('keywords', None, + "print the list of keywords"), + ] + display_option_names = map(lambda x: translate_longopt(x[0]), + display_options) + + # negative options are options that exclude other options + negative_opt = {'quiet': 'verbose'} + + + # -- Creation/initialization methods ------------------------------- + + def __init__ (self, attrs=None): + """Construct a new Distribution instance: initialize all the + attributes of a Distribution, and then use 'attrs' (a dictionary + mapping attribute names to values) to assign some of those + attributes their "real" values. (Any attributes not mentioned in + 'attrs' will be assigned to some null value: 0, None, an empty list + or dictionary, etc.) Most importantly, initialize the + 'command_obj' attribute to the empty dictionary; this will be + filled in with real command objects by 'parse_command_line()'. + """ + + # Default values for our command-line options + self.verbose = 1 + self.dry_run = 0 + self.help = 0 + for attr in self.display_option_names: + setattr(self, attr, 0) + + # Store the distribution meta-data (name, version, author, and so + # forth) in a separate object -- we're getting to have enough + # information here (and enough command-line options) that it's + # worth it. Also delegate 'get_XXX()' methods to the 'metadata' + # object in a sneaky and underhanded (but efficient!) way. + self.metadata = DistributionMetadata() + for basename in self.metadata._METHOD_BASENAMES: + method_name = "get_" + basename + setattr(self, method_name, getattr(self.metadata, method_name)) + + # 'cmdclass' maps command names to class objects, so we + # can 1) quickly figure out which class to instantiate when + # we need to create a new command object, and 2) have a way + # for the setup script to override command classes + self.cmdclass = {} + + # 'script_name' and 'script_args' are usually set to sys.argv[0] + # and sys.argv[1:], but they can be overridden when the caller is + # not necessarily a setup script run from the command-line. + self.script_name = None + self.script_args = None + + # 'command_options' is where we store command options between + # parsing them (from config files, the command-line, etc.) and when + # they are actually needed -- ie. when the command in question is + # instantiated. It is a dictionary of dictionaries of 2-tuples: + # command_options = { command_name : { option : (source, value) } } + self.command_options = {} + + # These options are really the business of various commands, rather + # than of the Distribution itself. We provide aliases for them in + # Distribution as a convenience to the developer. + self.packages = None + self.package_dir = None + self.py_modules = None + self.libraries = None + self.headers = None + self.ext_modules = None + self.ext_package = None + self.include_dirs = None + self.extra_path = None + self.scripts = None + self.data_files = None + + # And now initialize bookkeeping stuff that can't be supplied by + # the caller at all. 'command_obj' maps command names to + # Command instances -- that's how we enforce that every command + # class is a singleton. + self.command_obj = {} + + # 'have_run' maps command names to boolean values; it keeps track + # of whether we have actually run a particular command, to make it + # cheap to "run" a command whenever we think we might need to -- if + # it's already been done, no need for expensive filesystem + # operations, we just check the 'have_run' dictionary and carry on. + # It's only safe to query 'have_run' for a command class that has + # been instantiated -- a false value will be inserted when the + # command object is created, and replaced with a true value when + # the command is successfully run. Thus it's probably best to use + # '.get()' rather than a straight lookup. + self.have_run = {} + + # Now we'll use the attrs dictionary (ultimately, keyword args from + # the setup script) to possibly override any or all of these + # distribution options. + + if attrs: + + # Pull out the set of command options and work on them + # specifically. Note that this order guarantees that aliased + # command options will override any supplied redundantly + # through the general options dictionary. + options = attrs.get('options') + if options: + del attrs['options'] + for (command, cmd_options) in options.items(): + opt_dict = self.get_option_dict(command) + for (opt, val) in cmd_options.items(): + opt_dict[opt] = ("setup script", val) + + # Now work on the rest of the attributes. Any attribute that's + # not already defined is invalid! + for (key,val) in attrs.items(): + if hasattr(self.metadata, key): + setattr(self.metadata, key, val) + elif hasattr(self, key): + setattr(self, key, val) + else: + msg = "Unknown distribution option: %s" % repr(key) + if warnings is not None: + warnings.warn(msg) + else: + sys.stderr.write(msg + "\n") + + self.finalize_options() + + # __init__ () + + + def get_option_dict (self, command): + """Get the option dictionary for a given command. If that + command's option dictionary hasn't been created yet, then create it + and return the new dictionary; otherwise, return the existing + option dictionary. + """ + + dict = self.command_options.get(command) + if dict is None: + dict = self.command_options[command] = {} + return dict + + + def dump_option_dicts (self, header=None, commands=None, indent=""): + from pprint import pformat + + if commands is None: # dump all command option dicts + commands = self.command_options.keys() + commands.sort() + + if header is not None: + print indent + header + indent = indent + " " + + if not commands: + print indent + "no commands known yet" + return + + for cmd_name in commands: + opt_dict = self.command_options.get(cmd_name) + if opt_dict is None: + print indent + "no option dict for '%s' command" % cmd_name + else: + print indent + "option dict for '%s' command:" % cmd_name + out = pformat(opt_dict) + for line in string.split(out, "\n"): + print indent + " " + line + + # dump_option_dicts () + + + + # -- Config file finding/parsing methods --------------------------- + + def find_config_files (self): + """Find as many configuration files as should be processed for this + platform, and return a list of filenames in the order in which they + should be parsed. The filenames returned are guaranteed to exist + (modulo nasty race conditions). + + There are three possible config files: distutils.cfg in the + Distutils installation directory (ie. where the top-level + Distutils __inst__.py file lives), a file in the user's home + directory named .pydistutils.cfg on Unix and pydistutils.cfg + on Windows/Mac, and setup.cfg in the current directory. + """ + files = [] + check_environ() + + # Where to look for the system-wide Distutils config file + sys_dir = os.path.dirname(sys.modules['distutils'].__file__) + + # Look for the system config file + sys_file = os.path.join(sys_dir, "distutils.cfg") + if os.path.isfile(sys_file): + files.append(sys_file) + + # What to call the per-user config file + if os.name == 'posix': + user_filename = ".pydistutils.cfg" + else: + user_filename = "pydistutils.cfg" + + # And look for the user config file + if os.environ.has_key('HOME'): + user_file = os.path.join(os.environ.get('HOME'), user_filename) + if os.path.isfile(user_file): + files.append(user_file) + + # All platforms support local setup.cfg + local_file = "setup.cfg" + if os.path.isfile(local_file): + files.append(local_file) + + return files + + # find_config_files () + + + def parse_config_files (self, filenames=None): + + from ConfigParser import ConfigParser + + if filenames is None: + filenames = self.find_config_files() + + if DEBUG: print "Distribution.parse_config_files():" + + parser = ConfigParser() + for filename in filenames: + if DEBUG: print " reading", filename + parser.read(filename) + for section in parser.sections(): + options = parser.options(section) + opt_dict = self.get_option_dict(section) + + for opt in options: + if opt != '__name__': + val = parser.get(section,opt) + opt = string.replace(opt, '-', '_') + opt_dict[opt] = (filename, val) + + # Make the ConfigParser forget everything (so we retain + # the original filenames that options come from) -- gag, + # retch, puke -- another good reason for a distutils- + # specific config parser (sigh...) + parser.__init__() + + # If there was a "global" section in the config file, use it + # to set Distribution options. + + if self.command_options.has_key('global'): + for (opt, (src, val)) in self.command_options['global'].items(): + alias = self.negative_opt.get(opt) + try: + if alias: + setattr(self, alias, not strtobool(val)) + elif opt in ('verbose', 'dry_run'): # ugh! + setattr(self, opt, strtobool(val)) + except ValueError, msg: + raise DistutilsOptionError, msg + + # parse_config_files () + + + # -- Command-line parsing methods ---------------------------------- + + def parse_command_line (self): + """Parse the setup script's command line, taken from the + 'script_args' instance attribute (which defaults to 'sys.argv[1:]' + -- see 'setup()' in core.py). This list is first processed for + "global options" -- options that set attributes of the Distribution + instance. Then, it is alternately scanned for Distutils commands + and options for that command. Each new command terminates the + options for the previous command. The allowed options for a + command are determined by the 'user_options' attribute of the + command class -- thus, we have to be able to load command classes + in order to parse the command line. Any error in that 'options' + attribute raises DistutilsGetoptError; any error on the + command-line raises DistutilsArgError. If no Distutils commands + were found on the command line, raises DistutilsArgError. Return + true if command-line was successfully parsed and we should carry + on with executing commands; false if no errors but we shouldn't + execute commands (currently, this only happens if user asks for + help). + """ + # + # We now have enough information to show the Macintosh dialog + # that allows the user to interactively specify the "command line". + # + if sys.platform == 'mac': + import EasyDialogs + cmdlist = self.get_command_list() + self.script_args = EasyDialogs.GetArgv( + self.global_options + self.display_options, cmdlist) + + # We have to parse the command line a bit at a time -- global + # options, then the first command, then its options, and so on -- + # because each command will be handled by a different class, and + # the options that are valid for a particular class aren't known + # until we have loaded the command class, which doesn't happen + # until we know what the command is. + + self.commands = [] + parser = FancyGetopt(self.global_options + self.display_options) + parser.set_negative_aliases(self.negative_opt) + parser.set_aliases({'licence': 'license'}) + args = parser.getopt(args=self.script_args, object=self) + option_order = parser.get_option_order() + log.set_verbosity(self.verbose) + + # for display options we return immediately + if self.handle_display_options(option_order): + return + + while args: + args = self._parse_command_opts(parser, args) + if args is None: # user asked for help (and got it) + return + + # Handle the cases of --help as a "global" option, ie. + # "setup.py --help" and "setup.py --help command ...". For the + # former, we show global options (--verbose, --dry-run, etc.) + # and display-only options (--name, --version, etc.); for the + # latter, we omit the display-only options and show help for + # each command listed on the command line. + if self.help: + self._show_help(parser, + display_options=len(self.commands) == 0, + commands=self.commands) + return + + # Oops, no commands found -- an end-user error + if not self.commands: + raise DistutilsArgError, "no commands supplied" + + # All is well: return true + return 1 + + # parse_command_line() + + def _parse_command_opts (self, parser, args): + """Parse the command-line options for a single command. + 'parser' must be a FancyGetopt instance; 'args' must be the list + of arguments, starting with the current command (whose options + we are about to parse). Returns a new version of 'args' with + the next command at the front of the list; will be the empty + list if there are no more commands on the command line. Returns + None if the user asked for help on this command. + """ + # late import because of mutual dependence between these modules + from distutils.cmd import Command + + # Pull the current command from the head of the command line + command = args[0] + if not command_re.match(command): + raise SystemExit, "invalid command name '%s'" % command + self.commands.append(command) + + # Dig up the command class that implements this command, so we + # 1) know that it's a valid command, and 2) know which options + # it takes. + try: + cmd_class = self.get_command_class(command) + except DistutilsModuleError, msg: + raise DistutilsArgError, msg + + # Require that the command class be derived from Command -- want + # to be sure that the basic "command" interface is implemented. + if not issubclass(cmd_class, Command): + raise DistutilsClassError, \ + "command class %s must subclass Command" % cmd_class + + # Also make sure that the command object provides a list of its + # known options. + if not (hasattr(cmd_class, 'user_options') and + type(cmd_class.user_options) is ListType): + raise DistutilsClassError, \ + ("command class %s must provide " + + "'user_options' attribute (a list of tuples)") % \ + cmd_class + + # If the command class has a list of negative alias options, + # merge it in with the global negative aliases. + negative_opt = self.negative_opt + if hasattr(cmd_class, 'negative_opt'): + negative_opt = copy(negative_opt) + negative_opt.update(cmd_class.negative_opt) + + # Check for help_options in command class. They have a different + # format (tuple of four) so we need to preprocess them here. + if (hasattr(cmd_class, 'help_options') and + type(cmd_class.help_options) is ListType): + help_options = fix_help_options(cmd_class.help_options) + else: + help_options = [] + + + # All commands support the global options too, just by adding + # in 'global_options'. + parser.set_option_table(self.global_options + + cmd_class.user_options + + help_options) + parser.set_negative_aliases(negative_opt) + (args, opts) = parser.getopt(args[1:]) + if hasattr(opts, 'help') and opts.help: + self._show_help(parser, display_options=0, commands=[cmd_class]) + return + + if (hasattr(cmd_class, 'help_options') and + type(cmd_class.help_options) is ListType): + help_option_found=0 + for (help_option, short, desc, func) in cmd_class.help_options: + if hasattr(opts, parser.get_attr_name(help_option)): + help_option_found=1 + #print "showing help for option %s of command %s" % \ + # (help_option[0],cmd_class) + + if callable(func): + func() + else: + raise DistutilsClassError( + "invalid help function %s for help option '%s': " + "must be a callable object (function, etc.)" + % (`func`, help_option)) + + if help_option_found: + return + + # Put the options from the command-line into their official + # holding pen, the 'command_options' dictionary. + opt_dict = self.get_option_dict(command) + for (name, value) in vars(opts).items(): + opt_dict[name] = ("command line", value) + + return args + + # _parse_command_opts () + + + def finalize_options (self): + """Set final values for all the options on the Distribution + instance, analogous to the .finalize_options() method of Command + objects. + """ + + keywords = self.metadata.keywords + if keywords is not None: + if type(keywords) is StringType: + keywordlist = string.split(keywords, ',') + self.metadata.keywords = map(string.strip, keywordlist) + + platforms = self.metadata.platforms + if platforms is not None: + if type(platforms) is StringType: + platformlist = string.split(platforms, ',') + self.metadata.platforms = map(string.strip, platformlist) + + def _show_help (self, + parser, + global_options=1, + display_options=1, + commands=[]): + """Show help for the setup script command-line in the form of + several lists of command-line options. 'parser' should be a + FancyGetopt instance; do not expect it to be returned in the + same state, as its option table will be reset to make it + generate the correct help text. + + If 'global_options' is true, lists the global options: + --verbose, --dry-run, etc. If 'display_options' is true, lists + the "display-only" options: --name, --version, etc. Finally, + lists per-command help for every command name or command class + in 'commands'. + """ + # late import because of mutual dependence between these modules + from distutils.core import gen_usage + from distutils.cmd import Command + + if global_options: + parser.set_option_table(self.global_options) + parser.print_help("Global options:") + print + + if display_options: + parser.set_option_table(self.display_options) + parser.print_help( + "Information display options (just display " + + "information, ignore any commands)") + print + + for command in self.commands: + if type(command) is ClassType and issubclass(command, Command): + klass = command + else: + klass = self.get_command_class(command) + if (hasattr(klass, 'help_options') and + type(klass.help_options) is ListType): + parser.set_option_table(klass.user_options + + fix_help_options(klass.help_options)) + else: + parser.set_option_table(klass.user_options) + parser.print_help("Options for '%s' command:" % klass.__name__) + print + + print gen_usage(self.script_name) + return + + # _show_help () + + + def handle_display_options (self, option_order): + """If there were any non-global "display-only" options + (--help-commands or the metadata display options) on the command + line, display the requested info and return true; else return + false. + """ + from distutils.core import gen_usage + + # User just wants a list of commands -- we'll print it out and stop + # processing now (ie. if they ran "setup --help-commands foo bar", + # we ignore "foo bar"). + if self.help_commands: + self.print_commands() + print + print gen_usage(self.script_name) + return 1 + + # If user supplied any of the "display metadata" options, then + # display that metadata in the order in which the user supplied the + # metadata options. + any_display_options = 0 + is_display_option = {} + for option in self.display_options: + is_display_option[option[0]] = 1 + + for (opt, val) in option_order: + if val and is_display_option.get(opt): + opt = translate_longopt(opt) + value = getattr(self.metadata, "get_"+opt)() + if opt in ['keywords', 'platforms']: + print string.join(value, ',') + elif opt == 'classifiers': + print string.join(value, '\n') + else: + print value + any_display_options = 1 + + return any_display_options + + # handle_display_options() + + def print_command_list (self, commands, header, max_length): + """Print a subset of the list of all commands -- used by + 'print_commands()'. + """ + + print header + ":" + + for cmd in commands: + klass = self.cmdclass.get(cmd) + if not klass: + klass = self.get_command_class(cmd) + try: + description = klass.description + except AttributeError: + description = "(no description available)" + + print " %-*s %s" % (max_length, cmd, description) + + # print_command_list () + + + def print_commands (self): + """Print out a help message listing all available commands with a + description of each. The list is divided into "standard commands" + (listed in distutils.command.__all__) and "extra commands" + (mentioned in self.cmdclass, but not a standard command). The + descriptions come from the command class attribute + 'description'. + """ + + import distutils.command + std_commands = distutils.command.__all__ + is_std = {} + for cmd in std_commands: + is_std[cmd] = 1 + + extra_commands = [] + for cmd in self.cmdclass.keys(): + if not is_std.get(cmd): + extra_commands.append(cmd) + + max_length = 0 + for cmd in (std_commands + extra_commands): + if len(cmd) > max_length: + max_length = len(cmd) + + self.print_command_list(std_commands, + "Standard commands", + max_length) + if extra_commands: + print + self.print_command_list(extra_commands, + "Extra commands", + max_length) + + # print_commands () + + def get_command_list (self): + """Get a list of (command, description) tuples. + The list is divided into "standard commands" (listed in + distutils.command.__all__) and "extra commands" (mentioned in + self.cmdclass, but not a standard command). The descriptions come + from the command class attribute 'description'. + """ + # Currently this is only used on Mac OS, for the Mac-only GUI + # Distutils interface (by Jack Jansen) + + import distutils.command + std_commands = distutils.command.__all__ + is_std = {} + for cmd in std_commands: + is_std[cmd] = 1 + + extra_commands = [] + for cmd in self.cmdclass.keys(): + if not is_std.get(cmd): + extra_commands.append(cmd) + + rv = [] + for cmd in (std_commands + extra_commands): + klass = self.cmdclass.get(cmd) + if not klass: + klass = self.get_command_class(cmd) + try: + description = klass.description + except AttributeError: + description = "(no description available)" + rv.append((cmd, description)) + return rv + + # -- Command class/object methods ---------------------------------- + + def get_command_class (self, command): + """Return the class that implements the Distutils command named by + 'command'. First we check the 'cmdclass' dictionary; if the + command is mentioned there, we fetch the class object from the + dictionary and return it. Otherwise we load the command module + ("distutils.command." + command) and fetch the command class from + the module. The loaded class is also stored in 'cmdclass' + to speed future calls to 'get_command_class()'. + + Raises DistutilsModuleError if the expected module could not be + found, or if that module does not define the expected class. + """ + klass = self.cmdclass.get(command) + if klass: + return klass + + module_name = 'distutils.command.' + command + klass_name = command + + try: + __import__ (module_name) + module = sys.modules[module_name] + except ImportError: + raise DistutilsModuleError, \ + "invalid command '%s' (no module named '%s')" % \ + (command, module_name) + + try: + klass = getattr(module, klass_name) + except AttributeError: + raise DistutilsModuleError, \ + "invalid command '%s' (no class '%s' in module '%s')" \ + % (command, klass_name, module_name) + + self.cmdclass[command] = klass + return klass + + # get_command_class () + + def get_command_obj (self, command, create=1): + """Return the command object for 'command'. Normally this object + is cached on a previous call to 'get_command_obj()'; if no command + object for 'command' is in the cache, then we either create and + return it (if 'create' is true) or return None. + """ + cmd_obj = self.command_obj.get(command) + if not cmd_obj and create: + if DEBUG: + print "Distribution.get_command_obj(): " \ + "creating '%s' command object" % command + + klass = self.get_command_class(command) + cmd_obj = self.command_obj[command] = klass(self) + self.have_run[command] = 0 + + # Set any options that were supplied in config files + # or on the command line. (NB. support for error + # reporting is lame here: any errors aren't reported + # until 'finalize_options()' is called, which means + # we won't report the source of the error.) + options = self.command_options.get(command) + if options: + self._set_command_options(cmd_obj, options) + + return cmd_obj + + def _set_command_options (self, command_obj, option_dict=None): + """Set the options for 'command_obj' from 'option_dict'. Basically + this means copying elements of a dictionary ('option_dict') to + attributes of an instance ('command'). + + 'command_obj' must be a Command instance. If 'option_dict' is not + supplied, uses the standard option dictionary for this command + (from 'self.command_options'). + """ + command_name = command_obj.get_command_name() + if option_dict is None: + option_dict = self.get_option_dict(command_name) + + if DEBUG: print " setting options for '%s' command:" % command_name + for (option, (source, value)) in option_dict.items(): + if DEBUG: print " %s = %s (from %s)" % (option, value, source) + try: + bool_opts = map(translate_longopt, command_obj.boolean_options) + except AttributeError: + bool_opts = [] + try: + neg_opt = command_obj.negative_opt + except AttributeError: + neg_opt = {} + + try: + is_string = type(value) is StringType + if neg_opt.has_key(option) and is_string: + setattr(command_obj, neg_opt[option], not strtobool(value)) + elif option in bool_opts and is_string: + setattr(command_obj, option, strtobool(value)) + elif hasattr(command_obj, option): + setattr(command_obj, option, value) + else: + raise DistutilsOptionError, \ + ("error in %s: command '%s' has no such option '%s'" + % (source, command_name, option)) + except ValueError, msg: + raise DistutilsOptionError, msg + + def reinitialize_command (self, command, reinit_subcommands=0): + """Reinitializes a command to the state it was in when first + returned by 'get_command_obj()': ie., initialized but not yet + finalized. This provides the opportunity to sneak option + values in programmatically, overriding or supplementing + user-supplied values from the config files and command line. + You'll have to re-finalize the command object (by calling + 'finalize_options()' or 'ensure_finalized()') before using it for + real. + + 'command' should be a command name (string) or command object. If + 'reinit_subcommands' is true, also reinitializes the command's + sub-commands, as declared by the 'sub_commands' class attribute (if + it has one). See the "install" command for an example. Only + reinitializes the sub-commands that actually matter, ie. those + whose test predicates return true. + + Returns the reinitialized command object. + """ + from distutils.cmd import Command + if not isinstance(command, Command): + command_name = command + command = self.get_command_obj(command_name) + else: + command_name = command.get_command_name() + + if not command.finalized: + return command + command.initialize_options() + command.finalized = 0 + self.have_run[command_name] = 0 + self._set_command_options(command) + + if reinit_subcommands: + for sub in command.get_sub_commands(): + self.reinitialize_command(sub, reinit_subcommands) + + return command + + + # -- Methods that operate on the Distribution ---------------------- + + def announce (self, msg, level=1): + log.debug(msg) + + def run_commands (self): + """Run each command that was seen on the setup script command line. + Uses the list of commands found and cache of command objects + created by 'get_command_obj()'. + """ + for cmd in self.commands: + self.run_command(cmd) + + + # -- Methods that operate on its Commands -------------------------- + + def run_command (self, command): + """Do whatever it takes to run a command (including nothing at all, + if the command has already been run). Specifically: if we have + already created and run the command named by 'command', return + silently without doing anything. If the command named by 'command' + doesn't even have a command object yet, create one. Then invoke + 'run()' on that command object (or an existing one). + """ + # Already been here, done that? then return silently. + if self.have_run.get(command): + return + + log.info("running %s", command) + cmd_obj = self.get_command_obj(command) + cmd_obj.ensure_finalized() + cmd_obj.run() + self.have_run[command] = 1 + + + # -- Distribution query methods ------------------------------------ + + def has_pure_modules (self): + return len(self.packages or self.py_modules or []) > 0 + + def has_ext_modules (self): + return self.ext_modules and len(self.ext_modules) > 0 + + def has_c_libraries (self): + return self.libraries and len(self.libraries) > 0 + + def has_modules (self): + return self.has_pure_modules() or self.has_ext_modules() + + def has_headers (self): + return self.headers and len(self.headers) > 0 + + def has_scripts (self): + return self.scripts and len(self.scripts) > 0 + + def has_data_files (self): + return self.data_files and len(self.data_files) > 0 + + def is_pure (self): + return (self.has_pure_modules() and + not self.has_ext_modules() and + not self.has_c_libraries()) + + # -- Metadata query methods ---------------------------------------- + + # If you're looking for 'get_name()', 'get_version()', and so forth, + # they are defined in a sneaky way: the constructor binds self.get_XXX + # to self.metadata.get_XXX. The actual code is in the + # DistributionMetadata class, below. + +# class Distribution + + +class DistributionMetadata: + """Dummy class to hold the distribution meta-data: name, version, + author, and so forth. + """ + + _METHOD_BASENAMES = ("name", "version", "author", "author_email", + "maintainer", "maintainer_email", "url", + "license", "description", "long_description", + "keywords", "platforms", "fullname", "contact", + "contact_email", "licence", "classifiers", + "download_url") + + def __init__ (self): + self.name = None + self.version = None + self.author = None + self.author_email = None + self.maintainer = None + self.maintainer_email = None + self.url = None + self.license = None + self.description = None + self.long_description = None + self.keywords = None + self.platforms = None + self.classifiers = None + self.download_url = None + + def write_pkg_info (self, base_dir): + """Write the PKG-INFO file into the release tree. + """ + + pkg_info = open( os.path.join(base_dir, 'PKG-INFO'), 'w') + + pkg_info.write('Metadata-Version: 1.0\n') + pkg_info.write('Name: %s\n' % self.get_name() ) + pkg_info.write('Version: %s\n' % self.get_version() ) + pkg_info.write('Summary: %s\n' % self.get_description() ) + pkg_info.write('Home-page: %s\n' % self.get_url() ) + pkg_info.write('Author: %s\n' % self.get_contact() ) + pkg_info.write('Author-email: %s\n' % self.get_contact_email() ) + pkg_info.write('License: %s\n' % self.get_license() ) + if self.download_url: + pkg_info.write('Download-URL: %s\n' % self.download_url) + + long_desc = rfc822_escape( self.get_long_description() ) + pkg_info.write('Description: %s\n' % long_desc) + + keywords = string.join( self.get_keywords(), ',') + if keywords: + pkg_info.write('Keywords: %s\n' % keywords ) + + for platform in self.get_platforms(): + pkg_info.write('Platform: %s\n' % platform ) + + for classifier in self.get_classifiers(): + pkg_info.write('Classifier: %s\n' % classifier ) + + pkg_info.close() + + # write_pkg_info () + + # -- Metadata query methods ---------------------------------------- + + def get_name (self): + return self.name or "UNKNOWN" + + def get_version(self): + return self.version or "0.0.0" + + def get_fullname (self): + return "%s-%s" % (self.get_name(), self.get_version()) + + def get_author(self): + return self.author or "UNKNOWN" + + def get_author_email(self): + return self.author_email or "UNKNOWN" + + def get_maintainer(self): + return self.maintainer or "UNKNOWN" + + def get_maintainer_email(self): + return self.maintainer_email or "UNKNOWN" + + def get_contact(self): + return (self.maintainer or + self.author or + "UNKNOWN") + + def get_contact_email(self): + return (self.maintainer_email or + self.author_email or + "UNKNOWN") + + def get_url(self): + return self.url or "UNKNOWN" + + def get_license(self): + return self.license or "UNKNOWN" + get_licence = get_license + + def get_description(self): + return self.description or "UNKNOWN" + + def get_long_description(self): + return self.long_description or "UNKNOWN" + + def get_keywords(self): + return self.keywords or [] + + def get_platforms(self): + return self.platforms or ["UNKNOWN"] + + def get_classifiers(self): + return self.classifiers or [] + + def get_download_url(self): + return self.download_url or "UNKNOWN" + +# class DistributionMetadata + + +def fix_help_options (options): + """Convert a 4-tuple 'help_options' list as found in various command + classes to the 3-tuple form required by FancyGetopt. + """ + new_options = [] + for help_tuple in options: + new_options.append(help_tuple[0:3]) + return new_options + + +if __name__ == "__main__": + dist = Distribution() + print "ok" diff --git a/wxPython/distutils/emxccompiler.py b/wxPython/distutils/emxccompiler.py new file mode 100644 index 0000000000..76bdbae506 --- /dev/null +++ b/wxPython/distutils/emxccompiler.py @@ -0,0 +1,315 @@ +"""distutils.emxccompiler + +Provides the EMXCCompiler class, a subclass of UnixCCompiler that +handles the EMX port of the GNU C compiler to OS/2. +""" + +# issues: +# +# * OS/2 insists that DLLs can have names no longer than 8 characters +# We put export_symbols in a def-file, as though the DLL can have +# an arbitrary length name, but truncate the output filename. +# +# * only use OMF objects and use LINK386 as the linker (-Zomf) +# +# * always build for multithreading (-Zmt) as the accompanying OS/2 port +# of Python is only distributed with threads enabled. +# +# tested configurations: +# +# * EMX gcc 2.81/EMX 0.9d fix03 + +__revision__ = "$Id$" + +import os,sys,copy +from distutils.ccompiler import gen_preprocess_options, gen_lib_options +from distutils.unixccompiler import UnixCCompiler +from distutils.file_util import write_file +from distutils.errors import DistutilsExecError, CompileError, UnknownFileError +from distutils import log + +class EMXCCompiler (UnixCCompiler): + + compiler_type = 'emx' + obj_extension = ".obj" + static_lib_extension = ".lib" + shared_lib_extension = ".dll" + static_lib_format = "%s%s" + shared_lib_format = "%s%s" + res_extension = ".res" # compiled resource file + exe_extension = ".exe" + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + UnixCCompiler.__init__ (self, verbose, dry_run, force) + + (status, details) = check_config_h() + self.debug_print("Python's GCC status: %s (details: %s)" % + (status, details)) + if status is not CONFIG_H_OK: + self.warn( + "Python's pyconfig.h doesn't seem to support your compiler. " + + ("Reason: %s." % details) + + "Compiling may fail because of undefined preprocessor macros.") + + (self.gcc_version, self.ld_version) = \ + get_versions() + self.debug_print(self.compiler_type + ": gcc %s, ld %s\n" % + (self.gcc_version, + self.ld_version) ) + + # Hard-code GCC because that's what this is all about. + # XXX optimization, warnings etc. should be customizable. + self.set_executables(compiler='gcc -Zomf -Zmt -O2 -Wall', + compiler_so='gcc -Zomf -Zmt -O2 -Wall', + linker_exe='gcc -Zomf -Zmt -Zcrtdll', + linker_so='gcc -Zomf -Zmt -Zcrtdll -Zdll') + + # want the gcc library statically linked (so that we don't have + # to distribute a version dependent on the compiler we have) + self.dll_libraries=["gcc"] + + # __init__ () + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + if ext == '.rc': + # gcc requires '.rc' compiled to binary ('.res') files !!! + try: + self.spawn(["rc", "-r", src]) + except DistutilsExecError, msg: + raise CompileError, msg + else: # for other files use the C-compiler + try: + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + # use separate copies, so we can modify the lists + extra_preargs = copy.copy(extra_preargs or []) + libraries = copy.copy(libraries or []) + objects = copy.copy(objects or []) + + # Additional libraries + libraries.extend(self.dll_libraries) + + # handle export symbols by creating a def-file + # with executables this only works with gcc/ld as linker + if ((export_symbols is not None) and + (target_desc != self.EXECUTABLE)): + # (The linker doesn't do anything if output is up-to-date. + # So it would probably better to check if we really need this, + # but for this we had to insert some unchanged parts of + # UnixCCompiler, and this is not what we want.) + + # we want to put some files in the same directory as the + # object files are, build_temp doesn't help much + # where are the object files + temp_dir = os.path.dirname(objects[0]) + # name of dll to give the helper files the same base name + (dll_name, dll_extension) = os.path.splitext( + os.path.basename(output_filename)) + + # generate the filenames for these files + def_file = os.path.join(temp_dir, dll_name + ".def") + + # Generate .def file + contents = [ + "LIBRARY %s INITINSTANCE TERMINSTANCE" % \ + os.path.splitext(os.path.basename(output_filename))[0], + "DATA MULTIPLE NONSHARED", + "EXPORTS"] + for sym in export_symbols: + contents.append(' "%s"' % sym) + self.execute(write_file, (def_file, contents), + "writing %s" % def_file) + + # next add options for def-file and to creating import libraries + # for gcc/ld the def-file is specified as any other object files + objects.append(def_file) + + #end: if ((export_symbols is not None) and + # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): + + # who wants symbols and a many times larger output file + # should explicitly switch the debug mode on + # otherwise we let dllwrap/ld strip the output file + # (On my machine: 10KB < stripped_file < ??100KB + # unstripped_file = stripped_file + XXX KB + # ( XXX=254 for a typical python extension)) + if not debug: + extra_preargs.append("-s") + + UnixCCompiler.link(self, + target_desc, + objects, + output_filename, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + None, # export_symbols, we do this in our def-file + debug, + extra_preargs, + extra_postargs, + build_temp, + target_lang) + + # link () + + # -- Miscellaneous methods ----------------------------------------- + + # override the object_filenames method from CCompiler to + # support rc and res-files + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + if ext not in (self.src_extensions + ['.rc']): + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % \ + (ext, src_name) + if strip_dir: + base = os.path.basename (base) + if ext == '.rc': + # these need to be compiled to object files + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + # override the find_library_file method from UnixCCompiler + # to deal with file naming/searching differences + def find_library_file(self, dirs, lib, debug=0): + shortlib = '%s.lib' % lib + longlib = 'lib%s.lib' % lib # this form very rare + + # get EMX's default library directory search path + try: + emx_dirs = os.environ['LIBRARY_PATH'].split(';') + except KeyError: + emx_dirs = [] + + for dir in dirs + emx_dirs: + shortlibp = os.path.join(dir, shortlib) + longlibp = os.path.join(dir, longlib) + if os.path.exists(shortlibp): + return shortlibp + elif os.path.exists(longlibp): + return longlibp + + # Oops, didn't find it in *any* of 'dirs' + return None + +# class EMXCCompiler + + +# Because these compilers aren't configured in Python's pyconfig.h file by +# default, we should at least warn the user if he is using a unmodified +# version. + +CONFIG_H_OK = "ok" +CONFIG_H_NOTOK = "not ok" +CONFIG_H_UNCERTAIN = "uncertain" + +def check_config_h(): + + """Check if the current Python installation (specifically, pyconfig.h) + appears amenable to building extensions with GCC. Returns a tuple + (status, details), where 'status' is one of the following constants: + CONFIG_H_OK + all is well, go ahead and compile + CONFIG_H_NOTOK + doesn't look good + CONFIG_H_UNCERTAIN + not sure -- unable to read pyconfig.h + 'details' is a human-readable string explaining the situation. + + Note there are two ways to conclude "OK": either 'sys.version' contains + the string "GCC" (implying that this Python was built with GCC), or the + installed "pyconfig.h" contains the string "__GNUC__". + """ + + # XXX since this function also checks sys.version, it's not strictly a + # "pyconfig.h" check -- should probably be renamed... + + from distutils import sysconfig + import string + # if sys.version contains GCC then python was compiled with + # GCC, and the pyconfig.h file should be OK + if string.find(sys.version,"GCC") >= 0: + return (CONFIG_H_OK, "sys.version mentions 'GCC'") + + fn = sysconfig.get_config_h_filename() + try: + # It would probably better to read single lines to search. + # But we do this only once, and it is fast enough + f = open(fn) + s = f.read() + f.close() + + except IOError, exc: + # if we can't read this file, we cannot say it is wrong + # the compiler will complain later about this file as missing + return (CONFIG_H_UNCERTAIN, + "couldn't read '%s': %s" % (fn, exc.strerror)) + + else: + # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar + if string.find(s,"__GNUC__") >= 0: + return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn) + else: + return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn) + + +def get_versions(): + """ Try to find out the versions of gcc and ld. + If not possible it returns None for it. + """ + from distutils.version import StrictVersion + from distutils.spawn import find_executable + import re + + gcc_exe = find_executable('gcc') + if gcc_exe: + out = os.popen(gcc_exe + ' -dumpversion','r') + out_string = out.read() + out.close() + result = re.search('(\d+\.\d+\.\d+)',out_string) + if result: + gcc_version = StrictVersion(result.group(1)) + else: + gcc_version = None + else: + gcc_version = None + # EMX ld has no way of reporting version number, and we use GCC + # anyway - so we can link OMF DLLs + ld_version = None + return (gcc_version, ld_version) diff --git a/wxPython/distutils/errors.py b/wxPython/distutils/errors.py new file mode 100644 index 0000000000..94e83fb557 --- /dev/null +++ b/wxPython/distutils/errors.py @@ -0,0 +1,99 @@ +"""distutils.errors + +Provides exceptions used by the Distutils modules. Note that Distutils +modules may raise standard exceptions; in particular, SystemExit is +usually raised for errors that are obviously the end-user's fault +(eg. bad command-line arguments). + +This module is safe to use in "from ... import *" mode; it only exports +symbols whose names start with "Distutils" and end with "Error".""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +class DistutilsError (Exception): + """The root of all Distutils evil.""" + pass + +class DistutilsModuleError (DistutilsError): + """Unable to load an expected module, or to find an expected class + within some module (in particular, command modules and classes).""" + pass + +class DistutilsClassError (DistutilsError): + """Some command class (or possibly distribution class, if anyone + feels a need to subclass Distribution) is found not to be holding + up its end of the bargain, ie. implementing some part of the + "command "interface.""" + pass + +class DistutilsGetoptError (DistutilsError): + """The option table provided to 'fancy_getopt()' is bogus.""" + pass + +class DistutilsArgError (DistutilsError): + """Raised by fancy_getopt in response to getopt.error -- ie. an + error in the command line usage.""" + pass + +class DistutilsFileError (DistutilsError): + """Any problems in the filesystem: expected file not found, etc. + Typically this is for problems that we detect before IOError or + OSError could be raised.""" + pass + +class DistutilsOptionError (DistutilsError): + """Syntactic/semantic errors in command options, such as use of + mutually conflicting options, or inconsistent options, + badly-spelled values, etc. No distinction is made between option + values originating in the setup script, the command line, config + files, or what-have-you -- but if we *know* something originated in + the setup script, we'll raise DistutilsSetupError instead.""" + pass + +class DistutilsSetupError (DistutilsError): + """For errors that can be definitely blamed on the setup script, + such as invalid keyword arguments to 'setup()'.""" + pass + +class DistutilsPlatformError (DistutilsError): + """We don't know how to do something on the current platform (but + we do know how to do it on some platform) -- eg. trying to compile + C files on a platform not supported by a CCompiler subclass.""" + pass + +class DistutilsExecError (DistutilsError): + """Any problems executing an external program (such as the C + compiler, when compiling C files).""" + pass + +class DistutilsInternalError (DistutilsError): + """Internal inconsistencies or impossibilities (obviously, this + should never be seen if the code is working!).""" + pass + +class DistutilsTemplateError (DistutilsError): + """Syntax error in a file list template.""" + + +# Exception classes used by the CCompiler implementation classes +class CCompilerError (Exception): + """Some compile/link operation failed.""" + +class PreprocessError (CCompilerError): + """Failure to preprocess one or more C/C++ files.""" + +class CompileError (CCompilerError): + """Failure to compile one or more C/C++ source files.""" + +class LibError (CCompilerError): + """Failure to create a static library from one or more C/C++ object + files.""" + +class LinkError (CCompilerError): + """Failure to link one or more C/C++ object files into an executable + or shared library file.""" + +class UnknownFileError (CCompilerError): + """Attempt to process an unknown file type.""" diff --git a/wxPython/distutils/extension.py b/wxPython/distutils/extension.py new file mode 100644 index 0000000000..e69f3e93e0 --- /dev/null +++ b/wxPython/distutils/extension.py @@ -0,0 +1,241 @@ +"""distutils.extension + +Provides the Extension class, used to describe C/C++ extension +modules in setup scripts.""" + +__revision__ = "$Id$" + +import os, string, sys +from types import * + +try: + import warnings +except ImportError: + warnings = None + +# This class is really only used by the "build_ext" command, so it might +# make sense to put it in distutils.command.build_ext. However, that +# module is already big enough, and I want to make this class a bit more +# complex to simplify some common cases ("foo" module in "foo.c") and do +# better error-checking ("foo.c" actually exists). +# +# Also, putting this in build_ext.py means every setup script would have to +# import that large-ish module (indirectly, through distutils.core) in +# order to do anything. + +class Extension: + """Just a collection of attributes that describes an extension + module and everything needed to build it (hopefully in a portable + way, but there are hooks that let you be as unportable as you need). + + Instance attributes: + name : string + the full name of the extension, including any packages -- ie. + *not* a filename or pathname, but Python dotted name + sources : [string] + list of source filenames, relative to the distribution root + (where the setup script lives), in Unix form (slash-separated) + for portability. Source files may be C, C++, SWIG (.i), + platform-specific resource files, or whatever else is recognized + by the "build_ext" command as source for a Python extension. + include_dirs : [string] + list of directories to search for C/C++ header files (in Unix + form for portability) + define_macros : [(name : string, value : string|None)] + list of macros to define; each macro is defined using a 2-tuple, + where 'value' is either the string to define it to or None to + define it without a particular value (equivalent of "#define + FOO" in source or -DFOO on Unix C compiler command line) + undef_macros : [string] + list of macros to undefine explicitly + library_dirs : [string] + list of directories to search for C/C++ libraries at link time + libraries : [string] + list of library names (not filenames or paths) to link against + runtime_library_dirs : [string] + list of directories to search for C/C++ libraries at run time + (for shared extensions, this is when the extension is loaded) + extra_objects : [string] + list of extra files to link with (eg. object files not implied + by 'sources', static library that must be explicitly specified, + binary resource files, etc.) + extra_compile_args : [string] + any extra platform- and compiler-specific information to use + when compiling the source files in 'sources'. For platforms and + compilers where "command line" makes sense, this is typically a + list of command-line arguments, but for other platforms it could + be anything. + extra_link_args : [string] + any extra platform- and compiler-specific information to use + when linking object files together to create the extension (or + to create a new static Python interpreter). Similar + interpretation as for 'extra_compile_args'. + export_symbols : [string] + list of symbols to be exported from a shared extension. Not + used on all platforms, and not generally necessary for Python + extensions, which typically export exactly one symbol: "init" + + extension_name. + depends : [string] + list of files that the extension depends on + language : string + extension language (i.e. "c", "c++", "objc"). Will be detected + from the source extensions if not provided. + """ + + # When adding arguments to this constructor, be sure to update + # setup_keywords in core.py. + def __init__ (self, name, sources, + include_dirs=None, + define_macros=None, + undef_macros=None, + library_dirs=None, + libraries=None, + runtime_library_dirs=None, + extra_objects=None, + extra_compile_args=None, + extra_link_args=None, + export_symbols=None, + depends=None, + language=None, + **kw # To catch unknown keywords + ): + assert type(name) is StringType, "'name' must be a string" + assert (type(sources) is ListType and + map(type, sources) == [StringType]*len(sources)), \ + "'sources' must be a list of strings" + + self.name = name + self.sources = sources + self.include_dirs = include_dirs or [] + self.define_macros = define_macros or [] + self.undef_macros = undef_macros or [] + self.library_dirs = library_dirs or [] + self.libraries = libraries or [] + self.runtime_library_dirs = runtime_library_dirs or [] + self.extra_objects = extra_objects or [] + self.extra_compile_args = extra_compile_args or [] + self.extra_link_args = extra_link_args or [] + self.export_symbols = export_symbols or [] + self.depends = depends or [] + self.language = language + + # If there are unknown keyword options, warn about them + if len(kw): + L = kw.keys() ; L.sort() + L = map(repr, L) + msg = "Unknown Extension options: " + string.join(L, ', ') + if warnings is not None: + warnings.warn(msg) + else: + sys.stderr.write(msg + '\n') +# class Extension + + +def read_setup_file (filename): + from distutils.sysconfig import \ + parse_makefile, expand_makefile_vars, _variable_rx + from distutils.text_file import TextFile + from distutils.util import split_quoted + + # First pass over the file to gather "VAR = VALUE" assignments. + vars = parse_makefile(filename) + + # Second pass to gobble up the real content: lines of the form + # ... [ ...] [ ...] [ ...] + file = TextFile(filename, + strip_comments=1, skip_blanks=1, join_lines=1, + lstrip_ws=1, rstrip_ws=1) + extensions = [] + + while 1: + line = file.readline() + if line is None: # eof + break + if _variable_rx.match(line): # VAR=VALUE, handled in first pass + continue + + if line[0] == line[-1] == "*": + file.warn("'%s' lines not handled yet" % line) + continue + + #print "original line: " + line + line = expand_makefile_vars(line, vars) + words = split_quoted(line) + #print "expanded line: " + line + + # NB. this parses a slightly different syntax than the old + # makesetup script: here, there must be exactly one extension per + # line, and it must be the first word of the line. I have no idea + # why the old syntax supported multiple extensions per line, as + # they all wind up being the same. + + module = words[0] + ext = Extension(module, []) + append_next_word = None + + for word in words[1:]: + if append_next_word is not None: + append_next_word.append(word) + append_next_word = None + continue + + suffix = os.path.splitext(word)[1] + switch = word[0:2] ; value = word[2:] + + if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"): + # hmm, should we do something about C vs. C++ sources? + # or leave it up to the CCompiler implementation to + # worry about? + ext.sources.append(word) + elif switch == "-I": + ext.include_dirs.append(value) + elif switch == "-D": + equals = string.find(value, "=") + if equals == -1: # bare "-DFOO" -- no value + ext.define_macros.append((value, None)) + else: # "-DFOO=blah" + ext.define_macros.append((value[0:equals], + value[equals+2:])) + elif switch == "-U": + ext.undef_macros.append(value) + elif switch == "-C": # only here 'cause makesetup has it! + ext.extra_compile_args.append(word) + elif switch == "-l": + ext.libraries.append(value) + elif switch == "-L": + ext.library_dirs.append(value) + elif switch == "-R": + ext.runtime_library_dirs.append(value) + elif word == "-rpath": + append_next_word = ext.runtime_library_dirs + elif word == "-Xlinker": + append_next_word = ext.extra_link_args + elif word == "-Xcompiler": + append_next_word = ext.extra_compile_args + elif switch == "-u": + ext.extra_link_args.append(word) + if not value: + append_next_word = ext.extra_link_args + elif suffix in (".a", ".so", ".sl", ".o", ".dylib"): + # NB. a really faithful emulation of makesetup would + # append a .o file to extra_objects only if it + # had a slash in it; otherwise, it would s/.o/.c/ + # and append it to sources. Hmmmm. + ext.extra_objects.append(word) + else: + file.warn("unrecognized argument '%s'" % word) + + extensions.append(ext) + + #print "module:", module + #print "source files:", source_files + #print "cpp args:", cpp_args + #print "lib args:", library_args + + #extensions[module] = { 'sources': source_files, + # 'cpp_args': cpp_args, + # 'lib_args': library_args } + + return extensions + +# read_setup_file () diff --git a/wxPython/distutils/fancy_getopt.py b/wxPython/distutils/fancy_getopt.py new file mode 100644 index 0000000000..a4a4e7979e --- /dev/null +++ b/wxPython/distutils/fancy_getopt.py @@ -0,0 +1,501 @@ +"""distutils.fancy_getopt + +Wrapper around the standard getopt module that provides the following +additional features: + * short and long options are tied together + * options have help strings, so fancy_getopt could potentially + create a complete usage summary + * options set attributes of a passed-in object +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, string, re +from types import * +import getopt +from distutils.errors import * + +# Much like command_re in distutils.core, this is close to but not quite +# the same as a Python NAME -- except, in the spirit of most GNU +# utilities, we use '-' in place of '_'. (The spirit of LISP lives on!) +# The similarities to NAME are again not a coincidence... +longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)' +longopt_re = re.compile(r'^%s$' % longopt_pat) + +# For recognizing "negative alias" options, eg. "quiet=!verbose" +neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat)) + +# This is used to translate long options to legitimate Python identifiers +# (for use as attributes of some object). +longopt_xlate = string.maketrans('-', '_') + +class FancyGetopt: + """Wrapper around the standard 'getopt()' module that provides some + handy extra functionality: + * short and long options are tied together + * options have help strings, and help text can be assembled + from them + * options set attributes of a passed-in object + * boolean options can have "negative aliases" -- eg. if + --quiet is the "negative alias" of --verbose, then "--quiet" + on the command line sets 'verbose' to false + """ + + def __init__ (self, option_table=None): + + # The option table is (currently) a list of 3-tuples: + # (long_option, short_option, help_string) + # if an option takes an argument, its long_option should have '=' + # appended; short_option should just be a single character, no ':' + # in any case. If a long_option doesn't have a corresponding + # short_option, short_option should be None. All option tuples + # must have long options. + self.option_table = option_table + + # 'option_index' maps long option names to entries in the option + # table (ie. those 3-tuples). + self.option_index = {} + if self.option_table: + self._build_index() + + # 'alias' records (duh) alias options; {'foo': 'bar'} means + # --foo is an alias for --bar + self.alias = {} + + # 'negative_alias' keeps track of options that are the boolean + # opposite of some other option + self.negative_alias = {} + + # These keep track of the information in the option table. We + # don't actually populate these structures until we're ready to + # parse the command-line, since the 'option_table' passed in here + # isn't necessarily the final word. + self.short_opts = [] + self.long_opts = [] + self.short2long = {} + self.attr_name = {} + self.takes_arg = {} + + # And 'option_order' is filled up in 'getopt()'; it records the + # original order of options (and their values) on the command-line, + # but expands short options, converts aliases, etc. + self.option_order = [] + + # __init__ () + + + def _build_index (self): + self.option_index.clear() + for option in self.option_table: + self.option_index[option[0]] = option + + def set_option_table (self, option_table): + self.option_table = option_table + self._build_index() + + def add_option (self, long_option, short_option=None, help_string=None): + if self.option_index.has_key(long_option): + raise DistutilsGetoptError, \ + "option conflict: already an option '%s'" % long_option + else: + option = (long_option, short_option, help_string) + self.option_table.append(option) + self.option_index[long_option] = option + + + def has_option (self, long_option): + """Return true if the option table for this parser has an + option with long name 'long_option'.""" + return self.option_index.has_key(long_option) + + def get_attr_name (self, long_option): + """Translate long option name 'long_option' to the form it + has as an attribute of some object: ie., translate hyphens + to underscores.""" + return string.translate(long_option, longopt_xlate) + + + def _check_alias_dict (self, aliases, what): + assert type(aliases) is DictionaryType + for (alias, opt) in aliases.items(): + if not self.option_index.has_key(alias): + raise DistutilsGetoptError, \ + ("invalid %s '%s': " + "option '%s' not defined") % (what, alias, alias) + if not self.option_index.has_key(opt): + raise DistutilsGetoptError, \ + ("invalid %s '%s': " + "aliased option '%s' not defined") % (what, alias, opt) + + def set_aliases (self, alias): + """Set the aliases for this option parser.""" + self._check_alias_dict(alias, "alias") + self.alias = alias + + def set_negative_aliases (self, negative_alias): + """Set the negative aliases for this option parser. + 'negative_alias' should be a dictionary mapping option names to + option names, both the key and value must already be defined + in the option table.""" + self._check_alias_dict(negative_alias, "negative alias") + self.negative_alias = negative_alias + + + def _grok_option_table (self): + """Populate the various data structures that keep tabs on the + option table. Called by 'getopt()' before it can do anything + worthwhile. + """ + self.long_opts = [] + self.short_opts = [] + self.short2long.clear() + self.repeat = {} + + for option in self.option_table: + if len(option) == 3: + long, short, help = option + repeat = 0 + elif len(option) == 4: + long, short, help, repeat = option + else: + # the option table is part of the code, so simply + # assert that it is correct + assert "invalid option tuple: %s" % `option` + + # Type- and value-check the option names + if type(long) is not StringType or len(long) < 2: + raise DistutilsGetoptError, \ + ("invalid long option '%s': " + "must be a string of length >= 2") % long + + if (not ((short is None) or + (type(short) is StringType and len(short) == 1))): + raise DistutilsGetoptError, \ + ("invalid short option '%s': " + "must a single character or None") % short + + self.repeat[long] = repeat + self.long_opts.append(long) + + if long[-1] == '=': # option takes an argument? + if short: short = short + ':' + long = long[0:-1] + self.takes_arg[long] = 1 + else: + + # Is option is a "negative alias" for some other option (eg. + # "quiet" == "!verbose")? + alias_to = self.negative_alias.get(long) + if alias_to is not None: + if self.takes_arg[alias_to]: + raise DistutilsGetoptError, \ + ("invalid negative alias '%s': " + "aliased option '%s' takes a value") % \ + (long, alias_to) + + self.long_opts[-1] = long # XXX redundant?! + self.takes_arg[long] = 0 + + else: + self.takes_arg[long] = 0 + + # If this is an alias option, make sure its "takes arg" flag is + # the same as the option it's aliased to. + alias_to = self.alias.get(long) + if alias_to is not None: + if self.takes_arg[long] != self.takes_arg[alias_to]: + raise DistutilsGetoptError, \ + ("invalid alias '%s': inconsistent with " + "aliased option '%s' (one of them takes a value, " + "the other doesn't") % (long, alias_to) + + + # Now enforce some bondage on the long option name, so we can + # later translate it to an attribute name on some object. Have + # to do this a bit late to make sure we've removed any trailing + # '='. + if not longopt_re.match(long): + raise DistutilsGetoptError, \ + ("invalid long option name '%s' " + + "(must be letters, numbers, hyphens only") % long + + self.attr_name[long] = self.get_attr_name(long) + if short: + self.short_opts.append(short) + self.short2long[short[0]] = long + + # for option_table + + # _grok_option_table() + + + def getopt (self, args=None, object=None): + """Parse command-line options in args. Store as attributes on object. + + If 'args' is None or not supplied, uses 'sys.argv[1:]'. If + 'object' is None or not supplied, creates a new OptionDummy + object, stores option values there, and returns a tuple (args, + object). If 'object' is supplied, it is modified in place and + 'getopt()' just returns 'args'; in both cases, the returned + 'args' is a modified copy of the passed-in 'args' list, which + is left untouched. + """ + if args is None: + args = sys.argv[1:] + if object is None: + object = OptionDummy() + created_object = 1 + else: + created_object = 0 + + self._grok_option_table() + + short_opts = string.join(self.short_opts) + try: + opts, args = getopt.getopt(args, short_opts, self.long_opts) + except getopt.error, msg: + raise DistutilsArgError, msg + + for opt, val in opts: + if len(opt) == 2 and opt[0] == '-': # it's a short option + opt = self.short2long[opt[1]] + else: + assert len(opt) > 2 and opt[:2] == '--' + opt = opt[2:] + + alias = self.alias.get(opt) + if alias: + opt = alias + + if not self.takes_arg[opt]: # boolean option? + assert val == '', "boolean option can't have value" + alias = self.negative_alias.get(opt) + if alias: + opt = alias + val = 0 + else: + val = 1 + + attr = self.attr_name[opt] + # The only repeating option at the moment is 'verbose'. + # It has a negative option -q quiet, which should set verbose = 0. + if val and self.repeat.get(attr) is not None: + val = getattr(object, attr, 0) + 1 + setattr(object, attr, val) + self.option_order.append((opt, val)) + + # for opts + if created_object: + return args, object + else: + return args + + # getopt() + + + def get_option_order (self): + """Returns the list of (option, value) tuples processed by the + previous run of 'getopt()'. Raises RuntimeError if + 'getopt()' hasn't been called yet. + """ + if self.option_order is None: + raise RuntimeError, "'getopt()' hasn't been called yet" + else: + return self.option_order + + + def generate_help (self, header=None): + """Generate help text (a list of strings, one per suggested line of + output) from the option table for this FancyGetopt object. + """ + # Blithely assume the option table is good: probably wouldn't call + # 'generate_help()' unless you've already called 'getopt()'. + + # First pass: determine maximum length of long option names + max_opt = 0 + for option in self.option_table: + long = option[0] + short = option[1] + l = len(long) + if long[-1] == '=': + l = l - 1 + if short is not None: + l = l + 5 # " (-x)" where short == 'x' + if l > max_opt: + max_opt = l + + opt_width = max_opt + 2 + 2 + 2 # room for indent + dashes + gutter + + # Typical help block looks like this: + # --foo controls foonabulation + # Help block for longest option looks like this: + # --flimflam set the flim-flam level + # and with wrapped text: + # --flimflam set the flim-flam level (must be between + # 0 and 100, except on Tuesdays) + # Options with short names will have the short name shown (but + # it doesn't contribute to max_opt): + # --foo (-f) controls foonabulation + # If adding the short option would make the left column too wide, + # we push the explanation off to the next line + # --flimflam (-l) + # set the flim-flam level + # Important parameters: + # - 2 spaces before option block start lines + # - 2 dashes for each long option name + # - min. 2 spaces between option and explanation (gutter) + # - 5 characters (incl. space) for short option name + + # Now generate lines of help text. (If 80 columns were good enough + # for Jesus, then 78 columns are good enough for me!) + line_width = 78 + text_width = line_width - opt_width + big_indent = ' ' * opt_width + if header: + lines = [header] + else: + lines = ['Option summary:'] + + for option in self.option_table: + long, short, help = option[:3] + text = wrap_text(help, text_width) + if long[-1] == '=': + long = long[0:-1] + + # Case 1: no short option at all (makes life easy) + if short is None: + if text: + lines.append(" --%-*s %s" % (max_opt, long, text[0])) + else: + lines.append(" --%-*s " % (max_opt, long)) + + # Case 2: we have a short option, so we have to include it + # just after the long option + else: + opt_names = "%s (-%s)" % (long, short) + if text: + lines.append(" --%-*s %s" % + (max_opt, opt_names, text[0])) + else: + lines.append(" --%-*s" % opt_names) + + for l in text[1:]: + lines.append(big_indent + l) + + # for self.option_table + + return lines + + # generate_help () + + def print_help (self, header=None, file=None): + if file is None: + file = sys.stdout + for line in self.generate_help(header): + file.write(line + "\n") + +# class FancyGetopt + + +def fancy_getopt (options, negative_opt, object, args): + parser = FancyGetopt(options) + parser.set_negative_aliases(negative_opt) + return parser.getopt(args, object) + + +WS_TRANS = string.maketrans(string.whitespace, ' ' * len(string.whitespace)) + +def wrap_text (text, width): + """wrap_text(text : string, width : int) -> [string] + + Split 'text' into multiple lines of no more than 'width' characters + each, and return the list of strings that results. + """ + + if text is None: + return [] + if len(text) <= width: + return [text] + + text = string.expandtabs(text) + text = string.translate(text, WS_TRANS) + chunks = re.split(r'( +|-+)', text) + chunks = filter(None, chunks) # ' - ' results in empty strings + lines = [] + + while chunks: + + cur_line = [] # list of chunks (to-be-joined) + cur_len = 0 # length of current line + + while chunks: + l = len(chunks[0]) + if cur_len + l <= width: # can squeeze (at least) this chunk in + cur_line.append(chunks[0]) + del chunks[0] + cur_len = cur_len + l + else: # this line is full + # drop last chunk if all space + if cur_line and cur_line[-1][0] == ' ': + del cur_line[-1] + break + + if chunks: # any chunks left to process? + + # if the current line is still empty, then we had a single + # chunk that's too big too fit on a line -- so we break + # down and break it up at the line width + if cur_len == 0: + cur_line.append(chunks[0][0:width]) + chunks[0] = chunks[0][width:] + + # all-whitespace chunks at the end of a line can be discarded + # (and we know from the re.split above that if a chunk has + # *any* whitespace, it is *all* whitespace) + if chunks[0][0] == ' ': + del chunks[0] + + # and store this line in the list-of-all-lines -- as a single + # string, of course! + lines.append(string.join(cur_line, '')) + + # while chunks + + return lines + +# wrap_text () + + +def translate_longopt (opt): + """Convert a long option name to a valid Python identifier by + changing "-" to "_". + """ + return string.translate(opt, longopt_xlate) + + +class OptionDummy: + """Dummy class just used as a place to hold command-line option + values as instance attributes.""" + + def __init__ (self, options=[]): + """Create a new OptionDummy instance. The attributes listed in + 'options' will be initialized to None.""" + for opt in options: + setattr(self, opt, None) + +# class OptionDummy + + +if __name__ == "__main__": + text = """\ +Tra-la-la, supercalifragilisticexpialidocious. +How *do* you spell that odd word, anyways? +(Someone ask Mary -- she'll know [or she'll +say, "How should I know?"].)""" + + for w in (10, 20, 30, 40): + print "width: %d" % w + print string.join(wrap_text(text, w), "\n") + print diff --git a/wxPython/distutils/file_util.py b/wxPython/distutils/file_util.py new file mode 100644 index 0000000000..e230ce587e --- /dev/null +++ b/wxPython/distutils/file_util.py @@ -0,0 +1,253 @@ +"""distutils.file_util + +Utility functions for operating on single files. +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os +from distutils.errors import DistutilsFileError +from distutils import log + +# for generating verbose output in 'copy_file()' +_copy_action = { None: 'copying', + 'hard': 'hard linking', + 'sym': 'symbolically linking' } + + +def _copy_file_contents (src, dst, buffer_size=16*1024): + """Copy the file 'src' to 'dst'; both must be filenames. Any error + opening either file, reading from 'src', or writing to 'dst', raises + DistutilsFileError. Data is read/written in chunks of 'buffer_size' + bytes (default 16k). No attempt is made to handle anything apart from + regular files. + """ + # Stolen from shutil module in the standard library, but with + # custom error-handling added. + + fsrc = None + fdst = None + try: + try: + fsrc = open(src, 'rb') + except os.error, (errno, errstr): + raise DistutilsFileError, \ + "could not open '%s': %s" % (src, errstr) + + if os.path.exists(dst): + try: + os.unlink(dst) + except os.error, (errno, errstr): + raise DistutilsFileError, \ + "could not delete '%s': %s" % (dst, errstr) + + try: + fdst = open(dst, 'wb') + except os.error, (errno, errstr): + raise DistutilsFileError, \ + "could not create '%s': %s" % (dst, errstr) + + while 1: + try: + buf = fsrc.read(buffer_size) + except os.error, (errno, errstr): + raise DistutilsFileError, \ + "could not read from '%s': %s" % (src, errstr) + + if not buf: + break + + try: + fdst.write(buf) + except os.error, (errno, errstr): + raise DistutilsFileError, \ + "could not write to '%s': %s" % (dst, errstr) + + finally: + if fdst: + fdst.close() + if fsrc: + fsrc.close() + +# _copy_file_contents() + +def copy_file (src, dst, + preserve_mode=1, + preserve_times=1, + update=0, + link=None, + verbose=0, + dry_run=0): + + """Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is + copied there with the same name; otherwise, it must be a filename. (If + the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' + is true (the default), the file's mode (type and permission bits, or + whatever is analogous on the current platform) is copied. If + 'preserve_times' is true (the default), the last-modified and + last-access times are copied as well. If 'update' is true, 'src' will + only be copied if 'dst' does not exist, or if 'dst' does exist but is + older than 'src'. + + 'link' allows you to make hard links (os.link) or symbolic links + (os.symlink) instead of copying: set it to "hard" or "sym"; if it is + None (the default), files are copied. Don't set 'link' on systems that + don't support it: 'copy_file()' doesn't check if hard or symbolic + linking is available. + + Under Mac OS, uses the native file copy function in macostools; on + other systems, uses '_copy_file_contents()' to copy file contents. + + Return a tuple (dest_name, copied): 'dest_name' is the actual name of + the output file, and 'copied' is true if the file was copied (or would + have been copied, if 'dry_run' true). + """ + # XXX if the destination file already exists, we clobber it if + # copying, but blow up if linking. Hmmm. And I don't know what + # macostools.copyfile() does. Should definitely be consistent, and + # should probably blow up if destination exists and we would be + # changing it (ie. it's not already a hard/soft link to src OR + # (not update) and (src newer than dst). + + from distutils.dep_util import newer + from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE + + if not os.path.isfile(src): + raise DistutilsFileError, \ + "can't copy '%s': doesn't exist or not a regular file" % src + + if os.path.isdir(dst): + dir = dst + dst = os.path.join(dst, os.path.basename(src)) + else: + dir = os.path.dirname(dst) + + if update and not newer(src, dst): + log.debug("not copying %s (output up-to-date)", src) + return dst, 0 + + try: + action = _copy_action[link] + except KeyError: + raise ValueError, \ + "invalid value '%s' for 'link' argument" % link + if os.path.basename(dst) == os.path.basename(src): + log.info("%s %s -> %s", action, src, dir) + else: + log.info("%s %s -> %s", action, src, dst) + + if dry_run: + return (dst, 1) + + # On Mac OS, use the native file copy routine + if os.name == 'mac': + import macostools + try: + macostools.copy(src, dst, 0, preserve_times) + except os.error, exc: + raise DistutilsFileError, \ + "could not copy '%s' to '%s': %s" % (src, dst, exc[-1]) + + # If linking (hard or symbolic), use the appropriate system call + # (Unix only, of course, but that's the caller's responsibility) + elif link == 'hard': + if not (os.path.exists(dst) and os.path.samefile(src, dst)): + os.link(src, dst) + elif link == 'sym': + if not (os.path.exists(dst) and os.path.samefile(src, dst)): + os.symlink(src, dst) + + # Otherwise (non-Mac, not linking), copy the file contents and + # (optionally) copy the times and mode. + else: + _copy_file_contents(src, dst) + if preserve_mode or preserve_times: + st = os.stat(src) + + # According to David Ascher , utime() should be done + # before chmod() (at least under NT). + if preserve_times: + os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) + if preserve_mode: + os.chmod(dst, S_IMODE(st[ST_MODE])) + + return (dst, 1) + +# copy_file () + + +# XXX I suspect this is Unix-specific -- need porting help! +def move_file (src, dst, + verbose=0, + dry_run=0): + + """Move a file 'src' to 'dst'. If 'dst' is a directory, the file will + be moved into it with the same name; otherwise, 'src' is just renamed + to 'dst'. Return the new full name of the file. + + Handles cross-device moves on Unix using 'copy_file()'. What about + other systems??? + """ + from os.path import exists, isfile, isdir, basename, dirname + import errno + + log.info("moving %s -> %s", src, dst) + + if dry_run: + return dst + + if not isfile(src): + raise DistutilsFileError, \ + "can't move '%s': not a regular file" % src + + if isdir(dst): + dst = os.path.join(dst, basename(src)) + elif exists(dst): + raise DistutilsFileError, \ + "can't move '%s': destination '%s' already exists" % \ + (src, dst) + + if not isdir(dirname(dst)): + raise DistutilsFileError, \ + "can't move '%s': destination '%s' not a valid path" % \ + (src, dst) + + copy_it = 0 + try: + os.rename(src, dst) + except os.error, (num, msg): + if num == errno.EXDEV: + copy_it = 1 + else: + raise DistutilsFileError, \ + "couldn't move '%s' to '%s': %s" % (src, dst, msg) + + if copy_it: + copy_file(src, dst) + try: + os.unlink(src) + except os.error, (num, msg): + try: + os.unlink(dst) + except os.error: + pass + raise DistutilsFileError, \ + ("couldn't move '%s' to '%s' by copy/delete: " + + "delete '%s' failed: %s") % \ + (src, dst, src, msg) + + return dst + +# move_file () + + +def write_file (filename, contents): + """Create a file with the specified name and write 'contents' (a + sequence of strings without line terminators) to it. + """ + f = open(filename, "w") + for line in contents: + f.write(line + "\n") + f.close() diff --git a/wxPython/distutils/filelist.py b/wxPython/distutils/filelist.py new file mode 100644 index 0000000000..bfa53d2133 --- /dev/null +++ b/wxPython/distutils/filelist.py @@ -0,0 +1,355 @@ +"""distutils.filelist + +Provides the FileList class, used for poking about the filesystem +and building lists of files. +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import os, string, re +import fnmatch +from types import * +from glob import glob +from distutils.util import convert_path +from distutils.errors import DistutilsTemplateError, DistutilsInternalError +from distutils import log + +class FileList: + + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + + Instance attributes: + dir + directory from which files will be taken -- only used if + 'allfiles' not supplied to constructor + files + list of filenames currently being built/filtered/manipulated + allfiles + complete list of files under consideration (ie. without any + filtering applied) + """ + + def __init__(self, + warn=None, + debug_print=None): + # ignore argument to FileList, but keep them for backwards + # compatibility + + self.allfiles = None + self.files = [] + + def set_allfiles (self, allfiles): + self.allfiles = allfiles + + def findall (self, dir=os.curdir): + self.allfiles = findall(dir) + + def debug_print (self, msg): + """Print 'msg' to stdout if the global DEBUG (taken from the + DISTUTILS_DEBUG environment variable) flag is true. + """ + from distutils.debug import DEBUG + if DEBUG: + print msg + + # -- List-like methods --------------------------------------------- + + def append (self, item): + self.files.append(item) + + def extend (self, items): + self.files.extend(items) + + def sort (self): + # Not a strict lexical sort! + sortable_files = map(os.path.split, self.files) + sortable_files.sort() + self.files = [] + for sort_tuple in sortable_files: + self.files.append(apply(os.path.join, sort_tuple)) + + + # -- Other miscellaneous utility methods --------------------------- + + def remove_duplicates (self): + # Assumes list has been sorted! + for i in range(len(self.files) - 1, 0, -1): + if self.files[i] == self.files[i - 1]: + del self.files[i] + + + # -- "File template" methods --------------------------------------- + + def _parse_template_line (self, line): + words = string.split(line) + action = words[0] + + patterns = dir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistutilsTemplateError, \ + "'%s' expects ..." % action + + patterns = map(convert_path, words[1:]) + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistutilsTemplateError, \ + "'%s' expects ..." % action + + dir = convert_path(words[1]) + patterns = map(convert_path, words[2:]) + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistutilsTemplateError, \ + "'%s' expects a single " % action + + dir_pattern = convert_path(words[1]) + + else: + raise DistutilsTemplateError, "unknown action '%s'" % action + + return (action, patterns, dir, dir_pattern) + + # _parse_template_line () + + + def process_template_line (self, line): + + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dir_pattern). + (action, patterns, dir, dir_pattern) = self._parse_template_line(line) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + self.debug_print("include " + string.join(patterns)) + for pattern in patterns: + if not self.include_pattern(pattern, anchor=1): + log.warn("warning: no files found matching '%s'", + pattern) + + elif action == 'exclude': + self.debug_print("exclude " + string.join(patterns)) + for pattern in patterns: + if not self.exclude_pattern(pattern, anchor=1): + log.warn(("warning: no previously-included files " + "found matching '%s'"), pattern) + + elif action == 'global-include': + self.debug_print("global-include " + string.join(patterns)) + for pattern in patterns: + if not self.include_pattern(pattern, anchor=0): + log.warn(("warning: no files found matching '%s' " + + "anywhere in distribution"), pattern) + + elif action == 'global-exclude': + self.debug_print("global-exclude " + string.join(patterns)) + for pattern in patterns: + if not self.exclude_pattern(pattern, anchor=0): + log.warn(("warning: no previously-included files matching " + "'%s' found anywhere in distribution"), + pattern) + + elif action == 'recursive-include': + self.debug_print("recursive-include %s %s" % + (dir, string.join(patterns))) + for pattern in patterns: + if not self.include_pattern(pattern, prefix=dir): + log.warn(("warngin: no files found matching '%s' " + + "under directory '%s'"), + pattern, dir) + + elif action == 'recursive-exclude': + self.debug_print("recursive-exclude %s %s" % + (dir, string.join(patterns))) + for pattern in patterns: + if not self.exclude_pattern(pattern, prefix=dir): + log.warn(("warning: no previously-included files matching " + "'%s' found under directory '%s'"), + pattern, dir) + + elif action == 'graft': + self.debug_print("graft " + dir_pattern) + if not self.include_pattern(None, prefix=dir_pattern): + log.warn("warning: no directories found matching '%s'", + dir_pattern) + + elif action == 'prune': + self.debug_print("prune " + dir_pattern) + if not self.exclude_pattern(None, prefix=dir_pattern): + log.warn(("no previously-included directories found " + + "matching '%s'"), dir_pattern) + else: + raise DistutilsInternalError, \ + "this cannot happen: invalid action '%s'" % action + + # process_template_line () + + + # -- Filtering/selection methods ----------------------------------- + + def include_pattern (self, pattern, + anchor=1, prefix=None, is_regex=0): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. Patterns + are not quite the same as implemented by the 'fnmatch' module: '*' + and '?' match non-special characters, where "special" is platform- + dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return 1 if files are found. + """ + files_found = 0 + pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) + self.debug_print("include_pattern: applying regex r'%s'" % + pattern_re.pattern) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.debug_print(" adding " + name) + self.files.append(name) + files_found = 1 + + return files_found + + # include_pattern () + + + def exclude_pattern (self, pattern, + anchor=1, prefix=None, is_regex=0): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. Other parameters are the same as for + 'include_pattern()', above. + The list 'self.files' is modified in place. + Return 1 if files are found. + """ + files_found = 0 + pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) + self.debug_print("exclude_pattern: applying regex r'%s'" % + pattern_re.pattern) + for i in range(len(self.files)-1, -1, -1): + if pattern_re.search(self.files[i]): + self.debug_print(" removing " + self.files[i]) + del self.files[i] + files_found = 1 + + return files_found + + # exclude_pattern () + +# class FileList + + +# ---------------------------------------------------------------------- +# Utility functions + +def findall (dir = os.curdir): + """Find all files under 'dir' and return the list of full filenames + (relative to 'dir'). + """ + from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK + + list = [] + stack = [dir] + pop = stack.pop + push = stack.append + + while stack: + dir = pop() + names = os.listdir(dir) + + for name in names: + if dir != os.curdir: # avoid the dreaded "./" syndrome + fullname = os.path.join(dir, name) + else: + fullname = name + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat[ST_MODE] + if S_ISREG(mode): + list.append(fullname) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + return list + + +def glob_to_re (pattern): + """Translate a shell-like glob pattern to a regular expression; return + a string containing the regex. Differs from 'fnmatch.translate()' in + that '*' does not match "special characters" (which are + platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters. + # XXX currently the "special characters" are just slash -- i.e. this is + # Unix-only. + pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re) + return pattern_re + +# glob_to_re () + + +def translate_pattern (pattern, anchor=1, prefix=None, is_regex=0): + """Translate a shell-like wildcard pattern to a compiled regular + expression. Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if type(pattern) is StringType: + return re.compile(pattern) + else: + return pattern + + if pattern: + pattern_re = glob_to_re(pattern) + else: + pattern_re = '' + + if prefix is not None: + prefix_re = (glob_to_re(prefix))[0:-1] # ditch trailing $ + pattern_re = "^" + os.path.join(prefix_re, ".*" + pattern_re) + else: # no prefix -- respect anchor flag + if anchor: + pattern_re = "^" + pattern_re + + return re.compile(pattern_re) + +# translate_pattern () diff --git a/wxPython/distutils/log.py b/wxPython/distutils/log.py new file mode 100644 index 0000000000..0442033d66 --- /dev/null +++ b/wxPython/distutils/log.py @@ -0,0 +1,61 @@ +"""A simple log mechanism styled after PEP 282.""" + +# This module should be kept compatible with Python 1.5.2. + +# The class here is styled after PEP 282 so that it could later be +# replaced with a standard Python logging implementation. + +DEBUG = 1 +INFO = 2 +WARN = 3 +ERROR = 4 +FATAL = 5 + +import sys + +class Log: + + def __init__(self, threshold=WARN): + self.threshold = threshold + + def _log(self, level, msg, args): + if level >= self.threshold: + print msg % args + sys.stdout.flush() + + def log(self, level, msg, *args): + self._log(level, msg, args) + + def debug(self, msg, *args): + self._log(DEBUG, msg, args) + + def info(self, msg, *args): + self._log(INFO, msg, args) + + def warn(self, msg, *args): + self._log(WARN, msg, args) + + def error(self, msg, *args): + self._log(ERROR, msg, args) + + def fatal(self, msg, *args): + self._log(FATAL, msg, args) + +_global_log = Log() +log = _global_log.log +debug = _global_log.debug +info = _global_log.info +warn = _global_log.warn +error = _global_log.error +fatal = _global_log.fatal + +def set_threshold(level): + _global_log.threshold = level + +def set_verbosity(v): + if v == 0: + set_threshold(WARN) + if v == 1: + set_threshold(INFO) + if v == 2: + set_threshold(DEBUG) diff --git a/wxPython/distutils/msvccompiler.py b/wxPython/distutils/msvccompiler.py new file mode 100644 index 0000000000..e07a6d5a0c --- /dev/null +++ b/wxPython/distutils/msvccompiler.py @@ -0,0 +1,503 @@ +"""distutils.msvccompiler + +Contains MSVCCompiler, an implementation of the abstract CCompiler class +for the Microsoft Visual Studio.""" + +# Written by Perry Stoll +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from types import * +from distutils.errors import \ + DistutilsExecError, DistutilsPlatformError, \ + CompileError, LibError, LinkError +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options, gen_lib_options +from distutils import log + +_can_read_reg = 0 +try: + import _winreg + + _can_read_reg = 1 + hkey_mod = _winreg + + RegOpenKeyEx = _winreg.OpenKeyEx + RegEnumKey = _winreg.EnumKey + RegEnumValue = _winreg.EnumValue + RegError = _winreg.error + +except ImportError: + try: + import win32api + import win32con + _can_read_reg = 1 + hkey_mod = win32con + + RegOpenKeyEx = win32api.RegOpenKeyEx + RegEnumKey = win32api.RegEnumKey + RegEnumValue = win32api.RegEnumValue + RegError = win32api.error + + except ImportError: + pass + +if _can_read_reg: + HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT + HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE + HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER + HKEY_USERS = hkey_mod.HKEY_USERS + + + +def get_devstudio_versions (): + """Get list of devstudio versions from the Windows registry. Return a + list of strings containing version numbers; the list will be + empty if we were unable to access the registry (eg. couldn't import + a registry-access module) or the appropriate registry keys weren't + found.""" + + if not _can_read_reg: + return [] + + K = 'Software\\Microsoft\\Devstudio' + L = [] + for base in (HKEY_CLASSES_ROOT, + HKEY_LOCAL_MACHINE, + HKEY_CURRENT_USER, + HKEY_USERS): + try: + k = RegOpenKeyEx(base,K) + i = 0 + while 1: + try: + p = RegEnumKey(k,i) + if p[0] in '123456789' and p not in L: + L.append(p) + except RegError: + break + i = i + 1 + except RegError: + pass + L.sort() + L.reverse() + return L + +# get_devstudio_versions () + + +def get_msvc_paths (path, version='6.0', platform='x86'): + """Get a list of devstudio directories (include, lib or path). Return + a list of strings; will be empty list if unable to access the + registry or appropriate registry keys not found.""" + + if not _can_read_reg: + return [] + + L = [] + if path=='lib': + path= 'Library' + path = string.upper(path + ' Dirs') + K = ('Software\\Microsoft\\Devstudio\\%s\\' + + 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \ + (version,platform) + for base in (HKEY_CLASSES_ROOT, + HKEY_LOCAL_MACHINE, + HKEY_CURRENT_USER, + HKEY_USERS): + try: + k = RegOpenKeyEx(base,K) + i = 0 + while 1: + try: + (p,v,t) = RegEnumValue(k,i) + if string.upper(p) == path: + V = string.split(v,';') + for v in V: + if hasattr(v, "encode"): + try: + v = v.encode("mbcs") + except UnicodeError: + pass + if v == '' or v in L: continue + L.append(v) + break + i = i + 1 + except RegError: + break + except RegError: + pass + return L + +# get_msvc_paths() + + +def find_exe (exe, version_number): + """Try to find an MSVC executable program 'exe' (from version + 'version_number' of MSVC) in several places: first, one of the MSVC + program search paths from the registry; next, the directories in the + PATH environment variable. If any of those work, return an absolute + path that is known to exist. If none of them work, just return the + original program name, 'exe'.""" + + for p in get_msvc_paths ('path', version_number): + fn = os.path.join (os.path.abspath(p), exe) + if os.path.isfile(fn): + return fn + + # didn't find it; try existing path + for p in string.split (os.environ['Path'],';'): + fn = os.path.join(os.path.abspath(p),exe) + if os.path.isfile(fn): + return fn + + return exe # last desperate hope + + +def set_path_env_var (name, version_number): + """Set environment variable 'name' to an MSVC path type value obtained + from 'get_msvc_paths()'. This is equivalent to a SET command prior + to execution of spawned commands.""" + + p = get_msvc_paths (name, version_number) + if p: + os.environ[name] = string.join (p,';') + + +class MSVCCompiler (CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" + + compiler_type = 'msvc' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions + _mc_extensions) + res_extension = '.res' + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CCompiler.__init__ (self, verbose, dry_run, force) + versions = get_devstudio_versions () + + if versions: + version = versions[0] # highest version + + self.cc = find_exe("cl.exe", version) + self.linker = find_exe("link.exe", version) + self.lib = find_exe("lib.exe", version) + self.rc = find_exe("rc.exe", version) # resource compiler + self.mc = find_exe("mc.exe", version) # message compiler + set_path_env_var ('lib', version) + set_path_env_var ('include', version) + path=get_msvc_paths('path', version) + try: + for p in string.split(os.environ['path'],';'): + path.append(p) + except KeyError: + pass + os.environ['path'] = string.join(path,';') + else: + # devstudio not found in the registry + self.cc = "cl.exe" + self.linker = "link.exe" + self.lib = "lib.exe" + self.rc = "rc.exe" + self.mc = "mc.exe" + + self.preprocess_options = None + self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' , + '/DNDEBUG'] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', + '/Z7', '/D_DEBUG'] + + self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] + self.ldflags_shared_debug = [ + '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG' + ] + self.ldflags_static = [ '/nologo'] + + + # -- Worker methods ------------------------------------------------ + + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + # Copied from ccompiler.py, extended to return .res as 'object'-file + # for .rc input file + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + (base, ext) = os.path.splitext (src_name) + if ext not in self.src_extensions: + # Better to raise an exception instead of silently continuing + # and later complain about sources and targets having + # different lengths + raise CompileError ("Don't know how to compile %s" % src_name) + if strip_dir: + base = os.path.basename (base) + if ext in self._rc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + elif ext in self._mc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + + def compile(self, sources, + output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + + compile_opts = extra_preargs or [] + compile_opts.append ('/c') + if debug: + compile_opts.extend(self.compile_options_debug) + else: + compile_opts.extend(self.compile_options) + + for obj, (src, ext) in build.items(): + if debug: + # pass the full pathname to MSVC in debug mode, + # this allows the debugger to find the source file + # without asking the user to browse for it + src = os.path.abspath(src) + + if ext in self._c_extensions: + input_opt = "/Tc" + src + elif ext in self._cpp_extensions: + input_opt = "/Tp" + src + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt = src + output_opt = "/fo" + obj + try: + self.spawn ([self.rc] + pp_opts + + [output_opt] + [input_opt]) + except DistutilsExecError, msg: + raise CompileError, msg + continue + elif ext in self._mc_extensions: + + # Compile .MC to .RC file to .RES file. + # * '-h dir' specifies the directory for the + # generated include file + # * '-r dir' specifies the target directory of the + # generated RC file and the binary message resource + # it includes + # + # For now (since there are no options to change this), + # we use the source-directory for the include file and + # the build directory for the RC file and message + # resources. This works at least for win32all. + + h_dir = os.path.dirname (src) + rc_dir = os.path.dirname (obj) + try: + # first compile .MC to .RC and .H file + self.spawn ([self.mc] + + ['-h', h_dir, '-r', rc_dir] + [src]) + base, _ = os.path.splitext (os.path.basename (src)) + rc_file = os.path.join (rc_dir, base + '.rc') + # then compile .RC to .RES file + self.spawn ([self.rc] + + ["/fo" + obj] + [rc_file]) + + except DistutilsExecError, msg: + raise CompileError, msg + continue + else: + # how to handle this file? + raise CompileError ( + "Don't know how to compile %s to %s" % \ + (src, obj)) + + output_opt = "/Fo" + obj + try: + self.spawn ([self.cc] + compile_opts + pp_opts + + [input_opt, output_opt] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + return objects + + # compile () + + + def create_static_lib (self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + + (objects, output_dir) = self._fix_object_args (objects, output_dir) + output_filename = \ + self.library_filename (output_libname, output_dir=output_dir) + + if self._need_link (objects, output_filename): + lib_args = objects + ['/OUT:' + output_filename] + if debug: + pass # XXX what goes here? + try: + self.spawn ([self.lib] + lib_args) + except DistutilsExecError, msg: + raise LibError, msg + + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # create_static_lib () + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + (objects, output_dir) = self._fix_object_args (objects, output_dir) + (libraries, library_dirs, runtime_library_dirs) = \ + self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) + + if runtime_library_dirs: + self.warn ("I don't know what to do with 'runtime_library_dirs': " + + str (runtime_library_dirs)) + + lib_opts = gen_lib_options (self, + library_dirs, runtime_library_dirs, + libraries) + if output_dir is not None: + output_filename = os.path.join (output_dir, output_filename) + + if self._need_link (objects, output_filename): + + if target_desc == CCompiler.EXECUTABLE: + if debug: + ldflags = self.ldflags_shared_debug[1:] + else: + ldflags = self.ldflags_shared[1:] + else: + if debug: + ldflags = self.ldflags_shared_debug + else: + ldflags = self.ldflags_shared + + export_opts = [] + for sym in (export_symbols or []): + export_opts.append("/EXPORT:" + sym) + + ld_args = (ldflags + lib_opts + export_opts + + objects + ['/OUT:' + output_filename]) + + # The MSVC linker generates .lib and .exp files, which cannot be + # suppressed by any linker switches. The .lib files may even be + # needed! Make sure they are generated in the temporary build + # directory. Since they have different names for debug and release + # builds, they can go into the same directory. + if export_symbols is not None: + (dll_name, dll_ext) = os.path.splitext( + os.path.basename(output_filename)) + implib_file = os.path.join( + os.path.dirname(objects[0]), + self.library_filename(dll_name)) + ld_args.append ('/IMPLIB:' + implib_file) + + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + + self.mkpath (os.path.dirname (output_filename)) + try: + self.spawn ([self.linker] + ld_args) + except DistutilsExecError, msg: + raise LinkError, msg + + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # link () + + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. + + def library_dir_option (self, dir): + return "/LIBPATH:" + dir + + def runtime_library_dir_option (self, dir): + raise DistutilsPlatformError, \ + "don't know how to set runtime library search path for MSVC++" + + def library_option (self, lib): + return self.library_filename (lib) + + + def find_library_file (self, dirs, lib, debug=0): + # Prefer a debugging library if found (and requested), but deal + # with it if we don't have one. + if debug: + try_names = [lib + "_d", lib] + else: + try_names = [lib] + for dir in dirs: + for name in try_names: + libfile = os.path.join(dir, self.library_filename (name)) + if os.path.exists(libfile): + return libfile + else: + # Oops, didn't find it in *any* of 'dirs' + return None + + # find_library_file () + +# class MSVCCompiler diff --git a/wxPython/distutils/mwerkscompiler.py b/wxPython/distutils/mwerkscompiler.py new file mode 100644 index 0000000000..d546de1f25 --- /dev/null +++ b/wxPython/distutils/mwerkscompiler.py @@ -0,0 +1,248 @@ +"""distutils.mwerkscompiler + +Contains MWerksCompiler, an implementation of the abstract CCompiler class +for MetroWerks CodeWarrior on the Macintosh. Needs work to support CW on +Windows.""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from types import * +from distutils.errors import \ + DistutilsExecError, DistutilsPlatformError, \ + CompileError, LibError, LinkError +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options, gen_lib_options +import distutils.util +import distutils.dir_util +from distutils import log +import mkcwproject + +class MWerksCompiler (CCompiler) : + """Concrete class that implements an interface to MetroWerks CodeWarrior, + as defined by the CCompiler abstract class.""" + + compiler_type = 'mwerks' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.r'] + _exp_extension = '.exp' + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions) + res_extension = '.rsrc' + obj_extension = '.obj' # Not used, really + static_lib_extension = '.lib' + shared_lib_extension = '.slb' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '' + + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CCompiler.__init__ (self, verbose, dry_run, force) + + + def compile (self, + sources, + output_dir=None, + macros=None, + include_dirs=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + depends=None): + (output_dir, macros, include_dirs) = \ + self._fix_compile_args (output_dir, macros, include_dirs) + self.__sources = sources + self.__macros = macros + self.__include_dirs = include_dirs + # Don't need extra_preargs and extra_postargs for CW + return [] + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + # First fixup. + (objects, output_dir) = self._fix_object_args (objects, output_dir) + (libraries, library_dirs, runtime_library_dirs) = \ + self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) + + # First examine a couple of options for things that aren't implemented yet + if not target_desc in (self.SHARED_LIBRARY, self.SHARED_OBJECT): + raise DistutilsPlatformError, 'Can only make SHARED_LIBRARY or SHARED_OBJECT targets on the Mac' + if runtime_library_dirs: + raise DistutilsPlatformError, 'Runtime library dirs not implemented yet' + if extra_preargs or extra_postargs: + raise DistutilsPlatformError, 'Runtime library dirs not implemented yet' + if len(export_symbols) != 1: + raise DistutilsPlatformError, 'Need exactly one export symbol' + # Next there are various things for which we need absolute pathnames. + # This is because we (usually) create the project in a subdirectory of + # where we are now, and keeping the paths relative is too much work right + # now. + sources = map(self._filename_to_abs, self.__sources) + include_dirs = map(self._filename_to_abs, self.__include_dirs) + if objects: + objects = map(self._filename_to_abs, objects) + else: + objects = [] + if build_temp: + build_temp = self._filename_to_abs(build_temp) + else: + build_temp = os.curdir() + if output_dir: + output_filename = os.path.join(output_dir, output_filename) + # The output filename needs special handling: splitting it into dir and + # filename part. Actually I'm not sure this is really needed, but it + # can't hurt. + output_filename = self._filename_to_abs(output_filename) + output_dir, output_filename = os.path.split(output_filename) + # Now we need the short names of a couple of things for putting them + # into the project. + if output_filename[-8:] == '.ppc.slb': + basename = output_filename[:-8] + elif output_filename[-11:] == '.carbon.slb': + basename = output_filename[:-11] + else: + basename = os.path.strip(output_filename)[0] + projectname = basename + '.mcp' + targetname = basename + xmlname = basename + '.xml' + exportname = basename + '.mcp.exp' + prefixname = 'mwerks_%s_config.h'%basename + # Create the directories we need + distutils.dir_util.mkpath(build_temp, dry_run=self.dry_run) + distutils.dir_util.mkpath(output_dir, dry_run=self.dry_run) + # And on to filling in the parameters for the project builder + settings = {} + settings['mac_exportname'] = exportname + settings['mac_outputdir'] = output_dir + settings['mac_dllname'] = output_filename + settings['mac_targetname'] = targetname + settings['sysprefix'] = sys.prefix + settings['mac_sysprefixtype'] = 'Absolute' + sourcefilenames = [] + sourcefiledirs = [] + for filename in sources + objects: + dirname, filename = os.path.split(filename) + sourcefilenames.append(filename) + if not dirname in sourcefiledirs: + sourcefiledirs.append(dirname) + settings['sources'] = sourcefilenames + settings['libraries'] = libraries + settings['extrasearchdirs'] = sourcefiledirs + include_dirs + library_dirs + if self.dry_run: + print 'CALLING LINKER IN', os.getcwd() + for key, value in settings.items(): + print '%20.20s %s'%(key, value) + return + # Build the export file + exportfilename = os.path.join(build_temp, exportname) + log.debug("\tCreate export file %s", exportfilename) + fp = open(exportfilename, 'w') + fp.write('%s\n'%export_symbols[0]) + fp.close() + # Generate the prefix file, if needed, and put it in the settings + if self.__macros: + prefixfilename = os.path.join(os.getcwd(), os.path.join(build_temp, prefixname)) + fp = open(prefixfilename, 'w') + fp.write('#include "mwerks_shcarbon_config.h"\n') + for name, value in self.__macros: + if value is None: + fp.write('#define %s\n'%name) + else: + fp.write('#define %s %s\n'%(name, value)) + fp.close() + settings['prefixname'] = prefixname + + # Build the XML file. We need the full pathname (only lateron, really) + # because we pass this pathname to CodeWarrior in an AppleEvent, and CW + # doesn't have a clue about our working directory. + xmlfilename = os.path.join(os.getcwd(), os.path.join(build_temp, xmlname)) + log.debug("\tCreate XML file %s", xmlfilename) + xmlbuilder = mkcwproject.cwxmlgen.ProjectBuilder(settings) + xmlbuilder.generate() + xmldata = settings['tmp_projectxmldata'] + fp = open(xmlfilename, 'w') + fp.write(xmldata) + fp.close() + # Generate the project. Again a full pathname. + projectfilename = os.path.join(os.getcwd(), os.path.join(build_temp, projectname)) + log.debug('\tCreate project file %s', projectfilename) + mkcwproject.makeproject(xmlfilename, projectfilename) + # And build it + log.debug('\tBuild project') + mkcwproject.buildproject(projectfilename) + + def _filename_to_abs(self, filename): + # Some filenames seem to be unix-like. Convert to Mac names. +## if '/' in filename and ':' in filename: +## raise DistutilsPlatformError, 'Filename may be Unix or Mac style: %s'%filename +## if '/' in filename: +## filename = macurl2path(filename) + filename = distutils.util.convert_path(filename) + if not os.path.isabs(filename): + curdir = os.getcwd() + filename = os.path.join(curdir, filename) + # Finally remove .. components + components = string.split(filename, ':') + for i in range(1, len(components)): + if components[i] == '..': + components[i] = '' + return string.join(components, ':') + + def library_dir_option (self, dir): + """Return the compiler option to add 'dir' to the list of + directories searched for libraries. + """ + return # XXXX Not correct... + + def runtime_library_dir_option (self, dir): + """Return the compiler option to add 'dir' to the list of + directories searched for runtime libraries. + """ + # Nothing needed or Mwerks/Mac. + return + + def library_option (self, lib): + """Return the compiler option to add 'dir' to the list of libraries + linked into the shared library or executable. + """ + return + + def find_library_file (self, dirs, lib, debug=0): + """Search the specified list of directories for a static or shared + library file 'lib' and return the full path to that file. If + 'debug' true, look for a debugging version (if that makes sense on + the current platform). Return None if 'lib' wasn't found in any of + the specified directories. + """ + return 0 diff --git a/wxPython/distutils/spawn.py b/wxPython/distutils/spawn.py new file mode 100644 index 0000000000..4857ce5e63 --- /dev/null +++ b/wxPython/distutils/spawn.py @@ -0,0 +1,194 @@ +"""distutils.spawn + +Provides the 'spawn()' function, a front-end to various platform- +specific functions for launching another program in a sub-process. +Also provides the 'find_executable()' to search the path for a given +executable name. +""" + +# This module should be kept compatible with Python 1.5.2. + +__revision__ = "$Id$" + +import sys, os, string +from distutils.errors import * +from distutils import log + +def spawn (cmd, + search_path=1, + verbose=0, + dry_run=0): + + """Run another program, specified as a command list 'cmd', in a new + process. 'cmd' is just the argument list for the new process, ie. + cmd[0] is the program to run and cmd[1:] are the rest of its arguments. + There is no way to run a program with a name different from that of its + executable. + + If 'search_path' is true (the default), the system's executable + search path will be used to find the program; otherwise, cmd[0] + must be the exact path to the executable. If 'dry_run' is true, + the command will not actually be run. + + Raise DistutilsExecError if running the program fails in any way; just + return on success. + """ + if os.name == 'posix': + _spawn_posix(cmd, search_path, dry_run=dry_run) + elif os.name == 'nt': + _spawn_nt(cmd, search_path, dry_run=dry_run) + elif os.name == 'os2': + _spawn_os2(cmd, search_path, dry_run=dry_run) + else: + raise DistutilsPlatformError, \ + "don't know how to spawn programs on platform '%s'" % os.name + +# spawn () + + +def _nt_quote_args (args): + """Quote command-line arguments for DOS/Windows conventions: just + wraps every argument which contains blanks in double quotes, and + returns a new argument list. + """ + + # XXX this doesn't seem very robust to me -- but if the Windows guys + # say it'll work, I guess I'll have to accept it. (What if an arg + # contains quotes? What other magic characters, other than spaces, + # have to be escaped? Is there an escaping mechanism other than + # quoting?) + + for i in range(len(args)): + if string.find(args[i], ' ') != -1: + args[i] = '"%s"' % args[i] + return args + +def _spawn_nt (cmd, + search_path=1, + verbose=0, + dry_run=0): + + executable = cmd[0] + cmd = _nt_quote_args(cmd) + if search_path: + # either we find one or it stays the same + executable = find_executable(executable) or executable + log.info(string.join([executable] + cmd[1:], ' ')) + if not dry_run: + # spawn for NT requires a full path to the .exe + try: + rc = os.spawnv(os.P_WAIT, executable, cmd) + except OSError, exc: + # this seems to happen when the command isn't found + raise DistutilsExecError, \ + "command '%s' failed: %s" % (cmd[0], exc[-1]) + if rc != 0: + # and this reflects the command running but failing + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % (cmd[0], rc) + + +def _spawn_os2 (cmd, + search_path=1, + verbose=0, + dry_run=0): + + executable = cmd[0] + #cmd = _nt_quote_args(cmd) + if search_path: + # either we find one or it stays the same + executable = find_executable(executable) or executable + log.info(string.join([executable] + cmd[1:], ' ')) + if not dry_run: + # spawnv for OS/2 EMX requires a full path to the .exe + try: + rc = os.spawnv(os.P_WAIT, executable, cmd) + except OSError, exc: + # this seems to happen when the command isn't found + raise DistutilsExecError, \ + "command '%s' failed: %s" % (cmd[0], exc[-1]) + if rc != 0: + # and this reflects the command running but failing + print "command '%s' failed with exit status %d" % (cmd[0], rc) + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % (cmd[0], rc) + + +def _spawn_posix (cmd, + search_path=1, + verbose=0, + dry_run=0): + + log.info(string.join(cmd, ' ')) + if dry_run: + return + exec_fn = search_path and os.execvp or os.execv + + pid = os.fork() + + if pid == 0: # in the child + try: + #print "cmd[0] =", cmd[0] + #print "cmd =", cmd + exec_fn(cmd[0], cmd) + except OSError, e: + sys.stderr.write("unable to execute %s: %s\n" % + (cmd[0], e.strerror)) + os._exit(1) + + sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0]) + os._exit(1) + + + else: # in the parent + # Loop until the child either exits or is terminated by a signal + # (ie. keep waiting if it's merely stopped) + while 1: + (pid, status) = os.waitpid(pid, 0) + if os.WIFSIGNALED(status): + raise DistutilsExecError, \ + "command '%s' terminated by signal %d" % \ + (cmd[0], os.WTERMSIG(status)) + + elif os.WIFEXITED(status): + exit_status = os.WEXITSTATUS(status) + if exit_status == 0: + return # hey, it succeeded! + else: + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % \ + (cmd[0], exit_status) + + elif os.WIFSTOPPED(status): + continue + + else: + raise DistutilsExecError, \ + "unknown error executing '%s': termination status %d" % \ + (cmd[0], status) +# _spawn_posix () + + +def find_executable(executable, path=None): + """Try to find 'executable' in the directories listed in 'path' (a + string listing directories separated by 'os.pathsep'; defaults to + os.environ['PATH']). Returns the complete filename or None if not + found. + """ + if path is None: + path = os.environ['PATH'] + paths = string.split(path, os.pathsep) + (base, ext) = os.path.splitext(executable) + if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'): + executable = executable + '.exe' + if not os.path.isfile(executable): + for p in paths: + f = os.path.join(p, executable) + if os.path.isfile(f): + # the file exists, we have a shot at spawn working + return f + return None + else: + return executable + +# find_executable() diff --git a/wxPython/distutils/sysconfig.py b/wxPython/distutils/sysconfig.py new file mode 100644 index 0000000000..67353a8d64 --- /dev/null +++ b/wxPython/distutils/sysconfig.py @@ -0,0 +1,495 @@ +"""Provide access to Python's configuration information. The specific +configuration variables available depend heavily on the platform and +configuration. The values may be retrieved using +get_config_var(name), and the list of variables is available via +get_config_vars().keys(). Additional convenience functions are also +available. + +Written by: Fred L. Drake, Jr. +Email: +""" + +__revision__ = "$Id$" + +import os +import re +import string +import sys + +from errors import DistutilsPlatformError + +# These are needed in a couple of spots, so just compute them once. +PREFIX = os.path.normpath(sys.prefix) +EXEC_PREFIX = os.path.normpath(sys.exec_prefix) + +# python_build: (Boolean) if true, we're either building Python or +# building an extension with an un-installed Python, so we use +# different (hard-wired) directories. + +argv0_path = os.path.dirname(os.path.abspath(sys.executable)) +landmark = os.path.join(argv0_path, "Modules", "Setup") + +python_build = os.path.isfile(landmark) + +del argv0_path, landmark + + +def get_python_version (): + """Return a string containing the major and minor Python version, + leaving off the patchlevel. Sample return values could be '1.5' + or '2.2'. + """ + return sys.version[:3] + + +def get_python_inc(plat_specific=0, prefix=None): + """Return the directory containing installed Python header files. + + If 'plat_specific' is false (the default), this is the path to the + non-platform-specific header files, i.e. Python.h and so on; + otherwise, this is the path to platform-specific header files + (namely pyconfig.h). + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + if prefix is None: + prefix = plat_specific and EXEC_PREFIX or PREFIX + if os.name == "posix": + if python_build: + base = os.path.dirname(os.path.abspath(sys.executable)) + if plat_specific: + inc_dir = base + else: + inc_dir = os.path.join(base, "Include") + if not os.path.exists(inc_dir): + inc_dir = os.path.join(os.path.dirname(base), "Include") + return inc_dir + return os.path.join(prefix, "include", "python" + sys.version[:3]) + elif os.name == "nt": + return os.path.join(prefix, "include") + elif os.name == "mac": + if plat_specific: + return os.path.join(prefix, "Mac", "Include") + else: + return os.path.join(prefix, "Include") + elif os.name == "os2": + return os.path.join(prefix, "Include") + else: + raise DistutilsPlatformError( + "I don't know where Python installs its C header files " + "on platform '%s'" % os.name) + + +def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + """Return the directory containing the Python library (standard or + site additions). + + If 'plat_specific' is true, return the directory containing + platform-specific modules, i.e. any module from a non-pure-Python + module distribution; otherwise, return the platform-shared library + directory. If 'standard_lib' is true, return the directory + containing standard Python library modules; otherwise, return the + directory for site-specific modules. + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + if prefix is None: + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": + libpython = os.path.join(prefix, + "lib", "python" + get_python_version()) + if standard_lib: + return libpython + else: + return os.path.join(libpython, "site-packages") + + elif os.name == "nt": + if standard_lib: + return os.path.join(prefix, "Lib") + else: + if sys.version < "2.2": + return prefix + else: + return os.path.join(PREFIX, "Lib", "site-packages") + + elif os.name == "mac": + if plat_specific: + if standard_lib: + return os.path.join(prefix, "Lib", "lib-dynload") + else: + return os.path.join(prefix, "Lib", "site-packages") + else: + if standard_lib: + return os.path.join(prefix, "Lib") + else: + return os.path.join(prefix, "Lib", "site-packages") + + elif os.name == "os2": + if standard_lib: + return os.path.join(PREFIX, "Lib") + else: + return os.path.join(PREFIX, "Lib", "site-packages") + + else: + raise DistutilsPlatformError( + "I don't know where Python installs its library " + "on platform '%s'" % os.name) + + +def customize_compiler(compiler): + """Do any platform-specific customization of a CCompiler instance. + + Mainly needed on Unix, so we can plug in the information that + varies across Unices and is stored in Python's Makefile. + """ + if compiler.compiler_type == "unix": + (cc, cxx, opt, basecflags, ccshared, ldshared, so_ext) = \ + get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', 'CCSHARED', 'LDSHARED', 'SO') + + if os.environ.has_key('CC'): + cc = os.environ['CC'] + if os.environ.has_key('CXX'): + cxx = os.environ['CXX'] + if os.environ.has_key('CPP'): + cpp = os.environ['CPP'] + else: + cpp = cc + " -E" # not always + if os.environ.has_key('LDFLAGS'): + ldshared = ldshared + ' ' + os.environ['LDFLAGS'] + if basecflags: + opt = basecflags + ' ' + opt + if os.environ.has_key('CFLAGS'): + opt = opt + ' ' + os.environ['CFLAGS'] + ldshared = ldshared + ' ' + os.environ['CFLAGS'] + if os.environ.has_key('CPPFLAGS'): + cpp = cpp + ' ' + os.environ['CPPFLAGS'] + opt = opt + ' ' + os.environ['CPPFLAGS'] + ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + + cc_cmd = cc + ' ' + opt + compiler.set_executables( + preprocessor=cpp, + compiler=cc_cmd, + compiler_so=cc_cmd + ' ' + ccshared, + compiler_cxx=cxx, + linker_so=ldshared, + linker_exe=cc) + + compiler.shared_lib_extension = so_ext + + +def get_config_h_filename(): + """Return full pathname of installed pyconfig.h file.""" + if python_build: + inc_dir = os.curdir + else: + inc_dir = get_python_inc(plat_specific=1) + if sys.version < '2.2': + config_h = 'config.h' + else: + # The name of the config.h file changed in 2.2 + config_h = 'pyconfig.h' + return os.path.join(inc_dir, config_h) + + +def get_makefile_filename(): + """Return full pathname of installed Makefile from the Python build.""" + if python_build: + return os.path.join(os.path.dirname(sys.executable), "Makefile") + lib_dir = get_python_lib(plat_specific=1, standard_lib=1) + return os.path.join(lib_dir, "config", "Makefile") + + +def parse_config_h(fp, g=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if g is None: + g = {} + define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n") + # + while 1: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: v = int(v) + except ValueError: pass + g[n] = v + else: + m = undef_rx.match(line) + if m: + g[m.group(1)] = 0 + return g + + +# Regexes needed for parsing Makefile (and similar syntaxes, +# like old-style Setup files). +_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") +_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") +_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + +def parse_makefile(fn, g=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + from distutils.text_file import TextFile + fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1) + + if g is None: + g = {} + done = {} + notdone = {} + + while 1: + line = fp.readline() + if line is None: # eof + break + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = string.strip(v) + if "$" in v: + notdone[n] = v + else: + try: v = int(v) + except ValueError: pass + done[n] = v + + # do variable interpolation here + while notdone: + for name in notdone.keys(): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m: + n = m.group(1) + if done.has_key(n): + after = value[m.end():] + value = value[:m.start()] + str(done[n]) + after + if "$" in after: + notdone[name] = value + else: + try: value = int(value) + except ValueError: + done[name] = string.strip(value) + else: + done[name] = value + del notdone[name] + elif notdone.has_key(n): + # get it on a subsequent round + pass + else: + done[n] = "" + after = value[m.end():] + value = value[:m.start()] + after + if "$" in after: + notdone[name] = value + else: + try: value = int(value) + except ValueError: + done[name] = string.strip(value) + else: + done[name] = value + del notdone[name] + else: + # bogus variable reference; just drop it since we can't deal + del notdone[name] + + fp.close() + + # save the results in the global dictionary + g.update(done) + return g + + +def expand_makefile_vars(s, vars): + """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + 'string' according to 'vars' (a dictionary mapping variable names to + values). Variables not present in 'vars' are silently expanded to the + empty string. The variable values in 'vars' should not contain further + variable expansions; if 'vars' is the output of 'parse_makefile()', + you're fine. Returns a variable-expanded version of 's'. + """ + + # This algorithm does multiple expansion, so if vars['foo'] contains + # "${bar}", it will expand ${foo} to ${bar}, and then expand + # ${bar}... and so forth. This is fine as long as 'vars' comes from + # 'parse_makefile()', which takes care of such expansions eagerly, + # according to make's variable expansion semantics. + + while 1: + m = _findvar1_rx.search(s) or _findvar2_rx.search(s) + if m: + (beg, end) = m.span() + s = s[0:beg] + vars.get(m.group(1)) + s[end:] + else: + break + return s + + +_config_vars = None + +def _init_posix(): + """Initialize the module as appropriate for POSIX systems.""" + g = {} + # load the installed Makefile: + try: + filename = get_makefile_filename() + parse_makefile(filename, g) + except IOError, msg: + my_msg = "invalid Python installation: unable to open %s" % filename + if hasattr(msg, "strerror"): + my_msg = my_msg + " (%s)" % msg.strerror + + raise DistutilsPlatformError(my_msg) + + + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if python_build: + g['LDSHARED'] = g['BLDSHARED'] + + elif sys.version < '2.1': + # The following two branches are for 1.5.2 compatibility. + if sys.platform == 'aix4': # what about AIX 3.x ? + # Linker script is in the config directory, not in Modules as the + # Makefile says. + python_lib = get_python_lib(standard_lib=1) + ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') + python_exp = os.path.join(python_lib, 'config', 'python.exp') + + g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) + + elif sys.platform == 'beos': + # Linker script is in the config directory. In the Makefile it is + # relative to the srcdir, which after installation no longer makes + # sense. + python_lib = get_python_lib(standard_lib=1) + linkerscript_path = string.split(g['LDSHARED'])[0] + linkerscript_name = os.path.basename(linkerscript_path) + linkerscript = os.path.join(python_lib, 'config', + linkerscript_name) + + # XXX this isn't the right place to do this: adding the Python + # library to the link, if needed, should be in the "build_ext" + # command. (It's also needed for non-MS compilers on Windows, and + # it's taken care of for them by the 'build_ext.get_libraries()' + # method.) + g['LDSHARED'] = ("%s -L%s/lib -lpython%s" % + (linkerscript, PREFIX, sys.version[0:3])) + + global _config_vars + _config_vars = g + + +def _init_nt(): + """Initialize the module as appropriate for NT""" + g = {} + # set basic install directories + g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) + g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) + + # XXX hmmm.. a normal install puts include files here + g['INCLUDEPY'] = get_python_inc(plat_specific=0) + + g['SO'] = '.pyd' + g['EXE'] = ".exe" + + global _config_vars + _config_vars = g + + +def _init_mac(): + """Initialize the module as appropriate for Macintosh systems""" + g = {} + # set basic install directories + g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) + g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) + + # XXX hmmm.. a normal install puts include files here + g['INCLUDEPY'] = get_python_inc(plat_specific=0) + + import MacOS + if not hasattr(MacOS, 'runtimemodel'): + g['SO'] = '.ppc.slb' + else: + g['SO'] = '.%s.slb' % MacOS.runtimemodel + + # XXX are these used anywhere? + g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib") + g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib") + + # These are used by the extension module build + g['srcdir'] = ':' + global _config_vars + _config_vars = g + + +def _init_os2(): + """Initialize the module as appropriate for OS/2""" + g = {} + # set basic install directories + g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) + g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) + + # XXX hmmm.. a normal install puts include files here + g['INCLUDEPY'] = get_python_inc(plat_specific=0) + + g['SO'] = '.pyd' + g['EXE'] = ".exe" + + global _config_vars + _config_vars = g + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. Generally this includes + everything needed to build extensions and install both pure modules and + extensions. On Unix, this means every variable defined in Python's + installed Makefile; on Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _config_vars + if _config_vars is None: + func = globals().get("_init_" + os.name) + if func: + func() + else: + _config_vars = {} + + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _config_vars['prefix'] = PREFIX + _config_vars['exec_prefix'] = EXEC_PREFIX + + if args: + vals = [] + for name in args: + vals.append(_config_vars.get(name)) + return vals + else: + return _config_vars + +def get_config_var(name): + """Return the value of a single variable using the dictionary + returned by 'get_config_vars()'. Equivalent to + get_config_vars().get(name) + """ + return get_config_vars().get(name) diff --git a/wxPython/distutils/text_file.py b/wxPython/distutils/text_file.py new file mode 100644 index 0000000000..67efd65e36 --- /dev/null +++ b/wxPython/distutils/text_file.py @@ -0,0 +1,382 @@ +"""text_file + +provides the TextFile class, which gives an interface to text files +that (optionally) takes care of stripping comments, ignoring blank +lines, and joining lines with backslashes.""" + +__revision__ = "$Id$" + +from types import * +import sys, os, string + + +class TextFile: + + """Provides a file-like object that takes care of all the things you + commonly want to do when processing a text file that has some + line-by-line syntax: strip comments (as long as "#" is your + comment character), skip blank lines, join adjacent lines by + escaping the newline (ie. backslash at end of line), strip + leading and/or trailing whitespace. All of these are optional + and independently controllable. + + Provides a 'warn()' method so you can generate warning messages that + report physical line number, even if the logical line in question + spans multiple physical lines. Also provides 'unreadline()' for + implementing line-at-a-time lookahead. + + Constructor is called as: + + TextFile (filename=None, file=None, **options) + + It bombs (RuntimeError) if both 'filename' and 'file' are None; + 'filename' should be a string, and 'file' a file object (or + something that provides 'readline()' and 'close()' methods). It is + recommended that you supply at least 'filename', so that TextFile + can include it in warning messages. If 'file' is not supplied, + TextFile creates its own using the 'open()' builtin. + + The options are all boolean, and affect the value returned by + 'readline()': + strip_comments [default: true] + strip from "#" to end-of-line, as well as any whitespace + leading up to the "#" -- unless it is escaped by a backslash + lstrip_ws [default: false] + strip leading whitespace from each line before returning it + rstrip_ws [default: true] + strip trailing whitespace (including line terminator!) from + each line before returning it + skip_blanks [default: true} + skip lines that are empty *after* stripping comments and + whitespace. (If both lstrip_ws and rstrip_ws are false, + then some lines may consist of solely whitespace: these will + *not* be skipped, even if 'skip_blanks' is true.) + join_lines [default: false] + if a backslash is the last non-newline character on a line + after stripping comments and whitespace, join the following line + to it to form one "logical line"; if N consecutive lines end + with a backslash, then N+1 physical lines will be joined to + form one logical line. + collapse_join [default: false] + strip leading whitespace from lines that are joined to their + predecessor; only matters if (join_lines and not lstrip_ws) + + Note that since 'rstrip_ws' can strip the trailing newline, the + semantics of 'readline()' must differ from those of the builtin file + object's 'readline()' method! In particular, 'readline()' returns + None for end-of-file: an empty string might just be a blank line (or + an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is + not.""" + + default_options = { 'strip_comments': 1, + 'skip_blanks': 1, + 'lstrip_ws': 0, + 'rstrip_ws': 1, + 'join_lines': 0, + 'collapse_join': 0, + } + + def __init__ (self, filename=None, file=None, **options): + """Construct a new TextFile object. At least one of 'filename' + (a string) and 'file' (a file-like object) must be supplied. + They keyword argument options are described above and affect + the values returned by 'readline()'.""" + + if filename is None and file is None: + raise RuntimeError, \ + "you must supply either or both of 'filename' and 'file'" + + # set values for all options -- either from client option hash + # or fallback to default_options + for opt in self.default_options.keys(): + if options.has_key (opt): + setattr (self, opt, options[opt]) + + else: + setattr (self, opt, self.default_options[opt]) + + # sanity check client option hash + for opt in options.keys(): + if not self.default_options.has_key (opt): + raise KeyError, "invalid TextFile option '%s'" % opt + + if file is None: + self.open (filename) + else: + self.filename = filename + self.file = file + self.current_line = 0 # assuming that file is at BOF! + + # 'linebuf' is a stack of lines that will be emptied before we + # actually read from the file; it's only populated by an + # 'unreadline()' operation + self.linebuf = [] + + + def open (self, filename): + """Open a new file named 'filename'. This overrides both the + 'filename' and 'file' arguments to the constructor.""" + + self.filename = filename + self.file = open (self.filename, 'r') + self.current_line = 0 + + + def close (self): + """Close the current file and forget everything we know about it + (filename, current line number).""" + + self.file.close () + self.file = None + self.filename = None + self.current_line = None + + + def gen_error (self, msg, line=None): + outmsg = [] + if line is None: + line = self.current_line + outmsg.append(self.filename + ", ") + if type (line) in (ListType, TupleType): + outmsg.append("lines %d-%d: " % tuple (line)) + else: + outmsg.append("line %d: " % line) + outmsg.append(str(msg)) + return string.join(outmsg, "") + + + def error (self, msg, line=None): + raise ValueError, "error: " + self.gen_error(msg, line) + + def warn (self, msg, line=None): + """Print (to stderr) a warning message tied to the current logical + line in the current file. If the current logical line in the + file spans multiple physical lines, the warning refers to the + whole range, eg. "lines 3-5". If 'line' supplied, it overrides + the current line number; it may be a list or tuple to indicate a + range of physical lines, or an integer for a single physical + line.""" + sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n") + + + def readline (self): + """Read and return a single logical line from the current file (or + from an internal buffer if lines have previously been "unread" + with 'unreadline()'). If the 'join_lines' option is true, this + may involve reading multiple physical lines concatenated into a + single string. Updates the current line number, so calling + 'warn()' after 'readline()' emits a warning about the physical + line(s) just read. Returns None on end-of-file, since the empty + string can occur if 'rstrip_ws' is true but 'strip_blanks' is + not.""" + + # If any "unread" lines waiting in 'linebuf', return the top + # one. (We don't actually buffer read-ahead data -- lines only + # get put in 'linebuf' if the client explicitly does an + # 'unreadline()'. + if self.linebuf: + line = self.linebuf[-1] + del self.linebuf[-1] + return line + + buildup_line = '' + + while 1: + # read the line, make it None if EOF + line = self.file.readline() + if line == '': line = None + + if self.strip_comments and line: + + # Look for the first "#" in the line. If none, never + # mind. If we find one and it's the first character, or + # is not preceded by "\", then it starts a comment -- + # strip the comment, strip whitespace before it, and + # carry on. Otherwise, it's just an escaped "#", so + # unescape it (and any other escaped "#"'s that might be + # lurking in there) and otherwise leave the line alone. + + pos = string.find (line, "#") + if pos == -1: # no "#" -- no comments + pass + + # It's definitely a comment -- either "#" is the first + # character, or it's elsewhere and unescaped. + elif pos == 0 or line[pos-1] != "\\": + # Have to preserve the trailing newline, because it's + # the job of a later step (rstrip_ws) to remove it -- + # and if rstrip_ws is false, we'd better preserve it! + # (NB. this means that if the final line is all comment + # and has no trailing newline, we will think that it's + # EOF; I think that's OK.) + eol = (line[-1] == '\n') and '\n' or '' + line = line[0:pos] + eol + + # If all that's left is whitespace, then skip line + # *now*, before we try to join it to 'buildup_line' -- + # that way constructs like + # hello \\ + # # comment that should be ignored + # there + # result in "hello there". + if string.strip(line) == "": + continue + + else: # it's an escaped "#" + line = string.replace (line, "\\#", "#") + + + # did previous line end with a backslash? then accumulate + if self.join_lines and buildup_line: + # oops: end of file + if line is None: + self.warn ("continuation line immediately precedes " + "end-of-file") + return buildup_line + + if self.collapse_join: + line = string.lstrip (line) + line = buildup_line + line + + # careful: pay attention to line number when incrementing it + if type (self.current_line) is ListType: + self.current_line[1] = self.current_line[1] + 1 + else: + self.current_line = [self.current_line, + self.current_line+1] + # just an ordinary line, read it as usual + else: + if line is None: # eof + return None + + # still have to be careful about incrementing the line number! + if type (self.current_line) is ListType: + self.current_line = self.current_line[1] + 1 + else: + self.current_line = self.current_line + 1 + + + # strip whitespace however the client wants (leading and + # trailing, or one or the other, or neither) + if self.lstrip_ws and self.rstrip_ws: + line = string.strip (line) + elif self.lstrip_ws: + line = string.lstrip (line) + elif self.rstrip_ws: + line = string.rstrip (line) + + # blank line (whether we rstrip'ed or not)? skip to next line + # if appropriate + if (line == '' or line == '\n') and self.skip_blanks: + continue + + if self.join_lines: + if line[-1] == '\\': + buildup_line = line[:-1] + continue + + if line[-2:] == '\\\n': + buildup_line = line[0:-2] + '\n' + continue + + # well, I guess there's some actual content there: return it + return line + + # readline () + + + def readlines (self): + """Read and return the list of all logical lines remaining in the + current file.""" + + lines = [] + while 1: + line = self.readline() + if line is None: + return lines + lines.append (line) + + + def unreadline (self, line): + """Push 'line' (a string) onto an internal buffer that will be + checked by future 'readline()' calls. Handy for implementing + a parser with line-at-a-time lookahead.""" + + self.linebuf.append (line) + + +if __name__ == "__main__": + test_data = """# test file + +line 3 \\ +# intervening comment + continues on next line +""" + # result 1: no fancy options + result1 = map (lambda x: x + "\n", string.split (test_data, "\n")[0:-1]) + + # result 2: just strip comments + result2 = ["\n", + "line 3 \\\n", + " continues on next line\n"] + + # result 3: just strip blank lines + result3 = ["# test file\n", + "line 3 \\\n", + "# intervening comment\n", + " continues on next line\n"] + + # result 4: default, strip comments, blank lines, and trailing whitespace + result4 = ["line 3 \\", + " continues on next line"] + + # result 5: strip comments and blanks, plus join lines (but don't + # "collapse" joined lines + result5 = ["line 3 continues on next line"] + + # result 6: strip comments and blanks, plus join lines (and + # "collapse" joined lines + result6 = ["line 3 continues on next line"] + + def test_input (count, description, file, expected_result): + result = file.readlines () + # result = string.join (result, '') + if result == expected_result: + print "ok %d (%s)" % (count, description) + else: + print "not ok %d (%s):" % (count, description) + print "** expected:" + print expected_result + print "** received:" + print result + + + filename = "test.txt" + out_file = open (filename, "w") + out_file.write (test_data) + out_file.close () + + in_file = TextFile (filename, strip_comments=0, skip_blanks=0, + lstrip_ws=0, rstrip_ws=0) + test_input (1, "no processing", in_file, result1) + + in_file = TextFile (filename, strip_comments=1, skip_blanks=0, + lstrip_ws=0, rstrip_ws=0) + test_input (2, "strip comments", in_file, result2) + + in_file = TextFile (filename, strip_comments=0, skip_blanks=1, + lstrip_ws=0, rstrip_ws=0) + test_input (3, "strip blanks", in_file, result3) + + in_file = TextFile (filename) + test_input (4, "default processing", in_file, result4) + + in_file = TextFile (filename, strip_comments=1, skip_blanks=1, + join_lines=1, rstrip_ws=1) + test_input (5, "join lines without collapsing", in_file, result5) + + in_file = TextFile (filename, strip_comments=1, skip_blanks=1, + join_lines=1, rstrip_ws=1, collapse_join=1) + test_input (6, "join lines with collapsing", in_file, result6) + + os.remove (filename) diff --git a/wxPython/distutils/unixccompiler.py b/wxPython/distutils/unixccompiler.py new file mode 100644 index 0000000000..2a6b1beeea --- /dev/null +++ b/wxPython/distutils/unixccompiler.py @@ -0,0 +1,233 @@ +"""distutils.unixccompiler + +Contains the UnixCCompiler class, a subclass of CCompiler that handles +the "typical" Unix-style command-line C compiler: + * macros defined with -Dname[=value] + * macros undefined with -Uname + * include search directories specified with -Idir + * libraries specified with -lllib + * library search directories specified with -Ldir + * compile handled by 'cc' (or similar) executable with -c option: + compiles .c to .o + * link static library handled by 'ar' command (possibly with 'ranlib') + * link shared library handled by 'cc -shared' +""" + +__revision__ = "$Id$" + +import os, sys +from types import StringType, NoneType +from copy import copy + +from distutils import sysconfig +from distutils.dep_util import newer +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options, gen_lib_options +from distutils.errors import \ + DistutilsExecError, CompileError, LibError, LinkError +from distutils import log + +# XXX Things not currently handled: +# * optimization/debug/warning flags; we just use whatever's in Python's +# Makefile and live with it. Is this adequate? If not, we might +# have to have a bunch of subclasses GNUCCompiler, SGICCompiler, +# SunCCompiler, and I suspect down that road lies madness. +# * even if we don't know a warning flag from an optimization flag, +# we need some way for outsiders to feed preprocessor/compiler/linker +# flags in to us -- eg. a sysadmin might want to mandate certain flags +# via a site config file, or a user might want to set something for +# compiling this module distribution only via the setup.py command +# line, whatever. As long as these options come from something on the +# current system, they can be as system-dependent as they like, and we +# should just happily stuff them into the preprocessor/compiler/linker +# options and carry on. + +class UnixCCompiler(CCompiler): + + compiler_type = 'unix' + + # These are used by CCompiler in two places: the constructor sets + # instance attributes 'preprocessor', 'compiler', etc. from them, and + # 'set_executable()' allows any of these to be set. The defaults here + # are pretty generic; they will probably have to be set by an outsider + # (eg. using information discovered by the sysconfig about building + # Python extensions). + executables = {'preprocessor' : None, + 'compiler' : ["cc"], + 'compiler_so' : ["cc"], + 'compiler_cxx' : ["cc"], + 'linker_so' : ["cc", "-shared"], + 'linker_exe' : ["cc"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : None, + } + + if sys.platform[:6] == "darwin": + executables['ranlib'] = ["ranlib"] + + # Needed for the filename generation methods provided by the base + # class, CCompiler. NB. whoever instantiates/uses a particular + # UnixCCompiler instance should set 'shared_lib_ext' -- we set a + # reasonable common default here, but it's not necessarily used on all + # Unices! + + src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] + obj_extension = ".o" + static_lib_extension = ".a" + shared_lib_extension = ".so" + dylib_lib_extension = ".dylib" + static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" + + def preprocess(self, source, + output_file=None, macros=None, include_dirs=None, + extra_preargs=None, extra_postargs=None): + ignore, macros, include_dirs = \ + self._fix_compile_args(None, macros, include_dirs) + pp_opts = gen_preprocess_options(macros, include_dirs) + pp_args = self.preprocessor + pp_opts + if output_file: + pp_args.extend(['-o', output_file]) + if extra_preargs: + pp_args[:0] = extra_preargs + if extra_postargs: + pp_args.extend(extra_postargs) + pp_args.append(source) + + # We need to preprocess: either we're being forced to, or we're + # generating output to stdout, or there's a target output file and + # the source file is newer than the target (or the target doesn't + # exist). + if self.force or output_file is None or newer(source, output_file): + if output_file: + self.mkpath(os.path.dirname(output_file)) + try: + self.spawn(pp_args) + except DistutilsExecError, msg: + raise CompileError, msg + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + try: + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + def create_static_lib(self, objects, output_libname, + output_dir=None, debug=0, target_lang=None): + objects, output_dir = self._fix_object_args(objects, output_dir) + + output_filename = \ + self.library_filename(output_libname, output_dir=output_dir) + + if self._need_link(objects, output_filename): + self.mkpath(os.path.dirname(output_filename)) + self.spawn(self.archiver + + [output_filename] + + objects + self.objects) + + # Not many Unices required ranlib anymore -- SunOS 4.x is, I + # think the only major Unix that does. Maybe we need some + # platform intelligence here to skip ranlib if it's not + # needed -- or maybe Python's configure script took care of + # it for us, hence the check for leading colon. + if self.ranlib: + try: + self.spawn(self.ranlib + [output_filename]) + except DistutilsExecError, msg: + raise LibError, msg + else: + log.debug("skipping %s (up-to-date)", output_filename) + + def link(self, target_desc, objects, + output_filename, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, + export_symbols=None, debug=0, extra_preargs=None, + extra_postargs=None, build_temp=None, target_lang=None): + objects, output_dir = self._fix_object_args(objects, output_dir) + libraries, library_dirs, runtime_library_dirs = \ + self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) + + lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, + libraries) + if type(output_dir) not in (StringType, NoneType): + raise TypeError, "'output_dir' must be a string or None" + if output_dir is not None: + output_filename = os.path.join(output_dir, output_filename) + + if self._need_link(objects, output_filename): + ld_args = (objects + self.objects + + lib_opts + ['-o', output_filename]) + if debug: + ld_args[:0] = ['-g'] + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + self.mkpath(os.path.dirname(output_filename)) + try: + if target_desc == CCompiler.EXECUTABLE: + linker = self.linker_exe[:] + else: + linker = self.linker_so[:] + if target_lang == "c++" and self.compiler_cxx: + linker[0] = self.compiler_cxx[0] + self.spawn(linker + ld_args) + except DistutilsExecError, msg: + raise LinkError, msg + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. + + def library_dir_option(self, dir): + return "-L" + dir + + def runtime_library_dir_option(self, dir): + # XXX Hackish, at the very least. See Python bug #445902: + # http://sourceforge.net/tracker/index.php + # ?func=detail&aid=445902&group_id=5470&atid=105470 + # Linkers on different platforms need different options to + # specify that directories need to be added to the list of + # directories searched for dependencies when a dynamic library + # is sought. GCC has to be told to pass the -R option through + # to the linker, whereas other compilers just know this. + # Other compilers may need something slightly different. At + # this time, there's no way to determine this information from + # the configuration data stored in the Python installation, so + # we use this hack. + compiler = os.path.basename(sysconfig.get_config_var("CC")) + if sys.platform[:6] == "darwin": + # MacOSX's linker doesn't understand the -R flag at all + return "-L" + dir + elif compiler[:3] == "gcc" or compiler[:3] == "g++": + return "-Wl,-R" + dir + else: + return "-R" + dir + + def library_option(self, lib): + return "-l" + lib + + def find_library_file(self, dirs, lib, debug=0): + shared_f = self.library_filename(lib, lib_type='shared') + dylib_f = self.library_filename(lib, lib_type='dylib') + static_f = self.library_filename(lib, lib_type='static') + + for dir in dirs: + shared = os.path.join(dir, shared_f) + dylib = os.path.join(dir, dylib_f) + static = os.path.join(dir, static_f) + # We're second-guessing the linker here, with not much hard + # data to go on: GCC seems to prefer the shared library, so I'm + # assuming that *all* Unix C compilers do. And of course I'm + # ignoring even GCC's "-static" option. So sue me. + if os.path.exists(dylib): + return dylib + elif os.path.exists(shared): + return shared + elif os.path.exists(static): + return static + + # Oops, didn't find it in *any* of 'dirs' + return None diff --git a/wxPython/distutils/util.py b/wxPython/distutils/util.py new file mode 100644 index 0000000000..dc3183b691 --- /dev/null +++ b/wxPython/distutils/util.py @@ -0,0 +1,460 @@ +"""distutils.util + +Miscellaneous utility functions -- anything that doesn't fit into +one of the other *util.py modules. +""" + +__revision__ = "$Id$" + +import sys, os, string, re +from distutils.errors import DistutilsPlatformError +from distutils.dep_util import newer +from distutils.spawn import spawn +from distutils import log + +def get_platform (): + """Return a string that identifies the current platform. This is used + mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + For non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + + (osname, host, release, version, machine) = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = string.lower(osname) + osname = string.replace(osname, '/', '') + machine = string.replace(machine, ' ', '_') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile (r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + + return "%s-%s-%s" % (osname, release, machine) + +# get_platform () + + +def convert_path (pathname): + """Return 'pathname' as a name that will work on the native filesystem, + i.e. split it on '/' and put it back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError, "path '%s' cannot be absolute" % pathname + if pathname[-1] == '/': + raise ValueError, "path '%s' cannot end with '/'" % pathname + + paths = string.split(pathname, '/') + while '.' in paths: + paths.remove('.') + if not paths: + return os.curdir + return apply(os.path.join, paths) + +# convert_path () + + +def change_root (new_root, pathname): + """Return 'pathname' with 'new_root' prepended. If 'pathname' is + relative, this is equivalent to "os.path.join(new_root,pathname)". + Otherwise, it requires making 'pathname' relative and then joining the + two, which is tricky on DOS/Windows and Mac OS. + """ + if os.name == 'posix': + if not os.path.isabs(pathname): + return os.path.join(new_root, pathname) + else: + return os.path.join(new_root, pathname[1:]) + + elif os.name == 'nt': + (drive, path) = os.path.splitdrive(pathname) + if path[0] == '\\': + path = path[1:] + return os.path.join(new_root, path) + + elif os.name == 'os2': + (drive, path) = os.path.splitdrive(pathname) + if path[0] == os.sep: + path = path[1:] + return os.path.join(new_root, path) + + elif os.name == 'mac': + if not os.path.isabs(pathname): + return os.path.join(new_root, pathname) + else: + # Chop off volume name from start of path + elements = string.split(pathname, ":", 1) + pathname = ":" + elements[1] + return os.path.join(new_root, pathname) + + else: + raise DistutilsPlatformError, \ + "nothing known about platform '%s'" % os.name + + +_environ_checked = 0 +def check_environ (): + """Ensure that 'os.environ' has all the environment variables we + guarantee that users can use in config files, command-line options, + etc. Currently this includes: + HOME - user's home directory (Unix only) + PLAT - description of the current platform, including hardware + and OS (see 'get_platform()') + """ + global _environ_checked + if _environ_checked: + return + + if os.name == 'posix' and not os.environ.has_key('HOME'): + import pwd + os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] + + if not os.environ.has_key('PLAT'): + os.environ['PLAT'] = get_platform() + + _environ_checked = 1 + + +def subst_vars (s, local_vars): + """Perform shell/Perl-style variable substitution on 'string'. Every + occurrence of '$' followed by a name is considered a variable, and + variable is substituted by the value found in the 'local_vars' + dictionary, or in 'os.environ' if it's not in 'local_vars'. + 'os.environ' is first checked/augmented to guarantee that it contains + certain values: see 'check_environ()'. Raise ValueError for any + variables not found in either 'local_vars' or 'os.environ'. + """ + check_environ() + def _subst (match, local_vars=local_vars): + var_name = match.group(1) + if local_vars.has_key(var_name): + return str(local_vars[var_name]) + else: + return os.environ[var_name] + + try: + return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) + except KeyError, var: + raise ValueError, "invalid variable '$%s'" % var + +# subst_vars () + + +def grok_environment_error (exc, prefix="error: "): + """Generate a useful error message from an EnvironmentError (IOError or + OSError) exception object. Handles Python 1.5.1 and 1.5.2 styles, and + does what it can to deal with exception objects that don't have a + filename (which happens when the error is due to a two-file operation, + such as 'rename()' or 'link()'. Returns the error message as a string + prefixed with 'prefix'. + """ + # check for Python 1.5.2-style {IO,OS}Error exception objects + if hasattr(exc, 'filename') and hasattr(exc, 'strerror'): + if exc.filename: + error = prefix + "%s: %s" % (exc.filename, exc.strerror) + else: + # two-argument functions in posix module don't + # include the filename in the exception object! + error = prefix + "%s" % exc.strerror + else: + error = prefix + str(exc[-1]) + + return error + + +# Needed by 'split_quoted()' +_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) +_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") +_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') + +def split_quoted (s): + """Split a string up according to Unix shell-like rules for quotes and + backslashes. In short: words are delimited by spaces, as long as those + spaces are not escaped by a backslash, or inside a quoted string. + Single and double quotes are equivalent, and the quote characters can + be backslash-escaped. The backslash is stripped from any two-character + escape sequence, leaving only the escaped character. The quote + characters are stripped from any quoted string. Returns a list of + words. + """ + + # This is a nice algorithm for splitting up a single string, since it + # doesn't require character-by-character examination. It was a little + # bit of a brain-bender to get it working right, though... + + s = string.strip(s) + words = [] + pos = 0 + + while s: + m = _wordchars_re.match(s, pos) + end = m.end() + if end == len(s): + words.append(s[:end]) + break + + if s[end] in string.whitespace: # unescaped, unquoted whitespace: now + words.append(s[:end]) # we definitely have a word delimiter + s = string.lstrip(s[end:]) + pos = 0 + + elif s[end] == '\\': # preserve whatever is being escaped; + # will become part of the current word + s = s[:end] + s[end+1:] + pos = end+1 + + else: + if s[end] == "'": # slurp singly-quoted string + m = _squote_re.match(s, end) + elif s[end] == '"': # slurp doubly-quoted string + m = _dquote_re.match(s, end) + else: + raise RuntimeError, \ + "this can't happen (bad char '%c')" % s[end] + + if m is None: + raise ValueError, \ + "bad string (mismatched %s quotes?)" % s[end] + + (beg, end) = m.span() + s = s[:beg] + s[beg+1:end-1] + s[end:] + pos = m.end() - 2 + + if pos >= len(s): + words.append(s) + break + + return words + +# split_quoted () + + +def execute (func, args, msg=None, verbose=0, dry_run=0): + """Perform some action that affects the outside world (eg. by + writing to the filesystem). Such actions are special because they + are disabled by the 'dry_run' flag. This method takes care of all + that bureaucracy for you; all you have to do is supply the + function to call and an argument tuple for it (to embody the + "external action" being performed), and an optional message to + print. + """ + if msg is None: + msg = "%s%s" % (func.__name__, `args`) + if msg[-2:] == ',)': # correct for singleton tuple + msg = msg[0:-2] + ')' + + log.info(msg) + if not dry_run: + apply(func, args) + + +def strtobool (val): + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = string.lower(val) + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return 1 + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return 0 + else: + raise ValueError, "invalid truth value %s" % `val` + + +def byte_compile (py_files, + optimize=0, force=0, + prefix=None, base_dir=None, + verbose=1, dry_run=0, + direct=None): + """Byte-compile a collection of Python source files to either .pyc + or .pyo files in the same directory. 'py_files' is a list of files + to compile; any files that don't end in ".py" are silently skipped. + 'optimize' must be one of the following: + 0 - don't optimize (generate .pyc) + 1 - normal optimization (like "python -O") + 2 - extra optimization (like "python -OO") + If 'force' is true, all files are recompiled regardless of + timestamps. + + The source filename encoded in each bytecode file defaults to the + filenames listed in 'py_files'; you can modify these with 'prefix' and + 'basedir'. 'prefix' is a string that will be stripped off of each + source filename, and 'base_dir' is a directory name that will be + prepended (after 'prefix' is stripped). You can supply either or both + (or neither) of 'prefix' and 'base_dir', as you wish. + + If 'dry_run' is true, doesn't actually do anything that would + affect the filesystem. + + Byte-compilation is either done directly in this interpreter process + with the standard py_compile module, or indirectly by writing a + temporary script and executing it. Normally, you should let + 'byte_compile()' figure out to use direct compilation or not (see + the source for details). The 'direct' flag is used by the script + generated in indirect mode; unless you know what you're doing, leave + it set to None. + """ + + # First, if the caller didn't force us into direct or indirect mode, + # figure out which mode we should be in. We take a conservative + # approach: choose direct mode *only* if the current interpreter is + # in debug mode and optimize is 0. If we're not in debug mode (-O + # or -OO), we don't know which level of optimization this + # interpreter is running with, so we can't do direct + # byte-compilation and be certain that it's the right thing. Thus, + # always compile indirectly if the current interpreter is in either + # optimize mode, or if either optimization level was requested by + # the caller. + if direct is None: + direct = (__debug__ and optimize == 0) + + # "Indirect" byte-compilation: write a temporary script and then + # run it with the appropriate flags. + if not direct: + try: + from tempfile import mkstemp + (script_fd, script_name) = mkstemp(".py") + except ImportError: + from tempfile import mktemp + (script_fd, script_name) = None, mktemp(".py") + log.info("writing byte-compilation script '%s'", script_name) + if not dry_run: + if script_fd is not None: + script = os.fdopen(script_fd, "w") + else: + script = open(script_name, "w") + + script.write("""\ +from distutils.util import byte_compile +files = [ +""") + + # XXX would be nice to write absolute filenames, just for + # safety's sake (script should be more robust in the face of + # chdir'ing before running it). But this requires abspath'ing + # 'prefix' as well, and that breaks the hack in build_lib's + # 'byte_compile()' method that carefully tacks on a trailing + # slash (os.sep really) to make sure the prefix here is "just + # right". This whole prefix business is rather delicate -- the + # problem is that it's really a directory, but I'm treating it + # as a dumb string, so trailing slashes and so forth matter. + + #py_files = map(os.path.abspath, py_files) + #if prefix: + # prefix = os.path.abspath(prefix) + + script.write(string.join(map(repr, py_files), ",\n") + "]\n") + script.write(""" +byte_compile(files, optimize=%s, force=%s, + prefix=%s, base_dir=%s, + verbose=%s, dry_run=0, + direct=1) +""" % (`optimize`, `force`, `prefix`, `base_dir`, `verbose`)) + + script.close() + + cmd = [sys.executable, script_name] + if optimize == 1: + cmd.insert(1, "-O") + elif optimize == 2: + cmd.insert(1, "-OO") + spawn(cmd, dry_run=dry_run) + execute(os.remove, (script_name,), "removing %s" % script_name, + dry_run=dry_run) + + # "Direct" byte-compilation: use the py_compile module to compile + # right here, right now. Note that the script generated in indirect + # mode simply calls 'byte_compile()' in direct mode, a weird sort of + # cross-process recursion. Hey, it works! + else: + from py_compile import compile + + for file in py_files: + if file[-3:] != ".py": + # This lets us be lazy and not filter filenames in + # the "install_lib" command. + continue + + # Terminology from the py_compile module: + # cfile - byte-compiled file + # dfile - purported source filename (same as 'file' by default) + cfile = file + (__debug__ and "c" or "o") + dfile = file + if prefix: + if file[:len(prefix)] != prefix: + raise ValueError, \ + ("invalid prefix: filename %s doesn't start with %s" + % (`file`, `prefix`)) + dfile = dfile[len(prefix):] + if base_dir: + dfile = os.path.join(base_dir, dfile) + + cfile_base = os.path.basename(cfile) + if direct: + if force or newer(file, cfile): + log.info("byte-compiling %s to %s", file, cfile_base) + if not dry_run: + compile(file, cfile, dfile) + else: + log.debug("skipping byte-compilation of %s to %s", + file, cfile_base) + +# byte_compile () + +def rfc822_escape (header): + """Return a version of the string escaped for inclusion in an + RFC-822 header, by ensuring there are 8 spaces space after each newline. + """ + lines = string.split(header, '\n') + lines = map(string.strip, lines) + header = string.join(lines, '\n' + 8*' ') + return header diff --git a/wxPython/distutils/version.py b/wxPython/distutils/version.py new file mode 100644 index 0000000000..71a5614719 --- /dev/null +++ b/wxPython/distutils/version.py @@ -0,0 +1,299 @@ +# +# distutils/version.py +# +# Implements multiple version numbering conventions for the +# Python Module Distribution Utilities. +# +# $Id$ +# + +"""Provides classes to represent module version numbers (one class for +each style of version numbering). There are currently two such classes +implemented: StrictVersion and LooseVersion. + +Every version number class implements the following interface: + * the 'parse' method takes a string and parses it to some internal + representation; if the string is an invalid version number, + 'parse' raises a ValueError exception + * the class constructor takes an optional string argument which, + if supplied, is passed to 'parse' + * __str__ reconstructs the string that was passed to 'parse' (or + an equivalent string -- ie. one that will generate an equivalent + version number instance) + * __repr__ generates Python code to recreate the version number instance + * __cmp__ compares the current instance with either another instance + of the same class or a string (which will be parsed to an instance + of the same class, thus must follow the same rules) +""" + +import string, re +from types import StringType + +class Version: + """Abstract base class for version numbering classes. Just provides + constructor (__init__) and reproducer (__repr__), because those + seem to be the same for all version numbering classes. + """ + + def __init__ (self, vstring=None): + if vstring: + self.parse(vstring) + + def __repr__ (self): + return "%s ('%s')" % (self.__class__.__name__, str(self)) + + +# Interface for version-number classes -- must be implemented +# by the following classes (the concrete ones -- Version should +# be treated as an abstract class). +# __init__ (string) - create and take same action as 'parse' +# (string parameter is optional) +# parse (string) - convert a string representation to whatever +# internal representation is appropriate for +# this style of version numbering +# __str__ (self) - convert back to a string; should be very similar +# (if not identical to) the string supplied to parse +# __repr__ (self) - generate Python code to recreate +# the instance +# __cmp__ (self, other) - compare two version numbers ('other' may +# be an unparsed version string, or another +# instance of your version class) + + +class StrictVersion (Version): + + """Version numbering for anal retentives and software idealists. + Implements the standard interface for version number classes as + described above. A version number consists of two or three + dot-separated numeric components, with an optional "pre-release" tag + on the end. The pre-release tag consists of the letter 'a' or 'b' + followed by a number. If the numeric components of two version + numbers are equal, then one with a pre-release tag will always + be deemed earlier (lesser) than one without. + + The following are valid version numbers (shown in the order that + would be obtained by sorting according to the supplied cmp function): + + 0.4 0.4.0 (these two are equivalent) + 0.4.1 + 0.5a1 + 0.5b3 + 0.5 + 0.9.6 + 1.0 + 1.0.4a3 + 1.0.4b1 + 1.0.4 + + The following are examples of invalid version numbers: + + 1 + 2.7.2.2 + 1.3.a4 + 1.3pl1 + 1.3c4 + + The rationale for this version numbering system will be explained + in the distutils documentation. + """ + + version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', + re.VERBOSE) + + + def parse (self, vstring): + match = self.version_re.match(vstring) + if not match: + raise ValueError, "invalid version number '%s'" % vstring + + (major, minor, patch, prerelease, prerelease_num) = \ + match.group(1, 2, 4, 5, 6) + + if patch: + self.version = tuple(map(string.atoi, [major, minor, patch])) + else: + self.version = tuple(map(string.atoi, [major, minor]) + [0]) + + if prerelease: + self.prerelease = (prerelease[0], string.atoi(prerelease_num)) + else: + self.prerelease = None + + + def __str__ (self): + + if self.version[2] == 0: + vstring = string.join(map(str, self.version[0:2]), '.') + else: + vstring = string.join(map(str, self.version), '.') + + if self.prerelease: + vstring = vstring + self.prerelease[0] + str(self.prerelease[1]) + + return vstring + + + def __cmp__ (self, other): + if isinstance(other, StringType): + other = StrictVersion(other) + + compare = cmp(self.version, other.version) + if (compare == 0): # have to compare prerelease + + # case 1: neither has prerelease; they're equal + # case 2: self has prerelease, other doesn't; other is greater + # case 3: self doesn't have prerelease, other does: self is greater + # case 4: both have prerelease: must compare them! + + if (not self.prerelease and not other.prerelease): + return 0 + elif (self.prerelease and not other.prerelease): + return -1 + elif (not self.prerelease and other.prerelease): + return 1 + elif (self.prerelease and other.prerelease): + return cmp(self.prerelease, other.prerelease) + + else: # numeric versions don't match -- + return compare # prerelease stuff doesn't matter + + +# end class StrictVersion + + +# The rules according to Greg Stein: +# 1) a version number has 1 or more numbers separate by a period or by +# sequences of letters. If only periods, then these are compared +# left-to-right to determine an ordering. +# 2) sequences of letters are part of the tuple for comparison and are +# compared lexicographically +# 3) recognize the numeric components may have leading zeroes +# +# The LooseVersion class below implements these rules: a version number +# string is split up into a tuple of integer and string components, and +# comparison is a simple tuple comparison. This means that version +# numbers behave in a predictable and obvious way, but a way that might +# not necessarily be how people *want* version numbers to behave. There +# wouldn't be a problem if people could stick to purely numeric version +# numbers: just split on period and compare the numbers as tuples. +# However, people insist on putting letters into their version numbers; +# the most common purpose seems to be: +# - indicating a "pre-release" version +# ('alpha', 'beta', 'a', 'b', 'pre', 'p') +# - indicating a post-release patch ('p', 'pl', 'patch') +# but of course this can't cover all version number schemes, and there's +# no way to know what a programmer means without asking him. +# +# The problem is what to do with letters (and other non-numeric +# characters) in a version number. The current implementation does the +# obvious and predictable thing: keep them as strings and compare +# lexically within a tuple comparison. This has the desired effect if +# an appended letter sequence implies something "post-release": +# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002". +# +# However, if letters in a version number imply a pre-release version, +# the "obvious" thing isn't correct. Eg. you would expect that +# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison +# implemented here, this just isn't so. +# +# Two possible solutions come to mind. The first is to tie the +# comparison algorithm to a particular set of semantic rules, as has +# been done in the StrictVersion class above. This works great as long +# as everyone can go along with bondage and discipline. Hopefully a +# (large) subset of Python module programmers will agree that the +# particular flavour of bondage and discipline provided by StrictVersion +# provides enough benefit to be worth using, and will submit their +# version numbering scheme to its domination. The free-thinking +# anarchists in the lot will never give in, though, and something needs +# to be done to accommodate them. +# +# Perhaps a "moderately strict" version class could be implemented that +# lets almost anything slide (syntactically), and makes some heuristic +# assumptions about non-digits in version number strings. This could +# sink into special-case-hell, though; if I was as talented and +# idiosyncratic as Larry Wall, I'd go ahead and implement a class that +# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is +# just as happy dealing with things like "2g6" and "1.13++". I don't +# think I'm smart enough to do it right though. +# +# In any case, I've coded the test suite for this module (see +# ../test/test_version.py) specifically to fail on things like comparing +# "1.2a2" and "1.2". That's not because the *code* is doing anything +# wrong, it's because the simple, obvious design doesn't match my +# complicated, hairy expectations for real-world version numbers. It +# would be a snap to fix the test suite to say, "Yep, LooseVersion does +# the Right Thing" (ie. the code matches the conception). But I'd rather +# have a conception that matches common notions about version numbers. + +class LooseVersion (Version): + + """Version numbering for anarchists and software realists. + Implements the standard interface for version number classes as + described above. A version number consists of a series of numbers, + separated by either periods or strings of letters. When comparing + version numbers, the numeric components will be compared + numerically, and the alphabetic components lexically. The following + are all valid version numbers, in no particular order: + + 1.5.1 + 1.5.2b2 + 161 + 3.10a + 8.02 + 3.4j + 1996.07.12 + 3.2.pl0 + 3.1.1.6 + 2g6 + 11g + 0.960923 + 2.2beta29 + 1.13++ + 5.5.kw + 2.0b1pl0 + + In fact, there is no such thing as an invalid version number under + this scheme; the rules for comparison are simple and predictable, + but may not always give the results you want (for some definition + of "want"). + """ + + component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE) + + def __init__ (self, vstring=None): + if vstring: + self.parse(vstring) + + + def parse (self, vstring): + # I've given up on thinking I can reconstruct the version string + # from the parsed tuple -- so I just store the string here for + # use by __str__ + self.vstring = vstring + components = filter(lambda x: x and x != '.', + self.component_re.split(vstring)) + for i in range(len(components)): + try: + components[i] = int(components[i]) + except ValueError: + pass + + self.version = components + + + def __str__ (self): + return self.vstring + + + def __repr__ (self): + return "LooseVersion ('%s')" % str(self) + + + def __cmp__ (self, other): + if isinstance(other, StringType): + other = LooseVersion(other) + + return cmp(self.version, other.version) + + +# end class LooseVersion diff --git a/wxPython/my_distutils.py b/wxPython/my_distutils.py deleted file mode 100644 index f1603f4f5f..0000000000 --- a/wxPython/my_distutils.py +++ /dev/null @@ -1,488 +0,0 @@ - -import sys, os, string - -from distutils.msvccompiler import MSVCCompiler -from distutils.bcppcompiler import BCPPCompiler - -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options - -#---------------------------------------------------------------------- - -class MyMSVCCompiler(MSVCCompiler): - -## def __init__ (self, -## verbose=0, -## dry_run=0, -## force=0): -## MSVCCompiler.__init__(self, verbose, dry_run, force) - -## self.compile_options = [ '/nologo', -## '/Ox', -## '/MD', -## '/W3', -## '/GX', -## ] -## self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', -## '/Z7', '/D_DEBUG'] - - - - - ##------------------------------------------------------------ - ## Override the entire compile method just to add flags to the - ## RC command. There should be an easier way to do this from - ## distutils directly or in a derived class... - ##------------------------------------------------------------ - - def compile (self, - sources, - output_dir=None, - macros=None, - include_dirs=None, - debug=0, - extra_preargs=None, - extra_postargs=None): - - (output_dir, macros, include_dirs) = \ - self._fix_compile_args (output_dir, macros, include_dirs) - (objects, skip_sources) = self._prep_compile (sources, output_dir) - - if extra_postargs is None: - extra_postargs = [] - - pp_opts = gen_preprocess_options (macros, include_dirs) - compile_opts = extra_preargs or [] - compile_opts.append ('/c') - if debug: - compile_opts.extend (self.compile_options_debug) - else: - compile_opts.extend (self.compile_options) - - for i in range (len (sources)): - src = sources[i] ; obj = objects[i] - ext = (os.path.splitext (src))[1] - - if skip_sources[src]: - self.announce ("skipping %s (%s up-to-date)" % (src, obj)) - else: - self.mkpath (os.path.dirname (obj)) - - if ext in self._c_extensions: - input_opt = "/Tc" + os.path.abspath(src) ### RPD - elif ext in self._cpp_extensions: - input_opt = "/Tp" + os.path.abspath(src) ### RPD - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn ([self.rc] + pp_opts + ### RPD changed this line - [output_opt] + [input_opt]) - except DistutilsExecError, msg: - raise CompileError, msg - continue - elif ext in self._mc_extensions: - - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - - h_dir = os.path.dirname (src) - rc_dir = os.path.dirname (obj) - try: - # first compile .MC to .RC and .H file - self.spawn ([self.mc] + - ['-h', h_dir, '-r', rc_dir] + [src]) - base, _ = os.path.splitext (os.path.basename (src)) - rc_file = os.path.join (rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn ([self.rc] + - ["/fo" + obj] + [rc_file]) - - except DistutilsExecError, msg: - raise CompileError, msg - continue - else: - # how to handle this file? - raise CompileError ( - "Don't know how to compile %s to %s" % \ - (src, obj)) - - output_opt = "/Fo" + obj - try: - self.spawn ([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs) - except DistutilsExecError, msg: - raise CompileError, msg - - return objects - - # compile () - - - -from distutils.file_util import write_file -class MyBCPPCompiler(BCPPCompiler): - - ##------------------------------------------------------------ - ## Override the entire compile method just to add flags to the - ## RC command. There should be an easier way to do this from - ## distutils directly or in a derived class... - ##------------------------------------------------------------ - - def compile (self, - sources, - output_dir=None, - macros=None, - include_dirs=None, - debug=0, - extra_preargs=None, - extra_postargs=None): - - (output_dir, macros, include_dirs) = \ - self._fix_compile_args (output_dir, macros, include_dirs) - (objects, skip_sources) = self._prep_compile (sources, output_dir) - - if extra_postargs is None: - extra_postargs = [] - - pp_opts = gen_preprocess_options (macros, include_dirs) - compile_opts = extra_preargs or [] - compile_opts.append ('-c') - if debug: - compile_opts.extend (self.compile_options_debug) - else: - compile_opts.extend (self.compile_options) - - for i in range (len (sources)): - src = sources[i] ; obj = objects[i] - ext = (os.path.splitext (src))[1] - - if skip_sources[src]: - self.announce ("skipping %s (%s up-to-date)" % (src, obj)) - else: - src = os.path.normpath(src) - obj = os.path.normpath(obj) - self.mkpath(os.path.dirname(obj)) - - if ext == '.res': - # This is already a binary file -- skip it. - continue # the 'for' loop - if ext == '.rc': - # This needs to be compiled to a .res file -- do it now. - try: - self.spawn (["brcc32"] + pp_opts + ["-fo"] + - [obj] + [src]) ### RPD changed this lines only - except DistutilsExecError, msg: - raise CompileError, msg - continue # the 'for' loop - - # The next two are both for the real compiler. - if ext in self._c_extensions: - input_opt = "" - elif ext in self._cpp_extensions: - input_opt = "-P" - else: - # Unknown file type -- no extra options. The compiler - # will probably fail, but let it just in case this is a - # file the compiler recognizes even if we don't. - input_opt = "" - - output_opt = "-o" + obj - - # Compiler command line syntax is: "bcc32 [options] file(s)". - # Note that the source file names must appear at the end of - # the command line. - try: - self.spawn ([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs + [src]) - except DistutilsExecError, msg: - raise CompileError, msg - - return objects - - # compile () - - #################################################################### - # Now we need to replace cw32mt library used by default by distutils - # with cw32mti library as in wxWindows DLL make file - # Othervise we obtain Windows "Core dump" ;-). - # - # Evgeny A Cherkashin - # - #################################################################### - - def link (self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None): - - # XXX this ignores 'build_temp'! should follow the lead of - # msvccompiler.py - - (objects, output_dir) = self._fix_object_args (objects, output_dir) - (libraries, library_dirs, runtime_library_dirs) = \ - self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) - - if runtime_library_dirs: - self.warn ("I don't know what to do with 'runtime_library_dirs': " - + str (runtime_library_dirs)) - - if output_dir is not None: - output_filename = os.path.join (output_dir, output_filename) - - if self._need_link (objects, output_filename): - - # Figure out linker args based on type of target. - if target_desc == CCompiler.EXECUTABLE: - startup_obj = 'c0w32' - if debug: - ld_args = self.ldflags_exe_debug[:] - else: - ld_args = self.ldflags_exe[:] - else: - startup_obj = 'c0d32' - if debug: - ld_args = self.ldflags_shared_debug[:] - else: - ld_args = self.ldflags_shared[:] - - - # Create a temporary exports file for use by the linker - if export_symbols is None: - def_file = '' - else: - head, tail = os.path.split (output_filename) - modname, ext = os.path.splitext (tail) - temp_dir = os.path.dirname(objects[0]) # preserve tree structure - def_file = os.path.join (temp_dir, '%s.def' % modname) - contents = ['EXPORTS'] - for sym in (export_symbols or []): - contents.append(' %s=_%s' % (sym, sym)) - self.execute(write_file, (def_file, contents), - "writing %s" % def_file) - - # Borland C++ has problems with '/' in paths - objects2 = map(os.path.normpath, objects) - # split objects in .obj and .res files - # Borland C++ needs them at different positions in the command line - objects = [startup_obj] - resources = [] - for file in objects2: - (base, ext) = os.path.splitext(os.path.normcase(file)) - if ext == '.res': - resources.append(file) - else: - objects.append(file) - - - for l in library_dirs: - ld_args.append("/L%s" % os.path.normpath(l)) - ld_args.append("/L.") # we sometimes use relative paths - - # list of object files - ld_args.extend(objects) - - # XXX the command-line syntax for Borland C++ is a bit wonky; - # certain filenames are jammed together in one big string, but - # comma-delimited. This doesn't mesh too well with the - # Unix-centric attitude (with a DOS/Windows quoting hack) of - # 'spawn()', so constructing the argument list is a bit - # awkward. Note that doing the obvious thing and jamming all - # the filenames and commas into one argument would be wrong, - # because 'spawn()' would quote any filenames with spaces in - # them. Arghghh!. Apparently it works fine as coded... - - # name of dll/exe file - ld_args.extend([',',output_filename]) - # no map file and start libraries - ld_args.append(',,') - - for lib in libraries: - # see if we find it and if there is a bcpp specific lib - # (xxx_bcpp.lib) - libfile = self.find_library_file(library_dirs, lib, debug) - if libfile is None: - ld_args.append(lib) - # probably a BCPP internal library -- don't warn - # self.warn('library %s not found.' % lib) - else: - # full name which prefers bcpp_xxx.lib over xxx.lib - ld_args.append(libfile) - - # some default libraries - ld_args.append ('import32') - ld_args.append ('cw32mti') ### mt->mti (as in wx2) - - # def file for export symbols - ld_args.extend([',',def_file]) - # add resource files - ld_args.append(',') - ld_args.extend(resources) - - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath (os.path.dirname (output_filename)) - try: - self.spawn ([self.linker] + ld_args) - except DistutilsExecError, msg: - raise LinkError, msg - - else: - self.announce ("skipping %s (up-to-date)" % output_filename) - - # link () - - - -#---------------------------------------------------------------------- -# Hack this module and class into the distutils... - -from distutils import ccompiler - -if hasattr(ccompiler, "default_compiler"): - ccompiler.default_compiler['nt'] = 'my_msvc' -elif hasattr(ccompiler, "_default_compilers"): - lst = list(ccompiler._default_compilers) - lst.remove( ('nt', 'msvc') ) - lst.append( ('nt', 'my_msvc') ) - ccompiler._default_compilers = tuple(lst) - - -ccompiler.compiler_class['my_msvc'] = ('my_distutils', - 'MyMSVCCompiler', - 'My MSVC derived class') - - -ccompiler.compiler_class['my_bcpp'] = ('my_distutils', - 'MyBCPPCompiler', - 'My BCPP derived class') - -# make it look like it is part of the package... -import my_distutils -sys.modules['distutils.my_distutils'] = my_distutils - - -#---------------------------------------------------------------------- -# More hacking... Distutils in Python 2.1 changed the strip_dir flag -# passed to object_filenames to true, which causes problems for us since -# there are a few duplicate source/object names between some of the -# extensions in wxPython. This hack replaces the CCompiler._prep_compile -# method with this one. - -from distutils.dep_util import newer_pairwise - -def _prep_compile (self, sources, output_dir): - """Determine the list of object files corresponding to 'sources', - and figure out which ones really need to be recompiled. Return a - list of all object files and a dictionary telling which source - files can be skipped. - """ - # Get the list of expected output (object) files - objects = self.object_filenames (sources, - strip_dir=0, - output_dir=output_dir) - - if self.force: - skip_source = {} # rebuild everything - for source in sources: - skip_source[source] = 0 - else: - # Figure out which source files we have to recompile according - # to a simplistic check -- we just compare the source and - # object file, no deep dependency checking involving header - # files. - skip_source = {} # rebuild everything - for source in sources: # no wait, rebuild nothing - skip_source[source] = 1 - - (n_sources, n_objects) = newer_pairwise (sources, objects) - for source in n_sources: # no really, only rebuild what's - skip_source[source] = 0 # out-of-date - - return (objects, skip_source) - -# _prep_compile () - -CCompiler._prep_compile = _prep_compile - - - - -#---------------------------------------------------------------------- -# Run SWIG the way I want it done - -def run_swig(files, dir, gendir, package, USE_SWIG, force, swig_args, swig_deps=[]): - from distutils.file_util import copy_file - from distutils.dep_util import newer - from distutils.spawn import spawn - - sources = [] - - for file in files: - basefile = os.path.splitext(file)[0] - i_file = os.path.join(dir, file) - py_file = os.path.join(dir, gendir, basefile+'.py') - cpp_file = os.path.join(dir, gendir, basefile+'.cpp') - - sources.append(cpp_file) - - if USE_SWIG: - for dep in swig_deps: - if newer(dep, py_file) or newer(dep, cpp_file): - force = 1 - break - - if force or newer(i_file, py_file) or newer(i_file, cpp_file): - # we need forward slashes here even on win32 - cpp_file = string.join(string.split(cpp_file, '\\'), '/') - i_file = string.join(string.split(i_file, '\\'), '/') - - cmd = ['./wxSWIG/wxswig'] + swig_args + ['-I'+dir, '-c', '-o', cpp_file, i_file] - spawn(cmd, verbose=1) - - # copy the generated python file to the package directory - copy_file(py_file, package, update=not force, verbose=0) - - - return sources - - - -#---------------------------------------------------------------------- -# Update local copies of wxWindows contrib files - - -def contrib_copy_tree(src, dest, verbose=0): - from distutils.dir_util import mkpath, copy_tree - - mkpath(dest, verbose=verbose) - copy_tree(src, dest, update=1, verbose=verbose) - diff --git a/wxPython/samples/StyleEditor/STCStyleEditor.py b/wxPython/samples/StyleEditor/STCStyleEditor.py index 74a39d168c..9758734401 100644 --- a/wxPython/samples/StyleEditor/STCStyleEditor.py +++ b/wxPython/samples/StyleEditor/STCStyleEditor.py @@ -6,7 +6,7 @@ # # Created: 2001/08/20 # RCS-ID: $Id$ -# Copyright: (c) 2001 Riaan Booysen +# Copyright: (c) 2001 - 2002 Riaan Booysen # Licence: wxWindows license #----------------------------------------------------------------------------- #Boa:Dialog:STCStyleEditDlg @@ -53,6 +53,7 @@ Use the initSTC function to initialise your wxSTC from a config file. import os, sys, string, pprint, copy from wxPython.wx import * +from wxPython.help import * from wxPython.lib.anchors import LayoutAnchors from wxPython.stc import * @@ -62,170 +63,336 @@ commonPropDefs = {'fore': '#888888', 'size': 8, 'face': wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT).GetFaceName()} styleCategoryDescriptions = { -'-----Language-----': 'Styles spesific to the language', -'-----Standard-----': 'Styles shared by all languages', -'-----Settings-----': 'Properties set by STC methods', -'-----Common-----': 'User definable values that can be shared between languages'} - -[wxID_STCSTYLEEDITDLG, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN, wxID_STCSTYLEEDITDLGBGCOLBTN, wxID_STCSTYLEEDITDLGBGCOLCB, wxID_STCSTYLEEDITDLGBGCOLDEFCB, wxID_STCSTYLEEDITDLGCANCELBTN, wxID_STCSTYLEEDITDLGCOMMONDEFSBTN, wxID_STCSTYLEEDITDLGELEMENTLB, wxID_STCSTYLEEDITDLGFACECB, wxID_STCSTYLEEDITDLGFACEDEFCB, wxID_STCSTYLEEDITDLGFGCOLBTN, wxID_STCSTYLEEDITDLGFGCOLCB, wxID_STCSTYLEEDITDLGFGCOLDEFCB, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, wxID_STCSTYLEEDITDLGOKBTN, wxID_STCSTYLEEDITDLGPANEL1, wxID_STCSTYLEEDITDLGPANEL2, wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, wxID_STCSTYLEEDITDLGSIZECB, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, wxID_STCSTYLEEDITDLGSTATICBOX1, wxID_STCSTYLEEDITDLGSTATICBOX2, wxID_STCSTYLEEDITDLGSTATICLINE1, wxID_STCSTYLEEDITDLGSTATICTEXT2, wxID_STCSTYLEEDITDLGSTATICTEXT3, wxID_STCSTYLEEDITDLGSTATICTEXT4, wxID_STCSTYLEEDITDLGSTATICTEXT6, wxID_STCSTYLEEDITDLGSTATICTEXT7, wxID_STCSTYLEEDITDLGSTATICTEXT8, wxID_STCSTYLEEDITDLGSTATICTEXT9, wxID_STCSTYLEEDITDLGSTC, wxID_STCSTYLEEDITDLGSTYLEDEFST, wxID_STCSTYLEEDITDLGTABOLDCB, wxID_STCSTYLEEDITDLGTABOLDDEFCB, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB, wxID_STCSTYLEEDITDLGTAITALICCB, wxID_STCSTYLEEDITDLGTAITALICDEFCB, wxID_STCSTYLEEDITDLGTASIZEDEFCB, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB, wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB] = map(lambda _init_ctrls: wxNewId(), range(41)) + '----Language----': 'Styles spesific to the language', + '----Standard----': 'Styles shared by all languages', + '----Settings----': 'Properties set by STC methods', + '----Common----': 'User definable values that can be shared between languages'} + +[wxID_STCSTYLEEDITDLG, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN, + wxID_STCSTYLEEDITDLGBGCOLBTN, wxID_STCSTYLEEDITDLGBGCOLCB, + wxID_STCSTYLEEDITDLGBGCOLDEFCB, wxID_STCSTYLEEDITDLGBGCOLOKBTN, + wxID_STCSTYLEEDITDLGCANCELBTN, wxID_STCSTYLEEDITDLGCONTEXTHELPBUTTON1, + wxID_STCSTYLEEDITDLGELEMENTLB, wxID_STCSTYLEEDITDLGFACECB, + wxID_STCSTYLEEDITDLGFACEDEFCB, wxID_STCSTYLEEDITDLGFACEOKBTN, + wxID_STCSTYLEEDITDLGFGCOLBTN, wxID_STCSTYLEEDITDLGFGCOLCB, + wxID_STCSTYLEEDITDLGFGCOLDEFCB, wxID_STCSTYLEEDITDLGFGCOLOKBTN, + wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, wxID_STCSTYLEEDITDLGOKBTN, + wxID_STCSTYLEEDITDLGPANEL1, wxID_STCSTYLEEDITDLGPANEL2, + wxID_STCSTYLEEDITDLGPANEL3, wxID_STCSTYLEEDITDLGPANEL4, + wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, wxID_STCSTYLEEDITDLGSIZECB, + wxID_STCSTYLEEDITDLGSIZEOKBTN, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, + wxID_STCSTYLEEDITDLGSTATICBOX1, wxID_STCSTYLEEDITDLGSTATICBOX2, + wxID_STCSTYLEEDITDLGSTATICLINE1, wxID_STCSTYLEEDITDLGSTATICTEXT2, + wxID_STCSTYLEEDITDLGSTATICTEXT3, wxID_STCSTYLEEDITDLGSTATICTEXT4, + wxID_STCSTYLEEDITDLGSTATICTEXT6, wxID_STCSTYLEEDITDLGSTATICTEXT7, + wxID_STCSTYLEEDITDLGSTATICTEXT8, wxID_STCSTYLEEDITDLGSTATICTEXT9, + wxID_STCSTYLEEDITDLGSTC, wxID_STCSTYLEEDITDLGSTYLEDEFST, + wxID_STCSTYLEEDITDLGTABOLDCB, wxID_STCSTYLEEDITDLGTABOLDDEFCB, + wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB, + wxID_STCSTYLEEDITDLGTAITALICCB, wxID_STCSTYLEEDITDLGTAITALICDEFCB, + wxID_STCSTYLEEDITDLGTASIZEDEFCB, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB, + wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB, +] = map(lambda _init_ctrls: wxNewId(), range(47)) class STCStyleEditDlg(wxDialog): """ Style editor for the wxStyledTextCtrl """ _custom_classes = {'wxWindow' : ['wxStyledTextCtrl']} def _init_utils(self): + # generated method, don't edit pass def _init_ctrls(self, prnt): - wxDialog.__init__(self, id = wxID_STCSTYLEEDITDLG, name = 'STCStyleEditDlg', parent = prnt, pos = wxPoint(416, 307), size = wxSize(425, 481), style = wxWANTS_CHARS | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER, title = self.stc_title) + # generated method, don't edit + wxDialog.__init__(self, id=wxID_STCSTYLEEDITDLG, name='STCStyleEditDlg', + parent=prnt, pos=wxPoint(583, 291), size=wxSize(459, 482), + style=wxWANTS_CHARS | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER, + title=self.stc_title) self._init_utils() - self.SetClientSize(wxSize(417, 454)) - self.SetAutoLayout(true) + self.SetClientSize(wxSize(451, 455)) + self.SetAutoLayout(True) self.SetSizeHints(425, 400, -1, -1) + self.Center(wxBOTH) EVT_SIZE(self, self.OnStcstyleeditdlgSize) - self.staticBox2 = wxStaticBox(id = wxID_STCSTYLEEDITDLGSTATICBOX2, label = 'Text attributes', name = 'staticBox2', parent = self, pos = wxPoint(296, 56), size = wxSize(112, 99), style = 0) - self.staticBox2.SetConstraints(LayoutAnchors(self.staticBox2, false, true, true, false)) - - self.staticBox1 = wxStaticBox(id = wxID_STCSTYLEEDITDLGSTATICBOX1, label = 'Colour', name = 'staticBox1', parent = self, pos = wxPoint(157, 56), size = wxSize(128, 99), style = 0) - self.staticBox1.SetConstraints(LayoutAnchors(self.staticBox1, false, true, true, false)) - - self.elementLb = wxListBox(choices = [], id = wxID_STCSTYLEEDITDLGELEMENTLB, name = 'elementLb', parent = self, pos = wxPoint(8, 72), size = wxSize(144, 112), style = 0, validator = wxDefaultValidator) - self.elementLb.SetConstraints(LayoutAnchors(self.elementLb, true, true, true, false)) - EVT_LISTBOX(self.elementLb, wxID_STCSTYLEEDITDLGELEMENTLB, self.OnElementlbListbox) - - self.styleDefST = wxStaticText(id = wxID_STCSTYLEEDITDLGSTYLEDEFST, label = '(nothing selected)', name = 'styleDefST', parent = self, pos = wxPoint(56, 8), size = wxSize(352, 16), style = wxST_NO_AUTORESIZE) - self.styleDefST.SetFont(wxFont(8, wxSWISS, wxNORMAL, wxBOLD, false, self.sys_font)) - self.styleDefST.SetConstraints(LayoutAnchors(self.styleDefST, true, true, true, false)) - - self.taEOLfilledCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, label = 'EOL filled', name = 'taEOLfilledCb', parent = self.staticBox2, pos = wxPoint(8, 75), size = wxSize(72, 16), style = 0) - self.taEOLfilledCb.SetValue(false) - EVT_CHECKBOX(self.taEOLfilledCb, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, self.OnTaeoffilledcbCheckbox) - - self.staticText2 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT2, label = 'default', name = 'staticText2', parent = self.staticBox2, pos = wxPoint(72, 11), size = wxSize(32, 16), style = 0) - - self.taItalicCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTAITALICCB, label = 'Italic', name = 'taItalicCb', parent = self.staticBox2, pos = wxPoint(8, 43), size = wxSize(72, 16), style = 0) - EVT_CHECKBOX(self.taItalicCb, wxID_STCSTYLEEDITDLGTAITALICCB, self.OnTaitaliccbCheckbox) - - self.taUnderlinedDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB, label = 'checkBox1', name = 'taUnderlinedDefCb', parent = self.staticBox2, pos = wxPoint(88, 59), size = wxSize(16, 16), style = 0) - - self.taBoldDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTABOLDDEFCB, label = 'checkBox1', name = 'taBoldDefCb', parent = self.staticBox2, pos = wxPoint(88, 27), size = wxSize(16, 16), style = 0) - - self.taItalicDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTAITALICDEFCB, label = 'checkBox1', name = 'taItalicDefCb', parent = self.staticBox2, pos = wxPoint(88, 43), size = wxSize(16, 16), style = 0) - - self.taBoldCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTABOLDCB, label = 'Bold', name = 'taBoldCb', parent = self.staticBox2, pos = wxPoint(8, 27), size = wxSize(72, 16), style = 0) - EVT_CHECKBOX(self.taBoldCb, wxID_STCSTYLEEDITDLGTABOLDCB, self.OnTaboldcbCheckbox) - - self.taEOLfilledDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB, label = 'checkBox1', name = 'taEOLfilledDefCb', parent = self.staticBox2, pos = wxPoint(88, 75), size = wxSize(16, 16), style = 0) - - self.taUnderlinedCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTAUNDERLINEDCB, label = 'Underlined', name = 'taUnderlinedCb', parent = self.staticBox2, pos = wxPoint(8, 59), size = wxSize(72, 16), style = 0) - EVT_CHECKBOX(self.taUnderlinedCb, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB, self.OnTaunderlinedcbCheckbox) - - self.fgColDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGFGCOLDEFCB, label = 'checkBox1', name = 'fgColDefCb', parent = self.staticBox1, pos = wxPoint(104, 31), size = wxSize(16, 16), style = 0) - - self.staticText3 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT3, label = 'default', name = 'staticText3', parent = self.staticBox1, pos = wxPoint(88, 16), size = wxSize(32, 16), style = 0) - - self.bgColDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGBGCOLDEFCB, label = 'checkBox1', name = 'bgColDefCb', parent = self.staticBox1, pos = wxPoint(104, 71), size = wxSize(16, 16), style = 0) - - self.fgColBtn = wxButton(id = wxID_STCSTYLEEDITDLGFGCOLBTN, label = 'Foreground', name = 'fgColBtn', parent = self.staticBox1, pos = wxPoint(8, 16), size = wxSize(72, 16), style = 0) - EVT_BUTTON(self.fgColBtn, wxID_STCSTYLEEDITDLGFGCOLBTN, self.OnFgcolbtnButton) - - self.bgColBtn = wxButton(id = wxID_STCSTYLEEDITDLGBGCOLBTN, label = 'Background', name = 'bgColBtn', parent = self.staticBox1, pos = wxPoint(8, 56), size = wxSize(72, 16), style = 0) - EVT_BUTTON(self.bgColBtn, wxID_STCSTYLEEDITDLGBGCOLBTN, self.OnBgcolbtnButton) + self.speedsettingCh = wxChoice(choices=[], + id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, name='speedsettingCh', + parent=self, pos=wxPoint(96, 28), size=wxSize(346, 21), style=0, + validator=wxDefaultValidator) + self.speedsettingCh.SetConstraints(LayoutAnchors(self.speedsettingCh, + True, True, True, False)) + self.speedsettingCh.SetHelpText('The speed setting allows you to revert to one of the predefined style sets. This will overwrite your current settings when tha dialog is posted.') + EVT_CHOICE(self.speedsettingCh, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, + self.OnSpeedsettingchChoice) + + self.elementLb = wxListBox(choices=[], id=wxID_STCSTYLEEDITDLGELEMENTLB, + name='elementLb', parent=self, pos=wxPoint(8, 72), + size=wxSize(160, 112), style=0, validator=wxDefaultValidator) + self.elementLb.SetConstraints(LayoutAnchors(self.elementLb, True, True, + True, False)) + self.elementLb.SetHelpText('Select a style here to edit it. Common definitions can be added and maintained here. A common definition is a property that can be shared between styles and special cased per platform.') + EVT_LISTBOX(self.elementLb, wxID_STCSTYLEEDITDLGELEMENTLB, + self.OnElementlbListbox) + + self.addCommonItemBtn = wxButton(id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN, + label='Add', name='addCommonItemBtn', parent=self, pos=wxPoint(8, + 184), size=wxSize(80, 17), style=0) + self.addCommonItemBtn.SetToolTipString('Add new Common definition') + EVT_BUTTON(self.addCommonItemBtn, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN, + self.OnAddsharebtnButton) - self.staticLine1 = wxStaticLine(id = wxID_STCSTYLEEDITDLGSTATICLINE1, name = 'staticLine1', parent = self, pos = wxPoint(36, 62), size = wxSize(115, 2), style = wxLI_HORIZONTAL) - self.staticLine1.SetConstraints(LayoutAnchors(self.staticLine1, true, true, true, false)) + self.removeCommonItemBtn = wxButton(id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, + label='Remove', name='removeCommonItemBtn', parent=self, + pos=wxPoint(88, 184), size=wxSize(80, 17), style=0) + self.removeCommonItemBtn.SetToolTipString('Remove the selected Common definition') + EVT_BUTTON(self.removeCommonItemBtn, + wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, + self.OnRemovesharebtnButton) + + self.styleDefST = wxStaticText(id=wxID_STCSTYLEEDITDLGSTYLEDEFST, + label='(nothing selected)', name='styleDefST', parent=self, + pos=wxPoint(96, 8), size=wxSize(366, 16), + style=wxST_NO_AUTORESIZE) + self.styleDefST.SetFont(wxFont(self.style_font_size, wxSWISS, wxNORMAL, + wxBOLD, False, '')) + self.styleDefST.SetConstraints(LayoutAnchors(self.styleDefST, True, + True, True, False)) + + self.staticLine1 = wxStaticLine(id=wxID_STCSTYLEEDITDLGSTATICLINE1, + name='staticLine1', parent=self, pos=wxPoint(48, 62), + size=wxSize(120, 2), style=wxLI_HORIZONTAL) + self.staticLine1.SetConstraints(LayoutAnchors(self.staticLine1, True, + True, True, False)) + + self.staticText6 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT6, + label='Style', name='staticText6', parent=self, pos=wxPoint(8, + 56), size=wxSize(40, 13), style=0) + + self.staticText8 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT8, + label='Style def:', name='staticText8', parent=self, + pos=wxPoint(8, 8), size=wxSize(88, 13), style=0) + + self.staticText9 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT9, + label='SpeedSetting:', name='staticText9', parent=self, + pos=wxPoint(8, 32), size=wxSize(88, 13), style=0) + + self.panel3 = wxPanel(id=wxID_STCSTYLEEDITDLGPANEL3, name='panel3', + parent=self, pos=wxPoint(176, 56), size=wxSize(146, 104), + style=wxTAB_TRAVERSAL) + self.panel3.SetConstraints(LayoutAnchors(self.panel3, False, True, True, + False)) + + self.panel4 = wxPanel(id=wxID_STCSTYLEEDITDLGPANEL4, name='panel4', + parent=self, pos=wxPoint(330, 56), size=wxSize(114, 104), + style=wxTAB_TRAVERSAL) + self.panel4.SetConstraints(LayoutAnchors(self.panel4, False, True, True, + False)) + + self.panel1 = wxPanel(id=wxID_STCSTYLEEDITDLGPANEL1, name='panel1', + parent=self, pos=wxPoint(176, 161), size=wxSize(143, 40), + style=wxTAB_TRAVERSAL) + self.panel1.SetConstraints(LayoutAnchors(self.panel1, False, True, True, + False)) + + self.panel2 = wxPanel(id=wxID_STCSTYLEEDITDLGPANEL2, name='panel2', + parent=self, pos=wxPoint(330, 162), size=wxSize(112, 40), + style=wxTAB_TRAVERSAL) + self.panel2.SetConstraints(LayoutAnchors(self.panel2, False, True, True, + False)) + + self.stc = wxStyledTextCtrl(id=wxID_STCSTYLEEDITDLGSTC, name='stc', + parent=self, pos=wxPoint(8, 208), size=wxSize(435, 207), + style=wxSUNKEN_BORDER) + self.stc.SetConstraints(LayoutAnchors(self.stc, True, True, True, True)) + self.stc.SetHelpText('The style preview window. Click or move the cursor over a spesific style to select the style for editing in the editors above.') + EVT_LEFT_UP(self.stc, self.OnUpdateUI) + EVT_KEY_UP(self.stc, self.OnUpdateUI) - self.staticText6 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT6, label = 'Style', name = 'staticText6', parent = self, pos = wxPoint(8, 56), size = wxSize(23, 13), style = 0) + self.contextHelpButton1 = wxContextHelpButton(parent=self, + pos=wxPoint(8, 423), size=wxSize(24, 24), style=wxBU_AUTODRAW) + self.contextHelpButton1.SetConstraints(LayoutAnchors(self.contextHelpButton1, + True, False, False, True)) - self.okBtn = wxButton(id = wxID_STCSTYLEEDITDLGOKBTN, label = 'OK', name = 'okBtn', parent = self, pos = wxPoint(248, 422), size = wxSize(75, 23), style = 0) - self.okBtn.SetConstraints(LayoutAnchors(self.okBtn, false, false, true, true)) + self.okBtn = wxButton(id=wxID_STCSTYLEEDITDLGOKBTN, label='OK', + name='okBtn', parent=self, pos=wxPoint(282, 423), size=wxSize(75, + 23), style=0) + self.okBtn.SetConstraints(LayoutAnchors(self.okBtn, False, False, True, + True)) self.okBtn.SetToolTipString('Save changes to the config file') EVT_BUTTON(self.okBtn, wxID_STCSTYLEEDITDLGOKBTN, self.OnOkbtnButton) - self.cancelBtn = wxButton(id = wxID_STCSTYLEEDITDLGCANCELBTN, label = 'Cancel', name = 'cancelBtn', parent = self, pos = wxPoint(332, 422), size = wxSize(75, 23), style = 0) - self.cancelBtn.SetConstraints(LayoutAnchors(self.cancelBtn, false, false, true, true)) + self.cancelBtn = wxButton(id=wxID_STCSTYLEEDITDLGCANCELBTN, + label='Cancel', name='cancelBtn', parent=self, pos=wxPoint(366, + 423), size=wxSize(75, 23), style=0) + self.cancelBtn.SetConstraints(LayoutAnchors(self.cancelBtn, False, + False, True, True)) self.cancelBtn.SetToolTipString('Close dialog without saving changes') - EVT_BUTTON(self.cancelBtn, wxID_STCSTYLEEDITDLGCANCELBTN, self.OnCancelbtnButton) - - self.commonDefsBtn = wxButton(id = wxID_STCSTYLEEDITDLGCOMMONDEFSBTN, label = 'Common definitions', name = 'commonDefsBtn', parent = self, pos = wxPoint(8, 422), size = wxSize(104, 23), style = 0) - self.commonDefsBtn.SetConstraints(LayoutAnchors(self.commonDefsBtn, true, false, false, true)) - self.commonDefsBtn.SetToolTipString('Directly edit the common definitions dictionary') - self.commonDefsBtn.Show(false) - EVT_BUTTON(self.commonDefsBtn, wxID_STCSTYLEEDITDLGCOMMONDEFSBTN, self.OnCommondefsbtnButton) + EVT_BUTTON(self.cancelBtn, wxID_STCSTYLEEDITDLGCANCELBTN, + self.OnCancelbtnButton) - self.staticText8 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT8, label = 'Style def:', name = 'staticText8', parent = self, pos = wxPoint(8, 8), size = wxSize(44, 13), style = 0) + self.staticText4 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT4, + label='Face:', name='staticText4', parent=self.panel1, + pos=wxPoint(0, 0), size=wxSize(48, 13), style=0) - self.staticText9 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT9, label = 'SpeedSetting:', name = 'staticText9', parent = self, pos = wxPoint(8, 32), size = wxSize(67, 13), style = 0) - - self.speedsettingCh = wxChoice(choices = [], id = wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, name = 'speedsettingCh', parent = self, pos = wxPoint(88, 28), size = wxSize(320, 21), style = 0, validator = wxDefaultValidator) - self.speedsettingCh.SetConstraints(LayoutAnchors(self.speedsettingCh, true, true, true, false)) - EVT_CHOICE(self.speedsettingCh, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, self.OnSpeedsettingchChoice) - - self.stc = wxStyledTextCtrl(id = wxID_STCSTYLEEDITDLGSTC, name = 'stc', parent = self, pos = wxPoint(8, 208), size = wxSize(401, 206), style = wxSUNKEN_BORDER) - self.stc.SetConstraints(LayoutAnchors(self.stc, true, true, true, true)) - EVT_LEFT_UP(self.stc, self.OnUpdateUI) - EVT_KEY_UP(self.stc, self.OnUpdateUI) - - self.panel1 = wxPanel(id = wxID_STCSTYLEEDITDLGPANEL1, name = 'panel1', parent = self, pos = wxPoint(157, 161), size = wxSize(128, 40), style = wxTAB_TRAVERSAL) - self.panel1.SetConstraints(LayoutAnchors(self.panel1, false, true, true, false)) - - self.staticText4 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT4, label = 'Face:', name = 'staticText4', parent = self.panel1, pos = wxPoint(0, 0), size = wxSize(27, 13), style = 0) - - self.faceDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGFACEDEFCB, label = 'checkBox1', name = 'faceDefCb', parent = self.panel1, pos = wxPoint(104, 0), size = wxSize(16, 16), style = 0) - - self.fixedWidthChk = wxCheckBox(id = wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, label = '', name = 'fixedWidthChk', parent = self.panel1, pos = wxPoint(0, 23), size = wxSize(13, 19), style = 0) - self.fixedWidthChk.SetValue(false) + self.fixedWidthChk = wxCheckBox(id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, + label='', name='fixedWidthChk', parent=self.panel1, pos=wxPoint(0, + 23), size=wxSize(13, 19), style=0) self.fixedWidthChk.SetToolTipString('Check this for Fixed Width fonts') - EVT_CHECKBOX(self.fixedWidthChk, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, self.OnFixedwidthchkCheckbox) - - self.addCommonItemBtn = wxButton(id = wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN, label = 'Add', name = 'addCommonItemBtn', parent = self, pos = wxPoint(8, 184), size = wxSize(72, 16), style = 0) - self.addCommonItemBtn.SetToolTipString('Add new Common definition') - EVT_BUTTON(self.addCommonItemBtn, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN, self.OnAddsharebtnButton) - - self.removeCommonItemBtn = wxButton(id = wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, label = 'Remove', name = 'removeCommonItemBtn', parent = self, pos = wxPoint(80, 184), size = wxSize(72, 16), style = 0) - self.removeCommonItemBtn.Enable(false) - self.removeCommonItemBtn.SetToolTipString('Remove the selected Common definition') - EVT_BUTTON(self.removeCommonItemBtn, wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, self.OnRemovesharebtnButton) - - self.panel2 = wxPanel(id = wxID_STCSTYLEEDITDLGPANEL2, name = 'panel2', parent = self, pos = wxPoint(296, 162), size = wxSize(112, 40), style = wxTAB_TRAVERSAL) - self.panel2.SetConstraints(LayoutAnchors(self.panel2, false, true, true, false)) - - self.staticText7 = wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT7, label = 'Size:', name = 'staticText7', parent = self.panel2, pos = wxPoint(0, 0), size = wxSize(23, 13), style = 0) - - self.taSizeDefCb = wxCheckBox(id = wxID_STCSTYLEEDITDLGTASIZEDEFCB, label = 'checkBox1', name = 'taSizeDefCb', parent = self.panel2, pos = wxPoint(88, 0), size = wxSize(16, 16), style = 0) - - self.sizeCb = wxComboBox(choices = [], id = wxID_STCSTYLEEDITDLGSIZECB, name = 'sizeCb', parent = self.panel2, pos = wxPoint(0, 17), size = wxSize(112, 21), style = 0, validator = wxDefaultValidator, value = '') - self.sizeCb.SetLabel('') - - self.faceCb = wxComboBox(choices = [], id = wxID_STCSTYLEEDITDLGFACECB, name = 'faceCb', parent = self.panel1, pos = wxPoint(17, 18), size = wxSize(111, 21), style = 0, validator = wxDefaultValidator, value = '') - self.faceCb.SetLabel('') - - self.fgColCb = wxComboBox(choices = [], id = wxID_STCSTYLEEDITDLGFGCOLCB, name = 'fgColCb', parent = self.staticBox1, pos = wxPoint(8, 32), size = wxSize(91, 21), style = 0, validator = wxDefaultValidator, value = '') - self.fgColCb.SetLabel('') - - self.bgColCb = wxComboBox(choices = [], id = wxID_STCSTYLEEDITDLGBGCOLCB, name = 'bgColCb', parent = self.staticBox1, pos = wxPoint(8, 72), size = wxSize(91, 21), style = 0, validator = wxDefaultValidator, value = '') - self.bgColCb.SetLabel('') + EVT_CHECKBOX(self.fixedWidthChk, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, + self.OnFixedwidthchkCheckbox) + + self.faceCb = wxComboBox(choices=[], id=wxID_STCSTYLEEDITDLGFACECB, + name='faceCb', parent=self.panel1, pos=wxPoint(17, 18), + size=wxSize(105, 21), style=0, validator=wxDefaultValidator, + value='') + + self.staticText7 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT7, + label='Size:', name='staticText7', parent=self.panel2, + pos=wxPoint(0, 0), size=wxSize(40, 13), style=0) + + self.sizeCb = wxComboBox(choices=[], id=wxID_STCSTYLEEDITDLGSIZECB, + name='sizeCb', parent=self.panel2, pos=wxPoint(0, 17), + size=wxSize(91, 21), style=0, validator=wxDefaultValidator, + value='') + + self.sizeOkBtn = wxButton(id=wxID_STCSTYLEEDITDLGSIZEOKBTN, label='ok', + name='sizeOkBtn', parent=self.panel2, pos=wxPoint(90, 17), + size=wxSize(21, 21), style=0) + + self.faceOkBtn = wxButton(id=wxID_STCSTYLEEDITDLGFACEOKBTN, label='ok', + name='faceOkBtn', parent=self.panel1, pos=wxPoint(122, 18), + size=wxSize(21, 21), style=0) + + self.fgColBtn = wxButton(id=wxID_STCSTYLEEDITDLGFGCOLBTN, + label='Foreground', name='fgColBtn', parent=self.panel3, + pos=wxPoint(8, 16), size=wxSize(72, 16), style=0) + EVT_BUTTON(self.fgColBtn, wxID_STCSTYLEEDITDLGFGCOLBTN, + self.OnFgcolbtnButton) + + self.fgColCb = wxComboBox(choices=[], id=wxID_STCSTYLEEDITDLGFGCOLCB, + name='fgColCb', parent=self.panel3, pos=wxPoint(8, 32), + size=wxSize(89, 21), style=0, validator=wxDefaultValidator, + value='') + + self.fgColOkBtn = wxButton(id=wxID_STCSTYLEEDITDLGFGCOLOKBTN, + label='ok', name='fgColOkBtn', parent=self.panel3, pos=wxPoint(96, + 32), size=wxSize(21, 21), style=0) + + self.staticText3 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT3, + label='default', name='staticText3', parent=self.panel3, + pos=wxPoint(100, 16), size=wxSize(37, 16), style=0) + + self.fgColDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGFGCOLDEFCB, + label='checkBox1', name='fgColDefCb', parent=self.panel3, + pos=wxPoint(120, 31), size=wxSize(16, 16), style=0) + + self.bgColBtn = wxButton(id=wxID_STCSTYLEEDITDLGBGCOLBTN, + label='Background', name='bgColBtn', parent=self.panel3, + pos=wxPoint(8, 56), size=wxSize(72, 16), style=0) + EVT_BUTTON(self.bgColBtn, wxID_STCSTYLEEDITDLGBGCOLBTN, + self.OnBgcolbtnButton) + + self.bgColCb = wxComboBox(choices=[], id=wxID_STCSTYLEEDITDLGBGCOLCB, + name='bgColCb', parent=self.panel3, pos=wxPoint(8, 72), + size=wxSize(89, 21), style=0, validator=wxDefaultValidator, + value='') + + self.bgColOkBtn = wxButton(id=wxID_STCSTYLEEDITDLGBGCOLOKBTN, + label='ok', name='bgColOkBtn', parent=self.panel3, pos=wxPoint(96, + 72), size=wxSize(21, 21), style=0) + + self.staticBox2 = wxStaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX2, + label='Text attributes', name='staticBox2', parent=self.panel4, + pos=wxPoint(0, 0), size=wxSize(112, 99), style=0) + self.staticBox2.SetConstraints(LayoutAnchors(self.staticBox2, False, + True, True, False)) + self.staticBox2.SetHelpText('Text attribute flags.') + + self.staticText2 = wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT2, + label='default', name='staticText2', parent=self.panel4, + pos=wxPoint(68, 11), size=wxSize(37, 16), style=0) + + self.taBoldDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTABOLDDEFCB, + label='checkBox1', name='taBoldDefCb', parent=self.panel4, + pos=wxPoint(88, 27), size=wxSize(16, 16), style=0) + + self.taItalicDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTAITALICDEFCB, + label='checkBox1', name='taItalicDefCb', parent=self.panel4, + pos=wxPoint(88, 43), size=wxSize(16, 16), style=0) + + self.taUnderlinedDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB, + label='checkBox1', name='taUnderlinedDefCb', parent=self.panel4, + pos=wxPoint(88, 59), size=wxSize(16, 16), style=0) + + self.taEOLfilledDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB, + label='checkBox1', name='taEOLfilledDefCb', parent=self.panel4, + pos=wxPoint(88, 75), size=wxSize(16, 16), style=0) + + self.taEOLfilledCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, + label='EOL filled', name='taEOLfilledCb', parent=self.panel4, + pos=wxPoint(8, 75), size=wxSize(72, 16), style=0) + EVT_CHECKBOX(self.taEOLfilledCb, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, + self.OnTaeoffilledcbCheckbox) + + self.taUnderlinedCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB, + label='Underlined', name='taUnderlinedCb', parent=self.panel4, + pos=wxPoint(8, 59), size=wxSize(72, 16), style=0) + EVT_CHECKBOX(self.taUnderlinedCb, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB, + self.OnTaunderlinedcbCheckbox) + + self.taItalicCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTAITALICCB, + label='Italic', name='taItalicCb', parent=self.panel4, + pos=wxPoint(8, 43), size=wxSize(72, 16), style=0) + EVT_CHECKBOX(self.taItalicCb, wxID_STCSTYLEEDITDLGTAITALICCB, + self.OnTaitaliccbCheckbox) + + self.taBoldCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTABOLDCB, + label='Bold', name='taBoldCb', parent=self.panel4, pos=wxPoint(8, + 27), size=wxSize(72, 16), style=0) + EVT_CHECKBOX(self.taBoldCb, wxID_STCSTYLEEDITDLGTABOLDCB, + self.OnTaboldcbCheckbox) + + self.bgColDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGBGCOLDEFCB, + label='checkBox1', name='bgColDefCb', parent=self.panel3, + pos=wxPoint(120, 71), size=wxSize(16, 16), style=0) + + self.staticBox1 = wxStaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX1, + label='Colour', name='staticBox1', parent=self.panel3, + pos=wxPoint(0, 0), size=wxSize(142, 99), style=0) + self.staticBox1.SetConstraints(LayoutAnchors(self.staticBox1, False, + True, True, False)) + + self.faceDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGFACEDEFCB, + label='checkBox1', name='faceDefCb', parent=self.panel1, + pos=wxPoint(120, 0), size=wxSize(16, 16), style=0) + + self.taSizeDefCb = wxCheckBox(id=wxID_STCSTYLEEDITDLGTASIZEDEFCB, + label='checkBox1', name='taSizeDefCb', parent=self.panel2, + pos=wxPoint(88, 0), size=wxSize(16, 16), style=0) def __init__(self, parent, langTitle, lang, configFile, STCsToUpdate=()): self.stc_title = 'wxStyledTextCtrl Style Editor' self.stc_title = 'wxStyledTextCtrl Style Editor - %s' % langTitle - self.sys_font = wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT).GetFaceName() + if wxPlatform == '__WXMSW__': + self.style_font_size = 8 + else: + self.style_font_size = 10 self._init_ctrls(parent) - - self._onUpdateUI = false self.lang = lang self.configFile = configFile self.style = '' + self.styleNum = 0 self.names = [] self.values = {} self.STCsToUpdate = STCsToUpdate + self._blockUpdate = False - for combo, evtRet, evtRDC in ( - (self.fgColCb, self.OnfgColRet, self.OnGotoCommonDef), - (self.bgColCb, self.OnbgColRet, self.OnGotoCommonDef), - (self.faceCb, self.OnfaceRet, self.OnGotoCommonDef), - (self.sizeCb, self.OnsizeRet, self.OnGotoCommonDef)): - self.bindComboEvts(combo, evtRet, evtRDC) + + for combo, okBtn, evtRet, evtCB, evtRDC in ( + (self.fgColCb, self.fgColOkBtn, self.OnfgColRet, self.OnfgColCombobox, self.OnGotoCommonDef), + (self.bgColCb, self.bgColOkBtn, self.OnbgColRet, self.OnbgColCombobox, self.OnGotoCommonDef), + (self.faceCb, self.faceOkBtn, self.OnfaceRet, self.OnfaceCombobox, self.OnGotoCommonDef), + (self.sizeCb, self.sizeOkBtn, self.OnsizeRet, self.OnsizeCombobox, self.OnGotoCommonDef)): + self.bindComboEvts(combo, okBtn, evtRet, evtCB, evtRDC) (self.config, self.commonDefs, self.styleIdNames, self.styles, self.styleGroupNames, self.predefStyleGroups, @@ -241,12 +408,12 @@ class STCStyleEditDlg(wxDialog): margin = 0 self.stc.SetMarginType(margin, wxSTC_MARGIN_NUMBER) self.stc.SetMarginWidth(margin, 25) - self.stc.SetMarginSensitive(margin, true) + self.stc.SetMarginSensitive(margin, True) EVT_STC_MARGINCLICK(self.stc, wxID_STCSTYLEEDITDLGSTC, self.OnMarginClick) - self.stc.SetUseTabs(false) + self.stc.SetUseTabs(False) self.stc.SetTabWidth(4) - self.stc.SetIndentationGuides(true) + self.stc.SetIndentationGuides(True) self.stc.SetEdgeMode(wxSTC_EDGE_BACKGROUND) self.stc.SetEdgeColumn(44) @@ -256,7 +423,6 @@ class STCStyleEditDlg(wxDialog): self.defNames, self.defValues = parseProp(\ self.styleDict.get(wxSTC_STYLE_DEFAULT, '')) - self.stc.SetText(self.displaySrc) self.stc.EmptyUndoBuffer() self.stc.SetCurrentPos(self.stc.GetTextLength()) @@ -265,9 +431,9 @@ class STCStyleEditDlg(wxDialog): self.populateCombosWithCommonDefs() # Logical grouping of controls and the property they edit - self.allCtrls = [((self.fgColBtn, self.fgColCb), self.fgColDefCb, + self.allCtrls = [((self.fgColBtn, self.fgColCb, self.fgColOkBtn), self.fgColDefCb, 'fore', wxID_STCSTYLEEDITDLGFGCOLDEFCB), - ((self.bgColBtn, self.bgColCb), self.bgColDefCb, + ((self.bgColBtn, self.bgColCb, self.bgColOkBtn), self.bgColDefCb, 'back', wxID_STCSTYLEEDITDLGBGCOLDEFCB), (self.taBoldCb, self.taBoldDefCb, 'bold', wxID_STCSTYLEEDITDLGTABOLDDEFCB), @@ -277,12 +443,12 @@ class STCStyleEditDlg(wxDialog): 'underline', wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB), (self.taEOLfilledCb, self.taEOLfilledDefCb, 'eolfilled', wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB), - (self.sizeCb, self.taSizeDefCb, + ((self.sizeCb, self.sizeOkBtn), self.taSizeDefCb, 'size', wxID_STCSTYLEEDITDLGTASIZEDEFCB), - ((self.faceCb, self.fixedWidthChk), self.faceDefCb, + ((self.faceCb, self.faceOkBtn, self.fixedWidthChk), self.faceDefCb, 'face', wxID_STCSTYLEEDITDLGFACEDEFCB)] - self.clearCtrls(disableDefs=true) + self.clearCtrls(disableDefs=True) # centralised default checkbox event handler self.chbIdMap = {} for ctrl, chb, prop, wid in self.allCtrls: @@ -291,7 +457,6 @@ class STCStyleEditDlg(wxDialog): chb.SetToolTipString('Toggle defaults') self.Center(wxBOTH) - self._onUpdateUI = true #---Property methods------------------------------------------------------------ def getCtrlForProp(self, findprop): @@ -314,15 +479,16 @@ class STCStyleEditDlg(wxDialog): try: self.updateStyle() - return true + return True except KeyError, errkey: wxLogError('Name not found in Common definition, '\ 'please enter valid reference. (%s)'%errkey) self.restoreStyles(oldstyle) - return false + return False #---Control population methods-------------------------------------------------- def setStyles(self): + if self._blockUpdate: return self.styles, self.styleDict, self.styleNumIdxMap = \ setSTCStyles(self.stc, self.styles, self.styleIdNames, self.commonDefs, self.lang, self.lexer, self.keywords) @@ -346,8 +512,8 @@ class STCStyleEditDlg(wxDialog): def findInStyles(self, txt, styles): for style in styles: if string.find(style, txt) != -1: - return true - return false + return True + return False def rememberStyles(self): return self.names[:], copy.copy(self.values) @@ -356,58 +522,76 @@ class STCStyleEditDlg(wxDialog): self.names, self.values = style self.updateStyle() - def clearCtrls(self, isDefault=false, disableDefs=false): - for ctrl, chb, prop, wid in self.allCtrls: - if prop in ('fore', 'back'): - btn, txt = ctrl - btn.SetBackgroundColour(\ - wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE)) - btn.SetForegroundColour(wxColour(255, 255, 255)) - btn.Enable(isDefault) - txt.SetValue('') - txt.Enable(isDefault) - elif prop == 'size': - ctrl.SetValue('') - ctrl.Enable(isDefault) - elif prop == 'face': - ctrl[0].SetValue('') - ctrl[0].Enable(isDefault) - ctrl[1].Enable(isDefault) - ctrl[1].SetValue(false) - elif prop in ('bold', 'italic', 'underline', 'eolfilled'): - ctrl.SetValue(false) - ctrl.Enable(isDefault) - - chb.Enable(not isDefault and not disableDefs) - chb.SetValue(true) - - def populateProp(self, items, default, forceDisable=false): - for name, val in items: - if name: - ctrl, chb = self.getCtrlForProp(name) - - if name in ('fore', 'back'): - btn, txt = ctrl - repval = val%self.commonDefs - btn.SetBackgroundColour(strToCol(repval)) - btn.SetForegroundColour(wxColour(0, 0, 0)) - btn.Enable(not forceDisable) - txt.SetValue(val) - txt.Enable(not forceDisable) - chb.SetValue(default) - elif name == 'size': - ctrl.SetValue(val) - ctrl.Enable(not forceDisable) - chb.SetValue(default) - elif name == 'face': - ctrl[0].SetValue(val) - ctrl[0].Enable(not forceDisable) - ctrl[1].Enable(not forceDisable) - chb.SetValue(default) - elif name in ('bold', 'italic', 'underline', 'eolfilled'): - ctrl.Enable(not forceDisable) - ctrl.SetValue(true) - chb.SetValue(default) + def clearCtrls(self, isDefault=False, disableDefs=False): + self._blockUpdate = True + try: + for ctrl, chb, prop, wid in self.allCtrls: + if prop in ('fore', 'back'): + cbtn, txt, btn = ctrl + cbtn.SetBackgroundColour(\ + wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE)) + cbtn.SetForegroundColour(wxColour(255, 255, 255)) + cbtn.Enable(isDefault) + txt.SetValue('') + txt.Enable(isDefault) + btn.Enable(isDefault) + elif prop == 'size': + cmb, btn = ctrl + cmb.SetValue('') + cmb.Enable(isDefault) + btn.Enable(isDefault) + elif prop == 'face': + cmb, btn, chk = ctrl + cmb.SetValue('') + cmb.Enable(isDefault) + btn.Enable(isDefault) + chk.Enable(isDefault) + chk.SetValue(False) + elif prop in ('bold', 'italic', 'underline', 'eolfilled'): + ctrl.SetValue(False) + ctrl.Enable(isDefault) + + chb.Enable(not isDefault and not disableDefs) + chb.SetValue(True) + finally: + self._blockUpdate = False + + def populateProp(self, items, default, forceDisable=False): + self._blockUpdate = True + try: + for name, val in items: + if name: + ctrl, chb = self.getCtrlForProp(name) + + if name in ('fore', 'back'): + cbtn, txt, btn = ctrl + repval = val%self.commonDefs + cbtn.SetBackgroundColour(strToCol(repval)) + cbtn.SetForegroundColour(wxColour(0, 0, 0)) + cbtn.Enable(not forceDisable) + txt.SetValue(val) + txt.Enable(not forceDisable) + btn.Enable(not forceDisable) + chb.SetValue(default) + elif name == 'size': + cmb, btn = ctrl + cmb.SetValue(val) + cmb.Enable(not forceDisable) + btn.Enable(not forceDisable) + chb.SetValue(default) + elif name == 'face': + cmb, btn, chk = ctrl + cmb.SetValue(val) + cmb.Enable(not forceDisable) + btn.Enable(not forceDisable) + chk.Enable(not forceDisable) + chb.SetValue(default) + elif name in ('bold', 'italic', 'underline', 'eolfilled'): + ctrl.Enable(not forceDisable) + ctrl.SetValue(True) + chb.SetValue(default) + finally: + self._blockUpdate = False def valIsCommonDef(self, val): return len(val) >= 5 and val[:2] == '%(' @@ -418,15 +602,15 @@ class STCStyleEditDlg(wxDialog): # handle colour controls for settings if self.styleNum < 0: - self.fgColDefCb.Enable(true) + self.fgColDefCb.Enable(True) if self.styleNum == -1: - self.bgColDefCb.Enable(true) + self.bgColDefCb.Enable(True) # populate with default style - self.populateProp(self.defValues.items(), true, + self.populateProp(self.defValues.items(), True, self.styleNum != wxSTC_STYLE_DEFAULT) # override with current settings - self.populateProp(self.values.items(), false) + self.populateProp(self.values.items(), False) def getCommonDefPropType(self, commonDefName): val = self.commonDefs[commonDefName] @@ -434,50 +618,54 @@ class STCStyleEditDlg(wxDialog): if len(val) == 7 and val[0] == '#': return 'fore' return 'face' - def bindComboEvts(self, combo, returnEvtMeth, rdclickEvtMeth): - wId = wxNewId() - EVT_MENU(self, wId, returnEvtMeth) - combo.SetAcceleratorTable(wxAcceleratorTable([(0, WXK_RETURN, wId)])) + def bindComboEvts(self, combo, btn, btnEvtMeth, comboEvtMeth, rdclickEvtMeth): + EVT_COMBOBOX(combo, combo.GetId(), comboEvtMeth) + EVT_BUTTON(btn, btn.GetId(), btnEvtMeth) EVT_RIGHT_DCLICK(combo, rdclickEvtMeth) - combo.SetToolTipString('Select or press Enter to change, right double-click \n'\ - 'the drop down button to select Common definition (if applicable)') + combo.SetToolTipString('Select from list or click "ok" button on the right to change a manual entry, right double-click \n'\ + 'the drop down button to select Common definition in the Style Editor (if applicable)') + btn.SetToolTipString('Accept value') def populateCombosWithCommonDefs(self, fixedWidthOnly=None): - commonDefs = {'fore': [], 'face': [], 'size': []} - - if self.elementLb.GetSelection() < self.commonDefsStartIdx: - for common in self.commonDefs.keys(): - prop = self.getCommonDefPropType(common) - commonDefs[prop].append('%%(%s)%s'%(common, - prop=='size' and 'd' or 's')) - - # Colours - currFg, currBg = self.fgColCb.GetValue(), self.bgColCb.GetValue() - self.fgColCb.Clear(); self.bgColCb.Clear() - for colCommonDef in commonDefs['fore']: - self.fgColCb.Append(colCommonDef) - self.bgColCb.Append(colCommonDef) - self.fgColCb.SetValue(currFg); self.bgColCb.SetValue(currBg) - - # Font - if fixedWidthOnly is None: - fixedWidthOnly = self.fixedWidthChk.GetValue() - fontEnum = wxFontEnumerator() - fontEnum.EnumerateFacenames(fixedWidthOnly=fixedWidthOnly) - fontNameList = fontEnum.GetFacenames() - - currFace = self.faceCb.GetValue() - self.faceCb.Clear() - for colCommonDef in ['']+fontNameList+commonDefs['face']: - self.faceCb.Append(colCommonDef) - self.faceCb.SetValue(currFace) - - # Size (XXX add std font sizes) - currSize = self.sizeCb.GetValue() - self.sizeCb.Clear() - for colCommonDef in commonDefs['size']: - self.sizeCb.Append(colCommonDef) - self.sizeCb.SetValue(currSize) + self._blockUpdate = True + try: + commonDefs = {'fore': [], 'face': [], 'size': []} + + if self.elementLb.GetSelection() < self.commonDefsStartIdx: + for common in self.commonDefs.keys(): + prop = self.getCommonDefPropType(common) + commonDefs[prop].append('%%(%s)%s'%(common, + prop=='size' and 'd' or 's')) + + # Colours + currFg, currBg = self.fgColCb.GetValue(), self.bgColCb.GetValue() + self.fgColCb.Clear(); self.bgColCb.Clear() + for colCommonDef in commonDefs['fore']: + self.fgColCb.Append(colCommonDef) + self.bgColCb.Append(colCommonDef) + self.fgColCb.SetValue(currFg); self.bgColCb.SetValue(currBg) + + # Font + if fixedWidthOnly is None: + fixedWidthOnly = self.fixedWidthChk.GetValue() + fontEnum = wxFontEnumerator() + fontEnum.EnumerateFacenames(fixedWidthOnly=fixedWidthOnly) + fontNameList = fontEnum.GetFacenames() + + currFace = self.faceCb.GetValue() + self.faceCb.Clear() + for colCommonDef in ['']+fontNameList+commonDefs['face']: + self.faceCb.Append(colCommonDef) + self.faceCb.SetValue(currFace) + + # Size (XXX add std font sizes) + currSize = self.sizeCb.GetValue() + self.sizeCb.Clear() + for colCommonDef in commonDefs['size']: + self.sizeCb.Append(colCommonDef) + self.sizeCb.SetValue(currSize) + finally: + self._blockUpdate = False def populateStyleSelector(self): numStyles = self.styleIdNames.items() @@ -489,8 +677,8 @@ class STCStyleEditDlg(wxDialog): # add styles for num, name in numStyles: if num == wxSTC_STYLE_DEFAULT: - self.elementLb.InsertItems([name, '-----Language-----'], 0) - self.elementLb.Append('-----Standard-----') + self.elementLb.InsertItems([name, '----Language----'], 0) + self.elementLb.Append('----Standard----') stdStart = stdPos = self.elementLb.Number() else: # std styles @@ -507,7 +695,7 @@ class STCStyleEditDlg(wxDialog): self.styleNumLookup[name] = num # add settings - self.elementLb.Append('-----Settings-----') + self.elementLb.Append('----Settings----') settings = settingsIdNames.items() settings.sort();settings.reverse() for num, name in settings: @@ -515,7 +703,7 @@ class STCStyleEditDlg(wxDialog): self.styleNumLookup[name] = num # add definitions - self.elementLb.Append('-----Common-----') + self.elementLb.Append('----Common----') self.commonDefsStartIdx = self.elementLb.Number() for common in self.commonDefs.keys(): tpe = type(self.commonDefs[common]) @@ -526,7 +714,7 @@ class STCStyleEditDlg(wxDialog): def getColourDlg(self, colour, title=''): data = wxColourData() data.SetColour(colour) - data.SetChooseFull(true) + data.SetChooseFull(True) dlg = wxColourDialog(self, data) try: dlg.SetTitle(title) @@ -546,7 +734,7 @@ class STCStyleEditDlg(wxDialog): colBtn.SetBackgroundColour(col) colStr = colToStr(col) colCb.SetValue(colStr) - self.editProp(true, prop, colStr) + self.editProp(True, prop, colStr) def OnFgcolbtnButton(self, event): self.editColProp(self.fgColBtn, self.fgColCb, 'fore') @@ -554,8 +742,11 @@ class STCStyleEditDlg(wxDialog): def OnBgcolbtnButton(self, event): self.editColProp(self.bgColBtn, self.bgColCb, 'back') - def editColTCProp(self, colCb, colBtn, prop): - colStr = colCb.GetValue() + def editColTCProp(self, colCb, colBtn, prop, val=None): + if val is None: + colStr = colCb.GetValue() + else: + colStr = val if colStr: col = strToCol(colStr%self.commonDefs) if self.editProp(colStr!='', prop, colStr): @@ -571,10 +762,20 @@ class STCStyleEditDlg(wxDialog): try: self.editColTCProp(self.fgColCb, self.fgColBtn, 'fore') except AssertionError: wxLogError('Not a valid colour value') + def OnfgColCombobox(self, event): + if self._blockUpdate: return + try: self.editColTCProp(self.fgColCb, self.fgColBtn, 'fore', event.GetString()) + except AssertionError: wxLogError('Not a valid colour value') + def OnbgColRet(self, event): try: self.editColTCProp(self.bgColCb, self.bgColBtn, 'back') except AssertionError: wxLogError('Not a valid colour value') + def OnbgColCombobox(self, event): + if self._blockUpdate: return + try: self.editColTCProp(self.bgColCb, self.bgColBtn, 'back', event.GetString()) + except AssertionError: wxLogError('Not a valid colour value') + #---Text attribute events------------------------------------------------------- def OnTaeoffilledcbCheckbox(self, event): self.editProp(event.IsChecked(), 'eolfilled') @@ -593,17 +794,29 @@ class STCStyleEditDlg(wxDialog): if self.valIsCommonDef(val): idx = self.elementLb.FindString(val) if idx != -1: - self.elementLb.SetSelection(idx, true) + self.elementLb.SetSelection(idx, True) self.OnElementlbListbox(None) def OnfaceRet(self, event): - val = self.faceCb.GetValue() + self.setFace(self.faceCb.GetValue()) + + def OnfaceCombobox(self, event): + if self._blockUpdate: return + self.setFace(event.GetString()) + + def setFace(self, val): try: val%self.commonDefs except KeyError: wxLogError('Invalid common definition') else: self.editProp(val!='', 'face', val) def OnsizeRet(self, event): - val = self.sizeCb.GetValue() + self.setSize(self.sizeCb.GetValue()) + + def OnsizeCombobox(self, event): + if self._blockUpdate: return + self.setSize(event.GetString()) + + def setSize(self, val): try: int(val%self.commonDefs) except ValueError: wxLogError('Not a valid integer size value') except KeyError: wxLogError('Invalid common definition') @@ -619,19 +832,22 @@ class STCStyleEditDlg(wxDialog): if isCommon: common = styleIdent[2:-2] prop = self.getCommonDefPropType(common) - self.clearCtrls(disableDefs=true) + self.clearCtrls(disableDefs=True) if prop == 'fore': - self.fgColBtn.Enable(true) - self.fgColCb.Enable(true) + self.fgColBtn.Enable(True) + self.fgColCb.Enable(True) + self.fgColOkBtn.Enable(True) elif prop == 'face': - self.faceCb.Enable(true) - self.fixedWidthChk.Enable(true) + self.faceCb.Enable(True) + self.fixedWidthChk.Enable(True) + self.faceOkBtn.Enable(True) elif prop == 'size': - self.sizeCb.Enable(true) + self.sizeCb.Enable(True) + self.sizeOkBtn.Enable(True) commonDefVal = str(self.commonDefs[common]) self.styleDefST.SetLabel(commonDefVal) - self.populateProp( [(prop, commonDefVal)], true) + self.populateProp( [(prop, commonDefVal)], True) self.styleNum = 'common' self.style = [common, prop, commonDefVal] @@ -642,7 +858,6 @@ class STCStyleEditDlg(wxDialog): self.styleNum = self.styleNumLookup[styleIdent] self.style = self.styleDict[self.styleNum] self.names, self.values = parseProp(self.style) - if self.styleNum == wxSTC_STYLE_DEFAULT: self.defNames, self.defValues = \ self.names, self.values @@ -654,55 +869,59 @@ class STCStyleEditDlg(wxDialog): self.populateCtrls() # separator selected else: - self.clearCtrls(disableDefs=true) + self.clearCtrls(disableDefs=True) if styleIdent: self.styleDefST.SetLabel(styleCategoryDescriptions[styleIdent]) self.populateCombosWithCommonDefs() def OnDefaultCheckBox(self, event): - self._onUpdateUI = false - try: - if self.chbIdMap.has_key(event.GetId()): - ctrl, chb, prop, wid = self.chbIdMap[event.GetId()] - restore = not event.IsChecked() - if prop in ('fore', 'back'): - ctrl[0].Enable(restore) - ctrl[1].Enable(restore) - if restore: - # XXX use ctrl[1] !! - colStr = ctrl[1].GetValue() - #if prop == 'fore': colStr = self.fgColCb.GetValue() - #else: colStr = self.bgColCb.GetValue() - if colStr: self.editProp(true, prop, colStr) - else: - self.editProp(false, prop) - elif prop == 'size': - val = ctrl.GetValue() - if val: self.editProp(restore, prop, val) - ctrl.Enable(restore) - elif prop == 'face': - val = ctrl[0].GetStringSelection() - if val: self.editProp(restore, prop, val) - ctrl[0].Enable(restore) - ctrl[1].Enable(restore) - elif prop in ('bold', 'italic', 'underline', 'eolfilled'): - ctrl.Enable(restore) - if ctrl.GetValue(): self.editProp(restore, prop) - finally: - self._onUpdateUI = true + if self.chbIdMap.has_key(event.GetId()): + ctrl, chb, prop, wid = self.chbIdMap[event.GetId()] + restore = not event.IsChecked() + if prop in ('fore', 'back'): + cbtn, cmb, btn = ctrl + cbtn.Enable(restore) + cmb.Enable(restore) + btn.Enable(restore) + if restore: + colStr = cmb.GetValue() + #if prop == 'fore': colStr = self.fgColCb.GetValue() + #else: colStr = self.bgColCb.GetValue() + if colStr: self.editProp(True, prop, colStr) + else: + self.editProp(False, prop) + elif prop == 'size': + cmb, btn = ctrl + val = cmb.GetValue() + if val: self.editProp(restore, prop, val) + cmb.Enable(restore) + btn.Enable(restore) + elif prop == 'face': + cmb, btn, chk = ctrl + val = cmb.GetStringSelection() + if val: self.editProp(restore, prop, val) + cmb.Enable(restore) + btn.Enable(restore) + chk.Enable(restore) + elif prop in ('bold', 'italic', 'underline', 'eolfilled'): + ctrl.Enable(restore) + if ctrl.GetValue(): self.editProp(restore, prop) def OnOkbtnButton(self, event): # write styles and common defs to the config - writeStylesToConfig(self.config, 'style.%s'%self.lang, self.styles) - self.config.SetPath('') - self.config.Write(commonDefsFile, `self.commonDefs`) - self.config.Flush() - - for stc in self.STCsToUpdate: - setSTCStyles(stc, self.styles, self.styleIdNames, self.commonDefs, - self.lang, self.lexer, self.keywords) - + wxBeginBusyCursor() + try: + writeStylesToConfig(self.config, 'style.%s'%self.lang, self.styles) + self.config.SetPath('') + self.config.Write(commonDefsFile, `self.commonDefs`) + self.config.Flush() + + for stc in self.STCsToUpdate: + setSTCStyles(stc, self.styles, self.styleIdNames, self.commonDefs, + self.lang, self.lexer, self.keywords) + finally: + wxEndBusyCursor() self.EndModal(wxID_OK) def OnCancelbtnButton(self, event): @@ -755,7 +974,7 @@ class STCStyleEditDlg(wxDialog): self.commonDefs[name] = commonPropDefs[prop] self.elementLb.Append('%('+name+')'+\ (type(commonPropDefs[prop]) is type('') and 's' or 'd')) - self.elementLb.SetSelection(self.elementLb.Number()-1, true) + self.elementLb.SetSelection(self.elementLb.Number()-1, True) self.populateCombosWithCommonDefs() self.OnElementlbListbox(None) finally: @@ -787,20 +1006,19 @@ class STCStyleEditDlg(wxDialog): self.elementLb.Delete(selIdx) if selIdx == self.elementLb.Number(): selIdx = selIdx - 1 - self.elementLb.SetSelection(selIdx, true) + self.elementLb.SetSelection(selIdx, True) self.OnElementlbListbox(None) #---STC events------------------------------------------------------------------ def OnUpdateUI(self, event): - if self._onUpdateUI: - styleBefore = self.stc.GetStyleAt(self.stc.GetCurrentPos()) - if self.styleIdNames.has_key(styleBefore): - self.elementLb.SetStringSelection(self.styleIdNames[styleBefore], - true) - else: - self.elementLb.SetSelection(0, false) - self.styleDefST.SetLabel('Style %d not defined, sorry.'%styleBefore) - self.OnElementlbListbox(None) + styleBefore = self.stc.GetStyleAt(self.stc.GetCurrentPos()) + if self.styleIdNames.has_key(styleBefore): + self.elementLb.SetStringSelection(self.styleIdNames[styleBefore], + True) + else: + self.elementLb.SetSelection(0, False) + self.styleDefST.SetLabel('Style %d not defined, sorry.'%styleBefore) + self.OnElementlbListbox(None) event.Skip() def checkBraces(self, style): @@ -825,7 +1043,7 @@ class STCStyleEditDlg(wxDialog): event.Skip() def OnMarginClick(self, event): - self.elementLb.SetStringSelection('Line numbers', true) + self.elementLb.SetStringSelection('Line numbers', True) self.OnElementlbListbox(None) @@ -836,20 +1054,20 @@ class STCStyleEditDlg(wxDialog): class CommonDefDlg(wxDialog): def _init_ctrls(self, prnt): wxDialog.__init__(self, id = wxID_COMMONDEFDLG, name = 'CommonDefDlg', parent = prnt, pos = wxPoint(398, 249), size = wxSize(192, 220), style = wxDEFAULT_DIALOG_STYLE, title = 'Common definition') - self.SetClientSize(wxSize(184, 175)) + self.SetClientSize(wxSize(184, 200)) - self.propTypeRBx = wxRadioBox(choices = ['Colour value', 'Font face', 'Size value'], id = wxID_COMMONDEFDLGPROPTYPERBX, label = 'Common definition property type', majorDimension = 1, name = 'propTypeRBx', parent = self, point = wxPoint(8, 8), size = wxSize(168, 72), style = wxRA_SPECIFY_COLS, validator = wxDefaultValidator) + self.propTypeRBx = wxRadioBox(choices = ['Colour value', 'Font face', 'Size value'], id = wxID_COMMONDEFDLGPROPTYPERBX, label = 'Property type', majorDimension = 1, name = 'propTypeRBx', parent = self, point = wxPoint(8, 8), size = wxSize(168, 92), style = wxRA_SPECIFY_COLS, validator = wxDefaultValidator) self.propTypeRBx.SetSelection(self._propTypeIdx) - self.staticBox1 = wxStaticBox(id = wxID_COMMONDEFDLGSTATICBOX1, label = 'Name', name = 'staticBox1', parent = self, pos = wxPoint(8, 88), size = wxSize(168, 46), style = 0) + self.staticBox1 = wxStaticBox(id = wxID_COMMONDEFDLGSTATICBOX1, label = 'Name', name = 'staticBox1', parent = self, pos = wxPoint(8, 108), size = wxSize(168, 46), style = 0) - self.comDefNameTC = wxTextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC, name = 'comDefNameTC', parent = self, pos = wxPoint(16, 104), size = wxSize(152, 21), style = 0, value = '') + self.comDefNameTC = wxTextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC, name = 'comDefNameTC', parent = self, pos = wxPoint(16, 124), size = wxSize(152, 21), style = 0, value = '') self.comDefNameTC.SetLabel(self._comDefName) - self.okBtn = wxButton(id = wxID_COMMONDEFDLGOKBTN, label = 'OK', name = 'okBtn', parent = self, pos = wxPoint(8, 144), size = wxSize(80, 23), style = 0) + self.okBtn = wxButton(id = wxID_COMMONDEFDLGOKBTN, label = 'OK', name = 'okBtn', parent = self, pos = wxPoint(8, 164), size = wxSize(80, 23), style = 0) EVT_BUTTON(self.okBtn, wxID_COMMONDEFDLGOKBTN, self.OnOkbtnButton) - self.cancelBtn = wxButton(id = wxID_COMMONDEFDLGCANCELBTN, label = 'Cancel', name = 'cancelBtn', parent = self, pos = wxPoint(96, 144), size = wxSize(80, 23), style = 0) + self.cancelBtn = wxButton(id = wxID_COMMONDEFDLGCANCELBTN, label = 'Cancel', name = 'cancelBtn', parent = self, pos = wxPoint(96, 164), size = wxSize(80, 23), style = 0) EVT_BUTTON(self.cancelBtn, wxID_COMMONDEFDLGCANCELBTN, self.OnCancelbtnButton) def __init__(self, parent, name='', propIdx=0): @@ -878,9 +1096,9 @@ class CommonDefDlg(wxDialog): def setSelectionColour(stc, style): names, values = parseProp(style) if 'fore' in names: - stc.SetSelForeground(true, strToCol(values['fore'])) + stc.SetSelForeground(True, strToCol(values['fore'])) if 'back' in names: - stc.SetSelBackground(true, strToCol(values['back'])) + stc.SetSelBackground(True, strToCol(values['back'])) def setCursorColour(stc, style): names, values = parseProp(style) @@ -933,6 +1151,7 @@ def parsePropLine(prop): return int(string.split(name, '.')[-1]), value def setSTCStyles(stc, styles, styleIdNames, commonDefs, lang, lexer, keywords): + #wxLogMessage('Set style') styleDict = {} styleNumIdxMap = {} @@ -953,7 +1172,19 @@ def setSTCStyles(stc, styles, styleIdNames, commonDefs, lang, lexer, keywords): newStyles.append(writeProp(num, styleDict[num], lang)) idx = idx + 1 + # Set background colour to reduce flashing effect on refresh or page switch + bkCol = None + if styleDict.has_key(0): prop = styleDict[0] + else: prop = styleDict[wxSTC_STYLE_DEFAULT] + names, vals = parseProp(prop) + if 'back' in names: + bkCol = strToCol(vals['back']) + if bkCol is None: + bkCol = wxWHITE + stc.SetBackgroundColour(bkCol) + # Set the styles on the wxSTC +# stc.Show(False) stc.StyleResetDefault() stc.ClearDocumentStyle() stc.SetLexer(lexer) @@ -973,15 +1204,19 @@ def setSTCStyles(stc, styles, styleIdNames, commonDefs, lang, lexer, keywords): setEdgeColour(stc, style % commonDefs) stc.Colourise(0, stc.GetTextLength()) +# stc.Show(True) return newStyles, styleDict, styleNumIdxMap #---Config reading and writing ------------------------------------------------- commonDefsFile = 'common.defs.%s'%(wxPlatform == '__WXMSW__' and 'msw' or 'gtk') +def readPyValFromConfig(conf, name): + return eval(string.replace(conf.Read(name), '\r\n', '\n')+'\n') + def initFromConfig(configFile, lang): cfg = wxFileConfig(localFilename=configFile, style=wxCONFIG_USE_LOCAL_FILE) - cfg.SetExpandEnvVars(false) + cfg.SetExpandEnvVars(False) # read in all group names for this language groupPrefix = 'style.%s'%lang @@ -998,26 +1233,26 @@ def initFromConfig(configFile, lang): cont, val, idx = cfg.GetNextGroup(idx) # read in common elements - commonDefs = eval(cfg.Read(commonDefsFile)) + commonDefs = readPyValFromConfig(cfg, commonDefsFile) assert type(commonDefs) is type({}), \ 'Common definitions (%s) not a valid dict'%commonDefsFile - commonStyleIdNames = eval(cfg.Read('common.styleidnames')) + commonStyleIdNames = readPyValFromConfig(cfg, 'common.styleidnames') assert type(commonStyleIdNames) is type({}), \ 'Common definitions (%s) not a valid dict'%'common.styleidnames' # Lang spesific settings cfg.SetPath(lang) - styleIdNames = eval(cfg.Read('styleidnames')) + styleIdNames = readPyValFromConfig(cfg, 'styleidnames') assert type(commonStyleIdNames) is type({}), \ 'Not a valid dict [%s] styleidnames)'%lang styleIdNames.update(commonStyleIdNames) - braceInfo = eval(cfg.Read('braces')) + braceInfo = readPyValFromConfig(cfg, 'braces') assert type(commonStyleIdNames) is type({}), \ 'Not a valid dict [%s] braces)'%lang displaySrc = cfg.Read('displaysrc') - lexer = eval(cfg.Read('lexer')) + lexer = readPyValFromConfig(cfg, 'lexer') keywords = cfg.Read('keywords') cfg.SetPath('') @@ -1073,9 +1308,16 @@ def initSTC(stc, config, lang): #------------------------------------------------------------------------------- if __name__ == '__main__': + from wxPython.help import * + app = wxPySimpleApp() - config = os.path.abspath('stc-styles.rc.cfg') + provider = wxSimpleHelpProvider() + wxHelpProvider_Set(provider) + + home = os.environ.get('HOME') + if home: home = os.path.join(home, '.boa') + config = os.path.abspath(os.path.join(home, 'stc-styles.rc.cfg')) if 0: f = wxFrame(None, -1, 'Test frame (double click for editor)') stc = wxStyledTextCtrl(f, -1) @@ -1086,7 +1328,7 @@ if __name__ == '__main__': stc.SetText(open('STCStyleEditor.py').read()) EVT_LEFT_DCLICK(stc, OnDblClick) initSTC(stc, config, 'python') - f.Show(true) + f.Show(True) app.MainLoop() else: dlg = STCStyleEditDlg(None, @@ -1099,6 +1341,3 @@ if __name__ == '__main__': config) try: dlg.ShowModal() finally: dlg.Destroy() - del config - app.MainLoop() - diff --git a/wxPython/samples/doodle/.cvsignore b/wxPython/samples/doodle/.cvsignore index 9d0b71a3c7..f2bc31a03e 100644 --- a/wxPython/samples/doodle/.cvsignore +++ b/wxPython/samples/doodle/.cvsignore @@ -1,2 +1,3 @@ +.DS_Store build dist diff --git a/wxPython/samples/doodle/doodle.py b/wxPython/samples/doodle/doodle.py index 8fefcd0416..4895026e74 100644 --- a/wxPython/samples/doodle/doodle.py +++ b/wxPython/samples/doodle/doodle.py @@ -74,7 +74,7 @@ class DoodleWindow(wxWindow): dc.SetBackground(wxBrush(self.GetBackgroundColour())) dc.Clear() self.DrawLines(dc) - self.reInitBuffer = false + self.reInitBuffer = False def SetColour(self, colour): @@ -125,14 +125,14 @@ class DoodleWindow(wxWindow): def OnCheckMenuColours(self, event): text = self.menuColours[event.GetId()] if text == self.colour: - event.Check(true) + event.Check(True) else: - event.Check(false) + event.Check(False) def OnCheckMenuThickness(self, event): if event.GetId() == self.thickness: - event.Check(true) + event.Check(True) else: - event.Check(false) + event.Check(False) def OnLeftDown(self, event): @@ -180,7 +180,7 @@ class DoodleWindow(wxWindow): Called when the window is resized. We set a flag so the idle handler will resize the buffer. """ - self.reInitBuffer = true + self.reInitBuffer = True def OnIdle(self, event): @@ -192,7 +192,7 @@ class DoodleWindow(wxWindow): """ if self.reInitBuffer: self.InitBuffer() - self.Refresh(FALSE) + self.Refresh(False) def OnPaint(self, event): @@ -251,6 +251,6 @@ class DoodleFrame(wxFrame): if __name__ == '__main__': app = wxPySimpleApp() frame = DoodleFrame(None) - frame.Show(true) + frame.Show(True) app.MainLoop() diff --git a/wxPython/samples/doodle/superdoodle.py b/wxPython/samples/doodle/superdoodle.py index 1923d13654..08ee49339e 100644 --- a/wxPython/samples/doodle/superdoodle.py +++ b/wxPython/samples/doodle/superdoodle.py @@ -53,7 +53,7 @@ class DoodleFrame(wxFrame): # Tell the frame that it should layout itself in response to # size events. - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(box) @@ -213,7 +213,7 @@ class ControlPanel(wxPanel): box.Add(tGrid, 0, wxALL, spacing) box.Add(ci, 0, wxEXPAND|wxALL, spacing) self.SetSizer(box) - self.SetAutoLayout(true) + self.SetAutoLayout(True) # Resize this window so it is just large enough for the # minimum requirements of the sizer. @@ -348,7 +348,7 @@ instructions:

    lc.height.AsIs() button.SetConstraints(lc) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.Layout() self.CentreOnParent(wxBOTH) @@ -358,9 +358,9 @@ instructions:

    class DoodleApp(wxApp): def OnInit(self): frame = DoodleFrame(None) - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True #---------------------------------------------------------------------- diff --git a/wxPython/samples/frogedit/FrogEdit.py b/wxPython/samples/frogedit/FrogEdit.py index ee46be3474..157b0e043e 100644 --- a/wxPython/samples/frogedit/FrogEdit.py +++ b/wxPython/samples/frogedit/FrogEdit.py @@ -12,8 +12,6 @@ from wxPython.wx import * from StatusBar import * from FrogEditor import FrogEditor -TRUE = 1 -FALSE = 0 ABOUT_TEXT = """FrogEdit : Copyright 2001 Adam Feuer and Steve Howell wxEditor component : Copyright 1999 - 2001 Dirk Holtwic, Robin Dunn, Adam Feuer, Steve Howell @@ -95,7 +93,7 @@ class FrogEditFrame(wxFrame): def SetUpSplitter(self, splitter, win, log): splitter.SplitHorizontally(win, log) - splitter.SetSashPosition(360, true) + splitter.SetSashPosition(360, True) splitter.SetMinimumPaneSize(40) def MakeToolbar(self, win): @@ -109,7 +107,7 @@ class FrogEditFrame(wxFrame): borderWidth = 5 mainBox.Add(self.edl, 1, wxALL|wxGROW, borderWidth) win.SetSizer(mainBox) - win.SetAutoLayout(true) + win.SetAutoLayout(True) ##-------------- Init Menus @@ -180,9 +178,9 @@ class FrogEditFrame(wxFrame): result = dialog.ShowModal() dialog.Destroy() if result == wxID_OK: - return TRUE + return True else: - return FALSE + return False def SelectFileDialog(self, defaultDir=None, defaultFile=None, wildCard=None): if defaultDir == None: @@ -247,9 +245,9 @@ class FrogEditFrame(wxFrame): f.close() self.edl.UnTouchBuffer() self.sb.setFileName(fileName) - return TRUE + return True except: - return FALSE + return False def OpenFile(self, fileName): try: @@ -262,9 +260,9 @@ class FrogEditFrame(wxFrame): self.edl.SetText(contents) self.fileName = fileName self.sb.setFileName(fileName) - return TRUE + return True except: - return FALSE + return False @@ -288,7 +286,7 @@ class FrogEditFrame(wxFrame): return fileName = self.SelectFileDialog(self.GetCurrentDir()) if fileName is not None: - if self.OpenFile(fileName) is FALSE: + if self.OpenFile(fileName) is False: self.OpenFileError(fileName) self.edl.SetFocus() @@ -296,7 +294,7 @@ class FrogEditFrame(wxFrame): if self.fileName is None: return self.OnSaveFileAs(event) wxLogMessage("Saving %s..." % self.fileName) - if self.SaveFile(self.fileName) is not TRUE: + if self.SaveFile(self.fileName) is not True: self.SaveFileError(self.fileName) self.edl.SetFocus() @@ -305,7 +303,7 @@ class FrogEditFrame(wxFrame): if fileName is not None: self.fileName = fileName wxLogMessage("Saving %s..." % self.fileName) - if self.SaveFile(self.fileName) is not TRUE: + if self.SaveFile(self.fileName) is not True: self.SaveFileError(self.fileName) self.edl.SetFocus() @@ -331,7 +329,7 @@ class FrogEditFrame(wxFrame): def LoadInitialFile(self, fileName): if fileName is not None: - if self.OpenFile(fileName) is FALSE: + if self.OpenFile(fileName) is False: self.OpenFileError(fileName) @@ -354,7 +352,7 @@ class FrogEditLauncher: def Main(self): app = wxPySimpleApp() win = self.MakeAppFrame() - win.Show(true) + win.Show(True) win.LoadInitialFile(self.GetArgvFilename()) app.MainLoop() diff --git a/wxPython/samples/pySketch/pySketch.py b/wxPython/samples/pySketch/pySketch.py index 57edf205fd..2340d45e8a 100644 --- a/wxPython/samples/pySketch/pySketch.py +++ b/wxPython/samples/pySketch/pySketch.py @@ -36,13 +36,13 @@ Known Bugs: * Scrolling the window causes the drawing panel to be mucked up until you - refresh it. I've got no idea why. + refresh it. I've got no idea why. * I suspect that the reference counting for some wxPoint objects is getting mucked up; when the user quits, we get errors about being - unable to call del on a 'None' object. + unable to call del on a 'None' object. """ -import string, cPickle, os.path +import cPickle, os.path from wxPython.wx import * import traceback, types @@ -143,2146 +143,2146 @@ class DrawingFrame(wxFrame): # ========================================== def __init__(self, parent, id, title, fileName=None): - """ Standard constructor. + """ Standard constructor. - 'parent', 'id' and 'title' are all passed to the standard wxFrame - constructor. 'fileName' is the name and path of a saved file to - load into this frame, if any. - """ + 'parent', 'id' and 'title' are all passed to the standard wxFrame + constructor. 'fileName' is the name and path of a saved file to + load into this frame, if any. + """ wxFrame.__init__(self, parent, id, title, - style = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS | - wxNO_FULL_REPAINT_ON_RESIZE) - - # Setup our menu bar. - - menuBar = wxMenuBar() - - self.fileMenu = wxMenu() - self.fileMenu.Append(wxID_NEW, "New\tCTRL-N") - self.fileMenu.Append(wxID_OPEN, "Open...\tCTRL-O") - self.fileMenu.Append(wxID_CLOSE, "Close\tCTRL-W") - self.fileMenu.AppendSeparator() - self.fileMenu.Append(wxID_SAVE, "Save\tCTRL-S") - self.fileMenu.Append(wxID_SAVEAS, "Save As...") - self.fileMenu.Append(wxID_REVERT, "Revert...") - self.fileMenu.AppendSeparator() - self.fileMenu.Append(wxID_EXIT, "Quit\tCTRL-Q") - - menuBar.Append(self.fileMenu, "File") - - self.editMenu = wxMenu() - self.editMenu.Append(menu_UNDO, "Undo\tCTRL-Z") - self.editMenu.AppendSeparator() - self.editMenu.Append(menu_SELECT_ALL, "Select All\tCTRL-A") - self.editMenu.AppendSeparator() - self.editMenu.Append(menu_DUPLICATE, "Duplicate\tCTRL-D") - self.editMenu.Append(menu_EDIT_TEXT, "Edit...\tCTRL-E") - self.editMenu.Append(menu_DELETE, "Delete\tDEL") - - menuBar.Append(self.editMenu, "Edit") - - self.toolsMenu = wxMenu() - self.toolsMenu.Append(menu_SELECT, "Selection", kind=wxITEM_CHECK) - self.toolsMenu.Append(menu_LINE, "Line", kind=wxITEM_CHECK) - self.toolsMenu.Append(menu_RECT, "Rectangle", kind=wxITEM_CHECK) - self.toolsMenu.Append(menu_ELLIPSE, "Ellipse", kind=wxITEM_CHECK) - self.toolsMenu.Append(menu_TEXT, "Text", kind=wxITEM_CHECK) - - menuBar.Append(self.toolsMenu, "Tools") - - self.objectMenu = wxMenu() - self.objectMenu.Append(menu_MOVE_FORWARD, "Move Forward") - self.objectMenu.Append(menu_MOVE_TO_FRONT, "Move to Front\tCTRL-F") - self.objectMenu.Append(menu_MOVE_BACKWARD, "Move Backward") - self.objectMenu.Append(menu_MOVE_TO_BACK, "Move to Back\tCTRL-B") - - menuBar.Append(self.objectMenu, "Object") - - self.helpMenu = wxMenu() - self.helpMenu.Append(menu_ABOUT, "About pySketch...") - - menuBar.Append(self.helpMenu, "Help") - - self.SetMenuBar(menuBar) - - # Create our toolbar. - - self.toolbar = self.CreateToolBar(wxTB_HORIZONTAL | - wxNO_BORDER | wxTB_FLAT) - - self.toolbar.AddSimpleTool(wxID_NEW, - wxBitmap("images/new.bmp", - wxBITMAP_TYPE_BMP), - "New") - self.toolbar.AddSimpleTool(wxID_OPEN, - wxBitmap("images/open.bmp", - wxBITMAP_TYPE_BMP), - "Open") - self.toolbar.AddSimpleTool(wxID_SAVE, - wxBitmap("images/save.bmp", - wxBITMAP_TYPE_BMP), - "Save") - self.toolbar.AddSeparator() - self.toolbar.AddSimpleTool(menu_UNDO, - wxBitmap("images/undo.bmp", - wxBITMAP_TYPE_BMP), - "Undo") - self.toolbar.AddSeparator() - self.toolbar.AddSimpleTool(menu_DUPLICATE, - wxBitmap("images/duplicate.bmp", - wxBITMAP_TYPE_BMP), - "Duplicate") - self.toolbar.AddSeparator() - self.toolbar.AddSimpleTool(menu_MOVE_FORWARD, - wxBitmap("images/moveForward.bmp", - wxBITMAP_TYPE_BMP), - "Move Forward") - self.toolbar.AddSimpleTool(menu_MOVE_BACKWARD, - wxBitmap("images/moveBack.bmp", - wxBITMAP_TYPE_BMP), - "Move Backward") - - self.toolbar.Realize() - - # Associate each menu/toolbar item with the method that handles that - # item. - - EVT_MENU(self, wxID_NEW, self.doNew) - EVT_MENU(self, wxID_OPEN, self.doOpen) - EVT_MENU(self, wxID_CLOSE, self.doClose) - EVT_MENU(self, wxID_SAVE, self.doSave) - EVT_MENU(self, wxID_SAVEAS, self.doSaveAs) - EVT_MENU(self, wxID_REVERT, self.doRevert) - EVT_MENU(self, wxID_EXIT, self.doExit) - - EVT_MENU(self, menu_UNDO, self.doUndo) - EVT_MENU(self, menu_SELECT_ALL, self.doSelectAll) - EVT_MENU(self, menu_DUPLICATE, self.doDuplicate) - EVT_MENU(self, menu_EDIT_TEXT, self.doEditText) - EVT_MENU(self, menu_DELETE, self.doDelete) - - EVT_MENU(self, menu_SELECT, self.doChooseSelectTool) - EVT_MENU(self, menu_LINE, self.doChooseLineTool) - EVT_MENU(self, menu_RECT, self.doChooseRectTool) - EVT_MENU(self, menu_ELLIPSE, self.doChooseEllipseTool) - EVT_MENU(self, menu_TEXT, self.doChooseTextTool) - - EVT_MENU(self, menu_MOVE_FORWARD, self.doMoveForward) - EVT_MENU(self, menu_MOVE_TO_FRONT, self.doMoveToFront) - EVT_MENU(self, menu_MOVE_BACKWARD, self.doMoveBackward) - EVT_MENU(self, menu_MOVE_TO_BACK, self.doMoveToBack) - - EVT_MENU(self, menu_ABOUT, self.doShowAbout) - - # Install our own method to handle closing the window. This allows us - # to ask the user if he/she wants to save before closing the window, as - # well as keeping track of which windows are currently open. - - EVT_CLOSE(self, self.doClose) - - # Install our own method for handling keystrokes. We use this to let - # the user move the selected object(s) around using the arrow keys. - - EVT_CHAR_HOOK(self, self.onKeyEvent) - - # Setup our top-most panel. This holds the entire contents of the - # window, excluding the menu bar. - - self.topPanel = wxPanel(self, -1, style=wxSIMPLE_BORDER) - - # Setup our tool palette, with all our drawing tools and option icons. - - self.toolPalette = wxBoxSizer(wxVERTICAL) - - self.selectIcon = ToolPaletteIcon(self.topPanel, id_SELECT, - "select", "Selection Tool") - self.lineIcon = ToolPaletteIcon(self.topPanel, id_LINE, - "line", "Line Tool") - self.rectIcon = ToolPaletteIcon(self.topPanel, id_RECT, - "rect", "Rectangle Tool") - self.ellipseIcon = ToolPaletteIcon(self.topPanel, id_ELLIPSE, - "ellipse", "Ellipse Tool") - self.textIcon = ToolPaletteIcon(self.topPanel, id_TEXT, - "text", "Text Tool") - - toolSizer = wxGridSizer(0, 2, 5, 5) - toolSizer.Add(self.selectIcon) - toolSizer.Add(0, 0) # Gap to make tool icons line up nicely. - toolSizer.Add(self.lineIcon) - toolSizer.Add(self.rectIcon) - toolSizer.Add(self.ellipseIcon) - toolSizer.Add(self.textIcon) - - self.optionIndicator = ToolOptionIndicator(self.topPanel) - self.optionIndicator.SetToolTip( - wxToolTip("Shows Current Pen/Fill/Line Size Settings")) - - optionSizer = wxBoxSizer(wxHORIZONTAL) - - self.penOptIcon = ToolPaletteIcon(self.topPanel, id_PEN_OPT, - "penOpt", "Set Pen Colour") - self.fillOptIcon = ToolPaletteIcon(self.topPanel, id_FILL_OPT, - "fillOpt", "Set Fill Colour") - self.lineOptIcon = ToolPaletteIcon(self.topPanel, id_LINE_OPT, - "lineOpt", "Set Line Size") - - margin = wxLEFT | wxRIGHT - optionSizer.Add(self.penOptIcon, 0, margin, 1) - optionSizer.Add(self.fillOptIcon, 0, margin, 1) - optionSizer.Add(self.lineOptIcon, 0, margin, 1) - - margin = wxTOP | wxLEFT | wxRIGHT | wxALIGN_CENTRE - self.toolPalette.Add(toolSizer, 0, margin, 5) - self.toolPalette.Add(0, 0, 0, margin, 5) # Spacer. - self.toolPalette.Add(self.optionIndicator, 0, margin, 5) - self.toolPalette.Add(optionSizer, 0, margin, 5) + style = wxDEFAULT_FRAME_STYLE | wxWANTS_CHARS | + wxNO_FULL_REPAINT_ON_RESIZE) + + # Setup our menu bar. + + menuBar = wxMenuBar() + + self.fileMenu = wxMenu() + self.fileMenu.Append(wxID_NEW, "New\tCTRL-N") + self.fileMenu.Append(wxID_OPEN, "Open...\tCTRL-O") + self.fileMenu.Append(wxID_CLOSE, "Close\tCTRL-W") + self.fileMenu.AppendSeparator() + self.fileMenu.Append(wxID_SAVE, "Save\tCTRL-S") + self.fileMenu.Append(wxID_SAVEAS, "Save As...") + self.fileMenu.Append(wxID_REVERT, "Revert...") + self.fileMenu.AppendSeparator() + self.fileMenu.Append(wxID_EXIT, "Quit\tCTRL-Q") + + menuBar.Append(self.fileMenu, "File") + + self.editMenu = wxMenu() + self.editMenu.Append(menu_UNDO, "Undo\tCTRL-Z") + self.editMenu.AppendSeparator() + self.editMenu.Append(menu_SELECT_ALL, "Select All\tCTRL-A") + self.editMenu.AppendSeparator() + self.editMenu.Append(menu_DUPLICATE, "Duplicate\tCTRL-D") + self.editMenu.Append(menu_EDIT_TEXT, "Edit...\tCTRL-E") + self.editMenu.Append(menu_DELETE, "Delete\tDEL") + + menuBar.Append(self.editMenu, "Edit") + + self.toolsMenu = wxMenu() + self.toolsMenu.Append(menu_SELECT, "Selection", kind=wxITEM_CHECK) + self.toolsMenu.Append(menu_LINE, "Line", kind=wxITEM_CHECK) + self.toolsMenu.Append(menu_RECT, "Rectangle", kind=wxITEM_CHECK) + self.toolsMenu.Append(menu_ELLIPSE, "Ellipse", kind=wxITEM_CHECK) + self.toolsMenu.Append(menu_TEXT, "Text", kind=wxITEM_CHECK) + + menuBar.Append(self.toolsMenu, "Tools") + + self.objectMenu = wxMenu() + self.objectMenu.Append(menu_MOVE_FORWARD, "Move Forward") + self.objectMenu.Append(menu_MOVE_TO_FRONT, "Move to Front\tCTRL-F") + self.objectMenu.Append(menu_MOVE_BACKWARD, "Move Backward") + self.objectMenu.Append(menu_MOVE_TO_BACK, "Move to Back\tCTRL-B") + + menuBar.Append(self.objectMenu, "Object") + + self.helpMenu = wxMenu() + self.helpMenu.Append(menu_ABOUT, "About pySketch...") + + menuBar.Append(self.helpMenu, "Help") + + self.SetMenuBar(menuBar) + + # Create our toolbar. + + self.toolbar = self.CreateToolBar(wxTB_HORIZONTAL | + wxNO_BORDER | wxTB_FLAT) + + self.toolbar.AddSimpleTool(wxID_NEW, + wxBitmap("images/new.bmp", + wxBITMAP_TYPE_BMP), + "New") + self.toolbar.AddSimpleTool(wxID_OPEN, + wxBitmap("images/open.bmp", + wxBITMAP_TYPE_BMP), + "Open") + self.toolbar.AddSimpleTool(wxID_SAVE, + wxBitmap("images/save.bmp", + wxBITMAP_TYPE_BMP), + "Save") + self.toolbar.AddSeparator() + self.toolbar.AddSimpleTool(menu_UNDO, + wxBitmap("images/undo.bmp", + wxBITMAP_TYPE_BMP), + "Undo") + self.toolbar.AddSeparator() + self.toolbar.AddSimpleTool(menu_DUPLICATE, + wxBitmap("images/duplicate.bmp", + wxBITMAP_TYPE_BMP), + "Duplicate") + self.toolbar.AddSeparator() + self.toolbar.AddSimpleTool(menu_MOVE_FORWARD, + wxBitmap("images/moveForward.bmp", + wxBITMAP_TYPE_BMP), + "Move Forward") + self.toolbar.AddSimpleTool(menu_MOVE_BACKWARD, + wxBitmap("images/moveBack.bmp", + wxBITMAP_TYPE_BMP), + "Move Backward") + + self.toolbar.Realize() + + # Associate each menu/toolbar item with the method that handles that + # item. + + EVT_MENU(self, wxID_NEW, self.doNew) + EVT_MENU(self, wxID_OPEN, self.doOpen) + EVT_MENU(self, wxID_CLOSE, self.doClose) + EVT_MENU(self, wxID_SAVE, self.doSave) + EVT_MENU(self, wxID_SAVEAS, self.doSaveAs) + EVT_MENU(self, wxID_REVERT, self.doRevert) + EVT_MENU(self, wxID_EXIT, self.doExit) + + EVT_MENU(self, menu_UNDO, self.doUndo) + EVT_MENU(self, menu_SELECT_ALL, self.doSelectAll) + EVT_MENU(self, menu_DUPLICATE, self.doDuplicate) + EVT_MENU(self, menu_EDIT_TEXT, self.doEditText) + EVT_MENU(self, menu_DELETE, self.doDelete) + + EVT_MENU(self, menu_SELECT, self.doChooseSelectTool) + EVT_MENU(self, menu_LINE, self.doChooseLineTool) + EVT_MENU(self, menu_RECT, self.doChooseRectTool) + EVT_MENU(self, menu_ELLIPSE, self.doChooseEllipseTool) + EVT_MENU(self, menu_TEXT, self.doChooseTextTool) + + EVT_MENU(self, menu_MOVE_FORWARD, self.doMoveForward) + EVT_MENU(self, menu_MOVE_TO_FRONT, self.doMoveToFront) + EVT_MENU(self, menu_MOVE_BACKWARD, self.doMoveBackward) + EVT_MENU(self, menu_MOVE_TO_BACK, self.doMoveToBack) + + EVT_MENU(self, menu_ABOUT, self.doShowAbout) + + # Install our own method to handle closing the window. This allows us + # to ask the user if he/she wants to save before closing the window, as + # well as keeping track of which windows are currently open. + + EVT_CLOSE(self, self.doClose) + + # Install our own method for handling keystrokes. We use this to let + # the user move the selected object(s) around using the arrow keys. + + EVT_CHAR_HOOK(self, self.onKeyEvent) + + # Setup our top-most panel. This holds the entire contents of the + # window, excluding the menu bar. + + self.topPanel = wxPanel(self, -1, style=wxSIMPLE_BORDER) + + # Setup our tool palette, with all our drawing tools and option icons. + + self.toolPalette = wxBoxSizer(wxVERTICAL) + + self.selectIcon = ToolPaletteIcon(self.topPanel, id_SELECT, + "select", "Selection Tool") + self.lineIcon = ToolPaletteIcon(self.topPanel, id_LINE, + "line", "Line Tool") + self.rectIcon = ToolPaletteIcon(self.topPanel, id_RECT, + "rect", "Rectangle Tool") + self.ellipseIcon = ToolPaletteIcon(self.topPanel, id_ELLIPSE, + "ellipse", "Ellipse Tool") + self.textIcon = ToolPaletteIcon(self.topPanel, id_TEXT, + "text", "Text Tool") + + toolSizer = wxGridSizer(0, 2, 5, 5) + toolSizer.Add(self.selectIcon) + toolSizer.Add(0, 0) # Gap to make tool icons line up nicely. + toolSizer.Add(self.lineIcon) + toolSizer.Add(self.rectIcon) + toolSizer.Add(self.ellipseIcon) + toolSizer.Add(self.textIcon) + + self.optionIndicator = ToolOptionIndicator(self.topPanel) + self.optionIndicator.SetToolTip( + wxToolTip("Shows Current Pen/Fill/Line Size Settings")) + + optionSizer = wxBoxSizer(wxHORIZONTAL) + + self.penOptIcon = ToolPaletteIcon(self.topPanel, id_PEN_OPT, + "penOpt", "Set Pen Colour") + self.fillOptIcon = ToolPaletteIcon(self.topPanel, id_FILL_OPT, + "fillOpt", "Set Fill Colour") + self.lineOptIcon = ToolPaletteIcon(self.topPanel, id_LINE_OPT, + "lineOpt", "Set Line Size") + + margin = wxLEFT | wxRIGHT + optionSizer.Add(self.penOptIcon, 0, margin, 1) + optionSizer.Add(self.fillOptIcon, 0, margin, 1) + optionSizer.Add(self.lineOptIcon, 0, margin, 1) + + margin = wxTOP | wxLEFT | wxRIGHT | wxALIGN_CENTRE + self.toolPalette.Add(toolSizer, 0, margin, 5) + self.toolPalette.Add(0, 0, 0, margin, 5) # Spacer. + self.toolPalette.Add(self.optionIndicator, 0, margin, 5) + self.toolPalette.Add(optionSizer, 0, margin, 5) - # Make the tool palette icons respond when the user clicks on them. + # Make the tool palette icons respond when the user clicks on them. - EVT_LEFT_DOWN(self.selectIcon, self.onToolIconClick) - EVT_LEFT_DOWN(self.lineIcon, self.onToolIconClick) - EVT_LEFT_DOWN(self.rectIcon, self.onToolIconClick) - EVT_LEFT_DOWN(self.ellipseIcon, self.onToolIconClick) - EVT_LEFT_DOWN(self.textIcon, self.onToolIconClick) - EVT_LEFT_DOWN(self.penOptIcon, self.onPenOptionIconClick) - EVT_LEFT_DOWN(self.fillOptIcon, self.onFillOptionIconClick) - EVT_LEFT_DOWN(self.lineOptIcon, self.onLineOptionIconClick) + EVT_LEFT_DOWN(self.selectIcon, self.onToolIconClick) + EVT_LEFT_DOWN(self.lineIcon, self.onToolIconClick) + EVT_LEFT_DOWN(self.rectIcon, self.onToolIconClick) + EVT_LEFT_DOWN(self.ellipseIcon, self.onToolIconClick) + EVT_LEFT_DOWN(self.textIcon, self.onToolIconClick) + EVT_LEFT_DOWN(self.penOptIcon, self.onPenOptionIconClick) + EVT_LEFT_DOWN(self.fillOptIcon, self.onFillOptionIconClick) + EVT_LEFT_DOWN(self.lineOptIcon, self.onLineOptionIconClick) - # Setup the main drawing area. + # Setup the main drawing area. - self.drawPanel = wxScrolledWindow(self.topPanel, -1, - style=wxSUNKEN_BORDER) - self.drawPanel.SetBackgroundColour(wxWHITE) + self.drawPanel = wxScrolledWindow(self.topPanel, -1, + style=wxSUNKEN_BORDER) + self.drawPanel.SetBackgroundColour(wxWHITE) - self.drawPanel.EnableScrolling(true, true) - self.drawPanel.SetScrollbars(20, 20, PAGE_WIDTH / 20, PAGE_HEIGHT / 20) + self.drawPanel.EnableScrolling(True, True) + self.drawPanel.SetScrollbars(20, 20, PAGE_WIDTH / 20, PAGE_HEIGHT / 20) - EVT_LEFT_DOWN(self.drawPanel, self.onMouseEvent) - EVT_LEFT_DCLICK(self.drawPanel, self.onDoubleClickEvent) - EVT_RIGHT_DOWN(self.drawPanel, self.onRightClick) - EVT_MOTION(self.drawPanel, self.onMouseEvent) - EVT_LEFT_UP(self.drawPanel, self.onMouseEvent) - EVT_PAINT(self.drawPanel, self.onPaintEvent) + EVT_LEFT_DOWN(self.drawPanel, self.onMouseEvent) + EVT_LEFT_DCLICK(self.drawPanel, self.onDoubleClickEvent) + EVT_RIGHT_DOWN(self.drawPanel, self.onRightClick) + EVT_MOTION(self.drawPanel, self.onMouseEvent) + EVT_LEFT_UP(self.drawPanel, self.onMouseEvent) + EVT_PAINT(self.drawPanel, self.onPaintEvent) - # Position everything in the window. + # Position everything in the window. - topSizer = wxBoxSizer(wxHORIZONTAL) - topSizer.Add(self.toolPalette, 0) - topSizer.Add(self.drawPanel, 1, wxEXPAND) + topSizer = wxBoxSizer(wxHORIZONTAL) + topSizer.Add(self.toolPalette, 0) + topSizer.Add(self.drawPanel, 1, wxEXPAND) - self.topPanel.SetAutoLayout(true) - self.topPanel.SetSizer(topSizer) + self.topPanel.SetAutoLayout(True) + self.topPanel.SetSizer(topSizer) - self.SetSizeHints(minW=250, minH=200) - self.SetSize(wxSize(600, 400)) + self.SetSizeHints(minW=250, minH=200) + self.SetSize(wxSize(600, 400)) - # Select an initial tool. + # Select an initial tool. - self.curTool = None - self._setCurrentTool(self.selectIcon) + self.curTool = None + self._setCurrentTool(self.selectIcon) - # Setup our frame to hold the contents of a sketch document. + # Setup our frame to hold the contents of a sketch document. - self.dirty = false - self.fileName = fileName - self.contents = [] # front-to-back ordered list of DrawingObjects. - self.selection = [] # List of selected DrawingObjects. - self.undoInfo = None # Saved contents for undo. - self.dragMode = drag_NONE # Current mouse-drag mode. + self.dirty = False + self.fileName = fileName + self.contents = [] # front-to-back ordered list of DrawingObjects. + self.selection = [] # List of selected DrawingObjects. + self.undoInfo = None # Saved contents for undo. + self.dragMode = drag_NONE # Current mouse-drag mode. - if self.fileName != None: - self.loadContents() - - self._adjustMenus() - - # Finally, set our initial pen, fill and line options. - - self.penColour = wxBLACK - self.fillColour = wxWHITE - self.lineSize = 1 + if self.fileName != None: + self.loadContents() + + self._adjustMenus() + + # Finally, set our initial pen, fill and line options. + + self.penColour = wxBLACK + self.fillColour = wxWHITE + self.lineSize = 1 # ============================ # == Event Handling Methods == # ============================ def onToolIconClick(self, event): - """ Respond to the user clicking on one of our tool icons. - """ - iconID = wxPyTypeCast(event.GetEventObject(), "wxWindow").GetId() - if iconID == id_SELECT: self.doChooseSelectTool() - elif iconID == id_LINE: self.doChooseLineTool() - elif iconID == id_RECT: self.doChooseRectTool() - elif iconID == id_ELLIPSE: self.doChooseEllipseTool() - elif iconID == id_TEXT: self.doChooseTextTool() - else: wxBell() + """ Respond to the user clicking on one of our tool icons. + """ + iconID = wxPyTypeCast(event.GetEventObject(), "wxWindow").GetId() + if iconID == id_SELECT: self.doChooseSelectTool() + elif iconID == id_LINE: self.doChooseLineTool() + elif iconID == id_RECT: self.doChooseRectTool() + elif iconID == id_ELLIPSE: self.doChooseEllipseTool() + elif iconID == id_TEXT: self.doChooseTextTool() + else: wxBell() def onPenOptionIconClick(self, event): - """ Respond to the user clicking on the "Pen Options" icon. - """ - data = wxColourData() - if len(self.selection) == 1: - data.SetColour(self.selection[0].getPenColour()) - else: - data.SetColour(self.penColour) - - dialog = wxColourDialog(self, data) - if dialog.ShowModal() == wxID_OK: - c = dialog.GetColourData().GetColour() - self._setPenColour(wxColour(c.Red(), c.Green(), c.Blue())) + """ Respond to the user clicking on the "Pen Options" icon. + """ + data = wxColourData() + if len(self.selection) == 1: + data.SetColour(self.selection[0].getPenColour()) + else: + data.SetColour(self.penColour) + + dialog = wxColourDialog(self, data) + if dialog.ShowModal() == wxID_OK: + c = dialog.GetColourData().GetColour() + self._setPenColour(wxColour(c.Red(), c.Green(), c.Blue())) dialog.Destroy() def onFillOptionIconClick(self, event): - """ Respond to the user clicking on the "Fill Options" icon. - """ - data = wxColourData() - if len(self.selection) == 1: - data.SetColour(self.selection[0].getFillColour()) - else: - data.SetColour(self.fillColour) - - dialog = wxColourDialog(self, data) - if dialog.ShowModal() == wxID_OK: - c = dialog.GetColourData().GetColour() - self._setFillColour(wxColour(c.Red(), c.Green(), c.Blue())) + """ Respond to the user clicking on the "Fill Options" icon. + """ + data = wxColourData() + if len(self.selection) == 1: + data.SetColour(self.selection[0].getFillColour()) + else: + data.SetColour(self.fillColour) + + dialog = wxColourDialog(self, data) + if dialog.ShowModal() == wxID_OK: + c = dialog.GetColourData().GetColour() + self._setFillColour(wxColour(c.Red(), c.Green(), c.Blue())) dialog.Destroy() def onLineOptionIconClick(self, event): - """ Respond to the user clicking on the "Line Options" icon. - """ - if len(self.selection) == 1: - menu = self._buildLineSizePopup(self.selection[0].getLineSize()) - else: - menu = self._buildLineSizePopup(self.lineSize) - - pos = self.lineOptIcon.GetPosition() - pos.y = pos.y + self.lineOptIcon.GetSize().height + """ Respond to the user clicking on the "Line Options" icon. + """ + if len(self.selection) == 1: + menu = self._buildLineSizePopup(self.selection[0].getLineSize()) + else: + menu = self._buildLineSizePopup(self.lineSize) + + pos = self.lineOptIcon.GetPosition() + pos.y = pos.y + self.lineOptIcon.GetSize().height self.PopupMenu(menu, pos) menu.Destroy() def onKeyEvent(self, event): - """ Respond to a keypress event. - - We make the arrow keys move the selected object(s) by one pixel in - the given direction. - """ - if event.GetKeyCode() == WXK_UP: - self._moveObject(0, -1) - elif event.GetKeyCode() == WXK_DOWN: - self._moveObject(0, 1) - elif event.GetKeyCode() == WXK_LEFT: - self._moveObject(-1, 0) - elif event.GetKeyCode() == WXK_RIGHT: - self._moveObject(1, 0) - else: - event.Skip() + """ Respond to a keypress event. + + We make the arrow keys move the selected object(s) by one pixel in + the given direction. + """ + if event.GetKeyCode() == WXK_UP: + self._moveObject(0, -1) + elif event.GetKeyCode() == WXK_DOWN: + self._moveObject(0, 1) + elif event.GetKeyCode() == WXK_LEFT: + self._moveObject(-1, 0) + elif event.GetKeyCode() == WXK_RIGHT: + self._moveObject(1, 0) + else: + event.Skip() def onMouseEvent(self, event): - """ Respond to the user clicking on our main drawing panel. - - How we respond depends on the currently selected tool. - """ - if not (event.LeftDown() or event.Dragging() or event.LeftUp()): - return # Ignore mouse movement without click/drag. - - if self.curTool == self.selectIcon: - feedbackType = feedback_RECT - action = self.selectByRectangle - actionParam = param_RECT - selecting = true - dashedLine = true - elif self.curTool == self.lineIcon: - feedbackType = feedback_LINE - action = self.createLine - actionParam = param_LINE - selecting = false - dashedLine = false - elif self.curTool == self.rectIcon: - feedbackType = feedback_RECT - action = self.createRect - actionParam = param_RECT - selecting = false - dashedLine = false - elif self.curTool == self.ellipseIcon: - feedbackType = feedback_ELLIPSE - action = self.createEllipse - actionParam = param_RECT - selecting = false - dashedLine = false - elif self.curTool == self.textIcon: - feedbackType = feedback_RECT - action = self.createText - actionParam = param_RECT - selecting = false - dashedLine = true - else: - wxBell() - return - - if event.LeftDown(): - mousePt = self._getEventCoordinates(event) - if selecting: - obj, handle = self._getObjectAndSelectionHandleAt(mousePt) - - if selecting and (obj != None) and (handle != handle_NONE): - - # The user clicked on an object's selection handle. Let the - # user resize the clicked-on object. - - self.dragMode = drag_RESIZE - self.resizeObject = obj - - if obj.getType() == obj_LINE: - self.resizeFeedback = feedback_LINE - pos = obj.getPosition() - startPt = wxPoint(pos.x + obj.getStartPt().x, - pos.y + obj.getStartPt().y) - endPt = wxPoint(pos.x + obj.getEndPt().x, - pos.y + obj.getEndPt().y) - if handle == handle_START_POINT: - self.resizeAnchor = endPt - self.resizeFloater = startPt - else: - self.resizeAnchor = startPt - self.resizeFloater = endPt - else: - self.resizeFeedback = feedback_RECT - pos = obj.getPosition() - size = obj.getSize() - topLeft = wxPoint(pos.x, pos.y) - topRight = wxPoint(pos.x + size.width, pos.y) - botLeft = wxPoint(pos.x, pos.y + size.height) - botRight = wxPoint(pos.x + size.width, pos.y + size.height) - - if handle == handle_TOP_LEFT: - self.resizeAnchor = botRight - self.resizeFloater = topLeft - elif handle == handle_TOP_RIGHT: - self.resizeAnchor = botLeft - self.resizeFloater = topRight - elif handle == handle_BOTTOM_LEFT: - self.resizeAnchor = topRight - self.resizeFloater = botLeft - elif handle == handle_BOTTOM_RIGHT: - self.resizeAnchor = topLeft - self.resizeFloater = botRight - - self.curPt = mousePt - self.resizeOffsetX = self.resizeFloater.x - mousePt.x - self.resizeOffsetY = self.resizeFloater.y - mousePt.y - endPt = wxPoint(self.curPt.x + self.resizeOffsetX, - self.curPt.y + self.resizeOffsetY) - self._drawVisualFeedback(self.resizeAnchor, endPt, - self.resizeFeedback, false) - - elif selecting and (self._getObjectAt(mousePt) != None): - - # The user clicked on an object to select it. If the user - # drags, he/she will move the object. - - self.select(self._getObjectAt(mousePt)) - self.dragMode = drag_MOVE - self.moveOrigin = mousePt - self.curPt = mousePt - self._drawObjectOutline(0, 0) - - else: - - # The user is dragging out a selection rect or new object. - - self.dragOrigin = mousePt - self.curPt = mousePt - self.drawPanel.SetCursor(wxCROSS_CURSOR) - self.drawPanel.CaptureMouse() - self._drawVisualFeedback(mousePt, mousePt, feedbackType, - dashedLine) - self.dragMode = drag_DRAG - - event.Skip() - return - - if event.Dragging(): - if self.dragMode == drag_RESIZE: - - # We're resizing an object. - - mousePt = self._getEventCoordinates(event) - if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y): - # Erase previous visual feedback. - endPt = wxPoint(self.curPt.x + self.resizeOffsetX, - self.curPt.y + self.resizeOffsetY) - self._drawVisualFeedback(self.resizeAnchor, endPt, - self.resizeFeedback, false) - self.curPt = mousePt - # Draw new visual feedback. - endPt = wxPoint(self.curPt.x + self.resizeOffsetX, - self.curPt.y + self.resizeOffsetY) - self._drawVisualFeedback(self.resizeAnchor, endPt, - self.resizeFeedback, false) - - elif self.dragMode == drag_MOVE: - - # We're moving a selected object. - - mousePt = self._getEventCoordinates(event) - if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y): - # Erase previous visual feedback. - self._drawObjectOutline(self.curPt.x - self.moveOrigin.x, - self.curPt.y - self.moveOrigin.y) - self.curPt = mousePt - # Draw new visual feedback. - self._drawObjectOutline(self.curPt.x - self.moveOrigin.x, - self.curPt.y - self.moveOrigin.y) - - elif self.dragMode == drag_DRAG: - - # We're dragging out a new object or selection rect. - - mousePt = self._getEventCoordinates(event) - if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y): - # Erase previous visual feedback. - self._drawVisualFeedback(self.dragOrigin, self.curPt, - feedbackType, dashedLine) - self.curPt = mousePt - # Draw new visual feedback. - self._drawVisualFeedback(self.dragOrigin, self.curPt, - feedbackType, dashedLine) - - event.Skip() - return - - if event.LeftUp(): - if self.dragMode == drag_RESIZE: - - # We're resizing an object. - - mousePt = self._getEventCoordinates(event) - # Erase last visual feedback. - endPt = wxPoint(self.curPt.x + self.resizeOffsetX, - self.curPt.y + self.resizeOffsetY) - self._drawVisualFeedback(self.resizeAnchor, endPt, - self.resizeFeedback, false) - - resizePt = wxPoint(mousePt.x + self.resizeOffsetX, - mousePt.y + self.resizeOffsetY) - - if (self.resizeFloater.x != resizePt.x) or \ - (self.resizeFloater.y != resizePt.y): - self._resizeObject(self.resizeObject, - self.resizeAnchor, - self.resizeFloater, - resizePt) - else: - self.drawPanel.Refresh() # Clean up after empty resize. - - elif self.dragMode == drag_MOVE: - - # We're moving a selected object. - - mousePt = self._getEventCoordinates(event) - # Erase last visual feedback. - self._drawObjectOutline(self.curPt.x - self.moveOrigin.x, - self.curPt.y - self.moveOrigin.y) - if (self.moveOrigin.x != mousePt.x) or \ - (self.moveOrigin.y != mousePt.y): - self._moveObject(mousePt.x - self.moveOrigin.x, - mousePt.y - self.moveOrigin.y) - else: - self.drawPanel.Refresh() # Clean up after empty drag. - - elif self.dragMode == drag_DRAG: - - # We're dragging out a new object or selection rect. - - mousePt = self._getEventCoordinates(event) - # Erase last visual feedback. - self._drawVisualFeedback(self.dragOrigin, self.curPt, - feedbackType, dashedLine) - self.drawPanel.ReleaseMouse() - self.drawPanel.SetCursor(wxSTANDARD_CURSOR) - # Perform the appropriate action for the current tool. - if actionParam == param_RECT: - x1 = min(self.dragOrigin.x, self.curPt.x) - y1 = min(self.dragOrigin.y, self.curPt.y) - x2 = max(self.dragOrigin.x, self.curPt.x) - y2 = max(self.dragOrigin.y, self.curPt.y) - - startX = x1 - startY = y1 - width = x2 - x1 - height = y2 - y1 - - if not selecting: - if ((x2-x1) < 8) or ((y2-y1) < 8): return # Too small. - - action(x1, y1, x2-x1, y2-y1) - elif actionParam == param_LINE: - action(self.dragOrigin.x, self.dragOrigin.y, - self.curPt.x, self.curPt.y) - - self.dragMode = drag_NONE # We've finished with this mouse event. - event.Skip() + """ Respond to the user clicking on our main drawing panel. + + How we respond depends on the currently selected tool. + """ + if not (event.LeftDown() or event.Dragging() or event.LeftUp()): + return # Ignore mouse movement without click/drag. + + if self.curTool == self.selectIcon: + feedbackType = feedback_RECT + action = self.selectByRectangle + actionParam = param_RECT + selecting = True + dashedLine = True + elif self.curTool == self.lineIcon: + feedbackType = feedback_LINE + action = self.createLine + actionParam = param_LINE + selecting = False + dashedLine = False + elif self.curTool == self.rectIcon: + feedbackType = feedback_RECT + action = self.createRect + actionParam = param_RECT + selecting = False + dashedLine = False + elif self.curTool == self.ellipseIcon: + feedbackType = feedback_ELLIPSE + action = self.createEllipse + actionParam = param_RECT + selecting = False + dashedLine = False + elif self.curTool == self.textIcon: + feedbackType = feedback_RECT + action = self.createText + actionParam = param_RECT + selecting = False + dashedLine = True + else: + wxBell() + return + + if event.LeftDown(): + mousePt = self._getEventCoordinates(event) + if selecting: + obj, handle = self._getObjectAndSelectionHandleAt(mousePt) + + if selecting and (obj != None) and (handle != handle_NONE): + + # The user clicked on an object's selection handle. Let the + # user resize the clicked-on object. + + self.dragMode = drag_RESIZE + self.resizeObject = obj + + if obj.getType() == obj_LINE: + self.resizeFeedback = feedback_LINE + pos = obj.getPosition() + startPt = wxPoint(pos.x + obj.getStartPt().x, + pos.y + obj.getStartPt().y) + endPt = wxPoint(pos.x + obj.getEndPt().x, + pos.y + obj.getEndPt().y) + if handle == handle_START_POINT: + self.resizeAnchor = endPt + self.resizeFloater = startPt + else: + self.resizeAnchor = startPt + self.resizeFloater = endPt + else: + self.resizeFeedback = feedback_RECT + pos = obj.getPosition() + size = obj.getSize() + topLeft = wxPoint(pos.x, pos.y) + topRight = wxPoint(pos.x + size.width, pos.y) + botLeft = wxPoint(pos.x, pos.y + size.height) + botRight = wxPoint(pos.x + size.width, pos.y + size.height) + + if handle == handle_TOP_LEFT: + self.resizeAnchor = botRight + self.resizeFloater = topLeft + elif handle == handle_TOP_RIGHT: + self.resizeAnchor = botLeft + self.resizeFloater = topRight + elif handle == handle_BOTTOM_LEFT: + self.resizeAnchor = topRight + self.resizeFloater = botLeft + elif handle == handle_BOTTOM_RIGHT: + self.resizeAnchor = topLeft + self.resizeFloater = botRight + + self.curPt = mousePt + self.resizeOffsetX = self.resizeFloater.x - mousePt.x + self.resizeOffsetY = self.resizeFloater.y - mousePt.y + endPt = wxPoint(self.curPt.x + self.resizeOffsetX, + self.curPt.y + self.resizeOffsetY) + self._drawVisualFeedback(self.resizeAnchor, endPt, + self.resizeFeedback, False) + + elif selecting and (self._getObjectAt(mousePt) != None): + + # The user clicked on an object to select it. If the user + # drags, he/she will move the object. + + self.select(self._getObjectAt(mousePt)) + self.dragMode = drag_MOVE + self.moveOrigin = mousePt + self.curPt = mousePt + self._drawObjectOutline(0, 0) + + else: + + # The user is dragging out a selection rect or new object. + + self.dragOrigin = mousePt + self.curPt = mousePt + self.drawPanel.SetCursor(wxCROSS_CURSOR) + self.drawPanel.CaptureMouse() + self._drawVisualFeedback(mousePt, mousePt, feedbackType, + dashedLine) + self.dragMode = drag_DRAG + + event.Skip() + return + + if event.Dragging(): + if self.dragMode == drag_RESIZE: + + # We're resizing an object. + + mousePt = self._getEventCoordinates(event) + if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y): + # Erase previous visual feedback. + endPt = wxPoint(self.curPt.x + self.resizeOffsetX, + self.curPt.y + self.resizeOffsetY) + self._drawVisualFeedback(self.resizeAnchor, endPt, + self.resizeFeedback, False) + self.curPt = mousePt + # Draw new visual feedback. + endPt = wxPoint(self.curPt.x + self.resizeOffsetX, + self.curPt.y + self.resizeOffsetY) + self._drawVisualFeedback(self.resizeAnchor, endPt, + self.resizeFeedback, False) + + elif self.dragMode == drag_MOVE: + + # We're moving a selected object. + + mousePt = self._getEventCoordinates(event) + if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y): + # Erase previous visual feedback. + self._drawObjectOutline(self.curPt.x - self.moveOrigin.x, + self.curPt.y - self.moveOrigin.y) + self.curPt = mousePt + # Draw new visual feedback. + self._drawObjectOutline(self.curPt.x - self.moveOrigin.x, + self.curPt.y - self.moveOrigin.y) + + elif self.dragMode == drag_DRAG: + + # We're dragging out a new object or selection rect. + + mousePt = self._getEventCoordinates(event) + if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y): + # Erase previous visual feedback. + self._drawVisualFeedback(self.dragOrigin, self.curPt, + feedbackType, dashedLine) + self.curPt = mousePt + # Draw new visual feedback. + self._drawVisualFeedback(self.dragOrigin, self.curPt, + feedbackType, dashedLine) + + event.Skip() + return + + if event.LeftUp(): + if self.dragMode == drag_RESIZE: + + # We're resizing an object. + + mousePt = self._getEventCoordinates(event) + # Erase last visual feedback. + endPt = wxPoint(self.curPt.x + self.resizeOffsetX, + self.curPt.y + self.resizeOffsetY) + self._drawVisualFeedback(self.resizeAnchor, endPt, + self.resizeFeedback, False) + + resizePt = wxPoint(mousePt.x + self.resizeOffsetX, + mousePt.y + self.resizeOffsetY) + + if (self.resizeFloater.x != resizePt.x) or \ + (self.resizeFloater.y != resizePt.y): + self._resizeObject(self.resizeObject, + self.resizeAnchor, + self.resizeFloater, + resizePt) + else: + self.drawPanel.Refresh() # Clean up after empty resize. + + elif self.dragMode == drag_MOVE: + + # We're moving a selected object. + + mousePt = self._getEventCoordinates(event) + # Erase last visual feedback. + self._drawObjectOutline(self.curPt.x - self.moveOrigin.x, + self.curPt.y - self.moveOrigin.y) + if (self.moveOrigin.x != mousePt.x) or \ + (self.moveOrigin.y != mousePt.y): + self._moveObject(mousePt.x - self.moveOrigin.x, + mousePt.y - self.moveOrigin.y) + else: + self.drawPanel.Refresh() # Clean up after empty drag. + + elif self.dragMode == drag_DRAG: + + # We're dragging out a new object or selection rect. + + mousePt = self._getEventCoordinates(event) + # Erase last visual feedback. + self._drawVisualFeedback(self.dragOrigin, self.curPt, + feedbackType, dashedLine) + self.drawPanel.ReleaseMouse() + self.drawPanel.SetCursor(wxSTANDARD_CURSOR) + # Perform the appropriate action for the current tool. + if actionParam == param_RECT: + x1 = min(self.dragOrigin.x, self.curPt.x) + y1 = min(self.dragOrigin.y, self.curPt.y) + x2 = max(self.dragOrigin.x, self.curPt.x) + y2 = max(self.dragOrigin.y, self.curPt.y) + + startX = x1 + startY = y1 + width = x2 - x1 + height = y2 - y1 + + if not selecting: + if ((x2-x1) < 8) or ((y2-y1) < 8): return # Too small. + + action(x1, y1, x2-x1, y2-y1) + elif actionParam == param_LINE: + action(self.dragOrigin.x, self.dragOrigin.y, + self.curPt.x, self.curPt.y) + + self.dragMode = drag_NONE # We've finished with this mouse event. + event.Skip() def onDoubleClickEvent(self, event): - """ Respond to a double-click within our drawing panel. - """ - mousePt = self._getEventCoordinates(event) - obj = self._getObjectAt(mousePt) - if obj == None: return + """ Respond to a double-click within our drawing panel. + """ + mousePt = self._getEventCoordinates(event) + obj = self._getObjectAt(mousePt) + if obj == None: return - # Let the user edit the given object. + # Let the user edit the given object. - if obj.getType() == obj_TEXT: - editor = EditTextObjectDialog(self, "Edit Text Object") - editor.objectToDialog(obj) - if editor.ShowModal() == wxID_CANCEL: - editor.Destroy() - return + if obj.getType() == obj_TEXT: + editor = EditTextObjectDialog(self, "Edit Text Object") + editor.objectToDialog(obj) + if editor.ShowModal() == wxID_CANCEL: + editor.Destroy() + return - self._saveUndoInfo() + self._saveUndoInfo() - editor.dialogToObject(obj) - editor.Destroy() + editor.dialogToObject(obj) + editor.Destroy() - self.dirty = true - self.drawPanel.Refresh() - self._adjustMenus() - else: - wxBell() + self.dirty = True + self.drawPanel.Refresh() + self._adjustMenus() + else: + wxBell() def onRightClick(self, event): - """ Respond to the user right-clicking within our drawing panel. - - We select the clicked-on item, if necessary, and display a pop-up - menu of available options which can be applied to the selected - item(s). - """ - mousePt = self._getEventCoordinates(event) - obj = self._getObjectAt(mousePt) - - if obj == None: return # Nothing selected. - - # Select the clicked-on object. - - self.select(obj) - - # Build our pop-up menu. - - menu = wxMenu() - menu.Append(menu_DUPLICATE, "Duplicate") - menu.Append(menu_EDIT_TEXT, "Edit...") - menu.Append(menu_DELETE, "Delete") - menu.AppendSeparator() - menu.Append(menu_MOVE_FORWARD, "Move Forward") - menu.Append(menu_MOVE_TO_FRONT, "Move to Front") - menu.Append(menu_MOVE_BACKWARD, "Move Backward") - menu.Append(menu_MOVE_TO_BACK, "Move to Back") - - menu.Enable(menu_EDIT_TEXT, obj.getType() == obj_TEXT) - menu.Enable(menu_MOVE_FORWARD, obj != self.contents[0]) - menu.Enable(menu_MOVE_TO_FRONT, obj != self.contents[0]) - menu.Enable(menu_MOVE_BACKWARD, obj != self.contents[-1]) - menu.Enable(menu_MOVE_TO_BACK, obj != self.contents[-1]) - - EVT_MENU(self, menu_DUPLICATE, self.doDuplicate) - EVT_MENU(self, menu_EDIT_TEXT, self.doEditText) - EVT_MENU(self, menu_DELETE, self.doDelete) - EVT_MENU(self, menu_MOVE_FORWARD, self.doMoveForward) - EVT_MENU(self, menu_MOVE_TO_FRONT, self.doMoveToFront) - EVT_MENU(self, menu_MOVE_BACKWARD, self.doMoveBackward) - EVT_MENU(self, menu_MOVE_TO_BACK, self.doMoveToBack) - - # Show the pop-up menu. - - clickPt = wxPoint(mousePt.x + self.drawPanel.GetPosition().x, - mousePt.y + self.drawPanel.GetPosition().y) - self.drawPanel.PopupMenu(menu, clickPt) - menu.Destroy() + """ Respond to the user right-clicking within our drawing panel. + + We select the clicked-on item, if necessary, and display a pop-up + menu of available options which can be applied to the selected + item(s). + """ + mousePt = self._getEventCoordinates(event) + obj = self._getObjectAt(mousePt) + + if obj == None: return # Nothing selected. + + # Select the clicked-on object. + + self.select(obj) + + # Build our pop-up menu. + + menu = wxMenu() + menu.Append(menu_DUPLICATE, "Duplicate") + menu.Append(menu_EDIT_TEXT, "Edit...") + menu.Append(menu_DELETE, "Delete") + menu.AppendSeparator() + menu.Append(menu_MOVE_FORWARD, "Move Forward") + menu.Append(menu_MOVE_TO_FRONT, "Move to Front") + menu.Append(menu_MOVE_BACKWARD, "Move Backward") + menu.Append(menu_MOVE_TO_BACK, "Move to Back") + + menu.Enable(menu_EDIT_TEXT, obj.getType() == obj_TEXT) + menu.Enable(menu_MOVE_FORWARD, obj != self.contents[0]) + menu.Enable(menu_MOVE_TO_FRONT, obj != self.contents[0]) + menu.Enable(menu_MOVE_BACKWARD, obj != self.contents[-1]) + menu.Enable(menu_MOVE_TO_BACK, obj != self.contents[-1]) + + EVT_MENU(self, menu_DUPLICATE, self.doDuplicate) + EVT_MENU(self, menu_EDIT_TEXT, self.doEditText) + EVT_MENU(self, menu_DELETE, self.doDelete) + EVT_MENU(self, menu_MOVE_FORWARD, self.doMoveForward) + EVT_MENU(self, menu_MOVE_TO_FRONT, self.doMoveToFront) + EVT_MENU(self, menu_MOVE_BACKWARD, self.doMoveBackward) + EVT_MENU(self, menu_MOVE_TO_BACK, self.doMoveToBack) + + # Show the pop-up menu. + + clickPt = wxPoint(mousePt.x + self.drawPanel.GetPosition().x, + mousePt.y + self.drawPanel.GetPosition().y) + self.drawPanel.PopupMenu(menu, clickPt) + menu.Destroy() def onPaintEvent(self, event): - """ Respond to a request to redraw the contents of our drawing panel. - """ - dc = wxPaintDC(self.drawPanel) - self.drawPanel.PrepareDC(dc) - dc.BeginDrawing() + """ Respond to a request to redraw the contents of our drawing panel. + """ + dc = wxPaintDC(self.drawPanel) + self.drawPanel.PrepareDC(dc) + dc.BeginDrawing() - for i in range(len(self.contents)-1, -1, -1): - obj = self.contents[i] - if obj in self.selection: - obj.draw(dc, true) - else: - obj.draw(dc, false) + for i in range(len(self.contents)-1, -1, -1): + obj = self.contents[i] + if obj in self.selection: + obj.draw(dc, True) + else: + obj.draw(dc, False) - dc.EndDrawing() + dc.EndDrawing() # ========================== # == Menu Command Methods == # ========================== def doNew(self, event): - """ Respond to the "New" menu command. - """ - global _docList - newFrame = DrawingFrame(None, -1, "Untitled") - newFrame.Show(TRUE) - _docList.append(newFrame) + """ Respond to the "New" menu command. + """ + global _docList + newFrame = DrawingFrame(None, -1, "Untitled") + newFrame.Show(True) + _docList.append(newFrame) def doOpen(self, event): - """ Respond to the "Open" menu command. - """ - global _docList - - curDir = os.getcwd() - fileName = wxFileSelector("Open File", default_extension="psk", - flags = wxOPEN | wxFILE_MUST_EXIST) - if fileName == "": return - fileName = os.path.join(os.getcwd(), fileName) - os.chdir(curDir) - - title = os.path.basename(fileName) - - if (self.fileName == None) and (len(self.contents) == 0): - # Load contents into current (empty) document. - self.fileName = fileName - self.SetTitle(os.path.basename(fileName)) - self.loadContents() - else: - # Open a new frame for this document. - newFrame = DrawingFrame(None, -1, os.path.basename(fileName), - fileName=fileName) - newFrame.Show(true) - _docList.append(newFrame) + """ Respond to the "Open" menu command. + """ + global _docList + + curDir = os.getcwd() + fileName = wxFileSelector("Open File", default_extension="psk", + flags = wxOPEN | wxFILE_MUST_EXIST) + if fileName == "": return + fileName = os.path.join(os.getcwd(), fileName) + os.chdir(curDir) + + title = os.path.basename(fileName) + + if (self.fileName == None) and (len(self.contents) == 0): + # Load contents into current (empty) document. + self.fileName = fileName + self.SetTitle(os.path.basename(fileName)) + self.loadContents() + else: + # Open a new frame for this document. + newFrame = DrawingFrame(None, -1, os.path.basename(fileName), + fileName=fileName) + newFrame.Show(True) + _docList.append(newFrame) def doClose(self, event): - """ Respond to the "Close" menu command. - """ - global _docList + """ Respond to the "Close" menu command. + """ + global _docList - if self.dirty: - if not self.askIfUserWantsToSave("closing"): return + if self.dirty: + if not self.askIfUserWantsToSave("closing"): return - _docList.remove(self) - self.Destroy() + _docList.remove(self) + self.Destroy() def doSave(self, event): - """ Respond to the "Save" menu command. - """ - if self.fileName != None: - self.saveContents() + """ Respond to the "Save" menu command. + """ + if self.fileName != None: + self.saveContents() def doSaveAs(self, event): - """ Respond to the "Save As" menu command. - """ - if self.fileName == None: - default = "" - else: - default = self.fileName - - curDir = os.getcwd() - fileName = wxFileSelector("Save File As", "Saving", - default_filename=default, - default_extension="psk", - wildcard="*.psk", - flags = wxSAVE | wxOVERWRITE_PROMPT) - if fileName == "": return # User cancelled. - fileName = os.path.join(os.getcwd(), fileName) - os.chdir(curDir) - - title = os.path.basename(fileName) - self.SetTitle(title) - - self.fileName = fileName - self.saveContents() + """ Respond to the "Save As" menu command. + """ + if self.fileName == None: + default = "" + else: + default = self.fileName + + curDir = os.getcwd() + fileName = wxFileSelector("Save File As", "Saving", + default_filename=default, + default_extension="psk", + wildcard="*.psk", + flags = wxSAVE | wxOVERWRITE_PROMPT) + if fileName == "": return # User cancelled. + fileName = os.path.join(os.getcwd(), fileName) + os.chdir(curDir) + + title = os.path.basename(fileName) + self.SetTitle(title) + + self.fileName = fileName + self.saveContents() def doRevert(self, event): - """ Respond to the "Revert" menu command. - """ - if not self.dirty: return + """ Respond to the "Revert" menu command. + """ + if not self.dirty: return - if wxMessageBox("Discard changes made to this document?", "Confirm", - style = wxOK | wxCANCEL | wxICON_QUESTION, - parent=self) == wxCANCEL: return - self.loadContents() + if wxMessageBox("Discard changes made to this document?", "Confirm", + style = wxOK | wxCANCEL | wxICON_QUESTION, + parent=self) == wxCANCEL: return + self.loadContents() def doExit(self, event): - """ Respond to the "Quit" menu command. - """ - global _docList, _app - for doc in _docList: - if not doc.dirty: continue - doc.Raise() - if not doc.askIfUserWantsToSave("quitting"): return - _docList.remove(doc) - doc.Destroy() + """ Respond to the "Quit" menu command. + """ + global _docList, _app + for doc in _docList: + if not doc.dirty: continue + doc.Raise() + if not doc.askIfUserWantsToSave("quitting"): return + _docList.remove(doc) + doc.Destroy() - _app.ExitMainLoop() + _app.ExitMainLoop() def doUndo(self, event): - """ Respond to the "Undo" menu command. - """ - if self.undoInfo == None: return + """ Respond to the "Undo" menu command. + """ + if self.undoInfo == None: return - undoData = self.undoInfo - self._saveUndoInfo() # For undoing the undo... + undoData = self.undoInfo + self._saveUndoInfo() # For undoing the undo... - self.contents = [] + self.contents = [] - for type, data in undoData["contents"]: - obj = DrawingObject(type) - obj.setData(data) - self.contents.append(obj) + for type, data in undoData["contents"]: + obj = DrawingObject(type) + obj.setData(data) + self.contents.append(obj) - self.selection = [] - for i in undoData["selection"]: - self.selection.append(self.contents[i]) + self.selection = [] + for i in undoData["selection"]: + self.selection.append(self.contents[i]) - self.dirty = true - self.drawPanel.Refresh() - self._adjustMenus() + self.dirty = True + self.drawPanel.Refresh() + self._adjustMenus() def doSelectAll(self, event): - """ Respond to the "Select All" menu command. - """ - self.selectAll() + """ Respond to the "Select All" menu command. + """ + self.selectAll() def doDuplicate(self, event): - """ Respond to the "Duplicate" menu command. - """ - self._saveUndoInfo() + """ Respond to the "Duplicate" menu command. + """ + self._saveUndoInfo() - objs = [] - for obj in self.contents: - if obj in self.selection: - newObj = DrawingObject(obj.getType()) - newObj.setData(obj.getData()) - pos = obj.getPosition() - newObj.setPosition(wxPoint(pos.x + 10, pos.y + 10)) - objs.append(newObj) + objs = [] + for obj in self.contents: + if obj in self.selection: + newObj = DrawingObject(obj.getType()) + newObj.setData(obj.getData()) + pos = obj.getPosition() + newObj.setPosition(wxPoint(pos.x + 10, pos.y + 10)) + objs.append(newObj) - self.contents = objs + self.contents + self.contents = objs + self.contents - self.selectMany(objs) + self.selectMany(objs) def doEditText(self, event): - """ Respond to the "Edit Text" menu command. - """ - if len(self.selection) != 1: return + """ Respond to the "Edit Text" menu command. + """ + if len(self.selection) != 1: return - obj = self.selection[0] - if obj.getType() != obj_TEXT: return + obj = self.selection[0] + if obj.getType() != obj_TEXT: return - editor = EditTextObjectDialog(self, "Edit Text Object") - editor.objectToDialog(obj) - if editor.ShowModal() == wxID_CANCEL: - editor.Destroy() - return + editor = EditTextObjectDialog(self, "Edit Text Object") + editor.objectToDialog(obj) + if editor.ShowModal() == wxID_CANCEL: + editor.Destroy() + return - self._saveUndoInfo() + self._saveUndoInfo() - editor.dialogToObject(obj) - editor.Destroy() + editor.dialogToObject(obj) + editor.Destroy() - self.dirty = true - self.drawPanel.Refresh() - self._adjustMenus() + self.dirty = True + self.drawPanel.Refresh() + self._adjustMenus() def doDelete(self, event): - """ Respond to the "Delete" menu command. - """ - self._saveUndoInfo() + """ Respond to the "Delete" menu command. + """ + self._saveUndoInfo() - for obj in self.selection: - self.contents.remove(obj) - del obj - self.deselectAll() + for obj in self.selection: + self.contents.remove(obj) + del obj + self.deselectAll() def doChooseSelectTool(self, event=None): - """ Respond to the "Select Tool" menu command. - """ - self._setCurrentTool(self.selectIcon) - self.drawPanel.SetCursor(wxSTANDARD_CURSOR) - self._adjustMenus() + """ Respond to the "Select Tool" menu command. + """ + self._setCurrentTool(self.selectIcon) + self.drawPanel.SetCursor(wxSTANDARD_CURSOR) + self._adjustMenus() def doChooseLineTool(self, event=None): - """ Respond to the "Line Tool" menu command. - """ - self._setCurrentTool(self.lineIcon) - self.drawPanel.SetCursor(wxCROSS_CURSOR) - self.deselectAll() - self._adjustMenus() + """ Respond to the "Line Tool" menu command. + """ + self._setCurrentTool(self.lineIcon) + self.drawPanel.SetCursor(wxCROSS_CURSOR) + self.deselectAll() + self._adjustMenus() def doChooseRectTool(self, event=None): - """ Respond to the "Rect Tool" menu command. - """ - self._setCurrentTool(self.rectIcon) - self.drawPanel.SetCursor(wxCROSS_CURSOR) - self.deselectAll() - self._adjustMenus() + """ Respond to the "Rect Tool" menu command. + """ + self._setCurrentTool(self.rectIcon) + self.drawPanel.SetCursor(wxCROSS_CURSOR) + self.deselectAll() + self._adjustMenus() def doChooseEllipseTool(self, event=None): - """ Respond to the "Ellipse Tool" menu command. - """ - self._setCurrentTool(self.ellipseIcon) - self.drawPanel.SetCursor(wxCROSS_CURSOR) - self.deselectAll() - self._adjustMenus() + """ Respond to the "Ellipse Tool" menu command. + """ + self._setCurrentTool(self.ellipseIcon) + self.drawPanel.SetCursor(wxCROSS_CURSOR) + self.deselectAll() + self._adjustMenus() def doChooseTextTool(self, event=None): - """ Respond to the "Text Tool" menu command. - """ - self._setCurrentTool(self.textIcon) - self.drawPanel.SetCursor(wxCROSS_CURSOR) - self.deselectAll() - self._adjustMenus() + """ Respond to the "Text Tool" menu command. + """ + self._setCurrentTool(self.textIcon) + self.drawPanel.SetCursor(wxCROSS_CURSOR) + self.deselectAll() + self._adjustMenus() def doMoveForward(self, event): - """ Respond to the "Move Forward" menu command. - """ - if len(self.selection) != 1: return + """ Respond to the "Move Forward" menu command. + """ + if len(self.selection) != 1: return - self._saveUndoInfo() + self._saveUndoInfo() - obj = self.selection[0] - index = self.contents.index(obj) - if index == 0: return + obj = self.selection[0] + index = self.contents.index(obj) + if index == 0: return - del self.contents[index] - self.contents.insert(index-1, obj) + del self.contents[index] + self.contents.insert(index-1, obj) - self.drawPanel.Refresh() - self._adjustMenus() + self.drawPanel.Refresh() + self._adjustMenus() def doMoveToFront(self, event): - """ Respond to the "Move to Front" menu command. - """ - if len(self.selection) != 1: return + """ Respond to the "Move to Front" menu command. + """ + if len(self.selection) != 1: return - self._saveUndoInfo() + self._saveUndoInfo() - obj = self.selection[0] - self.contents.remove(obj) - self.contents.insert(0, obj) + obj = self.selection[0] + self.contents.remove(obj) + self.contents.insert(0, obj) - self.drawPanel.Refresh() - self._adjustMenus() + self.drawPanel.Refresh() + self._adjustMenus() def doMoveBackward(self, event): - """ Respond to the "Move Backward" menu command. - """ - if len(self.selection) != 1: return + """ Respond to the "Move Backward" menu command. + """ + if len(self.selection) != 1: return - self._saveUndoInfo() + self._saveUndoInfo() - obj = self.selection[0] - index = self.contents.index(obj) - if index == len(self.contents) - 1: return + obj = self.selection[0] + index = self.contents.index(obj) + if index == len(self.contents) - 1: return - del self.contents[index] - self.contents.insert(index+1, obj) + del self.contents[index] + self.contents.insert(index+1, obj) - self.drawPanel.Refresh() - self._adjustMenus() + self.drawPanel.Refresh() + self._adjustMenus() def doMoveToBack(self, event): - """ Respond to the "Move to Back" menu command. - """ - if len(self.selection) != 1: return + """ Respond to the "Move to Back" menu command. + """ + if len(self.selection) != 1: return - self._saveUndoInfo() + self._saveUndoInfo() - obj = self.selection[0] - self.contents.remove(obj) - self.contents.append(obj) + obj = self.selection[0] + self.contents.remove(obj) + self.contents.append(obj) - self.drawPanel.Refresh() - self._adjustMenus() + self.drawPanel.Refresh() + self._adjustMenus() def doShowAbout(self, event): - """ Respond to the "About pySketch" menu command. - """ - dialog = wxDialog(self, -1, "About pySketch") # , - #style=wxDIALOG_MODAL | wxSTAY_ON_TOP) - dialog.SetBackgroundColour(wxWHITE) - - panel = wxPanel(dialog, -1) - panel.SetBackgroundColour(wxWHITE) - - panelSizer = wxBoxSizer(wxVERTICAL) - - boldFont = wxFont(panel.GetFont().GetPointSize(), - panel.GetFont().GetFamily(), - wxNORMAL, wxBOLD) - - logo = wxStaticBitmap(panel, -1, wxBitmap("images/logo.bmp", - wxBITMAP_TYPE_BMP)) - - lab1 = wxStaticText(panel, -1, "pySketch") - lab1.SetFont(wxFont(36, boldFont.GetFamily(), wxITALIC, wxBOLD)) - lab1.SetSize(lab1.GetBestSize()) - - imageSizer = wxBoxSizer(wxHORIZONTAL) - imageSizer.Add(logo, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5) - imageSizer.Add(lab1, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5) - - lab2 = wxStaticText(panel, -1, "A simple object-oriented drawing " + \ - "program.") - lab2.SetFont(boldFont) - lab2.SetSize(lab2.GetBestSize()) - - lab3 = wxStaticText(panel, -1, "pySketch is completely free " + \ - "software; please") - lab3.SetFont(boldFont) - lab3.SetSize(lab3.GetBestSize()) - - lab4 = wxStaticText(panel, -1, "feel free to adapt or use this " + \ - "in any way you like.") - lab4.SetFont(boldFont) - lab4.SetSize(lab4.GetBestSize()) - - lab5 = wxStaticText(panel, -1, "Author: Erik Westra " + \ - "(ewestra@wave.co.nz)") - lab5.SetFont(boldFont) - lab5.SetSize(lab5.GetBestSize()) - - btnOK = wxButton(panel, wxID_OK, "OK") - - panelSizer.Add(imageSizer, 0, wxALIGN_CENTRE) - panelSizer.Add(10, 10) # Spacer. - panelSizer.Add(lab2, 0, wxALIGN_CENTRE) - panelSizer.Add(10, 10) # Spacer. - panelSizer.Add(lab3, 0, wxALIGN_CENTRE) - panelSizer.Add(lab4, 0, wxALIGN_CENTRE) - panelSizer.Add(10, 10) # Spacer. - panelSizer.Add(lab5, 0, wxALIGN_CENTRE) - panelSizer.Add(10, 10) # Spacer. - panelSizer.Add(btnOK, 0, wxALL | wxALIGN_CENTRE, 5) - - panel.SetAutoLayout(true) - panel.SetSizer(panelSizer) - panelSizer.Fit(panel) - - topSizer = wxBoxSizer(wxHORIZONTAL) - topSizer.Add(panel, 0, wxALL, 10) - - dialog.SetAutoLayout(true) - dialog.SetSizer(topSizer) - topSizer.Fit(dialog) - - dialog.Centre() - - btn = dialog.ShowModal() - dialog.Destroy() + """ Respond to the "About pySketch" menu command. + """ + dialog = wxDialog(self, -1, "About pySketch") # , + #style=wxDIALOG_MODAL | wxSTAY_ON_TOP) + dialog.SetBackgroundColour(wxWHITE) + + panel = wxPanel(dialog, -1) + panel.SetBackgroundColour(wxWHITE) + + panelSizer = wxBoxSizer(wxVERTICAL) + + boldFont = wxFont(panel.GetFont().GetPointSize(), + panel.GetFont().GetFamily(), + wxNORMAL, wxBOLD) + + logo = wxStaticBitmap(panel, -1, wxBitmap("images/logo.bmp", + wxBITMAP_TYPE_BMP)) + + lab1 = wxStaticText(panel, -1, "pySketch") + lab1.SetFont(wxFont(36, boldFont.GetFamily(), wxITALIC, wxBOLD)) + lab1.SetSize(lab1.GetBestSize()) + + imageSizer = wxBoxSizer(wxHORIZONTAL) + imageSizer.Add(logo, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5) + imageSizer.Add(lab1, 0, wxALL | wxALIGN_CENTRE_VERTICAL, 5) + + lab2 = wxStaticText(panel, -1, "A simple object-oriented drawing " + \ + "program.") + lab2.SetFont(boldFont) + lab2.SetSize(lab2.GetBestSize()) + + lab3 = wxStaticText(panel, -1, "pySketch is completely free " + \ + "software; please") + lab3.SetFont(boldFont) + lab3.SetSize(lab3.GetBestSize()) + + lab4 = wxStaticText(panel, -1, "feel free to adapt or use this " + \ + "in any way you like.") + lab4.SetFont(boldFont) + lab4.SetSize(lab4.GetBestSize()) + + lab5 = wxStaticText(panel, -1, "Author: Erik Westra " + \ + "(ewestra@wave.co.nz)") + lab5.SetFont(boldFont) + lab5.SetSize(lab5.GetBestSize()) + + btnOK = wxButton(panel, wxID_OK, "OK") + + panelSizer.Add(imageSizer, 0, wxALIGN_CENTRE) + panelSizer.Add(10, 10) # Spacer. + panelSizer.Add(lab2, 0, wxALIGN_CENTRE) + panelSizer.Add(10, 10) # Spacer. + panelSizer.Add(lab3, 0, wxALIGN_CENTRE) + panelSizer.Add(lab4, 0, wxALIGN_CENTRE) + panelSizer.Add(10, 10) # Spacer. + panelSizer.Add(lab5, 0, wxALIGN_CENTRE) + panelSizer.Add(10, 10) # Spacer. + panelSizer.Add(btnOK, 0, wxALL | wxALIGN_CENTRE, 5) + + panel.SetAutoLayout(True) + panel.SetSizer(panelSizer) + panelSizer.Fit(panel) + + topSizer = wxBoxSizer(wxHORIZONTAL) + topSizer.Add(panel, 0, wxALL, 10) + + dialog.SetAutoLayout(True) + dialog.SetSizer(topSizer) + topSizer.Fit(dialog) + + dialog.Centre() + + btn = dialog.ShowModal() + dialog.Destroy() # ============================= # == Object Creation Methods == # ============================= def createLine(self, x1, y1, x2, y2): - """ Create a new line object at the given position and size. - """ - self._saveUndoInfo() - - topLeftX = min(x1, x2) - topLeftY = min(y1, y2) - botRightX = max(x1, x2) - botRightY = max(y1, y2) - - obj = DrawingObject(obj_LINE, position=wxPoint(topLeftX, topLeftY), - size=wxSize(botRightX-topLeftX, - botRightY-topLeftY), - penColour=self.penColour, - fillColour=self.fillColour, - lineSize=self.lineSize, - startPt = wxPoint(x1 - topLeftX, y1 - topLeftY), - endPt = wxPoint(x2 - topLeftX, y2 - topLeftY)) - self.contents.insert(0, obj) - self.dirty = true - self.doChooseSelectTool() - self.select(obj) + """ Create a new line object at the given position and size. + """ + self._saveUndoInfo() + + topLeftX = min(x1, x2) + topLeftY = min(y1, y2) + botRightX = max(x1, x2) + botRightY = max(y1, y2) + + obj = DrawingObject(obj_LINE, position=wxPoint(topLeftX, topLeftY), + size=wxSize(botRightX-topLeftX, + botRightY-topLeftY), + penColour=self.penColour, + fillColour=self.fillColour, + lineSize=self.lineSize, + startPt = wxPoint(x1 - topLeftX, y1 - topLeftY), + endPt = wxPoint(x2 - topLeftX, y2 - topLeftY)) + self.contents.insert(0, obj) + self.dirty = True + self.doChooseSelectTool() + self.select(obj) def createRect(self, x, y, width, height): - """ Create a new rectangle object at the given position and size. - """ - self._saveUndoInfo() + """ Create a new rectangle object at the given position and size. + """ + self._saveUndoInfo() - obj = DrawingObject(obj_RECT, position=wxPoint(x, y), - size=wxSize(width, height), - penColour=self.penColour, - fillColour=self.fillColour, - lineSize=self.lineSize) - self.contents.insert(0, obj) - self.dirty = true - self.doChooseSelectTool() - self.select(obj) + obj = DrawingObject(obj_RECT, position=wxPoint(x, y), + size=wxSize(width, height), + penColour=self.penColour, + fillColour=self.fillColour, + lineSize=self.lineSize) + self.contents.insert(0, obj) + self.dirty = True + self.doChooseSelectTool() + self.select(obj) def createEllipse(self, x, y, width, height): - """ Create a new ellipse object at the given position and size. - """ - self._saveUndoInfo() + """ Create a new ellipse object at the given position and size. + """ + self._saveUndoInfo() - obj = DrawingObject(obj_ELLIPSE, position=wxPoint(x, y), - size=wxSize(width, height), - penColour=self.penColour, - fillColour=self.fillColour, - lineSize=self.lineSize) - self.contents.insert(0, obj) - self.dirty = true - self.doChooseSelectTool() - self.select(obj) + obj = DrawingObject(obj_ELLIPSE, position=wxPoint(x, y), + size=wxSize(width, height), + penColour=self.penColour, + fillColour=self.fillColour, + lineSize=self.lineSize) + self.contents.insert(0, obj) + self.dirty = True + self.doChooseSelectTool() + self.select(obj) def createText(self, x, y, width, height): - """ Create a new text object at the given position and size. - """ - editor = EditTextObjectDialog(self, "Create Text Object") - if editor.ShowModal() == wxID_CANCEL: - editor.Destroy() - return + """ Create a new text object at the given position and size. + """ + editor = EditTextObjectDialog(self, "Create Text Object") + if editor.ShowModal() == wxID_CANCEL: + editor.Destroy() + return - self._saveUndoInfo() + self._saveUndoInfo() - obj = DrawingObject(obj_TEXT, position=wxPoint(x, y), - size=wxSize(width, height)) - editor.dialogToObject(obj) - editor.Destroy() + obj = DrawingObject(obj_TEXT, position=wxPoint(x, y), + size=wxSize(width, height)) + editor.dialogToObject(obj) + editor.Destroy() - self.contents.insert(0, obj) - self.dirty = true - self.doChooseSelectTool() - self.select(obj) + self.contents.insert(0, obj) + self.dirty = True + self.doChooseSelectTool() + self.select(obj) # ======================= # == Selection Methods == # ======================= def selectAll(self): - """ Select every DrawingObject in our document. - """ - self.selection = [] - for obj in self.contents: - self.selection.append(obj) - self.drawPanel.Refresh() - self._adjustMenus() + """ Select every DrawingObject in our document. + """ + self.selection = [] + for obj in self.contents: + self.selection.append(obj) + self.drawPanel.Refresh() + self._adjustMenus() def deselectAll(self): - """ Deselect every DrawingObject in our document. - """ - self.selection = [] - self.drawPanel.Refresh() - self._adjustMenus() + """ Deselect every DrawingObject in our document. + """ + self.selection = [] + self.drawPanel.Refresh() + self._adjustMenus() def select(self, obj): - """ Select the given DrawingObject within our document. - """ - self.selection = [obj] - self.drawPanel.Refresh() - self._adjustMenus() + """ Select the given DrawingObject within our document. + """ + self.selection = [obj] + self.drawPanel.Refresh() + self._adjustMenus() def selectMany(self, objs): - """ Select the given list of DrawingObjects. - """ - self.selection = objs - self.drawPanel.Refresh() - self._adjustMenus() + """ Select the given list of DrawingObjects. + """ + self.selection = objs + self.drawPanel.Refresh() + self._adjustMenus() def selectByRectangle(self, x, y, width, height): - """ Select every DrawingObject in the given rectangular region. - """ - self.selection = [] - for obj in self.contents: - if obj.objectWithinRect(x, y, width, height): - self.selection.append(obj) - self.drawPanel.Refresh() - self._adjustMenus() + """ Select every DrawingObject in the given rectangular region. + """ + self.selection = [] + for obj in self.contents: + if obj.objectWithinRect(x, y, width, height): + self.selection.append(obj) + self.drawPanel.Refresh() + self._adjustMenus() # ====================== # == File I/O Methods == # ====================== def loadContents(self): - """ Load the contents of our document into memory. - """ - f = open(self.fileName, "rb") - objData = cPickle.load(f) - f.close() + """ Load the contents of our document into memory. + """ + f = open(self.fileName, "rb") + objData = cPickle.load(f) + f.close() - for type, data in objData: - obj = DrawingObject(type) - obj.setData(data) - self.contents.append(obj) + for type, data in objData: + obj = DrawingObject(type) + obj.setData(data) + self.contents.append(obj) - self.dirty = false - self.selection = [] - self.undoInfo = None + self.dirty = False + self.selection = [] + self.undoInfo = None - self.drawPanel.Refresh() - self._adjustMenus() + self.drawPanel.Refresh() + self._adjustMenus() def saveContents(self): - """ Save the contents of our document to disk. - """ - objData = [] - for obj in self.contents: - objData.append([obj.getType(), obj.getData()]) + """ Save the contents of our document to disk. + """ + objData = [] + for obj in self.contents: + objData.append([obj.getType(), obj.getData()]) - f = open(self.fileName, "wb") - cPickle.dump(objData, f) - f.close() + f = open(self.fileName, "wb") + cPickle.dump(objData, f) + f.close() - self.dirty = false + self.dirty = False def askIfUserWantsToSave(self, action): - """ Give the user the opportunity to save the current document. - - 'action' is a string describing the action about to be taken. If - the user wants to save the document, it is saved immediately. If - the user cancels, we return false. - """ - if not self.dirty: return true # Nothing to do. - - response = wxMessageBox("Save changes before " + action + "?", - "Confirm", wxYES_NO | wxCANCEL, self) - - if response == wxYES: - if self.fileName == None: - fileName = wxFileSelector("Save File As", "Saving", - default_extension="psk", - wildcard="*.psk", - flags = wxSAVE | wxOVERWRITE_PROMPT) - if fileName == "": return false # User cancelled. - self.fileName = fileName - - self.saveContents() - return true - elif response == wxNO: - return true # User doesn't want changes saved. - elif response == wxCANCEL: - return false # User cancelled. + """ Give the user the opportunity to save the current document. + + 'action' is a string describing the action about to be taken. If + the user wants to save the document, it is saved immediately. If + the user cancels, we return False. + """ + if not self.dirty: return True # Nothing to do. + + response = wxMessageBox("Save changes before " + action + "?", + "Confirm", wxYES_NO | wxCANCEL, self) + + if response == wxYES: + if self.fileName == None: + fileName = wxFileSelector("Save File As", "Saving", + default_extension="psk", + wildcard="*.psk", + flags = wxSAVE | wxOVERWRITE_PROMPT) + if fileName == "": return False # User cancelled. + self.fileName = fileName + + self.saveContents() + return True + elif response == wxNO: + return True # User doesn't want changes saved. + elif response == wxCANCEL: + return False # User cancelled. # ===================== # == Private Methods == # ===================== def _adjustMenus(self): - """ Adjust our menus and toolbar to reflect the current state of the - world. - """ - canSave = (self.fileName != None) and self.dirty - canRevert = (self.fileName != None) and self.dirty - canUndo = self.undoInfo != None - selection = len(self.selection) > 0 - onlyOne = len(self.selection) == 1 - isText = onlyOne and (self.selection[0].getType() == obj_TEXT) - front = onlyOne and (self.selection[0] == self.contents[0]) - back = onlyOne and (self.selection[0] == self.contents[-1]) - - # Enable/disable our menu items. - - self.fileMenu.Enable(wxID_SAVE, canSave) - self.fileMenu.Enable(wxID_REVERT, canRevert) - - self.editMenu.Enable(menu_UNDO, canUndo) - self.editMenu.Enable(menu_DUPLICATE, selection) - self.editMenu.Enable(menu_EDIT_TEXT, isText) - self.editMenu.Enable(menu_DELETE, selection) - - self.toolsMenu.Check(menu_SELECT, self.curTool == self.selectIcon) - self.toolsMenu.Check(menu_LINE, self.curTool == self.lineIcon) - self.toolsMenu.Check(menu_RECT, self.curTool == self.rectIcon) - self.toolsMenu.Check(menu_ELLIPSE, self.curTool == self.ellipseIcon) - self.toolsMenu.Check(menu_TEXT, self.curTool == self.textIcon) - - self.objectMenu.Enable(menu_MOVE_FORWARD, onlyOne and not front) - self.objectMenu.Enable(menu_MOVE_TO_FRONT, onlyOne and not front) - self.objectMenu.Enable(menu_MOVE_BACKWARD, onlyOne and not back) - self.objectMenu.Enable(menu_MOVE_TO_BACK, onlyOne and not back) - - # Enable/disable our toolbar icons. - - self.toolbar.EnableTool(wxID_NEW, true) - self.toolbar.EnableTool(wxID_OPEN, true) - self.toolbar.EnableTool(wxID_SAVE, canSave) - self.toolbar.EnableTool(menu_UNDO, canUndo) - self.toolbar.EnableTool(menu_DUPLICATE, selection) - self.toolbar.EnableTool(menu_MOVE_FORWARD, onlyOne and not front) - self.toolbar.EnableTool(menu_MOVE_BACKWARD, onlyOne and not back) + """ Adjust our menus and toolbar to reflect the current state of the + world. + """ + canSave = (self.fileName != None) and self.dirty + canRevert = (self.fileName != None) and self.dirty + canUndo = self.undoInfo != None + selection = len(self.selection) > 0 + onlyOne = len(self.selection) == 1 + isText = onlyOne and (self.selection[0].getType() == obj_TEXT) + front = onlyOne and (self.selection[0] == self.contents[0]) + back = onlyOne and (self.selection[0] == self.contents[-1]) + + # Enable/disable our menu items. + + self.fileMenu.Enable(wxID_SAVE, canSave) + self.fileMenu.Enable(wxID_REVERT, canRevert) + + self.editMenu.Enable(menu_UNDO, canUndo) + self.editMenu.Enable(menu_DUPLICATE, selection) + self.editMenu.Enable(menu_EDIT_TEXT, isText) + self.editMenu.Enable(menu_DELETE, selection) + + self.toolsMenu.Check(menu_SELECT, self.curTool == self.selectIcon) + self.toolsMenu.Check(menu_LINE, self.curTool == self.lineIcon) + self.toolsMenu.Check(menu_RECT, self.curTool == self.rectIcon) + self.toolsMenu.Check(menu_ELLIPSE, self.curTool == self.ellipseIcon) + self.toolsMenu.Check(menu_TEXT, self.curTool == self.textIcon) + + self.objectMenu.Enable(menu_MOVE_FORWARD, onlyOne and not front) + self.objectMenu.Enable(menu_MOVE_TO_FRONT, onlyOne and not front) + self.objectMenu.Enable(menu_MOVE_BACKWARD, onlyOne and not back) + self.objectMenu.Enable(menu_MOVE_TO_BACK, onlyOne and not back) + + # Enable/disable our toolbar icons. + + self.toolbar.EnableTool(wxID_NEW, True) + self.toolbar.EnableTool(wxID_OPEN, True) + self.toolbar.EnableTool(wxID_SAVE, canSave) + self.toolbar.EnableTool(menu_UNDO, canUndo) + self.toolbar.EnableTool(menu_DUPLICATE, selection) + self.toolbar.EnableTool(menu_MOVE_FORWARD, onlyOne and not front) + self.toolbar.EnableTool(menu_MOVE_BACKWARD, onlyOne and not back) def _setCurrentTool(self, newToolIcon): - """ Set the currently selected tool. - """ - if self.curTool == newToolIcon: return # Nothing to do. + """ Set the currently selected tool. + """ + if self.curTool == newToolIcon: return # Nothing to do. - if self.curTool != None: - self.curTool.deselect() + if self.curTool != None: + self.curTool.deselect() - newToolIcon.select() - self.curTool = newToolIcon + newToolIcon.select() + self.curTool = newToolIcon def _setPenColour(self, colour): - """ Set the default or selected object's pen colour. - """ - if len(self.selection) > 0: - self._saveUndoInfo() - for obj in self.selection: - obj.setPenColour(colour) - self.drawPanel.Refresh() - else: - self.penColour = colour - self.optionIndicator.setPenColour(colour) + """ Set the default or selected object's pen colour. + """ + if len(self.selection) > 0: + self._saveUndoInfo() + for obj in self.selection: + obj.setPenColour(colour) + self.drawPanel.Refresh() + else: + self.penColour = colour + self.optionIndicator.setPenColour(colour) def _setFillColour(self, colour): - """ Set the default or selected object's fill colour. - """ - if len(self.selection) > 0: - self._saveUndoInfo() - for obj in self.selection: - obj.setFillColour(colour) - self.drawPanel.Refresh() - else: - self.fillColour = colour - self.optionIndicator.setFillColour(colour) + """ Set the default or selected object's fill colour. + """ + if len(self.selection) > 0: + self._saveUndoInfo() + for obj in self.selection: + obj.setFillColour(colour) + self.drawPanel.Refresh() + else: + self.fillColour = colour + self.optionIndicator.setFillColour(colour) def _setLineSize(self, size): - """ Set the default or selected object's line size. - """ - if len(self.selection) > 0: - self._saveUndoInfo() - for obj in self.selection: - obj.setLineSize(size) - self.drawPanel.Refresh() - else: - self.lineSize = size - self.optionIndicator.setLineSize(size) + """ Set the default or selected object's line size. + """ + if len(self.selection) > 0: + self._saveUndoInfo() + for obj in self.selection: + obj.setLineSize(size) + self.drawPanel.Refresh() + else: + self.lineSize = size + self.optionIndicator.setLineSize(size) def _saveUndoInfo(self): - """ Remember the current state of the document, to allow for undo. + """ Remember the current state of the document, to allow for undo. - We make a copy of the document's contents, so that we can return to - the previous contents if the user does something and then wants to - undo the operation. - """ - savedContents = [] - for obj in self.contents: - savedContents.append([obj.getType(), obj.getData()]) + We make a copy of the document's contents, so that we can return to + the previous contents if the user does something and then wants to + undo the operation. + """ + savedContents = [] + for obj in self.contents: + savedContents.append([obj.getType(), obj.getData()]) - savedSelection = [] - for i in range(len(self.contents)): - if self.contents[i] in self.selection: - savedSelection.append(i) + savedSelection = [] + for i in range(len(self.contents)): + if self.contents[i] in self.selection: + savedSelection.append(i) - self.undoInfo = {"contents" : savedContents, - "selection" : savedSelection} + self.undoInfo = {"contents" : savedContents, + "selection" : savedSelection} def _resizeObject(self, obj, anchorPt, oldPt, newPt): - """ Resize the given object. + """ Resize the given object. - 'anchorPt' is the unchanging corner of the object, while the - opposite corner has been resized. 'oldPt' are the current - coordinates for this corner, while 'newPt' are the new coordinates. - The object should fit within the given dimensions, though if the - new point is less than the anchor point the object will need to be - moved as well as resized, to avoid giving it a negative size. - """ - if obj.getType() == obj_TEXT: - # Not allowed to resize text objects -- they're sized to fit text. - wxBell() - return + 'anchorPt' is the unchanging corner of the object, while the + opposite corner has been resized. 'oldPt' are the current + coordinates for this corner, while 'newPt' are the new coordinates. + The object should fit within the given dimensions, though if the + new point is less than the anchor point the object will need to be + moved as well as resized, to avoid giving it a negative size. + """ + if obj.getType() == obj_TEXT: + # Not allowed to resize text objects -- they're sized to fit text. + wxBell() + return - self._saveUndoInfo() + self._saveUndoInfo() - topLeft = wxPoint(min(anchorPt.x, newPt.x), - min(anchorPt.y, newPt.y)) - botRight = wxPoint(max(anchorPt.x, newPt.x), - max(anchorPt.y, newPt.y)) + topLeft = wxPoint(min(anchorPt.x, newPt.x), + min(anchorPt.y, newPt.y)) + botRight = wxPoint(max(anchorPt.x, newPt.x), + max(anchorPt.y, newPt.y)) - newWidth = botRight.x - topLeft.x - newHeight = botRight.y - topLeft.y + newWidth = botRight.x - topLeft.x + newHeight = botRight.y - topLeft.y - if obj.getType() == obj_LINE: - # Adjust the line so that its start and end points match the new - # overall object size. + if obj.getType() == obj_LINE: + # Adjust the line so that its start and end points match the new + # overall object size. - startPt = obj.getStartPt() - endPt = obj.getEndPt() + startPt = obj.getStartPt() + endPt = obj.getEndPt() - slopesDown = ((startPt.x < endPt.x) and (startPt.y < endPt.y)) or \ - ((startPt.x > endPt.x) and (startPt.y > endPt.y)) + slopesDown = ((startPt.x < endPt.x) and (startPt.y < endPt.y)) or \ + ((startPt.x > endPt.x) and (startPt.y > endPt.y)) - # Handle the user flipping the line. + # Handle the user flipping the line. - hFlip = ((anchorPt.x < oldPt.x) and (anchorPt.x > newPt.x)) or \ - ((anchorPt.x > oldPt.x) and (anchorPt.x < newPt.x)) - vFlip = ((anchorPt.y < oldPt.y) and (anchorPt.y > newPt.y)) or \ - ((anchorPt.y > oldPt.y) and (anchorPt.y < newPt.y)) + hFlip = ((anchorPt.x < oldPt.x) and (anchorPt.x > newPt.x)) or \ + ((anchorPt.x > oldPt.x) and (anchorPt.x < newPt.x)) + vFlip = ((anchorPt.y < oldPt.y) and (anchorPt.y > newPt.y)) or \ + ((anchorPt.y > oldPt.y) and (anchorPt.y < newPt.y)) - if (hFlip and not vFlip) or (vFlip and not hFlip): - slopesDown = not slopesDown # Line flipped. + if (hFlip and not vFlip) or (vFlip and not hFlip): + slopesDown = not slopesDown # Line flipped. - if slopesDown: - obj.setStartPt(wxPoint(0, 0)) - obj.setEndPt(wxPoint(newWidth, newHeight)) - else: - obj.setStartPt(wxPoint(0, newHeight)) - obj.setEndPt(wxPoint(newWidth, 0)) + if slopesDown: + obj.setStartPt(wxPoint(0, 0)) + obj.setEndPt(wxPoint(newWidth, newHeight)) + else: + obj.setStartPt(wxPoint(0, newHeight)) + obj.setEndPt(wxPoint(newWidth, 0)) - # Finally, adjust the bounds of the object to match the new dimensions. + # Finally, adjust the bounds of the object to match the new dimensions. - obj.setPosition(topLeft) - obj.setSize(wxSize(botRight.x - topLeft.x, botRight.y - topLeft.y)) + obj.setPosition(topLeft) + obj.setSize(wxSize(botRight.x - topLeft.x, botRight.y - topLeft.y)) - self.drawPanel.Refresh() + self.drawPanel.Refresh() def _moveObject(self, offsetX, offsetY): - """ Move the currently selected object(s) by the given offset. - """ - self._saveUndoInfo() + """ Move the currently selected object(s) by the given offset. + """ + self._saveUndoInfo() - for obj in self.selection: - pos = obj.getPosition() - pos.x = pos.x + offsetX - pos.y = pos.y + offsetY - obj.setPosition(pos) + for obj in self.selection: + pos = obj.getPosition() + pos.x = pos.x + offsetX + pos.y = pos.y + offsetY + obj.setPosition(pos) - self.drawPanel.Refresh() + self.drawPanel.Refresh() def _buildLineSizePopup(self, lineSize): - """ Build the pop-up menu used to set the line size. - - 'lineSize' is the current line size value. The corresponding item - is checked in the pop-up menu. - """ - menu = wxMenu() - menu.Append(id_LINESIZE_0, "no line", kind=wxITEM_CHECK) - menu.Append(id_LINESIZE_1, "1-pixel line", kind=wxITEM_CHECK) - menu.Append(id_LINESIZE_2, "2-pixel line", kind=wxITEM_CHECK) - menu.Append(id_LINESIZE_3, "3-pixel line", kind=wxITEM_CHECK) - menu.Append(id_LINESIZE_4, "4-pixel line", kind=wxITEM_CHECK) - menu.Append(id_LINESIZE_5, "5-pixel line", kind=wxITEM_CHECK) - - if lineSize == 0: menu.Check(id_LINESIZE_0, true) - elif lineSize == 1: menu.Check(id_LINESIZE_1, true) - elif lineSize == 2: menu.Check(id_LINESIZE_2, true) - elif lineSize == 3: menu.Check(id_LINESIZE_3, true) - elif lineSize == 4: menu.Check(id_LINESIZE_4, true) - elif lineSize == 5: menu.Check(id_LINESIZE_5, true) - - EVT_MENU(self, id_LINESIZE_0, self._lineSizePopupSelected) - EVT_MENU(self, id_LINESIZE_1, self._lineSizePopupSelected) - EVT_MENU(self, id_LINESIZE_2, self._lineSizePopupSelected) - EVT_MENU(self, id_LINESIZE_3, self._lineSizePopupSelected) - EVT_MENU(self, id_LINESIZE_4, self._lineSizePopupSelected) - EVT_MENU(self, id_LINESIZE_5, self._lineSizePopupSelected) - - return menu + """ Build the pop-up menu used to set the line size. + + 'lineSize' is the current line size value. The corresponding item + is checked in the pop-up menu. + """ + menu = wxMenu() + menu.Append(id_LINESIZE_0, "no line", kind=wxITEM_CHECK) + menu.Append(id_LINESIZE_1, "1-pixel line", kind=wxITEM_CHECK) + menu.Append(id_LINESIZE_2, "2-pixel line", kind=wxITEM_CHECK) + menu.Append(id_LINESIZE_3, "3-pixel line", kind=wxITEM_CHECK) + menu.Append(id_LINESIZE_4, "4-pixel line", kind=wxITEM_CHECK) + menu.Append(id_LINESIZE_5, "5-pixel line", kind=wxITEM_CHECK) + + if lineSize == 0: menu.Check(id_LINESIZE_0, True) + elif lineSize == 1: menu.Check(id_LINESIZE_1, True) + elif lineSize == 2: menu.Check(id_LINESIZE_2, True) + elif lineSize == 3: menu.Check(id_LINESIZE_3, True) + elif lineSize == 4: menu.Check(id_LINESIZE_4, True) + elif lineSize == 5: menu.Check(id_LINESIZE_5, True) + + EVT_MENU(self, id_LINESIZE_0, self._lineSizePopupSelected) + EVT_MENU(self, id_LINESIZE_1, self._lineSizePopupSelected) + EVT_MENU(self, id_LINESIZE_2, self._lineSizePopupSelected) + EVT_MENU(self, id_LINESIZE_3, self._lineSizePopupSelected) + EVT_MENU(self, id_LINESIZE_4, self._lineSizePopupSelected) + EVT_MENU(self, id_LINESIZE_5, self._lineSizePopupSelected) + + return menu def _lineSizePopupSelected(self, event): - """ Respond to the user selecting an item from the line size popup menu - """ - id = event.GetId() - if id == id_LINESIZE_0: self._setLineSize(0) - elif id == id_LINESIZE_1: self._setLineSize(1) - elif id == id_LINESIZE_2: self._setLineSize(2) - elif id == id_LINESIZE_3: self._setLineSize(3) - elif id == id_LINESIZE_4: self._setLineSize(4) - elif id == id_LINESIZE_5: self._setLineSize(5) - else: - wxBell() - return - - self.optionIndicator.setLineSize(self.lineSize) + """ Respond to the user selecting an item from the line size popup menu + """ + id = event.GetId() + if id == id_LINESIZE_0: self._setLineSize(0) + elif id == id_LINESIZE_1: self._setLineSize(1) + elif id == id_LINESIZE_2: self._setLineSize(2) + elif id == id_LINESIZE_3: self._setLineSize(3) + elif id == id_LINESIZE_4: self._setLineSize(4) + elif id == id_LINESIZE_5: self._setLineSize(5) + else: + wxBell() + return + + self.optionIndicator.setLineSize(self.lineSize) def _getEventCoordinates(self, event): - """ Return the coordinates associated with the given mouse event. + """ Return the coordinates associated with the given mouse event. - The coordinates have to be adjusted to allow for the current scroll - position. - """ + The coordinates have to be adjusted to allow for the current scroll + position. + """ originX, originY = self.drawPanel.GetViewStart() unitX, unitY = self.drawPanel.GetScrollPixelsPerUnit() return wxPoint(event.GetX() + (originX * unitX), - event.GetY() + (originY * unitY)) + event.GetY() + (originY * unitY)) def _getObjectAndSelectionHandleAt(self, pt): - """ Return the object and selection handle at the given point. + """ Return the object and selection handle at the given point. - We draw selection handles (small rectangles) around the currently - selected object(s). If the given point is within one of the - selection handle rectangles, we return the associated object and a - code indicating which selection handle the point is in. If the - point isn't within any selection handle at all, we return the tuple - (None, handle_NONE). - """ - for obj in self.selection: - handle = obj.getSelectionHandleContainingPoint(pt.x, pt.y) - if handle != handle_NONE: - return obj, handle + We draw selection handles (small rectangles) around the currently + selected object(s). If the given point is within one of the + selection handle rectangles, we return the associated object and a + code indicating which selection handle the point is in. If the + point isn't within any selection handle at all, we return the tuple + (None, handle_NONE). + """ + for obj in self.selection: + handle = obj.getSelectionHandleContainingPoint(pt.x, pt.y) + if handle != handle_NONE: + return obj, handle - return None, handle_NONE + return None, handle_NONE def _getObjectAt(self, pt): - """ Return the first object found which is at the given point. - """ - for obj in self.contents: - if obj.objectContainsPoint(pt.x, pt.y): - return obj - return None + """ Return the first object found which is at the given point. + """ + for obj in self.contents: + if obj.objectContainsPoint(pt.x, pt.y): + return obj + return None def _drawObjectOutline(self, offsetX, offsetY): - """ Draw an outline of the currently selected object. + """ Draw an outline of the currently selected object. - The selected object's outline is drawn at the object's position - plus the given offset. + The selected object's outline is drawn at the object's position + plus the given offset. - Note that the outline is drawn by *inverting* the window's - contents, so calling _drawObjectOutline twice in succession will - restore the window's contents back to what they were previously. - """ - if len(self.selection) != 1: return + Note that the outline is drawn by *inverting* the window's + contents, so calling _drawObjectOutline twice in succession will + restore the window's contents back to what they were previously. + """ + if len(self.selection) != 1: return - position = self.selection[0].getPosition() - size = self.selection[0].getSize() + position = self.selection[0].getPosition() + size = self.selection[0].getSize() - dc = wxClientDC(self.drawPanel) - self.drawPanel.PrepareDC(dc) - dc.BeginDrawing() - dc.SetPen(wxBLACK_DASHED_PEN) - dc.SetBrush(wxTRANSPARENT_BRUSH) - dc.SetLogicalFunction(wxINVERT) + dc = wxClientDC(self.drawPanel) + self.drawPanel.PrepareDC(dc) + dc.BeginDrawing() + dc.SetPen(wxBLACK_DASHED_PEN) + dc.SetBrush(wxTRANSPARENT_BRUSH) + dc.SetLogicalFunction(wxINVERT) - dc.DrawRectangle(position.x + offsetX, position.y + offsetY, - size.width, size.height) + dc.DrawRectangle(position.x + offsetX, position.y + offsetY, + size.width, size.height) - dc.EndDrawing() + dc.EndDrawing() def _drawVisualFeedback(self, startPt, endPt, type, dashedLine): - """ Draw visual feedback for a drawing operation. - - The visual feedback consists of a line, ellipse, or rectangle based - around the two given points. 'type' should be one of the following - predefined feedback type constants: - - feedback_RECT -> draw rectangular feedback. - feedback_LINE -> draw line feedback. - feedback_ELLIPSE -> draw elliptical feedback. - - if 'dashedLine' is true, the feedback is drawn as a dashed rather - than a solid line. - - Note that the feedback is drawn by *inverting* the window's - contents, so calling _drawVisualFeedback twice in succession will - restore the window's contents back to what they were previously. - """ - dc = wxClientDC(self.drawPanel) - self.drawPanel.PrepareDC(dc) - dc.BeginDrawing() - if dashedLine: - dc.SetPen(wxBLACK_DASHED_PEN) - else: - dc.SetPen(wxBLACK_PEN) - dc.SetBrush(wxTRANSPARENT_BRUSH) - dc.SetLogicalFunction(wxINVERT) - - if type == feedback_RECT: - dc.DrawRectangle(startPt.x, startPt.y, - endPt.x - startPt.x, - endPt.y - startPt.y) - elif type == feedback_LINE: - dc.DrawLine(startPt.x, startPt.y, endPt.x, endPt.y) - elif type == feedback_ELLIPSE: - dc.DrawEllipse(startPt.x, startPt.y, - endPt.x - startPt.x, - endPt.y - startPt.y) - - dc.EndDrawing() + """ Draw visual feedback for a drawing operation. + + The visual feedback consists of a line, ellipse, or rectangle based + around the two given points. 'type' should be one of the following + predefined feedback type constants: + + feedback_RECT -> draw rectangular feedback. + feedback_LINE -> draw line feedback. + feedback_ELLIPSE -> draw elliptical feedback. + + if 'dashedLine' is True, the feedback is drawn as a dashed rather + than a solid line. + + Note that the feedback is drawn by *inverting* the window's + contents, so calling _drawVisualFeedback twice in succession will + restore the window's contents back to what they were previously. + """ + dc = wxClientDC(self.drawPanel) + self.drawPanel.PrepareDC(dc) + dc.BeginDrawing() + if dashedLine: + dc.SetPen(wxBLACK_DASHED_PEN) + else: + dc.SetPen(wxBLACK_PEN) + dc.SetBrush(wxTRANSPARENT_BRUSH) + dc.SetLogicalFunction(wxINVERT) + + if type == feedback_RECT: + dc.DrawRectangle(startPt.x, startPt.y, + endPt.x - startPt.x, + endPt.y - startPt.y) + elif type == feedback_LINE: + dc.DrawLine(startPt.x, startPt.y, endPt.x, endPt.y) + elif type == feedback_ELLIPSE: + dc.DrawEllipse(startPt.x, startPt.y, + endPt.x - startPt.x, + endPt.y - startPt.y) + + dc.EndDrawing() #---------------------------------------------------------------------------- class DrawingObject: """ An object within the drawing panel. - A pySketch document consists of a front-to-back ordered list of - DrawingObjects. Each DrawingObject has the following properties: - - 'type' What type of object this is (text, line, etc). - 'position' The position of the object within the document. - 'size' The size of the object within the document. - 'penColour' The colour to use for drawing the object's outline. - 'fillColour' Colour to use for drawing object's interior. - 'lineSize' Line width (in pixels) to use for object's outline. - 'startPt' The point, relative to the object's position, where - an obj_LINE object's line should start. - 'endPt' The point, relative to the object's position, where - an obj_LINE object's line should end. - 'text' The object's text (obj_TEXT objects only). - 'textFont' The text object's font name. - 'textSize' The text object's point size. - 'textBoldface' If true, this text object will be drawn in - boldface. - 'textItalic' If true, this text object will be drawn in italic. - 'textUnderline' If true, this text object will be drawn underlined. - """ + A pySketch document consists of a front-to-back ordered list of + DrawingObjects. Each DrawingObject has the following properties: + + 'type' What type of object this is (text, line, etc). + 'position' The position of the object within the document. + 'size' The size of the object within the document. + 'penColour' The colour to use for drawing the object's outline. + 'fillColour' Colour to use for drawing object's interior. + 'lineSize' Line width (in pixels) to use for object's outline. + 'startPt' The point, relative to the object's position, where + an obj_LINE object's line should start. + 'endPt' The point, relative to the object's position, where + an obj_LINE object's line should end. + 'text' The object's text (obj_TEXT objects only). + 'textFont' The text object's font name. + 'textSize' The text object's point size. + 'textBoldface' If True, this text object will be drawn in + boldface. + 'textItalic' If True, this text object will be drawn in italic. + 'textUnderline' If True, this text object will be drawn underlined. + """ # ================== # == Constructors == # ================== def __init__(self, type, position=wxPoint(0, 0), size=wxSize(0, 0), - penColour=wxBLACK, fillColour=wxWHITE, lineSize=1, - text=None, startPt=wxPoint(0, 0), endPt=wxPoint(0,0)): - """ Standard constructor. - - 'type' is the type of object being created. This should be one of - the following constants: - - obj_LINE - obj_RECT - obj_ELLIPSE - obj_TEXT - - The remaining parameters let you set various options for the newly - created DrawingObject. - """ - self.type = type - self.position = position - self.size = size - self.penColour = penColour - self.fillColour = fillColour - self.lineSize = lineSize - self.startPt = startPt - self.endPt = endPt - self.text = text - self.textFont = wxSystemSettings_GetSystemFont( - wxSYS_DEFAULT_GUI_FONT).GetFaceName() - self.textSize = 12 - self.textBoldface = false - self.textItalic = false - self.textUnderline = false + penColour=wxBLACK, fillColour=wxWHITE, lineSize=1, + text=None, startPt=wxPoint(0, 0), endPt=wxPoint(0,0)): + """ Standard constructor. + + 'type' is the type of object being created. This should be one of + the following constants: + + obj_LINE + obj_RECT + obj_ELLIPSE + obj_TEXT + + The remaining parameters let you set various options for the newly + created DrawingObject. + """ + self.type = type + self.position = position + self.size = size + self.penColour = penColour + self.fillColour = fillColour + self.lineSize = lineSize + self.startPt = startPt + self.endPt = endPt + self.text = text + self.textFont = wxSystemSettings_GetSystemFont( + wxSYS_DEFAULT_GUI_FONT).GetFaceName() + self.textSize = 12 + self.textBoldface = False + self.textItalic = False + self.textUnderline = False # ============================= # == Object Property Methods == # ============================= def getData(self): - """ Return a copy of the object's internal data. - - This is used to save this DrawingObject to disk. - """ - return [self.type, self.position.x, self.position.y, - self.size.width, self.size.height, - self.penColour.Red(), - self.penColour.Green(), - self.penColour.Blue(), - self.fillColour.Red(), - self.fillColour.Green(), - self.fillColour.Blue(), - self.lineSize, - self.startPt.x, self.startPt.y, - self.endPt.x, self.endPt.y, - self.text, - self.textFont, - self.textSize, - self.textBoldface, - self.textItalic, - self.textUnderline] + """ Return a copy of the object's internal data. + + This is used to save this DrawingObject to disk. + """ + return [self.type, self.position.x, self.position.y, + self.size.width, self.size.height, + self.penColour.Red(), + self.penColour.Green(), + self.penColour.Blue(), + self.fillColour.Red(), + self.fillColour.Green(), + self.fillColour.Blue(), + self.lineSize, + self.startPt.x, self.startPt.y, + self.endPt.x, self.endPt.y, + self.text, + self.textFont, + self.textSize, + self.textBoldface, + self.textItalic, + self.textUnderline] def setData(self, data): - """ Set the object's internal data. - - 'data' is a copy of the object's saved data, as returned by - getData() above. This is used to restore a previously saved - DrawingObject. - """ - #data = copy.deepcopy(data) # Needed? - - self.type = data[0] - self.position = wxPoint(data[1], data[2]) - self.size = wxSize(data[3], data[4]) - self.penColour = wxColour(red=data[5], - green=data[6], - blue=data[7]) - self.fillColour = wxColour(red=data[8], - green=data[9], - blue=data[10]) - self.lineSize = data[11] - self.startPt = wxPoint(data[12], data[13]) - self.endPt = wxPoint(data[14], data[15]) - self.text = data[16] - self.textFont = data[17] - self.textSize = data[18] - self.textBoldface = data[19] - self.textItalic = data[20] - self.textUnderline = data[21] + """ Set the object's internal data. + + 'data' is a copy of the object's saved data, as returned by + getData() above. This is used to restore a previously saved + DrawingObject. + """ + #data = copy.deepcopy(data) # Needed? + + self.type = data[0] + self.position = wxPoint(data[1], data[2]) + self.size = wxSize(data[3], data[4]) + self.penColour = wxColour(red=data[5], + green=data[6], + blue=data[7]) + self.fillColour = wxColour(red=data[8], + green=data[9], + blue=data[10]) + self.lineSize = data[11] + self.startPt = wxPoint(data[12], data[13]) + self.endPt = wxPoint(data[14], data[15]) + self.text = data[16] + self.textFont = data[17] + self.textSize = data[18] + self.textBoldface = data[19] + self.textItalic = data[20] + self.textUnderline = data[21] def getType(self): - """ Return this DrawingObject's type. - """ - return self.type + """ Return this DrawingObject's type. + """ + return self.type def setPosition(self, position): - """ Set the origin (top-left corner) for this DrawingObject. - """ - self.position = position + """ Set the origin (top-left corner) for this DrawingObject. + """ + self.position = position def getPosition(self): - """ Return this DrawingObject's position. - """ - return self.position + """ Return this DrawingObject's position. + """ + return self.position def setSize(self, size): - """ Set the size for this DrawingObject. - """ - self.size = size + """ Set the size for this DrawingObject. + """ + self.size = size def getSize(self): - """ Return this DrawingObject's size. - """ - return self.size + """ Return this DrawingObject's size. + """ + return self.size def setPenColour(self, colour): - """ Set the pen colour used for this DrawingObject. - """ - self.penColour = colour + """ Set the pen colour used for this DrawingObject. + """ + self.penColour = colour def getPenColour(self): - """ Return this DrawingObject's pen colour. - """ - return self.penColour + """ Return this DrawingObject's pen colour. + """ + return self.penColour def setFillColour(self, colour): - """ Set the fill colour used for this DrawingObject. - """ - self.fillColour = colour + """ Set the fill colour used for this DrawingObject. + """ + self.fillColour = colour def getFillColour(self): - """ Return this DrawingObject's fill colour. - """ - return self.fillColour + """ Return this DrawingObject's fill colour. + """ + return self.fillColour def setLineSize(self, lineSize): - """ Set the linesize used for this DrawingObject. - """ - self.lineSize = lineSize + """ Set the linesize used for this DrawingObject. + """ + self.lineSize = lineSize def getLineSize(self): - """ Return this DrawingObject's line size. - """ - return self.lineSize + """ Return this DrawingObject's line size. + """ + return self.lineSize def setStartPt(self, startPt): - """ Set the starting point for this line DrawingObject. - """ - self.startPt = startPt + """ Set the starting point for this line DrawingObject. + """ + self.startPt = startPt def getStartPt(self): - """ Return the starting point for this line DrawingObject. - """ - return self.startPt + """ Return the starting point for this line DrawingObject. + """ + return self.startPt def setEndPt(self, endPt): - """ Set the ending point for this line DrawingObject. - """ - self.endPt = endPt + """ Set the ending point for this line DrawingObject. + """ + self.endPt = endPt def getEndPt(self): - """ Return the ending point for this line DrawingObject. - """ - return self.endPt + """ Return the ending point for this line DrawingObject. + """ + return self.endPt def setText(self, text): - """ Set the text for this DrawingObject. - """ - self.text = text + """ Set the text for this DrawingObject. + """ + self.text = text def getText(self): - """ Return this DrawingObject's text. - """ - return self.text + """ Return this DrawingObject's text. + """ + return self.text def setTextFont(self, font): - """ Set the typeface for this text DrawingObject. - """ - self.textFont = font + """ Set the typeface for this text DrawingObject. + """ + self.textFont = font def getTextFont(self): - """ Return this text DrawingObject's typeface. - """ - return self.textFont + """ Return this text DrawingObject's typeface. + """ + return self.textFont def setTextSize(self, size): - """ Set the point size for this text DrawingObject. - """ - self.textSize = size + """ Set the point size for this text DrawingObject. + """ + self.textSize = size def getTextSize(self): - """ Return this text DrawingObject's text size. - """ - return self.textSize + """ Return this text DrawingObject's text size. + """ + return self.textSize def setTextBoldface(self, boldface): - """ Set the boldface flag for this text DrawingObject. - """ - self.textBoldface = boldface + """ Set the boldface flag for this text DrawingObject. + """ + self.textBoldface = boldface def getTextBoldface(self): - """ Return this text DrawingObject's boldface flag. - """ - return self.textBoldface + """ Return this text DrawingObject's boldface flag. + """ + return self.textBoldface def setTextItalic(self, italic): - """ Set the italic flag for this text DrawingObject. - """ - self.textItalic = italic + """ Set the italic flag for this text DrawingObject. + """ + self.textItalic = italic def getTextItalic(self): - """ Return this text DrawingObject's italic flag. - """ - return self.textItalic + """ Return this text DrawingObject's italic flag. + """ + return self.textItalic def setTextUnderline(self, underline): - """ Set the underling flag for this text DrawingObject. - """ - self.textUnderline = underline + """ Set the underling flag for this text DrawingObject. + """ + self.textUnderline = underline def getTextUnderline(self): - """ Return this text DrawingObject's underline flag. - """ - return self.textUnderline + """ Return this text DrawingObject's underline flag. + """ + return self.textUnderline # ============================ # == Object Drawing Methods == # ============================ def draw(self, dc, selected): - """ Draw this DrawingObject into our window. - - 'dc' is the device context to use for drawing. If 'selected' is - true, the object is currently selected and should be drawn as such. - """ - if self.type != obj_TEXT: - if self.lineSize == 0: - dc.SetPen(wxPen(self.penColour, self.lineSize, wxTRANSPARENT)) - else: - dc.SetPen(wxPen(self.penColour, self.lineSize, wxSOLID)) - dc.SetBrush(wxBrush(self.fillColour, wxSOLID)) - else: - dc.SetTextForeground(self.penColour) - dc.SetTextBackground(self.fillColour) - - self._privateDraw(dc, self.position, selected) + """ Draw this DrawingObject into our window. + + 'dc' is the device context to use for drawing. If 'selected' is + True, the object is currently selected and should be drawn as such. + """ + if self.type != obj_TEXT: + if self.lineSize == 0: + dc.SetPen(wxPen(self.penColour, self.lineSize, wxTRANSPARENT)) + else: + dc.SetPen(wxPen(self.penColour, self.lineSize, wxSOLID)) + dc.SetBrush(wxBrush(self.fillColour, wxSOLID)) + else: + dc.SetTextForeground(self.penColour) + dc.SetTextBackground(self.fillColour) + + self._privateDraw(dc, self.position, selected) # ======================= # == Selection Methods == # ======================= def objectContainsPoint(self, x, y): - """ Returns true iff this object contains the given point. - - This is used to determine if the user clicked on the object. - """ - # Firstly, ignore any points outside of the object's bounds. - - if x < self.position.x: return false - if x > self.position.x + self.size.x: return false - if y < self.position.y: return false - if y > self.position.y + self.size.y: return false - - if self.type in [obj_RECT, obj_TEXT]: - # Rectangles and text are easy -- they're always selected if the - # point is within their bounds. - return true - - # Now things get tricky. There's no straightforward way of knowing - # whether the point is within the object's bounds...to get around this, - # we draw the object into a memory-based bitmap and see if the given - # point was drawn. This could no doubt be done more efficiently by - # some tricky maths, but this approach works and is simple enough. - - bitmap = wxEmptyBitmap(self.size.x + 10, self.size.y + 10) - dc = wxMemoryDC() - dc.SelectObject(bitmap) - dc.BeginDrawing() - dc.SetBackground(wxWHITE_BRUSH) - dc.Clear() - dc.SetPen(wxPen(wxBLACK, self.lineSize + 5, wxSOLID)) - dc.SetBrush(wxBLACK_BRUSH) - self._privateDraw(dc, wxPoint(5, 5), true) - dc.EndDrawing() - pixel = dc.GetPixel(x - self.position.x + 5, y - self.position.y + 5) - if (pixel.Red() == 0) and (pixel.Green() == 0) and (pixel.Blue() == 0): - return true - else: - return false + """ Returns True iff this object contains the given point. + + This is used to determine if the user clicked on the object. + """ + # Firstly, ignore any points outside of the object's bounds. + + if x < self.position.x: return False + if x > self.position.x + self.size.x: return False + if y < self.position.y: return False + if y > self.position.y + self.size.y: return False + + if self.type in [obj_RECT, obj_TEXT]: + # Rectangles and text are easy -- they're always selected if the + # point is within their bounds. + return True + + # Now things get tricky. There's no straightforward way of knowing + # whether the point is within the object's bounds...to get around this, + # we draw the object into a memory-based bitmap and see if the given + # point was drawn. This could no doubt be done more efficiently by + # some tricky maths, but this approach works and is simple enough. + + bitmap = wxEmptyBitmap(self.size.x + 10, self.size.y + 10) + dc = wxMemoryDC() + dc.SelectObject(bitmap) + dc.BeginDrawing() + dc.SetBackground(wxWHITE_BRUSH) + dc.Clear() + dc.SetPen(wxPen(wxBLACK, self.lineSize + 5, wxSOLID)) + dc.SetBrush(wxBLACK_BRUSH) + self._privateDraw(dc, wxPoint(5, 5), True) + dc.EndDrawing() + pixel = dc.GetPixel(x - self.position.x + 5, y - self.position.y + 5) + if (pixel.Red() == 0) and (pixel.Green() == 0) and (pixel.Blue() == 0): + return True + else: + return False def getSelectionHandleContainingPoint(self, x, y): - """ Return the selection handle containing the given point, if any. - - We return one of the predefined selection handle ID codes. - """ - if self.type == obj_LINE: - # We have selection handles at the start and end points. - if self._pointInSelRect(x, y, self.position.x + self.startPt.x, - self.position.y + self.startPt.y): - return handle_START_POINT - elif self._pointInSelRect(x, y, self.position.x + self.endPt.x, - self.position.y + self.endPt.y): - return handle_END_POINT - else: - return handle_NONE - else: - # We have selection handles at all four corners. - if self._pointInSelRect(x, y, self.position.x, self.position.y): - return handle_TOP_LEFT - elif self._pointInSelRect(x, y, self.position.x + self.size.width, - self.position.y): - return handle_TOP_RIGHT - elif self._pointInSelRect(x, y, self.position.x, - self.position.y + self.size.height): - return handle_BOTTOM_LEFT - elif self._pointInSelRect(x, y, self.position.x + self.size.width, - self.position.y + self.size.height): - return handle_BOTTOM_RIGHT - else: - return handle_NONE + """ Return the selection handle containing the given point, if any. + + We return one of the predefined selection handle ID codes. + """ + if self.type == obj_LINE: + # We have selection handles at the start and end points. + if self._pointInSelRect(x, y, self.position.x + self.startPt.x, + self.position.y + self.startPt.y): + return handle_START_POINT + elif self._pointInSelRect(x, y, self.position.x + self.endPt.x, + self.position.y + self.endPt.y): + return handle_END_POINT + else: + return handle_NONE + else: + # We have selection handles at all four corners. + if self._pointInSelRect(x, y, self.position.x, self.position.y): + return handle_TOP_LEFT + elif self._pointInSelRect(x, y, self.position.x + self.size.width, + self.position.y): + return handle_TOP_RIGHT + elif self._pointInSelRect(x, y, self.position.x, + self.position.y + self.size.height): + return handle_BOTTOM_LEFT + elif self._pointInSelRect(x, y, self.position.x + self.size.width, + self.position.y + self.size.height): + return handle_BOTTOM_RIGHT + else: + return handle_NONE def objectWithinRect(self, x, y, width, height): - """ Return true iff this object falls completely within the given rect. - """ - if x > self.position.x: return false - if x + width < self.position.x + self.size.width: return false - if y > self.position.y: return false - if y + height < self.position.y + self.size.height: return false - return true + """ Return True iff this object falls completely within the given rect. + """ + if x > self.position.x: return False + if x + width < self.position.x + self.size.width: return False + if y > self.position.y: return False + if y + height < self.position.y + self.size.height: return False + return True # ===================== # == Utility Methods == # ===================== def fitToText(self): - """ Resize a text DrawingObject so that it fits it's text exactly. - """ - if self.type != obj_TEXT: return + """ Resize a text DrawingObject so that it fits it's text exactly. + """ + if self.type != obj_TEXT: return - if self.textBoldface: weight = wxBOLD - else: weight = wxNORMAL - if self.textItalic: style = wxITALIC - else: style = wxNORMAL - font = wxFont(self.textSize, wxDEFAULT, style, weight, - self.textUnderline, self.textFont) + if self.textBoldface: weight = wxBOLD + else: weight = wxNORMAL + if self.textItalic: style = wxITALIC + else: style = wxNORMAL + font = wxFont(self.textSize, wxDEFAULT, style, weight, + self.textUnderline, self.textFont) - dummyWindow = wxFrame(None, -1, "") - dummyWindow.SetFont(font) - width, height = dummyWindow.GetTextExtent(self.text) - dummyWindow.Destroy() + dummyWindow = wxFrame(None, -1, "") + dummyWindow.SetFont(font) + width, height = dummyWindow.GetTextExtent(self.text) + dummyWindow.Destroy() - self.size = wxSize(width, height) + self.size = wxSize(width, height) # ===================== # == Private Methods == # ===================== def _privateDraw(self, dc, position, selected): - """ Private routine to draw this DrawingObject. - - 'dc' is the device context to use for drawing, while 'position' is - the position in which to draw the object. If 'selected' is true, - the object is drawn with selection handles. This private drawing - routine assumes that the pen and brush have already been set by the - caller. - """ - if self.type == obj_LINE: - dc.DrawLine(position.x + self.startPt.x, - position.y + self.startPt.y, - position.x + self.endPt.x, - position.y + self.endPt.y) - elif self.type == obj_RECT: - dc.DrawRectangle(position.x, position.y, - self.size.width, self.size.height) - elif self.type == obj_ELLIPSE: - dc.DrawEllipse(position.x, position.y, - self.size.width, self.size.height) - elif self.type == obj_TEXT: - if self.textBoldface: weight = wxBOLD - else: weight = wxNORMAL - if self.textItalic: style = wxITALIC - else: style = wxNORMAL - font = wxFont(self.textSize, wxDEFAULT, style, weight, - self.textUnderline, self.textFont) - dc.SetFont(font) - dc.DrawText(self.text, position.x, position.y) - - if selected: - dc.SetPen(wxTRANSPARENT_PEN) - dc.SetBrush(wxBLACK_BRUSH) - - if self.type == obj_LINE: - # Draw selection handles at the start and end points. - self._drawSelHandle(dc, position.x + self.startPt.x, - position.y + self.startPt.y) - self._drawSelHandle(dc, position.x + self.endPt.x, - position.y + self.endPt.y) - else: - # Draw selection handles at all four corners. - self._drawSelHandle(dc, position.x, position.y) - self._drawSelHandle(dc, position.x + self.size.width, - position.y) - self._drawSelHandle(dc, position.x, - position.y + self.size.height) - self._drawSelHandle(dc, position.x + self.size.width, - position.y + self.size.height) + """ Private routine to draw this DrawingObject. + + 'dc' is the device context to use for drawing, while 'position' is + the position in which to draw the object. If 'selected' is True, + the object is drawn with selection handles. This private drawing + routine assumes that the pen and brush have already been set by the + caller. + """ + if self.type == obj_LINE: + dc.DrawLine(position.x + self.startPt.x, + position.y + self.startPt.y, + position.x + self.endPt.x, + position.y + self.endPt.y) + elif self.type == obj_RECT: + dc.DrawRectangle(position.x, position.y, + self.size.width, self.size.height) + elif self.type == obj_ELLIPSE: + dc.DrawEllipse(position.x, position.y, + self.size.width, self.size.height) + elif self.type == obj_TEXT: + if self.textBoldface: weight = wxBOLD + else: weight = wxNORMAL + if self.textItalic: style = wxITALIC + else: style = wxNORMAL + font = wxFont(self.textSize, wxDEFAULT, style, weight, + self.textUnderline, self.textFont) + dc.SetFont(font) + dc.DrawText(self.text, position.x, position.y) + + if selected: + dc.SetPen(wxTRANSPARENT_PEN) + dc.SetBrush(wxBLACK_BRUSH) + + if self.type == obj_LINE: + # Draw selection handles at the start and end points. + self._drawSelHandle(dc, position.x + self.startPt.x, + position.y + self.startPt.y) + self._drawSelHandle(dc, position.x + self.endPt.x, + position.y + self.endPt.y) + else: + # Draw selection handles at all four corners. + self._drawSelHandle(dc, position.x, position.y) + self._drawSelHandle(dc, position.x + self.size.width, + position.y) + self._drawSelHandle(dc, position.x, + position.y + self.size.height) + self._drawSelHandle(dc, position.x + self.size.width, + position.y + self.size.height) def _drawSelHandle(self, dc, x, y): - """ Draw a selection handle around this DrawingObject. + """ Draw a selection handle around this DrawingObject. - 'dc' is the device context to draw the selection handle within, - while 'x' and 'y' are the coordinates to use for the centre of the - selection handle. - """ - dc.DrawRectangle(x - 3, y - 3, 6, 6) + 'dc' is the device context to draw the selection handle within, + while 'x' and 'y' are the coordinates to use for the centre of the + selection handle. + """ + dc.DrawRectangle(x - 3, y - 3, 6, 6) def _pointInSelRect(self, x, y, rX, rY): - """ Return true iff (x, y) is within the selection handle at (rX, ry). - """ - if x < rX - 3: return false - elif x > rX + 3: return false - elif y < rY - 3: return false - elif y > rY + 3: return false - else: return true + """ Return True iff (x, y) is within the selection handle at (rX, ry). + """ + if x < rX - 3: return False + elif x > rX + 3: return False + elif y < rY - 3: return False + elif y > rY + 3: return False + else: return True #---------------------------------------------------------------------------- class ToolPaletteIcon(wxStaticBitmap): """ An icon appearing in the tool palette area of our sketching window. - Note that this is actually implemented as a wxStaticBitmap rather - than as a wxIcon. wxIcon has a very specific meaning, and isn't - appropriate for this more general use. + Note that this is actually implemented as a wxStaticBitmap rather + than as a wxIcon. wxIcon has a very specific meaning, and isn't + appropriate for this more general use. """ def __init__(self, parent, iconID, iconName, toolTip): - """ Standard constructor. + """ Standard constructor. - 'parent' is the parent window this icon will be part of. - 'iconID' is the internal ID used for this icon. - 'iconName' is the name used for this icon. - 'toolTip' is the tool tip text to show for this icon. + 'parent' is the parent window this icon will be part of. + 'iconID' is the internal ID used for this icon. + 'iconName' is the name used for this icon. + 'toolTip' is the tool tip text to show for this icon. - The icon name is used to get the appropriate bitmap for this icon. - """ - bmp = wxBitmap("images/" + iconName + "Icon.bmp", wxBITMAP_TYPE_BMP) - wxStaticBitmap.__init__(self, parent, iconID, bmp, wxDefaultPosition, - wxSize(bmp.GetWidth(), bmp.GetHeight())) - self.SetToolTip(wxToolTip(toolTip)) + The icon name is used to get the appropriate bitmap for this icon. + """ + bmp = wxBitmap("images/" + iconName + "Icon.bmp", wxBITMAP_TYPE_BMP) + wxStaticBitmap.__init__(self, parent, iconID, bmp, wxDefaultPosition, + wxSize(bmp.GetWidth(), bmp.GetHeight())) + self.SetToolTip(wxToolTip(toolTip)) - self.iconID = iconID - self.iconName = iconName - self.isSelected = false + self.iconID = iconID + self.iconName = iconName + self.isSelected = False def select(self): - """ Select the icon. + """ Select the icon. - The icon's visual representation is updated appropriately. - """ - if self.isSelected: return # Nothing to do! + The icon's visual representation is updated appropriately. + """ + if self.isSelected: return # Nothing to do! - bmp = wxBitmap("images/" + self.iconName + "IconSel.bmp", - wxBITMAP_TYPE_BMP) - self.SetBitmap(bmp) - self.isSelected = true + bmp = wxBitmap("images/" + self.iconName + "IconSel.bmp", + wxBITMAP_TYPE_BMP) + self.SetBitmap(bmp) + self.isSelected = True def deselect(self): - """ Deselect the icon. + """ Deselect the icon. - The icon's visual representation is updated appropriately. - """ - if not self.isSelected: return # Nothing to do! + The icon's visual representation is updated appropriately. + """ + if not self.isSelected: return # Nothing to do! - bmp = wxBitmap("images/" + self.iconName + "Icon.bmp", - wxBITMAP_TYPE_BMP) - self.SetBitmap(bmp) - self.isSelected = false + bmp = wxBitmap("images/" + self.iconName + "Icon.bmp", + wxBITMAP_TYPE_BMP) + self.SetBitmap(bmp) + self.isSelected = False #---------------------------------------------------------------------------- @@ -2290,298 +2290,298 @@ class ToolOptionIndicator(wxWindow): """ A visual indicator which shows the current tool options. """ def __init__(self, parent): - """ Standard constructor. - """ - wxWindow.__init__(self, parent, -1, wxDefaultPosition, wxSize(52, 32)) + """ Standard constructor. + """ + wxWindow.__init__(self, parent, -1, wxDefaultPosition, wxSize(52, 32)) - self.penColour = wxBLACK - self.fillColour = wxWHITE - self.lineSize = 1 + self.penColour = wxBLACK + self.fillColour = wxWHITE + self.lineSize = 1 - EVT_PAINT(self, self.OnPaint) + EVT_PAINT(self, self.OnPaint) def setPenColour(self, penColour): - """ Set the indicator's current pen colour. - """ - self.penColour = penColour - self.Refresh() + """ Set the indicator's current pen colour. + """ + self.penColour = penColour + self.Refresh() def setFillColour(self, fillColour): - """ Set the indicator's current fill colour. - """ - self.fillColour = fillColour - self.Refresh() + """ Set the indicator's current fill colour. + """ + self.fillColour = fillColour + self.Refresh() def setLineSize(self, lineSize): - """ Set the indicator's current pen colour. - """ - self.lineSize = lineSize - self.Refresh() + """ Set the indicator's current pen colour. + """ + self.lineSize = lineSize + self.Refresh() def OnPaint(self, event): - """ Paint our tool option indicator. - """ - dc = wxPaintDC(self) - dc.BeginDrawing() + """ Paint our tool option indicator. + """ + dc = wxPaintDC(self) + dc.BeginDrawing() - if self.lineSize == 0: - dc.SetPen(wxPen(self.penColour, self.lineSize, wxTRANSPARENT)) - else: - dc.SetPen(wxPen(self.penColour, self.lineSize, wxSOLID)) - dc.SetBrush(wxBrush(self.fillColour, wxSOLID)) + if self.lineSize == 0: + dc.SetPen(wxPen(self.penColour, self.lineSize, wxTRANSPARENT)) + else: + dc.SetPen(wxPen(self.penColour, self.lineSize, wxSOLID)) + dc.SetBrush(wxBrush(self.fillColour, wxSOLID)) - dc.DrawRectangle(5, 5, self.GetSize().width - 10, - self.GetSize().height - 10) + dc.DrawRectangle(5, 5, self.GetSize().width - 10, + self.GetSize().height - 10) - dc.EndDrawing() + dc.EndDrawing() #---------------------------------------------------------------------------- class EditTextObjectDialog(wxDialog): """ Dialog box used to edit the properties of a text object. - The user can edit the object's text, font, size, and text style. + The user can edit the object's text, font, size, and text style. """ def __init__(self, parent, title): - """ Standard constructor. - """ - wxDialog.__init__(self, parent, -1, title) + """ Standard constructor. + """ + wxDialog.__init__(self, parent, -1, title) - self.textCtrl = wxTextCtrl(self, 1001, "", style=wxTE_PROCESS_ENTER, - validator=TextObjectValidator()) - extent = self.textCtrl.GetFullTextExtent("Hy") - lineHeight = extent[1] + extent[3] - self.textCtrl.SetSize(wxSize(-1, lineHeight * 4)) + self.textCtrl = wxTextCtrl(self, 1001, "", style=wxTE_PROCESS_ENTER, + validator=TextObjectValidator()) + extent = self.textCtrl.GetFullTextExtent("Hy") + lineHeight = extent[1] + extent[3] + self.textCtrl.SetSize(wxSize(-1, lineHeight * 4)) - EVT_TEXT_ENTER(self, 1001, self._doEnter) + EVT_TEXT_ENTER(self, 1001, self._doEnter) - fonts = wxFontEnumerator() - fonts.EnumerateFacenames() - self.fontList = fonts.GetFacenames() - self.fontList.sort() + fonts = wxFontEnumerator() + fonts.EnumerateFacenames() + self.fontList = fonts.GetFacenames() + self.fontList.sort() - fontLabel = wxStaticText(self, -1, "Font:") - self._setFontOptions(fontLabel, weight=wxBOLD) + fontLabel = wxStaticText(self, -1, "Font:") + self._setFontOptions(fontLabel, weight=wxBOLD) - self.fontCombo = wxComboBox(self, -1, "", wxDefaultPosition, - wxDefaultSize, self.fontList, - style = wxCB_READONLY) - self.fontCombo.SetSelection(0) # Default to first available font. + self.fontCombo = wxComboBox(self, -1, "", wxDefaultPosition, + wxDefaultSize, self.fontList, + style = wxCB_READONLY) + self.fontCombo.SetSelection(0) # Default to first available font. - self.sizeList = ["8", "9", "10", "12", "14", "16", - "18", "20", "24", "32", "48", "72"] + self.sizeList = ["8", "9", "10", "12", "14", "16", + "18", "20", "24", "32", "48", "72"] - sizeLabel = wxStaticText(self, -1, "Size:") - self._setFontOptions(sizeLabel, weight=wxBOLD) + sizeLabel = wxStaticText(self, -1, "Size:") + self._setFontOptions(sizeLabel, weight=wxBOLD) - self.sizeCombo = wxComboBox(self, -1, "", wxDefaultPosition, - wxDefaultSize, self.sizeList, - style=wxCB_READONLY) - self.sizeCombo.SetSelection(3) # Default to 12 point text. + self.sizeCombo = wxComboBox(self, -1, "", wxDefaultPosition, + wxDefaultSize, self.sizeList, + style=wxCB_READONLY) + self.sizeCombo.SetSelection(3) # Default to 12 point text. - gap = wxLEFT | wxTOP | wxRIGHT + gap = wxLEFT | wxTOP | wxRIGHT - comboSizer = wxBoxSizer(wxHORIZONTAL) - comboSizer.Add(fontLabel, 0, gap | wxALIGN_CENTRE_VERTICAL, 5) - comboSizer.Add(self.fontCombo, 0, gap, 5) - comboSizer.Add(5, 5) # Spacer. - comboSizer.Add(sizeLabel, 0, gap | wxALIGN_CENTRE_VERTICAL, 5) - comboSizer.Add(self.sizeCombo, 0, gap, 5) + comboSizer = wxBoxSizer(wxHORIZONTAL) + comboSizer.Add(fontLabel, 0, gap | wxALIGN_CENTRE_VERTICAL, 5) + comboSizer.Add(self.fontCombo, 0, gap, 5) + comboSizer.Add(5, 5) # Spacer. + comboSizer.Add(sizeLabel, 0, gap | wxALIGN_CENTRE_VERTICAL, 5) + comboSizer.Add(self.sizeCombo, 0, gap, 5) - self.boldCheckbox = wxCheckBox(self, -1, "Bold") - self.italicCheckbox = wxCheckBox(self, -1, "Italic") - self.underlineCheckbox = wxCheckBox(self, -1, "Underline") + self.boldCheckbox = wxCheckBox(self, -1, "Bold") + self.italicCheckbox = wxCheckBox(self, -1, "Italic") + self.underlineCheckbox = wxCheckBox(self, -1, "Underline") - self._setFontOptions(self.boldCheckbox, weight=wxBOLD) - self._setFontOptions(self.italicCheckbox, style=wxITALIC) - self._setFontOptions(self.underlineCheckbox, underline=true) + self._setFontOptions(self.boldCheckbox, weight=wxBOLD) + self._setFontOptions(self.italicCheckbox, style=wxITALIC) + self._setFontOptions(self.underlineCheckbox, underline=True) - styleSizer = wxBoxSizer(wxHORIZONTAL) - styleSizer.Add(self.boldCheckbox, 0, gap, 5) - styleSizer.Add(self.italicCheckbox, 0, gap, 5) - styleSizer.Add(self.underlineCheckbox, 0, gap, 5) + styleSizer = wxBoxSizer(wxHORIZONTAL) + styleSizer.Add(self.boldCheckbox, 0, gap, 5) + styleSizer.Add(self.italicCheckbox, 0, gap, 5) + styleSizer.Add(self.underlineCheckbox, 0, gap, 5) - self.okButton = wxButton(self, wxID_OK, "OK") - self.cancelButton = wxButton(self, wxID_CANCEL, "Cancel") + self.okButton = wxButton(self, wxID_OK, "OK") + self.cancelButton = wxButton(self, wxID_CANCEL, "Cancel") - btnSizer = wxBoxSizer(wxHORIZONTAL) - btnSizer.Add(self.okButton, 0, gap, 5) - btnSizer.Add(self.cancelButton, 0, gap, 5) + btnSizer = wxBoxSizer(wxHORIZONTAL) + btnSizer.Add(self.okButton, 0, gap, 5) + btnSizer.Add(self.cancelButton, 0, gap, 5) - sizer = wxBoxSizer(wxVERTICAL) - sizer.Add(self.textCtrl, 1, gap | wxEXPAND, 5) - sizer.Add(10, 10) # Spacer. - sizer.Add(comboSizer, 0, gap | wxALIGN_CENTRE, 5) - sizer.Add(styleSizer, 0, gap | wxALIGN_CENTRE, 5) - sizer.Add(10, 10) # Spacer. - sizer.Add(btnSizer, 0, gap | wxALIGN_CENTRE, 5) + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(self.textCtrl, 1, gap | wxEXPAND, 5) + sizer.Add(10, 10) # Spacer. + sizer.Add(comboSizer, 0, gap | wxALIGN_CENTRE, 5) + sizer.Add(styleSizer, 0, gap | wxALIGN_CENTRE, 5) + sizer.Add(10, 10) # Spacer. + sizer.Add(btnSizer, 0, gap | wxALIGN_CENTRE, 5) - self.SetAutoLayout(true) - self.SetSizer(sizer) - sizer.Fit(self) + self.SetAutoLayout(True) + self.SetSizer(sizer) + sizer.Fit(self) - self.textCtrl.SetFocus() + self.textCtrl.SetFocus() def objectToDialog(self, obj): - """ Copy the properties of the given text object into the dialog box. - """ - self.textCtrl.SetValue(obj.getText()) - self.textCtrl.SetSelection(0, len(obj.getText())) + """ Copy the properties of the given text object into the dialog box. + """ + self.textCtrl.SetValue(obj.getText()) + self.textCtrl.SetSelection(0, len(obj.getText())) - for i in range(len(self.fontList)): - if self.fontList[i] == obj.getTextFont(): - self.fontCombo.SetSelection(i) - break + for i in range(len(self.fontList)): + if self.fontList[i] == obj.getTextFont(): + self.fontCombo.SetSelection(i) + break - for i in range(len(self.sizeList)): - if self.sizeList[i] == str(obj.getTextSize()): - self.sizeCombo.SetSelection(i) - break + for i in range(len(self.sizeList)): + if self.sizeList[i] == str(obj.getTextSize()): + self.sizeCombo.SetSelection(i) + break - self.boldCheckbox.SetValue(obj.getTextBoldface()) - self.italicCheckbox.SetValue(obj.getTextItalic()) - self.underlineCheckbox.SetValue(obj.getTextUnderline()) + self.boldCheckbox.SetValue(obj.getTextBoldface()) + self.italicCheckbox.SetValue(obj.getTextItalic()) + self.underlineCheckbox.SetValue(obj.getTextUnderline()) def dialogToObject(self, obj): - """ Copy the properties from the dialog box into the given text object. - """ - obj.setText(self.textCtrl.GetValue()) - obj.setTextFont(self.fontCombo.GetValue()) - obj.setTextSize(string.atoi(self.sizeCombo.GetValue())) - obj.setTextBoldface(self.boldCheckbox.GetValue()) - obj.setTextItalic(self.italicCheckbox.GetValue()) - obj.setTextUnderline(self.underlineCheckbox.GetValue()) - obj.fitToText() + """ Copy the properties from the dialog box into the given text object. + """ + obj.setText(self.textCtrl.GetValue()) + obj.setTextFont(self.fontCombo.GetValue()) + obj.setTextSize(int(self.sizeCombo.GetValue())) + obj.setTextBoldface(self.boldCheckbox.GetValue()) + obj.setTextItalic(self.italicCheckbox.GetValue()) + obj.setTextUnderline(self.underlineCheckbox.GetValue()) + obj.fitToText() # ====================== # == Private Routines == # ====================== def _setFontOptions(self, ctrl, family=None, pointSize=-1, - style=wxNORMAL, weight=wxNORMAL, - underline=false): - """ Change the font settings for the given control. + style=wxNORMAL, weight=wxNORMAL, + underline=False): + """ Change the font settings for the given control. - The meaning of the 'family', 'pointSize', 'style', 'weight' and - 'underline' parameters are the same as for the wxFont constructor. - If the family and/or pointSize isn't specified, the current default - value is used. - """ - if family == None: family = ctrl.GetFont().GetFamily() - if pointSize == -1: pointSize = ctrl.GetFont().GetPointSize() + The meaning of the 'family', 'pointSize', 'style', 'weight' and + 'underline' parameters are the same as for the wxFont constructor. + If the family and/or pointSize isn't specified, the current default + value is used. + """ + if family == None: family = ctrl.GetFont().GetFamily() + if pointSize == -1: pointSize = ctrl.GetFont().GetPointSize() - ctrl.SetFont(wxFont(pointSize, family, style, weight, underline)) - ctrl.SetSize(ctrl.GetBestSize()) # Adjust size to reflect font change. + ctrl.SetFont(wxFont(pointSize, family, style, weight, underline)) + ctrl.SetSize(ctrl.GetBestSize()) # Adjust size to reflect font change. def _doEnter(self, event): - """ Respond to the user hitting the ENTER key. + """ Respond to the user hitting the ENTER key. - We simulate clicking on the "OK" button. - """ - if self.Validate(): self.Show(false) + We simulate clicking on the "OK" button. + """ + if self.Validate(): self.Show(False) #---------------------------------------------------------------------------- class TextObjectValidator(wxPyValidator): """ This validator is used to ensure that the user has entered something - into the text object editor dialog's text field. + into the text object editor dialog's text field. """ def __init__(self): - """ Standard constructor. - """ - wxPyValidator.__init__(self) + """ Standard constructor. + """ + wxPyValidator.__init__(self) def Clone(self): - """ Standard cloner. + """ Standard cloner. - Note that every validator must implement the Clone() method. - """ - return TextObjectValidator() + Note that every validator must implement the Clone() method. + """ + return TextObjectValidator() def Validate(self, win): - """ Validate the contents of the given text control. - """ - textCtrl = wxPyTypeCast(self.GetWindow(), "wxTextCtrl") - text = textCtrl.GetValue() + """ Validate the contents of the given text control. + """ + textCtrl = wxPyTypeCast(self.GetWindow(), "wxTextCtrl") + text = textCtrl.GetValue() - if len(text) == 0: - wxMessageBox("A text object must contain some text!", "Error") - return false - else: - return true + if len(text) == 0: + wxMessageBox("A text object must contain some text!", "Error") + return False + else: + return True def TransferToWindow(self): - """ Transfer data from validator to window. + """ Transfer data from validator to window. - The default implementation returns false, indicating that an error - occurred. We simply return true, as we don't do any data transfer. - """ - return true # Prevent wxDialog from complaining. + The default implementation returns False, indicating that an error + occurred. We simply return True, as we don't do any data transfer. + """ + return True # Prevent wxDialog from complaining. def TransferFromWindow(self): - """ Transfer data from window to validator. + """ Transfer data from window to validator. - The default implementation returns false, indicating that an error - occurred. We simply return true, as we don't do any data transfer. - """ - return true # Prevent wxDialog from complaining. + The default implementation returns False, indicating that an error + occurred. We simply return True, as we don't do any data transfer. + """ + return True # Prevent wxDialog from complaining. #---------------------------------------------------------------------------- class ExceptionHandler: """ A simple error-handling class to write exceptions to a text file. - Under MS Windows, the standard DOS console window doesn't scroll and - closes as soon as the application exits, making it hard to find and - view Python exceptions. This utility class allows you to handle Python - exceptions in a more friendly manner. + Under MS Windows, the standard DOS console window doesn't scroll and + closes as soon as the application exits, making it hard to find and + view Python exceptions. This utility class allows you to handle Python + exceptions in a more friendly manner. """ def __init__(self): - """ Standard constructor. - """ - self._buff = "" - if os.path.exists("errors.txt"): - os.remove("errors.txt") # Delete previous error log, if any. + """ Standard constructor. + """ + self._buff = "" + if os.path.exists("errors.txt"): + os.remove("errors.txt") # Delete previous error log, if any. def write(self, s): - """ Write the given error message to a text file. - - Note that if the error message doesn't end in a carriage return, we - have to buffer up the inputs until a carriage return is received. - """ - if (s[-1] != "\n") and (s[-1] != "\r"): - self._buff = self._buff + s - return - - try: - s = self._buff + s - self._buff = "" - - if s[:9] == "Traceback": - # Tell the user than an exception occurred. - wxMessageBox("An internal error has occurred.\nPlease " + \ - "refer to the 'errors.txt' file for details.", - "Error", wxOK | wxCENTRE | wxICON_EXCLAMATION) - - f = open("errors.txt", "a") - f.write(s) - f.close() - except: - pass # Don't recursively crash on errors. + """ Write the given error message to a text file. + + Note that if the error message doesn't end in a carriage return, we + have to buffer up the inputs until a carriage return is received. + """ + if (s[-1] != "\n") and (s[-1] != "\r"): + self._buff = self._buff + s + return + + try: + s = self._buff + s + self._buff = "" + + if s[:9] == "Traceback": + # Tell the user than an exception occurred. + wxMessageBox("An internal error has occurred.\nPlease " + \ + "refer to the 'errors.txt' file for details.", + "Error", wxOK | wxCENTRE | wxICON_EXCLAMATION) + + f = open("errors.txt", "a") + f.write(s) + f.close() + except: + pass # Don't recursively crash on errors. #---------------------------------------------------------------------------- @@ -2589,32 +2589,32 @@ class SketchApp(wxApp): """ The main pySketch application object. """ def OnInit(self): - """ Initialise the application. - """ + """ Initialise the application. + """ wxInitAllImageHandlers() - global _docList - _docList = [] - - if len(sys.argv) == 1: - # No file name was specified on the command line -> start with a - # blank document. - frame = DrawingFrame(None, -1, "Untitled") - frame.Centre() - frame.Show(TRUE) - _docList.append(frame) - else: - # Load the file(s) specified on the command line. - for arg in sys.argv[1:]: - fileName = os.path.join(os.getcwd(), arg) - if os.path.isfile(fileName): - frame = DrawingFrame(None, -1, - os.path.basename(fileName), - fileName=fileName) - frame.Show(TRUE) - _docList.append(frame) - - return TRUE + global _docList + _docList = [] + + if len(sys.argv) == 1: + # No file name was specified on the command line -> start with a + # blank document. + frame = DrawingFrame(None, -1, "Untitled") + frame.Centre() + frame.Show(True) + _docList.append(frame) + else: + # Load the file(s) specified on the command line. + for arg in sys.argv[1:]: + fileName = os.path.join(os.getcwd(), arg) + if os.path.isfile(fileName): + frame = DrawingFrame(None, -1, + os.path.basename(fileName), + fileName=fileName) + frame.Show(True) + _docList.append(frame) + + return True #---------------------------------------------------------------------------- diff --git a/wxPython/samples/stxview/README.txt b/wxPython/samples/stxview/README.txt deleted file mode 100644 index e25e6c52c8..0000000000 --- a/wxPython/samples/stxview/README.txt +++ /dev/null @@ -1,3 +0,0 @@ - -This sample is a simple StructuredText viewer/editor. - diff --git a/wxPython/samples/stxview/StructuredText/ClassicDocumentClass.py b/wxPython/samples/stxview/StructuredText/ClassicDocumentClass.py deleted file mode 100644 index 69fc9c81bb..0000000000 --- a/wxPython/samples/stxview/StructuredText/ClassicDocumentClass.py +++ /dev/null @@ -1,684 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -import re, ST, STDOM -from string import split, join, replace, expandtabs, strip, find -from STletters import letters,lettpunc,punctuations - -StringType=type('') -ListType=type([]) - -class StructuredTextExample(ST.StructuredTextParagraph): - """Represents a section of document with literal text, as for examples""" - - def __init__(self, subs, **kw): - t=[]; a=t.append - for s in subs: a(s.getNodeValue()) - apply(ST.StructuredTextParagraph.__init__, - (self, join(t,'\n\n'), ()), - kw) - - def getColorizableTexts(self): return () - def setColorizableTexts(self, src): pass # never color examples - -class StructuredTextBullet(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextNumbered(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextDescriptionTitle(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextDescriptionBody(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextDescription(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - - def __init__(self, title, src, subs, **kw): - apply(ST.StructuredTextParagraph.__init__, (self, src, subs), kw) - self._title=title - - def getColorizableTexts(self): return self._title, self._src - def setColorizableTexts(self, src): self._title, self._src = src - - def getChildren(self): - return (StructuredTextDescriptionTitle(self._title), - StructuredTextDescriptionBody(self._src, self._subs)) - -class StructuredTextSectionTitle(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextSection(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - def __init__(self, src, subs=None, **kw): - apply(ST.StructuredTextParagraph.__init__, - (self, StructuredTextSectionTitle(src), subs), - kw) - - def getColorizableTexts(self): - return self._src.getColorizableTexts() - - def setColorizableTexts(self,src): - self._src.setColorizableTexts(src) - -# a StructuredTextTable holds StructuredTextRows -class StructuredTextTable(ST.StructuredTextDocument): - """ - rows is a list of lists containing tuples, which - represent the columns/cells in each rows. - EX - rows = [[('row 1:column1',1)],[('row2:column1',1)]] - """ - - def __init__(self, rows, src, subs, **kw): - apply(ST.StructuredTextDocument.__init__,(self,subs),kw) - self._rows = [] - for row in rows: - if row: - self._rows.append(StructuredTextRow(row,kw)) - - def getRows(self): - return [self._rows] - - def _getRows(self): - return self.getRows() - - def getColorizableTexts(self): - """ - return a tuple where each item is a column/cell's - contents. The tuple, result, will be of this format. - ("r1 col1", "r1=col2", "r2 col1", "r2 col2") - """ - - #result = () - result = [] - for row in self._rows: - for column in row.getColumns()[0]: - #result = result[:] + (column.getColorizableTexts(),) - result.append(column.getColorizableTexts()[0]) - return result - - def setColorizableTexts(self,texts): - """ - texts is going to a tuple where each item is the - result of being mapped to the colortext function. - Need to insert the results appropriately into the - individual columns/cells - """ - for row_index in range(len(self._rows)): - for column_index in range(len(self._rows[row_index]._columns)): - self._rows[row_index]._columns[column_index].setColorizableTexts((texts[0],)) - texts = texts[1:] - - def _getColorizableTexts(self): - return self.getColorizableTexts() - - def _setColorizableTexts(self): - return self.setColorizableTexts() - -# StructuredTextRow holds StructuredTextColumns -class StructuredTextRow(ST.StructuredTextDocument): - - def __init__(self,row,kw): - """ - row is a list of tuples, where each tuple is - the raw text for a cell/column and the span - of that cell/column". - EX - [('this is column one',1), ('this is column two',1)] - """ - - apply(ST.StructuredTextDocument.__init__,(self,[]),kw) - self._columns = [] - for column in row: - self._columns.append(StructuredTextColumn(column[0],column[1],kw)) - def getColumns(self): - return [self._columns] - - def _getColumns(self): - return [self._columns] - -# this holds the raw text of a table cell -class StructuredTextColumn(ST.StructuredTextParagraph): - """ - StructuredTextColumn is a cell/column in a table. - This contains the actual text of a column and is - thus a StructuredTextParagraph. A StructuredTextColumn - also holds the span of its column - """ - - def __init__(self,text,span,kw): - apply(ST.StructuredTextParagraph.__init__,(self,text,[]),kw) - self._span = span - - def getSpan(self): - return self._span - - def _getSpan(self): - return self._span - -class StructuredTextMarkup(STDOM.Element): - - def __init__(self, v, **kw): - self._value=v - self._attributes=kw.keys() - for k, v in kw.items(): setattr(self, k, v) - - def getChildren(self, type=type, lt=type([])): - v=self._value - if type(v) is not lt: v=[v] - return v - - def getColorizableTexts(self): return self._value, - def setColorizableTexts(self, v): self._value=v[0] - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, `self._value`) - -class StructuredTextLiteral(StructuredTextMarkup): - def getColorizableTexts(self): return () - def setColorizableTexts(self, v): pass - -class StructuredTextEmphasis(StructuredTextMarkup): pass - -class StructuredTextStrong(StructuredTextMarkup): pass - -class StructuredTextInnerLink(StructuredTextMarkup): pass - -class StructuredTextNamedLink(StructuredTextMarkup): pass - -class StructuredTextUnderline(StructuredTextMarkup): pass - -class StructuredTextLink(StructuredTextMarkup): - "A simple hyperlink" - -class DocumentClass: - """ - Class instance calls [ex.=> x()] require a structured text - structure. Doc will then parse each paragraph in the structure - and will find the special structures within each paragraph. - Each special structure will be stored as an instance. Special - structures within another special structure are stored within - the 'top' structure - EX : '-underline this-' => would be turned into an underline - instance. '-underline **this**' would be stored as an underline - instance with a strong instance stored in its string - """ - - paragraph_types = [ - 'doc_bullet', - 'doc_numbered', - 'doc_description', - 'doc_header', - 'doc_table', - ] - - text_types = [ - 'doc_href', - 'doc_strong', - 'doc_emphasize', - 'doc_literal', - 'doc_inner_link', - 'doc_named_link', - 'doc_underline', - ] - - def __call__(self, doc): - if type(doc) is type(''): - doc=ST.StructuredText(doc) - doc.setSubparagraphs(self.color_paragraphs( - doc.getSubparagraphs())) - else: - doc=ST.StructuredTextDocument(self.color_paragraphs( - doc.getSubparagraphs())) - return doc - - def parse(self, raw_string, text_type, - type=type, st=type(''), lt=type([])): - - """ - Parse accepts a raw_string, an expr to test the raw_string, - and the raw_string's subparagraphs. - - Parse will continue to search through raw_string until - all instances of expr in raw_string are found. - - If no instances of expr are found, raw_string is returned. - Otherwise a list of substrings and instances is returned - """ - - tmp = [] # the list to be returned if raw_string is split - append=tmp.append - - if type(text_type) is st: text_type=getattr(self, text_type) - - while 1: - t = text_type(raw_string) - if not t: break - #an instance of expr was found - t, start, end = t - - if start: append(raw_string[0:start]) - - tt=type(t) - if tt is st: - # if we get a string back, add it to text to be parsed - raw_string = t+raw_string[end:len(raw_string)] - else: - if tt is lt: - # is we get a list, append it's elements - tmp[len(tmp):]=t - else: - # normal case, an object - append(t) - raw_string = raw_string[end:len(raw_string)] - - if not tmp: return raw_string # nothing found - - if raw_string: append(raw_string) - elif len(tmp)==1: return tmp[0] - - return tmp - - - def color_text(self, str, types=None): - """Search the paragraph for each special structure - """ - if types is None: types=self.text_types - - for text_type in types: - - if type(str) is StringType: - str = self.parse(str, text_type) - elif type(str) is ListType: - r=[]; a=r.append - for s in str: - if type(s) is StringType: - s=self.parse(s, text_type) - if type(s) is ListType: r[len(r):]=s - else: a(s) - else: - s.setColorizableTexts( - map(self.color_text, - s.getColorizableTexts() - )) - a(s) - str=r - else: - r=[]; a=r.append; color=self.color_text - for s in str.getColorizableTexts(): - color(s, (text_type,)) - a(s) - - str.setColorizableTexts(r) - - return str - - def color_paragraphs(self, raw_paragraphs, - type=type, sequence_types=(type([]), type(())), - st=type('')): - result=[] - for paragraph in raw_paragraphs: - - if paragraph.getNodeName() != 'StructuredTextParagraph': - result.append(paragraph) - continue - - for pt in self.paragraph_types: - if type(pt) is st: - # grab the corresponding function - pt=getattr(self, pt) - # evaluate the paragraph - r=pt(paragraph) - if r: - if type(r) not in sequence_types: - r=r, - new_paragraphs=r - for paragraph in new_paragraphs: - paragraph.setSubparagraphs(self.color_paragraphs(paragraph.getSubparagraphs())) - break - else: - new_paragraphs=ST.StructuredTextParagraph(paragraph.getColorizableTexts()[0], - self.color_paragraphs(paragraph.getSubparagraphs()), - indent=paragraph.indent), - # color the inline StructuredText types - # for each StructuredTextParagraph - for paragraph in new_paragraphs: - paragraph.setColorizableTexts( - map(self.color_text, - paragraph.getColorizableTexts() - )) - result.append(paragraph) - - return result - - def doc_table(self,paragraph, expr = re.compile('(\s*)([||]+)').match): - #print "paragraph=>", type(paragraph), paragraph, paragraph._src - text = paragraph.getColorizableTexts()[0] - m = expr(text) - - if not (m): - return None - rows = [] - - # initial split - for row in split(text,"\n"): - rows.append(row) - - # clean up the rows - for index in range(len(rows)): - tmp = [] - rows[index] = strip(rows[index]) - l = len(rows[index])-2 - result = split(rows[index][:l],"||") - for text in result: - if text: - tmp.append(text) - tmp.append('') - else: - tmp.append(text) - rows[index] = tmp - # remove trailing '''s - for index in range(len(rows)): - l = len(rows[index])-1 - rows[index] = rows[index][:l] - - result = [] - for row in rows: - cspan = 0 - tmp = [] - for item in row: - if item: - tmp.append((item,cspan)) - cspan = 0 - else: - cspan = cspan + 1 - result.append(tmp) - - subs = paragraph.getSubparagraphs() - indent=paragraph.indent - return StructuredTextTable(result,text,subs,indent=paragraph.indent) - - def doc_bullet(self, paragraph, expr = re.compile('\s*[-*o]\s+').match): - top=paragraph.getColorizableTexts()[0] - m=expr(top) - - if not m: - return None - - subs=paragraph.getSubparagraphs() - if top[-2:]=='::': - subs=[StructuredTextExample(subs)] - top=top[:-1] - return StructuredTextBullet(top[m.span()[1]:], subs, - indent=paragraph.indent, - bullet=top[:m.span()[1]] - ) - - def doc_numbered( - self, paragraph, - expr = re.compile('(\s*[%s]+\.)|(\s*[0-9]+\.)|(\s*[0-9]+\s+)' % letters).match): - - # This is the old expression. It had a nasty habit - # of grabbing paragraphs that began with a single - # letter word even if there was no following period. - - #expr = re.compile('\s*' - # '(([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.)*' - # '([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.?' - # '\s+').match): - - top=paragraph.getColorizableTexts()[0] - m=expr(top) - if not m: return None - subs=paragraph.getSubparagraphs() - if top[-2:]=='::': - subs=[StructuredTextExample(subs)] - top=top[:-1] - return StructuredTextNumbered(top[m.span()[1]:], subs, - indent=paragraph.indent, - number=top[:m.span()[1]]) - - def doc_description( - self, paragraph, - delim = re.compile('\s+--\s+').search, - nb=re.compile(r'[^\000- ]').search, - ): - - top=paragraph.getColorizableTexts()[0] - d=delim(top) - if not d: return None - start, end = d.span() - title=top[:start] - if find(title, '\n') >= 0: return None - if not nb(title): return None - d=top[start:end] - top=top[end:] - - subs=paragraph.getSubparagraphs() - if top[-2:]=='::': - subs=[StructuredTextExample(subs)] - top=top[:-1] - - return StructuredTextDescription( - title, top, subs, - indent=paragraph.indent, - delim=d) - - def doc_header(self, paragraph, - expr = re.compile('[ %s0-9.:/,-_*<>\?\'\"]+' % letters).match - ): - subs=paragraph.getSubparagraphs() - if not subs: return None - top=paragraph.getColorizableTexts()[0] - if not strip(top): return None - if top[-2:]=='::': - subs=StructuredTextExample(subs) - if strip(top)=='::': return subs - return ST.StructuredTextParagraph(top[:-1], - [subs], - indent=paragraph.indent, - level=paragraph.level) - - if find(top,'\n') >= 0: return None - return StructuredTextSection(top, subs, indent=paragraph.indent, level=paragraph.level) - - def doc_literal( - self, s, - expr=re.compile( - "(?:\s|^)'" # open - "([^ \t\n\r\f\v']|[^ \t\n\r\f\v'][^\n']*[^ \t\n\r\f\v'])" # contents - "'(?:\s|[,.;:!?]|$)" # close - ).search): - - r=expr(s) - if r: - start, end = r.span(1) - return (StructuredTextLiteral(s[start:end]), start-1, end+1) - else: - return None - - def doc_emphasize( - self, s, - expr = re.compile('\s*\*([ \n%s0-9]+)\*(?!\*|-)' % lettpunc).search - ): - - r=expr(s) - if r: - start, end = r.span(1) - return (StructuredTextEmphasis(s[start:end]), start-1, end+1) - else: - return None - - def doc_inner_link(self, - s, - expr1 = re.compile("\.\.\s*").search, - expr2 = re.compile("\[[%s0-9]+\]" % letters).search): - - # make sure we dont grab a named link - if expr2(s) and expr1(s): - start1,end1 = expr1(s).span() - start2,end2 = expr2(s).span() - if end1 == start2: - # uh-oh, looks like a named link - return None - else: - # the .. is somewhere else, ignore it - return (StructuredTextInnerLink(s[start2+1:end2-1]),start2,end2) - return None - elif expr2(s) and not expr1(s): - start,end = expr2(s).span() - return (StructuredTextInnerLink(s[start+1:end-1]),start,end) - return None - - def doc_named_link(self, - s, - expr=re.compile("(\.\.\s)(\[[%s0-9]+\])" % letters).search): - - result = expr(s) - if result: - start,end = result.span(2) - a,b = result.span(1) - str = strip(s[a:b]) + s[start:end] - str = s[start+1:end-1] - st,en = result.span() - return (StructuredTextNamedLink(str),st,en) - #return (StructuredTextNamedLink(s[st:en]),st,en) - return None - - def doc_underline(self, - s, - expr=re.compile("\s+\_([0-9%s ]+)\_" % lettpunc).search): - - result = expr(s) - if result: - start,end = result.span(1) - st,e = result.span() - return (StructuredTextUnderline(s[start:end]),st,e) - else: - return None - - def doc_strong(self, - s, - expr = re.compile('\s*\*\*([ \n%s0-9]+)\*\*' % lettpunc).search - ): - - r=expr(s) - if r: - start, end = r.span(1) - return (StructuredTextStrong(s[start:end]), start-2, end+2) - else: - return None - - def doc_href( - - self, s, - expr1 = re.compile("(\"[ %s0-9\n\-\.\,\;\(\)\/\:\/\*\']+\")(:)([a-zA-Z0-9\@\.\,\?\!\/\:\;\-\#\~]+)([,]*\s*)" % letters).search, - expr2 = re.compile('(\"[ %s0-9\n\-\.\:\;\(\)\/\*\']+\")([,]+\s+)([a-zA-Z0-9\@\.\,\?\!\/\:\;\-\#\~]+)(\s*)' % letters).search): - - r=expr1(s) or expr2(s) - - if r: - # need to grab the href part and the - # beginning part - - start,e = r.span(1) - name = s[start:e] - name = replace(name,'"','',2) - st,end = r.span(3) - - if s[end-1:end] in punctuations: end-=1 - link = s[st:end] - - # name is the href title, link is the target - # of the href - return (StructuredTextLink(name, href=link), - start, end) - - - else: - return None diff --git a/wxPython/samples/stxview/StructuredText/ClassicStructuredText.py b/wxPython/samples/stxview/StructuredText/ClassicStructuredText.py deleted file mode 100644 index b591558f73..0000000000 --- a/wxPython/samples/stxview/StructuredText/ClassicStructuredText.py +++ /dev/null @@ -1,625 +0,0 @@ -#! /usr/bin/env python -- # -*- python -*- -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## -'''Structured Text Manipulation - -Parse a structured text string into a form that can be used with -structured formats, like html. - -Structured text is text that uses indentation and simple -symbology to indicate the structure of a document. - -A structured string consists of a sequence of paragraphs separated by -one or more blank lines. Each paragraph has a level which is defined -as the minimum indentation of the paragraph. A paragraph is a -sub-paragraph of another paragraph if the other paragraph is the last -preceding paragraph that has a lower level. - -Special symbology is used to indicate special constructs: - -- A single-line paragraph whose immediately succeeding paragraphs are lower - level is treated as a header. - -- A paragraph that begins with a '-', '*', or 'o' is treated as an - unordered list (bullet) element. - -- A paragraph that begins with a sequence of digits followed by a - white-space character is treated as an ordered list element. - -- A paragraph that begins with a sequence of sequences, where each - sequence is a sequence of digits or a sequence of letters followed - by a period, is treated as an ordered list element. - -- A paragraph with a first line that contains some text, followed by - some white-space and '--' is treated as - a descriptive list element. The leading text is treated as the - element title. - -- Sub-paragraphs of a paragraph that ends in the word 'example' or the - word 'examples', or '::' is treated as example code and is output as is. - -- Text enclosed single quotes (with white-space to the left of the - first quote and whitespace or punctuation to the right of the second quote) - is treated as example code. - -- Text surrounded by '*' characters (with white-space to the left of the - first '*' and whitespace or punctuation to the right of the second '*') - is emphasized. - -- Text surrounded by '**' characters (with white-space to the left of the - first '**' and whitespace or punctuation to the right of the second '**') - is made strong. - -- Text surrounded by '_' underscore characters (with whitespace to the left - and whitespace or punctuation to the right) is made underlined. - -- Text encloded by double quotes followed by a colon, a URL, and concluded - by punctuation plus white space, *or* just white space, is treated as a - hyper link. For example: - - "Zope":http://www.zope.org/ is ... - - Is interpreted as '
    Zope is ....' - Note: This works for relative as well as absolute URLs. - -- Text enclosed by double quotes followed by a comma, one or more spaces, - an absolute URL and concluded by punctuation plus white space, or just - white space, is treated as a hyper link. For example: - - "mail me", mailto:amos@digicool.com. - - Is interpreted as 'mail me.' - -- Text enclosed in brackets which consists only of letters, digits, - underscores and dashes is treated as hyper links within the document. - For example: - - As demonstrated by Smith [12] this technique is quite effective. - - Is interpreted as '... by Smith [12] this ...'. Together - with the next rule this allows easy coding of references or end notes. - -- Text enclosed in brackets which is preceded by the start of a line, two - periods and a space is treated as a named link. For example: - - .. [12] "Effective Techniques" Smith, Joe ... - - Is interpreted as '[12] "Effective Techniques" ...'. - Together with the previous rule this allows easy coding of references or - end notes. - - -- A paragraph that has blocks of text enclosed in '||' is treated as a - table. The text blocks correspond to table cells and table rows are - denoted by newlines. By default the cells are center aligned. A cell - can span more than one column by preceding a block of text with an - equivalent number of cell separators '||'. Newlines and '|' cannot - be a part of the cell text. For example: - - |||| **Ingredients** || - || *Name* || *Amount* || - ||Spam||10|| - ||Eggs||3|| - - is interpreted as:: - - - - - - - - - - - - - - - - - -
    Ingredients
    Name Amount
    Spam10
    Eggs3
    - -''' - -import ts_regex -import regex -from ts_regex import gsub -from string import split, join, strip, find -import string,re - - -def untabify(aString, - indent_tab=ts_regex.compile('\(\n\|^\)\( *\)\t').search_group, - ): - '''\ - Convert indentation tabs to spaces. - ''' - result='' - rest=aString - while 1: - ts_results = indent_tab(rest, (1,2)) - if ts_results: - start, grps = ts_results - lnl=len(grps[0]) - indent=len(grps[1]) - result=result+rest[:start] - rest="\n%s%s" % (' ' * ((indent/8+1)*8), - rest[start+indent+1+lnl:]) - else: - return result+rest - -def indent(aString, indent=2): - """Indent a string the given number of spaces""" - r=split(untabify(aString),'\n') - if not r: return '' - if not r[-1]: del r[-1] - tab=' '*level - return "%s%s\n" % (tab,join(r,'\n'+tab)) - -def reindent(aString, indent=2, already_untabified=0): - "reindent a block of text, so that the minimum indent is as given" - - if not already_untabified: aString=untabify(aString) - - l=indent_level(aString)[0] - if indent==l: return aString - - r=[] - - append=r.append - - if indent > l: - tab=' ' * (indent-l) - for s in split(aString,'\n'): append(tab+s) - else: - l=l-indent - for s in split(aString,'\n'): append(s[l:]) - - return join(r,'\n') - -def indent_level(aString, - indent_space=ts_regex.compile('\n\( *\)').search_group, - ): - '''\ - Find the minimum indentation for a string, not counting blank lines. - ''' - start=0 - text='\n'+aString - indent=l=len(text) - while 1: - - ts_results = indent_space(text, (1,2), start) - if ts_results: - start, grps = ts_results - i=len(grps[0]) - start=start+i+1 - if start < l and text[start] != '\n': # Skip blank lines - if not i: return (0,aString) - if i < indent: indent = i - else: - return (indent,aString) - -def paragraphs(list,start): - l=len(list) - level=list[start][0] - i=start+1 - while i < l and list[i][0] > level: i=i+1 - return i-1-start - -def structure(list): - if not list: return [] - i=0 - l=len(list) - r=[] - while i < l: - sublen=paragraphs(list,i) - i=i+1 - r.append((list[i-1][1],structure(list[i:i+sublen]))) - i=i+sublen - return r - - -class Table: - CELL=' %s\n' - ROW=' \n%s \n' - TABLE='\n\n%s
    ' - - def create(self,aPar, - td_reg=re.compile(r'[ \t\n]*\|\|([^\0x00|]*)') - ): - '''parses a table and returns nested list representing the - table''' - self.table=[] - text=filter(None,split(aPar,'\n')) - for line in text: - row=[] - while 1: - mo = td_reg.match(line) - if not mo: return 0 - pos = mo.end(1) - row.append(mo.group(1)) - if pos==len(line):break - line=line[pos:] - self.table.append(row) - return 1 - - def html(self): - '''Creates an HTML representation of table''' - htmltable=[] - for row in self.table: - htmlrow=[] - colspan=1 - for cell in row: - if cell=='': - colspan=colspan+1 - continue - else: - htmlrow.append(self.CELL%(colspan,cell)) - colspan=1 - htmltable.append(self.ROW%join(htmlrow,'')) - return self.TABLE%join(htmltable,'') - -table=Table() - -class StructuredText: - - """Model text as structured collection of paragraphs. - - Structure is implied by the indentation level. - - This class is intended as a base classes that do actual text - output formatting. - """ - - def __init__(self, aStructuredString, level=0, - paragraph_divider=regex.compile('\(\r?\n *\)+\r?\n'), - ): - '''Convert a structured text string into a structured text object. - - Aguments: - - aStructuredString -- The string to be parsed. - level -- The level of top level headings to be created. - ''' - - - pat = ' \"([%s0-9-_,./?=@~&]*)\":' % string.letters+ \ - '([-:%s0-9_,./?=@#~&]*?)' % string.letters + \ - '([.:?;] )' - - p_reg = re.compile(pat,re.M) - - aStructuredString = p_reg.sub(r'\1\3 ' , aStructuredString) - - pat = ' \"([%s0-9-_,./?=@~&]*)\", ' % string.letters+ \ - '([-:%s0-9_,./?=@#~&]*?)' % string.letters + \ - '([.:?;] )' - - p_reg = re.compile(pat,re.M) - - aStructuredString = p_reg.sub(r'\1\3 ' , aStructuredString) - - - protoless = find(aStructuredString, '\2\3',s) - s=under.sub( r'\1\2\3',s) - s=code.sub( r'\1\2\3',s) - s=em.sub( r'\1\2\3',s) - return s - -class HTML(StructuredText): - - '''\ - An HTML structured text formatter. - '''\ - - def __str__(self, - extra_dl=re.compile("\n
    "), - extra_ul=re.compile("\n
      "), - extra_ol=re.compile("\n
        "), - ): - '''\ - Return an HTML string representation of the structured text data. - - ''' - s=self._str(self.structure,self.level) - s=extra_dl.sub('\n',s) - s=extra_ul.sub('\n',s) - s=extra_ol.sub('\n',s) - return s - - def ul(self, before, p, after): - if p: p="

        %s

        " % strip(ctag(p)) - return ('%s
        • %s\n%s\n
        \n' - % (before,p,after)) - - def ol(self, before, p, after): - if p: p="

        %s

        " % strip(ctag(p)) - return ('%s
        1. %s\n%s\n
        \n' - % (before,p,after)) - - def dl(self, before, t, d, after): - return ('%s
        %s

        %s

        \n%s\n
        \n' - % (before,ctag(t),ctag(d),after)) - - def head(self, before, t, level, d): - if level > 0 and level < 6: - return ('%s%s\n%s\n' - % (before,level,strip(ctag(t)),level,d)) - - t="

        %s

        " % strip(ctag(t)) - return ('%s
        %s\n
        %s\n
        \n' - % (before,t,d)) - - def normal(self,before,p,after): - return '%s

        %s

        \n%s\n' % (before,ctag(p),after) - - def pre(self,structure,tagged=0): - if not structure: return '' - if tagged: - r='' - else: - r='
        \n'
        -        for s in structure:
        -            r="%s%s\n\n%s" % (r,html_quote(s[0]),self.pre(s[1],1))
        -        if not tagged: r=r+'
        \n' - return r - - def table(self,before,table,after): - return '%s

        %s

        \n%s\n' % (before,ctag(table),after) - - def _str(self,structure,level, - # Static - bullet=ts_regex.compile('[ \t\n]*[o*-][ \t\n]+\([^\0]*\)' - ).match_group, - example=ts_regex.compile('[\0- ]examples?:[\0- ]*$' - ).search, - dl=ts_regex.compile('\([^\n]+\)[ \t]+--[ \t\n]+\([^\0]*\)' - ).match_group, - nl=ts_regex.compile('\n').search, - ol=ts_regex.compile( - '[ \t]*\(\([0-9]+\|[%s]+\)[.)]\)+[ \t\n]+\([^\0]*\|$\)' % string.letters - ).match_group, - olp=ts_regex.compile('[ \t]*([0-9]+)[ \t\n]+\([^\0]*\|$\)' - ).match_group, - ): - r='' - for s in structure: - - ts_results = bullet(s[0], (1,)) - if ts_results: - p = ts_results[1] - if s[0][-2:]=='::' and s[1]: ps=self.pre(s[1]) - else: ps=self._str(s[1],level) - r=self.ul(r,p,ps) - continue - ts_results = ol(s[0], (3,)) - if ts_results: - p = ts_results[1] - if s[0][-2:]=='::' and s[1]: ps=self.pre(s[1]) - else: ps=self._str(s[1],level) - r=self.ol(r,p,ps) - continue - ts_results = olp(s[0], (1,)) - if ts_results: - p = ts_results[1] - if s[0][-2:]=='::' and s[1]: ps=self.pre(s[1]) - else: ps=self._str(s[1],level) - r=self.ol(r,p,ps) - continue - ts_results = dl(s[0], (1,2)) - if ts_results: - t,d = ts_results[1] - r=self.dl(r,t,d,self._str(s[1],level)) - continue - if example(s[0]) >= 0 and s[1]: - # Introduce an example, using pre tags: - r=self.normal(r,s[0],self.pre(s[1])) - continue - if s[0][-2:]=='::' and s[1]: - # Introduce an example, using pre tags: - r=self.normal(r,s[0][:-1],self.pre(s[1])) - continue - if table.create(s[0]): - ## table support. - r=self.table(r,table.html(),self._str(s[1],level)) - continue - else: - - if nl(s[0]) < 0 and s[1] and s[0][-1:] != ':': - # Treat as a heading - t=s[0] - r=self.head(r,t,level, - self._str(s[1],level and level+1)) - else: - r=self.normal(r,s[0],self._str(s[1],level)) - return r - - -def html_quote(v, - character_entities=( - (re.compile('&'), '&'), - (re.compile("<"), '<' ), - (re.compile(">"), '>' ), - (re.compile('"'), '"') - )): #" - text=str(v) - for re,name in character_entities: - text=re.sub(name,text) - return text - -def html_with_references(text, level=1): - text = re.sub( - r'[\0\n]\.\. \[([0-9_%s-]+)\]' % string.letters, - r'\n
        [\1]', - text) - - text = re.sub( - r'([\x00- ,])\[(?P[0-9_%s-]+)\]([\x00- ,.:])' % string.letters, - r'\1[\2]\3', - text) - - text = re.sub( - r'([\0- ,])\[([^]]+)\.html\]([\0- ,.:])', - r'\1[\2]\3', - text) - - return HTML(text,level=level) - - -def main(): - import sys, getopt - - opts,args=getopt.getopt(sys.argv[1:],'twl') - - if args: - [infile]=args - s=open(infile,'r').read() - else: - s=sys.stdin.read() - - if opts: - - if filter(lambda o: o[0]=='-w', opts): - print 'Content-Type: text/html\n' - - if filter(lambda o: o[0]=='-l', opts): - import locale - locale.setlocale(locale.LC_ALL,"") - - if s[:2]=='#!': - s=re.sub('^#![^\n]+','',s) - - mo = re.compile('([\0-\n]*\n)').match(s) - if mo is not None: - s = s[len(mo.group(0)) :] - - s=str(html_with_references(s)) - if s[:4]=='

        ': - t=s[4:find(s,'

        ')] - s='''%s - - %s - - ''' % (t,s) - print s - else: - print html_with_references(s) - -if __name__=="__main__": main() diff --git a/wxPython/samples/stxview/StructuredText/DocBookClass.py b/wxPython/samples/stxview/StructuredText/DocBookClass.py deleted file mode 100644 index 5a14f33d78..0000000000 --- a/wxPython/samples/stxview/StructuredText/DocBookClass.py +++ /dev/null @@ -1,332 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -import string -from string import join, split, find, lstrip - -class DocBookClass: - - element_types={ - '#text': '_text', - 'StructuredTextDocument': 'document', - 'StructuredTextParagraph': 'paragraph', - 'StructuredTextExample': 'example', - 'StructuredTextBullet': 'bullet', - 'StructuredTextNumbered': 'numbered', - 'StructuredTextDescription': 'description', - 'StructuredTextDescriptionTitle': 'descriptionTitle', - 'StructuredTextDescriptionBody': 'descriptionBody', - 'StructuredTextSection': 'section', - 'StructuredTextSectionTitle': 'sectionTitle', - 'StructuredTextLiteral': 'literal', - 'StructuredTextEmphasis': 'emphasis', - 'StructuredTextStrong': 'strong', - 'StructuredTextLink': 'link', - 'StructuredTextXref': 'xref', - 'StructuredTextSGML': 'sgml', - } - - def dispatch(self, doc, level, output): - getattr(self, self.element_types[doc.getNodeName()])(doc, level, output) - - def __call__(self, doc, level=1): - r=[] - self.dispatch(doc, level-1, r.append) - return join(r,'') - - def _text(self, doc, level, output): - if doc.getNodeName() == 'StructuredTextLiteral': - output(doc.getNodeValue()) - else: - output(lstrip(doc.getNodeValue())) - - def document(self, doc, level, output): - output('\n') - output('\n') - children=doc.getChildNodes() - if (children and - children[0].getNodeName() == 'StructuredTextSection'): - output('%s' % children[0].getChildNodes()[0].getNodeValue()) - for c in children: - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n') - - def section(self, doc, level, output): - output('\n
        \n') - children=doc.getChildNodes() - for c in children: - getattr(self, self.element_types[c.getNodeName()])(c, level+1, output) - output('\n
        \n') - - def sectionTitle(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - try: - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - except: - print "failed", c.getNodeName(), c - output('\n') - - def description(self, doc, level, output): - p=doc.getPreviousSibling() - if p is None or p.getNodeName() is not doc.getNodeName(): - output('\n') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - n=doc.getNextSibling() - if n is None or n.getNodeName() is not doc.getNodeName(): - output('\n') - - def descriptionTitle(self, doc, level, output): - output('\n') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n') - - def descriptionBody(self, doc, level, output): - output('\n') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n') - output('\n') - - def bullet(self, doc, level, output): - p=doc.getPreviousSibling() - if p is None or p.getNodeName() is not doc.getNodeName(): - output('\n') - output('\n') - - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - n=doc.getNextSibling() - output('\n') - if n is None or n.getNodeName() is not doc.getNodeName(): - output('\n') - - def numbered(self, doc, level, output): - p=doc.getPreviousSibling() - if p is None or p.getNodeName() is not doc.getNodeName(): - output('\n') - output('\n') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - n=doc.getNextSibling() - output('\n') - if n is None or n.getNodeName() is not doc.getNodeName(): - output('\n') - - def example(self, doc, level, output): - i=0 - for c in doc.getChildNodes(): - if i==0: - output('\n' in your body will break this... - ## - output(prestrip(c.getNodeValue())) - output('\n]]>\n') - else: - getattr(self, self.element_types[c.getNodeName()])( - c, level, output) - - def paragraph(self, doc, level, output): - output('\n\n') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])( - c, level, output) - output('\n\n') - - def link(self, doc, level, output): - output('' % doc.href) - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('') - - def emphasis(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output(' ') - - def literal(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - output(c.getNodeValue()) - output('') - - def strong(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('') - - def xref(self, doc, level, output): - output('' % doc.getNodeValue()) - - def sgml(self, doc, level, output): - output(doc.getNodeValue()) - - -def prestrip(v): - v=string.replace(v, '\r\n', '\n') - v=string.replace(v, '\r', '\n') - v=string.replace(v, '\t', ' ') - lines=string.split(v, '\n') - indent=len(lines[0]) - for line in lines: - if not len(line): continue - i=len(line)-len(string.lstrip(line)) - if i < indent: - indent=i - nlines=[] - for line in lines: - nlines.append(line[indent:]) - return string.join(nlines, '\n') - - -class DocBookChapter(DocBookClass): - - def document(self, doc, level, output): - output('\n') - children=doc.getChildNodes() - if (children and - children[0].getNodeName() == 'StructuredTextSection'): - output('%s' % children[0].getChildNodes()[0].getNodeValue()) - for c in children[0].getChildNodes()[1:]: - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n') - -ets = DocBookClass.element_types -ets.update({'StructuredTextImage': 'image'}) - -class DocBookChapterWithFigures(DocBookChapter): - - element_types = ets - - def image(self, doc, level, output): - if hasattr(doc, 'key'): - output('
        %s\n' % (doc.key, doc.getNodeValue()) ) - else: - output('
        %s\n' % doc.getNodeValue()) -## for c in doc.getChildNodes(): -## getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n
        \n' % doc.href) - -class DocBookArticle(DocBookClass): - - def document(self, doc, level, output): - output('\n') - output('
        \n') - children=doc.getChildNodes() - if (children and - children[0].getNodeName() == 'StructuredTextSection'): - output('\n%s\n\n' % - children[0].getChildNodes()[0].getNodeValue()) - for c in children: - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('
        \n') - - -class DocBookBook: - - def __init__(self, title=''): - self.title = title - self.chapters = [] - - def addChapter(self, chapter): - self.chapters.append(chapter) - - def read(self): - out = '\n\n' - out = out + '%s\n' % self.title - for chapter in self.chapters: - out = out + chapter + '\n\n' - - return out - - def __str__(self): - return self.read() - - diff --git a/wxPython/samples/stxview/StructuredText/DocumentClass.py b/wxPython/samples/stxview/StructuredText/DocumentClass.py deleted file mode 100644 index 405f35e25d..0000000000 --- a/wxPython/samples/stxview/StructuredText/DocumentClass.py +++ /dev/null @@ -1,998 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -import re, ST, STDOM -from string import split, join, replace, expandtabs, strip, find, rstrip -from STletters import * - - -StringType=type('') -ListType=type([]) - -def flatten(obj, append): - if obj.getNodeType()==STDOM.TEXT_NODE: - append(obj.getNodeValue()) - else: - for child in obj.getChildNodes(): - flatten(child, append) - - -class StructuredTextExample(ST.StructuredTextParagraph): - """Represents a section of document with literal text, as for examples""" - - def __init__(self, subs, **kw): - t=[] - a=t.append - for s in subs: - flatten(s, a) - apply(ST.StructuredTextParagraph.__init__, - (self, join(t,'\n\n'), ()), - kw) - - def getColorizableTexts(self): return () - def setColorizableTexts(self, src): pass # never color examples - -class StructuredTextBullet(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextNumbered(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextDescriptionTitle(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextDescriptionBody(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextDescription(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - - def __init__(self, title, src, subs, **kw): - apply(ST.StructuredTextParagraph.__init__, (self, src, subs), kw) - self._title=title - - def getColorizableTexts(self): return self._title, self._src - def setColorizableTexts(self, src): self._title, self._src = src - - def getChildren(self): - return (StructuredTextDescriptionTitle(self._title), - StructuredTextDescriptionBody(self._src, self._subs)) - -class StructuredTextSectionTitle(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - -class StructuredTextSection(ST.StructuredTextParagraph): - """Represents a section of a document with a title and a body""" - def __init__(self, src, subs=None, **kw): - apply(ST.StructuredTextParagraph.__init__, - (self, StructuredTextSectionTitle(src), subs), - kw) - - def getColorizableTexts(self): - return self._src.getColorizableTexts() - - def setColorizableTexts(self,src): - self._src.setColorizableTexts(src) - -# a StructuredTextTable holds StructuredTextRows -class StructuredTextTable(ST.StructuredTextParagraph): - """ - rows is a list of lists containing tuples, which - represent the columns/cells in each rows. - EX - rows = [[('row 1:column1',1)],[('row2:column1',1)]] - """ - - def __init__(self, rows, src, subs, **kw): - apply(ST.StructuredTextParagraph.__init__,(self,subs),kw) - self._rows = [] - for row in rows: - if row: - self._rows.append(StructuredTextRow(row,kw)) - - def getRows(self): - return [self._rows] - - def _getRows(self): - return self.getRows() - - def getColumns(self): - result = [] - for row in self._rows: - result.append(row.getColumns()) - return result - - def _getColumns(self): - return self.getColumns() - - def setColumns(self,columns): - for index in range(len(self._rows)): - self._rows[index].setColumns(columns[index]) - - def _setColumns(self,columns): - return self.setColumns(columns) - - def getColorizableTexts(self): - """ - return a tuple where each item is a column/cell's - contents. The tuple, result, will be of this format. - ("r1 col1", "r1=col2", "r2 col1", "r2 col2") - """ - - result = [] - for row in self._rows: - for column in row.getColumns()[0]: - result.append(column.getColorizableTexts()[0]) - return result - - def setColorizableTexts(self,texts): - """ - texts is going to a tuple where each item is the - result of being mapped to the colortext function. - Need to insert the results appropriately into the - individual columns/cells - """ - for row_index in range(len(self._rows)): - for column_index in range(len(self._rows[row_index]._columns)): - self._rows[row_index]._columns[column_index].setColorizableTexts((texts[0],)) - texts = texts[1:] - - def _getColorizableTexts(self): - return self.getColorizableTexts() - - def _setColorizableTexts(self): - return self.setColorizableTexts() - -# StructuredTextRow holds StructuredTextColumns -class StructuredTextRow(ST.StructuredTextParagraph): - - def __init__(self,row,kw): - """ - row is a list of tuples, where each tuple is - the raw text for a cell/column and the span - of that cell/column. - EX - [('this is column one',1), ('this is column two',1)] - """ - - apply(ST.StructuredTextParagraph.__init__,(self,[]),kw) - - self._columns = [] - for column in row: - self._columns.append(StructuredTextColumn(column[0], - column[1], - column[2], - column[3], - column[4], - kw)) - - def getColumns(self): - return [self._columns] - - def _getColumns(self): - return [self._columns] - - def setColumns(self,columns): - self._columns = columns - - def _setColumns(self,columns): - return self.setColumns(columns) - -# this holds the text of a table cell -class StructuredTextColumn(ST.StructuredTextParagraph): - """ - StructuredTextColumn is a cell/column in a table. - A cell can hold multiple paragraphs. The cell - is either classified as a StructuredTextTableHeader - or StructuredTextTableData. - """ - - def __init__(self,text,span,align,valign,typ,kw): - apply(ST.StructuredTextParagraph.__init__,(self,text,[]),kw) - self._span = span - self._align = align - self._valign = valign - self._type = typ - - def getSpan(self): - return self._span - - def _getSpan(self): - return self._span - - def getAlign(self): - return self._align - - def _getAlign(self): - return self.getAlign() - - def getValign(self): - return self._valign - - def _getValign(self): - return self.getValign() - - def getType(self): - return self._type - - def _getType(self): - return self.getType() - -class StructuredTextTableHeader(ST.StructuredTextParagraph): pass - -class StructuredTextTableData(ST.StructuredTextParagraph): pass - -class StructuredTextMarkup(STDOM.Element): - - def __init__(self, v, **kw): - self._value=v - self._attributes=kw.keys() - for k, v in kw.items(): setattr(self, k, v) - - def getChildren(self, type=type, lt=type([])): - v=self._value - if type(v) is not lt: v=[v] - return v - - def getColorizableTexts(self): return self._value, - def setColorizableTexts(self, v): self._value=v[0] - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, `self._value`) - -class StructuredTextLiteral(StructuredTextMarkup): - def getColorizableTexts(self): return () - def setColorizableTexts(self, v): pass - -class StructuredTextEmphasis(StructuredTextMarkup): pass - -class StructuredTextStrong(StructuredTextMarkup): pass - -class StructuredTextInnerLink(StructuredTextMarkup): pass - -class StructuredTextNamedLink(StructuredTextMarkup): pass - -class StructuredTextUnderline(StructuredTextMarkup): pass - -class StructuredTextSGML(StructuredTextMarkup): pass - -class StructuredTextLink(StructuredTextMarkup): pass - -class StructuredTextXref(StructuredTextMarkup): pass - -class DocumentClass: - """ - Class instance calls [ex.=> x()] require a structured text - structure. Doc will then parse each paragraph in the structure - and will find the special structures within each paragraph. - Each special structure will be stored as an instance. Special - structures within another special structure are stored within - the 'top' structure - EX : '-underline this-' => would be turned into an underline - instance. '-underline **this**' would be stored as an underline - instance with a strong instance stored in its string - """ - - paragraph_types = [ - 'doc_bullet', - 'doc_numbered', - 'doc_description', - 'doc_header', - 'doc_table', - ] - - #'doc_inner_link', - #'doc_named_link', - #'doc_underline', - text_types = [ - 'doc_sgml', - 'doc_href', - 'doc_strong', - 'doc_emphasize', - 'doc_literal', - 'doc_sgml', - 'doc_xref', - ] - - def __call__(self, doc): - if type(doc) is type(''): - doc=ST.StructuredText(doc) - doc.setSubparagraphs(self.color_paragraphs( - doc.getSubparagraphs())) - else: - doc=ST.StructuredTextDocument(self.color_paragraphs( - doc.getSubparagraphs())) - return doc - - def parse(self, raw_string, text_type, - type=type, st=type(''), lt=type([])): - - """ - Parse accepts a raw_string, an expr to test the raw_string, - and the raw_string's subparagraphs. - - Parse will continue to search through raw_string until - all instances of expr in raw_string are found. - - If no instances of expr are found, raw_string is returned. - Otherwise a list of substrings and instances is returned - """ - - tmp = [] # the list to be returned if raw_string is split - append=tmp.append - - if type(text_type) is st: text_type=getattr(self, text_type) - - while 1: - t = text_type(raw_string) - if not t: break - #an instance of expr was found - t, start, end = t - - if start: append(raw_string[0:start]) - - tt=type(t) - if tt is st: - # if we get a string back, add it to text to be parsed - raw_string = t+raw_string[end:len(raw_string)] - else: - if tt is lt: - # is we get a list, append it's elements - tmp[len(tmp):]=t - else: - # normal case, an object - append(t) - raw_string = raw_string[end:len(raw_string)] - - if not tmp: return raw_string # nothing found - - if raw_string: append(raw_string) - elif len(tmp)==1: return tmp[0] - - return tmp - - - def color_text(self, str, types=None): - """Search the paragraph for each special structure - """ - if types is None: types=self.text_types - - for text_type in types: - - if type(str) is StringType: - str = self.parse(str, text_type) - elif type(str) is ListType: - r=[]; a=r.append - for s in str: - if type(s) is StringType: - s=self.parse(s, text_type) - if type(s) is ListType: r[len(r):]=s - else: a(s) - else: - s.setColorizableTexts( - map(self.color_text, - s.getColorizableTexts() - )) - a(s) - str=r - else: - r=[]; a=r.append; color=self.color_text - for s in str.getColorizableTexts(): - color(s, (text_type,)) - a(s) - - str.setColorizableTexts(r) - - return str - - def color_paragraphs(self, raw_paragraphs, - type=type, sequence_types=(type([]), type(())), - st=type('')): - result=[] - for paragraph in raw_paragraphs: - if paragraph.getNodeName() != 'StructuredTextParagraph': - result.append(paragraph) - continue - - for pt in self.paragraph_types: - if type(pt) is st: - # grab the corresponding function - pt=getattr(self, pt) - # evaluate the paragraph - r=pt(paragraph) - if r: - if type(r) not in sequence_types: - r=r, - new_paragraphs=r - for paragraph in new_paragraphs: - paragraph.setSubparagraphs(self.color_paragraphs(paragraph.getSubparagraphs())) - break - else: - new_paragraphs=ST.StructuredTextParagraph(paragraph.getColorizableTexts()[0], - self.color_paragraphs(paragraph.getSubparagraphs()), - indent=paragraph.indent), - - # color the inline StructuredText types - # for each StructuredTextParagraph - for paragraph in new_paragraphs: - - if paragraph.getNodeName() is "StructuredTextTable": - cells = paragraph.getColumns() - text = paragraph.getColorizableTexts() - text = map(ST.StructuredText,text) - text = map(self.__call__,text) - for t in range(len(text)): - text[t] = text[t].getSubparagraphs() - paragraph.setColorizableTexts(text) - - paragraph.setColorizableTexts( - map(self.color_text, - paragraph.getColorizableTexts() - )) - result.append(paragraph) - - return result - - def doc_table(self, paragraph, expr = re.compile(r'\s*\|[-]+\|').match): - text = paragraph.getColorizableTexts()[0] - m = expr(text) - - subs = paragraph.getSubparagraphs() - - if not (m): - return None - rows = [] - - spans = [] - ROWS = [] - COLS = [] - indexes = [] - ignore = [] - - TDdivider = re.compile("[\-]+").match - THdivider = re.compile("[\=]+").match - col = re.compile('\|').search - innertable = re.compile('\|([-]+|[=]+)\|').search - - text = strip(text) - rows = split(text,'\n') - foo = "" - - for row in range(len(rows)): - rows[row] = strip(rows[row]) - - # have indexes store if a row is a divider - # or a cell part - for index in range(len(rows)): - tmpstr = rows[index][1:len(rows[index])-1] - if TDdivider(tmpstr): - indexes.append("TDdivider") - elif THdivider(tmpstr): - indexes.append("THdivider") - else: - indexes.append("cell") - - for index in range(len(indexes)): - if indexes[index] is "TDdivider" or indexes[index] is THdivider: - ignore = [] # reset ignore - #continue # skip dividers - - tmp = strip(rows[index]) # clean the row up - tmp = tmp[1:len(tmp)-1] # remove leading + trailing | - offset = 0 - - # find the start and end of inner - # tables. ignore everything between - if innertable(tmp): - tmpstr = strip(tmp) - while innertable(tmpstr): - start,end = innertable(tmpstr).span() - if not (start,end-1) in ignore: - ignore.append(start,end-1) - tmpstr = " " + tmpstr[end:] - - # find the location of column dividers - # NOTE: |'s in inner tables do not count - # as column dividers - if col(tmp): - while col(tmp): - bar = 1 # true if start is not in ignore - start,end = col(tmp).span() - - if not start+offset in spans: - for s,e in ignore: - if start+offset >= s or start+offset <= e: - bar = None - break - if bar: # start is clean - spans.append(start+offset) - if not bar: - foo = foo + tmp[:end] - tmp = tmp[end:] - offset = offset + end - else: - COLS.append((foo + tmp[0:start],start+offset)) - foo = "" - tmp = " " + tmp[end:] - offset = offset + start - if not offset+len(tmp) in spans: - spans.append(offset+len(tmp)) - COLS.append((foo + tmp,offset+len(tmp))) - foo = "" - ROWS.append(COLS) - COLS = [] - - spans.sort() - ROWS = ROWS[1:len(ROWS)] - - # find each column span - cols = [] - tmp = [] - - for row in ROWS: - for c in row: - tmp.append(c[1]) - cols.append(tmp) - tmp = [] - - cur = 1 - tmp = [] - C = [] - for col in cols: - for span in spans: - if not span in col: - cur = cur + 1 - else: - tmp.append(cur) - cur = 1 - C.append(tmp) - tmp = [] - - for index in range(len(C)): - for i in range(len(C[index])): - ROWS[index][i] = (ROWS[index][i][0],C[index][i]) - rows = ROWS - - # label things as either TableData or - # Table header - TD = [] - TH = [] - all = [] - for index in range(len(indexes)): - if indexes[index] is "TDdivider": - TD.append(index) - all.append(index) - if indexes[index] is "THdivider": - TH.append(index) - all.append(index) - TD = TD[1:] - dividers = all[1:] - #print "TD => ", TD - #print "TH => ", TH - #print "all => ", all, "\n" - - for div in dividers: - if div in TD: - index = all.index(div) - for rowindex in range(all[index-1],all[index]): - for i in range(len(rows[rowindex])): - rows[rowindex][i] = (rows[rowindex][i][0], - rows[rowindex][i][1], - "td") - else: - index = all.index(div) - for rowindex in range(all[index-1],all[index]): - for i in range(len(rows[rowindex])): - rows[rowindex][i] = (rows[rowindex][i][0], - rows[rowindex][i][1], - "th") - - # now munge the multi-line cells together - # as paragraphs - ROWS = [] - COLS = [] - for row in rows: - for index in range(len(row)): - if not COLS: - COLS = range(len(row)) - for i in range(len(COLS)): - COLS[i] = ["",1,""] - if TDdivider(row[index][0]) or THdivider(row[index][0]): - ROWS.append(COLS) - COLS = [] - else: - COLS[index][0] = COLS[index][0] + (row[index][0]) + "\n" - COLS[index][1] = row[index][1] - COLS[index][2] = row[index][2] - - # now that each cell has been munged together, - # determine the cell's alignment. - # Default is to center. Also determine the cell's - # vertical alignment, top, middle, bottom. Default is - # to middle - rows = [] - cols = [] - for row in ROWS: - for index in range(len(row)): - topindent = 0 - bottomindent = 0 - leftindent = 0 - rightindent = 0 - left = [] - right = [] - text = row[index][0] - text = split(text,'\n') - text = text[:len(text)-1] - align = "" - valign = "" - for t in text: - t = strip(t) - if not t: - topindent = topindent + 1 - else: - break - text.reverse() - for t in text: - t = strip(t) - if not t: - bottomindent = bottomindent + 1 - else: - break - text.reverse() - tmp = join(text[topindent:len(text)-bottomindent],"\n") - pars = re.compile("\n\s*\n").split(tmp) - for par in pars: - if index > 0: - par = par[1:] - par = split(par, ' ') - for p in par: - if not p: - leftindent = leftindent+1 - else: - break - left.append(leftindent) - leftindent = 0 - par.reverse() - for p in par: - if not p: - rightindent = rightindent + 1 - else: - break - right.append(rightindent) - rightindent = 0 - left.sort() - right.sort() - - if topindent == bottomindent: - valign="middle" - elif topindent < 1: - valign="top" - elif bottomindent < 1: - valign="bottom" - else: - valign="middle" - - if left[0] < 1: - align = "left" - elif right[0] < 1: - align = "right" - elif left[0] > 1 and right[0] > 1: - align="center" - else: - align="left" - - cols.append(row[index][0],row[index][1],align,valign,row[index][2]) - rows.append(cols) - cols = [] - return StructuredTextTable(rows,text,subs,indent=paragraph.indent) - - def doc_bullet(self, paragraph, expr = re.compile(r'\s*[-*o]\s+').match): - top=paragraph.getColorizableTexts()[0] - m=expr(top) - - if not m: - return None - - subs=paragraph.getSubparagraphs() - if top[-2:]=='::': - subs=[StructuredTextExample(subs)] - top=top[:-1] - return StructuredTextBullet(top[m.span()[1]:], subs, - indent=paragraph.indent, - bullet=top[:m.span()[1]] - ) - - def doc_numbered( - self, paragraph, - expr = re.compile(r'(\s*[%s]+\.)|(\s*[0-9]+\.)|(\s*[0-9]+\s+)' % letters).match): - - # This is the old expression. It had a nasty habit - # of grabbing paragraphs that began with a single - # letter word even if there was no following period. - - #expr = re.compile('\s*' - # '(([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.)*' - # '([a-zA-Z]|[0-9]+|[ivxlcdmIVXLCDM]+)\.?' - # '\s+').match): - - top=paragraph.getColorizableTexts()[0] - m=expr(top) - if not m: return None - subs=paragraph.getSubparagraphs() - if top[-2:]=='::': - subs=[StructuredTextExample(subs)] - top=top[:-1] - return StructuredTextNumbered(top[m.span()[1]:], subs, - indent=paragraph.indent, - number=top[:m.span()[1]]) - - def doc_description( - self, paragraph, - delim = re.compile(r'\s+--\s+').search, - nb=re.compile(r'[^\000- ]').search, - ): - - top=paragraph.getColorizableTexts()[0] - d=delim(top) - if not d: return None - start, end = d.span() - title=top[:start] - if find(title, '\n') >= 0: return None - if not nb(title): return None - d=top[start:end] - top=top[end:] - - subs=paragraph.getSubparagraphs() - if top[-2:]=='::': - subs=[StructuredTextExample(subs)] - top=top[:-1] - - return StructuredTextDescription( - title, top, subs, - indent=paragraph.indent, - delim=d) - - def doc_header(self, paragraph, - expr = re.compile(r'[ %s0-9.:/,-_*<>\?\'\"]+' % letters).match - ): - subs=paragraph.getSubparagraphs() - if not subs: return None - top=paragraph.getColorizableTexts()[0] - if not strip(top): return None - if top[-2:]=='::': - subs=StructuredTextExample(subs) - if strip(top)=='::': return subs - return ST.StructuredTextParagraph( - top[:-1], [subs], indent=paragraph.indent) - - if find(top,'\n') >= 0: return None - return StructuredTextSection(top, subs, indent=paragraph.indent) - - def doc_literal( - self, s, - expr=re.compile( - r"(?:\s|^)'" # open - r"([^ \t\n\r\f\v']|[^ \t\n\r\f\v'][^\n']*[^ \t\n\r\f\v'])" # contents - r"'(?:\s|[,.;:!?]|$)" # close - ).search): - - r=expr(s) - if r: - start, end = r.span(1) - return (StructuredTextLiteral(s[start:end]), start-1, end+1) - else: - return None - - def doc_emphasize( - self, s, - expr = re.compile(r'\s*\*([ \n%s0-9]+)\*(?!\*|-)' % lettpunc).search - ): - - r=expr(s) - if r: - start, end = r.span(1) - return (StructuredTextEmphasis(s[start:end]), start-1, end+1) - else: - return None - - def doc_inner_link(self, - s, - expr1 = re.compile(r"\.\.\s*").search, - expr2 = re.compile(r"\[[%s0-9]+\]" % letters ).search): - - # make sure we dont grab a named link - if expr2(s) and expr1(s): - start1,end1 = expr1(s).span() - start2,end2 = expr2(s).span() - if end1 == start2: - # uh-oh, looks like a named link - return None - else: - # the .. is somewhere else, ignore it - return (StructuredTextInnerLink(s[start2+1,end2-1],start2,end2)) - return None - elif expr2(s) and not expr1(s): - start,end = expr2(s).span() - return (StructuredTextInnerLink(s[start+1:end-1]),start,end) - return None - - def doc_named_link(self, - s, - expr=re.compile(r"(\.\.\s)(\[[%s0-9]+\])" % letters).search): - - result = expr(s) - if result: - start,end = result.span(2) - a,b = result.span(1) - str = strip(s[a:b]) + s[start:end] - st,en = result.span() - return (StructuredTextNamedLink(str),st,en) - #return (StructuredTextNamedLink(s[st:en]),st,en) - return None - - def doc_underline(self, - s, - expr=re.compile(r"\s+\_([%s0-9\s]+)\_" % lettpunc).search): - - result = expr(s) - if result: - start,end = result.span(1) - st,e = result.span() - return (StructuredTextUnderline(s[start:end]),st,e) - else: - return None - - def doc_strong(self, - s, - expr = re.compile(r'\s*\*\*([ \n%s0-9]+)\*\*' % lettpunc).search - ): - - r=expr(s) - if r: - start, end = r.span(1) - return (StructuredTextStrong(s[start:end]), start-2, end+2) - else: - return None - - ## Some constants to make the doc_href() regex easier to read. - _DQUOTEDTEXT = r'("[%s0-9\n\-\.\,\;\(\)\/\:\/\*\']+")' % letters ## double quoted text - _URL_AND_PUNC = r'([%s0-9\@\.\,\?\!\/\:\;\-\#\~]+)' % letters - _SPACES = r'(\s*)' - - def doc_href(self, s, - expr1 = re.compile(_DQUOTEDTEXT + "(:)" + _URL_AND_PUNC + _SPACES).search, - expr2 = re.compile(_DQUOTEDTEXT + r'(\,\s+)' + _URL_AND_PUNC + _SPACES).search): - - punctuation = re.compile(r"[\,\.\?\!\;]+").match - r=expr1(s) or expr2(s) - - if r: - # need to grab the href part and the - # beginning part - - start,e = r.span(1) - name = s[start:e] - name = replace(name,'"','',2) - #start = start + 1 - st,end = r.span(3) - if punctuation(s[end-1:end]): - end = end -1 - link = s[st:end] - #end = end - 1 - - # name is the href title, link is the target - # of the href - return (StructuredTextLink(name, href=link), - start, end) - - #return (StructuredTextLink(s[start:end], href=s[start:end]), - # start, end) - else: - return None - - def doc_sgml(self,s,expr=re.compile(r"\<[%s0-9\.\=\'\"\:\/\-\#\+\s\*]+\>" % letters).search): - """ - SGML text is ignored and outputed as-is - """ - r = expr(s) - if r: - start,end = r.span() - text = s[start:end] - return (StructuredTextSGML(text),start,end) - - - def doc_xref(self, s, - expr = re.compile('\[([%s0-9\-.:/;,\n\~]+)\]' % letters).search - ): - r = expr(s) - if r: - start, end = r.span(1) - return (StructuredTextXref(s[start:end]), start-1, end+1) - else: - return None - - - - diff --git a/wxPython/samples/stxview/StructuredText/DocumentWithImages.py b/wxPython/samples/stxview/StructuredText/DocumentWithImages.py deleted file mode 100644 index ac73abf307..0000000000 --- a/wxPython/samples/stxview/StructuredText/DocumentWithImages.py +++ /dev/null @@ -1,134 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -import re, ST, STDOM -from string import split, join, replace, expandtabs, strip, find - -from DocumentClass import * - -class StructuredTextImage(StructuredTextMarkup): - "A simple embedded image" - -class DocumentWithImages(DocumentClass): - """ - - """ - - - text_types = [ - 'doc_img', - ] + DocumentClass.text_types - - - def doc_img( - self, s, - expr1=re.compile('\"([ _a-zA-Z0-9*.:/;,\-\n\~]+)\":img:([a-zA-Z0-9\-.:/;,\n\~]+)').search, - expr2=re.compile('\"([ _a-zA-Z0-9*.:/;,\-\n\~]+)\":img:([a-zA-Z0-9\-.:/;,\n\~]+):([a-zA-Z0-9\-.:/;,\n\~]+)').search - ): - - - r = expr2(s) - if r: - startt, endt = r.span(1) - startk, endk = r.span(2) - starth, endh = r.span(3) - start, end = r.span() - return (StructuredTextImage(s[startt:endt], href=s[starth:endh], key=s[startk:endk]), - start, end) - - - else: - - r=expr1(s) - - if r: - startt, endt = r.span(1) - starth, endh = r.span(2) - start, end = r.span() - return (StructuredTextImage(s[startt:endt], href=s[starth:endh]), - start, end) - - return None - diff --git a/wxPython/samples/stxview/StructuredText/HTMLClass.py b/wxPython/samples/stxview/StructuredText/HTMLClass.py deleted file mode 100644 index 951aec4c97..0000000000 --- a/wxPython/samples/stxview/StructuredText/HTMLClass.py +++ /dev/null @@ -1,307 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -from string import join, split, find -from cgi import escape -import re, sys, ST - -class HTMLClass: - - element_types={ - '#text': '_text', - 'StructuredTextDocument': 'document', - 'StructuredTextParagraph': 'paragraph', - 'StructuredTextExample': 'example', - 'StructuredTextBullet': 'bullet', - 'StructuredTextNumbered': 'numbered', - 'StructuredTextDescription': 'description', - 'StructuredTextDescriptionTitle': 'descriptionTitle', - 'StructuredTextDescriptionBody': 'descriptionBody', - 'StructuredTextSection': 'section', - 'StructuredTextSectionTitle': 'sectionTitle', - 'StructuredTextLiteral': 'literal', - 'StructuredTextEmphasis': 'emphasis', - 'StructuredTextStrong': 'strong', - 'StructuredTextLink': 'link', - 'StructuredTextXref': 'xref', - 'StructuredTextInnerLink':'innerLink', - 'StructuredTextNamedLink':'namedLink', - 'StructuredTextUnderline':'underline', - 'StructuredTextTable':'table', - 'StructuredTextSGML':'sgml', - } - - def dispatch(self, doc, level, output): - getattr(self, self.element_types[doc.getNodeName()])(doc, level, output) - - def __call__(self, doc, level=1): - r=[] - self.dispatch(doc, level-1, r.append) - return join(r,'') - - def _text(self, doc, level, output): - output(doc.getNodeValue()) - - def document(self, doc, level, output): - output('\n') - children=doc.getChildNodes() - if (children and - children[0].getNodeName() == 'StructuredTextSection'): - output('\n%s\n\n' % - children[0].getChildNodes()[0].getNodeValue()) - output('\n') - for c in children: - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n') - output('\n') - - def section(self, doc, level, output): - children=doc.getChildNodes() - for c in children: - getattr(self, self.element_types[c.getNodeName()])(c, level+1, output) - - def sectionTitle(self, doc, level, output): - output('' % (level)) - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n' % (level)) - - def description(self, doc, level, output): - p=doc.getPreviousSibling() - if p is None or p.getNodeName() is not doc.getNodeName(): - output('
        \n') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - n=doc.getNextSibling() - if n is None or n.getNodeName() is not doc.getNodeName(): - output('
        \n') - - def descriptionTitle(self, doc, level, output): - output('
        ') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('
        \n') - - def descriptionBody(self, doc, level, output): - output('
        ') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('
        \n') - - def bullet(self, doc, level, output): - p=doc.getPreviousSibling() - if p is None or p.getNodeName() is not doc.getNodeName(): - output('\n
          \n') - output('
        • ') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - n=doc.getNextSibling() - output('
        • \n') - if n is None or n.getNodeName() is not doc.getNodeName(): - output('\n
        \n') - - def numbered(self, doc, level, output): - p=doc.getPreviousSibling() - if p is None or p.getNodeName() is not doc.getNodeName(): - output('\n
          \n') - output('
        1. ') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - n=doc.getNextSibling() - output('
        2. \n') - if n is None or n.getNodeName() is not doc.getNodeName(): - output('\n
        \n') - - def example(self, doc, level, output): - i=0 - for c in doc.getChildNodes(): - if i==0: - output('\n
        \n')
        -                output(escape(c.getNodeValue()))
        -                output('\n
        \n') - else: - getattr(self, self.element_types[c.getNodeName()])( - c, level, output) - - def paragraph(self, doc, level, output): - i=0 - output('

        ') - for c in doc.getChildNodes(): - if c.getNodeName() in ['StructuredTextParagraph']: - getattr(self, self.element_types[c.getNodeName()])( - c, level, output) - else: - getattr(self, self.element_types[c.getNodeName()])( - c, level, output) - output('

        \n') - - def link(self, doc, level, output): - output('' % doc.href) - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('') - - def emphasis(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('') - - def literal(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - output(escape(c.getNodeValue())) - output('') - - def strong(self, doc, level, output): - output('') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('') - - def underline(self, doc, level, output): - output("") - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output("") - - def innerLink(self, doc, level, output): - output('[') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output(']') - - def namedLink(self, doc, level, output): - output('[') - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output(']') - - def sgml(self,doc,level,output): - for c in doc.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - - def xref(self, doc, level, output): - val = doc.getNodeValue() - output('[%s]' % (val, val) ) - - def table(self,doc,level,output): - """ - A StructuredTextTable holds StructuredTextRow(s) which - holds StructuredTextColumn(s). A StructuredTextColumn - is a type of StructuredTextParagraph and thus holds - the actual data. - """ - output("\n") - for row in doc.getRows()[0]: - output("\n") - for column in row.getColumns()[0]: - if hasattr(column,"getAlign"): - str = "<%s colspan=%s align=%s valign=%s>" % (column.getType(), - column.getSpan(), - column.getAlign(), - column.getValign()) - else: - str = "\n") - output("\n") - output("
        " % column.getSpan() - output(str) - for c in column.getChildNodes(): - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - if hasattr(column,"getType"): - output("\n") - else: - output("
        \n") - - - - - diff --git a/wxPython/samples/stxview/StructuredText/HTMLWithImages.py b/wxPython/samples/stxview/StructuredText/HTMLWithImages.py deleted file mode 100644 index 2b25a8891c..0000000000 --- a/wxPython/samples/stxview/StructuredText/HTMLWithImages.py +++ /dev/null @@ -1,128 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -from string import join, split, find -import re, sys, ST -import time - -from HTMLClass import HTMLClass - -ets = HTMLClass.element_types -ets.update({'StructuredTextImage': 'image'}) - -class HTMLWithImages(HTMLClass): - - element_types = ets - - def document(self, doc, level, output): - output('\n') - children=doc.getChildNodes() - if (children and - children[0].getNodeName() == 'StructuredTextSection'): - output('\n%s\n\n' % - children[0].getChildNodes()[0].getNodeValue()) - output('\n') - for c in children: - getattr(self, self.element_types[c.getNodeName()])(c, level, output) - output('\n') - output('\n') - - def image(self, doc, level, output): - if hasattr(doc, 'key'): - output('\n' % doc.key) - output('%s\n' % (doc.href, doc.getNodeValue())) - if doc.getNodeValue() and hasattr(doc, 'key'): - output('

        Figure %s %s

        \n' % (doc.key, doc.getNodeValue())) - - def xref(self, doc, level, output): - val = doc.getNodeValue() - output('Figure %s' % (val, val) ) - - - - - - - diff --git a/wxPython/samples/stxview/StructuredText/ST.py b/wxPython/samples/stxview/StructuredText/ST.py deleted file mode 100644 index 3917adcaa8..0000000000 --- a/wxPython/samples/stxview/StructuredText/ST.py +++ /dev/null @@ -1,283 +0,0 @@ -import re, STDOM -from string import split, join, replace, expandtabs, strip, find - -##################################################################### -# Updated functions # -##################################################################### - -def indention(str,front = re.compile("^\s+").match): - """ - Convert all tabs to the appropriate number of spaces. - Find the number of leading spaces. If none, return 0 - """ - - if front(str): - start,end = front(str).span() - return end-start-1 - else: - return 0 # no leading spaces - -def insert(struct, top, level): - """ - find what will be the parant paragraph of - a sentence and return that paragraph's - sub-paragraphs. The new paragraph will be - appended to those sub-paragraphs - """ - #print "struct", struct, top-1 - if not top-1 in range(len(struct)): - if struct: - return struct[len(struct)-1].getSubparagraphs() - return struct - run = struct[top-1] - i = 0 - while i+1 < level: - run = run.getSubparagraphs()[len(run.getSubparagraphs())-1] - i = i + 1 - #print "parent for level ", level, " was => ", run.getColorizableTexts() - return run.getSubparagraphs() - -def display(struct): - """ - runs through the structure and prints out - the paragraphs. If the insertion works - correctly, display's results should mimic - the orignal paragraphs. - """ - - if struct.getColorizableTexts(): - print join(struct.getColorizableTexts()),"\n" - if struct.getSubparagraphs(): - for x in struct.getSubparagraphs(): - display(x) - -def display2(struct): - """ - runs through the structure and prints out - the paragraphs. If the insertion works - correctly, display's results should mimic - the orignal paragraphs. - """ - - if struct.getNodeValue(): - print struct.getNodeValue(),"\n" - if struct.getSubparagraphs(): - for x in struct.getSubparagraphs(): - display(x) - -def findlevel(levels,indent): - """ - remove all level information of levels - with a greater level of indentation. - Then return which level should insert this - paragraph - """ - - keys = levels.keys() - for key in keys: - if levels[key] > indent: - del(levels[key]) - keys = levels.keys() - if not(keys): - return 0 - else: - for key in keys: - if levels[key] == indent: - return key - highest = 0 - for key in keys: - if key > highest: - highest = key - return highest-1 - -##################################################################### - -# Golly, the capitalization of this function always makes me think it's a class -def StructuredText(paragraphs, paragraph_delimiter=re.compile('\n\s*\n')): - """ - StructuredText accepts paragraphs, which is a list of - lines to be parsed. StructuredText creates a structure - which mimics the structure of the paragraphs. - Structure => [paragraph,[sub-paragraphs]] - """ - - currentlevel = 0 - currentindent = 0 - levels = {0:0} - level = 0 # which header are we under - struct = [] # the structure to be returned - run = struct - - paragraphs = filter( - strip, - paragraph_delimiter.split(expandtabs('\n\n'+paragraphs+'\n\n')) - ) - - if not paragraphs: return [] - - ind = [] # structure based on indention levels - for paragraph in paragraphs: - ind.append([indention(paragraph), paragraph]) - - currentindent = indention(paragraphs[0]) - levels[0] = currentindent - - ############################################################# - # updated # - ############################################################# - - for indent,paragraph in ind : - if indent == 0: - level = level + 1 - currentlevel = 0 - currentindent = 0 - levels = {0:0} - struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) - elif indent > currentindent: - currentlevel = currentlevel + 1 - currentindent = indent - levels[currentlevel] = indent - run = insert(struct,level,currentlevel) - run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) - elif indent < currentindent: - result = findlevel(levels,indent) - if result > 0: - currentlevel = result - currentindent = indent - if not level: - struct.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) - else: - run = insert(struct,level,currentlevel) - run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) - else: - if insert(struct,level,currentlevel): - run = insert(struct,level,currentlevel) - else: - run = struct - currentindet = indent - run.append(StructuredTextParagraph(paragraph, indent=indent, level=currentlevel)) - - return StructuredTextDocument(struct) - -Basic = StructuredText - -class StructuredTextParagraph(STDOM.Element): - - indent=0 - - def __init__(self, src, subs=None, **kw): - if subs is None: subs=[] - self._src=src - self._subs=list(subs) - - self._attributes=kw.keys() - for k, v in kw.items(): setattr(self, k, v) - - def getChildren(self, type=type, lt=type([])): - src=self._src - if type(src) is not lt: src=[src] - return src+self._subs - - def getAttribute(self, name): - return getattr(self, name, None) - - def getAttributeNode(self, name): - if hasattr(self, name): - return STDOM.Attr(name, getattr(self, name)) - - def getAttributes(self): - d={} - for a in self._attributes: - d[a]=getattr(self, a, '') - return STDOM.NamedNodeMap(d) - - def getSubparagraphs(self): - return self._subs - - def setSubparagraphs(self, subs): - self._subs=subs - - def getColorizableTexts(self): - return (self._src,) - - def setColorizableTexts(self, src): - self._src=src[0] - - def __repr__(self): - r=[]; a=r.append - a((' '*(self.indent or 0))+ - ('%s(' % self.__class__.__name__) - +str(self._src)+', [' - ) - for p in self._subs: a(`p`) - a((' '*(self.indent or 0))+'])') - return join(r,'\n') - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_Children(self, type=type, lt=type([])): - return self.getChildren(type,lt) - - def _get_Attribute(self, name): - return self.getAttribute(name) - - def _get_AttributeNode(self, name): - return self.getAttributeNode(name) - - def _get_Attributes(self): - return self.getAttributes() - - def _get_Subparagraphs(self): - return self.getSubparagraphs() - - def _set_Subparagraphs(self, subs): - return self.setSubparagraphs(subs) - - def _get_ColorizableTexts(self): - return self.getColorizableTexts() - - def _set_ColorizableTexts(self, src): - return self.setColorizableTexts(src) - -class StructuredTextDocument(StructuredTextParagraph): - """ - A StructuredTextDocument holds StructuredTextParagraphs - as its subparagraphs. - """ - _attributes=() - - def __init__(self, subs=None, **kw): - apply(StructuredTextParagraph.__init__, - (self, '', subs), - kw) - - def getChildren(self): - return self._subs - - def getColorizableTexts(self): - return () - - def setColorizableTexts(self, src): - pass - - def __repr__(self): - r=[]; a=r.append - a('%s([' % self.__class__.__name__) - for p in self._subs: a(`p`+',') - a('])') - return join(r,'\n') - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_Children(self): - return self.getChildren() - - def _get_ColorizableTexts(self): - return self.getColorizableTexts() - - def _set_ColorizableTexts(self, src): - return self.setColorizableTexts(src) diff --git a/wxPython/samples/stxview/StructuredText/STDOM.py b/wxPython/samples/stxview/StructuredText/STDOM.py deleted file mode 100644 index c38f2fa6f4..0000000000 --- a/wxPython/samples/stxview/StructuredText/STDOM.py +++ /dev/null @@ -1,736 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## -""" -DOM implementation in StructuredText : Read-Only methods - -All standard Zope objects support DOM to a limited extent. -""" -import string - - -# Node type codes -# --------------- - -ELEMENT_NODE = 1 -ATTRIBUTE_NODE = 2 -TEXT_NODE = 3 -CDATA_SECTION_NODE = 4 -ENTITY_REFERENCE_NODE = 5 -ENTITY_NODE = 6 -PROCESSING_INSTRUCTION_NODE = 7 -COMMENT_NODE = 8 -DOCUMENT_NODE = 9 -DOCUMENT_TYPE_NODE = 10 -DOCUMENT_FRAGMENT_NODE = 11 -NOTATION_NODE = 12 - -# Exception codes -# --------------- - -INDEX_SIZE_ERR = 1 -DOMSTRING_SIZE_ERR = 2 -HIERARCHY_REQUEST_ERR = 3 -WRONG_DOCUMENT_ERR = 4 -INVALID_CHARACTER_ERR = 5 -NO_DATA_ALLOWED_ERR = 6 -NO_MODIFICATION_ALLOWED_ERR = 7 -NOT_FOUND_ERR = 8 -NOT_SUPPORTED_ERR = 9 -INUSE_ATTRIBUTE_ERR = 10 - -# Exceptions -# ---------- - -class DOMException(Exception): - pass -class IndexSizeException(DOMException): - code = INDEX_SIZE_ERR -class DOMStringSizeException(DOMException): - code = DOMSTRING_SIZE_ERR -class HierarchyRequestException(DOMException): - code = HIERARCHY_REQUEST_ERR -class WrongDocumentException(DOMException): - code = WRONG_DOCUMENT_ERR -class InvalidCharacterException(DOMException): - code = INVALID_CHARACTER_ERR -class NoDataAllowedException(DOMException): - code = NO_DATA_ALLOWED_ERR -class NoModificationAllowedException(DOMException): - code = NO_MODIFICATION_ALLOWED_ERR -class NotFoundException(DOMException): - code = NOT_FOUND_ERR -class NotSupportedException(DOMException): - code = NOT_SUPPORTED_ERR -class InUseAttributeException(DOMException): - code = INUSE_ATTRIBUTE_ERR - -# Node classes -# ------------ - -class ParentNode: - """ - A node that can have children, or, more precisely, that implements - the child access methods of the DOM. - """ - - def getChildNodes(self, type=type, st=type('')): - """ - Returns a NodeList that contains all children of this node. - If there are no children, this is a empty NodeList - """ - - r=[] - for n in self.getChildren(): - if type(n) is st: n=TextNode(n) - r.append(n.__of__(self)) - - return NodeList(r) - - def getFirstChild(self, type=type, st=type('')): - """ - The first child of this node. If there is no such node - this returns None - """ - children = self.getChildren() - - if not children: - return None - - n=children[0] - - if type(n) is st: - n=TextNode(n) - - return n.__of__(self) - - def getLastChild(self, type=type, st=type('')): - """ - The last child of this node. If there is no such node - this returns None. - """ - children = self.getChildren() - if not children: return None - n=chidren[-1] - if type(n) is st: n=TextNode(n) - return n.__of__(self) - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_ChildNodes(self, type=type, st=type('')): - return self.getChildNodes(type,st) - - def _get_FirstChild(self, type=type, st=type('')): - return self.getFirstChild(type,st) - - def _get_LastChild(self, type=type, st=type('')): - return self.getLastChild(type,st) - -class NodeWrapper(ParentNode): - """ - This is an acquisition-like wrapper that provides parent access for - DOM sans circular references! - """ - - def __init__(self, aq_self, aq_parent): - self.aq_self=aq_self - self.aq_parent=aq_parent - - def __getattr__(self, name): - return getattr(self.aq_self, name) - - def getParentNode(self): - """ - The parent of this node. All nodes except Document - DocumentFragment and Attr may have a parent - """ - return self.aq_parent - - def _getDOMIndex(self, children, getattr=getattr): - i=0 - self=self.aq_self - for child in children: - if getattr(child, 'aq_self', child) is self: - self._DOMIndex=i - return i - i=i+1 - return None - - def getPreviousSibling(self, - type=type, - st=type(''), - getattr=getattr, - None=None): - - """ - The node immediately preceding this node. If - there is no such node, this returns None. - """ - - children = self.aq_parent.getChildren() - if not children: - return None - - index=getattr(self, '_DOMIndex', None) - if index is None: - index=self._getDOMIndex(children) - if index is None: return None - - index=index-1 - if index < 0: return None - try: n=children[index] - except IndexError: return None - else: - if type(n) is st: - n=TextNode(n) - n._DOMIndex=index - return n.__of__(self) - - - def getNextSibling(self, type=type, st=type('')): - """ - The node immediately preceding this node. If - there is no such node, this returns None. - """ - children = self.aq_parent.getChildren() - if not children: - return None - - index=getattr(self, '_DOMIndex', None) - if index is None: - index=self._getDOMIndex(children) - if index is None: - return None - - index=index+1 - try: n=children[index] - except IndexError: - return None - else: - if type(n) is st: - n=TextNode(n) - n._DOMIndex=index - return n.__of__(self) - - def getOwnerDocument(self): - """ - The Document object associated with this node, if any. - """ - return self.aq_parent.getOwnerDocument() - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_ParentNode(self): - return self.getParentNode() - - def _get_DOMIndex(self, children, getattr=getattr): - return self._getDOMIndex(children,getattr) - - def _get_PreviousSibling(self, - type=type, - st=type(''), - getattr=getattr, - None=None): - - return self.getPreviousSibling(type,st,getattr,None) - - def _get_NextSibling(self, type=type, st=type('')): - return self.getNextSibling(type,st) - - def _get_OwnerDocument(self): - return self.getOwnerDocument() - -class Node(ParentNode): - """ - Node Interface - """ - - # Get a DOM wrapper with a parent link - def __of__(self, parent): - return NodeWrapper(self, parent) - - # DOM attributes - # -------------- - - def getNodeName(self): - """ - The name of this node, depending on its type - """ - - def getNodeValue(self): - """ - The value of this node, depending on its type - """ - return None - - def getParentNode(self): - """ - The parent of this node. All nodes except Document - DocumentFragment and Attr may have a parent - """ - - def getChildren(self): - """ - Get a Python sequence of children - """ - return () - - def getPreviousSibling(self, - type=type, - st=type(''), - getattr=getattr, - None=None): - """ - The node immediately preceding this node. If - there is no such node, this returns None. - """ - - def getNextSibling(self, type=type, st=type('')): - """ - The node immediately preceding this node. If - there is no such node, this returns None. - """ - - def getAttributes(self): - """ - Returns a NamedNodeMap containing the attributes - of this node (if it is an element) or None otherwise. - """ - return None - - def getOwnerDocument(self): - """ - The Document object associated with this node, if any. - """ - - # DOM Methods - # ----------- - - def hasChildNodes(self): - """ - Returns true if the node has any children, false - if it doesn't. - """ - return len(self.getChildren()) - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_NodeName(self): - return self.getNodeName() - - def _get_NodeValue(self): - return self.getNodeValue() - - def _get_ParentNode(self): - return self.getParentNode() - - def _get_Children(self): - return self.getChildren() - - def _get_PreviousSibling(self, - type=type, - st=type(''), - getattr=getattr, - None=None): - - return self.getPreviousSibling(type,st,getattr,None) - - def _get_NextSibling(self, type=type, st=type('')): - return self.getNextSibling() - - def _get_Attributes(self): - return self.getAttributes() - - def _get_OwnerDocument(self): - return self.getOwnerDocument() - - def _has_ChildNodes(self): - return self.hasChildNodes() - - -class TextNode(Node): - - def __init__(self, str): self._value=str - - def getNodeType(self): - return TEXT_NODE - - def getNodeName(self): - return '#text' - - def getNodeValue(self): - return self._value - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_NodeType(self): - return self.getNodeType() - - def _get_NodeName(self): - return self.getNodeName() - - def _get_NodeValue(self): - return self.getNodeValue() - -class Element(Node): - """ - Element interface - """ - - # Element Attributes - # ------------------ - - def getTagName(self): - """The name of the element""" - return self.__class__.__name__ - - def getNodeName(self): - """The name of this node, depending on its type""" - return self.__class__.__name__ - - def getNodeType(self): - """A code representing the type of the node.""" - return ELEMENT_NODE - - def getNodeValue(self, type=type, st=type('')): - r=[] - for c in self.getChildren(): - if type(c) is not st: - c=c.getNodeValue() - r.append(c) - return string.join(r,'') - - def getParentNode(self): - """ - The parent of this node. All nodes except Document - DocumentFragment and Attr may have a parent - """ - - # Element Methods - # --------------- - - _attributes=() - - def getAttribute(self, name): return getattr(self, name, None) - def getAttributeNode(self, name): - if hasattr(self, name): - return Attr(name, getattr(self, name)) - - def getAttributes(self): - d={} - for a in self._attributes: - d[a]=getattr(self, a, '') - return NamedNodeMap(d) - - def getAttribute(self, name): - """Retrieves an attribute value by name.""" - return None - - def getAttributeNode(self, name): - """ Retrieves an Attr node by name or None if - there is no such attribute. """ - return None - - def getElementsByTagName(self, tagname): - """ - Returns a NodeList of all the Elements with a given tag - name in the order in which they would be encountered in a - preorder traversal of the Document tree. Parameter: tagname - The name of the tag to match (* = all tags). Return Value: A new - NodeList object containing all the matched Elements. - """ - nodeList = [] - for child in self.getChildren(): - if (child.getNodeType()==ELEMENT_NODE and \ - child.getTagName()==tagname or tagname== '*'): - - nodeList.append(child) - - if hasattr(child, 'getElementsByTagName'): - n1 = child.getElementsByTagName(tagname) - nodeList = nodeList + n1._data - return NodeList(nodeList) - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_TagName(self): - return self.getTagName() - - def _get_NodeName(self): - return self.getNodeName() - - def _get_NodeType(self): - return self.getNodeType() - - def _get_NodeValue(self, type=type, st=type('')): - return self.getNodeValue(type,st) - - def _get_ParentNode(self): - return self.getParentNode() - - def _get_Attribute(self, name): - return self.getAttribute(name) - - def _get_AttributeNode(self, name): - return self.getAttributeNode(name) - - def _get_Attributes(self): - return self.getAttributes() - - def _get_Attribute(self, name): - return self.getAttribute(name) - - def _get_AttributeNode(self, name): - return self.getAttributeNode(name) - - def _get_ElementsByTagName(self, tagname): - return self.getElementsByTagName(tagname) - - -class NodeList: - """ - NodeList interface - Provides the abstraction of an ordered - collection of nodes. - - Python extensions: can use sequence-style 'len', 'getitem', and - 'for..in' constructs. - """ - - def __init__(self,list=None): - self._data = list or [] - - def __getitem__(self, index, type=type, st=type('')): - return self._data[index] - - def __getslice__(self, i, j): - return self._data[i:j] - - def item(self, index): - """ - Returns the index-th item in the collection - """ - try: return self._data[index] - except IndexError: return None - - def getLength(self): - """ - The length of the NodeList - """ - return len(self._data) - - __len__=getLength - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_Length(self): - return self.getLength() - -class NamedNodeMap: - """ - NamedNodeMap interface - Is used to represent collections - of nodes that can be accessed by name. NamedNodeMaps are not - maintained in any particular order. - - Python extensions: can use sequence-style 'len', 'getitem', and - 'for..in' constructs, and mapping-style 'getitem'. - """ - - def __init__(self, data=None): - if data is None: - data = {} - self._data = data - - def item(self, index): - """ - Returns the index-th item in the map - """ - try: return self._data.values()[index] - except IndexError: return None - - def __getitem__(self, key): - if type(key)==type(1): - return self._data.values()[key] - else: - return self._data[key] - - def getLength(self): - """ - The length of the NodeList - """ - return len(self._data) - - __len__ = getLength - - def getNamedItem(self, name): - """ - Retrieves a node specified by name. Parameters: - name Name of a node to retrieve. Return Value A Node (of any - type) with the specified name, or None if the specified name - did not identify any node in the map. - """ - if self._data.has_key(name): - return self._data[name] - return None - - """ - create aliases for all above functions in the pythony way. - """ - def _get_Length(self): - return self.getLength() - - def _get_NamedItem(self, name): - return self.getNamedItem(name) - -class Attr(Node): - """ - Attr interface - The Attr interface represents an attriubte in an - Element object. Attr objects inherit the Node Interface - """ - - def __init__(self, name, value, specified=1): - self.name = name - self.value = value - self.specified = specified - - def getNodeName(self): - """ - The name of this node, depending on its type - """ - return self.name - - def getName(self): - """ - Returns the name of this attribute. - """ - return self.name - - def getNodeValue(self): - """ - The value of this node, depending on its type - """ - return self.value - - def getNodeType(self): - """ - A code representing the type of the node. - """ - return ATTRIBUTE_NODE - - def getSpecified(self): - """ - If this attribute was explicitly given a value in the - original document, this is true; otherwise, it is false. - """ - return self.specified - - """ - create aliases for all above functions in the pythony way. - """ - - def _get_NodeName(self): - return self.getNodeName() - - def _get_Name(self): - return self.getName() - - def _get_NodeValue(self): - return self.getNodeValue() - - def _get_NodeType(self): - return self.getNodeType() - - def _get_Specified(self): - return self.getSpecified() diff --git a/wxPython/samples/stxview/StructuredText/STNG.txt b/wxPython/samples/stxview/StructuredText/STNG.txt deleted file mode 100644 index 20c7e6fc82..0000000000 --- a/wxPython/samples/stxview/StructuredText/STNG.txt +++ /dev/null @@ -1,116 +0,0 @@ -Using Structured Text - - The goal of StructuredText is to make it possible to express - structured text using a relatively simple plain text format. Simple - structures, like bullets or headings are indicated through - conventions that are natural, for some definition of - "natural". Hierarchical structures are indicated through - indentation. The use of indentation to express hierarchical - structure is inspired by the Python programming language. - - Use of StructuredText consists of one to three logical steps. In the - first step, a text string is converted to a network of objects using - the 'StructuredText.Basic' facility, as in the following - example:: - - raw=open("mydocument.txt").read() - import StructuredText - st=StructuredText.Basic(raw) - - The output of 'StructuredText.Basic' is simply a - StructuredTextDocument object containing StructuredTextParagraph - objects arranged in a hierarchy. Paragraphs are delimited by strings - of two or more whitespace characters beginning and ending with - newline characters. Hierarchy is indicated by indentation. The - indentation of a paragraph is the minimum number of leading spaces - in a line containing non-white-space characters after converting tab - characters to spaces (assuming a tab stop every eight characters). - - StructuredTextNode objects support the read-only subset of the - Document Object Model (DOM) API. It should be possible to process - 'StructuredTextNode' hierarchies using XML tools such as XSLT. - - The second step in using StructuredText is to apply additional - structuring rules based on text content. A variety of differentText - rules can be used. Typically, these are used to implement a - structured text language for producing documents, but any sort of - structured text language could be implemented in the second - step. For example, it is possible to use StructuredText to implement - structured text formats for representing structured data. The second - step, which could consist of multiple processing steps, is - performed by processing, or "coloring", the hierarchy of generic - StructuredTextParagraph objects into a network of more specialized - objects. Typically, the objects produced should also implement the DOM - API to allow processing with XML tools. - - A document processor is provided to convert a StructuredTextDocument - object containing only StructuredStructuredTextParagraph objects - into a StructuredTextDocument object containing a richer collection - of objects such as bullets, headings, emphasis, and so on using - hints in the text. Hints are selected based on conventions of the - sort typically seen in electronic mail or news-group postings. It - should be noted, however, that these conventions are somewhat - culturally dependent, fortunately, the document processor is easily - customized to implement alternative rules. Here's an example of - using the DOC processor to convert the output of the previous example:: - - doc=StructuredText.Document(st) - - The final step is to process the colored networks produced from the - second step to produce additional outputs. The final step could be - performed by Python programs, or by XML tools. A Python outputter is - provided for the document processor output that produces Hypertext Markup - Language (HTML) text:: - - html=StructuredText.HTML(doc) - -Customizing the document processor - - The document processor is driven by two tables. The first table, - named 'paragraph_types', is a sequence of callable objects or method - names for coloring paragraphs. If a table entry is a string, then it - is the name of a method of the document processor to be used. For - each input paragraph, the objects in the table are called until one - returns a value (not 'None'). The value returned replaces the - original input paragraph in the output. If none of the objects in - the paragraph types table return a value, then a copy of the - original paragraph is used. The new object returned by calling a - paragraph type should implement the ReadOnlyDOM, - StructuredTextColorizable, and StructuredTextSubparagraphContainer - interfaces. See the 'Document.py' source file for examples. - - A paragraph type may return a list or tuple of replacement - paragraphs, this allowing a paragraph to be split into multiple - paragraphs. - - The second table, 'text_types', is a sequence of callable objects or - method names for coloring text. The callable objects in this table - are used in sequence to transform the input text into new text or - objects. The callable objects are passed a string and return - nothing ('None') or a three-element tuple consisting of: - - - a replacement object, - - - a starting position, and - - - an ending position - - The text from the starting position is (logically) replaced with the - replacement object. The replacement object is typically an object - that implements that implements the ReadOnlyDOM, and - StructuredTextColorizable interfaces. The replacement object can - also be a string or a list of strings or objects. Replacement is - done from beginning to end and text after the replacement ending - position will be passed to the character type objects for processing. - -Example: adding wiki links - - We want to add support for Wiki links. A Wiki link is a string of - text containing mixed-case letters, such that at least two of the - letters are upper case and such that the first letter is upper case. - - - - - - diff --git a/wxPython/samples/stxview/StructuredText/STletters.py b/wxPython/samples/stxview/StructuredText/STletters.py deleted file mode 100644 index 5168b01e47..0000000000 --- a/wxPython/samples/stxview/StructuredText/STletters.py +++ /dev/null @@ -1,15 +0,0 @@ -import string - -try: - del string - import locale - locale.setlocale(locale.LC_ALL,"") -except: - pass - -import string - -letters = string.letters -punctuations = string.punctuation - -lettpunc = letters + punctuations diff --git a/wxPython/samples/stxview/StructuredText/StructuredText.py b/wxPython/samples/stxview/StructuredText/StructuredText.py deleted file mode 100644 index 2408f2331c..0000000000 --- a/wxPython/samples/stxview/StructuredText/StructuredText.py +++ /dev/null @@ -1,148 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -""" Alias module for StructuredTextClassic compatibility which makes -use of StructuredTextNG """ - - -import HTMLClass, DocumentClass, ClassicDocumentClass -from ST import Basic - -import re, string,sys -from STletters import letters - -Document = ClassicDocumentClass.DocumentClass() -HTMLNG = HTMLClass.HTMLClass() - -def HTML(aStructuredString, level=0): - st = Basic(aStructuredString) - doc = Document(st) - return HTMLNG(doc) - -def StructuredText(aStructuredString, level=0): - return HTML(aStructuredString,level) - -def html_with_references(text, level=1): - text = re.sub( - r'[\000\n]\.\. \[([0-9_%s-]+)\]' % letters, - r'\n [\1]', - text) - - text = re.sub( - r'([\000- ,])\[(?P[0-9_%s-]+)\]([\000- ,.:])' % letters, - r'\1[\2]\3', - text) - - text = re.sub( - r'([\000- ,])\[([^]]+)\.html\]([\000- ,.:])', - r'\1[\2]\3', - text) - - return HTML(text,level=level) - -def html_quote(v, - character_entities=( - (re.compile('&'), '&'), - (re.compile("<"), '<' ), - (re.compile(">"), '>' ), - (re.compile('"'), '"') - )): #" - text=str(v) - for re,name in character_entities: - text=re.sub(name,text) - return text - - -if __name__=='__main__': - import getopt - - opts,args = getopt.getopt(sys.argv[1:],'',[]) - - for k,v in opts: - pass - - - for f in args: - print HTML(open(f).read()) diff --git a/wxPython/samples/stxview/StructuredText/Zwiki.py b/wxPython/samples/stxview/StructuredText/Zwiki.py deleted file mode 100644 index c08ea51e57..0000000000 --- a/wxPython/samples/stxview/StructuredText/Zwiki.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/python -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -from Html import HTML -from string import split -from ST import DOC -import re - -""" -This is the new structured text type. -""" - -class Zwiki_Title: - def __init__(self,str=''): - self.expr1 = re.compile('([A-Z]+[A-Z]+[a-zA-Z]*)').search - self.expr2 = re.compile('([A-Z]+[a-z]+[A-Z]+[a-zA-Z]*)').search - self.str = [str] - self.typ = "Zwiki_Title" - - def type(self): - return '%s' % self.typ - - def string(self): - return self.str - - def __getitem__(self,index): - return self.str[index] - - def __call__(self,raw_string,subs): - - """ - The raw_string is checked to see if it matches the rules - for this structured text expression. If the raw_string does, - it is parsed for the sub-string which matches and a doc_inner_link - instance is returned whose string is the matching substring. - If raw_string does not match, nothing is returned. - """ - - if self.expr1(raw_string): - start,end = self.expr1(raw_string).span() - result = Zwiki_Title(raw_string[start:end]) - result.start,result.end = self.expr1(raw_string).span() - return result - elif self.expr2(raw_string): - start,end = self.expr2(raw_string).span() - result = Zwiki_Title(raw_string[start:end]) - result.start,result.end = self.expr2(raw_string).span() - return result - else: - return None - - def span(self): - return self.start,self.end - -class Zwiki_doc(DOC): - - def __init__(self): - DOC.__init__(self) - """ - Add the new type to self.types - """ - self.types.append(Zwiki_Title()) - -class Zwiki_parser(HTML): - def __init__(self): - HTML.__init__(self) - self.types["Zwiki_Title"] = self.zwiki_title - - def zwiki_title(self,object): - result = "" - for x in object.string(): - result = result + x - result = "%s" % (result,result) - #result = "" % result - self.string = self.string + result diff --git a/wxPython/samples/stxview/StructuredText/__init__.py b/wxPython/samples/stxview/StructuredText/__init__.py deleted file mode 100644 index a5c1e5b047..0000000000 --- a/wxPython/samples/stxview/StructuredText/__init__.py +++ /dev/null @@ -1,112 +0,0 @@ -############################################################################## -# -# Zope Public License (ZPL) Version 1.0 -# ------------------------------------- -# -# Copyright (c) Digital Creations. All rights reserved. -# -# This license has been certified as Open Source(tm). -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions in source code must retain the above copyright -# notice, this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. Digital Creations requests that attribution be given to Zope -# in any manner possible. Zope includes a "Powered by Zope" -# button that is installed by default. While it is not a license -# violation to remove this button, it is requested that the -# attribution remain. A significant investment has been put -# into Zope, and this effort will continue if the Zope community -# continues to grow. This is one way to assure that growth. -# -# 4. All advertising materials and documentation mentioning -# features derived from or use of this software must display -# the following acknowledgement: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# In the event that the product being advertised includes an -# intact Zope distribution (with copyright and license included) -# then this clause is waived. -# -# 5. Names associated with Zope or Digital Creations must not be used to -# endorse or promote products derived from this software without -# prior written permission from Digital Creations. -# -# 6. Modified redistributions of any form whatsoever must retain -# the following acknowledgment: -# -# "This product includes software developed by Digital Creations -# for use in the Z Object Publishing Environment -# (http://www.zope.org/)." -# -# Intact (re-)distributions of any official Zope release do not -# require an external acknowledgement. -# -# 7. Modifications are encouraged but must be packaged separately as -# patches to official Zope releases. Distributions that do not -# clearly separate the patches from the original work must be clearly -# labeled as unofficial distributions. Modifications which do not -# carry the name Zope may be packaged in any form, as long as they -# conform to all of the clauses above. -# -# -# Disclaimer -# -# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY -# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# -# This software consists of contributions made by Digital Creations and -# many individuals on behalf of Digital Creations. Specific -# attributions are listed in the accompanying credits file. -# -############################################################################## - -import HTMLClass, DocumentClass -import ClassicDocumentClass -from StructuredText import html_with_references, HTML -from ST import Basic -import DocBookClass -import HTMLWithImages -import DocumentWithImages - -ClassicHTML=HTML -HTMLNG=HTMLClass.HTMLClass() - -def HTML(src, level=0, type=type, StringType=type('')): - if type(src) is StringType: - return ClassicHTML(src, level) - return HTMLNG(src, level) - -Classic=ClassicDocumentClass.DocumentClass() -Document=DocumentClass.DocumentClass() -DocumentWithImages=DocumentWithImages.DocumentWithImages() -HTMLWithImages=HTMLWithImages.HTMLWithImages() - -DocBookBook=DocBookClass.DocBookBook() -DocBookChapter=DocBookClass.DocBookChapter() -DocBookChapterWithFigures=DocBookClass.DocBookChapterWithFigures() -DocBookArticle=DocBookClass.DocBookArticle() - - diff --git a/wxPython/samples/stxview/stxview.py b/wxPython/samples/stxview/stxview.py deleted file mode 100644 index f9be495c01..0000000000 --- a/wxPython/samples/stxview/stxview.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python -#---------------------------------------------------------------------- - -import sys, os -import StructuredText -from wxPython.wx import * - - -USE_WXHTML = 1 - - -if not USE_WXHTML: - try: # try to load the IE ActiveX control - from wxPython.lib.activexwrapper import MakeActiveXClass - import win32com.client.gencache - browserModule = win32com.client.gencache.EnsureModule( - "{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 0, 1, 1) - except: - USE_WXHTML = 1 - -if not USE_WXHTML: - BrowserClass = MakeActiveXClass(browserModule.WebBrowser) - - class MyHtmlWindow(BrowserClass): - def SetPage(self, html): - import tempfile - filename = tempfile.mktemp('.html') - f = open(filename, 'w') - f.write(html) - f.close() - self.Navigate(os.path.abspath(filename)) - self.filename = filename - - def OnDocumentComplete(self, pDisp=None, URL=None): - os.unlink(self.filename) - -else: - from wxPython.html import * - MyHtmlWindow = wxHtmlWindow - - - -class StxFrame(wxFrame): - title = "StxViewer" - def __init__(self, stxFile): - wxFrame.__init__(self, None, -1, self.title, size=(650, 700), - style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE) - - ##self.CreateStatusBar() - - menu = wxMenu() - menu.Append(10, "&Open\tCtrl-O", "Open a Structured Text file") - EVT_MENU(self, 10, self.OnOpen) - menu.Append(20, "&Close", "Close the current file") - EVT_MENU(self, 20, self.OnClose) - menu.Append(30, "&Save\tCtrl-S", "Save the current file") - EVT_MENU(self, 30, self.OnSave) - menu.Append(40, "Save &as", "Save the current file to a new name") - EVT_MENU(self, 40, self.OnSaveAs) - menu.Append(45, "Save as &html", "Save the current file as HTML") - EVT_MENU(self, 45, self.OnSaveAsHTML) - menu.AppendSeparator() - menu.Append(50, "&Refresh\tCtrl-R", "Reload the file from disk") - EVT_MENU(self, 50, self.OnRefresh) - menu.AppendSeparator() - menu.Append(60, "E&xit\tCtrl-X", "Close the application") - EVT_MENU(self, 60, self.OnExit) - - - menuBar = wxMenuBar() - menuBar.Append(menu, "&File") - self.SetMenuBar(menuBar) - - - nb = wxNotebook(self, -1) - EVT_NOTEBOOK_PAGE_CHANGED(self, -1, self.OnPageChanged) - - self.htmlWin = MyHtmlWindow(nb, -1) - nb.AddPage(self.htmlWin, "View") - - self.editWin = wxTextCtrl(nb, -1, "", style=wxTE_MULTILINE) - self.editWin.SetFont(wxFont(10, wxTELETYPE, wxNORMAL, wxNORMAL)) - nb.AddPage(self.editWin, "Edit") - - self.viewHtml = wxTextCtrl(nb, -1, "", style=wxTE_MULTILINE|wxTE_READONLY) - self.viewHtml.SetFont(wxFont(10, wxTELETYPE, wxNORMAL, wxNORMAL)) - nb.AddPage(self.viewHtml, "HTML") - - self.LoadStxFile(stxFile) - - - def LoadStxFile(self, stxFile): - self.file = stxFile - if stxFile is not None: - text = open(stxFile).read() - self.SetTitle(self.title + ': ' + stxFile) - else: - text = "" - self.SetTitle(self.title) - self.LoadStxText(text) - - - def LoadStxText(self, text): - # Old ST - html = str(StructuredText.html_with_references(text)) - - # NG Version - #st = StructuredText.Basic(text) - #doc = StructuredText.Document(st) - #html = StructuredText.HTMLNG(doc) - - self.htmlWin.SetPage(html) - self.editWin.SetValue(text) - self.viewHtml.SetValue(html) - self.html = html - - - def OnPageChanged(self, evt): - if evt.GetOldSelection() == 1: # if it was on the edit page - text = self.editWin.GetValue() - self.LoadStxText(text) - - - def OnOpen(self, evt): - dlg = wxFileDialog(self, defaultDir=os.getcwd(), - wildcard = "STX files (*.stx)|*.stx|" - "Text files (*.txt)|*.txt|" - "All files (*.*)|*.*", - style=wxOPEN) - if dlg.ShowModal() == wxID_OK: - self.LoadStxFile(dlg.GetPath()) - dlg.Destroy() - - - - def OnClose(self, evt): - self.LoadStxFile(None) - - - def OnSave(self, evt): - if not self.file: - self.OnSaveAs(evt) - else: - text = self.editWin.GetValue() - open(self.file, 'w').write(text) - self.LoadStxFile(self.file) - - - def OnSaveAs(self, evt): - dlg = wxFileDialog(self, "Save as...", defaultDir=os.getcwd(), - wildcard = "STX files (*.stx)|*.stx|" - "Text files (*.txt)|*.txt|" - "All files (*.*)|*.*", - style=wxSAVE) - if dlg.ShowModal() == wxID_OK: - file = dlg.GetPath() - text = self.editWin.GetValue() - open(file, 'w').write(text) - self.LoadStxFile(file) - dlg.Destroy() - - - def OnSaveAsHTML(self, evt): - dlg = wxFileDialog(self, "Save as...", defaultDir=os.getcwd(), - wildcard = "HTML files (*.html)|*.html|" - "All files (*.*)|*.*", - style=wxSAVE) - if dlg.ShowModal() == wxID_OK: - file = dlg.GetPath() - text = self.editWin.GetValue() - self.LoadStxText(text) - open(file, 'w').write(self.html) - dlg.Destroy() - - - - def OnRefresh(self, evt): - self.LoadStxFile(self.file) - - - def OnExit(self, evt): - self.Close(true) - - - - - -app = wxPySimpleApp() -wxInitAllImageHandlers() - -if len(sys.argv) > 1: - filename = sys.argv[1] -else: - filename = None - -frame = StxFrame(filename) -frame.Show(true) -app.MainLoop() - - - diff --git a/wxPython/samples/stxview/test.stx b/wxPython/samples/stxview/test.stx deleted file mode 100644 index 20f53b2acd..0000000000 --- a/wxPython/samples/stxview/test.stx +++ /dev/null @@ -1,127 +0,0 @@ -Structured Text Manipulation - - Parse a structured text string into a form that can be used with - structured formats, like html. - - Structured text is text that uses indentation and simple - symbology to indicate the structure of a document. - - A structured string consists of a sequence of paragraphs separated by - one or more blank lines. Each paragraph has a level which is defined - as the minimum indentation of the paragraph. A paragraph is a - sub-paragraph of another paragraph if the other paragraph is the last - preceding paragraph that has a lower level. - -Special symbology is used to indicate special constructs: - - - A single-line paragraph whose immediately succeeding paragraphs are lower - level is treated as a header. - - - A paragraph that begins with a '-', '*', or 'o' is treated as an - unordered list (bullet) element. - - - A paragraph that begins with a sequence of digits followed by a - white-space character is treated as an ordered list element. - - - A paragraph that begins with a sequence of sequences, where each - sequence is a sequence of digits or a sequence of letters followed - by a period, is treated as an ordered list element. If the sequence is - made up of lower-case i's and v's, a lower-case roman-numeral list is - generated. If the sequence is made up of upper-case I's and V's, an - upper-case roman-numeral list is generated. If the sequence is made - up of other lower case letters (typically a,b,c) a lowercase alphabetic - list is generated. If the sequence is made of of other upper case - letters (typically, A,B,C) an uppercase alphabetic list is generated. - If the sequence is something else (typically, 1,2,3), a arabic-numeral - list is generated. - - - A paragraph with a first line that contains some text, followed by - some white-space and '--' is treated as a descriptive list element. - The leading text is treated as the element title. - - - Sub-paragraphs of a paragraph that ends in the word 'example' or the - word 'examples', or '::' is treated as example code and is output as is. - - - Text enclosed single quotes (with white-space to the left of the - first quote and whitespace or puctuation to the right of the second quote) - is treated as example code. - - - Text surrounded by '*' characters (with white-space to the left of the - first '*' and whitespace or puctuation to the right of the second '*') - is *emphasized*. - - - Text surrounded by '**' characters (with white-space to the left of the - first '**' and whitespace or puctuation to the right of the second '**') - is made **strong**. - - - Text surrounded by '_' underscore characters (with whitespace to the left - and whitespace or punctuation to the right) is made _underlined_. - - - Text encloded by double quotes followed by a colon, a URL, and concluded - by punctuation plus white space, *or* just white space, is treated as a - hyper link. For example: - - '"Zope":http://www.zope.org/ is ...' - - Is interpreted as 'Zope is ...' - Note: This works for relative as well as absolute URLs. - - - Text enclosed by double quotes followed by a comma, one or more spaces, - an absolute URL and concluded by punctuation plus white space, or just - white space, is treated as a hyper link. For example: - - "mail me", mailto:amos@digicool.com. - - Is interpreted as 'mail me.' - - - Text enclosed in brackets which consists only of letters, digits, - underscores and dashes is treated as hyper links within the document. - For example: - - As demonstrated by Smith [12] this technique is quite effective. - - Is interpreted as '... by Smith [12] this ...'. Together - with the next rule this allows easy coding of references or end notes. - - - Text enclosed in brackets which is preceded by the start of a line, two - periods and a space is treated as a named link. For example: - - .. [12] "Effective Techniques" Smith, Joe ... - - Is interpreted as '[12] "Effective Techniques" ...'. - Together with the previous rule this allows easy coding of references or - end notes. - - - - A paragraph that has blocks of text enclosed in '||' is treated as a - table. The text blocks correspond to table cells and table rows are - denoted by newlines. By default the cells are center aligned. A cell - can span more than one column by preceding a block of text with an - equivalent number of cell separators '||'. Newlines and '|' cannot - be a part of the cell text. For example: - - |||| **Ingredients** || - || *Name* || *Amount* || - ||Spam||10|| - ||Eggs||3|| - - is interpreted as:: - - - - - - - - - - - - - - - - - -
        Ingredients
        Name Amount
        Spam10
        Eggs3
        - diff --git a/wxPython/samples/wxProject/wxProject.py b/wxPython/samples/wxProject/wxProject.py index 03b6df1075..6023785ee1 100644 --- a/wxPython/samples/wxProject/wxProject.py +++ b/wxPython/samples/wxProject/wxProject.py @@ -89,12 +89,12 @@ class main_window(wxFrame): # Install the tree and the editor. # ------------------------------------------------------------------------------------ splitter.SplitVertically (self.tree, self.editor) - splitter.SetSashPosition (180, true) + splitter.SetSashPosition (180, True) - self.Show(true) + self.Show(True) # Some global state variables. - self.projectdirty = false + self.projectdirty = False # ---------------------------------------------------------------------------------------- # Some nice little handlers. @@ -118,9 +118,9 @@ class main_window(wxFrame): self.tree.Expand (self.root) self.editor.Clear() - self.editor.Enable (false) + self.editor.Enable (False) - self.projectdirty = false + self.projectdirty = False except IOError: pass @@ -139,7 +139,7 @@ class main_window(wxFrame): (child,iter) = self.tree.GetNextChild(self.root,iter) output.write (self.tree.GetItemText(child) + "\n") output.close() - self.projectdirty = false + self.projectdirty = False except IOError: dlg_m = wxMessageDialog (self, 'There was an error saving the project file.', 'Error!', wxOK) @@ -151,7 +151,7 @@ class main_window(wxFrame): # ---------------------------------------------------------------------------------------- def OnProjectOpen(self, event): - open_it = true + open_it = True if self.projectdirty: dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject', wxYES_NO | wxCANCEL) @@ -159,7 +159,7 @@ class main_window(wxFrame): if result == wxID_YES: self.project_save() if result == wxID_CANCEL: - open_it = false + open_it = False dlg.Destroy() if open_it: dlg = wxFileDialog(self, "Choose a project to open", ".", "", "*.wxp", wxOPEN) @@ -168,7 +168,7 @@ class main_window(wxFrame): dlg.Destroy() def OnProjectNew(self, event): - open_it = true + open_it = True if self.projectdirty: dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject', wxYES_NO | wxCANCEL) @@ -176,7 +176,7 @@ class main_window(wxFrame): if result == wxID_YES: self.project_save() if result == wxID_CANCEL: - open_it = false + open_it = False dlg.Destroy() if open_it: @@ -202,7 +202,7 @@ class main_window(wxFrame): dlg.Destroy() def OnProjectExit(self, event): - close = true + close = True if self.projectdirty: dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject', wxYES_NO | wxCANCEL) @@ -210,7 +210,7 @@ class main_window(wxFrame): if result == wxID_YES: self.project_save() if result == wxID_CANCEL: - close = false + close = False dlg.Destroy() if close: self.Close() @@ -243,10 +243,10 @@ class main_window(wxFrame): event.Veto() def OnTreeLabelEditEnd(self, event): - self.projectdirty = true + self.projectdirty = True def OnTreeItemActivated(self, event): - go_ahead = true + go_ahead = True if self.activeitem != self.root: if self.editor.IsModified(): dlg=wxMessageDialog(self, 'The edited file has changed. Save it?', @@ -255,7 +255,7 @@ class main_window(wxFrame): if result == wxID_YES: self.editor.SaveFile (self.tree.GetItemText (self.activeitem)) if result == wxID_CANCEL: - go_ahead = false + go_ahead = False dlg.Destroy() if go_ahead: self.tree.SetItemBold (self.activeitem, 0) @@ -279,7 +279,7 @@ class App(wxApp): self.SetTopWindow(frame) if (projfile != 'Unnamed'): frame.project_open (projfile) - return true + return True app = App(0) app.MainLoop() diff --git a/wxPython/scripts/CreateBatchFiles.py b/wxPython/scripts/CreateBatchFiles.py index 269a55d25d..871650d52f 100644 --- a/wxPython/scripts/CreateBatchFiles.py +++ b/wxPython/scripts/CreateBatchFiles.py @@ -1,6 +1,6 @@ #---------------------------------------------------------------------- # Name: CreateBatchFiles.py -# Purpose: Run by the InnoSetup installer to create a DOS batch +# Purpose: Run by the InnoSetup installer to create a DOS batch # file for each of the wxPython tool scripts. # # Author: Robin Dunn @@ -22,6 +22,8 @@ scripts = [ ("img2png", 0), ("xrced", 1), ("pyshell", 1), ("pycrust", 1), + ("pycwrap", 1), + ("helpviewer", 1), ] template = """\ diff --git a/wxPython/scripts/CreateMacScripts.py b/wxPython/scripts/CreateMacScripts.py index 8108771e7c..d8ab06fca0 100644 --- a/wxPython/scripts/CreateMacScripts.py +++ b/wxPython/scripts/CreateMacScripts.py @@ -1,6 +1,6 @@ #---------------------------------------------------------------------- # Name: CreateMacScripts.py -# Purpose: Massages the scripts to be usable with MachoPython +# Purpose: Massages the scripts to be usable with MachoPython # # Author: Robin Dunn # @@ -13,23 +13,30 @@ import sys, os python = sys.executable destdir = os.path.split(python)[0] +prefix = destdir pythonw = os.path.join(destdir, 'pythonw') scriptdir = os.getcwd() if len(sys.argv) > 1: - destdir = sys.argv[1] + root = sys.argv[1] + p = prefix = sys.argv[2] + if p[0] == '/': p = p[1:] + destdir = os.path.join(root, p) + from CreateBatchFiles import scripts repltxt = "#!/usr/bin/env python" -gui_template = """\ -#!/bin/sh -exec /Applications/Python.app/Contents/MacOS/python %s.py -""" + +# use the existing pythonw as a template +gui_template = open(pythonw, "r").read().replace('"$@"', '"%s.py" "$@"') + def main(): for script, usegui in scripts: destfile = os.path.join(destdir, script) + prefixfile = os.path.join(prefix, script) + thescript = open(script).read() if usegui: f = open(destfile+'.py', 'w') @@ -38,7 +45,7 @@ def main(): f.close() f = open(destfile, 'w') print destfile - f.write(gui_template % destfile) + f.write(gui_template % prefixfile) f.close() else: diff --git a/wxPython/scripts/helpviewer b/wxPython/scripts/helpviewer new file mode 100755 index 0000000000..c31cc70a15 --- /dev/null +++ b/wxPython/scripts/helpviewer @@ -0,0 +1,4 @@ +#!/usr/bin/env python + +from wxPython.tools.helpviewer import main +main() diff --git a/wxPython/scripts/helpviewer.bat b/wxPython/scripts/helpviewer.bat new file mode 100755 index 0000000000..d881374690 --- /dev/null +++ b/wxPython/scripts/helpviewer.bat @@ -0,0 +1,3 @@ +@echo off + +start e:\tools\Python22\pythonw.exe e:\PROJECTS\wx\wxPython\scripts\helpviewer %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/img2png.bat b/wxPython/scripts/img2png.bat index d926caa621..a69fee0c02 100755 --- a/wxPython/scripts/img2png.bat +++ b/wxPython/scripts/img2png.bat @@ -1,3 +1,3 @@ @echo off -C:\TOOLS\PYTHON22\PYTHON.EXE C:\projects\wx\wxPython\scripts\img2png %1 %2 %3 %4 %5 %6 %7 %8 %9 +e:\tools\Python22\python.exe e:\PROJECTS\wx\wxPython\scripts\img2png %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/img2py.bat b/wxPython/scripts/img2py.bat index b63e13ac62..e2451895ec 100755 --- a/wxPython/scripts/img2py.bat +++ b/wxPython/scripts/img2py.bat @@ -1,3 +1,3 @@ @echo off -C:\TOOLS\PYTHON22\PYTHON.EXE C:\projects\wx\wxPython\scripts\img2py %1 %2 %3 %4 %5 %6 %7 %8 %9 +e:\tools\Python22\python.exe e:\PROJECTS\wx\wxPython\scripts\img2py %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/img2xpm.bat b/wxPython/scripts/img2xpm.bat index adda6be6de..45bff43e11 100755 --- a/wxPython/scripts/img2xpm.bat +++ b/wxPython/scripts/img2xpm.bat @@ -1,3 +1,3 @@ @echo off -C:\TOOLS\PYTHON22\PYTHON.EXE C:\projects\wx\wxPython\scripts\img2xpm %1 %2 %3 %4 %5 %6 %7 %8 %9 +e:\tools\Python22\python.exe e:\PROJECTS\wx\wxPython\scripts\img2xpm %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/pycrust.bat b/wxPython/scripts/pycrust.bat index 6f4b5dc07c..a2fc4f3416 100755 --- a/wxPython/scripts/pycrust.bat +++ b/wxPython/scripts/pycrust.bat @@ -1,3 +1,3 @@ @echo off -start C:\TOOLS\PYTHON22\pythonw.exe C:\projects\wx\wxPython\scripts\pycrust %1 %2 %3 %4 %5 %6 %7 %8 %9 +start e:\tools\Python22\pythonw.exe e:\PROJECTS\wx\wxPython\scripts\pycrust %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/pycwrap b/wxPython/scripts/pycwrap new file mode 100755 index 0000000000..911c5ec778 --- /dev/null +++ b/wxPython/scripts/pycwrap @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +from wxPython.lib.PyCrust.wrap import main +import sys, os + +sys.path.insert(0, os.curdir) +main(sys.argv) diff --git a/wxPython/scripts/pycwrap.bat b/wxPython/scripts/pycwrap.bat new file mode 100755 index 0000000000..40562b5629 --- /dev/null +++ b/wxPython/scripts/pycwrap.bat @@ -0,0 +1,3 @@ +@echo off + +start e:\tools\Python22\pythonw.exe e:\PROJECTS\wx\wxPython\scripts\pycwrap %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/pyshell.bat b/wxPython/scripts/pyshell.bat index 6e02101940..fff21cd258 100755 --- a/wxPython/scripts/pyshell.bat +++ b/wxPython/scripts/pyshell.bat @@ -1,3 +1,3 @@ @echo off -start C:\TOOLS\PYTHON22\pythonw.exe C:\projects\wx\wxPython\scripts\pyshell %1 %2 %3 %4 %5 %6 %7 %8 %9 +start e:\tools\Python22\pythonw.exe e:\PROJECTS\wx\wxPython\scripts\pyshell %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/scripts/xrced.bat b/wxPython/scripts/xrced.bat index e3b87fa793..2bfdd300cb 100755 --- a/wxPython/scripts/xrced.bat +++ b/wxPython/scripts/xrced.bat @@ -1,3 +1,3 @@ @echo off -start C:\TOOLS\PYTHON22\pythonw.exe C:\projects\wx\wxPython\scripts\xrced %1 %2 %3 %4 %5 %6 %7 %8 %9 +start e:\tools\Python22\pythonw.exe e:\PROJECTS\wx\wxPython\scripts\xrced %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/wxPython/setup.py b/wxPython/setup.py index 7d6a2c6247..e8dedd03f4 100755 --- a/wxPython/setup.py +++ b/wxPython/setup.py @@ -1,19 +1,19 @@ #!/usr/bin/env python #---------------------------------------------------------------------- -import sys, os, string, glob +import sys, os, glob from distutils.core import setup, Extension from distutils.file_util import copy_file from distutils.dir_util import mkpath from distutils.dep_util import newer - -from my_distutils import run_swig, contrib_copy_tree +from distutils.spawn import spawn +from distutils.command.install_data import install_data #---------------------------------------------------------------------- # flags and values that affect this script #---------------------------------------------------------------------- -VERSION = "2.3.3pre8" +VERSION = "2.5.0p1" DESCRIPTION = "Cross platform GUI toolkit for Python" AUTHOR = "Robin Dunn" AUTHOR_EMAIL = "Robin Dunn " @@ -23,26 +23,31 @@ LONG_DESCRIPTION = """\ wxPython is a GUI toolkit for Python that is a wrapper around the wxWindows C++ GUI library. wxPython provides a large variety of window types and controls, all implemented with a native look and -feel (and native runtime speed) on the platforms it is supported +feel (by using the native widgets) on the platforms it is supported on. """ +# Config values below this point can be reset on the setup.py command line. + BUILD_GLCANVAS = 1 # If true, build the contrib/glcanvas extension module BUILD_OGL = 1 # If true, build the contrib/ogl extension module BUILD_STC = 1 # If true, build the contrib/stc extension module BUILD_XRC = 1 # XML based resource system BUILD_GIZMOS = 1 # Build a module for the gizmos contrib library -BUILD_DLLWIDGET = 1# Build a module that enables unknown wx widgets +BUILD_DLLWIDGET = 0# Build a module that enables unknown wx widgets # to be loaded from a DLL and to be used from Python. # Internet Explorer wrapper (experimental) BUILD_IEWIN = (os.name == 'nt') +BUILD_CANVAS = 0 # Build a canvas module using the one in wx/contrib (experimental) +BUILD_ART2D = 0 # Build a canvas module using code from the wxArt2D project (experimental) + + CORE_ONLY = 0 # if true, don't build any of the above -GL_ONLY = 0 # Only used when making the -gl RPM. See the "b" script - # for the ugly details +PREP_ONLY = 0 # Only run the prepatory steps, not the actual build. USE_SWIG = 0 # Should we actually execute SWIG, or just use the # files already in the distribution? @@ -51,9 +56,13 @@ UNICODE = 0 # This will pass the 'wxUSE_UNICODE' flag to SWIG and # will ensure that the right headers are found and the # right libs are linked. -IN_CVS_TREE = 0 # Set to true if building in a full wxWindows CVS - # tree, otherwise will assume all needed files are - # available in the wxPython source distribution +IN_CVS_TREE = 1 # Set to true if building in a full wxWindows CVS + # tree, or the new style of a full wxPythonSrc tarball. + # wxPython used to be distributed as a separate source + # tarball without the wxWindows but with a copy of the + # needed contrib code. That's no longer the case and so + # this setting is now defaulting to true. Eventually it + # should be removed entirly. UNDEF_NDEBUG = 1 # Python 2.2 on Unix/Linux by default defines NDEBUG, # and distutils will pick this up and use it on the @@ -66,13 +75,21 @@ UNDEF_NDEBUG = 1 # Python 2.2 on Unix/Linux by default defines NDEBUG, NO_SCRIPTS = 0 # Don't install the tool scripts +WX_CONFIG = None # Usually you shouldn't need to touch this, but you can set + # it to pass an alternate version of wx-config or alternate + # flags, eg. as required by the .deb in-tree build. By + # default a wx-config command will be assembled based on + # version, port, etc. and it will be looked for on the + # default $PATH. + +WXPORT = 'gtk' # On Linux/Unix there are several ports of wxWindows available. + # Setting this value lets you select which will be used for + # the wxPython build. Possibilites are 'gtk', 'gtk2' and + # 'x11'. Curently only gtk and gtk2 works. + +BUILD_BASE = "build" # Directory to use for temporary build files. -WX_CONFIG = "wx-config" # Usually you shouldn't need to touch this, - # but you can set it to pass an alternate - # version of wx-config or alternate flags, - # eg. as required by the .deb in-tree build. -BUILD_BASE = "build" # Some MSW build settings @@ -87,7 +104,7 @@ HYBRID = 1 # If set and not debug or FINAL, then build a # wxWindows must have been built with /MD, not /MDd # (using FINAL=hybrid will do it.) -WXDLLVER = '233' # Version part of wxWindows DLL name +WXDLLVER = '250' # Version part of wxWindows DLL name #---------------------------------------------------------------------- @@ -120,18 +137,18 @@ def libFlag(): PKGDIR = 'wxPython' wxpExtensions = [] +DATA_FILES = [] force = '--force' in sys.argv or '-f' in sys.argv debug = '--debug' in sys.argv or '-g' in sys.argv -bcpp_compiling = '-c' in sys.argv and 'my_bcpp' in sys.argv # Bad heuristic +# change the PORT default for wxMac +if sys.platform[:6] == "darwin": + WXPORT = 'mac' -if bcpp_compiling: - msg("Compiling wxPython by Borland C/C++ Compiler") - HYBRID=0 - WXBCPPLIBVER = string.replace(WXDLLVER,"_","") - # Version part of BCPP build LIBRARY name - WXDLLVER="" # no dll ver path avaible +# and do the same for wxMSW, just for consistency +if os.name == 'nt': + WXPORT = 'msw' #---------------------------------------------------------------------- @@ -141,21 +158,21 @@ if bcpp_compiling: # Boolean (int) flags for flag in ['BUILD_GLCANVAS', 'BUILD_OGL', 'BUILD_STC', 'BUILD_XRC', 'BUILD_GIZMOS', 'BUILD_DLLWIDGET', 'BUILD_IEWIN', - 'CORE_ONLY', 'USE_SWIG', 'IN_CVS_TREE', 'UNICODE', + 'CORE_ONLY', 'PREP_ONLY', 'USE_SWIG', 'IN_CVS_TREE', 'UNICODE', 'UNDEF_NDEBUG', 'NO_SCRIPTS', 'FINAL', 'HYBRID', ]: for x in range(len(sys.argv)): - if string.find(sys.argv[x], flag) == 0: - pos = string.find(sys.argv[x], '=') + 1 + if sys.argv[x].find(flag) == 0: + pos = sys.argv[x].find('=') + 1 if pos > 0: vars()[flag] = eval(sys.argv[x][pos:]) sys.argv[x] = '' # String options -for option in ['WX_CONFIG', 'WXDLLVER', 'BUILD_BASE']: +for option in ['WX_CONFIG', 'WXDLLVER', 'BUILD_BASE', 'WXPORT']: for x in range(len(sys.argv)): - if string.find(sys.argv[x], option) == 0: - pos = string.find(sys.argv[x], '=') + 1 + if sys.argv[x].find(option) == 0: + pos = sys.argv[x].find('=') + 1 if pos > 0: vars()[option] = sys.argv[x][pos:] sys.argv[x] = '' @@ -163,6 +180,123 @@ for option in ['WX_CONFIG', 'WXDLLVER', 'BUILD_BASE']: sys.argv = filter(None, sys.argv) +#---------------------------------------------------------------------- +# some helper functions +#---------------------------------------------------------------------- + +def Verify_WX_CONFIG(): + """ Called below for the builds that need wx-config, + if WX_CONFIG is not set then tries to select the specific + wx*-config script based on build options. If not found + then it defaults to 'wx-config'. + """ + # if WX_CONFIG hasn't been set to an explicit value then construct one. + global WX_CONFIG + if WX_CONFIG is None: + if debug: # TODO: Fix this. wxPython's --debug shouldn't be tied to wxWindows... + df = 'd' + else: + df = '' + if UNICODE: + uf = 'u' + else: + uf = '' + ver2 = VERSION[:3] + WX_CONFIG = 'wx%s%s%s-%s-config' % (WXPORT, uf, df, ver2) + + searchpath = os.environ["PATH"] + for p in searchpath.split(':'): + fp = os.path.join(p, WX_CONFIG) + if os.path.exists(fp) and os.access(fp, os.X_OK): + # success + msg("Found wx-config: " + fp) + WX_CONFIG = fp + break + else: + msg("WX_CONFIG not specified and %s not found on $PATH " + "defaulting to \"wx-config\"" % WX_CONFIG) + WX_CONFIG = 'wx-config' + + + +def run_swig(files, dir, gendir, package, USE_SWIG, force, swig_args, swig_deps=[]): + """Run SWIG the way I want it done""" + if not os.path.exists(os.path.join(dir, gendir)): + os.mkdir(os.path.join(dir, gendir)) + + sources = [] + + for file in files: + basefile = os.path.splitext(file)[0] + i_file = os.path.join(dir, file) + py_file = os.path.join(dir, gendir, basefile+'.py') + cpp_file = os.path.join(dir, gendir, basefile+'.cpp') + + sources.append(cpp_file) + + if USE_SWIG: + for dep in swig_deps: + if newer(dep, py_file) or newer(dep, cpp_file): + force = 1 + break + + if force or newer(i_file, py_file) or newer(i_file, cpp_file): + # we need forward slashes here even on win32 + cpp_file = '/'.join(cpp_file.split('\\')) + i_file = '/'.join(i_file.split('\\')) + + cmd = ['./wxSWIG/wxswig'] + swig_args + ['-I'+dir, '-c', '-o', cpp_file, i_file] + msg(' '.join(cmd)) + spawn(cmd) + + # copy the generated python file to the package directory + copy_file(py_file, package, update=not force, verbose=0) + + return sources + + + +def contrib_copy_tree(src, dest, verbose=0): + """Update local copies of wxWindows contrib files""" + from distutils.dir_util import mkpath, copy_tree + + mkpath(dest, verbose=verbose) + copy_tree(src, dest, update=1, verbose=verbose) + + + +class smart_install_data(install_data): + def run(self): + #need to change self.install_dir to the actual library dir + install_cmd = self.get_finalized_command('install') + self.install_dir = getattr(install_cmd, 'install_lib') + return install_data.run(self) + + +def build_locale_dir(destdir, verbose=1): + """Build a locale dir under the wxPython package for MSW""" + moFiles = glob.glob(opj(WXDIR, 'locale', '*.mo')) + for src in moFiles: + lang = os.path.splitext(os.path.basename(src))[0] + dest = opj(destdir, lang, 'LC_MESSAGES') + mkpath(dest, verbose=verbose) + copy_file(src, opj(dest, 'wxstd.mo'), update=1, verbose=verbose) + + +def build_locale_list(srcdir): + # get a list of all files under the srcdir, to be used for install_data + def walk_helper(lst, dirname, files): + for f in files: + filename = opj(dirname, f) + if not os.path.isdir(filename): + lst.append( (dirname, [filename]) ) + file_list = [] + os.path.walk(srcdir, walk_helper, file_list) + return file_list + + + + #---------------------------------------------------------------------- # sanity checks @@ -176,15 +310,15 @@ if CORE_ONLY: BUILD_DLLWIDGET = 0 BUILD_IEWIN = 0 +if debug: + FINAL = 0 + HYBRID = 0 -if UNICODE and os.name != 'nt': - print "UNICODE is currently only supported on Win32" - sys.exit() +if FINAL: + HYBRID = 0 - -if UNICODE: - BUILD_BASE = BUILD_BASE + '.unicode' - VERSION = VERSION + 'u' +if UNICODE and WXPORT not in ['msw', 'gtk2']: + raise SystemExit, "UNICODE mode not currently supported on this WXPORT: "+WXPORT #---------------------------------------------------------------------- @@ -203,20 +337,13 @@ if os.name == 'nt': WXPLAT = '__WXMSW__' GENDIR = 'msw' - if debug: - FINAL = 0 - HYBRID = 0 - - if HYBRID: - FINAL = 0 - includes = ['src', opj(WXDIR, 'lib', 'mswdll' + libFlag()), opj(WXDIR, 'include'), ] - defines = [ ('WIN32', None), # Some of these are no longer - ('__WIN32__', None), # necessary. Anybody know which? + defines = [ ('WIN32', None), + ('__WIN32__', None), ('_WINDOWS', None), ('__WINDOWS__', None), ('WINVER', '0x0400'), @@ -231,21 +358,8 @@ if os.name == 'nt': ('WXP_USE_THREAD', '1'), ] - if bcpp_compiling: # overwrite it - defines = [ - ('_WINDOWS', None), - ('WINVER', '0x0400'), - ('STRICT', None), - - ('WXUSINGDLL', '1'), - - ('SWIG_GLOBAL', None), - ('HAVE_CONFIG_H', None), - ('WXP_USE_THREAD', '1'), - - ('WXUSE_DEFINE','1'), - ('_RTLDLL',None), - ] + if UNDEF_NDEBUG: + defines.append( ('NDEBUG',) ) # using a 1-tuple makes it do an undef if not FINAL or HYBRID: @@ -255,12 +369,9 @@ if os.name == 'nt': wxdll = 'wxmsw' + WXDLLVER + libFlag() libs = [ wxdll ] - if bcpp_compiling: - libs = [ 'wx'+WXBCPPLIBVER ] - libs = libs + ['kernel32', 'user32', 'gdi32', 'comdlg32', 'winspool', 'winmm', 'shell32', 'oldnames', 'comctl32', - 'ctl3d32', 'odbc32', 'ole32', 'oleaut32', 'uuid', 'rpcrt4', + 'odbc32', 'ole32', 'oleaut32', 'uuid', 'rpcrt4', 'advapi32', 'wsock32'] @@ -269,32 +380,22 @@ if os.name == 'nt': ] lflags = None - - if bcpp_compiling: # BCC flags - cflags = ['-5', '-VF', ### To support MSVC spurious semicolons in the class scope - ### else, all semicolons at the end of all DECLARE_...CALLBACK... macros must be eliminated - '-Hc', '-H=' + opj(WXDIR, '\src\msw\wx32.csm'), - '@' + opj(WXDIR, '\src\msw\wxwin32.cfg') - ] - if not FINAL: - cflags = cflags + ['/Od', '/v', '/y'] - lflags = lflags + ['/v', ] - - else: # MSVC flags - if FINAL: - pass #cflags = cflags + ['/O1'] - elif HYBRID : - pass #cflags = cflags + ['/Ox'] - else: - pass # cflags = cflags + ['/Od', '/Z7'] - # lflags = ['/DEBUG', ] + # Other MSVC flags... + # To bad I don't remember why I was playing with these, can they be removed? + if FINAL: + pass #cflags = cflags + ['/O1'] + elif HYBRID : + pass #cflags = cflags + ['/Ox'] + else: + pass # cflags = cflags + ['/Od', '/Z7'] + # lflags = ['/DEBUG', ] +#---------------------------------------------------------------------- elif os.name == 'posix' and sys.platform[:6] == "darwin": # Flags and such for a Darwin (Max OS X) build of Python - WXDIR = '..' # assumes IN_CVS_TREE WXPLAT = '__WXMAC__' GENDIR = 'mac' @@ -304,60 +405,98 @@ elif os.name == 'posix' and sys.platform[:6] == "darwin": ('HAVE_CONFIG_H', None), ('WXP_USE_THREAD', '1'), ] + if UNDEF_NDEBUG: + defines.append( ('NDEBUG',) ) # using a 1-tuple makes it do an undef libdirs = [] - libs = [] + libs = ['stdc++'] + + Verify_WX_CONFIG() cflags = os.popen(WX_CONFIG + ' --cxxflags', 'r').read()[:-1] - cflags = string.split(cflags) - if UNDEF_NDEBUG: - cflags.append('-UNDEBUG') + cflags = cflags.split() if debug: cflags.append('-g') cflags.append('-O0') lflags = os.popen(WX_CONFIG + ' --libs', 'r').read()[:-1] - lflags = string.split(lflags) + lflags = lflags.split() NO_SCRIPTS = 1 -elif os.name == 'posix': - # Set flags for Unix type platforms +#---------------------------------------------------------------------- +elif os.name == 'posix': + # Set flags for other Unix type platforms WXDIR = '..' # assumes IN_CVS_TREE - WXPLAT = '__WXGTK__' # and assumes GTK... - GENDIR = 'gtk' # Need to allow for Motif eventually too + GENDIR = WXPORT + + if WXPORT == 'gtk': + WXPLAT = '__WXGTK__' + portcfg = os.popen('gtk-config --cflags', 'r').read()[:-1] + elif WXPORT == 'gtk2': + WXPLAT = '__WXGTK__' + GENDIR = 'gtk' # no code differences so use the same generated sources + portcfg = os.popen('pkg-config gtk+-2.0 --cflags', 'r').read()[:-1] + BUILD_BASE = BUILD_BASE + '-' + WXPORT + elif WXPORT == 'x11': + WXPLAT = '__WXX11__' + portcfg = '' + BUILD_BASE = BUILD_BASE + '-' + WXPORT + else: + raise SystemExit, "Unknown WXPORT value: " + WXPORT includes = ['src'] defines = [('SWIG_GLOBAL', None), ('HAVE_CONFIG_H', None), ('WXP_USE_THREAD', '1'), ] + if UNDEF_NDEBUG: + defines.append( ('NDEBUG',) ) # using a 1-tuple makes it do an undef + libdirs = [] libs = [] - cflags = os.popen(WX_CONFIG + ' --cxxflags', 'r').read()[:-1] + ' ' + \ - os.popen('gtk-config --cflags', 'r').read()[:-1] - cflags = string.split(cflags) - if UNDEF_NDEBUG: - cflags.append('-UNDEBUG') + Verify_WX_CONFIG() + + cflags = os.popen(WX_CONFIG + ' --cxxflags', 'r').read()[:-1] + ' ' + portcfg + + cflags = cflags.split() if debug: cflags.append('-g') cflags.append('-O0') lflags = os.popen(WX_CONFIG + ' --libs', 'r').read()[:-1] - lflags = string.split(lflags) + lflags = lflags.split() + + # Some distros (e.g. Mandrake) put libGLU in /usr/X11R6/lib, but + # wx-config doesn't output that for some reason. For now, just + # add it unconditionally but we should really check if the lib is + # really found there or wx-config should be fixed. + libdirs.append("/usr/X11R6/lib") +#---------------------------------------------------------------------- else: - raise 'Sorry Charlie...' + raise 'Sorry Charlie, platform not supported...' + + +#---------------------------------------------------------------------- +# post platform setup checks and tweaks +#---------------------------------------------------------------------- + +if UNICODE: + BUILD_BASE = BUILD_BASE + '.unicode' + VERSION = VERSION + 'u' #---------------------------------------------------------------------- # Check if the version file needs updated #---------------------------------------------------------------------- -#if IN_CVS_TREE and newer('setup.py', 'src/__version__.py'): +##if IN_CVS_TREE and newer('setup.py', 'src/__version__.py'): + +# Always do it since the version string can change based on the UNICODE flag open('src/__version__.py', 'w').write("ver = '%s'\n" % VERSION) @@ -383,118 +522,123 @@ swig_deps = ['src/my_typemaps.i'] # Define the CORE extension module #---------------------------------------------------------------------- -if not GL_ONLY: - msg('Preparing CORE...') - swig_files = [ 'wx.i', 'windows.i', 'windows2.i', 'windows3.i', 'events.i', - 'misc.i', 'misc2.i', 'gdi.i', 'mdi.i', 'controls.i', - 'controls2.i', 'cmndlgs.i', 'stattool.i', 'frames.i', 'image.i', - 'printfw.i', 'sizers.i', 'clip_dnd.i', - 'filesys.i', 'streams.i', 'utils.i', 'fonts.i' - ] - - swig_sources = run_swig(swig_files, 'src', GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) - - copy_file('src/__init__.py', PKGDIR, update=1, verbose=0) - copy_file('src/__version__.py', PKGDIR, update=1, verbose=0) - copy_file('src/wxc.pyd.manifest', PKGDIR, update=1, verbose=0) - - if IN_CVS_TREE: # update the license files - mkpath('licence') - for file in ['preamble.txt', 'licence.txt', 'licendoc.txt', 'lgpl.txt']: - copy_file(opj(WXDIR, 'docs', file), opj('licence',file), update=1, verbose=0) - - - if os.name == 'nt': - rc_file = ['src/wxc.rc'] - else: - rc_file = [] - - - ext = Extension('wxc', ['src/helpers.cpp', - 'src/libpy.c', - ] + rc_file + swig_sources, - - include_dirs = includes, - define_macros = defines, - - library_dirs = libdirs, - libraries = libs, - - extra_compile_args = cflags, - extra_link_args = lflags, - ) - wxpExtensions.append(ext) - - - # Extension for the grid module - swig_sources = run_swig(['grid.i'], 'src', GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) - ext = Extension('gridc', swig_sources, - include_dirs = includes, - define_macros = defines, - library_dirs = libdirs, - libraries = libs, - extra_compile_args = cflags, - extra_link_args = lflags, - ) - wxpExtensions.append(ext) +msg('Preparing CORE...') +swig_files = [ 'wx.i', 'windows.i', 'windows2.i', 'windows3.i', 'events.i', + 'misc.i', 'misc2.i', 'gdi.i', 'mdi.i', 'controls.i', + 'controls2.i', 'cmndlgs.i', 'stattool.i', 'frames.i', 'image.i', + 'printfw.i', 'sizers.i', 'clip_dnd.i', + 'filesys.i', 'streams.i', 'utils.i', 'fonts.i' + ] +swig_sources = run_swig(swig_files, 'src', GENDIR, PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) - # Extension for the html modules - swig_sources = run_swig(['html.i', 'htmlhelp.i'], 'src', GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) - ext = Extension('htmlc', swig_sources, - include_dirs = includes, - define_macros = defines, - library_dirs = libdirs, - libraries = libs, - extra_compile_args = cflags, - extra_link_args = lflags, - ) - wxpExtensions.append(ext) +copy_file('src/__init__.py', PKGDIR, update=1, verbose=0) +copy_file('src/__version__.py', PKGDIR, update=1, verbose=0) - # Extension for the calendar module - swig_sources = run_swig(['calendar.i'], 'src', GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) - ext = Extension('calendarc', swig_sources, - include_dirs = includes, - define_macros = defines, - library_dirs = libdirs, - libraries = libs, - extra_compile_args = cflags, - extra_link_args = lflags, - ) - wxpExtensions.append(ext) +if IN_CVS_TREE: # update the license files + mkpath('licence') + for file in ['preamble.txt', 'licence.txt', 'licendoc.txt', 'lgpl.txt']: + copy_file(opj(WXDIR, 'docs', file), opj('licence',file), update=1, verbose=0) - # Extension for the help module - swig_sources = run_swig(['help.i'], 'src', GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) - ext = Extension('helpc', swig_sources, - include_dirs = includes, - define_macros = defines, - library_dirs = libdirs, - libraries = libs, - extra_compile_args = cflags, - extra_link_args = lflags, - ) - wxpExtensions.append(ext) +if os.name == 'nt': + build_locale_dir(opj(PKGDIR, 'locale')) + DATA_FILES += build_locale_list(opj(PKGDIR, 'locale')) - # Extension for the wizard module - swig_sources = run_swig(['wizard.i'], 'src', GENDIR, PKGDIR, - USE_SWIG, swig_force, swig_args, swig_deps) - ext = Extension('wizardc', swig_sources, - include_dirs = includes, - define_macros = defines, - library_dirs = libdirs, - libraries = libs, - extra_compile_args = cflags, - extra_link_args = lflags, - ) - wxpExtensions.append(ext) +if os.name == 'nt': + rc_file = ['src/wxc.rc'] +else: + rc_file = [] + + +ext = Extension('wxc', ['src/helpers.cpp', + 'src/drawlist.cpp', + 'src/libpy.c', + ] + rc_file + swig_sources, + + include_dirs = includes, + define_macros = defines, + + library_dirs = libdirs, + libraries = libs, + + extra_compile_args = cflags, + extra_link_args = lflags, + ) +wxpExtensions.append(ext) + + +# Extension for the grid module +swig_sources = run_swig(['grid.i'], 'src', GENDIR, PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) +ext = Extension('gridc', swig_sources, + include_dirs = includes, + define_macros = defines, + library_dirs = libdirs, + libraries = libs, + extra_compile_args = cflags, + extra_link_args = lflags, + ) +wxpExtensions.append(ext) + + +# Extension for the html modules +swig_sources = run_swig(['html.i', 'htmlhelp.i'], 'src', GENDIR, PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) +ext = Extension('htmlc', swig_sources, + include_dirs = includes, + define_macros = defines, + library_dirs = libdirs, + libraries = libs, + extra_compile_args = cflags, + extra_link_args = lflags, + ) +wxpExtensions.append(ext) + + +# Extension for the calendar module +swig_sources = run_swig(['calendar.i'], 'src', GENDIR, PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) +ext = Extension('calendarc', swig_sources, + include_dirs = includes, + define_macros = defines, + library_dirs = libdirs, + libraries = libs, + extra_compile_args = cflags, + extra_link_args = lflags, + ) +wxpExtensions.append(ext) + + +# Extension for the help module +swig_sources = run_swig(['help.i'], 'src', GENDIR, PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) +ext = Extension('helpc', swig_sources, + include_dirs = includes, + define_macros = defines, + library_dirs = libdirs, + libraries = libs, + extra_compile_args = cflags, + extra_link_args = lflags, + ) +wxpExtensions.append(ext) + + +# Extension for the wizard module +swig_sources = run_swig(['wizard.i'], 'src', GENDIR, PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) +ext = Extension('wizardc', swig_sources, + include_dirs = includes, + define_macros = defines, + library_dirs = libdirs, + libraries = libs, + extra_compile_args = cflags, + extra_link_args = lflags, + ) +wxpExtensions.append(ext) #---------------------------------------------------------------------- @@ -504,7 +648,7 @@ if not GL_ONLY: CTRB_SRC = opj(WXDIR, 'contrib/src') CTRB_INC = opj(WXDIR, 'contrib/include/wx') -if BUILD_GLCANVAS or GL_ONLY: +if BUILD_GLCANVAS: msg('Preparing GLCANVAS...') location = 'contrib/glcanvas' swig_files = ['glcanvas.i'] @@ -516,7 +660,7 @@ if BUILD_GLCANVAS or GL_ONLY: gl_libs = [] if os.name == 'posix': gl_config = os.popen(WX_CONFIG + ' --gl-libs', 'r').read()[:-1] - gl_lflags = string.split(gl_config) + lflags + gl_lflags = gl_config.split() + lflags gl_libs = libs else: other_sources = [opj(location, 'msw/myglcanvas.cpp')] @@ -543,7 +687,7 @@ if BUILD_GLCANVAS or GL_ONLY: # Define the OGL extension module #---------------------------------------------------------------------- -if not GL_ONLY and BUILD_OGL: +if BUILD_OGL: msg('Preparing OGL...') location = 'contrib/ogl' OGLLOC = opj(location, 'contrib/src/ogl') @@ -592,7 +736,7 @@ if not GL_ONLY and BUILD_OGL: # Define the STC extension module #---------------------------------------------------------------------- -if not GL_ONLY and BUILD_STC: +if BUILD_STC: msg('Preparing STC...') location = 'contrib/stc' STCLOC = opj(location, 'contrib/src/stc') @@ -608,6 +752,7 @@ if not GL_ONLY and BUILD_STC: msg('Running gen_iface.py, regenerating stc.h and stc.cpp...') cwd = os.getcwd() os.chdir(opj(CTRB_SRC, 'stc')) + sys.path.insert(0, os.curdir) import gen_iface gen_iface.main([]) os.chdir(cwd) @@ -705,7 +850,7 @@ if not GL_ONLY and BUILD_STC: # Define the IEWIN extension module (experimental) #---------------------------------------------------------------------- -if not GL_ONLY and BUILD_IEWIN: +if BUILD_IEWIN: msg('Preparing IEWIN...') location = 'contrib/iewin' @@ -736,7 +881,7 @@ if not GL_ONLY and BUILD_IEWIN: # Define the XRC extension module #---------------------------------------------------------------------- -if not GL_ONLY and BUILD_XRC: +if BUILD_XRC: msg('Preparing XRC...') location = 'contrib/xrc' XMLLOC = opj(location, 'contrib/src/xrc') @@ -786,6 +931,7 @@ if not GL_ONLY and BUILD_XRC: '%s/xh_radbt.cpp' % XMLLOC, '%s/xh_radbx.cpp' % XMLLOC, '%s/xh_scrol.cpp' % XMLLOC, + '%s/xh_scwin.cpp' % XMLLOC, '%s/xh_sizer.cpp' % XMLLOC, '%s/xh_slidr.cpp' % XMLLOC, @@ -824,7 +970,7 @@ if not GL_ONLY and BUILD_XRC: # Define the GIZMOS extension module #---------------------------------------------------------------------- -if not GL_ONLY and BUILD_GIZMOS: +if BUILD_GIZMOS: msg('Preparing GIZMOS...') location = 'contrib/gizmos' GIZMOLOC = opj(location, 'contrib/src/gizmos') @@ -870,7 +1016,7 @@ if not GL_ONLY and BUILD_GIZMOS: # Define the DLLWIDGET extension module #---------------------------------------------------------------------- -if not GL_ONLY and BUILD_DLLWIDGET: +if BUILD_DLLWIDGET: msg('Preparing DLLWIDGET...') location = 'contrib/dllwidget' swig_files = ['dllwidget_.i'] @@ -899,36 +1045,149 @@ if not GL_ONLY and BUILD_DLLWIDGET: #---------------------------------------------------------------------- -# Tools and scripts +# Define the CANVAS extension module #---------------------------------------------------------------------- -## TOOLS = [("wxPython/tools", glob.glob("tools/*.py")), -## ("wxPython/tools/XRCed", glob.glob("tools/XRCed/*.py") + -## glob.glob("tools/XRCed/*.xrc") + -## ["tools/XRCed/CHANGES", -## "tools/XRCed/TODO", -## "tools/XRCed/README"]), -## ] +if BUILD_CANVAS: + msg('Preparing CANVAS...') + location = 'contrib/canvas' + CANVASLOC = opj(location, 'contrib/src/canvas') + CANVASINC = opj(location, 'contrib/include') + swig_files = ['canvas.i'] + + swig_sources = run_swig(swig_files, location, '', PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) + + if IN_CVS_TREE: + # make sure local copy of contrib files are up to date + contrib_copy_tree(opj(CTRB_INC, 'canvas'), opj(CANVASINC, 'wx/canvas')) + contrib_copy_tree(opj(CTRB_SRC, 'canvas'), CANVASLOC) + + ext = Extension('canvasc', ['%s/bbox.cpp' % CANVASLOC, + '%s/liner.cpp' % CANVASLOC, + '%s/polygon.cpp' % CANVASLOC, + '%s/canvas.cpp' % CANVASLOC, + ] + swig_sources, + + include_dirs = [CANVASINC] + includes, + define_macros = defines, + + library_dirs = libdirs, + libraries = libs, + + extra_compile_args = cflags, + extra_link_args = lflags, + ) + + wxpExtensions.append(ext) + + +#---------------------------------------------------------------------- +# Define the ART2D extension module +#---------------------------------------------------------------------- + +if BUILD_ART2D: + msg('Preparing ART2D...') + location = 'contrib/art2d' + ART2DLOC = opj(location, 'modules/canvas/src') + ART2DINC = opj(location, 'modules/canvas/include') + EXPATLOC = opj(location, 'modules/expat') + EXPATINC = opj(location, 'modules/expat/include') + + swig_files = ['art2d.i', + 'art2d_misc.i', + 'art2d_base.i', + 'art2d_canvas.i', + ] + + swig_sources = run_swig(swig_files, location, '', PKGDIR, + USE_SWIG, swig_force, swig_args, swig_deps) + + if IN_CVS_TREE: + # Don't copy data in this case as the code snapshots are + # taken manually + pass + + ext = Extension('art2dc', [ opj(ART2DLOC, 'afmatrix.cpp'), + opj(ART2DLOC, 'bbox.cpp'), + opj(ART2DLOC, 'cancom.cpp'), + opj(ART2DLOC, 'candoc.cpp'), + opj(ART2DLOC, 'canglob.cpp'), + opj(ART2DLOC, 'canobj3d.cpp'), + opj(ART2DLOC, 'canobj.cpp'), + opj(ART2DLOC, 'canprim.cpp'), + opj(ART2DLOC, 'canprop.cpp'), + opj(ART2DLOC, 'canvas.cpp'), + opj(ART2DLOC, 'docviewref.cpp'), + opj(ART2DLOC, 'drawer.cpp'), + opj(ART2DLOC, 'eval.cpp'), + opj(ART2DLOC, 'graph.cpp'), + opj(ART2DLOC, 'layerinf.cpp'), + opj(ART2DLOC, 'liner.cpp'), + opj(ART2DLOC, 'meta.cpp'), + opj(ART2DLOC, 'objlist.cpp'), + opj(ART2DLOC, 'polygon.cpp'), + opj(ART2DLOC, 'recur.cpp'), + opj(ART2DLOC, 'rendimg.cpp'), + opj(ART2DLOC, 'tools.cpp'), + opj(ART2DLOC, 'vpath.cpp'), + opj(ART2DLOC, 'xmlpars.cpp'), + + opj(EXPATLOC, 'xmlparse/xmlparse.c'), + opj(EXPATLOC, 'xmltok/xmlrole.c'), + opj(EXPATLOC, 'xmltok/xmltok.c'), + + ] + swig_sources, + + include_dirs = [ ART2DINC, + EXPATINC, + opj(EXPATLOC, 'xmltok'), + opj(EXPATLOC, 'xmlparse'), + ] + includes, + define_macros = defines, + + library_dirs = libdirs, + libraries = libs, + + extra_compile_args = cflags, + extra_link_args = lflags, + ) + + wxpExtensions.append(ext) + + +#---------------------------------------------------------------------- +# Tools and scripts +#---------------------------------------------------------------------- if NO_SCRIPTS: SCRIPTS = None else: - SCRIPTS = [opj('scripts/img2png'), + SCRIPTS = [opj('scripts/helpviewer'), + opj('scripts/img2png'), opj('scripts/img2xpm'), opj('scripts/img2py'), opj('scripts/xrced'), opj('scripts/pyshell'), opj('scripts/pycrust'), + opj('scripts/pycwrap'), ] +DATA_FILES.append( ('wxPython/tools/XRCed', glob.glob('wxPython/tools/XRCed/*.txt') + + [ 'wxPython/tools/XRCed/xrced.xrc'])) + +DATA_FILES.append( ('wxPython/lib/PyCrust', glob.glob('wxPython/lib/PyCrust/*.txt') + + glob.glob('wxPython/lib/PyCrust/*.ico'))) + + #---------------------------------------------------------------------- # Do the Setup/Build/Install/Whatever #---------------------------------------------------------------------- if __name__ == "__main__": - if not GL_ONLY: + if not PREP_ONLY: setup(name = PKGDIR, version = VERSION, description = DESCRIPTION, @@ -940,9 +1199,11 @@ if __name__ == "__main__": packages = [PKGDIR, PKGDIR+'.lib', + PKGDIR+'.lib.colourchooser', PKGDIR+'.lib.editor', PKGDIR+'.lib.mixins', PKGDIR+'.lib.PyCrust', + PKGDIR+'.lib.PyCrust.wxd', PKGDIR+'.tools', PKGDIR+'.tools.XRCed', ], @@ -952,29 +1213,13 @@ if __name__ == "__main__": options = { 'build' : { 'build_base' : BUILD_BASE }}, - ##data_files = TOOLS, scripts = SCRIPTS, - ) - else: - - setup(name = "wxPython-gl", - version = VERSION, - description = "wxGLCanvas class for wxPython", - author = AUTHOR, - author_email = AUTHOR_EMAIL, - url = URL, - license = LICENSE, - - py_modules = [ "wxPython.glcanvas" ], - - ext_package = PKGDIR, - ext_modules = wxpExtensions, + cmdclass = { 'install_data': smart_install_data}, + data_files = DATA_FILES, ) - - #---------------------------------------------------------------------- #---------------------------------------------------------------------- diff --git a/wxPython/src/__version__.py b/wxPython/src/__version__.py index b846f0cf7f..ccace370f1 100644 --- a/wxPython/src/__version__.py +++ b/wxPython/src/__version__.py @@ -1 +1 @@ -ver = '2.3.3pre8' +ver = '2.5.0p1' diff --git a/wxPython/src/_calextras.py b/wxPython/src/_calextras.py index f2f8bde23c..1b8ba8cb2f 100644 --- a/wxPython/src/_calextras.py +++ b/wxPython/src/_calextras.py @@ -2,3 +2,4 @@ # Stuff these names into the wx namespace so wxPyConstructObject can find them wx.wxCalendarEventPtr = wxCalendarEventPtr +wx.wxCalendarCtrlPtr = wxCalendarCtrlPtr diff --git a/wxPython/src/_defs.i b/wxPython/src/_defs.i index 553b379839..7e07e02954 100644 --- a/wxPython/src/_defs.i +++ b/wxPython/src/_defs.i @@ -298,6 +298,7 @@ enum { wxRA_SPECIFY_ROWS, wxRA_SPECIFY_COLS, wxRB_GROUP, + wxRB_SINGLE, wxGA_PROGRESSBAR, wxGA_HORIZONTAL, wxGA_VERTICAL, @@ -532,6 +533,17 @@ enum { wxMOUSE_BTN_MIDDLE, wxMOUSE_BTN_RIGHT, + // It looks like wxTabCtrl may rise from the dead. Uncomment these if + // it gets an implementation for all platforms... +// wxTC_RIGHTJUSTIFY, +// wxTC_FIXEDWIDTH, +// wxTC_TOP, +// wxTC_LEFT, +// wxTC_RIGHT, +// wxTC_BOTTOM, +// wxTC_MULTILINE, +// wxTC_OWNERDRAW, + }; @@ -921,12 +933,6 @@ enum wxHitTest -#define FALSE 0 -#define false 0 -#define TRUE 1 -#define true 1 - - //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- diff --git a/wxPython/src/_extras.py b/wxPython/src/_extras.py index 0e72a395d9..be34766f07 100644 --- a/wxPython/src/_extras.py +++ b/wxPython/src/_extras.py @@ -1,6 +1,6 @@ #---------------------------------------------------------------------------- # Name: _extra.py -# Purpose: This file is appended to the shadow class file generated +# Purpose: This file is appended to the shadow class file generated # by SWIG. We add some unSWIGable things here. # # Author: Robin Dunn @@ -131,6 +131,12 @@ def EVT_WINDOW_CREATE(win, func): def EVT_WINDOW_DESTROY(win, func): win.Connect(-1, -1, wxEVT_DESTROY, func) +def EVT_WINDOW_CREATE_ID(win, id, func): + win.Connect(id, -1, wxEVT_CREATE, func) + +def EVT_WINDOW_DESTROY_ID(win, id, func): + win.Connect(id, -1, wxEVT_DESTROY, func) + def EVT_SET_CURSOR(win, func): win.Connect(-1, -1, wxEVT_SET_CURSOR, func) @@ -263,7 +269,7 @@ def EVT_COMMAND_SCROLL(win, id, func): win.Connect(id, -1, wxEVT_SCROLL_PAGEDOWN, func) win.Connect(id, -1, wxEVT_SCROLL_THUMBTRACK,func) win.Connect(id, -1, wxEVT_SCROLL_THUMBRELEASE,func) - win.Connect(-1, -1, wxEVT_SCROLL_ENDSCROLL, func) + win.Connect(id, -1, wxEVT_SCROLL_ENDSCROLL, func) def EVT_COMMAND_SCROLL_TOP(win, id, func): win.Connect(id, -1, wxEVT_SCROLL_TOP, func) @@ -587,17 +593,50 @@ wxColor = wxColour wxNamedColor = wxNamedColour wxPen = wxPyPen wxScrollbar = wxScrollBar +wxPoint2D = wxPoint2DDouble + +wxPyAssertionError = wxc.wxPyAssertionError # backwards compatibility -wxNoRefBitmap = wxBitmap -wxPyDefaultPosition = wxDefaultPosition -wxPyDefaultSize = wxDefaultSize -NULL = None +wxNoRefBitmap = wxBitmap +wxPyDefaultPosition = wxDefaultPosition +wxPyDefaultSize = wxDefaultSize +NULL = None wxSystemSettings_GetSystemColour = wxSystemSettings_GetColour wxSystemSettings_GetSystemFont = wxSystemSettings_GetFont wxSystemSettings_GetSystemMetric = wxSystemSettings_GetMetric + +# workarounds for bad wxRTTI names +__wxPyPtrTypeMap['wxGauge95'] = 'wxGauge' + + + +def NewId(): + import warnings + warnings.warn("Use wxNewId instead", DeprecationWarning, 2) + return wxNewId() + +def RegisterId(ID): + import warnings + warnings.warn("Use wxRegisterId instead", DeprecationWarning, 2) + return wxRegisterId(ID) + + + +# Use Python's bool constants if available, make aliases if not +try: + True +except NameError: + True = 1==1 + False = 1==0 + +# Backwards compaatible +TRUE = true = True +FALSE = false = False + + #---------------------------------------------------------------------- # wxGTK sets the locale when initialized. Doing this at the Python # level should set it up to match what GTK is doing at the C level. @@ -608,7 +647,11 @@ if wxPlatform == "__WXGTK__": except: pass - +if wxPlatform == "__WXMSW__": + import os + localedir = os.path.join(os.path.split(__file__)[0], "locale") + wxLocale_AddCatalogLookupPathPrefix(localedir) + del os #---------------------------------------------------------------------- # wxWindows version numbers. wxPython version is in __version__. @@ -660,6 +703,18 @@ def wxPyTypeCast(obj, typeStr): theObj.thisown = obj.thisown return theObj +#---------------------------------------------------------------------------- +# An isinstance for Pythons < 2.2 that can check a sequence of class objects +# like the one in 2.2 can. + +def wxPy_isinstance(obj, klasses): + import types + if sys.version[:3] < "2.2" and type(klasses) in [types.TupleType, types.ListType]: + for klass in klasses: + if isinstance(obj, klass): return True + return False + else: + return isinstance(obj, klasses) #---------------------------------------------------------------------------- _wxCallAfterId = None @@ -685,6 +740,9 @@ def wxCallAfter(callable, *args, **kw): evt.kw = kw wxPostEvent(app, evt) +# an alias +wxRunLater = wxCallAfter + #---------------------------------------------------------------------- class wxPyDeadObjectError(AttributeError): @@ -744,7 +802,7 @@ class wxPyOnDemandOutputWindow: self.text = wxTextCtrl(self.frame, -1, "", style = wxTE_MULTILINE|wxTE_READONLY) self.frame.SetSize(wxSize(450, 300)) - self.frame.Show(true) + self.frame.Show(True) EVT_CLOSE(self.frame, self.OnCloseWindow) self.text.AppendText(str) @@ -765,12 +823,17 @@ class wxApp(wxPyApp): error = 'wxApp.error' outputWindowClass = wxPyOnDemandOutputWindow - def __init__(self, redirect=_defRedirect, filename=None): + def __init__(self, redirect=_defRedirect, filename=None, useBestVisual=False): wxPyApp.__init__(self) self.stdioWin = None self.saveStdio = (sys.stdout, sys.stderr) + + # This has to be done before OnInit + self.SetUseBestVisual(useBestVisual) + if redirect: self.RedirectStdio(filename) + # this initializes wxWindows and then calls our OnInit _wxStart(self.OnInit) @@ -797,7 +860,7 @@ class wxApp(wxPyApp): if filename: sys.stdout = sys.stderr = open(filename, 'a') else: - self.stdioWin = self.outputWindowClass() # wxPyOnDemandOutputWindow + self.stdioWin = self.outputWindowClass() sys.stdout = sys.stderr = self.stdioWin @@ -805,6 +868,21 @@ class wxApp(wxPyApp): sys.stdout, sys.stderr = self.saveStdio +# change from wxPyApp_ to wxApp_ +wxApp_GetMacDefaultEncodingIsPC = wxc.wxPyApp_GetMacDefaultEncodingIsPC +wxApp_GetMacSupportPCMenuShortcuts = wxc.wxPyApp_GetMacSupportPCMenuShortcuts +wxApp_GetMacAboutMenuItemId = wxc.wxPyApp_GetMacAboutMenuItemId +wxApp_GetMacPreferencesMenuItemId = wxc.wxPyApp_GetMacPreferencesMenuItemId +wxApp_GetMacExitMenuItemId = wxc.wxPyApp_GetMacExitMenuItemId +wxApp_GetMacHelpMenuTitleName = wxc.wxPyApp_GetMacHelpMenuTitleName +wxApp_SetMacDefaultEncodingIsPC = wxc.wxPyApp_SetMacDefaultEncodingIsPC +wxApp_SetMacSupportPCMenuShortcuts = wxc.wxPyApp_SetMacSupportPCMenuShortcuts +wxApp_SetMacAboutMenuItemId = wxc.wxPyApp_SetMacAboutMenuItemId +wxApp_SetMacPreferencesMenuItemId = wxc.wxPyApp_SetMacPreferencesMenuItemId +wxApp_SetMacExitMenuItemId = wxc.wxPyApp_SetMacExitMenuItemId +wxApp_SetMacHelpMenuTitleName = wxc.wxPyApp_SetMacHelpMenuTitleName + + #---------------------------------------------------------------------------- class wxPySimpleApp(wxApp): @@ -812,7 +890,7 @@ class wxPySimpleApp(wxApp): wxApp.__init__(self, flag) def OnInit(self): wxInitAllImageHandlers() - return true + return True class wxPyWidgetTester(wxApp): @@ -823,11 +901,11 @@ class wxPyWidgetTester(wxApp): def OnInit(self): self.frame = wxFrame(None, -1, "Widget Tester", pos=(0,0), size=self.size) self.SetTopWindow(self.frame) - return true + return True def SetWidget(self, widgetClass, *args): w = apply(widgetClass, (self.frame,) + args) - self.frame.Show(true) + self.frame.Show(True) #---------------------------------------------------------------------------- # DO NOT hold any other references to this object. This is how we diff --git a/wxPython/src/_helpextras.py b/wxPython/src/_helpextras.py index c933721561..ea0abe70e4 100644 --- a/wxPython/src/_helpextras.py +++ b/wxPython/src/_helpextras.py @@ -1,3 +1,4 @@ # Stuff these names into the wx namespace so wxPyConstructObject can find them import wx wx.wxHelpEventPtr = wxHelpEventPtr +wx.wxContextHelpButtonPtr = wxContextHelpButtonPtr diff --git a/wxPython/src/_htmlextras.py b/wxPython/src/_htmlextras.py index 88f8b12ba6..c538da3162 100644 --- a/wxPython/src/_htmlextras.py +++ b/wxPython/src/_htmlextras.py @@ -11,4 +11,5 @@ wx.wxHtmlContainerCellPtr = wxHtmlContainerCellPtr wx.wxHtmlWidgetCellPtr = wxHtmlWidgetCellPtr wx.wxHtmlWindowPtr = wxHtmlWindowPtr wx.wxHtmlLinkInfoPtr = wxHtmlLinkInfoPtr +wx.wxHtmlFilterPtr = wxHtmlFilterPtr diff --git a/wxPython/src/_wizardextras.py b/wxPython/src/_wizardextras.py index 4cd30aff7f..c46be8f422 100644 --- a/wxPython/src/_wizardextras.py +++ b/wxPython/src/_wizardextras.py @@ -1,3 +1,7 @@ # Stuff these names into the wx namespace so wxPyConstructObject can find them import wx wx.wxWizardEventPtr = wxWizardEventPtr +wx.wxWizardPagePtr = wxWizardPagePtr +wx.wxPyWizardPagePtr = wxPyWizardPagePtr +wx.wxWizardPageSimplePtr = wxWizardPageSimplePtr +wx.wxWizardPtr = wxWizardPtr diff --git a/wxPython/src/clip_dnd.i b/wxPython/src/clip_dnd.i index d1be82ee3e..e5547215f4 100644 --- a/wxPython/src/clip_dnd.i +++ b/wxPython/src/clip_dnd.i @@ -111,10 +111,13 @@ public: wxDataFormat GetPreferredFormat(Direction dir = wxDataObject::Get); size_t GetFormatCount(Direction dir = wxDataObject::Get); + + // TODO: Fix these two to be usable from wxPython. void GetAllFormats(wxDataFormat *formats, Direction dir = wxDataObject::Get); - size_t GetDataSize(const wxDataFormat& format); bool GetDataHere(const wxDataFormat& format, void *buf); + + size_t GetDataSize(const wxDataFormat& format); bool SetData(const wxDataFormat& format, size_t len, const void * buf); bool IsSupportedFormat(const wxDataFormat& format); @@ -288,7 +291,7 @@ wxBitmap wxPyBitmapDataObject::GetBitmap() { void wxPyBitmapDataObject::SetBitmap(const wxBitmap& bitmap) { wxPyBeginBlockThreads(); if (m_myInst.findCallback("SetBitmap")) { - PyObject* bo = wxPyConstructObject((void*)&bitmap, "wxBitmap"); + PyObject* bo = wxPyConstructObject((void*)&bitmap, wxT("wxBitmap")); m_myInst.callCallback(Py_BuildValue("(O)", bo)); Py_DECREF(bo); } @@ -452,15 +455,17 @@ bool wxIsDragResultOk(wxDragResult res); class wxPyDropSource : public wxDropSource { public: #ifdef __WXMSW__ - wxPyDropSource(wxWindow *win = NULL, - const wxCursor &cursorCopy = wxNullCursor, - const wxCursor &cursorMove = wxNullCursor, - const wxCursor &cursorStop = wxNullCursor) - : wxDropSource(win, cursorCopy, cursorMove, cursorStop) {} + wxPyDropSource(wxWindow *win = NULL, + const wxCursor © = wxNullCursor, + const wxCursor &move = wxNullCursor, + const wxCursor &none = wxNullCursor) + : wxDropSource(win, copy, move, none) {} #else wxPyDropSource(wxWindow *win = NULL, - const wxIcon &go = wxNullIcon) - : wxDropSource(win, go) {} + const wxIcon& copy = wxNullIcon, + const wxIcon& move = wxNullIcon, + const wxIcon& none = wxNullIcon) + : wxDropSource(win, copy, move, none) {} #endif ~wxPyDropSource() { } @@ -476,13 +481,15 @@ IMP_PYCALLBACK_BOOL_DR(wxPyDropSource, wxDropSource, GiveFeedback); %name(wxDropSource) class wxPyDropSource { public: #ifdef __WXMSW__ - wxPyDropSource(wxWindow *win = NULL, - const wxCursor &cursorCopy = wxNullCursor, - const wxCursor &cursorMove = wxNullCursor, - const wxCursor &cursorStop = wxNullCursor); + wxPyDropSource(wxWindow *win = NULL, + const wxCursor © = wxNullCursor, + const wxCursor &move = wxNullCursor, + const wxCursor &none = wxNullCursor); #else wxPyDropSource(wxWindow *win = NULL, - const wxIcon &go = wxNullIcon); + const wxIcon& copy = wxNullIcon, + const wxIcon& move = wxNullIcon, + const wxIcon& none = wxNullIcon); #endif void _setCallbackInfo(PyObject* self, PyObject* _class, int incref); diff --git a/wxPython/src/controls.i b/wxPython/src/controls.i index 96ca6cb7b4..c3f57ddb65 100644 --- a/wxPython/src/controls.i +++ b/wxPython/src/controls.i @@ -338,6 +338,7 @@ public: %pragma(python) addtomethod = "wxPreCheckBox:val._setOORInfo(val)" bool GetValue(); + bool IsChecked(); void SetValue(const bool state); }; @@ -1003,18 +1004,15 @@ public: int FindString(const wxString& string); wxString GetString(int n); - -#ifdef __WXGTK__ - %name(GetItemLabel)wxString GetLabel( int item ); - %name(SetItemLabel)void SetLabel( int item, const wxString& label ); -#else void SetString(int n, const wxString& label); %pragma(python) addtoclass = " GetItemLabel = GetString SetItemLabel = SetString " +#ifndef __WXGTK__ int GetColumnCount(); int GetRowCount(); + int GetNextItem(int item, wxDirection dir, long style); #endif int GetSelection(); diff --git a/wxPython/src/controls2.i b/wxPython/src/controls2.i index 194a5ddb68..323166e3a8 100644 --- a/wxPython/src/controls2.i +++ b/wxPython/src/controls2.i @@ -498,7 +498,6 @@ public: return val " - // Sets information about the item bool SetItem(wxListItem& info) ; @@ -560,6 +559,10 @@ public: // view, otherwise the large icon view. int GetItemSpacing(bool isSmall) const; +#ifndef __WXMSW__ + void SetItemSpacing( int spacing, bool isSmall = FALSE ); +#endif + // Gets the number of selected items in the list control int GetSelectedItemCount() const; @@ -624,6 +627,8 @@ public: // End label editing, optionally cancelling the edit bool EndEditLabel(bool cancel); +#else + void EditLabel(long item); #endif // Ensures this item is visible @@ -700,6 +705,14 @@ public: '''get the currently focused item or -1 if none''' return self.GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED) + def GetFirstSelected(self, *args): + '''return first selected item, or -1 when none''' + return self.GetNextSelected(-1) + + def GetNextSelected(self, item): + '''return subsequent selected items, or -1 when no more''' + return self.GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED) + def IsSelected(self, idx): '''return TRUE if the item is selected''' return self.GetItemState(idx, wxLIST_STATE_SELECTED) != 0 @@ -717,10 +730,14 @@ public: '''Append an item to the list control. The entry parameter should be a sequence with an item for each column''' if len(entry): + if wx.wxUSE_UNICODE: + cvtfunc = unicode + else: + cvtfunc = str pos = self.GetItemCount() - self.InsertStringItem(pos, str(entry[0])) + self.InsertStringItem(pos, cvtfunc(entry[0])) for i in range(1, len(entry)): - self.SetStringItem(pos, i, str(entry[i])) + self.SetStringItem(pos, i, cvtfunc(entry[i])) return pos " @@ -1091,8 +1108,8 @@ public: bool found; wxPyBeginBlockThreads(); if ((found = m_myInst.findCallback("OnCompareItems"))) { - PyObject *o1 = wxPyConstructObject((void*)&item1, "wxTreeItemId"); - PyObject *o2 = wxPyConstructObject((void*)&item2, "wxTreeItemId"); + PyObject *o1 = wxPyConstructObject((void*)&item1, wxT("wxTreeItemId")); + PyObject *o2 = wxPyConstructObject((void*)&item2, wxT("wxTreeItemId")); rval = m_myInst.callCallback(Py_BuildValue("(OO)",o1,o2)); Py_DECREF(o1); Py_DECREF(o2); @@ -1205,6 +1222,16 @@ public: } + // get the item's text colour + wxColour GetItemTextColour(const wxTreeItemId& item) const; + + // get the item's background colour + wxColour GetItemBackgroundColour(const wxTreeItemId& item) const; + + // get the item's font + wxFont GetItemFont(const wxTreeItemId& item) const; + + bool IsVisible(const wxTreeItemId& item); bool ItemHasChildren(const wxTreeItemId& item); bool IsExpanded(const wxTreeItemId& item); @@ -1212,7 +1239,7 @@ public: wxTreeItemId GetRootItem(); wxTreeItemId GetSelection(); - %name(GetItemParent) wxTreeItemId GetParent(const wxTreeItemId& item); + wxTreeItemId GetItemParent(const wxTreeItemId& item); //size_t GetSelections(wxArrayTreeItemIds& selection); %addmethods { PyObject* GetSelections() { @@ -1223,7 +1250,7 @@ public: num = self->GetSelections(array); for (x=0; x < num; x++) { wxTreeItemId *tii = new wxTreeItemId(array.Item(x)); - PyObject* item = wxPyConstructObject((void*)tii, "wxTreeItemId", TRUE); + PyObject* item = wxPyConstructObject((void*)tii, wxT("wxTreeItemId"), TRUE); PyList_Append(rval, item); } wxPyEndBlockThreads(); @@ -1283,12 +1310,11 @@ public: void SelectItem(const wxTreeItemId& item); void EnsureVisible(const wxTreeItemId& item); void ScrollTo(const wxTreeItemId& item); -#ifdef __WXMSW__ - wxTextCtrl* EditLabel(const wxTreeItemId& item); + wxTextCtrl* GetEditControl(); - void EndEditLabel(const wxTreeItemId& item, int discardChanges = FALSE); -#else void EditLabel(const wxTreeItemId& item); +#ifdef __WXMSW__ + void EndEditLabel(const wxTreeItemId& item, int discardChanges = FALSE); #endif void SortChildren(const wxTreeItemId& item); @@ -1314,7 +1340,7 @@ public: if (self->GetBoundingRect(item, rect, textOnly)) { wxPyBeginBlockThreads(); wxRect* r = new wxRect(rect); - PyObject* val = wxPyConstructObject((void*)r, "wxRect"); + PyObject* val = wxPyConstructObject((void*)r, wxT("wxRect")); wxPyEndBlockThreads(); return val; } diff --git a/wxPython/src/drawlist.cpp b/wxPython/src/drawlist.cpp new file mode 100644 index 0000000000..cba7952b24 --- /dev/null +++ b/wxPython/src/drawlist.cpp @@ -0,0 +1,350 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: drawlist.cpp +// Purpose: Helper functions for optimized list drawing on a wxDC +// +// Author: Robin Dunn Chris Barker +// +// Created: +// RCS-ID: $Id$ +// Copyright: (c) 2003 by Total Control Software +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + + +#undef DEBUG +#include +#include "helpers.h" + + +//---------------------------------------------------------------------- + + + +PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw, + PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) { + + wxPyBeginBlockThreads(); // _DrawXXXList + + bool isFastSeq = PyList_Check(pyCoords) || PyTuple_Check(pyCoords); + bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens); + bool isFastBrushes = PyList_Check(pyBrushes) || PyTuple_Check(pyBrushes); + int numObjs = 0; + int numPens = 0; + int numBrushes = 0; + wxPen* pen; + wxBrush* brush; + PyObject* obj; + PyObject* coords; + int x1, x2, x3, x4; + int i = 0; + PyObject* retval; + + if (!PySequence_Check(pyCoords)) { + goto err0; + } + if (!PySequence_Check(pyPens)) { + goto err1; + } + if (!PySequence_Check(pyBrushes)) { + goto err2; + } + numObjs = PySequence_Length(pyCoords); + numPens = PySequence_Length(pyPens); + numBrushes = PySequence_Length(pyBrushes); + for (i = 0; i < numObjs; i++) { + // Use a new pen? + if (i < numPens) { + if (isFastPens) { + obj = PySequence_Fast_GET_ITEM(pyPens, i); + } + else { + obj = PySequence_GetItem(pyPens, i); + } + if (SWIG_GetPtrObj(obj, (void **) &pen, "_wxPen_p")) { + if (!isFastPens) + Py_DECREF(obj); + goto err1; + } + + dc.SetPen(*pen); + if (!isFastPens) + Py_DECREF(obj); + } + // Use a new brush? + if (i < numBrushes) { + if (isFastBrushes) { + obj = PySequence_Fast_GET_ITEM(pyBrushes, i); + } + else { + obj = PySequence_GetItem(pyBrushes, i); + } + if (SWIG_GetPtrObj(obj, (void **) &brush, "_wxBrush_p")) { + if (!isFastBrushes) + Py_DECREF(obj); + goto err2; + } + + dc.SetBrush(*brush); + if (!isFastBrushes) + Py_DECREF(obj); + } + + // Get the Coordinates + if (isFastSeq) { + coords = PySequence_Fast_GET_ITEM(pyCoords, i); + } + else { + coords = PySequence_GetItem(pyCoords, i); + } + + + // call the drawOp + bool success = doDraw(dc, coords); + if (!isFastSeq) + Py_DECREF(coords); + + if (! success) { + retval = NULL; + goto exit; + } + + } // end of main for loop + + Py_INCREF(Py_None); + retval = Py_None; + goto exit; + + + err0: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of coordinates"); + retval = NULL; + goto exit; + + err1: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens"); + retval = NULL; + goto exit; + + err2: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxBrushes"); + retval = NULL; + goto exit; + + + exit: + wxPyEndBlockThreads(); + return retval; +} + + + +bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords) { + int x, y; + + if (! wxPy2int_seq_helper(coords, &x, &y)) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); + return FALSE; + } + dc.DrawPoint(x, y); + return TRUE; +} + +bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords) { + int x1, y1, x2, y2; + + if (! wxPy4int_seq_helper(coords, &x1, &y1, &x2, &y2)) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x1,y1, x1,y2) sequences."); + return FALSE; + } + dc.DrawLine(x1,y1, x2,y2); + return TRUE; +} + +bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords) { + int x, y, w, h; + + if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences."); + return FALSE; + } + dc.DrawRectangle(x, y, w, h); + return TRUE; +} + +bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords) { + int x, y, w, h; + + if (! wxPy4int_seq_helper(coords, &x, &y, &w, &h)) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y, w,h) sequences."); + return FALSE; + } + dc.DrawEllipse(x, y, w, h); + return TRUE; +} + + +bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords) { + wxPoint* points; + int numPoints; + + points = wxPoint_LIST_helper(coords, &numPoints); + if (! points) { + PyErr_SetString(PyExc_TypeError, "Expected a sequence of sequences of (x,y) sequences."); + return FALSE; + } + dc.DrawPolygon(numPoints, points); + return TRUE; +} + + +//---------------------------------------------------------------------- + + + +PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList) { + wxPyBeginBlockThreads(); + + bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints); + bool isFastText = PyList_Check(textList) || PyTuple_Check(textList); + bool isFastForeground = PyList_Check(foregroundList) || PyTuple_Check(foregroundList); + bool isFastBackground = PyList_Check(backgroundList) || PyTuple_Check(backgroundList); + int numText = 0; + int numPoints = 0; + int numForeground = 0; + int numBackground = 0; + PyObject* obj; + int x1, y1; + int i = 0; + wxColor* color; + PyObject* retval; + wxString string; + + if (!PySequence_Check(pyPoints)) { + goto err0; + } + if (!PySequence_Check(textList)) { + goto err1; + } + if (!PySequence_Check(foregroundList)) { + goto err2; + } + if (!PySequence_Check(backgroundList)) { + goto err3; + } + numPoints = PySequence_Length(pyPoints); + numText = PySequence_Length(textList); + numForeground = PySequence_Length(foregroundList); + numBackground = PySequence_Length(backgroundList); + + for (i = 0; i < numPoints; i++) { + // Use a new string ? + if (i < numText) { + if ( isFastText ) { + obj = PySequence_Fast_GET_ITEM(textList, i); + } + else { + obj = PySequence_GetItem(textList, i); + } + if (! PyString_Check(obj) ) { + Py_DECREF(obj); + goto err1; + } + string = Py2wxString(obj); + if ( !isFastText ) + Py_DECREF(obj); + } + + if (i < numForeground) { + // Use a new foreground ? + if ( isFastForeground ) { + obj = PySequence_Fast_GET_ITEM(foregroundList, i); + } + else { + obj = PySequence_GetItem(foregroundList, i); + } + if (SWIG_GetPtrObj(obj, (void **) &color, "_wxColour_p")) { + if (!isFastForeground) + Py_DECREF(obj); + goto err2; + } + dc.SetTextForeground(*color); + if ( !isFastForeground ) + Py_DECREF(obj); + } + + if (i < numBackground) { + // Use a new background ? + if ( isFastBackground ) { + obj = PySequence_Fast_GET_ITEM(backgroundList, i); + } + else { + obj = PySequence_GetItem(backgroundList, i); + } + if (SWIG_GetPtrObj(obj, (void **) &color, "_wxColour_p")) { + if (!isFastBackground) + Py_DECREF(obj); + goto err3; + } + dc.SetTextBackground(*color); + if ( !isFastBackground ) + Py_DECREF(obj); + } + + // Get the point coordinates + if (isFastSeq) { + obj = PySequence_Fast_GET_ITEM(pyPoints, i); + } + else { + obj = PySequence_GetItem(pyPoints, i); + } + if (! wxPy2int_seq_helper(obj, &x1, &y1)) { + if (! isFastSeq) + Py_DECREF(obj); + goto err0; + } + if (PyErr_Occurred()) { + retval = NULL; + if (!isFastSeq) + Py_DECREF(obj); + goto exit; + } + + + // Now draw the text + dc.DrawText(string, x1, y1); + + if (!isFastText) + Py_DECREF(obj); + } + + Py_INCREF(Py_None); + retval = Py_None; + goto exit; + + err0: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); + retval = NULL; + goto exit; + err1: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of strings"); + retval = NULL; + goto exit; + + err2: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for foregrounds"); + retval = NULL; + goto exit; + + err3: + PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxColours for backgrounds"); + retval = NULL; + goto exit; + + exit: + wxPyEndBlockThreads(); + return retval; +} + + + +//---------------------------------------------------------------------- diff --git a/wxPython/src/events.i b/wxPython/src/events.i index 5983169335..aba54b3e45 100644 --- a/wxPython/src/events.i +++ b/wxPython/src/events.i @@ -225,9 +225,9 @@ public: bool MetaDown(); bool AltDown(); bool ShiftDown(); - long KeyCode(); long GetKeyCode(); + %pragma(python) addtoclass = "KeyCode = GetKeyCode" bool HasModifiers(); // get the raw key code (platform-dependent) @@ -407,7 +407,7 @@ public: for (int i=0; iRed())); - PyTuple_SetItem(rv, 1, PyInt_FromLong(self->Green())); - PyTuple_SetItem(rv, 2, PyInt_FromLong(self->Blue())); + int red = -1; + int green = -1; + int blue = -1; + if (self->Ok()) { + red = self->Red(); + green = self->Green(); + blue = self->Blue(); + } + PyTuple_SetItem(rv, 0, PyInt_FromLong(red)); + PyTuple_SetItem(rv, 1, PyInt_FromLong(green)); + PyTuple_SetItem(rv, 2, PyInt_FromLong(blue)); return rv; } + bool __eq__(PyObject* obj) { + wxColour tmp; + wxColour* ptr = &tmp; + if (obj == Py_None) return FALSE; + wxPyBLOCK_THREADS(bool success = wxColour_helper(obj, &ptr); PyErr_Clear()); + if (! success) return FALSE; + return *self == *ptr; + } + bool __ne__(PyObject* obj) { + wxColour tmp; + wxColour* ptr = &tmp; + if (obj == Py_None) return TRUE; + wxPyBLOCK_THREADS(bool success = wxColour_helper(obj, &ptr); PyErr_Clear()); + if (! success) return TRUE; + return *self != *ptr; + } } - %pragma(python) addtoclass = "asTuple = Get" - %pragma(python) addtoclass = "def __str__(self): return str(self.asTuple())" - %pragma(python) addtoclass = "def __repr__(self): return str(self.asTuple())" + + %pragma(python) addtoclass = "asTuple = Get + def __str__(self): return str(self.asTuple()) + def __repr__(self): return 'wxColour:' + str(self.asTuple()) + def __nonzero__(self): return self.Ok() + def __getinitargs__(self): return () + def __getstate__(self): return self.asTuple() + def __setstate__(self, state): self.Set(*state) +" }; @@ -388,15 +419,15 @@ public: if ( !cName2.Replace(wxT("GRAY"), wxT("GREY")) ) cName2.clear(); - wxNode *node = self->First(); + wxNode *node = self->GetFirst(); while ( node ) { const wxChar *key = node->GetKeyString(); if ( cName == key || cName2 == key ) { - wxColour* c = (wxColour *)node->Data(); + wxColour* c = (wxColour *)node->GetData(); c->Set(red, green, blue); return; } - node = node->Next(); + node = node->GetNext(); } // otherwise append the new colour @@ -535,34 +566,34 @@ public: //---------------------------------------------------------------------- - class wxDC : public wxObject { public: // wxDC(); **** abstract base class, can't instantiate. ~wxDC(); void BeginDrawing(); + // %name(BlitXY) - bool Blit(long xdest, long ydest, - long width, long height, - wxDC *source, long xsrc, long ysrc, + bool Blit(wxCoord xdest, wxCoord ydest, + wxCoord width, wxCoord height, + wxDC *source, wxCoord xsrc, wxCoord ysrc, int logicalFunc = wxCOPY, int useMask = FALSE); // bool Blit(const wxPoint& destPt, const wxSize& sz, // wxDC *source, const wxPoint& srcPt, // int logicalFunc = wxCOPY, int useMask = FALSE); void Clear(); - void CrossHair(long x, long y); + void CrossHair(wxCoord x, wxCoord y); void DestroyClippingRegion(); - long DeviceToLogicalX(long x); - long DeviceToLogicalXRel(long x); - long DeviceToLogicalY(long y); - long DeviceToLogicalYRel(long y); - void DrawArc(long x1, long y1, long x2, long y2, long xc, long yc); - void DrawCircle(long x, long y, long radius); - void DrawEllipse(long x, long y, long width, long height); - void DrawEllipticArc(long x, long y, long width, long height, long start, long end); - void DrawIcon(const wxIcon& icon, long x, long y); + wxCoord DeviceToLogicalX(wxCoord x); + wxCoord DeviceToLogicalXRel(wxCoord x); + wxCoord DeviceToLogicalY(wxCoord y); + wxCoord DeviceToLogicalYRel(wxCoord y); + void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc); + void DrawCircle(wxCoord x, wxCoord y, wxCoord radius); + void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height); + void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord width, wxCoord height, wxCoord start, wxCoord end); + void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y); void DrawLabel(const wxString& text, const wxRect& rect, int alignment = wxALIGN_LEFT | wxALIGN_TOP, @@ -580,27 +611,27 @@ public: } } - void DrawLine(long x1, long y1, long x2, long y2); - void DrawLines(int PCOUNT, wxPoint* points, long xoffset=0, long yoffset=0); - void DrawPolygon(int PCOUNT, wxPoint* points, long xoffset=0, long yoffset=0, + void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2); + void DrawLines(int PCOUNT, wxPoint* points, wxCoord xoffset=0, wxCoord yoffset=0); + void DrawPolygon(int PCOUNT, wxPoint* points, wxCoord xoffset=0, wxCoord yoffset=0, int fill_style=wxODDEVEN_RULE); - void DrawPoint(long x, long y); - void DrawRectangle(long x, long y, long width, long height); + void DrawPoint(wxCoord x, wxCoord y); + void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height); %name(DrawRectangleRect)void DrawRectangle(const wxRect& rect); void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle); - void DrawRoundedRectangle(long x, long y, long width, long height, long radius=20); + void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, wxCoord radius=20); void DrawSpline(int PCOUNT, wxPoint* points); - void DrawText(const wxString& text, long x, long y); + void DrawText(const wxString& text, wxCoord x, wxCoord y); void EndDoc(); void EndDrawing(); void EndPage(); - bool FloodFill(long x, long y, const wxColour& colour, int style=wxFLOOD_SURFACE); + bool FloodFill(wxCoord x, wxCoord y, const wxColour& colour, int style=wxFLOOD_SURFACE); wxBrush GetBackground(); wxBrush GetBrush(); - long GetCharHeight(); - long GetCharWidth(); - void GetClippingBox(long *OUTPUT, long *OUTPUT, - long *OUTPUT, long *OUTPUT); + wxCoord GetCharHeight(); + wxCoord GetCharWidth(); + void GetClippingBox(wxCoord *OUTPUT, wxCoord *OUTPUT, + wxCoord *OUTPUT, wxCoord *OUTPUT); wxFont GetFont(); int GetLogicalFunction(); void GetLogicalScale(double *OUTPUT, double *OUTPUT); @@ -608,7 +639,7 @@ public: bool GetOptimization(); wxPen GetPen(); %addmethods { - %new wxColour* GetPixel(long x, long y) { + %new wxColour* GetPixel(wxCoord x, wxCoord y) { wxColour* wc = new wxColour(); self->GetPixel(x, y, wc); return wc; @@ -618,25 +649,27 @@ public: wxSize GetSize(); wxSize GetSizeMM(); wxColour GetTextBackground(); - void GetTextExtent(const wxString& string, long *OUTPUT, long *OUTPUT); + void GetTextExtent(const wxString& string, wxCoord *OUTPUT, wxCoord *OUTPUT); %name(GetFullTextExtent)void GetTextExtent(const wxString& string, - long *OUTPUT, long *OUTPUT, long *OUTPUT, long* OUTPUT, + wxCoord *OUTPUT, wxCoord *OUTPUT, wxCoord *OUTPUT, wxCoord* OUTPUT, const wxFont* font = NULL); + void GetMultiLineTextExtent(const wxString& text, wxCoord *OUTPUT, wxCoord *OUTPUT, wxCoord *OUTPUT, + wxFont *font = NULL); wxColour GetTextForeground(); void GetUserScale(double *OUTPUT, double *OUTPUT); - long LogicalToDeviceX(long x); - long LogicalToDeviceXRel(long x); - long LogicalToDeviceY(long y); - long LogicalToDeviceYRel(long y); - long MaxX(); - long MaxY(); - long MinX(); - long MinY(); + wxCoord LogicalToDeviceX(wxCoord x); + wxCoord LogicalToDeviceXRel(wxCoord x); + wxCoord LogicalToDeviceY(wxCoord y); + wxCoord LogicalToDeviceYRel(wxCoord y); + wxCoord MaxX(); + wxCoord MaxY(); + wxCoord MinX(); + wxCoord MinY(); bool Ok(); - void SetDeviceOrigin(long x, long y); + void SetDeviceOrigin(wxCoord x, wxCoord y); void SetBackground(const wxBrush& brush); void SetBackgroundMode(int mode); - void SetClippingRegion(long x, long y, long width, long height); + void SetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height); %name(SetClippingRegionAsRegion) void SetClippingRegion(const wxRegion& region); %name(SetClippingRect) void SetClippingRegion(const wxRect& rect); void SetPalette(const wxPalette& colourMap); @@ -655,7 +688,7 @@ public: - void DrawBitmap(const wxBitmap& bitmap, long x, long y, + void DrawBitmap(const wxBitmap& bitmap, wxCoord x, wxCoord y, int useMask = FALSE); bool CanDrawBitmap(); @@ -681,192 +714,39 @@ public: #endif - %addmethods { - // NOTE: These methods are VERY SIMILAR in implentation. It would be - // nice to factor out common code and or turn them into a set of - // template-like macros. - - // Draw a point for every set of coordinants in pyPoints, optionally - // setting a new pen for each - PyObject* _DrawPointList(PyObject* pyPoints, PyObject* pyPens) { - wxPyBeginBlockThreads(); - - bool isFastSeq = PyList_Check(pyPoints) || PyTuple_Check(pyPoints); - bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens); - int numObjs = 0; - int numPens = 0; - wxPen* pen; - PyObject* obj; - int x1, y1; - int i = 0; - PyObject* retval; - - if (!PySequence_Check(pyPoints)) { - goto err0; - } - if (!PySequence_Check(pyPens)) { - goto err1; - } - numObjs = PySequence_Length(pyPoints); - numPens = PySequence_Length(pyPens); - - for (i = 0; i < numObjs; i++) { - // Use a new pen? - if (i < numPens) { - if (isFastPens) { - obj = PySequence_Fast_GET_ITEM(pyPens, i); - } - else { - obj = PySequence_GetItem(pyPens, i); - } - if (SWIG_GetPtrObj(obj, (void **) &pen, "_wxPen_p")) { - if (!isFastPens) - Py_DECREF(obj); - goto err1; - } - - self->SetPen(*pen); - if (!isFastPens) - Py_DECREF(obj); - } - - // Get the point coordinants - if (isFastSeq) { - obj = PySequence_Fast_GET_ITEM(pyPoints, i); - } - else { - obj = PySequence_GetItem(pyPoints, i); - } - if (! _2int_seq_helper(obj, &x1, &y1)) { - if (!isFastPens) - Py_DECREF(obj); - goto err0; - } - if (PyErr_Occurred()) { - retval = NULL; - if (!isFastPens) - Py_DECREF(obj); - goto exit; - } - - - // Now draw the point - self->DrawPoint(x1, y1); - - if (!isFastSeq) - Py_DECREF(obj); - } + %addmethods { // See drawlist.cpp for impplementaion of these... - Py_INCREF(Py_None); - retval = Py_None; - goto exit; - - err1: - PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens"); - retval = NULL; - goto exit; - err0: - PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x,y) sequences."); - retval = NULL; - goto exit; - - exit: - wxPyEndBlockThreads(); - return retval; + PyObject* _DrawPointList(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) + { + return wxPyDrawXXXList(*self, wxPyDrawXXXPoint, pyCoords, pyPens, pyBrushes); } + PyObject* _DrawLineList(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) + { + return wxPyDrawXXXList(*self, wxPyDrawXXXLine, pyCoords, pyPens, pyBrushes); + } - // Draw a line for every set of coordinants in pyLines, optionally - // setting a new pen for each - PyObject* _DrawLineList(PyObject* pyLines, PyObject* pyPens) { - wxPyBeginBlockThreads(); - - bool isFastSeq = PyList_Check(pyLines) || PyTuple_Check(pyLines); - bool isFastPens = PyList_Check(pyPens) || PyTuple_Check(pyPens); - int numObjs = 0; - int numPens = 0; - wxPen* pen; - PyObject* obj; - int x1, y1, x2, y2; - int i = 0; - PyObject* retval; - - if (!PySequence_Check(pyLines)) { - goto err0; - } - if (!PySequence_Check(pyPens)) { - goto err1; - } - numObjs = PySequence_Length(pyLines); - numPens = PySequence_Length(pyPens); - - for (i = 0; i < numObjs; i++) { - // Use a new pen? - if (i < numPens) { - if (isFastPens) { - obj = PySequence_Fast_GET_ITEM(pyPens, i); - } - else { - obj = PySequence_GetItem(pyPens, i); - } - if (SWIG_GetPtrObj(obj, (void **) &pen, "_wxPen_p")) { - if (!isFastPens) - Py_DECREF(obj); - goto err1; - } - - self->SetPen(*pen); - if (!isFastPens) - Py_DECREF(obj); - } - - // Get the line coordinants - if (isFastSeq) { - obj = PySequence_Fast_GET_ITEM(pyLines, i); - } - else { - obj = PySequence_GetItem(pyLines, i); - } - if (! _4int_seq_helper(obj, &x1, &y1, &x2, &y2)) { - if (!isFastPens) - Py_DECREF(obj); - goto err0; - } - if (PyErr_Occurred()) { - retval = NULL; - if (!isFastPens) - Py_DECREF(obj); - goto exit; - } - - // Now draw the line - self->DrawLine(x1, y1, x2, y2); - - if (!isFastSeq) - Py_DECREF(obj); - } - - Py_INCREF(Py_None); - retval = Py_None; - goto exit; + PyObject* _DrawRectangleList(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) + { + return wxPyDrawXXXList(*self, wxPyDrawXXXRectangle, pyCoords, pyPens, pyBrushes); + } - err1: - PyErr_SetString(PyExc_TypeError, "Expected a sequence of wxPens"); - retval = NULL; - goto exit; + PyObject* _DrawEllipseList(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) + { + return wxPyDrawXXXList(*self, wxPyDrawXXXEllipse, pyCoords, pyPens, pyBrushes); + } - err0: - PyErr_SetString(PyExc_TypeError, "Expected a sequence of (x1,y1, x2,y2) sequences."); - retval = NULL; - goto exit; + PyObject* _DrawPolygonList(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes) + { + return wxPyDrawXXXList(*self, wxPyDrawXXXPolygon, pyCoords, pyPens, pyBrushes); + } - exit: - wxPyEndBlockThreads(); - return retval; + PyObject* _DrawTextList(PyObject* textList, PyObject* pyPoints, + PyObject* foregroundList, PyObject* backgroundList) { + return wxPyDrawTextList(*self, textList, pyPoints, foregroundList, backgroundList); } } - %pragma(python) addtoclass = " def DrawPointList(self, points, pens=None): if pens is None: @@ -875,7 +755,8 @@ public: pens = [pens] elif len(pens) != len(points): raise ValueError('points and pens must have same length') - return self._DrawPointList(points, pens) + return self._DrawPointList(points, pens, []) + def DrawLineList(self, lines, pens=None): if pens is None: @@ -884,7 +765,83 @@ public: pens = [pens] elif len(pens) != len(lines): raise ValueError('lines and pens must have same length') - return self._DrawLineList(lines, pens) + return self._DrawLineList(lines, pens, []) + + + def DrawRectangleList(self, rectangles, pens=None, brushes=None): + if pens is None: + pens = [] + elif isinstance(pens, wxPenPtr): + pens = [pens] + elif len(pens) != len(rectangles): + raise ValueError('rectangles and pens must have same length') + if brushes is None: + brushes = [] + elif isinstance(brushes, wxBrushPtr): + brushes = [brushes] + elif len(brushes) != len(rectangles): + raise ValueError('rectangles and brushes must have same length') + return self._DrawRectangleList(rectangles, pens, brushes) + + + def DrawEllipseList(self, ellipses, pens=None, brushes=None): + if pens is None: + pens = [] + elif isinstance(pens, wxPenPtr): + pens = [pens] + elif len(pens) != len(ellipses): + raise ValueError('ellipses and pens must have same length') + if brushes is None: + brushes = [] + elif isinstance(brushes, wxBrushPtr): + brushes = [brushes] + elif len(brushes) != len(ellipses): + raise ValueError('ellipses and brushes must have same length') + return self._DrawEllipseList(ellipses, pens, brushes) + + + def DrawPolygonList(self, polygons, pens=None, brushes=None): + ## Note: This does not currently support fill style or offset + ## you can always use the non-List version if need be. + ## I really would like to support fill-style, however, + ## but wxODDEVEN_RULE does not appear to be defined at the Python level + ## [It's in wx.py... --Robin] + if pens is None: + pens = [] + elif isinstance(pens, wxPenPtr): + pens = [pens] + elif len(pens) != len(polygons): + raise ValueError('polygons and pens must have same length') + if brushes is None: + brushes = [] + elif isinstance(brushes, wxBrushPtr): + brushes = [brushes] + elif len(brushes) != len(polygons): + raise ValueError('polygons and brushes must have same length') + return self._DrawPolygonList(polygons, pens, brushes) + + + def DrawTextList(self, textList, coords, foregrounds = None, backgrounds = None, fonts = None): + ## NOTE: this does not currently support changing the font + ## Make sure you set Background mode to wxSolid (DC.SetBackgroundMode) + ## If you want backgounds to do anything. + if type(textList) == type(''): + textList = [textList] + elif len(textList) != len(coords): + raise ValueError('textlist and coords must have same length') + if foregrounds is None: + foregrounds = [] + elif isinstance(foregrounds, wxColourPtr): + foregrounds = [foregrounds] + elif len(foregrounds) != len(coords): + raise ValueError('foregrounds and coords must have same length') + if backgrounds is None: + backgrounds = [] + elif isinstance(backgrounds, wxColourPtr): + backgrounds = [backgrounds] + elif len(backgrounds) != len(coords): + raise ValueError('backgrounds and coords must have same length') + return self._DrawTextList(textList, coords, foregrounds, backgrounds) " @@ -1082,7 +1039,7 @@ enum wxRegionContain { class wxRegion : public wxGDIObject { public: - wxRegion(long x=0, long y=0, long width=0, long height=0); + wxRegion(wxCoord x=0, wxCoord y=0, wxCoord width=0, wxCoord height=0); #ifndef __WXMAC__ %name(wxRegionFromPoints)wxRegion(int PCOUNT, wxPoint* points, int fillStyle = wxWINDING_RULE); #endif @@ -1093,28 +1050,28 @@ public: bool Offset(wxCoord x, wxCoord y); #endif - wxRegionContain Contains(long x, long y); + wxRegionContain Contains(wxCoord x, wxCoord y); %name(ContainsPoint)wxRegionContain Contains(const wxPoint& pt); %name(ContainsRect)wxRegionContain Contains(const wxRect& rect); - %name(ContainsRectDim)wxRegionContain Contains(long x, long y, long w, long h); + %name(ContainsRectDim)wxRegionContain Contains(wxCoord x, wxCoord y, wxCoord w, wxCoord h); wxRect GetBox(); - bool Intersect(long x, long y, long width, long height); + bool Intersect(wxCoord x, wxCoord y, wxCoord width, wxCoord height); %name(IntersectRect)bool Intersect(const wxRect& rect); %name(IntersectRegion)bool Intersect(const wxRegion& region); bool IsEmpty(); - bool Union(long x, long y, long width, long height); + bool Union(wxCoord x, wxCoord y, wxCoord width, wxCoord height); %name(UnionRect)bool Union(const wxRect& rect); %name(UnionRegion)bool Union(const wxRegion& region); - bool Subtract(long x, long y, long width, long height); + bool Subtract(wxCoord x, wxCoord y, wxCoord width, wxCoord height); %name(SubtractRect)bool Subtract(const wxRect& rect); %name(SubtractRegion)bool Subtract(const wxRegion& region); - bool Xor(long x, long y, long width, long height); + bool Xor(wxCoord x, wxCoord y, wxCoord width, wxCoord height); %name(XorRect)bool Xor(const wxRect& rect); %name(XorRegion)bool Xor(const wxRegion& region); }; @@ -1126,12 +1083,12 @@ public: wxRegionIterator(const wxRegion& region); ~wxRegionIterator(); - long GetX(); - long GetY(); - long GetW(); - long GetWidth(); - long GetH(); - long GetHeight(); + wxCoord GetX(); + wxCoord GetY(); + wxCoord GetW(); + wxCoord GetWidth(); + wxCoord GetH(); + wxCoord GetHeight(); wxRect GetRect(); bool HaveRects(); void Reset(); diff --git a/wxPython/src/grid.i b/wxPython/src/grid.i index ed7a4e4e8a..8e10b08c6f 100644 --- a/wxPython/src/grid.i +++ b/wxPython/src/grid.i @@ -1,4 +1,4 @@ -///////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// // Name: grid.i // Purpose: SWIG definitions for the new wxGrid and related classes // @@ -70,7 +70,7 @@ PyObject* wxPyMake_##TYPE(TYPE* source) { \ /* Otherwise make a new wrapper for it the old fashioned way and \ give it the OOR treatment */ \ if (! target) { \ - target = wxPyConstructObject(source, #TYPE, FALSE); \ + target = wxPyConstructObject(source, wxT(#TYPE), FALSE); \ if (target) \ source->SetClientObject(new wxPyOORClientData(target)); \ } \ @@ -571,7 +571,7 @@ public: PyObject* go = wxPyMake_wxObject(&grid); PyObject* dco = wxPyMake_wxObject(&dc); PyObject* ao = wxPyMake_wxGridCellAttr(&attr); - PyObject* ro = wxPyConstructObject((void*)&rect, "wxRect", 0); + PyObject* ro = wxPyConstructObject((void*)&rect, wxT("wxRect"), 0); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OOOOiii)", go, ao, dco, ro, row, col, isSelected)); @@ -747,6 +747,9 @@ public: wxControl* GetControl(); void SetControl(wxControl* control); + wxGridCellAttr* GetCellAttr(); + void SetCellAttr(wxGridCellAttr* attr); + void SetParameters(const wxString& params); void IncRef(); void DecRef(); @@ -768,6 +771,7 @@ public: virtual void HandleReturn(wxKeyEvent& event); virtual void Destroy(); + virtual wxString GetValue(); }; @@ -816,7 +820,7 @@ public: } - wxGridCellEditor*Clone() const { + wxGridCellEditor* Clone() const { wxGridCellEditor* rval = NULL; wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "Clone")) { @@ -856,7 +860,7 @@ public: wxPyBeginBlockThreads(); if ((found = wxPyCBH_findCallback(m_myInst, "PaintBackground)"))) { PyObject* ao = wxPyMake_wxGridCellAttr(attr); - PyObject* ro = wxPyConstructObject((void*)&rectCell, "wxRect", 0); + PyObject* ro = wxPyConstructObject((void*)&rectCell, wxT("wxRect"), 0); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OO)", ro, ao)); @@ -880,6 +884,7 @@ public: DEC_PYCALLBACK__(StartingClick); DEC_PYCALLBACK__(Destroy); DEC_PYCALLBACK__STRING(SetParameters); + DEC_PYCALLBACK_STRING__const(GetValue); PYPRIVATE; }; @@ -893,6 +898,7 @@ IMP_PYCALLBACK__any(wxPyGridCellEditor, wxGridCellEditor, StartingKey, wxKeyEven IMP_PYCALLBACK__any(wxPyGridCellEditor, wxGridCellEditor, HandleReturn, wxKeyEvent); IMP_PYCALLBACK__(wxPyGridCellEditor, wxGridCellEditor, StartingClick); IMP_PYCALLBACK__(wxPyGridCellEditor, wxGridCellEditor, Destroy); +IMP_PYCALLBACK_STRING__const(wxPyGridCellEditor, wxGridCellEditor, GetValue); %} @@ -914,6 +920,7 @@ public: void base_HandleReturn(wxKeyEvent& event); void base_Destroy(); void base_SetParameters(const wxString& params); + wxString base_GetValue(); }; //--------------------------------------------------------------------------- @@ -1403,8 +1410,17 @@ public: return *self != other; } } - %pragma(python) addtoclass = "def __str__(self): return str(self.asTuple())" - %pragma(python) addtoclass = "def __repr__(self): return str(self.asTuple())" + %pragma(python) addtoclass = " + def __str__(self): return str(self.asTuple()) + def __repr__(self): return 'wxGridCellCoords'+str(self.asTuple()) + def __len__(self): return len(self.asTuple()) + def __getitem__(self, index): return self.asTuple()[index] + def __setitem__(self, index, val): + if index == 0: self.SetRow(val) + elif index == 1: self.SetCol(val) + else: raise IndexError + " + }; // Typemap to allow conversion of sequence objects to wxGridCellCoords... @@ -1440,6 +1456,36 @@ bool wxGridCellCoords_helper(PyObject* source, wxGridCellCoords** obj) { } %} + + +// Typemap to convert an array of cells coords to a list of tuples... +%typemap(python, out) wxGridCellCoordsArray { + $target = wxGridCellCoordsArray_helper($source); +} + +%typemap(python, ret) wxGridCellCoordsArray { + delete $source; +} + + +// ...and the helper function for the above typemap. +%{ +PyObject* wxGridCellCoordsArray_helper(const wxGridCellCoordsArray* source) +{ + PyObject* list = PyList_New(0); + size_t idx; + for (idx = 0; idx < source->GetCount(); idx += 1) { + wxGridCellCoords& coord = source->Item(idx); + PyObject* tup = PyTuple_New(2); + PyTuple_SET_ITEM(tup, 0, PyInt_FromLong(coord.GetRow())); + PyTuple_SET_ITEM(tup, 1, PyInt_FromLong(coord.GetCol())); + PyList_Append(list, tup); + Py_DECREF(tup); + } + return list; +} +%} + //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // The grid itself @@ -1509,7 +1555,8 @@ public: // void DrawTextRectangle( wxDC& dc, const wxString&, const wxRect&, int horizontalAlignment = wxLEFT, - int verticalAlignment = wxTOP ); + int verticalAlignment = wxTOP, + int textOrientation = wxHORIZONTAL ); // // Split a string containing newline chararcters into an array of // // strings and return the number of lines @@ -1614,6 +1661,7 @@ public: wxFont GetLabelFont(); void GetRowLabelAlignment( int *OUTPUT, int *OUTPUT ); void GetColLabelAlignment( int *OUTPUT, int *OUTPUT ); + int GetColLabelTextOrientation(); wxString GetRowLabelValue( int row ); wxString GetColLabelValue( int col ); wxColour GetGridLineColour(); @@ -1628,6 +1676,7 @@ public: void SetLabelFont( const wxFont& ); void SetRowLabelAlignment( int horiz, int vert ); void SetColLabelAlignment( int horiz, int vert ); + void SetColLabelTextOrientation( int textOrientation ); void SetRowLabelValue( int row, const wxString& ); void SetColLabelValue( int col, const wxString& ); void SetGridLineColour( const wxColour& ); @@ -1700,6 +1749,13 @@ public: // and also set the grid size to just fit its contents void AutoSize(); + // autosize row height depending on label text + void AutoSizeRowLabelSize( int row ); + + // autosize column width depending on label text + void AutoSizeColLabelSize( int col ); + + // column won't be resized to be lesser width - this must be called during // the grid creation because it won't resize the column if it's already // narrower than the minimal width @@ -1763,12 +1819,15 @@ public: bool IsInSelection( int row, int col ); // TODO: ??? bool IsInSelection( const wxGridCellCoords& coords ) -// TODO: These need typemaps -// wxGridCellCoordsArray GetSelectedCells() const; -// wxGridCellCoordsArray GetSelectionBlockTopLeft() const; -// wxGridCellCoordsArray GetSelectionBlockBottomRight() const; -// wxArrayInt GetSelectedRows() const; -// wxArrayInt GetSelectedCols() const; + const wxGridCellCoordsArray GetSelectedCells() const; + const wxGridCellCoordsArray GetSelectionBlockTopLeft() const; + const wxGridCellCoordsArray GetSelectionBlockBottomRight() const; + const wxArrayInt GetSelectedRows() const; + const wxArrayInt GetSelectedCols() const; + + void DeselectRow( int row ); + void DeselectCol( int col ); + void DeselectCell( int row, int col ); // This function returns the rectangle that encloses the block of cells diff --git a/wxPython/src/helpers.cpp b/wxPython/src/helpers.cpp index e317a426be..c47bd837c5 100644 --- a/wxPython/src/helpers.cpp +++ b/wxPython/src/helpers.cpp @@ -46,6 +46,7 @@ void WXDLLEXPORT wxEntryCleanup(); wxPyApp* wxPythonApp = NULL; // Global instance of application object bool wxPyDoCleanup = FALSE; +bool wxPyDoingCleanup = FALSE; #ifdef WXP_WITH_THREAD @@ -67,6 +68,11 @@ wxMutex* wxPyTMutex = NULL; #endif +static PyObject* wxPython_dict = NULL; +static PyObject* wxPyPtrTypeMap = NULL; +static PyObject* wxPyAssertionError = NULL; + + #ifdef __WXMSW__ // If building for win32... //---------------------------------------------------------------------- // This gets run when the DLL is loaded. We just need to save a handle. @@ -90,16 +96,19 @@ BOOL WINAPI DllMain( // Classes for implementing the wxp main application shell. //---------------------------------------------------------------------- +IMPLEMENT_ABSTRACT_CLASS(wxPyApp, wxApp); + wxPyApp::wxPyApp() { - SetUseBestVisual(TRUE); + m_assertMode = wxPYAPP_ASSERT_EXCEPTION; } + wxPyApp::~wxPyApp() { } -// This one isn't acutally called... See __wxStart() +// This one isn't acutally called... We fake it with __wxStart() bool wxPyApp::OnInit() { return FALSE; } @@ -126,6 +135,200 @@ int wxPyApp::MainLoop() { } +bool wxPyApp::OnInitGui() { + bool rval=TRUE; + wxApp::OnInitGui(); // in this case always call the base class version + // wxPyBeginBlockThreads(); *** only called from within __wxStart so we already have the GIL + if (wxPyCBH_findCallback(m_myInst, "OnInitGui")) + rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); + // wxPyEndBlockThreads(); *** + return rval; +} + + +int wxPyApp::OnExit() { + int rval=0; + wxPyBeginBlockThreads(); + if (wxPyCBH_findCallback(m_myInst, "OnExit")) + rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); + wxPyEndBlockThreads(); + wxApp::OnExit(); // in this case always call the base class version + return rval; +} + + +#ifdef __WXDEBUG__ +void wxPyApp::OnAssert(const wxChar *file, + int line, + const wxChar *cond, + const wxChar *msg) { + + // If the OnAssert is overloaded in the Python class then call it... + bool found; + wxPyBeginBlockThreads(); + if ((found = wxPyCBH_findCallback(m_myInst, "OnAssert"))) { + PyObject* fso = wx2PyString(file); + PyObject* cso = wx2PyString(file); + PyObject* mso; + if (msg != NULL) + mso = wx2PyString(file); + else { + mso = Py_None; Py_INCREF(Py_None); + } + wxPyCBH_callCallback(m_myInst, Py_BuildValue("(OiOO)", fso, line, cso, mso)); + Py_DECREF(fso); + Py_DECREF(cso); + Py_DECREF(mso); + } + wxPyEndBlockThreads(); + + // ...otherwise do our own thing with it + if (! found) { + // ignore it? + if (m_assertMode & wxPYAPP_ASSERT_SUPPRESS) + return; + + // turn it into a Python exception? + if (m_assertMode & wxPYAPP_ASSERT_EXCEPTION) { + wxString buf; + buf.Alloc(4096); + buf.Printf(wxT("C++ assertion \"%s\" failed in %s(%d)"), cond, file, line); + if (msg != NULL) { + buf += wxT(": "); + buf += msg; + } + + // set the exception + wxPyBeginBlockThreads(); + PyObject* s = wx2PyString(buf); + PyErr_SetObject(wxPyAssertionError, s); + Py_DECREF(s); + wxPyEndBlockThreads(); + + // Now when control returns to whatever API wrapper was called from + // Python it should detect that an exception is set and will return + // NULL, signalling the exception to Python. + } + + // Send it to the normal log destination, but only if + // not _DIALOG because it will call this too + if ( (m_assertMode & wxPYAPP_ASSERT_LOG) && !(m_assertMode & wxPYAPP_ASSERT_DIALOG)) { + wxString buf; + buf.Alloc(4096); + buf.Printf(wxT("%s(%d): assert \"%s\" failed"), + file, line, cond); + if (msg != NULL) { + buf += wxT(": "); + buf += msg; + } + wxLogDebug(buf); + } + + // do the normal wx assert dialog? + if (m_assertMode & wxPYAPP_ASSERT_DIALOG) + wxApp::OnAssert(file, line, cond, msg); + } +} +#endif + + +/*static*/ +bool wxPyApp::GetMacDefaultEncodingIsPC() { +#ifdef __WXMAC__ + return s_macDefaultEncodingIsPC; +#else + return 0; +#endif +} + +/*static*/ +bool wxPyApp::GetMacSupportPCMenuShortcuts() { +#ifdef __WXMAC__ + return s_macSupportPCMenuShortcuts; +#else + return 0; +#endif +} + +/*static*/ +long wxPyApp::GetMacAboutMenuItemId() { +#ifdef __WXMAC__ + return s_macAboutMenuItemId; +#else + return 0; +#endif +} + +/*static*/ +long wxPyApp::GetMacPreferencesMenuItemId() { +#ifdef __WXMAC__ + return s_macPreferencesMenuItemId; +#else + return 0; +#endif +} + +/*static*/ +long wxPyApp::GetMacExitMenuItemId() { +#ifdef __WXMAC__ + return s_macExitMenuItemId; +#else + return 0; +#endif +} + +/*static*/ +wxString wxPyApp::GetMacHelpMenuTitleName() { +#ifdef __WXMAC__ + return s_macHelpMenuTitleName; +#else + return wxEmptyString; +#endif +} + +/*static*/ +void wxPyApp::SetMacDefaultEncodingIsPC(bool val) { +#ifdef __WXMAC__ + s_macDefaultEncodingIsPC = val; +#endif +} + +/*static*/ +void wxPyApp::SetMacSupportPCMenuShortcuts(bool val) { +#ifdef __WXMAC__ + s_macSupportPCMenuShortcuts = val; +#endif +} + +/*static*/ +void wxPyApp::SetMacAboutMenuItemId(long val) { +#ifdef __WXMAC__ + s_macAboutMenuItemId = val; +#endif +} + +/*static*/ +void wxPyApp::SetMacPreferencesMenuItemId(long val) { +#ifdef __WXMAC__ + s_macPreferencesMenuItemId = val; +#endif +} + +/*static*/ +void wxPyApp::SetMacExitMenuItemId(long val) { +#ifdef __WXMAC__ + s_macExitMenuItemId = val; +#endif +} + +/*static*/ +void wxPyApp::SetMacHelpMenuTitleName(const wxString& val) { +#ifdef __WXMAC__ + s_macHelpMenuTitleName = val; +#endif +} + + //--------------------------------------------------------------------- //---------------------------------------------------------------------- @@ -170,7 +373,7 @@ static wxChar* wxPyCopyWString(const wxChar *src) // This is where we pick up the first part of the wxEntry functionality... // The rest is in __wxStart and __wxCleanup. This function is called when // wxcmodule is imported. (Before there is a wxApp object.) -void __wxPreStart() +void __wxPreStart(PyObject* moduleDict) { #ifdef __WXMSW__ @@ -185,6 +388,11 @@ void __wxPreStart() wxApp::CheckBuildOptions(wxBuildOptions()); + wxPyAssertionError = PyErr_NewException("wxPython.wxc.wxPyAssertionError", + PyExc_AssertionError, NULL); + PyDict_SetItemString(moduleDict, "wxPyAssertionError", wxPyAssertionError); + + // Bail out if there is already a wxApp created. This means that the // toolkit has already been initialized, as in embedding wxPython in // a C++ wxWindows app, so we don't need to call wxEntryStart. @@ -202,12 +410,7 @@ void __wxPreStart() int x; for(x=0; xm_initialized = (wxTopLevelWindows.GetCount() > 0); #endif + Py_DECREF(result); + Py_DECREF(pyint); Py_INCREF(Py_None); return Py_None; + + error: + Py_XDECREF(result); + Py_XDECREF(pyint); + return NULL; } void __wxCleanup() { + wxPyDoingCleanup = TRUE; if (wxPyDoCleanup) wxEntryCleanup(); #ifdef WXP_WITH_THREAD @@ -293,9 +501,6 @@ void __wxCleanup() { -static PyObject* wxPython_dict = NULL; -static PyObject* wxPyPtrTypeMap = NULL; - PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) { @@ -346,15 +551,20 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args) //--------------------------------------------------------------------------- void wxPyClientData_dtor(wxPyClientData* self) { - wxPyBeginBlockThreads(); - Py_DECREF(self->m_obj); - wxPyEndBlockThreads(); + if (! wxPyDoingCleanup) { // Don't do it during cleanup as Python + // may have already garbage collected the object... + wxPyBeginBlockThreads(); + Py_DECREF(self->m_obj); + wxPyEndBlockThreads(); + } } void wxPyUserData_dtor(wxPyUserData* self) { - wxPyBeginBlockThreads(); - Py_DECREF(self->m_obj); - wxPyEndBlockThreads(); + if (! wxPyDoingCleanup) { + wxPyBeginBlockThreads(); + Py_DECREF(self->m_obj); + wxPyEndBlockThreads(); + } } @@ -377,6 +587,8 @@ void wxPyOORClientData_dtor(wxPyOORClientData* self) { Py_INCREF(deadObjectClass); } + // TODO: If wxPyDOingCleanup, should we skip the code below? + // Clear the instance's dictionary, put the name of the old class into the // instance, and then reset the class to be the dead class. if (self->m_obj->ob_refcnt > 1) { // but only if there is more than one reference @@ -412,14 +624,26 @@ void wxPyPtrTypeMap_Add(const char* commonName, const char* ptrName) { PyObject* wxPyClassExists(const wxString& className) { + PyObject* item; + wxString name(className); + char buff[64]; // should always be big enough... + if (!className) return NULL; - char buff[64]; // should always be big enough... - - sprintf(buff, "%sPtr", className.mbc_str()); + // Try the name as-is first + sprintf(buff, "%sPtr", (const char*)name.mbc_str()); PyObject* classobj = PyDict_GetItemString(wxPython_dict, buff); + // if not found see if there is a mapped name for it + if ( ! classobj) { + if ((item = PyDict_GetItemString(wxPyPtrTypeMap, (char*)(const char*)name.mbc_str())) != NULL) { + name = wxString(PyString_AsString(item), *wxConvCurrent); + sprintf(buff, "%sPtr", (const char*)name.mbc_str()); + classobj = PyDict_GetItemString(wxPython_dict, buff); + } + } + return classobj; // returns NULL if not found } @@ -445,8 +669,8 @@ PyObject* wxPyMake_wxObject(wxObject* source, bool checkEvtHandler) { if (! target) { // Otherwise make it the old fashioned way by making a // new shadow object and putting this pointer in it. - wxClassInfo* info = source->GetClassInfo(); - wxChar* name = (wxChar*)info->GetClassName(); + wxClassInfo* info = source->GetClassInfo(); + wxString name = info->GetClassName(); PyObject* klass = wxPyClassExists(name); while (info && !klass) { name = (wxChar*)info->GetBaseClassName1(); @@ -691,13 +915,15 @@ PyObject* wxPyInputStream::read(int size) { // check if we have a real wxInputStream to work with if (!m_wxis) { + wxPyBeginBlockThreads(); PyErr_SetString(PyExc_IOError, "no valid C-wxInputStream"); + wxPyEndBlockThreads(); return NULL; } if (size < 0) { - // read until EOF - while (! m_wxis->Eof()) { + // read while bytes are available on the stream + while ( m_wxis->CanRead() ) { m_wxis->Read(buf.GetAppendBuf(BUFSIZE), BUFSIZE); buf.UngetAppendBuf(m_wxis->LastRead()); } @@ -708,13 +934,16 @@ PyObject* wxPyInputStream::read(int size) { } // error check - if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { + wxPyBeginBlockThreads(); + wxStreamError err = m_wxis->GetLastError(); + if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) { PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); } else { // We use only strings for the streams, not unicode obj = PyString_FromStringAndSize(buf, buf.GetDataLen()); } + wxPyEndBlockThreads(); return obj; } @@ -727,24 +956,29 @@ PyObject* wxPyInputStream::readline(int size) { // check if we have a real wxInputStream to work with if (!m_wxis) { + wxPyBeginBlockThreads(); PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream"); + wxPyEndBlockThreads(); return NULL; } // read until \n or byte limit reached - for (i=ch=0; (ch != '\n') && (!m_wxis->Eof()) && ((size < 0) || (i < size)); i++) { + for (i=ch=0; (ch != '\n') && (m_wxis->CanRead()) && ((size < 0) || (i < size)); i++) { ch = m_wxis->GetC(); buf.AppendByte(ch); } // errorcheck - if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { + wxPyBeginBlockThreads(); + wxStreamError err = m_wxis->GetLastError(); + if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) { PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); } else { // We use only strings for the streams, not unicode obj = PyString_FromStringAndSize((char*)buf.GetData(), buf.GetDataLen()); } + wxPyEndBlockThreads(); return obj; } @@ -754,33 +988,45 @@ PyObject* wxPyInputStream::readlines(int sizehint) { // check if we have a real wxInputStream to work with if (!m_wxis) { - PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below"); + wxPyBeginBlockThreads(); + PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream"); + wxPyEndBlockThreads(); return NULL; } // init list + wxPyBeginBlockThreads(); pylist = PyList_New(0); if (!pylist) { + wxPyBeginBlockThreads(); PyErr_NoMemory(); + wxPyEndBlockThreads(); return NULL; } // read sizehint bytes or until EOF int i; - for (i=0; (!m_wxis->Eof()) && ((sizehint < 0) || (i < sizehint));) { + for (i=0; (m_wxis->CanRead()) && ((sizehint < 0) || (i < sizehint));) { PyObject* s = this->readline(); if (s == NULL) { + wxPyBeginBlockThreads(); Py_DECREF(pylist); + wxPyEndBlockThreads(); return NULL; } + wxPyBeginBlockThreads(); PyList_Append(pylist, s); i += PyString_Size(s); + wxPyEndBlockThreads(); } // error check - if (m_wxis->LastError() == wxSTREAM_READ_ERROR) { + wxStreamError err = m_wxis->GetLastError(); + if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) { + wxPyBeginBlockThreads(); Py_DECREF(pylist); PyErr_SetString(PyExc_IOError,"IOError in wxInputStream"); + wxPyEndBlockThreads(); return NULL; } @@ -889,7 +1135,6 @@ size_t wxPyCBInputStream::OnSysRead(void *buffer, size_t bufsize) { else m_lasterror = wxSTREAM_READ_ERROR; wxPyEndBlockThreads(); - m_lastcount = o; return o; } @@ -956,9 +1201,9 @@ void wxPyCallback::EventThunker(wxEvent& event) { wxPyBeginBlockThreads(); wxString className = event.GetClassInfo()->GetClassName(); - if (className == "wxPyEvent") + if (className == wxT("wxPyEvent")) arg = ((wxPyEvent*)&event)->GetSelf(); - else if (className == "wxPyCommandEvent") + else if (className == wxT("wxPyCommandEvent")) arg = ((wxPyCommandEvent*)&event)->GetSelf(); else { arg = wxPyConstructObject((void*)&event, className); @@ -1287,19 +1532,20 @@ void wxPyTimer::Notify() { //--------------------------------------------------------------------------- // Convert a wxList to a Python List -PyObject* wxPy_ConvertList(wxListBase* list, const char* className) { +PyObject* wxPy_ConvertList(wxListBase* listbase, const char* className) { + wxList* list = (wxList*)listbase; // this is probably bad... PyObject* pyList; PyObject* pyObj; wxObject* wxObj; - wxNode* node = list->First(); + wxNode* node = list->GetFirst(); wxPyBeginBlockThreads(); pyList = PyList_New(0); while (node) { - wxObj = node->Data(); + wxObj = node->GetData(); pyObj = wxPyMake_wxObject(wxObj); //wxPyConstructObject(wxObj, className); PyList_Append(pyList, pyObj); - node = node->Next(); + node = node->GetNext(); } wxPyEndBlockThreads(); return pyList; @@ -1315,10 +1561,14 @@ long wxPyGetWinHandle(wxWindow* win) { // Find and return the actual X-Window. #ifdef __WXGTK__ if (win->m_wxwindow) { +#ifdef __WXGTK20__ + return (long) GDK_WINDOW_XWINDOW(GTK_PIZZA(win->m_wxwindow)->bin_window); +#else GdkWindowPrivate* bwin = (GdkWindowPrivate*)GTK_PIZZA(win->m_wxwindow)->bin_window; if (bwin) { return (long)bwin->xwindow; } +#endif } #endif return 0; @@ -1344,7 +1594,12 @@ wxString* wxString_in_helper(PyObject* source) { } #if wxUSE_UNICODE if (PyUnicode_Check(source)) { - target = new wxString(PyUnicode_AS_UNICODE(source)); + target = new wxString(); + size_t len = PyUnicode_GET_SIZE(source); + if (len) { + PyUnicode_AsWideChar((PyUnicodeObject*)source, target->GetWriteBuf(len), len); + target->UngetWriteBuf(); + } } else { // It is a string, get pointers to it and transform to unicode char* tmpPtr; int tmpSize; @@ -1386,7 +1641,11 @@ wxString Py2wxString(PyObject* source) #if wxUSE_UNICODE if (PyUnicode_Check(source)) { - target = PyUnicode_AS_UNICODE(source); + size_t len = PyUnicode_GET_SIZE(source); + if (len) { + PyUnicode_AsWideChar((PyUnicodeObject*)source, target.GetWriteBuf(len), len); + target.UngetWriteBuf(); + } } else { // It is a string, get pointers to it and transform to unicode char* tmpPtr; int tmpSize; @@ -1419,7 +1678,7 @@ PyObject* wx2PyString(const wxString& src) { PyObject* str; #if wxUSE_UNICODE - str = PyUnicode_FromUnicode(src.c_str(), src.Len()); + str = PyUnicode_FromWideChar(src.c_str(), src.Len()); #else str = PyString_FromStringAndSize(src.c_str(), src.Len()); #endif @@ -1624,7 +1883,7 @@ error2: if (!isFast) Py_DECREF(o); error1: - delete temp; + delete [] temp; error0: PyErr_SetString(PyExc_TypeError, "Expected a sequence of length-2 sequences or wxPoints."); return NULL; @@ -1765,7 +2024,7 @@ wxPen** wxPen_LIST_helper(PyObject* source) { } -bool _2int_seq_helper(PyObject* source, int* i1, int* i2) { +bool wxPy2int_seq_helper(PyObject* source, int* i1, int* i2) { bool isFast = PyList_Check(source) || PyTuple_Check(source); PyObject *o1, *o2; @@ -1792,7 +2051,7 @@ bool _2int_seq_helper(PyObject* source, int* i1, int* i2) { } -bool _4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4) { +bool wxPy4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4) { bool isFast = PyList_Check(source) || PyTuple_Check(source); PyObject *o1, *o2, *o3, *o4; @@ -1859,6 +2118,7 @@ bool wxSize_helper(PyObject* source, wxSize** obj) { return FALSE; } + bool wxPoint_helper(PyObject* source, wxPoint** obj) { // If source is an object instance then it may already be the right type @@ -1974,9 +2234,9 @@ bool wxColour_helper(PyObject* source, wxColour** obj) { *obj = ptr; return TRUE; } - // otherwise a string is expected - else if (PyString_Check(source)) { - wxString spec(PyString_AS_STRING(source), *wxConvCurrent); + // otherwise check for a string + else if (PyString_Check(source) || PyUnicode_Check(source)) { + wxString spec = Py2wxString(source); if (spec.GetChar(0) == '#' && spec.Length() == 7) { // It's #RRGGBB long red, green, blue; red = green = blue = 0; @@ -1992,15 +2252,63 @@ bool wxColour_helper(PyObject* source, wxColour** obj) { return TRUE; } } + // last chance: 3-tuple of integers is expected + else if (PySequence_Check(source) && PyObject_Length(source) == 3) { + PyObject* o1 = PySequence_GetItem(source, 0); + PyObject* o2 = PySequence_GetItem(source, 1); + PyObject* o3 = PySequence_GetItem(source, 2); + if (!PyNumber_Check(o1) || !PyNumber_Check(o2) || !PyNumber_Check(o3)) { + Py_DECREF(o1); + Py_DECREF(o2); + Py_DECREF(o3); + goto error; + } + **obj = wxColour(PyInt_AsLong(o1), PyInt_AsLong(o2), PyInt_AsLong(o3)); + Py_DECREF(o1); + Py_DECREF(o2); + Py_DECREF(o3); + return TRUE; + } error: PyErr_SetString(PyExc_TypeError, - "Expected a wxColour object or a string containing a colour " - "name or '#RRGGBB'."); + "Expected a wxColour object or a string containing a colour name or '#RRGGBB'."); + return FALSE; +} + + + +bool wxPoint2DDouble_helper(PyObject* source, wxPoint2DDouble** obj) { + // If source is an object instance then it may already be the right type + if (PyInstance_Check(source)) { + wxPoint2DDouble* ptr; + if (SWIG_GetPtrObj(source, (void **)&ptr, "_wxPoint2DDouble_p")) + goto error; + *obj = ptr; + return TRUE; + } + // otherwise a length-2 sequence of floats is expected + if (PySequence_Check(source) && PySequence_Length(source) == 2) { + PyObject* o1 = PySequence_GetItem(source, 0); + PyObject* o2 = PySequence_GetItem(source, 1); + // This should really check for integers, not numbers -- but that would break code. + if (!PyNumber_Check(o1) || !PyNumber_Check(o2)) { + Py_DECREF(o1); + Py_DECREF(o2); + goto error; + } + **obj = wxPoint2DDouble(PyFloat_AsDouble(o1), PyFloat_AsDouble(o2)); + Py_DECREF(o1); + Py_DECREF(o2); + return TRUE; + } + error: + PyErr_SetString(PyExc_TypeError, "Expected a 2-tuple of floats or a wxPoint2DDouble object."); return FALSE; } + //---------------------------------------------------------------------- PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) { @@ -2008,7 +2316,7 @@ PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) { PyObject* list = PyList_New(0); for (size_t i=0; i < arr.GetCount(); i++) { #if wxUSE_UNICODE - PyObject* str = PyUnicode_FromUnicode(arr[i].c_str(), arr[i].Len()); + PyObject* str = PyUnicode_FromWideChar(arr[i].c_str(), arr[i].Len()); #else PyObject* str = PyString_FromStringAndSize(arr[i].c_str(), arr[i].Len()); #endif diff --git a/wxPython/src/helpers.h b/wxPython/src/helpers.h index 1ca7acd7da..58c81db3a7 100644 --- a/wxPython/src/helpers.h +++ b/wxPython/src/helpers.h @@ -14,27 +14,13 @@ #define __wxp_helpers__ #include - +#include //--------------------------------------------------------------------------- typedef unsigned char byte; - -class wxPyApp: public wxApp -{ -public: - wxPyApp(); - ~wxPyApp(); - bool OnInit(); - int MainLoop(); -}; - -extern wxPyApp *wxPythonApp; - -//---------------------------------------------------------------------- - -void __wxPreStart(); +void __wxPreStart(PyObject*); PyObject* __wxStart(PyObject*, PyObject* args); void __wxCleanup(); @@ -80,6 +66,8 @@ void wxPyEndAllowThreads(PyThreadState* state); void wxPyBeginBlockThreads(); void wxPyEndBlockThreads(); +#define wxPyBLOCK_THREADS(stmt) wxPyBeginBlockThreads(); stmt; wxPyEndBlockThreads() + //---------------------------------------------------------------------- // These are helpers used by the typemaps @@ -101,6 +89,9 @@ bool wxRealPoint_helper(PyObject* source, wxRealPoint** obj); bool wxRect_helper(PyObject* source, wxRect** obj); bool wxColour_helper(PyObject* source, wxColour** obj); +bool wxPoint2DDouble_helper(PyObject* source, wxPoint2DDouble** obj); + + //---------------------------------------------------------------------- // Other helpful stuff @@ -109,8 +100,8 @@ bool wxColour_helper(PyObject* source, wxColour** obj); (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) #endif -bool _2int_seq_helper(PyObject* source, int* i1, int* i2); -bool _4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4); +bool wxPy2int_seq_helper(PyObject* source, int* i1, int* i2); +bool wxPy4int_seq_helper(PyObject* source, int* i1, int* i2, int* i3, int* i4); PyObject* wxArrayString2PyList_helper(const wxArrayString& arr); @@ -120,6 +111,21 @@ PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr); #define DECLARE_DEF_STRING(name) static const wxString wxPy##name(wx##name) #define DECLARE_DEF_STRING2(name,val) static const wxString wxPy##name(val) +//---------------------------------------------------------------------- +// functions used by the DrawXXXList enhancements added to wxDC + +typedef bool (*wxPyDrawListOp_t)(wxDC& dc, PyObject* coords); +PyObject* wxPyDrawXXXList(wxDC& dc, wxPyDrawListOp_t doDraw, + PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes); +bool wxPyDrawXXXPoint(wxDC& dc, PyObject* coords); +bool wxPyDrawXXXLine(wxDC& dc, PyObject* coords); +bool wxPyDrawXXXRectangle(wxDC& dc, PyObject* coords); +bool wxPyDrawXXXEllipse(wxDC& dc, PyObject* coords); +bool wxPyDrawXXXPolygon(wxDC& dc, PyObject* coords); + +PyObject* wxPyDrawTextList(wxDC& dc, PyObject* textList, PyObject* pyPoints, + PyObject* foregroundList, PyObject* backgroundList); + //---------------------------------------------------------------------- #ifndef SWIGCODE @@ -270,6 +276,7 @@ struct wxPyCoreAPI { bool (*p_wxRealPoint_helper)(PyObject* source, wxRealPoint** obj); bool (*p_wxRect_helper)(PyObject* source, wxRect** obj); bool (*p_wxColour_helper)(PyObject* source, wxColour** obj); + bool (*p_wxPoint2DDouble_helper)(PyObject* source, wxPoint2DDouble** obj); void (*p_wxPyCBH_setCallbackInfo)(wxPyCallbackHelper& cbh, PyObject* self, PyObject* klass, int incref); bool (*p_wxPyCBH_findCallback)(const wxPyCallbackHelper& cbh, const char* name); @@ -403,18 +410,77 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); -//--------------------------------------------------------------------------- -// These macros are used to implement the virtual methods that should -// redirect to a Python method if one exists. The names designate the -// return type, if any, as well as any parameter types. //--------------------------------------------------------------------------- -#define PYPRIVATE \ +// This is used in C++ classes that need to be able to make callback to +// "overloaded" python methods + +#define PYPRIVATE \ void _setCallbackInfo(PyObject* self, PyObject* _class, int incref=1) { \ wxPyCBH_setCallbackInfo(m_myInst, self, _class, incref); \ - } \ + } \ private: wxPyCallbackHelper m_myInst + +//--------------------------------------------------------------------------- + +enum { + wxPYAPP_ASSERT_SUPPRESS = 1, + wxPYAPP_ASSERT_EXCEPTION = 2, + wxPYAPP_ASSERT_DIALOG = 4, + wxPYAPP_ASSERT_LOG = 8 +}; + +class wxPyApp: public wxApp +{ + DECLARE_ABSTRACT_CLASS(wxPyApp); + +public: + wxPyApp(); + ~wxPyApp(); + bool OnInit(); + int MainLoop(); + + int GetAssertMode() { return m_assertMode; } + void SetAssertMode(int mode) { m_assertMode = mode; } + + virtual bool OnInitGui(); + virtual int OnExit(); +#ifdef __WXDEBUG__ + virtual void OnAssert(const wxChar *file, + int line, + const wxChar *cond, + const wxChar *msg); +#endif + // virtual int FilterEvent(wxEvent& event); // This one too???? + + + static bool GetMacDefaultEncodingIsPC(); + static bool GetMacSupportPCMenuShortcuts(); + static long GetMacAboutMenuItemId(); + static long GetMacPreferencesMenuItemId(); + static long GetMacExitMenuItemId(); + static wxString GetMacHelpMenuTitleName(); + + static void SetMacDefaultEncodingIsPC(bool val); + static void SetMacSupportPCMenuShortcuts(bool val); + static void SetMacAboutMenuItemId(long val); + static void SetMacPreferencesMenuItemId(long val); + static void SetMacExitMenuItemId(long val); + static void SetMacHelpMenuTitleName(const wxString& val); + + + PYPRIVATE; + int m_assertMode; +}; + +extern wxPyApp *wxPythonApp; + + +//---------------------------------------------------------------------- +// These macros are used to implement the virtual methods that should +// redirect to a Python method if one exists. The names designate the +// return type, if any, as well as any parameter types. //--------------------------------------------------------------------------- #define DEC_PYCALLBACK__(CBNAME) \ @@ -425,10 +491,10 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); #define IMP_PYCALLBACK__(CLASS, PCLASS, CBNAME) \ void CLASS::CBNAME() { \ bool found; \ - wxPyBeginBlockThreads(); \ + wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) \ wxPyCBH_callCallback(m_myInst, Py_BuildValue("()")); \ - wxPyEndBlockThreads(); \ + wxPyEndBlockThreads(); \ if (! found) \ PCLASS::CBNAME(); \ } \ @@ -1173,6 +1239,34 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); //--------------------------------------------------------------------------- +#define DEC_PYCALLBACK_STRING__const(CBNAME) \ + wxString CBNAME() const; \ + wxString base_##CBNAME() const; + +#define IMP_PYCALLBACK_STRING__const(CLASS, PCLASS, CBNAME) \ + wxString CLASS::CBNAME() const { \ + wxString rval; \ + bool found; \ + wxPyBeginBlockThreads(); \ + if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ + PyObject* ro; \ + ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); \ + if (ro) { \ + rval = Py2wxString(ro); \ + Py_DECREF(ro); \ + } \ + } \ + wxPyEndBlockThreads(); \ + if (! found) \ + rval = PCLASS::CBNAME(); \ + return rval; \ + } \ + wxString CLASS::base_##CBNAME() const { \ + return PCLASS::CBNAME(); \ + } + +//--------------------------------------------------------------------------- + #define DEC_PYCALLBACK_STRING__pure(CBNAME) \ wxString CBNAME(); @@ -1203,7 +1297,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool rval=FALSE; \ wxPyBeginBlockThreads(); \ if (wxPyCBH_findCallback(m_myInst, #CBNAME)) { \ - PyObject* obj = wxPyConstructObject((void*)&a, "wxHtmlTag", 0); \ + PyObject* obj = wxPyConstructObject((void*)&a, wxT("wxHtmlTag"), 0); \ rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); \ Py_DECREF(obj); \ } \ @@ -1222,7 +1316,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool found; \ wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ - PyObject* obj = wxPyConstructObject((void*)cell, "wxHtmlCell", 0); \ + PyObject* obj = wxPyConstructObject((void*)cell, wxT("wxHtmlCell"), 0); \ wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(Oii)",obj,x,y)); \ Py_DECREF(obj); \ } \ @@ -1246,8 +1340,8 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool found; \ wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ - PyObject* obj = wxPyConstructObject((void*)cell, "wxHtmlCell", 0); \ - PyObject* o2 = wxPyConstructObject((void*)&e, "wxMouseEvent", 0); \ + PyObject* obj = wxPyConstructObject((void*)cell, wxT("wxHtmlCell"), 0); \ + PyObject* o2 = wxPyConstructObject((void*)&e, wxT("wxMouseEvent"), 0); \ wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(OiiO)",obj,x,y,o2)); \ Py_DECREF(obj); \ Py_DECREF(o2); \ @@ -1582,7 +1676,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool found; \ wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ - PyObject* obj = wxPyConstructObject((void*)&a, #Type, 0); \ + PyObject* obj = wxPyConstructObject((void*)&a, wxT(#Type), 0); \ wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); \ Py_DECREF(obj); \ } \ @@ -1607,7 +1701,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool found; \ wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ - PyObject* obj = wxPyConstructObject((void*)&a, #Type, 0); \ + PyObject* obj = wxPyConstructObject((void*)&a, wxT(#Type), 0); \ wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); \ Py_DECREF(obj); \ } \ @@ -1632,7 +1726,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool found; \ wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ - PyObject* obj = wxPyConstructObject((void*)&a, #Type, 0); \ + PyObject* obj = wxPyConstructObject((void*)&a, wxT(#Type), 0); \ rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); \ Py_DECREF(obj); \ } \ @@ -1656,7 +1750,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool rv=FALSE; \ wxPyBeginBlockThreads(); \ if (wxPyCBH_findCallback(m_myInst, #CBNAME)) { \ - PyObject* obj = wxPyConstructObject((void*)&a, #Type, 0); \ + PyObject* obj = wxPyConstructObject((void*)&a, wxT(#Type), 0); \ rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); \ Py_DECREF(obj); \ } \ @@ -1766,7 +1860,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); wxPyBeginBlockThreads(); \ if ((found = wxPyCBH_findCallback(m_myInst, #CBNAME))) { \ PyObject* ro; \ - PyObject* obj = wxPyConstructObject((void*)&e, "wxMouseEvent", 0); \ + PyObject* obj = wxPyConstructObject((void*)&e, wxT("wxMouseEvent"), 0); \ ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(O)",obj)); \ if (ro) { \ rval = PyInt_AsLong(ro); \ @@ -1851,6 +1945,29 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); //--------------------------------------------------------------------------- +#define DEC_PYCALLBACK_OBJECT_STRING_pure(CBNAME) \ + wxObject* CBNAME(const wxString& a); + +#define IMP_PYCALLBACK_OBJECT_STRING_pure(CLASS, PCLASS, CBNAME) \ + wxObject* CLASS::CBNAME(const wxString& a) { \ + wxObject* rv = NULL; \ + wxPyBeginBlockThreads(); \ + if (wxPyCBH_findCallback(m_myInst, #CBNAME)) { \ + PyObject* so = wx2PyString(a); \ + PyObject* ro; \ + ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(O)", so)); \ + if (ro) { \ + SWIG_GetPtrObj(ro, (void **)&rv, "_wxObject_p"); \ + Py_DECREF(ro); \ + } \ + Py_DECREF(so); \ + } \ + wxPyEndBlockThreads(); \ + return rv; \ + } + +//--------------------------------------------------------------------------- + #define DEC_PYCALLBACK_BOOL_NODE_pure(CBNAME) \ bool CBNAME(wxXmlNode* a); @@ -1860,7 +1977,7 @@ void wxPyCBH_delete(wxPyCallbackHelper* cbh); bool rv=FALSE; \ wxPyBeginBlockThreads(); \ if (wxPyCBH_findCallback(m_myInst, #CBNAME)) { \ - PyObject* obj = wxPyConstructObject((void*)a, "wxXmlNode", 0); \ + PyObject* obj = wxPyConstructObject((void*)a, wxT("wxXmlNode"), 0); \ rv = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); \ Py_DECREF(obj); \ } \ diff --git a/wxPython/src/html.i b/wxPython/src/html.i index 9d757ed813..7673a3637e 100644 --- a/wxPython/src/html.i +++ b/wxPython/src/html.i @@ -21,6 +21,7 @@ #include #include #include +#include #include "printfw.h" %} @@ -37,8 +38,10 @@ %extern controls.i %extern controls2.i %extern printfw.i - %extern utils.i +%extern filesys.i +%extern streams.i + %pragma(python) code = "import wx" @@ -158,7 +161,9 @@ public: void InitParser(const wxString& source); void DoneParser(); void DoParsing(int begin_pos, int end_pos); + void StopParsing(); // wxObject* GetProduct(); + void AddTagHandler(wxHtmlTagHandler *handler); wxString* GetSource(); void PushTagHandler(wxHtmlTagHandler* handler, wxString tags); @@ -415,6 +420,7 @@ public: %name(SetWidthFloatFromTag)void SetWidthFloat(const wxHtmlTag& tag); void SetMinHeight(int h, int align = wxHTML_ALIGN_TOP); void SetBackgroundColour(const wxColour& clr); + wxColour GetBackgroundColour(); void SetBorder(const wxColour& clr1, const wxColour& clr2); wxHtmlCell* GetFirstCell(); }; @@ -442,9 +448,75 @@ public: }; - //--------------------------------------------------------------------------- +// wxHtmlFilter +//--------------------------------------------------------------------------- + + +%{ // here's the C++ version +class wxPyHtmlFilter : public wxHtmlFilter { + DECLARE_ABSTRACT_CLASS(wxPyHtmlFilter); +public: + wxPyHtmlFilter() : wxHtmlFilter() {} + + // returns TRUE if this filter is able to open&read given file + virtual bool CanRead(const wxFSFile& file) const { + bool rval = FALSE; + bool found; + wxPyBeginBlockThreads(); + if ((found = wxPyCBH_findCallback(m_myInst, "CanRead"))) { + PyObject* obj = wxPyMake_wxObject((wxFSFile*)&file); // cast away const + rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); + Py_DECREF(obj); + } + wxPyEndBlockThreads(); + return rval; + } + + + // Reads given file and returns HTML document. + // Returns empty string if opening failed + virtual wxString ReadFile(const wxFSFile& file) const { + wxString rval; + bool found; + wxPyBeginBlockThreads(); + if ((found = wxPyCBH_findCallback(m_myInst, "ReadFile"))) { + PyObject* obj = wxPyMake_wxObject((wxFSFile*)&file); // cast away const + PyObject* ro; + ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(O)", obj)); + Py_DECREF(obj); + if (ro) { + rval = Py2wxString(ro); + Py_DECREF(ro); + } + } + wxPyEndBlockThreads(); + return rval; + } + + PYPRIVATE; +}; + +IMPLEMENT_ABSTRACT_CLASS(wxPyHtmlFilter, wxHtmlFilter); +%} + + +// And now the version seen by SWIG + +%name(wxHtmlFilter) class wxPyHtmlFilter : public wxObject { +public: + wxPyHtmlFilter(); + + void _setCallbackInfo(PyObject* self, PyObject* _class); + %pragma(python) addtomethod = "__init__:self._setCallbackInfo(self, wxHtmlFilter)" +}; + + +// TODO: wxHtmlFilterHTML + + //--------------------------------------------------------------------------- +// wxHtmlWindow //--------------------------------------------------------------------------- %{ @@ -455,7 +527,7 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxHW_SCROLLBAR_AUTO, - const wxString& name = "htmlWindow") + const wxString& name = wxPyHtmlWindowNameStr) : wxHtmlWindow(parent, id, pos, size, style, name) {}; wxPyHtmlWindow() : wxHtmlWindow() {}; @@ -478,7 +550,6 @@ public: DEC_PYCALLBACK__STRING(OnSetTitle); DEC_PYCALLBACK__CELLINTINT(OnCellMouseHover); DEC_PYCALLBACK__CELLINTINTME(OnCellClicked); -// DEC_PYCALLBACK_BOOL_STRING(OnOpeningURL); PYPRIVATE; }; @@ -486,14 +557,13 @@ IMPLEMENT_ABSTRACT_CLASS( wxPyHtmlWindow, wxHtmlWindow ); IMP_PYCALLBACK__STRING(wxPyHtmlWindow, wxHtmlWindow, OnSetTitle); IMP_PYCALLBACK__CELLINTINT(wxPyHtmlWindow, wxHtmlWindow, OnCellMouseHover); IMP_PYCALLBACK__CELLINTINTME(wxPyHtmlWindow, wxHtmlWindow, OnCellClicked); -// IMP_PYCALLBACK_BOOL_STRING(wxPyHtmlWindow, wxHtmlWindow, OnOpeningURL); void wxPyHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link) { bool found; wxPyBeginBlockThreads(); if ((found = wxPyCBH_findCallback(m_myInst, "OnLinkClicked"))) { - PyObject* obj = wxPyConstructObject((void*)&link, "wxHtmlLinkInfo", 0); + PyObject* obj = wxPyConstructObject((void*)&link, wxT("wxHtmlLinkInfo"), 0); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", obj)); Py_DECREF(obj); } @@ -564,18 +634,45 @@ public: %pragma(python) addtomethod = "__init__:self._setOORInfo(self)" %pragma(python) addtomethod = "wxPreHtmlWindow:val._setOORInfo(val)" + // Set HTML page and display it. !! source is HTML document itself, + // it is NOT address/filename of HTML document. If you want to + // specify document location, use LoadPage() istead + // Return value : FALSE if an error occured, TRUE otherwise bool SetPage(const wxString& source); + + // Load HTML page from given location. Location can be either + // a) /usr/wxGTK2/docs/html/wx.htm + // b) http://www.somewhere.uk/document.htm + // c) ftp://ftp.somesite.cz/pub/something.htm + // In case there is no prefix (http:,ftp:), the method + // will try to find it itself (1. local file, then http or ftp) + // After the page is loaded, the method calls SetPage() to display it. + // Note : you can also use path relative to previously loaded page + // Return value : same as SetPage bool LoadPage(const wxString& location); + + // Append to current page bool AppendToPage(const wxString& source); + + // Returns full location of opened page wxString GetOpenedPage(); + + // Returns anchor within opened page wxString GetOpenedAnchor(); + + // Returns of opened page or empty string otherwise wxString GetOpenedPageTitle(); + // Sets frame in which page title will be displayed. Format is format of + // frame title, e.g. "HtmlHelp : %s". It must contain exactly one %s void SetRelatedFrame(wxFrame* frame, const wxString& format); wxFrame* GetRelatedFrame(); + + // After(!) calling SetRelatedFrame, this sets statusbar slot where messages + // will be displayed. Default is -1 = no messages. void SetRelatedStatusBar(int bar); - //void SetFonts(wxString normal_face, wxString fixed_face, int *LIST); + // Sets fonts to be used when displaying HTML page. %addmethods { void SetFonts(wxString normal_face, wxString fixed_face, PyObject* sizes) { int* temp = int_LIST_helper(sizes); @@ -587,20 +684,39 @@ public: } void SetTitle(const wxString& title); + + // Sets space between text and window borders. void SetBorders(int b); + + // Saves custom settings into cfg config. it will use the path 'path' + // if given, otherwise it will save info into currently selected path. + // saved values : things set by SetFonts, SetBorders. void ReadCustomization(wxConfigBase *cfg, wxString path = wxPyEmptyString); void WriteCustomization(wxConfigBase *cfg, wxString path = wxPyEmptyString); + + // Goes to previous/next page (in browsing history) + // Returns TRUE if successful, FALSE otherwise bool HistoryBack(); bool HistoryForward(); bool HistoryCanBack(); bool HistoryCanForward(); + + // Resets History void HistoryClear(); + + // Returns pointer to conteiners/cells structure. wxHtmlContainerCell* GetInternalRepresentation(); + + // Returns a pointer to the parser. wxHtmlWinParser* GetParser(); bool ScrollToAnchor(const wxString& anchor); bool HasAnchor(const wxString& anchor); + //Adds input filter + static void AddFilter(wxPyHtmlFilter *filter); + + void base_OnLinkClicked(const wxHtmlLinkInfo& link); void base_OnSetTitle(const wxString& title); void base_OnCellMouseHover(wxHtmlCell *cell, wxCoord x, wxCoord y); @@ -609,12 +725,6 @@ public: const wxMouseEvent& event); }; -// Static methods are mapped to stand-alone functions -%inline %{ - void wxHtmlWindow_AddFilter(wxHtmlFilter *filter) { - wxHtmlWindow::AddFilter(filter); - } -%} //--------------------------------------------------------------------------- @@ -702,6 +812,7 @@ public: wxPyPtrTypeMap_Add("wxHtmlTagHandler", "wxPyHtmlTagHandler"); wxPyPtrTypeMap_Add("wxHtmlWinTagHandler", "wxPyHtmlWinTagHandler"); wxPyPtrTypeMap_Add("wxHtmlWindow", "wxPyHtmlWindow"); + wxPyPtrTypeMap_Add("wxHtmlFilter", "wxPyHtmlFilter"); %} //---------------------------------------------------------------------- diff --git a/wxPython/src/image.i b/wxPython/src/image.i index 84d1c7c5f0..7f125f11bc 100644 --- a/wxPython/src/image.i +++ b/wxPython/src/image.i @@ -179,6 +179,21 @@ public: return PyString_FromStringAndSize((char*)data, len); } + void SetDataBuffer(PyObject* data) { + unsigned char* buffer; + int size; + + if (!PyArg_Parse(data, "w#", &buffer, &size)) + return; + + if (size != self->GetWidth() * self->GetHeight() * 3) { + PyErr_SetString(PyExc_TypeError, "Incorrect buffer size"); + return; + } + + self->SetData(buffer); + } + void SetData(PyObject* data) { unsigned char* dataPtr; diff --git a/wxPython/src/misc.i b/wxPython/src/misc.i index 482f489f3b..1719b55c64 100644 --- a/wxPython/src/misc.i +++ b/wxPython/src/misc.i @@ -17,6 +17,7 @@ #include <wx/resource.h> #include <wx/tooltip.h> #include <wx/busyinfo.h> +#include <wx/geometry.h> %} //---------------------------------------------------------------------- @@ -79,22 +80,38 @@ public: return tup; } - int __cmp__(const wxSize* sz) { - if (! sz) return 1; - if (*self == *sz) return 0; - return -1; + bool __eq__(PyObject* obj) { + wxSize tmp; + wxSize* ptr = &tmp; + if (obj == Py_None) return FALSE; + wxPyBLOCK_THREADS(bool success = wxSize_helper(obj, &ptr); PyErr_Clear()); + if (! success) return FALSE; + return *self == *ptr; } + bool __ne__(PyObject* obj) { + wxSize tmp; + wxSize* ptr = &tmp; + if (obj == Py_None) return TRUE; + wxPyBLOCK_THREADS(bool success = wxSize_helper(obj, &ptr); PyErr_Clear()); + if (! success) return TRUE; + return *self != *ptr; + } + } %pragma(python) addtoclass = " def __str__(self): return str(self.asTuple()) - def __repr__(self): return str(self.asTuple()) + def __repr__(self): return 'wxSize'+str(self.asTuple()) def __len__(self): return len(self.asTuple()) def __getitem__(self, index): return self.asTuple()[index] def __setitem__(self, index, val): if index == 0: self.width = val elif index == 1: self.height = val else: raise IndexError + def __nonzero__(self): return self.asTuple() != (0,0) + def __getinitargs__(self): return () + def __getstate__(self): return self.asTuple() + def __setstate__(self, state): self.Set(*state) " }; @@ -122,31 +139,46 @@ public: return tup; } - wxRealPoint __add__(const wxRealPoint* p) { - if (! p) return *self; - return *self + *p; + wxRealPoint __add__(const wxRealPoint& p) { + return *self + p; } - wxRealPoint __sub__(const wxRealPoint* p) { - if (! p) return *self; - return *self - *p; + wxRealPoint __sub__(const wxRealPoint& p) { + return *self - p; } - int __cmp__(const wxRealPoint* p) { - if (! p) return 1; - if (*self == *p) return 0; - return -1; + bool __eq__(PyObject* obj) { + wxRealPoint tmp; + wxRealPoint* ptr = &tmp; + if (obj == Py_None) return FALSE; + wxPyBLOCK_THREADS(bool success = wxRealPoint_helper(obj, &ptr); PyErr_Clear()); + if (! success) return FALSE; + return *self == *ptr; } + bool __ne__(PyObject* obj) { + wxRealPoint tmp; + wxRealPoint* ptr = &tmp; + if (obj == Py_None) return TRUE; + wxPyBLOCK_THREADS(bool success = wxRealPoint_helper(obj, &ptr); PyErr_Clear()); + if (! success) return TRUE; + return *self != *ptr; + } + } + %pragma(python) addtoclass = " def __str__(self): return str(self.asTuple()) - def __repr__(self): return str(self.asTuple()) + def __repr__(self): return 'wxRealPoint'+str(self.asTuple()) def __len__(self): return len(self.asTuple()) def __getitem__(self, index): return self.asTuple()[index] def __setitem__(self, index, val): if index == 0: self.width = val elif index == 1: self.height = val else: raise IndexError + def __nonzero__(self): return self.asTuple() != (0.0, 0.0) + def __getinitargs__(self): return () + def __getstate__(self): return self.asTuple() + def __setstate__(self, state): self.Set(*state) " }; @@ -172,31 +204,46 @@ public: return tup; } - wxPoint __add__(const wxPoint* p) { - if (! p) return *self; - return *self + *p; + wxPoint __add__(const wxPoint& p) { + return *self + p; } - wxPoint __sub__(const wxPoint* p) { - if (! p) return *self; - return *self - *p; + wxPoint __sub__(const wxPoint& p) { + return *self - p; } - int __cmp__(const wxPoint* p) { - if (! p) return 1; - if (*self == *p) return 0; - return -1; + bool __eq__(PyObject* obj) { + wxPoint tmp; + wxPoint* ptr = &tmp; + if (obj == Py_None) return FALSE; + wxPyBLOCK_THREADS(bool success = wxPoint_helper(obj, &ptr); PyErr_Clear()); + if (! success) return FALSE; + return *self == *ptr; + } + bool __ne__(PyObject* obj) { + wxPoint tmp; + wxPoint* ptr = &tmp; + if (obj == Py_None) return TRUE; + wxPyBLOCK_THREADS(bool success = wxPoint_helper(obj, &ptr); PyErr_Clear()); + if (! success) return TRUE; + return *self != *ptr; } + } + %pragma(python) addtoclass = " def __str__(self): return str(self.asTuple()) - def __repr__(self): return str(self.asTuple()) + def __repr__(self): return 'wxPoint'+str(self.asTuple()) def __len__(self): return len(self.asTuple()) def __getitem__(self, index): return self.asTuple()[index] def __setitem__(self, index, val): if index == 0: self.x = val elif index == 1: self.y = val else: raise IndexError + def __nonzero__(self): return self.asTuple() != (0,0) + def __getinitargs__(self): return () + def __getstate__(self): return self.asTuple() + def __setstate__(self, state): self.Set(*state) " }; @@ -204,7 +251,7 @@ public: class wxRect { public: - wxRect(int x=0, int y=0, int w=0, int h=0); + wxRect(int x=0, int y=0, int width=0, int height=0); // TODO: do this one too... wxRect(const wxPoint& pos, const wxSize& size); ~wxRect(); @@ -233,12 +280,24 @@ public: void SetTop(int top); void SetBottom(int bottom); + void Deflate(int dx, int dy); void Inflate(int dx, int dy); - bool Inside(int cx, int cy); + %name(InsideXY)bool Inside(int cx, int cy); + bool Inside(const wxPoint& pt); + bool Intersects(const wxRect& rect); + %name(OffsetXY) void Offset(int dx, int dy); + void Offset(const wxPoint& pt); int x, y, width, height; %addmethods { + void Set(int x=0, int y=0, int width=0, int height=0) { + self->x = x; + self->y = y; + self->width = width; + self->height = height; + } + PyObject* asTuple() { wxPyBeginBlockThreads(); PyObject* tup = PyTuple_New(4); @@ -250,21 +309,32 @@ public: return tup; } - wxRect __add__(const wxRect* rect) { - if (! rect) return *self; - return *self + *rect; + wxRect __add__(const wxRect& rect) { + return *self + rect; } - int __cmp__(const wxRect* rect) { - if (! rect) return 1; - if (*self == *rect) return 0; - return -1; + bool __eq__(PyObject* obj) { + wxRect tmp; + wxRect* ptr = &tmp; + if (obj == Py_None) return FALSE; + wxPyBLOCK_THREADS(bool success = wxRect_helper(obj, &ptr); PyErr_Clear()); + if (! success) return FALSE; + return *self == *ptr; + } + bool __ne__(PyObject* obj) { + wxRect tmp; + wxRect* ptr = &tmp; + if (obj == Py_None) return TRUE; + wxPyBLOCK_THREADS(bool success = wxRect_helper(obj, &ptr); PyErr_Clear()); + if (! success) return TRUE; + return *self != *ptr; } + } %pragma(python) addtoclass = " def __str__(self): return str(self.asTuple()) - def __repr__(self): return str(self.asTuple()) + def __repr__(self): return 'wxRect'+str(self.asTuple()) def __len__(self): return len(self.asTuple()) def __getitem__(self, index): return self.asTuple()[index] def __setitem__(self, index, val): @@ -273,6 +343,10 @@ public: elif index == 2: self.width = val elif index == 3: self.height = val else: raise IndexError + def __nonzero__(self): return self.asTuple() != (0,0,0,0) + def __getinitargs__(self): return () + def __getstate__(self): return self.asTuple() + def __setstate__(self, state): self.Set(*state) # override the __getattr__ made by SWIG def __getattr__(self, name): @@ -328,7 +402,7 @@ public: if (dest != wxRect(0,0,0,0)) { wxPyBeginBlockThreads(); wxRect* newRect = new wxRect(dest); - obj = wxPyConstructObject((void*)newRect, "wxRect"); + obj = wxPyConstructObject((void*)newRect, wxT("wxRect")); PyObject* one = PyInt_FromLong(1); PyObject_SetAttrString(obj, "thisown", one); Py_DECREF(one); @@ -341,13 +415,116 @@ public: %} + +//--------------------------------------------------------------------------- +// wxPoint2Ds represent a point or a vector in a 2d coordinate system + +class wxPoint2DDouble +{ +public: + double m_x; + double m_y; + + %name(x)double m_x; + %name(y)double m_y; + + wxPoint2DDouble( double x=0 , double y=0 ); + %name(wxPoint2DDoubleCopy)wxPoint2DDouble( const wxPoint2DDouble &pt ); + %name(wxPoint2DDoubleFromPoint)wxPoint2DDouble( const wxPoint &pt ); + + // two different conversions to integers, floor and rounding + void GetFloor( int* OUTPUT , int* OUTPUT ) const; + void GetRounded( int* OUTPUT , int* OUTPUT ) const; + + double GetVectorLength() const; + double GetVectorAngle() const ; + void SetVectorLength( double length ); + void SetVectorAngle( double degrees ); + // LinkError: void SetPolarCoordinates( double angle , double length ); + // LinkError: void Normalize(); + %pragma(python) addtoclass = " + def SetPolarCoordinates(self, angle, length): + self.SetVectorLength(length) + self.SetVectorAngle(angle) + def Normalize(self): + self.SetVectorLength(1.0) + " + + double GetDistance( const wxPoint2DDouble &pt ) const; + double GetDistanceSquare( const wxPoint2DDouble &pt ) const; + double GetDotProduct( const wxPoint2DDouble &vec ) const; + double GetCrossProduct( const wxPoint2DDouble &vec ) const; + + %addmethods { + void Set( double x=0 , double y=0 ) { + self->m_x = x; + self->m_y = y; + } + + // the reflection of this point + wxPoint2DDouble __neg__() { return -(*self); } + + wxPoint2DDouble& __iadd__(const wxPoint2DDouble& pt) { return (*self) += pt; } + wxPoint2DDouble& __isub__(const wxPoint2DDouble& pt) { return (*self) -= pt; } + wxPoint2DDouble& __imul__(const wxPoint2DDouble& pt) { return (*self) *= pt; } + wxPoint2DDouble& __idiv__(const wxPoint2DDouble& pt) { return (*self) /= pt; } + + // TODO: + //wxPoint2DDouble& operator*=(double n); + //wxPoint2DDouble& operator*=(int n); + //wxPoint2DDouble& operator/=(double n); + //wxPoint2DDouble& operator/=(int n); + + bool __eq__(PyObject* obj) { + wxPoint2DDouble tmp; + wxPoint2DDouble* ptr = &tmp; + if (obj == Py_None) return FALSE; + wxPyBLOCK_THREADS(bool success = wxPoint2DDouble_helper(obj, &ptr); PyErr_Clear()); + if (! success) return FALSE; + return *self == *ptr; + } + bool __ne__(PyObject* obj) { + wxPoint2DDouble tmp; + wxPoint2DDouble* ptr = &tmp; + if (obj == Py_None) return TRUE; + wxPyBLOCK_THREADS(bool success = wxPoint2DDouble_helper(obj, &ptr); PyErr_Clear()); + if (! success) return TRUE; + return *self != *ptr; + } + + + PyObject* asTuple() { + wxPyBeginBlockThreads(); + PyObject* tup = PyTuple_New(2); + PyTuple_SET_ITEM(tup, 0, PyFloat_FromDouble(self->m_x)); + PyTuple_SET_ITEM(tup, 1, PyFloat_FromDouble(self->m_y)); + wxPyEndBlockThreads(); + return tup; + } + } + + %pragma(python) addtoclass = " + def __str__(self): return str(self.asTuple()) + def __repr__(self): return 'wxPoint2DDouble'+str(self.asTuple()) + def __len__(self): return len(self.asTuple()) + def __getitem__(self, index): return self.asTuple()[index] + def __setitem__(self, index, val): + if index == 0: self.m_x = val + elif index == 1: self.m_yt = val + else: raise IndexError + def __nonzero__(self): return self.asTuple() != (0.0, 0.0) + def __getinitargs__(self): return () + def __getstate__(self): return self.asTuple() + def __setstate__(self, state): self.Set(*state) +" +}; + + //--------------------------------------------------------------------------- // Miscellaneous functions long wxNewId(); void wxRegisterId(long id); -%name(NewId) long wxNewId(); -%name(RegisterId) void wxRegisterId(long id); long wxGetCurrentId(); void wxBell(); @@ -381,14 +558,16 @@ bool wxYield(); bool wxYieldIfNeeded(); void wxEnableTopLevelWindows(bool enable); -%inline %{ +#ifdef wxUSE_RESOURCES +inline %{ wxString wxGetResource(const wxString& section, const wxString& entry, const wxString& file = wxPyEmptyString) { - wxChar * retval; + wxChar* retval; wxGetResource(section, entry, &retval, file); return retval; } %} +#endif wxString wxStripMenuCodes(const wxString& in); diff --git a/wxPython/src/misc2.i b/wxPython/src/misc2.i index db800a4455..15edd72de2 100644 --- a/wxPython/src/misc2.i +++ b/wxPython/src/misc2.i @@ -183,6 +183,7 @@ wxWindow* wxGetTopLevelParent(wxWindow *win); //--------------------------------------------------------------------------- // Resource System +#ifdef wxUSE_WX_RESOURCES bool wxResourceAddIdentifier(char* name, int value); void wxResourceClear(void); wxBitmap wxResourceCreateBitmap(char* resource); @@ -192,6 +193,7 @@ int wxResourceGetIdentifier(char* name); bool wxResourceParseData(char* resource, wxResourceTable *table = NULL); bool wxResourceParseFile(char* filename, wxResourceTable *table = NULL); bool wxResourceParseString(char* resource, wxResourceTable *table = NULL); +#endif //--------------------------------------------------------------------------- // System Settings @@ -407,7 +409,7 @@ public: //---------------------------------------------------------------------- -bool wxSafeYield(wxWindow* win=NULL); +bool wxSafeYield(wxWindow* win=NULL, bool onlyIfNeeded=FALSE); void wxPostEvent(wxEvtHandler *dest, wxEvent& event); void wxWakeUpIdle(); @@ -509,8 +511,10 @@ public: bool BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen = FALSE, wxRect* rect = NULL); - %name(BeginDrag2) bool BeginDrag(const wxPoint& hotspot, wxWindow* window, - wxWindow* fullScreenRect); + %name(BeginDragBounded) bool BeginDrag(const wxPoint& hotspot, wxWindow* window, + wxWindow* boundingWindow); + + %pragma(python) addtoclass = "BeginDrag2 = BeginDragBounded" bool EndDrag(); bool Move(const wxPoint& pt); @@ -629,6 +633,10 @@ public: static unsigned long GetTraceMask(); static bool IsAllowedTraceMask(const wxString& mask); + static void SetLogLevel(unsigned long logLevel); + static unsigned long GetLogLevel(); + + // static void TimeStamp(wxString *str); %addmethods { wxString TimeStamp() { @@ -695,6 +703,7 @@ void wxLogError(const wxString& msg); void wxLogWarning(const wxString& msg); void wxLogMessage(const wxString& msg); void wxLogInfo(const wxString& msg); +void wxLogDebug(const wxString& msg); void wxLogVerbose(const wxString& msg); void wxLogStatus(const wxString& msg); %name(wxLogStatusFrame)void wxLogStatus(wxFrame *pFrame, const wxString& msg); @@ -1108,10 +1117,10 @@ class wxFileTypeInfo public: // ctors // a normal item - wxFileTypeInfo(const char* mimeType, - const char* openCmd, - const char* printCmd, - const char* desc); + wxFileTypeInfo(const wxString& mimeType, + const wxString& openCmd, + const wxString& printCmd, + const wxString& desc); // the array elements correspond to the parameters of the ctor above in @@ -1205,7 +1214,7 @@ public: wxString str; if (self->GetMimeType(&str)) { #if wxUSE_UNICODE - return PyUnicode_FromUnicode(str.c_str(), str.Len()); + return PyUnicode_FromWideChar(str.c_str(), str.Len()); #else return PyString_FromStringAndSize(str.c_str(), str.Len()); #endif @@ -1255,9 +1264,9 @@ public: wxPyBeginBlockThreads(); PyObject* tuple = PyTuple_New(3); PyTuple_SetItem(tuple, 0, wxPyConstructObject(new wxIcon(icon), - "wxIcon", TRUE)); + wxT("wxIcon"), TRUE)); #if wxUSE_UNICODE - PyTuple_SetItem(tuple, 1, PyUnicode_FromUnicode(iconFile.c_str(), iconFile.Len())); + PyTuple_SetItem(tuple, 1, PyUnicode_FromWideChar(iconFile.c_str(), iconFile.Len())); #else PyTuple_SetItem(tuple, 1, PyString_FromStringAndSize(iconFile.c_str(), iconFile.Len())); #endif @@ -1276,7 +1285,7 @@ public: wxString str; if (self->GetDescription(&str)) { #if wxUSE_UNICODE - return PyUnicode_FromUnicode(str.c_str(), str.Len()); + return PyUnicode_FromWideChar(str.c_str(), str.Len()); #else return PyString_FromStringAndSize(str.c_str(), str.Len()); #endif @@ -1293,7 +1302,7 @@ public: wxString str; if (self->GetOpenCommand(&str, wxFileType::MessageParameters(filename, mimetype))) { #if wxUSE_UNICODE - return PyUnicode_FromUnicode(str.c_str(), str.Len()); + return PyUnicode_FromWideChar(str.c_str(), str.Len()); #else return PyString_FromStringAndSize(str.c_str(), str.Len()); #endif @@ -1310,7 +1319,7 @@ public: wxString str; if (self->GetPrintCommand(&str, wxFileType::MessageParameters(filename, mimetype))) { #if wxUSE_UNICODE - return PyUnicode_FromUnicode(str.c_str(), str.Len()); + return PyUnicode_FromWideChar(str.c_str(), str.Len()); #else return PyString_FromStringAndSize(str.c_str(), str.Len()); #endif @@ -1525,7 +1534,7 @@ public: wxBitmap rval = wxNullBitmap; wxPyBeginBlockThreads(); if ((wxPyCBH_findCallback(m_myInst, "CreateBitmap"))) { - PyObject* so = wxPyConstructObject((void*)&size, "wxSize", 0); + PyObject* so = wxPyConstructObject((void*)&size, wxT("wxSize"), 0); PyObject* ro; wxBitmap* ptr; PyObject* s1, *s2; @@ -1580,8 +1589,6 @@ public: const wxString& client = wxPyART_OTHER, const wxSize& size = wxDefaultSize); - // Destroy caches & all providers - static void CleanUpProviders(); }; @@ -1691,7 +1698,7 @@ public: // #define ADD_STRING(dict, str) \ // wxString tmp##str(str); \ // PyDict_SetItemString(dict, #str, \ -// PyUnicode_FromUnicode(tmp##str.c_str(), tmp##str.Len())) +// PyUnicode_FromWideChar(tmp##str.c_str(), tmp##str.Len())) // #else // #define ADD_STRING(dict, str) \ // PyDict_SetItemString(d, #str, PyString_FromString(str)) diff --git a/wxPython/src/my_typemaps.i b/wxPython/src/my_typemaps.i index 7f5ccb9443..4a3e33a01a 100644 --- a/wxPython/src/my_typemaps.i +++ b/wxPython/src/my_typemaps.i @@ -168,7 +168,7 @@ $function %typemap(python, out) wxString { #if wxUSE_UNICODE - $target = PyUnicode_FromUnicode($source->c_str(), $source->Len()); + $target = PyUnicode_FromWideChar($source->c_str(), $source->Len()); #else $target = PyString_FromStringAndSize($source->c_str(), $source->Len()); #endif @@ -180,7 +180,7 @@ $function %typemap(python, out) wxString* { #if wxUSE_UNICODE - $target = PyUnicode_FromUnicode($source->c_str(), $source->Len()); + $target = PyUnicode_FromWideChar($source->c_str(), $source->Len()); #else $target = PyString_FromStringAndSize($source->c_str(), $source->Len()); #endif @@ -244,6 +244,12 @@ $function return NULL; } +%typemap(python,in) wxPoint2DDouble& (wxPoint2DDouble temp) { + $target = &temp; + if (! wxPoint2DDouble_helper($source, &$target)) + return NULL; +} + //--------------------------------------------------------------------------- // Typemap to convert strings to wxColour. Two string formats are accepted, // either a colour name, or a hex colour spec like "#RRGGBB" @@ -268,11 +274,10 @@ $function PyObject* item = PySequence_GetItem($source, i); #if wxUSE_UNICODE PyObject* str = PyObject_Unicode(item); - $target->Add(PyUnicode_AsUnicode(str)); #else PyObject* str = PyObject_Str(item); - $target->Add(PyString_AsString(str)); #endif + $target->Add(Py2wxString(str)); Py_DECREF(item); Py_DECREF(str); } @@ -308,6 +313,29 @@ $function } +// Typemaps to convert an array of ints to a list +%typemap(python, out) wxArrayInt& { + $target = PyList_New(0); + size_t idx; + for (idx = 0; idx < $source->GetCount(); idx += 1) { + PyObject* val = PyInt_FromLong($source->Item(idx)); + PyList_Append($target, val); + Py_DECREF(val); + } +} + +%typemap(python, out) wxArrayInt { + $target = PyList_New(0); + size_t idx; + for (idx = 0; idx < $source->GetCount(); idx += 1) { + PyObject* val = PyInt_FromLong($source->Item(idx)); + PyList_Append($target, val); + Py_DECREF(val); + } + delete $source; +} + + //--------------------------------------------------------------------------- // Map T_OUTPUTs for floats to return ints. @@ -360,6 +388,11 @@ $function %typemap(python,ignore) byte *OUTPUT = byte *T_OUTPUT; %typemap(python,argout) byte *OUTPUT = byte *T_OUTPUT; + +%typemap(python,ignore) wxCoord *OUTPUT = int *OUTPUT; +%typemap(python,argout) wxCoord *OUTPUT = int *OUTPUT; + + //--------------------------------------------------------------------------- // Typemaps to convert return values that are base class pointers // to the real derived type, if possible. See wxPyMake_wxObject in @@ -369,6 +402,8 @@ $function %typemap(python, out) wxMenu* { $target = wxPyMake_wxObject($source); } %typemap(python, out) wxValidator* { $target = wxPyMake_wxObject($source); } +%typemap(python, out) wxApp* { $target = wxPyMake_wxObject($source); } +%typemap(python, out) wxPyApp* { $target = wxPyMake_wxObject($source); } %typemap(python, out) wxDC* { $target = wxPyMake_wxObject($source); } %typemap(python, out) wxFSFile* { $target = wxPyMake_wxObject($source); } %typemap(python, out) wxFileSystem* { $target = wxPyMake_wxObject($source); } diff --git a/wxPython/src/pyistream.h b/wxPython/src/pyistream.h index 5dcd924779..930af405c4 100644 --- a/wxPython/src/pyistream.h +++ b/wxPython/src/pyistream.h @@ -50,6 +50,19 @@ public: void write(wxString data); void writelines(wxStringPtrList); */ + + // wxInputStream methods that may come in handy... + + char Peek() { if (m_wxis) return m_wxis->Peek(); else return -1; } + char GetC() { if (m_wxis) return m_wxis->GetC(); else return -1; } + size_t LastRead() { if (m_wxis) return m_wxis->LastRead(); else return 0; } + bool CanRead() { if (m_wxis) return m_wxis->CanRead(); else return FALSE; } + bool Eof() { if (m_wxis) return m_wxis->Eof(); else return FALSE; } + bool Ungetch(char c) { if (m_wxis) return m_wxis->Ungetch(c); else return FALSE; } + + unsigned long SeekI(unsigned long pos, wxSeekMode mode) + { if (m_wxis) return m_wxis->SeekI(pos, mode); else return 0; } + unsigned long TellI() { if (m_wxis) return m_wxis->TellI(); else return 0; } }; diff --git a/wxPython/src/sizers.i b/wxPython/src/sizers.i index 75ff5e3969..b841dd758c 100644 --- a/wxPython/src/sizers.i +++ b/wxPython/src/sizers.i @@ -30,7 +30,6 @@ %import controls.i %pragma(python) code = "import wx" -%pragma(python) code = "import string" //--------------------------------------------------------------------------- @@ -39,16 +38,20 @@ class wxSizerItem : public wxObject { public: // No need to ever create one directly in Python... - //wxSizerItem( int width, int height, int option, int flag, int border, wxObject* userData); - //wxSizerItem( wxWindow *window, int option, int flag, int border, wxObject* userData ); - //wxSizerItem( wxSizer *sizer, int option, int flag, int border, wxObject* userData ); + //wxSizerItem( int width, int height, int proportion, int flag, int border, wxObject* userData); + //wxSizerItem( wxWindow *window, int proportion, int flag, int border, wxObject* userData ); + //wxSizerItem( wxSizer *sizer, int proportion, int flag, int border, wxObject* userData ); void DeleteWindows(); + void DetachSizer(); - wxPoint GetPosition(); wxSize GetSize(); wxSize CalcMin(); void SetDimension( wxPoint pos, wxSize size ); + + wxSize GetMinSize(); + void SetInitSize( int x, int y ); + %name(SetRatioWH) void SetRatio( int width, int height ); %name(SetRatioSize) void SetRatio( wxSize size ); void SetRatio( float ratio ); @@ -58,18 +61,26 @@ public: bool IsSizer(); bool IsSpacer(); + void SetProportion( int proportion ); + int GetProportion(); + %pragma(python) addtoclass = "SetOption = SetProportion" + %pragma(python) addtoclass = "GetOption = GetProportion" + void SetFlag( int flag ); + int GetFlag(); + void SetBorder( int border ); + int GetBorder(); + wxWindow *GetWindow(); void SetWindow( wxWindow *window ); wxSizer *GetSizer(); void SetSizer( wxSizer *sizer ); - int GetOption(); - int GetFlag(); - int GetBorder(); + const wxSize& GetSpacer(); + void SetSpacer( const wxSize &size ); - void SetInitSize( int x, int y ); - void SetOption( int option ); - void SetFlag( int flag ); - void SetBorder( int border ); + void Show( bool show ); + bool IsShown(); + + wxPoint GetPosition(); // wxObject* GetUserData(); %addmethods { @@ -104,103 +115,127 @@ public: %addmethods { void Destroy() { delete self; } - void AddWindow(wxWindow *window, int option=0, int flag=0, int border=0, + void AddWindow(wxWindow *window, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Add(window, option, flag, border, data); + self->Add(window, proportion, flag, border, data); } - void AddSizer(wxSizer *sizer, int option=0, int flag=0, int border=0, + void AddSizer(wxSizer *sizer, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Add(sizer, option, flag, border, data); + self->Add(sizer, proportion, flag, border, data); } - void AddSpacer(int width, int height, int option=0, int flag=0, + void AddSpacer(int width, int height, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Add(width, height, option, flag, border, data); + self->Add(width, height, proportion, flag, border, data); } - - void InsertWindow(int before, wxWindow *window, int option=0, int flag=0, + void InsertWindow(int before, wxWindow *window, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Insert(before, window, option, flag, border, data); + self->Insert(before, window, proportion, flag, border, data); } - void InsertSizer(int before, wxSizer *sizer, int option=0, int flag=0, + void InsertSizer(int before, wxSizer *sizer, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Insert(before, sizer, option, flag, border, data); + self->Insert(before, sizer, proportion, flag, border, data); } - void InsertSpacer(int before, int width, int height, int option=0, int flag=0, + void InsertSpacer(int before, int width, int height, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Insert(before, width, height, option, flag, border, data); + self->Insert(before, width, height, proportion, flag, border, data); } - void PrependWindow(wxWindow *window, int option=0, int flag=0, int border=0, + void PrependWindow(wxWindow *window, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Prepend(window, option, flag, border, data); + self->Prepend(window, proportion, flag, border, data); } - void PrependSizer(wxSizer *sizer, int option=0, int flag=0, int border=0, + void PrependSizer(wxSizer *sizer, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Prepend(sizer, option, flag, border, data); + self->Prepend(sizer, proportion, flag, border, data); } - void PrependSpacer(int width, int height, int option=0, int flag=0, + void PrependSpacer(int width, int height, int proportion=0, int flag=0, int border=0, PyObject* userData=NULL) { wxPyUserData* data = NULL; if (userData) data = new wxPyUserData(userData); - self->Prepend(width, height, option, flag, border, data); + self->Prepend(width, height, proportion, flag, border, data); } + + // TODO: AddItem, InsertItem, PrependItem + } - %name(RemoveWindow)bool Remove( wxWindow *window ); + %name(RemoveWindow)bool Remove( wxWindow *window ); // TODO: This is DEPRECATED. Should all be removed? %name(RemoveSizer)bool Remove( wxSizer *sizer ); %name(RemovePos)bool Remove( int pos ); + %name(DetachWindow)bool Detach( wxWindow *window ); + %name(DetachSizer)bool Detach( wxSizer *sizer ); + %name(DetachPos)bool Detach( int pos ); + %pragma(python) addtoclass = " def Add(self, *args, **kw): if type(args[0]) == type(1): apply(self.AddSpacer, args, kw) - elif string.find(args[0].this, 'Sizer') != -1: + elif isinstance(args[0], wxSizerPtr): apply(self.AddSizer, args, kw) - else: + elif isinstance(args[0], wxWindowPtr): apply(self.AddWindow, args, kw) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' def Insert(self, *args, **kw): if type(args[1]) == type(1): apply(self.InsertSpacer, args, kw) - elif string.find(args[1].this, 'Sizer') != -1: + elif isinstance(args[1], wxSizerPtr): apply(self.InsertSizer, args, kw) - else: + elif isinstance(args[1], wxWindowPtr): apply(self.InsertWindow, args, kw) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' def Prepend(self, *args, **kw): if type(args[0]) == type(1): apply(self.PrependSpacer, args, kw) - elif string.find(args[0].this, 'Sizer') != -1: + elif isinstance(args[0], wxSizerPtr): apply(self.PrependSizer, args, kw) - else: + elif isinstance(args[0], wxWindowPtr): apply(self.PrependWindow, args, kw) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' def Remove(self, *args, **kw): if type(args[0]) == type(1): - apply(self.RemovePos, args, kw) - elif string.find(args[0].this, 'Sizer') != -1: - apply(self.RemoveSizer, args, kw) + return apply(self.RemovePos, args, kw) + elif isinstance(args[0], wxSizerPtr): + return apply(self.RemoveSizer, args, kw) + elif isinstance(args[0], wxWindowPtr): + return apply(self.RemoveWindow, args, kw) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' + + def Detach(self, *args, **kw): + if type(args[0]) == type(1): + return apply(self.DetachPos, args, kw) + elif isinstance(args[0], wxSizerPtr): + return apply(self.DetachSizer, args, kw) + elif isinstance(args[0], wxWindowPtr): + return apply(self.DetachWindow, args, kw) else: - apply(self.RemoveWindow, args, kw) + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' def AddMany(self, widgets): for childinfo in widgets: @@ -209,22 +244,38 @@ public: apply(self.Add, childinfo) " + void Clear( bool delete_windows = false ); + void DeleteWindows(); - void SetDimension( int x, int y, int width, int height ); void SetMinSize(wxSize size); - %name(SetItemMinSizeWindow) void SetItemMinSize(wxWindow* window, int width, int height); - %name(SetItemMinSizeSizer) void SetItemMinSize(wxSizer* sizer, int width, int height); - %name(SetItemMinSizePos) void SetItemMinSize(int pos, int width, int height); + %name(SetItemMinSizeWindow) void SetItemMinSize(wxWindow* window, wxSize size); + %name(SetItemMinSizeSizer) void SetItemMinSize(wxSizer* sizer, wxSize size); + %name(SetItemMinSizePos) void SetItemMinSize(int pos, wxSize size); + %name(SetItemMinSizeWindowWH) void SetItemMinSize(wxWindow* window, int width, int height); + %name(SetItemMinSizeSizerWH) void SetItemMinSize(wxSizer* sizer, int width, int height); + %name(SetItemMinSizePosWH) void SetItemMinSize(int pos, int width, int height); %pragma(python) addtoclass = " def SetItemMinSize(self, *args): if type(args[0]) == type(1): apply(self.SetItemMinSizePos, args) - elif string.find(args[0].this, 'Sizer') != -1: + elif isinstance(args[0], wxSizerPtr): apply(self.SetItemMinSizeSizer, args) - else: + elif isinstance(args[0], wxWindowPtr): apply(self.SetItemMinSizeWindow, args) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' + + def SetItemMinSizeWH(self, *args): + if type(args[0]) == type(1): + apply(self.SetItemMinSizePosWH, args) + elif isinstance(args[0], wxSizerPtr): + apply(self.SetItemMinSizeSizerWH, args) + elif isinstance(args[0], wxWindowPtr): + apply(self.SetItemMinSizeWindowWH, args) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' " wxSize GetSize(); @@ -251,17 +302,64 @@ public: void SetSizeHints( wxWindow *window ); void SetVirtualSizeHints( wxWindow *window ); - void Clear( bool delete_windows=FALSE ); - void DeleteWindows(); - // wxList& GetChildren(); %addmethods { PyObject* GetChildren() { - wxList& list = self->GetChildren(); + wxSizerItemList& list = self->GetChildren(); return wxPy_ConvertList(&list, "wxSizerItem"); } } + + void SetDimension( int x, int y, int width, int height ); + + // Manage whether individual windows or sub-sizers are considered + // in the layout calculations or not. + %name(ShowWindow)void Show( wxWindow *window, bool show = TRUE ); + %name(ShowSizer)void Show( wxSizer *sizer, bool show = TRUE ); + %name(ShowPos)void Show( size_t index, bool show = TRUE ); + %name(HideWindow)void Hide( wxWindow *window ); + %name(HideSizer)void Hide( wxSizer *sizer ); + %name(HidePos)void Hide( size_t index ); + %name(IsShownWindow)bool IsShown( wxWindow *window ); + %name(IsShownSizer)bool IsShown( wxSizer *sizer ); + %name(IsShownPos)bool IsShown( size_t index ); + + %pragma(python) addtoclass = " + def Show(self, *args): + if type(args[0]) == type(1): + apply(self.ShowPos, args) + elif isinstance(args[0], wxSizerPtr): + apply(self.ShowSizer, args) + elif isinstance(args[0], wxWindowPtr): + apply(self.ShowWindow, args) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' + + def Hide(self, *args): + if type(args[0]) == type(1): + apply(self.HidePos, args) + elif isinstance(args[0], wxSizerPtr): + apply(self.HideSizer, args) + elif isinstance(args[0], wxWindowPtr): + apply(self.HideWindow, args) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' + + def IsShown(self, *args): + if type(args[0]) == type(1): + return apply(self.IsShownPos, args) + elif isinstance(args[0], wxSizerPtr): + return apply(self.IsShownSizer, args) + elif isinstance(args[0], wxWindowPtr): + return apply(self.IsShownWindow, args) + else: + raise TypeError, 'Expected int, wxSizer or wxWindow parameter' +" + + // Recursively call wxWindow::Show () on all sizer items. + void ShowItems (bool show); + }; @@ -303,6 +401,7 @@ public: wxBoxSizer(int orient = wxHORIZONTAL); %pragma(python) addtomethod = "__init__:self._setOORInfo(self)" int GetOrientation(); + void SetOrientation(int orient); void RecalcSizes(); wxSize CalcMin(); }; @@ -352,6 +451,19 @@ public: //--------------------------------------------------------------------------- +enum wxFlexSizerGrowMode +{ + // don't resize the cells in non-flexible direction at all + wxFLEX_GROWMODE_NONE, + + // uniformly resize only the specified ones (default) + wxFLEX_GROWMODE_SPECIFIED, + + // uniformly resize all cells + wxFLEX_GROWMODE_ALL +}; + + class wxFlexGridSizer: public wxGridSizer { public: @@ -361,11 +473,22 @@ public: void RecalcSizes(); wxSize CalcMin(); - void AddGrowableRow( size_t idx ); + void AddGrowableRow( size_t idx, int proportion = 0 ); void RemoveGrowableRow( size_t idx ); - void AddGrowableCol( size_t idx ); + void AddGrowableCol( size_t idx, int proportion = 0 ); void RemoveGrowableCol( size_t idx ); + // the sizer cells may grow in both directions, not grow at all or only + // grow in one direction but not the other + + // the direction may be wxVERTICAL, wxHORIZONTAL or wxBOTH (default) + void SetFlexibleDirection(int direction); + int GetFlexibleDirection(); + + // note that the grow mode only applies to the direction which is not + // flexible + void SetNonFlexibleGrowMode(wxFlexSizerGrowMode mode); + wxFlexSizerGrowMode GetNonFlexibleGrowMode(); }; //--------------------------------------------------------------------------- diff --git a/wxPython/src/stattool.i b/wxPython/src/stattool.i index 84b81d7d4f..26c4e1537d 100644 --- a/wxPython/src/stattool.i +++ b/wxPython/src/stattool.i @@ -196,7 +196,7 @@ public: // Insert the new tool at the given position, if pos == GetToolsCount(), it // is equivalent to DoAddTool() - wxToolBarToolBase *InsertTool(size_t pos, + wxToolBarToolBase *DoInsertTool(size_t pos, int id, const wxString& label, const wxBitmap& bitmap, @@ -270,7 +270,7 @@ public: # 2.3.3. They are renamed to have 'Label' in the name so as to be # able to keep backwards compatibility with using the above # methods. Eventually these should migrate to be the methods used - # primarily and loose the 'Label' in the name... + # primarily and lose the 'Label' in the name... def AddLabelTool(self, id, label, bitmap, bmpDisabled = wxNullBitmap, diff --git a/wxPython/src/streams.i b/wxPython/src/streams.i index 9e4feb1537..8bf7f2156d 100644 --- a/wxPython/src/streams.i +++ b/wxPython/src/streams.i @@ -28,7 +28,6 @@ %import _defs.i %pragma(python) code = "import wx" -%pragma(python) code = "import string" //---------------------------------------------------------------------- // typemaps for wxInputStream @@ -61,7 +60,7 @@ if ($source) { _ptr = new wxPyInputStream($source); } - $target = wxPyConstructObject(_ptr, "wxInputStream", TRUE); + $target = wxPyConstructObject(_ptr, wxT("wxInputStream"), TRUE); } //---------------------------------------------------------------------- @@ -88,6 +87,12 @@ // $target=0; // } +enum wxSeekMode +{ + wxFromStart, + wxFromCurrent, + wxFromEnd +}; @@ -118,6 +123,16 @@ public: void write(wxString data); void writelines(wxStringPtrList); */ + + char Peek(); + char GetC(); + size_t LastRead(); + bool CanRead(); + bool Eof(); + bool Ungetch(char c); + + long SeekI(long pos, wxSeekMode mode = wxFromStart); + long TellI(); } diff --git a/wxPython/src/utils.i b/wxPython/src/utils.i index f82808534f..b40a1044a7 100644 --- a/wxPython/src/utils.i +++ b/wxPython/src/utils.i @@ -35,7 +35,7 @@ // Import some definitions of other classes, etc. %import _defs.i -%pragma(python) code = "import string" +%pragma(python) code = "import wx" //--------------------------------------------------------------------------- @@ -46,7 +46,7 @@ if (ret) { PyTuple_SET_ITEM(ret, 0, PyInt_FromLong(flag)); #if wxUSE_UNICODE - PyTuple_SET_ITEM(ret, 1, PyUnicode_FromUnicode(str.c_str(), str.Len())); + PyTuple_SET_ITEM(ret, 1, PyUnicode_FromWideChar(str.c_str(), str.Len())); #else PyTuple_SET_ITEM(ret, 1, PyString_FromStringAndSize(str.c_str(), str.Len())); #endif @@ -449,6 +449,10 @@ public: // return the wxDateTime object for the current time static inline wxDateTime Now(); + // return the wxDateTime object for the current time with millisecond + // precision (if available on this platform) + static wxDateTime UNow(); + // return the wxDateTime object for today midnight: i.e. as Now() but // with time set to 0 static inline wxDateTime Today(); @@ -528,8 +532,8 @@ public: // calendar calculations // set to the given week day in the same week as this one - wxDateTime& SetToWeekDayInSameWeek(WeekDay weekday); - wxDateTime GetWeekDayInSameWeek(WeekDay weekday); + wxDateTime& SetToWeekDayInSameWeek(WeekDay weekday, WeekFlags flags = Monday_First); + wxDateTime GetWeekDayInSameWeek(WeekDay weekday, WeekFlags flags = Monday_First); // set to the next week day following this one wxDateTime& SetToNextWeekDay(WeekDay weekday); @@ -563,8 +567,8 @@ public: // sets the date to the given day of the given week in the year, // returns TRUE on success and FALSE if given date doesn't exist (e.g. // numWeek is > 53) - bool SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday = Mon); - wxDateTime GetWeek(wxDateTime_t numWeek, WeekDay weekday = Mon); + bool SetToTheWeek(wxDateTime_t numWeek, WeekDay weekday = Mon, WeekFlags flags = Monday_First); + wxDateTime GetWeek(wxDateTime_t numWeek, WeekDay weekday = Mon, WeekFlags flags = Monday_First); // sets the date to the last day of the given (or current) month or the // given (or current) year @@ -758,17 +762,17 @@ public: %pragma(python) addtoclass = " def __add__(self, other): - if string.find(other.this, 'wxTimeSpan') != -1: + if isinstance(other, wxTimeSpanPtr): return self.__add__TS(other) - if string.find(other.this, 'wxDateSpan') != -1: + if isinstance(other, wxDateSpanPtr): return self.__add__DS(other) raise TypeError, 'Invalid r.h.s. type for __add__' def __sub__(self, other): - if string.find(other.this, 'wxDateTime') != -1: + if isinstance(other, wxDateTimePtr): return self.__sub__DT(other) - if string.find(other.this, 'wxTimeSpan') != -1: + if isinstance(other, wxTimeSpanPtr): return self.__sub__TS(other) - if string.find(other.this, 'wxDateSpan') != -1: + if isinstance(other, wxDateSpanPtr): return self.__sub__DS(other) raise TypeError, 'Invalid r.h.s. type for __sub__' " diff --git a/wxPython/src/windows.i b/wxPython/src/windows.i index 702922d27b..5b6ccf56da 100644 --- a/wxPython/src/windows.i +++ b/wxPython/src/windows.i @@ -216,12 +216,17 @@ public: void DragAcceptFiles(bool accept); #endif void Enable(bool enable); + void Disable(); // Find child window by ID or name %name(FindWindowById) wxWindow* FindWindow(long id); %name(FindWindowByName) wxWindow* FindWindow(const wxString& name); void Fit(); + + // set virtual size to satisfy children + void FitInside(); + wxColour GetBackgroundColour(); wxBorder GetBorder() const; @@ -291,7 +296,9 @@ public: bool IsShown(); bool IsTopLevel(); void Layout(); +#ifdef wxUSE_WX_RESOURCES bool LoadFromResource(wxWindow* parent, const wxString& resourceName, const wxResourceTable* resourceTable = NULL); +#endif void Lower(); void MakeModal(bool flag=TRUE); %name(MoveXY)void Move(int x, int y, int flags = wxSIZE_USE_EXISTING); @@ -365,6 +372,8 @@ public: wxSize GetVirtualSize() const; %name(GetVirtualSizeTuple)void GetVirtualSize( int *OUTPUT, int *OUTPUT ) const; + wxSize GetBestVirtualSize(); + %name(SetClientSizeWH)void SetClientSize(int width, int height); void SetClientSize(const wxSize& size); //void SetPalette(wxPalette* palette); @@ -410,6 +419,13 @@ public: wxSize GetBestSize(); wxSize GetMaxSize(); + // There are times (and windows) where 'Best' size and 'Min' size + // are vastly out of sync. This should be remedied somehow, but in + // the meantime, this method will return the larger of BestSize + // (the window's smallest legible size), and any user specified + // MinSize hint. + wxSize GetAdjustedBestSize(); + void SetCaret(wxCaret *caret); wxCaret *GetCaret(); %pragma(python) addtoclass = "# replaces broken shadow method @@ -761,6 +777,7 @@ public: wxMenu *Replace(size_t pos, wxMenu *menu, const wxString& title); wxMenu *Remove(size_t pos); void EnableTop(size_t pos, bool enable); + bool IsEnabledTop(size_t pos); void SetLabelTop(size_t pos, const wxString& label); wxString GetLabelTop(size_t pos); int FindMenu(const wxString& title); diff --git a/wxPython/src/windows2.i b/wxPython/src/windows2.i index 045654592e..77fedbb253 100644 --- a/wxPython/src/windows2.i +++ b/wxPython/src/windows2.i @@ -65,7 +65,7 @@ enum { class wxNotebookEvent : public wxNotifyEvent { public: wxNotebookEvent(wxEventType commandType = wxEVT_NULL, int id = 0, - int nSel = -1, int nOldSel = -1); + int sel = -1, int oldSel = -1); int GetSelection(); int GetOldSelection(); @@ -96,36 +96,36 @@ public: %pragma(python) addtomethod = "wxPreNotebook:val._setOORInfo(val)" int GetPageCount(); - int SetSelection(int nPage); - void AdvanceSelection(bool bForward = TRUE); + int SetSelection(int page); + void AdvanceSelection(bool forward = TRUE); int GetSelection(); - bool SetPageText(int nPage, const wxString& strText); - wxString GetPageText(int nPage) const; + bool SetPageText(int page, const wxString& text); + wxString GetPageText(int page) const; void SetImageList(wxImageList* imageList); void AssignImageList(wxImageList *imageList) ; %pragma(python) addtomethod = "AssignImageList:_args[0].thisown = 0" wxImageList* GetImageList(); - int GetPageImage(int nPage); - bool SetPageImage(int nPage, int nImage); + int GetPageImage(int page); + bool SetPageImage(int page, int image); int GetRowCount(); void SetPageSize(const wxSize& size); void SetPadding(const wxSize& padding); - bool DeletePage(int nPage); - bool RemovePage(int nPage); + bool DeletePage(int page); + bool RemovePage(int page); bool DeleteAllPages(); - bool AddPage(/*wxNotebookPage*/ wxWindow *pPage, - const wxString& strText, - int bSelect = FALSE, + bool AddPage(/*wxNotebookPage*/ wxWindow *page, + const wxString& text, + int select = FALSE, int imageId = -1); - bool InsertPage(int nPage, - /*wxNotebookPage*/ wxWindow *pPage, - const wxString& strText, - bool bSelect = FALSE, + bool InsertPage(int page, + /*wxNotebookPage*/ wxWindow *page, + const wxString& text, + bool select = FALSE, int imageId = -1); - /*wxNotebookPage*/ wxWindow *GetPage(int nPage); + /*wxNotebookPage*/ wxWindow *GetPage(int page); %addmethods { void ResizeChildren() { diff --git a/wxPython/src/wxc.pyd.manifest b/wxPython/src/winxp.manifest similarity index 90% rename from wxPython/src/wxc.pyd.manifest rename to wxPython/src/winxp.manifest index f898b261fa..50cbb8a67d 100644 --- a/wxPython/src/wxc.pyd.manifest +++ b/wxPython/src/winxp.manifest @@ -6,7 +6,7 @@ name="Controls" type="win32" /> -<description>wxPython: GUI library for Python</description> +<description>Python Interpreter</description> <dependency> <dependentAssembly> <assemblyIdentity diff --git a/wxPython/src/wizard.i b/wxPython/src/wizard.i index f3a4bed4ac..e63443348f 100644 --- a/wxPython/src/wizard.i +++ b/wxPython/src/wizard.i @@ -43,7 +43,8 @@ enum { wxEVT_WIZARD_PAGE_CHANGED, wxEVT_WIZARD_PAGE_CHANGING, wxEVT_WIZARD_CANCEL, - wxEVT_WIZARD_HELP + wxEVT_WIZARD_HELP, + wxEVT_WIZARD_FINISHED }; @@ -61,6 +62,9 @@ def EVT_WIZARD_CANCEL(win, id, func): def EVT_WIZARD_HELP(win, id, func): win.Connect(id, -1, wxEVT_WIZARD_HELP, func) +def EVT_WIZARD_FINISHED(win, id, func): + win.Connect(id, -1, wxEVT_WIZARD_FINISHED, func) + " //---------------------------------------------------------------------- @@ -361,6 +365,9 @@ public: // page first and return FALSE without changing the page if // TransferDataFromWindow() returns FALSE - otherwise, returns TRUE bool ShowPage(wxWizardPage *page, bool goingForward = TRUE); + + bool HasNextPage(wxWizardPage* page); + bool HasPrevPage(wxWizardPage* page); }; diff --git a/wxPython/src/wx.i b/wxPython/src/wx.i index 476b7c1dde..747fa6839e 100644 --- a/wxPython/src/wx.i +++ b/wxPython/src/wx.i @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: wxp.i +// Name: wx.i // Purpose: SWIG interface file for a python wxWindows module // // Author: Robin Dunn @@ -65,6 +65,14 @@ wxSize wxDefaultSize; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- +enum { + wxPYAPP_ASSERT_SUPPRESS = 1, + wxPYAPP_ASSERT_EXCEPTION = 2, + wxPYAPP_ASSERT_DIALOG = 4, + wxPYAPP_ASSERT_LOG = 8 +}; + + class wxPyApp : public wxEvtHandler { public: %addmethods { @@ -76,6 +84,11 @@ public: ~wxPyApp(); + void _setCallbackInfo(PyObject* self, PyObject* _class); + %pragma(python) addtomethod = "__init__:self._setCallbackInfo(self, wxPyApp)" + %pragma(python) addtomethod = "__init__:self._setOORInfo(self)" + + wxString GetAppName(); #ifdef __WXMSW__ bool GetAuto3D(); @@ -105,6 +118,24 @@ public: void SetTopWindow(wxWindow* window); void SetVendorName(const wxString& name); void SetUseBestVisual(bool flag); + + int GetAssertMode(); + void SetAssertMode(int mode); + + + static bool GetMacDefaultEncodingIsPC(); + static bool GetMacSupportPCMenuShortcuts(); + static long GetMacAboutMenuItemId(); + static long GetMacPreferencesMenuItemId(); + static long GetMacExitMenuItemId(); + static wxString GetMacHelpMenuTitleName(); + + static void SetMacDefaultEncodingIsPC(bool val); + static void SetMacSupportPCMenuShortcuts(bool val); + static void SetMacAboutMenuItemId(long val); + static void SetMacPreferencesMenuItemId(long val); + static void SetMacExitMenuItemId(long val); + static void SetMacHelpMenuTitleName(const wxString& val); }; %inline %{ @@ -192,6 +223,7 @@ static wxPyCoreAPI API = { wxRealPoint_helper, wxRect_helper, wxColour_helper, + wxPoint2DDouble_helper, wxPyCBH_setCallbackInfo, wxPyCBH_findCallback, @@ -226,7 +258,7 @@ static wxPyCoreAPI API = { Py_XDECREF(v); - __wxPreStart(); // initialize the GUI toolkit, if needed. + __wxPreStart(d); // initialize the GUI toolkit, if needed. // Since these modules are all linked together, initialize them now @@ -261,7 +293,7 @@ static wxPyCoreAPI API = { PyDict_SetItemString(d,"wxVERSION_NUMBER", PyInt_FromLong((long)wxVERSION_NUMBER )); #if wxUSE_UNICODE wxString tempStr(wxVERSION_STRING); - PyDict_SetItemString(d,"wxVERSION_STRING", PyUnicode_FromUnicode(tempStr.c_str(), tempStr.Len())); + PyDict_SetItemString(d,"wxVERSION_STRING", PyUnicode_FromWideChar(tempStr.c_str(), tempStr.Len())); #else PyDict_SetItemString(d,"wxVERSION_STRING", PyString_FromString(wxVERSION_STRING)); #endif @@ -275,3 +307,4 @@ static wxPyCoreAPI API = { %pragma(python) include="_extras.py"; + diff --git a/wxPython/src/wxPython.h b/wxPython/src/wxPython.h index 67fb55da52..dfe04e89ba 100644 --- a/wxPython/src/wxPython.h +++ b/wxPython/src/wxPython.h @@ -71,6 +71,7 @@ static void wxPyCoreAPI_IMPORT() { #define wxRealPoint_helper(a,b) (wxPyCoreAPIPtr->p_wxRealPoint_helper(a,b)) #define wxRect_helper(a,b) (wxPyCoreAPIPtr->p_wxRect_helper(a,b)) #define wxColour_helper(a,b) (wxPyCoreAPIPtr->p_wxColour_helper(a,b)) +#define wxPoint2DDouble_helper(a,b) (wxPyCoreAPIPtr->p_wxPoint2DDouble_helper(a,b)) #define wxPyCBH_setCallbackInfo(a, b, c, d) (wxPyCoreAPIPtr->p_wxPyCBH_setCallbackInfo(a,b,c,d)) #define wxPyCBH_findCallback(a, b) (wxPyCoreAPIPtr->p_wxPyCBH_findCallback(a, b)) diff --git a/wxPython/src/wxc.rc b/wxPython/src/wxc.rc index 0f16edf830..70b574d596 100644 --- a/wxPython/src/wxc.rc +++ b/wxPython/src/wxc.rc @@ -1,5 +1,5 @@ aa_wxpicon ICON "wxp.ico" #include "wx/msw/wx.rc" -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "wxc.pyd.manifest" + diff --git a/wxPython/tests/gridtest.py b/wxPython/tests/gridtest.py index c4988db150..8635051d5c 100644 --- a/wxPython/tests/gridtest.py +++ b/wxPython/tests/gridtest.py @@ -104,7 +104,7 @@ class MyCellEditor(wxPyGridCellEditor): elif key < 256 and key >= 0 and chr(key) in string.printable: ch = chr(key) if not evt.ShiftDown(): - ch = string.lower(ch) + ch = ch.lower() if ch is not None: # Replace the text. Other option would be to append it. diff --git a/wxPython/tests/hangman.py b/wxPython/tests/hangman.py index 76b9622689..c735372bf4 100644 --- a/wxPython/tests/hangman.py +++ b/wxPython/tests/hangman.py @@ -1,12 +1,12 @@ -"""Hangman.py, a simple wxPython game, inspired by the +"""Hangman.py, a simple wxPython game, inspired by the old bsd game by Ken Arnold. From the original man page: - In hangman, the computer picks a word from the on-line - word list and you must try to guess it. The computer - keeps track of which letters have been guessed and how + In hangman, the computer picks a word from the on-line + word list and you must try to guess it. The computer + keeps track of which letters have been guessed and how many wrong guesses you have made on the screen in a - graphic fashion. + graphic fashion. That says it all, doesn't it? @@ -14,35 +14,35 @@ Have fun with it, Harm van der Heijden (H.v.d.Heijden@phys.tue.nl)""" -import random,re,string +import random,re from wxPython.wx import * class WordFetcher: def __init__(self, filename, min_length = 5): - self.min_length = min_length - print "Trying to open file %s" % (filename,) - try: - f = open(filename, "r") - except: - print "Couldn't open dictionary file %s, using build-ins" % (filename,) - self.words = self.builtin_words - self.filename = None - return - self.words = f.read() - self.filename = filename - print "Got %d bytes." % (len(self.words),) + self.min_length = min_length + print "Trying to open file %s" % (filename,) + try: + f = open(filename, "r") + except: + print "Couldn't open dictionary file %s, using build-ins" % (filename,) + self.words = self.builtin_words + self.filename = None + return + self.words = f.read() + self.filename = filename + print "Got %d bytes." % (len(self.words),) def SetMinLength(min_length): - self.min_length = min_length + self.min_length = min_length def Get(self): - reg = re.compile('\s+([a-zA-Z]+)\s+') - n = 50 # safety valve; maximum number of tries to find a suitable word - while n: - index = int(random.random()*len(self.words)) - m = reg.search(self.words[index:]) - if m and len(m.groups()[0]) >= self.min_length: break - n = n - 1 - if n: return string.lower(m.groups()[0]) - return "error" + reg = re.compile('\s+([a-zA-Z]+)\s+') + n = 50 # safety valve; maximum number of tries to find a suitable word + while n: + index = int(random.random()*len(self.words)) + m = reg.search(self.words[index:]) + if m and len(m.groups()[0]) >= self.min_length: break + n = n - 1 + if n: return string.lower(m.groups()[0]) + return "error" builtin_words = ' albatros banana electrometer eggshell' def stdprint(x): @@ -50,47 +50,47 @@ def stdprint(x): class URLWordFetcher(WordFetcher): def __init__(self, url): - self.OpenURL(url) - WordFetcher.__init__(self, "hangman_dict.txt") + self.OpenURL(url) + WordFetcher.__init__(self, "hangman_dict.txt") def logprint(self,x): - print x + print x def RetrieveAsFile(self, host, path=''): - from httplib import HTTP - try: - h = HTTP(host) - except: - self.logprint("Failed to create HTTP connection to %s... is the network available?" % (host)) - return None - h.putrequest('GET',path) - h.putheader('Accept','text/html') - h.putheader('Accept','text/plain') - h.endheaders() - errcode, errmsg, headers = h.getreply() - if errcode != 200: - self.logprint("HTTP error code %d: %s" % (errcode, errmsg)) - return None - f = h.getfile() - return f + from httplib import HTTP + try: + h = HTTP(host) + except: + self.logprint("Failed to create HTTP connection to %s... is the network available?" % (host)) + return None + h.putrequest('GET',path) + h.putheader('Accept','text/html') + h.putheader('Accept','text/plain') + h.endheaders() + errcode, errmsg, headers = h.getreply() + if errcode != 200: + self.logprint("HTTP error code %d: %s" % (errcode, errmsg)) + return None + f = h.getfile() + return f def OpenURL(self,url): - from htmllib import HTMLParser - import formatter - self.url = url - m = re.match('http://([^/]+)(/\S*)\s*', url) - if m: - host = m.groups()[0] - path = m.groups()[1] - else: - m = re.match('http://(\S+)\s*', url) - if not m: - # Invalid URL - self.logprint("Invalid or unsupported URL: %s" % (url)) - return - host = m.groups()[0] - path = '' - f = self.RetrieveAsFile(host,path) - if not f: - self.logprint("Could not open %s" % (url)) - return + from htmllib import HTMLParser + import formatter + self.url = url + m = re.match('http://([^/]+)(/\S*)\s*', url) + if m: + host = m.groups()[0] + path = m.groups()[1] + else: + m = re.match('http://(\S+)\s*', url) + if not m: + # Invalid URL + self.logprint("Invalid or unsupported URL: %s" % (url)) + return + host = m.groups()[0] + path = '' + f = self.RetrieveAsFile(host,path) + if not f: + self.logprint("Could not open %s" % (url)) + return self.logprint("Receiving data...") data = f.read() tmp = open('hangman_dict.txt','w') @@ -103,287 +103,287 @@ class URLWordFetcher(WordFetcher): class HangmanWnd(wxWindow): def __init__(self, parent, id, pos=wxDefaultPosition, size=wxDefaultSize): - wxWindow.__init__(self, parent, id, pos, size) - self.SetBackgroundColour(wxNamedColour('white')) - if wxPlatform == '__WXGTK__': - self.font = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL) - else: - self.font = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL) - self.SetFocus() + wxWindow.__init__(self, parent, id, pos, size) + self.SetBackgroundColour(wxNamedColour('white')) + if wxPlatform == '__WXGTK__': + self.font = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL) + else: + self.font = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL) + self.SetFocus() def StartGame(self, word): - self.word = word - self.guess = [] - self.tries = 0 - self.misses = 0 - self.Draw() + self.word = word + self.guess = [] + self.tries = 0 + self.misses = 0 + self.Draw() def EndGame(self): - self.misses = 7; - self.guess = map(chr, range(ord('a'),ord('z')+1)) - self.Draw() + self.misses = 7; + self.guess = map(chr, range(ord('a'),ord('z')+1)) + self.Draw() def HandleKey(self, key): - self.message = "" - if self.guess.count(key): - self.message = 'Already guessed %s' % (key,) - return 0 - self.guess.append(key) - self.guess.sort() - self.tries = self.tries+1 - if not key in self.word: - self.misses = self.misses+1 - if self.misses == 7: - self.EndGame() - return 1 - has_won = 1 - for letter in self.word: - if not self.guess.count(letter): - has_won = 0 - break - if has_won: - self.Draw() - return 2 - self.Draw() - return 0 + self.message = "" + if self.guess.count(key): + self.message = 'Already guessed %s' % (key,) + return 0 + self.guess.append(key) + self.guess.sort() + self.tries = self.tries+1 + if not key in self.word: + self.misses = self.misses+1 + if self.misses == 7: + self.EndGame() + return 1 + has_won = 1 + for letter in self.word: + if not self.guess.count(letter): + has_won = 0 + break + if has_won: + self.Draw() + return 2 + self.Draw() + return 0 def Draw(self, dc = None): - if not dc: - dc = wxClientDC(self) - dc.SetFont(self.font) - dc.Clear() - (x,y) = self.GetSizeTuple() - x1 = x-200; y1 = 20 - for letter in self.word: - if self.guess.count(letter): - dc.DrawText(letter, x1, y1) - else: - dc.DrawText('.', x1, y1) - x1 = x1 + 10 - x1 = x-200 - dc.DrawText("tries %d misses %d" % (self.tries,self.misses),x1,50) - guesses = "" - for letter in self.guess: - guesses = guesses + letter - dc.DrawText("guessed:", x1, 70) - dc.DrawText(guesses[:13], x1+80, 70) - dc.DrawText(guesses[13:], x1+80, 90) - dc.SetUserScale(x/1000., y/1000.) - self.DrawVictim(dc) + if not dc: + dc = wxClientDC(self) + dc.SetFont(self.font) + dc.Clear() + (x,y) = self.GetSizeTuple() + x1 = x-200; y1 = 20 + for letter in self.word: + if self.guess.count(letter): + dc.DrawText(letter, x1, y1) + else: + dc.DrawText('.', x1, y1) + x1 = x1 + 10 + x1 = x-200 + dc.DrawText("tries %d misses %d" % (self.tries,self.misses),x1,50) + guesses = "" + for letter in self.guess: + guesses = guesses + letter + dc.DrawText("guessed:", x1, 70) + dc.DrawText(guesses[:13], x1+80, 70) + dc.DrawText(guesses[13:], x1+80, 90) + dc.SetUserScale(x/1000., y/1000.) + self.DrawVictim(dc) def DrawVictim(self, dc): - dc.SetPen(wxPen(wxNamedColour('black'), 20)) - dc.DrawLines([(10, 980), (10,900), (700,900), (700,940), (720,940), - (720,980), (900,980)]) - dc.DrawLines([(100,900), (100, 100), (300,100)]) - dc.DrawLine(100,200,200,100) - if ( self.misses == 0 ): return - dc.SetPen(wxPen(wxNamedColour('blue'), 10)) - dc.DrawLine(300,100,300,200) - if ( self.misses == 1 ): return - dc.DrawEllipse(250,200,100,100) - if ( self.misses == 2 ): return - dc.DrawLine(300,300,300,600) - if ( self.misses == 3) : return - dc.DrawLine(300,300,250,550) - if ( self.misses == 4) : return - dc.DrawLine(300,300,350,550) - if ( self.misses == 5) : return - dc.DrawLine(300,600,350,850) - if ( self.misses == 6) : return - dc.DrawLine(300,600,250,850) + dc.SetPen(wxPen(wxNamedColour('black'), 20)) + dc.DrawLines([(10, 980), (10,900), (700,900), (700,940), (720,940), + (720,980), (900,980)]) + dc.DrawLines([(100,900), (100, 100), (300,100)]) + dc.DrawLine(100,200,200,100) + if ( self.misses == 0 ): return + dc.SetPen(wxPen(wxNamedColour('blue'), 10)) + dc.DrawLine(300,100,300,200) + if ( self.misses == 1 ): return + dc.DrawEllipse(250,200,100,100) + if ( self.misses == 2 ): return + dc.DrawLine(300,300,300,600) + if ( self.misses == 3) : return + dc.DrawLine(300,300,250,550) + if ( self.misses == 4) : return + dc.DrawLine(300,300,350,550) + if ( self.misses == 5) : return + dc.DrawLine(300,600,350,850) + if ( self.misses == 6) : return + dc.DrawLine(300,600,250,850) def OnPaint(self, event): - dc = wxPaintDC(self) - self.Draw(dc) + dc = wxPaintDC(self) + self.Draw(dc) class HangmanDemo(HangmanWnd): def __init__(self, wf, parent, id, pos, size): - HangmanWnd.__init__(self, parent, id, pos, size) - self.StartGame("dummy") - self.start_new = 1 - self.wf = wf - self.delay = 500 - self.timer = self.PlayTimer(self.MakeMove) + HangmanWnd.__init__(self, parent, id, pos, size) + self.StartGame("dummy") + self.start_new = 1 + self.wf = wf + self.delay = 500 + self.timer = self.PlayTimer(self.MakeMove) def MakeMove(self): - self.timer.Stop() - if self.start_new: - self.StartGame(self.wf.Get()) - self.start_new = 0 - self.left = list('aaaabcdeeeeefghiiiiijklmnnnoooopqrssssttttuuuuvwxyz') - else: - key = self.left[int(random.random()*len(self.left))] - while self.left.count(key): self.left.remove(key) - self.start_new = self.HandleKey(key) - self.timer.Start(self.delay) + self.timer.Stop() + if self.start_new: + self.StartGame(self.wf.Get()) + self.start_new = 0 + self.left = list('aaaabcdeeeeefghiiiiijklmnnnoooopqrssssttttuuuuvwxyz') + else: + key = self.left[int(random.random()*len(self.left))] + while self.left.count(key): self.left.remove(key) + self.start_new = self.HandleKey(key) + self.timer.Start(self.delay) def Stop(self): - self.timer.Stop() + self.timer.Stop() class PlayTimer(wxTimer): - def __init__(self,func): - wxTimer.__init__(self) - self.func = func - self.Start(1000) - def Notify(self): - apply(self.func, ()) + def __init__(self,func): + wxTimer.__init__(self) + self.func = func + self.Start(1000) + def Notify(self): + apply(self.func, ()) class HangmanDemoFrame(wxFrame): def __init__(self, wf, parent, id, pos, size): - wxFrame.__init__(self, parent, id, "Hangman demo", pos, size) - self.demo = HangmanDemo(wf, self, -1, wxDefaultPosition, wxDefaultSize) + wxFrame.__init__(self, parent, id, "Hangman demo", pos, size) + self.demo = HangmanDemo(wf, self, -1, wxDefaultPosition, wxDefaultSize) def OnCloseWindow(self, event): - self.demo.timer.Stop() - self.Destroy() + self.demo.timer.Stop() + self.Destroy() class AboutBox(wxDialog): def __init__(self, parent,wf): - wxDialog.__init__(self, parent, -1, "About Hangman", wxDefaultPosition, wxSize(350,450)) - self.wnd = HangmanDemo(wf, self, -1, wxPoint(1,1), wxSize(350,150)) - self.static = wxStaticText(self, -1, __doc__, wxPoint(1,160), wxSize(350, 250)) - self.button = wxButton(self, 2001, "OK", wxPoint(150,420), wxSize(50,-1)) - EVT_BUTTON(self, 2001, self.OnOK) + wxDialog.__init__(self, parent, -1, "About Hangman", wxDefaultPosition, wxSize(350,450)) + self.wnd = HangmanDemo(wf, self, -1, wxPoint(1,1), wxSize(350,150)) + self.static = wxStaticText(self, -1, __doc__, wxPoint(1,160), wxSize(350, 250)) + self.button = wxButton(self, 2001, "OK", wxPoint(150,420), wxSize(50,-1)) + EVT_BUTTON(self, 2001, self.OnOK) def OnOK(self, event): - self.wnd.Stop() - self.EndModal(wxID_OK) - + self.wnd.Stop() + self.EndModal(wxID_OK) + class MyFrame(wxFrame): def __init__(self, wf): - self.wf = wf - wxFrame.__init__(self, NULL, -1, "hangman", wxDefaultPosition, wxSize(400,300)) - self.wnd = HangmanWnd(self, -1) - menu = wxMenu() - menu.Append(1001, "New") - menu.Append(1002, "End") - menu.AppendSeparator() - menu.Append(1003, "Reset") - menu.Append(1004, "Demo...") - menu.AppendSeparator() - menu.Append(1005, "Exit") - menubar = wxMenuBar() - menubar.Append(menu, "Game") - menu = wxMenu() - #menu.Append(1010, "Internal", "Use internal dictionary", TRUE) - menu.Append(1011, "ASCII File...") - urls = [ 'wxPython home', 'http://208.240.253.245/wxPython/main.html', - 'slashdot.org', 'http://slashdot.org/', - 'cnn.com', 'http://cnn.com', - 'The New York Times', 'http://www.nytimes.com', - 'De Volkskrant', 'http://www.volkskrant.nl/frameless/25000006.html', - 'Gnu GPL', 'http://www.fsf.org/copyleft/gpl.html', - 'Bijbel: Genesis', 'http://www.coas.com/bijbel/gn1.htm'] - urlmenu = wxMenu() - for item in range(0,len(urls),2): - urlmenu.Append(1020+item/2, urls[item], urls[item+1]) - urlmenu.Append(1080, 'Other...', 'Enter an URL') - menu.AppendMenu(1012, 'URL', urlmenu, 'Use a webpage') - menu.Append(1013, 'Dump', 'Write contents to stdout') - menubar.Append(menu, "Dictionary") - self.urls = urls - self.urloffset = 1020 - menu = wxMenu() - menu.Append(1090, "About...") - menubar.Append(menu, "Help") - self.SetMenuBar(menubar) - self.CreateStatusBar(2) - EVT_MENU(self, 1001, self.OnGameNew) - EVT_MENU(self, 1002, self.OnGameEnd) - EVT_MENU(self, 1003, self.OnGameReset) - EVT_MENU(self, 1004, self.OnGameDemo) - EVT_MENU(self, 1005, self.OnWindowClose) - EVT_MENU(self, 1011, self.OnDictFile) - EVT_MENU_RANGE(self, 1020, 1020+len(urls)/2, self.OnDictURL) - EVT_MENU(self, 1080, self.OnDictURLSel) - EVT_MENU(self, 1013, self.OnDictDump) - EVT_MENU(self, 1090, self.OnHelpAbout) - EVT_CHAR(self.wnd, self.OnChar) - self.OnGameReset() + self.wf = wf + wxFrame.__init__(self, NULL, -1, "hangman", wxDefaultPosition, wxSize(400,300)) + self.wnd = HangmanWnd(self, -1) + menu = wxMenu() + menu.Append(1001, "New") + menu.Append(1002, "End") + menu.AppendSeparator() + menu.Append(1003, "Reset") + menu.Append(1004, "Demo...") + menu.AppendSeparator() + menu.Append(1005, "Exit") + menubar = wxMenuBar() + menubar.Append(menu, "Game") + menu = wxMenu() + #menu.Append(1010, "Internal", "Use internal dictionary", TRUE) + menu.Append(1011, "ASCII File...") + urls = [ 'wxPython home', 'http://208.240.253.245/wxPython/main.html', + 'slashdot.org', 'http://slashdot.org/', + 'cnn.com', 'http://cnn.com', + 'The New York Times', 'http://www.nytimes.com', + 'De Volkskrant', 'http://www.volkskrant.nl/frameless/25000006.html', + 'Gnu GPL', 'http://www.fsf.org/copyleft/gpl.html', + 'Bijbel: Genesis', 'http://www.coas.com/bijbel/gn1.htm'] + urlmenu = wxMenu() + for item in range(0,len(urls),2): + urlmenu.Append(1020+item/2, urls[item], urls[item+1]) + urlmenu.Append(1080, 'Other...', 'Enter an URL') + menu.AppendMenu(1012, 'URL', urlmenu, 'Use a webpage') + menu.Append(1013, 'Dump', 'Write contents to stdout') + menubar.Append(menu, "Dictionary") + self.urls = urls + self.urloffset = 1020 + menu = wxMenu() + menu.Append(1090, "About...") + menubar.Append(menu, "Help") + self.SetMenuBar(menubar) + self.CreateStatusBar(2) + EVT_MENU(self, 1001, self.OnGameNew) + EVT_MENU(self, 1002, self.OnGameEnd) + EVT_MENU(self, 1003, self.OnGameReset) + EVT_MENU(self, 1004, self.OnGameDemo) + EVT_MENU(self, 1005, self.OnWindowClose) + EVT_MENU(self, 1011, self.OnDictFile) + EVT_MENU_RANGE(self, 1020, 1020+len(urls)/2, self.OnDictURL) + EVT_MENU(self, 1080, self.OnDictURLSel) + EVT_MENU(self, 1013, self.OnDictDump) + EVT_MENU(self, 1090, self.OnHelpAbout) + EVT_CHAR(self.wnd, self.OnChar) + self.OnGameReset() def OnGameNew(self, event): - word = self.wf.Get() - self.in_progress = 1 - self.SetStatusText("",0) - self.wnd.StartGame(word) + word = self.wf.Get() + self.in_progress = 1 + self.SetStatusText("",0) + self.wnd.StartGame(word) def OnGameEnd(self, event): - self.UpdateAverages(0) - self.in_progress = 0 - self.SetStatusText("",0) - self.wnd.EndGame() + self.UpdateAverages(0) + self.in_progress = 0 + self.SetStatusText("",0) + self.wnd.EndGame() def OnGameReset(self, event=None): - self.played = 0 - self.won = 0 - self.history = [] - self.average = 0.0 - self.OnGameNew(None) + self.played = 0 + self.won = 0 + self.history = [] + self.average = 0.0 + self.OnGameNew(None) def OnGameDemo(self, event): - frame = HangmanDemoFrame(self.wf, self, -1, wxDefaultPosition, self.GetSize()) - frame.Show(TRUE) + frame = HangmanDemoFrame(self.wf, self, -1, wxDefaultPosition, self.GetSize()) + frame.Show(TRUE) def OnDictFile(self, event): - fd = wxFileDialog(self) - if (self.wf.filename): - fd.SetFilename(self.wf.filename) - if fd.ShowModal() == wxID_OK: - file = fd.GetPath() - self.wf = WordFetcher(file) + fd = wxFileDialog(self) + if (self.wf.filename): + fd.SetFilename(self.wf.filename) + if fd.ShowModal() == wxID_OK: + file = fd.GetPath() + self.wf = WordFetcher(file) def OnDictURL(self, event): - item = (event.GetId() - self.urloffset)*2 - print "Trying to open %s at %s" % (self.urls[item], self.urls[item+1]) - self.wf = URLWordFetcher(self.urls[item+1]) + item = (event.GetId() - self.urloffset)*2 + print "Trying to open %s at %s" % (self.urls[item], self.urls[item+1]) + self.wf = URLWordFetcher(self.urls[item+1]) def OnDictURLSel(self, event): - msg = wxTextEntryDialog(self, "Enter the URL of the dictionary document", "Enter URL") - if msg.ShowModal() == wxID_OK: - url = msg.GetValue() - self.wf = URLWordFetcher(url) + msg = wxTextEntryDialog(self, "Enter the URL of the dictionary document", "Enter URL") + if msg.ShowModal() == wxID_OK: + url = msg.GetValue() + self.wf = URLWordFetcher(url) def OnDictDump(self, event): - print self.wf.words + print self.wf.words def OnHelpAbout(self, event): - about = AboutBox(self, self.wf) - about.ShowModal() - about.wnd.Stop() # that damn timer won't stop! + about = AboutBox(self, self.wf) + about.ShowModal() + about.wnd.Stop() # that damn timer won't stop! def UpdateAverages(self, has_won): - if has_won: - self.won = self.won + 1 - self.played = self.played+1 - self.history.append(self.wnd.misses) # ugly - total = 0.0 - for m in self.history: - total = total + m - self.average = float(total/len(self.history)) + if has_won: + self.won = self.won + 1 + self.played = self.played+1 + self.history.append(self.wnd.misses) # ugly + total = 0.0 + for m in self.history: + total = total + m + self.average = float(total/len(self.history)) def OnChar(self, event): - if not self.in_progress: - self.OnGameNew(None) - return - key = event.KeyCode(); - if key >= ord('A') and key <= ord('Z'): - key = key + ord('a') - ord('A') - key = chr(key) - if key < 'a' or key > 'z': - event.Skip() - return - res = self.wnd.HandleKey(key) - if res == 0: - self.SetStatusText(self.wnd.message) - elif res == 1: - self.UpdateAverages(0) - self.SetStatusText("Too bad, you're dead!",0) - self.in_progress = 0 + if not self.in_progress: + self.OnGameNew(None) + return + key = event.KeyCode(); + if key >= ord('A') and key <= ord('Z'): + key = key + ord('a') - ord('A') + key = chr(key) + if key < 'a' or key > 'z': + event.Skip() + return + res = self.wnd.HandleKey(key) + if res == 0: + self.SetStatusText(self.wnd.message) + elif res == 1: + self.UpdateAverages(0) + self.SetStatusText("Too bad, you're dead!",0) + self.in_progress = 0 elif res == 2: - self.in_progress = 0 - self.UpdateAverages(1) - self.SetStatusText("Congratulations!",0) - if self.played: - percent = (100.*self.won)/self.played - else: - percent = 0.0 - self.SetStatusText("p %d, w %d (%g %%), av %g" % (self.played,self.won, percent, self.average),1) + self.in_progress = 0 + self.UpdateAverages(1) + self.SetStatusText("Congratulations!",0) + if self.played: + percent = (100.*self.won)/self.played + else: + percent = 0.0 + self.SetStatusText("p %d, w %d (%g %%), av %g" % (self.played,self.won, percent, self.average),1) def OnWindowClose(self, event): - self.Destroy() - + self.Destroy() + class MyApp(wxApp): def OnInit(self): - if wxPlatform == '__WXGTK__': - defaultfile = "/usr/share/games/hangman-words" - elif wxPlatform == '__WXMSW__': - defaultfile = "c:\\windows\\hardware.txt" - else: - defaultfile = "" - wf = WordFetcher(defaultfile) - frame = MyFrame(wf) - self.SetTopWindow(frame) - frame.Show(TRUE) - return TRUE + if wxPlatform == '__WXGTK__': + defaultfile = "/usr/share/games/hangman-words" + elif wxPlatform == '__WXMSW__': + defaultfile = "c:\\windows\\hardware.txt" + else: + defaultfile = "" + wf = WordFetcher(defaultfile) + frame = MyFrame(wf) + self.SetTopWindow(frame) + frame.Show(TRUE) + return TRUE if __name__ == '__main__': app = MyApp(0) diff --git a/wxPython/tests/tabs.py b/wxPython/tests/tabs.py index 1af9a13cfb..46d946bc62 100644 --- a/wxPython/tests/tabs.py +++ b/wxPython/tests/tabs.py @@ -1,5 +1,4 @@ from wxPython.wx import * -import string, sys class Test: def __init__(self): diff --git a/wxPython/tests/test7.py b/wxPython/tests/test7.py index 50f394ad5f..11b786e19f 100644 --- a/wxPython/tests/test7.py +++ b/wxPython/tests/test7.py @@ -35,17 +35,26 @@ class MyFrame(wxFrame): wxStaticText(panel, -1, "Size:", wxDLG_PNT(panel, wxPoint(4, 4)), wxDefaultSize) wxStaticText(panel, -1, "Pos:", - wxDLG_PNT(panel, wxPoint(4, 14)), wxDefaultSize) + wxDLG_PNT(panel, wxPoint(4, 18)), wxDefaultSize) + wxStaticText(panel, -1, "ScreenPos:", + wxDLG_PNT(panel, wxPoint(4, 32)), wxDefaultSize) self.sizeCtrl = wxTextCtrl(panel, -1, "", - wxDLG_PNT(panel, wxPoint(24, 4)), + wxDLG_PNT(panel, wxPoint(36, 4)), wxDLG_SZE(panel, wxSize(36, -1)), wxTE_READONLY) self.posCtrl = wxTextCtrl(panel, -1, "", - wxDLG_PNT(panel, wxPoint(24, 14)), + wxDLG_PNT(panel, wxPoint(36, 18)), wxDLG_SZE(panel, wxSize(36, -1)), wxTE_READONLY) + self.sposCtrl = wxTextCtrl(panel, -1, "", + wxDLG_PNT(panel, wxPoint(36, 32)), + wxDLG_SZE(panel, wxSize(36, -1)), + wxTE_READONLY) + + panel.Fit() + self.Fit() # This method is called automatically when the CLOSE event is # sent to this window @@ -59,6 +68,8 @@ class MyFrame(wxFrame): def OnSize(self, event): size = event.GetSize() self.sizeCtrl.SetValue("%s, %s" % (size.width, size.height)) + p = self.ClientToScreen((0,0)) + self.sposCtrl.SetValue("%s, %s" % (p.x, p.y)) # tell the event system to continue looking for an event handler, # so the default handler will get called. @@ -69,6 +80,8 @@ class MyFrame(wxFrame): def OnMove(self, event): pos = event.GetPosition() self.posCtrl.SetValue("%s, %s" % (pos.x, pos.y)) + p = self.ClientToScreen((0,0)) + self.sposCtrl.SetValue("%s, %s" % (p.x, p.y)) diff --git a/wxPython/tests/test8.py b/wxPython/tests/test8.py index ec383b7a09..34cd268791 100644 --- a/wxPython/tests/test8.py +++ b/wxPython/tests/test8.py @@ -18,15 +18,15 @@ use_wxpython = 1 def DoThread(mesg): while 1: sleeptime = (random() * 3) + 0.5 - print "Hello from %s (%1.3f)" % (mesg, sleeptime) - time.sleep(sleeptime) + print "Hello from %s (%1.3f)" % (mesg, sleeptime) + time.sleep(sleeptime) # the same, but write it to a textctrl. def DoTextCtrlThread(text, mesg): while 1: sleeptime = (random() * 3) + 0.5 - text.WriteText("Hello from %s (%1.3f)\n" % (mesg, sleeptime)) - time.sleep(sleeptime) + text.WriteText("Hello from %s (%1.3f)\n" % (mesg, sleeptime)) + time.sleep(sleeptime) # A very simple queue for textctrls. # Nice demonstration of the power of OO programming too (at least I think so!) @@ -34,41 +34,41 @@ def DoTextCtrlThread(text, mesg): # The main (UI) thread must call Flush to force output. (see MyFrame::OnIdle) class wxTextCtrlQueue(wxTextCtrl): def __init__(self, parent, id, value, pos, size, flags): - wxTextCtrl.__init__(self,parent, id, value, pos, size, flags) - self.queue = [] + wxTextCtrl.__init__(self,parent, id, value, pos, size, flags) + self.queue = [] def WriteText(self, value): - self.queue.append(value) + self.queue.append(value) def Flush(self): - queue = self.queue - self.queue = [] - for value in queue: - wxTextCtrl.WriteText(self,value) + queue = self.queue + self.queue = [] + for value in queue: + wxTextCtrl.WriteText(self,value) # MyFrame and MyApp are very simple classes to test python threads in # wxPython. class MyFrame(wxFrame): def __init__(self): - wxFrame.__init__(self, NULL, -1, "test threads", wxDefaultPosition, wxSize(300,200)) - self.text = wxTextCtrlQueue(self, -1, "thread output\n", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE) - menu = wxMenu() - menu.Append(1001, "Start thread") - self.cnt = 0; - menubar = wxMenuBar() - menubar.Append(menu, "Action") - self.SetMenuBar(menubar) - EVT_MENU(self, 1001, self.StartThread) + wxFrame.__init__(self, NULL, -1, "test threads", wxDefaultPosition, wxSize(300,200)) + self.text = wxTextCtrlQueue(self, -1, "thread output\n", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE) + menu = wxMenu() + menu.Append(1001, "Start thread") + self.cnt = 0; + menubar = wxMenuBar() + menubar.Append(menu, "Action") + self.SetMenuBar(menubar) + EVT_MENU(self, 1001, self.StartThread) def StartThread(self, event): - self.cnt = self.cnt + 1 - thread.start_new_thread(DoTextCtrlThread, (self.text, "thread %d" % self.cnt)) + self.cnt = self.cnt + 1 + thread.start_new_thread(DoTextCtrlThread, (self.text, "thread %d" % self.cnt)) def OnIdle(self, event): - self.text.Flush() + self.text.Flush() class MyApp(wxApp): def OnInit(self): - frame = MyFrame() - self.SetTopWindow(frame) - frame.Show(TRUE) - return TRUE + frame = MyFrame() + self.SetTopWindow(frame) + frame.Show(TRUE) + return TRUE # Start two threads that print a message every second thread.start_new_thread(DoThread, ("thread A",)) @@ -80,6 +80,6 @@ if use_wxpython: app.MainLoop() else: while 1: - print "main loop" - time.sleep(4) + print "main loop" + time.sleep(4) print 'done!' diff --git a/wxPython/tests/testDlg.py b/wxPython/tests/testDlg.py index 6dee2656d4..5bad5eb49a 100644 --- a/wxPython/tests/testDlg.py +++ b/wxPython/tests/testDlg.py @@ -5,43 +5,43 @@ from wxPython.wx import * ## Create a new frame class, derived from the wxPython Frame. class Dialog(wxDialog): - def __init__(self, parent, title): - # First, call the base class' __init__ method to create the frame - wxDialog.__init__( self, parent, -1, title, wxDefaultPosition, wxDefaultSize ) + def __init__(self, parent, title): + # First, call the base class' __init__ method to create the frame + wxDialog.__init__( self, parent, -1, title, wxDefaultPosition, wxDefaultSize ) wxButton(self, wxID_OK, "OK", (10, 10)) wxButton(self, wxID_CANCEL, "Cancel", (50,50)) - self.Centre( wxBOTH ) + self.Centre( wxBOTH ) - # This method is called automatically when the CLOSE event is - # sent to this window - #def OnCloseWindow(self, event): - # self.Destroy() + # This method is called automatically when the CLOSE event is + # sent to this window + #def OnCloseWindow(self, event): + # self.Destroy() - #def OnCloseMe(self, event): - #self.Close(true) + #def OnCloseMe(self, event): + #self.Close(true) def main(): - # Every wxWindows application must have a class derived from wxApp - class App(wxApp): + # Every wxWindows application must have a class derived from wxApp + class App(wxApp): - # wxWindows calls this method to initialize the application - def OnInit(self): + # wxWindows calls this method to initialize the application + def OnInit(self): - # Create an instance of our customized Frame class - dialog = Dialog( NULL, 'test' ) - dialog.ShowModal() + # Create an instance of our customized Frame class + dialog = Dialog( NULL, 'test' ) + dialog.ShowModal() print "got here" dialog.Destroy() - # Tell wxWindows that this is our main window - # Return a success flag - return true + # Tell wxWindows that this is our main window + # Return a success flag + return true - app = App(0) # Create an instance of the application class - app.MainLoop() # Tell it to start processing events + app = App(0) # Create an instance of the application class + app.MainLoop() # Tell it to start processing events diff --git a/wxPython/tests/testTree.py b/wxPython/tests/testTree.py index e445371c94..1b91ffd427 100644 --- a/wxPython/tests/testTree.py +++ b/wxPython/tests/testTree.py @@ -7,110 +7,110 @@ from stat import * GlobalObjList = [] class Obj: - def __init__(self, obj): - self.obj = obj - # Uncomment next line to eliminate crash. - # GlobalObjList.append(self) - - def Name(self): - head, tail = os.path.split(self.obj) - if tail: - return tail - else: - return head - - def HasChildren(self): - return os.path.isdir(self.obj) - - def Children(self): - objList = os.listdir(self.obj) - objList.sort() - objList = map(lambda obj,parent=self.obj: os.path.join(parent,obj), - objList) - objectList = map(Obj, objList) - return objectList - - def __str__(self): - return self.obj - - def __repr__(self): - return self.obj - - def __del__(self): - print 'del', self.obj - + def __init__(self, obj): + self.obj = obj + # Uncomment next line to eliminate crash. + # GlobalObjList.append(self) + + def Name(self): + head, tail = os.path.split(self.obj) + if tail: + return tail + else: + return head + + def HasChildren(self): + return os.path.isdir(self.obj) + + def Children(self): + objList = os.listdir(self.obj) + objList.sort() + objList = map(lambda obj,parent=self.obj: os.path.join(parent,obj), + objList) + objectList = map(Obj, objList) + return objectList + + def __str__(self): + return self.obj + + def __repr__(self): + return self.obj + + def __del__(self): + print 'del', self.obj + #---------------------------------------------------------------------- class pyTree(wx.wxTreeCtrl): - def __init__(self, parent, id, obj): - wx.wxTreeCtrl.__init__(self, parent, id) - self.root = self.AddRoot(obj.Name(), -1, -1, wx.wxTreeItemData('')) - self.SetPyData(self.root, obj) - if obj.HasChildren(): - self.SetItemHasChildren(self.root, wx.TRUE) - wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding) - wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed) - wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) - self.output = None - - def SetOutput(self, output): - self.output = output - - def OnItemExpanding(self,event): - item = event.GetItem() - obj = self.GetPyData(item) - children = obj.Children() - for child in children: - new_item = self.AppendItem(item, child.Name(), -1, -1, - wx.wxTreeItemData('')) - self.SetPyData(new_item, child) - if child.HasChildren(): - self.SetItemHasChildren(new_item, wx.TRUE) - - def OnItemCollapsed(self, event): - item = event.GetItem() - self.DeleteChildren(item) - - def OnSelChanged(self, event): - if not self.output: - return - obj = self.GetPyData( event.GetItem() ) - apply(self.output, (`obj`,)) + def __init__(self, parent, id, obj): + wx.wxTreeCtrl.__init__(self, parent, id) + self.root = self.AddRoot(obj.Name(), -1, -1, wx.wxTreeItemData('')) + self.SetPyData(self.root, obj) + if obj.HasChildren(): + self.SetItemHasChildren(self.root, wx.TRUE) + wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding) + wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed) + wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) + self.output = None + + def SetOutput(self, output): + self.output = output + + def OnItemExpanding(self,event): + item = event.GetItem() + obj = self.GetPyData(item) + children = obj.Children() + for child in children: + new_item = self.AppendItem(item, child.Name(), -1, -1, + wx.wxTreeItemData('')) + self.SetPyData(new_item, child) + if child.HasChildren(): + self.SetItemHasChildren(new_item, wx.TRUE) + + def OnItemCollapsed(self, event): + item = event.GetItem() + self.DeleteChildren(item) + + def OnSelChanged(self, event): + if not self.output: + return + obj = self.GetPyData( event.GetItem() ) + apply(self.output, (`obj`,)) #---------------------------------------------------------------------- if __name__ == '__main__': - class MyFrame(wx.wxFrame): - - def __init__(self): - wx.wxFrame.__init__(self, wx.NULL, -1, 'PyTreeItemData Test', - wx.wxDefaultPosition, wx.wxSize(600,500)) - split = wx.wxSplitterWindow(self, -1) - - if sys.platform == 'win32': - tree = pyTree(split, -1, Obj('C:\\')) - else: - tree = pyTree(split, -1, Obj('/')) - - text = wx.wxTextCtrl(split, -1, '', wx.wxDefaultPosition, - wx.wxDefaultSize, wx.wxTE_MULTILINE) - split.SplitVertically(tree, text, 200) - tree.SetOutput(text.SetValue) - tree.SelectItem(tree.root) - - class MyApp(wx.wxApp): - - def OnInit(self): - frame = MyFrame() - frame.Show(wx.TRUE) - self.SetTopWindow(frame) - return wx.TRUE - - app = MyApp(0) - app.MainLoop() + class MyFrame(wx.wxFrame): + + def __init__(self): + wx.wxFrame.__init__(self, wx.NULL, -1, 'PyTreeItemData Test', + wx.wxDefaultPosition, wx.wxSize(600,500)) + split = wx.wxSplitterWindow(self, -1) + + if sys.platform == 'win32': + tree = pyTree(split, -1, Obj('C:\\')) + else: + tree = pyTree(split, -1, Obj('/')) + + text = wx.wxTextCtrl(split, -1, '', wx.wxDefaultPosition, + wx.wxDefaultSize, wx.wxTE_MULTILINE) + split.SplitVertically(tree, text, 200) + tree.SetOutput(text.SetValue) + tree.SelectItem(tree.root) + + class MyApp(wx.wxApp): + + def OnInit(self): + frame = MyFrame() + frame.Show(wx.TRUE) + self.SetTopWindow(frame) + return wx.TRUE + + app = MyApp(0) + app.MainLoop() diff --git a/wxPython/tests/txml.py b/wxPython/tests/txml.py index 9c87e276dc..c8ea85f53c 100644 --- a/wxPython/tests/txml.py +++ b/wxPython/tests/txml.py @@ -3,7 +3,7 @@ Build a GUI Tree (wxWindows) from an XML file using pyExpat """ -import sys,string +import sys from xml.parsers import pyexpat from wxPython.wx import * @@ -59,7 +59,7 @@ def EndElement( name ): def CharacterData ( data ): global NodeStack - if string.strip(data): + if data.strip(): app.tree.AppendItem(NodeStack[-1],data) diff --git a/wxPython/tests/val.py b/wxPython/tests/val.py index 9a05123019..d36f0c092c 100644 --- a/wxPython/tests/val.py +++ b/wxPython/tests/val.py @@ -1,5 +1,4 @@ from wxPython.wx import * -import string class floatValidator(wxPyValidator): @@ -24,7 +23,7 @@ class floatValidator(wxPyValidator): if self.obj and self.attrName: tc = wxPyTypeCast(self.GetWindow(), "wxTextCtrl") text = tc.GetValue() - setattr(self.obj, self.attrName, string.atof(text)) + setattr(self.obj, self.attrName, float(text)) return true diff --git a/wxPython/tests/wxPlotCanvas.py b/wxPython/tests/wxPlotCanvas.py index baa9112c10..c65e7011fb 100644 --- a/wxPython/tests/wxPlotCanvas.py +++ b/wxPython/tests/wxPlotCanvas.py @@ -20,22 +20,21 @@ Original comment follows below: """ from wxPython import wx -import string # Not everybody will have Numeric, so let's be cool about it... try: import Numeric except: # bummer! - d = wx.wxMessageDialog(wx.NULL, + d = wx.wxMessageDialog(wx.NULL, """This module requires the Numeric module, which could not be imported. It probably is not installed (it's not part of the standard Python -distribution). See the Python site (http://www.python.org) for -information on downloading source or binaries.""", +distribution). See the Python site (http://www.python.org) for +information on downloading source or binaries.""", "Numeric not found") if d.ShowModal() == wx.wxID_CANCEL: - d = wx.wxMessageDialog(wx.NULL, "I kid you not! Pressing Cancel won't help you!", "Not a joke", wx.wxOK) - d.ShowModal() + d = wx.wxMessageDialog(wx.NULL, "I kid you not! Pressing Cancel won't help you!", "Not a joke", wx.wxOK) + d.ShowModal() import sys sys.exit() @@ -46,7 +45,7 @@ class PolyPoints: def __init__(self, points, attr): self.points = Numeric.array(points) - self.scaled = self.points + self.scaled = self.points self.attributes = {} for name, value in self._attributes.items(): try: @@ -71,11 +70,11 @@ class PolyLine(PolyPoints): 'width': 1} def draw(self, dc): - color = self.attributes['color'] - width = self.attributes['width'] - arguments = [] - dc.SetPen(wx.wxPen(wx.wxNamedColour(color), width)) - dc.DrawLines(map(tuple,self.scaled)) + color = self.attributes['color'] + width = self.attributes['width'] + arguments = [] + dc.SetPen(wx.wxPen(wx.wxNamedColour(color), width)) + dc.DrawLines(map(tuple,self.scaled)) class PolyMarker(PolyPoints): @@ -88,25 +87,25 @@ class PolyMarker(PolyPoints): 'width': 1, 'fillcolor': None, 'size': 2, - 'fillstyle': wx.wxSOLID, + 'fillstyle': wx.wxSOLID, 'outline': 'black', 'marker': 'circle'} def draw(self, dc): - color = self.attributes['color'] - width = self.attributes['width'] + color = self.attributes['color'] + width = self.attributes['width'] size = self.attributes['size'] fillcolor = self.attributes['fillcolor'] fillstyle = self.attributes['fillstyle'] marker = self.attributes['marker'] - dc.SetPen(wx.wxPen(wx.wxNamedColour(color),width)) - if fillcolor: - dc.SetBrush(wx.wxBrush(wx.wxNamedColour(fillcolor),fillstyle)) - else: - dc.SetBrush(wx.wxBrush(wx.wxNamedColour('black'), wx.wxTRANSPARENT)) + dc.SetPen(wx.wxPen(wx.wxNamedColour(color),width)) + if fillcolor: + dc.SetBrush(wx.wxBrush(wx.wxNamedColour(fillcolor),fillstyle)) + else: + dc.SetBrush(wx.wxBrush(wx.wxNamedColour('black'), wx.wxTRANSPARENT)) - self._drawmarkers(dc, self.scaled, marker, size) + self._drawmarkers(dc, self.scaled, marker, size) def _drawmarkers(self, dc, coords, marker,size=1): f = eval('self._' +marker) @@ -114,31 +113,31 @@ class PolyMarker(PolyPoints): f(dc, xc, yc, size) def _circle(self, dc, xc, yc, size=1): - dc.DrawEllipse(xc-2.5*size,yc-2.5*size,5.*size,5.*size) + dc.DrawEllipse(xc-2.5*size,yc-2.5*size,5.*size,5.*size) def _dot(self, dc, xc, yc, size=1): - dc.DrawPoint(xc,yc) + dc.DrawPoint(xc,yc) def _square(self, dc, xc, yc, size=1): - dc.DrawRectangle(xc-2.5*size,yc-2.5*size,5.*size,5.*size) - + dc.DrawRectangle(xc-2.5*size,yc-2.5*size,5.*size,5.*size) + def _triangle(self, dc, xc, yc, size=1): - dc.DrawPolygon([(-0.5*size*5,0.2886751*size*5), - (0.5*size*5,0.2886751*size*5), - (0.0,-0.577350*size*5)],xc,yc) + dc.DrawPolygon([(-0.5*size*5,0.2886751*size*5), + (0.5*size*5,0.2886751*size*5), + (0.0,-0.577350*size*5)],xc,yc) def _triangle_down(self, dc, xc, yc, size=1): - dc.DrawPolygon([(-0.5*size*5,-0.2886751*size*5), - (0.5*size*5,-0.2886751*size*5), - (0.0,0.577350*size*5)],xc,yc) + dc.DrawPolygon([(-0.5*size*5,-0.2886751*size*5), + (0.5*size*5,-0.2886751*size*5), + (0.0,0.577350*size*5)],xc,yc) def _cross(self, dc, xc, yc, size=1): - dc.DrawLine(xc-2.5*size,yc-2.5*size,xc+2.5*size,yc+2.5*size) - dc.DrawLine(xc-2.5*size,yc+2.5*size,xc+2.5*size,yc-2.5*size) + dc.DrawLine(xc-2.5*size,yc-2.5*size,xc+2.5*size,yc+2.5*size) + dc.DrawLine(xc-2.5*size,yc+2.5*size,xc+2.5*size,yc-2.5*size) def _plus(self, dc, xc, yc, size=1): - dc.DrawLine(xc-2.5*size,yc,xc+2.5*size,yc) - dc.DrawLine(xc,yc-2.5*size,xc,yc+2.5*size) + dc.DrawLine(xc-2.5*size,yc,xc+2.5*size,yc) + dc.DrawLine(xc,yc-2.5*size,xc,yc+2.5*size) class PlotGraphics: @@ -146,191 +145,191 @@ class PlotGraphics: self.objects = objects def boundingBox(self): - p1, p2 = self.objects[0].boundingBox() - for o in self.objects[1:]: - p1o, p2o = o.boundingBox() - p1 = Numeric.minimum(p1, p1o) - p2 = Numeric.maximum(p2, p2o) - return p1, p2 + p1, p2 = self.objects[0].boundingBox() + for o in self.objects[1:]: + p1o, p2o = o.boundingBox() + p1 = Numeric.minimum(p1, p1o) + p2 = Numeric.maximum(p2, p2o) + return p1, p2 def scaleAndShift(self, scale=1, shift=0): - for o in self.objects: - o.scaleAndShift(scale, shift) + for o in self.objects: + o.scaleAndShift(scale, shift) def draw(self, canvas): - for o in self.objects: - o.draw(canvas) + for o in self.objects: + o.draw(canvas) def __len__(self): - return len(self.objects) + return len(self.objects) def __getitem__(self, item): - return self.objects[item] + return self.objects[item] class PlotCanvas(wx.wxWindow): def __init__(self, parent, id = -1): - wx.wxWindow.__init__(self, parent, id, wx.wxPyDefaultPosition, wx.wxPyDefaultSize) - self.border = (1,1) - self.SetClientSizeWH(400,400) - self.SetBackgroundColour(wx.wxNamedColour("white")) + wx.wxWindow.__init__(self, parent, id, wx.wxPyDefaultPosition, wx.wxPyDefaultSize) + self.border = (1,1) + self.SetClientSizeWH(400,400) + self.SetBackgroundColour(wx.wxNamedColour("white")) - wx.EVT_SIZE(self,self.reconfigure) - self._setsize() - self.last_draw = None -# self.font = self._testFont(font) + wx.EVT_SIZE(self,self.reconfigure) + self._setsize() + self.last_draw = None +# self.font = self._testFont(font) def OnPaint(self, event): - pdc = wx.wxPaintDC(self) - if self.last_draw is not None: - apply(self.draw, self.last_draw + (pdc,)) + pdc = wx.wxPaintDC(self) + if self.last_draw is not None: + apply(self.draw, self.last_draw + (pdc,)) def reconfigure(self, event): - (new_width,new_height) = self.GetClientSizeTuple() + (new_width,new_height) = self.GetClientSizeTuple() if new_width == self.width and new_height == self.height: return self._setsize() # self.redraw() def _testFont(self, font): - if font is not None: - bg = self.canvas.cget('background') - try: - item = CanvasText(self.canvas, 0, 0, anchor=NW, - text='0', fill=bg, font=font) - self.canvas.delete(item) - except TclError: - font = None - return font + if font is not None: + bg = self.canvas.cget('background') + try: + item = CanvasText(self.canvas, 0, 0, anchor=NW, + text='0', fill=bg, font=font) + self.canvas.delete(item) + except TclError: + font = None + return font def _setsize(self): - (self.width,self.height) = self.GetClientSizeTuple(); - self.plotbox_size = 0.97*Numeric.array([self.width, -self.height]) - xo = 0.5*(self.width-self.plotbox_size[0]) - yo = self.height-0.5*(self.height+self.plotbox_size[1]) - self.plotbox_origin = Numeric.array([xo, yo]) + (self.width,self.height) = self.GetClientSizeTuple(); + self.plotbox_size = 0.97*Numeric.array([self.width, -self.height]) + xo = 0.5*(self.width-self.plotbox_size[0]) + yo = self.height-0.5*(self.height+self.plotbox_size[1]) + self.plotbox_origin = Numeric.array([xo, yo]) def draw(self, graphics, xaxis = None, yaxis = None, dc = None): - if dc == None: dc = wx.wxClientDC(self) - dc.BeginDrawing() - dc.Clear() - self.last_draw = (graphics, xaxis, yaxis) - p1, p2 = graphics.boundingBox() - xaxis = self._axisInterval(xaxis, p1[0], p2[0]) - yaxis = self._axisInterval(yaxis, p1[1], p2[1]) - text_width = [0., 0.] - text_height = [0., 0.] - if xaxis is not None: - p1[0] = xaxis[0] - p2[0] = xaxis[1] - xticks = self._ticks(xaxis[0], xaxis[1]) - bb = dc.GetTextExtent(xticks[0][1]) - text_height[1] = bb[1] - text_width[0] = 0.5*bb[0] - bb = dc.GetTextExtent(xticks[-1][1]) - text_width[1] = 0.5*bb[0] - else: - xticks = None - if yaxis is not None: - p1[1] = yaxis[0] - p2[1] = yaxis[1] - yticks = self._ticks(yaxis[0], yaxis[1]) - for y in yticks: - bb = dc.GetTextExtent(y[1]) - text_width[0] = max(text_width[0],bb[0]) - h = 0.5*bb[1] - text_height[0] = h - text_height[1] = max(text_height[1], h) - else: - yticks = None - text1 = Numeric.array([text_width[0], -text_height[1]]) - text2 = Numeric.array([text_width[1], -text_height[0]]) - scale = (self.plotbox_size-text1-text2) / (p2-p1) - shift = -p1*scale + self.plotbox_origin + text1 - self._drawAxes(dc, xaxis, yaxis, p1, p2, + if dc == None: dc = wx.wxClientDC(self) + dc.BeginDrawing() + dc.Clear() + self.last_draw = (graphics, xaxis, yaxis) + p1, p2 = graphics.boundingBox() + xaxis = self._axisInterval(xaxis, p1[0], p2[0]) + yaxis = self._axisInterval(yaxis, p1[1], p2[1]) + text_width = [0., 0.] + text_height = [0., 0.] + if xaxis is not None: + p1[0] = xaxis[0] + p2[0] = xaxis[1] + xticks = self._ticks(xaxis[0], xaxis[1]) + bb = dc.GetTextExtent(xticks[0][1]) + text_height[1] = bb[1] + text_width[0] = 0.5*bb[0] + bb = dc.GetTextExtent(xticks[-1][1]) + text_width[1] = 0.5*bb[0] + else: + xticks = None + if yaxis is not None: + p1[1] = yaxis[0] + p2[1] = yaxis[1] + yticks = self._ticks(yaxis[0], yaxis[1]) + for y in yticks: + bb = dc.GetTextExtent(y[1]) + text_width[0] = max(text_width[0],bb[0]) + h = 0.5*bb[1] + text_height[0] = h + text_height[1] = max(text_height[1], h) + else: + yticks = None + text1 = Numeric.array([text_width[0], -text_height[1]]) + text2 = Numeric.array([text_width[1], -text_height[0]]) + scale = (self.plotbox_size-text1-text2) / (p2-p1) + shift = -p1*scale + self.plotbox_origin + text1 + self._drawAxes(dc, xaxis, yaxis, p1, p2, scale, shift, xticks, yticks) - graphics.scaleAndShift(scale, shift) - graphics.draw(dc) - dc.EndDrawing() + graphics.scaleAndShift(scale, shift) + graphics.draw(dc) + dc.EndDrawing() def _axisInterval(self, spec, lower, upper): - if spec is None: - return None - if spec == 'minimal': - if lower == upper: - return lower-0.5, upper+0.5 - else: - return lower, upper - if spec == 'automatic': - range = upper-lower - if range == 0.: - return lower-0.5, upper+0.5 - log = Numeric.log10(range) - power = Numeric.floor(log) - fraction = log-power - if fraction <= 0.05: - power = power-1 - grid = 10.**power - lower = lower - lower % grid - mod = upper % grid - if mod != 0: - upper = upper - mod + grid - return lower, upper - if type(spec) == type(()): - lower, upper = spec - if lower <= upper: - return lower, upper - else: - return upper, lower - raise ValueError, str(spec) + ': illegal axis specification' + if spec is None: + return None + if spec == 'minimal': + if lower == upper: + return lower-0.5, upper+0.5 + else: + return lower, upper + if spec == 'automatic': + range = upper-lower + if range == 0.: + return lower-0.5, upper+0.5 + log = Numeric.log10(range) + power = Numeric.floor(log) + fraction = log-power + if fraction <= 0.05: + power = power-1 + grid = 10.**power + lower = lower - lower % grid + mod = upper % grid + if mod != 0: + upper = upper - mod + grid + return lower, upper + if type(spec) == type(()): + lower, upper = spec + if lower <= upper: + return lower, upper + else: + return upper, lower + raise ValueError, str(spec) + ': illegal axis specification' def _drawAxes(self, dc, xaxis, yaxis, bb1, bb2, scale, shift, xticks, yticks): - dc.SetPen(wx.wxPen(wx.wxNamedColour('BLACK'),1)) - if xaxis is not None: - lower, upper = xaxis - text = 1 - for y, d in [(bb1[1], -3), (bb2[1], 3)]: - p1 = scale*Numeric.array([lower, y])+shift - p2 = scale*Numeric.array([upper, y])+shift - dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) - for x, label in xticks: - p = scale*Numeric.array([x, y])+shift - dc.DrawLine(p[0],p[1],p[0],p[1]+d) - if text: - dc.DrawText(label,p[0],p[1]) - text = 0 - - if yaxis is not None: - lower, upper = yaxis - text = 1 - h = dc.GetCharHeight() - for x, d in [(bb1[0], -3), (bb2[0], 3)]: - p1 = scale*Numeric.array([x, lower])+shift - p2 = scale*Numeric.array([x, upper])+shift - dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) - for y, label in yticks: - p = scale*Numeric.array([x, y])+shift - dc.DrawLine(p[0],p[1],p[0]-d,p[1]) - if text: - dc.DrawText(label,p[0]-dc.GetTextExtent(label)[0], - p[1]-0.5*h) - text = 0 + dc.SetPen(wx.wxPen(wx.wxNamedColour('BLACK'),1)) + if xaxis is not None: + lower, upper = xaxis + text = 1 + for y, d in [(bb1[1], -3), (bb2[1], 3)]: + p1 = scale*Numeric.array([lower, y])+shift + p2 = scale*Numeric.array([upper, y])+shift + dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) + for x, label in xticks: + p = scale*Numeric.array([x, y])+shift + dc.DrawLine(p[0],p[1],p[0],p[1]+d) + if text: + dc.DrawText(label,p[0],p[1]) + text = 0 + + if yaxis is not None: + lower, upper = yaxis + text = 1 + h = dc.GetCharHeight() + for x, d in [(bb1[0], -3), (bb2[0], 3)]: + p1 = scale*Numeric.array([x, lower])+shift + p2 = scale*Numeric.array([x, upper])+shift + dc.DrawLine(p1[0],p1[1],p2[0],p2[1]) + for y, label in yticks: + p = scale*Numeric.array([x, y])+shift + dc.DrawLine(p[0],p[1],p[0]-d,p[1]) + if text: + dc.DrawText(label,p[0]-dc.GetTextExtent(label)[0], + p[1]-0.5*h) + text = 0 def _ticks(self, lower, upper): - ideal = (upper-lower)/7. - log = Numeric.log10(ideal) - power = Numeric.floor(log) - fraction = log-power - factor = 1. - error = fraction - for f, lf in self._multiples: - e = Numeric.fabs(fraction-lf) - if e < error: - error = e - factor = f - grid = factor * 10.**power + ideal = (upper-lower)/7. + log = Numeric.log10(ideal) + power = Numeric.floor(log) + fraction = log-power + factor = 1. + error = fraction + for f, lf in self._multiples: + e = Numeric.fabs(fraction-lf) + if e < error: + error = e + factor = f + grid = factor * 10.**power if power > 3 or power < -3: format = '%+7.0e' elif power >= 0: @@ -339,18 +338,18 @@ class PlotCanvas(wx.wxWindow): else: digits = -int(power) format = '%'+`digits+2`+'.'+`digits`+'f' - ticks = [] - t = -grid*Numeric.floor(-lower/grid) - while t <= upper: - ticks.append(t, format % (t,)) - t = t + grid - return ticks + ticks = [] + t = -grid*Numeric.floor(-lower/grid) + while t <= upper: + ticks.append(t, format % (t,)) + t = t + grid + return ticks _multiples = [(2., Numeric.log10(2.)), (5., Numeric.log10(5.))] def redraw(self,dc=None): - if self.last_draw is not None: - apply(self.draw, self.last_draw + (dc,)) + if self.last_draw is not None: + apply(self.draw, self.last_draw + (dc,)) def clear(self): self.canvas.delete('all') @@ -362,98 +361,98 @@ class PlotCanvas(wx.wxWindow): if __name__ == '__main__': class AppFrame(wx.wxFrame): - def __init__(self, parent, id, title): - wx.wxFrame.__init__(self, parent, id, title, - wx.wxPyDefaultPosition, wx.wxSize(400, 400)) - - # Now Create the menu bar and items - self.mainmenu = wx.wxMenuBar() - - menu = wx.wxMenu() - menu.Append(200, '&Print...', 'Print the current plot') - wx.EVT_MENU(self, 200, self.OnFilePrint) - menu.Append(209, 'E&xit', 'Enough of this already!') - wx.EVT_MENU(self, 209, self.OnFileExit) - self.mainmenu.Append(menu, '&File') - - menu = wx.wxMenu() - menu.Append(210, '&Draw', 'Draw plots') - wx.EVT_MENU(self,210,self.OnPlotDraw) - menu.Append(211, '&Redraw', 'Redraw plots') - wx.EVT_MENU(self,211,self.OnPlotRedraw) - menu.Append(212, '&Clear', 'Clear canvas') - wx.EVT_MENU(self,212,self.OnPlotClear) - self.mainmenu.Append(menu, '&Plot') - - menu = wx.wxMenu() - menu.Append(220, '&About', 'About this thing...') - wx.EVT_MENU(self, 220, self.OnHelpAbout) - self.mainmenu.Append(menu, '&Help') - - self.SetMenuBar(self.mainmenu) - - # A status bar to tell people what's happening - self.CreateStatusBar(1) - - self.client = PlotCanvas(self) - - def OnFilePrint(self, event): - d = wx.wxMessageDialog(self, + def __init__(self, parent, id, title): + wx.wxFrame.__init__(self, parent, id, title, + wx.wxPyDefaultPosition, wx.wxSize(400, 400)) + + # Now Create the menu bar and items + self.mainmenu = wx.wxMenuBar() + + menu = wx.wxMenu() + menu.Append(200, '&Print...', 'Print the current plot') + wx.EVT_MENU(self, 200, self.OnFilePrint) + menu.Append(209, 'E&xit', 'Enough of this already!') + wx.EVT_MENU(self, 209, self.OnFileExit) + self.mainmenu.Append(menu, '&File') + + menu = wx.wxMenu() + menu.Append(210, '&Draw', 'Draw plots') + wx.EVT_MENU(self,210,self.OnPlotDraw) + menu.Append(211, '&Redraw', 'Redraw plots') + wx.EVT_MENU(self,211,self.OnPlotRedraw) + menu.Append(212, '&Clear', 'Clear canvas') + wx.EVT_MENU(self,212,self.OnPlotClear) + self.mainmenu.Append(menu, '&Plot') + + menu = wx.wxMenu() + menu.Append(220, '&About', 'About this thing...') + wx.EVT_MENU(self, 220, self.OnHelpAbout) + self.mainmenu.Append(menu, '&Help') + + self.SetMenuBar(self.mainmenu) + + # A status bar to tell people what's happening + self.CreateStatusBar(1) + + self.client = PlotCanvas(self) + + def OnFilePrint(self, event): + d = wx.wxMessageDialog(self, """As of this writing, printing support in wxPython is shaky at best. Are you sure you want to do this?""", "Danger!", wx.wxYES_NO) if d.ShowModal() == wx.wxID_YES: - psdc = wx.wxPostScriptDC("out.ps", wx.TRUE, self) - self.client.redraw(psdc) + psdc = wx.wxPostScriptDC("out.ps", wx.TRUE, self) + self.client.redraw(psdc) - def OnFileExit(self, event): - self.Close() + def OnFileExit(self, event): + self.Close() - def OnPlotDraw(self, event): - self.client.draw(InitObjects(),'automatic','automatic'); + def OnPlotDraw(self, event): + self.client.draw(InitObjects(),'automatic','automatic'); - def OnPlotRedraw(self,event): - self.client.redraw() + def OnPlotRedraw(self,event): + self.client.redraw() - def OnPlotClear(self,event): - self.client.last_draw = None - dc = wx.wxClientDC(self.client) - dc.Clear() + def OnPlotClear(self,event): + self.client.last_draw = None + dc = wx.wxClientDC(self.client) + dc.Clear() - def OnHelpAbout(self, event): - about = wx.wxMessageDialog(self, __doc__, "About...", wx.wxOK) - about.ShowModal() + def OnHelpAbout(self, event): + about = wx.wxMessageDialog(self, __doc__, "About...", wx.wxOK) + about.ShowModal() - def OnCloseWindow(self, event): - self.Destroy() + def OnCloseWindow(self, event): + self.Destroy() def InitObjects(): - # 100 points sin function, plotted as green circles - data1 = 2.*Numeric.pi*Numeric.arange(200)/200. - data1.shape = (100, 2) - data1[:,1] = Numeric.sin(data1[:,0]) - markers1 = PolyMarker(data1, color='green', marker='circle',size=1) + # 100 points sin function, plotted as green circles + data1 = 2.*Numeric.pi*Numeric.arange(200)/200. + data1.shape = (100, 2) + data1[:,1] = Numeric.sin(data1[:,0]) + markers1 = PolyMarker(data1, color='green', marker='circle',size=1) - # 50 points cos function, plotted as red line - data1 = 2.*Numeric.pi*Numeric.arange(100)/100. - data1.shape = (50,2) - data1[:,1] = Numeric.cos(data1[:,0]) - lines = PolyLine(data1, color='red') + # 50 points cos function, plotted as red line + data1 = 2.*Numeric.pi*Numeric.arange(100)/100. + data1.shape = (50,2) + data1[:,1] = Numeric.cos(data1[:,0]) + lines = PolyLine(data1, color='red') - # A few more points... - pi = Numeric.pi - markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.), - (3.*pi/4., -1)], color='blue', - fillcolor='green', marker='cross') + # A few more points... + pi = Numeric.pi + markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.), + (3.*pi/4., -1)], color='blue', + fillcolor='green', marker='cross') - return PlotGraphics([markers1, lines, markers2]) + return PlotGraphics([markers1, lines, markers2]) class MyApp(wx.wxApp): - def OnInit(self): - frame = AppFrame(wx.NULL, -1, "wxPlotCanvas") - frame.Show(wx.TRUE) - self.SetTopWindow(frame) - return wx.TRUE + def OnInit(self): + frame = AppFrame(wx.NULL, -1, "wxPlotCanvas") + frame.Show(wx.TRUE) + self.SetTopWindow(frame) + return wx.TRUE app = MyApp(0) diff --git a/wxPython/tests/wxSlash.py b/wxPython/tests/wxSlash.py index ae1164d233..c98148a028 100644 --- a/wxPython/tests/wxSlash.py +++ b/wxPython/tests/wxSlash.py @@ -164,22 +164,22 @@ class AppStatusBar(wxStatusBar): # This is a simple timer class to start a function after a short delay; class QuickTimer(wxTimer): def __init__(self, func, wait=100): - wxTimer.__init__(self) - self.callback = func - self.Start(wait); # wait .1 second (.001 second doesn't work. why?) + wxTimer.__init__(self) + self.callback = func + self.Start(wait); # wait .1 second (.001 second doesn't work. why?) def Notify(self): - self.Stop(); - apply(self.callback, ()); + self.Stop(); + apply(self.callback, ()); class AppFrame(wxFrame): def __init__(self, parent, id, title): wxFrame.__init__(self, parent, id, title, wxPyDefaultPosition, wxSize(650, 250)) - # if the window manager closes the window: - EVT_CLOSE(self, self.OnCloseWindow); + # if the window manager closes the window: + EVT_CLOSE(self, self.OnCloseWindow); - # Now Create the menu bar and items + # Now Create the menu bar and items self.mainmenu = wxMenuBar() menu = wxMenu() @@ -202,46 +202,46 @@ class AppFrame(wxFrame): menu.Append(222, '&Settings...', 'External browser Settings') EVT_MENU(self, 222, self.OnBrowserSettings) self.mainmenu.Append(menu, '&Browser') - menu = wxMenu() - menu.Append(230, '&About', 'Some documentation'); - EVT_MENU(self, 230, self.OnAbout) - self.mainmenu.Append(menu, '&Help') + menu = wxMenu() + menu.Append(230, '&About', 'Some documentation'); + EVT_MENU(self, 230, self.OnAbout) + self.mainmenu.Append(menu, '&Help') self.SetMenuBar(self.mainmenu) - if wxPlatform == '__WXGTK__': - # I like lynx. Also Netscape 4.5 doesn't react to my cmdline opts - self.BrowserSettings = "xterm -e lynx %s &" - elif wxPlatform == '__WXMSW__': - # netscape 4.x likes to hang out here... - self.BrowserSettings = '\\progra~1\\Netscape\\Communicator\\Program\\netscape.exe %s' - else: - # a wild guess... - self.BrowserSettings = 'netscape %s' - - # A status bar to tell people what's happening - self.sb = AppStatusBar(self) + if wxPlatform == '__WXGTK__': + # I like lynx. Also Netscape 4.5 doesn't react to my cmdline opts + self.BrowserSettings = "xterm -e lynx %s &" + elif wxPlatform == '__WXMSW__': + # netscape 4.x likes to hang out here... + self.BrowserSettings = '\\progra~1\\Netscape\\Communicator\\Program\\netscape.exe %s' + else: + # a wild guess... + self.BrowserSettings = 'netscape %s' + + # A status bar to tell people what's happening + self.sb = AppStatusBar(self) self.SetStatusBar(self.sb) self.list = wxListCtrl(self, 1100) - self.list.SetSingleStyle(wxLC_REPORT) - self.list.InsertColumn(0, 'Subject') - self.list.InsertColumn(1, 'Date') - self.list.InsertColumn(2, 'Posted by') - self.list.InsertColumn(3, 'Comments') + self.list.SetSingleStyle(wxLC_REPORT) + self.list.InsertColumn(0, 'Subject') + self.list.InsertColumn(1, 'Date') + self.list.InsertColumn(2, 'Posted by') + self.list.InsertColumn(3, 'Comments') self.list.SetColumnWidth(0, 300) self.list.SetColumnWidth(1, 150) self.list.SetColumnWidth(2, 100) self.list.SetColumnWidth(3, 100) EVT_LIST_ITEM_SELECTED(self, 1100, self.OnItemSelected) - EVT_LEFT_DCLICK(self.list, self.OnLeftDClick) + EVT_LEFT_DCLICK(self.list, self.OnLeftDClick) - self.logprint("Connecting to slashdot... Please wait.") - # wxYield doesn't yet work here. That's why we use a timer - # to make sure that we see some GUI stuff before the slashdot - # file is transfered. - self.timer = QuickTimer(self.DoRefresh, 1000) + self.logprint("Connecting to slashdot... Please wait.") + # wxYield doesn't yet work here. That's why we use a timer + # to make sure that we see some GUI stuff before the slashdot + # file is transfered. + self.timer = QuickTimer(self.DoRefresh, 1000) def logprint(self, x): self.sb.logprint(x) @@ -263,12 +263,12 @@ class AppFrame(wxFrame): self.list.SetStringItem(i, 3, article[6]) self.url.append(article[1]) i = i + 1 - self.logprint("File retrieved OK.") + self.logprint("File retrieved OK.") def OnViewRefresh(self, event): - self.logprint("Connecting to slashdot... Please wait."); - wxYield() - self.DoRefresh() + self.logprint("Connecting to slashdot... Please wait."); + wxYield() + self.DoRefresh() def DoViewIndex(self): if self.UseInternal: @@ -278,12 +278,12 @@ class AppFrame(wxFrame): else: self.logprint(self.BrowserSettings % ('http://slashdot.org')) os.system(self.BrowserSettings % ('http://slashdot.org')) - self.logprint("OK") + self.logprint("OK") def OnViewIndex(self, event): - self.logprint("Starting browser... Please wait.") - wxYield() - self.DoViewIndex() + self.logprint("Starting browser... Please wait.") + wxYield() + self.DoViewIndex() def DoViewArticle(self): if self.current<0: return @@ -294,12 +294,12 @@ class AppFrame(wxFrame): else: self.logprint(self.BrowserSettings % (url)) os.system(self.BrowserSettings % (url)) - self.logprint("OK") + self.logprint("OK") def OnViewArticle(self, event): - self.logprint("Starting browser... Please wait.") - wxYield() - self.DoViewArticle() + self.logprint("Starting browser... Please wait.") + wxYield() + self.DoViewArticle() def OnBrowserInternal(self, event): if self.mainmenu.Checked(220): @@ -313,28 +313,28 @@ class AppFrame(wxFrame): self.BrowserSettings = dlg.GetValue() def OnAbout(self, event): - dlg = wxMessageDialog(self, __doc__, "wxSlash", wxOK | wxICON_INFORMATION) - dlg.ShowModal() + dlg = wxMessageDialog(self, __doc__, "wxSlash", wxOK | wxICON_INFORMATION) + dlg.ShowModal() def OnItemSelected(self, event): self.current = event.m_itemIndex self.logprint("URL: %s" % (self.url[self.current])) def OnLeftDClick(self, event): - (x,y) = event.Position(); - # Actually, we should convert x,y to logical coords using - # a dc, but only for a wxScrolledWindow widget. - # Now wxGTK derives wxListCtrl from wxScrolledWindow, - # and wxMSW from wxControl... So that doesn't work. - #dc = wxClientDC(self.list) - ##self.list.PrepareDC(dc) - #x = dc.DeviceToLogicalX( event.GetX() ) - #y = dc.DeviceToLogicalY( event.GetY() ) - id = self.list.HitTest(wxPoint(x,y)) - #print "Double click at %d %d" % (x,y), id - # Okay, we got a double click. Let's assume it's the current selection - wxYield() - self.OnViewArticle(event) + (x,y) = event.Position(); + # Actually, we should convert x,y to logical coords using + # a dc, but only for a wxScrolledWindow widget. + # Now wxGTK derives wxListCtrl from wxScrolledWindow, + # and wxMSW from wxControl... So that doesn't work. + #dc = wxClientDC(self.list) + ##self.list.PrepareDC(dc) + #x = dc.DeviceToLogicalX( event.GetX() ) + #y = dc.DeviceToLogicalY( event.GetY() ) + id = self.list.HitTest(wxPoint(x,y)) + #print "Double click at %d %d" % (x,y), id + # Okay, we got a double click. Let's assume it's the current selection + wxYield() + self.OnViewArticle(event) def OnCloseWindow(self, event): self.Destroy() diff --git a/wxPython/wxPython/.cvsignore b/wxPython/wxPython/.cvsignore index d342ce52e3..157b98a798 100644 --- a/wxPython/wxPython/.cvsignore +++ b/wxPython/wxPython/.cvsignore @@ -2,4 +2,5 @@ *.pyc *.pyd .DS_Store +locale wxc.pyd.manifest diff --git a/wxPython/wxPython/lib/CDate.py b/wxPython/wxPython/lib/CDate.py index c4f0d9b79c..d900e0d203 100644 --- a/wxPython/wxPython/lib/CDate.py +++ b/wxPython/wxPython/lib/CDate.py @@ -11,11 +11,11 @@ import time Month = {2: 'February', 3: 'March', None: 0, 'July': 7, 11: - 'November', 'December': 12, 'June': 6, 'January': 1, 'September': 9, - 'August': 8, 'March': 3, 'November': 11, 'April': 4, 12: 'December', - 'May': 5, 10: 'October', 9: 'September', 8: 'August', 7: 'July', 6: - 'June', 5: 'May', 4: 'April', 'October': 10, 'February': 2, 1: - 'January', 0: None} + 'November', 'December': 12, 'June': 6, 'January': 1, 'September': 9, + 'August': 8, 'March': 3, 'November': 11, 'April': 4, 12: 'December', + 'May': 5, 10: 'October', 9: 'September', 8: 'August', 7: 'July', 6: + 'June', 5: 'May', 4: 'April', 'October': 10, 'February': 2, 1: + 'January', 0: None} # Number of days per month (except for February in leap years) mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] diff --git a/wxPython/wxPython/lib/ErrorDialogs.py b/wxPython/wxPython/lib/ErrorDialogs.py index 102ef63283..4bcf9f6dca 100644 --- a/wxPython/wxPython/lib/ErrorDialogs.py +++ b/wxPython/wxPython/lib/ErrorDialogs.py @@ -191,7 +191,7 @@ class wxPyNonWindowingErrorHandler: self.file = file def write(self,s): import sys - if string.find(s,"Warning") <> 0\ + if s.find("Warning") <> 0\ and self.this_exception is not sys.last_traceback: wxPyNonWindowingError("The Python interpreter encountered an error " "not handled by any\nexception handler--this " @@ -276,10 +276,10 @@ class wxPythonRExec (rexec.RExec): class wxPyNonFatalErrorDialogWithTraceback(wxDialog): this_exception = 0 populate_function = populate_wxPyNonFatalErrorDialogWithTraceback - no_continue_button = false - fatal = false - modal = true - exitjustreturns = false # really only for testing! + no_continue_button = False + fatal = False + modal = True + exitjustreturns = False # really only for testing! def __init__(self, parent, id, pos=wxPyDefaultPosition, @@ -293,7 +293,7 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): caption="Python error!", versionname=None, errorname=None, - disable_exit_button=false): + disable_exit_button=False): if self.fatal: whetherNF = "" @@ -309,7 +309,7 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): wxDialog.__init__(self, parent, id, title, pos, size, style) - self.topsizer = self.populate_function( false,true ) + self.topsizer = self.populate_function( False,True ) self.SetProgramName(programname) self.SetVersion(version) @@ -332,10 +332,10 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): if not disable_mail_button: EVT_BUTTON(self, wxPyError_ID_MAIL, self.OnMail) else: - self.GetMailButton().Enable(false) + self.GetMailButton().Enable(False) # disable the entry box for an e-mail address by default (NOT PROPERLY DOCUMENTED) if not hasattr(self,"enable_mail_address_box"): - self.FindWindowById(wxPyError_ID_ADDRESS).Enable(false) + self.FindWindowById(wxPyError_ID_ADDRESS).Enable(False) if not disable_exit_button: EVT_BUTTON(self, wxPyError_ID_EXIT, self.OnExit) @@ -380,7 +380,7 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): value = value[:-1] if _debug: print "%s.SetTraceback(): ...SetValue('%s' (^M=\\r; ^J=\\n))"\ - % (self,string.replace(value,'\n',"^J")) + % (self,value.replace('\n',"^J")) c.SetValue(value) # Despite using the wxADJUST_MINSIZE flag in the @@ -399,7 +399,7 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): print "%s.SetTraceback(): %s.GetBestSize() = (%s,%s)"\ % (self,c,size.width,size.height) w,h = 0,0 - for v in string.split(value,"\n"): + for v in value.split("\n"): pw,ph,d,e = t = c.GetFullTextExtent(v) if _debug: print v, t @@ -415,7 +415,7 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): self.sizerAroundText.SetItemMinSize (c,w,h) c.SetSize ((w,h)) c.SetSizeHints (w,h,w,h) - c.Refresh()#.SetAutoLayout(FALSE) + c.Refresh()#.SetAutoLayout(False) #^ the reason we need the above seems to be to replace the #faulty GetBestSize of wxTextCtrl... @@ -503,7 +503,7 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): if self.modal: self.ShowModal() else: - self.Show(true) + self.Show(True) except: if not locals().has_key("c"): @@ -654,8 +654,8 @@ class wxPyNonFatalErrorDialogWithTraceback(wxDialog): class wxPyFatalErrorDialogWithTraceback(wxPyNonFatalErrorDialogWithTraceback): populate_function = populate_wxPyFatalErrorDialogWithTraceback - no_continue_button = true - fatal = true + no_continue_button = True + fatal = True class wxPyNonFatalErrorDialog(wxPyNonFatalErrorDialogWithTraceback): populate_function = populate_wxPyNonFatalErrorDialog @@ -669,7 +669,7 @@ def _startmailerwithhtml(mailto,subject,html,text=None,mailfrom=None): s = 'mailto:%s?subject=%s&body=%s' % (mailto, urllib.quote(subject), urllib.quote( - string.replace(text,'\n','\r\n'), + text.replace('\n','\r\n'), "")) # Note that RFC 2368 requires that line breaks in the body of @@ -719,7 +719,7 @@ def _writehtmlmessage(mailto,subject,html,text=None,parent=None,mailfrom=None): def _createhtmlmail (html, text, subject, to=None, mailfrom=None): """Create a mime-message that will render HTML in popular - MUAs, text in better ones (if indeed text is not untrue (e.g. None) + MUAs, text in better ones (if indeed text is not unTrue (e.g. None) """ import MimeWriter, mimetools, cStringIO @@ -797,7 +797,7 @@ def wxPyResizeHTMLWindowToDispelScrollbar(window, # Will go no further than specified fraction of display size. w = 200 if type(fraction) == type(''): - fraction = string.atoi(fraction[:-1]) / 100. + fraction = int(fraction[:-1]) / 100. ds = wxDisplaySize () c = window.GetInternalRepresentation () while w < ds[0] * fraction: @@ -812,7 +812,7 @@ def wxPyResizeHTMLWindowToDispelScrollbar(window, w = w + 20 else: if type(defaultfraction) == type(''): - defaultfraction = string.atoi(defaultfraction[:-1]) / 100. + defaultfraction = int(defaultfraction[:-1]) / 100. defaultsize = (defaultfraction * ds[0], defaultfraction * ds[1]) if _debug: print 'defaultsize =',defaultsize @@ -849,7 +849,7 @@ def wxPyFatalOrNonFatalError(parent, else: populate_function = populate_wxPyNonFatalError - sizer = populate_function(dlg,false,true) + sizer = populate_function(dlg,False,True) window = dlg.FindWindowById(wxPyError_ID_HTML) window.SetPage(msg) @@ -875,5 +875,5 @@ def wxPyFatalOrNonFatalError(parent, dlg.Destroy() return v else: - dlg.Show(true) + dlg.Show(True) diff --git a/wxPython/wxPython/lib/PyCrust/CHANGES.txt b/wxPython/wxPython/lib/PyCrust/CHANGES.txt new file mode 100644 index 0000000000..1e2bdafe8e --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/CHANGES.txt @@ -0,0 +1,512 @@ +============= + CHANGES.txt +============= + +----------------------------------------- + Changes made to each release of PyCrust +----------------------------------------- + + +0.9 (2/27/2003 to 3/20/2003) +============================ + +Added fontIncrease, fontDecrease, fontDefault signals, receivers and +keybindings: + + Ctrl+] Increase font size. + Ctrl+[ Decrease font size. + Ctrl+= Default font size. + +Continued enhancement of the decorator capability to provide better +documentation and docstrings for wxPython classes and functions. + +Introduced new tabbed interface: + +* Namespace +* Calltip +* Session +* Dispatcher +* wxPython Docs +* wxSTC Docs + +Filling.tree now expands tuples as well as lists. (It should have done +this all along, I just never noticed this omission before.) + +Added this True/False test to all modules: + + try: + True + except NameError: + True = 1==1 + False = 1==0 + +Added wxd directory with decoration classes. + + +0.8.2 (1/5/2003 to 2/26/2003) +============================= + +Wrapped sys.ps1, sys.ps2, and sys.ps3 in str(). (Thanks, Kieran +Holland.) + +Fixed minor things found by PyChecker. + +Changed locals to use __main__.__dict__ and added code to clean up the +namespace, making it as close to the regular Python environment as +possible. This solves the problem of pickling and unpickling instances +of classes defined in the shell. + +Made shell.PasteAndRun() a little more forgiving when it finds a ps2 +prompt line with no trailing space, such when you copy code from a web +page. + +Improved autocomplete behavior by adding these to shell: + self.AutoCompSetAutoHide(False) + self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`') + +Added decor directory, decorator.py, stcDecor.py, and +stcConstants.py. These all serve the purpose of adding docstrings to +existing wxPython classes, in particular the wxStyledTextControl. + +Added wrap.py, a command line utility for running a wxPython app with +additional runtime-tools loaded, such as PyCrust (the only tool at +this point). + +Flushed the clipboard Cut/Copy operations so that selections will +exist in the clipboard even after PyCrust has been closed. + +Improved the suppression of docstrings for simple data types appearing +in the namespace viewer. + +Better handling of autocompletion with numeric types; no +autocompletion when typing a dot after an integer. If the +autocompletion is desired, type a space before the dot: + + func = 3 . + +More Filling!!! The namespace tree is now dynamically updated. + + +0.8.1 (12/20/2002 to 12/25/2002) +================================ + +Improved keyboard handling with Autocomplete active. You can now use +Enter as well as Tab to select an item from the list. + +Disabled autocomplete for lists of 2000 items or more. The current +implementation of wxSTC can't handle lists this big. + +Changed filling to always display docstrings for objects. This is +useful for objects whose docstrings have been decorated, rather than +coming directly from the source code. (Hmmm. Sounds like someone is +doing some decorating. I wonder where that would be helpful? ;-) + +Fixed handling of icon. Added images.py file. + + +0.8 (10/29/2002 to 12/16/2002) +============================== + +Added "help" to startup banner info. + +Made all wx and stc imports explicit. No more import *. + +Replaced use of wx's true and false with Python's True and False. + +Changed introspect.getRoot() to use tokenize module. This does a +slightly better job than the previous parsing routine and the code is +clearer. + +Improved handling of whitespace and empty types during introspection. + +Fixed cut/copy clipboard problem under Linux. (Robin Dunn rocks!!!) + +Added shell.about() which works like this: + + >>> shell.about() + PyCrust Version: 0.8 + Shell Revision: 1.80 + Interpreter Revision: 1.15 + Python Version: 2.2.2 + wxPython Version: 2.3.3.1 + Platform: linux2 + +Added copy plus and paste plus to shell menu. + +Moved shell menu from shell.py to shellmenu.py. + +Added sys.stdin.readlines() support. + +Added time.sleep() in readline() and OnIdle() event handler to free up +the CPU. + + +0.7.2 (2/22/2002 to 8/27/2002) +============================== + +Tweaked getAttributeNames() to pick up a few more attributes: + + '__bases__', '__class__', '__dict__', '__name__', 'func_closure', + 'func_code', 'func_defaults', 'func_dict', 'func_doc', + 'func_globals', 'func_name' + +Added a tests directory and unit tests. + +Improved support for empty types in the shell: [], () and {} as far as +when call tips and autocompletion are available. + +Added support for the other triple string - ''''''. + +Refactored introspect.py to improve testability. + +Improved call tips for unbound methods by leaving the "self" +parameter, since unbound methods require an instance be passed. + +Fixed call tip bug where a tip was displayed when a "(" was typed +after an object that wasn't callable. + +Fixed getAllAttributeNames when str(object) fails. + +Added brace highlighting. (Thank you, Kevin Altis.) + +Fixed problem displaying unicode objects in PyFilling. + +Changed how filling.py checks for expandable objects. Lists are now +expandable objects. + +Made the key handling more robust when there is an active text +selection that includes text prior to the last primary prompt. Thanks +to Raul Cota for pointing this out. + +Fixed wxSTC problem with brace highlighting and non-us keyboards. +(Thank you for the patch, Jean-Michel Fauth.) + +Added busy = wxBusyCursor() to key point in shell and filling. + +Added OnCloseWindow handler to ShellFrame and CrustFrame. + +Default to SetWrapMode(1) for shell and namespace viewer. + +Added shell.wrap() and shell.zoom(). + +Added Raul Cota autoCompleteKeys hooks. + +Cleaned up various little key handling bugs. + +Changed input methods to get values from shell, rather than dialog +boxes. Renamed readIn to readline and readRaw to raw_input. + + +0.7.1 (12/12/2001 to 2/21/2002) +=============================== + +Fixed OnChar() issues effecting European keyboards, as reported by +Jean-Michel Fauth. + +Fixed introspect.py issue with xmlrpc objects reported by Kevin Altis. + +Fixed some introspect/PyFilling issues with regard to Python 2.2. + +Fixed font background color as reported by Keith J. Farmer. (Thanks) + +Fixed problem with call tips and autocompletion inside multiline +commands as report by Kevin Altis. + +Improved OnKeyDown handling of cut/copy/paste operations based on +feedback from Syver Enstad. (Thanks) + +Added a shell.help() method to display some help info. + +Changed sort of items in the namespace viewer to case insensitive. + +Changed attributes.sort(lambda x, y: cmp(x.upper(), y.upper())) in +advance of an upcoming fix to an autocompletion matching bug in wxSTC. + +Improved support for ZODB by allowing namespace drilldown into BTrees. + +Added shell.PasteAndRun() to support pasting multiple commands into +the shell from the clipboard. Ctrl+Shift+V or v. + +Enter now always processes a command (or copies down a previous one.) +To insert a line break, press Ctrl+Enter. + +Escape key clears the current, unexecuted command. + +History retrieval changed to replace current command. Added new keys +to insert from history - Shift+Up and Shift+Down. + +Better call tips on objects with __call__ methods. + +Improved call tip positioning calculation. + + +0.7 (10/15/2001 to 12/11/2001) +============================== + +Changed how command history retrieval functions work. Added Alt-P, +Alt-N as keybindings for Retrieve-Previous, Retrieve-Next. + +Added full support for mult-line commands, similar to IDLE. + +Changed introspect.getAttributeNames() to do a case insensitive sort. + +Changed Cut/Copy/Paste to deal with prompts intelligently. Cut and +Copy remove all prompts. Paste can handle prompted or not-prompted +text. + +Added CopyWithPrompts() method attached to Ctrl-Shift-C for those +times when you really do want all the prompts left intact. + +Improved handling of the shell's read-only zone. + +Changed CrustFrame.__init__ parameter spec to include all parameters +allowed by a wxFrame. + +Changed FillingText to be read-only. + +Renamed PyCrust.py to PyCrustApp.py to eliminate package/module name +conflicts that kept you from doing "from PyCrust import shell" inside +files located in the PyCrust directory. + +Renamed PyFilling.py to PyFillingApp.py and PyShell.py to +PyShellApp.py to maintain consistency. + +Removed the __date__ property from all modules. + +Fixed bug in introspect.getCallTip(), reported by Kevin Altis. + + +0.6.1 (9/19/2001 to 10/12/2001) +=============================== + +Changed Shell.run() to always position to the end of existing text, as +suggested by Raul Cota. + +Changed introspect.getAllAttributeNames() to break circular references +in object.__class__, which occurs in Zope/ZODB extension classes. + +Changed filling.FillingTree.getChildren() to introspect extension +classes. + +Fixed minor bugs in introspect.getCallTip() that were interfering with +call tips for Zope/ZODB extension class methods. + +In preparation for wxPython 2.3.2, added code to fix a font sizing +problem. Versions of wxPython prior to 2.3.2 had a sizing bug on Win +platform where the font was 2 points larger than what was specified. + +Added a hack to introspect.getAllAttributeNames() to "wake up" ZODB +objects that are asleep - in a "ghost" state. Otherwise it returns +incomplete info. + + +0.6 (8/21/2001 to 9/12/2001) +============================ + +Added PyFilling.py and filling.py. + +PyShell.py and PyFilling.py can now be run standalone, as well as +PyCrust.py. + +Added crust.py and moved some code from PyCrust.py to it. + +Added command history retrieval features submitted by Richie Hindle. + +Changed shell.write() to replace line endings with OS-specific +endings. Changed shell.py and interpreter.py to use os.linesep in +strings having hardcoded line endings. + +Added shell.redirectStdin(), shell.redirectStdout() and +shell.redirectStderr() to allow the surrounding app to toggle requests +that the specified sys.std* be redirected to the shell. These can also +be run from within the shell itself, of course. + +The shell now adds the current working directory "." to the search +path: + + sys.path.insert(0, os.curdir) + +Added support for distutils installations. + + +0.5.4 (8/17/2001 to 8/20/2001) +============================== + +Changed default font size under *nix to: + + 'size' : 12, + 'lnsize' : 10, + +Changed Shell to expect a parameter referencing an Interpreter class, +rather than an intepreter instance, to facilitate subclassing of +Interpreter, which effectively broke when the Editor class was +eliminated. + +Fixed PyCrustAlaCarte.py, which had been broken by previous changes. + +Created InterpreterAlaCarte class as an example for use in the demo. + +Split PyCrust.py into PyCrust.py and PyShell.py in anticipation of +PyFilling. + + +0.5.3 (8/16/2001) +================= + +Added patch to PyCrust.py to fix wxPython bug: + + wxID_SELECTALL = NewId() # This *should* be defined by wxPython. + + +0.5.2 (8/14/2001 to 8/15/2001) +============================== + +Shortened module names by dropping "PyCrust" as a prefix. + +Changed version to VERSION in version module. + +Added Options menu to PyCrust application. + +Eliminated the Editor class (and editor module) by merging with Shell. +This means that Shell "is a" wxStyledTextCtrl rather than "has a". +There just wasn't enough non-gui code to justify the separation. Plus, +Shell will be much easier for gui toolkits/designers to deal with now. + + +0.5.1 (8/10/2001 to 8/14/2001) +============================== + +Added introspect module. + +Moved some functionality from PyCrustInterp to introspect. + +Changed introspect.getRoot() to no longer remove whitespace from the +command. This was a remnant of a previous approach that, when left as +part of the current approach, turned out to be a really bad thing. + +Changed introspect.getRoot() to allow commands of '', "", """""", [], +(), and {} to pass through. This allows you to type them, followed by +a dot, and get autocomplete options on them. + +Changed introspect.getRoot() to identify some situations where strings +shouldn't be considered roots. For example: + + >>> import PyCrust # To illustrate the potential problem. + >>> len('PyCrust.py') + +Typing the dot at the end of "PyCrust" in the second line above should +NOT result in an autocompletion list because "PyCrust" is part of a +string in this context, not a reference to the PyCrust module +object. Similar reasoning applies to call tips. For example: + + >>> len('dir(') + +Typing the left paren at the end of "dir" should NOT result in a call +tip. + +Both features now behave properly in the examples given. However, +there is still the case where whitespace precedes the potential root +and that is NOT handled properly. For example: + + >>> len('this is a dir(') + +and + + >>> len('This is PyCrust.py') + +More code needs to be written to handle more complex situations. + +Added locals=None parameter to Shell.__init__(). + +Added support for magic attribute retrieval. Users can change this +with: + + >>> shell.editor.autoCompleteIncludeMagic = 0 + +Added the ability to set filters on auto completion to exclude +attributes prefixed with a single or double underscore. Users can +exclude one or the other or both with: + + >>> shell.editor.autoCompleteExcludeSingle = 1 + >>> shell.editor.autoCompleteExcludeDouble = 1 + + +0.5 (8/8/2001) +============== + +Mostly just a final version change before creating a release. + + +0.4 (8/4/2001 to 8/7/2001) +========================== + +Changed version/revision handling. + +Fixed bugs. + + +0.3 (8/2/2001 to 8/3/2001) +========================== + +Removed lots of cruft. + +Added lots of docstrings. + +Imported to CVS repository at SourceForge. + +Added call tips. + + +0.2 (7/30/2001 to 8/2/2001) +=========================== + +Renamed several files. + +Added command autocompletion. + +Added menus to PyCrust.py: File, Edit and Help + +Added sample applications: PyCrustAlaCarte.py, PyCrustAlaMode.py, and +PyCrustMinimus.py. + + +0.1 (7/1/2001 to 7/19/2001) +=========================== + +Added basic syntax coloring much like Boa. + +Added read-only logging much like IDLE. + +Can retrieve a previous command by putting the cursor back on that +line and hitting enter. + +Stdin and raw_input operate properly so you can now do help() and +license() without hanging. + +Redefined "quit", "exit", and "close" to display a better-than-nothing +response. + +Home key honors the prompt. + +Created SourceForge account, but nothing was posted. + + +In the beginning, there was pie... (7/1/2001) +============================================= + +Blame it all on IDLE, Boa and PythonWin. I was using all three, got +frustrated with their dissimilarities, and began to let everyone know +how I felt. At the same time, Scintilla looked like an interesting +tool to build a shell around. And while I didn't receive much in the +way of positive feedback, let alone encouragement, I just couldn't let +go of the idea of a Scintilla-based Python shell. Then the PythonCard +project got to the point where they were talking about including a +shell in their development environment. That was all the incentive I +needed. PyCrust had to happen... + + +CVS Information +=============== +$Date$ +$Revision$ +$Id$ diff --git a/wxPython/wxPython/lib/PyCrust/PyCrustApp.py b/wxPython/wxPython/lib/PyCrust/PyCrustApp.py index d262fbea91..036e368002 100755 --- a/wxPython/wxPython/lib/PyCrust/PyCrustApp.py +++ b/wxPython/wxPython/lib/PyCrust/PyCrustApp.py @@ -1,39 +1,70 @@ -#!/usr/bin/env python + """PyCrustApp is a python shell and namespace browser application.""" +# The next two lines, and the other code below that makes use of +# ``__main__`` and ``original``, serve the purpose of cleaning up the +# main namespace to look as much as possible like the regular Python +# shell environment. +import __main__ +original = __main__.__dict__.keys() + __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -from wxPython.wx import * -from crust import CrustFrame +from wxPython import wx +try: + True +except NameError: + True = 1==1 + False = 1==0 -class App(wxApp): + +class App(wx.wxApp): """PyCrust standalone application.""" def OnInit(self): - wxInitAllImageHandlers() - locals = {'__app__': 'PyCrust Standalone Application'} - self.crustFrame = CrustFrame(locals=locals) - self.crustFrame.SetSize((750, 525)) - self.crustFrame.Show(true) - self.crustFrame.crust.shell.SetFocus() - self.SetTopWindow(self.crustFrame) + from wxPython import wx + wx.wxInitAllImageHandlers() + locals = __main__.__dict__ + from crust import CrustFrame + self.frame = CrustFrame(locals=locals) + self.frame.SetSize((800, 600)) + self.frame.Show() + self.SetTopWindow(self.frame) # Add the application object to the sys module's namespace. # This allows a shell user to do: # >>> import sys - # >>> sys.application.whatever + # >>> sys.app.whatever import sys - sys.application = self - return true + sys.app = self + return 1 +''' +The main() function needs to handle being imported, such as with the +pycrust script that wxPython installs: -def main(): - application = App(1) - application.MainLoop() + #!/usr/bin/env python -if __name__ == '__main__': + from wxPython.lib.PyCrust.PyCrustApp import main main() +''' +def main(): + import __main__ + md = __main__.__dict__ + keepers = original + keepers.append('App') + for key in md.keys(): + if key not in keepers: + del md[key] + app = App(0) + if md.has_key('App') and md['App'] is App: + del md['App'] + if md.has_key('__main__') and md['__main__'] is __main__: + del md['__main__'] + app.MainLoop() +if __name__ == '__main__': + main() diff --git a/wxPython/wxPython/lib/PyCrust/PyFillingApp.py b/wxPython/wxPython/lib/PyCrust/PyFillingApp.py index 6869f1aa73..b204210a80 100755 --- a/wxPython/wxPython/lib/PyCrust/PyFillingApp.py +++ b/wxPython/wxPython/lib/PyCrust/PyFillingApp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python + """PyFillingApp is a python namespace inspection application.""" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" @@ -6,30 +6,40 @@ __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] # We use this object to get more introspection when run standalone. -application = None +app = None import filling # These are imported just to have something interesting to inspect. -from PyCrust import crust -from PyCrust import interpreter -from PyCrust import introspect -from PyCrust import pseudo -from PyCrust import shell +import crust +import interpreter +import introspect +import pseudo +import shell + import sys from wxPython import wx +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class App(filling.App): + def OnInit(self): + filling.App.OnInit(self) + self.root = self.fillingFrame.filling.tree.root + return True def main(): """Create and run the application.""" - global application - application = filling.App(0) - root = application.fillingFrame.filling.fillingTree.root - application.fillingFrame.filling.fillingTree.Expand(root) - application.MainLoop() + global app + app = App(0) + app.fillingFrame.filling.tree.Expand(app.root) + app.MainLoop() if __name__ == '__main__': main() - - diff --git a/wxPython/wxPython/lib/PyCrust/PyShellApp.py b/wxPython/wxPython/lib/PyCrust/PyShellApp.py index ff60f5f845..2ef7aae07f 100755 --- a/wxPython/wxPython/lib/PyCrust/PyShellApp.py +++ b/wxPython/wxPython/lib/PyCrust/PyShellApp.py @@ -1,40 +1,71 @@ -#!/usr/bin/env python + """PyShellApp is a python shell application.""" +# The next two lines, and the other code below that makes use of +# ``__main__`` and ``original``, serve the purpose of cleaning up the +# main namespace to look as much as possible like the regular Python +# shell environment. +import __main__ +original = __main__.__dict__.keys() + __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -from wxPython.wx import * -from shell import ShellFrame +from wxPython import wx + +try: + True +except NameError: + True = 1==1 + False = 1==0 -class App(wxApp): +class App(wx.wxApp): """PyShell standalone application.""" def OnInit(self): - wxInitAllImageHandlers() - locals = {'__app__': 'PyShell Standalone Application'} - self.shellFrame = ShellFrame(locals=locals) - self.shellFrame.SetSize((750, 525)) - self.shellFrame.Show(true) - self.shellFrame.shell.SetFocus() - self.SetTopWindow(self.shellFrame) + from wxPython import wx + wx.wxInitAllImageHandlers() + locals = __main__.__dict__ + from shell import ShellFrame + self.frame = ShellFrame(locals=locals) + self.frame.SetSize((750, 525)) + self.frame.Show() + self.SetTopWindow(self.frame) + self.frame.shell.SetFocus() # Add the application object to the sys module's namespace. # This allows a shell user to do: # >>> import sys - # >>> sys.application.whatever + # >>> sys.app.whatever import sys - sys.application = self - return true + sys.app = self + return 1 +''' +The main() function needs to handle being imported, such as with the +pycrust script that wxPython installs: -def main(): - application = App(1) - application.MainLoop() + #!/usr/bin/env python -if __name__ == '__main__': + from wxPython.lib.PyCrust.PyCrustApp import main main() +''' +def main(): + import __main__ + md = __main__.__dict__ + keepers = original + keepers.append('App') + for key in md.keys(): + if key not in keepers: + del md[key] + app = App(0) + if md.has_key('App') and md['App'] is App: + del md['App'] + if md.has_key('__main__') and md['__main__'] is __main__: + del md['__main__'] + app.MainLoop() - +if __name__ == '__main__': + main() diff --git a/wxPython/wxPython/lib/PyCrust/README.txt b/wxPython/wxPython/lib/PyCrust/README.txt index c8c66c0e15..b6a0126705 100644 --- a/wxPython/wxPython/lib/PyCrust/README.txt +++ b/wxPython/wxPython/lib/PyCrust/README.txt @@ -1,68 +1,79 @@ -PyCrust - The Flakiest Python Shell +===================================== + PyCrust - The Flakiest Python Shell +===================================== + Half-baked by Patrick K. O'Brien (pobrien@orbtech.com) -============================================================== -* Orbtech - "Your source for Python programming expertise." * -* Sample all our half-baked Python goods at www.orbtech.com. * -============================================================== +Orbtech - "Your source for Python programming expertise." +Sample all our half-baked Python goods at www.orbtech.com. + What is PyCrust? ---------------- + PyCrust is an interactive Python environment written in Python. PyCrust components can run standalone or be integrated into other development environments and/or other Python applications. -PyCrust comes with an interactive Python shell (PyShell), an -interactive namespace/object tree control (PyFilling) and an +PyCrust comes with an interactive Python shell (PyShell), an +interactive namespace/object tree control (PyFilling) and an integrated, split-window combination of the two (PyCrust). What is PyCrust good for? ------------------------- -Have you ever tried to bake a pie without one? Well, you -shouldn't build a Python program without a PyCrust either. + +Have you ever tried to bake a pie without one? Well, you shouldn't +build a Python program without a PyCrust either. What else do I need to use PyCrust? ----------------------------------- -PyCrust requires Python 2.1 or later, and wxPython 2.3.1 or later. + +PyCrust requires Python 2.1.3 or later, and wxPython 2.4 or later. PyCrust uses wxPython and the Scintilla wrapper (wxStyledTextCtrl). -Python is available at http://www.python.org/. -wxPython is available at http://www.wxpython.org/. +Python is available at http://www.python.org/. wxPython is available +at http://www.wxpython.org/. Where can I get the latest version of PyCrust? ---------------------------------------------- -The latest production version ships with wxPython. -The latest developer version is available in CVS at: + +The latest production version ships with wxPython. The latest +developer version is available in CVS at: http://sourceforge.net/cvs/?group_id=31263 Where is the PyCrust project hosted? ------------------------------------ + At SourceForge, of course. The SourceForge summary page: http://sourceforge.net/projects/pycrust/ I found a bug in PyCrust, what do I do with it? ----------------------------------------------- + You can send it to me at pobrien@orbtech.com. I want a new feature added to PyCrust. Will you do it? ------------------------------------------------------ -Flattery and money will get you anything. Short of that, you -can send me a request and I'll see what I can do. + +Flattery and money will get you anything. Short of that, you can send +me a request and I'll see what I can do. Does PyCrust have a mailing list full of wonderful people? ---------------------------------------------------------- + As a matter of fact, we do. Join the PyCrust mailing lists at: http://sourceforge.net/mail/?group_id=31263 What is the CVS information for this README file? ------------------------------------------------- + $Date$ $Revision$ $Id$ diff --git a/wxPython/wxPython/lib/PyCrust/crust.py b/wxPython/wxPython/lib/PyCrust/crust.py index 435b1ed64a..caeb20f6db 100644 --- a/wxPython/wxPython/lib/PyCrust/crust.py +++ b/wxPython/wxPython/lib/PyCrust/crust.py @@ -4,78 +4,163 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -from wxPython.wx import * -from shell import Shell +from wxPython import wx from filling import Filling -from version import VERSION import os +from shell import Shell +from shellmenu import ShellMenu +from version import VERSION + +try: + True +except NameError: + True = 1==1 + False = 1==0 -class Crust(wxSplitterWindow): +class Crust(wx.wxSplitterWindow): """PyCrust Crust based on wxSplitterWindow.""" name = 'PyCrust Crust' revision = __revision__ - def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ - size=wxDefaultSize, style=wxSP_3D, name='Crust Window', \ - rootObject=None, rootLabel=None, rootIsNamespace=1, \ - intro='', locals=None, \ + def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition, + size=wx.wxDefaultSize, style=wx.wxSP_3D, + name='Crust Window', rootObject=None, rootLabel=None, + rootIsNamespace=True, intro='', locals=None, InterpClass=None, *args, **kwds): """Create a PyCrust Crust instance.""" - wxSplitterWindow.__init__(self, parent, id, pos, size, style, name) - self.shell = Shell(parent=self, introText=intro, \ - locals=locals, InterpClass=InterpClass, \ + wx.wxSplitterWindow.__init__(self, parent, id, pos, size, style, name) + self.shell = Shell(parent=self, introText=intro, + locals=locals, InterpClass=InterpClass, *args, **kwds) - self.filling = Filling(parent=self, \ - rootObject=self.shell.interp.locals, \ - rootLabel=rootLabel, rootIsNamespace=1) - """Add 'filling' to the interpreter's locals.""" + if rootObject is None: + rootObject = self.shell.interp.locals + self.notebook = wx.wxNotebook(parent=self, id=-1) + self.shell.interp.locals['notebook'] = self.notebook + self.filling = Filling(parent=self.notebook, + rootObject=rootObject, + rootLabel=rootLabel, + rootIsNamespace=rootIsNamespace) + # Add 'filling' to the interpreter's locals. self.shell.interp.locals['filling'] = self.filling - self.SplitHorizontally(self.shell, self.filling, 300) + self.notebook.AddPage(page=self.filling, text='Namespace', select=True) + self.calltip = Calltip(parent=self.notebook) + self.notebook.AddPage(page=self.calltip, text='Calltip') + self.sessionlisting = SessionListing(parent=self.notebook) + self.notebook.AddPage(page=self.sessionlisting, text='Session') + self.dispatcherlisting = DispatcherListing(parent=self.notebook) + self.notebook.AddPage(page=self.dispatcherlisting, text='Dispatcher') + from wxd import wx_ + self.wxdocs = Filling(parent=self.notebook, + rootObject=wx_, + rootLabel='wx', + rootIsNamespace=False, + static=True) + self.notebook.AddPage(page=self.wxdocs, text='wxPython Docs') + from wxd import stc_ + self.stcdocs = Filling(parent=self.notebook, + rootObject=stc_.StyledTextCtrl, + rootLabel='StyledTextCtrl', + rootIsNamespace=False, + static=True) + self.notebook.AddPage(page=self.stcdocs, text='StyledTextCtrl Docs') + self.SplitHorizontally(self.shell, self.notebook, 300) self.SetMinimumPaneSize(1) -# Temporary hack to share menus between PyCrust and PyShell. -from shell import ShellMenu +class Calltip(wx.wxTextCtrl): + """Text control containing the most recent shell calltip.""" + + def __init__(self, parent=None, id=-1): + import dispatcher + style = wx.wxTE_MULTILINE | wx.wxTE_READONLY | wx.wxTE_RICH2 + wx.wxTextCtrl.__init__(self, parent=parent, id=id, style=style) + self.SetBackgroundColour(wx.wxColour(255, 255, 232)) + dispatcher.connect(receiver=self.display, signal='Shell.calltip') + + def display(self, calltip): + """Receiver for Shell.calltip signal.""" + self.SetValue(calltip) + + +class SessionListing(wx.wxTextCtrl): + """Text control containing all commands for session.""" + + def __init__(self, parent=None, id=-1): + import dispatcher + style = wx.wxTE_MULTILINE | wx.wxTE_READONLY | \ + wx.wxTE_RICH2 | wx.wxTE_DONTWRAP + wx.wxTextCtrl.__init__(self, parent=parent, id=id, style=style) + dispatcher.connect(receiver=self.push, signal='Interpreter.push') -class CrustFrame(wxFrame, ShellMenu): + def push(self, command, more): + """Receiver for Interpreter.push signal.""" + if command and not more: + self.SetInsertionPointEnd() + start, end = self.GetSelection() + if start != end: + self.SetSelection(0, 0) + self.AppendText(command + '\n') + + +class DispatcherListing(wx.wxTextCtrl): + """Text control containing all dispatches for session.""" + + def __init__(self, parent=None, id=-1): + import dispatcher + style = wx.wxTE_MULTILINE | wx.wxTE_READONLY | \ + wx.wxTE_RICH2 | wx.wxTE_DONTWRAP + wx.wxTextCtrl.__init__(self, parent=parent, id=id, style=style) + dispatcher.connect(receiver=self.spy) + + def spy(self, signal, sender): + """Receiver for Any signal from Any sender.""" + text = '%r from %s' % (signal, sender) + self.SetInsertionPointEnd() + start, end = self.GetSelection() + if start != end: + self.SetSelection(0, 0) + self.AppendText(text + '\n') + + +class CrustFrame(wx.wxFrame, ShellMenu): """Frame containing all the PyCrust components.""" name = 'PyCrust Frame' revision = __revision__ - def __init__(self, parent=None, id=-1, title='PyCrust', \ - pos=wxDefaultPosition, size=wxDefaultSize, \ - style=wxDEFAULT_FRAME_STYLE, \ - rootObject=None, rootLabel=None, rootIsNamespace=1, \ + def __init__(self, parent=None, id=-1, title='PyCrust', + pos=wx.wxDefaultPosition, size=wx.wxDefaultSize, + style=wx.wxDEFAULT_FRAME_STYLE, + rootObject=None, rootLabel=None, rootIsNamespace=True, locals=None, InterpClass=None, *args, **kwds): """Create a PyCrust CrustFrame instance.""" - wxFrame.__init__(self, parent, id, title, pos, size, style) - intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION - intro += '\nSponsored by Orbtech - Your source for Python programming expertise.' + wx.wxFrame.__init__(self, parent, id, title, pos, size, style) + intro = 'PyCrust %s - The Flakiest Python Shell' % VERSION + intro += '\nSponsored by Orbtech - ' + intro += 'Your source for Python programming expertise.' self.CreateStatusBar() self.SetStatusText(intro.replace('\n', ', ')) import images self.SetIcon(images.getPyCrustIcon()) - self.crust = Crust(parent=self, intro=intro, \ - rootObject=rootObject, \ - rootLabel=rootLabel, \ - rootIsNamespace=rootIsNamespace, \ - locals=locals, \ + self.crust = Crust(parent=self, intro=intro, + rootObject=rootObject, + rootLabel=rootLabel, + rootIsNamespace=rootIsNamespace, + locals=locals, InterpClass=InterpClass, *args, **kwds) # Override the filling so that status messages go to the status bar. - self.crust.filling.fillingTree.setStatusText = self.SetStatusText + self.crust.filling.tree.setStatusText = self.SetStatusText # Override the shell so that status messages go to the status bar. self.crust.shell.setStatusText = self.SetStatusText # Fix a problem with the sash shrinking to nothing. self.crust.filling.SetSashPosition(200) - # Set focus to the shell editor. - self.crust.shell.SetFocus() - # Temporary hack to share menus between PyCrust and PyShell. self.shell = self.crust.shell self.createMenus() - EVT_CLOSE(self, self.OnCloseWindow) + wx.EVT_CLOSE(self, self.OnCloseWindow) + # Set focus to the shell editor. + self.crust.shell.SetFocus() def OnCloseWindow(self, event): self.crust.shell.destroy() diff --git a/wxPython/wxPython/lib/PyCrust/dispatcher.py b/wxPython/wxPython/lib/PyCrust/dispatcher.py new file mode 100644 index 0000000000..9509d1eddd --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/dispatcher.py @@ -0,0 +1,266 @@ +"""Provides global signal dispatching services.""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + +import exceptions +import types +import weakref + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class DispatcherError(exceptions.Exception): + def __init__(self, args=None): + self.args = args + + +class Parameter: + """Used to represent default parameter values.""" + def __repr__(self): + return self.__class__.__name__ + +class Any(Parameter): pass +Any = Any() + +class Anonymous(Parameter): pass +Anonymous = Anonymous() + + +connections = {} +senders = {} +_boundMethods = weakref.WeakKeyDictionary() + + +def connect(receiver, signal=Any, sender=Any, weak=True): + """Connect receiver to sender for signal. + + If sender is Any, receiver will receive signal from any sender. + If signal is Any, receiver will receive any signal from sender. + If sender is None, receiver will receive signal from Anonymous. + If signal is Any and sender is None, receiver will receive any + signal from Anonymous. + If signal is Any and sender is Any, receiver will receive any + signal from any sender. + If weak is true, weak references will be used.""" + if signal is None: + raise DispatcherError, 'signal cannot be None' + if weak: + receiver = safeRef(receiver) + senderkey = id(sender) + signals = {} + if connections.has_key(senderkey): + signals = connections[senderkey] + else: + connections[senderkey] = signals + # Keep track of senders for cleanup. + if sender not in (None, Any): + def remove(object, senderkey=senderkey): + _removeSender(senderkey=senderkey) + # Skip objects that can not be weakly referenced, which means + # they won't be automatically cleaned up, but that's too bad. + try: + weakSender = weakref.ref(sender, remove) + senders[senderkey] = weakSender + except: + pass + receivers = [] + if signals.has_key(signal): + receivers = signals[signal] + else: + signals[signal] = receivers + try: + receivers.remove(receiver) + except ValueError: + pass + receivers.append(receiver) + +def disconnect(receiver, signal=Any, sender=Any, weak=True): + """Disconnect receiver from sender for signal. + + Disconnecting is not required. The use of disconnect is the same as for + connect, only in reverse. Think of it as undoing a previous connection.""" + if signal is None: + raise DispatcherError, 'signal cannot be None' + if weak: + receiver = safeRef(receiver) + senderkey = id(sender) + try: + receivers = connections[senderkey][signal] + except KeyError: + raise DispatcherError, \ + 'No receivers for signal %r from sender %s' % (signal, sender) + try: + receivers.remove(receiver) + except ValueError: + raise DispatcherError, \ + 'No connection to receiver %s for signal %r from sender %s' % \ + (receiver, signal, sender) + _cleanupConnections(senderkey, signal) + +def send(signal, sender=Anonymous, **kwds): + """Send signal from sender to all connected receivers. + + Return a list of tuple pairs [(receiver, response), ... ]. + If sender is not specified, signal is sent anonymously.""" + senderkey = id(sender) + anykey = id(Any) + # Get receivers that receive *this* signal from *this* sender. + receivers = [] + try: + receivers.extend(connections[senderkey][signal]) + except KeyError: + pass + # Add receivers that receive *any* signal from *this* sender. + anyreceivers = [] + try: + anyreceivers = connections[senderkey][Any] + except KeyError: + pass + for receiver in anyreceivers: + if receivers.count(receiver) == 0: + receivers.append(receiver) + # Add receivers that receive *this* signal from *any* sender. + anyreceivers = [] + try: + anyreceivers = connections[anykey][signal] + except KeyError: + pass + for receiver in anyreceivers: + if receivers.count(receiver) == 0: + receivers.append(receiver) + # Add receivers that receive *any* signal from *any* sender. + anyreceivers = [] + try: + anyreceivers = connections[anykey][Any] + except KeyError: + pass + for receiver in anyreceivers: + if receivers.count(receiver) == 0: + receivers.append(receiver) + # Call each receiver with whatever arguments it can accept. + # Return a list of tuple pairs [(receiver, response), ... ]. + responses = [] + for receiver in receivers: + if type(receiver) is weakref.ReferenceType \ + or isinstance(receiver, BoundMethodWeakref): + # Dereference the weak reference. + receiver = receiver() + if receiver is None: + # This receiver is dead, so skip it. + continue + response = _call(receiver, signal=signal, sender=sender, **kwds) + responses += [(receiver, response)] + return responses + +def _call(receiver, **kwds): + """Call receiver with only arguments it can accept.""" +## if type(receiver) is types.InstanceType: + if hasattr(receiver, '__call__') and \ + (hasattr(receiver.__call__, 'im_func') or hasattr(receiver.__call__, 'im_code')): + # receiver is a class instance; assume it is callable. + # Reassign receiver to the actual method that will be called. + receiver = receiver.__call__ + if hasattr(receiver, 'im_func'): + # receiver is a method. Drop the first argument, usually 'self'. + fc = receiver.im_func.func_code + acceptable = fc.co_varnames[1:fc.co_argcount] + elif hasattr(receiver, 'func_code'): + # receiver is a function. + fc = receiver.func_code + acceptable = fc.co_varnames[0:fc.co_argcount] + else: + raise DispatcherError, 'Unknown receiver %s of type %s' % (receiver, type(receiver)) + if not (fc.co_flags & 8): + # fc does not have a **kwds type parameter, therefore + # remove unacceptable arguments. + for arg in kwds.keys(): + if arg not in acceptable: + del kwds[arg] + return receiver(**kwds) + + +def safeRef(object): + """Return a *safe* weak reference to a callable object.""" + if hasattr(object, 'im_self'): + if object.im_self is not None: + # Turn a bound method into a BoundMethodWeakref instance. + # Keep track of these instances for lookup by disconnect(). + selfkey = object.im_self + funckey = object.im_func + if not _boundMethods.has_key(selfkey): + _boundMethods[selfkey] = weakref.WeakKeyDictionary() + if not _boundMethods[selfkey].has_key(funckey): + _boundMethods[selfkey][funckey] = \ + BoundMethodWeakref(boundMethod=object) + return _boundMethods[selfkey][funckey] + return weakref.ref(object, _removeReceiver) + + +class BoundMethodWeakref: + """BoundMethodWeakref class.""" + + def __init__(self, boundMethod): + """Return a weak-reference-like instance for a bound method.""" + self.isDead = 0 + def remove(object, self=self): + """Set self.isDead to true when method or instance is destroyed.""" + self.isDead = 1 + _removeReceiver(receiver=self) + self.weakSelf = weakref.ref(boundMethod.im_self, remove) + self.weakFunc = weakref.ref(boundMethod.im_func, remove) + + def __repr__(self): + """Return the closest representation.""" + return '<bound method weakref for %s.%s>' % (self.weakSelf, self.weakFunc) + + def __call__(self): + """Return a strong reference to the bound method.""" + if self.isDead: + return None + else: + object = self.weakSelf() + method = self.weakFunc().__name__ + try: # wxPython hack to handle wxDead objects. + return getattr(object, method) + except AttributeError: +## _removeReceiver(receiver=self) + return None + + +def _removeReceiver(receiver): + """Remove receiver from connections.""" + for senderkey in connections.keys(): + for signal in connections[senderkey].keys(): + receivers = connections[senderkey][signal] + try: + receivers.remove(receiver) + except: + pass + _cleanupConnections(senderkey, signal) + +def _cleanupConnections(senderkey, signal): + """Delete any empty signals for senderkey. Delete senderkey if empty.""" + receivers = connections[senderkey][signal] + if not receivers: + # No more connected receivers. Therefore, remove the signal. + signals = connections[senderkey] + del signals[signal] + if not signals: + # No more signal connections. Therefore, remove the sender. + _removeSender(senderkey) + +def _removeSender(senderkey): + """Remove senderkey from connections.""" + del connections[senderkey] + # Senderkey will only be in senders dictionary if sender + # could be weakly referenced. + try: + del senders[senderkey] + except: + pass diff --git a/wxPython/wxPython/lib/PyCrust/filling.py b/wxPython/wxPython/lib/PyCrust/filling.py index a8da260894..9a846b4def 100644 --- a/wxPython/wxPython/lib/PyCrust/filling.py +++ b/wxPython/wxPython/lib/PyCrust/filling.py @@ -1,163 +1,217 @@ -"""PyCrust Filling is the gui tree control through which a user can navigate -the local namespace or any object.""" +"""PyCrust Filling is the gui tree control through which a user can +navigate the local namespace or any object.""" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -from wxPython.wx import * -from wxPython.stc import * +from wxPython import wx +from wxPython import stc from version import VERSION +import dispatcher import inspect import introspect import keyword import sys import types +try: + True +except NameError: + True = 1==1 + False = 1==0 + COMMONTYPES = [getattr(types, t) for t in dir(types) \ if not t.startswith('_') \ and t not in ('ClassType', 'InstanceType', 'ModuleType')] + +DOCTYPES = ('BuiltinFunctionType', 'BuiltinMethodType', 'ClassType', + 'FunctionType', 'GeneratorType', 'InstanceType', + 'LambdaType', 'MethodType', 'ModuleType', + 'UnboundMethodType', 'method-wrapper') + +SIMPLETYPES = [getattr(types, t) for t in dir(types) \ + if not t.startswith('_') and t not in DOCTYPES] + try: COMMONTYPES.append(type(''.__repr__)) # Method-wrapper in version 2.2.x. except AttributeError: pass -class FillingTree(wxTreeCtrl): +class FillingTree(wx.wxTreeCtrl): """PyCrust FillingTree based on wxTreeCtrl.""" name = 'PyCrust Filling Tree' revision = __revision__ - def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ - size=wxDefaultSize, style=wxTR_HAS_BUTTONS, \ - rootObject=None, rootLabel=None, rootIsNamespace=0): + def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition, + size=wx.wxDefaultSize, style=wx.wxTR_DEFAULT_STYLE, + rootObject=None, rootLabel=None, rootIsNamespace=0, + static=False): """Create a PyCrust FillingTree instance.""" - wxTreeCtrl.__init__(self, parent, id, pos, size) + wx.wxTreeCtrl.__init__(self, parent, id, pos, size, style) self.rootIsNamespace = rootIsNamespace - if not rootObject: - import __main__ - rootObject = __main__ + import __main__ + if rootObject is None: + rootObject = __main__.__dict__ self.rootIsNamespace = 1 - if not rootLabel: rootLabel = 'Ingredients' - rootData = wxTreeItemData(rootObject) - self.root = self.AddRoot(rootLabel, -1, -1, rootData) - self.SetItemHasChildren(self.root, self.hasChildren(self.root)) - EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding) - EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed) - EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) - - def hasChildren(self, o): + if rootObject is __main__.__dict__ and rootLabel is None: + rootLabel = 'locals()' + if not rootLabel: + rootLabel = 'Ingredients' + rootData = wx.wxTreeItemData(rootObject) + self.item = self.root = self.AddRoot(rootLabel, -1, -1, rootData) + self.SetItemHasChildren(self.root, self.hasChildren(rootObject)) + wx.EVT_TREE_ITEM_EXPANDING(self, self.GetId(), self.OnItemExpanding) + wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemCollapsed) + wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) + wx.EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated) + if not static: + dispatcher.connect(receiver=self.push, signal='Interpreter.push') + + def push(self, command, more): + """Receiver for Interpreter.push signal.""" + self.display() + + def OnItemExpanding(self, event): + """Add children to the item.""" + busy = wx.wxBusyCursor() + item = event.GetItem() + if self.IsExpanded(item): + return + self.addChildren(item) +# self.SelectItem(item) + + def OnItemCollapsed(self, event): + """Remove all children from the item.""" + busy = wx.wxBusyCursor() + item = event.GetItem() +# self.CollapseAndReset(item) +# self.DeleteChildren(item) +# self.SelectItem(item) + + def OnSelChanged(self, event): + """Display information about the item.""" + busy = wx.wxBusyCursor() + self.item = event.GetItem() + self.display() + + def OnItemActivated(self, event): + """Launch a DirFrame.""" + item = event.GetItem() + text = self.getFullName(item) + obj = self.GetPyData(item) + frame = FillingFrame(parent=self, size=(600, 100), rootObject=obj, + rootLabel=text, rootIsNamespace=False) + frame.Show() + + def hasChildren(self, obj): """Return true if object has children.""" - if self.getChildren(o): - return true + if self.getChildren(obj): + return True else: - return false - - def getChildren(self, o): - """Return a dictionary with the attributes or contents of object.""" - busy = wxBusyCursor() - otype = type(o) - if (otype is types.DictType) \ - or str(otype)[17:23] == 'BTrees' and hasattr(o, 'keys'): - return o + return False + + def getChildren(self, obj): + """Return dictionary with attributes or contents of object.""" + busy = wx.wxBusyCursor() + otype = type(obj) + if otype is types.DictType \ + or str(otype)[17:23] == 'BTrees' and hasattr(obj, 'keys'): + return obj d = {} - if otype is types.ListType: - for n in range(len(o)): + if otype is types.ListType or otype is types.TupleType: + for n in range(len(obj)): key = '[' + str(n) + ']' - d[key] = o[n] + d[key] = obj[n] if otype not in COMMONTYPES: - for key in introspect.getAttributeNames(o): - # Believe it or not, some attributes can disappear, such as - # the exc_traceback attribute of the sys module. So this is - # nested in a try block. + for key in introspect.getAttributeNames(obj): + # Believe it or not, some attributes can disappear, + # such as the exc_traceback attribute of the sys + # module. So this is nested in a try block. try: - d[key] = getattr(o, key) + d[key] = getattr(obj, key) except: pass return d - def OnItemExpanding(self, event): - busy = wxBusyCursor() - selection = event.GetItem() - if self.IsExpanded(selection): - return - o = self.GetPyData(selection) - children = self.getChildren(o) + def addChildren(self, item): + self.DeleteChildren(item) + obj = self.GetPyData(item) + children = self.getChildren(obj) if not children: return - list = children.keys() - try: - list.sort(lambda x, y: cmp(x.lower(), y.lower())) - except: - pass - for item in list: - itemtext = str(item) - # Show string dictionary items with single quotes, except for - # the first level of items, if they represent a namespace. - if type(o) is types.DictType \ - and type(item) is types.StringType \ - and (selection != self.root \ - or (selection == self.root and not self.rootIsNamespace)): - itemtext = repr(item) - child = self.AppendItem(selection, itemtext, -1, -1, \ - wxTreeItemData(children[item])) - self.SetItemHasChildren(child, self.hasChildren(children[item])) - - def OnItemCollapsed(self, event): - """Remove all children from the item.""" - busy = wxBusyCursor() - item = event.GetItem() - self.DeleteChildren(item) - - def OnSelChanged(self, event): - busy = wxBusyCursor() - item = event.GetItem() - if item == self.root: - self.setText('') + keys = children.keys() + keys.sort(lambda x, y: cmp(x.lower(), y.lower())) + for key in keys: + itemtext = str(key) + # Show string dictionary items with single quotes, except + # for the first level of items, if they represent a + # namespace. + if type(obj) is types.DictType \ + and type(key) is types.StringType \ + and (item != self.root \ + or (item == self.root and not self.rootIsNamespace)): + itemtext = repr(key) + child = children[key] + data = wx.wxTreeItemData(child) + branch = self.AppendItem(parent=item, text=itemtext, data=data) + self.SetItemHasChildren(branch, self.hasChildren(child)) + + def display(self): + item = self.item + if self.IsExpanded(item): + self.addChildren(item) + self.setText('') + obj = self.GetPyData(item) + if obj is None: # Windows bug fix. return - o = self.GetPyData(item) - otype = type(o) + self.SetItemHasChildren(item, self.hasChildren(obj)) + otype = type(obj) text = '' text += self.getFullName(item) text += '\n\nType: ' + str(otype) try: - value = str(o) + value = str(obj) except: value = '' if otype is types.StringType or otype is types.UnicodeType: - value = repr(o) + value = repr(obj) text += '\n\nValue: ' + value + if otype not in SIMPLETYPES: + try: + text += '\n\nDocstring:\n\n"""' + \ + inspect.getdoc(obj).strip() + '"""' + except: + pass if otype is types.InstanceType: try: text += '\n\nClass Definition:\n\n' + \ - inspect.getsource(o.__class__) + inspect.getsource(obj.__class__) except: - try: - text += '\n\n"""' + inspect.getdoc(o).strip() + '"""' - except: - pass + pass else: try: text += '\n\nSource Code:\n\n' + \ - inspect.getsource(o) + inspect.getsource(obj) except: - try: - text += '\n\n"""' + inspect.getdoc(o).strip() + '"""' - except: - pass + pass self.setText(text) def getFullName(self, item, partial=''): """Return a syntactically proper name for item.""" - parent = self.GetItemParent(item) - parento = self.GetPyData(parent) name = self.GetItemText(item) + parent = None + obj = None + if item != self.root: + parent = self.GetItemParent(item) + obj = self.GetPyData(parent) # Apply dictionary syntax to dictionary items, except the root # and first level children of a namepace. - if (type(parento) is types.DictType \ - or str(type(parento))[17:23] == 'BTrees' \ - and hasattr(parento, 'keys')) \ + if (type(obj) is types.DictType \ + or str(type(obj))[17:23] == 'BTrees' \ + and hasattr(obj, 'keys')) \ and ((item != self.root and parent != self.root) \ or (parent == self.root and not self.rootIsNamespace)): name = '[' + name + ']' @@ -177,19 +231,19 @@ class FillingTree(wxTreeCtrl): def setText(self, text): """Display information about the current selection.""" - # This method will most likely be replaced by the enclosing app - # to do something more interesting, like write to a text control. + # This method will likely be replaced by the enclosing app to + # do something more interesting, like write to a text control. print text def setStatusText(self, text): """Display status information.""" - # This method will most likely be replaced by the enclosing app - # to do something more interesting, like write to a status bar. + # This method will likely be replaced by the enclosing app to + # do something more interesting, like write to a status bar. print text -if wxPlatform == '__WXMSW__': +if wx.wxPlatform == '__WXMSW__': faces = { 'times' : 'Times New Roman', 'mono' : 'Courier New', 'helv' : 'Lucida Console', @@ -199,12 +253,6 @@ if wxPlatform == '__WXMSW__': 'lnsize' : 9, 'backcol': '#FFFFFF', } - # Versions of wxPython prior to 2.3.2 had a sizing bug on Win platform. - # The font was 2 points too large. So we need to reduce the font size. - if ((wxMAJOR_VERSION, wxMINOR_VERSION) == (2, 3) and wxRELEASE_NUMBER < 2) \ - or (wxMAJOR_VERSION <= 2 and wxMINOR_VERSION <= 2): - faces['size'] -= 2 - faces['lnsize'] -= 2 else: # GTK faces = { 'times' : 'Times', 'mono' : 'Courier', @@ -216,24 +264,45 @@ else: # GTK } -class FillingText(wxStyledTextCtrl): +class FillingText(stc.wxStyledTextCtrl): """PyCrust FillingText based on wxStyledTextCtrl.""" name = 'PyCrust Filling Text' revision = __revision__ - def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ - size=wxDefaultSize, style=wxCLIP_CHILDREN): + def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition, + size=wx.wxDefaultSize, style=wx.wxCLIP_CHILDREN, + static=False): """Create a PyCrust FillingText instance.""" - wxStyledTextCtrl.__init__(self, parent, id, pos, size, style) + stc.wxStyledTextCtrl.__init__(self, parent, id, pos, size, style) # Configure various defaults and user preferences. self.config() + dispatcher.connect(receiver=self.fontsizer, signal='FontIncrease') + dispatcher.connect(receiver=self.fontsizer, signal='FontDecrease') + dispatcher.connect(receiver=self.fontsizer, signal='FontDefault') + if not static: + dispatcher.connect(receiver=self.push, signal='Interpreter.push') + + def push(self, command, more): + """Receiver for Interpreter.push signal.""" + self.Refresh() + + def fontsizer(self, signal): + """Receiver for Font* signals.""" + size = self.GetZoom() + if signal == 'FontIncrease': + size += 1 + elif signal == 'FontDecrease': + size -= 1 + elif signal == 'FontDefault': + size = 0 + self.SetZoom(size) def config(self): """Configure shell based on user preferences.""" self.SetMarginWidth(1, 0) - self.SetLexer(wxSTC_LEX_PYTHON) + self.SetLexer(stc.wxSTC_LEX_PYTHON) self.SetKeyWords(0, ' '.join(keyword.kwlist)) self.setStyles(faces) @@ -250,96 +319,117 @@ class FillingText(wxStyledTextCtrl): """Configure font size, typeface and color for lexer.""" # Default style - self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) + self.StyleSetSpec(stc.wxSTC_STYLE_DEFAULT, + "face:%(mono)s,size:%(size)d" % faces) self.StyleClearAll() # Built in styles - self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces) - self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88") - self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88") + self.StyleSetSpec(stc.wxSTC_STYLE_LINENUMBER, + "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces) + self.StyleSetSpec(stc.wxSTC_STYLE_CONTROLCHAR, + "face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_STYLE_BRACELIGHT, + "fore:#0000FF,back:#FFFF88") + self.StyleSetSpec(stc.wxSTC_STYLE_BRACEBAD, + "fore:#FF0000,back:#FFFF88") # Python styles - self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_NUMBER, "") - self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold") - self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000") - self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8") - self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold") - self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold") - self.StyleSetSpec(wxSTC_P_OPERATOR, "") - self.StyleSetSpec(wxSTC_P_IDENTIFIER, "") - self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F") - self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces) + self.StyleSetSpec(stc.wxSTC_P_DEFAULT, + "face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_COMMENTLINE, + "fore:#007F00,face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_NUMBER, + "") + self.StyleSetSpec(stc.wxSTC_P_STRING, + "fore:#7F007F,face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_CHARACTER, + "fore:#7F007F,face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_WORD, + "fore:#00007F,bold") + self.StyleSetSpec(stc.wxSTC_P_TRIPLE, + "fore:#7F0000") + self.StyleSetSpec(stc.wxSTC_P_TRIPLEDOUBLE, + "fore:#000033,back:#FFFFE8") + self.StyleSetSpec(stc.wxSTC_P_CLASSNAME, + "fore:#0000FF,bold") + self.StyleSetSpec(stc.wxSTC_P_DEFNAME, + "fore:#007F7F,bold") + self.StyleSetSpec(stc.wxSTC_P_OPERATOR, + "") + self.StyleSetSpec(stc.wxSTC_P_IDENTIFIER, + "") + self.StyleSetSpec(stc.wxSTC_P_COMMENTBLOCK, + "fore:#7F7F7F") + self.StyleSetSpec(stc.wxSTC_P_STRINGEOL, + "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces) def SetText(self, *args, **kwds): self.SetReadOnly(0) - wxStyledTextCtrl.SetText(self, *args, **kwds) + stc.wxStyledTextCtrl.SetText(self, *args, **kwds) self.SetReadOnly(1) -class Filling(wxSplitterWindow): +class Filling(wx.wxSplitterWindow): """PyCrust Filling based on wxSplitterWindow.""" name = 'PyCrust Filling' revision = __revision__ - def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ - size=wxDefaultSize, style=wxSP_3D, name='Filling Window', \ - rootObject=None, rootLabel=None, rootIsNamespace=0): + def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition, + size=wx.wxDefaultSize, style=wx.wxSP_3D, + name='Filling Window', rootObject=None, + rootLabel=None, rootIsNamespace=0, static=False): """Create a PyCrust Filling instance.""" - wxSplitterWindow.__init__(self, parent, id, pos, size, style, name) - self.fillingTree = FillingTree(parent=self, rootObject=rootObject, \ - rootLabel=rootLabel, \ - rootIsNamespace=rootIsNamespace) - self.fillingText = FillingText(parent=self) - self.SplitVertically(self.fillingTree, self.fillingText, 200) + wx.wxSplitterWindow.__init__(self, parent, id, pos, size, style, name) + self.tree = FillingTree(parent=self, rootObject=rootObject, + rootLabel=rootLabel, + rootIsNamespace=rootIsNamespace, + static=static) + self.text = FillingText(parent=self, static=static) + self.SplitVertically(self.tree, self.text, 200) self.SetMinimumPaneSize(1) - # Override the filling so that descriptions go to fillingText. - self.fillingTree.setText = self.fillingText.SetText - # Select the root item. - self.fillingTree.SelectItem(self.fillingTree.root) + # Override the filling so that descriptions go to FillingText. + self.tree.setText = self.text.SetText + # Display the root item. +## self.tree.SelectItem(self.tree.root) + self.tree.display() -class FillingFrame(wxFrame): +class FillingFrame(wx.wxFrame): """Frame containing the PyCrust filling, or namespace tree component.""" name = 'PyCrust Filling Frame' revision = __revision__ - def __init__(self, parent=None, id=-1, title='PyFilling', \ - pos=wxDefaultPosition, size=wxDefaultSize, \ - style=wxDEFAULT_FRAME_STYLE, rootObject=None, \ - rootLabel=None, rootIsNamespace=0): + def __init__(self, parent=None, id=-1, title='PyFilling', + pos=wx.wxDefaultPosition, size=wx.wxDefaultSize, + style=wx.wxDEFAULT_FRAME_STYLE, rootObject=None, + rootLabel=None, rootIsNamespace=0, static=False): """Create a PyCrust FillingFrame instance.""" - wxFrame.__init__(self, parent, id, title, pos, size, style) - intro = 'Welcome To PyFilling - The Tastiest Namespace Inspector' + wx.wxFrame.__init__(self, parent, id, title, pos, size, style) + intro = 'PyFilling - The Tastiest Namespace Inspector' self.CreateStatusBar() self.SetStatusText(intro) - if wxPlatform == '__WXMSW__': - import os - filename = os.path.join(os.path.dirname(__file__), 'PyCrust.ico') - icon = wxIcon(filename, wxBITMAP_TYPE_ICO) - self.SetIcon(icon) - self.filling = Filling(parent=self, rootObject=rootObject, \ - rootLabel=rootLabel, \ - rootIsNamespace=rootIsNamespace) - # Override the filling so that status messages go to the status bar. - self.filling.fillingTree.setStatusText = self.SetStatusText - - -class App(wxApp): + import images + self.SetIcon(images.getPyCrustIcon()) + self.filling = Filling(parent=self, rootObject=rootObject, + rootLabel=rootLabel, + rootIsNamespace=rootIsNamespace, + static=static) + # Override so that status messages go to the status bar. + self.filling.tree.setStatusText = self.SetStatusText + + +class App(wx.wxApp): """PyFilling standalone application.""" def OnInit(self): + wx.wxInitAllImageHandlers() self.fillingFrame = FillingFrame() - self.fillingFrame.Show(true) + self.fillingFrame.Show(True) self.SetTopWindow(self.fillingFrame) - return true + return True diff --git a/wxPython/wxPython/lib/PyCrust/interpreter.py b/wxPython/wxPython/lib/PyCrust/interpreter.py index 4cd752daa3..07caaafc84 100644 --- a/wxPython/wxPython/lib/PyCrust/interpreter.py +++ b/wxPython/wxPython/lib/PyCrust/interpreter.py @@ -7,15 +7,22 @@ __revision__ = "$Revision$"[11:-2] import os import sys from code import InteractiveInterpreter +import dispatcher import introspect +try: + True +except NameError: + True = 1==1 + False = 1==0 + class Interpreter(InteractiveInterpreter): """PyCrust Interpreter based on code.InteractiveInterpreter.""" revision = __revision__ - def __init__(self, locals=None, rawin=None, \ + def __init__(self, locals=None, rawin=None, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr): """Create an interactive interpreter object.""" InteractiveInterpreter.__init__(self, locals=locals) @@ -26,8 +33,8 @@ class Interpreter(InteractiveInterpreter): import __builtin__ __builtin__.raw_input = rawin del __builtin__ - copyright = \ - 'Type "copyright", "credits" or "license" for more information.' + copyright = 'Type "help", "copyright", "credits" or "license"' + copyright += ' for more information.' self.introText = 'Python %s on %s%s%s' % \ (sys.version, sys.platform, os.linesep, copyright) try: @@ -47,29 +54,32 @@ class Interpreter(InteractiveInterpreter): """Send command to the interpreter to be executed. Because this may be called recursively, we append a new list - onto the commandBuffer list and then append commands into that. - If the passed in command is part of a multi-line command we keep - appending the pieces to the last list in commandBuffer until we - have a complete command. If not, we delete that last list.""" + onto the commandBuffer list and then append commands into + that. If the passed in command is part of a multi-line + command we keep appending the pieces to the last list in + commandBuffer until we have a complete command. If not, we + delete that last list.""" + command = str(command) # In case the command is unicode. if not self.more: try: del self.commandBuffer[-1] except IndexError: pass if not self.more: self.commandBuffer.append([]) self.commandBuffer[-1].append(command) source = '\n'.join(self.commandBuffer[-1]) - self.more = self.runsource(source) - return self.more + more = self.more = self.runsource(source) + dispatcher.send(signal='Interpreter.push', sender=self, + command=command, more=more, source=source) + return more def runsource(self, source): """Compile and run source code in the interpreter.""" stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr - sys.stdin = self.stdin - sys.stdout = self.stdout - sys.stderr = self.stderr + sys.stdin, sys.stdout, sys.stderr = \ + self.stdin, self.stdout, self.stderr more = InteractiveInterpreter.runsource(self, source) # If sys.std* is still what we set it to, then restore it. - # But, if the executed source changed sys.std*, assume it - # was meant to be changed and leave it. Power to the people. + # But, if the executed source changed sys.std*, assume it was + # meant to be changed and leave it. Power to the people. if sys.stdin == self.stdin: sys.stdin = stdin if sys.stdout == self.stdout: @@ -86,22 +96,28 @@ class Interpreter(InteractiveInterpreter): """Return list of auto-completion options for a command. The list of options will be based on the locals namespace.""" - return introspect.getAutoCompleteList(command, self.locals, *args, **kwds) + stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr + sys.stdin, sys.stdout, sys.stderr = \ + self.stdin, self.stdout, self.stderr + l = introspect.getAutoCompleteList(command, self.locals, + *args, **kwds) + sys.stdin, sys.stdout, sys.stderr = stdin, stdout, stderr + return l def getCallTip(self, command='', *args, **kwds): """Return call tip text for a command. - The call tip information will be based on the locals namespace.""" + Call tip information will be based on the locals namespace.""" return introspect.getCallTip(command, self.locals, *args, **kwds) class InterpreterAlaCarte(Interpreter): """PyCrustAlaCarte Demo Interpreter.""" - def __init__(self, locals, rawin, stdin, stdout, stderr, \ + def __init__(self, locals, rawin, stdin, stdout, stderr, ps1='main prompt', ps2='continuation prompt'): """Create an interactive interpreter object.""" - Interpreter.__init__(self, locals=locals, rawin=rawin, \ + Interpreter.__init__(self, locals=locals, rawin=rawin, stdin=stdin, stdout=stdout, stderr=stderr) sys.ps1 = ps1 sys.ps2 = ps2 diff --git a/wxPython/wxPython/lib/PyCrust/introspect.py b/wxPython/wxPython/lib/PyCrust/introspect.py index d568dc6c6f..482464735d 100644 --- a/wxPython/wxPython/lib/PyCrust/introspect.py +++ b/wxPython/wxPython/lib/PyCrust/introspect.py @@ -1,15 +1,24 @@ -"""Provides a variety of introspective-type support functions for things -like call tips and command auto completion.""" +"""Provides a variety of introspective-type support functions for +things like call tips and command auto completion.""" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] +from __future__ import nested_scopes + +import cStringIO import inspect -import string +import tokenize import types -def getAutoCompleteList(command='', locals=None, includeMagic=1, \ +try: + True +except NameError: + True = 1==1 + False = 1==0 + +def getAutoCompleteList(command='', locals=None, includeMagic=1, includeSingle=1, includeDouble=1): """Return list of auto-completion options for command. @@ -25,19 +34,20 @@ def getAutoCompleteList(command='', locals=None, includeMagic=1, \ except: pass else: - attributes = getAttributeNames(object, includeMagic, \ + attributes = getAttributeNames(object, includeMagic, includeSingle, includeDouble) return attributes -def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1): - """Return list of unique attributes, including inherited, for an object.""" +def getAttributeNames(object, includeMagic=1, includeSingle=1, + includeDouble=1): + """Return list of unique attributes, including inherited, for object.""" attributes = [] dict = {} if not hasattrAlwaysReturnsTrue(object): - # Add some attributes that don't always get picked up. - # If they don't apply, they'll get filtered out at the end. - attributes += ['__bases__', '__class__', '__dict__', '__name__', \ - 'func_closure', 'func_code', 'func_defaults', \ + # Add some attributes that don't always get picked up. If + # they don't apply, they'll get filtered out at the end. + attributes += ['__bases__', '__class__', '__dict__', '__name__', + 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name'] if includeMagic: try: attributes += object._getAttributeNames() @@ -65,19 +75,20 @@ def hasattrAlwaysReturnsTrue(object): return hasattr(object, 'bogu5_123_aTTri8ute') def getAllAttributeNames(object): - """Return mapping of all attributes, including inherited, for an object. + """Return dict of all attributes, including inherited, for an object. Recursively walk through a class and all base classes. """ attrdict = {} # (object, technique, count): [list of attributes] # !!! - # !!! Do Not use hasattr() as a test anywhere in this function, - # !!! because it is unreliable with remote objects - xmlrpc, soap, etc. - # !!! They always return true for hasattr(). + # Do Not use hasattr() as a test anywhere in this function, + # because it is unreliable with remote objects: xmlrpc, soap, etc. + # They always return true for hasattr(). # !!! try: - # Yes, this can fail if object is an instance of a class with - # __str__ (or __repr__) having a bug or raising an exception. :-( + # Yes, this can fail if object is an instance of a class with + # __str__ (or __repr__) having a bug or raising an + # exception. :-( key = str(object) except: key = 'anonymous' @@ -102,7 +113,8 @@ def getAllAttributeNames(object): pass else: if klass is object: - # Break a circular reference. This happens with extension classes. + # Break a circular reference. This happens with extension + # classes. pass else: attrdict.update(getAllAttributeNames(klass)) @@ -152,7 +164,7 @@ def getCallTip(command='', locals=None): if dropSelf: # The first parameter to a method is a reference to an # instance, usually coded as "self", and is usually passed - # automatically by Python and therefore we want to drop it. + # automatically by Python; therefore we want to drop it. temp = argspec.split(',') if len(temp) == 1: # No other arguments. argspec = '()' @@ -167,10 +179,15 @@ def getCallTip(command='', locals=None): # "Return call tip text for a command." # tip3 is the rest of the docstring, like: # "The call tip information will be based on ... <snip> + firstline = doc.split('\n')[0].lstrip() + if tip1 == firstline: + tip1 = '' + else: + tip1 += '\n\n' docpieces = doc.split('\n\n') tip2 = docpieces[0] tip3 = '\n\n'.join(docpieces[1:]) - tip = '%s\n\n%s\n\n%s' % (tip1, tip2, tip3) + tip = '%s%s\n\n%s' % (tip1, tip2, tip3) else: tip = tip1 calltip = (name, argspec[1:-1], tip.strip()) @@ -179,47 +196,108 @@ def getCallTip(command='', locals=None): def getRoot(command, terminator=None): """Return the rightmost root portion of an arbitrary Python command. - Return only the root portion that can be eval()'d without side effects. - The command would normally terminate with a "(" or ".". The terminator - and anything after the terminator will be dropped.""" - root = '' - validChars = "._" + string.uppercase + string.lowercase + string.digits - emptyTypes = ("''", '""', '""""""', "''''''", '[]', '()', '{}') - validSeparators = string.whitespace + ',+-*/=%<>&|^~:([{' - # Drop the final terminator and anything that follows. + Return only the root portion that can be eval()'d without side + effects. The command would normally terminate with a '(' or + '.'. The terminator and anything after the terminator will be + dropped.""" command = rtrimTerminus(command, terminator) - if len(command) == 0: - root = '' - elif command in emptyTypes and terminator in ('.', '', None): - # Let empty type delimiter pairs go through. - root = command + tokens = getTokens(command) + if not tokens: + return '' + if tokens[-1][0] is tokenize.ENDMARKER: + # Remove the end marker. + del tokens[-1] + if terminator == '.' and \ + (tokens[-1][1] <> '.' or tokens[-1][0] is not tokenize.OP): + # Trap decimals in numbers, versus the dot operator. + return '' else: - # Go backward through the command until we hit an "invalid" character. - i = len(command) - while i and command[i-1] in validChars: - i -= 1 - # Default to everything from the "invalid" character to the end. - root = command[i:] - # Override certain exceptions. - if i > 0 and command[i-1] in ("'", '"'): - # Detect situations where we are in the middle of a string. - # This code catches the simplest case, but needs to catch others. - root = '' - elif ((2 <= i < len(command) and command[i] == '.') \ - or (2 <= i <= len(command) and terminator in ('.', '', None))) \ - and command[i-2:i] in emptyTypes: - # Allow empty types to get through. - # Don't confuse an empty tupple with an argumentless callable. - if i == 2 or (i >= 3 and command[i-3] in validSeparators): - root = command[i-2:] - return root + # Strip off the terminator. + command = command[:-1] + command = command.rstrip() + tokens = getTokens(command) + tokens.reverse() + line = '' + start = None + prefix = '' + laststring = '.' + emptyTypes = ('[]', '()', '{}') + for token in tokens: + tokentype = token[0] + tokenstring = token[1] + line = token[4] + if tokentype is tokenize.ENDMARKER: + continue + if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \ + and laststring != '.': + # We've reached something that's not part of the root. + if prefix and line[token[3][1]] != ' ': + # If it doesn't have a space after it, remove the prefix. + prefix = '' + break + if tokentype in (tokenize.NAME, tokenize.STRING, tokenize.NUMBER) \ + or (tokentype is tokenize.OP and tokenstring == '.'): + if prefix: + # The prefix isn't valid because it comes after a dot. + prefix = '' + break + else: + # start represents the last known good point in the line. + start = token[2][1] + elif len(tokenstring) == 1 and tokenstring in ('[({])}'): + # Remember, we're working backwords. + # So prefix += tokenstring would be wrong. + if prefix in emptyTypes and tokenstring in ('[({'): + # We've already got an empty type identified so now we + # are in a nested situation and we can break out with + # what we've got. + break + else: + prefix = tokenstring + prefix + else: + # We've reached something that's not part of the root. + break + laststring = tokenstring + if start is None: + start = len(line) + root = line[start:] + if prefix in emptyTypes: + # Empty types are safe to be eval()'d and introspected. + root = prefix + root + return root + +def getTokens(command): + """Return list of token tuples for command.""" + command = str(command) # In case the command is unicode, which fails. + f = cStringIO.StringIO(command) + # tokens is a list of token tuples, each looking like: + # (type, string, (srow, scol), (erow, ecol), line) + tokens = [] + # Can't use list comprehension: + # tokens = [token for token in tokenize.generate_tokens(f.readline)] + # because of need to append as much as possible before TokenError. + try: +## This code wasn't backward compatible with Python 2.1.3. +## +## for token in tokenize.generate_tokens(f.readline): +## tokens.append(token) + + # This works with Python 2.1.3 (with nested_scopes). + def eater(*args): + tokens.append(args) + tokenize.tokenize_loop(f.readline, eater) + except tokenize.TokenError: + # This is due to a premature EOF, which we expect since we are + # feeding in fragments of Python code. + pass + return tokens def rtrimTerminus(command, terminator=None): - """Return command minus the final terminator and anything that follows.""" + """Return command minus anything that fillows the final terminator.""" if terminator: pieces = command.split(terminator) if len(pieces) > 1: - command = terminator.join(pieces[:-1]) + command = terminator.join(pieces[:-1]) + terminator return command def getBaseObject(object): @@ -228,12 +306,14 @@ def getBaseObject(object): # Builtin functions don't have an argspec that we can get. dropSelf = 0 elif inspect.ismethod(object): - # Get the function from the object otherwise inspect.getargspec() - # complains that the object isn't a Python function. + # Get the function from the object otherwise + # inspect.getargspec() complains that the object isn't a + # Python function. try: if object.im_self is None: - # This is an unbound method so we do not drop self from the - # argspec, since an instance must be passed as the first arg. + # This is an unbound method so we do not drop self + # from the argspec, since an instance must be passed + # as the first arg. dropSelf = 0 else: dropSelf = 1 @@ -269,6 +349,3 @@ def getConstructor(object): if constructor is not None: return constructor return None - - - diff --git a/wxPython/wxPython/lib/PyCrust/pseudo.py b/wxPython/wxPython/lib/PyCrust/pseudo.py index 0483388f69..583854809a 100644 --- a/wxPython/wxPython/lib/PyCrust/pseudo.py +++ b/wxPython/wxPython/lib/PyCrust/pseudo.py @@ -4,88 +4,97 @@ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] +try: + True +except NameError: + True = 1==1 + False = 1==0 + + class PseudoKeyword: """A callable class that calls a method passed as a parameter. - + Good for creating a pseudo keyword in the python runtime environment. The keyword is really an object that has a repr() that calls itself which calls the method that was passed in the init of the object. All this just to avoid having to type in the closing parens on a method. So, for example: - + >>> quit = PseudoKeyword(SomeObject.someMethod) >>> quit - + SomeObject.someMethod gets executed as if it had been called directly and the user didn't have to type the parens, like - "quit()". This technique is most applicable for pseudo keywords + 'quit()'. This technique is most applicable for pseudo keywords like quit, exit and help. - - If SomeObject.someMethod can take parameters, they can still be - passed by using the keyword in the traditional way with parens. - """ + + If SomeObject.someMethod can take parameters, they can still be + passed by using the keyword in the traditional way with parens.""" + def __init__(self, method): """Create a callable object that executes method when called.""" - + if callable(method): self.method = method else: raise ValueError, 'method must be callable' - + def __call__(self, *args, **kwds): self.method(*args, **kwds) - + def __repr__(self): self() return '' class PseudoFile: - + def __init__(self): """Create a file-like object.""" pass - + def readline(self): pass def write(self, s): pass - + def writelines(self, l): map(self.write, l) - + def flush(self): pass - + def isatty(self): pass - - + + class PseudoFileIn(PseudoFile): - - def __init__(self, readline): + + def __init__(self, readline, readlines=None): if callable(readline): self.readline = readline else: raise ValueError, 'readline must be callable' - + if callable(readlines): + self.readlines = readlines + def isatty(self): return 1 class PseudoFileOut(PseudoFile): - + def __init__(self, write): if callable(write): self.write = write else: raise ValueError, 'write must be callable' - + def isatty(self): return 1 - - + + class PseudoFileErr(PseudoFile): def __init__(self, write): @@ -93,9 +102,6 @@ class PseudoFileErr(PseudoFile): self.write = write else: raise ValueError, 'write must be callable' - + def isatty(self): return 1 - - - diff --git a/wxPython/wxPython/lib/PyCrust/shell.py b/wxPython/wxPython/lib/PyCrust/shell.py index e72edd6928..f522356f09 100644 --- a/wxPython/wxPython/lib/PyCrust/shell.py +++ b/wxPython/wxPython/lib/PyCrust/shell.py @@ -1,28 +1,52 @@ -"""The PyCrust Shell is an interactive text control in which a user types in -commands to be sent to the interpreter. This particular shell is based on -wxPython's wxStyledTextCtrl. The latest files are always available at the -SourceForge project page at http://sourceforge.net/projects/pycrust/. +"""The PyCrust Shell is an interactive text control in which a user +types in commands to be sent to the interpreter. This particular shell +is based on wxPython's wxStyledTextCtrl. The latest files are always +available at the SourceForge project page at +http://sourceforge.net/projects/pycrust/. + Sponsored by Orbtech - Your source for Python programming expertise.""" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -from wxPython.wx import * -from wxPython.stc import * import keyword import os import sys +import time from pseudo import PseudoFileIn from pseudo import PseudoFileOut from pseudo import PseudoFileErr +from shellmenu import ShellMenu from version import VERSION +import dispatcher + +try: + import wxd.d_wx +except ImportError: + from wxPython import wx +else: + from wxd.d_wx import wx + +try: + import wxd.d_stc +except ImportError: + from wxPython import stc +else: + from wxd.d_stc import stc + +try: + True +except NameError: + True = 1==1 + False = 1==0 sys.ps3 = '<-- ' # Input prompt. -NAVKEYS = (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, WXK_PRIOR, WXK_NEXT) +NAVKEYS = (wx.WXK_END, wx.WXK_LEFT, wx.WXK_RIGHT, + wx.WXK_UP, wx.WXK_DOWN, wx.WXK_PRIOR, wx.WXK_NEXT) -if wxPlatform == '__WXMSW__': +if wx.wxPlatform == '__WXMSW__': faces = { 'times' : 'Times New Roman', 'mono' : 'Courier New', 'helv' : 'Lucida Console', @@ -32,11 +56,6 @@ if wxPlatform == '__WXMSW__': 'lnsize' : 9, 'backcol': '#FFFFFF', } - # Versions of wxPython prior to 2.3.2 had a sizing bug on Win platform. - # The font was 2 points too large. So we need to reduce the font size. - if (wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER) < (2, 3, 2): - faces['size'] -= 2 - faces['lnsize'] -= 2 else: # GTK faces = { 'times' : 'Times', 'mono' : 'Courier', @@ -48,30 +67,69 @@ else: # GTK } +class ShellFrame(wx.wxFrame, ShellMenu): + """Frame containing the PyCrust shell component.""" + + name = 'PyCrust Shell Frame' + revision = __revision__ + + def __init__(self, parent=None, id=-1, title='PyShell', + pos=wx.wxDefaultPosition, size=wx.wxDefaultSize, + style=wx.wxDEFAULT_FRAME_STYLE, locals=None, + InterpClass=None, *args, **kwds): + """Create a PyCrust ShellFrame instance.""" + wx.wxFrame.__init__(self, parent, id, title, pos, size, style) + intro = 'PyCrust %s - The Flakiest Python Shell' % VERSION + intro += '\nSponsored by Orbtech - ' + \ + 'Your source for Python programming expertise.' + self.CreateStatusBar() + self.SetStatusText(intro.replace('\n', ', ')) + import images + self.SetIcon(images.getPyCrustIcon()) + self.shell = Shell(parent=self, id=-1, introText=intro, + locals=locals, InterpClass=InterpClass, + *args, **kwds) + # Override the shell so that status messages go to the status bar. + self.shell.setStatusText = self.SetStatusText + self.createMenus() + wx.EVT_CLOSE(self, self.OnCloseWindow) + + def OnCloseWindow(self, event): + """Event handler for closing.""" + # This isn't working the way I want, but I'll leave it for now. + if self.shell.waiting: + event.Veto(True) + else: + self.shell.destroy() + self.Destroy() + + class ShellFacade: """Simplified interface to all shell-related functionality. - This is a semi-transparent facade, in that all attributes of other are - still accessible, even though only some are visible to the user.""" + This is a semi-transparent facade, in that all attributes of other + are accessible, even though only some are visible to the user.""" name = 'PyCrust Shell Interface' revision = __revision__ def __init__(self, other): """Create a ShellFacade instance.""" - methods = ['ask', - 'clear', - 'pause', - 'prompt', - 'quit', - 'redirectStderr', - 'redirectStdin', - 'redirectStdout', - 'run', - 'runfile', - 'wrap', - 'zoom', - ] + methods = [ + 'about', + 'ask', + 'clear', + 'pause', + 'prompt', + 'quit', + 'redirectStderr', + 'redirectStdin', + 'redirectStdout', + 'run', + 'runfile', + 'wrap', + 'zoom', + ] for method in methods: self.__dict__[method] = getattr(other, method) d = self.__dict__ @@ -95,7 +153,11 @@ Alt+N Retrieve Next History item. Shift+Up Arrow Insert Previous History item. Shift+Down Arrow Insert Next History item. F8 Command-completion of History item. - (Type a few characters of a previous command and then press F8.) + (Type a few characters of a previous command and press F8.) +Ctrl+Enter Insert new line into multiline command. +Ctrl+] Increase font size. +Ctrl+[ Decrease font size. +Ctrl+= Default font size. """ def help(self): @@ -112,7 +174,7 @@ F8 Command-completion of History item. if self.__dict__.has_key(name): self.__dict__[name] = value elif hasattr(self.other, name): - return setattr(self.other, name, value) + setattr(self.other, name, value) else: raise AttributeError, name @@ -129,17 +191,19 @@ F8 Command-completion of History item. return list -class Shell(wxStyledTextCtrl): +class Shell(stc.wxStyledTextCtrl): """PyCrust Shell based on wxStyledTextCtrl.""" name = 'PyCrust Shell' revision = __revision__ - def __init__(self, parent, id=-1, pos=wxDefaultPosition, \ - size=wxDefaultSize, style=wxCLIP_CHILDREN, introText='', \ - locals=None, InterpClass=None, *args, **kwds): + def __init__(self, parent, id=-1, pos=wx.wxDefaultPosition, + size=wx.wxDefaultSize, style=wx.wxCLIP_CHILDREN, + introText='', locals=None, InterpClass=None, *args, **kwds): """Create a PyCrust Shell instance.""" - wxStyledTextCtrl.__init__(self, parent, id, pos, size, style) + stc.wxStyledTextCtrl.__init__(self, parent, id, pos, size, style) + if locals is None: + locals = {} # Grab these so they can be restored by self.redirect* methods. self.stdin = sys.stdin self.stdout = sys.stdout @@ -151,24 +215,16 @@ class Shell(wxStyledTextCtrl): from interpreter import Interpreter else: Interpreter = InterpClass - # Create default locals so we have something interesting. - shellLocals = {'__name__': 'PyCrust-Shell', - '__doc__': 'PyCrust-Shell, The PyCrust Python Shell.', - '__version__': VERSION, - } - # Add the dictionary that was passed in. - if locals: - shellLocals.update(locals) # Create a replacement for stdin. - self.reader = PseudoFileIn(self.readline) + self.reader = PseudoFileIn(self.readline, self.readlines) self.reader.input = '' self.reader.isreading = 0 # Set up the interpreter. - self.interp = Interpreter(locals=shellLocals, \ - rawin=self.raw_input, \ - stdin=self.reader, \ - stdout=PseudoFileOut(self.writeOut), \ - stderr=PseudoFileErr(self.writeErr), \ + self.interp = Interpreter(locals=locals, + rawin=self.raw_input, + stdin=self.reader, + stdout=PseudoFileOut(self.writeOut), + stderr=PseudoFileErr(self.writeErr), *args, **kwds) # Find out for which keycodes the interpreter will autocomplete. self.autoCompleteKeys = self.interp.getAutoCompleteKeys() @@ -177,45 +233,60 @@ class Shell(wxStyledTextCtrl): self.promptPosEnd = 0 # Keep track of multi-line commands. self.more = 0 - # Create the command history. Commands are added into the front of - # the list (ie. at index 0) as they are entered. self.historyIndex - # is the current position in the history; it gets incremented as you - # retrieve the previous command, decremented as you retrieve the - # next, and reset when you hit Enter. self.historyIndex == -1 means - # you're on the current command, not in the history. + # Create the command history. Commands are added into the + # front of the list (ie. at index 0) as they are entered. + # self.historyIndex is the current position in the history; it + # gets incremented as you retrieve the previous command, + # decremented as you retrieve the next, and reset when you hit + # Enter. self.historyIndex == -1 means you're on the current + # command, not in the history. self.history = [] self.historyIndex = -1 # Assign handlers for keyboard events. - EVT_KEY_DOWN(self, self.OnKeyDown) - EVT_CHAR(self, self.OnChar) + wx.EVT_KEY_DOWN(self, self.OnKeyDown) + wx.EVT_CHAR(self, self.OnChar) # Assign handlers for wxSTC events. - EVT_STC_UPDATEUI(self, id, self.OnUpdateUI) + stc.EVT_STC_UPDATEUI(self, id, self.OnUpdateUI) + # Assign handler for idle time. + self.waiting = False + wx.EVT_IDLE(self, self.OnIdle) + dispatcher.connect(receiver=self.fontsizer, signal='FontIncrease') + dispatcher.connect(receiver=self.fontsizer, signal='FontDecrease') + dispatcher.connect(receiver=self.fontsizer, signal='FontDefault') # Configure various defaults and user preferences. self.config() # Display the introductory banner information. - try: self.showIntro(introText) - except: pass + self.showIntro(introText) # Assign some pseudo keywords to the interpreter's namespace. - try: self.setBuiltinKeywords() - except: pass + self.setBuiltinKeywords() # Add 'shell' to the interpreter's local namespace. - try: self.setLocalShell() - except: pass + self.setLocalShell() # Do this last so the user has complete control over their - # environment. They can override anything they want. - try: self.execStartupScript(self.interp.startupScript) - except: pass + # environment. They can override anything they want. + self.execStartupScript(self.interp.startupScript) + wx.wxCallAfter(self.ScrollToLine, 0) + + def fontsizer(self, signal): + """Receiver for Font* signals.""" + size = self.GetZoom() + if signal == 'FontIncrease': + size += 1 + elif signal == 'FontDecrease': + size -= 1 + elif signal == 'FontDefault': + size = 0 + self.SetZoom(size) def destroy(self): - # del self.interp + del self.interp pass def config(self): """Configure shell based on user preferences.""" - self.SetMarginType(1, wxSTC_MARGIN_NUMBER) + self.SetMarginType(1, stc.wxSTC_MARGIN_NUMBER) self.SetMarginWidth(1, 40) - self.SetLexer(wxSTC_LEX_PYTHON) + self.SetLexer(stc.wxSTC_LEX_PYTHON) self.SetKeyWords(0, ' '.join(keyword.kwlist)) self.setStyles(faces) @@ -229,30 +300,32 @@ class Shell(wxStyledTextCtrl): self.autoCompleteIncludeDouble = 1 self.autoCompleteCaseInsensitive = 1 self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive) + self.AutoCompSetAutoHide(False) + self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`') # Do we want to automatically pop up command argument help? self.autoCallTip = 1 - self.CallTipSetBackground(wxColour(255, 255, 232)) + self.CallTipSetBackground(wx.wxColour(255, 255, 232)) self.wrap() try: - self.SetEndAtLastLine(false) + self.SetEndAtLastLine(False) except AttributeError: pass def showIntro(self, text=''): """Display introductory text in the shell.""" if text: - if not text.endswith(os.linesep): text += os.linesep + if not text.endswith(os.linesep): + text += os.linesep self.write(text) try: self.write(self.interp.introText) except AttributeError: pass - wxCallAfter(self.ScrollToLine, 0) def setBuiltinKeywords(self): """Create pseudo keywords as part of builtins. - This simply sets "close", "exit" and "quit" to a helpful string. + This sets `close`, `exit` and `quit` to a helpful string. """ import __builtin__ __builtin__.close = __builtin__.exit = __builtin__.quit = \ @@ -263,10 +336,10 @@ class Shell(wxStyledTextCtrl): # XXX Good enough for now but later we want to send a close event. - # In the close event handler we can make sure they want to quit. - # Other applications, like PythonCard, may choose to hide rather than - # quit so we should just post the event and let the surrounding app - # decide what it wants to do. + # In the close event handler we can make sure they want to + # quit. Other applications, like PythonCard, may choose to + # hide rather than quit so we should just post the event and + # let the surrounding app decide what it wants to do. self.write('Click on the close button to leave the application.') def setLocalShell(self): @@ -276,9 +349,8 @@ class Shell(wxStyledTextCtrl): def execStartupScript(self, startupScript): """Execute the user's PYTHONSTARTUP script if they have one.""" if startupScript and os.path.isfile(startupScript): - startupText = 'Startup script executed: ' + startupScript - self.push('print %s;execfile(%s)' % \ - (`startupText`, `startupScript`)) + text = 'Startup script executed: ' + startupScript + self.push('print %r; execfile(%r)' % (text, startupScript)) else: self.push('') @@ -286,61 +358,95 @@ class Shell(wxStyledTextCtrl): """Configure font size, typeface and color for lexer.""" # Default style - self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d,back:%(backcol)s" % faces) + self.StyleSetSpec(stc.wxSTC_STYLE_DEFAULT, + "face:%(mono)s,size:%(size)d,back:%(backcol)s" % \ + faces) self.StyleClearAll() # Built in styles - self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces) - self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#0000FF,back:#FFFF88") - self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#FF0000,back:#FFFF88") + self.StyleSetSpec(stc.wxSTC_STYLE_LINENUMBER, + "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces) + self.StyleSetSpec(stc.wxSTC_STYLE_CONTROLCHAR, + "face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_STYLE_BRACELIGHT, + "fore:#0000FF,back:#FFFF88") + self.StyleSetSpec(stc.wxSTC_STYLE_BRACEBAD, + "fore:#FF0000,back:#FFFF88") # Python styles - self.StyleSetSpec(wxSTC_P_DEFAULT, "face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_NUMBER, "") - self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,face:%(mono)s" % faces) - self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold") - self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000") - self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#000033,back:#FFFFE8") - self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold") - self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold") - self.StyleSetSpec(wxSTC_P_OPERATOR, "") - self.StyleSetSpec(wxSTC_P_IDENTIFIER, "") - self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F") - self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces) - - def OnUpdateUI(self, evt): + self.StyleSetSpec(stc.wxSTC_P_DEFAULT, + "face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_COMMENTLINE, + "fore:#007F00,face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_NUMBER, + "") + self.StyleSetSpec(stc.wxSTC_P_STRING, + "fore:#7F007F,face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_CHARACTER, + "fore:#7F007F,face:%(mono)s" % faces) + self.StyleSetSpec(stc.wxSTC_P_WORD, + "fore:#00007F,bold") + self.StyleSetSpec(stc.wxSTC_P_TRIPLE, + "fore:#7F0000") + self.StyleSetSpec(stc.wxSTC_P_TRIPLEDOUBLE, + "fore:#000033,back:#FFFFE8") + self.StyleSetSpec(stc.wxSTC_P_CLASSNAME, + "fore:#0000FF,bold") + self.StyleSetSpec(stc.wxSTC_P_DEFNAME, + "fore:#007F7F,bold") + self.StyleSetSpec(stc.wxSTC_P_OPERATOR, + "") + self.StyleSetSpec(stc.wxSTC_P_IDENTIFIER, + "") + self.StyleSetSpec(stc.wxSTC_P_COMMENTBLOCK, + "fore:#7F7F7F") + self.StyleSetSpec(stc.wxSTC_P_STRINGEOL, + "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces) + + def about(self): + """Display information about PyCrust.""" + text = """ +Author: %r +PyCrust Version: %s +Shell Revision: %s +Interpreter Revision: %s +Python Version: %s +wxPython Version: %s +Platform: %s""" % \ + (__author__, VERSION, self.revision, self.interp.revision, + sys.version.split()[0], wx.__version__, sys.platform) + self.write(text.strip()) + + def OnIdle(self, event): + """Free the CPU to do other things.""" + if self.waiting: + time.sleep(0.05) + + def OnUpdateUI(self, event): """Check for matching braces.""" + # If the auto-complete window is up let it do its thing. + if self.AutoCompActive(): + return braceAtCaret = -1 braceOpposite = -1 charBefore = None caretPos = self.GetCurrentPos() if caretPos > 0: charBefore = self.GetCharAt(caretPos - 1) - #*** Patch to fix bug in wxSTC for wxPython < 2.3.3. - if charBefore < 0: - charBefore = 32 # Mimic a space. - #*** styleBefore = self.GetStyleAt(caretPos - 1) # Check before. if charBefore and chr(charBefore) in '[]{}()' \ - and styleBefore == wxSTC_P_OPERATOR: + and styleBefore == stc.wxSTC_P_OPERATOR: braceAtCaret = caretPos - 1 # Check after. if braceAtCaret < 0: charAfter = self.GetCharAt(caretPos) - #*** Patch to fix bug in wxSTC for wxPython < 2.3.3. - if charAfter < 0: - charAfter = 32 # Mimic a space. - #*** styleAfter = self.GetStyleAt(caretPos) if charAfter and chr(charAfter) in '[]{}()' \ - and styleAfter == wxSTC_P_OPERATOR: + and styleAfter == stc.wxSTC_P_OPERATOR: braceAtCaret = caretPos if braceAtCaret >= 0: @@ -353,36 +459,42 @@ class Shell(wxStyledTextCtrl): def OnChar(self, event): """Keypress event handler. + + Only receives an event if OnKeyDown calls event.Skip() for the + corresponding event.""" - Only receives an event if OnKeyDown calls event.Skip() for - the corresponding event.""" - - # Prevent modification of previously submitted commands/responses. + # Prevent modification of previously submitted + # commands/responses. if not self.CanEdit(): return key = event.KeyCode() currpos = self.GetCurrentPos() stoppos = self.promptPosEnd # Return (Enter) needs to be ignored in this handler. - if key == WXK_RETURN: + if key == wx.WXK_RETURN: pass elif key in self.autoCompleteKeys: # Usually the dot (period) key activates auto completion. - # Get the command between the prompt and the cursor. - # Add the autocomplete character to the end of the command. + # Get the command between the prompt and the cursor. Add + # the autocomplete character to the end of the command. + if self.AutoCompActive(): + self.AutoCompCancel() command = self.GetTextRange(stoppos, currpos) + chr(key) self.write(chr(key)) - if self.autoComplete: self.autoCompleteShow(command) + if self.autoComplete: + self.autoCompleteShow(command) elif key == ord('('): - # The left paren activates a call tip and cancels - # an active auto completion. - if self.AutoCompActive(): self.AutoCompCancel() - # Get the command between the prompt and the cursor. - # Add the '(' to the end of the command. + # The left paren activates a call tip and cancels an + # active auto completion. + if self.AutoCompActive(): + self.AutoCompCancel() + # Get the command between the prompt and the cursor. Add + # the '(' to the end of the command. self.ReplaceSelection('') command = self.GetTextRange(stoppos, currpos) + '(' self.write('(') - if self.autoCallTip: self.autoCallTipShow(command) + if self.autoCallTip: + self.autoCallTipShow(command) else: # Allow the normal event handling to take place. event.Skip() @@ -390,53 +502,69 @@ class Shell(wxStyledTextCtrl): def OnKeyDown(self, event): """Key down event handler.""" - # Prevent modification of previously submitted commands/responses. key = event.KeyCode() + # If the auto-complete window is up let it do its thing. + if self.AutoCompActive(): + event.Skip() + return + # Prevent modification of previously submitted + # commands/responses. controlDown = event.ControlDown() altDown = event.AltDown() shiftDown = event.ShiftDown() currpos = self.GetCurrentPos() endpos = self.GetTextLength() selecting = self.GetSelectionStart() != self.GetSelectionEnd() - # Return (Enter) is used to submit a command to the interpreter. - if not controlDown and key == WXK_RETURN: - if self.AutoCompActive(): self.AutoCompCancel() - if self.CallTipActive(): self.CallTipCancel() + # Return (Enter) is used to submit a command to the + # interpreter. + if not controlDown and key == wx.WXK_RETURN: + if self.CallTipActive(): + self.CallTipCancel() self.processLine() # Ctrl+Return (Cntrl+Enter) is used to insert a line break. - elif controlDown and key == WXK_RETURN: - if self.AutoCompActive(): self.AutoCompCancel() - if self.CallTipActive(): self.CallTipCancel() + elif controlDown and key == wx.WXK_RETURN: + if self.CallTipActive(): + self.CallTipCancel() if currpos == endpos: self.processLine() else: self.insertLineBreak() - # If the auto-complete window is up let it do its thing. - elif self.AutoCompActive(): - event.Skip() # Let Ctrl-Alt-* get handled normally. elif controlDown and altDown: event.Skip() # Clear the current, unexecuted command. - elif key == WXK_ESCAPE: + elif key == wx.WXK_ESCAPE: if self.CallTipActive(): event.Skip() else: self.clearCommand() + # Increase font size. + elif controlDown and key in (ord(']'),): + dispatcher.send(signal='FontIncrease') + # Decrease font size. + elif controlDown and key in (ord('['),): + dispatcher.send(signal='FontDecrease') + # Default font size. + elif controlDown and key in (ord('='),): + dispatcher.send(signal='FontDefault') # Cut to the clipboard. elif (controlDown and key in (ord('X'), ord('x'))) \ - or (shiftDown and key == WXK_DELETE): + or (shiftDown and key == wx.WXK_DELETE): self.Cut() # Copy to the clipboard. elif controlDown and not shiftDown \ - and key in (ord('C'), ord('c'), WXK_INSERT): + and key in (ord('C'), ord('c'), wx.WXK_INSERT): self.Copy() # Copy to the clipboard, including prompts. elif controlDown and shiftDown \ - and key in (ord('C'), ord('c'), WXK_INSERT): + and key in (ord('C'), ord('c'), wx.WXK_INSERT): self.CopyWithPrompts() + # Copy to the clipboard, including prefixed prompts. + elif altDown and not controlDown \ + and key in (ord('C'), ord('c'), wx.WXK_INSERT): + self.CopyWithPromptsPrefixed() # Home needs to be aware of the prompt. - elif key == WXK_HOME: + elif key == wx.WXK_HOME: home = self.promptPosEnd if currpos > home: self.SetCurrentPos(home) @@ -446,50 +574,48 @@ class Shell(wxStyledTextCtrl): else: event.Skip() # - # The following handlers modify text, so we need to see if there - # is a selection that includes text prior to the prompt. + # The following handlers modify text, so we need to see if + # there is a selection that includes text prior to the prompt. # # Don't modify a selection with text prior to the prompt. elif selecting and key not in NAVKEYS and not self.CanEdit(): pass # Paste from the clipboard. - elif (controlDown and not shiftDown \ - and key in (ord('V'), ord('v'))) \ - or (shiftDown and not controlDown and key == WXK_INSERT): + elif (controlDown and not shiftDown and key in (ord('V'), ord('v'))) \ + or (shiftDown and not controlDown and key == wx.WXK_INSERT): self.Paste() # Paste from the clipboard, run commands. - elif controlDown and shiftDown \ - and key in (ord('V'), ord('v')): + elif controlDown and shiftDown and key in (ord('V'), ord('v')): self.PasteAndRun() # Replace with the previous command from the history buffer. - elif (controlDown and key == WXK_UP) \ - or (altDown and key in (ord('P'), ord('p'))): + elif (controlDown and key == wx.WXK_UP) \ + or (altDown and key in (ord('P'), ord('p'))): self.OnHistoryReplace(step=+1) # Replace with the next command from the history buffer. - elif (controlDown and key == WXK_DOWN) \ - or (altDown and key in (ord('N'), ord('n'))): + elif (controlDown and key == wx.WXK_DOWN) \ + or (altDown and key in (ord('N'), ord('n'))): self.OnHistoryReplace(step=-1) # Insert the previous command from the history buffer. - elif (shiftDown and key == WXK_UP) and self.CanEdit(): + elif (shiftDown and key == wx.WXK_UP) and self.CanEdit(): self.OnHistoryInsert(step=+1) # Insert the next command from the history buffer. - elif (shiftDown and key == WXK_DOWN) and self.CanEdit(): + elif (shiftDown and key == wx.WXK_DOWN) and self.CanEdit(): self.OnHistoryInsert(step=-1) # Search up the history for the text in front of the cursor. - elif key == WXK_F8: + elif key == wx.WXK_F8: self.OnHistorySearch() # Don't backspace over the latest non-continuation prompt. - elif key == WXK_BACK: + elif key == wx.WXK_BACK: if selecting and self.CanEdit(): event.Skip() elif currpos > self.promptPosEnd: event.Skip() # Only allow these keys after the latest prompt. - elif key in (WXK_TAB, WXK_DELETE): + elif key in (wx.WXK_TAB, wx.WXK_DELETE): if self.CanEdit(): event.Skip() # Don't toggle between insert mode and overwrite mode. - elif key == WXK_INSERT: + elif key == wx.WXK_INSERT: pass # Don't allow line deletion. elif controlDown and key in (ord('L'), ord('l')): @@ -521,13 +647,14 @@ class Shell(wxStyledTextCtrl): def replaceFromHistory(self, step): """Replace selection with command from the history buffer.""" + ps2 = str(sys.ps2) self.ReplaceSelection('') newindex = self.historyIndex + step if -1 <= newindex <= len(self.history): self.historyIndex = newindex if 0 <= newindex <= len(self.history)-1: command = self.history[self.historyIndex] - command = command.replace('\n', os.linesep + sys.ps2) + command = command.replace('\n', os.linesep + ps2) self.ReplaceSelection(command) def OnHistoryInsert(self, step): @@ -551,8 +678,8 @@ class Shell(wxStyledTextCtrl): searchText = searchText[:-numCharsAfterCursor] if not searchText: return - # Search upwards from the current history position and loop back - # to the beginning if we don't find anything. + # Search upwards from the current history position and loop + # back to the beginning if we don't find anything. if (self.historyIndex <= -1) \ or (self.historyIndex >= len(self.history)-2): searchOrder = range(len(self.history)) @@ -562,7 +689,7 @@ class Shell(wxStyledTextCtrl): for i in searchOrder: command = self.history[i] if command[:len(searchText)] == searchText: - # Replace the current selection with the one we've found. + # Replace the current selection with the one we found. self.ReplaceSelection(command[len(searchText):]) endpos = self.GetCurrentPos() self.SetSelection(endpos, startpos) @@ -573,8 +700,8 @@ class Shell(wxStyledTextCtrl): def setStatusText(self, text): """Display status information.""" - # This method will most likely be replaced by the enclosing app - # to do something more interesting, like write to a status bar. + # This method will likely be replaced by the enclosing app to + # do something more interesting, like write to a status bar. print text def insertLineBreak(self): @@ -587,24 +714,27 @@ class Shell(wxStyledTextCtrl): def processLine(self): """Process the line of text at which the user hit Enter.""" - # The user hit ENTER and we need to decide what to do. They could be - # sitting on any line in the shell. + # The user hit ENTER and we need to decide what to do. They + # could be sitting on any line in the shell. - thepos = self.GetCurrentPos() + thepos = self.GetCurrentPos() startpos = self.promptPosEnd endpos = self.GetTextLength() - # If they hit RETURN inside the current command, execute the command. + ps2 = str(sys.ps2) + # If they hit RETURN inside the current command, execute the + # command. if self.CanEdit(): self.SetCurrentPos(endpos) self.interp.more = 0 command = self.GetTextRange(startpos, endpos) - lines = command.split(os.linesep + sys.ps2) + lines = command.split(os.linesep + ps2) lines = [line.rstrip() for line in lines] command = '\n'.join(lines) if self.reader.isreading: if not command: - # Match the behavior of the standard Python shell when - # the user hits return without entering a value. + # Match the behavior of the standard Python shell + # when the user hits return without entering a + # value. command = '\n' self.reader.input = command self.write(os.linesep) @@ -626,8 +756,8 @@ class Shell(wxStyledTextCtrl): """Extract a multi-line command from the editor. The command may not necessarily be valid Python syntax.""" - # XXX Need to extract real prompts here. Need to keep track of the - # prompt every time a command is issued. + # XXX Need to extract real prompts here. Need to keep track of + # the prompt every time a command is issued. ps1 = str(sys.ps1) ps1size = len(ps1) ps2 = str(sys.ps2) @@ -650,9 +780,9 @@ class Shell(wxStyledTextCtrl): self.GotoLine(line) stoppos = self.GetCurrentPos() command = self.GetTextRange(startpos, stoppos) - command = command.replace(os.linesep + sys.ps2, '\n') + command = command.replace(os.linesep + ps2, '\n') command = command.rstrip() - command = command.replace('\n', os.linesep + sys.ps2) + command = command.replace('\n', os.linesep + ps2) else: command = '' if rstrip: @@ -665,7 +795,7 @@ class Shell(wxStyledTextCtrl): The command may not necessarily be valid Python syntax.""" if not text: text = self.GetCurLine()[0] - # Strip the prompt off the front of text leaving just the command. + # Strip the prompt off the front leaving just the command. command = self.lstripPrompt(text) if command == text: command = '' # Real commands have prompts. @@ -685,12 +815,14 @@ class Shell(wxStyledTextCtrl): elif text[:ps2size] == ps2: text = text[ps2size:] return text - + def push(self, command): """Send command to the interpreter for execution.""" self.write(os.linesep) - busy = wxBusyCursor() + busy = wx.wxBusyCursor() + self.waiting = True self.more = self.interp.push(command) + self.waiting = False del busy if not self.more: self.addHistory(command.rstrip()) @@ -726,7 +858,7 @@ class Shell(wxStyledTextCtrl): return text def prompt(self): - """Display appropriate prompt for the context, either ps1, ps2 or ps3. + """Display proper prompt for the context: ps1, ps2 or ps3. If this is a continuation line, autoindent as necessary.""" isreading = self.reader.isreading @@ -765,13 +897,21 @@ class Shell(wxStyledTextCtrl): self.prompt() try: while not reader.input: - wxYield() + wx.wxYieldIfNeeded() input = reader.input finally: reader.input = '' reader.isreading = 0 + input = str(input) # In case of Unicode. return input + def readlines(self): + """Replacement for stdin.readlines().""" + lines = [] + while lines[-1:] != ['\n']: + lines.append(self.readline()) + return lines + def raw_input(self, prompt=''): """Return string based on user input.""" if prompt: @@ -780,10 +920,10 @@ class Shell(wxStyledTextCtrl): def ask(self, prompt='Please enter your response:'): """Get response from the user using a dialog box.""" - dialog = wxTextEntryDialog(None, prompt, \ - 'Input Dialog (Raw)', '') + dialog = wx.wxTextEntryDialog(None, prompt, + 'Input Dialog (Raw)', '') try: - if dialog.ShowModal() == wxID_OK: + if dialog.ShowModal() == wx.wxID_OK: text = dialog.GetValue() return text finally: @@ -799,27 +939,29 @@ class Shell(wxStyledTextCtrl): self.ClearAll() def run(self, command, prompt=1, verbose=1): - """Execute command within the shell as if it was typed in directly. + """Execute command as if it was typed in directly. >>> shell.run('print "this"') >>> print "this" this - >>> + >>> """ # Go to the very bottom of the text. endpos = self.GetTextLength() - self.SetCurrentPos(endpos) + self.SetCurrentPos(endpos) command = command.rstrip() if prompt: self.prompt() if verbose: self.write(command) self.push(command) def runfile(self, filename): - """Execute all commands in file as if they were typed into the shell.""" + """Execute all commands in file as if they were typed into the + shell.""" file = open(filename) try: self.prompt() for command in file.readlines(): - if command[:6] == 'shell.': # Run shell methods silently. + if command[:6] == 'shell.': + # Run shell methods silently. self.run(command, prompt=0, verbose=0) else: self.run(command, prompt=0, verbose=1) @@ -828,18 +970,19 @@ class Shell(wxStyledTextCtrl): def autoCompleteShow(self, command): """Display auto-completion popup list.""" - list = self.interp.getAutoCompleteList(command, - includeMagic=self.autoCompleteIncludeMagic, - includeSingle=self.autoCompleteIncludeSingle, + list = self.interp.getAutoCompleteList(command, + includeMagic=self.autoCompleteIncludeMagic, + includeSingle=self.autoCompleteIncludeSingle, includeDouble=self.autoCompleteIncludeDouble) - if list: + if list and len(list) < 2000: options = ' '.join(list) offset = 0 self.AutoCompShow(offset, options) def autoCallTipShow(self, command): - """Display argument spec and docstring in a popup bubble thingie.""" - if self.CallTipActive: self.CallTipCancel() + """Display argument spec and docstring in a popup window.""" + if self.CallTipActive(): + self.CallTipCancel() (name, argspec, tip) = self.interp.getCallTip(command) if argspec: startpos = self.GetCurrentPos() @@ -850,8 +993,10 @@ class Shell(wxStyledTextCtrl): curpos = self.GetCurrentPos() tippos = curpos - (len(name) + 1) fallback = curpos - self.GetColumn(curpos) - # In case there isn't enough room, only go back to the fallback. + # In case there isn't enough room, only go back to the + # fallback. tippos = max(tippos, fallback) + dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip) self.CallTipShow(tippos, tip) def writeOut(self, text): @@ -886,8 +1031,8 @@ class Shell(wxStyledTextCtrl): def CanCut(self): """Return true if text is selected and can be cut.""" if self.GetSelectionStart() != self.GetSelectionEnd() \ - and self.GetSelectionStart() >= self.promptPosEnd \ - and self.GetSelectionEnd() >= self.promptPosEnd: + and self.GetSelectionStart() >= self.promptPosEnd \ + and self.GetSelectionEnd() >= self.promptPosEnd: return 1 else: return 0 @@ -898,7 +1043,7 @@ class Shell(wxStyledTextCtrl): def CanPaste(self): """Return true if a paste should succeed.""" - if self.CanEdit() and wxStyledTextCtrl.CanPaste(self): + if self.CanEdit() and stc.wxStyledTextCtrl.CanPaste(self): return 1 else: return 0 @@ -907,7 +1052,7 @@ class Shell(wxStyledTextCtrl): """Return true if editing should succeed.""" if self.GetSelectionStart() != self.GetSelectionEnd(): if self.GetSelectionStart() >= self.promptPosEnd \ - and self.GetSelectionEnd() >= self.promptPosEnd: + and self.GetSelectionEnd() >= self.promptPosEnd: return 1 else: return 0 @@ -917,71 +1062,97 @@ class Shell(wxStyledTextCtrl): def Cut(self): """Remove selection and place it on the clipboard.""" if self.CanCut() and self.CanCopy(): - if self.AutoCompActive(): self.AutoCompCancel() - if self.CallTipActive: self.CallTipCancel() + if self.AutoCompActive(): + self.AutoCompCancel() + if self.CallTipActive(): + self.CallTipCancel() self.Copy() self.ReplaceSelection('') def Copy(self): """Copy selection and place it on the clipboard.""" if self.CanCopy(): + ps1 = str(sys.ps1) + ps2 = str(sys.ps2) command = self.GetSelectedText() - command = command.replace(os.linesep + sys.ps2, os.linesep) - command = command.replace(os.linesep + sys.ps1, os.linesep) + command = command.replace(os.linesep + ps2, os.linesep) + command = command.replace(os.linesep + ps1, os.linesep) command = self.lstripPrompt(text=command) - data = wxTextDataObject(command) - if wxTheClipboard.Open(): - wxTheClipboard.SetData(data) - wxTheClipboard.Close() + data = wx.wxTextDataObject(command) + self._clip(data) def CopyWithPrompts(self): """Copy selection, including prompts, and place it on the clipboard.""" if self.CanCopy(): command = self.GetSelectedText() - data = wxTextDataObject(command) - if wxTheClipboard.Open(): - wxTheClipboard.SetData(data) - wxTheClipboard.Close() + data = wx.wxTextDataObject(command) + self._clip(data) + + def CopyWithPromptsPrefixed(self): + """Copy selection, including prompts prefixed with four + spaces, and place it on the clipboard.""" + if self.CanCopy(): + command = self.GetSelectedText() + spaces = ' ' * 4 + command = spaces + command.replace(os.linesep, + os.linesep + spaces) + data = wx.wxTextDataObject(command) + self._clip(data) + + def _clip(self, data): + if wx.wxTheClipboard.Open(): + wx.wxTheClipboard.UsePrimarySelection(False) + wx.wxTheClipboard.SetData(data) + wx.wxTheClipboard.Flush() + wx.wxTheClipboard.Close() def Paste(self): """Replace selection with clipboard contents.""" - if self.CanPaste() and wxTheClipboard.Open(): - if wxTheClipboard.IsSupported(wxDataFormat(wxDF_TEXT)): - data = wxTextDataObject() - if wxTheClipboard.GetData(data): + if self.CanPaste() and wx.wxTheClipboard.Open(): + ps2 = str(sys.ps2) + if wx.wxTheClipboard.IsSupported(wx.wxDataFormat(wx.wxDF_TEXT)): + data = wx.wxTextDataObject() + if wx.wxTheClipboard.GetData(data): self.ReplaceSelection('') command = data.GetText() command = command.rstrip() command = self.fixLineEndings(command) command = self.lstripPrompt(text=command) - command = command.replace(os.linesep + sys.ps2, '\n') + command = command.replace(os.linesep + ps2, '\n') command = command.replace(os.linesep, '\n') - command = command.replace('\n', os.linesep + sys.ps2) + command = command.replace('\n', os.linesep + ps2) self.write(command) - wxTheClipboard.Close() + wx.wxTheClipboard.Close() def PasteAndRun(self): """Replace selection with clipboard contents, run commands.""" - if wxTheClipboard.Open(): - if wxTheClipboard.IsSupported(wxDataFormat(wxDF_TEXT)): - data = wxTextDataObject() - if wxTheClipboard.GetData(data): + if wx.wxTheClipboard.Open(): + ps1 = str(sys.ps1) + ps2 = str(sys.ps2) + if wx.wxTheClipboard.IsSupported(wx.wxDataFormat(wx.wxDF_TEXT)): + data = wx.wxTextDataObject() + if wx.wxTheClipboard.GetData(data): endpos = self.GetTextLength() self.SetCurrentPos(endpos) startpos = self.promptPosEnd self.SetSelection(startpos, endpos) self.ReplaceSelection('') text = data.GetText() - text = text.strip() + text = text.lstrip() text = self.fixLineEndings(text) - text = self.lstripPrompt(text=text) - text = text.replace(os.linesep + sys.ps1, '\n') - text = text.replace(os.linesep + sys.ps2, '\n') + text = self.lstripPrompt(text) + text = text.replace(os.linesep + ps1, '\n') + text = text.replace(os.linesep + ps2, '\n') text = text.replace(os.linesep, '\n') lines = text.split('\n') commands = [] command = '' for line in lines: + if line.strip() == ps2.strip(): + # If we are pasting from something like a + # web page that drops the trailing space + # from the ps2 prompt of a blank line. + line = '' if line.strip() != '' and line.lstrip() == line: # New command. if command: @@ -994,11 +1165,11 @@ class Shell(wxStyledTextCtrl): command += '\n' command += line commands.append(command) - for command in commands: - command = command.replace('\n', os.linesep + sys.ps2) + for command in commands: + command = command.replace('\n', os.linesep + ps2) self.write(command) self.processLine() - wxTheClipboard.Close() + wx.wxTheClipboard.Close() def wrap(self, wrap=1): """Sets whether text is word wrapped.""" @@ -1009,214 +1180,8 @@ class Shell(wxStyledTextCtrl): def zoom(self, points=0): """Set the zoom level. - - This number of points is added to the size of all fonts. - It may be positive to magnify or negative to reduce.""" + + This number of points is added to the size of all fonts. It + may be positive to magnify or negative to reduce.""" self.SetZoom(points) - -wxID_SELECTALL = NewId() # This *should* be defined by wxPython. -ID_AUTOCOMP = NewId() -ID_AUTOCOMP_SHOW = NewId() -ID_AUTOCOMP_INCLUDE_MAGIC = NewId() -ID_AUTOCOMP_INCLUDE_SINGLE = NewId() -ID_AUTOCOMP_INCLUDE_DOUBLE = NewId() -ID_CALLTIPS = NewId() -ID_CALLTIPS_SHOW = NewId() - - -class ShellMenu: - """Mixin class to add standard menu items.""" - - def createMenus(self): - m = self.fileMenu = wxMenu() - m.AppendSeparator() - m.Append(wxID_EXIT, 'E&xit', 'Exit PyCrust') - - m = self.editMenu = wxMenu() - m.Append(wxID_UNDO, '&Undo \tCtrl+Z', 'Undo the last action') - m.Append(wxID_REDO, '&Redo \tCtrl+Y', 'Redo the last undone action') - m.AppendSeparator() - m.Append(wxID_CUT, 'Cu&t \tCtrl+X', 'Cut the selection') - m.Append(wxID_COPY, '&Copy \tCtrl+C', 'Copy the selection') - m.Append(wxID_PASTE, '&Paste \tCtrl+V', 'Paste') - m.AppendSeparator() - m.Append(wxID_CLEAR, 'Cle&ar', 'Delete the selection') - m.Append(wxID_SELECTALL, 'Select A&ll', 'Select all text') - - m = self.autocompMenu = wxMenu() - m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', \ - 'Show auto completion during dot syntax', 1) - m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', \ - 'Include attributes visible to __getattr__ and __setattr__', 1) - m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', \ - 'Include attibutes prefixed by a single underscore', 1) - m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', \ - 'Include attibutes prefixed by a double underscore', 1) - - m = self.calltipsMenu = wxMenu() - m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', \ - 'Show call tips with argument specifications', 1) - - m = self.optionsMenu = wxMenu() - m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, \ - 'Auto Completion Options') - m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, \ - 'Call Tip Options') - - m = self.helpMenu = wxMenu() - m.AppendSeparator() - m.Append(wxID_ABOUT, '&About...', 'About PyCrust') - - b = self.menuBar = wxMenuBar() - b.Append(self.fileMenu, '&File') - b.Append(self.editMenu, '&Edit') - b.Append(self.optionsMenu, '&Options') - b.Append(self.helpMenu, '&Help') - self.SetMenuBar(b) - - EVT_MENU(self, wxID_EXIT, self.OnExit) - EVT_MENU(self, wxID_UNDO, self.OnUndo) - EVT_MENU(self, wxID_REDO, self.OnRedo) - EVT_MENU(self, wxID_CUT, self.OnCut) - EVT_MENU(self, wxID_COPY, self.OnCopy) - EVT_MENU(self, wxID_PASTE, self.OnPaste) - EVT_MENU(self, wxID_CLEAR, self.OnClear) - EVT_MENU(self, wxID_SELECTALL, self.OnSelectAll) - EVT_MENU(self, wxID_ABOUT, self.OnAbout) - EVT_MENU(self, ID_AUTOCOMP_SHOW, \ - self.OnAutoCompleteShow) - EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, \ - self.OnAutoCompleteIncludeMagic) - EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, \ - self.OnAutoCompleteIncludeSingle) - EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, \ - self.OnAutoCompleteIncludeDouble) - EVT_MENU(self, ID_CALLTIPS_SHOW, \ - self.OnCallTipsShow) - - EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateMenu) - EVT_UPDATE_UI(self, wxID_CLEAR, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu) - EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu) - - def OnExit(self, event): - self.Close(true) - - def OnUndo(self, event): - self.shell.Undo() - - def OnRedo(self, event): - self.shell.Redo() - - def OnCut(self, event): - self.shell.Cut() - - def OnCopy(self, event): - self.shell.Copy() - - def OnPaste(self, event): - self.shell.Paste() - - def OnClear(self, event): - self.shell.Clear() - - def OnSelectAll(self, event): - self.shell.SelectAll() - - def OnAbout(self, event): - """Display an About PyCrust window.""" - import sys - title = 'About PyCrust' - text = 'PyCrust %s\n\n' % VERSION + \ - 'Yet another Python shell, only flakier.\n\n' + \ - 'Half-baked by Patrick K. O\'Brien,\n' + \ - 'the other half is still in the oven.\n\n' + \ - 'Shell Revision: %s\n' % self.shell.revision + \ - 'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \ - 'Python Version: %s\n' % sys.version.split()[0] + \ - 'wxPython Version: %s\n' % wx.__version__ + \ - 'Platform: %s\n' % sys.platform - dialog = wxMessageDialog(self, text, title, wxOK | wxICON_INFORMATION) - dialog.ShowModal() - dialog.Destroy() - - def OnAutoCompleteShow(self, event): - self.shell.autoComplete = event.IsChecked() - - def OnAutoCompleteIncludeMagic(self, event): - self.shell.autoCompleteIncludeMagic = event.IsChecked() - - def OnAutoCompleteIncludeSingle(self, event): - self.shell.autoCompleteIncludeSingle = event.IsChecked() - - def OnAutoCompleteIncludeDouble(self, event): - self.shell.autoCompleteIncludeDouble = event.IsChecked() - - def OnCallTipsShow(self, event): - self.shell.autoCallTip = event.IsChecked() - - def OnUpdateMenu(self, event): - """Update menu items based on current status.""" - id = event.GetId() - if id == wxID_UNDO: - event.Enable(self.shell.CanUndo()) - elif id == wxID_REDO: - event.Enable(self.shell.CanRedo()) - elif id == wxID_CUT: - event.Enable(self.shell.CanCut()) - elif id == wxID_COPY: - event.Enable(self.shell.CanCopy()) - elif id == wxID_PASTE: - event.Enable(self.shell.CanPaste()) - elif id == wxID_CLEAR: - event.Enable(self.shell.CanCut()) - elif id == ID_AUTOCOMP_SHOW: - event.Check(self.shell.autoComplete) - elif id == ID_AUTOCOMP_INCLUDE_MAGIC: - event.Check(self.shell.autoCompleteIncludeMagic) - elif id == ID_AUTOCOMP_INCLUDE_SINGLE: - event.Check(self.shell.autoCompleteIncludeSingle) - elif id == ID_AUTOCOMP_INCLUDE_DOUBLE: - event.Check(self.shell.autoCompleteIncludeDouble) - elif id == ID_CALLTIPS_SHOW: - event.Check(self.shell.autoCallTip) - - -class ShellFrame(wxFrame, ShellMenu): - """Frame containing the PyCrust shell component.""" - - name = 'PyCrust Shell Frame' - revision = __revision__ - - def __init__(self, parent=None, id=-1, title='PyShell', \ - pos=wxDefaultPosition, size=wxDefaultSize, \ - style=wxDEFAULT_FRAME_STYLE, locals=None, \ - InterpClass=None, *args, **kwds): - """Create a PyCrust ShellFrame instance.""" - wxFrame.__init__(self, parent, id, title, pos, size, style) - intro = 'Welcome To PyCrust %s - The Flakiest Python Shell' % VERSION - intro += '\nSponsored by Orbtech - Your source for Python programming expertise.' - self.CreateStatusBar() - self.SetStatusText(intro.replace('\n', ', ')) - import images - self.SetIcon(images.getPyCrustIcon()) - self.shell = Shell(parent=self, id=-1, introText=intro, \ - locals=locals, InterpClass=InterpClass, \ - *args, **kwds) - # Override the shell so that status messages go to the status bar. - self.shell.setStatusText = self.SetStatusText - self.createMenus() - EVT_CLOSE(self, self.OnCloseWindow) - - def OnCloseWindow(self, event): - self.shell.destroy() - self.Destroy() - diff --git a/wxPython/wxPython/lib/PyCrust/shellmenu.py b/wxPython/wxPython/lib/PyCrust/shellmenu.py new file mode 100644 index 0000000000..1e3175a1f7 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/shellmenu.py @@ -0,0 +1,226 @@ +"""Shell menu mixin shared by shell and crust.""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + +from wxPython import wx +import sys +from version import VERSION + +try: + True +except NameError: + True = 1==1 + False = 1==0 + +ID_AUTOCOMP = wx.wxNewId() +ID_AUTOCOMP_SHOW = wx.wxNewId() +ID_AUTOCOMP_INCLUDE_MAGIC = wx.wxNewId() +ID_AUTOCOMP_INCLUDE_SINGLE = wx.wxNewId() +ID_AUTOCOMP_INCLUDE_DOUBLE = wx.wxNewId() +ID_CALLTIPS = wx.wxNewId() +ID_CALLTIPS_SHOW = wx.wxNewId() +ID_COPY_PLUS = wx.wxNewId() +ID_PASTE_PLUS = wx.wxNewId() +ID_WRAP = wx.wxNewId() + + +class ShellMenu: + """Mixin class to add standard menu items.""" + + def createMenus(self): + m = self.fileMenu = wx.wxMenu() + m.AppendSeparator() + m.Append(wx.wxID_EXIT, 'E&xit', 'Exit PyCrust') + + m = self.editMenu = wx.wxMenu() + m.Append(wx.wxID_UNDO, '&Undo \tCtrl+Z', + 'Undo the last action') + m.Append(wx.wxID_REDO, '&Redo \tCtrl+Y', + 'Redo the last undone action') + m.AppendSeparator() + m.Append(wx.wxID_CUT, 'Cu&t \tCtrl+X', + 'Cut the selection') + m.Append(wx.wxID_COPY, '&Copy \tCtrl+C', + 'Copy the selection - removing prompts') + m.Append(ID_COPY_PLUS, 'Cop&y Plus \tCtrl+Shift+C', + 'Copy the selection - retaining prompts') + m.Append(wx.wxID_PASTE, '&Paste \tCtrl+V', 'Paste') + m.Append(ID_PASTE_PLUS, 'Past&e Plus \tCtrl+Shift+V', + 'Paste and run commands') + m.AppendSeparator() + m.Append(wx.wxID_CLEAR, 'Cle&ar', + 'Delete the selection') + m.Append(wx.wxID_SELECTALL, 'Select A&ll \tCtrl+A', + 'Select all text') + + m = self.autocompMenu = wx.wxMenu() + m.Append(ID_AUTOCOMP_SHOW, 'Show Auto Completion', + 'Show auto completion during dot syntax', 1) + m.Append(ID_AUTOCOMP_INCLUDE_MAGIC, 'Include Magic Attributes', + 'Include attributes visible to __getattr__ and __setattr__', + 1) + m.Append(ID_AUTOCOMP_INCLUDE_SINGLE, 'Include Single Underscores', + 'Include attibutes prefixed by a single underscore', 1) + m.Append(ID_AUTOCOMP_INCLUDE_DOUBLE, 'Include Double Underscores', + 'Include attibutes prefixed by a double underscore', 1) + + m = self.calltipsMenu = wx.wxMenu() + m.Append(ID_CALLTIPS_SHOW, 'Show Call Tips', + 'Show call tips with argument specifications', 1) + + m = self.optionsMenu = wx.wxMenu() + m.AppendMenu(ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, + 'Auto Completion Options') + m.AppendMenu(ID_CALLTIPS, '&Call Tips', self.calltipsMenu, + 'Call Tip Options') + m.Append(ID_WRAP, '&Wrap Lines', + 'Wrap lines at right edge', 1) + + m = self.helpMenu = wx.wxMenu() + m.AppendSeparator() + m.Append(wx.wxID_ABOUT, '&About...', 'About PyCrust') + + b = self.menuBar = wx.wxMenuBar() + b.Append(self.fileMenu, '&File') + b.Append(self.editMenu, '&Edit') + b.Append(self.optionsMenu, '&Options') + b.Append(self.helpMenu, '&Help') + self.SetMenuBar(b) + + wx.EVT_MENU(self, wx.wxID_EXIT, self.OnExit) + wx.EVT_MENU(self, wx.wxID_UNDO, self.OnUndo) + wx.EVT_MENU(self, wx.wxID_REDO, self.OnRedo) + wx.EVT_MENU(self, wx.wxID_CUT, self.OnCut) + wx.EVT_MENU(self, wx.wxID_COPY, self.OnCopy) + wx.EVT_MENU(self, ID_COPY_PLUS, self.OnCopyPlus) + wx.EVT_MENU(self, wx.wxID_PASTE, self.OnPaste) + wx.EVT_MENU(self, ID_PASTE_PLUS, self.OnPastePlus) + wx.EVT_MENU(self, wx.wxID_CLEAR, self.OnClear) + wx.EVT_MENU(self, wx.wxID_SELECTALL, self.OnSelectAll) + wx.EVT_MENU(self, wx.wxID_ABOUT, self.OnAbout) + wx.EVT_MENU(self, ID_AUTOCOMP_SHOW, + self.OnAutoCompleteShow) + wx.EVT_MENU(self, ID_AUTOCOMP_INCLUDE_MAGIC, + self.OnAutoCompleteIncludeMagic) + wx.EVT_MENU(self, ID_AUTOCOMP_INCLUDE_SINGLE, + self.OnAutoCompleteIncludeSingle) + wx.EVT_MENU(self, ID_AUTOCOMP_INCLUDE_DOUBLE, + self.OnAutoCompleteIncludeDouble) + wx.EVT_MENU(self, ID_CALLTIPS_SHOW, + self.OnCallTipsShow) + wx.EVT_MENU(self, ID_WRAP, self.OnWrap) + + wx.EVT_UPDATE_UI(self, wx.wxID_UNDO, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, wx.wxID_REDO, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, wx.wxID_CUT, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, wx.wxID_COPY, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_COPY_PLUS, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, wx.wxID_PASTE, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_PASTE_PLUS, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, wx.wxID_CLEAR, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_SHOW, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_MAGIC, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_SINGLE, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_AUTOCOMP_INCLUDE_DOUBLE, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_CALLTIPS_SHOW, self.OnUpdateMenu) + wx.EVT_UPDATE_UI(self, ID_WRAP, self.OnUpdateMenu) + + def OnExit(self, event): + self.Close(True) + + def OnUndo(self, event): + self.shell.Undo() + + def OnRedo(self, event): + self.shell.Redo() + + def OnCut(self, event): + self.shell.Cut() + + def OnCopy(self, event): + self.shell.Copy() + + def OnCopyPlus(self, event): + self.shell.CopyWithPrompts() + + def OnPaste(self, event): + self.shell.Paste() + + def OnPastePlus(self, event): + self.shell.PasteAndRun() + + def OnClear(self, event): + self.shell.Clear() + + def OnSelectAll(self, event): + self.shell.SelectAll() + + def OnAbout(self, event): + """Display an About PyCrust window.""" + title = 'About PyCrust' + text = 'PyCrust %s\n\n' % VERSION + \ + 'Yet another Python shell, only flakier.\n\n' + \ + 'Half-baked by Patrick K. O\'Brien,\n' + \ + 'the other half is still in the oven.\n\n' + \ + 'Shell Revision: %s\n' % self.shell.revision + \ + 'Interpreter Revision: %s\n\n' % self.shell.interp.revision + \ + 'Python Version: %s\n' % sys.version.split()[0] + \ + 'wxPython Version: %s\n' % wx.__version__ + \ + 'Platform: %s\n' % sys.platform + dialog = wx.wxMessageDialog(self, text, title, + wx.wxOK | wx.wxICON_INFORMATION) + dialog.ShowModal() + dialog.Destroy() + + def OnAutoCompleteShow(self, event): + self.shell.autoComplete = event.IsChecked() + + def OnAutoCompleteIncludeMagic(self, event): + self.shell.autoCompleteIncludeMagic = event.IsChecked() + + def OnAutoCompleteIncludeSingle(self, event): + self.shell.autoCompleteIncludeSingle = event.IsChecked() + + def OnAutoCompleteIncludeDouble(self, event): + self.shell.autoCompleteIncludeDouble = event.IsChecked() + + def OnCallTipsShow(self, event): + self.shell.autoCallTip = event.IsChecked() + + def OnWrap(self, event): + self.shell.SetWrapMode(event.IsChecked()) + + def OnUpdateMenu(self, event): + """Update menu items based on current status.""" + id = event.GetId() + if id == wx.wxID_UNDO: + event.Enable(self.shell.CanUndo()) + elif id == wx.wxID_REDO: + event.Enable(self.shell.CanRedo()) + elif id == wx.wxID_CUT: + event.Enable(self.shell.CanCut()) + elif id == wx.wxID_COPY: + event.Enable(self.shell.CanCopy()) + elif id == ID_COPY_PLUS: + event.Enable(self.shell.CanCopy()) + elif id == wx.wxID_PASTE: + event.Enable(self.shell.CanPaste()) + elif id == ID_PASTE_PLUS: + event.Enable(self.shell.CanPaste()) + elif id == wx.wxID_CLEAR: + event.Enable(self.shell.CanCut()) + elif id == ID_AUTOCOMP_SHOW: + event.Check(self.shell.autoComplete) + elif id == ID_AUTOCOMP_INCLUDE_MAGIC: + event.Check(self.shell.autoCompleteIncludeMagic) + elif id == ID_AUTOCOMP_INCLUDE_SINGLE: + event.Check(self.shell.autoCompleteIncludeSingle) + elif id == ID_AUTOCOMP_INCLUDE_DOUBLE: + event.Check(self.shell.autoCompleteIncludeDouble) + elif id == ID_CALLTIPS_SHOW: + event.Check(self.shell.autoCallTip) + elif id == ID_WRAP: + event.Check(self.shell.GetWrapMode()) + diff --git a/wxPython/wxPython/lib/PyCrust/version.py b/wxPython/wxPython/lib/PyCrust/version.py index ef2b9d7b80..3950c4a402 100644 --- a/wxPython/wxPython/lib/PyCrust/version.py +++ b/wxPython/wxPython/lib/PyCrust/version.py @@ -1,10 +1,11 @@ -"""Provides an object representing the current "version" or "release" of -PyCrust as a whole. Individual classes, such as the shell, filling and -interpreter, each have a revision property based on the CVS Revision.""" +"""Provides an object representing the current 'version' or 'release' +of PyCrust as a whole. Individual classes, such as the shell, filling +and interpreter, each have a revision property based on the CVS +Revision.""" __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" __cvsid__ = "$Id$" __revision__ = "$Revision$"[11:-2] -VERSION = '0.7.2' +VERSION = '0.9' diff --git a/wxPython/wxPython/lib/PyCrust/wrap.py b/wxPython/wxPython/lib/PyCrust/wrap.py new file mode 100644 index 0000000000..cdfbfee359 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wrap.py @@ -0,0 +1,56 @@ + +"""Wrap is a command line utility that runs a wxPython program with +additional runtime-tools, such as PyCrust.""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + +import os +import sys +from wxPython import wx +from crust import CrustFrame as Frame + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +def wrap(app): + wx.wxInitAllImageHandlers() + frame = Frame() + frame.SetSize((750, 525)) + frame.Show(True) + frame.shell.interp.locals['app'] = app + app.MainLoop() + + +def main(argv): + if len(argv) < 2: + print "Please specify a module name." + raise SystemExit + name = argv[1] + if name[-3:] == '.py': + name = name[:-3] + module = __import__(name) + # Find the App class. + App = None + d = module.__dict__ + for item in d.keys(): + try: + if issubclass(d[item], wx.wxApp): + App = d[item] + except (NameError, TypeError): + pass + if App is None: + print "No App class found." + raise SystemExit + app = App() + wrap(app) + + +if __name__ == '__main__': + sys.path.insert(0, os.curdir) + main(sys.argv) diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Accelerators.py b/wxPython/wxPython/lib/PyCrust/wxd/Accelerators.py new file mode 100644 index 0000000000..2ab1469239 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Accelerators.py @@ -0,0 +1,58 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class AcceleratorEntry: + """""" + + def __init__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def GetCommand(self): + """""" + pass + + def GetFlags(self): + """""" + pass + + def GetKeyCode(self): + """""" + pass + + def Set(self): + """""" + pass + + +class AcceleratorTable(Object): + """""" + + def __init__(self): + """""" + pass + + def __del__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/App.py b/wxPython/wxPython/lib/PyCrust/wxd/App.py new file mode 100644 index 0000000000..8da71fecf6 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/App.py @@ -0,0 +1,358 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import EvtHandler +import Parameters as wx + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class PyApp(EvtHandler): + """Python Application base class. + + It is used to: + + - set and get application-wide properties; + + - implement the windowing system message or event loop; + + - initiate application processing via App.OnInit; + + - allow default processing of events not handled by other objects + in the application.""" + + def __init__(self): + """Create a PyApp instance.""" + pass + + def Dispatch(self): + """Dispatches the next event in the windowing system event + queue. + + This can be used for programming event loops.""" + pass + + def ExitMainLoop(self): + """Call this to explicitly exit the main message (event) loop. + + You should normally exit the main loop (and the application) + by deleting the top window, which wxPython does automatically.""" + pass + + def GetAppName(self): + """Return the application name.""" + pass + + def GetAssertMode(self): + """Return the current assertion mode.""" + pass + + def GetAuto3D(self): + """Returns True if 3D control mode is on, False otherwise. + Windows only.""" + pass + + def GetClassName(self): + """Return the class name of the application.""" + pass + + def GetExitOnFrameDelete(self): + """Returns True if the application will exit when the + top-level window is deleted, False otherwise.""" + pass + + def GetPrintMode(self): + """Deprecated.""" + pass + + def GetTopWindow(self): + """Return the top window. + + If the top window hasn't been set using App.SetTopWindow, + this method will find the first top-level window (frame or + dialog) and return that.""" + pass + + def GetUseBestVisual(self): + """Return True if the application will use the best visual on + systems that support different visuals, False otherwise.""" + pass + + def GetVendorName(self): + """Return the application's vendor name.""" + pass + + def Initialized(self): + """Return True if the application has been initialized + (i.e. if App.OnInit has returned successfully). This can be + useful for error message routines to determine which method of + output is best for the current state of the program (some + windowing systems may not like dialogs to pop up before the + main loop has been entered).""" + pass + + def MainLoop(self): + """Called by wxWindows on creation of the application. + Override this if you wish to provide your own + (environment-dependent) main loop. + + Return 0 under X, and the wParam of the WM_QUIT message under + Windows.""" + pass + + def OnAssert(self, file, line, cond, msg): + """Called when an assert failure occurs, i.e. the condition + specified in ASSERT macro evaluated to FALSE. It is only + called in debug mode (when __WXDEBUG__ is defined) as asserts + are not left in the release code at all. + + The base class version show the default assert failure dialog + box proposing to the user to stop the program, continue or + ignore all subsequent asserts. + + file is the name of the source file where the assert occured + + line is the line number in this file where the assert occured + + cond is the condition of the failed assert in string form + + msg is the message specified as argument to ASSERT_MSG or + FAIL_MSG, will be NULL if just ASSERT or FAIL was used""" + pass + + def OnExit(self): + """Provide this member function for any processing which needs + to be done as the application is about to exit. OnExit is + called after destroying all application windows and controls, + but before wxWindows cleanup.""" + pass + + def OnInit(self): + """This must be provided by the application, and will usually + create the application's main window, optionally calling + App.SetTopWindow. + + Return True to continue processing, False to exit the + application.""" + pass + + def OnInitGui(self): + """Called just after the platform's GUI has been initialized, + but before the App.OnInit() gets called. Rarely needed in + practice. Unlike App.OnInit(), does not need to return + True/False.""" + pass + + def Pending(self): + """Return True if unprocessed events are in the window system + event queue.""" + pass + + def ProcessIdle(self): + """Sends the EVT_IDLE event and is called inside the MainLoop. + + You only need this if you implement your own main loop.""" + pass + + def SetAppName(self, name): + """Set the name of the application.""" + pass + + def SetAssertMode(self, mode): + """Lets you control how C++ assertions are processed. + + Valid modes are: PYAPP_ASSERT_SUPPRESS, + PYAPP_ASSERT_EXCEPTION, and PYAPP_ASSERT_DIALOG. Using + _SUPPRESS will give you behavior like the old final builds and + the assert will be ignored, _EXCEPTION is the new default + described above, and _DIALOG is like the default in 2.3.3.1 + and prior hybrid builds. You can also combine _EXCEPTION and + _DIALOG if you wish, although I don't know why you would.""" + pass + + def SetAuto3D(self, auto3D): + """Switches automatic 3D controls on or off. Windows only. + + If auto3D is True, all controls will be created with 3D + appearances unless overridden for a control or dialog. The + default is True.""" + pass + + def SetClassName(self, name): + """Set the class name of the application.""" + pass + + def SetExitOnFrameDelete(self, flag): + """If flag is True (the default), the application will exit + when the top-level frame is deleted. If False, the + application will continue to run.""" + pass + + def SetPrintMode(self, mode): + """Deprecated.""" + pass + + def SetTopWindow(self, window): + """Set the 'top' window. + + You can call this from within App.OnInit to let wxWindows + know which is the main window. You don't have to set the top + window; it is only a convenience so that (for example) certain + dialogs without parents can use a specific window as the top + window. If no top window is specified by the application, + wxWindows just uses the first frame or dialog in its top-level + window list, when it needs to use the top window.""" + pass + + def SetUseBestVisual(self, flag): + """Allows the programmer to specify whether the application + will use the best visual on systems that support several + visual on the same display. This is typically the case under + Solaris and IRIX, where the default visual is only 8-bit + whereas certain applications are supposed to run in TrueColour + mode. + + Note that this function has to be called in the constructor of + the App instance and won't have any effect when called later + on. + + This function currently only has effect under GTK.""" + pass + + def SetVendorName(self, name): + """Sets the name of application's vendor. The name will be + used in registry access.""" + pass + + def Yield(self, onlyIfNeeded=False): + """Yields control to pending messages in the windowing system. + This can be useful, for example, when a time-consuming process + writes to a text window. Without an occasional yield, the + text window will not be updated properly, and on systems with + cooperative multitasking, such as Windows 3.1 other processes + will not respond. + + Caution should be exercised, however, since yielding may allow + the user to perform actions which are not compatible with the + current task. Disabling menu items or whole menus during + processing can avoid unwanted reentrance of code: see + wx.SafeYield for a better function. + + Calling Yield() recursively is normally an error and an assert + failure is raised in debug build if such situation is + detected. However if the the onlyIfNeeded parameter is True, + the method will just silently return False instead.""" + pass + + +from wxPython.wx import wxPlatform +_redirect = (wxPlatform == '__WXMSW__' or wxPlatform == '__WXMAC__') +del wxPlatform + + +class App(PyApp): + """The main application class. + + Inherit from this class and implement an OnInit method that + creates a frame and then calls self.SetTopWindow(frame).""" + + def __init__(self, redirect=_redirect, filename=None, useBestVisual=False): + """Create an App instance. + + redirect defaults to True on Windows and Mac. If redirect is + True, stdio goes to an output window or a file if filename is + not None.""" + pass + + +del _redirect + + +class PyOnDemandOutputWindow: + """Used by App to display stdout and stderr messages if app is + created using App(redirect=True). Mostly useful on Windows or + Mac where apps aren't always launched from the command line.""" + pass + + +class PySimpleApp(App): + """Use instead of App for simple apps with a simple frame or + dialog, particularly for testing.""" + + def __init__(self, flag=0): + """Create a PySimpleApp instance. + + flag is the same as App's redirect parameter to redirect stdio.""" + pass + + def OnInit(self): + """Automatically does a wx.InitAllImageHandlers().""" + pass + + +class PyWidgetTester(App): + """Use instead of App for testing widgets. Provides a frame + containing an instance of a widget. + + Create a PyWidgetTester instance with the desired size for the + frame, then create the widget and show the frame using SetWidget.""" + + def __init__(self, size=(250, 100)): + """Create a PyWidgetTester instance, with no stdio redirection. + + size is for the frame to hold the widget.""" + pass + + def OnInit(self): + """Creates a frame that will hold the widget to be tested.""" + pass + + def SetWidget(self, widgetClass, *args): + """Create a widgetClass instance using the supplied args and + with a frame as parent, then show the frame.""" + pass + + +class SingleInstanceChecker: + """Allows one to check that only a single instance of a program is + running. To do it, you should create an object of this class. As + long as this object is alive, calls to IsAnotherRunning() from + other processes will return True. + + As the object should have the life span as big as possible, it + makes sense to create it either as a global or in App.OnInit().""" + + def __init__(self, name, path=wx.EmptyString): + """Create a SingleInstanceChecker instance. + + name should be as unique as possible. It is used as the mutex + name under Win32 and the lock file name under Unix. + App.GetAppName() and wx.GetUserId() are commonly used. + + path is optional and is ignored under Win32 and used as the + directory to create the lock file in under Unix (default is + wx.GetHomeDir()).""" + pass + + def Create(self, name, path=wx.EmptyString): + """Create a SingleInstanceChecker instance.""" + pass + + def IsAnotherRunning(self): + """Return True if another copy of this program is already running.""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Base.py b/wxPython/wxPython/lib/PyCrust/wxd/Base.py new file mode 100644 index 0000000000..fd5c706bbb --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Base.py @@ -0,0 +1,206 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +class Object: + """Base class for all other wxPython classes.""" + + def __init__(self): + """Create a Object instance.""" + pass + + def Destroy(self): + """Destroy the Object instance.""" + pass + + def GetClassName(self): + """Return the name of the class.""" + pass + + +class EvtHandler(Object): + """Base class that can handle events from the windowing system. + + If the handler is part of a chain, the destructor will unlink + itself and restore the previous and next handlers so that they + point to each other.""" + + def __init__(self): + """Create a EvtHandler instance.""" + pass + + def AddPendingEvent(self, event): + """Post an event to be processed later. + + event is an Event instance to add to process queue. + + The difference between sending an event (using the + ProcessEvent method) and posting it is that in the first case + the event is processed before the function returns, while in + the second case, the function returns immediately and the + event will be processed sometime later (usually during the + next event loop iteration). + + A copy of event is made by the function, so the original can + be deleted as soon as function returns (it is common that the + original is created on the stack). This requires that the + Event::Clone method be implemented by event so that it can + be duplicated and stored until it gets processed. + + This is also the method to call for inter-thread + communication. It will post events safely between different + threads which means that this method is thread-safe by using + critical sections where needed. In a multi-threaded program, + you often need to inform the main GUI thread about the status + of other working threads and such notification should be done + using this method. + + This method automatically wakes up idle handling if the + underlying window system is currently idle and thus would not + send any idle events. (Waking up idle handling is done + calling WakeUpIdle.)""" + pass + + def Connect(self, id, lastId, eventType, func): + """Connects the given function dynamically with the event + handler, id and event type. This is an alternative to the use + of static event tables. + + id is the identifier (or first of the identifier range) to be + associated with the event handler function. + + lastId is the second part of the identifier range to be + associated with the event handler function. + + eventType is the event type to be associated with this event + handler. + + function is the event handler function. + + userData is data to be associated with the event table entry.""" + pass + + def Disconnect(self, id, lastId=-1, eventType=wx.EVT_NULL): + """Disconnects the given function dynamically from the event + handler, using the specified parameters as search criteria and + returning True if a matching function has been found and + removed. This method can only disconnect functions which have + been added using the EvtHandler.Connect method. There is no + way to disconnect functions connected using the (static) event + tables. + + id is the identifier (or first of the identifier range) to be + associated with the event handler function. + + lastId is the second part of the identifier range to be + associated with the event handler function. + + eventType is the event type to be associated with this event + handler. + + function is the event handler function. + + userData is data to be associated with the event table entry.""" + pass + + def GetEvtHandlerEnabled(self): + """Return True if the event handler is enabled, False + otherwise.""" + pass + + def GetNextHandler(self): + """Return the next handler in the chain.""" + pass + + def GetPreviousHandler(self): + """Return the previous handler in the chain.""" + pass + + def ProcessEvent(self, event): + """Processes an event, searching event tables and calling zero + or more suitable event handler function(s). Return True if a + suitable event handler function was found and executed, and + the function did not call Event.Skip(). + + event is an Event to process. + + Normally, your application would not call this function: it is + called in the wxPython implementation to dispatch incoming + user interface events to the framework (and application). + + However, you might need to call it if implementing new + functionality (such as a new control) where you define new + event types, as opposed to allowing the user to override + virtual functions. + + An instance where you might actually override the ProcessEvent + function is where you want to direct event processing to event + handlers not normally noticed by wxWindows. For example, in + the document/view architecture, documents and views are + potential event handlers. When an event reaches a frame, + ProcessEvent will need to be called on the associated document + and view in case event handler functions are associated with + these objects. The property classes library (Property) also + overrides ProcessEvent for similar reasons. + + The normal order of event table searching is as follows: + + 1. If the object is disabled (via a call to + EvtHandler.SetEvtHandlerEnabled) the function skips to step + (6). + + 2. If the object is a Window, ProcessEvent is recursively + called on the window's Validator. If this returns TRUE, the + function exits. + + 3. SearchEventTable is called for this event handler. If this + fails, the base class table is tried, and so on until no more + tables exist or an appropriate function was found, in which + case the function exits. + + 4. The search is applied down the entire chain of event + handlers (usually the chain has a length of one). If this + succeeds, the function exits. + + 5. If the object is a Window and the event is a + CommandEvent, ProcessEvent is recursively applied to the + parent window's event handler. If this returns TRUE, the + function exits. + + 6. Finally, ProcessEvent is called on the App object. + + See also: + + EvtHandler::SearchEventTable""" + pass + + def SetEvtHandlerEnabled(self, enabled): + """Enable or disable the event handler. + + You can use this function to avoid having to remove the event + handler from the chain, for example when implementing a dialog + editor and changing from edit to test mode.""" + pass + + def SetNextHandler(self, handler): + """Set the pointer to the next handler.""" + pass + + def SetPreviousHandler(self, handler): + """Set the pointer to the previous handler.""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/ClipDragDrop.py b/wxPython/wxPython/lib/PyCrust/wxd/ClipDragDrop.py new file mode 100644 index 0000000000..cae61264a2 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/ClipDragDrop.py @@ -0,0 +1,485 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class Clipboard(Object): + """""" + + def AddData(self): + """""" + pass + + def Clear(self): + """""" + pass + + def Close(self): + """""" + pass + + def Flush(self): + """""" + pass + + def GetData(self): + """""" + pass + + def IsOpened(self): + """""" + pass + + def IsSupported(self): + """""" + pass + + def Open(self): + """""" + pass + + def SetData(self): + """""" + pass + + def UsePrimarySelection(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DataFormat: + """""" + + def GetId(self): + """""" + pass + + def GetType(self): + """""" + pass + + def SetId(self): + """""" + pass + + def SetType(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DataObject: + """""" + + def GetAllFormats(self): + """""" + pass + + def GetDataHere(self): + """""" + pass + + def GetDataSize(self): + """""" + pass + + def GetFormatCount(self): + """""" + pass + + def GetPreferredFormat(self): + """""" + pass + + def IsSupportedFormat(self): + """""" + pass + + def SetData(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DataObjectComposite(DataObject): + """""" + + def Add(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DataObjectSimple(DataObject): + """""" + + def GetFormat(self): + """""" + pass + + def SetFormat(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PyDataObjectSimple(DataObjectSimple): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class BitmapDataObject(DataObjectSimple): + """""" + + def GetBitmap(self): + """""" + pass + + def SetBitmap(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PyBitmapDataObject(BitmapDataObject): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class CustomDataObject(DataObjectSimple): + """""" + + def GetData(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def SetData(self): + """""" + pass + + def TakeData(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DragImage(Object): + """""" + + def BeginDrag(self): + """""" + pass + + def BeginDrag2(self): + """""" + pass + + def EndDrag(self): + """""" + pass + + def GetImageRect(self): + """""" + pass + + def Hide(self): + """""" + pass + + def Move(self): + """""" + pass + + def RedrawImage(self): + """""" + pass + + def SetBackingBitmap(self): + """""" + pass + + def Show(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DropSource: + """""" + + def DoDragDrop(self): + """""" + pass + + def GetDataObject(self): + """""" + pass + + def SetCursor(self): + """""" + pass + + def SetData(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_GiveFeedback(self): + """""" + pass + + +class DropTarget: + """""" + + def __init__(self): + """""" + pass + + +class PyDropTarget(DropTarget): + """""" + + def GetData(self): + """""" + pass + + def GetDataObject(self): + """""" + pass + + def SetDataObject(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_OnDragOver(self): + """""" + pass + + def base_OnDrop(self): + """""" + pass + + def base_OnEnter(self): + """""" + pass + + def base_OnLeave(self): + """""" + pass + + +class FileDataObject(DataObjectSimple): + """""" + + def GetFilenames(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FileDropTarget(PyDropTarget): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_OnData(self): + """""" + pass + + def base_OnDragOver(self): + """""" + pass + + def base_OnDrop(self): + """""" + pass + + def base_OnEnter(self): + """""" + pass + + def base_OnLeave(self): + """""" + pass + + +class TextDataObject(DataObjectSimple): + """""" + + def GetText(self): + """""" + pass + + def GetTextLength(self): + """""" + pass + + def SetText(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PyTextDataObject(TextDataObject): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class TextDropTarget(PyDropTarget): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_OnData(self): + """""" + pass + + def base_OnDragOver(self): + """""" + pass + + def base_OnDrop(self): + """""" + pass + + def base_OnEnter(self): + """""" + pass + + def base_OnLeave(self): + """""" + pass + + +class URLDataObject(DataObjectComposite): + """""" + + def GetURL(self): + """""" + pass + + def SetURL(self): + """""" + pass + + def __init__(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Config.py b/wxPython/wxPython/lib/PyCrust/wxd/Config.py new file mode 100644 index 0000000000..1ef8602f05 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Config.py @@ -0,0 +1,199 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +class ConfigBase: + """""" + + def DeleteAll(self): + """""" + pass + + def DeleteEntry(self): + """""" + pass + + def DeleteGroup(self): + """""" + pass + + def Exists(self): + """""" + pass + + def ExpandEnvVars(self): + """""" + pass + + def Flush(self): + """""" + pass + + def GetAppName(self): + """""" + pass + + def GetEntryType(self): + """""" + pass + + def GetFirstEntry(self): + """""" + pass + + def GetFirstGroup(self): + """""" + pass + + def GetNextEntry(self): + """""" + pass + + def GetNextGroup(self): + """""" + pass + + def GetNumberOfEntries(self): + """""" + pass + + def GetNumberOfGroups(self): + """""" + pass + + def GetPath(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetVendorName(self): + """""" + pass + + def HasEntry(self): + """""" + pass + + def HasGroup(self): + """""" + pass + + def IsExpandingEnvVars(self): + """""" + pass + + def IsRecordingDefaults(self): + """""" + pass + + def Read(self): + """""" + pass + + def ReadBool(self): + """""" + pass + + def ReadFloat(self): + """""" + pass + + def ReadInt(self): + """""" + pass + + def RenameEntry(self): + """""" + pass + + def RenameGroup(self): + """""" + pass + + def SetAppName(self): + """""" + pass + + def SetExpandEnvVars(self): + """""" + pass + + def SetPath(self): + """""" + pass + + def SetRecordDefaults(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def SetVendorName(self): + """""" + pass + + def Write(self): + """""" + pass + + def WriteBool(self): + """""" + pass + + def WriteFloat(self): + """""" + pass + + def WriteInt(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Config(ConfigBase): + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FileConfig(ConfigBase): + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Controls.py b/wxPython/wxPython/lib/PyCrust/wxd/Controls.py new file mode 100644 index 0000000000..1d1fad0210 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Controls.py @@ -0,0 +1,1846 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx +from Window import Window + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class Control(Window): + """Base class for a control or 'widget'. + + A control is generally a small window which processes user input + and/or displays one or more item of data.""" + + def __init__(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, + validator=wx.DefaultValidator, name='control'): + """Create a Control instance.""" + pass + + def Command(self, event): + """Simulates the effect of the user issuing a command to the + item. See CommandEvent.""" + pass + + def Create(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, + validator=wx.DefaultValidator, name='control'): + """Create a Control instance.""" + pass + + def GetLabel(self): + """Return the string label for the control.""" + pass + + def SetLabel(self, label): + """Set the string label for the control.""" + pass + + +class PyControl(Control): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_AcceptsFocus(self): + """""" + pass + + def base_AcceptsFocusFromKeyboard(self): + """""" + pass + + def base_AddChild(self): + """""" + pass + + def base_DoGetBestSize(self): + """""" + pass + + def base_DoGetClientSize(self): + """""" + pass + + def base_DoGetPosition(self): + """""" + pass + + def base_DoGetSize(self): + """""" + pass + + def base_DoGetVirtualSize(self): + """""" + pass + + def base_DoMoveWindow(self): + """""" + pass + + def base_DoSetClientSize(self): + """""" + pass + + def base_DoSetSize(self): + """""" + pass + + def base_DoSetVirtualSize(self): + """""" + pass + + def base_GetMaxSize(self): + """""" + pass + + def base_InitDialog(self): + """""" + pass + + def base_RemoveChild(self): + """""" + pass + + def base_TransferDataFromWindow(self): + """""" + pass + + def base_TransferDataToWindow(self): + """""" + pass + + def base_Validate(self): + """""" + pass + + +class ControlWithItems(Control): + """""" + + def Append(self): + """""" + pass + + def AppendItems(self): + """""" + pass + + def Delete(self): + """""" + pass + + def FindString(self): + """""" + pass + + def GetClientData(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def GetSelection(self): + """""" + pass + + def GetString(self): + """""" + pass + + def GetStringSelection(self): + """""" + pass + + def Number(self): + """""" + pass + + def Select(self): + """""" + pass + + def SetClientData(self): + """""" + pass + + def SetString(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Button(Control): + """A button is a control that contains a text string, and is one + of the most common elements of a GUI. It may be placed on a + dialog box or panel, or indeed almost any other window. + + Styles + ------ + + BU_LEFT: Left-justifies the label. WIN32 only. + + BU_TOP: Aligns the label to the top of the button. WIN32 only. + + BU_RIGHT: Right-justifies the bitmap label. WIN32 only. + + BU_BOTTOM: Aligns the label to the bottom of the button. WIN32 + only. + + BU_EXACTFIT: Creates the button as small as possible instead of + making it of the standard size (which is the default behaviour.) + + Events + ------ + + EVT_BUTTON(win,id,func): Sent when the button is clicked.""" + + def __init__(self, parent, id, label, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, + validator=wx.DefaultValidator, name='button'): + """Create and show a button. + + parent: Parent window. Must not be None. + id: Button identifier. A value of -1 indicates a default value. + label: The text to be displayed on the button. + pos: The button position on it's parent. + size: Button size. If the default size (-1, -1) is specified + then the button is sized appropriately for the text. + style: Window style. See Button. + validator: Window validator. + name: Window name.""" + pass + + def Create(self, parent, id, label, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, + validator=wx.DefaultValidator, name='button'): + """Create and show a button.""" + pass + + def SetBackgroundColour(self): + """""" + pass + + def SetDefault(self): + """Set the button to be the default item for the panel or + dialog box. + + Under Windows, only dialog box buttons respond to this + function. As normal under Windows and Motif, pressing return + causes the default button to be depressed when the return key + is pressed. See also Window.SetFocus which sets the keyboard + focus for windows and text panel items, and + Panel.SetDefaultItem.""" + pass + + def SetForegroundColour(self): + """""" + pass + + +class BitmapButton(Button): + """""" + + def Create(self): + """""" + pass + + def GetBitmapDisabled(self): + """""" + pass + + def GetBitmapFocus(self): + """""" + pass + + def GetBitmapLabel(self): + """""" + pass + + def GetBitmapSelected(self): + """""" + pass + + def GetMarginX(self): + """""" + pass + + def GetMarginY(self): + """""" + pass + + def SetBitmapDisabled(self): + """""" + pass + + def SetBitmapFocus(self): + """""" + pass + + def SetBitmapLabel(self): + """""" + pass + + def SetBitmapSelected(self): + """""" + pass + + def SetMargins(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class CheckBox(Control): + """""" + + def __init__(self): + """""" + pass + + def Create(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def IsChecked(self): + """""" + pass + + def SetValue(self): + """""" + pass + + +class Choice(ControlWithItems): + """""" + + def __init__(self): + """""" + pass + + def Clear(self): + """""" + pass + + def Create(self): + """""" + pass + + def GetColumns(self): + """""" + pass + + def Select(self): + """""" + pass + + def SetColumns(self): + """""" + pass + + def SetSelection(self): + """""" + pass + + def SetString(self): + """""" + pass + + def SetStringSelection(self): + """""" + pass + + +class Gauge(Control): + """""" + + def Create(self): + """""" + pass + + def GetBezelFace(self): + """""" + pass + + def GetRange(self): + """""" + pass + + def GetShadowWidth(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def SetBezelFace(self): + """""" + pass + + def SetRange(self): + """""" + pass + + def SetShadowWidth(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class GenericDirCtrl(Control): + """""" + + def Create(self): + """""" + pass + + def ExpandPath(self): + """""" + pass + + def GetDefaultPath(self): + """""" + pass + + def GetFilePath(self): + """""" + pass + + def GetFilter(self): + """""" + pass + + def GetFilterIndex(self): + """""" + pass + + def GetFilterListCtrl(self): + """""" + pass + + def GetPath(self): + """""" + pass + + def GetRootId(self): + """""" + pass + + def GetShowHidden(self): + """""" + pass + + def GetTreeCtrl(self): + """""" + pass + + def SetDefaultPath(self): + """""" + pass + + def SetFilter(self): + """""" + pass + + def SetFilterIndex(self): + """""" + pass + + def SetPath(self): + """""" + pass + + def ShowHidden(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ListBox(ControlWithItems): + """""" + + def Clear(self): + """""" + pass + + def Create(self): + """""" + pass + + def Deselect(self): + """""" + pass + + def GetSelections(self): + """""" + pass + + def InsertItems(self): + """""" + pass + + def IsSelected(self): + """""" + pass + + def Selected(self): + """""" + pass + + def Set(self): + """""" + pass + + def SetFirstItem(self): + """""" + pass + + def SetFirstItemStr(self): + """""" + pass + + def SetSelection(self): + """""" + pass + + def SetString(self): + """""" + pass + + def SetStringSelection(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class CheckListBox(ListBox): + """""" + + def __init__(self): + """""" + pass + + def Check(self): + """""" + pass + + def Create(self): + """""" + pass + + def GetItemHeight(self): + """""" + pass + + def HitTest(self): + """""" + pass + + def HitTestXY(self): + """""" + pass + + def InsertItems(self): + """""" + pass + + def IsChecked(self): + """""" + pass + + +class ListCtrl(Control): + """""" + + def Append(self): + """""" + pass + + def Arrange(self): + """""" + pass + + def AssignImageList(self): + """""" + pass + + def ClearAll(self): + """""" + pass + + def ClearColumnImage(self): + """""" + pass + + def Create(self): + """""" + pass + + def DeleteAllColumns(self): + """""" + pass + + def DeleteAllItems(self): + """""" + pass + + def DeleteColumn(self): + """""" + pass + + def DeleteItem(self): + """""" + pass + + def EnsureVisible(self): + """""" + pass + + def FindItem(self): + """""" + pass + + def FindItemAtPos(self): + """""" + pass + + def FindItemData(self): + """""" + pass + + def Focus(self): + """""" + pass + + def GetColumn(self): + """""" + pass + + def GetColumnCount(self): + """""" + pass + + def GetColumnWidth(self): + """""" + pass + + def GetCountPerPage(self): + """""" + pass + + def GetFirstSelected(self): + """""" + pass + + def GetFocusedItem(self): + """""" + pass + + def GetImageList(self): + """""" + pass + + def GetItem(self): + """""" + pass + + def GetItemBackgroundColour(self): + """""" + pass + + def GetItemCount(self): + """""" + pass + + def GetItemData(self): + """""" + pass + + def GetItemPosition(self): + """""" + pass + + def GetItemRect(self): + """""" + pass + + def GetItemSpacing(self): + """""" + pass + + def GetItemState(self): + """""" + pass + + def GetItemText(self): + """""" + pass + + def GetItemTextColour(self): + """""" + pass + + def GetMainWindow(self): + """""" + pass + + def GetNextItem(self): + """""" + pass + + def GetNextSelected(self): + """""" + pass + + def GetSelectedItemCount(self): + """""" + pass + + def GetTextColour(self): + """""" + pass + + def GetTopItem(self): + """""" + pass + + def HitTest(self): + """""" + pass + + def InsertColumn(self): + """""" + pass + + def InsertColumnInfo(self): + """""" + pass + + def InsertImageItem(self): + """""" + pass + + def InsertImageStringItem(self): + """""" + pass + + def InsertItem(self): + """""" + pass + + def InsertStringItem(self): + """""" + pass + + def IsSelected(self): + """""" + pass + + def IsVirtual(self): + """""" + pass + + def RefreshItem(self): + """""" + pass + + def RefreshItems(self): + """""" + pass + + def ScrollList(self): + """""" + pass + + def Select(self): + """""" + pass + + def SetBackgroundColour(self): + """""" + pass + + def SetColumn(self): + """""" + pass + + def SetColumnImage(self): + """""" + pass + + def SetColumnWidth(self): + """""" + pass + + def SetForegroundColour(self): + """""" + pass + + def SetImageList(self): + """""" + pass + + def SetItem(self): + """""" + pass + + def SetItemBackgroundColour(self): + """""" + pass + + def SetItemCount(self): + """""" + pass + + def SetItemData(self): + """""" + pass + + def SetItemImage(self): + """""" + pass + + def SetItemPosition(self): + """""" + pass + + def SetItemState(self): + """""" + pass + + def SetItemText(self): + """""" + pass + + def SetItemTextColour(self): + """""" + pass + + def SetSingleStyle(self): + """""" + pass + + def SetStringItem(self): + """""" + pass + + def SetTextColour(self): + """""" + pass + + def SetWindowStyleFlag(self): + """""" + pass + + def SortItems(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class ListItem(Object): + """""" + + def Clear(self): + """""" + pass + + def ClearAttributes(self): + """""" + pass + + def GetAlign(self): + """""" + pass + + def GetAttributes(self): + """""" + pass + + def GetBackgroundColour(self): + """""" + pass + + def GetColumn(self): + """""" + pass + + def GetData(self): + """""" + pass + + def GetFont(self): + """""" + pass + + def GetId(self): + """""" + pass + + def GetImage(self): + """""" + pass + + def GetMask(self): + """""" + pass + + def GetState(self): + """""" + pass + + def GetText(self): + """""" + pass + + def GetTextColour(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def HasAttributes(self): + """""" + pass + + def SetAlign(self): + """""" + pass + + def SetBackgroundColour(self): + """""" + pass + + def SetColumn(self): + """""" + pass + + def SetData(self): + """""" + pass + + def SetFont(self): + """""" + pass + + def SetId(self): + """""" + pass + + def SetImage(self): + """""" + pass + + def SetMask(self): + """""" + pass + + def SetState(self): + """""" + pass + + def SetStateMask(self): + """""" + pass + + def SetText(self): + """""" + pass + + def SetTextColour(self): + """""" + pass + + def SetWidth(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class ListItemAttr: + """""" + + def GetBackgroundColour(self): + """""" + pass + + def GetFont(self): + """""" + pass + + def GetTextColour(self): + """""" + pass + + def HasBackgroundColour(self): + """""" + pass + + def HasFont(self): + """""" + pass + + def HasTextColour(self): + """""" + pass + + def SetBackgroundColour(self): + """""" + pass + + def SetFont(self): + """""" + pass + + def SetTextColour(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ListView(ListCtrl): + """""" + + def ClearColumnImage(self): + """""" + pass + + def Create(self): + """""" + pass + + def Focus(self): + """""" + pass + + def GetFirstSelected(self): + """""" + pass + + def GetFocusedItem(self): + """""" + pass + + def GetNextSelected(self): + """""" + pass + + def IsSelected(self): + """""" + pass + + def Select(self): + """""" + pass + + def SetColumnImage(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Notebook(Control): + + def __init__(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, name=wx.PyNOTEBOOK_NAME): + """""" + pass + + def AddPage(self, pPage, strText, bSelect=False, imageId=-1): + """""" + pass + + def AdvanceSelection(self, bForward=True): + """""" + pass + + def AssignImageList(self, imageList) : + """""" + pass + + def Create(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, name=wx.PyNOTEBOOK_NAME): + """""" + pass + + def DeleteAllPages(self): + """""" + pass + + def DeletePage(self, nPage): + """""" + pass + + def GetImageList(self): + """""" + pass + + def GetPage(self, nPage): + """""" + pass + + def GetPageCount(self): + """""" + pass + + def GetPageImage(self, nPage): + """""" + pass + + def GetPageText(self, nPage): + """""" + pass + + def GetRowCount(self): + """""" + pass + + def GetSelection(self): + """""" + pass + + def InsertPage(self, nPage, pPage, strText, bSelect=False, imageId=-1): + """""" + pass + + def RemovePage(self, nPage): + """""" + pass + + def ResizeChildren(self): + """""" + pass + + def SetImageList(self, imageList): + """""" + pass + + def SetPadding(self, padding): + """""" + pass + + def SetPageImage(self, nPage, nImage): + """""" + pass + + def SetPageSize(self, size): + """""" + pass + + def SetPageText(self, nPage, strText): + """""" + pass + + def SetSelection(self, nPage): + """""" + pass + + +class RadioBox(Control): + """""" + + def Create(self): + """""" + pass + + def Enable(self): + """""" + pass + + def EnableItem(self): + """""" + pass + + def FindString(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def GetItemLabel(self): + """""" + pass + + def GetSelection(self): + """""" + pass + + def GetString(self): + """""" + pass + + def GetStringSelection(self): + """""" + pass + + def Number(self): + """""" + pass + + def SetItemLabel(self): + """""" + pass + + def SetSelection(self): + """""" + pass + + def SetStringSelection(self): + """""" + pass + + def Show(self): + """""" + pass + + def ShowItem(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class RadioButton(Control): + """""" + + def Create(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ScrollBar(Control): + """""" + + def Create(self): + """""" + pass + + def GetPageSize(self): + """""" + pass + + def GetRange(self): + """""" + pass + + def GetThumbLength(self): + """""" + pass + + def GetThumbPosition(self): + """""" + pass + + def GetThumbSize(self): + """""" + pass + + def IsVertical(self): + """""" + pass + + def SetScrollbar(self): + """""" + pass + + def SetThumbPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Slider(Control): + """""" + + def ClearSel(self): + """""" + pass + + def ClearTicks(self): + """""" + pass + + def Create(self): + """""" + pass + + def GetLineSize(self): + """""" + pass + + def GetMax(self): + """""" + pass + + def GetMin(self): + """""" + pass + + def GetPageSize(self): + """""" + pass + + def GetSelEnd(self): + """""" + pass + + def GetSelStart(self): + """""" + pass + + def GetThumbLength(self): + """""" + pass + + def GetTickFreq(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def SetLineSize(self): + """""" + pass + + def SetPageSize(self): + """""" + pass + + def SetRange(self): + """""" + pass + + def SetSelection(self): + """""" + pass + + def SetThumbLength(self): + """""" + pass + + def SetTick(self): + """""" + pass + + def SetTickFreq(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SpinButton(Control): + """""" + + def Create(self): + """""" + pass + + def GetMax(self): + """""" + pass + + def GetMin(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def SetRange(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SpinCtrl(SpinButton): + """""" + + def Create(self): + """""" + pass + + def GetMax(self): + """""" + pass + + def GetMin(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def SetRange(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class StaticBitmap(Control): + """""" + + def Create(self): + """""" + pass + + def GetBitmap(self): + """""" + pass + + def SetBitmap(self): + """""" + pass + + def SetIcon(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class StaticBox(Control): + """""" + + def Create(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class StaticLine(Control): + """""" + + def Create(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class StaticText(Control): + """""" + + def Create(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def SetLabel(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TextAttr: + """""" + + def GetBackgroundColour(self): + """""" + pass + + def GetFont(self): + """""" + pass + + def GetTextColour(self): + """""" + pass + + def HasBackgroundColour(self): + """""" + pass + + def HasFont(self): + """""" + pass + + def HasTextColour(self): + """""" + pass + + def IsDefault(self): + """""" + pass + + def SetBackgroundColour(self): + """""" + pass + + def SetFont(self): + """""" + pass + + def SetTextColour(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TextCtrl(Control): + """""" + + def AppendText(self): + """""" + pass + + def CanCopy(self): + """""" + pass + + def CanCut(self): + """""" + pass + + def CanPaste(self): + """""" + pass + + def CanRedo(self): + """""" + pass + + def CanUndo(self): + """""" + pass + + def Clear(self): + """""" + pass + + def Copy(self): + """""" + pass + + def Create(self): + """""" + pass + + def Cut(self): + """""" + pass + + def DiscardEdits(self): + """""" + pass + + def EmulateKeyPress(self): + """""" + pass + + def GetDefaultStyle(self): + """""" + pass + + def GetInsertionPoint(self): + """""" + pass + + def GetLastPosition(self): + """""" + pass + + def GetLineLength(self): + """""" + pass + + def GetLineText(self): + """""" + pass + + def GetNumberOfLines(self): + """""" + pass + + def GetRange(self): + """""" + pass + + def GetSelection(self): + """""" + pass + + def GetString(self): + """""" + pass + + def GetStringSelection(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def IsEditable(self): + """""" + pass + + def IsModified(self): + """""" + pass + + def IsMultiLine(self): + """""" + pass + + def IsSingleLine(self): + """""" + pass + + def LoadFile(self): + """""" + pass + + def Paste(self): + """""" + pass + + def PositionToXY(self): + """""" + pass + + def Redo(self): + """""" + pass + + def Remove(self): + """""" + pass + + def Replace(self): + """""" + pass + + def SaveFile(self): + """""" + pass + + def SelectAll(self): + """""" + pass + + def SetDefaultStyle(self): + """""" + pass + + def SetEditable(self): + """""" + pass + + def SetInsertionPoint(self): + """""" + pass + + def SetInsertionPointEnd(self): + """""" + pass + + def SetMaxLength(self): + """""" + pass + + def SetSelection(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def ShowPosition(self): + """""" + pass + + def Undo(self): + """""" + pass + + def WriteText(self): + """""" + pass + + def XYToPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + def write(self): + """""" + pass + + +class ToggleButton(Control): + """""" + + def Create(self): + """""" + pass + + def GetValue(self): + """""" + pass + + def SetLabel(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/DataStructures.py b/wxPython/wxPython/lib/PyCrust/wxd/DataStructures.py new file mode 100644 index 0000000000..59e533ea3c --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/DataStructures.py @@ -0,0 +1,485 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +class Point: + """""" + + def Set(self): + """""" + pass + + def __add__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __eq__(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __getitem__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __len__(self): + """""" + pass + + def __ne__(self): + """""" + pass + + def __nonzero__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + def __setitem__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def __sub__(self): + """""" + pass + + def asTuple(self): + """""" + pass + + +class Point2DDouble: + """""" + + def GetCrossProduct(self): + """""" + pass + + def GetDistance(self): + """""" + pass + + def GetDistanceSquare(self): + """""" + pass + + def GetDotProduct(self): + """""" + pass + + def GetFloor(self): + """""" + pass + + def GetRounded(self): + """""" + pass + + def GetVectorAngle(self): + """""" + pass + + def GetVectorLength(self): + """""" + pass + + def Normalize(self): + """""" + pass + + def SetPolarCoordinates(self): + """""" + pass + + def SetVectorAngle(self): + """""" + pass + + def SetVectorLength(self): + """""" + pass + + def __eq__(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __getitem__(self): + """""" + pass + + def __iadd__(self): + """""" + pass + + def __idiv__(self): + """""" + pass + + def __imul__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __isub__(self): + """""" + pass + + def __len__(self): + """""" + pass + + def __ne__(self): + """""" + pass + + def __neg__(self): + """""" + pass + + def __nonzero__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + def __setitem__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def asTuple(self): + """""" + pass + + +class RealPoint: + """""" + + def Set(self): + """""" + pass + + def __add__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __eq__(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __getitem__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __len__(self): + """""" + pass + + def __ne__(self): + """""" + pass + + def __nonzero__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + def __setitem__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def __sub__(self): + """""" + pass + + def asTuple(self): + """""" + pass + + +class Rect: + """""" + + def GetBottom(self): + """""" + pass + + def GetHeight(self): + """""" + pass + + def GetLeft(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetRight(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def GetTop(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def Inflate(self): + """""" + pass + + def Inside(self): + """""" + pass + + def SetBottom(self): + """""" + pass + + def SetHeight(self): + """""" + pass + + def SetLeft(self): + """""" + pass + + def SetPosition(self): + """""" + pass + + def SetRight(self): + """""" + pass + + def SetSize(self): + """""" + pass + + def SetTop(self): + """""" + pass + + def SetWidth(self): + """""" + pass + + def SetX(self): + """""" + pass + + def SetY(self): + """""" + pass + + def __add__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __eq__(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __getitem__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __len__(self): + """""" + pass + + def __ne__(self): + """""" + pass + + def __nonzero__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + def __setitem__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def asTuple(self): + """""" + pass + + +class Size: + """""" + + def GetHeight(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def Set(self): + """""" + pass + + def SetHeight(self): + """""" + pass + + def SetWidth(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __eq__(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __getitem__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __len__(self): + """""" + pass + + def __ne__(self): + """""" + pass + + def __nonzero__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + def __setitem__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def asTuple(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/DateTime.py b/wxPython/wxPython/lib/PyCrust/wxd/DateTime.py new file mode 100644 index 0000000000..a6fb8d7fdd --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/DateTime.py @@ -0,0 +1,553 @@ +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +class DateSpan: + """""" + + def Add(self): + """""" + pass + + def GetDays(self): + """""" + pass + + def GetMonths(self): + """""" + pass + + def GetTotalDays(self): + """""" + pass + + def GetWeeks(self): + """""" + pass + + def GetYears(self): + """""" + pass + + def Multiply(self): + """""" + pass + + def Neg(self): + """""" + pass + + def SetDays(self): + """""" + pass + + def SetMonths(self): + """""" + pass + + def SetWeeks(self): + """""" + pass + + def SetYears(self): + """""" + pass + + def Subtract(self): + """""" + pass + + def __add__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __mul__(self): + """""" + pass + + def __neg__(self): + """""" + pass + + def __rmul__(self): + """""" + pass + + def __sub__(self): + """""" + pass + + +class DateTime: + """""" + + def AddDS(self): + """""" + pass + + def AddTS(self): + """""" + pass + + def Format(self): + """""" + pass + + def FormatDate(self): + """""" + pass + + def FormatISODate(self): + """""" + pass + + def FormatISOTime(self): + """""" + pass + + def FormatTime(self): + """""" + pass + + def GetDay(self): + """""" + pass + + def GetDayOfYear(self): + """""" + pass + + def GetHour(self): + """""" + pass + + def GetJDN(self): + """""" + pass + + def GetJulianDayNumber(self): + """""" + pass + + def GetLastMonthDay(self): + """""" + pass + + def GetLastWeekDay(self): + """""" + pass + + def GetMJD(self): + """""" + pass + + def GetMillisecond(self): + """""" + pass + + def GetMinute(self): + """""" + pass + + def GetModifiedJulianDayNumber(self): + """""" + pass + + def GetMonth(self): + """""" + pass + + def GetNextWeekDay(self): + """""" + pass + + def GetPrevWeekDay(self): + """""" + pass + + def GetRataDie(self): + """""" + pass + + def GetSecond(self): + """""" + pass + + def GetTicks(self): + """""" + pass + + def GetWeek(self): + """""" + pass + + def GetWeekDay(self): + """""" + pass + + def GetWeekDayInSameWeek(self): + """""" + pass + + def GetWeekOfMonth(self): + """""" + pass + + def GetWeekOfYear(self): + """""" + pass + + def GetYear(self): + """""" + pass + + def GetYearDay(self): + """""" + pass + + def IsBetween(self): + """""" + pass + + def IsDST(self): + """""" + pass + + def IsEarlierThan(self): + """""" + pass + + def IsEqualTo(self): + """""" + pass + + def IsEqualUpTo(self): + """""" + pass + + def IsLaterThan(self): + """""" + pass + + def IsSameDate(self): + """""" + pass + + def IsSameTime(self): + """""" + pass + + def IsStrictlyBetween(self): + """""" + pass + + def IsValid(self): + """""" + pass + + def IsWorkDay(self): + """""" + pass + + def MakeGMT(self): + """""" + pass + + def MakeTimezone(self): + """""" + pass + + def ParseDate(self): + """""" + pass + + def ParseDateTime(self): + """""" + pass + + def ParseFormat(self): + """""" + pass + + def ParseRfc822Date(self): + """""" + pass + + def ParseTime(self): + """""" + pass + + def ResetTime(self): + """""" + pass + + def Set(self): + """""" + pass + + def SetDay(self): + """""" + pass + + def SetHMS(self): + """""" + pass + + def SetHour(self): + """""" + pass + + def SetJDN(self): + """""" + pass + + def SetMillisecond(self): + """""" + pass + + def SetMinute(self): + """""" + pass + + def SetMonth(self): + """""" + pass + + def SetSecond(self): + """""" + pass + + def SetTimeT(self): + """""" + pass + + def SetToCurrent(self): + """""" + pass + + def SetToLastMonthDay(self): + """""" + pass + + def SetToLastWeekDay(self): + """""" + pass + + def SetToNextWeekDay(self): + """""" + pass + + def SetToPrevWeekDay(self): + """""" + pass + + def SetToTheWeek(self): + """""" + pass + + def SetToWeekDay(self): + """""" + pass + + def SetToWeekDayInSameWeek(self): + """""" + pass + + def SetToYearDay(self): + """""" + pass + + def SetYear(self): + """""" + pass + + def Subtract(self): + """""" + pass + + def SubtractDS(self): + """""" + pass + + def SubtractTS(self): + """""" + pass + + def ToGMT(self): + """""" + pass + + def ToTimezone(self): + """""" + pass + + def __add__(self): + """""" + pass + + def __cmp__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def __sub__(self): + """""" + pass + + def _wxDateTimePtr__add__DS(self): + """""" + pass + + def _wxDateTimePtr__add__TS(self): + """""" + pass + + def _wxDateTimePtr__sub__DS(self): + """""" + pass + + def _wxDateTimePtr__sub__DT(self): + """""" + pass + + def _wxDateTimePtr__sub__TS(self): + """""" + pass + + +class TimeSpan: + """""" + + def Abs(self): + """""" + pass + + def Add(self): + """""" + pass + + def Format(self): + """""" + pass + + def GetDays(self): + """""" + pass + + def GetHours(self): + """""" + pass + + def GetMilliseconds(self): + """""" + pass + + def GetMinutes(self): + """""" + pass + + def GetSeconds(self): + """""" + pass + + def GetWeeks(self): + """""" + pass + + def IsEqualTo(self): + """""" + pass + + def IsLongerThan(self): + """""" + pass + + def IsNegative(self): + """""" + pass + + def IsNull(self): + """""" + pass + + def IsPositive(self): + """""" + pass + + def IsShorterThan(self): + """""" + pass + + def Multiply(self): + """""" + pass + + def Neg(self): + """""" + pass + + def Subtract(self): + """""" + pass + + def __add__(self): + """""" + pass + + def __cmp__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __mul__(self): + """""" + pass + + def __neg__(self): + """""" + pass + + def __rmul__(self): + """""" + pass + + def __sub__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Dialogs.py b/wxPython/wxPython/lib/PyCrust/wxd/Dialogs.py new file mode 100644 index 0000000000..56ca3c2d17 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Dialogs.py @@ -0,0 +1,471 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +from Frames import Frame +import Parameters as wx +from Window import TopLevelWindow + + +class Dialog(TopLevelWindow): + """""" + + def Centre(self): + """""" + pass + + def Create(self): + """""" + pass + + def CreateButtonSizer(self): + """""" + pass + + def CreateTextSizer(self): + """""" + pass + + def EndModal(self): + """""" + pass + + def GetReturnCode(self): + """""" + pass + + def IsModal(self): + """""" + pass + + def SetModal(self): + """""" + pass + + def SetReturnCode(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ColourDialog(Dialog): + """""" + + def GetColourData(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ColourData(Object): + """""" + + def GetChooseFull(self): + """""" + pass + + def GetColour(self): + """""" + pass + + def GetCustomColour(self): + """""" + pass + + def SetChooseFull(self): + """""" + pass + + def SetColour(self): + """""" + pass + + def SetCustomColour(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ColourDatabase(Object): + """""" + + def Append(self): + """""" + pass + + def FindColour(self): + """""" + pass + + def FindName(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DirDialog(Dialog): + """""" + + def GetMessage(self): + """""" + pass + + def GetPath(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def SetMessage(self): + """""" + pass + + def SetPath(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FileDialog(Dialog): + """""" + + def GetDirectory(self): + """""" + pass + + def GetFilename(self): + """""" + pass + + def GetFilenames(self): + """""" + pass + + def GetFilterIndex(self): + """""" + pass + + def GetMessage(self): + """""" + pass + + def GetPath(self): + """""" + pass + + def GetPaths(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetWildcard(self): + """""" + pass + + def SetDirectory(self): + """""" + pass + + def SetFilename(self): + """""" + pass + + def SetFilterIndex(self): + """""" + pass + + def SetMessage(self): + """""" + pass + + def SetPath(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def SetWildcard(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FindReplaceDialog(Dialog): + """""" + + def Create(self): + """""" + pass + + def GetData(self): + """""" + pass + + def SetData(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FindReplaceData(Object): + """""" + + def GetFindString(self): + """""" + pass + + def GetFlags(self): + """""" + pass + + def GetReplaceString(self): + """""" + pass + + def SetFindString(self): + """""" + pass + + def SetFlags(self): + """""" + pass + + def SetReplaceString(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FontDialog(Dialog): + """""" + + def GetFontData(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FontData(Object): + """""" + + def EnableEffects(self): + """""" + pass + + def GetAllowSymbols(self): + """""" + pass + + def GetChosenFont(self): + """""" + pass + + def GetColour(self): + """""" + pass + + def GetEnableEffects(self): + """""" + pass + + def GetInitialFont(self): + """""" + pass + + def GetShowHelp(self): + """""" + pass + + def SetAllowSymbols(self): + """""" + pass + + def SetChosenFont(self): + """""" + pass + + def SetColour(self): + """""" + pass + + def SetInitialFont(self): + """""" + pass + + def SetRange(self): + """""" + pass + + def SetShowHelp(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class MessageDialog(Dialog): + """""" + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + + +class MultiChoiceDialog(Dialog): + """""" + + def GetSelections(self): + """""" + pass + + def SetSelections(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ProgressDialog(Frame): + """""" + + def Resume(self): + """""" + pass + + def Update(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SingleChoiceDialog(Dialog): + """""" + + def GetSelection(self): + """""" + pass + + def GetStringSelection(self): + """""" + pass + + def SetSelection(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TextEntryDialog(Dialog): + """""" + + def GetValue(self): + """""" + pass + + def SetValue(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Drawing.py b/wxPython/wxPython/lib/PyCrust/wxd/Drawing.py new file mode 100644 index 0000000000..a6819f532c --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Drawing.py @@ -0,0 +1,1466 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class DC(Object): + """""" + + def BeginDrawing(self): + """""" + pass + + def Blit(self): + """""" + pass + + def CalcBoundingBox(self): + """""" + pass + + def CanDrawBitmap(self): + """""" + pass + + def CanGetTextExtent(self): + """""" + pass + + def Clear(self): + """""" + pass + + def CrossHair(self): + """""" + pass + + def DestroyClippingRegion(self): + """""" + pass + + def DeviceToLogicalX(self): + """""" + pass + + def DeviceToLogicalXRel(self): + """""" + pass + + def DeviceToLogicalY(self): + """""" + pass + + def DeviceToLogicalYRel(self): + """""" + pass + + def DrawArc(self): + """""" + pass + + def DrawBitmap(self): + """""" + pass + + def DrawCircle(self): + """""" + pass + + def DrawEllipse(self): + """""" + pass + + def DrawEllipticArc(self): + """""" + pass + + def DrawIcon(self): + """""" + pass + + def DrawImageLabel(self): + """""" + pass + + def DrawLabel(self): + """""" + pass + + def DrawLine(self): + """""" + pass + + def DrawLineList(self): + """""" + pass + + def DrawLines(self): + """""" + pass + + def DrawPoint(self): + """""" + pass + + def DrawPointList(self): + """""" + pass + + def DrawPolygon(self): + """""" + pass + + def DrawRectangle(self): + """""" + pass + + def DrawRectangleRect(self): + """""" + pass + + def DrawRotatedText(self): + """""" + pass + + def DrawRoundedRectangle(self): + """""" + pass + + def DrawSpline(self): + """""" + pass + + def DrawText(self): + """""" + pass + + def EndDoc(self): + """""" + pass + + def EndDrawing(self): + """""" + pass + + def EndPage(self): + """""" + pass + + def FloodFill(self): + """""" + pass + + def GetBackground(self): + """""" + pass + + def GetBoundingBox(self): + """""" + pass + + def GetBrush(self): + """""" + pass + + def GetCharHeight(self): + """""" + pass + + def GetCharWidth(self): + """""" + pass + + def GetClippingBox(self): + """""" + pass + + def GetDepth(self): + """""" + pass + + def GetDeviceOrigin(self): + """""" + pass + + def GetFont(self): + """""" + pass + + def GetFullTextExtent(self): + """""" + pass + + def GetLogicalFunction(self): + """""" + pass + + def GetLogicalOrigin(self): + """""" + pass + + def GetLogicalScale(self): + """""" + pass + + def GetMapMode(self): + """""" + pass + + def GetMultiLineTextExtent(self): + """""" + pass + + def GetOptimization(self): + """""" + pass + + def GetPPI(self): + """""" + pass + + def GetPen(self): + """""" + pass + + def GetPixel(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def GetSizeMM(self): + """""" + pass + + def GetSizeTuple(self): + """""" + pass + + def GetTextBackground(self): + """""" + pass + + def GetTextExtent(self): + """""" + pass + + def GetTextForeground(self): + """""" + pass + + def GetUserScale(self): + """""" + pass + + def LogicalToDeviceX(self): + """""" + pass + + def LogicalToDeviceXRel(self): + """""" + pass + + def LogicalToDeviceY(self): + """""" + pass + + def LogicalToDeviceYRel(self): + """""" + pass + + def MaxX(self): + """""" + pass + + def MaxY(self): + """""" + pass + + def MinX(self): + """""" + pass + + def MinY(self): + """""" + pass + + def Ok(self): + """""" + pass + + def ResetBoundingBox(self): + """""" + pass + + def SetAxisOrientation(self): + """""" + pass + + def SetBackground(self): + """""" + pass + + def SetBackgroundMode(self): + """""" + pass + + def SetBrush(self): + """""" + pass + + def SetClippingRect(self): + """""" + pass + + def SetClippingRegion(self): + """""" + pass + + def SetClippingRegionAsRegion(self): + """""" + pass + + def SetDeviceOrigin(self): + """""" + pass + + def SetFont(self): + """""" + pass + + def SetLogicalFunction(self): + """""" + pass + + def SetLogicalOrigin(self): + """""" + pass + + def SetLogicalScale(self): + """""" + pass + + def SetMapMode(self): + """""" + pass + + def SetOptimization(self): + """""" + pass + + def SetPalette(self): + """""" + pass + + def SetPen(self): + """""" + pass + + def SetTextBackground(self): + """""" + pass + + def SetTextForeground(self): + """""" + pass + + def SetUserScale(self): + """""" + pass + + def StartDoc(self): + """""" + pass + + def StartPage(self): + """""" + pass + + def _DrawLineList(self): + """""" + pass + + def _DrawPointList(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ClientDC(DC): + """""" + + def __init__(self): + """""" + pass + + +class MemoryDC(DC): + """""" + + def SelectObject(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class BufferedDC(MemoryDC): + """""" + + def UnMask(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class BufferedPaintDC(BufferedDC): + """""" + + def __init__(self): + """""" + pass + + +class PaintDC(DC): + """""" + + def __init__(self): + """""" + pass + + +class PostScriptDC(DC): + """""" + + def GetPrintData(self): + """""" + pass + + def SetPrintData(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ScreenDC(DC): + """""" + + def EndDrawingOnTop(self): + """""" + pass + + def StartDrawingOnTop(self): + """""" + pass + + def StartDrawingOnTopWin(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class WindowDC(DC): + """""" + + def __init__(self): + """""" + pass + + +class GDIObject(Object): + """""" + + def GetVisible(self): + """""" + pass + + def IsNull(self): + """""" + pass + + def SetVisible(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Bitmap(GDIObject): + """""" + + def CopyFromIcon(self): + """""" + pass + + def GetDepth(self): + """""" + pass + + def GetHeight(self): + """""" + pass + + def GetMask(self): + """""" + pass + + def GetPalette(self): + """""" + pass + + def GetSubBitmap(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def LoadFile(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SaveFile(self): + """""" + pass + + def SetDepth(self): + """""" + pass + + def SetHeight(self): + """""" + pass + + def SetMask(self): + """""" + pass + + def SetWidth(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Brush(GDIObject): + """""" + + def GetColour(self): + """""" + pass + + def GetStipple(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetColour(self): + """""" + pass + + def SetStipple(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class BrushList(Object): + """""" + + def AddBrush(self): + """""" + pass + + def FindOrCreateBrush(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def RemoveBrush(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Colour(Object): + """""" + + def Blue(self): + """""" + pass + + def Get(self): + """""" + pass + + def Green(self): + """""" + pass + + def Ok(self): + """""" + pass + + def Red(self): + """""" + pass + + def Set(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __eq__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __ne__(self): + """""" + pass + + def __nonzero__(self): + """""" + pass + + def __str__(self): + """""" + pass + + def asTuple(self): + """""" + pass + + +class Cursor(GDIObject): + """""" + + def Ok(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Font(Object): + """""" + + def GetEncoding(self): + """""" + pass + + def GetFaceName(self): + """""" + pass + + def GetFamily(self): + """""" + pass + + def GetFamilyString(self): + """""" + pass + + def GetNativeFontInfo(self): + """""" + pass + + def GetNativeFontInfoDesc(self): + """""" + pass + + def GetNativeFontInfoUserDesc(self): + """""" + pass + + def GetNoAntiAliasing(self): + """""" + pass + + def GetPointSize(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetStyleString(self): + """""" + pass + + def GetUnderlined(self): + """""" + pass + + def GetWeight(self): + """""" + pass + + def GetWeightString(self): + """""" + pass + + def IsFixedWidth(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetEncoding(self): + """""" + pass + + def SetFaceName(self): + """""" + pass + + def SetFamily(self): + """""" + pass + + def SetNativeFontInfo(self): + """""" + pass + + def SetNativeFontInfoUserDesc(self): + """""" + pass + + def SetNoAntiAliasing(self): + """""" + pass + + def SetPointSize(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def SetUnderlined(self): + """""" + pass + + def SetWeight(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def wxFontFromNativeInfoString(self): + """""" + pass + + +class FontList(Object): + """""" + + def AddFont(self): + """""" + pass + + def FindOrCreateFont(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def RemoveFont(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Icon(GDIObject): + """""" + + def CopyFromBitmap(self): + """""" + pass + + def GetDepth(self): + """""" + pass + + def GetHeight(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def LoadFile(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetDepth(self): + """""" + pass + + def SetHeight(self): + """""" + pass + + def SetWidth(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class IconBundle: + """""" + + def AddIcon(self): + """""" + pass + + def AddIconFromFile(self): + """""" + pass + + def GetIcon(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Image(Object): + """""" + + def ConvertToBitmap(self): + """""" + pass + + def ConvertToMono(self): + """""" + pass + + def ConvertToMonoBitmap(self): + """""" + pass + + def Copy(self): + """""" + pass + + def CountColours(self): + """""" + pass + + def Create(self): + """""" + pass + + def Destroy(self): + """""" + pass + + def FindFirstUnusedColour(self): + """""" + pass + + def GetBlue(self): + """""" + pass + + def GetData(self): + """""" + pass + + def GetDataBuffer(self): + """""" + pass + + def GetGreen(self): + """""" + pass + + def GetHeight(self): + """""" + pass + + def GetMaskBlue(self): + """""" + pass + + def GetMaskGreen(self): + """""" + pass + + def GetMaskRed(self): + """""" + pass + + def GetOption(self): + """""" + pass + + def GetOptionInt(self): + """""" + pass + + def GetRed(self): + """""" + pass + + def GetSubImage(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def HasMask(self): + """""" + pass + + def HasOption(self): + """""" + pass + + def LoadFile(self): + """""" + pass + + def LoadMimeFile(self): + """""" + pass + + def LoadMimeStream(self): + """""" + pass + + def LoadStream(self): + """""" + pass + + def Mirror(self): + """""" + pass + + def Ok(self): + """""" + pass + + def Paste(self): + """""" + pass + + def Replace(self): + """""" + pass + + def Rescale(self): + """""" + pass + + def Rotate(self): + """""" + pass + + def Rotate90(self): + """""" + pass + + def SaveFile(self): + """""" + pass + + def SaveMimeFile(self): + """""" + pass + + def Scale(self): + """""" + pass + + def SetData(self): + """""" + pass + + def SetMask(self): + """""" + pass + + def SetMaskColour(self): + """""" + pass + + def SetMaskFromImage(self): + """""" + pass + + def SetOption(self): + """""" + pass + + def SetOptionInt(self): + """""" + pass + + def SetRGB(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ImageList(Object): + """""" + + def Add(self): + """""" + pass + + def AddIcon(self): + """""" + pass + + def AddWithColourMask(self): + """""" + pass + + def Draw(self): + """""" + pass + + def GetImageCount(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def Remove(self): + """""" + pass + + def RemoveAll(self): + """""" + pass + + def Replace(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Mask(Object): + """""" + + def Destroy(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Palette(GDIObject): + """""" + + def GetPixel(self): + """""" + pass + + def GetRGB(self): + """""" + pass + + def Ok(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Pen(GDIObject): + """""" + + def GetCap(self): + """""" + pass + + def GetColour(self): + """""" + pass + + def GetDashes(self): + """""" + pass + + def GetJoin(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetCap(self): + """""" + pass + + def SetColour(self): + """""" + pass + + def SetDashes(self): + """""" + pass + + def SetJoin(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def SetWidth(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PenList(Object): + """""" + + def AddPen(self): + """""" + pass + + def FindOrCreatePen(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def RemovePen(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PyPen(Pen): + """""" + + def SetDashes(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Region(GDIObject): + """""" + + def Clear(self): + """""" + pass + + def Contains(self): + """""" + pass + + def ContainsPoint(self): + """""" + pass + + def ContainsRect(self): + """""" + pass + + def ContainsRectDim(self): + """""" + pass + + def GetBox(self): + """""" + pass + + def Intersect(self): + """""" + pass + + def IntersectRect(self): + """""" + pass + + def IntersectRegion(self): + """""" + pass + + def IsEmpty(self): + """""" + pass + + def Offset(self): + """""" + pass + + def Subtract(self): + """""" + pass + + def SubtractRect(self): + """""" + pass + + def SubtractRegion(self): + """""" + pass + + def Union(self): + """""" + pass + + def UnionRect(self): + """""" + pass + + def UnionRegion(self): + """""" + pass + + def Xor(self): + """""" + pass + + def XorRect(self): + """""" + pass + + def XorRegion(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class RegionIterator(Object): + """""" + + def GetH(self): + """""" + pass + + def GetHeight(self): + """""" + pass + + def GetRect(self): + """""" + pass + + def GetW(self): + """""" + pass + + def GetWidth(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def HaveRects(self): + """""" + pass + + def Next(self): + """""" + pass + + def Reset(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Errors.py b/wxPython/wxPython/lib/PyCrust/wxd/Errors.py new file mode 100644 index 0000000000..e1b5fea2bd --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Errors.py @@ -0,0 +1,25 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +class PyAssertionError(AssertionError): + """""" + pass + + +class PyDeadObjectError(AttributeError): + """Instances of wx objects that are OOR capable will have their + __class__ attribute changed to a _wxPyDeadObject class when the + C++ object is deleted. Subsequent attempts to access object + attributes will raise this error, rather than segfault.""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/EventFunctions.py b/wxPython/wxPython/lib/PyCrust/wxd/EventFunctions.py new file mode 100644 index 0000000000..24be2c9a13 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/EventFunctions.py @@ -0,0 +1,794 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +def EVT_ACTIVATE(win, func): + """""" + pass + +def EVT_ACTIVATE_APP(win, func): + """""" + pass + +def EVT_BUTTON(win, id, func): + """""" + pass + +def EVT_CALCULATE_LAYOUT(): + """""" + pass + +def EVT_CHAR(win, func): + """""" + pass + +def EVT_CHAR_HOOK(win, func): + """""" + pass + +def EVT_CHECKBOX(win, id, func): + """""" + pass + +def EVT_CHECKLISTBOX(win, id, func): + """""" + pass + +def EVT_CHILD_FOCUS(win, func): + """""" + pass + +def EVT_CHOICE(win, id, func): + """""" + pass + +def EVT_CLOSE(win, func): + """""" + pass + +def EVT_COMBOBOX(win, id, func): + """""" + pass + +def EVT_COMMAND(win, id, cmd, func): + """""" + pass + +def EVT_COMMAND_ENTER(win, id, func): + """""" + pass + +def EVT_COMMAND_FIND(): + """""" + pass + +def EVT_COMMAND_FIND_CLOSE(): + """""" + pass + +def EVT_COMMAND_FIND_NEXT(): + """""" + pass + +def EVT_COMMAND_FIND_REPLACE(): + """""" + pass + +def EVT_COMMAND_FIND_REPLACE_ALL(): + """""" + pass + +def EVT_COMMAND_KILL_FOCUS(win, id, func): + """""" + pass + +def EVT_COMMAND_LEFT_CLICK(win, id, func): + """""" + pass + +def EVT_COMMAND_LEFT_DCLICK(win, id, func): + """""" + pass + +def EVT_COMMAND_RANGE(win, id1, id2, cmd, func): + """""" + pass + +def EVT_COMMAND_RIGHT_CLICK(win, id, func): + """""" + pass + +def EVT_COMMAND_RIGHT_DCLICK(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_BOTTOM(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_LINEDOWN(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_LINEUP(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_PAGEDOWN(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_PAGEUP(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_THUMBRELEASE(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_THUMBTRACK(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLLWIN_TOP(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_BOTTOM(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_ENDSCROLL(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_LINEDOWN(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_LINEUP(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_PAGEDOWN(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_PAGEUP(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_THUMBRELEASE(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_THUMBTRACK(win, id, func): + """""" + pass + +def EVT_COMMAND_SCROLL_TOP(win, id, func): + """""" + pass + +def EVT_COMMAND_SET_FOCUS(win, id, func): + """""" + pass + +def EVT_CONTEXT_MENU(win, func): + """""" + pass + +def EVT_DISPLAY_CHANGED(win, func): + """""" + pass + +def EVT_DROP_FILES(win, func): + """""" + pass + +def EVT_END_PROCESS(eh, id, func): + """""" + pass + +def EVT_END_SESSION(win, func): + """""" + pass + +def EVT_ENTER_WINDOW(win, func): + """""" + pass + +def EVT_ERASE_BACKGROUND(win, func): + """""" + pass + +def EVT_ICONIZE(win, func): + """""" + pass + +def EVT_IDLE(win, func): + """""" + pass + +def EVT_INIT_DIALOG(win, func): + """""" + pass + +def EVT_JOYSTICK_EVENTS(win, func): + """""" + pass + +def EVT_JOY_DOWN(win, func): + """""" + pass + +def EVT_JOY_MOVE(win, func): + """""" + pass + +def EVT_JOY_UP(win, func): + """""" + pass + +def EVT_JOY_ZMOVE(win, func): + """""" + pass + +def EVT_KEY_DOWN(win, func): + """""" + pass + +def EVT_KEY_UP(win, func): + """""" + pass + +def EVT_KILL_FOCUS(win, func): + """""" + pass + +def EVT_LEAVE_WINDOW(win, func): + """""" + pass + +def EVT_LEFT_DCLICK(win, func): + """""" + pass + +def EVT_LEFT_DOWN(win, func): + """""" + pass + +def EVT_LEFT_UP(win, func): + """""" + pass + +def EVT_LISTBOX(win, id, func): + """""" + pass + +def EVT_LISTBOX_DCLICK(win, id, func): + """""" + pass + +def EVT_LIST_BEGIN_DRAG(): + """""" + pass + +def EVT_LIST_BEGIN_LABEL_EDIT(): + """""" + pass + +def EVT_LIST_BEGIN_RDRAG(): + """""" + pass + +def EVT_LIST_CACHE_HINT(): + """""" + pass + +def EVT_LIST_COL_BEGIN_DRAG(): + """""" + pass + +def EVT_LIST_COL_CLICK(): + """""" + pass + +def EVT_LIST_COL_DRAGGING(): + """""" + pass + +def EVT_LIST_COL_END_DRAG(): + """""" + pass + +def EVT_LIST_COL_RIGHT_CLICK(): + """""" + pass + +def EVT_LIST_DELETE_ALL_ITEMS(): + """""" + pass + +def EVT_LIST_DELETE_ITEM(): + """""" + pass + +def EVT_LIST_END_LABEL_EDIT(): + """""" + pass + +def EVT_LIST_GET_INFO(): + """""" + pass + +def EVT_LIST_INSERT_ITEM(): + """""" + pass + +def EVT_LIST_ITEM_ACTIVATED(): + """""" + pass + +def EVT_LIST_ITEM_DESELECTED(): + """""" + pass + +def EVT_LIST_ITEM_FOCUSED(): + """""" + pass + +def EVT_LIST_ITEM_MIDDLE_CLICK(): + """""" + pass + +def EVT_LIST_ITEM_RIGHT_CLICK(): + """""" + pass + +def EVT_LIST_ITEM_SELECTED(): + """""" + pass + +def EVT_LIST_KEY_DOWN(): + """""" + pass + +def EVT_LIST_SET_INFO(): + """""" + pass + +def EVT_MAXIMIZE(win, func): + """""" + pass + +def EVT_MENU(win, id, func): + """""" + pass + +def EVT_MENU_CLOSE(win, func): + """""" + pass + +def EVT_MENU_HIGHLIGHT(win, id, func): + """""" + pass + +def EVT_MENU_HIGHLIGHT_ALL(win, func): + """""" + pass + +def EVT_MENU_OPEN(win, func): + """""" + pass + +def EVT_MENU_RANGE(win, id1, id2, func): + """""" + pass + +def EVT_MIDDLE_DCLICK(win, func): + """""" + pass + +def EVT_MIDDLE_DOWN(win, func): + """""" + pass + +def EVT_MIDDLE_UP(win, func): + """""" + pass + +def EVT_MOTION(win, func): + """""" + pass + +def EVT_MOUSEWHEEL(win, func): + """""" + pass + +def EVT_MOUSE_CAPTURE_CHANGED(win, func): + """""" + pass + +def EVT_MOUSE_EVENTS(win, func): + """""" + pass + +def EVT_MOVE(win, func): + """""" + pass + +def EVT_NAVIGATION_KEY(win, func): + """""" + pass + +def EVT_NOTEBOOK_PAGE_CHANGED(win, id, func): + """""" + pass + +def EVT_NOTEBOOK_PAGE_CHANGING(win, id, func): + """""" + pass + +def EVT_PAINT(win, func): + """""" + pass + +def EVT_PALETTE_CHANGED(win, func): + """""" + pass + +def EVT_QUERY_END_SESSION(win, func): + """""" + pass + +def EVT_QUERY_LAYOUT_INFO(): + """""" + pass + +def EVT_QUERY_NEW_PALETTE(win, func): + """""" + pass + +def EVT_RADIOBOX(win, id, func): + """""" + pass + +def EVT_RADIOBUTTON(win, id, func): + """""" + pass + +def EVT_RIGHT_DCLICK(win, func): + """""" + pass + +def EVT_RIGHT_DOWN(win, func): + """""" + pass + +def EVT_RIGHT_UP(win, func): + """""" + pass + +def EVT_SASH_DRAGGED(win, id, func): + """""" + pass + +def EVT_SASH_DRAGGED_RANGE(win, id1, id2, func): + """""" + pass + +def EVT_SCROLL(win, func): + """""" + pass + +def EVT_SCROLLWIN(win, func): + """""" + pass + +def EVT_SCROLLWIN_BOTTOM(win, func): + """""" + pass + +def EVT_SCROLLWIN_LINEDOWN(win, func): + """""" + pass + +def EVT_SCROLLWIN_LINEUP(win, func): + """""" + pass + +def EVT_SCROLLWIN_PAGEDOWN(win, func): + """""" + pass + +def EVT_SCROLLWIN_PAGEUP(win, func): + """""" + pass + +def EVT_SCROLLWIN_THUMBRELEASE(win, func): + """""" + pass + +def EVT_SCROLLWIN_THUMBTRACK(win, func): + """""" + pass + +def EVT_SCROLLWIN_TOP(win, func): + """""" + pass + +def EVT_SCROLL_BOTTOM(win, func): + """""" + pass + +def EVT_SCROLL_ENDSCROLL(win, func): + """""" + pass + +def EVT_SCROLL_LINEDOWN(win, func): + """""" + pass + +def EVT_SCROLL_LINEUP(win, func): + """""" + pass + +def EVT_SCROLL_PAGEDOWN(win, func): + """""" + pass + +def EVT_SCROLL_PAGEUP(win, func): + """""" + pass + +def EVT_SCROLL_THUMBRELEASE(win, func): + """""" + pass + +def EVT_SCROLL_THUMBTRACK(win, func): + """""" + pass + +def EVT_SCROLL_TOP(win, func): + """""" + pass + +def EVT_SET_CURSOR(win, func): + """""" + pass + +def EVT_SET_FOCUS(win, func): + """""" + pass + +def EVT_SHOW(win, func): + """""" + pass + +def EVT_SIZE(): + """""" + pass + +def EVT_SLIDER(win, id, func): + """""" + pass + +def EVT_SPIN(win, id, func): + """""" + pass + +def EVT_SPINCTRL(win, id, func): + """""" + pass + +def EVT_SPIN_DOWN(win, id, func): + """""" + pass + +def EVT_SPIN_UP(win, id, func): + """""" + pass + +def EVT_SPLITTER_DOUBLECLICKED(win, id, func): + """""" + pass + +def EVT_SPLITTER_SASH_POS_CHANGED(win, id, func): + """""" + pass + +def EVT_SPLITTER_SASH_POS_CHANGING(win, id, func): + """""" + pass + +def EVT_SPLITTER_UNSPLIT(win, id, func): + """""" + pass + +def EVT_SYS_COLOUR_CHANGED(win, func): + """""" + pass + +def EVT_TASKBAR_LEFT_DCLICK(win, func): + """""" + pass + +def EVT_TASKBAR_LEFT_DOWN(win, func): + """""" + pass + +def EVT_TASKBAR_LEFT_UP(win, func): + """""" + pass + +def EVT_TASKBAR_MOVE(win, func): + """""" + pass + +def EVT_TASKBAR_RIGHT_DCLICK(win, func): + """""" + pass + +def EVT_TASKBAR_RIGHT_DOWN(win, func): + """""" + pass + +def EVT_TASKBAR_RIGHT_UP(win, func): + """""" + pass + +def EVT_TEXT(win, id, func): + """""" + pass + +def EVT_TEXT_ENTER(win, id, func): + """""" + pass + +def EVT_TEXT_MAXLEN(win, id, func): + """""" + pass + +def EVT_TEXT_URL(win, id, func): + """""" + pass + +def EVT_TIMER(win, id, func): + """""" + pass + +def EVT_TOGGLEBUTTON(win, id, func): + """""" + pass + +def EVT_TOOL(win, id, func): + """""" + pass + +def EVT_TOOL_ENTER(win, id, func): + """""" + pass + +def EVT_TOOL_RANGE(win, id, id2, func): + """""" + pass + +def EVT_TOOL_RCLICKED(win, id, func): + """""" + pass + +def EVT_TOOL_RCLICKED_RANGE(win, id, id2, func): + """""" + pass + +def EVT_TREE_BEGIN_DRAG(): + """""" + pass + +def EVT_TREE_BEGIN_LABEL_EDIT(): + """""" + pass + +def EVT_TREE_BEGIN_RDRAG(): + """""" + pass + +def EVT_TREE_DELETE_ITEM(): + """""" + pass + +def EVT_TREE_END_DRAG(): + """""" + pass + +def EVT_TREE_END_LABEL_EDIT(): + """""" + pass + +def EVT_TREE_GET_INFO(): + """""" + pass + +def EVT_TREE_ITEM_ACTIVATED(): + """""" + pass + +def EVT_TREE_ITEM_COLLAPSED(): + """""" + pass + +def EVT_TREE_ITEM_COLLAPSING(): + """""" + pass + +def EVT_TREE_ITEM_EXPANDED(): + """""" + pass + +def EVT_TREE_ITEM_EXPANDING(): + """""" + pass + +def EVT_TREE_ITEM_MIDDLE_CLICK(): + """""" + pass + +def EVT_TREE_ITEM_RIGHT_CLICK(): + """""" + pass + +def EVT_TREE_KEY_DOWN(): + """""" + pass + +def EVT_TREE_SEL_CHANGED(): + """""" + pass + +def EVT_TREE_SEL_CHANGING(): + """""" + pass + +def EVT_TREE_SET_INFO(): + """""" + pass + +def EVT_UPDATE_UI(win, id, func): + """""" + pass + +def EVT_UPDATE_UI_RANGE(win, id, id2, func): + """""" + pass + +def EVT_VLBOX(win, id, func): + """""" + pass + +def EVT_WINDOW_CREATE(win, func): + """""" + pass + +def EVT_WINDOW_DESTROY(win, func): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Events.py b/wxPython/wxPython/lib/PyCrust/wxd/Events.py new file mode 100644 index 0000000000..c9e5a642e3 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Events.py @@ -0,0 +1,1275 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class Event(Object): + """""" + + def __init__(self): + """""" + pass + + def Clone(self): + """""" + pass + + def GetEventObject(self): + """""" + pass + + def GetEventType(self): + """""" + pass + + def GetId(self): + """""" + pass + + def GetSkipped(self): + """""" + pass + + def GetTimestamp(self): + """""" + pass + + def SetEventObject(self): + """""" + pass + + def SetEventType(self): + """""" + pass + + def SetId(self): + """""" + pass + + def SetTimestamp(self): + """""" + pass + + def Skip(self): + """""" + pass + + +class PyEvent(Event): + """""" + + def GetSelf(self): + """""" + pass + + def SetSelf(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ActivateEvent(Event): + """""" + + def GetActive(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class CalculateLayoutEvent(Event): + """""" + + def GetFlags(self): + """""" + pass + + def GetRect(self): + """""" + pass + + def SetFlags(self): + """""" + pass + + def SetRect(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class CloseEvent(Event): + """""" + + def CanVeto(self): + """""" + pass + + def GetLoggingOff(self): + """""" + pass + + def GetVeto(self): + """""" + pass + + def SetCanVeto(self): + """""" + pass + + def SetLoggingOff(self): + """""" + pass + + def Veto(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class CommandEvent(Event): + """""" + + def __init__(self): + """""" + pass + + def Checked(self): + """""" + pass + + def GetClientData(self): + """""" + pass + + def GetExtraLong(self): + """""" + pass + + def GetInt(self): + """""" + pass + + def GetSelection(self): + """""" + pass + + def GetString(self): + """""" + pass + + def IsChecked(self): + """""" + pass + + def IsSelection(self): + """""" + pass + + def SetExtraLong(self): + """""" + pass + + def SetInt(self): + """""" + pass + + def SetString(self): + """""" + pass + + +class ChildFocusEvent(CommandEvent): + """""" + + def GetWindow(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ContextMenuEvent(CommandEvent): + """""" + + def GetPosition(self): + """""" + pass + + def SetPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DisplayChangedEvent(Event): + """""" + + def __init__(self): + """""" + pass + + +class DropFilesEvent(Event): + """""" + + def GetFiles(self): + """""" + pass + + def GetNumberOfFiles(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class EraseEvent(Event): + """""" + + def GetDC(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FindDialogEvent(CommandEvent): + """""" + + def GetDialog(self): + """""" + pass + + def GetFindString(self): + """""" + pass + + def GetFlags(self): + """""" + pass + + def GetReplaceString(self): + """""" + pass + + def SetFindString(self): + """""" + pass + + def SetFlags(self): + """""" + pass + + def SetReplaceString(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FocusEvent(Event): + """""" + + def __init__(self): + """""" + pass + + +class IconizeEvent(Event): + """""" + + def Iconized(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class IdleEvent(Event): + """""" + + def MoreRequested(self): + """""" + pass + + def RequestMore(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class InitDialogEvent(Event): + """""" + + def __init__(self): + """""" + pass + + +class JoystickEvent(Event): + """""" + + def ButtonDown(self): + """""" + pass + + def ButtonIsDown(self): + """""" + pass + + def ButtonUp(self): + """""" + pass + + def GetButtonChange(self): + """""" + pass + + def GetButtonState(self): + """""" + pass + + def GetJoystick(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetZPosition(self): + """""" + pass + + def IsButton(self): + """""" + pass + + def IsMove(self): + """""" + pass + + def IsZMove(self): + """""" + pass + + def SetButtonChange(self): + """""" + pass + + def SetButtonState(self): + """""" + pass + + def SetJoystick(self): + """""" + pass + + def SetPosition(self): + """""" + pass + + def SetZPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class KeyEvent(Event): + """""" + + def AltDown(self): + """""" + pass + + def ControlDown(self): + """""" + pass + + def GetKeyCode(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetPositionTuple(self): + """""" + pass + + def GetRawKeyCode(self): + """""" + pass + + def GetRawKeyFlags(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def HasModifiers(self): + """""" + pass + + def KeyCode(self): + """""" + pass + + def MetaDown(self): + """""" + pass + + def ShiftDown(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class MaximizeEvent(Event): + """""" + + def __init__(self): + """""" + pass + + +class MenuEvent(Event): + """""" + + def GetMenuId(self): + """""" + pass + + def IsPopup(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class MouseCaptureChangedEvent(Event): + """""" + + def GetCapturedWindow(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class MouseEvent(Event): + """""" + + def AltDown(self): + """""" + pass + + def Button(self): + """""" + pass + + def ButtonDClick(self): + """""" + pass + + def ButtonDown(self): + """""" + pass + + def ButtonIsDown(self): + """""" + pass + + def ButtonUp(self): + """""" + pass + + def ControlDown(self): + """""" + pass + + def Dragging(self): + """""" + pass + + def Entering(self): + """""" + pass + + def GetLinesPerAction(self): + """""" + pass + + def GetLogicalPosition(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetPositionTuple(self): + """""" + pass + + def GetWheelDelta(self): + """""" + pass + + def GetWheelRotation(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def IsButton(self): + """""" + pass + + def Leaving(self): + """""" + pass + + def LeftDClick(self): + """""" + pass + + def LeftDown(self): + """""" + pass + + def LeftIsDown(self): + """""" + pass + + def LeftUp(self): + """""" + pass + + def MetaDown(self): + """""" + pass + + def MiddleDClick(self): + """""" + pass + + def MiddleDown(self): + """""" + pass + + def MiddleIsDown(self): + """""" + pass + + def MiddleUp(self): + """""" + pass + + def Moving(self): + """""" + pass + + def RightDClick(self): + """""" + pass + + def RightDown(self): + """""" + pass + + def RightIsDown(self): + """""" + pass + + def RightUp(self): + """""" + pass + + def ShiftDown(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class MoveEvent(Event): + """""" + + def GetPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class NavigationKeyEvent(Event): + """""" + + def GetCurrentFocus(self): + """""" + pass + + def GetDirection(self): + """""" + pass + + def IsWindowChange(self): + """""" + pass + + def SetCurrentFocus(self): + """""" + pass + + def SetDirection(self): + """""" + pass + + def SetWindowChange(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class NotifyEvent(CommandEvent): + """""" + + def __init__(self): + """""" + pass + + def Allow(self): + """""" + pass + + def IsAllowed(self): + """""" + pass + + def Veto(self): + """""" + pass + + +class ListEvent(NotifyEvent): + """""" + + def GetCacheFrom(self): + """""" + pass + + def GetCacheTo(self): + """""" + pass + + def GetCode(self): + """""" + pass + + def GetColumn(self): + """""" + pass + + def GetData(self): + """""" + pass + + def GetImage(self): + """""" + pass + + def GetIndex(self): + """""" + pass + + def GetItem(self): + """""" + pass + + def GetKeyCode(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetMask(self): + """""" + pass + + def GetPoint(self): + """""" + pass + + def GetText(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class NotebookEvent(NotifyEvent): + + def __init__(self, commandType=wx.EVT_NULL, id=0, nSel=-1, nOldSel=-1): + """""" + pass + + def GetSelection(self): + """""" + pass + + def GetOldSelection(self): + """""" + pass + + def SetOldSelection(self, page): + """""" + pass + + def SetSelection(self, page): + """""" + pass + + +class PaintEvent(Event): + """""" + + def __init__(self): + """""" + pass + + +class PaletteChangedEvent(Event): + """""" + + def GetChangedWindow(self): + """""" + pass + + def SetChangedWindow(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ProcessEvent(Event): + """""" + + def GetExitCode(self): + """""" + pass + + def GetPid(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class PyCommandEvent(CommandEvent): + """""" + + def GetSelf(self): + """""" + pass + + def SetSelf(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class QueryLayoutInfoEvent(Event): + """""" + + def GetAlignment(self): + """""" + pass + + def GetFlags(self): + """""" + pass + + def GetOrientation(self): + """""" + pass + + def GetRequestedLength(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def SetAlignment(self): + """""" + pass + + def SetFlags(self): + """""" + pass + + def SetOrientation(self): + """""" + pass + + def SetRequestedLength(self): + """""" + pass + + def SetSize(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class QueryNewPaletteEvent(Event): + """""" + + def GetPaletteRealized(self): + """""" + pass + + def SetPaletteRealized(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SashEvent(CommandEvent): + """""" + + def GetDragRect(self): + """""" + pass + + def GetDragStatus(self): + """""" + pass + + def GetEdge(self): + """""" + pass + + def SetDragRect(self): + """""" + pass + + def SetDragStatus(self): + """""" + pass + + def SetEdge(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ScrollEvent(CommandEvent): + """""" + + def GetOrientation(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ScrollWinEvent(Event): + """""" + + def GetOrientation(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SetCursorEvent(Event): + """""" + + def GetCursor(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def HasCursor(self): + """""" + pass + + def SetCursor(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ShowEvent(Event): + """""" + + def GetShow(self): + """""" + pass + + def SetShow(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SizeEvent(Event): + """""" + + def GetSize(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SpinEvent(ScrollEvent): + """""" + + def __init__(self): + """""" + pass + + +class SplitterEvent(NotifyEvent): + """""" + + def GetSashPosition(self): + """""" + pass + + def GetWindowBeingRemoved(self): + """""" + pass + + def GetX(self): + """""" + pass + + def GetY(self): + """""" + pass + + def SetSashPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SysColourChangedEvent(Event): + """""" + + def __init__(self): + """""" + pass + + +class TextUrlEvent(CommandEvent): + """""" + + def GetMouseEvent(self): + """""" + pass + + def GetURLEnd(self): + """""" + pass + + def GetURLStart(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TimerEvent(Event): + """""" + + def GetInterval(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TreeEvent(NotifyEvent): + """""" + + def GetCode(self): + """""" + pass + + def GetItem(self): + """""" + pass + + def GetKeyCode(self): + """""" + pass + + def GetKeyEvent(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetOldItem(self): + """""" + pass + + def GetPoint(self): + """""" + pass + + def IsEditCancelled(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class UpdateUIEvent(Event): + """""" + + def Check(self): + """""" + pass + + def Enable(self): + """""" + pass + + def GetChecked(self): + """""" + pass + + def GetEnabled(self): + """""" + pass + + def GetSetChecked(self): + """""" + pass + + def GetSetEnabled(self): + """""" + pass + + def GetSetText(self): + """""" + pass + + def GetText(self): + """""" + pass + + def SetText(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class WindowCreateEvent(CommandEvent): + """""" + + def GetWindow(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class WindowDestroyEvent(CommandEvent): + """""" + + def GetWindow(self): + """""" + pass + + def __init__(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/FileSystem.py b/wxPython/wxPython/lib/PyCrust/wxd/FileSystem.py new file mode 100644 index 0000000000..41780660c4 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/FileSystem.py @@ -0,0 +1,193 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class FSFile(Object): + """""" + + def GetAnchor(self): + """""" + pass + + def GetLocation(self): + """""" + pass + + def GetMimeType(self): + """""" + pass + + def GetModificationTime(self): + """""" + pass + + def GetStream(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FileSystem(Object): + """""" + + def ChangePathTo(self): + """""" + pass + + def FindFirst(self): + """""" + pass + + def FindNext(self): + """""" + pass + + def GetPath(self): + """""" + pass + + def OpenFile(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class CPPFileSystemHandler(Object): + """""" + + def __init__(self): + """""" + pass + + +class FileSystemHandler(CPPFileSystemHandler): + """""" + + def CanOpen(self): + """""" + pass + + def FindFirst(self): + """""" + pass + + def FindNext(self): + """""" + pass + + def GetAnchor(self): + """""" + pass + + def GetLeftLocation(self): + """""" + pass + + def GetMimeTypeFromExt(self): + """""" + pass + + def GetProtocol(self): + """""" + pass + + def GetRightLocation(self): + """""" + pass + + def OpenFile(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class InternetFSHandler(CPPFileSystemHandler): + """""" + + def CanOpen(self): + """""" + pass + + def OpenFile(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class MemoryFSHandler(CPPFileSystemHandler): + """""" + + def CanOpen(self): + """""" + pass + + def FindFirst(self): + """""" + pass + + def FindNext(self): + """""" + pass + + def OpenFile(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ZipFSHandler(CPPFileSystemHandler): + """""" + + def CanOpen(self): + """""" + pass + + def FindFirst(self): + """""" + pass + + def FindNext(self): + """""" + pass + + def OpenFile(self): + """""" + pass + + def __init__(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Frames.py b/wxPython/wxPython/lib/PyCrust/wxd/Frames.py new file mode 100644 index 0000000000..94c0e72074 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Frames.py @@ -0,0 +1,440 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx +from Window import TopLevelWindow, Window + + +class Frame(TopLevelWindow): + """A frame is a window whose size and position can (usually) be + changed by the user. It usually has thick borders and a title bar, + and can optionally contain a menu bar, toolbar and status bar. A + frame can contain any window that is not a frame or dialog. + + A frame that has a status bar and toolbar created via the + CreateStatusBar/CreateToolBar functions manages these windows, and + adjusts the value returned by GetClientSize to reflect the + remaining size available to application windows. + + An application should normally define a CloseEvent handler for the + frame to respond to system close events, for example so that + related data and subwindows can be cleaned up.""" + + def __init__(self, parent, id, title, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, + name=wx.PyFrameNameStr): + """Create a Frame instance. + + parent - The window parent. This may be NULL. If it is + non-NULL, the frame will always be displayed on top of the + parent window on Windows. + + id - The window identifier. It may take a value of -1 to + indicate a default value. + + title - The caption to be displayed on the frame's title bar. + + pos - The window position. A value of (-1, -1) indicates a + default position, chosen by either the windowing system or + wxWindows, depending on platform. + + size - The window size. A value of (-1, -1) indicates a + default size, chosen by either the windowing system or + wxWindows, depending on platform. + + style - The window style. + + name - The name of the window. This parameter is used to + associate a name with the item, allowing the application user + to set Motif resource values for individual windows.""" + pass + + def Create(self, parent, id, title, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, + name=wx.PyFrameNameStr): + """Create a Frame instance.""" + pass + + def Command(self, id): + """Simulate a menu command; id is a menu item identifier.""" + pass + + def CreateStatusBar(self, number=1, style=wx.ST_SIZEGRIP, id=-1, + name=wx.PyStatusLineNameStr): + """Create a status bar at the bottom of frame. + + number - The number of fields to create. Specify a value + greater than 1 to create a multi-field status bar. + + style - The status bar style. See wx.StatusBar for a list of + valid styles. + + id - The status bar window identifier. If -1, an identifier + will be chosen by wxWindows. + + name - The status bar window name. + + The width of the status bar is the whole width of the frame + (adjusted automatically when resizing), and the height and + text size are chosen by the host windowing system. + + By default, the status bar is an instance of wx.StatusBar.""" + pass + + def CreateToolBar(self, style=wx.NO_BORDER|wx.TB_HORIZONTAL, id=-1, + name=wx.PyToolBarNameStr): + """Create a toolbar at the top or left of frame. + + style - The toolbar style. See wxToolBar for a list of valid + styles. + + id - The toolbar window identifier. If -1, an identifier will + be chosen by wxWindows. + + name - The toolbar window name. + + By default, the toolbar is an instance of wx.ToolBar (which is + defined to be a suitable toolbar class on each platform, such + as wx.ToolBar95). + + When a toolbar has been created with this function, or made + known to the frame with wx.Frame.SetToolBar, the frame will + manage the toolbar position and adjust the return value from + wx.Window.GetClientSize to reflect the available space for + application windows.""" + pass + + def DoGiveHelp(self, text, show): + """Show help text (typically in the statusbar). + + show is False if you are hiding the help, True otherwise. + + Meant to be overridden if a derived frame wants to do + something else with help text from menus and etc. The default + implementation simply calls Frame.SetStatusText.""" + pass + + def GetClientAreaOrigin(self): + """Return origin of frame client area (in client coordinates). + + It may be different from (0, 0) if the frame has a toolbar.""" + pass + + def GetMenuBar(self): + """Return menubar currently associated with frame (if any).""" + pass + + def GetStatusBar(self): + """Return status bar currently associated with frame (if any).""" + pass + + def GetStatusBarPane(self): + """Return status bar pane used to display menu and toolbar + help.""" + pass + + def GetToolBar(self): + """Return toolbar currently associated with frame (if any).""" + pass + + def PopStatusText(self, number=0): + """Redraw status bar with previous status text. + + number - The status field (starting from zero).""" + pass + + def ProcessCommand(self, id): + """Process menu command; return True if processed. + + id is the menu command identifier.""" + pass + + def PushStatusText(self, text, number=0): + """Set status bar text and redraw status bar, remembering + previous text. + + text - The text for the status field. + + number - The status field (starting from zero). + + Use an empty string to clear the status bar.""" + pass + + def SendSizeEvent(self): + """Send a dummy size event to the frame forcing it to + reevaluate its children positions. It is sometimes useful to + call this function after adding or deleting a children after + the frame creation or if a child size changes. + + Note that if the frame is using either sizers or constraints + for the children layout, it is enough to call Frame.Layout() + directly and this function should not be used in this case.""" + pass + + def SetMenuBar(self, menubar): + """Show the menu bar in the frame. + + menuBar - The menu bar to associate with the frame. + + If the frame is destroyed, the menu bar and its menus will be + destroyed also, so do not delete the menu bar explicitly + (except by resetting the frame's menu bar to another frame or + NULL). + + Under Windows, a call to Frame.OnSize is generated, so be sure + to initialize data members properly before calling SetMenuBar. + + Note that it is not possible to call this function twice for + the same frame object.""" + pass + + def SetStatusBar(self, statBar): + """Associate a status bar with the frame.""" + pass + + def SetStatusBarPane(self, n): + """Set the status bar pane used to display menu and toolbar + help. Using -1 disables help display.""" + pass + + def SetStatusText(self, text, number=0): + """Set status bar text and redraw status bar. + + text - The text for the status field. + + number - The status field (starting from zero). + + Use an empty string to clear the status bar.""" + pass + + def SetStatusWidths(self, choices): + """Sets the widths of the fields in the status bar. + + choices - a Python list of integers, each of which is a status + field width in pixels. A value of -1 indicates that the field + is variable width; at least one field must be -1. + + The widths of the variable fields are calculated from the + total width of all fields, minus the sum of widths of the + non-variable fields, divided by the number of variable fields.""" + pass + + def SetToolBar(self, toolbar): + """Associate a toolbar with the frame.""" + pass + + +class LayoutAlgorithm(Object): + """""" + + def __init__(self): + """""" + pass + + def LayoutFrame(self): + """""" + pass + + def LayoutMDIFrame(self): + """""" + pass + + def LayoutWindow(self): + """""" + pass + + +class MDIChildFrame(Frame): + """""" + + def __init__(self): + """""" + pass + + def Create(self): + """""" + pass + + def Activate(self): + """""" + pass + + def Maximize(self): + """""" + pass + + def Restore(self): + """""" + pass + + +class MDIClientWindow(Window): + """""" + + def __init__(self): + """""" + pass + + def Create(self): + """""" + pass + + +class MDIParentFrame(Frame): + """""" + + def __init__(self): + """""" + pass + + def Create(self): + """""" + pass + + def ActivateNext(self): + """""" + pass + + def ActivatePrevious(self): + """""" + pass + + def ArrangeIcons(self): + """""" + pass + + def Cascade(self): + """""" + pass + + def GetActiveChild(self): + """""" + pass + + def GetClientWindow(self): + """""" + pass + + def GetToolBar(self): + """""" + pass + + def Tile(self): + """""" + pass + + +class MiniFrame(Frame): + """""" + + def __init__(self): + """""" + pass + + def Create(self): + """""" + pass + + +class SplashScreen(Frame): + """""" + + def __init__(self): + """""" + pass + + def GetSplashStyle(self): + """""" + pass + + def GetSplashWindow(self): + """""" + pass + + def GetTimeout(self): + """""" + pass + + +class SplashScreenWindow(Window): + """""" + + def __init__(self): + """""" + pass + + def GetBitmap(self): + """""" + pass + + def SetBitmap(self): + """""" + pass + + +class StatusBar(Window): + """""" + + def __init__(self): + """""" + pass + + def Create(self): + """""" + pass + + def GetBorderX(self): + """""" + pass + + def GetBorderY(self): + """""" + pass + + def GetFieldRect(self): + """""" + pass + + def GetFieldsCount(self): + """""" + pass + + def GetStatusText(self): + """""" + pass + + def PopStatusText(self): + """""" + pass + + def PushStatusText(self): + """""" + pass + + def SetFieldsCount(self): + """""" + pass + + def SetMinHeight(self): + """""" + pass + + def SetStatusText(self): + """""" + pass + + def SetStatusWidths(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Functions.py b/wxPython/wxPython/lib/PyCrust/wxd/Functions.py new file mode 100644 index 0000000000..67af4e18be --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Functions.py @@ -0,0 +1,1262 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +def ArtProvider_GetBitmap(): + """""" + pass + +def ArtProvider_GetIcon(): + """""" + pass + +def ArtProvider_PopProvider(): + """""" + pass + +def ArtProvider_PushProvider(): + """""" + pass + +def ArtProvider_RemoveProvider(): + """""" + pass + +def BeginBusyCursor(): + """""" + pass + +def Bell(): + """""" + pass + +def BitmapFromBits(): + """""" + pass + +def BitmapFromIcon(): + """""" + pass + +def BitmapFromImage(): + """""" + pass + +def BitmapFromXPMData(): + """""" + pass + +def BufferedDCInternalBuffer(): + """""" + pass + +def Button_GetDefaultSize(): + """""" + pass + +def CallAfter(callable, *args, **kw): + """Call the specified function after the current and pending event + handlers have been completed. This is also good for making GUI + method calls from non-GUI threads.""" + pass + +def Caret_GetBlinkTime(): + """""" + pass + +def Caret_SetBlinkTime(): + """""" + pass + +def ClientDisplayRect(): + """""" + pass + +def ColourDisplay(): + """""" + pass + +def ConfigBase_Create(): + """""" + pass + +def ConfigBase_DontCreateOnDemand(): + """""" + pass + +def ConfigBase_Get(): + """""" + pass + +def ConfigBase_Set(): + """""" + pass + +def CreateFileTipProvider(): + """""" + pass + +def CustomDataFormat(): + """""" + pass + +def DLG_PNT(): + """""" + pass + +def DLG_SZE(): + """""" + pass + +def DateSpan_Day(): + """""" + pass + +def DateSpan_Days(): + """""" + pass + +def DateSpan_Month(): + """""" + pass + +def DateSpan_Months(): + """""" + pass + +def DateSpan_Week(): + """""" + pass + +def DateSpan_Weeks(): + """""" + pass + +def DateSpan_Year(): + """""" + pass + +def DateSpan_Years(): + """""" + pass + +def DateTimeFromDMY(): + """""" + pass + +def DateTimeFromHMS(): + """""" + pass + +def DateTimeFromJDN(): + """""" + pass + +def DateTimeFromTimeT(): + """""" + pass + +def DateTime_ConvertYearToBC(): + """""" + pass + +def DateTime_GetAmPmStrings(): + """""" + pass + +def DateTime_GetBeginDST(): + """""" + pass + +def DateTime_GetCentury(): + """""" + pass + +def DateTime_GetCountry(): + """""" + pass + +def DateTime_GetCurrentMonth(): + """""" + pass + +def DateTime_GetCurrentYear(): + """""" + pass + +def DateTime_GetEndDST(): + """""" + pass + +def DateTime_GetMonthName(): + """""" + pass + +def DateTime_GetNumberOfDaysInMonth(): + """""" + pass + +def DateTime_GetNumberOfDaysinYear(): + """""" + pass + +def DateTime_GetWeekDayName(): + """""" + pass + +def DateTime_IsDSTApplicable(): + """""" + pass + +def DateTime_IsLeapYear(): + """""" + pass + +def DateTime_IsWestEuropeanCountry(): + """""" + pass + +def DateTime_Now(): + """""" + pass + +def DateTime_SetCountry(): + """""" + pass + +def DateTime_Today(): + """""" + pass + +def DateTime_UNow(): + """""" + pass + +def DirSelector(): + """""" + pass + +def DisplayDepth(): + """""" + pass + +def DisplaySize(): + """""" + pass + +def DisplaySizeMM(): + """""" + pass + +def DragIcon(): + """""" + pass + +def DragListItem(): + """""" + pass + +def DragString(): + """""" + pass + +def DragTreeItem(): + """""" + pass + +def EmptyBitmap(): + """""" + pass + +def EmptyIcon(): + """""" + pass + +def EmptyImage(): + """""" + pass + +def EnableTopLevelWindows(): + """""" + pass + +def EncodingConverter_GetAllEquivalents(): + """""" + pass + +def EncodingConverter_GetPlatformEquivalents(): + """""" + pass + +def EndBusyCursor(): + """""" + pass + +def Execute(): + """""" + pass + +def FileSelector(): + """""" + pass + +def FileSystem_AddHandler(): + """""" + pass + +def FileSystem_CleanUpHandlers(): + """""" + pass + +def FileTypeInfoSequence(): + """""" + pass + +def FileType_ExpandCommand(): + """""" + pass + +def FindWindowAtPoint(): + """""" + pass + +def FindWindowById(id, parent=wx.NULL): + """""" + pass + +def FindWindowByLabel(label, parent=wx.NULL): + """""" + pass + +def FindWindowByName(name, parent=wx.NULL): + """""" + pass + +def FontFromNativeInfo(): + """""" + pass + +def FontMapper_Get(): + """""" + pass + +def FontMapper_GetDefaultConfigPath(): + """""" + pass + +def FontMapper_GetEncodingDescription(): + """""" + pass + +def FontMapper_GetEncodingName(): + """""" + pass + +def FontMapper_Set(): + """""" + pass + +def Font_GetDefaultEncoding(): + """""" + pass + +def Font_SetDefaultEncoding(): + """""" + pass + +def GenericFindWindowAtPoint(): + """""" + pass + +def GetAccelFromString(): + """""" + pass + +def GetActiveWindow(): + """""" + pass + +def GetApp(): + """""" + pass + +def GetClientDisplayRect(): + """""" + pass + +def GetCurrentId(): + """""" + pass + +def GetCurrentTime(): + """""" + pass + +def GetDisplayDepth(): + """""" + pass + +def GetDisplaySize(): + """""" + pass + +def GetDisplaySizeMM(): + """""" + pass + +def GetElapsedTime(): + """""" + pass + +def GetEmailAddress(): + """""" + pass + +def GetFullHostName(): + """""" + pass + +def GetHomeDir(): + """""" + pass + +def GetHostName(): + """""" + pass + +def GetLocalTime(): + """""" + pass + +def GetLocalTimeMillis(): + """""" + pass + +def GetLocale(): + """""" + pass + +def GetMousePosition(): + """""" + pass + +def GetNumberFromUser(): + """""" + pass + +def GetOsDescription(): + """""" + pass + +def GetOsVersion(): + """""" + pass + +def GetPasswordFromUser(): + """""" + pass + +def GetProcessId(): + """""" + pass + +def GetSingleChoice(): + """""" + pass + +def GetSingleChoiceIndex(): + """""" + pass + +def GetTextFromUser(): + """""" + pass + +def GetTopLevelParent(): + """""" + pass + +def GetTranslation(): + """""" + pass + +def GetUTCTime(): + """""" + pass + +def GetUserHome(): + """""" + pass + +def GetUserId(): + """""" + pass + +def GetUserName(): + """""" + pass + +def IconBundleFromFile(): + """""" + pass + +def IconBundleFromIcon(): + """""" + pass + +def IconFromBitmap(): + """""" + pass + +def IconFromXPMData(): + """""" + pass + +def ImageFromBitmap(): + """""" + pass + +def ImageFromData(): + """""" + pass + +def ImageFromMime(): + """""" + pass + +def ImageFromStream(): + """""" + pass + +def ImageFromStreamMime(): + """""" + pass + +def Image_AddHandler(): + """""" + pass + +def Image_CanRead(): + """""" + pass + +def Image_CanReadStream(): + """""" + pass + +def Image_GetImageCount(): + """""" + pass + +def Image_InsertHandler(): + """""" + pass + +def Image_RemoveHandler(): + """""" + pass + +def InitAllImageHandlers(): + """""" + pass + +def IntersectRect(): + """""" + pass + +def IsBusy(): + """""" + pass + +def IsDragResultOk(): + """""" + pass + +def LoadFileSelector(): + """""" + pass + +def Locale_AddCatalogLookupPathPrefix(): + """""" + pass + +def Locale_AddLanguage(): + """""" + pass + +def Locale_GetLanguageInfo(): + """""" + pass + +def Locale_GetSystemEncoding(): + """""" + pass + +def Locale_GetSystemEncodingName(): + """""" + pass + +def Locale_GetSystemLanguage(): + """""" + pass + +def LogDebug(): + """""" + pass + +def LogError(): + """""" + pass + +def LogFatalError(): + """""" + pass + +def LogGeneric(): + """""" + pass + +def LogInfo(): + """""" + pass + +def LogMessage(): + """""" + pass + +def LogStatus(): + """""" + pass + +def LogStatusFrame(): + """""" + pass + +def LogSysError(): + """""" + pass + +def LogTrace(): + """""" + pass + +def LogTraceMask(): + """""" + pass + +def LogVerbose(): + """""" + pass + +def LogWarning(): + """""" + pass + +def Log_AddTraceMask(): + """""" + pass + +def Log_ClearTraceMasks(): + """""" + pass + +def Log_DontCreateOnDemand(): + """""" + pass + +def Log_EnableLogging(): + """""" + pass + +def Log_FlushActive(): + """""" + pass + +def Log_GetActiveTarget(): + """""" + pass + +def Log_GetLogLevel(): + """""" + pass + +def Log_GetTimestamp(): + """""" + pass + +def Log_GetTraceMask(): + """""" + pass + +def Log_GetTraceMasks(): + """""" + pass + +def Log_IsAllowedTraceMask(): + """""" + pass + +def Log_IsEnabled(): + """""" + pass + +def Log_OnLog(): + """""" + pass + +def Log_RemoveTraceMask(): + """""" + pass + +def Log_Resume(): + """""" + pass + +def Log_SetActiveTarget(): + """""" + pass + +def Log_SetLogLevel(): + """""" + pass + +def Log_SetTimestamp(): + """""" + pass + +def Log_SetTraceMask(): + """""" + pass + +def Log_SetVerbose(): + """""" + pass + +def Log_Suspend(): + """""" + pass + +def MaskColour(): + """""" + pass + +def MemoryDCFromDC(): + """""" + pass + +def MemoryFSHandler_AddFile(): + """""" + pass + +def MemoryFSHandler_RemoveFile(): + """""" + pass + +def MenuItem_GetLabelFromText(): + """""" + pass + +def MessageBox(): + """""" + pass + +def MimeTypesManager_IsOfType(): + """""" + pass + +def MutexGuiEnter(): + """""" + pass + +def MutexGuiLeave(): + """""" + pass + +def NamedColour(): + """""" + pass + +def NamedColour(): + """""" + pass + +def NewEventType(): + """""" + pass + +def NewId(): + """""" + pass + +def Now(): + """""" + pass + +def NullFileTypeInfo(): + """""" + pass + +def Point2DDoubleCopy(): + """""" + pass + +def Point2DDoubleFromPoint(): + """""" + pass + +def PostEvent(): + """""" + pass + +def PostScriptDC_GetResolution(): + """""" + pass + +def PostScriptDC_SetResolution(): + """""" + pass + +def PreBitmapButton(): + """""" + pass + +def PreButton(): + """""" + pass + +def PreCheckBox(): + """""" + pass + +def PreCheckListBox(): + """""" + pass + +def PreChoice(): + """""" + pass + +def PreComboBox(): + """""" + pass + +def PreControl(): + """""" + pass + +def PreDialog(): + """""" + pass + +def PreDirFilterListCtrl(): + """""" + pass + +def PreFindReplaceDialog(): + """""" + pass + +def PreFrame(): + """""" + pass + +def PreGauge(): + """""" + pass + +def PreGenericDirCtrl(): + """""" + pass + +def PreListBox(): + """""" + pass + +def PreListCtrl(): + """""" + pass + +def PreListView(): + """""" + pass + +def PreMDIChildFrame(): + """""" + pass + +def PreMDIClientWindow(): + """""" + pass + +def PreMDIParentFrame(): + """""" + pass + +def PreMiniFrame(): + """""" + pass + +def PreNotebook(): + """""" + pass + +def PrePanel(): + """""" + pass + +def PrePopupTransientWindow(): + """""" + pass + +def PrePopupWindow(): + """""" + pass + +def PreRadioBox(): + """""" + pass + +def PreRadioButton(): + """""" + pass + +def PreSashLayoutWindow(): + """""" + pass + +def PreSashWindow(): + """""" + pass + +def PreScrollBar(): + """""" + pass + +def PreScrolledWindow(): + """""" + pass + +def PreSingleInstanceChecker(): + """""" + pass + +def PreSlider(): + """""" + pass + +def PreSpinButton(): + """""" + pass + +def PreSpinCtrl(): + """""" + pass + +def PreSplitterWindow(): + """""" + pass + +def PreStaticBitmap(): + """""" + pass + +def PreStaticBox(): + """""" + pass + +def PreStaticLine(): + """""" + pass + +def PreStaticText(): + """""" + pass + +def PreStatusBar(): + """""" + pass + +def PreTextCtrl(): + """""" + pass + +def PreToggleButton(): + """""" + pass + +def PreToolBar(): + """""" + pass + +def PreToolBarSimple(): + """""" + pass + +def PreTopLevelWindow(): + """""" + pass + +def PreTreeCtrl(): + """""" + pass + +def PreWindow(): + """""" + pass + +def Process_Exists(): + """""" + pass + +def Process_Kill(): + """""" + pass + +def Process_Open(): + """""" + pass + +def PyTypeCast(obj, typeStr): + """This helper function will take a wxPython object and convert it + to another wxPython object type. This will not be able to create + objects that are derived from wxPython classes by the user, only + those that are actually part of wxPython and directly corespond to + C++ objects. + + This is useful in situations where some method returns a generic + type such as wxWindow, but you know that it is actually some + derived type such as a TextCtrl. You can't call TextCtrl + specific methods on a Window object, but you can use this + function to create a TextCtrl object that will pass the same + pointer to the C++ code. You use it like this: + + textCtrl = PyTypeCast(window, "TextCtrl") + + WARNING: Using this function to type cast objects into types that + they are not is not recommended and is likely to cause + your program to crash... Hard.""" + pass + +def Py_isinstance(obj, klasses): + """An isinstance for Python < 2.2 that can check a sequence of + class objects like the one in 2.2 can.""" + pass + +def RegionFromPoints(): + """""" + pass + +def RegisterId(): + """""" + pass + +## def RunLater(callable, *args, **kw): +## """An alias for CallAfter.""" +## pass + +RunLater = CallAfter + +def SafeShowMessage(): + """""" + pass + +def SafeYield(): + """""" + pass + +def SaveFileSelector(): + """""" + pass + +def SetCursor(): + """""" + pass + +def Shell(): + """""" + pass + +def ShowTip(): + """""" + pass + +def Shutdown(): + """""" + pass + +def Sleep(): + """""" + pass + +def StartTimer(): + """""" + pass + +def StockCursor(): + """""" + pass + +def StripMenuCodes(): + """""" + pass + +def SysErrorCode(): + """""" + pass + +def SysErrorMsg(): + """""" + pass + +def SystemSettings_GetColour(): + """""" + pass + +def SystemSettings_GetFont(): + """""" + pass + +def SystemSettings_GetMetric(): + """""" + pass + +def SystemSettings_GetScreenType(): + """""" + pass + +def SystemSettings_GetColour(): + """""" + pass + +def SystemSettings_GetFont(): + """""" + pass + +def SystemSettings_GetMetric(): + """""" + pass + +def SystemSettings_HasFeature(): + """""" + pass + +def SystemSettings_SetScreenType(): + """""" + pass + +def TextAttr_Combine(): + """""" + pass + +def Thread_IsMain(): + """""" + pass + +def TimeSpan_Day(): + """""" + pass + +def TimeSpan_Days(): + """""" + pass + +def TimeSpan_Hour(): + """""" + pass + +def TimeSpan_Hours(): + """""" + pass + +def TimeSpan_Minute(): + """""" + pass + +def TimeSpan_Minutes(): + """""" + pass + +def TimeSpan_Second(): + """""" + pass + +def TimeSpan_Seconds(): + """""" + pass + +def TimeSpan_Week(): + """""" + pass + +def TimeSpan_Weeks(): + """""" + pass + +def ToolTip_Enable(): + """""" + pass + +def ToolTip_SetDelay(): + """""" + pass + +def Usleep(): + """""" + pass + +def Validator_IsSilent(): + """""" + pass + +def Validator_SetBellOnError(): + """""" + pass + +def WakeUpIdle(): + """""" + pass + +def WaveData(): + """""" + pass + +def Window_FindFocus(): + """""" + pass + +def Window_GetCapture(): + """""" + pass + +def Window_NewControlId(): + """""" + pass + +def Window_NextControlId(): + """""" + pass + +def Window_PrevControlId(): + """""" + pass + +def Yield(): + """""" + pass + +def YieldIfNeeded(): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Help.py b/wxPython/wxPython/lib/PyCrust/wxd/Help.py new file mode 100644 index 0000000000..e2518b37cc --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Help.py @@ -0,0 +1,127 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx +from Window import Window + + +class PopupWindow(Window): + """""" + + def Create(self): + """""" + pass + + def Position(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PopupTransientWindow(PopupWindow): + """""" + + def Dismiss(self): + """""" + pass + + def Popup(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class TipProvider: + """""" + + def GetCurrentTip(self): + """""" + pass + + def GetTip(self): + """""" + pass + + def PreprocessTip(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PyTipProvider(TipProvider): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class TipWindow(PopupTransientWindow): + """""" + + def Close(self): + """""" + pass + + def SetBoundingRect(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ToolTip(Object): + """""" + + def GetTip(self): + """""" + pass + + def GetWindow(self): + """""" + pass + + def SetTip(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/ImageHandlers.py b/wxPython/wxPython/lib/PyCrust/wxd/ImageHandlers.py new file mode 100644 index 0000000000..f034f394bb --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/ImageHandlers.py @@ -0,0 +1,142 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class ImageHandler(Object): + """""" + + def CanRead(self): + """""" + pass + + def GetExtension(self): + """""" + pass + + def GetMimeType(self): + """""" + pass + + def GetName(self): + """""" + pass + + def GetType(self): + """""" + pass + + def SetExtension(self): + """""" + pass + + def SetMimeType(self): + """""" + pass + + def SetName(self): + """""" + pass + + def SetType(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class BMPHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + +class GIFHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + +class ICOHandler(BMPHandler): + """""" + + def __init__(self): + """""" + pass + + +class CURHandler(ICOHandler): + """""" + + def __init__(self): + """""" + pass + + +class ANIHandler(CURHandler): + """""" + + def __init__(self): + """""" + pass + + +class JPEGHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + +class PCXHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + +class PNGHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + +class PNMHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + +class TIFFHandler(ImageHandler): + """""" + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Joystick.py b/wxPython/wxPython/lib/PyCrust/wxd/Joystick.py new file mode 100644 index 0000000000..2d787b63ce --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Joystick.py @@ -0,0 +1,197 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class Joystick(Object): + """""" + + def GetButtonState(self): + """""" + pass + + def GetManufacturerId(self): + """""" + pass + + def GetMaxAxes(self): + """""" + pass + + def GetMaxButtons(self): + """""" + pass + + def GetMovementThreshold(self): + """""" + pass + + def GetNumberAxes(self): + """""" + pass + + def GetNumberButtons(self): + """""" + pass + + def GetNumberJoysticks(self): + """""" + pass + + def GetPOVCTSPosition(self): + """""" + pass + + def GetPOVPosition(self): + """""" + pass + + def GetPollingMax(self): + """""" + pass + + def GetPollingMin(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetProductId(self): + """""" + pass + + def GetProductName(self): + """""" + pass + + def GetRudderMax(self): + """""" + pass + + def GetRudderMin(self): + """""" + pass + + def GetRudderPosition(self): + """""" + pass + + def GetUMax(self): + """""" + pass + + def GetUMin(self): + """""" + pass + + def GetUPosition(self): + """""" + pass + + def GetVMax(self): + """""" + pass + + def GetVMin(self): + """""" + pass + + def GetVPosition(self): + """""" + pass + + def GetXMax(self): + """""" + pass + + def GetXMin(self): + """""" + pass + + def GetYMax(self): + """""" + pass + + def GetYMin(self): + """""" + pass + + def GetZMax(self): + """""" + pass + + def GetZMin(self): + """""" + pass + + def GetZPosition(self): + """""" + pass + + def HasPOV(self): + """""" + pass + + def HasPOV4Dir(self): + """""" + pass + + def HasPOVCTS(self): + """""" + pass + + def HasRudder(self): + """""" + pass + + def HasU(self): + """""" + pass + + def HasV(self): + """""" + pass + + def HasZ(self): + """""" + pass + + def IsOk(self): + """""" + pass + + def ReleaseCapture(self): + """""" + pass + + def SetCapture(self): + """""" + pass + + def SetMovementThreshold(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/LayoutConstraints.py b/wxPython/wxPython/lib/PyCrust/wxd/LayoutConstraints.py new file mode 100644 index 0000000000..5017e62c43 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/LayoutConstraints.py @@ -0,0 +1,80 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class IndividualLayoutConstraint(Object): + """""" + + def Above(self): + """""" + pass + + def Absolute(self): + """""" + pass + + def AsIs(self): + """""" + pass + + def Below(self): + """""" + pass + + def LeftOf(self): + """""" + pass + + def PercentOf(self): + """""" + pass + + def RightOf(self): + """""" + pass + + def SameAs(self): + """""" + pass + + def Set(self): + """""" + pass + + def Unconstrained(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class LayoutConstraints(Object): + """""" + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Logging.py b/wxPython/wxPython/lib/PyCrust/wxd/Logging.py new file mode 100644 index 0000000000..ca2ed02d70 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Logging.py @@ -0,0 +1,145 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +class Log: + """""" + + def Flush(self): + """""" + pass + + def GetVerbose(self): + """""" + pass + + def HasPendingMessages(self): + """""" + pass + + def TimeStamp(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PyLog(Log): + """""" + + def Destroy(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class LogChain(Log): + """""" + + def GetOldLog(self): + """""" + pass + + def IsPassingMessages(self): + """""" + pass + + def PassMessages(self): + """""" + pass + + def SetLog(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class LogGui(Log): + """""" + + def __init__(self): + """""" + pass + + +class LogNull: + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class LogStderr(Log): + """""" + + def __init__(self): + """""" + pass + + +class LogTextCtrl(Log): + """""" + + def __init__(self): + """""" + pass + + +class LogWindow(Log): + """""" + + def GetFrame(self): + """""" + pass + + def GetOldLog(self): + """""" + pass + + def IsPassingMessages(self): + """""" + pass + + def PassMessages(self): + """""" + pass + + def Show(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Menus.py b/wxPython/wxPython/lib/PyCrust/wxd/Menus.py new file mode 100644 index 0000000000..3ec16fd151 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Menus.py @@ -0,0 +1,477 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object, EvtHandler +import Parameters as wx +from Window import Window + + +class FileHistory(Object): + """""" + + def AddFileToHistory(self): + """""" + pass + + def AddFilesToMenu(self): + """""" + pass + + def AddFilesToThisMenu(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def GetHistoryFile(self): + """""" + pass + + def GetMaxFiles(self): + """""" + pass + + def GetNoHistoryFiles(self): + """""" + pass + + def Load(self): + """""" + pass + + def RemoveFileFromHistory(self): + """""" + pass + + def RemoveMenu(self): + """""" + pass + + def Save(self): + """""" + pass + + def UseMenu(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Menu(EvtHandler): + """""" + + def Append(self): + """""" + pass + + def AppendCheckItem(self): + """""" + pass + + def AppendItem(self): + """""" + pass + + def AppendMenu(self): + """""" + pass + + def AppendRadioItem(self): + """""" + pass + + def AppendSeparator(self): + """""" + pass + + def Break(self): + """""" + pass + + def Check(self): + """""" + pass + + def Delete(self): + """""" + pass + + def DeleteItem(self): + """""" + pass + + def Destroy(self): + """""" + pass + + def DestroyId(self): + """""" + pass + + def DestroyItem(self): + """""" + pass + + def Enable(self): + """""" + pass + + def FindItem(self): + """""" + pass + + def FindItemById(self): + """""" + pass + + def GetEventHandler(self): + """""" + pass + + def GetHelpString(self): + """""" + pass + + def GetInvokingWindow(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetMenuItemCount(self): + """""" + pass + + def GetMenuItems(self): + """""" + pass + + def GetParent(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetTitle(self): + """""" + pass + + def Insert(self): + """""" + pass + + def InsertCheckItem(self): + """""" + pass + + def InsertItem(self): + """""" + pass + + def InsertMenu(self): + """""" + pass + + def InsertRadioItem(self): + """""" + pass + + def InsertSeparator(self): + """""" + pass + + def IsAttached(self): + """""" + pass + + def IsChecked(self): + """""" + pass + + def IsEnabled(self): + """""" + pass + + def Prepend(self): + """""" + pass + + def PrependCheckItem(self): + """""" + pass + + def PrependItem(self): + """""" + pass + + def PrependMenu(self): + """""" + pass + + def PrependRadioItem(self): + """""" + pass + + def PrependSeparator(self): + """""" + pass + + def Remove(self): + """""" + pass + + def RemoveItem(self): + """""" + pass + + def SetEventHandler(self): + """""" + pass + + def SetHelpString(self): + """""" + pass + + def SetInvokingWindow(self): + """""" + pass + + def SetLabel(self): + """""" + pass + + def SetParent(self): + """""" + pass + + def SetTitle(self): + """""" + pass + + def UpdateUI(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class MenuBar(Window): + """""" + + def Append(self): + """""" + pass + + def Check(self): + """""" + pass + + def Enable(self): + """""" + pass + + def EnableTop(self): + """""" + pass + + def FindItemById(self): + """""" + pass + + def FindMenu(self): + """""" + pass + + def FindMenuItem(self): + """""" + pass + + def GetHelpString(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetLabelTop(self): + """""" + pass + + def GetMenu(self): + """""" + pass + + def GetMenuCount(self): + """""" + pass + + def Insert(self): + """""" + pass + + def IsChecked(self): + """""" + pass + + def IsEnabled(self): + """""" + pass + + def IsEnabledTop(self): + """""" + pass + + def Remove(self): + """""" + pass + + def Replace(self): + """""" + pass + + def SetHelpString(self): + """""" + pass + + def SetLabel(self): + """""" + pass + + def SetLabelTop(self): + """""" + pass + + def __init__(self): + """""" + pass + +class MenuItem(Object): + """""" + + def Check(self): + """""" + pass + + def Enable(self): + """""" + pass + + def GetAccel(self): + """""" + pass + + def GetBitmap(self): + """""" + pass + + def GetHelp(self): + """""" + pass + + def GetId(self): + """""" + pass + + def GetKind(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetMenu(self): + """""" + pass + + def GetSubMenu(self): + """""" + pass + + def GetText(self): + """""" + pass + + def IsCheckable(self): + """""" + pass + + def IsChecked(self): + """""" + pass + + def IsEnabled(self): + """""" + pass + + def IsSeparator(self): + """""" + pass + + def IsSubMenu(self): + """""" + pass + + def SetAccel(self): + """""" + pass + + def SetBitmap(self): + """""" + pass + + def SetCheckable(self): + """""" + pass + + def SetHelp(self): + """""" + pass + + def SetId(self): + """""" + pass + + def SetSubMenu(self): + """""" + pass + + def SetText(self): + """""" + pass + + def Toggle(self): + """""" + pass + + def __init__(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/MimeTypes.py b/wxPython/wxPython/lib/PyCrust/wxd/MimeTypes.py new file mode 100644 index 0000000000..2637b3dd37 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/MimeTypes.py @@ -0,0 +1,185 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx + + +class FileType: + """""" + + def GetAllCommands(self): + """""" + pass + + def GetDescription(self): + """""" + pass + + def GetExtensions(self): + """""" + pass + + def GetIcon(self): + """""" + pass + + def GetIconInfo(self): + """""" + pass + + def GetMimeType(self): + """""" + pass + + def GetMimeTypes(self): + """""" + pass + + def GetOpenCommand(self): + """""" + pass + + def GetPrintCommand(self): + """""" + pass + + def SetCommand(self): + """""" + pass + + def SetDefaultIcon(self): + """""" + pass + + def Unassociate(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FileTypeInfo: + """""" + + def GetDescription(self): + """""" + pass + + def GetExtensions(self): + """""" + pass + + def GetExtensionsCount(self): + """""" + pass + + def GetIconFile(self): + """""" + pass + + def GetIconIndex(self): + """""" + pass + + def GetMimeType(self): + """""" + pass + + def GetOpenCommand(self): + """""" + pass + + def GetPrintCommand(self): + """""" + pass + + def GetShortDesc(self): + """""" + pass + + def IsValid(self): + """""" + pass + + def SetIcon(self): + """""" + pass + + def SetShortDesc(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class MimeTypesManager: + """""" + + def AddFallback(self): + """""" + pass + + def Associate(self): + """""" + pass + + def ClearData(self): + """""" + pass + + def EnumAllFileTypes(self): + """""" + pass + + def GetFileTypeFromExtension(self): + """""" + pass + + def GetFileTypeFromMimeType(self): + """""" + pass + + def Initialize(self): + """""" + pass + + def ReadMailcap(self): + """""" + pass + + def ReadMimeTypes(self): + """""" + pass + + def Unassociate(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Misc.py b/wxPython/wxPython/lib/PyCrust/wxd/Misc.py new file mode 100644 index 0000000000..132e85cea8 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Misc.py @@ -0,0 +1,558 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class ArtProvider(Object): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class BusyCursor: + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class BusyInfo(Object): + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Caret: + """""" + + def GetPosition(self): + """""" + pass + + def GetPositionTuple(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def GetSizeTuple(self): + """""" + pass + + def GetWindow(self): + """""" + pass + + def Hide(self): + """""" + pass + + def IsOk(self): + """""" + pass + + def IsVisible(self): + """""" + pass + + def Move(self): + """""" + pass + + def MoveXY(self): + """""" + pass + + def SetSize(self): + """""" + pass + + def SetSizeWH(self): + """""" + pass + + def Show(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class EncodingConverter(Object): + """""" + + def Convert(self): + """""" + pass + + def Init(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class DirItemData(Object): + """""" + + def SetNewDirName(self): + """""" + pass + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class Effects(Object): + """""" + + def DrawSunkenEdge(self): + """""" + pass + + def GetDarkShadow(self): + """""" + pass + + def GetFaceColour(self): + """""" + pass + + def GetHighlightColour(self): + """""" + pass + + def GetLightShadow(self): + """""" + pass + + def GetMediumShadow(self): + """""" + pass + + def Set(self): + """""" + pass + + def SetDarkShadow(self): + """""" + pass + + def SetFaceColour(self): + """""" + pass + + def SetHighlightColour(self): + """""" + pass + + def SetLightShadow(self): + """""" + pass + + def SetMediumShadow(self): + """""" + pass + + def TileBitmap(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FontEnumerator: + """""" + + def EnumerateEncodings(self): + """""" + pass + + def EnumerateFacenames(self): + """""" + pass + + def GetEncodings(self): + """""" + pass + + def GetFacenames(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class FontMapper: + """""" + + def CharsetToEncoding(self): + """""" + pass + + def GetAltForEncoding(self): + """""" + pass + + def IsEncodingAvailable(self): + """""" + pass + + def SetConfig(self): + """""" + pass + + def SetConfigPath(self): + """""" + pass + + def SetDialogParent(self): + """""" + pass + + def SetDialogTitle(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class LanguageInfo: + """""" + + def __getattr__(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __setattr__(self): + """""" + pass + + +class Locale: + """""" + + def AddCatalog(self): + """""" + pass + + def GetCanonicalName(self): + """""" + pass + + def GetLanguage(self): + """""" + pass + + def GetLocale(self): + """""" + pass + + def GetName(self): + """""" + pass + + def GetString(self): + """""" + pass + + def GetSysName(self): + """""" + pass + + def Init(self): + """""" + pass + + def IsLoaded(self): + """""" + pass + + def IsOk(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class NativeFontInfo: + """""" + + def FromString(self): + """""" + pass + + def FromUserString(self): + """""" + pass + + def GetEncoding(self): + """""" + pass + + def GetFaceName(self): + """""" + pass + + def GetFamily(self): + """""" + pass + + def GetPointSize(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetUnderlined(self): + """""" + pass + + def GetWeight(self): + """""" + pass + + def Init(self): + """""" + pass + + def SetEncoding(self): + """""" + pass + + def SetFaceName(self): + """""" + pass + + def SetFamily(self): + """""" + pass + + def SetPointSize(self): + """""" + pass + + def SetStyle(self): + """""" + pass + + def SetUnderlined(self): + """""" + pass + + def SetWeight(self): + """""" + pass + + def ToString(self): + """""" + pass + + def ToUserString(self): + """""" + pass + + def __init__(self): + """""" + pass + + def __str__(self): + """""" + pass + + +class PyTimer(Object): + """""" + + def GetInterval(self): + """""" + pass + + def IsOneShot(self): + """""" + pass + + def IsRunning(self): + """""" + pass + + def SetOwner(self): + """""" + pass + + def Start(self): + """""" + pass + + def Stop(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class StopWatch: + """""" + + def Pause(self): + """""" + pass + + def Resume(self): + """""" + pass + + def Start(self): + """""" + pass + + def Time(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SystemSettings: + """""" + + def __init__(self): + """""" + pass + + +class Timer(PyTimer): + """""" + + def __init__(self, evtHandler=None, id=-1): + """Create a Timer instance.""" + pass + + +class Wave(Object): + """""" + + def IsOk(self): + """""" + pass + + def Play(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class WindowDisabler: + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Panel.py b/wxPython/wxPython/lib/PyCrust/wxd/Panel.py new file mode 100644 index 0000000000..41e535b7ce --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Panel.py @@ -0,0 +1,240 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx +from Window import Window + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class Panel(Window): + """""" + + def __init__(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.TAB_TRAVERSAL, + name=wx.PyPanelNameStr): + """""" + pass + + def Create(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.TAB_TRAVERSAL, + name=wx.PyPanelNameStr): + """""" + pass + + def InitDialog(self): + """""" + pass + + +class PyPanel(Panel): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_AcceptsFocus(self): + """""" + pass + + def base_AcceptsFocusFromKeyboard(self): + """""" + pass + + def base_AddChild(self): + """""" + pass + + def base_DoGetBestSize(self): + """""" + pass + + def base_DoGetClientSize(self): + """""" + pass + + def base_DoGetPosition(self): + """""" + pass + + def base_DoGetSize(self): + """""" + pass + + def base_DoGetVirtualSize(self): + """""" + pass + + def base_DoMoveWindow(self): + """""" + pass + + def base_DoSetClientSize(self): + """""" + pass + + def base_DoSetSize(self): + """""" + pass + + def base_DoSetVirtualSize(self): + """""" + pass + + def base_GetMaxSize(self): + """""" + pass + + def base_InitDialog(self): + """""" + pass + + def base_RemoveChild(self): + """""" + pass + + def base_TransferDataFromWindow(self): + """""" + pass + + def base_TransferDataToWindow(self): + """""" + pass + + def base_Validate(self): + """""" + pass + + +class ScrolledWindow(Panel): + """""" + + def __init__(self, parent, id=-1, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.HSCROLL|wx.VSCROLL, + name=wx.PyPanelNameStr): + """""" + pass + + def Create(self, parent, id=-1, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=wx.HSCROLL|wx.VSCROLL, + name=wx.PyPanelNameStr): + """""" + pass + + def AdjustScrollbars(self): + """""" + pass + + def CalcScrolledPosition(self, *args): + """*args can be a point or (x, y) tuple""" + pass + + def CalcScrolledPosition1(self, pt): + """""" + pass + + def CalcScrolledPosition2(self, x, y): + """""" + pass + + def CalcUnscrolledPosition(self, *args): + """*args can be a point or (x, y) tuple""" + pass + + def CalcUnscrolledPosition1(self, pt): + """""" + pass + + def CalcUnscrolledPosition2(self, x, y): + """""" + pass + + def EnableScrolling(self, xScrolling, yScrolling): + """""" + pass + + def GetScaleX(self): + """""" + pass + + def GetScaleY(self): + """""" + pass + + def GetScrollPageSize(self, orient): + """""" + pass + + def GetScrollPixelsPerUnit(self): + """""" + pass + + def GetTargetWindow(self): + """""" + pass + + def GetViewStart(self): + """""" + pass + + def IsRetained(self): + """""" + pass + + def Layout(self): + """""" + pass + + def PrepareDC(self, dc): + """""" + pass + + def Scroll(self, x, y): + """""" + pass + + def SetScale(self, xs, ys): + """""" + pass + + def SetScrollPageSize(self, orient, pageSize): + """""" + pass + + def SetScrollRate(self, xstep, ystep): + """Set the x, y scrolling increments.""" + pass + + def SetScrollbars(self, pixelsPerUnitX, pixelsPerUnitY, + noUnitsX, noUnitsY, xPos=0, yPos=0, noRefresh=False): + """""" + pass + + def SetTargetWindow(self, window): + """""" + pass + + def ViewStart(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Parameters.py b/wxPython/wxPython/lib/PyCrust/wxd/Parameters.py new file mode 100644 index 0000000000..2bc3c79592 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Parameters.py @@ -0,0 +1,68 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +class _Param: + """Used by this module to represent default wxPython parameter values, + including parameter representations like style=wx.HSCROLL|wx.VSCROLL.""" + + def __init__(self, value=None): + if value is None: + value = 'wx.' + self.__class__.__name__ + self.value = value + + def __repr__(self): + return self.value + + def __or__(self, other): + value = '%s|%s' % (self, other) + return self.__class__(value) + +_params = ( + 'BOTH', + 'DEFAULT_FRAME_STYLE', + 'DefaultPosition', + 'DefaultSize', + 'DefaultValidator', + 'EmptyString', + 'EVT_NULL', + 'HSCROLL', + 'NO_BORDER', + 'NULL', + 'NullColour', + 'PyFrameNameStr', + 'PyNOTEBOOK_NAME', + 'PyPanelNameStr', + 'PyStatusLineNameStr', + 'PySTCNameStr', + 'PyToolBarNameStr', + 'SIZE_AUTO', + 'SIZE_USE_EXISTING', + 'ST_SIZEGRIP', + 'TAB_TRAVERSAL', + 'TB_HORIZONTAL', + 'VSCROLL', + ) + +## Create classes, then instances, like this: + +## class BOTH(Param): pass +## BOTH = BOTH() + +for _param in _params: + exec 'class %s(_Param): pass' % _param + exec '%s = %s()' % (_param, _param) + +del _param +del _params +del _Param diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Printing.py b/wxPython/wxPython/lib/PyCrust/wxd/Printing.py new file mode 100644 index 0000000000..e51d4e0e8c --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Printing.py @@ -0,0 +1,651 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +from Dialogs import Dialog +from Frames import Frame +import Parameters as wx + + +class PageSetupDialog(Dialog): + """""" + + def GetPageSetupData(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PageSetupDialogData(Object): + """""" + + def EnableHelp(self): + """""" + pass + + def EnableMargins(self): + """""" + pass + + def EnableOrientation(self): + """""" + pass + + def EnablePaper(self): + """""" + pass + + def EnablePrinter(self): + """""" + pass + + def GetDefaultInfo(self): + """""" + pass + + def GetDefaultMinMargins(self): + """""" + pass + + def GetEnableHelp(self): + """""" + pass + + def GetEnableMargins(self): + """""" + pass + + def GetEnableOrientation(self): + """""" + pass + + def GetEnablePaper(self): + """""" + pass + + def GetEnablePrinter(self): + """""" + pass + + def GetMarginBottomRight(self): + """""" + pass + + def GetMarginTopLeft(self): + """""" + pass + + def GetMinMarginBottomRight(self): + """""" + pass + + def GetMinMarginTopLeft(self): + """""" + pass + + def GetPaperId(self): + """""" + pass + + def GetPaperSize(self): + """""" + pass + + def GetPrintData(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetDefaultInfo(self): + """""" + pass + + def SetDefaultMinMargins(self): + """""" + pass + + def SetMarginBottomRight(self): + """""" + pass + + def SetMarginTopLeft(self): + """""" + pass + + def SetMinMarginBottomRight(self): + """""" + pass + + def SetMinMarginTopLeft(self): + """""" + pass + + def SetPaperId(self): + """""" + pass + + def SetPaperSize(self): + """""" + pass + + def SetPrintData(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PrintDialog(Dialog): + """""" + + def GetPrintDC(self): + """""" + pass + + def GetPrintDialogData(self): + """""" + pass + + def ShowModal(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PrintDialogData(Object): + """""" + + def EnableHelp(self): + """""" + pass + + def EnablePageNumbers(self): + """""" + pass + + def EnablePrintToFile(self): + """""" + pass + + def EnableSelection(self): + """""" + pass + + def GetAllPages(self): + """""" + pass + + def GetCollate(self): + """""" + pass + + def GetFromPage(self): + """""" + pass + + def GetMaxPage(self): + """""" + pass + + def GetMinPage(self): + """""" + pass + + def GetNoCopies(self): + """""" + pass + + def GetPrintData(self): + """""" + pass + + def GetPrintToFile(self): + """""" + pass + + def GetToPage(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetCollate(self): + """""" + pass + + def SetFromPage(self): + """""" + pass + + def SetMaxPage(self): + """""" + pass + + def SetMinPage(self): + """""" + pass + + def SetNoCopies(self): + """""" + pass + + def SetPrintData(self): + """""" + pass + + def SetPrintToFile(self): + """""" + pass + + def SetSetupDialog(self): + """""" + pass + + def SetToPage(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PreviewFrame(Frame): + """""" + + def Initialize(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PrintData(Object): + """""" + + def GetCollate(self): + """""" + pass + + def GetColour(self): + """""" + pass + + def GetDuplex(self): + """""" + pass + + def GetFilename(self): + """""" + pass + + def GetFontMetricPath(self): + """""" + pass + + def GetNoCopies(self): + """""" + pass + + def GetOrientation(self): + """""" + pass + + def GetPaperId(self): + """""" + pass + + def GetPaperSize(self): + """""" + pass + + def GetPreviewCommand(self): + """""" + pass + + def GetPrintMode(self): + """""" + pass + + def GetPrinterCommand(self): + """""" + pass + + def GetPrinterName(self): + """""" + pass + + def GetPrinterOptions(self): + """""" + pass + + def GetPrinterScaleX(self): + """""" + pass + + def GetPrinterScaleY(self): + """""" + pass + + def GetPrinterTranslateX(self): + """""" + pass + + def GetPrinterTranslateY(self): + """""" + pass + + def GetQuality(self): + """""" + pass + + def Ok(self): + """""" + pass + + def SetCollate(self): + """""" + pass + + def SetColour(self): + """""" + pass + + def SetDuplex(self): + """""" + pass + + def SetFilename(self): + """""" + pass + + def SetFontMetricPath(self): + """""" + pass + + def SetNoCopies(self): + """""" + pass + + def SetOrientation(self): + """""" + pass + + def SetPaperId(self): + """""" + pass + + def SetPaperSize(self): + """""" + pass + + def SetPreviewCommand(self): + """""" + pass + + def SetPrintMode(self): + """""" + pass + + def SetPrinterCommand(self): + """""" + pass + + def SetPrinterName(self): + """""" + pass + + def SetPrinterOptions(self): + """""" + pass + + def SetPrinterScaleX(self): + """""" + pass + + def SetPrinterScaleY(self): + """""" + pass + + def SetPrinterScaling(self): + """""" + pass + + def SetPrinterTranslateX(self): + """""" + pass + + def SetPrinterTranslateY(self): + """""" + pass + + def SetPrinterTranslation(self): + """""" + pass + + def SetQuality(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PrintPreview(Object): + """""" + + def GetCanvas(self): + """""" + pass + + def GetCurrentPage(self): + """""" + pass + + def GetFrame(self): + """""" + pass + + def GetMaxPage(self): + """""" + pass + + def GetMinPage(self): + """""" + pass + + def GetPrintDialogData(self): + """""" + pass + + def GetPrintout(self): + """""" + pass + + def GetPrintoutForPrinting(self): + """""" + pass + + def GetZoom(self): + """""" + pass + + def Ok(self): + """""" + pass + + def Print(self): + """""" + pass + + def SetCanvas(self): + """""" + pass + + def SetCurrentPage(self): + """""" + pass + + def SetFrame(self): + """""" + pass + + def SetPrintout(self): + """""" + pass + + def SetZoom(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Printer(Object): + """""" + + def CreateAbortWindow(self): + """""" + pass + + def GetPrintDialogData(self): + """""" + pass + + def Print(self): + """""" + pass + + def PrintDialog(self): + """""" + pass + + def ReportError(self): + """""" + pass + + def Setup(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class Printout(Object): + """""" + + def Destroy(self): + """""" + pass + + def GetDC(self): + """""" + pass + + def GetPPIPrinter(self): + """""" + pass + + def GetPPIScreen(self): + """""" + pass + + def GetPageSizeMM(self): + """""" + pass + + def GetPageSizePixels(self): + """""" + pass + + def IsPreview(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_GetPageInfo(self): + """""" + pass + + def base_HasPage(self): + """""" + pass + + def base_OnBeginDocument(self): + """""" + pass + + def base_OnBeginPrinting(self): + """""" + pass + + def base_OnEndDocument(self): + """""" + pass + + def base_OnEndPrinting(self): + """""" + pass + + def base_OnPreparePrinting(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Process.py b/wxPython/wxPython/lib/PyCrust/wxd/Process.py new file mode 100644 index 0000000000..97c410eaf2 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Process.py @@ -0,0 +1,77 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import EvtHandler + + +class Process(EvtHandler): + """""" + + def CloseOutput(self): + """""" + pass + + def Destroy(self): + """""" + pass + + def Detach(self): + """""" + pass + + def GetErrorStream(self): + """""" + pass + + def GetInputStream(self): + """""" + pass + + def GetOutputStream(self): + """""" + pass + + def IsErrorAvailable(self): + """""" + pass + + def IsInputAvailable(self): + """""" + pass + + def IsInputOpened(self): + """""" + pass + + def IsRedirected(self): + """""" + pass + + def Redirect(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_OnTerminate(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/SashSplitter.py b/wxPython/wxPython/lib/PyCrust/wxd/SashSplitter.py new file mode 100644 index 0000000000..fd35e0c718 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/SashSplitter.py @@ -0,0 +1,226 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +import Parameters as wx +from Window import Window + + +class SashWindow(Window): + """""" + + def Create(self): + """""" + pass + + def GetDefaultBorderSize(self): + """""" + pass + + def GetEdgeMargin(self): + """""" + pass + + def GetExtraBorderSize(self): + """""" + pass + + def GetMaximumSizeX(self): + """""" + pass + + def GetMaximumSizeY(self): + """""" + pass + + def GetMinimumSizeX(self): + """""" + pass + + def GetMinimumSizeY(self): + """""" + pass + + def GetSashVisible(self): + """""" + pass + + def HasBorder(self): + """""" + pass + + def SetDefaultBorderSize(self): + """""" + pass + + def SetExtraBorderSize(self): + """""" + pass + + def SetMaximumSizeX(self): + """""" + pass + + def SetMaximumSizeY(self): + """""" + pass + + def SetMinimumSizeX(self): + """""" + pass + + def SetMinimumSizeY(self): + """""" + pass + + def SetSashBorder(self): + """""" + pass + + def SetSashVisible(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SashLayoutWindow(SashWindow): + """""" + + def Create(self): + """""" + pass + + def GetAlignment(self): + """""" + pass + + def GetOrientation(self): + """""" + pass + + def SetAlignment(self): + """""" + pass + + def SetDefaultSize(self): + """""" + pass + + def SetOrientation(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class SplitterWindow(Window): + """""" + + def Create(self): + """""" + pass + + def GetBorderSize(self): + """""" + pass + + def GetMinimumPaneSize(self): + """""" + pass + + def GetNeedUpdating(self): + """""" + pass + + def GetSashPosition(self): + """""" + pass + + def GetSashSize(self): + """""" + pass + + def GetSplitMode(self): + """""" + pass + + def GetWindow1(self): + """""" + pass + + def GetWindow2(self): + """""" + pass + + def Initialize(self): + """""" + pass + + def IsSplit(self): + """""" + pass + + def ReplaceWindow(self): + """""" + pass + + def SetBorderSize(self): + """""" + pass + + def SetMinimumPaneSize(self): + """""" + pass + + def SetNeedUpdating(self): + """""" + pass + + def SetSashPosition(self): + """""" + pass + + def SetSashSize(self): + """""" + pass + + def SetSplitMode(self): + """""" + pass + + def SizeWindows(self): + """""" + pass + + def SplitHorizontally(self): + """""" + pass + + def SplitVertically(self): + """""" + pass + + def Unsplit(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Sizers.py b/wxPython/wxPython/lib/PyCrust/wxd/Sizers.py new file mode 100644 index 0000000000..44446b3d51 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Sizers.py @@ -0,0 +1,488 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +import Parameters as wx + + +class Sizer(Object): + """""" + + def Add(self): + """""" + pass + + def AddMany(self): + """""" + pass + + def AddSizer(self): + """""" + pass + + def AddSpacer(self): + """""" + pass + + def AddWindow(self): + """""" + pass + + def Clear(self): + """""" + pass + + def DeleteWindows(self): + """""" + pass + + def Destroy(self): + """""" + pass + + def Fit(self): + """""" + pass + + def FitInside(self): + """""" + pass + + def GetChildren(self): + """""" + pass + + def GetMinSize(self): + """""" + pass + + def GetMinSizeTuple(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetPositionTuple(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def GetSizeTuple(self): + """""" + pass + + def Hide(self): + """""" + pass + + def HideSizer(self): + """""" + pass + + def HideWindow(self): + """""" + pass + + def Insert(self): + """""" + pass + + def InsertSizer(self): + """""" + pass + + def InsertSpacer(self): + """""" + pass + + def InsertWindow(self): + """""" + pass + + def IsShown(self): + """""" + pass + + def IsShownSizer(self): + """""" + pass + + def IsShownWindow(self): + """""" + pass + + def Layout(self): + """""" + pass + + def Prepend(self): + """""" + pass + + def PrependSizer(self): + """""" + pass + + def PrependSpacer(self): + """""" + pass + + def PrependWindow(self): + """""" + pass + + def Remove(self): + """""" + pass + + def RemovePos(self): + """""" + pass + + def RemoveSizer(self): + """""" + pass + + def RemoveWindow(self): + """""" + pass + + def SetDimension(self): + """""" + pass + + def SetItemMinSize(self): + """""" + pass + + def SetItemMinSizePos(self): + """""" + pass + + def SetItemMinSizeSizer(self): + """""" + pass + + def SetItemMinSizeWindow(self): + """""" + pass + + def SetMinSize(self): + """""" + pass + + def SetSizeHints(self): + """""" + pass + + def SetVirtualSizeHints(self): + """""" + pass + + def Show(self): + """""" + pass + + def ShowItems(self): + """""" + pass + + def ShowSizer(self): + """""" + pass + + def ShowWindow(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setOORInfo(self): + """""" + pass + + +class SizerItem(Object): + """""" + + def CalcMin(self): + """""" + pass + + def DeleteWindows(self): + """""" + pass + + def GetBorder(self): + """""" + pass + + def GetFlag(self): + """""" + pass + + def GetOption(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetRatio(self): + """""" + pass + + def GetSize(self): + """""" + pass + + def GetSizer(self): + """""" + pass + + def GetUserData(self): + """""" + pass + + def GetWindow(self): + """""" + pass + + def IsShown(self): + """""" + pass + + def IsSizer(self): + """""" + pass + + def IsSpacer(self): + """""" + pass + + def IsWindow(self): + """""" + pass + + def SetBorder(self): + """""" + pass + + def SetDimension(self): + """""" + pass + + def SetFlag(self): + """""" + pass + + def SetInitSize(self): + """""" + pass + + def SetOption(self): + """""" + pass + + def SetRatio(self): + """""" + pass + + def SetRatioSize(self): + """""" + pass + + def SetRatioWH(self): + """""" + pass + + def SetSizer(self): + """""" + pass + + def SetWindow(self): + """""" + pass + + def Show(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class BoxSizer(Sizer): + """""" + + def CalcMin(self): + """""" + pass + + def GetOrientation(self): + """""" + pass + + def RecalcSizes(self): + """""" + pass + + def SetOrientation(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class GridSizer(Sizer): + """""" + + def CalcMin(self): + """""" + pass + + def GetCols(self): + """""" + pass + + def GetHGap(self): + """""" + pass + + def GetRows(self): + """""" + pass + + def GetVGap(self): + """""" + pass + + def RecalcSizes(self): + """""" + pass + + def SetCols(self): + """""" + pass + + def SetHGap(self): + """""" + pass + + def SetRows(self): + """""" + pass + + def SetVGap(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class FlexGridSizer(GridSizer): + """""" + + def AddGrowableCol(self): + """""" + pass + + def AddGrowableRow(self): + """""" + pass + + def CalcMin(self): + """""" + pass + + def RecalcSizes(self): + """""" + pass + + def RemoveGrowableCol(self): + """""" + pass + + def RemoveGrowableRow(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class NotebookSizer(Sizer): + """""" + + def CalcMin(self): + """""" + pass + + def GetNotebook(self): + """""" + pass + + def RecalcSizes(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class PySizer(Sizer): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class StaticBoxSizer(BoxSizer): + """""" + + def CalcMin(self): + """""" + pass + + def GetStaticBox(self): + """""" + pass + + def RecalcSizes(self): + """""" + pass + + def __init__(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Streams.py b/wxPython/wxPython/lib/PyCrust/wxd/Streams.py new file mode 100644 index 0000000000..a08b7b336b --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Streams.py @@ -0,0 +1,96 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +class InputStream: + """""" + + def CanRead(self): + """""" + pass + + def Eof(self): + """""" + pass + + def GetC(self): + """""" + pass + + def LastRead(self): + """""" + pass + + def Peek(self): + """""" + pass + + def SeekI(self): + """""" + pass + + def TellI(self): + """""" + pass + + def Ungetch(self): + """""" + pass + + def __init__(self): + """""" + pass + + def close(self): + """""" + pass + + def eof(self): + """""" + pass + + def flush(self): + """""" + pass + + def read(self): + """""" + pass + + def readline(self): + """""" + pass + + def readlines(self): + """""" + pass + + def seek(self): + """""" + pass + + def tell(self): + """""" + pass + + +class OutputStream: + """""" + + def __init__(self): + """""" + pass + + def write(self): + """""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/StyledTextConstants.py b/wxPython/wxPython/lib/PyCrust/wxd/StyledTextConstants.py new file mode 100644 index 0000000000..0dced840ff --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/StyledTextConstants.py @@ -0,0 +1,643 @@ +"""wxStyledTextControl constants for documentation. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +from wxPython import wx +from wxPython import stc + + +""" +>>> from wxPython import stc_c +>>> def gen_constants(): +... print '# Begin generated constants.' +... for item in dir(stc_c): # dir returns a sorted list. +... if not callable(stc_c.__dict__[item]) \ +... and not item.startswith('__'): +... print item, '=', 'stc.' + item, ' #', \ +... repr(stc_c.__dict__[item]) +... print '# End generated constants.' + +""" + +# Begin generated constants. +STC_USE_DND = stc.STC_USE_DND # 1 +wxEVT_STC_CHANGE = stc.wxEVT_STC_CHANGE # 10206 +wxEVT_STC_CHARADDED = stc.wxEVT_STC_CHARADDED # 10208 +wxEVT_STC_DOUBLECLICK = stc.wxEVT_STC_DOUBLECLICK # 10213 +wxEVT_STC_DO_DROP = stc.wxEVT_STC_DO_DROP # 10227 +wxEVT_STC_DRAG_OVER = stc.wxEVT_STC_DRAG_OVER # 10226 +wxEVT_STC_DWELLEND = stc.wxEVT_STC_DWELLEND # 10224 +wxEVT_STC_DWELLSTART = stc.wxEVT_STC_DWELLSTART # 10223 +wxEVT_STC_KEY = stc.wxEVT_STC_KEY # 10212 +wxEVT_STC_MACRORECORD = stc.wxEVT_STC_MACRORECORD # 10216 +wxEVT_STC_MARGINCLICK = stc.wxEVT_STC_MARGINCLICK # 10217 +wxEVT_STC_MODIFIED = stc.wxEVT_STC_MODIFIED # 10215 +wxEVT_STC_NEEDSHOWN = stc.wxEVT_STC_NEEDSHOWN # 10218 +wxEVT_STC_PAINTED = stc.wxEVT_STC_PAINTED # 10220 +wxEVT_STC_POSCHANGED = stc.wxEVT_STC_POSCHANGED # 10219 +wxEVT_STC_ROMODIFYATTEMPT = stc.wxEVT_STC_ROMODIFYATTEMPT # 10211 +wxEVT_STC_SAVEPOINTLEFT = stc.wxEVT_STC_SAVEPOINTLEFT # 10210 +wxEVT_STC_SAVEPOINTREACHED = stc.wxEVT_STC_SAVEPOINTREACHED # 10209 +wxEVT_STC_START_DRAG = stc.wxEVT_STC_START_DRAG # 10225 +wxEVT_STC_STYLENEEDED = stc.wxEVT_STC_STYLENEEDED # 10207 +wxEVT_STC_UPDATEUI = stc.wxEVT_STC_UPDATEUI # 10214 +wxEVT_STC_URIDROPPED = stc.wxEVT_STC_URIDROPPED # 10222 +wxEVT_STC_USERLISTSELECTION = stc.wxEVT_STC_USERLISTSELECTION # 10221 +wxEVT_STC_ZOOM = stc.wxEVT_STC_ZOOM # 10228 +wxSTC_ADA_CHARACTER = stc.wxSTC_ADA_CHARACTER # 5 +wxSTC_ADA_COMMENT = stc.wxSTC_ADA_COMMENT # 1 +wxSTC_ADA_DEFAULT = stc.wxSTC_ADA_DEFAULT # 0 +wxSTC_ADA_IDENTIFIER = stc.wxSTC_ADA_IDENTIFIER # 7 +wxSTC_ADA_NUMBER = stc.wxSTC_ADA_NUMBER # 2 +wxSTC_ADA_OPERATOR = stc.wxSTC_ADA_OPERATOR # 6 +wxSTC_ADA_STRING = stc.wxSTC_ADA_STRING # 4 +wxSTC_ADA_STRINGEOL = stc.wxSTC_ADA_STRINGEOL # 8 +wxSTC_ADA_WORD = stc.wxSTC_ADA_WORD # 3 +wxSTC_AVE_COMMENT = stc.wxSTC_AVE_COMMENT # 1 +wxSTC_AVE_DEFAULT = stc.wxSTC_AVE_DEFAULT # 0 +wxSTC_AVE_ENUM = stc.wxSTC_AVE_ENUM # 7 +wxSTC_AVE_IDENTIFIER = stc.wxSTC_AVE_IDENTIFIER # 9 +wxSTC_AVE_KEYWORD = stc.wxSTC_AVE_KEYWORD # 4 +wxSTC_AVE_NUMBER = stc.wxSTC_AVE_NUMBER # 2 +wxSTC_AVE_OPERATOR = stc.wxSTC_AVE_OPERATOR # 10 +wxSTC_AVE_STATEMENT = stc.wxSTC_AVE_STATEMENT # 5 +wxSTC_AVE_STRING = stc.wxSTC_AVE_STRING # 6 +wxSTC_AVE_STRINGEOL = stc.wxSTC_AVE_STRINGEOL # 8 +wxSTC_AVE_WORD = stc.wxSTC_AVE_WORD # 3 +wxSTC_BAAN_COMMENT = stc.wxSTC_BAAN_COMMENT # 1 +wxSTC_BAAN_COMMENTDOC = stc.wxSTC_BAAN_COMMENTDOC # 2 +wxSTC_BAAN_DEFAULT = stc.wxSTC_BAAN_DEFAULT # 0 +wxSTC_BAAN_IDENTIFIER = stc.wxSTC_BAAN_IDENTIFIER # 8 +wxSTC_BAAN_NUMBER = stc.wxSTC_BAAN_NUMBER # 3 +wxSTC_BAAN_OPERATOR = stc.wxSTC_BAAN_OPERATOR # 7 +wxSTC_BAAN_PREPROCESSOR = stc.wxSTC_BAAN_PREPROCESSOR # 6 +wxSTC_BAAN_STRING = stc.wxSTC_BAAN_STRING # 5 +wxSTC_BAAN_STRINGEOL = stc.wxSTC_BAAN_STRINGEOL # 9 +wxSTC_BAAN_WORD = stc.wxSTC_BAAN_WORD # 4 +wxSTC_BAAN_WORD2 = stc.wxSTC_BAAN_WORD2 # 10 +wxSTC_BAT_COMMAND = stc.wxSTC_BAT_COMMAND # 5 +wxSTC_BAT_COMMENT = stc.wxSTC_BAT_COMMENT # 1 +wxSTC_BAT_DEFAULT = stc.wxSTC_BAT_DEFAULT # 0 +wxSTC_BAT_HIDE = stc.wxSTC_BAT_HIDE # 4 +wxSTC_BAT_IDENTIFIER = stc.wxSTC_BAT_IDENTIFIER # 6 +wxSTC_BAT_LABEL = stc.wxSTC_BAT_LABEL # 3 +wxSTC_BAT_OPERATOR = stc.wxSTC_BAT_OPERATOR # 7 +wxSTC_BAT_WORD = stc.wxSTC_BAT_WORD # 2 +wxSTC_B_COMMENT = stc.wxSTC_B_COMMENT # 1 +wxSTC_B_DATE = stc.wxSTC_B_DATE # 8 +wxSTC_B_DEFAULT = stc.wxSTC_B_DEFAULT # 0 +wxSTC_B_IDENTIFIER = stc.wxSTC_B_IDENTIFIER # 7 +wxSTC_B_KEYWORD = stc.wxSTC_B_KEYWORD # 3 +wxSTC_B_NUMBER = stc.wxSTC_B_NUMBER # 2 +wxSTC_B_OPERATOR = stc.wxSTC_B_OPERATOR # 6 +wxSTC_B_PREPROCESSOR = stc.wxSTC_B_PREPROCESSOR # 5 +wxSTC_B_STRING = stc.wxSTC_B_STRING # 4 +wxSTC_CACHE_CARET = stc.wxSTC_CACHE_CARET # 1 +wxSTC_CACHE_DOCUMENT = stc.wxSTC_CACHE_DOCUMENT # 3 +wxSTC_CACHE_NONE = stc.wxSTC_CACHE_NONE # 0 +wxSTC_CACHE_PAGE = stc.wxSTC_CACHE_PAGE # 2 +wxSTC_CARET_EVEN = stc.wxSTC_CARET_EVEN # 8 +wxSTC_CARET_JUMPS = stc.wxSTC_CARET_JUMPS # 16 +wxSTC_CARET_SLOP = stc.wxSTC_CARET_SLOP # 1 +wxSTC_CARET_STRICT = stc.wxSTC_CARET_STRICT # 4 +wxSTC_CASE_LOWER = stc.wxSTC_CASE_LOWER # 2 +wxSTC_CASE_MIXED = stc.wxSTC_CASE_MIXED # 0 +wxSTC_CASE_UPPER = stc.wxSTC_CASE_UPPER # 1 +wxSTC_CHARSET_ANSI = stc.wxSTC_CHARSET_ANSI # 0 +wxSTC_CHARSET_ARABIC = stc.wxSTC_CHARSET_ARABIC # 178 +wxSTC_CHARSET_BALTIC = stc.wxSTC_CHARSET_BALTIC # 186 +wxSTC_CHARSET_CHINESEBIG5 = stc.wxSTC_CHARSET_CHINESEBIG5 # 136 +wxSTC_CHARSET_DEFAULT = stc.wxSTC_CHARSET_DEFAULT # 1 +wxSTC_CHARSET_EASTEUROPE = stc.wxSTC_CHARSET_EASTEUROPE # 238 +wxSTC_CHARSET_GB2312 = stc.wxSTC_CHARSET_GB2312 # 134 +wxSTC_CHARSET_GREEK = stc.wxSTC_CHARSET_GREEK # 161 +wxSTC_CHARSET_HANGUL = stc.wxSTC_CHARSET_HANGUL # 129 +wxSTC_CHARSET_HEBREW = stc.wxSTC_CHARSET_HEBREW # 177 +wxSTC_CHARSET_JOHAB = stc.wxSTC_CHARSET_JOHAB # 130 +wxSTC_CHARSET_MAC = stc.wxSTC_CHARSET_MAC # 77 +wxSTC_CHARSET_OEM = stc.wxSTC_CHARSET_OEM # 255 +wxSTC_CHARSET_RUSSIAN = stc.wxSTC_CHARSET_RUSSIAN # 204 +wxSTC_CHARSET_SHIFTJIS = stc.wxSTC_CHARSET_SHIFTJIS # 128 +wxSTC_CHARSET_SYMBOL = stc.wxSTC_CHARSET_SYMBOL # 2 +wxSTC_CHARSET_THAI = stc.wxSTC_CHARSET_THAI # 222 +wxSTC_CHARSET_TURKISH = stc.wxSTC_CHARSET_TURKISH # 162 +wxSTC_CHARSET_VIETNAMESE = stc.wxSTC_CHARSET_VIETNAMESE # 163 +wxSTC_CMD_BACKTAB = stc.wxSTC_CMD_BACKTAB # 2328 +wxSTC_CMD_CANCEL = stc.wxSTC_CMD_CANCEL # 2325 +wxSTC_CMD_CHARLEFT = stc.wxSTC_CMD_CHARLEFT # 2304 +wxSTC_CMD_CHARLEFTEXTEND = stc.wxSTC_CMD_CHARLEFTEXTEND # 2305 +wxSTC_CMD_CHARRIGHT = stc.wxSTC_CMD_CHARRIGHT # 2306 +wxSTC_CMD_CHARRIGHTEXTEND = stc.wxSTC_CMD_CHARRIGHTEXTEND # 2307 +wxSTC_CMD_CLEAR = stc.wxSTC_CMD_CLEAR # 2180 +wxSTC_CMD_COPY = stc.wxSTC_CMD_COPY # 2178 +wxSTC_CMD_CUT = stc.wxSTC_CMD_CUT # 2177 +wxSTC_CMD_DELETEBACK = stc.wxSTC_CMD_DELETEBACK # 2326 +wxSTC_CMD_DELETEBACKNOTLINE = stc.wxSTC_CMD_DELETEBACKNOTLINE # 2344 +wxSTC_CMD_DELLINELEFT = stc.wxSTC_CMD_DELLINELEFT # 2395 +wxSTC_CMD_DELLINERIGHT = stc.wxSTC_CMD_DELLINERIGHT # 2396 +wxSTC_CMD_DELWORDLEFT = stc.wxSTC_CMD_DELWORDLEFT # 2335 +wxSTC_CMD_DELWORDRIGHT = stc.wxSTC_CMD_DELWORDRIGHT # 2336 +wxSTC_CMD_DOCUMENTEND = stc.wxSTC_CMD_DOCUMENTEND # 2318 +wxSTC_CMD_DOCUMENTENDEXTEND = stc.wxSTC_CMD_DOCUMENTENDEXTEND # 2319 +wxSTC_CMD_DOCUMENTSTART = stc.wxSTC_CMD_DOCUMENTSTART # 2316 +wxSTC_CMD_DOCUMENTSTARTEXTEND = stc.wxSTC_CMD_DOCUMENTSTARTEXTEND # 2317 +wxSTC_CMD_EDITTOGGLEOVERTYPE = stc.wxSTC_CMD_EDITTOGGLEOVERTYPE # 2324 +wxSTC_CMD_FORMFEED = stc.wxSTC_CMD_FORMFEED # 2330 +wxSTC_CMD_HOME = stc.wxSTC_CMD_HOME # 2312 +wxSTC_CMD_HOMEDISPLAY = stc.wxSTC_CMD_HOMEDISPLAY # 2345 +wxSTC_CMD_HOMEDISPLAYEXTEND = stc.wxSTC_CMD_HOMEDISPLAYEXTEND # 2346 +wxSTC_CMD_HOMEEXTEND = stc.wxSTC_CMD_HOMEEXTEND # 2313 +wxSTC_CMD_LINECUT = stc.wxSTC_CMD_LINECUT # 2337 +wxSTC_CMD_LINEDELETE = stc.wxSTC_CMD_LINEDELETE # 2338 +wxSTC_CMD_LINEDOWN = stc.wxSTC_CMD_LINEDOWN # 2300 +wxSTC_CMD_LINEDOWNEXTEND = stc.wxSTC_CMD_LINEDOWNEXTEND # 2301 +wxSTC_CMD_LINEEND = stc.wxSTC_CMD_LINEEND # 2314 +wxSTC_CMD_LINEENDDISPLAY = stc.wxSTC_CMD_LINEENDDISPLAY # 2347 +wxSTC_CMD_LINEENDDISPLAYEXTEND = stc.wxSTC_CMD_LINEENDDISPLAYEXTEND # 2348 +wxSTC_CMD_LINEENDEXTEND = stc.wxSTC_CMD_LINEENDEXTEND # 2315 +wxSTC_CMD_LINESCROLLDOWN = stc.wxSTC_CMD_LINESCROLLDOWN # 2342 +wxSTC_CMD_LINESCROLLUP = stc.wxSTC_CMD_LINESCROLLUP # 2343 +wxSTC_CMD_LINETRANSPOSE = stc.wxSTC_CMD_LINETRANSPOSE # 2339 +wxSTC_CMD_LINEUP = stc.wxSTC_CMD_LINEUP # 2302 +wxSTC_CMD_LINEUPEXTEND = stc.wxSTC_CMD_LINEUPEXTEND # 2303 +wxSTC_CMD_LOWERCASE = stc.wxSTC_CMD_LOWERCASE # 2340 +wxSTC_CMD_NEWLINE = stc.wxSTC_CMD_NEWLINE # 2329 +wxSTC_CMD_PAGEDOWN = stc.wxSTC_CMD_PAGEDOWN # 2322 +wxSTC_CMD_PAGEDOWNEXTEND = stc.wxSTC_CMD_PAGEDOWNEXTEND # 2323 +wxSTC_CMD_PAGEUP = stc.wxSTC_CMD_PAGEUP # 2320 +wxSTC_CMD_PAGEUPEXTEND = stc.wxSTC_CMD_PAGEUPEXTEND # 2321 +wxSTC_CMD_PASTE = stc.wxSTC_CMD_PASTE # 2179 +wxSTC_CMD_REDO = stc.wxSTC_CMD_REDO # 2011 +wxSTC_CMD_SELECTALL = stc.wxSTC_CMD_SELECTALL # 2013 +wxSTC_CMD_TAB = stc.wxSTC_CMD_TAB # 2327 +wxSTC_CMD_UNDO = stc.wxSTC_CMD_UNDO # 2176 +wxSTC_CMD_UPPERCASE = stc.wxSTC_CMD_UPPERCASE # 2341 +wxSTC_CMD_VCHOME = stc.wxSTC_CMD_VCHOME # 2331 +wxSTC_CMD_VCHOMEEXTEND = stc.wxSTC_CMD_VCHOMEEXTEND # 2332 +wxSTC_CMD_WORDLEFT = stc.wxSTC_CMD_WORDLEFT # 2308 +wxSTC_CMD_WORDLEFTEXTEND = stc.wxSTC_CMD_WORDLEFTEXTEND # 2309 +wxSTC_CMD_WORDPARTLEFT = stc.wxSTC_CMD_WORDPARTLEFT # 2390 +wxSTC_CMD_WORDPARTLEFTEXTEND = stc.wxSTC_CMD_WORDPARTLEFTEXTEND # 2391 +wxSTC_CMD_WORDPARTRIGHT = stc.wxSTC_CMD_WORDPARTRIGHT # 2392 +wxSTC_CMD_WORDPARTRIGHTEXTEND = stc.wxSTC_CMD_WORDPARTRIGHTEXTEND # 2393 +wxSTC_CMD_WORDRIGHT = stc.wxSTC_CMD_WORDRIGHT # 2310 +wxSTC_CMD_WORDRIGHTEXTEND = stc.wxSTC_CMD_WORDRIGHTEXTEND # 2311 +wxSTC_CMD_ZOOMIN = stc.wxSTC_CMD_ZOOMIN # 2333 +wxSTC_CMD_ZOOMOUT = stc.wxSTC_CMD_ZOOMOUT # 2334 +wxSTC_CONF_COMMENT = stc.wxSTC_CONF_COMMENT # 1 +wxSTC_CONF_DEFAULT = stc.wxSTC_CONF_DEFAULT # 0 +wxSTC_CONF_DIRECTIVE = stc.wxSTC_CONF_DIRECTIVE # 9 +wxSTC_CONF_EXTENSION = stc.wxSTC_CONF_EXTENSION # 4 +wxSTC_CONF_IDENTIFIER = stc.wxSTC_CONF_IDENTIFIER # 3 +wxSTC_CONF_IP = stc.wxSTC_CONF_IP # 8 +wxSTC_CONF_NUMBER = stc.wxSTC_CONF_NUMBER # 2 +wxSTC_CONF_OPERATOR = stc.wxSTC_CONF_OPERATOR # 7 +wxSTC_CONF_PARAMETER = stc.wxSTC_CONF_PARAMETER # 5 +wxSTC_CONF_STRING = stc.wxSTC_CONF_STRING # 6 +wxSTC_CP_UTF8 = stc.wxSTC_CP_UTF8 # 65001 +wxSTC_CURSORNORMAL = stc.wxSTC_CURSORNORMAL # -1 +wxSTC_CURSORWAIT = stc.wxSTC_CURSORWAIT # 3 +wxSTC_C_CHARACTER = stc.wxSTC_C_CHARACTER # 7 +wxSTC_C_COMMENT = stc.wxSTC_C_COMMENT # 1 +wxSTC_C_COMMENTDOC = stc.wxSTC_C_COMMENTDOC # 3 +wxSTC_C_COMMENTDOCKEYWORD = stc.wxSTC_C_COMMENTDOCKEYWORD # 17 +wxSTC_C_COMMENTDOCKEYWORDERROR = stc.wxSTC_C_COMMENTDOCKEYWORDERROR # 18 +wxSTC_C_COMMENTLINE = stc.wxSTC_C_COMMENTLINE # 2 +wxSTC_C_COMMENTLINEDOC = stc.wxSTC_C_COMMENTLINEDOC # 15 +wxSTC_C_DEFAULT = stc.wxSTC_C_DEFAULT # 0 +wxSTC_C_IDENTIFIER = stc.wxSTC_C_IDENTIFIER # 11 +wxSTC_C_NUMBER = stc.wxSTC_C_NUMBER # 4 +wxSTC_C_OPERATOR = stc.wxSTC_C_OPERATOR # 10 +wxSTC_C_PREPROCESSOR = stc.wxSTC_C_PREPROCESSOR # 9 +wxSTC_C_REGEX = stc.wxSTC_C_REGEX # 14 +wxSTC_C_STRING = stc.wxSTC_C_STRING # 6 +wxSTC_C_STRINGEOL = stc.wxSTC_C_STRINGEOL # 12 +wxSTC_C_UUID = stc.wxSTC_C_UUID # 8 +wxSTC_C_VERBATIM = stc.wxSTC_C_VERBATIM # 13 +wxSTC_C_WORD = stc.wxSTC_C_WORD # 5 +wxSTC_C_WORD2 = stc.wxSTC_C_WORD2 # 16 +wxSTC_DIFF_ADDED = stc.wxSTC_DIFF_ADDED # 6 +wxSTC_DIFF_COMMAND = stc.wxSTC_DIFF_COMMAND # 2 +wxSTC_DIFF_COMMENT = stc.wxSTC_DIFF_COMMENT # 1 +wxSTC_DIFF_DEFAULT = stc.wxSTC_DIFF_DEFAULT # 0 +wxSTC_DIFF_DELETED = stc.wxSTC_DIFF_DELETED # 5 +wxSTC_DIFF_HEADER = stc.wxSTC_DIFF_HEADER # 3 +wxSTC_DIFF_POSITION = stc.wxSTC_DIFF_POSITION # 4 +wxSTC_EDGE_BACKGROUND = stc.wxSTC_EDGE_BACKGROUND # 2 +wxSTC_EDGE_LINE = stc.wxSTC_EDGE_LINE # 1 +wxSTC_EDGE_NONE = stc.wxSTC_EDGE_NONE # 0 +wxSTC_EIFFEL_CHARACTER = stc.wxSTC_EIFFEL_CHARACTER # 5 +wxSTC_EIFFEL_COMMENTLINE = stc.wxSTC_EIFFEL_COMMENTLINE # 1 +wxSTC_EIFFEL_DEFAULT = stc.wxSTC_EIFFEL_DEFAULT # 0 +wxSTC_EIFFEL_IDENTIFIER = stc.wxSTC_EIFFEL_IDENTIFIER # 7 +wxSTC_EIFFEL_NUMBER = stc.wxSTC_EIFFEL_NUMBER # 2 +wxSTC_EIFFEL_OPERATOR = stc.wxSTC_EIFFEL_OPERATOR # 6 +wxSTC_EIFFEL_STRING = stc.wxSTC_EIFFEL_STRING # 4 +wxSTC_EIFFEL_STRINGEOL = stc.wxSTC_EIFFEL_STRINGEOL # 8 +wxSTC_EIFFEL_WORD = stc.wxSTC_EIFFEL_WORD # 3 +wxSTC_EOL_CR = stc.wxSTC_EOL_CR # 1 +wxSTC_EOL_CRLF = stc.wxSTC_EOL_CRLF # 0 +wxSTC_EOL_LF = stc.wxSTC_EOL_LF # 2 +wxSTC_ERR_BORLAND = stc.wxSTC_ERR_BORLAND # 5 +wxSTC_ERR_CMD = stc.wxSTC_ERR_CMD # 4 +wxSTC_ERR_CTAG = stc.wxSTC_ERR_CTAG # 9 +wxSTC_ERR_DEFAULT = stc.wxSTC_ERR_DEFAULT # 0 +wxSTC_ERR_DIFF_ADDITION = stc.wxSTC_ERR_DIFF_ADDITION # 11 +wxSTC_ERR_DIFF_CHANGED = stc.wxSTC_ERR_DIFF_CHANGED # 10 +wxSTC_ERR_DIFF_DELETION = stc.wxSTC_ERR_DIFF_DELETION # 12 +wxSTC_ERR_DIFF_MESSAGE = stc.wxSTC_ERR_DIFF_MESSAGE # 13 +wxSTC_ERR_GCC = stc.wxSTC_ERR_GCC # 2 +wxSTC_ERR_LUA = stc.wxSTC_ERR_LUA # 8 +wxSTC_ERR_MS = stc.wxSTC_ERR_MS # 3 +wxSTC_ERR_NET = stc.wxSTC_ERR_NET # 7 +wxSTC_ERR_PERL = stc.wxSTC_ERR_PERL # 6 +wxSTC_ERR_PYTHON = stc.wxSTC_ERR_PYTHON # 1 +wxSTC_FIND_MATCHCASE = stc.wxSTC_FIND_MATCHCASE # 4 +wxSTC_FIND_REGEXP = stc.wxSTC_FIND_REGEXP # 2097152 +wxSTC_FIND_WHOLEWORD = stc.wxSTC_FIND_WHOLEWORD # 2 +wxSTC_FIND_WORDSTART = stc.wxSTC_FIND_WORDSTART # 1048576 +wxSTC_FOLDLEVELBASE = stc.wxSTC_FOLDLEVELBASE # 1024 +wxSTC_FOLDLEVELHEADERFLAG = stc.wxSTC_FOLDLEVELHEADERFLAG # 8192 +wxSTC_FOLDLEVELNUMBERMASK = stc.wxSTC_FOLDLEVELNUMBERMASK # 4095 +wxSTC_FOLDLEVELWHITEFLAG = stc.wxSTC_FOLDLEVELWHITEFLAG # 4096 +wxSTC_HBA_COMMENTLINE = stc.wxSTC_HBA_COMMENTLINE # 82 +wxSTC_HBA_DEFAULT = stc.wxSTC_HBA_DEFAULT # 81 +wxSTC_HBA_IDENTIFIER = stc.wxSTC_HBA_IDENTIFIER # 86 +wxSTC_HBA_NUMBER = stc.wxSTC_HBA_NUMBER # 83 +wxSTC_HBA_START = stc.wxSTC_HBA_START # 80 +wxSTC_HBA_STRING = stc.wxSTC_HBA_STRING # 85 +wxSTC_HBA_STRINGEOL = stc.wxSTC_HBA_STRINGEOL # 87 +wxSTC_HBA_WORD = stc.wxSTC_HBA_WORD # 84 +wxSTC_HB_COMMENTLINE = stc.wxSTC_HB_COMMENTLINE # 72 +wxSTC_HB_DEFAULT = stc.wxSTC_HB_DEFAULT # 71 +wxSTC_HB_IDENTIFIER = stc.wxSTC_HB_IDENTIFIER # 76 +wxSTC_HB_NUMBER = stc.wxSTC_HB_NUMBER # 73 +wxSTC_HB_START = stc.wxSTC_HB_START # 70 +wxSTC_HB_STRING = stc.wxSTC_HB_STRING # 75 +wxSTC_HB_STRINGEOL = stc.wxSTC_HB_STRINGEOL # 77 +wxSTC_HB_WORD = stc.wxSTC_HB_WORD # 74 +wxSTC_HJA_COMMENT = stc.wxSTC_HJA_COMMENT # 57 +wxSTC_HJA_COMMENTDOC = stc.wxSTC_HJA_COMMENTDOC # 59 +wxSTC_HJA_COMMENTLINE = stc.wxSTC_HJA_COMMENTLINE # 58 +wxSTC_HJA_DEFAULT = stc.wxSTC_HJA_DEFAULT # 56 +wxSTC_HJA_DOUBLESTRING = stc.wxSTC_HJA_DOUBLESTRING # 63 +wxSTC_HJA_KEYWORD = stc.wxSTC_HJA_KEYWORD # 62 +wxSTC_HJA_NUMBER = stc.wxSTC_HJA_NUMBER # 60 +wxSTC_HJA_REGEX = stc.wxSTC_HJA_REGEX # 67 +wxSTC_HJA_SINGLESTRING = stc.wxSTC_HJA_SINGLESTRING # 64 +wxSTC_HJA_START = stc.wxSTC_HJA_START # 55 +wxSTC_HJA_STRINGEOL = stc.wxSTC_HJA_STRINGEOL # 66 +wxSTC_HJA_SYMBOLS = stc.wxSTC_HJA_SYMBOLS # 65 +wxSTC_HJA_WORD = stc.wxSTC_HJA_WORD # 61 +wxSTC_HJ_COMMENT = stc.wxSTC_HJ_COMMENT # 42 +wxSTC_HJ_COMMENTDOC = stc.wxSTC_HJ_COMMENTDOC # 44 +wxSTC_HJ_COMMENTLINE = stc.wxSTC_HJ_COMMENTLINE # 43 +wxSTC_HJ_DEFAULT = stc.wxSTC_HJ_DEFAULT # 41 +wxSTC_HJ_DOUBLESTRING = stc.wxSTC_HJ_DOUBLESTRING # 48 +wxSTC_HJ_KEYWORD = stc.wxSTC_HJ_KEYWORD # 47 +wxSTC_HJ_NUMBER = stc.wxSTC_HJ_NUMBER # 45 +wxSTC_HJ_REGEX = stc.wxSTC_HJ_REGEX # 52 +wxSTC_HJ_SINGLESTRING = stc.wxSTC_HJ_SINGLESTRING # 49 +wxSTC_HJ_START = stc.wxSTC_HJ_START # 40 +wxSTC_HJ_STRINGEOL = stc.wxSTC_HJ_STRINGEOL # 51 +wxSTC_HJ_SYMBOLS = stc.wxSTC_HJ_SYMBOLS # 50 +wxSTC_HJ_WORD = stc.wxSTC_HJ_WORD # 46 +wxSTC_HPA_CHARACTER = stc.wxSTC_HPA_CHARACTER # 110 +wxSTC_HPA_CLASSNAME = stc.wxSTC_HPA_CLASSNAME # 114 +wxSTC_HPA_COMMENTLINE = stc.wxSTC_HPA_COMMENTLINE # 107 +wxSTC_HPA_DEFAULT = stc.wxSTC_HPA_DEFAULT # 106 +wxSTC_HPA_DEFNAME = stc.wxSTC_HPA_DEFNAME # 115 +wxSTC_HPA_IDENTIFIER = stc.wxSTC_HPA_IDENTIFIER # 117 +wxSTC_HPA_NUMBER = stc.wxSTC_HPA_NUMBER # 108 +wxSTC_HPA_OPERATOR = stc.wxSTC_HPA_OPERATOR # 116 +wxSTC_HPA_START = stc.wxSTC_HPA_START # 105 +wxSTC_HPA_STRING = stc.wxSTC_HPA_STRING # 109 +wxSTC_HPA_TRIPLE = stc.wxSTC_HPA_TRIPLE # 112 +wxSTC_HPA_TRIPLEDOUBLE = stc.wxSTC_HPA_TRIPLEDOUBLE # 113 +wxSTC_HPA_WORD = stc.wxSTC_HPA_WORD # 111 +wxSTC_HPHP_COMMENT = stc.wxSTC_HPHP_COMMENT # 124 +wxSTC_HPHP_COMMENTLINE = stc.wxSTC_HPHP_COMMENTLINE # 125 +wxSTC_HPHP_DEFAULT = stc.wxSTC_HPHP_DEFAULT # 118 +wxSTC_HPHP_HSTRING = stc.wxSTC_HPHP_HSTRING # 119 +wxSTC_HPHP_HSTRING_VARIABLE = stc.wxSTC_HPHP_HSTRING_VARIABLE # 126 +wxSTC_HPHP_NUMBER = stc.wxSTC_HPHP_NUMBER # 122 +wxSTC_HPHP_OPERATOR = stc.wxSTC_HPHP_OPERATOR # 127 +wxSTC_HPHP_SIMPLESTRING = stc.wxSTC_HPHP_SIMPLESTRING # 120 +wxSTC_HPHP_VARIABLE = stc.wxSTC_HPHP_VARIABLE # 123 +wxSTC_HPHP_WORD = stc.wxSTC_HPHP_WORD # 121 +wxSTC_HP_CHARACTER = stc.wxSTC_HP_CHARACTER # 95 +wxSTC_HP_CLASSNAME = stc.wxSTC_HP_CLASSNAME # 99 +wxSTC_HP_COMMENTLINE = stc.wxSTC_HP_COMMENTLINE # 92 +wxSTC_HP_DEFAULT = stc.wxSTC_HP_DEFAULT # 91 +wxSTC_HP_DEFNAME = stc.wxSTC_HP_DEFNAME # 100 +wxSTC_HP_IDENTIFIER = stc.wxSTC_HP_IDENTIFIER # 102 +wxSTC_HP_NUMBER = stc.wxSTC_HP_NUMBER # 93 +wxSTC_HP_OPERATOR = stc.wxSTC_HP_OPERATOR # 101 +wxSTC_HP_START = stc.wxSTC_HP_START # 90 +wxSTC_HP_STRING = stc.wxSTC_HP_STRING # 94 +wxSTC_HP_TRIPLE = stc.wxSTC_HP_TRIPLE # 97 +wxSTC_HP_TRIPLEDOUBLE = stc.wxSTC_HP_TRIPLEDOUBLE # 98 +wxSTC_HP_WORD = stc.wxSTC_HP_WORD # 96 +wxSTC_H_ASP = stc.wxSTC_H_ASP # 15 +wxSTC_H_ASPAT = stc.wxSTC_H_ASPAT # 16 +wxSTC_H_ATTRIBUTE = stc.wxSTC_H_ATTRIBUTE # 3 +wxSTC_H_ATTRIBUTEUNKNOWN = stc.wxSTC_H_ATTRIBUTEUNKNOWN # 4 +wxSTC_H_CDATA = stc.wxSTC_H_CDATA # 17 +wxSTC_H_COMMENT = stc.wxSTC_H_COMMENT # 9 +wxSTC_H_DEFAULT = stc.wxSTC_H_DEFAULT # 0 +wxSTC_H_DOUBLESTRING = stc.wxSTC_H_DOUBLESTRING # 6 +wxSTC_H_ENTITY = stc.wxSTC_H_ENTITY # 10 +wxSTC_H_NUMBER = stc.wxSTC_H_NUMBER # 5 +wxSTC_H_OTHER = stc.wxSTC_H_OTHER # 8 +wxSTC_H_QUESTION = stc.wxSTC_H_QUESTION # 18 +wxSTC_H_SCRIPT = stc.wxSTC_H_SCRIPT # 14 +wxSTC_H_SGML_1ST_PARAM = stc.wxSTC_H_SGML_1ST_PARAM # 23 +wxSTC_H_SGML_1ST_PARAM_COMMENT = stc.wxSTC_H_SGML_1ST_PARAM_COMMENT # 30 +wxSTC_H_SGML_BLOCK_DEFAULT = stc.wxSTC_H_SGML_BLOCK_DEFAULT # 31 +wxSTC_H_SGML_COMMAND = stc.wxSTC_H_SGML_COMMAND # 22 +wxSTC_H_SGML_COMMENT = stc.wxSTC_H_SGML_COMMENT # 29 +wxSTC_H_SGML_DEFAULT = stc.wxSTC_H_SGML_DEFAULT # 21 +wxSTC_H_SGML_DOUBLESTRING = stc.wxSTC_H_SGML_DOUBLESTRING # 24 +wxSTC_H_SGML_ENTITY = stc.wxSTC_H_SGML_ENTITY # 28 +wxSTC_H_SGML_ERROR = stc.wxSTC_H_SGML_ERROR # 26 +wxSTC_H_SGML_SIMPLESTRING = stc.wxSTC_H_SGML_SIMPLESTRING # 25 +wxSTC_H_SGML_SPECIAL = stc.wxSTC_H_SGML_SPECIAL # 27 +wxSTC_H_SINGLESTRING = stc.wxSTC_H_SINGLESTRING # 7 +wxSTC_H_TAG = stc.wxSTC_H_TAG # 1 +wxSTC_H_TAGEND = stc.wxSTC_H_TAGEND # 11 +wxSTC_H_TAGUNKNOWN = stc.wxSTC_H_TAGUNKNOWN # 2 +wxSTC_H_VALUE = stc.wxSTC_H_VALUE # 19 +wxSTC_H_XCCOMMENT = stc.wxSTC_H_XCCOMMENT # 20 +wxSTC_H_XMLEND = stc.wxSTC_H_XMLEND # 13 +wxSTC_H_XMLSTART = stc.wxSTC_H_XMLSTART # 12 +wxSTC_INDIC0_MASK = stc.wxSTC_INDIC0_MASK # 32 +wxSTC_INDIC1_MASK = stc.wxSTC_INDIC1_MASK # 64 +wxSTC_INDIC2_MASK = stc.wxSTC_INDIC2_MASK # 128 +wxSTC_INDICS_MASK = stc.wxSTC_INDICS_MASK # 224 +wxSTC_INDIC_DIAGONAL = stc.wxSTC_INDIC_DIAGONAL # 3 +wxSTC_INDIC_MAX = stc.wxSTC_INDIC_MAX # 7 +wxSTC_INDIC_PLAIN = stc.wxSTC_INDIC_PLAIN # 0 +wxSTC_INDIC_SQUIGGLE = stc.wxSTC_INDIC_SQUIGGLE # 1 +wxSTC_INDIC_STRIKE = stc.wxSTC_INDIC_STRIKE # 4 +wxSTC_INDIC_TT = stc.wxSTC_INDIC_TT # 2 +wxSTC_INVALID_POSITION = stc.wxSTC_INVALID_POSITION # -1 +wxSTC_KEY_ADD = stc.wxSTC_KEY_ADD # 310 +wxSTC_KEY_BACK = stc.wxSTC_KEY_BACK # 8 +wxSTC_KEY_DELETE = stc.wxSTC_KEY_DELETE # 308 +wxSTC_KEY_DIVIDE = stc.wxSTC_KEY_DIVIDE # 312 +wxSTC_KEY_DOWN = stc.wxSTC_KEY_DOWN # 300 +wxSTC_KEY_END = stc.wxSTC_KEY_END # 305 +wxSTC_KEY_ESCAPE = stc.wxSTC_KEY_ESCAPE # 7 +wxSTC_KEY_HOME = stc.wxSTC_KEY_HOME # 304 +wxSTC_KEY_INSERT = stc.wxSTC_KEY_INSERT # 309 +wxSTC_KEY_LEFT = stc.wxSTC_KEY_LEFT # 302 +wxSTC_KEY_NEXT = stc.wxSTC_KEY_NEXT # 307 +wxSTC_KEY_PRIOR = stc.wxSTC_KEY_PRIOR # 306 +wxSTC_KEY_RETURN = stc.wxSTC_KEY_RETURN # 13 +wxSTC_KEY_RIGHT = stc.wxSTC_KEY_RIGHT # 303 +wxSTC_KEY_SUBTRACT = stc.wxSTC_KEY_SUBTRACT # 311 +wxSTC_KEY_TAB = stc.wxSTC_KEY_TAB # 9 +wxSTC_KEY_UP = stc.wxSTC_KEY_UP # 301 +wxSTC_LASTSTEPINUNDOREDO = stc.wxSTC_LASTSTEPINUNDOREDO # 256 +wxSTC_LEXER_START = stc.wxSTC_LEXER_START # 4000 +wxSTC_LEX_ADA = stc.wxSTC_LEX_ADA # 20 +wxSTC_LEX_ASP = stc.wxSTC_LEX_ASP # 29 +wxSTC_LEX_AUTOMATIC = stc.wxSTC_LEX_AUTOMATIC # 1000 +wxSTC_LEX_AVE = stc.wxSTC_LEX_AVE # 19 +wxSTC_LEX_BAAN = stc.wxSTC_LEX_BAAN # 31 +wxSTC_LEX_BATCH = stc.wxSTC_LEX_BATCH # 12 +wxSTC_LEX_BULLANT = stc.wxSTC_LEX_BULLANT # 27 +wxSTC_LEX_CONF = stc.wxSTC_LEX_CONF # 17 +wxSTC_LEX_CONTAINER = stc.wxSTC_LEX_CONTAINER # 0 +wxSTC_LEX_CPP = stc.wxSTC_LEX_CPP # 3 +wxSTC_LEX_DIFF = stc.wxSTC_LEX_DIFF # 16 +wxSTC_LEX_EIFFEL = stc.wxSTC_LEX_EIFFEL # 23 +wxSTC_LEX_EIFFELKW = stc.wxSTC_LEX_EIFFELKW # 24 +wxSTC_LEX_ERRORLIST = stc.wxSTC_LEX_ERRORLIST # 10 +wxSTC_LEX_HTML = stc.wxSTC_LEX_HTML # 4 +wxSTC_LEX_LATEX = stc.wxSTC_LEX_LATEX # 14 +wxSTC_LEX_LISP = stc.wxSTC_LEX_LISP # 21 +wxSTC_LEX_LUA = stc.wxSTC_LEX_LUA # 15 +wxSTC_LEX_MAKEFILE = stc.wxSTC_LEX_MAKEFILE # 11 +wxSTC_LEX_MATLAB = stc.wxSTC_LEX_MATLAB # 32 +wxSTC_LEX_NNCRONTAB = stc.wxSTC_LEX_NNCRONTAB # 26 +wxSTC_LEX_NULL = stc.wxSTC_LEX_NULL # 1 +wxSTC_LEX_PASCAL = stc.wxSTC_LEX_PASCAL # 18 +wxSTC_LEX_PERL = stc.wxSTC_LEX_PERL # 6 +wxSTC_LEX_PHP = stc.wxSTC_LEX_PHP # 30 +wxSTC_LEX_PROPERTIES = stc.wxSTC_LEX_PROPERTIES # 9 +wxSTC_LEX_PYTHON = stc.wxSTC_LEX_PYTHON # 2 +wxSTC_LEX_RUBY = stc.wxSTC_LEX_RUBY # 22 +wxSTC_LEX_SCRIPTOL = stc.wxSTC_LEX_SCRIPTOL # 33 +wxSTC_LEX_SQL = stc.wxSTC_LEX_SQL # 7 +wxSTC_LEX_TCL = stc.wxSTC_LEX_TCL # 25 +wxSTC_LEX_VB = stc.wxSTC_LEX_VB # 8 +wxSTC_LEX_VBSCRIPT = stc.wxSTC_LEX_VBSCRIPT # 28 +wxSTC_LEX_XCODE = stc.wxSTC_LEX_XCODE # 13 +wxSTC_LEX_XML = stc.wxSTC_LEX_XML # 5 +wxSTC_LISP_COMMENT = stc.wxSTC_LISP_COMMENT # 1 +wxSTC_LISP_DEFAULT = stc.wxSTC_LISP_DEFAULT # 0 +wxSTC_LISP_IDENTIFIER = stc.wxSTC_LISP_IDENTIFIER # 9 +wxSTC_LISP_KEYWORD = stc.wxSTC_LISP_KEYWORD # 3 +wxSTC_LISP_NUMBER = stc.wxSTC_LISP_NUMBER # 2 +wxSTC_LISP_OPERATOR = stc.wxSTC_LISP_OPERATOR # 10 +wxSTC_LISP_STRING = stc.wxSTC_LISP_STRING # 6 +wxSTC_LISP_STRINGEOL = stc.wxSTC_LISP_STRINGEOL # 8 +wxSTC_LUA_CHARACTER = stc.wxSTC_LUA_CHARACTER # 7 +wxSTC_LUA_COMMENT = stc.wxSTC_LUA_COMMENT # 1 +wxSTC_LUA_COMMENTDOC = stc.wxSTC_LUA_COMMENTDOC # 3 +wxSTC_LUA_COMMENTLINE = stc.wxSTC_LUA_COMMENTLINE # 2 +wxSTC_LUA_DEFAULT = stc.wxSTC_LUA_DEFAULT # 0 +wxSTC_LUA_IDENTIFIER = stc.wxSTC_LUA_IDENTIFIER # 11 +wxSTC_LUA_LITERALSTRING = stc.wxSTC_LUA_LITERALSTRING # 8 +wxSTC_LUA_NUMBER = stc.wxSTC_LUA_NUMBER # 4 +wxSTC_LUA_OPERATOR = stc.wxSTC_LUA_OPERATOR # 10 +wxSTC_LUA_PREPROCESSOR = stc.wxSTC_LUA_PREPROCESSOR # 9 +wxSTC_LUA_STRING = stc.wxSTC_LUA_STRING # 6 +wxSTC_LUA_STRINGEOL = stc.wxSTC_LUA_STRINGEOL # 12 +wxSTC_LUA_WORD = stc.wxSTC_LUA_WORD # 5 +wxSTC_LUA_WORD2 = stc.wxSTC_LUA_WORD2 # 13 +wxSTC_LUA_WORD3 = stc.wxSTC_LUA_WORD3 # 14 +wxSTC_LUA_WORD4 = stc.wxSTC_LUA_WORD4 # 15 +wxSTC_LUA_WORD5 = stc.wxSTC_LUA_WORD5 # 16 +wxSTC_LUA_WORD6 = stc.wxSTC_LUA_WORD6 # 17 +wxSTC_L_COMMAND = stc.wxSTC_L_COMMAND # 1 +wxSTC_L_COMMENT = stc.wxSTC_L_COMMENT # 4 +wxSTC_L_DEFAULT = stc.wxSTC_L_DEFAULT # 0 +wxSTC_L_MATH = stc.wxSTC_L_MATH # 3 +wxSTC_L_TAG = stc.wxSTC_L_TAG # 2 +wxSTC_MAKE_COMMENT = stc.wxSTC_MAKE_COMMENT # 1 +wxSTC_MAKE_DEFAULT = stc.wxSTC_MAKE_DEFAULT # 0 +wxSTC_MAKE_IDENTIFIER = stc.wxSTC_MAKE_IDENTIFIER # 3 +wxSTC_MAKE_IDEOL = stc.wxSTC_MAKE_IDEOL # 9 +wxSTC_MAKE_OPERATOR = stc.wxSTC_MAKE_OPERATOR # 4 +wxSTC_MAKE_PREPROCESSOR = stc.wxSTC_MAKE_PREPROCESSOR # 2 +wxSTC_MAKE_TARGET = stc.wxSTC_MAKE_TARGET # 5 +wxSTC_MARGIN_NUMBER = stc.wxSTC_MARGIN_NUMBER # 1 +wxSTC_MARGIN_SYMBOL = stc.wxSTC_MARGIN_SYMBOL # 0 +wxSTC_MARKER_MAX = stc.wxSTC_MARKER_MAX # 31 +wxSTC_MARKNUM_FOLDER = stc.wxSTC_MARKNUM_FOLDER # 30 +wxSTC_MARKNUM_FOLDEREND = stc.wxSTC_MARKNUM_FOLDEREND # 25 +wxSTC_MARKNUM_FOLDERMIDTAIL = stc.wxSTC_MARKNUM_FOLDERMIDTAIL # 27 +wxSTC_MARKNUM_FOLDEROPEN = stc.wxSTC_MARKNUM_FOLDEROPEN # 31 +wxSTC_MARKNUM_FOLDEROPENMID = stc.wxSTC_MARKNUM_FOLDEROPENMID # 26 +wxSTC_MARKNUM_FOLDERSUB = stc.wxSTC_MARKNUM_FOLDERSUB # 29 +wxSTC_MARKNUM_FOLDERTAIL = stc.wxSTC_MARKNUM_FOLDERTAIL # 28 +wxSTC_MARK_ARROW = stc.wxSTC_MARK_ARROW # 2 +wxSTC_MARK_ARROWDOWN = stc.wxSTC_MARK_ARROWDOWN # 6 +wxSTC_MARK_ARROWS = stc.wxSTC_MARK_ARROWS # 24 +wxSTC_MARK_BACKGROUND = stc.wxSTC_MARK_BACKGROUND # 22 +wxSTC_MARK_BOXMINUS = stc.wxSTC_MARK_BOXMINUS # 14 +wxSTC_MARK_BOXMINUSCONNECTED = stc.wxSTC_MARK_BOXMINUSCONNECTED # 15 +wxSTC_MARK_BOXPLUS = stc.wxSTC_MARK_BOXPLUS # 12 +wxSTC_MARK_BOXPLUSCONNECTED = stc.wxSTC_MARK_BOXPLUSCONNECTED # 13 +wxSTC_MARK_CHARACTER = stc.wxSTC_MARK_CHARACTER # 10000 +wxSTC_MARK_CIRCLE = stc.wxSTC_MARK_CIRCLE # 0 +wxSTC_MARK_CIRCLEMINUS = stc.wxSTC_MARK_CIRCLEMINUS # 20 +wxSTC_MARK_CIRCLEMINUSCONNECTED = stc.wxSTC_MARK_CIRCLEMINUSCONNECTED # 21 +wxSTC_MARK_CIRCLEPLUS = stc.wxSTC_MARK_CIRCLEPLUS # 18 +wxSTC_MARK_CIRCLEPLUSCONNECTED = stc.wxSTC_MARK_CIRCLEPLUSCONNECTED # 19 +wxSTC_MARK_DOTDOTDOT = stc.wxSTC_MARK_DOTDOTDOT # 23 +wxSTC_MARK_EMPTY = stc.wxSTC_MARK_EMPTY # 5 +wxSTC_MARK_LCORNER = stc.wxSTC_MARK_LCORNER # 10 +wxSTC_MARK_LCORNERCURVE = stc.wxSTC_MARK_LCORNERCURVE # 16 +wxSTC_MARK_MINUS = stc.wxSTC_MARK_MINUS # 7 +wxSTC_MARK_PLUS = stc.wxSTC_MARK_PLUS # 8 +wxSTC_MARK_ROUNDRECT = stc.wxSTC_MARK_ROUNDRECT # 1 +wxSTC_MARK_SHORTARROW = stc.wxSTC_MARK_SHORTARROW # 4 +wxSTC_MARK_SMALLRECT = stc.wxSTC_MARK_SMALLRECT # 3 +wxSTC_MARK_TCORNER = stc.wxSTC_MARK_TCORNER # 11 +wxSTC_MARK_TCORNERCURVE = stc.wxSTC_MARK_TCORNERCURVE # 17 +wxSTC_MARK_VLINE = stc.wxSTC_MARK_VLINE # 9 +wxSTC_MASK_FOLDERS = stc.wxSTC_MASK_FOLDERS # -33554432 +wxSTC_MATLAB_COMMAND = stc.wxSTC_MATLAB_COMMAND # 2 +wxSTC_MATLAB_COMMENT = stc.wxSTC_MATLAB_COMMENT # 1 +wxSTC_MATLAB_DEFAULT = stc.wxSTC_MATLAB_DEFAULT # 0 +wxSTC_MATLAB_IDENTIFIER = stc.wxSTC_MATLAB_IDENTIFIER # 7 +wxSTC_MATLAB_KEYWORD = stc.wxSTC_MATLAB_KEYWORD # 4 +wxSTC_MATLAB_NUMBER = stc.wxSTC_MATLAB_NUMBER # 3 +wxSTC_MATLAB_OPERATOR = stc.wxSTC_MATLAB_OPERATOR # 6 +wxSTC_MATLAB_STRING = stc.wxSTC_MATLAB_STRING # 5 +wxSTC_MODEVENTMASKALL = stc.wxSTC_MODEVENTMASKALL # 3959 +wxSTC_MOD_BEFOREDELETE = stc.wxSTC_MOD_BEFOREDELETE # 2048 +wxSTC_MOD_BEFOREINSERT = stc.wxSTC_MOD_BEFOREINSERT # 1024 +wxSTC_MOD_CHANGEFOLD = stc.wxSTC_MOD_CHANGEFOLD # 8 +wxSTC_MOD_CHANGEMARKER = stc.wxSTC_MOD_CHANGEMARKER # 512 +wxSTC_MOD_CHANGESTYLE = stc.wxSTC_MOD_CHANGESTYLE # 4 +wxSTC_MOD_DELETETEXT = stc.wxSTC_MOD_DELETETEXT # 2 +wxSTC_MOD_INSERTTEXT = stc.wxSTC_MOD_INSERTTEXT # 1 +wxSTC_NNCRONTAB_ASTERISK = stc.wxSTC_NNCRONTAB_ASTERISK # 6 +wxSTC_NNCRONTAB_COMMENT = stc.wxSTC_NNCRONTAB_COMMENT # 1 +wxSTC_NNCRONTAB_DEFAULT = stc.wxSTC_NNCRONTAB_DEFAULT # 0 +wxSTC_NNCRONTAB_ENVIRONMENT = stc.wxSTC_NNCRONTAB_ENVIRONMENT # 9 +wxSTC_NNCRONTAB_IDENTIFIER = stc.wxSTC_NNCRONTAB_IDENTIFIER # 10 +wxSTC_NNCRONTAB_KEYWORD = stc.wxSTC_NNCRONTAB_KEYWORD # 4 +wxSTC_NNCRONTAB_MODIFIER = stc.wxSTC_NNCRONTAB_MODIFIER # 5 +wxSTC_NNCRONTAB_NUMBER = stc.wxSTC_NNCRONTAB_NUMBER # 7 +wxSTC_NNCRONTAB_SECTION = stc.wxSTC_NNCRONTAB_SECTION # 3 +wxSTC_NNCRONTAB_STRING = stc.wxSTC_NNCRONTAB_STRING # 8 +wxSTC_NNCRONTAB_TASK = stc.wxSTC_NNCRONTAB_TASK # 2 +wxSTC_OPTIONAL_START = stc.wxSTC_OPTIONAL_START # 3000 +wxSTC_PERFORMED_REDO = stc.wxSTC_PERFORMED_REDO # 64 +wxSTC_PERFORMED_UNDO = stc.wxSTC_PERFORMED_UNDO # 32 +wxSTC_PERFORMED_USER = stc.wxSTC_PERFORMED_USER # 16 +wxSTC_PL_ARRAY = stc.wxSTC_PL_ARRAY # 13 +wxSTC_PL_BACKTICKS = stc.wxSTC_PL_BACKTICKS # 20 +wxSTC_PL_CHARACTER = stc.wxSTC_PL_CHARACTER # 7 +wxSTC_PL_COMMENTLINE = stc.wxSTC_PL_COMMENTLINE # 2 +wxSTC_PL_DATASECTION = stc.wxSTC_PL_DATASECTION # 21 +wxSTC_PL_DEFAULT = stc.wxSTC_PL_DEFAULT # 0 +wxSTC_PL_ERROR = stc.wxSTC_PL_ERROR # 1 +wxSTC_PL_HASH = stc.wxSTC_PL_HASH # 14 +wxSTC_PL_HERE_DELIM = stc.wxSTC_PL_HERE_DELIM # 22 +wxSTC_PL_HERE_Q = stc.wxSTC_PL_HERE_Q # 23 +wxSTC_PL_HERE_QQ = stc.wxSTC_PL_HERE_QQ # 24 +wxSTC_PL_HERE_QX = stc.wxSTC_PL_HERE_QX # 25 +wxSTC_PL_IDENTIFIER = stc.wxSTC_PL_IDENTIFIER # 11 +wxSTC_PL_LONGQUOTE = stc.wxSTC_PL_LONGQUOTE # 19 +wxSTC_PL_NUMBER = stc.wxSTC_PL_NUMBER # 4 +wxSTC_PL_OPERATOR = stc.wxSTC_PL_OPERATOR # 10 +wxSTC_PL_POD = stc.wxSTC_PL_POD # 3 +wxSTC_PL_PREPROCESSOR = stc.wxSTC_PL_PREPROCESSOR # 9 +wxSTC_PL_PUNCTUATION = stc.wxSTC_PL_PUNCTUATION # 8 +wxSTC_PL_REGEX = stc.wxSTC_PL_REGEX # 17 +wxSTC_PL_REGSUBST = stc.wxSTC_PL_REGSUBST # 18 +wxSTC_PL_SCALAR = stc.wxSTC_PL_SCALAR # 12 +wxSTC_PL_STRING = stc.wxSTC_PL_STRING # 6 +wxSTC_PL_STRING_Q = stc.wxSTC_PL_STRING_Q # 26 +wxSTC_PL_STRING_QQ = stc.wxSTC_PL_STRING_QQ # 27 +wxSTC_PL_STRING_QR = stc.wxSTC_PL_STRING_QR # 29 +wxSTC_PL_STRING_QW = stc.wxSTC_PL_STRING_QW # 30 +wxSTC_PL_STRING_QX = stc.wxSTC_PL_STRING_QX # 28 +wxSTC_PL_SYMBOLTABLE = stc.wxSTC_PL_SYMBOLTABLE # 15 +wxSTC_PL_WORD = stc.wxSTC_PL_WORD # 5 +wxSTC_PRINT_BLACKONWHITE = stc.wxSTC_PRINT_BLACKONWHITE # 2 +wxSTC_PRINT_COLOURONWHITE = stc.wxSTC_PRINT_COLOURONWHITE # 3 +wxSTC_PRINT_COLOURONWHITEDEFAULTBG = stc.wxSTC_PRINT_COLOURONWHITEDEFAULTBG # 4 +wxSTC_PRINT_INVERTLIGHT = stc.wxSTC_PRINT_INVERTLIGHT # 1 +wxSTC_PRINT_NORMAL = stc.wxSTC_PRINT_NORMAL # 0 +wxSTC_PROPS_ASSIGNMENT = stc.wxSTC_PROPS_ASSIGNMENT # 3 +wxSTC_PROPS_COMMENT = stc.wxSTC_PROPS_COMMENT # 1 +wxSTC_PROPS_DEFAULT = stc.wxSTC_PROPS_DEFAULT # 0 +wxSTC_PROPS_DEFVAL = stc.wxSTC_PROPS_DEFVAL # 4 +wxSTC_PROPS_SECTION = stc.wxSTC_PROPS_SECTION # 2 +wxSTC_P_CHARACTER = stc.wxSTC_P_CHARACTER # 4 +wxSTC_P_CLASSNAME = stc.wxSTC_P_CLASSNAME # 8 +wxSTC_P_COMMENTBLOCK = stc.wxSTC_P_COMMENTBLOCK # 12 +wxSTC_P_COMMENTLINE = stc.wxSTC_P_COMMENTLINE # 1 +wxSTC_P_DEFAULT = stc.wxSTC_P_DEFAULT # 0 +wxSTC_P_DEFNAME = stc.wxSTC_P_DEFNAME # 9 +wxSTC_P_IDENTIFIER = stc.wxSTC_P_IDENTIFIER # 11 +wxSTC_P_NUMBER = stc.wxSTC_P_NUMBER # 2 +wxSTC_P_OPERATOR = stc.wxSTC_P_OPERATOR # 10 +wxSTC_P_STRING = stc.wxSTC_P_STRING # 3 +wxSTC_P_STRINGEOL = stc.wxSTC_P_STRINGEOL # 13 +wxSTC_P_TRIPLE = stc.wxSTC_P_TRIPLE # 6 +wxSTC_P_TRIPLEDOUBLE = stc.wxSTC_P_TRIPLEDOUBLE # 7 +wxSTC_P_WORD = stc.wxSTC_P_WORD # 5 +wxSTC_SCMOD_ALT = stc.wxSTC_SCMOD_ALT # 4 +wxSTC_SCMOD_CTRL = stc.wxSTC_SCMOD_CTRL # 2 +wxSTC_SCMOD_SHIFT = stc.wxSTC_SCMOD_SHIFT # 1 +wxSTC_SCRIPTOL_CHARACTER = stc.wxSTC_SCRIPTOL_CHARACTER # 7 +wxSTC_SCRIPTOL_COMMENT = stc.wxSTC_SCRIPTOL_COMMENT # 1 +wxSTC_SCRIPTOL_COMMENTBASIC = stc.wxSTC_SCRIPTOL_COMMENTBASIC # 19 +wxSTC_SCRIPTOL_COMMENTDOC = stc.wxSTC_SCRIPTOL_COMMENTDOC # 3 +wxSTC_SCRIPTOL_COMMENTDOCKEYWORD = stc.wxSTC_SCRIPTOL_COMMENTDOCKEYWORD # 17 +wxSTC_SCRIPTOL_COMMENTDOCKEYWORDERROR = stc.wxSTC_SCRIPTOL_COMMENTDOCKEYWORDERROR # 18 +wxSTC_SCRIPTOL_COMMENTLINE = stc.wxSTC_SCRIPTOL_COMMENTLINE # 2 +wxSTC_SCRIPTOL_COMMENTLINEDOC = stc.wxSTC_SCRIPTOL_COMMENTLINEDOC # 15 +wxSTC_SCRIPTOL_DEFAULT = stc.wxSTC_SCRIPTOL_DEFAULT # 0 +wxSTC_SCRIPTOL_IDENTIFIER = stc.wxSTC_SCRIPTOL_IDENTIFIER # 11 +wxSTC_SCRIPTOL_NUMBER = stc.wxSTC_SCRIPTOL_NUMBER # 4 +wxSTC_SCRIPTOL_OPERATOR = stc.wxSTC_SCRIPTOL_OPERATOR # 10 +wxSTC_SCRIPTOL_PREPROCESSOR = stc.wxSTC_SCRIPTOL_PREPROCESSOR # 9 +wxSTC_SCRIPTOL_REGEX = stc.wxSTC_SCRIPTOL_REGEX # 14 +wxSTC_SCRIPTOL_STRING = stc.wxSTC_SCRIPTOL_STRING # 6 +wxSTC_SCRIPTOL_STRINGEOL = stc.wxSTC_SCRIPTOL_STRINGEOL # 12 +wxSTC_SCRIPTOL_UUID = stc.wxSTC_SCRIPTOL_UUID # 8 +wxSTC_SCRIPTOL_VERBATIM = stc.wxSTC_SCRIPTOL_VERBATIM # 13 +wxSTC_SCRIPTOL_WORD = stc.wxSTC_SCRIPTOL_WORD # 5 +wxSTC_SCRIPTOL_WORD2 = stc.wxSTC_SCRIPTOL_WORD2 # 16 +wxSTC_START = stc.wxSTC_START # 2000 +wxSTC_STYLE_BRACEBAD = stc.wxSTC_STYLE_BRACEBAD # 35 +wxSTC_STYLE_BRACELIGHT = stc.wxSTC_STYLE_BRACELIGHT # 34 +wxSTC_STYLE_CONTROLCHAR = stc.wxSTC_STYLE_CONTROLCHAR # 36 +wxSTC_STYLE_DEFAULT = stc.wxSTC_STYLE_DEFAULT # 32 +wxSTC_STYLE_INDENTGUIDE = stc.wxSTC_STYLE_INDENTGUIDE # 37 +wxSTC_STYLE_LASTPREDEFINED = stc.wxSTC_STYLE_LASTPREDEFINED # 39 +wxSTC_STYLE_LINENUMBER = stc.wxSTC_STYLE_LINENUMBER # 33 +wxSTC_STYLE_MAX = stc.wxSTC_STYLE_MAX # 127 +wxSTC_TIME_FOREVER = stc.wxSTC_TIME_FOREVER # 10000000 +wxSTC_USE_POPUP = stc.wxSTC_USE_POPUP # 1 +wxSTC_VISIBLE_SLOP = stc.wxSTC_VISIBLE_SLOP # 1 +wxSTC_VISIBLE_STRICT = stc.wxSTC_VISIBLE_STRICT # 4 +wxSTC_WRAP_NONE = stc.wxSTC_WRAP_NONE # 0 +wxSTC_WRAP_WORD = stc.wxSTC_WRAP_WORD # 1 +wxSTC_WS_INVISIBLE = stc.wxSTC_WS_INVISIBLE # 0 +wxSTC_WS_VISIBLEAFTERINDENT = stc.wxSTC_WS_VISIBLEAFTERINDENT # 2 +wxSTC_WS_VISIBLEALWAYS = stc.wxSTC_WS_VISIBLEALWAYS # 1 +# End generated constants. diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Threading.py b/wxPython/wxPython/lib/PyCrust/wxd/Threading.py new file mode 100644 index 0000000000..ff1f86bd93 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Threading.py @@ -0,0 +1,26 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +class MutexGuiLocker: + """""" + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/ToolBar.py b/wxPython/wxPython/lib/PyCrust/wxd/ToolBar.py new file mode 100644 index 0000000000..d12ac61b54 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/ToolBar.py @@ -0,0 +1,403 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +from Controls import Control +import Parameters as wx + + +class ToolBarBase(Control): + """""" + + def AddCheckLabelTool(self): + """""" + pass + + def AddCheckTool(self): + """""" + pass + + def AddControl(self): + """""" + pass + + def AddLabelTool(self): + """""" + pass + + def AddRadioLabelTool(self): + """""" + pass + + def AddRadioTool(self): + """""" + pass + + def AddSeparator(self): + """""" + pass + + def AddSimpleTool(self): + """""" + pass + + def AddTool(self): + """""" + pass + + def ClearTools(self): + """""" + pass + + def DeleteTool(self): + """""" + pass + + def DeleteToolByPos(self): + """""" + pass + + def DoAddTool(self): + """""" + pass + + def DoInsertTool(self): + """""" + pass + + def EnableTool(self): + """""" + pass + + def FindControl(self): + """""" + pass + + def FindToolForPosition(self): + """""" + pass + + def GetMargins(self): + """""" + pass + + def GetMaxCols(self): + """""" + pass + + def GetMaxRows(self): + """""" + pass + + def GetToolBitmapSize(self): + """""" + pass + + def GetToolClientData(self): + """""" + pass + + def GetToolEnabled(self): + """""" + pass + + def GetToolLongHelp(self): + """""" + pass + + def GetToolMargins(self): + """""" + pass + + def GetToolPacking(self): + """""" + pass + + def GetToolSeparation(self): + """""" + pass + + def GetToolShortHelp(self): + """""" + pass + + def GetToolSize(self): + """""" + pass + + def GetToolState(self): + """""" + pass + + def InsertControl(self): + """""" + pass + + def InsertLabelTool(self): + """""" + pass + + def InsertSeparator(self): + """""" + pass + + def InsertSimpleTool(self): + """""" + pass + + def InsertTool(self): + """""" + pass + + def IsVertical(self): + """""" + pass + + def Realize(self): + """""" + pass + + def RemoveTool(self): + """""" + pass + + def SetMargins(self): + """""" + pass + + def SetMarginsXY(self): + """""" + pass + + def SetMaxRowsCols(self): + """""" + pass + + def SetRows(self): + """""" + pass + + def SetToggle(self): + """""" + pass + + def SetToolBitmapSize(self): + """""" + pass + + def SetToolClientData(self): + """""" + pass + + def SetToolLongHelp(self): + """""" + pass + + def SetToolPacking(self): + """""" + pass + + def SetToolSeparation(self): + """""" + pass + + def SetToolShortHelp(self): + """""" + pass + + def ToggleTool(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ToolBar(ToolBarBase): + """""" + + def Create(self): + """""" + pass + + def FindToolForPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ToolBarSimple(ToolBarBase): + """""" + + def Create(self): + """""" + pass + + def FindToolForPosition(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class ToolBarToolBase(Object): + """""" + + def Attach(self): + """""" + pass + + def CanBeToggled(self): + """""" + pass + + def Destroy(self): + """""" + pass + + def Detach(self): + """""" + pass + + def Enable(self): + """""" + pass + + def GetBitmap(self): + """""" + pass + + def GetBitmap1(self): + """""" + pass + + def GetBitmap2(self): + """""" + pass + + def GetClientData(self): + """""" + pass + + def GetControl(self): + """""" + pass + + def GetDisabledBitmap(self): + """""" + pass + + def GetId(self): + """""" + pass + + def GetKind(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetLongHelp(self): + """""" + pass + + def GetNormalBitmap(self): + """""" + pass + + def GetShortHelp(self): + """""" + pass + + def GetStyle(self): + """""" + pass + + def GetToolBar(self): + """""" + pass + + def IsButton(self): + """""" + pass + + def IsControl(self): + """""" + pass + + def IsEnabled(self): + """""" + pass + + def IsSeparator(self): + """""" + pass + + def IsToggled(self): + """""" + pass + + def SetBitmap1(self): + """""" + pass + + def SetBitmap2(self): + """""" + pass + + def SetClientData(self): + """""" + pass + + def SetDisabledBitmap(self): + """""" + pass + + def SetLabel(self): + """""" + pass + + def SetLongHelp(self): + """""" + pass + + def SetNormalBitmap(self): + """""" + pass + + def SetShortHelp(self): + """""" + pass + + def SetToggle(self): + """""" + pass + + def Toggle(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Tree.py b/wxPython/wxPython/lib/PyCrust/wxd/Tree.py new file mode 100644 index 0000000000..46ae981f33 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Tree.py @@ -0,0 +1,402 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import Object +from Controls import Control +import Parameters as wx + + +class TreeCtrl(Control): + """""" + + def AddRoot(self): + """""" + pass + + def AppendItem(self): + """""" + pass + + def AssignImageList(self): + """""" + pass + + def AssignStateImageList(self): + """""" + pass + + def Collapse(self): + """""" + pass + + def CollapseAndReset(self): + """""" + pass + + def Create(self): + """""" + pass + + def Delete(self): + """""" + pass + + def DeleteAllItems(self): + """""" + pass + + def DeleteChildren(self): + """""" + pass + + def EditLabel(self): + """""" + pass + + def EnsureVisible(self): + """""" + pass + + def Expand(self): + """""" + pass + + def GetBoundingRect(self): + """""" + pass + + def GetChildrenCount(self): + """""" + pass + + def GetCount(self): + """""" + pass + + def GetEditControl(self): + """""" + pass + + def GetFirstChild(self): + """""" + pass + + def GetFirstVisibleItem(self): + """""" + pass + + def GetImageList(self): + """""" + pass + + def GetIndent(self): + """""" + pass + + def GetItemBackgroundColour(self): + """""" + pass + + def GetItemData(self): + """""" + pass + + def GetItemFont(self): + """""" + pass + + def GetItemImage(self): + """""" + pass + + def GetItemParent(self): + """""" + pass + + def GetItemSelectedImage(self): + """""" + pass + + def GetItemText(self): + """""" + pass + + def GetItemTextColour(self): + """""" + pass + + def GetLastChild(self): + """""" + pass + + def GetNextChild(self): + """""" + pass + + def GetNextSibling(self): + """""" + pass + + def GetNextVisible(self): + """""" + pass + + def GetPrevSibling(self): + """""" + pass + + def GetPrevVisible(self): + """""" + pass + + def GetPyData(self): + """""" + pass + + def GetRootItem(self): + """""" + pass + + def GetSelection(self): + """""" + pass + + def GetSelections(self): + """""" + pass + + def GetSpacing(self): + """""" + pass + + def GetStateImageList(self): + """""" + pass + + def HitTest(self): + """""" + pass + + def InsertItem(self): + """""" + pass + + def InsertItemBefore(self): + """""" + pass + + def IsBold(self): + """""" + pass + + def IsExpanded(self): + """""" + pass + + def IsSelected(self): + """""" + pass + + def IsVisible(self): + """""" + pass + + def ItemHasChildren(self): + """""" + pass + + def PrependItem(self): + """""" + pass + + def ScrollTo(self): + """""" + pass + + def SelectItem(self): + """""" + pass + + def SetImageList(self): + """""" + pass + + def SetIndent(self): + """""" + pass + + def SetItemBackgroundColour(self): + """""" + pass + + def SetItemBold(self): + """""" + pass + + def SetItemData(self): + """""" + pass + + def SetItemFont(self): + """""" + pass + + def SetItemHasChildren(self): + """""" + pass + + def SetItemImage(self): + """""" + pass + + def SetItemSelectedImage(self): + """""" + pass + + def SetItemText(self): + """""" + pass + + def SetItemTextColour(self): + """""" + pass + + def SetPyData(self): + """""" + pass + + def SetSpacing(self): + """""" + pass + + def SetStateImageList(self): + """""" + pass + + def SortChildren(self): + """""" + pass + + def Toggle(self): + """""" + pass + + def Unselect(self): + """""" + pass + + def UnselectAll(self): + """""" + pass + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + +class TreeItemAttr: + """""" + + def GetBackgroundColour(self): + """""" + pass + + def GetFont(self): + """""" + pass + + def GetTextColour(self): + """""" + pass + + def HasBackgroundColour(self): + """""" + pass + + def HasFont(self): + """""" + pass + + def HasTextColour(self): + """""" + pass + + def SetBackgroundColour(self): + """""" + pass + + def SetFont(self): + """""" + pass + + def SetTextColour(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TreeItemData(Object): + """""" + + def GetData(self): + """""" + pass + + def GetId(self): + """""" + pass + + def SetData(self): + """""" + pass + + def SetId(self): + """""" + pass + + def __init__(self): + """""" + pass + + +class TreeItemId: + """""" + + def IsOk(self): + """""" + pass + + def Ok(self): + """""" + pass + + def __cmp__(self): + """""" + pass + + def __del__(self): + """""" + pass + + def __init__(self): + """""" + pass + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Validators.py b/wxPython/wxPython/lib/PyCrust/wxd/Validators.py new file mode 100644 index 0000000000..6c5e87e240 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Validators.py @@ -0,0 +1,56 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import EvtHandler +import Parameters as wx + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class Validator(EvtHandler): + """""" + + def __init__(self): + """""" + pass + + def Clone(self): + """""" + pass + + def GetWindow(self): + """""" + pass + + def SetWindow(self, window): + """""" + pass + + +class PyValidator(Validator): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self, _class, incref=True): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/Window.py b/wxPython/wxPython/lib/PyCrust/wxd/Window.py new file mode 100644 index 0000000000..51392a094d --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/Window.py @@ -0,0 +1,850 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Base import EvtHandler +import Parameters as wx + +try: + True +except NameError: + True = 1==1 + False = 1==0 + + +class Window(EvtHandler): + """""" + + def __init__(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, name=wx.PyPanelNameStr): + """""" + pass + + def AcceptsFocus(self): + """""" + pass + + def AddChild(self, child): + """""" + pass + + def CaptureMouse(self): + """""" + pass + + def Center(self, direction=wx.BOTH): + """""" + pass + + def CenterOnParent(self, direction=wx.BOTH): + """""" + pass + + def CenterOnScreen(self, direction=wx.BOTH): + """""" + pass + + def Centre(self, direction=wx.BOTH): + """""" + pass + + def CentreOnParent(self, direction=wx.BOTH): + """""" + pass + + def CentreOnScreen(self, direction=wx.BOTH): + """""" + pass + + def Clear(self): + """""" + pass + + def ClientToScreen(self, pt): + """""" + pass + + def ClientToScreenXY(self, x, y): + """""" + pass + + def Close(self, force=False): + """""" + pass + + def ConvertDialogPointToPixels(self, pt): + """""" + pass + + def ConvertDialogSizeToPixels(self, sz): + """""" + pass + + def ConvertPixelPointToDialog(self, pt): + """""" + pass + + def ConvertPixelSizeToDialog(self, sz): + """""" + pass + + def Create(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, name=wx.PyPanelNameStr): + """""" + pass + + def DLG_PNT(self, win, point_or_x, y=None): + """""" + pass + + def DLG_SZE(self, win, size_width, height=None): + """""" + pass + + def Destroy(self): + """""" + pass + + def DestroyChildren(self): + """""" + pass + + def DragAcceptFiles(self, accept): + """Windows only.""" + pass + + def Enable(self, enable): + """""" + pass + + def FindWindowById(self, id): + """""" + pass + + def FindWindowByName(self, name): + """""" + pass + + def Fit(self): + """""" + pass + + def FitInside(self): + """""" + pass + + def Freeze(self): + """""" + pass + + def GetAcceleratorTable(self): + """""" + pass + + def GetAdjustedBestSize(self): + """""" + pass + + def GetAutoLayout(self): + """""" + pass + + def GetBackgroundColour(self): + """""" + pass + + def GetBestSize(self): + """""" + pass + + def GetBestVirtualSize(self): + """""" + pass + + def GetBorder(self): + """""" + pass + + def GetCaret(self): + """""" + pass + + def GetCharHeight(self): + """""" + pass + + def GetCharWidth(self): + """""" + pass + + def GetChildren(self): + """""" + pass + + def GetClientAreaOrigin(self): + """""" + pass + + def GetClientRect(self): + """""" + pass + + def GetClientSize(self): + """""" + pass + + def GetClientSizeTuple(self): + """""" + pass + + def GetConstraints(self): + """""" + pass + + def GetContainingSizer(self): + """""" + pass + + def GetCursor(self): + """""" + pass + + def GetDefaultItem(self): + """""" + pass + + def GetDropTarget(self): + """""" + pass + + def GetEventHandler(self): + """""" + pass + + def GetFont(self): + """""" + pass + + def GetForegroundColour(self): + """""" + pass + + def GetFullTextExtent(self): + """""" + pass + + def GetGrandParent(self): + """""" + pass + + def GetHandle(self): + """""" + pass + + def GetHelpText(self): + """""" + pass + + def GetId(self): + """""" + pass + + def GetLabel(self): + """""" + pass + + def GetMaxSize(self): + """""" + pass + + def GetName(self): + """""" + pass + + def GetParent(self): + """""" + pass + + def GetPosition(self): + """""" + pass + + def GetPositionTuple(self): + """""" + pass + + def GetRect(self): + """""" + pass + + def GetScrollPos(self, orientation): + """""" + pass + + def GetScrollRange(self, orientation): + """""" + pass + + def GetScrollThumb(self, orientation): + """""" + pass + + def GetSize(self): + """""" + pass + + def GetSizeTuple(self): + """""" + pass + + def GetSizer(self): + """""" + pass + + def GetTextExtent(self, string): + """""" + pass + + def GetTitle(self): + """""" + pass + + def GetToolTip(self): + """""" + pass + + def GetUpdateRegion(self): + """""" + pass + + def GetValidator(self): + """""" + pass + + def GetVirtualSize(self): + """""" + pass + + def GetVirtualSizeTuple(self): + """""" + pass + + def GetWindowStyleFlag(self): + """""" + pass + + def HasCapture(self): + """""" + pass + + def HasScrollbar(self, orient): + """""" + pass + + def Hide(self): + """""" + pass + + def HitTest(self, pt): + """""" + pass + + def InitDialog(self): + """""" + pass + + def IsBeingDeleted(self): + """""" + pass + + def IsEnabled(self): + """""" + pass + + def IsExposed(self, x, y, w=0, h=0): + """""" + pass + + def IsExposedPoint(self, pt): + """""" + pass + + def IsExposedRect(self, rect): + """""" + pass + + def IsRetained(self): + """""" + pass + + def IsShown(self): + """""" + pass + + def IsTopLevel(self): + """""" + pass + + def Layout(self): + """""" + pass + + def LineDown(self): + """""" + pass + + def LineUp(self): + """""" + pass + + def LoadFromResource(self, parent, resourceName, resourceTable=wx.NULL): + """Only if USE_WX_RESOURCES.""" + pass + + def Lower(self): + """""" + pass + + def MakeModal(self, flag=True): + """""" + pass + + def Move(self, point, flags=wx.SIZE_USE_EXISTING): + """""" + pass + + def MoveXY(self, x, y, flags=wx.SIZE_USE_EXISTING): + """""" + pass + + def OnPaint(self, event): + """Windows only.""" + pass + + def PageDown(self): + """""" + pass + + def PageUp(self): + """""" + pass + + def PopEventHandler(self, deleteHandler=False): + """""" + pass + + def PopupMenu(self, menu, pos): + """""" + pass + + def PopupMenuXY(self, menu, x, y): + """""" + pass + + def PushEventHandler(self, handler): + """""" + pass + + def Raise(self): + """""" + pass + + def Refresh(self, eraseBackground=True, rect=wx.NULL): + """""" + pass + + def RefreshRect(self, rect): + """""" + pass + + def ReleaseMouse(self): + """""" + pass + + def RemoveChild(self, child): + """""" + pass + + def RemoveEventHandler(self, handler): + """""" + pass + + def Reparent(self, newParent): + """""" + pass + + def ScreenToClient(self, pt): + """""" + pass + + def ScreenToClientXY(self, x, y): + """""" + pass + + def ScrollLines(self, lines): + """""" + pass + + def ScrollPages(self, pages): + """""" + pass + + def ScrollWindow(self, dx, dy, rect=wx.NULL): + """""" + pass + + def SetAcceleratorTable(self, accel): + """""" + pass + + def SetAutoLayout(self, autoLayout): + """""" + pass + + def SetBackgroundColour(self, colour): + """""" + pass + + def SetCaret(self, caret): + """""" + pass + + def SetClientSize(self, size): + """""" + pass + + def SetClientSizeWH(self, width, height): + """""" + pass + + def SetConstraints(self, constraints): + """""" + pass + + def SetContainingSizer(self, sizer): + """""" + pass + + def SetCursor(self, cursor): + """""" + pass + + def SetDefaultItem(self, btn): + """""" + pass + + def SetDimensions(self): + """""" + pass + + def SetDropTarget(self, target): + """""" + pass + + def SetEventHandler(self, handler): + """""" + pass + + def SetExtraStyle(self, exStyle): + """""" + pass + + def SetFocus(self): + """""" + pass + + def SetFocusFromKbd(self): + """""" + pass + + def SetFont(self, font): + """""" + pass + + def SetForegroundColour(self, colour): + """""" + pass + + def SetHelpText(self, helpText): + """""" + pass + + def SetHelpTextForId(self, text): + """""" + pass + + def SetId(self, id): + """""" + pass + + def SetLabel(self, label): + """""" + pass + + def SetName(self, name): + """""" + pass + + def SetPosition(self, pos, flags=wx.SIZE_USE_EXISTING): + """""" + pass + + def SetRect(self, rect, sizeFlags=wx.SIZE_AUTO): + """""" + pass + + def SetScrollPos(self, orientation, pos, refresh=True): + """""" + pass + + def SetScrollbar(self, orientation, pos, thumbSize, range, refresh=True): + """""" + pass + + def SetSize(self, x, y, width, height, sizeFlags=wx.SIZE_AUTO): + """""" + pass + + def SetSizeHints(self, minW, minH, maxW=-1, maxH=-1, incW=-1, incH=-1): + """""" + pass + + def SetSizer(self, sizer, deleteOld=True): + """""" + pass + + def SetSizerAndFit(self, sizer, deleteOld=True): + """""" + pass + + def SetTitle(self, title): + """""" + pass + + def SetTmpDefaultItem(self, win): + """""" + pass + + def SetToolTip(self, tooltip): + """""" + pass + + def SetToolTipString(self, tip): + """""" + pass + + def SetValidator(self, validator): + """""" + pass + + def SetVirtualSize(self, size): + """""" + pass + + def SetVirtualSizeHints(self, minW, minH, maxW=-1, maxH=-1): + """""" + pass + + def SetVirtualSizeWH(self, x, y): + """""" + pass + + def SetWindowStyle(self, style): + """""" + pass + + def SetWindowStyleFlag(self, style): + """""" + pass + + def Show(self, show=True): + """""" + pass + + def Thaw(self): + """""" + pass + + def TransferDataFromWindow(self): + """""" + pass + + def TransferDataToWindow(self): + """""" + pass + + def UnsetConstraints(self, constraints): + """""" + pass + + def Update(self): + """""" + pass + + def UpdateWindowUI(self): + """""" + pass + + def Validate(self): + """""" + pass + + def WarpPointer(self, x, y): + """""" + pass + + +class PyWindow(Window): + """""" + + def __init__(self): + """""" + pass + + def _setCallbackInfo(self): + """""" + pass + + def base_AcceptsFocus(self): + """""" + pass + + def base_AcceptsFocusFromKeyboard(self): + """""" + pass + + def base_AddChild(self): + """""" + pass + + def base_DoGetBestSize(self): + """""" + pass + + def base_DoGetClientSize(self): + """""" + pass + + def base_DoGetPosition(self): + """""" + pass + + def base_DoGetSize(self): + """""" + pass + + def base_DoGetVirtualSize(self): + """""" + pass + + def base_DoMoveWindow(self): + """""" + pass + + def base_DoSetClientSize(self): + """""" + pass + + def base_DoSetSize(self): + """""" + pass + + def base_DoSetVirtualSize(self): + """""" + pass + + def base_GetMaxSize(self): + """""" + pass + + def base_InitDialog(self): + """""" + pass + + def base_RemoveChild(self): + """""" + pass + + def base_TransferDataFromWindow(self): + """""" + pass + + def base_TransferDataToWindow(self): + """""" + pass + + def base_Validate(self): + """""" + pass + + +class TopLevelWindow(Window): + """""" + + def Create(self): + """""" + pass + + def GetIcon(self): + """""" + pass + + def GetTitle(self): + """""" + pass + + def Iconize(self): + """""" + pass + + def IsFullScreen(self): + """""" + pass + + def IsIconized(self): + """""" + pass + + def IsMaximized(self): + """""" + pass + + def Maximize(self): + """""" + pass + + def Restore(self): + """""" + pass + + def SetIcon(self): + """""" + pass + + def SetIcons(self): + """""" + pass + + def SetTitle(self): + """""" + pass + + def ShowFullScreen(self): + """""" + pass + + def __init__(self): + """""" + pass + + diff --git a/wxPython/wxPython/lib/PyCrust/wxd/__init__.py b/wxPython/wxPython/lib/PyCrust/wxd/__init__.py new file mode 100644 index 0000000000..db6003cf3b --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/__init__.py @@ -0,0 +1 @@ +# Orbtech python package. \ No newline at end of file diff --git a/wxPython/wxPython/lib/PyCrust/wxd/d_stc.py b/wxPython/wxPython/lib/PyCrust/wxd/d_stc.py new file mode 100644 index 0000000000..e906ffc889 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/d_stc.py @@ -0,0 +1,17 @@ +"""Decorator utility for documentation and shell scripting. + +When you import stc from this module, all of the classes get decorated +with docstrings from our decoration class definitions. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + +from wxPython import stc + +import stc_ + +import decorator + +decorator.decorate(real=stc, decoration=stc_) diff --git a/wxPython/wxPython/lib/PyCrust/wxd/d_wx.py b/wxPython/wxPython/lib/PyCrust/wxd/d_wx.py new file mode 100644 index 0000000000..f837473463 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/d_wx.py @@ -0,0 +1,17 @@ +"""Decorator utility for documentation and shell scripting. + +When you import wx from this module, all of the classes get decorated +with docstrings from our decoration class definitions. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + +from wxPython import wx + +import wx_ + +import decorator + +decorator.decorate(real=wx, decoration=wx_) diff --git a/wxPython/wxPython/lib/PyCrust/wxd/decorator.py b/wxPython/wxPython/lib/PyCrust/wxd/decorator.py new file mode 100644 index 0000000000..6765268f5b --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/decorator.py @@ -0,0 +1,92 @@ +"""Decorator utility for documentation and shell scripting.""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +import inspect + +try: + True +except NameError: + True = 1==1 + False = 1==0 + +def decorate(real, decoration): + """Decorate real module with docstrings from decoration module.""" + realdict = real.__dict__ + for item in decoration.__dict__.values(): + if inspect.isclass(item): + decorateClass(item, realdict) + elif inspect.isfunction(item): + decorateFunction(item, realdict) + +def decorateClass(item, realdict): + classname = item.__name__ + if not classname.startswith('wx'): + classname = 'wx' + classname + try: + wxclass = realdict[classname] + except: + print classname + else: + if item.__doc__: + wxclass.__doc__ = item.__doc__ + # Get attributes from only the item's local dictionary! + for attrname, attr in item.__dict__.items(): + # If the attribute has a docstring, and the wx class has a + # matching attribute. + if hasattr(attr, '__doc__') and hasattr(wxclass, attrname): + if inspect.isfunction(attr): + # Class methods are functions. + doc = getdoc(attr, drop=True) + # Is getattr() okay, or do we want to only look in + # the wxclass.__dict__ and wxclassPtr.__dict__? + wxattr = getattr(wxclass, attrname) + # Our class code may be defined incorrectly, and + # the wxattr may not actually be a class method, + # but that's okay because the following attempt + # will simply fail. + try: + func = wxattr.im_func + func.__doc__ = doc + except: + pass + +def decorateFunction(item, realdict): + funcname = item.__name__ + if funcname in realdict.keys(): + func = realdict[funcname] + doc = getdoc(item, drop=False) + try: + # Built-in functions have a read-only docstring. :-( + func.__doc__ = doc + except: + # print funcname + pass + +def getdoc(attr, drop=False): + """Return a docstring for attr, which should be a method.""" + doc = '' + if attr.__doc__: + doc = inspect.getdoc(attr).strip() + name = attr.__name__ + # tip is a string with name(argspec), like: "SetLabel(label)" + tip = '' + argspec = apply(inspect.formatargspec, inspect.getargspec(attr)) + # The first parameter to a method is a reference to an instance, + # usually coded as "self", and is usually passed automatically by + # Python and therefore we want to drop it. + temp = argspec.split(',') + if len(temp) == 1: # No other arguments. + argspec = '()' + elif drop: # Drop the first argument. + argspec = '(' + ','.join(temp[1:]).lstrip() + else: + argspec = ','.join(temp).lstrip() + tip = name + argspec + firstline = doc.split('\n')[0].lstrip() + if tip != firstline: + doc = '%s\n\n%s' % (tip, doc) + return doc diff --git a/wxPython/wxPython/lib/PyCrust/wxd/gen.py b/wxPython/wxPython/lib/PyCrust/wxd/gen.py new file mode 100644 index 0000000000..2e07922ade --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/gen.py @@ -0,0 +1,71 @@ + +import inspect +from wxPython import wx + + +def scan(): + d = wx.__dict__ + newd = {} + keys = d.keys() + keys.sort() + for key in keys: + if key.endswith('Ptr'): + # Skip + pass + elif key+'Ptr' in keys: + # Rename + newd[key] = d[key+'Ptr'] + else: + # Include as is + newd[key] = d[key] + d = newd + keys = d.keys() + keys.sort() + for key in keys: + value = d[key] + if inspect.isclass(value): + # genClass(value) + pass + elif callable(value): + genFunction(value) + pass + else: + # print type(value), value + pass + + +def genClass(cls): + sp4 = ' ' * 4 + name = cls.__name__ + if name.endswith('Ptr'): + name = name[:-3] +## if name != 'wxNotebook': +## return + parent = '' + if cls.__bases__: + parent = cls.__bases__[0].__name__ + if parent.endswith('Ptr'): + parent = parent[:-3] + parent = '(%s)' % parent + items = cls.__dict__.keys() + items.sort() + print + print 'class %s%s:' % (name, parent) + print sp4 + '""""""' + print + for item in items: + attr = cls.__dict__[item] + if inspect.isfunction(attr): + print sp4 + 'def ' + item + '(self):' + print sp4 + sp4 + '""""""' + print sp4 + sp4 + 'pass' + print + + +def genFunction(func): + sp4 = ' ' * 4 + name = func.__name__ + print 'def %s():' % name + print sp4 + '""""""' + print sp4 + 'pass' + print diff --git a/wxPython/wxPython/lib/PyCrust/wxd/stc_.py b/wxPython/wxPython/lib/PyCrust/wxd/stc_.py new file mode 100644 index 0000000000..2902d24cb5 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/stc_.py @@ -0,0 +1,1409 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +from Controls import Control +import Parameters as wx + + +class StyledTextCtrl(Control): + """StyledTextCtrl class.""" + + def __init__(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0, name=wx.PySTCNameStr): + """Create a StyledTextCtrl instance.""" + pass + + def AddRefDocument(self, docPointer): + """Extend life of document.""" + pass + + def AddStyledText(self, data): + """Add array of cells to document.""" + pass + + def AddText(self, text): + """Add text to the document.""" + pass + + def AutoCompActive(self): + """Is there an auto-completion list visible?""" + pass + + def AutoCompCancel(self): + """Remove the auto-completion list from the screen.""" + pass + + def AutoCompComplete(self): + """User has selected an item so remove the list and insert the + selection.""" + pass + + def AutoCompGetAutoHide(self): + """Return whether or not autocompletion is hidden + automatically when nothing matches.""" + pass + + def AutoCompGetCancelAtStart(self): + """Return whether auto-completion cancelled by backspacing + before start.""" + pass + + def AutoCompGetChooseSingle(self): + """Return whether a single item auto-completion list + automatically choose the item.""" + pass + + def AutoCompGetDropRestOfWord(self): + """Return whether or not autocompletion deletes any word + characters after the inserted text upon completion.""" + pass + + def AutoCompGetIgnoreCase(self): + """Return state of ignore case flag.""" + pass + + def AutoCompGetSeparator(self): + """Return the auto-completion list separator character.""" + pass + + def AutoCompPosStart(self): + """Return the position of the caret when the auto-completion + list was displayed.""" + pass + + def AutoCompSelect(self, text): + """Select the item in the auto-completion list that starts + with a string.""" + pass + + def AutoCompSetAutoHide(self, autoHide): + """Set whether or not autocompletion is hidden automatically + when nothing matches.""" + pass + + def AutoCompSetCancelAtStart(self, cancel): + """Should the auto-completion list be cancelled if the user + backspaces to a position before where the box was created.""" + pass + + def AutoCompSetChooseSingle(self, chooseSingle): + """Should a single item auto-completion list automatically + choose the item.""" + pass + + def AutoCompSetDropRestOfWord(self, dropRestOfWord): + """Set whether or not autocompletion deletes any word + characters after the inserted text upon completion.""" + pass + + def AutoCompSetFillUps(self, characterSet): + """Define a set of characters that when typed will cause the + autocompletion to choose the selected item.""" + pass + + def AutoCompSetIgnoreCase(self, ignoreCase): + """Set whether case is significant when performing + auto-completion searches.""" + pass + + def AutoCompSetSeparator(self, separatorCharacter): + """Change the separator character in the string setting up an + auto-completion list. Default is space but can be changed if + items contain space.""" + pass + + def AutoCompShow(self, lenEntered, itemList): + """Display a auto-completion list. + + The lenEntered parameter indicates how many characters before + the caret should be used to provide context.""" + pass + + def AutoCompStops(self, characterSet): + """Define a set of character that when typed cancel the + auto-completion list.""" + pass + + def BeginUndoAction(self): + """Start a sequence of actions that is undone and redone as a + unit. May be nested.""" + pass + + def BraceBadLight(self, pos): + """Highlight the character at a position indicating there is + no matching brace.""" + pass + + def BraceHighlight(self, pos1, pos2): + """Highlight the characters at two positions.""" + pass + + def BraceMatch(self, pos): + """Find the position of a matching brace or INVALID_POSITION + if no match.""" + pass + + def CallTipActive(self): + """Is there an active call tip?""" + pass + + def CallTipCancel(self): + """Remove the call tip from the screen.""" + pass + + def CallTipPosAtStart(self): + """Return the position where the caret was before displaying + the call tip.""" + pass + + def CallTipSetBackground(self, back): + """Set the background colour for the call tip.""" + pass + + def CallTipSetHighlight(self, start, end): + """Highlight a segment of the definition.""" + pass + + def CallTipShow(self, pos, definition): + """Show a call tip containing a definition near position pos.""" + pass + + def CanPaste(self): + """Will a paste succeed?""" + pass + + def CanRedo(self): + """Are there any redoable actions in the undo history?""" + pass + + def CanUndo(self): + """Are there any undoable actions in the undo history?""" + pass + + def Clear(self): + """Clear the selection.""" + pass + + def ClearAll(self): + """Delete all text in the document.""" + pass + + def ClearDocumentStyle(self): + """Set all style bytes to 0, remove all folding information.""" + pass + + def CmdKeyAssign(self, key, modifiers, cmd): + """When key+modifier combination km is pressed perform msg.""" + pass + + def CmdKeyClear(self, key, modifiers): + """When key+modifier combination km do nothing.""" + pass + + def CmdKeyClearAll(self): + """Drop all key mappings.""" + pass + + def CmdKeyExecute(self, cmd): + """Perform one of the operations defined by the STC_CMD_* + constants.""" + pass + + def Colourise(self, start, end): + """Colourise a segment of the document using the current + lexing language.""" + pass + + def ConvertEOLs(self, eolMode): + """Convert all line endings in the document to one mode.""" + pass + + def Copy(self): + """Copy the selection to the clipboard.""" + pass + + def CreateDocument(self): + """Create a new document object. + + Starts with reference count of 1 and not selected into editor.""" + pass + + def Cut(self): + """Cut the selection to the clipboard.""" + pass + + def DelLineLeft(self): + """Delete from the current position to the start of the line.""" + pass + + def DelLineRight(self): + """Delete from the current position to the end of the line.""" + pass + + def DocLineFromVisible(self, lineDisplay): + """Find the document line of a display line taking hidden + lines into account.""" + pass + + def EmptyUndoBuffer(self): + """Delete the undo history.""" + pass + + def EndUndoAction(self): + """End a sequence of actions that is undone and redone as a + unit.""" + pass + + def EnsureCaretVisible(self): + """Ensure the caret is visible.""" + pass + + def EnsureVisible(self, line): + """Ensure a particular line is visible by expanding any header + line hiding it.""" + pass + + def EnsureVisibleEnforcePolicy(self, line): + """Ensure a particular line is visible by expanding any header + line hiding it. Use the currently set visibility policy to + determine which range to display.""" + pass + + def FindText(self, minPos, maxPos, text, flags=0): + """Find some text in the document.""" + pass + + def FormatRange(self, doDraw, startPos, endPos, draw, + target, renderRect, pageRect): + """On Windows, will draw the document into a display context + such as a printer.""" + pass + + def GetAnchor(self): + """Return the position of the opposite end of the selection to + the caret.""" + pass + + def GetBackSpaceUnIndents(self): + """Does a backspace pressed when caret is within indentation + unindent?""" + pass + + def GetBufferedDraw(self): + """Is drawing done first into a buffer or direct to the + screen?""" + pass + + def GetCaretForeground(self): + """Return the foreground colour of the caret.""" + pass + + def GetCaretLineBack(self): + """Return the colour of the background of the line containing + the caret.""" + pass + + def GetCaretLineVisible(self): + """Is the background of the line containing the caret in a + different colour?""" + pass + + def GetCaretPeriod(self): + """Return the time in milliseconds that the caret is on and + off.""" + pass + + def GetCaretWidth(self): + """Return the width of the insert mode caret.""" + pass + + def GetCharAt(self, pos): + """Return the character byte at the position.""" + pass + + def GetCodePage(self): + """Return the code page used to interpret the bytes of the + document as characters.""" + pass + + def GetColumn(self, pos): + """Return the column number of a position, taking tab width + into account.""" + pass + + def GetControlCharSymbol(self): + """Return the way control characters are displayed.""" + pass + + def GetCurLine(self): + """Return (text, pos) tuple with the text of the line + containing the caret and the position of the caret within the + line.""" + pass + + def GetCurrentLine(self): + """Return the line number of the line with the caret.""" + pass + + def GetCurrentPos(self): + """Return the position of the caret.""" + pass + + def GetCursor(self): + """Return cursor type.""" + pass + + def GetDocPointer(self): + """Return a pointer to the document object.""" + pass + + def GetEOLMode(self): + """Return the current end of line mode: CRLF, CR, or LF.""" + pass + + def GetEdgeColour(self): + """Return the colour used in edge indication.""" + pass + + def GetEdgeColumn(self): + """Return the column number which text should be kept within.""" + pass + + def GetEdgeMode(self): + """Return the edge highlight mode.""" + pass + + def GetEndAtLastLine(self): + """Return whether the maximum scroll position has the last + line at the bottom of the view.""" + pass + + def GetEndStyled(self): + """Return the position of the last correctly styled character.""" + pass + + def GetFirstVisibleLine(self): + """Return the line at the top of the display.""" + pass + + def GetFoldExpanded(self, line): + """Is a header line expanded?""" + pass + + def GetFoldLevel(self, line): + """Return the fold level of a line.""" + pass + + def GetFoldParent(self, line): + """Find the parent line of a child line.""" + pass + + def GetHighlightGuide(self): + """Return the highlighted indentation guide column.""" + pass + + def GetIndent(self): + """Return indentation size.""" + pass + + def GetIndentationGuides(self): + """Are the indentation guides visible?""" + pass + + def GetLastChild(self, line, level): + """Find the last child line of a header line.""" + pass + + def GetLastKeydownProcessed(self): + """Can be used to prevent the EVT_CHAR handler from adding the + char.""" + pass + + def GetLayoutCache(self): + """Return the degree of caching of layout information.""" + pass + + def GetLength(self): + """Return the number of characters in the document.""" + pass + + def GetLexer(self): + """Return the lexing language of the document.""" + pass + + def GetLine(self, line): + """Return the contents of a line.""" + pass + + def GetLineCount(self): + """Return the number of lines in the document. There is + always at least one.""" + pass + + def GetLineEndPosition(self, line): + """Return the position after the last visible characters on a + line.""" + pass + + def GetLineIndentPosition(self, line): + """Return the position before the first non indentation + character on a line.""" + pass + + def GetLineIndentation(self, line): + """Return the number of columns that a line is indented.""" + pass + + def GetLineState(self, line): + """Return the extra styling information for a line.""" + pass + + def GetLineVisible(self, line): + """Is a line visible?""" + pass + + def GetMarginLeft(self): + """Return the size in pixels of the left margin.""" + pass + + def GetMarginMask(self, margin): + """Return the marker mask of a margin.""" + pass + + def GetMarginRight(self): + """Return the size in pixels of the right margin.""" + pass + + def GetMarginSensitive(self, margin): + """Return the mouse click sensitivity of a margin.""" + pass + + def GetMarginType(self, margin): + """Return the type of a margin.""" + pass + + def GetMarginWidth(self, margin): + """Return the width of a margin in pixels.""" + pass + + def GetMaxLineState(self): + """Return the last line number that has line state.""" + pass + + def GetModEventMask(self): + """Return which document modification events are sent to the + container.""" + pass + + def GetModify(self): + """Is the document different from when it was last saved?""" + pass + + def GetMouseDownCaptures(self): + """Return whether mouse gets captured.""" + pass + + def GetMouseDwellTime(self): + """Return the time the mouse must sit still to generate a + mouse dwell event.""" + pass + + def GetOvertype(self): + """Return true if overtype mode is active otherwise false is + returned.""" + pass + + def GetPrintColourMode(self): + """Return the print colour mode.""" + pass + + def GetPrintMagnification(self): + """Return the print magnification.""" + pass + + def GetReadOnly(self): + """In read-only mode?""" + pass + + def GetSTCFocus(self): + """Return internal focus flag.""" + pass + + def GetScrollWidth(self): + """Return the document width assumed for scrolling.""" + pass + + def GetSearchFlags(self): + """Return the search flags used by SearchInTarget.""" + pass + + def GetSelectedText(self): + """Return the selected text.""" + pass + + def GetSelectionEnd(self): + """Return the position at the end of the selection.""" + pass + + def GetSelection(self): + """Return the start and end positions of the current + selection.""" + pass + + def GetSelectionStart(self): + """Return the position at the start of the selection.""" + pass + + def GetStatus(self): + """Return error status.""" + pass + + def GetStyleAt(self, pos): + """Return the style byte at the position.""" + pass + + def GetStyleBits(self): + """Return number of bits in style bytes used to hold the + lexical state.""" + pass + + def GetStyledText(self, startPos, endPos): + """Return a buffer of cells.""" + pass + + def GetTabIndents(self): + """Does a tab pressed when caret is within indentation indent?""" + pass + + def GetTabWidth(self): + """Return the visible size of a tab.""" + pass + + def GetTargetEnd(self): + """Return the position that ends the target.""" + pass + + def GetTargetStart(self): + """Return the position that starts the target.""" + pass + + def GetText(self): + """Return all the text in the document.""" + pass + + def GetTextLength(self): + """Return the number of characters in the document.""" + pass + + def GetTextRange(self, startPos, endPos): + """Return a range of text.""" + pass + + def GetUndoCollection(self): + """Is undo history being collected?""" + pass + + def GetUseHorizontalScrollBar(self): + """Is the horizontal scroll bar visible?""" + pass + + def GetUseTabs(self): + """Return whether tabs will be used in indentation.""" + pass + + def GetViewEOL(self): + """Are the end of line characters visible?""" + pass + + def GetViewWhiteSpace(self): + """Are white space characters currently visible? Return one + of SCWS_* constants.""" + pass + + def GetWrapMode(self): + """Return whether text is word wrapped.""" + pass + + def GetXOffset(self): + """Return the xOffset (self, ie, horizonal scroll position).""" + pass + + def GetZoom(self): + """Return the zoom level.""" + pass + + def GotoLine(self, line): + """Set caret to start of a line and ensure it is visible.""" + pass + + def GotoPos(self, pos): + """Set caret to a position and ensure it is visible.""" + pass + + def HideLines(self, lineStart, lineEnd): + """Make a range of lines invisible.""" + pass + + def HideSelection(self, normal): + """Draw the selection in normal style or with selection + highlighted.""" + pass + + def HomeDisplay(self): + """Move caret to first position on display line.""" + pass + + def HomeDisplayExtend(self): + """Move caret to first position on display line extending + selection to new caret position.""" + pass + + def IndicatorGetForeground(self, indic): + """Return the foreground colour of an indicator.""" + pass + + def IndicatorGetStyle(self, indic): + """Return the style of an indicator.""" + pass + + def IndicatorSetForeground(self, indic, fore): + """Set the foreground colour of an indicator.""" + pass + + def IndicatorSetStyle(self, indic, style): + """Set an indicator to plain, squiggle or TT.""" + pass + + def InsertText(self, pos, text): + """Insert string at a position.""" + pass + + def LineEndDisplay(self): + """Move caret to last position on display line.""" + pass + + def LineEndDisplayExtend(self): + """Move caret to last position on display line extending + selection to new caret position.""" + pass + + def LineFromPosition(self, pos): + """Return the line containing a position.""" + pass + + def LineLength(self, line): + """How many characters are on a line, not including end of + line characters?""" + pass + + def LineScroll(self, columns, lines): + """Scroll horizontally and vertically.""" + pass + + def LinesOnScreen(self): + """Retrieves the number of lines completely visible.""" + pass + + def MarkerAdd(self, line, markerNumber): + """Add a marker to a line, return an ID that can be used to + find or delete the marker.""" + pass + + def MarkerDefine(self, markerNumber, markerSymbol, + foreground=wx.NullColour, background=wx.NullColour): + """Set the symbol used for a particular marker number, and + optionally the fore and background colours.""" + pass + + def MarkerDelete(self, line, markerNumber): + """Delete a marker from a line.""" + pass + + def MarkerDeleteAll(self, markerNumber): + """Delete all markers with a particular number from all lines.""" + pass + + def MarkerDeleteHandle(self, handle): + """Delete a marker.""" + pass + + def MarkerGet(self, line): + """Return a bit mask of all the markers set on a line.""" + pass + + def MarkerLineFromHandle(self, handle): + """Return the line number at which a particular marker is + located.""" + pass + + def MarkerNext(self, lineStart, markerMask): + """Find the next line after lineStart that includes a marker + in mask.""" + pass + + def MarkerPrevious(self, lineStart, markerMask): + """Find the previous line before lineStart that includes a + marker in mask.""" + pass + + def MarkerSetBackground(self, markerNumber, back): + """Set the background colour used for a particular marker + number.""" + pass + + def MarkerSetForeground(self, markerNumber, fore): + """Set the foreground colour used for a particular marker + number.""" + pass + + def MoveCaretInsideView(self): + """Move the caret inside current view if it is not there + already.""" + pass + + def Paste(self): + """Paste the contents of the clipboard into the document + replacing the selection.""" + pass + + def PointFromPosition(self, pos): + """Return the point in the window where a position is + displayed.""" + pass + + def PositionFromLine(self, line): + """Return the position at the start of a line.""" + pass + + def PositionFromPoint(self, pt): + """Find the position from a point within the window.""" + pass + + def PositionFromPointClose(self, x, y): + """Find the position from a point within the window but return + INVALID_POSITION if not close to text.""" + pass + + def Redo(self): + """Redo the next action on the undo history.""" + pass + + def ReleaseDocument(self, docPointer): + """Release a reference to the document, deleting document if + it fades to black.""" + pass + + def ReplaceSelection(self, text): + """Replace the selected text with the argument text.""" + pass + + def ReplaceTarget(self, text): + """Replace the target text with the argument text. + + Text is counted so it can contain nulls. Return the length + of the replacement text.""" + pass + + def ReplaceTargetRE(self, text): + """Replace the target text with the argument text after \d + processing. + + Text is counted so it can contain nulls. Looks for \d where d + is between 1 and 9 and replaces these with the strings matched + in the last search operation which were surrounded by \(self, + and \). Return the length of the replacement text including + any change caused by processing the \d patterns.""" + pass + + def ScrollToColumn(self, column): + """Scroll enough to make the given column visible.""" + pass + + def ScrollToLine(self, line): + """Scroll enough to make the given line visible.""" + pass + + def SearchAnchor(self): + """Sets the current caret position to be the search anchor.""" + pass + + def SearchInTarget(self, text): + """Search for a counted string in the target and set the + target to the found range. + + Text is counted so it can contain nulls. Return length of + range or -1 for failure in which case target is not moved.""" + pass + + def SearchNext(self, flags, text): + """Find some text starting at the search anchor. Does not + ensure the selection is visible.""" + pass + + def SearchPrev(self, flags, text): + """Find some text starting at the search anchor and moving + backwards. Does not ensure the selection is visible.""" + pass + + def SelectAll(self): + """Select all the text in the document.""" + pass + + def SelectionIsRectangle(self): + """Is the selection rectangular? The alternative is the more + common stream selection.""" + pass + + def SendMsg(self, msg, wp=0, lp=0): + """Send a message to Scintilla.""" + pass + + def SetAnchor(self, posAnchor): + """Set the selection anchor to a position. The anchor is the + opposite end of the selection from the caret.""" + pass + + def SetBackSpaceUnIndents(self, bsUnIndents): + """Sets whether a backspace pressed when caret is within + indentation unindents.""" + pass + + def SetBufferedDraw(self, buffered): + """If drawing is buffered then each line of text is drawn into + a bitmap buffer before drawing it to the screen to avoid + flicker.""" + pass + + def SetCaretForeground(self, fore): + """Set the foreground colour of the caret.""" + pass + + def SetCaretLineBack(self, back): + """Set the colour of the background of the line containing the + caret.""" + pass + + def SetCaretLineVisible(self, show): + """Display the background of the line containing the caret in + a different colour.""" + pass + + def SetCaretPeriod(self, periodMilliseconds): + """Return the time in milliseconds that the caret is on and + off. 0 = steady on.""" + pass + + def SetCaretWidth(self, pixelWidth): + """Set the width of the insert mode caret.""" + pass + + def SetCodePage(self, codePage): + """Set the code page used to interpret the bytes of the + document as characters.""" + pass + + def SetControlCharSymbol(self, symbol): + """Change the way control characters are displayed: If symbol + is < 32, keep the drawn way, else, use the given character.""" + pass + + def SetCurrentPos(self, pos): + """Sets the position of the caret.""" + pass + + def SetCursor(self, cursorType): + """Sets the cursor to one of the SC_CURSOR* values.""" + pass + + def SetDocPointer(self, docPointer): + """Change the document object used.""" + pass + + def SetEOLMode(self, eolMode): + """Set the current end of line mode.""" + pass + + def SetEdgeColour(self, edgeColour): + """Change the colour used in edge indication.""" + pass + + def SetEdgeColumn(self, column): + """Set the column number of the edge. If text goes past the + edge then it is highlighted.""" + pass + + def SetEdgeMode(self, mode): + """The edge may be displayed by a line (self, EDGE_LINE) or by + highlighting text that goes beyond it (self, EDGE_BACKGROUND) + or not displayed at all (self, EDGE_NONE).""" + pass + + def SetEndAtLastLine(self, endAtLastLine): + """Sets the scroll range so that maximum scroll position has + the last line at the bottom of the view (self, default). + Setting this to false allows scrolling one page below the last + line.""" + pass + + def SetFoldExpanded(self, line, expanded): + """Show the children of a header line.""" + pass + + def SetFoldFlags(self, flags): + """Set some debugging options for folding.""" + pass + + def SetFoldLevel(self, line, level): + """Set the fold level of a line. This encodes an integer + level along with flags indicating whether the line is a header + and whether it is effectively white space.""" + pass + + def SetHScrollBar(self, bar): + """Set the horizontal scrollbar to use instead of the one + that's built-in.""" + pass + + def SetHighlightGuide(self, column): + """Set the highlighted indentation guide column. 0 = no + highlighted guide.""" + pass + + def SetIndent(self, indentSize): + """Set the number of spaces used for one level of indentation.""" + pass + + def SetIndentationGuides(self, show): + """Show or hide indentation guides.""" + pass + + def SetKeyWords(self, keywordSet, keyWords): + """Set up the key words used by the lexer.""" + pass + + def SetLastKeydownProcessed(self, val): + """Set ???.""" + pass + + def SetLayoutCache(self, mode): + """Sets the degree of caching of layout information.""" + pass + + def SetLexer(self, lexer): + """Set the lexing language of the document.""" + pass + + def SetLexerLanguage(self, language): + """Set the lexing language of the document based on string + name.""" + pass + + def SetLineIndentation(self, line, indentSize): + """Change the indentation of a line to a number of columns.""" + pass + + def SetLineState(self, line, state): + """Used to hold extra styling information for each line.""" + pass + + def SetMarginLeft(self, pixelWidth): + """Sets the size in pixels of the left margin.""" + pass + + def SetMarginMask(self, margin, mask): + """Set a mask that determines which markers are displayed in a + margin.""" + pass + + def SetMarginRight(self, pixelWidth): + """Sets the size in pixels of the right margin.""" + pass + + def SetMarginSensitive(self, margin, sensitive): + """Make a margin sensitive or insensitive to mouse clicks.""" + pass + + def SetMarginType(self, margin, marginType): + """Set a margin to be either numeric or symbolic.""" + pass + + def SetMarginWidth(self, margin, pixelWidth): + """Set the width of a margin to a width expressed in pixels.""" + pass + + def SetMargins(self, left, right): + """Set the left and right margin in the edit area, measured in + pixels.""" + pass + + def SetModEventMask(self, mask): + """Set which document modification events are sent to the + container.""" + pass + + def SetMouseDownCaptures(self, captures): + """Set whether the mouse is captured when its button is + pressed.""" + pass + + def SetMouseDwellTime(self, periodMilliseconds): + """Sets the time the mouse must sit still to generate a mouse + dwell event.""" + pass + + def SetOvertype(self, overtype): + """Set to overtype (self, true) or insert mode.""" + pass + + def SetPrintColourMode(self, mode): + """Modify colours when printing for clearer printed text.""" + pass + + def SetPrintMagnification(self, magnification): + """Sets the print magnification added to the point size of + each style for printing.""" + pass + + def SetProperty(self, key, value): + """Set up a value that may be used by a lexer for some + optional feature.""" + pass + + def SetReadOnly(self, readOnly): + """Set to read only or read write.""" + pass + + def SetSTCFocus(self, focus): + """Change internal focus flag.""" + pass + + def SetSavePoint(self): + """Remember the current position in the undo history as the + position at which the document was saved.""" + pass + + def SetScrollWidth(self, pixelWidth): + """Sets the document width assumed for scrolling.""" + pass + + def SetSearchFlags(self, flags): + """Set the search flags used by SearchInTarget.""" + pass + + def SetSelBackground(self, useSetting, back): + """Set the background colour of the selection and whether to + use this setting.""" + pass + + def SetSelForeground(self, useSetting, fore): + """Set the foreground colour of the selection and whether to + use this setting.""" + pass + + def SetSelection(self, start, end): + """Select a range of text.""" + pass + + def SetSelectionEnd(self, pos): + """Sets the position that ends the selection - this becomes + the currentPosition.""" + pass + + def SetSelectionStart(self, pos): + """Sets the position that starts the selection - this becomes + the anchor.""" + pass + + def SetStatus(self, statusCode): + """Change error status - 0 = OK.""" + pass + + def SetStyleBits(self, bits): + """Divide each styling byte into lexical class bits (self, + default: 5) and indicator bits (self, default: 3). If a lexer + requires more than 32 lexical states, then this is used to + expand the possible states.""" + pass + + def SetStyleBytes(self, length, styleBytes): + """Set the styles for a segment of the document.""" + pass + + def SetStyling(self, length, style): + """Change style from current styling position for length + characters to a style and move the current styling position to + after this newly styled segment.""" + pass + + def SetTabIndents(self, tabIndents): + """Sets whether a tab pressed when caret is within indentation + indents.""" + pass + + def SetTabWidth(self, tabWidth): + """Change the visible size of a tab to be a multiple of the + width of a space character.""" + pass + + def SetTargetEnd(self, pos): + """Sets the position that ends the target which is used for + updating the document without affecting the scroll position.""" + pass + + def SetTargetStart(self, pos): + """Sets the position that starts the target which is used for + updating the document without affecting the scroll position.""" + pass + + def SetText(self, text): + """Replace the contents of the document with the argument + text.""" + pass + + def SetUndoCollection(self, collectUndo): + """Choose between collecting actions into the undo history and + discarding them.""" + pass + + def SetUseHorizontalScrollBar(self, show): + """Show or hide the horizontal scroll bar.""" + pass + + def SetUseTabs(self, useTabs): + """Indentation will only use space characters if useTabs is + false, otherwise it will use a combination of tabs and spaces.""" + pass + + def SetVScrollBar(self, bar): + """Set the vertical scrollbar to use instead of the one that's + built-in.""" + pass + + def SetViewEOL(self, visible): + """Make the end of line characters visible or invisible.""" + pass + + def SetViewWhiteSpace(self, viewWS): + """Make white space characters invisible, always visible or + visible outside indentation.""" + pass + + def SetVisiblePolicy(self, visiblePolicy, visibleSlop): + """Set the way the display area is determined when a + particular line is to be moved to by Find, FindNext, GotoLine, + etc.""" + pass + + def SetWhitespaceBackground(self, useSetting, back): + """Set the background colour of all whitespace and whether to + use this setting.""" + pass + + def SetWhitespaceForeground(self, useSetting, fore): + """Set the foreground colour of all whitespace and whether to + use this setting.""" + pass + + def SetWordChars(self, characters): + """Set the set of characters making up words for when moving + or selecting by word.""" + pass + + def SetWrapMode(self, mode): + """Sets whether text is word wrapped.""" + pass + + def SetXCaretPolicy(self, caretPolicy, caretSlop): + """Set the way the caret is kept visible when going sideway. + The exclusion zone is given in pixels.""" + pass + + def SetXOffset(self, newOffset): + """Set the xOffset (self, ie, horizonal scroll position).""" + pass + + def SetYCaretPolicy(self, caretPolicy, caretSlop): + """Set the way the line the caret is on is kept visible. The + exclusion zone is given in lines.""" + pass + + def SetZoom(self, zoom): + """Set the zoom level. This number of points is added to the + size of all fonts. It may be positive to magnify or negative + to reduce.""" + pass + + def ShowLines(self, lineStart, lineEnd): + """Make a range of lines visible.""" + pass + + def StartRecord(self): + """Start notifying the container of all key presses and + commands.""" + pass + + def StartStyling(self, pos, mask): + """Set the current styling position and mask. + + The styling mask can be used to protect some bits in each + styling byte from modification.""" + pass + + def StopRecord(self): + """Stop notifying the container of all key presses and + commands.""" + pass + + def StyleClearAll(self): + """Clear all the styles and make equivalent to the global + default style.""" + pass + + def StyleResetDefault(self): + """Reset the default style to its state at startup.""" + pass + + def StyleSetBackground(self, style, back): + """Set the background colour of a style.""" + pass + + def StyleSetBold(self, style, bold): + """Set a style to be bold or not.""" + pass + + def StyleSetCase(self, style, caseForce): + """Set a style to be mixed case, or to force upper or lower + case.""" + pass + + def StyleSetChangeable(self, style, changeable): + """Set a style to be changeable or not (self, read only). + Experimental feature, currently buggy.""" + pass + + def StyleSetCharacterSet(self, style, characterSet): + """Set the character set of the font in a style.""" + pass + + def StyleSetEOLFilled(self, style, filled): + """Set a style to have its end of line filled or not.""" + pass + + def StyleSetFaceName(self, style, fontName): + """Set the font of a style.""" + pass + + def StyleSetFont(self, styleNum, font): + """Set style size, face, bold, italic, and underline + attributes from a Font's attributes.""" + pass + + def StyleSetFontAttr(self, styleNum, size, faceName, + bold, italic, underline): + """Set all font style attributes at once.""" + pass + + def StyleSetForeground(self, style, fore): + """Set the foreground colour of a style.""" + pass + + def StyleSetItalic(self, style, italic): + """Set a style to be italic or not.""" + pass + + def StyleSetSize(self, style, sizePoints): + """Set the size of characters of a style.""" + pass + + def StyleSetSpec(self, styleNum, spec): + """Extract style settings from a spec-string which is composed + of one or more of the following comma separated elements: + + bold turns on bold + italic turns on italics + fore:#RRGGBB sets the foreground colour + back:#RRGGBB sets the background colour + face:[facename] sets the font face name to use + size:[num] sets the font size in points + eol turns on eol filling + underline turns on underlining + """ + pass + + def StyleSetUnderline(self, style, underline): + """Set a style to be underlined or not.""" + pass + + def StyleSetVisible(self, style, visible): + """Set a style to be visible or not.""" + pass + + def TextHeight(self, line): + """Return the height of a particular line of text in pixels.""" + pass + + def TextWidth(self, style, text): + """Measure the pixel width of some text in a particular style. + Nul terminated text argument. Does not handle tab or control + characters.""" + pass + + def ToggleFold(self, line): + """Switch a header line between expanded and contracted.""" + pass + + def Undo(self): + """Undo one action in the undo history.""" + pass + + def UsePopUp(self, allowPopUp): + """Set whether a pop up menu is displayed automatically when + the user presses the wrong mouse button.""" + pass + + def UserListShow(self, listType, itemList): + """Display a list of strings and send notification when user + chooses one.""" + pass + + def VisibleFromDocLine(self, line): + """Find the display line of a document line taking hidden + lines into account.""" + pass + + def WordEndPosition(self, pos, onlyWordCharacters): + """Return position of end of word.""" + pass + + def WordPartLeft(self): + """Move to the previous change in capitalisation.""" + pass + + def WordPartLeftExtend(self): + """Move to the previous change in capitalisation extending + selection to new caret position.""" + pass + + def WordPartRight(self): + """Move to the change next in capitalisation.""" + pass + + def WordPartRightExtend(self): + """Move to the next change in capitalisation extending + selection to new caret position.""" + pass + + def WordStartPosition(self, pos, onlyWordCharacters): + """Return position of start of word.""" + pass diff --git a/wxPython/wxPython/lib/PyCrust/wxd/wx_.py b/wxPython/wxPython/lib/PyCrust/wxd/wx_.py new file mode 100644 index 0000000000..492d623714 --- /dev/null +++ b/wxPython/wxPython/lib/PyCrust/wxd/wx_.py @@ -0,0 +1,62 @@ +"""Decorator classes for documentation and shell scripting. +""" + +__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" +__cvsid__ = "$Id$" +__revision__ = "$Revision$"[11:-2] + + +# These are not the real wxPython classes. These are Python versions +# for documentation purposes. They are also used to apply docstrings +# to the real wxPython classes, which are SWIG-generated wrappers for +# C-language classes. + + +_topics = { + 'Accelerators': None, + 'App': None, + 'Base': None, + 'ClipDragDrop': None, + 'Config': None, + 'Controls': None, + 'DataStructures': None, + 'DateTime': None, + 'Dialogs': None, + 'Drawing': None, + 'Errors': None, + 'EventFunctions': None, + 'Events': None, + 'FileSystem': None, + 'Frames': None, + 'Functions': None, + 'Help': None, + 'ImageHandlers': None, + 'Joystick': None, + 'LayoutConstraints': None, + 'Logging': None, + 'Menus': None, + 'MimeTypes': None, + 'Misc': None, + 'Panel': None, + 'Printing': None, + 'Process': None, + 'SashSplitter': None, + 'Sizers': None, + 'Streams': None, + 'Threading': None, + 'ToolBar': None, + 'Tree': None, + 'Validators': None, + 'Window': None, + } + +for topic in _topics.keys(): + _topics[topic] = __import__(topic, globals()) + exec 'from %s import *' % topic + +del topic # Cleanup the namespace. + +try: + del wx # Cleanup any module that imports Parameters as wx. +except: + pass diff --git a/wxPython/wxPython/lib/PythonBitmaps.py b/wxPython/wxPython/lib/PythonBitmaps.py index 79dfb0dcdd..bd06899ba5 100644 --- a/wxPython/wxPython/lib/PythonBitmaps.py +++ b/wxPython/wxPython/lib/PythonBitmaps.py @@ -21,7 +21,7 @@ getwxPythonImage PythonBitmaps - --This takes a single argument. If it tests true, + --This takes a single argument. If it tests True, getPythonPoweredBitmap() is returned, else getwxPythonBitmap() is returned. diff --git a/wxPython/wxPython/lib/buttons.py b/wxPython/wxPython/lib/buttons.py index e8e2a66f64..128ef0a2cc 100644 --- a/wxPython/wxPython/lib/buttons.py +++ b/wxPython/wxPython/lib/buttons.py @@ -28,13 +28,15 @@ wxGenBitmapToggleButton the same but with bitmaps. """ from wxPython.wx import * +import imageutils + #---------------------------------------------------------------------- class wxGenButtonEvent(wxPyCommandEvent): def __init__(self, eventType, ID): wxPyCommandEvent.__init__(self, eventType, ID) - self.isDown = false + self.isDown = False self.theButton = None def SetIsDown(self, isDown): @@ -63,10 +65,10 @@ class wxGenButton(wxPyControl): style = wxNO_BORDER wxPyControl.__init__(self, parent, ID, pos, size, style, validator, name) - self.up = true + self.up = True self.bezelWidth = 2 - self.hasFocus = false - self.useFocusInd = true + self.hasFocus = False + self.useFocusInd = True self.SetLabel(label) self.SetPosition(pos) @@ -131,6 +133,11 @@ class wxGenButton(wxPyControl): return self.IsShown() and self.IsEnabled() + def Enable(self, enable=True): + wxPyControl.Enable(self, enable) + self.Refresh() + + def SetBezelWidth(self, width): """Set the width of the 3D effect""" self.bezelWidth = width @@ -187,7 +194,7 @@ class wxGenButton(wxPyControl): def _GetLabelSize(self): """ used internally """ w, h = self.GetTextExtent(self.GetLabel()) - return w, h, true + return w, h, True def Notify(self): @@ -270,7 +277,7 @@ class wxGenButton(wxPyControl): def OnLeftDown(self, event): if not self.IsEnabled(): return - self.up = false + self.up = False self.CaptureMouse() self.SetFocus() self.Refresh() @@ -278,35 +285,36 @@ class wxGenButton(wxPyControl): def OnLeftUp(self, event): - if not self.IsEnabled(): + if not self.IsEnabled() or not self.HasCapture(): return - self.ReleaseMouse() - if not self.up: # if the button was down when the mouse was released... - self.Notify() - self.up = true - self.Refresh() - event.Skip() + if self.HasCapture(): + self.ReleaseMouse() + if not self.up: # if the button was down when the mouse was released... + self.Notify() + self.up = True + self.Refresh() + event.Skip() def OnMotion(self, event): - if not self.IsEnabled(): + if not self.IsEnabled() or not self.HasCapture(): return - if event.LeftIsDown(): + if event.LeftIsDown() and self.HasCapture(): x,y = event.GetPositionTuple() w,h = self.GetClientSizeTuple() if self.up and x<w and x>=0 and y<h and y>=0: - self.up = false + self.up = False self.Refresh() return if not self.up and (x<0 or y<0 or x>=w or y>=h): - self.up = true + self.up = True self.Refresh() return event.Skip() def OnGainFocus(self, event): - self.hasFocus = true + self.hasFocus = True dc = wxClientDC(self) w, h = self.GetClientSizeTuple() if self.useFocusInd: @@ -314,7 +322,7 @@ class wxGenButton(wxPyControl): def OnLoseFocus(self, event): - self.hasFocus = false + self.hasFocus = False dc = wxClientDC(self) w, h = self.GetClientSizeTuple() if self.useFocusInd: @@ -323,14 +331,14 @@ class wxGenButton(wxPyControl): def OnKeyDown(self, event): if self.hasFocus and event.KeyCode() == ord(" "): - self.up = false + self.up = False self.Refresh() event.Skip() def OnKeyUp(self, event): if self.hasFocus and event.KeyCode() == ord(" "): - self.up = true + self.up = True self.Notify() self.Refresh() event.Skip() @@ -343,10 +351,10 @@ class wxGenBitmapButton(wxGenButton): pos = wxDefaultPosition, size = wxDefaultSize, style = 0, validator = wxDefaultValidator, name = "genbutton"): - self.bmpLabel = bitmap self.bmpDisabled = None self.bmpFocus = None self.bmpSelected = None + self.SetBitmapLabel(bitmap) wxGenButton.__init__(self, parent, ID, "", pos, size, style, validator, name) @@ -367,22 +375,32 @@ class wxGenBitmapButton(wxGenButton): def SetBitmapFocus(self, bitmap): """Set bitmap to display when the button has the focus""" self.bmpFocus = bitmap - self.SetUseFocusIndicator(false) + self.SetUseFocusIndicator(False) def SetBitmapSelected(self, bitmap): """Set bitmap to display when the button is selected (pressed down)""" self.bmpSelected = bitmap - def SetBitmapLabel(self, bitmap): - """Set the bitmap to display normally. This is the only one that is required.""" + def SetBitmapLabel(self, bitmap, createOthers=True): + """ + Set the bitmap to display normally. + This is the only one that is required. If + createOthers is True, then the other bitmaps + will be generated on the fly. Currently, + only the disabled bitmap is generated. + """ self.bmpLabel = bitmap + if bitmap is not None and createOthers: + image = wxImageFromBitmap(bitmap) + imageutils.grayOut(image) + self.SetBitmapDisabled(wxBitmapFromImage(image)) def _GetLabelSize(self): """ used internally """ if not self.bmpLabel: - return -1, -1, false - return self.bmpLabel.GetWidth()+2, self.bmpLabel.GetHeight()+2, false + return -1, -1, False + return self.bmpLabel.GetWidth()+2, self.bmpLabel.GetHeight()+2, False def DrawLabel(self, dc, width, height, dw=0, dy=0): bmp = self.bmpLabel @@ -415,7 +433,7 @@ class wxGenBitmapTextButton(wxGenBitmapButton): # generic bitmapped button w """ used internally """ w, h = self.GetTextExtent(self.GetLabel()) if not self.bmpLabel: - return w, h, true # if there isn't a bitmap use the size of the text + return w, h, True # if there isn't a bitmap use the size of the text w_bmp = self.bmpLabel.GetWidth()+2 h_bmp = self.bmpLabel.GetHeight()+2 @@ -424,7 +442,7 @@ class wxGenBitmapTextButton(wxGenBitmapButton): # generic bitmapped button w height = h_bmp else: height = h - return width, height, true + return width, height, True def DrawLabel(self, dc, width, height, dw=0, dy=0): @@ -456,10 +474,10 @@ class wxGenBitmapTextButton(wxGenBitmapButton): # generic bitmapped button w pos_x = (width-bw-tw)/2+dw # adjust for bitmap and text to centre if bmp !=None: - dc.DrawBitmap(bmp, pos_x, (height-bh)/2+dy, hasMask) # draw bitmap if available + dc.DrawBitmap(bmp, pos_x, (height-bh)/2+dy, hasMask) # draw bitmap if available pos_x = pos_x + 2 # extra spacing from bitmap - dc.DrawText(label, pos_x + dw+bw, (height-th)/2+dy) # draw the text + dc.DrawText(label, pos_x + dw+bw, (height-th)/2+dy) # draw the text #---------------------------------------------------------------------- @@ -468,9 +486,12 @@ class wxGenBitmapTextButton(wxGenBitmapButton): # generic bitmapped button w class __ToggleMixin: def SetToggle(self, flag): self.up = not flag + self.Refresh() + SetValue = SetToggle def GetToggle(self): return not self.up + GetValue = GetToggle def OnLeftDown(self, event): if not self.IsEnabled(): @@ -482,16 +503,33 @@ class __ToggleMixin: self.Refresh() def OnLeftUp(self, event): - if not self.IsEnabled(): + if not self.IsEnabled() or not self.HasCapture(): return - if self.up != self.saveUp: - self.Notify() - self.ReleaseMouse() - self.Refresh() + if self.HasCapture(): + if self.up != self.saveUp: + self.Notify() + self.ReleaseMouse() + self.Refresh() def OnKeyDown(self, event): event.Skip() + def OnMotion(self, event): + if not self.IsEnabled(): + return + if event.LeftIsDown() and self.HasCapture(): + x,y = event.GetPositionTuple() + w,h = self.GetClientSizeTuple() + if x<w and x>=0 and y<h and y>=0: + self.up = not self.saveUp + self.Refresh() + return + if (x<0 or y<0 or x>=w or y>=h): + self.up = self.saveUp + self.Refresh() + return + event.Skip() + def OnKeyUp(self, event): if self.hasFocus and event.KeyCode() == ord(" "): self.up = not self.up diff --git a/wxPython/wxPython/lib/calendar.py b/wxPython/wxPython/lib/calendar.py index df66d76a9e..29ba2c753c 100644 --- a/wxPython/wxPython/lib/calendar.py +++ b/wxPython/wxPython/lib/calendar.py @@ -13,7 +13,6 @@ from wxPython.wx import * from CDate import * -import string, time CalDays = [6, 0, 1, 2, 3, 4, 5] @@ -44,7 +43,7 @@ class CalDraw: self.DefParms() def DefParms(self): - self.num_auto = TRUE # auto scale of the cal number day size + self.num_auto = True # auto scale of the cal number day size self.num_size = 12 # default size of calendar if no auto size self.max_num_size = 12 # maximum size for calendar number @@ -53,7 +52,7 @@ class CalDraw: self.num_indent_horz = 0 # points indent from position, used to offset if not centered self.num_indent_vert = 0 - self.week_auto = TRUE # auto scale of week font text + self.week_auto = True # auto scale of week font text self.week_size = 10 self.max_week_size = 12 @@ -71,13 +70,13 @@ class CalDraw: self.font = wxSWISS self.bold = wxNORMAL - self.hide_title = FALSE - self.hide_grid = FALSE - self.outer_border = TRUE + self.hide_title = False + self.hide_grid = False + self.outer_border = True self.title_offset = 0 self.cal_week_scale = 0.7 - self.show_weekend = FALSE + self.show_weekend = False self.cal_type = "NORMAL" def SetWeekColor(self, font_color, week_color): # set font and background color for week title @@ -123,7 +122,7 @@ class CalDraw: self.InitScale() self.DrawBorder() - if self.hide_title is FALSE: + if self.hide_title is False: self.DrawMonth() self.Center() @@ -131,7 +130,7 @@ class CalDraw: self.DrawGrid() self.GetRect() - if self.show_weekend is TRUE: # highlight weekend dates + if self.show_weekend is True: # highlight weekend dates self.SetWeekEnd() self.AddSelect(sel_lst) # overrides the weekend highlight @@ -154,7 +153,7 @@ class CalDraw: self.DC.SetBrush(brush) self.DC.SetPen(wxPen(wxNamedColour(self.border_color), 1)) - if self.outer_border is TRUE: + if self.outer_border is True: rect = wxRect(self.cx_st, self.cy_st, self.sizew, self.sizeh) # full display window area self.DC.DrawRectangle(rect.x, rect.y, rect.width, rect.height) @@ -245,7 +244,7 @@ class CalDraw: rect_w = self.gridx[7]-self.gridx[0] f = wxFont(10, self.font, wxNORMAL, self.bold) # initial font setting - if self.week_auto == TRUE: + if self.week_auto == True: test_size = self.max_week_size # max size test_day = ' Sun ' while test_size > 2: @@ -289,7 +288,7 @@ class CalDraw: def DrawNum(self): # draw the day numbers f = wxFont(10, self.font, wxNORMAL, self.bold) # initial font setting - if self.num_auto == TRUE: + if self.num_auto == True: test_size = self.max_num_size # max size test_day = ' 99 ' while test_size > 2: @@ -362,7 +361,7 @@ class CalDraw: brush = wxBrush(wxNamedColour(sel_color), wxSOLID) self.DC.SetBrush(brush) - if self.hide_grid is FALSE: + if self.hide_grid is False: self.DC.SetPen(wxPen(wxNamedColour(self.grid_color), 0)) else: self.DC.SetPen(wxPen(wxNamedColour(self.back_color), 0)) @@ -384,7 +383,7 @@ class CalDraw: y2 = y1 + self.cheight for i in range(8): - if self.hide_grid is FALSE: + if self.hide_grid is False: self.DC.DrawLine(x1, y1, x1, y2) self.gridx.append(x1) x1 = x1 + self.dl_w @@ -394,7 +393,7 @@ class CalDraw: x2 = x1 + self.cwidth for i in range(8): - if self.hide_grid is FALSE: + if self.hide_grid is False: self.DC.DrawLine(x1, y1, x2, y1) self.gridy.append(y1) if i == 0: @@ -429,10 +428,10 @@ class wxCalendar(wxWindow): self.grid_color = 'BLACK' self.back_color = 'WHITE' - self.hide_grid = FALSE + self.hide_grid = False self.sel_color = 'RED' - self.hide_title = FALSE - self.show_weekend = FALSE + self.hide_title = False + self.show_weekend = False self.cal_type = "NORMAL" self.week_color = 'LIGHT GREY' @@ -460,10 +459,10 @@ class wxCalendar(wxWindow): # control some of the main calendar attributes def HideTitle(self): - self.hide_title = TRUE + self.hide_title = True def HideGrid(self): - self.hide_grid = TRUE + self.hide_grid = True # determine the calendar rectangle click area and draw a selection @@ -606,13 +605,13 @@ class wxCalendar(wxWindow): self.select_list.append(list_val) def ShowWeekEnd(self): - self.show_weekend = TRUE # highlight weekend + self.show_weekend = True # highlight weekend def SetBusType(self): self.cal_type = "BUS" def OnSize(self, evt): - self.Refresh(false) + self.Refresh(False) evt.Skip() def OnPaint(self, event): @@ -685,7 +684,7 @@ class wxCalendar(wxWindow): def SelectDay(self, key): sel_size = 1 self.DrawRect(self.sel_key, self.back_color, sel_size) # clear large selection - if self.hide_grid is FALSE: + if self.hide_grid is False: self.DrawRect(self.sel_key, self.grid_color) self.DrawRect(key, self.sel_color, sel_size) diff --git a/wxPython/wxPython/lib/colourchooser/__init__.py b/wxPython/wxPython/lib/colourchooser/__init__.py new file mode 100644 index 0000000000..dcb9ec8897 --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/__init__.py @@ -0,0 +1,26 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix <mgilfix@eecs.tufts.edu> + +This file is part of wxPyColourChooser. + +This version of wxPyColourChooser is open source; you can redistribute it +and/or modify it under the licensed terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +from pycolourchooser import * + +# For the American in you +wxPyColorChooser = wxPyColourChooser + +__all__ = [ + 'canvas', + 'pycolourbox', + 'pycolourchooser', + 'pycolourslider', + 'pypalette', +] diff --git a/wxPython/wxPython/lib/colourchooser/canvas.py b/wxPython/wxPython/lib/colourchooser/canvas.py new file mode 100644 index 0000000000..730a6fb629 --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/canvas.py @@ -0,0 +1,120 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix <mgilfix@eecs.tufts.edu> + +This file is part of wxPyColourChooser. + +This version of wxPyColourChooser is open source; you can redistribute it +and/or modify it under the licensed terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +from wxPython.wx import * + +class BitmapBuffer(wxMemoryDC): + """A screen buffer class. + + This class implements a screen output buffer. Data is meant to + be drawn in the buffer class and then blitted directly to the + output device, or on-screen window. + """ + def __init__(self, width, height, colour): + """Initialize the empty buffer object.""" + wxMemoryDC.__init__(self) + + self.width = width + self.height = height + self.colour = colour + + self.bitmap = wxEmptyBitmap(self.width, self.height) + self.SelectObject(self.bitmap) + + # Initialize the buffer to the background colour + self.SetBackground(wxBrush(self.colour, wxSOLID)) + self.Clear() + + # Make each logical unit of the buffer equal to 1 pixel + self.SetMapMode(wxMM_TEXT) + + def GetBitmap(self): + """Returns the internal bitmap for direct drawing.""" + return self.bitmap + +class Canvas(wxWindow): + """A canvas class for arbitrary drawing. + + The Canvas class implements a window that allows for drawing + arbitrary graphics. It implements a double buffer scheme and + blits the off-screen buffer to the window during paint calls + by the windowing system for speed. + + Some other methods for determining the canvas colour and size + are also provided. + """ + def __init__(self, parent, id, + pos=wxDefaultPosition, + size=wxDefaultSize, + style=wxSIMPLE_BORDER): + """Creates a canvas instance and initializes the off-screen + buffer. Also sets the handler for rendering the canvas + automatically via size and paint calls from the windowing + system.""" + wxWindow.__init__(self, parent, id, pos, size, style) + + # Perform an intial sizing + self.ReDraw() + + # Register event handlers + EVT_SIZE(self, self.onSize) + EVT_PAINT(self, self.onPaint) + + def MakeNewBuffer(self): + size = self.GetSizeTuple() + self.buffer = BitmapBuffer(size[0], size[1], + self.GetBackgroundColour()) + + def onSize(self, event): + """Perform actual redraw to off-screen buffer only when the + size of the canvas has changed. This saves a lot of computation + since the same image can be re-used, provided the canvas size + hasn't changed.""" + self.MakeNewBuffer() + self.DrawBuffer() + self.Refresh() + + def ReDraw(self): + """Explicitly tells the canvas to redraw it's contents.""" + self.onSize(None) + + def Refresh(self): + """Re-draws the buffer contents on-screen.""" + dc = wxClientDC(self) + self.Blit(dc) + + def onPaint(self, event): + """Renders the off-screen buffer on-screen.""" + dc = wxPaintDC(self) + self.Blit(dc) + + def Blit(self, dc): + """Performs the blit of the buffer contents on-screen.""" + width, height = self.buffer.GetSize() + dc.BeginDrawing() + dc.Blit(0, 0, width, height, self.buffer, 0, 0) + dc.EndDrawing() + + def GetBoundingRect(self): + """Returns a tuple that contains the co-ordinates of the + top-left and bottom-right corners of the canvas.""" + x, y = self.GetPositionTuple() + w, h = self.GetSize() + return(x, y + h, x + w, y) + + def DrawBuffer(self): + """Actual drawing function for drawing into the off-screen + buffer. To be overrideen in the implementing class. Do nothing + by default.""" + pass diff --git a/wxPython/wxPython/lib/colourchooser/intl.py b/wxPython/wxPython/lib/colourchooser/intl.py new file mode 100644 index 0000000000..cfc84f1359 --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/intl.py @@ -0,0 +1,24 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix <mgilfix@eecs.tufts.edu> + +This file is part of wxPyColourChooser. + +This version of wxPyColourChooser is open source; you can redistribute it +and/or modify it under the licensed terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +try: + import gettext + + gettext.bindtextdomain('wxpycolourchooser') + gettext.textdomain('wxpycolourchooser') + _ = gettext.gettext +except Exception, strerror: + print "Warning: Couldn't import translation function: %(str)s" %{ 'str' : strerror } + print "Defaulting to En" + _ = lambda x: x diff --git a/wxPython/wxPython/lib/colourchooser/pycolourbox.py b/wxPython/wxPython/lib/colourchooser/pycolourbox.py new file mode 100644 index 0000000000..e48bdc373a --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/pycolourbox.py @@ -0,0 +1,79 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix <mgilfix@eecs.tufts.edu> + +This file is part of wxPyColourChooser. + +This version of wxPyColourChooser is open source; you can redistribute it +and/or modify it under the licensed terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +from wxPython.wx import * + +class PyColourBox(wxPanel): + """A Colour Selection Box + + The Colour selection box implements button like behavior but contains + a solid-filled, coloured sub-box. Placing the colour in a sub-box allows + for filling in the main panel's background for a high-lighting effect. + """ + def __init__(self, parent, id, colour=(0, 0, 0), size=(25, 20)): + """Creates a new colour box instance and initializes the colour + content.""" + wxPanel.__init__(self, parent, id, + size=wxSize(size[0], size[1])) + + self.colour_box = wxPanel(self, -1, style=wxSIMPLE_BORDER) + + sizer = wxGridSizer(1, 1) + sizer.Add(self.colour_box, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL) + sizer.SetItemMinSize(self.colour_box, size[0] - 5, size[1] - 5) + self.SetAutoLayout(True) + self.SetSizer(sizer) + self.Layout() + + self.real_bg = self.GetBackgroundColour() + self.SetColourTuple(colour) + + def GetColourBox(self): + """Returns a reference to the internal box object containing the + color. This function is useful for setting up event handlers for + the box.""" + return self.colour_box + + def GetColour(self): + """Returns a wxColour object indicating the box's current colour.""" + return self.colour_box.GetBackgroundColour() + + def SetColour(self, colour): + """Accepts a wxColour object and sets the box's current color.""" + self.colour_box.SetBackgroundColour(colour) + self.colour_box.Refresh() + + def SetColourTuple(self, colour): + """Sets the box's current couple to the given tuple.""" + self.colour = colour + self.colour_box.SetBackgroundColour(apply(wxColour, self.colour)) + + def Update(self): + wxPanel.Update(self) + self.colour_box.Update() + + def SetHighlight(self, val): + """Accepts a boolean 'val' toggling the box's highlighting.""" + # XXX This code has been disabled for now until I can figure out + # how to get this to work reliably across all platforms. + if val: + #A wxColourPtr is returned in windows, making this difficult + red =(self.real_bg.Red() - 45) % 255 + green =(self.real_bg.Green() - 45) % 255 + blue =(self.real_bg.Blue() - 45) % 255 + new_colour = wxColour(red, green, blue) + self.SetBackgroundColour(new_colour) + else: + self.SetBackgroundColour(self.real_bg) + self.Refresh() diff --git a/wxPython/wxPython/lib/colourchooser/pycolourchooser.py b/wxPython/wxPython/lib/colourchooser/pycolourchooser.py new file mode 100644 index 0000000000..28c691060f --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/pycolourchooser.py @@ -0,0 +1,385 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix <mgilfix@eecs.tufts.edu> + +This file is part of wxPyColourChooser. + +This version of wxPyColourChooser is open source; you can redistribute it +and/or modify it under the licensed terms. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +import pycolourbox +import pypalette +import pycolourslider +import colorsys +from intl import _ +from wxPython.wx import * + +class wxPyColourChooser(wxPanel): + """A Pure-Python implementation of the colour chooser dialog. + + The PyColourChooser is a pure python implementation of the colour + chooser dialog. It's useful for embedding the colour choosing functionality + inside other widgets, when the pop-up dialog is undesirable. It can also + be used as a drop-in replacement on the GTK platform, as the native + dialog is kind of ugly. + """ + + colour_names = [ + 'ORANGE', + 'GOLDENROD', + 'WHEAT', + 'SPRING GREEN', + 'SKY BLUE', + 'SLATE BLUE', + 'MEDIUM VIOLET RED', + 'PURPLE', + + 'RED', + 'YELLOW', + 'MEDIUM SPRING GREEN', + 'PALE GREEN', + 'CYAN', + 'LIGHT STEEL BLUE', + 'ORCHID', + 'LIGHT MAGENTA', + + 'BROWN', + 'YELLOW', + 'GREEN', + 'CADET BLUE', + 'MEDIUM BLUE', + 'MAGENTA', + 'MAROON', + 'ORANGE RED', + + 'FIREBRICK', + 'CORAL', + 'FOREST GREEN', + 'AQUAMARINE', + 'BLUE', + 'NAVY', + 'THISTLE', + 'MEDIUM VIOLET RED', + + 'INDIAN RED', + 'GOLD', + 'MEDIUM SEA GREEN', + 'MEDIUM BLUE', + 'MIDNIGHT BLUE', + 'GREY', + 'PURPLE', + 'KHAKI', + + 'BLACK', + 'MEDIUM FOREST GREEN', + 'KHAKI', + 'DARK GREY', + 'SEA GREEN', + 'LIGHT GREY', + 'MEDIUM SLATE BLUE', + 'WHITE', + ] + + # Generate the custom colours. These colours are shared across + # all instances of the colour chooser + NO_CUSTOM_COLOURS = 16 + custom_colours = [ (wxColour(255, 255, 255), + pycolourslider.PyColourSlider.HEIGHT / 2) + ] * NO_CUSTOM_COLOURS + last_custom = 0 + + idADD_CUSTOM = wxNewId() + idSCROLL = wxNewId() + + def __init__(self, parent, id): + """Creates an instance of the colour chooser. Note that it is best to + accept the given size of the colour chooser as it is currently not + resizeable.""" + wxPanel.__init__(self, parent, id) + + self.basic_label = wxStaticText(self, -1, _("Basic Colours:")) + self.custom_label = wxStaticText(self, -1, _("Custom Colours:")) + self.add_button = wxButton(self, self.idADD_CUSTOM, _("Add to Custom Colours")) + + EVT_BUTTON(self, self.idADD_CUSTOM, self.onAddCustom) + + # Since we're going to be constructing widgets that require some serious + # computation, let's process any events (like redraws) right now + wxYield() + + # Create the basic colours palette + self.colour_boxs = [ ] + colour_grid = wxGridSizer(6, 8) + for name in self.colour_names: + new_id = wxNewId() + box = pycolourbox.PyColourBox(self, new_id) + EVT_LEFT_DOWN(box.GetColourBox(), lambda x, b=box: self.onBasicClick(x, b)) + self.colour_boxs.append(box) + colour_grid.Add(box, 0, wxEXPAND) + + # Create the custom colours palette + self.custom_boxs = [ ] + custom_grid = wxGridSizer(2, 8) + for wxcolour, slidepos in self.custom_colours: + new_id = wxNewId() + custom = pycolourbox.PyColourBox(self, new_id) + EVT_LEFT_DOWN(custom.GetColourBox(), lambda x, b=custom: self.onCustomClick(x, b)) + custom.SetColour(wxcolour) + custom_grid.Add(custom, 0, wxEXPAND) + self.custom_boxs.append(custom) + + csizer = wxBoxSizer(wxVERTICAL) + csizer.Add(1, 25) + csizer.Add(self.basic_label, 0, wxEXPAND) + csizer.Add(1, 5) + csizer.Add(colour_grid, 0, wxEXPAND) + csizer.Add(1, 25) + csizer.Add(self.custom_label, 0, wxEXPAND) + csizer.Add(1, 5) + csizer.Add(custom_grid, 0, wxEXPAND) + csizer.Add(1, 5) + csizer.Add(self.add_button, 0, wxEXPAND) + + self.palette = pypalette.PyPalette(self, -1) + self.colour_slider = pycolourslider.PyColourSlider(self, -1) + self.slider = wxSlider(self, self.idSCROLL, 86, 0, self.colour_slider.HEIGHT - 1, + style=wxSL_VERTICAL, size=wxSize(15, self.colour_slider.HEIGHT)) + EVT_COMMAND_SCROLL(self, self.idSCROLL, self.onScroll) + psizer = wxBoxSizer(wxHORIZONTAL) + psizer.Add(self.palette, 0, 0) + psizer.Add(10, 1) + psizer.Add(self.colour_slider, 0, wxALIGN_CENTER_VERTICAL) + psizer.Add(self.slider, 0, wxALIGN_CENTER_VERTICAL) + + # Register mouse events for dragging across the palette + EVT_LEFT_DOWN(self.palette, self.onPaletteDown) + EVT_LEFT_UP(self.palette, self.onPaletteUp) + EVT_MOTION(self.palette, self.onPaletteMotion) + self.mouse_down = False + + self.solid = pycolourbox.PyColourBox(self, -1, size=wxSize(75, 50)) + slabel = wxStaticText(self, -1, _("Solid Colour")) + ssizer = wxBoxSizer(wxVERTICAL) + ssizer.Add(self.solid, 0, 0) + ssizer.Add(1, 2) + ssizer.Add(slabel, 0, wxALIGN_CENTER_HORIZONTAL) + + hlabel = wxStaticText(self, -1, _("H:")) + self.hentry = wxTextCtrl(self, -1) + self.hentry.SetSize((40, -1)) + slabel = wxStaticText(self, -1, _("S:")) + self.sentry = wxTextCtrl(self, -1) + self.sentry.SetSize((40, -1)) + vlabel = wxStaticText(self, -1, _("V:")) + self.ventry = wxTextCtrl(self, -1) + self.ventry.SetSize((40, -1)) + hsvgrid = wxFlexGridSizer(1, 6, 2, 2) + hsvgrid.AddMany ([ + (hlabel, 0, wxALIGN_CENTER_VERTICAL), (self.hentry, 0, 0), + (slabel, 0, wxALIGN_CENTER_VERTICAL), (self.sentry, 0, 0), + (vlabel, 0, wxALIGN_CENTER_VERTICAL), (self.ventry, 0, 0), + ]) + + rlabel = wxStaticText(self, -1, _("R:")) + self.rentry = wxTextCtrl(self, -1) + self.rentry.SetSize((40, -1)) + glabel = wxStaticText(self, -1, _("G:")) + self.gentry = wxTextCtrl(self, -1) + self.gentry.SetSize((40, -1)) + blabel = wxStaticText(self, -1, _("B:")) + self.bentry = wxTextCtrl(self, -1) + self.bentry.SetSize((40, -1)) + lgrid = wxFlexGridSizer(1, 6, 2, 2) + lgrid.AddMany([ + (rlabel, 0, wxALIGN_CENTER_VERTICAL), (self.rentry, 0, 0), + (glabel, 0, wxALIGN_CENTER_VERTICAL), (self.gentry, 0, 0), + (blabel, 0, wxALIGN_CENTER_VERTICAL), (self.bentry, 0, 0), + ]) + + gsizer = wxGridSizer(2, 1) + gsizer.SetVGap (10) + gsizer.SetHGap (2) + gsizer.Add(hsvgrid, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL) + gsizer.Add(lgrid, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL) + + hsizer = wxBoxSizer(wxHORIZONTAL) + hsizer.Add(ssizer, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL) + hsizer.Add(gsizer, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL) + + vsizer = wxBoxSizer(wxVERTICAL) + vsizer.Add(1, 5) + vsizer.Add(psizer, 0, 0) + vsizer.Add(1, 15) + vsizer.Add(hsizer, 0, wxEXPAND) + + sizer = wxBoxSizer(wxHORIZONTAL) + sizer.Add(5, 1) + sizer.Add(csizer, 0, wxEXPAND) + sizer.Add(10, 1) + sizer.Add(vsizer, 0, wxEXPAND) + self.SetAutoLayout(True) + self.SetSizer(sizer) + sizer.Fit(self) + + self.InitColours() + self.UpdateColour(self.solid.GetColour()) + + def InitColours(self): + """Initializes the pre-set palette colours.""" + for i in range(len(self.colour_names)): + colour = wxTheColourDatabase.FindColour(self.colour_names[i]) + self.colour_boxs[i].SetColourTuple((colour.Red(), + colour.Green(), + colour.Blue())) + + def onBasicClick(self, event, box): + """Highlights the selected colour box and updates the solid colour + display and colour slider to reflect the choice.""" + if hasattr(self, '_old_custom_highlight'): + self._old_custom_highlight.SetHighlight(False) + if hasattr(self, '_old_colour_highlight'): + self._old_colour_highlight.SetHighlight(False) + box.SetHighlight(True) + self._old_colour_highlight = box + self.UpdateColour(box.GetColour()) + + def onCustomClick(self, event, box): + """Highlights the selected custom colour box and updates the solid + colour display and colour slider to reflect the choice.""" + if hasattr(self, '_old_colour_highlight'): + self._old_colour_highlight.SetHighlight(False) + if hasattr(self, '_old_custom_highlight'): + self._old_custom_highlight.SetHighlight(False) + box.SetHighlight(True) + self._old_custom_highlight = box + + # Update the colour panel and then the slider accordingly + box_index = self.custom_boxs.index(box) + base_colour, slidepos = self.custom_colours[box_index] + self.UpdateColour(box.GetColour()) + self.slider.SetValue(slidepos) + + def onAddCustom(self, event): + """Adds a custom colour to the custom colour box set. Boxes are + chosen in a round-robin fashion, eventually overwriting previously + added colours.""" + # Store the colour and slider position so we can restore the + # custom colours just as they were + self.setCustomColour(self.last_custom, + self.solid.GetColour(), + self.colour_slider.GetBaseColour(), + self.slider.GetValue()) + self.last_custom = (self.last_custom + 1) % self.NO_CUSTOM_COLOURS + + def setCustomColour (self, index, true_colour, base_colour, slidepos): + """Sets the custom colour at the given index. true_colour is wxColour + object containing the actual rgb value of the custom colour. + base_colour (wxColour) and slidepos (int) are used to configure the + colour slider and set everything to its original position.""" + self.custom_boxs[index].SetColour(true_colour) + self.custom_colours[index] = (base_colour, slidepos) + + def UpdateColour(self, colour): + """Performs necessary updates for when the colour selection has + changed.""" + # Reset the palette to erase any highlighting + self.palette.ReDraw() + + # Set the color info + self.solid.SetColour(colour) + self.colour_slider.SetBaseColour(colour) + self.colour_slider.ReDraw() + self.slider.SetValue(0) + self.UpdateEntries(colour) + + def UpdateEntries(self, colour): + """Updates the color levels to display the new values.""" + # Temporary bindings + r = colour.Red() + g = colour.Green() + b = colour.Blue() + + # Update the RGB entries + self.rentry.SetValue(str(r)) + self.gentry.SetValue(str(g)) + self.bentry.SetValue(str(b)) + + # Convert to HSV + h,s,v = colorsys.rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0) + self.hentry.SetValue("%.2f" % (h)) + self.sentry.SetValue("%.2f" % (s)) + self.ventry.SetValue("%.2f" % (v)) + + def onPaletteDown(self, event): + """Stores state that the mouse has been pressed and updates + the selected colour values.""" + self.mouse_down = True + self.palette.ReDraw() + self.doPaletteClick(event.m_x, event.m_y) + + def onPaletteUp(self, event): + """Stores state that the mouse is no longer depressed.""" + self.mouse_down = False + + def onPaletteMotion(self, event): + """Updates the colour values during mouse motion while the + mouse button is depressed.""" + if self.mouse_down: + self.doPaletteClick(event.m_x, event.m_y) + + def doPaletteClick(self, m_x, m_y): + """Updates the colour values based on the mouse location + over the palette.""" + # Get the colour value and update + colour = self.palette.GetValue(m_x, m_y) + self.UpdateColour(colour) + + # Highlight a fresh selected area + self.palette.ReDraw() + self.palette.HighlightPoint(m_x, m_y) + + # Force an onscreen update + self.solid.Update() + self.colour_slider.Refresh() + + def onScroll(self, event): + """Updates the solid colour display to reflect the changing slider.""" + value = self.slider.GetValue() + colour = self.colour_slider.GetValue(value) + self.solid.SetColour(colour) + self.UpdateEntries(colour) + + def SetValue(self, colour): + """Updates the colour chooser to reflect the given wxColour.""" + self.UpdateColour(colour) + + def GetValue(self): + """Returns a wxColour object indicating the current colour choice.""" + return self.solid.GetColour() + +def main(): + """Simple test display.""" + class App(wxApp): + def OnInit(self): + frame = wxFrame(NULL, -1, 'PyColourChooser Test') + + chooser = wxPyColourChooser(frame, -1) + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(chooser, 0, 0) + frame.SetAutoLayout(True) + frame.SetSizer(sizer) + sizer.Fit(frame) + + frame.Show(True) + self.SetTopWindow(frame) + return True + app = App() + app.MainLoop() + +if __name__ == '__main__': + main() diff --git a/wxPython/wxPython/lib/colourchooser/pycolourslider.py b/wxPython/wxPython/lib/colourchooser/pycolourslider.py new file mode 100644 index 0000000000..17cab48e8f --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/pycolourslider.py @@ -0,0 +1,82 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix + +This file is part of wxPyColourChooser. + +You should have received a file COPYING containing license terms +along with this program; if not, write to Michael Gilfix +(mgilfix@eecs.tufts.edu) for a copy. + +This version of wxPyColourChooser is open source; you can redistribute it and/or +modify it under the terms listed in the file COPYING. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +import canvas +import colorsys +from wxPython.wx import * + +class PyColourSlider(canvas.Canvas): + """A Pure-Python Colour Slider + + The colour slider displays transitions from value 0 to value 1 in + HSV, allowing the user to select a colour within the transition + spectrum. + + This class is best accompanying by a wxSlider that allows the user + to select a particular colour shade. + """ + + HEIGHT = 172 + WIDTH = 12 + + def __init__(self, parent, id, colour=None): + """Creates a blank slider instance. A colour must be set before the + slider will be filled in.""" + # Set the base colour first since our base class calls the buffer + # drawing function + self.SetBaseColour(colour) + + canvas.Canvas.__init__(self, parent, id, + size=wxSize(self.WIDTH, self.HEIGHT)) + + def SetBaseColour(self, colour): + """Sets the base, or target colour, to use as the central colour + when calculating colour transitions.""" + self.base_colour = colour + + def GetBaseColour(self): + """Return the current colour used as a colour base for filling out + the slider.""" + return self.base_colour + + def GetValue(self, pos): + """Returns the colour value for a position on the slider. The position + must be within the valid height of the slider, or results can be + unpredictable.""" + return self.buffer.GetPixel(0, pos) + + def DrawBuffer(self): + """Actual implementation of the widget's drawing. We simply draw + from value 0.0 to value 1.0 in HSV.""" + if self.base_colour is None: + return + + target_red = self.base_colour.Red() + target_green = self.base_colour.Green() + target_blue = self.base_colour.Blue() + + h,s,v = colorsys.rgb_to_hsv(target_red / 255.0, target_green / 255.0, + target_blue / 255.0) + v = 1.0 + vstep = 1.0 / self.HEIGHT + for y_pos in range(0, self.HEIGHT): + r,g,b = [c * 255.0 for c in colorsys.hsv_to_rgb(h,s,v)] + colour = wxColour(int(r), int(g),(b)) + self.buffer.SetPen(wxPen(colour, 1, wxSOLID)) + self.buffer.DrawRectangle(0, y_pos, 15, 1) + v = v - vstep diff --git a/wxPython/wxPython/lib/colourchooser/pypalette.py b/wxPython/wxPython/lib/colourchooser/pypalette.py new file mode 100644 index 0000000000..3cbbfeeb49 --- /dev/null +++ b/wxPython/wxPython/lib/colourchooser/pypalette.py @@ -0,0 +1,214 @@ +""" +wxPyColourChooser +Copyright (C) 2002 Michael Gilfix + +This file is part of wxPyColourChooser. + +You should have received a file COPYING containing license terms +along with this program; if not, write to Michael Gilfix +(mgilfix@eecs.tufts.edu) for a copy. + +This version of wxPyColourChooser is open source; you can redistribute it and/or +modify it under the terms listed in the file COPYING. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +""" + +import canvas +import colorsys +import cStringIO, zlib +from wxPython.wx import * + +# Bitmap functions generated from img2py +def getData(): + return zlib.decompress( +'x\xdaUV{<\x93{\x18\x1f:\xe3\xc8Xj\xa3a\xe6R\x9db*B.3\x93\xeb\xe9\x1c\xb7\ +\xe4\xb2r9\x8c\xe5\x12e\xc9\xda\x88\x9a\xb4\x83\xcet\xa1N\xae\x85\xe3\xb2\ +\xe1,\xb7\xc2\x8a\xd0\x99D\xc8t\xdc\x86r\x1f\x96\\\x16k:\xebC\xe78\xef\xe7\ +\xf3\xbe\xbf?\xde\xf7\xf9=\xcf\xf3\xbd<\xbf\xf7WgG;\x90,L\x16\x00\x00\x80\ +\x1c\xec\xad]\xc5+[|7\xc8\x00\xc5O\xccv\xddE\xf1\xb2\x8d`\xe5\xe0&#\xbebdpT\ +\x00`\xbb\x94\x835\xc6\x8d\x989\x97\xd5N\xca\xb3\x05\xdb\xdc\x9c[\xd0\xf4\ +\xd2\xe6\x7f\xb9\xd3\xaa\xe9\x85\xd3\xd5\xd9\xbe]\xa7\xf2\xf1\xf2\x1b\xef\ +\x1b\xe6\xb7\tF\xca\t`\xef\xf9\xb5\xa2\x87\xe1\x8d\xd3\x8ft\xef\x06z\xa5\x8f\ +\xd7\x04\xf6y\xaf\xfbT\x0e\xad~\xce\xf1E\xa7\xc7\xe9\r\x8c\xab\xb7\xad_\xe4/\ +r\xf9\xb1\xbe\x97[\xb3\x88\xfcx\xd6\\\xdf\x15\x88\xca\xcc\xc0\xb0\x10\xef\ +\x81B\x9a\xf3Xzq\x1c\xb9\xa2E\xb2\xd3v\x80\xfd90@Ju[\xc3H\xe0\xea\xca\xdc\ +\xfbr\xde\xbb\xf0U\xcd\xf4\xd7\xfe\xabc\xbaN\xc2\xe3\xcc>T\xa6)(\xaa\x9f\xe7\ +\n\xaa\xe9\x00gcz\xa8Y\xb4\x8a\xc4\x0fr\x9a\x89\xe4\x9eJ\xe7\xa6z\xaf\xf7\ +\xcc\xc4\x11YI\xbfx\n@y\x04\x01\x00\nL\xd8\xb3#\xfa\x0e\'\xb7\xc1n\x98\xd3h\ +\xd5\x14\xd50\xeaA\x0bd\x8a\x16\x07\x96\xa0#\x13/!\xbf\xf1\xe5\x94)\xd5\xc3\ +\xfe\x9ej\x0c<\x8b<8\x89\x98\xcb\x9ek\x18X^\xf9\xa9\xffJ\r/\xd93\xda\xc2\xfd\ +\xfa\tt\xb9\xa3\x07\xe8u1\xc5\\O\xe9w\x94\xd6\n\x1e\xe8\xb1Q#@Z\xe2\x10\xd1\ +\xcb\xc7\x17\xbd\x9e\x94\x14~\xf9\xd6\xe0\xb1\xb3\xe8\xd8\x07E\xe4\xa6F\x87\ +\xbe6:K\xf8\xfanrn\x8b\xa4=e\xb3\x98\xf3\xc8\xde|\x0b\xf0\xb5\xb7\xfb\x0e\ +\xf5\x83:m3\xcbs\xfe*T\xc7\x89\xe1\x1a\xc8X=\xbfZ\xc4#\xd0\xee\x93d\xb6lL\ +\x15\xe4\xe3\xf7\xd8w\r\x1eK\xe0\xce\xad-`\x19g\xe6\x1f\xc8}\xcc}\xee\xecF\ +\x19_\xa6PUq\xee\xa2\x80\x1d\xbc\xf5\x14g\xe04\xa4\xc0EZB\xe6[\x1al\xb2!,\ +\xac\xa4\xf3O\x83\xa5y\x96(\xa7\xdd\xc61\x1aX\xa4X\xa8\x96\xdf2\x93\x067\x1c\ +\xf0\xed\x10\xaa\xe3\xe9\x96\xac\'l\x14\xb7\xc1\x0ed\x85\x96\xb1\x84m&d\x872\ +\x1f)\xe6wt\xd6\tV\xbe\xd4\xbe\xeaE\xcf\xaca\x92f4*Z\xce\xf8\xa0\xd9\x97\xa2\ ++\xcc\x90$\xbb\xac8\x0b\xf7\x93\xfa\xb6\xf2\x92\x9d\xa0M\xec\xc6\xaa<\x17\ +\xad\x8d\'\xc29\xd1uQjcU}\x8a\x1c\xbf\x9fg\x12\x9c\x1f\\4RZ8\xe2\xf5s@J\t\ +\xc5\rU\x92\xab\xf6B\xb3\x97\x8f^\xb8\xa5_\xd0\x98tQ\xa6KA\x12\x0c\x14gl\xc0\ +\x00\xe4f*=\xa3\x1ef\x0c\rU<\xb1sO\xaa\x0c\x82;\r)\xc8\x9c\xc0\x1f9CMch\xd4\ +\x9fn\xde/g\xc3C\xb0\xb0\x8cuS6\xf3;\x8d2q\x7fG7\x88;\xb4~9\xd5e\xa1}\x7f\ +\xd5\xa9Z\x88\x99\xaft+\xeca?\xa2qh\xaf\x8af\xbf\x82\xfe%\xac\xf6\nC_\xc6D\ +\xc6Ry\xb3\xb7N\x11"\xcfU\xbb@m\x86AY\na\xfa;\xa1\x93\x96\xf2i\xd0\x04S\x90~\ +\x1b\xb8z[1C\xde\x15w\xed\x0b\xd8\xd0\xbe\\\x19\x84\x84\xfe\x1bE\re\xda\x1az\ +6\xe6\xbe!+\x86V\xbd\xfb\xc3\xfb\xd9[\xff\xc0\x8c\xc5\nH<\x82U#2S\t\xc8\x1en\ +\xa7\xb5E\xde\x14W\xd2w\xe3\xf0\x18\x02\xa0\xf7\xad\xb6\xb2\x96\xfb\xbbH\x02\ +\x0b\x85P\xb7\xe4\x02!\xe6a\xc4d\xe8]\x17\xa4\x8bk2G\xaf\xa2p\\\x8e\xd0\x8e\ +\t\nf\xce\xf0\x10}O\xc1\x95\x9e\x80\xa6\x91\x8d\xae0\xcf\xa0\xc7\x97-h\xc3\ +\x1f\xb8"l\x14\xcaz9\xffYl\x15.l|\xc4\x94\xdd&\x9c\x9f\xf8\xb8f7\x08cA\x1e\ +\x85\x11,\xb0\xba\xf1\x87639\xfbJ\xef~e\xf3\xdbK\xd4\xe7\xec\xa5\x92\x17\xf7\ +\x1aO\xe3*\xd5\xf3\xcbA\xef\xf4\xa4[\x1d\xaf\xd7>M-\xf1\xb9@\xea\x96x\xd9(\ +\x06Z\xec+J\xed\xe5\xd45\x95\xe1\xba\xeb\xf4\xa4\xa3i\xbb\x82}\xd0\xf6Lh\xe8\ +E4;0\x9aPk\x0emo~G\x04\xb6&u\xb31\x80\xdao\x01\xf5P\x1d\xd8\x05\x92qmV\xf6R\ +\x17\x89\x1a-\xf4\x15P*\xf9?|\xcea\xa9\x8f\x99~6\x92^\xf8\x03s\x11;v\xe2D\ +\xc4^\x1c>Q\xbfY\xd0n\xbaE\xc0b=\x91\x0c=[U\x86\xfb\x06\xb52\x92\x19M1uz<\ +\xb1\xa4r~4\x83E\xe2y\x08\x0f\nQ\x84\xe8\xfa\xfa\xea\x13\x0e\xd4\x95\x91\\\ +\x7f\xf6)\x08`\xb6\x89\xc5\x95^\xff\xe2\\\x03X\xe4\xbe\x88x\x8f\xe34\xb7\xe6\ +\xbe\t\xf8\\w\x9c\xd3\x1a\xee\x98\xeeW\x92\xad\x83\x99\xb6B\xcb\x8f\xbdD\x86\ +\xc6\xe3\xab\x1b\xb2\xdf\x08:9\xbc\x9e\xf3\xf9h\xd1\xec\xd98\xc8%\x0b\x87c\ +\xb8\xbc\x0f\xad\x89\xca\xa5\x94J\xa9\x88j\x1ddo\x91u\x84\xf3\xcd\xea\xc5\ +\xf6\x99\xab\xe0\xd7-\x92\xff:\xe6)T\x07\x0bd\x1b\xa9+9\xa4\x86\xec2F\xa1\ +\xa6\x7f\xbc\xd1C\x9e\xf4=D\x12\xa2\x07\x94\t\xb1\xe8\xb5\xfb\x94\x14q~R\xa1\ +\xe6Y<\xad\xcb\x94j\xbc\xb3##\x0f\xd0 \xbf\xc9\x01\xf8\xad\xb8V\x82sdO7\xbd\ +\xbe\xd5Bd\x9f\xc0m#\xd4h<j\xf5*\x84\x86VKt\x0c4\xc1QkD\xbd\xee\xd0\xdc\xcc\ +\xad\xc5bN\'\x8f\x1b\x92\x95\x8e\xdf,\xb1\xfa\xe0\xc7f\xd5\xc7\x95\xd1&\xe06\ +\xcb\xb4t/\xa0KTj\xd0\xe2\xfb\xd2\xc3!\xf1\xcb?\r7_\x14K$xs(\xfa}~\xe2\xd9\ +\xe5gP\xd4\xfaq\x97\xb1\x0b\xd2]\xe5|\x19o2(Vm\xfe>\xe5\x13jZ\xdan\x98\xf3\ +\xe4:\x1ep\x93B\xec6?\tO\x0eaB\x99>\xc6Zkr\xcf!\x1b\x84|\xb5\xdb\x8b*O\xb4\ +\xe7\x14Ko\xa0\x93\xecmq\xd7\xf0\xbd\x12\x07\x8d\x95\xd7\x7f\xf5&\xb8bmj\xda\ +/&`>e\xeb\xfc\x14a\x19\x94S\x7f\xd2\xb5:\x8c\x04\x8f\x91\x03\xc2Q\x0e\xff{\ +\x93\xc7\xea\xd6\xbb\x1b\x0e7\xe7E\xa6\xae\x9d\xc6\x85%\x9e\xfbnc\xe3\xff\ +\xd4\xa2`9\x13\xa3\x97\x9e\xa4\x9b\x06\xa5\x9f\xec\x9f\x1a\x0c\xf0\xfe\xcd\ +\x021\x9b\x0cM\xc06\xfd u:\xe7:g\x02\xc1r\x926\x9b\x7f\xe2\xf9\xe3\xed\xf1qU\ +\xbe\xbf\xe8\x91\t\x0c0\xfb-\xe5%d\xef\x19v\x966\xec\xaaB\xe2`N[\x8c\xda\x98\ +\xf4\xb4\x83\x13\xcc\x8a\x83\x81\xa3\x91%\xdb\xad\xab\xff\x87\xe1\xba\xda\ +\xb5\xdb\xf0\x17\xfd\xf4F\x18KTNH\xf5J\xbc\x97\xdfB:\xa7\x96\xdf/k\x1c\xeaF_\ +\x8c\xfc\xdfap\x1e\x99\xae8\x94b\xa1t<\xb54.3c\xd9\xe8y=u9FM;D\xa6\xc0\xea~\ +\x0f"O\xee\x81\xdc\xa3\xb2\x1a\xa0\xa7\x02\xb9\x7f>\xfdg\x974\xc8\x0b\xbaU6P\ +\xe7\x14\xd8\xd5 \x90\xbc\x0b\xf0\xb7\xc4\x7f\x08\xfaPl\xf5\xa7\x96\xac\xc2\ +\x0f*\x05\xf3\x83\xe8\xce\xa7\xc4\x8c\xdbX\xa4U\x9b\xeeW\xe9\xf1\xbf\xa4Q#\ +\xcbDQ\x18h\x02\xca\'\xca\xee),1"\x8d\xfb<\x15\xafl\xb8\xb3z\x18\x18\xaf\xb6\ +I$\xa2\xbc\xe5\xe5J\xbe\x00\r\x08&<\x0eK\x98\x0e.[\xd1\xea`\xa9\xe2\x96\xae-\ +d9%\xc0 \x85\xc5{c_\x03x\xaf\x8f\x98P= 0\x8e\xff\xaa\xf5>7\xfeO\x7f\x1b\xcbm\ +\xb1W\xa7\t\x9b\xe1w\x02\xc5\xb5\x9fM/\x8d\xab\xe4u\r\x06\xa0\xd6\xc9\xb5\ +\xf2\xb7J\x01\xda<\r\x9f\xd1\x06\x03\xea>\xab\x9d\xe6\xde\xb4\xbb\xb1\xc6\ +\xa3EP\x1e\x17\x16\xf2\x1c\xa7\x823\xa7\xcc~\xd1\xdb\xb2\xcb\xbd\xe1\xdb\xf0\ +W(,\xe9XD)3I\xc4\x15z_\x98\x8b\xb2v\xdb\x13\xd0\xb8\xf3U"\xb713\xaf\xa0\x1dC\ +j\x0b\xb0\xf9\xfd\xef\x0ex\xd7l\xa5\xc1\xf7Z\xd2\x12\x1f\xbe\r\x87Shjm\xe3\ +\x1c\x92\xbc\xc7^\x9e\xe5\x84\xf9\xb8\xcb\x88+\x12\xb4M\xee\xb0\xbb\xcd\xc4\ +\x9c\xc7V\x1f\xde\x1b\x02\xb0!\x0c\xbeY&\xf6\xe9\xdd[u:0\x0f)(\xc5g\n\xd5\ +\xb6\xcc\xf0st\n\x113\x81Q\xcc\xef\xaa\x1b\x9a#\xad|\x12\x98\xd8\xf7"\xa2\ +\xa2\xd7\xdbwz+\x08\xb8\x0c\x9d&mZ\\-<\xbaG6j\x9cy@\x8ah\x10@\x8e\xd9\x12\ +\x9dK\x00\xf3\xabdo\x1f\x8b\x80\x9c\xf7i^#\xc1X\x7f-\x13R](\x17\xa0\x89p\x9c\ +L\x1a\xc5\x9c\x88U\xde\xc7\x9d\xd04\x04\x8en\x11\x8112\xbd\xf6J\x96wP\x06\ +\xcd\xa9x\x08\xf7\xc3\xfc\x0e\xceE\xef\xf9j\xd50\x19~\x02~\xf7C\x13\xae\xd8\ +\xea\x8e\xc9\x8c\xafpU\xc8\x8d\xaa\xe5\x88Q\xfan\x93\xf7\xf0(\xb0\x93\xf5NH\ +\x1f\xae\xc5\xf8\xaa\x97F4\x19;\x19\xe4=\x89\xe0\xae\x15\xc9\xb6\xfe\xe2\xce\ +\x1e\xca\xe6\x1a\n<\t\xa9].x\x03\xfd\x1c\x86Fd?\xbd\x17|z\x03\xa8\xafX[N"|\ +\x16\xa3#\x0e\x92\xf0h{^+K\x04/!\x8f\xac\xf4\xe4\xbbH\xa9.\x85q\xdd\x93\xc7\ +\xbb`\x96\xbb\xb5\xefQ\xdc\x9ch+G\xf8\xbf\xf6b\xdc\xfbww\xcf\xc7\x85\xf7\n@\ +\x8d[\xdc\x1b\x8e\xd5\x85\x1c\xf0@JG\x08\xc9;\n\xfb\x9dX\xc5\x8e\t\\\xb3g#\ +\xa0\xa2\xb7`\n\x96\x116?\xda\x83\xea\xa1\x7f.Y\x9f\xcb\xda_\x8c\xe9\x01s\ +\x0f\xf6\x03\xb7:\xa0\xc6\x94\xaat\xc4\x96r\x1c\x12\x06\x1dZ\xf7\x10V\xd5\ +\x088\x02N\xc6\xcc\x05y\xd7\xc0T\x07,c\xea\xb2\xcf\xc7=>y\x87M_\x9a\x86\x12\ +\xa5\x92\x83\n_"\x84\xff\x8b7\x95\xfeu\x02\x9c\xf7\xe4\xfacQyo\xda\xbb\t\xed\ +\xdeS\xd3\xb7\x04/j\xdb\x96\xae\xec\xd3\x01\xb8P\x8ap\x8c7\x88\xc2\xa8\xfd\ +\x1d\xd5\xd1=\xab$*\x8c\x9dd\xacu\x07\xe3\xa6X\xed\x1d\xb9eHd@\x8f\xb7\xd4V\ +\xdc\x95\x0f\xa91\xba\xe3s?\n\x12\xf2\x97\xefh\xf4\x1d\x89\x04\xccC)\x8f\x83\ +\xbf\x84\xd5\xe0A\xb7\xccC\xf9\xc3fGA\x92\xe4\x12\x89\x03\x14bb\xdfe\xd9\x7f\ +\x0f\x86\xc6R\xf9wC\x114\xe0\xdd\xae9\xc9ef\x92\xb6\x12\x1eU\'ZW\xa2\xe9\xa7\ +4\x15\xfdb\nr\x17\xf1\xe15IkA\xe5\x12aM[&\x93T\x16\xa5\x92x\xf8\xc3\xd4\xca\ +\xd8[\x96]wPNO\t!5\xaf&\xfarlLC\xdd\x00\xdd\x8e\x13qc\xea&]nAb\x8b1>)9\x047\ +\xc5\x8e\x1a\xd5\x84\x8b\x7f\x8f\x01\x0e6\x8e\xd6eV~W\xff\x01[x\x1b=' ) + +def getBitmap(): + return wxBitmapFromImage(getImage()) + +def getImage(): + stream = cStringIO.StringIO(getData()) + return wxImageFromStream(stream) + +class PyPalette(canvas.Canvas): + """The Pure-Python Palette + + The PyPalette is a pure python implementation of a colour palette. The + palette implementation here imitates the palette layout used by MS + Windows and Adobe Photoshop. + + The actual palette image has been embedded as an XPM for speed. The + actual reverse-engineered drawing algorithm is provided in the + GeneratePaletteBMP() method. The algorithm is tweakable by supplying + the granularity factor to improve speed at the cost of display + beauty. Since the generator isn't used in real time, no one will + likely care :) But if you need it for some sort of unforeseen realtime + application, it's there. + """ + + HORIZONTAL_STEP = 2 + VERTICAL_STEP = 4 + + def __init__(self, parent, id): + """Creates a palette object.""" + # Load the pre-generated palette XPM + self.palette = getBitmap () + canvas.Canvas.__init__ (self, parent, id, size=wxSize(200, 192)) + + def GetValue(self, x, y): + """Returns a colour value at a specific x, y coordinate pair. This + is useful for determining the colour found a specific mouse click + in an external event handler.""" + return self.buffer.GetPixel(x, y) + + def DrawBuffer(self): + """Draws the palette XPM into the memory buffer.""" + #self.GeneratePaletteBMP ("foo.bmp") + self.buffer.DrawBitmap(self.palette, 0, 0, 0) + + def HighlightPoint(self, x, y): + """Highlights an area of the palette with a little circle around + the coordinate point""" + colour = wxColour(0, 0, 0) + self.buffer.SetPen(wxPen(colour, 1, wxSOLID)) + self.buffer.SetBrush(wxBrush(colour, wxTRANSPARENT)) + self.buffer.DrawCircle(x, y, 3) + self.Refresh() + + def GeneratePaletteBMP(self, file_name, granularity=1): + """The actual palette drawing algorithm. + + This used to be 100% reverse engineered by looking at the + values on the MS map, but has since been redone Correctly(tm) + according to the HSV (hue, saturation, value) colour model by + Charl P. Botha <http://cpbotha.net/>. + + Speed is tweakable by changing the granularity factor, but + that affects how nice the output looks (makes the vertical + blocks bigger. This method was used to generate the embedded + XPM data.""" + self.vertical_step = self.VERTICAL_STEP * granularity + width, height = self.GetSize () + + # simply iterate over hue (horizontal) and saturation (vertical) + value = 1.0 + for y in range(0, height, self.vertical_step): + saturation = 1.0 - float(y) / float(height) + for x in range(0, width, self.HORIZONTAL_STEP): + hue = float(x) / float(width) + r,g,b = colorsys.hsv_to_rgb(hue, saturation, value) + colour = wxColour(r * 255.0, g * 255.0, b * 255.0) + self.buffer.SetPen(wxPen(colour, 1, wxSOLID)) + self.buffer.SetBrush(wxBrush(colour, wxSOLID)) + self.buffer.DrawRectangle(x, y, + self.HORIZONTAL_STEP, + self.vertical_step) + + # this code is now simpler (and works) + bitmap = self.buffer.GetBitmap() + image = wxImageFromBitmap(bitmap) + image.SaveFile (file_name, wxBITMAP_TYPE_XPM) diff --git a/wxPython/wxPython/lib/colourselect.py b/wxPython/wxPython/lib/colourselect.py index db9043d802..fbf1999f37 100644 --- a/wxPython/wxPython/lib/colourselect.py +++ b/wxPython/wxPython/lib/colourselect.py @@ -76,7 +76,7 @@ class ColourSelect(wxButton): def OnClick(self, event): data = wxColourData() - data.SetChooseFull(true) + data.SetChooseFull(True) data.SetColour(self.set_colour_val) dlg = wxColourDialog(self.GetParent(), data) changed = dlg.ShowModal() == wxID_OK diff --git a/wxPython/wxPython/lib/dialogs.py b/wxPython/wxPython/lib/dialogs.py index dd600ddd27..920b659af4 100644 --- a/wxPython/wxPython/lib/dialogs.py +++ b/wxPython/wxPython/lib/dialogs.py @@ -1,47 +1,59 @@ -from wxPython.wx import * -from layoutf import Layoutf -import string +#---------------------------------------------------------------------- +# Name: wxPython.lib.dialogs +# Purpose: wxScrolledMessageDialog, wxMultipleChoiceDialog and +# function wrappers for the common dialogs by Kevin Altis. +# +# Author: Various +# +# Created: 3-January-2002 +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- +from wxPython import wx +from layoutf import Layoutf +#---------------------------------------------------------------------- -class wxScrolledMessageDialog(wxDialog): - def __init__(self, parent, msg, caption, pos = wxDefaultPosition, size = (500,300)): - wxDialog.__init__(self, parent, -1, caption, pos, size) +class wxScrolledMessageDialog(wx.wxDialog): + def __init__(self, parent, msg, caption, pos = wx.wxDefaultPosition, size = (500,300)): + wx.wxDialog.__init__(self, parent, -1, caption, pos, size) x, y = pos if x == -1 and y == -1: - self.CenterOnScreen(wxBOTH) - text = wxTextCtrl(self, -1, msg, wxDefaultPosition, - wxDefaultSize, - wxTE_MULTILINE | wxTE_READONLY) - ok = wxButton(self, wxID_OK, "OK") + self.CenterOnScreen(wx.wxBOTH) + text = wx.wxTextCtrl(self, -1, msg, wx.wxDefaultPosition, + wx.wxDefaultSize, + wx.wxTE_MULTILINE | wx.wxTE_READONLY) + ok = wx.wxButton(self, wx.wxID_OK, "OK") text.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok))) ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,))) - self.SetAutoLayout(TRUE) + self.SetAutoLayout(1) self.Layout() -class wxMultipleChoiceDialog(wxDialog): - def __init__(self, parent, msg, title, lst, pos = wxDefaultPosition, size = (200,200)): - wxDialog.__init__(self, parent, -1, title, pos, size) +class wxMultipleChoiceDialog(wx.wxDialog): + def __init__(self, parent, msg, title, lst, pos = wx.wxDefaultPosition, size = (200,200)): + wx.wxDialog.__init__(self, parent, -1, title, pos, size) x, y = pos if x == -1 and y == -1: - self.CenterOnScreen(wxBOTH) - dc = wxClientDC(self) + self.CenterOnScreen(wx.wxBOTH) + dc = wx.wxClientDC(self) height = 0 - for line in string.split(msg,'\n'): + for line in msg.splitlines(): height = height + dc.GetTextExtent(msg)[1] + 4 - stat = wxStaticText(self, -1, msg) - self.lbox = wxListBox(self, 100, wxDefaultPosition, - wxDefaultSize, lst, wxLB_MULTIPLE) - ok = wxButton(self, wxID_OK, "OK") - cancel = wxButton(self, wxID_CANCEL, "Cancel") + stat = wx.wxStaticText(self, -1, msg) + self.lbox = wx.wxListBox(self, 100, wx.wxDefaultPosition, + wx.wxDefaultSize, lst, wx.wxLB_MULTIPLE) + ok = wx.wxButton(self, wx.wxID_OK, "OK") + cancel = wx.wxButton(self, wx.wxID_CANCEL, "Cancel") stat.SetConstraints(Layoutf('t=t10#1;l=l5#1;r=r5#1;h!%d' % (height,), (self,))) self.lbox.SetConstraints(Layoutf('t=b10#2;l=l5#1;r=r5#1;b=t5#3', (self, stat, ok))) ok.SetConstraints(Layoutf('b=b5#1;x%w25#1;w!80;h!25', (self,))) cancel.SetConstraints(Layoutf('b=b5#1;x%w75#1;w!80;h!25', (self,))) - self.SetAutoLayout(TRUE) + self.SetAutoLayout(1) self.lst = lst self.Layout() @@ -56,46 +68,317 @@ class wxMultipleChoiceDialog(wxDialog): return tuple(val) + +#---------------------------------------------------------------------- +""" +function wrappers for wxPython system dialogs +Author: Kevin Altis +Date: 2003-1-2 +Rev: 3 + +This is the third refactor of the PythonCard dialog.py module +for inclusion in the main wxPython distribution. There are a number of +design decisions and subsequent code refactoring to be done, so I'm +releasing this just to get some feedback. + +rev 3: +- result dictionary replaced by DialogResults class instance +- should message arg be replaced with msg? most wxWindows dialogs + seem to use the abbreviation? + +rev 2: +- All dialog classes have been replaced by function wrappers +- Changed arg lists to more closely match wxWindows docs and wxPython.lib.dialogs +- changed 'returned' value to the actual button id the user clicked on +- added a returnedString value for the string version of the return value +- reworked colorDialog and fontDialog so you can pass in just a color or font + for the most common usage case +- probably need to use colour instead of color to match the English English + spelling in wxWindows (sigh) +- I still think we could lose the parent arg and just always use None +""" + +class DialogResults: + def __init__(self, returned): + self.returned = returned + self.accepted = returned in (wx.wxID_OK, wx.wxID_YES) + self.returnedString = returnedString(returned) + + def __repr__(self): + return str(self.__dict__) + +def returnedString(ret): + if ret == wx.wxID_OK: + return "Ok" + elif ret == wx.wxID_CANCEL: + return "Cancel" + elif ret == wx.wxID_YES: + return "Yes" + elif ret == wx.wxID_NO: + return "No" + + +# findDialog was created before wxPython got a Find/Replace dialog +# but it may be instructive as to how a function wrapper can +# be added for your own custom dialogs +# this dialog is always modal, while wxFindReplaceDialog is +# modeless and so doesn't lend itself to a function wrapper +def findDialog(parent=None, searchText='', wholeWordsOnly=0, caseSensitive=0): + dlg = wx.wxDialog(parent, -1, "Find", wx.wxDefaultPosition, wx.wxSize(370, 120)) + + wx.wxStaticText(dlg, -1, 'Find what:', wx.wxPoint(7, 10)) + wSearchText = wx.wxTextCtrl(dlg, -1, searchText, + wx.wxPoint(70, 7), wx.wxSize(195, -1)) + wSearchText.SetValue(searchText) + wx.wxButton(dlg, wx.wxID_OK, "Find Next", wx.wxPoint(280, 5), wx.wxDefaultSize).SetDefault() + wx.wxButton(dlg, wx.wxID_CANCEL, "Cancel", wx.wxPoint(280, 35), wx.wxDefaultSize) + wWholeWord = wx.wxCheckBox(dlg, -1, 'Match whole word only', + wx.wxPoint(7, 35), wx.wxDefaultSize, wx.wxNO_BORDER) + if wholeWordsOnly: + wWholeWord.SetValue(1) + wCase = wx.wxCheckBox(dlg, -1, 'Match case', + wx.wxPoint(7, 55), wx.wxDefaultSize, wx.wxNO_BORDER) + if caseSensitive: + wCase.SetValue(1) + wSearchText.SetSelection(0, len(wSearchText.GetValue())) + wSearchText.SetFocus() + + result = DialogResults(dlg.ShowModal()) + result.text = wSearchText.GetValue() + result.wholeword = wWholeWord.GetValue() + result.casesensitive = wCase.GetValue() + dlg.Destroy() + return result + + +def colorDialog(parent=None, colorData=None, color=None): + if colorData: + dialog = wx.wxColourDialog(parent, colorData) + else: + dialog = wx.wxColourDialog(parent) + dialog.GetColourData().SetChooseFull(1) + if color is not None: + dialog.GetColourData().SetColour(color) + result = DialogResults(dialog.ShowModal()) + result.colorData = dialog.GetColourData() + result.color = result.colorData.GetColour().Get() + dialog.Destroy() + return result + +# it is easier to just duplicate the code than +# try and replace color with colour in the result +def colourDialog(parent=None, colourData=None, colour=None): + if colourData: + dialog = wx.wxColourDialog(parent, colourData) + else: + dialog = wx.wxColourDialog(parent) + dialog.GetColourData().SetChooseFull(1) + if colour is not None: + dialog.GetColourData().SetColour(color) + result = DialogResults(dialog.ShowModal()) + result.colourData = dialog.GetColourData() + result.colour = result.colourData.GetColour().Get() + dialog.Destroy() + return result + + +def fontDialog(parent=None, fontData=None, font=None): + if fontData is None: + fontData = wx.wxFontData() + if font is not None: + aFontData.SetInitialFont(font) + dialog = wx.wxFontDialog(parent, fontData) + result = DialogResults(dialog.ShowModal()) + if result.accepted: + fontData = dialog.GetFontData() + result.fontData = fontData + result.color = fontData.GetColour().Get() + result.colour = result.color + result.font = fontData.GetChosenFont() + else: + result.color = None + result.colour = None + result.font = None + dialog.Destroy() + return result + + +def textEntryDialog(parent=None, message='', title='', defaultText='', style=wx.wxOK | wx.wxCANCEL): + dialog = wx.wxTextEntryDialog(parent, message, title, defaultText, style) + result = DialogResults(dialog.ShowModal()) + result.text = dialog.GetValue() + dialog.Destroy() + return result + + +def messageDialog(parent=None, message='', title='Message box', + aStyle = wx.wxOK | wx.wxCANCEL | wx.wxCENTRE, + pos=wx.wxDefaultPosition): + dialog = wx.wxMessageDialog(parent, message, title, aStyle, pos) + result = DialogResults(dialog.ShowModal()) + dialog.Destroy() + return result + + +# KEA alerts are common, so I'm providing a class rather than +# requiring the user code to set up the right icons and buttons +# the with messageDialog function +def alertDialog(parent=None, message='', title='Alert', pos=wx.wxDefaultPosition): + return messageDialog(parent, message, title, wx.wxICON_EXCLAMATION | wx.wxOK, pos) + + +def scrolledMessageDialog(parent=None, message='', title='', pos=wx.wxDefaultPosition, size=(500,300)): + dialog = wxScrolledMessageDialog(parent, message, title, pos, size) + result = DialogResults(dialog.ShowModal()) + dialog.Destroy() + return result + + +def fileDialog(parent=None, title='Open', directory='', filename='', wildcard='*.*', + style=wx.wxOPEN | wx.wxMULTIPLE): + dialog = wx.wxFileDialog(parent, title, directory, filename, wildcard, style) + result = DialogResults(dialog.ShowModal()) + if result.accepted: + result.paths = dialog.GetPaths() + else: + result.paths = None + dialog.Destroy() + return result + + +# openFileDialog and saveFileDialog are convenience functions +# they represent the most common usages of the fileDialog +# with the most common style options +def openFileDialog(parent=None, title='Open', directory='', filename='', + wildcard='All Files (*.*)|*.*', + style=wx.wxOPEN | wx.wxMULTIPLE): + return fileDialog(parent, title, directory, filename, wildcard, style) + + +def saveFileDialog(parent=None, title='Save', directory='', filename='', + wildcard='All Files (*.*)|*.*', + style=wx.wxSAVE | wx.wxHIDE_READONLY | wx.wxOVERWRITE_PROMPT): + return fileDialog(parent, title, directory, filename, wildcard, style) + + +def dirDialog(parent=None, message='Choose a directory', path='', style=0, + pos=wx.wxDefaultPosition, size=wx.wxDefaultSize): + dialog = wx.wxDirDialog(parent, message, path, style, pos, size) + result = DialogResults(dialog.ShowModal()) + if result.accepted: + result.path = dialog.GetPath() + else: + result.path = None + dialog.Destroy() + return result + +directoryDialog = dirDialog + + +def singleChoiceDialog(parent=None, message='', title='', lst=[], + style=wx.wxOK | wx.wxCANCEL | wx.wxCENTRE): + dialog = wx.wxSingleChoiceDialog(parent, + message, + title, + lst, + style) + result = DialogResults(dialog.ShowModal()) + result.selection = dialog.GetStringSelection() + dialog.Destroy() + return result + + +def multipleChoiceDialog(parent=None, message='', title='', lst=[], pos=wx.wxDefaultPosition, size=(200,200)): + dialog = wxMultipleChoiceDialog(parent, message, title, lst, pos, size) + result = DialogResults(dialog.ShowModal()) + result.selection = dialog.GetValueString() + dialog.Destroy() + return result + + if __name__ == '__main__': - class MyFrame(wxFrame): - def __init__(self): - wxFrame.__init__(self, NULL, -1, "hello", - wxDefaultPosition, wxSize(200,200)) - wxButton(self, 100, "Multiple Test",wxPoint(0,0)) - wxButton(self, 101, "Message Test", wxPoint(0,100)) - EVT_BUTTON(self, 100, self.OnMultipleTest) - EVT_BUTTON(self, 101, self.OnMessageTest) - - def OnMultipleTest(self, event): - self.lst = [ 'apple', 'pear', 'banana', 'coconut', 'orange', - 'etc', 'etc..', 'etc...' ] - dlg = wxMultipleChoiceDialog(self, - "Pick some from\n this list\nblabla", - "m.s.d.", self.lst) - if (dlg.ShowModal() == wxID_OK): - print "Selection:", dlg.GetValue(), " -> ", dlg.GetValueString() - - def OnMessageTest(self, event): - import sys; - f = open(sys.argv[0],"r") - msg = f.read() - dlg = wxScrolledMessageDialog(self, msg, "message test") - dlg.ShowModal() - - - class MyApp(wxApp): + class MyApp(wx.wxApp): + def OnInit(self): - frame = MyFrame() - frame.Show(TRUE) - self.SetTopWindow(frame) - return TRUE + frame = wx.wxFrame(wx.NULL, -1, "Dialogs", size=(400, 200)) + panel = wx.wxPanel(frame, -1) + self.panel = panel - app = MyApp(0) - app.MainLoop() + frame.Show(1) + dialogNames = [ + 'alertDialog', + 'colorDialog', + 'directoryDialog', + 'fileDialog', + 'findDialog', + 'fontDialog', + 'messageDialog', + 'multipleChoiceDialog', + 'openFileDialog', + 'saveFileDialog', + 'scrolledMessageDialog', + 'singleChoiceDialog', + 'textEntryDialog', + ] + self.nameList = wx.wxListBox(panel, -1, (0, 0), (130, 180), dialogNames, style=wx.wxLB_SINGLE) + wx.EVT_LISTBOX(panel, self.nameList.GetId(), self.OnNameListSelected) + tstyle = wx.wxTE_RICH2 | wx.wxTE_PROCESS_TAB | wx.wxTE_MULTILINE + self.text1 = wx.wxTextCtrl(panel, -1, pos=(150, 0), size=(200, 180), style=tstyle) + self.SetTopWindow(frame) + return 1 + def OnNameListSelected(self, evt): + import pprint + sel = evt.GetString() + result = None + if sel == 'alertDialog': + result = alertDialog(message='Danger Will Robinson') + elif sel == 'colorDialog': + result = colorDialog() + elif sel == 'directoryDialog': + result = directoryDialog() + elif sel == 'fileDialog': + wildcard = "JPG files (*.jpg;*.jpeg)|*.jpeg;*.JPG;*.JPEG;*.jpg|GIF files (*.gif)|*.GIF;*.gif|All Files (*.*)|*.*" + result = fileDialog(None, 'Open', '', '', wildcard) + elif sel == 'findDialog': + result = findDialog() + elif sel == 'fontDialog': + result = fontDialog() + elif sel == 'messageDialog': + result = messageDialog(None, 'Hello from Python and wxPython!', + 'A Message Box', wx.wxOK | wx.wxICON_INFORMATION) + #wx.wxYES_NO | wx.wxNO_DEFAULT | wx.wxCANCEL | wx.wxICON_INFORMATION) + #result = messageDialog(None, 'message', 'title') + elif sel == 'multipleChoiceDialog': + result = multipleChoiceDialog(None, "message", "title", ['one', 'two', 'three']) + elif sel == 'openFileDialog': + result = openFileDialog() + elif sel == 'saveFileDialog': + result = saveFileDialog() + elif sel == 'scrolledMessageDialog': + msg = "Can't find the file dialog.py" + try: + # read this source file and then display it + import sys + filename = sys.argv[-1] + fp = open(filename) + message = fp.read() + fp.close() + except: + pass + result = scrolledMessageDialog(None, message, filename) + elif sel == 'singleChoiceDialog': + result = singleChoiceDialog(None, "message", "title", ['one', 'two', 'three']) + elif sel == 'textEntryDialog': + result = textEntryDialog(None, "message", "title", "text") + if result: + #self.text1.SetValue(pprint.pformat(result.__dict__)) + self.text1.SetValue(str(result)) + app = MyApp(0) + app.MainLoop() diff --git a/wxPython/wxPython/lib/editor/editor.py b/wxPython/wxPython/lib/editor/editor.py index 72fc6d5cee..77f5c94edf 100644 --- a/wxPython/wxPython/lib/editor/editor.py +++ b/wxPython/wxPython/lib/editor/editor.py @@ -24,7 +24,6 @@ import os, time from wxPython.wx import * -from string import * import selection import images @@ -123,7 +122,7 @@ class wxEditor(wxScrolledWindow): if wxPlatform == "__WXMSW__": return wxFont(10, wxMODERN, wxNORMAL, wxNORMAL) else: - return wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, false) + return wxFont(12, wxMODERN, wxNORMAL, wxNORMAL, False) def UnixKeyHack(self, key): # this will be obsolete when we get the new wxWindows patch @@ -163,7 +162,7 @@ class wxEditor(wxScrolledWindow): if dc.Ok(): self.SetCharDimensions() self.KeepCursorOnScreen() - self.DrawSimpleCursor(0,0,dc, true) + self.DrawSimpleCursor(0,0,dc, True) self.Draw(dc) def OnPaint(self, event): @@ -257,7 +256,7 @@ class wxEditor(wxScrolledWindow): self.DrawSimpleCursor(x, y, dc) - def DrawSimpleCursor(self, xp, yp, dc = None, old=false): + def DrawSimpleCursor(self, xp, yp, dc = None, old=False): if not dc: dc = wxClientDC(self) @@ -354,13 +353,13 @@ class wxEditor(wxScrolledWindow): return len(self.lines) def UnTouchBuffer(self): - self.bufferTouched = FALSE + self.bufferTouched = False def BufferWasTouched(self): return self.bufferTouched def TouchBuffer(self): - self.bufferTouched = TRUE + self.bufferTouched = True ##-------------------------- Mouse scroll timing functions @@ -368,7 +367,7 @@ class wxEditor(wxScrolledWindow): def InitScrolling(self): # we don't rely on the windows system to scroll for us; we just # redraw the screen manually every time - self.EnableScrolling(FALSE, FALSE) + self.EnableScrolling(False, False) self.nextScrollTime = 0 self.SCROLLDELAY = 0.050 # seconds self.scrollTimer = wxTimer(self) @@ -377,12 +376,12 @@ class wxEditor(wxScrolledWindow): def CanScroll(self): if time.time() > self.nextScrollTime: self.nextScrollTime = time.time() + self.SCROLLDELAY - return true + return True else: - return false + return False def SetScrollTimer(self): - oneShot = true + oneShot = True self.scrollTimer.Start(1000*self.SCROLLDELAY/2, oneShot) EVT_TIMER(self, -1, self.OnTimer) @@ -449,7 +448,7 @@ class wxEditor(wxScrolledWindow): def OnMotion(self, event): if event.LeftIsDown() and self.HasCapture(): - self.Selecting = true + self.Selecting = True self.MouseToCursor(event) self.SelectUpdate() @@ -467,8 +466,8 @@ class wxEditor(wxScrolledWindow): if self.SelectEnd is None: self.OnClick() else: - self.Selecting = false - self.SelectNotify(false, self.SelectBegin, self.SelectEnd) + self.Selecting = False + self.SelectNotify(False, self.SelectBegin, self.SelectEnd) self.ReleaseMouse() self.scrollTimer.Stop() @@ -630,8 +629,8 @@ class wxEditor(wxScrolledWindow): def SelectOff(self): self.SelectBegin = None self.SelectEnd = None - self.Selecting = false - self.SelectNotify(false,None,None) + self.Selecting = False + self.SelectNotify(False,None,None) def CopySelection(self, event): selection = self.FindSelection() @@ -650,7 +649,7 @@ class wxEditor(wxScrolledWindow): def CopyToClipboard(self, linesOfText): do = wxTextDataObject() - do.SetText(string.join(linesOfText, os.linesep)) + do.SetText(os.linesep.join(linesOfText)) wxTheClipboard.Open() wxTheClipboard.SetData(do) wxTheClipboard.Close() @@ -837,29 +836,29 @@ class wxEditor(wxScrolledWindow): keySettingFunction(action) if not action.has_key(key): - return false + return False if event.ShiftDown(): if not self.Selecting: - self.Selecting = true + self.Selecting = True self.SelectBegin = (self.cy, self.cx) action[key](event) self.SelectEnd = (self.cy, self.cx) else: action[key](event) if self.Selecting: - self.Selecting = false + self.Selecting = False self.SelectNotify(self.Selecting, self.SelectBegin, self.SelectEnd) self.UpdateView() - return true + return True def MoveSpecialKey(self, event, key): return self.Move(self.SetMoveSpecialFuncs, key, event) def MoveSpecialControlKey(self, event, key): if not event.ControlDown(): - return false + return False return self.Move(self.SetMoveSpecialControlFuncs, key, event) def Dispatch(self, keySettingFunction, key, event): @@ -868,21 +867,21 @@ class wxEditor(wxScrolledWindow): if action.has_key(key): action[key](event) self.UpdateView() - return true - return false + return True + return False def ModifierKey(self, key, event, modifierKeyDown, MappingFunc): if not modifierKeyDown: - return false + return False key = self.UnixKeyHack(key) try: key = chr(key) except: - return false + return False if not self.Dispatch(MappingFunc, key, event): wxBell() - return true + return True def ControlKey(self, event, key): return self.ModifierKey(key, event, event.ControlDown(), self.SetControlFuncs) @@ -892,14 +891,14 @@ class wxEditor(wxScrolledWindow): def SpecialControlKey(self, event, key): if not event.ControlDown(): - return false + return False if not self.Dispatch(self.SetSpecialControlFuncs, key, event): wxBell() - return true + return True def ShiftKey(self, event, key): if not event.ShiftDown(): - return false + return False return self.Dispatch(self.SetShiftFuncs, key, event) def NormalChar(self, event, key): diff --git a/wxPython/wxPython/lib/editor/selection.py b/wxPython/wxPython/lib/editor/selection.py index d57982e75b..9a9ed9b2c8 100644 --- a/wxPython/wxPython/lib/editor/selection.py +++ b/wxPython/wxPython/lib/editor/selection.py @@ -1,5 +1,5 @@ -TRUE = 1 -FALSE = 0 +True = 1 +False = 0 def RestOfLine(sx, width, data, bool): if len(data) == 0 and sx == 0: @@ -10,16 +10,16 @@ def RestOfLine(sx, width, data, bool): def Selection(SelectBegin,SelectEnd, sx, width, line, data): if SelectEnd is None or SelectBegin is None: - return RestOfLine(sx, width, data, FALSE) + return RestOfLine(sx, width, data, False) (bRow, bCol) = SelectBegin (eRow, eCol) = SelectEnd if (eRow < bRow): (bRow, bCol) = SelectEnd (eRow, eCol) = SelectBegin if (line < bRow or eRow < line): - return RestOfLine(sx, width, data, FALSE) + return RestOfLine(sx, width, data, False) if (bRow < line and line < eRow): - return RestOfLine(sx, width, data, TRUE) + return RestOfLine(sx, width, data, True) if (bRow == eRow) and (eCol < bCol): (bCol, eCol) = (eCol, bCol) # selection either starts or ends on this line @@ -31,12 +31,12 @@ def Selection(SelectBegin,SelectEnd, sx, width, line, data): pieces = [] if (sx < bCol): if bCol <= end: - pieces += [(data[sx:bCol], FALSE)] + pieces += [(data[sx:bCol], False)] else: - return [(data[sx:end], FALSE)] - pieces += [(data[max(bCol,sx):min(eCol,end)], TRUE)] + return [(data[sx:end], False)] + pieces += [(data[max(bCol,sx):min(eCol,end)], True)] if (eCol < end): - pieces += [(data[eCol:end], FALSE)] + pieces += [(data[eCol:end], False)] return pieces diff --git a/wxPython/wxPython/lib/evtmgr.py b/wxPython/wxPython/lib/evtmgr.py new file mode 100644 index 0000000000..ef6fab004d --- /dev/null +++ b/wxPython/wxPython/lib/evtmgr.py @@ -0,0 +1,519 @@ +#--------------------------------------------------------------------------- +# Name: wxPython.lib.evtmgr +# Purpose: An easier, more "Pythonic" and more OO method of registering +# handlers for wxWindows events using the Publish/Subscribe +# pattern. +# +# Author: Robb Shecter and Robin Dunn +# +# Created: 12-December-2002 +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Robb Shecter <robb@acm.org> +# Licence: wxWindows license +#--------------------------------------------------------------------------- + +""" +A module that allows multiple handlers to respond to single wxWindows +events. This allows true NxN Observer/Observable connections: One +event can be received by multiple handlers, and one handler can +receive multiple events. + +There are two ways to register event handlers. The first way is +similar to standard wxPython handler registration: + + from wxPython.lib.evtmgr import eventManager + eventManager.Register(handleEvents, EVT_BUTTON, win=frame, id=101) + +There's also a new object-oriented way to register for events. This +invocation is equivalent to the one above, but does not require the +programmer to declare or track control ids or parent containers: + + eventManager.Register(handleEvents, EVT_BUTTON, myButton) + +This module is Python 2.1+ compatible. + +Author: Robb Shecter +""" +from wxPython import wx +import pubsub + +#--------------------------------------------------------------------------- + + +class EventManager: + """ + This is the main class in the module, and is the only class that + the application programmer needs to use. There is a pre-created + instance of this class called 'eventManager'. It should not be + necessary to create other instances. + """ + def __init__(self): + self.eventAdapterDict = {} + self.messageAdapterDict = {} + self.windowTopicLookup = {} + self.listenerTopicLookup = {} + self.__publisher = pubsub.Publisher() + self.EMPTY_LIST = [] + + + def Register(self, listener, event, source=None, win=None, id=None): + """ + Registers a listener function (or any callable object) to + receive events of type event coming from the source window. + For example: + + eventManager.Register(self.OnButton, EVT_BUTTON, theButton) + + Alternatively, the specific window where the event is + delivered, and/or the ID of the event source can be specified. + For example: + + eventManager.Register(self.OnButton, EVT_BUTTON, win=self, id=ID_BUTTON) + or + eventManager.Register(self.OnButton, EVT_BUTTON, theButton, self) + """ + + # 1. Check if the 'event' is actually one of the multi- + # event macros. + if _macroInfo.isMultiEvent(event): + raise 'Cannot register the macro, '+`event`+'. Register instead the individual events.' + + # Support a more OO API. This allows the GUI widget itself to + # be specified, and the id to be retrieved from the system, + # instead of kept track of explicitly by the programmer. + # (Being used to doing GUI work with Java, this seems to me to be + # the natural way of doing things.) + if source is not None: + id = source.GetId() + if win is None: + # Some widgets do not function as their own windows. + win = self._determineWindow(source) + topic = (event, win, id) + + # Create an adapter from the PS system back to wxEvents, and + # possibly one from wxEvents: + if not self.__haveMessageAdapter(listener, topic): + messageAdapter = MessageAdapter(eventHandler=listener, topicPattern=topic) + try: + self.messageAdapterDict[topic][listener] = messageAdapter + except KeyError: + self.messageAdapterDict[topic] = {} + self.messageAdapterDict[topic][listener] = messageAdapter + + if not self.eventAdapterDict.has_key(topic): + self.eventAdapterDict[topic] = EventAdapter(event, win, id) + else: + # Throwing away a duplicate request + pass + + # For time efficiency when deregistering by window: + try: + self.windowTopicLookup[win].append(topic) + except KeyError: + self.windowTopicLookup[win] = [] + self.windowTopicLookup[win].append(topic) + + # For time efficiency when deregistering by listener: + try: + self.listenerTopicLookup[listener].append(topic) + except KeyError: + self.listenerTopicLookup[listener] = [] + self.listenerTopicLookup[listener].append(topic) + + # See if the source understands the listeningFor protocol. + # This is a bit of a test I'm working on - it allows classes + # to know when their events are being listened to. I use + # it to enable chaining events from contained windows only + # when needed. + if source is not None: + try: + # Let the source know that we're listening for this + # event. + source.listeningFor(event) + except AttributeError: + pass + + # Some aliases for Register, just for kicks + Bind = Register + Subscribe = Register + + + def DeregisterWindow(self, win): + """ + Deregister all events coming from the given window. + """ + win = self._determineWindow(win) + topics = self.__getTopics(win) + if topics: + for aTopic in topics: + self.__deregisterTopic(aTopic) + del self.windowTopicLookup[win] + + + def DeregisterListener(self, listener): + """ + Deregister all event notifications for the given listener. + """ + try: + topicList = self.listenerTopicLookup[listener] + except KeyError: + return + + for topic in topicList: + topicDict = self.messageAdapterDict[topic] + if topicDict.has_key(listener): + topicDict[listener].Destroy() + del topicDict[listener] + if len(topicDict) == 0: + self.eventAdapterDict[topic].Destroy() + del self.eventAdapterDict[topic] + del self.messageAdapterDict[topic] + del self.listenerTopicLookup[listener] + + + def GetStats(self): + """ + Return a dictionary with data about my state. + """ + stats = {} + stats['Adapters: Message'] = reduce(lambda x,y: x+y, map(len, self.messageAdapterDict.values())) + stats['Adapters: Event'] = len(self.eventAdapterDict) + stats['Topics: Total'] = len(self.__getTopics()) + stats['Topics: Dead'] = len(self.GetDeadTopics()) + return stats + + + def DeregisterDeadTopics(self): + """ + Deregister any entries relating to dead + wxPython objects. Not sure if this is an + important issue; 1) My app code always de-registers + listeners it doesn't need. 2) I don't think + that lingering references to these dead objects + is a problem. + """ + for topic in self.GetDeadTopics(): + self.DeregisterTopic(topic) + + + def GetDeadTopics(self): + """ + Return a list of topics relating to dead wxPython + objects. + """ + return filter(self.__isDeadTopic, self.__getTopics()) + + + def __winString(self, aWin): + """ + A string rep of a window for debugging + """ + try: + name = aWin.GetClassName() + i = id(aWin) + return '%s #%d' % (name, i) + except wx.wxPyDeadObjectError: + return '(dead wxObject)' + + + def __topicString(self, aTopic): + """ + A string rep of a topic for debugging + """ + return '[%-26s %s]' % (aTopic[0].__name__, self.winString(aTopic[1])) + + + def __listenerString(self, aListener): + """ + A string rep of a listener for debugging + """ + try: + return aListener.im_class.__name__ + '.' + aListener.__name__ + except: + return 'Function ' + aListener.__name__ + + + def __deregisterTopic(self, aTopic): + try: + messageAdapterList = self.messageAdapterDict[aTopic].values() + except KeyError: + # This topic isn't valid. Probably because it was deleted + # by listener. + return + for messageAdapter in messageAdapterList: + messageAdapter.Destroy() + self.eventAdapterDict[aTopic].Destroy() + del self.messageAdapterDict[aTopic] + del self.eventAdapterDict[aTopic] + + + def __getTopics(self, win=None): + if win is None: + return self.messageAdapterDict.keys() + if win is not None: + try: + return self.windowTopicLookup[win] + except KeyError: + return self.EMPTY_LIST + + + def __isDeadWxObject(self, anObject): + return isinstance(anObject, wx._wxPyDeadObject) + + + def __isDeadTopic(self, aTopic): + return self.__isDeadWxObject(aTopic[1]) + + + def __haveMessageAdapter(self, eventHandler, topicPattern): + """ + Return True if there's already a message adapter + with these specs. + """ + try: + return self.messageAdapterDict[topicPattern].has_key(eventHandler) + except KeyError: + return 0 + + + def _determineWindow(self, aComponent): + """ + Return the window that corresponds to this component. + A window is something that supports the Connect protocol. + Most things registered with the event manager are a window, + but there are apparently some exceptions. If more are + discovered, the implementation can be changed to a dictionary + lookup along the lines of class : function-to-get-window. + """ + if isinstance(aComponent, wx.wxMenuItem): + return aComponent.GetMenu() + else: + return aComponent + + + +#--------------------------------------------------------------------------- +# From here down is implementaion and support classes, although you may +# find some of them useful in other contexts. +#--------------------------------------------------------------------------- + + +class EventMacroInfo: + """ + A class that provides information about event macros. + """ + def __init__(self): + self.lookupTable = {} + + + def getEventTypes(self, eventMacro): + """ + Return the list of event types that the given + macro corresponds to. + """ + try: + return self.lookupTable[eventMacro] + except KeyError: + win = FakeWindow() + try: + eventMacro(win, None, None) + except TypeError: + eventMacro(win, None) + self.lookupTable[eventMacro] = win.eventTypes + return win.eventTypes + + + def eventIsA(self, event, macroList): + """ + Return True if the event is one of the given + macros. + """ + eventType = event.GetEventType() + for macro in macroList: + if eventType in self.getEventTypes(macro): + return 1 + return 0 + + + def macroIsA(self, macro, macroList): + """ + Return True if the macro is in the macroList. + The added value of this method is that it takes + multi-events into account. The macroList parameter + will be coerced into a sequence if needed. + """ + if callable(macroList): + macroList = (macroList,) + testList = self.getEventTypes(macro) + eventList = [] + for m in macroList: + eventList.extend(self.getEventTypes(m)) + # Return True if every element in testList is in eventList + for element in testList: + if element not in eventList: + return 0 + return 1 + + + def isMultiEvent(self, macro): + """ + Return True if the given macro actually causes + multiple events to be registered. + """ + return len(self.getEventTypes(macro)) > 1 + + +#--------------------------------------------------------------------------- + +class FakeWindow: + """ + Used internally by the EventMacroInfo class. The FakeWindow is + the most important component of the macro-info utility: it + implements the Connect() protocol of wxWindow, but instead of + registering for events, it keeps track of what parameters were + passed to it. + """ + def __init__(self): + self.eventTypes = [] + + def Connect(self, id1, id2, eventType, handlerFunction): + self.eventTypes.append(eventType) + + +#--------------------------------------------------------------------------- + +class EventAdapter: + """ + A class that adapts incoming wxWindows events to + Publish/Subscribe messages. + + In other words, this is the object that's seen by the + wxWindows system. Only one of these registers for any + particular wxWindows event. It then relays it into the + PS system, which lets many listeners respond. + """ + def __init__(self, func, win, id): + """ + Instantiate a new adapter. Pre-compute my Publish/Subscribe + topic, which is constant, and register with wxWindows. + """ + self.publisher = pubsub.Publisher() + self.topic = ((func, win, id),) + self.id = id + self.win = win + self.eventType = _macroInfo.getEventTypes(func)[0] + + # Register myself with the wxWindows event system + try: + func(win, id, self.handleEvent) + self.callStyle = 3 + except TypeError: + func(win, self.handleEvent) + self.callStyle = 2 + + + def disconnect(self): + if self.callStyle == 3: + return self.win.Disconnect(self.id, -1, self.eventType) + else: + return self.win.Disconnect(-1, -1, self.eventType) + + + def handleEvent(self, event): + """ + In response to a wxWindows event, send a PS message + """ + self.publisher.sendMessage(topic=self.topic, data=event) + + + def Destroy(self): + try: + if not self.disconnect(): + print 'disconnect failed' + except wx.wxPyDeadObjectError: + print 'disconnect failed: dead object' ##???? + + +#--------------------------------------------------------------------------- + +class MessageAdapter: + """ + A class that adapts incoming Publish/Subscribe messages + to wxWindows event calls. + + This class works opposite the EventAdapter, and + retrieves the information an EventAdapter has sent in a message. + Strictly speaking, this class is not required: Event listeners + could pull the original wxEvent object out of the PS Message + themselves. + + However, by pairing an instance of this class with each wxEvent + handler, the handlers can use the standard API: they receive an + event as a parameter. + """ + def __init__(self, eventHandler, topicPattern): + """ + Instantiate a new MessageAdapter that send wxEvents to the + given eventHandler. + """ + self.eventHandler = eventHandler + pubsub.Publisher().subscribe(listener=self.deliverEvent, topic=(topicPattern,)) + + def deliverEvent(self, message): + event = message.data # Extract the wxEvent + self.eventHandler(event) # Perform the call as wxWindows would + + def Destroy(self): + pubsub.Publisher().unsubscribe(listener=self.deliverEvent) + + +#--------------------------------------------------------------------------- +# Create globals + +_macroInfo = EventMacroInfo() + +# For now a singleton is not enforced. Should it be or can we trust +# the programmers? +eventManager = EventManager() + + +#--------------------------------------------------------------------------- +# simple test code + + +if __name__ == '__main__': + from wxPython.wx import wxPySimpleApp, wxFrame, wxToggleButton, wxBoxSizer, wxHORIZONTAL, EVT_MOTION, EVT_LEFT_DOWN, EVT_TOGGLEBUTTON, wxALL + app = wxPySimpleApp() + frame = wxFrame(None, -1, 'Event Test', size=(300,300)) + button = wxToggleButton(frame, -1, 'Listen for Mouse Events') + sizer = wxBoxSizer(wxHORIZONTAL) + sizer.Add(button, 0, 0 | wxALL, 10) + frame.SetAutoLayout(1) + frame.SetSizer(sizer) + + # + # Demonstrate 1) register/deregister, 2) Multiple listeners receiving + # one event, and 3) Multiple events going to one listener. + # + + def printEvent(event): + print 'Name:',event.GetClassName(),'Timestamp',event.GetTimestamp() + + def enableFrameEvents(event): + # Turn the output of mouse events on and off + if event.IsChecked(): + print '\nEnabling mouse events...' + eventManager.Register(printEvent, EVT_MOTION, frame) + eventManager.Register(printEvent, EVT_LEFT_DOWN, frame) + else: + print '\nDisabling mouse events...' + eventManager.DeregisterWindow(frame) + + # Send togglebutton events to both the on/off code as well + # as the function that prints to stdout. + eventManager.Register(printEvent, EVT_TOGGLEBUTTON, button) + eventManager.Register(enableFrameEvents, EVT_TOGGLEBUTTON, button) + + frame.CenterOnScreen() + frame.Show(1) + app.MainLoop() diff --git a/wxPython/wxPython/lib/fancytext.py b/wxPython/wxPython/lib/fancytext.py index 566e24627d..0767c986e7 100644 --- a/wxPython/wxPython/lib/fancytext.py +++ b/wxPython/wxPython/lib/fancytext.py @@ -13,7 +13,7 @@ encoding, and color. See the example on the bottom for a better idea of how this works. Note that start and end tags for the string are provided if enclose is -true, so for instance, renderToBitmap("X<sub>1</sub>") will work. +True, so for instance, renderToBitmap("X<sub>1</sub>") will work. """ # Copyright 2001 Timothy Hochberg diff --git a/wxPython/wxPython/lib/filebrowsebutton.py b/wxPython/wxPython/lib/filebrowsebutton.py index 0ddc2818c6..e9481d5daa 100644 --- a/wxPython/wxPython/lib/filebrowsebutton.py +++ b/wxPython/wxPython/lib/filebrowsebutton.py @@ -64,7 +64,7 @@ class FileBrowseButton(wxPanel): self.fileMask = fileMask self.fileMode = fileMode self.changeCallback = changeCallback - self.callCallback = true + self.callCallback = True # get background to match it @@ -99,14 +99,14 @@ class FileBrowseButton(wxPanel): box.Add( self.textControl, 1, wxLEFT|wxCENTER, 5) self.browseButton = self.createBrowseButton() - box.Add( self.browseButton, 0, wxCENTER) + box.Add( self.browseButton, 0, wxLEFT|wxCENTER, 5) # add a border around the whole thing and resize the panel to fit outsidebox = wxBoxSizer(wxVERTICAL) outsidebox.Add(box, 1, wxEXPAND|wxALL, 3) outsidebox.Fit(self) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer( outsidebox ) self.Layout() if type( size ) == types.TupleType: @@ -195,7 +195,7 @@ class FileBrowseButton(wxPanel): def SetLabel( self, value ): """ Set the label's current text """ rvalue = self.label.SetLabel( value ) - self.Refresh( true ) + self.Refresh( True ) return rvalue @@ -404,7 +404,7 @@ if __name__ == "__main__": ID = wxNewId() innerbox.Add( wxButton( panel, ID,"Change Value", ), 1, wxEXPAND) EVT_BUTTON( self, ID, self.OnChangeValue ) - panel.SetAutoLayout(true) + panel.SetAutoLayout(True) panel.SetSizer( innerbox ) self.history={"c:\\temp":1, "c:\\tmp":1, "r:\\temp":1,"z:\\temp":1} @@ -417,7 +417,7 @@ if __name__ == "__main__": self.history[event.GetString ()]=1 def OnCloseMe(self, event): - self.Close(true) + self.Close(True) def OnChangeLabel( self, event ): self.bottomcontrol.SetLabel( "Label Updated" ) def OnChangeValue( self, event ): @@ -433,9 +433,9 @@ if __name__ == "__main__": wxImage_AddHandler(wxGIFHandler()) frame = DemoFrame(NULL) #frame = RulesPanel(NULL ) - frame.Show(true) + frame.Show(True) self.SetTopWindow(frame) - return true + return True def test( ): app = DemoApp(0) diff --git a/wxPython/wxPython/lib/floatbar.py b/wxPython/wxPython/lib/floatbar.py index 05629e892e..19b0231ebb 100644 --- a/wxPython/wxPython/lib/floatbar.py +++ b/wxPython/wxPython/lib/floatbar.py @@ -50,8 +50,8 @@ else: wxToolBar subclass which can be dragged off its frame and later replaced there. Drag on the toolbar to release it, close it like a normal window to make it return to its original - position. Programmatically, call SetFloatable(true) and then - Float(true) to float, Float(false) to dock. + position. Programmatically, call SetFloatable(True) and then + Float(True) to float, Float(False) to dock. """ def __init__(self,*_args,**_kwargs): @@ -175,7 +175,7 @@ else: newpos = self.parentframe.GetPosition() newpos.y = newpos.y + _DOCKTHRESHOLD * 2 self.floatframe.SetPosition(newpos) - self.floatframe.Show(true) + self.floatframe.Show(True) EVT_CLOSE(self.floatframe, self.OnDock) #EVT_MOVE(self.floatframe, self.OnMove) @@ -208,9 +208,9 @@ else: #homepos = homepos[0], homepos[1] + self.titleheight #floatpos = self.floatframe.GetPositionTuple() #if abs(homepos[0] - floatpos[0]) < 35 and abs(homepos[1] - floatpos[1]) < 35: - # self._SetFauxBarVisible(true) + # self._SetFauxBarVisible(True) #else: - # self._SetFauxBarVisible(false) + # self._SetFauxBarVisible(False) def OnMouse(self, e): @@ -240,7 +240,7 @@ else: if e.Dragging(): if not self.IsFloating(): - self.Float(true) + self.Float(True) self.oldpos = (e.GetX(), e.GetY()) else: if hasattr(self, 'oldpos'): diff --git a/wxPython/wxPython/lib/gridmovers.py b/wxPython/wxPython/lib/gridmovers.py new file mode 100644 index 0000000000..3a2c45e909 --- /dev/null +++ b/wxPython/wxPython/lib/gridmovers.py @@ -0,0 +1,419 @@ +#---------------------------------------------------------------------------- +# Name: GridColMover.py +# Purpose: Grid Column Mover Extension +# +# Author: Gerrit van Dyk (email: gerritvd@decillion.net) +# +# Version 0.1 +# Date: Nov 19, 2002 +# RCS-ID: $Id$ +# Licence: wxWindows license +#---------------------------------------------------------------------------- + +from wxPython.wx import * +from wxPython.grid import wxGridPtr + +#---------------------------------------------------------------------------- +# event class and macors + + +wxEVT_COMMAND_GRID_COL_MOVE = wxNewEventType() +wxEVT_COMMAND_GRID_ROW_MOVE = wxNewEventType() + +def EVT_GRID_COL_MOVE(win, id, func): + win.Connect(id, -1, wxEVT_COMMAND_GRID_COL_MOVE, func) + +def EVT_GRID_ROW_MOVE(win,id,func): + win.Connect(id, -1, wxEVT_COMMAND_GRID_ROW_MOVE, func) + + +class wxGridColMoveEvent(wxPyCommandEvent): + def __init__(self, id, dCol, bCol): + wxPyCommandEvent.__init__(self, id = id) + self.SetEventType(wxEVT_COMMAND_GRID_COL_MOVE) + self.moveColumn = dCol + self.beforeColumn = bCol + + def GetMoveColumn(self): + return self.moveColumn + + def GetBeforeColumn(self): + return self.beforeColumn + + +class wxGridRowMoveEvent(wxPyCommandEvent): + def __init__(self, id, dRow, bRow): + wxPyCommandEvent.__init__(self,id = id) + self.SetEventType(wxEVT_COMMAND_GRID_ROW_MOVE) + self.moveRow = dRow + self.beforeRow = bRow + + def GetMoveRow(self): + return self.moveRow + + def GetBeforeRow(self): + return self.beforeRow + + +#---------------------------------------------------------------------------- +# graft new methods into the wxGridPtr class + +def _ColToRect(self,col): + if self.GetNumberRows() > 0: + rect = self.CellToRect(0,col) + else: + rect = wxRect() + rect.height = self.GetColLabelSize() + rect.width = self.GetColSize(col) + for cCol in range(0,col): + rect.x += self.GetColSize(cCol) + rect.y = self.GetGridColLabelWindow().GetPosition()[1] + return rect + +wxGridPtr.ColToRect = _ColToRect + + +def _RowToRect(self,row): + if self.GetNumberCols() > 0: + rect = self.CellToRect(row,0) + else: + rect = wxRect() + rect.width = self.GetRowLabelSize() + rect.height = self.GetRowSize(row) + for cRow in range(0,row): + rect.y += self.GetRowSize(cRow) + rect.x = self.GetGridRowLabelWindow().GetPosition()[0] + return rect + +wxGridPtr.RowToRect = _RowToRect + + +#---------------------------------------------------------------------------- + +class ColDragWindow(wxWindow): + def __init__(self,parent,image,dragCol): + wxWindow.__init__(self,parent,wxSIMPLE_BORDER) + self.image = image + self.SetSize((self.image.GetWidth(),self.image.GetHeight())) + self.ux = parent.GetScrollPixelsPerUnit()[0] + self.moveColumn = dragCol + + EVT_PAINT(self,self.OnPaint) + + def DisplayAt(self,pos,y): + x = self.GetPositionTuple()[0] + if x == pos: + self.Refresh() # Need to display insertion point + else: + self.MoveXY(pos,y) + + def GetMoveColumn(self): + return self.moveColumn + + def _GetInsertionInfo(self): + parent = self.GetParent() + sx = parent.GetViewStart()[0] * self.ux + sx -= parent._rlSize + x = self.GetPositionTuple()[0] + w = self.GetSizeTuple()[0] + sCol = parent.XToCol(x + sx) + eCol = parent.XToCol(x + w + sx) + iPos = xPos = xCol = 99999 + centerPos = x + sx + (w / 2) + for col in range(sCol,eCol + 1): + cx = parent.ColToRect(col)[0] + if abs(cx - centerPos) < iPos: + iPos = abs(cx - centerPos) + xCol = col + xPos = cx + if xCol < 0 or xCol > parent.GetNumberCols(): + xCol = parent.GetNumberCols() + return (xPos - sx - x,xCol) + + def GetInsertionColumn(self): + return self._GetInsertionInfo()[1] + + def GetInsertionPos(self): + return self._GetInsertionInfo()[0] + + def OnPaint(self,evt): + dc = wxPaintDC(self) + w,h = self.GetSize() + dc.DrawBitmap(self.image,0,0) + dc.SetPen(wxPen(wxBLACK,1,wxSOLID)) + dc.SetBrush(wxTRANSPARENT_BRUSH) + dc.DrawRectangle(0,0,w,h) + iPos = self.GetInsertionPos() + dc.DrawLine(iPos,h - 10,iPos,h) + + + + +class RowDragWindow(wxWindow): + def __init__(self,parent,image,dragRow): + wxWindow.__init__(self,parent,wxSIMPLE_BORDER) + self.image = image + self.SetSize((self.image.GetWidth(),self.image.GetHeight())) + self.uy = parent.GetScrollPixelsPerUnit()[1] + self.moveRow = dragRow + + EVT_PAINT(self,self.OnPaint) + + def DisplayAt(self,x,pos): + y = self.GetPositionTuple()[1] + if y == pos: + self.Refresh() # Need to display insertion point + else: + self.MoveXY(x,pos) + + def GetMoveRow(self): + return self.moveRow + + def _GetInsertionInfo(self): + parent = self.GetParent() + sy = parent.GetViewStart()[1] * self.uy + sy -= parent._clSize + y = self.GetPositionTuple()[1] + h = self.GetSizeTuple()[1] + sRow = parent.YToRow(y + sy) + eRow = parent.YToRow(y + h + sy) + iPos = yPos = yRow = 99999 + centerPos = y + sy + (h / 2) + for row in range(sRow,eRow + 1): + cy = parent.RowToRect(row)[1] + if abs(cy - centerPos) < iPos: + iPos = abs(cy - centerPos) + yRow = row + yPos = cy + if yRow < 0 or yRow > parent.GetNumberRows(): + yRow = parent.GetNumberRows() + return (yPos - sy - y,yRow) + + def GetInsertionRow(self): + return self._GetInsertionInfo()[1] + + def GetInsertionPos(self): + return self._GetInsertionInfo()[0] + + def OnPaint(self,evt): + dc = wxPaintDC(self) + w,h = self.GetSize() + dc.DrawBitmap(self.image,0,0) + dc.SetPen(wxPen(wxBLACK,1,wxSOLID)) + dc.SetBrush(wxTRANSPARENT_BRUSH) + dc.DrawRectangle(0,0,w,h) + iPos = self.GetInsertionPos() + dc.DrawLine(w - 10,iPos,w,iPos) + +#---------------------------------------------------------------------------- + +class wxGridColMover(wxEvtHandler): + def __init__(self,grid): + wxEvtHandler.__init__(self) + + self.grid = grid + self.grid._rlSize = self.grid.GetRowLabelSize() + self.lwin = grid.GetGridColLabelWindow() + self.lwin.PushEventHandler(self) + self.colWin = None + self.ux = self.grid.GetScrollPixelsPerUnit()[0] + self.startX = -10 + self.cellX = 0 + self.didMove = False + self.isDragging = False + + EVT_MOTION(self,self.OnMouseMove) + EVT_LEFT_DOWN(self,self.OnPress) + EVT_LEFT_UP(self,self.OnRelease) + + def OnMouseMove(self,evt): + if self.isDragging: + if abs(self.startX - evt.m_x) >= 3: + self.didMove = True + sx,y = self.grid.GetViewStart() + w,h = self.lwin.GetClientSizeTuple() + x = sx * self.ux + if (evt.m_x + x) < x: + x = evt.m_x + x + elif evt.m_x > w: + x += evt.m_x - w + if x < 1: x = 0 + else: x /= self.ux + if x != sx: + if wxPlatform == '__WXMSW__': + self.colWin.Show(False) + self.grid.Scroll(x,y) + x,y = self.lwin.ClientToScreenXY(evt.m_x,0) + x,y = self.grid.ScreenToClientXY(x,y) + if not self.colWin.IsShown(): + self.colWin.Show(True) + px = x - self.cellX + if px < 0 + self.grid._rlSize: px = 0 + self.grid._rlSize + if px > w - self.colWin.GetSizeTuple()[0] + self.grid._rlSize: + px = w - self.colWin.GetSizeTuple()[0] + self.grid._rlSize + self.colWin.DisplayAt(px,y) + return + evt.Skip() + + def OnPress(self,evt): + self.startX = evt.m_x + sx = self.grid.GetViewStart()[0] * self.ux + sx -= self.grid._rlSize + px,py = self.lwin.ClientToScreenXY(evt.m_x,evt.m_y) + px,py = self.grid.ScreenToClientXY(px,py) + if self.grid.XToEdgeOfCol(px + sx) != wxNOT_FOUND: + evt.Skip() + return + + self.isDragging = True + self.didMove = False + col = self.grid.XToCol(px + sx) + rect = self.grid.ColToRect(col) + self.cellX = px + sx - rect.x + size = self.lwin.GetSizeTuple() + rect.y = 0 + rect.x -= sx + self.grid._rlSize + rect.height = size[1] + colImg = self._CaptureImage(rect) + self.colWin = ColDragWindow(self.grid,colImg,col) + self.colWin.Show(False) + self.lwin.CaptureMouse() + + def OnRelease(self,evt): + if self.isDragging: + self.lwin.ReleaseMouse() + self.colWin.Show(False) + self.isDragging = False + if not self.didMove: + px = self.lwin.ClientToScreenXY(self.startX,0)[0] + px = self.grid.ScreenToClientXY(px,0)[0] + sx = self.grid.GetViewStart()[0] * self.ux + sx -= self.grid._rlSize + col = self.grid.XToCol(px+sx) + if col != wxNOT_FOUND: + self.grid.SelectCol(col,evt.m_controlDown) + return + else: + bCol = self.colWin.GetInsertionColumn() + dCol = self.colWin.GetMoveColumn() + wxPostEvent(self,wxGridColMoveEvent(self.grid.GetId(), + dCol,bCol)) + self.colWin.Destroy() + evt.Skip() + + def _CaptureImage(self,rect): + bmp = wxEmptyBitmap(rect.width,rect.height) + memdc = wxMemoryDC() + memdc.SelectObject(bmp) + dc = wxWindowDC(self.lwin) + memdc.Blit(0,0,rect.width,rect.height,dc,rect.x,rect.y) + memdc.SelectObject(wxNullBitmap) + return bmp + + + +class wxGridRowMover(wxEvtHandler): + def __init__(self,grid): + wxEvtHandler.__init__(self) + + self.grid = grid + self.grid._clSize = self.grid.GetColLabelSize() + self.lwin = grid.GetGridRowLabelWindow() + self.lwin.PushEventHandler(self) + self.rowWin = None + self.uy = self.grid.GetScrollPixelsPerUnit()[1] + self.startY = -10 + self.cellY = 0 + self.didMove = False + self.isDragging = False + + EVT_MOTION(self,self.OnMouseMove) + EVT_LEFT_DOWN(self,self.OnPress) + EVT_LEFT_UP(self,self.OnRelease) + + def OnMouseMove(self,evt): + if self.isDragging: + if abs(self.startY - evt.m_y) >= 3: + self.didMove = True + x,sy = self.grid.GetViewStart() + w,h = self.lwin.GetClientSizeTuple() + y = sy * self.uy + if (evt.m_y + y) < y: + y = evt.m_y + y + elif evt.m_y > h: + y += evt.m_y - h + if y < 1: y = 0 + else: y /= self.uy + if y != sy: + if wxPlatform == '__WXMSW__': + self.rowWin.Show(False) + self.grid.Scroll(x,y) + x,y = self.lwin.ClientToScreenXY(0,evt.m_y) + x,y = self.grid.ScreenToClientXY(x,y) + if not self.rowWin.IsShown(): + self.rowWin.Show(True) + py = y - self.cellY + if py < 0 + self.grid._clSize: py = 0 + self.grid._clSize + if py > h - self.rowWin.GetSizeTuple()[1] + self.grid._clSize: + py = h - self.rowWin.GetSizeTuple()[1] + self.grid._clSize + self.rowWin.DisplayAt(x,py) + return + evt.Skip() + + def OnPress(self,evt): + self.startY = evt.m_y + sy = self.grid.GetViewStart()[1] * self.uy + sy -= self.grid._clSize + px,py = self.lwin.ClientToScreenXY(evt.m_x,evt.m_y) + px,py = self.grid.ScreenToClientXY(px,py) + if self.grid.YToEdgeOfRow(py + sy) != wxNOT_FOUND: + evt.Skip() + return + + self.isDragging = True + self.didMove = False + row = self.grid.YToRow(py + sy) + rect = self.grid.RowToRect(row) + self.cellY = py + sy - rect.y + size = self.lwin.GetSizeTuple() + rect.x = 0 + rect.y -= sy + self.grid._clSize + rect.width = size[0] + rowImg = self._CaptureImage(rect) + self.rowWin = RowDragWindow(self.grid,rowImg,row) + self.rowWin.Show(False) + self.lwin.CaptureMouse() + + def OnRelease(self,evt): + if self.isDragging: + self.lwin.ReleaseMouse() + self.rowWin.Show(False) + self.isDragging = False + if not self.didMove: + py = self.lwin.ClientToScreenXY(0,self.startY)[1] + py = self.grid.ScreenToClientXY(0,py)[1] + sy = self.grid.GetViewStart()[1] * self.uy + sy -= self.grid._clSize + row = self.grid.YToRow(py + sy) + if row != wxNOT_FOUND: + self.grid.SelectRow(row,evt.m_controlDown) + return + else: + bRow = self.rowWin.GetInsertionRow() + dRow = self.rowWin.GetMoveRow() + wxPostEvent(self,wxGridRowMoveEvent(self.grid.GetId(), + dRow,bRow)) + self.rowWin.Destroy() + evt.Skip() + + def _CaptureImage(self,rect): + bmp = wxEmptyBitmap(rect.width,rect.height) + memdc = wxMemoryDC() + memdc.SelectObject(bmp) + dc = wxWindowDC(self.lwin) + memdc.Blit(0,0,rect.width,rect.height,dc,rect.x,rect.y) + memdc.SelectObject(wxNullBitmap) + return bmp + + +#---------------------------------------------------------------------------- diff --git a/wxPython/wxPython/lib/grids.py b/wxPython/wxPython/lib/grids.py index 9d517db3b0..5425d1adf4 100644 --- a/wxPython/wxPython/lib/grids.py +++ b/wxPython/wxPython/lib/grids.py @@ -126,8 +126,8 @@ class wxGridSizer(wxPySizer): sz = self.GetSize() pt = self.GetPosition() - w = (sz.width - (ncols - 1) * self.hgap) / ncols; - h = (sz.height - (nrows - 1) * self.vgap) / nrows; + w = (sz.width - (ncols - 1) * self.hgap) / ncols; + h = (sz.height - (nrows - 1) * self.vgap) / nrows; x = pt.x for c in range(ncols): diff --git a/wxPython/wxPython/lib/imagebrowser.py b/wxPython/wxPython/lib/imagebrowser.py index b47ef31484..6496bb1a13 100644 --- a/wxPython/wxPython/lib/imagebrowser.py +++ b/wxPython/wxPython/lib/imagebrowser.py @@ -14,10 +14,10 @@ # View "All Image" File Types as default filter # Sort the file list # Use newer "re" function for patterns - + #--------------------------------------------------------------------------- -import os, sys, string +import os, sys from wxPython.wx import * dir_path = os.getcwd() @@ -29,8 +29,8 @@ def ConvertBMP(file_nm): fl_fld = os.path.splitext(file_nm) ext = fl_fld[1] - ext = string.lower(ext[1:]) - if ext == 'bmp': + ext = ext[1:].lower() + if ext == 'bmp': image = wxImage(file_nm, wxBITMAP_TYPE_BMP) elif ext == 'gif': image = wxImage(file_nm, wxBITMAP_TYPE_GIF) @@ -93,31 +93,31 @@ class ImageView(wxWindow): def DrawImage(self, dc): try: - image = self.image + image = self.image except: return self.DrawBorder(dc) if image is None: return - + bmp = image.ConvertToBitmap() - + iwidth = bmp.GetWidth() # dimensions of image file iheight = bmp.GetHeight() - + diffx = (self.image_sizex - iwidth)/2 # center calc if iwidth >= self.image_sizex -10: # if image width fits in window adjust diffx = 5 iwidth = self.image_sizex - 10 - + diffy = (self.image_sizey - iheight)/2 # center calc if iheight >= self.image_sizey - 10: # if image height fits in window adjust diffy = 5 iheight = self.image_sizey - 10 image.Rescale(iwidth, iheight) # rescale to fit the window - image.ConvertToBitmap() + image.ConvertToBitmap() bmp = image.ConvertToBitmap() dc.DrawBitmap(bmp, diffx, diffy) # draw the image to window @@ -125,40 +125,40 @@ class ImageView(wxWindow): class ImageDialog(wxDialog): def __init__(self, parent, set_dir = None): wxDialog.__init__(self, parent, -1, "Image Browser", wxPyDefaultPosition, wxSize(400, 400)) - + self.x_pos = 30 # initial display positions self.y_pos = 20 - self.delta = 20 + self.delta = 20 size = wxSize(80, 25) - + self.set_dir = os.getcwd() - + if set_dir != None: if os.path.exists(set_dir): # set to working directory if nothing set self.set_dir = set_dir - + self.dir_x = self.x_pos self.dir_y = self.y_pos self.DisplayDir() # display the directory value - + self.y_pos = self.y_pos + self.delta - mID = NewId() + mID = wxNewId() wxButton(self, mID, ' Set Directory ', wxPoint(self.x_pos, self.y_pos), size).SetDefault() EVT_BUTTON(self, mID, self.SetDirect) - self.type_posy = self.y_pos # save the y position for the image type combo + self.type_posy = self.y_pos # save the y position for the image type combo self.fl_ext = '*.bmp' # initial setting for file filtering self.GetFiles() # get the file list - + self.y_pos = self.y_pos + self.delta + 10 self.list_height = 150 - + # List of Labels - mID = NewId() + mID = wxNewId() self.tb = tb = wxListBox(self, mID, wxPoint(self.x_pos, self.y_pos), wxSize(160, self.list_height), self.fl_list, wxLB_SINGLE) EVT_LISTBOX(self, mID, self.OnListClick) EVT_LISTBOX_DCLICK(self, mID, self.OnListDClick) @@ -170,13 +170,13 @@ class ImageDialog(wxDialog): image_sizey = self.list_height self.fl_types = ["All Images", "Bmp", "Gif", "Png", "Jpg", "Ico", "Pnm", "Pcx", "Tif", "All Files"] - self.fl_ext_types = { "All Images": "All", "Bmp": "*.bmp", "Gif": "*.gif", "Png": "*.png", "Jpg": "*.jpg", + self.fl_ext_types = { "All Images": "All", "Bmp": "*.bmp", "Gif": "*.gif", "Png": "*.png", "Jpg": "*.jpg", "Ico": "*.ico", "Pnm": "*.pnm", "Pcx": "*.pcx", "Tif": "*.tif", "All Files": "*.*" } - + self.set_type = self.fl_types[0] # initial file filter setting self.fl_ext = self.fl_ext_types[self.set_type] - - mID = NewId() + + mID = wxNewId() self.sel_type = wxComboBox(self, mID, self.set_type, wxPoint(image_posx , self.type_posy), wxSize(150, -1), self.fl_types, wxCB_DROPDOWN) EVT_COMBOBOX(self, mID, self.OnSetType) @@ -184,7 +184,7 @@ class ImageDialog(wxDialog): self.y_pos = self.y_pos + height + 20 - mID = NewId() + mID = wxNewId() wxButton(self, mID, ' Select ', wxPoint(100, self.y_pos), size).SetDefault() EVT_BUTTON(self, mID, self.OnOk) @@ -193,7 +193,7 @@ class ImageDialog(wxDialog): self.y_pos = self.y_pos + self.delta fsize = wxSize(400, self.y_pos + 50) # resize dialog for final vertical position self.SetSize(fsize) - + self.ResetFiles() def GetFiles(self): # get the file list using directory and extension values @@ -204,7 +204,7 @@ class ImageDialog(wxDialog): self.fl_val = FindFiles(self, self.set_dir, filter) all_files = all_files + self.fl_val.files # add to list of files self.fl_list = all_files - else: + else: self.fl_val = FindFiles(self, self.set_dir, self.fl_ext) self.fl_list = self.fl_val.files @@ -212,19 +212,19 @@ class ImageDialog(wxDialog): def DisplayDir(self): # display the working directory wxStaticText(self, -1, self.set_dir, wxPoint(self.dir_x, self.dir_y), wxSize(250, -1)) - + def OnSetType(self, event): val = event.GetString() # get file type value self.fl_ext = self.fl_ext_types[val] - self.ResetFiles() - + self.ResetFiles() + def OnListDClick(self, event): self.OnOk(0) - + def OnListClick(self, event): val = event.GetSelection() self.SetListValue(val) - + def SetListValue(self, val): file_nm = self.fl_list[val] self.set_file = file_val = os.path.join(self.set_dir, file_nm) @@ -237,7 +237,7 @@ class ImageDialog(wxDialog): self.set_dir = dlg.GetPath() self.ResetFiles() dlg.Destroy() - + def ResetFiles(self): # refresh the display with files and initial image self.DisplayDir() self.GetFiles() @@ -247,13 +247,13 @@ class ImageDialog(wxDialog): self.SetListValue(0) except: self.image_view.SetValue(None) - + def GetFile(self): return self.set_file def GetDirectory(self): return self.set_dir - + def OnCancel(self, event): self.result = None self.EndModal(wxID_CANCEL) @@ -278,23 +278,23 @@ class FindFiles: dirlist = [".."] self.dir = dir self.file = "" - mask = string.upper(mask) + mask = mask.upper() pattern = self.MakeRegex(mask) for i in os.listdir(dir): if i == "." or i == "..": - continue + continue path = os.path.join(dir, i) - path = string.upper(path) - value = string.upper(i) + path = path.upper() + value = i.upper() if pattern.match(value) != None: filelist.append(i) - self.files = filelist + self.files = filelist def MakeRegex(self, pattern): import re - f = "" # Set up a regex for file names + f = "" # Set up a regex for file names for ch in pattern: if ch == "*": f = f + ".*" diff --git a/wxPython/wxPython/lib/imageutils.py b/wxPython/wxPython/lib/imageutils.py new file mode 100644 index 0000000000..7636508194 --- /dev/null +++ b/wxPython/wxPython/lib/imageutils.py @@ -0,0 +1,45 @@ +#---------------------------------------------------------------------- +# Name: wxPython.lib.imageutils +# Purpose: A collection of functions for simple image manipulations +# +# Author: Robb Shecter +# +# Created: 7-Nov-2002 +# RCS-ID: $Id$ +# Copyright: (c) 2002 by +# Licence: wxWindows license +#---------------------------------------------------------------------- + +from __future__ import nested_scopes + + +def grayOut(anImage): + """ + Convert the given image (in place) to a grayed-out + version, appropriate for a 'disabled' appearance. + """ + factor = 0.7 # 0 < f < 1. Higher is grayer. + if anImage.HasMask(): + maskColor = (anImage.GetMaskRed(), anImage.GetMaskGreen(), anImage.GetMaskBlue()) + else: + maskColor = None + data = map(ord, list(anImage.GetData())) + + for i in range(0, len(data), 3): + pixel = (data[i], data[i+1], data[i+2]) + pixel = makeGray(pixel, factor, maskColor) + for x in range(3): + data[i+x] = pixel[x] + anImage.SetData(''.join(map(chr, data))) + + +def makeGray((r,g,b), factor, maskColor): + """ + Make a pixel grayed-out. If the pixel + matches the maskColor, it won't be + changed. + """ + if (r,g,b) != maskColor: + return map(lambda x: ((230 - x) * factor) + x, (r,g,b)) + else: + return (r,g,b) diff --git a/wxPython/wxPython/lib/infoframe.py b/wxPython/wxPython/lib/infoframe.py index dd898c57a0..f98b7fc5a4 100644 --- a/wxPython/wxPython/lib/infoframe.py +++ b/wxPython/wxPython/lib/infoframe.py @@ -121,7 +121,7 @@ see the appropriate "stub" file in the wxPython demo. """ from wxPython.wx import * -import string, sys, types, tempfile, os +import sys, tempfile, os class _MyStatusBar(wxStatusBar): def __init__(self, parent,callbacks=None,useopenbutton=0): @@ -187,7 +187,7 @@ class _MyStatusBar(wxStatusBar): self.button2.SetLabel ("Open New File") self.useopenbutton = 1 - self.useopenbutton self.OnSize("") - self.button2.Refresh(TRUE) + self.button2.Refresh(True) self.Refresh() @@ -269,7 +269,7 @@ class wxPyInformationalMessagesFrame: useopenbutton=hasattr(self, "nofile")) self.frame.SetStatusBar(self.frame.sb) - self.frame.Show(true) + self.frame.Show(True) EVT_CLOSE(self.frame, self.OnCloseWindow) if hasattr(self,"nofile"): @@ -341,7 +341,7 @@ class wxPyInformationalMessagesFrame: if m is not None:# and m.__dict__.has_key("__debug__"): m.__dict__["__debug__"] = 0 - if self.frame is not None: # typically true, but, e.g., allows + if self.frame is not None: # typically True, but, e.g., allows # DisableOutput method (which calls this # one) to be called when the frame is not # actually open, so that it is always safe diff --git a/wxPython/wxPython/lib/intctrl.py b/wxPython/wxPython/lib/intctrl.py new file mode 100644 index 0000000000..cf17abdaa4 --- /dev/null +++ b/wxPython/wxPython/lib/intctrl.py @@ -0,0 +1,866 @@ +#---------------------------------------------------------------------------- +# Name: wxPython.lib.intctrl.py +# Author: Will Sadkin +# Created: 01/16/2003 +# Copyright: (c) 2003 by Will Sadkin +# RCS-ID: $Id$ +# License: wxWindows license +#---------------------------------------------------------------------------- +# NOTE: +# This was written to provide a standard integer edit control for wxPython. +# +# wxIntCtrl permits integer (long) values to be retrieved or set via +# .GetValue() and .SetValue(), and provides an EVT_INT() event function +# for trapping changes to the control. +# +# It supports negative integers as well as the naturals, and does not +# permit leading zeros or an empty control; attempting to delete the +# contents of the control will result in a (selected) value of zero, +# thus preserving a legitimate integer value, or an empty control +# (if a value of None is allowed for the control.) Similarly, replacing the +# contents of the control with '-' will result in a selected (absolute) +# value of -1. +# +# wxIntCtrl also supports range limits, with the option of either +# enforcing them or simply coloring the text of the control if the limits +# are exceeded. + +from wxPython.wx import * +import types, string +from sys import maxint +MAXINT = maxint # (constants should be in upper case) +MININT = -maxint-1 + +#---------------------------------------------------------------------------- + +wxEVT_COMMAND_INT_UPDATED = wxNewEventType() + +# wxWindows' wxTextCtrl translates Composite "control key" +# events into single events before returning them to its OnChar +# routine. The doc says that this results in 1 for Ctrl-A, 2 for +# Ctrl-B, etc. However, there are no wxPython or wxWindows +# symbols for them, so I'm defining codes for Ctrl-X (cut) and +# Ctrl-V (paste) here for readability: +WXK_CTRL_X = (ord('X')+1) - ord('A') +WXK_CTRL_V = (ord('V')+1) - ord('A') + + +def EVT_INT(win, id, func): + """Used to trap events indicating that the current + integer value of the control has been changed.""" + win.Connect(id, -1, wxEVT_COMMAND_INT_UPDATED, func) + + +class wxIntUpdatedEvent(wxPyCommandEvent): + def __init__(self, id, value = 0, object=None): + wxPyCommandEvent.__init__(self, wxEVT_COMMAND_INT_UPDATED, id) + + self.__value = value + self.SetEventObject(object) + + def GetValue(self): + """Retrieve the value of the control at the time + this event was generated.""" + return self.__value + + +#---------------------------------------------------------------------------- + +class wxIntValidator( wxPyValidator ): + """ + Validator class used with wxIntCtrl; handles all validation of input + prior to changing the value of the underlying wxTextCtrl. + """ + def __init__(self): + wxPyValidator.__init__(self) + EVT_CHAR(self, self.OnChar) + + def Clone (self): + return self.__class__() + + def Validate(self, window): # window here is the *parent* of the ctrl + """ + Because each operation on the control is vetted as it's made, + the value of the control is always valid. + """ + return 1 + + + def OnChar(self, event): + """ + Validates keystrokes to make sure the resulting value will a legal + value. Erasing the value causes it to be set to 0, with the value + selected, so it can be replaced. Similarly, replacing the value + with a '-' sign causes the value to become -1, with the value + selected. Leading zeros are removed if introduced by selection, + and are prevented from being inserted. + """ + key = event.KeyCode() + ctrl = event.GetEventObject() + + + value = ctrl.GetValue() + textval = wxTextCtrl.GetValue(ctrl) + allow_none = ctrl.IsNoneAllowed() + + pos = ctrl.GetInsertionPoint() + sel_start, sel_to = ctrl.GetSelection() + select_len = sel_to - sel_start + +# (Uncomment for debugging:) +## print 'keycode:', key +## print 'pos:', pos +## print 'sel_start, sel_to:', sel_start, sel_to +## print 'select_len:', select_len +## print 'textval:', textval + + # set defaults for processing: + allow_event = 1 + set_to_none = 0 + set_to_zero = 0 + set_to_minus_one = 0 + paste = 0 + internally_set = 0 + + new_value = value + new_text = textval + new_pos = pos + + # Validate action, and predict resulting value, so we can + # range check the result and validate that too. + + if key in (WXK_DELETE, WXK_BACK, WXK_CTRL_X): + if select_len: + new_text = textval[:sel_start] + textval[sel_to:] + elif key == WXK_DELETE and pos < len(textval): + new_text = textval[:pos] + textval[pos+1:] + elif key == WXK_BACK and pos > 0: + new_text = textval[:pos-1] + textval[pos:] + # (else value shouldn't change) + + if new_text in ('', '-'): + # Deletion of last significant digit: + if allow_none and new_text == '': + new_value = None + set_to_none = 1 + else: + new_value = 0 + set_to_zero = 1 + else: + try: + new_value = ctrl._fromGUI(new_text) + except ValueError: + allow_event = 0 + + + elif key == WXK_CTRL_V: # (see comments at top of file) + # Only allow paste if number: + paste_text = ctrl._getClipboardContents() + new_text = textval[:sel_start] + paste_text + textval[sel_to:] + if new_text == '' and allow_none: + new_value = None + set_to_none = 1 + else: + try: + # Convert the resulting strings, verifying they + # are legal integers and will fit in proper + # size if ctrl limited to int. (if not, + # disallow event.) + new_value = ctrl._fromGUI(new_text) + if paste_text: + paste_value = ctrl._fromGUI(paste_text) + else: + paste_value = 0 + new_pos = sel_start + len(str(paste_value)) + + # if resulting value is 0, truncate and highlight value: + if new_value == 0 and len(new_text) > 1: + set_to_zero = 1 + + elif paste_value == 0: + # Disallow pasting a leading zero with nothing selected: + if( select_len == 0 + and value is not None + and ( (value >= 0 and pos == 0) + or (value < 0 and pos in [0,1]) ) ): + allow_event = 0 + paste = 1 + + except ValueError: + allow_event = 0 + + + elif key < WXK_SPACE or key > 255: + pass # event ok + + + elif chr(key) == '-': + # Allow '-' to result in -1 if replacing entire contents: + if( value is None + or (value == 0 and pos == 0) + or (select_len >= len(str(abs(value)))) ): + new_value = -1 + set_to_minus_one = 1 + + # else allow negative sign only at start, and only if + # number isn't already zero or negative: + elif pos != 0 or (value is not None and value < 0): + allow_event = 0 + else: + new_text = '-' + textval + new_pos = 1 + try: + new_value = ctrl._fromGUI(new_text) + except ValueError: + allow_event = 0 + + + elif chr(key) in string.digits: + # disallow inserting a leading zero with nothing selected + if( chr(key) == '0' + and select_len == 0 + and value is not None + and ( (value >= 0 and pos == 0) + or (value < 0 and pos in [0,1]) ) ): + allow_event = 0 + # disallow inserting digits before the minus sign: + elif value is not None and value < 0 and pos == 0: + allow_event = 0 + else: + new_text = textval[:sel_start] + chr(key) + textval[sel_to:] + try: + new_value = ctrl._fromGUI(new_text) + except ValueError: + allow_event = 0 + + else: + # not a legal char + allow_event = 0 + + + if allow_event: + # Do range checking for new candidate value: + if ctrl.IsLimited() and not ctrl.IsInBounds(new_value): + allow_event = 0 + elif new_value is not None: + # ensure resulting text doesn't result in a leading 0: + if not set_to_zero and not set_to_minus_one: + if( (new_value > 0 and new_text[0] == '0') + or (new_value < 0 and new_text[1] == '0') + or (new_value == 0 and select_len > 1 ) ): + + # Allow replacement of leading chars with + # zero, but remove the leading zero, effectively + # making this like "remove leading digits" + + # Account for leading zero when positioning cursor: + if( key == WXK_BACK + or (paste and paste_value == 0 and new_pos > 0) ): + new_pos = new_pos - 1 + + wxCallAfter(ctrl.SetValue, new_value) + wxCallAfter(ctrl.SetInsertionPoint, new_pos) + internally_set = 1 + + elif paste: + # Always do paste numerically, to remove + # leading/trailing spaces + wxCallAfter(ctrl.SetValue, new_value) + wxCallAfter(ctrl.SetInsertionPoint, new_pos) + internally_set = 1 + + elif (new_value == 0 and len(new_text) > 1 ): + allow_event = 0 + + if allow_event: + ctrl._colorValue(new_value) # (one way or t'other) + +# (Uncomment for debugging:) +## if allow_event: +## print 'new value:', new_value +## if paste: print 'paste' +## if set_to_none: print 'set_to_none' +## if set_to_zero: print 'set_to_zero' +## if set_to_minus_one: print 'set_to_minus_one' +## if internally_set: print 'internally_set' +## else: +## print 'new text:', new_text +## print 'disallowed' +## print + + if allow_event: + if set_to_none: + wxCallAfter(ctrl.SetValue, new_value) + + elif set_to_zero: + # select to "empty" numeric value + wxCallAfter(ctrl.SetValue, new_value) + wxCallAfter(ctrl.SetInsertionPoint, 0) + wxCallAfter(ctrl.SetSelection, 0, 1) + + elif set_to_minus_one: + wxCallAfter(ctrl.SetValue, new_value) + wxCallAfter(ctrl.SetInsertionPoint, 1) + wxCallAfter(ctrl.SetSelection, 1, 2) + + elif not internally_set: + event.Skip() # allow base wxTextCtrl to finish processing + + elif not wxValidator_IsSilent(): + wxBell() + + + def TransferToWindow(self): + """ Transfer data from validator to window. + + The default implementation returns False, indicating that an error + occurred. We simply return True, as we don't do any data transfer. + """ + return True # Prevent wxDialog from complaining. + + + def TransferFromWindow(self): + """ Transfer data from window to validator. + + The default implementation returns False, indicating that an error + occurred. We simply return True, as we don't do any data transfer. + """ + return True # Prevent wxDialog from complaining. + + +#---------------------------------------------------------------------------- + +class wxIntCtrl(wxTextCtrl): + """ + This class provides a control that takes and returns integers as + value, and provides bounds support and optional value limiting. + + wxIntCtrl( + parent, id = -1, + value = 0, + min = None, + max = None, + limited = False, + allow_none = False, + allow_long = False, + default_color = wxBLACK, + oob_color = wxRED, + pos = wxDefaultPosition, + size = wxDefaultSize, + style = 0, + name = "integer") + + value + If no initial value is set, the default will be zero, or + the minimum value, if specified. If an illegal string is specified, + a ValueError will result. (You can always later set the initial + value with SetValue() after instantiation of the control.) + min + The minimum value that the control should allow. This can be + adjusted with SetMin(). If the control is not limited, any value + below this bound will be colored with the current out-of-bounds color. + If min < -sys.maxint-1 and the control is configured to not allow long + values, the minimum bound will still be set to the long value, but + the implicit bound will be -sys.maxint-1. + max + The maximum value that the control should allow. This can be + adjusted with SetMax(). If the control is not limited, any value + above this bound will be colored with the current out-of-bounds color. + if max > sys.maxint and the control is configured to not allow long + values, the maximum bound will still be set to the long value, but + the implicit bound will be sys.maxint. + + limited + Boolean indicating whether the control prevents values from + exceeding the currently set minimum and maximum values (bounds). + If False and bounds are set, out-of-bounds values will + be colored with the current out-of-bounds color. + + allow_none + Boolean indicating whether or not the control is allowed to be + empty, representing a value of None for the control. + + allow_long + Boolean indicating whether or not the control is allowed to hold + and return a long as well as an int. + + default_color + Color value used for in-bounds values of the control. + + oob_color + Color value used for out-of-bounds values of the control + when the bounds are set but the control is not limited. + """ + def __init__ ( + self, parent, id=-1, + value = 0, min=None, max=None, + limited = 0, allow_none = 0, allow_long = 0, + default_color = wxBLACK, oob_color = wxRED, + pos = wxDefaultPosition, size = wxDefaultSize, + style = 0, name = "integer", + ): + + # Establish attrs required for any operation on value: + self.__min = None + self.__max = None + self.__limited = 0 + self.__default_color = wxBLACK + self.__oob_color = wxRED + self.__allow_none = 0 + self.__allow_long = 0 + + wxTextCtrl.__init__( + self, parent, id, self._toGUI(0), + pos, size, style, wxIntValidator(), name ) + + # The following lets us set out our "integer update" events: + EVT_TEXT( self, self.GetId(), self.OnText ) + + # Establish parameters, with appropriate error checking + + self.SetBounds(min, max) + self.SetLimited(limited) + self.SetColors(default_color, oob_color) + self.SetNoneAllowed(allow_none) + self.SetLongAllowed(allow_long) + self.SetValue(value) + + + def OnText( self, event ): + """ + Handles an event indicating that the text control's value + has changed, and issue EVT_INT event. + """ + try: + self.GetEventHandler().ProcessEvent( + wxIntUpdatedEvent( self.GetId(), self.GetValue(), self ) ) + except ValueError: + return + # let normal processing of the text continue + event.Skip() + + + def GetValue(self): + """ + Returns the current integer (long) value of the control. + """ + return self._fromGUI( wxTextCtrl.GetValue(self) ) + + def SetValue(self, value): + """ + Sets the value of the control to the integer value specified. + The resulting actual value of the control may be altered to + conform with the bounds set on the control if limited, + or colored if not limited but the value is out-of-bounds. + A ValueError exception will be raised if an invalid value + is specified. + """ + wxTextCtrl.SetValue( self, self._toGUI(value) ) + self._colorValue() + + + def SetMin(self, min=None): + """ + Sets the minimum value of the control. If a value of None + is provided, then the control will have no explicit minimum value. + If the value specified is greater than the current maximum value, + then the function returns 0 and the minimum will not change from + its current setting. On success, the function returns 1. + + If successful and the current value is lower than the new lower + bound, if the control is limited, the value will be automatically + adjusted to the new minimum value; if not limited, the value in the + control will be colored with the current out-of-bounds color. + + If min > -sys.maxint-1 and the control is configured to not allow longs, + the function will return 0, and the min will not be set. + """ + if( self.__max is None + or min is None + or (self.__max is not None and self.__max >= min) ): + self.__min = min + + if self.IsLimited() and min is not None and self.GetValue() < min: + self.SetValue(min) + else: + self._colorValue() + return 1 + else: + return 0 + + + def GetMin(self): + """ + Gets the minimum value of the control. It will return the current + minimum integer, or None if not specified. + """ + return self.__min + + + def SetMax(self, max=None): + """ + Sets the maximum value of the control. If a value of None + is provided, then the control will have no explicit maximum value. + If the value specified is less than the current minimum value, then + the function returns 0 and the maximum will not change from its + current setting. On success, the function returns 1. + + If successful and the current value is greater than the new upper + bound, if the control is limited the value will be automatically + adjusted to this maximum value; if not limited, the value in the + control will be colored with the current out-of-bounds color. + + If max > sys.maxint and the control is configured to not allow longs, + the function will return 0, and the max will not be set. + """ + if( self.__min is None + or max is None + or (self.__min is not None and self.__min <= max) ): + self.__max = max + + if self.IsLimited() and max is not None and self.GetValue() > max: + self.SetValue(max) + else: + self._colorValue() + return 1 + else: + return 0 + + + def GetMax(self): + """ + Gets the maximum value of the control. It will return the current + maximum integer, or None if not specified. + """ + return self.__max + + + def SetBounds(self, min=None, max=None): + """ + This function is a convenience function for setting the min and max + values at the same time. The function only applies the maximum bound + if setting the minimum bound is successful, and returns True + only if both operations succeed. + NOTE: leaving out an argument will remove the corresponding bound. + """ + ret = self.SetMin(min) + return ret and self.SetMax(max) + + + def GetBounds(self): + """ + This function returns a two-tuple (min,max), indicating the + current bounds of the control. Each value can be None if + that bound is not set. + """ + return (self.__min, self.__max) + + + def SetLimited(self, limited): + """ + If called with a value of True, this function will cause the control + to limit the value to fall within the bounds currently specified. + If the control's value currently exceeds the bounds, it will then + be limited accordingly. + + If called with a value of 0, this function will disable value + limiting, but coloring of out-of-bounds values will still take + place if bounds have been set for the control. + """ + self.__limited = limited + if limited: + min = self.GetMin() + max = self.GetMax() + if not min is None and self.GetValue() < min: + self.SetValue(min) + elif not max is None and self.GetValue() > max: + self.SetValue(max) + else: + self._colorValue() + + + def IsLimited(self): + """ + Returns True if the control is currently limiting the + value to fall within the current bounds. + """ + return self.__limited + + + def IsInBounds(self, value=None): + """ + Returns True if no value is specified and the current value + of the control falls within the current bounds. This function can + also be called with a value to see if that value would fall within + the current bounds of the given control. + """ + if value is None: + value = self.GetValue() + + if( not (value is None and self.IsNoneAllowed()) + and type(value) not in (types.IntType, types.LongType) ): + raise ValueError ( + 'wxIntCtrl requires integer values, passed %s'% repr(value) ) + + min = self.GetMin() + max = self.GetMax() + if min is None: min = value + if max is None: max = value + + # if bounds set, and value is None, return False + if value == None and (min is not None or max is not None): + return 0 + else: + return min <= value <= max + + + def SetNoneAllowed(self, allow_none): + """ + Change the behavior of the validation code, allowing control + to have a value of None or not, as appropriate. If the value + of the control is currently None, and allow_none is 0, the + value of the control will be set to the minimum value of the + control, or 0 if no lower bound is set. + """ + self.__allow_none = allow_none + if not allow_none and self.GetValue() is None: + min = self.GetMin() + if min is not None: self.SetValue(min) + else: self.SetValue(0) + + + def IsNoneAllowed(self): + return self.__allow_none + + + def SetLongAllowed(self, allow_long): + """ + Change the behavior of the validation code, allowing control + to have a long value or not, as appropriate. If the value + of the control is currently long, and allow_long is 0, the + value of the control will be adjusted to fall within the + size of an integer type, at either the sys.maxint or -sys.maxint-1, + for positive and negative values, respectively. + """ + current_value = self.GetValue() + if not allow_long and type(current_value) is types.LongType: + if current_value > 0: + self.SetValue(MAXINT) + else: + self.SetValue(MININT) + self.__allow_long = allow_long + + + def IsLongAllowed(self): + return self.__allow_long + + + + def SetColors(self, default_color=wxBLACK, oob_color=wxRED): + """ + Tells the control what colors to use for normal and out-of-bounds + values. If the value currently exceeds the bounds, it will be + recolored accordingly. + """ + self.__default_color = default_color + self.__oob_color = oob_color + self._colorValue() + + + def GetColors(self): + """ + Returns a tuple of (default_color, oob_color), indicating + the current color settings for the control. + """ + return self.__default_color, self.__oob_color + + + def _colorValue(self, value=None): + """ + Colors text with oob_color if current value exceeds bounds + set for control. + """ + if not self.IsInBounds(value): + self.SetForegroundColour(self.__oob_color) + else: + self.SetForegroundColour(self.__default_color) + self.Refresh() + + + def _toGUI( self, value ): + """ + Conversion function used to set the value of the control; does + type and bounds checking and raises ValueError if argument is + not a valid value. + """ + if value is None and self.IsNoneAllowed(): + return '' + elif type(value) == types.LongType and not self.IsLongAllowed(): + raise ValueError ( + 'wxIntCtrl requires integer value, passed long' ) + elif type(value) not in (types.IntType, types.LongType): + raise ValueError ( + 'wxIntCtrl requires integer value, passed %s'% repr(value) ) + + elif self.IsLimited(): + min = self.GetMin() + max = self.GetMax() + if not min is None and value < min: + raise ValueError ( + 'value is below minimum value of control %d'% value ) + if not max is None and value > max: + raise ValueError ( + 'value exceeds value of control %d'% value ) + + return str(value) + + + def _fromGUI( self, value ): + """ + Conversion function used in getting the value of the control. + """ + if value == '': + if not self.IsNoneAllowed(): + return 0 + else: + return None + else: + try: + return int( value ) + except ValueError: + if self.IsLongAllowed(): + return long( value ) + else: + raise + + + def Cut( self ): + """ + Override the wxTextCtrl's .Cut function, with our own + that does validation. Will result in a value of 0 + if entire contents of control are removed. + """ + sel_start, sel_to = self.GetSelection() + select_len = sel_to - sel_start + textval = wxTextCtrl.GetValue(self) + + do = wxTextDataObject() + do.SetText(textval[sel_start:sel_to]) + wxTheClipboard.Open() + wxTheClipboard.SetData(do) + wxTheClipboard.Close() + if select_len == len(wxTextCtrl.GetValue(self)): + if not self.IsNoneAllowed(): + self.SetValue(0) + self.SetInsertionPoint(0) + self.SetSelection(0,1) + else: + self.SetValue(None) + else: + new_value = self._fromGUI(textval[:sel_start] + textval[sel_to:]) + self.SetValue(new_value) + + + def _getClipboardContents( self ): + """ + Subroutine for getting the current contents of the clipboard. + """ + do = wxTextDataObject() + wxTheClipboard.Open() + success = wxTheClipboard.GetData(do) + wxTheClipboard.Close() + + if not success: + return None + else: + # Remove leading and trailing spaces before evaluating contents + return do.GetText().strip() + + + def Paste( self ): + """ + Override the wxTextCtrl's .Paste function, with our own + that does validation. Will raise ValueError if not a + valid integerizable value. + """ + paste_text = self._getClipboardContents() + if paste_text: + # (conversion will raise ValueError if paste isn't legal) + sel_start, sel_to = self.GetSelection() + text = wxTextCtrl.GetValue( self ) + new_text = text[:sel_start] + paste_text + text[sel_to:] + if new_text == '' and self.IsNoneAllowed(): + self.SetValue(None) + else: + value = self._fromGUI(new_text) + self.SetValue(value) + new_pos = sel_start + len(paste_text) + wxCallAfter(self.SetInsertionPoint, new_pos) + + + +#=========================================================================== + +if __name__ == '__main__': + + import traceback + + class myDialog(wxDialog): + def __init__(self, parent, id, title, + pos = wxPyDefaultPosition, size = wxPyDefaultSize, + style = wxDEFAULT_DIALOG_STYLE ): + wxDialog.__init__(self, parent, id, title, pos, size, style) + + self.int_ctrl = wxIntCtrl(self, NewId(), size=(55,20)) + self.OK = wxButton( self, wxID_OK, "OK") + self.Cancel = wxButton( self, wxID_CANCEL, "Cancel") + + vs = wxBoxSizer( wxVERTICAL ) + vs.AddWindow( self.int_ctrl, 0, wxALIGN_CENTRE|wxALL, 5 ) + hs = wxBoxSizer( wxHORIZONTAL ) + hs.AddWindow( self.OK, 0, wxALIGN_CENTRE|wxALL, 5 ) + hs.AddWindow( self.Cancel, 0, wxALIGN_CENTRE|wxALL, 5 ) + vs.AddSizer(hs, 0, wxALIGN_CENTRE|wxALL, 5 ) + + self.SetAutoLayout( True ) + self.SetSizer( vs ) + vs.Fit( self ) + vs.SetSizeHints( self ) + EVT_INT(self, self.int_ctrl.GetId(), self.OnInt) + + def OnInt(self, event): + print 'int now', event.GetValue() + + class TestApp(wxApp): + def OnInit(self): + try: + self.frame = wxFrame(NULL, -1, "Test", + wxPoint(20,20), wxSize(120,100) ) + self.panel = wxPanel(self.frame, -1) + button = wxButton(self.panel, 10, "Push Me", + wxPoint(20, 20)) + EVT_BUTTON(self, 10, self.OnClick) + except: + traceback.print_exc() + return False + return True + + def OnClick(self, event): + dlg = myDialog(self.panel, -1, "test wxIntCtrl") + dlg.int_ctrl.SetValue(501) + dlg.int_ctrl.SetInsertionPoint(1) + dlg.int_ctrl.SetSelection(1,2) + rc = dlg.ShowModal() + print 'final value', dlg.int_ctrl.GetValue() + del dlg + self.frame.Destroy() + + def Show(self): + self.frame.Show(True) + + try: + app = TestApp(0) + app.Show() + app.MainLoop() + except: + traceback.print_exc() diff --git a/wxPython/wxPython/lib/layoutf.py b/wxPython/wxPython/lib/layoutf.py index c0f90b2083..4e1c20ac08 100644 --- a/wxPython/wxPython/lib/layoutf.py +++ b/wxPython/wxPython/lib/layoutf.py @@ -1,7 +1,7 @@ from wxPython.wx import wxLayoutConstraints,\ wxTop, wxLeft, wxBottom, wxRight, \ wxHeight, wxWidth, wxCentreX, wxCentreY -import re,string +import re class Layoutf(wxLayoutConstraints): """ @@ -130,8 +130,8 @@ time of this writing not documented. self.pack(pstr,winlist) def pack(self, pstr, winlist): - pstr = string.lower(pstr) - for item in string.split(pstr,';'): + pstr = pstr.lower() + for item in pstr.split(';'): m = self.rexp1.match(item) if m: g = list(m.groups()) @@ -159,8 +159,8 @@ time of this writing not documented. else: func(winlist[g[4]], cmp) def debug_pack(self, pstr, winlist): - pstr = string.lower(pstr) - for item in string.split(pstr,';'): + pstr = pstr.lower() + for item in pstr.split(';'): m = self.rexp1.match(item) if m: g = list(m.groups()) @@ -202,7 +202,7 @@ if __name__=='__main__': wxPyDefaultPosition, wxSize(500, 300)) EVT_CLOSE(self, self.OnCloseWindow) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_BUTTON(self, 100, self.OnButton) EVT_BUTTON(self, 101, self.OnAbout) @@ -234,7 +234,7 @@ if __name__=='__main__': wxStaticText(self.panelD, -1, "Panel D", wxPoint(4, 4)).SetBackgroundColour(wxGREEN) def OnButton(self, event): - self.Close(true) + self.Close(True) def OnAbout(self, event): try: diff --git a/wxPython/wxPython/lib/mixins/listctrl.py b/wxPython/wxPython/lib/mixins/listctrl.py index 1c70c12ce7..c422c17cad 100644 --- a/wxPython/wxPython/lib/mixins/listctrl.py +++ b/wxPython/wxPython/lib/mixins/listctrl.py @@ -11,6 +11,7 @@ #---------------------------------------------------------------------------- from wxPython.wx import * +import locale #---------------------------------------------------------------------------- @@ -105,7 +106,12 @@ class wxColumnSorterMixin: item1 = self.itemDataMap[key1][col] item2 = self.itemDataMap[key2][col] - cmpVal = cmp(item1, item2) + #--- Internationalization of string sorting with locale module + if type(item1) == type('') or type(item2) == type(''): + cmpVal = locale.strcoll(str(item1), str(item2)) + else: + cmpVal = cmp(item1, item2) + #--- # If the items are equal then pick something else to make the sort value unique if cmpVal == 0: @@ -132,137 +138,102 @@ class wxColumnSorterMixin: class wxListCtrlAutoWidthMixin: """ A mix-in class that automatically resizes the last column to take up - the remaining width of the wxListCtrl. + the remaining width of the wxListCtrl. - This causes the wxListCtrl to automatically take up the full width of - the list, without either a horizontal scroll bar (unless absolutely - necessary) or empty space to the right of the last column. + This causes the wxListCtrl to automatically take up the full width of + the list, without either a horizontal scroll bar (unless absolutely + necessary) or empty space to the right of the last column. - NOTE: This only works for report-style lists. + NOTE: This only works for report-style lists. - WARNING: If you override the EVT_SIZE event in your wxListCtrl, make - sure you call event.Skip() to ensure that the mixin's - _OnResize method is called. + WARNING: If you override the EVT_SIZE event in your wxListCtrl, make + sure you call event.Skip() to ensure that the mixin's + _OnResize method is called. - This mix-in class was written by Erik Westra <ewestra@wave.co.nz> + This mix-in class was written by Erik Westra <ewestra@wave.co.nz> """ def __init__(self): - """ Standard initialiser. - """ - self._needResize = false - self._lastColMinWidth = None + """ Standard initialiser. + """ + self._lastColMinWidth = None - EVT_SIZE(self, self._onResize) - EVT_LIST_COL_END_DRAG(self, self.GetId(), self._onEndColDrag) - EVT_IDLE(self, self._onIdle) + EVT_SIZE(self, self._onResize) + EVT_LIST_COL_END_DRAG(self, self.GetId(), self._onResize) def resizeLastColumn(self, minWidth): - """ Resize the last column appropriately. + """ Resize the last column appropriately. - If the list's columns are too wide to fit within the window, we use - a horizontal scrollbar. Otherwise, we expand the right-most column - to take up the remaining free space in the list. + If the list's columns are too wide to fit within the window, we use + a horizontal scrollbar. Otherwise, we expand the right-most column + to take up the remaining free space in the list. - This method is called automatically when the wxListCtrl is resized; - you can also call it yourself whenever you want the last column to - be resized appropriately (eg, when adding, removing or resizing - columns). + This method is called automatically when the wxListCtrl is resized; + you can also call it yourself whenever you want the last column to + be resized appropriately (eg, when adding, removing or resizing + columns). - 'minWidth' is the preferred minimum width for the last column. - """ - self._lastColMinWidth = minWidth - self._doResize() + 'minWidth' is the preferred minimum width for the last column. + """ + self._lastColMinWidth = minWidth + self._doResize() # ===================== # == Private Methods == # ===================== def _onResize(self, event): - """ Respond to the wxListCtrl being resized. + """ Respond to the wxListCtrl being resized. - We automatically resize the last column in the list. - """ - self._doResize() + We automatically resize the last column in the list. + """ + wxCallAfter(self._doResize) event.Skip() - def _onEndColDrag(self, event): - """ Respond to the user resizing one of our columns. - We resize the last column in the list to match. Note that, because - of a quirk in the way columns are resized under MS Windows, we - actually have to do the column resize in idle time. - """ - self._needResize = true - event.Skip() + def _doResize(self): + """ Resize the last column as appropriate. + If the list's columns are too wide to fit within the window, we use + a horizontal scrollbar. Otherwise, we expand the right-most column + to take up the remaining free space in the list. - def _onIdle(self, event): - """ Respond to an idle event. + We remember the current size of the last column, before resizing, + as the preferred minimum width if we haven't previously been given + or calculated a minimum width. This ensure that repeated calls to + _doResize() don't cause the last column to size itself too large. + """ + numCols = self.GetColumnCount() + if numCols == 0: return # Nothing to resize. - We resize the last column, if we've been asked to do so. - """ - if self._needResize: - self._doResize() - self.Refresh() # Fixes redraw problem under MS Windows. - self._needResize = false - event.Skip() + if self._lastColMinWidth == None: + self._lastColMinWidth = self.GetColumnWidth(numCols - 1) + # We're showing the vertical scrollbar -> allow for scrollbar width + # NOTE: on GTK, the scrollbar is included in the client size, but on + # Windows it is not included + listWidth = self.GetClientSize().width + if wxPlatform != '__WXMSW__': + if self.GetItemCount() > self.GetCountPerPage(): + scrollWidth = wxSystemSettings_GetSystemMetric(wxSYS_VSCROLL_X) + listWidth = listWidth - scrollWidth - def _doResize(self): - """ Resize the last column as appropriate. - - If the list's columns are too wide to fit within the window, we use - a horizontal scrollbar. Otherwise, we expand the right-most column - to take up the remaining free space in the list. - - We remember the current size of the last column, before resizing, - as the preferred minimum width if we haven't previously been given - or calculated a minimum width. This ensure that repeated calls to - _doResize() don't cause the last column to size itself too large. - """ - numCols = self.GetColumnCount() - if numCols == 0: return # Nothing to resize. - - if self._lastColMinWidth == None: - self._lastColMinWidth = self.GetColumnWidth(numCols - 1) - - listWidth = self.GetSize().width - if self.GetItemCount() > self.GetCountPerPage(): - # We're showing the vertical scrollbar -> allow for scrollbar width - scrollWidth = wxSystemSettings_GetSystemMetric(wxSYS_VSCROLL_X) - listWidth = listWidth - scrollWidth - - totColWidth = 0 # Width of all columns except last one. - for col in range(numCols-1): - totColWidth = totColWidth + self.GetColumnWidth(col) - - lastColWidth = self.GetColumnWidth(numCols - 1) - - # NOTE: This is the extra number of pixels required to make the - # wxListCtrl size correctly, at least under Windows 2000. - # Unfortunately, different OSs and even different versions of the - # same OS may implement the wxListCtrl differently, so different - # margins may be needed to get the columns resized correctly. No - # doubt the margin could be calculated in a more intelligent - # manner... - if wxPlatform == '__WXMSW__': - margin = 6 - elif wxPlatform == '__WXGTK__': - margin = 8 - else: - margin = 0 + totColWidth = 0 # Width of all columns except last one. + for col in range(numCols-1): + totColWidth = totColWidth + self.GetColumnWidth(col) + + lastColWidth = self.GetColumnWidth(numCols - 1) - if totColWidth + self._lastColMinWidth > listWidth - margin: - # We haven't got the width to show the last column at its minimum - # width -> set it to its minimum width and allow the horizontal - # scrollbar to show. - self.SetColumnWidth(numCols-1, self._lastColMinWidth) - return + if totColWidth + self._lastColMinWidth > listWidth: + # We haven't got the width to show the last column at its minimum + # width -> set it to its minimum width and allow the horizontal + # scrollbar to show. + self.SetColumnWidth(numCols-1, self._lastColMinWidth) + return - # Resize the last column to take up the remaining available space. + # Resize the last column to take up the remaining available space. - self.SetColumnWidth(numCols-1, listWidth - totColWidth - margin) + self.SetColumnWidth(numCols-1, listWidth - totColWidth) diff --git a/wxPython/wxPython/lib/mixins/rubberband.py b/wxPython/wxPython/lib/mixins/rubberband.py new file mode 100644 index 0000000000..f71dbf50a9 --- /dev/null +++ b/wxPython/wxPython/lib/mixins/rubberband.py @@ -0,0 +1,389 @@ +""" +A mixin class for doing "RubberBand"-ing on a window. + +by "Robb Shecter" <rs@onsitetech.com> + +$Id$ + +""" + +from wxPython.wx import * +import Image + +# +# Some miscellaneous mathematical and geometrical functions +# + +def isNegative(aNumber): + """ + x < 0: 1 + else: 0 + """ + return aNumber < 0 + + +def normalizeBox(box): + """ + Convert any negative measurements in the current + box to positive, and adjust the origin. + """ + x, y, w, h = box + if w < 0: + x += (w+1) + w *= -1 + if h < 0: + y += (h+1) + h *= -1 + return (x, y, w, h) + + +def boxToExtent(box): + """ + Convert a box specification to an extent specification. + I put this into a seperate function after I realized that + I had been implementing it wrong in several places. + """ + b = normalizeBox(box) + return (b[0], b[1], b[0]+b[2]-1, b[1]+b[3]-1) + + +def pointInBox(x, y, box): + """ + Return True if the given point is contained in the box. + """ + e = boxToExtent(box) + return x >= e[0] and x <= e[2] and y >= e[1] and y <= e[3] + + +def pointOnBox(x, y, box, thickness=1): + """ + Return True if the point is on the outside edge + of the box. The thickness defines how thick the + edge should be. This is necessary for HCI reasons: + For example, it's normally very difficult for a user + to manuever the mouse onto a one pixel border. + """ + outerBox = box + innerBox = (box[0]+thickness, box[1]+thickness, box[2]-(thickness*2), box[3]-(thickness*2)) + return pointInBox(x, y, outerBox) and not pointInBox(x, y, innerBox) + + +def getCursorPosition(x, y, box, thickness=1): + """ + Return a position number in the range 0 .. 7 to indicate + where on the box border the point is. The layout is: + + 0 1 2 + 7 3 + 6 5 4 + """ + x0, y0, x1, y1 = boxToExtent(box) + w, h = box[2], box[3] + delta = thickness - 1 + p = None + + if pointInBox(x, y, (x0, y0, thickness, thickness)): + p = 0 + elif pointInBox(x, y, (x1-delta, y0, thickness, thickness)): + p = 2 + elif pointInBox(x, y, (x1-delta, y1-delta, thickness, thickness)): + p = 4 + elif pointInBox(x, y, (x0, y1-delta, thickness, thickness)): + p = 6 + elif pointInBox(x, y, (x0+thickness, y0, w-(thickness*2), thickness)): + p = 1 + elif pointInBox(x, y, (x1-delta, y0+thickness, thickness, h-(thickness*2))): + p = 3 + elif pointInBox(x, y, (x0+thickness, y1-delta, w-(thickness*2), thickness)): + p = 5 + elif pointInBox(x, y, (x0, y0+thickness, thickness, h-(thickness*2))): + p = 7 + + return p + + + + +class RubberBand: + """ + A stretchable border which is drawn on top of an + image to define an area. + """ + def __init__(self, drawingSurface, aspectRatio=None): + self.__THICKNESS = 5 + self.drawingSurface = drawingSurface + self.aspectRatio = aspectRatio + self.hasLetUp = 0 + self.currentlyMoving = None + self.currentBox = None + self.__enabled = 1 + self.__currentCursor = None + EVT_MOUSE_EVENTS(drawingSurface, self.__handleMouseEvents) + EVT_PAINT(drawingSurface, self.__handleOnPaint) + + def __setEnabled(self, enabled): + self.__enabled = enabled + + def __isEnabled(self): + return self.__enabled + + def __handleOnPaint(self, event): + #print 'paint' + event.Skip() + + def __isMovingCursor(self): + """ + Return True if the current cursor is one used to + mean moving the rubberband. + """ + return self.__currentCursor == wxCURSOR_HAND + + def __isSizingCursor(self): + """ + Return True if the current cursor is one of the ones + I may use to signify sizing. + """ + sizingCursors = [wxCURSOR_SIZENESW, + wxCURSOR_SIZENS, + wxCURSOR_SIZENWSE, + wxCURSOR_SIZEWE, + wxCURSOR_SIZING, + wxCURSOR_CROSS] + try: + sizingCursors.index(self.__currentCursor) + return 1 + except ValueError: + return 0 + + + def __handleMouseEvents(self, event): + """ + React according to the new event. This is the main + entry point into the class. This method contains the + logic for the class's behavior. + """ + if not self.enabled: + return + + x, y = event.GetPosition() + + # First make sure we have started a box. + if self.currentBox == None and not event.LeftDown(): + # No box started yet. Set cursor to the initial kind. + self.__setCursor(wxCURSOR_CROSS) + return + + if event.LeftDown(): + if self.currentBox == None: + # No RB Box, so start a new one. + self.currentBox = (x, y, 0, 0) + self.hasLetUp = 0 + elif self.__isSizingCursor(): + # Starting a sizing operation. Change the origin. + position = getCursorPosition(x, y, self.currentBox, thickness=self.__THICKNESS) + self.currentBox = self.__denormalizeBox(position, self.currentBox) + + elif event.Dragging() and event.LeftIsDown(): + # Use the cursor type to determine operation + if self.__isMovingCursor(): + if self.currentlyMoving or pointInBox(x, y, self.currentBox): + if not self.currentlyMoving: + self.currentlyMoving = (x - self.currentBox[0], y - self.currentBox[1]) + self.__moveTo(x - self.currentlyMoving[0], y - self.currentlyMoving[1]) + elif self.__isSizingCursor(): + self.__resizeBox(x, y) + + elif event.LeftUp(): + self.hasLetUp = 1 + self.currentlyMoving = None + self.__normalizeBox() + + elif event.Moving() and not event.Dragging(): + # Simple mouse movement event + self.__mouseMoved(x,y) + + def __denormalizeBox(self, position, box): + x, y, w, h = box + b = box + if position == 2 or position == 3: + b = (x, y + (h-1), w, h * -1) + elif position == 0 or position == 1 or position == 7: + b = (x + (w-1), y + (h-1), w * -1, h * -1) + elif position == 6: + b = (x + (w-1), y, w * -1, h) + return b + + def __resizeBox(self, x, y): + """ + Resize and repaint the box based on the given mouse + coordinates. + """ + # Implement the correct behavior for dragging a side + # of the box: Only change one dimension. + if not self.aspectRatio: + if self.__currentCursor == wxCURSOR_SIZENS: + x = None + elif self.__currentCursor == wxCURSOR_SIZEWE: + y = None + + x0,y0,w0,h0 = self.currentBox + currentExtent = boxToExtent(self.currentBox) + if x == None: + if w0 < 1: + w0 += 1 + else: + w0 -= 1 + x = x0 + w0 + if y == None: + if h0 < 1: + h0 += 1 + else: + h0 -= 1 + y = y0 + h0 + x1,y1 = x, y + w, h = abs(x1-x0)+1, abs(y1-y0)+1 + if self.aspectRatio: + w = max(w, int(h * self.aspectRatio)) + h = int(w / self.aspectRatio) + w *= [1,-1][isNegative(x1-x0)] + h *= [1,-1][isNegative(y1-y0)] + newbox = (x0, y0, w, h) + self.__drawAndErase(boxToDraw=normalizeBox(newbox), boxToErase=normalizeBox(self.currentBox)) + self.currentBox = (x0, y0, w, h) + + def __normalizeBox(self): + """ + Convert any negative measurements in the current + box to positive, and adjust the origin. + """ + self.currentBox = normalizeBox(self.currentBox) + + def __mouseMoved(self, x, y): + """ + Called when the mouse moved without any buttons pressed + or dragging being done. + """ + # Are we on the bounding box? + if pointOnBox(x, y, self.currentBox, thickness=self.__THICKNESS): + position = getCursorPosition(x, y, self.currentBox, thickness=self.__THICKNESS) + cursor = [ + wxCURSOR_SIZENWSE, + wxCURSOR_SIZENS, + wxCURSOR_SIZENESW, + wxCURSOR_SIZEWE, + wxCURSOR_SIZENWSE, + wxCURSOR_SIZENS, + wxCURSOR_SIZENESW, + wxCURSOR_SIZEWE + ] [position] + self.__setCursor(cursor) + elif pointInBox(x, y, self.currentBox): + self.__setCursor(wxCURSOR_HAND) + else: + self.__setCursor() + + def __setCursor(self, id=None): + """ + Set the mouse cursor to the given id. + """ + if self.__currentCursor != id: # Avoid redundant calls + if id: + self.drawingSurface.SetCursor(wxStockCursor(id)) + else: + self.drawingSurface.SetCursor(wxNullCursor) + self.__currentCursor = id + + def __moveCenterTo(self, x, y): + """ + Move the rubber band so that its center is at (x,y). + """ + x0, y0, w, h = self.currentBox + x2, y2 = x - (w/2), y - (h/2) + self.__moveTo(x2, y2) + + def __moveTo(self, x, y): + """ + Move the rubber band so that its origin is at (x,y). + """ + newbox = (x, y, self.currentBox[2], self.currentBox[3]) + self.__drawAndErase(boxToDraw=newbox, boxToErase=self.currentBox) + self.currentBox = newbox + + def __drawAndErase(self, boxToDraw, boxToErase=None): + """ + Draw one box shape and possibly erase another. + """ + dc = wxClientDC(self.drawingSurface) + dc.BeginDrawing() + dc.SetPen(wxPen(wxWHITE, 1, wxDOT)) + dc.SetBrush(wxTRANSPARENT_BRUSH) + dc.SetLogicalFunction(wxXOR) + if boxToErase: + dc.DrawRectangle(*boxToErase) + dc.DrawRectangle(*boxToDraw) + dc.EndDrawing() + + def __dumpMouseEvent(self, event): + print 'Moving: ',event.Moving() + print 'Dragging: ',event.Dragging() + print 'LeftDown: ',event.LeftDown() + print 'LeftisDown: ',event.LeftIsDown() + print 'LeftUp: ',event.LeftUp() + print 'Position: ',event.GetPosition() + print 'x,y: ',event.GetX(),event.GetY() + print + + + # + # The public API: + # + + def reset(self, aspectRatio=None): + """ + Clear the existing rubberband + """ + self.currentBox = None + self.aspectRatio = aspectRatio + self.drawingSurface.Refresh() + + def getCurrentExtent(self): + """ + Return (x0, y0, x1, y1) or None if + no drawing has yet been done. + """ + if not self.currentBox: + extent = None + else: + extent = boxToExtent(self.currentBox) + return extent + + enabled = property(__isEnabled, __setEnabled, None, 'True if I am responding to mouse events') + + + +if __name__ == '__main__': + app = wxPySimpleApp() + frame = wxFrame(None, -1, title='RubberBand Test', size=(300,300)) + + # Add a panel that the rubberband will work on. + panel = wxPanel(frame, -1) + panel.SetBackgroundColour(wxBLUE) + + # Create the rubberband + frame.rubberBand = RubberBand(drawingSurface=panel) + frame.rubberBand.reset(aspectRatio=0.5) + + # Add a button that creates a new rubberband + def __newRubberBand(event): + frame.rubberBand.reset() + button = wxButton(frame, 100, 'Reset Rubberband') + EVT_BUTTON(frame, 100, __newRubberBand) + + # Layout the frame + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(panel, 1, wxEXPAND | wxALL, 5) + sizer.Add(button, 0, wxALIGN_CENTER | wxALL, 5) + frame.SetAutoLayout(1) + frame.SetSizer(sizer) + frame.Show(1) + app.MainLoop() diff --git a/wxPython/wxPython/lib/multisash.py b/wxPython/wxPython/lib/multisash.py new file mode 100644 index 0000000000..9f5602e5a6 --- /dev/null +++ b/wxPython/wxPython/lib/multisash.py @@ -0,0 +1,726 @@ +#---------------------------------------------------------------------- +# Name: multisash +# Purpose: Multi Sash control +# +# Author: Gerrit van Dyk +# +# Created: 2002/11/20 +# Version: 0.1 +# RCS-ID: $Id$ +# License: wxWindows licensie +#---------------------------------------------------------------------- + +from wxPython.wx import * + +MV_HOR = 0 +MV_VER = not MV_HOR + +SH_SIZE = 5 +CR_SIZE = SH_SIZE * 3 + +#---------------------------------------------------------------------- + +class wxMultiSash(wxWindow): + def __init__(self, *_args,**_kwargs): + apply(wxWindow.__init__,(self,) + _args,_kwargs) + self._defChild = EmptyChild + self.child = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize()) + EVT_SIZE(self,self.OnMultiSize) + + def SetDefaultChildClass(self,childCls): + self._defChild = childCls + self.child.DefaultChildChanged() + + def OnMultiSize(self,evt): + self.child.SetSize(self.GetSize()) + + def UnSelect(self): + self.child.UnSelect() + + def Clear(self): + old = self.child + self.child = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize()) + old.Destroy() + self.child.OnSize(None) + + def GetSaveData(self): + saveData = {} + saveData['_defChild'] = str(self._defChild) + saveData['child'] = self.child.GetSaveData() + return saveData + + def SetSaveData(self,data): + dChild = data['_defChild'] + mod = dChild.split('.')[0] + exec 'import %s' % mod + self._defChild = eval(dChild) + old = self.child + self.child = wxMultiSplit(self,self,wxPoint(0,0),self.GetSize()) + self.child.SetSaveData(data['child']) + old.Destroy() + self.OnMultiSize(None) + self.child.OnSize(None) + + +#---------------------------------------------------------------------- + + +class wxMultiSplit(wxWindow): + def __init__(self,multiView,parent,pos,size,view1 = None): + wxWindow.__init__(self,id = -1,parent = parent,pos = pos,size = size, + style = wxCLIP_CHILDREN) + self.multiView = multiView + self.view2 = None + if view1: + self.view1 = view1 + self.view1.Reparent(self) + self.view1.MoveXY(0,0) + else: + self.view1 = wxMultiViewLeaf(self.multiView,self, + wxPoint(0,0),self.GetSize()) + self.direction = None + + EVT_SIZE(self,self.OnSize) + + def GetSaveData(self): + saveData = {} + if self.view1: + saveData['view1'] = self.view1.GetSaveData() + if isinstance(self.view1,wxMultiSplit): + saveData['view1IsSplit'] = 1 + if self.view2: + saveData['view2'] = self.view2.GetSaveData() + if isinstance(self.view2,wxMultiSplit): + saveData['view2IsSplit'] = 1 + saveData['direction'] = self.direction + v1,v2 = self.GetPositionTuple() + saveData['x'] = v1 + saveData['y'] = v2 + v1,v2 = self.GetSizeTuple() + saveData['w'] = v1 + saveData['h'] = v2 + return saveData + + def SetSaveData(self,data): + self.direction = data['direction'] + self.SetDimensions(data['x'],data['y'],data['w'],data['h']) + v1Data = data.get('view1',None) + if v1Data: + isSplit = data.get('view1IsSplit',None) + old = self.view1 + if isSplit: + self.view1 = wxMultiSplit(self.multiView,self, + wxPoint(0,0),self.GetSize()) + else: + self.view1 = wxMultiViewLeaf(self.multiView,self, + wxPoint(0,0),self.GetSize()) + self.view1.SetSaveData(v1Data) + if old: + old.Destroy() + v2Data = data.get('view2',None) + if v2Data: + isSplit = data.get('view2IsSplit',None) + old = self.view2 + if isSplit: + self.view2 = wxMultiSplit(self.multiView,self, + wxPoint(0,0),self.GetSize()) + else: + self.view2 = wxMultiViewLeaf(self.multiView,self, + wxPoint(0,0),self.GetSize()) + self.view2.SetSaveData(v2Data) + if old: + old.Destroy() + if self.view1: + self.view1.OnSize(None) + if self.view2: + self.view2.OnSize(None) + + def UnSelect(self): + if self.view1: + self.view1.UnSelect() + if self.view2: + self.view2.UnSelect() + + def DefaultChildChanged(self): + if not self.view2: + self.view1.DefaultChildChanged() + + def AddLeaf(self,direction,caller,pos): + if self.view2: + if caller == self.view1: + self.view1 = wxMultiSplit(self.multiView,self, + caller.GetPosition(), + caller.GetSize(), + caller) + self.view1.AddLeaf(direction,caller,pos) + else: + self.view2 = wxMultiSplit(self.multiView,self, + caller.GetPosition(), + caller.GetSize(), + caller) + self.view2.AddLeaf(direction,caller,pos) + else: + self.direction = direction + w,h = self.GetSizeTuple() + if direction == MV_HOR: + x,y = (pos,0) + w1,h1 = (w-pos,h) + w2,h2 = (pos,h) + else: + x,y = (0,pos) + w1,h1 = (w,h-pos) + w2,h2 = (w,pos) + self.view2 = wxMultiViewLeaf(self.multiView,self, + wxPoint(x,y),wxSize(w1,h1)) + self.view1.SetSize(wxSize(w2,h2)) + self.view2.OnSize(None) + + def DestroyLeaf(self,caller): + if not self.view2: # We will only have 2 windows if + return # we need to destroy any + parent = self.GetParent() # Another splitview + if parent == self.multiView: # We'r at the root + if caller == self.view1: + old = self.view1 + self.view1 = self.view2 + self.view2 = None + old.Destroy() + else: + self.view2.Destroy() + self.view2 = None + self.view1.SetSize(self.GetSize()) + self.view1.Move(self.GetPosition()) + else: + w,h = self.GetSizeTuple() + x,y = self.GetPositionTuple() + if caller == self.view1: + if self == parent.view1: + parent.view1 = self.view2 + else: + parent.view2 = self.view2 + self.view2.Reparent(parent) + self.view2.SetDimensions(x,y,w,h) + else: + if self == parent.view1: + parent.view1 = self.view1 + else: + parent.view2 = self.view1 + self.view1.Reparent(parent) + self.view1.SetDimensions(x,y,w,h) + self.view1 = None + self.view2 = None + self.Destroy() + + def CanSize(self,side,view): + if self.SizeTarget(side,view): + return True + return False + + def SizeTarget(self,side,view): + if self.direction == side and self.view2 and view == self.view1: + return self + parent = self.GetParent() + if parent != self.multiView: + return parent.SizeTarget(side,self) + return None + + def SizeLeaf(self,leaf,pos,side): + if self.direction != side: + return + if not (self.view1 and self.view2): + return + if pos < 10: return + w,h = self.GetSizeTuple() + if side == MV_HOR: + if pos > w - 10: return + else: + if pos > h - 10: return + if side == MV_HOR: + self.view1.SetDimensions(0,0,pos,h) + self.view2.SetDimensions(pos,0,w-pos,h) + else: + self.view1.SetDimensions(0,0,w,pos) + self.view2.SetDimensions(0,pos,w,h-pos) + + def OnSize(self,evt): + if not self.view2: + self.view1.SetSize(self.GetSize()) + self.view1.OnSize(None) + return + v1w,v1h = self.view1.GetSizeTuple() + v2w,v2h = self.view2.GetSizeTuple() + v1x,v1y = self.view1.GetPositionTuple() + v2x,v2y = self.view2.GetPositionTuple() + w,h = self.GetSizeTuple() + + if v1x != v2x: + ratio = float(w) / float((v1w + v2w)) + v1w *= ratio + v2w = w - v1w + v2x = v1w + else: + v1w = v2w = w + + if v1y != v2y: + ratio = float(h) / float((v1h + v2h)) + v1h *= ratio + v2h = h - v1h + v2y = v1h + else: + v1h = v2h = h + + self.view1.SetDimensions(v1x,v1y,v1w,v1h) + self.view2.SetDimensions(v2x,v2y,v2w,v2h) + self.view1.OnSize(None) + self.view2.OnSize(None) + + +#---------------------------------------------------------------------- + + +class wxMultiViewLeaf(wxWindow): + def __init__(self,multiView,parent,pos,size): + wxWindow.__init__(self,id = -1,parent = parent,pos = pos,size = size, + style = wxCLIP_CHILDREN) + self.multiView = multiView + + self.sizerHor = MultiSizer(self,MV_HOR) + self.sizerVer = MultiSizer(self,MV_VER) + self.creatorHor = MultiCreator(self,MV_HOR) + self.creatorVer = MultiCreator(self,MV_VER) + self.detail = MultiClient(self,multiView._defChild) + self.closer = MultiCloser(self) + + EVT_SIZE(self,self.OnSize) + + def GetSaveData(self): + saveData = {} + saveData['detailClass'] = str(self.detail.child.__class__) + if hasattr(self.detail.child,'GetSaveData'): + attr = getattr(self.detail.child,'GetSaveData') + if callable(attr): + dData = attr() + if dData: + saveData['detail'] = dData + v1,v2 = self.GetPositionTuple() + saveData['x'] = v1 + saveData['y'] = v2 + v1,v2 = self.GetSizeTuple() + saveData['w'] = v1 + saveData['h'] = v2 + return saveData + + def SetSaveData(self,data): + dChild = data['detailClass'] + mod = dChild.split('.')[0] + exec 'import %s' % mod + detClass = eval(dChild) + self.SetDimensions(data['x'],data['y'],data['w'],data['h']) + old = self.detail + self.detail = MultiClient(self,detClass) + dData = data.get('detail',None) + if dData: + if hasattr(self.detail.child,'SetSaveData'): + attr = getattr(self.detail.child,'SetSaveData') + if callable(attr): + attr(dData) + old.Destroy() + self.detail.OnSize(None) + + def UnSelect(self): + self.detail.UnSelect() + + def DefaultChildChanged(self): + self.detail.SetNewChildCls(self.multiView._defChild) + + def AddLeaf(self,direction,pos): + if pos < 10: return + w,h = self.GetSizeTuple() + if direction == MV_VER: + if pos > h - 10: return + else: + if pos > w - 10: return + self.GetParent().AddLeaf(direction,self,pos) + + def DestroyLeaf(self): + self.GetParent().DestroyLeaf(self) + + def SizeTarget(self,side): + return self.GetParent().SizeTarget(side,self) + + def CanSize(self,side): + return self.GetParent().CanSize(side,self) + + def OnSize(self,evt): + self.sizerHor.OnSize(evt) + self.sizerVer.OnSize(evt) + self.creatorHor.OnSize(evt) + self.creatorVer.OnSize(evt) + self.detail.OnSize(evt) + self.closer.OnSize(evt) + +#---------------------------------------------------------------------- + + +class MultiClient(wxWindow): + def __init__(self,parent,childCls): + w,h = self.CalcSize(parent) + wxWindow.__init__(self,id = -1,parent = parent, + pos = wxPoint(0,0), + size = wxSize(w,h), + style = wxCLIP_CHILDREN | wxSUNKEN_BORDER) + self.child = childCls(self) + self.child.MoveXY(2,2) + self.normalColour = self.GetBackgroundColour() + self.selected = False + + EVT_SET_FOCUS(self,self.OnSetFocus) + EVT_CHILD_FOCUS(self,self.OnChildFocus) + + def UnSelect(self): + if self.selected: + self.selected = False + self.SetBackgroundColour(self.normalColour) + self.Refresh() + + def Select(self): + self.GetParent().multiView.UnSelect() + self.selected = True + self.SetBackgroundColour(wxColour(255,255,0)) # Yellow + self.Refresh() + + def CalcSize(self,parent): + w,h = parent.GetSizeTuple() + w -= SH_SIZE + h -= SH_SIZE + return (w,h) + + def OnSize(self,evt): + w,h = self.CalcSize(self.GetParent()) + self.SetDimensions(0,0,w,h) + w,h = self.GetClientSizeTuple() + self.child.SetSize(wxSize(w-4,h-4)) + + def SetNewChildCls(self,childCls): + if self.child: + self.child.Destroy() + self.child = None + self.child = childCls(self) + self.child.MoveXY(2,2) + + def OnSetFocus(self,evt): + self.Select() + + def OnChildFocus(self,evt): + self.OnSetFocus(evt) +## from Funcs import FindFocusedChild +## child = FindFocusedChild(self) +## EVT_KILL_FOCUS(child,self.OnChildKillFocus) + + +#---------------------------------------------------------------------- + + +class MultiSizer(wxWindow): + def __init__(self,parent,side): + self.side = side + x,y,w,h = self.CalcSizePos(parent) + wxWindow.__init__(self,id = -1,parent = parent, + pos = wxPoint(x,y), + size = wxSize(w,h), + style = wxCLIP_CHILDREN) + + self.px = None # Previous X + self.py = None # Previous Y + self.isDrag = False # In Dragging + self.dragTarget = None # View being sized + + EVT_LEAVE_WINDOW(self,self.OnLeave) + EVT_ENTER_WINDOW(self,self.OnEnter) + EVT_MOTION(self,self.OnMouseMove) + EVT_LEFT_DOWN(self,self.OnPress) + EVT_LEFT_UP(self,self.OnRelease) + + def CalcSizePos(self,parent): + pw,ph = parent.GetSizeTuple() + if self.side == MV_HOR: + x = CR_SIZE + 2 + y = ph - SH_SIZE + w = pw - CR_SIZE - SH_SIZE - 2 + h = SH_SIZE + else: + x = pw - SH_SIZE + y = CR_SIZE + 2 + SH_SIZE + w = SH_SIZE + h = ph - CR_SIZE - SH_SIZE - 4 - SH_SIZE # For Closer + return (x,y,w,h) + + def OnSize(self,evt): + x,y,w,h = self.CalcSizePos(self.GetParent()) + self.SetDimensions(x,y,w,h) + + def OnLeave(self,evt): + self.SetCursor(wxStockCursor(wxCURSOR_ARROW)) + + def OnEnter(self,evt): + if not self.GetParent().CanSize(not self.side): + return + if self.side == MV_HOR: + self.SetCursor(wxStockCursor(wxCURSOR_SIZENS)) + else: + self.SetCursor(wxStockCursor(wxCURSOR_SIZEWE)) + + def OnMouseMove(self,evt): + if self.isDrag: + DrawSash(self.dragTarget,self.px,self.py,self.side) + self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) + self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py) + DrawSash(self.dragTarget,self.px,self.py,self.side) + else: + evt.Skip() + + def OnPress(self,evt): + self.dragTarget = self.GetParent().SizeTarget(not self.side) + if self.dragTarget: + self.isDrag = True + self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) + self.px,self.py = self.dragTarget.ScreenToClientXY(self.px,self.py) + DrawSash(self.dragTarget,self.px,self.py,self.side) + self.CaptureMouse() + else: + evt.Skip() + + def OnRelease(self,evt): + if self.isDrag: + DrawSash(self.dragTarget,self.px,self.py,self.side) + self.ReleaseMouse() + self.isDrag = False + if self.side == MV_HOR: + self.dragTarget.SizeLeaf(self.GetParent(), + self.py,not self.side) + else: + self.dragTarget.SizeLeaf(self.GetParent(), + self.px,not self.side) + self.dragTarget = None + else: + evt.Skip() + +#---------------------------------------------------------------------- + + +class MultiCreator(wxWindow): + def __init__(self,parent,side): + self.side = side + x,y,w,h = self.CalcSizePos(parent) + wxWindow.__init__(self,id = -1,parent = parent, + pos = wxPoint(x,y), + size = wxSize(w,h), + style = wxCLIP_CHILDREN) + + self.px = None # Previous X + self.py = None # Previous Y + self.isDrag = False # In Dragging + + EVT_LEAVE_WINDOW(self,self.OnLeave) + EVT_ENTER_WINDOW(self,self.OnEnter) + EVT_MOTION(self,self.OnMouseMove) + EVT_LEFT_DOWN(self,self.OnPress) + EVT_LEFT_UP(self,self.OnRelease) + EVT_PAINT(self,self.OnPaint) + + def CalcSizePos(self,parent): + pw,ph = parent.GetSizeTuple() + if self.side == MV_HOR: + x = 2 + y = ph - SH_SIZE + w = CR_SIZE + h = SH_SIZE + else: + x = pw - SH_SIZE + y = 4 + SH_SIZE # Make provision for closer + w = SH_SIZE + h = CR_SIZE + return (x,y,w,h) + + def OnSize(self,evt): + x,y,w,h = self.CalcSizePos(self.GetParent()) + self.SetDimensions(x,y,w,h) + + def OnLeave(self,evt): + self.SetCursor(wxStockCursor(wxCURSOR_ARROW)) + + def OnEnter(self,evt): + if self.side == MV_HOR: + self.SetCursor(wxStockCursor(wxCURSOR_HAND)) + else: + self.SetCursor(wxStockCursor(wxCURSOR_POINT_LEFT)) + + def OnMouseMove(self,evt): + if self.isDrag: + parent = self.GetParent() + DrawSash(parent,self.px,self.py,self.side) + self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) + self.px,self.py = parent.ScreenToClientXY(self.px,self.py) + DrawSash(parent,self.px,self.py,self.side) + else: + evt.Skip() + + def OnPress(self,evt): + self.isDrag = True + parent = self.GetParent() + self.px,self.py = self.ClientToScreenXY(evt.m_x,evt.m_y) + self.px,self.py = parent.ScreenToClientXY(self.px,self.py) + DrawSash(parent,self.px,self.py,self.side) + self.CaptureMouse() + + def OnRelease(self,evt): + if self.isDrag: + parent = self.GetParent() + DrawSash(parent,self.px,self.py,self.side) + self.ReleaseMouse() + self.isDrag = False + + if self.side == MV_HOR: + parent.AddLeaf(MV_VER,self.py) + else: + parent.AddLeaf(MV_HOR,self.px) + else: + evt.Skip() + + def OnPaint(self,evt): + dc = wxPaintDC(self) + dc.SetBackground(wxBrush(self.GetBackgroundColour(),wxSOLID)) + dc.Clear() + + highlight = wxPen(wxSystemSettings_GetSystemColour( + wxSYS_COLOUR_BTNHIGHLIGHT),1,wxSOLID) + shadow = wxPen(wxSystemSettings_GetSystemColour( + wxSYS_COLOUR_BTNSHADOW),1,wxSOLID) + black = wxPen(wxBLACK,1,wxSOLID) + w,h = self.GetSizeTuple() + w -= 1 + h -= 1 + + # Draw outline + dc.SetPen(highlight) + dc.DrawLine(0,0,0,h) + dc.DrawLine(0,0,w,0) + dc.SetPen(black) + dc.DrawLine(0,h,w+1,h) + dc.DrawLine(w,0,w,h) + dc.SetPen(shadow) + dc.DrawLine(w-1,2,w-1,h) + +#---------------------------------------------------------------------- + + +class MultiCloser(wxWindow): + def __init__(self,parent): + x,y,w,h = self.CalcSizePos(parent) + wxWindow.__init__(self,id = -1,parent = parent, + pos = wxPoint(x,y), + size = wxSize(w,h), + style = wxCLIP_CHILDREN) + + self.down = False + self.entered = False + + EVT_LEFT_DOWN(self,self.OnPress) + EVT_LEFT_UP(self,self.OnRelease) + EVT_PAINT(self,self.OnPaint) + EVT_LEAVE_WINDOW(self,self.OnLeave) + EVT_ENTER_WINDOW(self,self.OnEnter) + + def OnLeave(self,evt): + self.SetCursor(wxStockCursor(wxCURSOR_ARROW)) + self.entered = False + + def OnEnter(self,evt): + self.SetCursor(wxStockCursor(wxCURSOR_BULLSEYE)) + self.entered = True + + def OnPress(self,evt): + self.down = True + evt.Skip() + + def OnRelease(self,evt): + if self.down and self.entered: + self.GetParent().DestroyLeaf() + else: + evt.Skip() + self.down = False + + def OnPaint(self,evt): + dc = wxPaintDC(self) + dc.SetBackground(wxBrush(wxRED,wxSOLID)) + dc.Clear() + + def CalcSizePos(self,parent): + pw,ph = parent.GetSizeTuple() + x = pw - SH_SIZE + w = SH_SIZE + h = SH_SIZE + 2 + y = 1 + return (x,y,w,h) + + def OnSize(self,evt): + x,y,w,h = self.CalcSizePos(self.GetParent()) + self.SetDimensions(x,y,w,h) + + +#---------------------------------------------------------------------- + + +class EmptyChild(wxWindow): + def __init__(self,parent): + wxWindow.__init__(self,parent,-1, style = wxCLIP_CHILDREN) + + +#---------------------------------------------------------------------- + + +def DrawSash(win,x,y,direction): + dc = wxScreenDC() + dc.StartDrawingOnTopWin(win) + bmp = wxEmptyBitmap(8,8) + bdc = wxMemoryDC() + bdc.SelectObject(bmp) + bdc.DrawRectangle(-1,-1,10,10) + for i in range(8): + for j in range(8): + if ((i + j) & 1): + bdc.DrawPoint(i,j) + + brush = wxBrush(wxColour(0,0,0)) + brush.SetStipple(bmp) + + dc.SetBrush(brush) + dc.SetLogicalFunction(wxXOR) + + body_w,body_h = win.GetClientSizeTuple() + + if y < 0: + y = 0 + if y > body_h: + y = body_h + if x < 0: + x = 0 + if x > body_w: + x = body_w + + if direction == MV_HOR: + x = 0 + else: + y = 0 + + x,y = win.ClientToScreenXY(x,y) + + w = body_w + h = body_h + + if direction == MV_HOR: + dc.DrawRectangle(x,y-2,w,4) + else: + dc.DrawRectangle(x-2,y,4,h) + + dc.EndDrawingOnTop() diff --git a/wxPython/wxPython/lib/mvctree.py b/wxPython/wxPython/lib/mvctree.py index b00eaa3c09..cdf05f7ada 100644 --- a/wxPython/wxPython/lib/mvctree.py +++ b/wxPython/wxPython/lib/mvctree.py @@ -47,9 +47,9 @@ class MVCTreeNode: if self.kids is None: self.kids = [] self.data = data - self.expanded = false - self.selected = false - self.built = false + self.expanded = False + self.selected = False + self.built = False self.scale = 0 def GetChildren(self): @@ -136,7 +136,7 @@ class Painter: self.bgcolor = wxNamedColour("WHITE") self.fgcolor = wxNamedColour("BLUE") self.linecolor = wxNamedColour("GREY") - self.font = wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false) + self.font = wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, False) self.bmp = None def GetFont(self): @@ -239,10 +239,10 @@ class wxTreeModel: raise NotImplementedError def IsEditable(self, node): - return false + return False def SetEditable(self, node): - return false + return False class NodePainter: """ @@ -330,10 +330,10 @@ class BasicTreeModel(wxTreeModel): return not self.children.has_key(node) def IsEditable(self, node): - return false + return False def SetEditable(self, node, bool): - return false + return False class FileEditor(Editor): @@ -374,9 +374,9 @@ class FileEditor(Editor): def _key(self, evt): if evt.KeyCode() == WXK_RETURN: - self.EndEdit(true) + self.EndEdit(True) elif evt.KeyCode() == WXK_ESCAPE: - self.EndEdit(false) + self.EndEdit(False) else: evt.Skip() @@ -385,7 +385,7 @@ class FileEditor(Editor): pos = evt.GetPosition() edsize = self.editcomp.GetSize() if pos.x < 0 or pos.y < 0 or pos.x > edsize.width or pos.y > edsize.height: - self.EndEdit(false) + self.EndEdit(False) class FileWrapper: @@ -405,11 +405,10 @@ class FSTreeModel(BasicTreeModel): """ def __init__(self, path): BasicTreeModel.__init__(self) - import string - fw = FileWrapper(path, string.split(path, os.sep)[-1]) + fw = FileWrapper(path, path.split(os.sep)[-1]) self._Build(path, fw) self.SetRoot(fw) - self._editable = true + self._editable = True def _Build(self, path, fileWrapper): for name in os.listdir(path): fw = FileWrapper(path, name) @@ -431,13 +430,12 @@ class LateFSTreeModel(FSTreeModel): """ def __init__(self, path): BasicTreeModel.__init__(self) - import string - name = string.split(path, os.sep)[-1] + name = path.split(os.sep)[-1] pathpart = path[:-len(name)] fw = FileWrapper(pathpart, name) self._Build(path, fw) self.SetRoot(fw) - self._editable = true + self._editable = True self.children = {} self.parents = {} def _Build(self, path, parent): @@ -496,8 +494,8 @@ class Rect: if other.y >= self.y: if other.width + other.x <= self.width + self.x: if other.height + other.y <= self.height + self.y: - return true - return false + return True + return False def __str__(self): return "Rect: " + str([self.x, self.y, self.width, self.height]) @@ -616,7 +614,7 @@ class TreePainter(Painter): if node.expanded: for kid in node.kids: if not self.paintWalk(kid, dc, paintRects): - return false + return False for kid in node.kids: px = (kid.projx - self.tree.layout.NODE_STEP) + 5 py = kid.projy + kid.height/2 @@ -640,7 +638,7 @@ class TreePainter(Painter): if not node.expanded: dc.DrawLine(px, py -2, px, py + 3) dc.DrawLine(px -2, py, px + 3, py) - return true + return True def OnMouse(self, evt): Painter.OnMouse(self, evt) @@ -752,12 +750,12 @@ class wxMVCTree(wxScrolledWindow): painter = None, *args, **kwargs): apply(wxScrolledWindow.__init__, (self, parent, id), kwargs) self.nodemap = {} - self._multiselect = false + self._multiselect = False self._selections = [] - self._assumeChildren = false - self._scrollx = false - self._scrolly = false - self.doubleBuffered = false + self._assumeChildren = False + self._scrollx = False + self._scrolly = False + self.doubleBuffered = False self._lastPhysicalSize = self.GetSize() self._editors = [] if not model: @@ -773,10 +771,10 @@ class wxMVCTree(wxScrolledWindow): if not painter: painter = TreePainter(self) self.painter = painter - self.SetFont(wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, false)) + self.SetFont(wxFont(9, wxDEFAULT, wxNORMAL, wxNORMAL, False)) EVT_MOUSE_EVENTS(self, self.OnMouse) EVT_KEY_DOWN(self, self.OnKeyDown) - self.doubleBuffered = true + self.doubleBuffered = True EVT_SIZE(self, self.OnSize) EVT_ERASE_BACKGROUND(self, self.OnEraseBackground) EVT_PAINT(self, self.OnPaint) @@ -785,7 +783,7 @@ class wxMVCTree(wxScrolledWindow): def Refresh(self): if self.doubleBuffered: self.painter.ClearBuffer() - wxScrolledWindow.Refresh(self, false) + wxScrolledWindow.Refresh(self, False) def GetPainter(self): return self.painter @@ -876,7 +874,7 @@ class wxMVCTree(wxScrolledWindow): self._selections = [] self.layoutRoot = MVCTreeNode() self.layoutRoot.data = self.model.GetRoot() - self.layoutRoot.expanded = true + self.layoutRoot.expanded = True self.LoadChildren(self.layoutRoot) self.currentRoot = self.layoutRoot self.offset = [0,0] @@ -897,7 +895,7 @@ class wxMVCTree(wxScrolledWindow): layoutNode.Add(p) p.data = self.GetModel().GetChildAt(layoutNode.data, i) self.nodemap[p.data]=p - layoutNode.built = true + layoutNode.built = True if not self._assumeChildren: for kid in layoutNode.kids: self.LoadChildren(kid) @@ -925,10 +923,10 @@ class wxMVCTree(wxScrolledWindow): return for node in nodeTuple: treenode = self.nodemap[node] - treenode.selected = true + treenode.selected = True for node in self._selections: treenode = self.nodemap[node] - node.selected = false + node.selected = False self._selections = list(nodeTuple) e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), nodeTuple[0], nodes = nodeTuple) self.GetEventHandler().ProcessEvent(e) @@ -964,9 +962,9 @@ class wxMVCTree(wxScrolledWindow): e = wxMVCTreeNotifyEvent(wxEVT_MVCTREE_END_EDIT, self.GetId(), node) self.GetEventHandler().ProcessEvent(e) if not e.notify.IsAllowed(): - return false + return False self._currentEditor = None - return true + return True def SetExpanded(self, node, bool): @@ -997,7 +995,7 @@ class wxMVCTree(wxScrolledWindow): def IsExpanded(self, node): return self.nodemap[node].expanded - def AddToSelection(self, nodeOrTuple, enableMulti = true, shiftMulti = false): + def AddToSelection(self, nodeOrTuple, enableMulti = True, shiftMulti = False): nodeTuple = nodeOrTuple if type(nodeOrTuple)!= type(()): nodeTuple = (nodeOrTuple,) @@ -1009,13 +1007,13 @@ class wxMVCTree(wxScrolledWindow): if not (self.IsMultiSelect() and (enableMulti or shiftMulti)): for node in self._selections: treenode = self.nodemap[node] - treenode.selected = false + treenode.selected = False changeparents.append(treenode) node = nodeTuple[0] self._selections = [node] treenode = self.nodemap[node] changeparents.append(treenode) - treenode.selected = true + treenode.selected = True else: if shiftMulti: for node in nodeTuple: @@ -1026,11 +1024,11 @@ class wxMVCTree(wxScrolledWindow): for kid in oldtreenode.parent.kids: if kid == treenode or kid == oldtreenode: found = not found - kid.selected = true + kid.selected = True self._selections.append(kid.data) changeparents.append(kid) elif found: - kid.selected = true + kid.selected = True self._selections.append(kid.data) changeparents.append(kid) else: @@ -1040,7 +1038,7 @@ class wxMVCTree(wxScrolledWindow): except ValueError: self._selections.append(node) treenode = self.nodemap[node] - treenode.selected = true + treenode.selected = True changeparents.append(treenode) e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), nodeTuple[0], nodes = nodeTuple) self.GetEventHandler().ProcessEvent(e) @@ -1059,7 +1057,7 @@ class wxMVCTree(wxScrolledWindow): self._selections.remove(node) treenode = self.nodemap[node] changeparents.append(treenode) - treenode.selected = false + treenode.selected = False e = wxMVCTreeEvent(wxEVT_MVCTREE_SEL_CHANGED, self.GetId(), node, nodes = nodeTuple) self.GetEventHandler().ProcessEvent(e) dc = wxClientDC(self) @@ -1103,14 +1101,14 @@ class wxMVCTree(wxScrolledWindow): to paint the control. """ try: - self.EnableScrolling(false, false) + self.EnableScrolling(False, False) if not self.laidOut: self.layout.Layout(self.currentRoot) - self.laidOut = true - self.transformed = false + self.laidOut = True + self.transformed = False if not self.transformed: self.transform.Transform(self.currentRoot, self.offset, self.rotation) - self.transformed = true + self.transformed = True tsize = None tsize = list(self.transform.GetSize()) tsize[0] = tsize[0] + 50 diff --git a/wxPython/wxPython/lib/popupctl.py b/wxPython/wxPython/lib/popupctl.py new file mode 100644 index 0000000000..466e06f77d --- /dev/null +++ b/wxPython/wxPython/lib/popupctl.py @@ -0,0 +1,243 @@ +#---------------------------------------------------------------------- +# Name: popup +# Purpose: Generic popup control +# +# Author: Gerrit van Dyk +# +# Created: 2002/11/20 +# Version: 0.1 +# RCS-ID: $Id$ +# License: wxWindows license +#---------------------------------------------------------------------- + +from wxPython.wx import * +from wxPython.lib.buttons import wxGenButtonEvent + + +class PopButton(wxPyControl): + def __init__(self,*_args,**_kwargs): + apply(wxPyControl.__init__,(self,) + _args,_kwargs) + + self.up = True + self.didDown = False + + self.InitColours() + + EVT_LEFT_DOWN(self, self.OnLeftDown) + EVT_LEFT_UP(self, self.OnLeftUp) + EVT_MOTION(self, self.OnMotion) + EVT_PAINT(self, self.OnPaint) + + def InitColours(self): + faceClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE) + self.faceDnClr = faceClr + self.SetBackgroundColour(faceClr) + + shadowClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNSHADOW) + highlightClr = wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNHIGHLIGHT) + self.shadowPen = wxPen(shadowClr, 1, wxSOLID) + self.highlightPen = wxPen(highlightClr, 1, wxSOLID) + self.blackPen = wxPen(wxBLACK, 1, wxSOLID) + + def Notify(self): + evt = wxGenButtonEvent(wxEVT_COMMAND_BUTTON_CLICKED, self.GetId()) + evt.SetIsDown(not self.up) + evt.SetButtonObj(self) + evt.SetEventObject(self) + self.GetEventHandler().ProcessEvent(evt) + + def OnEraseBackground(self, event): + pass + + def OnLeftDown(self, event): + if not self.IsEnabled(): + return + self.didDown = True + self.up = False + self.CaptureMouse() + self.GetParent().textCtrl.SetFocus() + self.Refresh() + event.Skip() + + def OnLeftUp(self, event): + if not self.IsEnabled(): + return + if self.didDown: + self.ReleaseMouse() + if not self.up: + self.Notify() + self.up = True + self.Refresh() + self.didDown = False + event.Skip() + + def OnMotion(self, event): + if not self.IsEnabled(): + return + if event.LeftIsDown(): + if self.didDown: + x,y = event.GetPositionTuple() + w,h = self.GetClientSizeTuple() + if self.up and x<w and x>=0 and y<h and y>=0: + self.up = False + self.Refresh() + return + if not self.up and (x<0 or y<0 or x>=w or y>=h): + self.up = True + self.Refresh() + return + event.Skip() + + def DrawBezel(self, dc, x1, y1, x2, y2): + # draw the upper left sides + if self.up: + dc.SetPen(self.highlightPen) + else: + dc.SetPen(self.shadowPen) + for i in range(2): + dc.DrawLine(x1+i, y1, x1+i, y2-i) + dc.DrawLine(x1, y1+i, x2-i, y1+i) + + # draw the lower right sides + if self.up: + dc.SetPen(self.shadowPen) + else: + dc.SetPen(self.highlightPen) + for i in range(2): + dc.DrawLine(x1+i, y2-i, x2+1, y2-i) + dc.DrawLine(x2-i, y1+i, x2-i, y2) + + def DrawArrow(self,dc): + size = self.GetSize() + mx = size.x / 2 + my = size.y / 2 + dc.SetPen(self.highlightPen) + dc.DrawLine(mx-5,my-5,mx+5,my-5) + dc.DrawLine(mx-5,my-5,mx,my+5) + dc.SetPen(self.shadowPen) + dc.DrawLine(mx+4,my-5,mx,my+5) + dc.SetPen(self.blackPen) + dc.DrawLine(mx+5,my-5,mx,my+5) + + def OnPaint(self, event): + width, height = self.GetClientSizeTuple() + x1 = y1 = 0 + x2 = width - 1 + y2 = height - 1 + dc = wxBufferedPaintDC(self) + if self.up: + dc.SetBackground(wxBrush(self.GetBackgroundColour(), wxSOLID)) + else: + dc.SetBackground(wxBrush(self.faceDnClr, wxSOLID)) + dc.Clear() + self.DrawBezel(dc, x1, y1, x2, y2) + self.DrawArrow(dc) + + +#--------------------------------------------------------------------------- + + +# Tried to use wxPopupWindow but the control misbehaves on MSW +class wxPopupDialog(wxDialog): + def __init__(self,parent,content = None): + wxDialog.__init__(self,parent,-1,'', style = wxSTAY_ON_TOP) + + self.ctrl = parent + self.win = wxWindow(self,-1,pos = wxPoint(0,0),style = 0) + + if content: + self.SetContent(content) + + def SetContent(self,content): + self.content = content + self.content.Reparent(self.win) + self.content.Show(True) + self.win.SetClientSize(self.content.GetSize()) + self.SetSize(self.win.GetSize()) + + def Display(self): + pos = self.ctrl.ClientToScreen( (0,0) ) + dSize = wxGetDisplaySize() + selfSize = self.GetSize() + tcSize = self.ctrl.GetSize() + + pos.x -= (selfSize.x - tcSize.x) / 2 + if pos.x + selfSize.x > dSize.x: + pos.x = dSize.x - selfSize.x + if pos.x < 0: + pos.x = 0 + + pos.y += tcSize.height + if pos.y + selfSize.y > dSize.y: + pos.y = dSize.y - selfSize.y + if pos.y < 0: + pos.y = 0 + + self.MoveXY(pos.x,pos.y) + + self.ctrl.FormatContent() + + self.ShowModal() + + +#--------------------------------------------------------------------------- + + +class wxPopupControl(wxPyControl): + def __init__(self,*_args,**_kwargs): + if _kwargs.has_key('value'): + del _kwargs['value'] + apply(wxPyControl.__init__,(self,) + _args,_kwargs) + + self.textCtrl = wxTextCtrl(self,-1,'',pos = wxPoint(0,0)) + self.bCtrl = PopButton(self,-1) + self.pop = None + self.content = None + self.OnSize(None) + + EVT_SIZE(self,self.OnSize) + EVT_BUTTON(self.bCtrl,self.bCtrl.GetId(),self.OnButton) + + def OnSize(self,evt): + w,h = self.GetClientSizeTuple() + self.textCtrl.SetDimensions(0,0,w-17,h) + self.bCtrl.SetDimensions(w-17,0,17,h) + + def OnButton(self,evt): + if not self.pop: + if self.content: + self.pop = wxPopupDialog(self,self.content) + del self.content + else: + print 'No Content to pop' + if self.pop: + self.pop.Display() + + def Enable(self,flag): + wxPyControl.Enable(self,flag) + self.textCtrl.Enable(flag) + self.bCtrl.Enable(flag) + + def SetPopupContent(self,content): + if not self.pop: + self.content = content + self.content.Show(False) + else: + self.pop.SetContent(content) + + def FormatContent(self): + pass + + def PopDown(self): + if self.pop: + self.pop.EndModal(1) + + def SetValue(self,value): + self.textCtrl.SetValue(value) + + def GetValue(self): + return self.textCtrl.GetValue() + + +# an alias +wxPopupCtrl = wxPopupControl diff --git a/wxPython/wxPython/lib/printout.py b/wxPython/wxPython/lib/printout.py index 33f3a24432..56814081dc 100644 --- a/wxPython/wxPython/lib/printout.py +++ b/wxPython/wxPython/lib/printout.py @@ -15,7 +15,7 @@ # add index to data list after parsing total pages for paging #---------------------------------------------------------------------------- -import os, sys, string, copy +import os, sys, copy from wxPython.wx import * import copy @@ -45,14 +45,14 @@ class PrintBase: fcolour = font["Colour"] return wxColour(fcolour[0], fcolour[1], fcolour[2]) - def OutTextRegion(self, textout, txtdraw = TRUE): - textlines = string.splitfields(textout, '\n') + def OutTextRegion(self, textout, txtdraw = True): + textlines = textout.split('\n') y = copy.copy(self.y) + self.pt_space_before for text in textlines: remain = 'X' while remain != "": vout, remain = self.SetFlow(text, self.region) - if self.draw == TRUE and txtdraw == TRUE: + if self.draw == True and txtdraw == True: test_out = self.TestFull(vout) if self.align == wxALIGN_LEFT: self.DC.DrawText(test_out, self.indent+self.pcell_left_margin, y) @@ -88,12 +88,12 @@ class PrintBase: def SetFlow(self, ln_text, width): width = width - self.pcell_right_margin text = "" - split = string.split(ln_text) + split = ln_text.split() if len(split) == 1: return ln_text, "" try: - w, h = self.DC.GetTextExtent(split[0]) + w, h = self.DC.GetTextExtent(" " + split[0]) if w >= width: return ln_text, "" except: @@ -101,7 +101,7 @@ class PrintBase: cnt = 0 for word in split: - bword = " " + word # blank + word + bword = " " + word # blank + word length = len(bword) w, h = self.DC.GetTextExtent(text + bword) @@ -109,12 +109,12 @@ class PrintBase: text = text + bword cnt = cnt + 1 else: - remain = string.joinfields(split[cnt:],' ') - text = string.strip(text) + remain = ' '.join(split[cnt:]) + text = text.strip() return text, remain - remain = string.joinfields(split[cnt:],' ') - vout = string.strip(text) + remain = ' '.join(split[cnt:]) + vout = text.strip() return vout, remain def SetChar(self, ln_text, width): # truncate string to fit into width @@ -128,8 +128,8 @@ class PrintBase: text = text + val return text - def OutTextPageWidth(self, textout, y_out, align, indent, txtdraw = TRUE): - textlines = string.splitfields(textout, '\n') + def OutTextPageWidth(self, textout, y_out, align, indent, txtdraw = True): + textlines = textout.split('\n') y = copy.copy(y_out) pagew = self.parent.page_width * self.pwidth # full page width @@ -140,7 +140,7 @@ class PrintBase: remain = 'X' while remain != "": vout, remain = self.SetFlow(text, pagew) - if self.draw == TRUE and txtdraw == TRUE: + if self.draw == True and txtdraw == True: test_out = vout if align == wxALIGN_LEFT: self.DC.DrawText(test_out, indent, y) @@ -169,7 +169,7 @@ class PrintBase: def GetNow(self): full = str(wxDateTime_Now()) # get the current date and time in print format - flds = string.splitfields(full) + flds = full.split() date = flds[0] time = flds[1] return date, time @@ -350,26 +350,26 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): x, y = self.DC.GetTextExtent("W") self.space = y - if self.total_pages == None: + if self.total_pages is None: self.GetTotalPages() # total pages for display/printing self.data_cnt = self.page_index[self.page-1] - self.draw = TRUE + self.draw = True self.PrintHeader() self.PrintFooter() self.OutPage() def GetTotalPages(self): self.data_cnt = 0 - self.draw = FALSE + self.draw = False self.page_index = [0] cnt = 0 while 1: test = self.OutPage() self.page_index.append(self.data_cnt) - if test == FALSE: + if test == False: break cnt = cnt + 1 @@ -383,23 +383,23 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): if self.label != []: # check if header defined self.PrintLabel() else: - return FALSE + return False for val in self.data: try: row_val = self.data[self.data_cnt] except: self.FinishDraw() - return FALSE + return False - max_y = self.PrintRow(row_val, FALSE) # test to see if row will fit in remaining space + max_y = self.PrintRow(row_val, False) # test to see if row will fit in remaining space test = max_y + self.space if test > self.y_end: break self.ColourRowCells(max_y-self.y+self.space) # colour the row/column - max_y = self.PrintRow(row_val, TRUE) # row fits - print text + max_y = self.PrintRow(row_val, True) # row fits - print text self.DrawGridLine() # top line of cell self.y = max_y + self.space @@ -411,9 +411,9 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.FinishDraw() if self.data_cnt == len(self.data): # last value in list - return FALSE + return False - return TRUE + return True def PrintLabel(self): @@ -431,7 +431,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.align = wxALIGN_LEFT - max_out = self.OutTextRegion(vtxt, TRUE) + max_out = self.OutTextRegion(vtxt, True) if max_out > max_y: max_y = max_out self.col = self.col + 1 @@ -440,7 +440,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.y = max_y + self.label_space def PrintHeader(self): # print the header array - if self.draw == FALSE: + if self.draw == False: return for val in self.parent.header: @@ -457,10 +457,10 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): else: addtext = "" - self.OutTextPageWidth(text+addtext, self.pheader_margin, val["Align"], header_indent, TRUE) + self.OutTextPageWidth(text+addtext, self.pheader_margin, val["Align"], header_indent, True) def PrintFooter(self): # print the header array - if self.draw == FALSE: + if self.draw == False: return footer_pos = self.parent.page_height * self.pheight - self.pfooter_margin + self.vertical_offset @@ -484,7 +484,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): else: addtext = "" - self.OutTextPageWidth(text+addtext, footer_pos, val["Align"], footer_indent, TRUE) + self.OutTextPageWidth(text+addtext, footer_pos, val["Align"], footer_indent, True) def LabelColorRow(self, colour): @@ -494,13 +494,13 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.DC.DrawRectangle(self.column[0], self.y, self.end_x-self.column[0]+1, height) def ColourRowCells(self, height): - if self.draw == FALSE: + if self.draw == False: return col = 0 for colour in self.column_bgcolour: cellcolour = self.GetCellColour(self.data_cnt, col) - if cellcolour != None: + if cellcolour is not None: colour = cellcolour brush = wxBrush(colour, wxSOLID) @@ -512,7 +512,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.DC.DrawRectangle(start_x, self.y, width, height) col = col + 1 - def PrintRow(self, row_val, draw = TRUE, align = wxALIGN_LEFT): + def PrintRow(self, row_val, draw = True, align = wxALIGN_LEFT): self.SetPrintFont(self.text_font) self.pt_space_before = self.text_pt_space_before # set the point spacing @@ -527,7 +527,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): fcolour = self.column_txtcolour[self.col] # set font colour celltext = self.GetCellText(self.data_cnt, self.col) - if celltext != None: + if celltext is not None: fcolour = celltext # override the column colour self.DC.SetTextForeground(fcolour) @@ -565,7 +565,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.DrawColumns() # draw all vertical lines def DrawGridLine(self): - if self.draw == TRUE: + if self.draw == True: try: size = self.row_line_size[self.data_cnt] except: @@ -583,7 +583,7 @@ class PrintTableDraw(wxScrolledWindow, PrintBase): self.DC.DrawLine(self.column[0], y_out, self.end_x, y_out) def DrawColumns(self): - if self.draw == TRUE: + if self.draw == True: col = 0 for val in self.column: try: @@ -800,30 +800,30 @@ class PrintTable: def SetHeader(self, text = "", type = "Text", font=None, align = None, indent = None, colour = None, size = None): set = { "Text": text } - if font == None: + if font is None: set["Font"] = copy.copy(self.default_font) else: set["Font"] = font - if colour != None: + if colour is not None: setfont = set["Font"] setfont["Colour"] = self.GetColour(colour) - if size != None: + if size is not None: setfont = set["Font"] setfont["Size"] = size - if align == None: + if align is None: set["Align"] = self.header_align else: set["Align"] = align - if indent == None: + if indent is None: set["Indent"] = self.header_indent else: set["Indent"] = indent - if type == None: + if type is None: set["Type"] = self.header_type else: set["Type"] = type @@ -833,30 +833,30 @@ class PrintTable: def SetFooter(self, text = "", type = None, font=None, align = None, indent = None, colour = None, size = None): set = { "Text": text } - if font == None: + if font is None: set["Font"] = copy.copy(self.default_font) else: set["Font"] = font - if colour != None: + if colour is not None: setfont = set["Font"] setfont["Colour"] = self.GetColour(colour) - if size != None: + if size is not None: setfont = set["Font"] setfont["Size"] = size - if align == None: + if align is None: set["Align"] = self.footer_align else: set["Align"] = align - if indent == None: + if indent is None: set["Indent"] = self.footer_indent else: set["Indent"] = indent - if type == None: + if type is None: set["Type"] = self.footer_type else: set["Type"] = type @@ -879,7 +879,7 @@ class PrintTable: if self.parentFrame: frame.SetPosition(self.preview_frame_pos) frame.SetSize(self.preview_frame_size) - frame.Show(true) + frame.Show(True) def Print(self): pdd = wxPrintDialogData() @@ -905,7 +905,7 @@ class PrintTable: if self.preview is None: table.SetPSize(size[0]/self.page_width, size[1]/self.page_height) table.SetPTSize(size[0], size[1]) - table.SetPreview(FALSE) + table.SetPreview(False) else: if self.preview == 1: table.scale = self.scale @@ -933,9 +933,9 @@ class PrintTable: def HasPage(self, page): if page <= self.page_total: - return true + return True else: - return false + return False def SetPage(self, page): self.page = page @@ -956,9 +956,9 @@ class PrintTable: class PrintGrid: def __init__(self, parent, grid, format = [], total_col = None, total_row = None): - if total_row == None: + if total_row is None: total_row = grid.GetNumberRows() - if total_col == None: + if total_col is None: total_col = grid.GetNumberCols() self.total_row = total_row @@ -1025,7 +1025,7 @@ class SetPrintout(wxPrintout): end = self.canvas.HasPage(page) return end except: - return true + return True def GetPageInfo(self): try: @@ -1084,7 +1084,7 @@ class SetPrintout(wxPrintout): self.canvas.SetPageSize(self.psizew, self.psizeh) self.canvas.DoDrawing(dc) - return true + return True diff --git a/wxPython/wxPython/lib/pubsub.py b/wxPython/wxPython/lib/pubsub.py new file mode 100644 index 0000000000..c2b6968094 --- /dev/null +++ b/wxPython/wxPython/lib/pubsub.py @@ -0,0 +1,382 @@ +#--------------------------------------------------------------------------- +# Name: wxPython.lib.pubsub +# Purpose: The Publish/Subscribe framework used by evtmgr.EventManager +# +# Author: Robb Shecter and Robin Dunn +# +# Created: 12-December-2002 +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Robb Shecter <robb@acm.org> +# Licence: wxWindows license +#--------------------------------------------------------------------------- +""" +This module has classes for implementing the Publish/Subscribe design +pattern. + +It's a very flexible PS implementation: The message topics are tuples +of any length, containing any objects (that can be used as hash keys). +A subscriber's topic matches any message topic for which it's a +sublist. + +It also has many optimizations to favor time efficiency (ie., run-time +speed). I did this because I use it to support extreme uses. For +example, piping every wxWindows mouse event through to multiple +listeners, and expecting the app to have no noticeable slowdown. This +has made the code somewhat obfuscated, but I've done my best to +document it. + +The Server and Message classes are the two that clients interact +with.. + +This module is compatible with Python 2.1. + +Author: Robb Shecter +""" + +#--------------------------------------------------------------------------- + +class Publisher: + """ + The publish/subscribe server. This class is a Singleton. + """ + def __init__(self): + self.topicDict = {} + self.functionDict = {} + self.subscribeAllList = [] + self.messageCount = 0 + self.deliveryCount = 0 + + + # + # Public API + # + + def subscribe(self, topic, listener): + """ + Add the given subscription to the list. This will + add an entry recording the fact that the listener wants + to get messages for (at least) the given topic. This + method may be called multiple times for one listener, + registering it with many topics. It can also be invoked + many times for a particular topic, each time with a + different listener. + + listener: expected to be either a method or function that + takes zero or one parameters. (Not counting 'self' in the + case of methods. If it accepts a parameter, it will be given + a reference to a Message object. + + topic: will be converted to a tuple if it isn't one. + It's a pattern matches any topic that it's a sublist + of. For example, this pattern: + + ('sports',) + + would match these: + + ('sports',) + ('sports', 'baseball') + ('sports', 'baseball', 'highscores') + + but not these: + + () + ('news') + (12345) + """ + if not callable(listener): + raise TypeError('The P/S listener, '+`listener`+', is not callable.') + aTopic = Topic(topic) + + # Determine now (at registration time) how many parameters + # the listener expects, and get a reference to a function which + # calls it correctly at message-send time. + callableVersion = self.__makeCallable(listener) + + # Add this tuple to a list which is in a dict keyed by + # the topic's first element. + self.__addTopicToCorrectList(aTopic, listener, callableVersion) + + # Add to a dict in order to speed-up unsubscribing. + self.__addFunctionLookup(listener, aTopic) + + + def unsubscribe(self, listener): + """ + Remove the given listener from the registry, + for all topics that it's associated with. + """ + if not callable(listener): + raise TypeError('The P/S listener, '+`listener`+', is not callable.') + topicList = self.getAssociatedTopics(listener) + for aTopic in topicList: + subscriberList = self.__getTopicList(aTopic) + listToKeep = [] + for subscriber in subscriberList: + if subscriber[0] != listener: + listToKeep.append(subscriber) + self.__setTopicList(aTopic, listToKeep) + self.__delFunctionLookup(listener) + + + def getAssociatedTopics(self, listener): + """ + Return a list of topics the given listener is + registered with. + """ + return self.functionDict.get(listener, []) + + + def sendMessage(self, topic, data=None): + """ + Relay a message to registered listeners. + """ + aTopic = Topic(topic) + message = Message(aTopic.items, data) + topicList = self.__getTopicList(aTopic) + + # Send to the matching topics + for subscriber in topicList: + if subscriber[1].matches(aTopic): + subscriber[2](message) + + # Send to any listeners registered for ALL + for subscriber in self.subscribeAllList: + subscriber[2](message) + + + # + # Private methods + # + + def __makeCallable(self, function): + """ + Return a function that is what the server + will actually call. + + This is a time optimization: this removes a test + for the number of parameters from the inner loop + of sendMessage(). + """ + parameters = self.__parameterCount(function) + if parameters == 0: + # Return a function that calls the listener + # with no arguments. + return lambda m, f=function: f() + elif parameters == 1: + # Return a function that calls the listener + # with one argument (which will be the message). + return lambda m, f=function: f(m) + else: + raise TypeError('The publish/subscribe listener, '+`function`+', has wrong parameter count') + + + def __parameterCount(self, callableObject): + """ + Return the effective number of parameters required + by the callable object. In other words, the 'self' + parameter of methods is not counted. + """ + try: + # Try to handle this like a method + return callableObject.im_func.func_code.co_argcount - 1 + except AttributeError: + pass + + try: + # Try to handle this like a function + return callableObject.func_code.co_argcount + except AttributeError: + raise 'Cannot determine if this is a method or function: '+str(callableObject) + + def __addFunctionLookup(self, aFunction, aTopic): + try: + aList = self.functionDict[aFunction] + except KeyError: + aList = [] + self.functionDict[aFunction] = aList + aList.append(aTopic) + + + def __delFunctionLookup(self, aFunction): + try: + del self.functionDict[aFunction] + except KeyError: + print 'Warning: listener not found. Logic error in PublishSubscribe?', aFunction + + + def __addTopicToCorrectList(self, topic, listener, callableVersion): + if len(topic.items) == 0: + self.subscribeAllList.append((listener, topic, callableVersion)) + else: + self.__getTopicList(topic).append((listener, topic, callableVersion)) + + + def __getTopicList(self, aTopic): + """ + Return the correct sublist of subscribers based on the + given topic. + """ + try: + elementZero = aTopic.items[0] + except IndexError: + return self.subscribeAllList + + try: + subList = self.topicDict[elementZero] + except KeyError: + subList = [] + self.topicDict[elementZero] = subList + return subList + + + def __setTopicList(self, aTopic, aSubscriberList): + try: + self.topicDict[aTopic.items[0]] = aSubscriberList + except IndexError: + self.subscribeAllList = aSubscriberList + + + def __call__(self): + return self + + +# Create an instance with the same name as the class, effectivly +# hiding the class object so it can't be instantiated any more. From +# this point forward any calls to Publisher() will invoke the __call__ +# of this instance which just returns itself. +# +# The only flaw with this approach is that you can't derive a new +# class from Publisher without jumping through hoops. If this ever +# becomes an issue then a new Singleton implementaion will need to be +# employed. +Publisher = Publisher() + + +#--------------------------------------------------------------------------- + +class Message: + """ + A simple container object for the two components of + a message; the topic and the data. + """ + def __init__(self, topic, data): + self.topic = topic + self.data = data + + def __str__(self): + return '[Topic: '+`self.topic`+', Data: '+`self.data`+']' + + +#--------------------------------------------------------------------------- + +class Topic: + """ + A class that represents a publish/subscribe topic. + Currently, it's only used internally in the framework; the + API expects and returns plain old tuples. + + It currently exists mostly as a place to keep the matches() + function. This function, though, could also correctly be + seen as an attribute of the P/S server. Getting rid of this + class would also mean one fewer object instantiation per + message send. + """ + + listType = type([]) + tupleType = type(()) + + def __init__(self, items): + # Make sure we have a tuple. + if type(items) == self.__class__.listType: + items = tuple(items) + elif type(items) != self.__class__.tupleType: + items = (items,) + self.items = items + self.length = len(items) + + + def matches(self, aTopic): + """ + Consider myself to be a topic pattern, + and return True if I match the given specific + topic. For example, + a = ('sports') + b = ('sports','baseball') + a.matches(b) --> 1 + b.matches(a) --> 0 + """ + # The question this method answers is equivalent to; + # is my list a sublist of aTopic's? So, my algorithm + # is: 1) make a copy of the aTopic list which is + # truncated to the pattern's length. 2) Test for + # equality. + # + # This algorithm may be somewhat memory-intensive, + # because it creates a temporary list on each + # call to match. A possible to-do would be to + # re-write this with a hand-coded loop. + return (self.items == aTopic.items[:self.length]) + + + def __repr__(self): + import string + return '<Topic>' + string.join(map(repr, self.items), ', ') + '</Topic>' + + + def __eq__(self, aTopic): + """ + Return True if I equal the given topic. We're considered + equal if our tuples are equal. + """ + if type(self) != type(aTopic): + return 0 + else: + return self.items == aTopic.items + + + def __ne__(self, aTopic): + """ + Return False if I equal the given topic. + """ + return not self == aTopic + + +#--------------------------------------------------------------------------- + + +# +# Code for a simple command-line test +# +if __name__ == '__main__': + + class SimpleListener: + def __init__(self, number): + self.number = number + def notify(self, message): + print '#'+str(self.number)+' got the message:', message + + # Build a list of ten listeners. + lList = [] + for x in range(10): + lList.append(SimpleListener(x)) + + server = Publisher() + + # Everyone's interested in politics... + for x in lList: + Publisher().subscribe(topic='politics', listener=x.notify) # also tests singleton + + # But only the first four are interested in trivia. + for x in lList[:4]: + server.subscribe(topic='trivia', listener=x.notify) + + # This one subscribes to everything. + everythingListener = SimpleListener(999) + server.subscribe(topic=(), listener=everythingListener.notify) + + # Now send out two messages, testing topic matching. + server.sendMessage(topic='trivia', data='What is the capitol of Oregon?') + server.sendMessage(topic=('politics','germany'), data='The Greens have picked up another seat in the Bundestag.') + +#--------------------------------------------------------------------------- diff --git a/wxPython/wxPython/lib/pyshell.py b/wxPython/wxPython/lib/pyshell.py index 7457f3c830..9e47e6a537 100644 --- a/wxPython/wxPython/lib/pyshell.py +++ b/wxPython/wxPython/lib/pyshell.py @@ -30,7 +30,7 @@ etc... But it's a good start. from wxPython.wx import * from wxPython.stc import * -import sys, string, keyword +import sys, keyword from code import InteractiveInterpreter #---------------------------------------------------------------------- @@ -238,7 +238,7 @@ class PyShellWindow(wxStyledTextCtrl, InteractiveInterpreter): lastPos = self.GetTextLength() if self.lastPromptPos and self.lastPromptPos != lastPos: self.SetLexer(wxSTC_LEX_PYTHON) - self.SetKeywords(0, string.join(keyword.kwlist)) + self.SetKeywords(0, ' '.join(keyword.kwlist)) self.Colourise(self.lastPromptPos, lastPos) @@ -248,7 +248,7 @@ class PyShellWindow(wxStyledTextCtrl, InteractiveInterpreter): def OnUpdateUI(self, evt): # check for matching braces braceAtCaret = -1 - braceOpposite = -1 + braceOpposite = -1 charBefore = None caretPos = self.GetCurrentPos() if caretPos > 0: diff --git a/wxPython/wxPython/lib/rpcMixin.py b/wxPython/wxPython/lib/rpcMixin.py index 26a640a3d0..2ca4695689 100644 --- a/wxPython/wxPython/lib/rpcMixin.py +++ b/wxPython/wxPython/lib/rpcMixin.py @@ -72,7 +72,6 @@ from wxPython.wx import * import xmlrpcserver,xmlrpclib import threading import SocketServer -import string import new import sys @@ -305,7 +304,7 @@ class rpcMixin: event.rpcStatusLock.acquire() doQuit = 0 try: - methsplit = string.split(event.method,'.') + methsplit = event.method.split('.') meth = self for piece in methsplit: meth = getattr(meth,piece) @@ -388,8 +387,8 @@ if __name__ == '__main__': self.frame = rpcFrame(NULL, -1, "wxPython RPCDemo", wxDefaultPosition, wxSize(300,300), rpcHost='localhost',rpcPort=port) - self.frame.Show(TRUE) - return TRUE + self.frame.Show(True) + return True def testcon(port): diff --git a/wxPython/wxPython/lib/scrolledpanel.py b/wxPython/wxPython/lib/scrolledpanel.py new file mode 100644 index 0000000000..b8da67e498 --- /dev/null +++ b/wxPython/wxPython/lib/scrolledpanel.py @@ -0,0 +1,85 @@ +#---------------------------------------------------------------------------- +# Name: wxScrolledPanel.py +# Author: Will Sadkin +# Created: 03/21/2003 +# Copyright: (c) 2003 by Will Sadkin +# RCS-ID: $Id$ +# License: wxWindows license +#---------------------------------------------------------------------------- +# + +from wxPython.wx import * + + +class wxScrolledPanel( wxScrolledWindow ): + """ +wxScrolledPanel fills a "hole" in the implementation of wxScrolledWindow, +providing automatic scrollbar and scrolling behavior and the tab traversal +management that wxScrolledWindow lacks. This code was based on the original +demo code showing how to do this, but is now available for general use +as a proper class (and the demo is now converted to just use it.) +""" + def __init__(self, parent, id=-1, + pos = wxDefaultPosition, size = wxDefaultSize, + style = wxTAB_TRAVERSAL, name = "scrolledpanel"): + + wxScrolledWindow.__init__(self, parent, -1, + pos=pos, size=size, + style=style, name=name) + + + def SetupScrolling(self, scroll_x=True, scroll_y=True, rate_x=1, rate_y=1): + """ + This function sets up the event handling necessary to handle + scrolling properly. It should be called within the __init__ + function of any class that is derived from wxScrolledPanel, + once the controls on the panel have been constructed and + thus the size of the scrolling area can be determined. + + """ + # The following is all that is needed to integrate the sizer and the + # scrolled window. + if not scroll_x: rate_x = 0 + if not scroll_y: rate_y = 0 + + self.SetScrollRate(rate_x, rate_y) + + self.GetSizer().SetVirtualSizeHints(self) + EVT_CHILD_FOCUS(self, self.OnChildFocus) + wxCallAfter(self.Scroll, 0, 0) # scroll back to top after initial events + + + def OnChildFocus(self, evt): + # If the child window that gets the focus is not visible, + # this handler will try to scroll enough to see it. + evt.Skip() + child = evt.GetWindow() + + sppu_x, sppu_y = self.GetScrollPixelsPerUnit() + vs_x, vs_y = self.GetViewStart() + cpos = child.GetPosition() + csz = child.GetSize() + new_vs_x, new_vs_y = -1, -1 + + # is it before the left edge? + if cpos.x < 0 and sppu_x > 0: + new_vs_x = cpos.x / sppu_x + + # is it above the top? + if cpos.y < 0 and sppu_y > 0: + new_vs_y = cpos.y / sppu_y + + + # is it past the right edge ? + if cpos.x + csz.width > self.GetClientSize().width and sppu_x > 0: + diff = (cpos.x + csz.width - self.GetClientSize().width) / sppu_x + new_vs_x = vs_x + diff + 1 + + # is it below the bottom ? + if cpos.y + csz.height > self.GetClientSize().height and sppu_y > 0: + diff = (cpos.y + csz.height - self.GetClientSize().height) / sppu_y + new_vs_y = vs_y + diff + 1 + + # if we need to adjust + if new_vs_x != -1 or new_vs_y != -1: + self.Scroll(new_vs_x, new_vs_y) diff --git a/wxPython/wxPython/lib/sheet.py b/wxPython/wxPython/lib/sheet.py index 4b6612a072..06d7ffd749 100644 --- a/wxPython/wxPython/lib/sheet.py +++ b/wxPython/wxPython/lib/sheet.py @@ -5,7 +5,7 @@ from wxPython.wx import * from wxPython.grid import * -from string import * +import string #--------------------------------------------------------------------------- class CTextCellEditor(wxTextCtrl): @@ -20,26 +20,26 @@ class CTextCellEditor(wxTextCtrl): key = evt.GetKeyCode() if key == WXK_DOWN: self._grid.DisableCellEditControl() # Commit the edit - self._grid.MoveCursorDown(false) # Change the current cell + self._grid.MoveCursorDown(False) # Change the current cell elif key == WXK_UP: self._grid.DisableCellEditControl() # Commit the edit - self._grid.MoveCursorUp(false) # Change the current cell + self._grid.MoveCursorUp(False) # Change the current cell elif key == WXK_LEFT: self._grid.DisableCellEditControl() # Commit the edit - self._grid.MoveCursorLeft(false) # Change the current cell + self._grid.MoveCursorLeft(False) # Change the current cell elif key == WXK_RIGHT: self._grid.DisableCellEditControl() # Commit the edit - self._grid.MoveCursorRight(false) # Change the current cell - + self._grid.MoveCursorRight(False) # Change the current cell + evt.Skip() # Continue event - + #--------------------------------------------------------------------------- class CCellEditor(wxPyGridCellEditor): """ Custom cell editor """ def __init__(self, grid): wxPyGridCellEditor.__init__(self) self._grid = grid # Save a reference to the grid - + def Create(self, parent, id, evtHandler): """ Create the actual edit control. Must derive from wxControl. Must Override @@ -68,7 +68,7 @@ class CCellEditor(wxPyGridCellEditor): """ # Call base class method. self.base_PaintBackground(self, rect, attr) - + def BeginEdit(self, row, col, grid): """ Fetch the value from the table and prepare edit control to begin editing. Set the focus to the edit control. Must Override. @@ -76,19 +76,19 @@ class CCellEditor(wxPyGridCellEditor): self._startValue = grid.GetTable().GetValue(row, col) self._tc.SetValue(self._startValue) self._tc.SetFocus() - + # Select the text when initiating an edit so that subsequent typing # replaces the contents. self._tc.SetSelection(0, self._tc.GetLastPosition()) - + def EndEdit(self, row, col, grid): - """ Commit editing the current cell. Returns true if the value has changed. + """ Commit editing the current cell. Returns True if the value has changed. If necessary, the control may be destroyed. Must Override. """ - changed = false # Assume value not changed + changed = False # Assume value not changed val = self._tc.GetValue() # Get value in edit control if val != self._startValue: # Compare - changed = true # If different then changed is true + changed = True # If different then changed is True grid.GetTable().SetValue(row, col, val) # Update the table self._startValue = '' # Clear the class' start value self._tc.SetValue('') # Clear contents of the edit control @@ -101,7 +101,7 @@ class CCellEditor(wxPyGridCellEditor): self._tc.SetInsertionPointEnd() def IsAcceptedKey(self, evt): - """ Return true to allow the given key to start editing. The base class + """ Return True to allow the given key to start editing. The base class version only checks that the event has no modifiers. F2 is special and will always start the editor. """ @@ -117,15 +117,15 @@ class CCellEditor(wxPyGridCellEditor): if key in [WXK_NUMPAD0, WXK_NUMPAD1, WXK_NUMPAD2, WXK_NUMPAD3, WXK_NUMPAD4, WXK_NUMPAD5, WXK_NUMPAD6, WXK_NUMPAD7, WXK_NUMPAD8, WXK_NUMPAD9]: ch = chr(ord('0') + key - WXK_NUMPAD0) - + elif key == WXK_BACK: # Empty text control when init w/ back key ch = "" # Handle normal keys elif key < 256 and key >= 0 and chr(key) in string.printable: ch = chr(key) if not evt.ShiftDown(): - ch = string.lower(ch) - + ch = ch.lower() + if ch is not None: # If are at this point with a key, self._tc.SetValue(ch) # replace the contents of the text control. self._tc.SetInsertionPointEnd() # Move to the end so that subsequent keys are appended @@ -150,7 +150,7 @@ class CCellEditor(wxPyGridCellEditor): class CSheet(wxGrid): def __init__(self, parent): wxGrid.__init__(self, parent, -1) - + # Init variables self._lastCol = -1 # Init last cell column clicked self._lastRow = -1 # Init last cell row clicked @@ -159,7 +159,7 @@ class CSheet(wxGrid): self.RegisterDataType(wxGRID_VALUE_STRING, wxGridCellStringRenderer(), CCellEditor(self)) - + self.CreateGrid(4, 3) # By default start with a 4 x 3 grid self.SetColLabelSize(18) # Default sizes and alignment self.SetRowLabelSize(50) @@ -167,8 +167,8 @@ class CSheet(wxGrid): self.SetColSize(0, 75) # Default column sizes self.SetColSize(1, 75) self.SetColSize(2, 75) - - # Sink events + + # Sink events EVT_GRID_CELL_LEFT_CLICK( self, self.OnLeftClick) EVT_GRID_CELL_RIGHT_CLICK( self, self.OnRightClick) EVT_GRID_CELL_LEFT_DCLICK( self, self.OnLeftDoubleClick) @@ -183,7 +183,7 @@ class CSheet(wxGrid): # Save the last cell coordinates self._lastRow, self._lastCol = event.GetRow(), event.GetCol() event.Skip() - + def OnRowSize(self, event): event.Skip() @@ -192,48 +192,48 @@ class CSheet(wxGrid): def OnCellChange(self, event): event.Skip() - + def OnLeftClick(self, event): """ Override left-click behavior to prevent left-click edit initiation """ # Save the cell clicked currCell = (event.GetRow(), event.GetCol()) - + # Suppress event if same cell clicked twice in a row. # This prevents a single-click from initiating an edit. if currCell != (self._lastRow, self._lastCol): event.Skip() - + def OnRightClick(self, event): """ Move grid cursor when a cell is right-clicked """ self.SetGridCursor( event.GetRow(), event.GetCol() ) event.Skip() - + def OnLeftDoubleClick(self, event): """ Initiate the cell editor on a double-click """ # Move grid cursor to double-clicked cell if self.CanEnableCellControl(): self.SetGridCursor( event.GetRow(), event.GetCol() ) - self.EnableCellEditControl(true) # Show the cell editor + self.EnableCellEditControl(True) # Show the cell editor event.Skip() def OnRangeSelect(self, event): """ Track which cells are selected so that copy/paste behavior can be implemented """ - # If a single cell is selected, then Selecting() returns false (0) + # If a single cell is selected, then Selecting() returns False (0) # and range coords are entire grid. In this case cancel previous selection. - # If more than one cell is selected, then Selecting() is true (1) + # If more than one cell is selected, then Selecting() is True (1) # and range accurately reflects selected cells. Save them. - # If more cells are added to a selection, selecting remains true (1) + # If more cells are added to a selection, selecting remains True (1) self._selected = None if event.Selecting(): self._selected = ((event.GetTopRow(), event.GetLeftCol()), (event.GetBottomRow(), event.GetRightCol())) event.Skip() - + def Copy(self): """ Copy the currently selected cells to the clipboard """ # TODO: raise an error when there are no cells selected? if self._selected == None: return ((r1, c1), (r2, c2)) = self._selected - + # Build a string to put on the clipboard # (Is there a faster way to do this in Python?) crlf = chr(13) + chr(10) @@ -245,7 +245,7 @@ class CSheet(wxGrid): s += tab s += self.GetCellValue(row, c2) s += crlf - + # Put the string on the clipboard if wxTheClipboard.Open(): wxTheClipboard.Clear() @@ -261,15 +261,15 @@ class CSheet(wxGrid): wxTheClipboard.Close() if not success: return # Exit on failure s = td.GetText() # Get the text - + crlf = chr(13) + chr(10) # CrLf characters tab = chr(9) # Tab character - - rows = split(s, crlf) # split into rows + + rows = s.split(crlf) # split into rows rows = rows[0:-1] # leave out last element, which is always empty for i in range(0, len(rows)): # split rows into elements - rows[i] = split(rows[i], tab) - + rows[i] = rows[i].split(tab) + # Get the starting and ending cell range to paste into if self._selected == None: # If no cells selected... r1 = self.GetGridCursorRow() # Start the paste at the current location @@ -278,7 +278,7 @@ class CSheet(wxGrid): c2 = self.GetNumberCols()-1 else: # If cells selected, only paste there ((r1, c1), (r2, c2)) = self._selected - + # Enter data into spreadsheet cells one at a time r = r1 # Init row and column counters c = c1 @@ -306,8 +306,8 @@ class CSheet(wxGrid): def SetNumberRows(self, numRows=1): """ Set the number of rows in the sheet """ # Check for non-negative number - if numRows < 0: return false - + if numRows < 0: return False + # Adjust number of rows curRows = self.GetNumberRows() if curRows < numRows: @@ -315,13 +315,13 @@ class CSheet(wxGrid): elif curRows > numRows: self.DeleteRows(numRows, curRows - numRows) - return true + return True def SetNumberCols(self, numCols=1): """ Set the number of columns in the sheet """ # Check for non-negative number - if numCols < 0: return false - + if numCols < 0: return False + # Adjust number of rows curCols = self.GetNumberCols() if curCols < numCols: @@ -329,4 +329,4 @@ class CSheet(wxGrid): elif curCols > numCols: self.DeleteCols(numCols, curCols - numCols) - return true + return True diff --git a/wxPython/wxPython/lib/shell.py b/wxPython/wxPython/lib/shell.py index 2434f55bca..c6cab9deea 100644 --- a/wxPython/wxPython/lib/shell.py +++ b/wxPython/wxPython/lib/shell.py @@ -29,7 +29,7 @@ History: __version__ ="$Revision$" # $RCSfile$ -import sys, string, code, traceback +import sys, code, traceback from wxPython.wx import * from wxPython.html import * @@ -58,11 +58,11 @@ class PyShellInput(wxPanel): tid =wxNewId() self.entry =wxTextCtrl(self, tid, style = wxTE_MULTILINE) EVT_CHAR(self.entry, self.OnChar) - self.entry.SetFont(wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, false)) + self.entry.SetFont(wxFont(9, wxMODERN, wxNORMAL, wxNORMAL, False)) sizer =wxBoxSizer(wxVERTICAL) sizer.AddMany([(self.label, 0, wxEXPAND), (self.entry, 1, wxEXPAND)]) self.SetSizer(sizer) - self.SetAutoLayout(true) + self.SetAutoLayout(True) EVT_SET_FOCUS(self, self.OnSetFocus) # when in "continuation" mode, # two consecutive newlines are required @@ -90,7 +90,7 @@ class PyShellInput(wxPanel): return text =self.entry.GetValue() # weird CRLF thingy - text =string.replace(text, "\r\n", "\n") + text = text.replace("\r\n", "\n") # see if we've finished if (not (self.first_line or text[-1] =="\n") # in continuation mode or (text[-1] =="\\") # escaped newline @@ -153,7 +153,7 @@ class PyShellOutput(wxPanel): self.client =self.html # used in OnSize() self.text =self.intro self.html.SetPage(self.text) - self.html.SetAutoLayout(TRUE) + self.html.SetAutoLayout(True) self.line_buffer ="" # refreshes are annoying self.in_batch =0 @@ -193,9 +193,9 @@ class PyShellOutput(wxPanel): if 0 and __debug__: sys.__stdout__.write(text) # handle entities for (symbol, eref) in self.erefs: - text =string.replace(text, symbol, eref) + text = text.replace(symbol, eref) # replace newlines - text =string.replace(text, "\n", style[2]) + text = text.replace("\n", style[2]) # add to contents self.text =self.text +style[0] +text +style[1] if not self.in_batch: self.UpdWindow() @@ -302,14 +302,14 @@ class PyShell(wxPanel): (etype, value, tb) =sys.exc_info() # remove myself from traceback tblist =traceback.extract_tb(tb)[1:] - msg =string.join(traceback.format_exception_only(etype, value) + msg = ' '.join(traceback.format_exception_only(etype, value) +traceback.format_list(tblist)) self.output.write_exc(msg) def ShowSyntaxError(self): """display message about syntax error (no traceback here)""" (etype, value, tb) =sys.exc_info() - msg =string.join(traceback.format_exception_only(etype, value)) + msg = ' '.join(traceback.format_exception_only(etype, value)) self.output.write_exc(msg) def OnSize(self, event): @@ -328,7 +328,7 @@ if __name__ == '__main__': """Demonstrates usage of both default and customized shells""" def OnInit(self): frame = MyFrame() - frame.Show(TRUE) + frame.Show(True) self.SetTopWindow(frame) ## PyShellInput.PS1 =" let's get some work done..." ## PyShellInput.PS2 =" ok, what do you really mean?" @@ -344,8 +344,8 @@ if __name__ == '__main__': ## "<br><-- move this sash to see html debug output</I><br>\n" ## PyShellOutput.html_debug =1 ## frame = MyFrame(title="Customized wxPython Shell") -## frame.Show(TRUE) - return TRUE +## frame.Show(True) + return True app = MyApp(0) app.MainLoop() diff --git a/wxPython/wxPython/lib/splashscreen.py b/wxPython/wxPython/lib/splashscreen.py index 19159beccf..b1ec425319 100644 --- a/wxPython/wxPython/lib/splashscreen.py +++ b/wxPython/wxPython/lib/splashscreen.py @@ -57,7 +57,7 @@ class SplashScreen(wxFrame): EVT_PAINT(self, self.OnPaint) EVT_ERASE_BACKGROUND(self, self.OnEraseBG) - self.Show(true) + self.Show(True) class SplashTimer(wxTimer): @@ -73,16 +73,16 @@ class SplashScreen(wxFrame): def OnPaint(self, event): dc = wxPaintDC(self) - dc.DrawBitmap(self.bitmap, 0,0, false) + dc.DrawBitmap(self.bitmap, 0,0, False) def OnEraseBG(self, event): pass def OnSplashExitDefault(self, event=None): - self.Close(true) + self.Close(True) def OnCloseWindow(self, event=None): - self.Show(false) + self.Show(False) self.timer.Stop() del self.timer self.Destroy() @@ -100,12 +100,12 @@ if __name__ == "__main__": wxImage_AddHandler(wxPNGHandler()) wxImage_AddHandler(wxGIFHandler()) self.splash = SplashScreen(NULL, bitmapfile="splashscreen.jpg", callback=self.OnSplashExit) - self.splash.Show(true) + self.splash.Show(True) self.SetTopWindow(self.splash) - return true + return True def OnSplashExit(self, event=None): print "Yay! Application callback worked!" - self.splash.Close(true) + self.splash.Close(True) del self.splash ### Build working windows here... def test(sceneGraph=None): diff --git a/wxPython/wxPython/lib/stattext.py b/wxPython/wxPython/lib/stattext.py index 0aa919f850..d93b16d156 100644 --- a/wxPython/wxPython/lib/stattext.py +++ b/wxPython/wxPython/lib/stattext.py @@ -16,7 +16,6 @@ """ from wxPython.wx import * -import string #---------------------------------------------------------------------- @@ -65,6 +64,8 @@ class wxGenStaticText(wxPyControl): style = self.GetWindowStyleFlag() if not style & wxST_NO_AUTORESIZE: self.SetSize(self.GetBestSize()) + self.Refresh() + def SetFont(self, font): """ @@ -75,6 +76,7 @@ class wxGenStaticText(wxPyControl): style = self.GetWindowStyleFlag() if not style & wxST_NO_AUTORESIZE: self.SetSize(self.GetBestSize()) + self.Refresh() def DoGetBestSize(self): @@ -94,13 +96,17 @@ class wxGenStaticText(wxPyControl): def AcceptsFocus(self): """Overridden base class virtual.""" - return false + return False def OnPaint(self, event): - width, height = self.GetClientSize() dc = wxBufferedPaintDC(self) + #dc = wxPaintDC(self) + width, height = self.GetClientSize() + if not width or not height: + return dc.SetBackground(wxBrush(self.GetBackgroundColour(), wxSOLID)) + dc.SetTextForeground(self.GetForegroundColour()) dc.Clear() dc.SetFont(self.GetFont()) label = self.GetLabel() diff --git a/wxPython/wxPython/lib/throbber.py b/wxPython/wxPython/lib/throbber.py new file mode 100644 index 0000000000..3211ce699e --- /dev/null +++ b/wxPython/wxPython/lib/throbber.py @@ -0,0 +1,253 @@ +""" +A throbber displays an animated image that can be +started, stopped, reversed, etc. Useful for showing +an ongoing process (like most web browsers use) or +simply for adding eye-candy to an application. + +Throbbers run in a separate thread so normal application +processing can continue unencumbered. +""" + +# +# throbber.py - Cliff Wells <clifford.wells@attbi.com> +# +# Thanks to Harald Massa <harald.massa@suedvers.de> for +# suggestions and sample code. +# +# $Id$ +# + +import threading, os +from wxPython.wx import * + +# ------------------------------------------------------------------------------ + +wxEVT_UPDATE_THROBBER = wxNewEventType() +def EVT_UPDATE_THROBBER(win, func): + win.Connect(-1, -1, wxEVT_UPDATE_THROBBER, func) + +class UpdateThrobberEvent(wxPyEvent): + def __init__(self): + wxPyEvent.__init__(self) + self.SetEventType(wxEVT_UPDATE_THROBBER) + +# ------------------------------------------------------------------------------ + +class Throbber(wxPanel): + """ + The first argument is either the name of a file that will be split into frames + (a composite image) or a list of strings of image names that will be treated + as individual frames. If a single (composite) image is given, then additional + information must be provided: the number of frames in the image and the width + of each frame. The first frame is treated as the "at rest" frame (it is not + shown during animation, but only when Throbber.Rest() is called. + A second, single image may be optionally specified to overlay on top of the + animation. A label may also be specified to show on top of the animation. + """ + def __init__(self, parent, id, + bitmap, # single (composite) bitmap or list of bitmaps + pos = wxDefaultPosition, + size = wxDefaultSize, + frameDelay = 0.1,# time between frames + frames = 0, # number of frames (only necessary for composite image) + frameWidth = 0, # width of each frame (only necessary for composite image) + label = None, # optional text to be displayed + overlay = None, # optional image to overlay on animation + reverse = 0, # reverse direction at end of animation + style = 0, # window style + name = "throbber"): + wxPanel.__init__(self, parent, id, pos, size, style, name) + self.name = name + self.label = label + _seqTypes = (type([]), type(())) + + # set size, guessing if necessary + width, height = size + if width == -1: + if type(bitmap) in _seqTypes: + width = bitmap[0].GetWidth() + else: + if frameWidth: + width = frameWidth + if height == -1: + if type(bitmap) in _seqTypes: + height = bitmap[0].GetHeight() + else: + height = bitmap.GetHeight() + self.width, self.height = width, height + + # double check it + assert width != -1 and height != -1, "Unable to guess size" + + if label: + extentX, extentY = self.GetTextExtent(label) + self.labelX = (width - extentX)/2 + self.labelY = (height - extentY)/2 + self.frameDelay = frameDelay + self.current = 0 + self.direction = 1 + self.autoReverse = reverse + self.overlay = overlay + if overlay is not None: + self.overlay = overlay + self.overlayX = (width - self.overlay.GetWidth()) / 2 + self.overlayY = (height - self.overlay.GetHeight()) / 2 + self.showOverlay = overlay is not None + self.showLabel = label is not None + + # do we have a sequence of images? + if type(bitmap) in _seqTypes: + self.submaps = bitmap + self.frames = len(self.submaps) + # or a composite image that needs to be split? + else: + self.frames = frames + self.submaps = [] + for chunk in range(frames): + rect = (chunk * frameWidth, 0, width, height) + self.submaps.append(bitmap.GetSubBitmap(rect)) + + # self.sequence can be changed, but it's not recommended doing it + # while the throbber is running. self.sequence[0] should always + # refer to whatever frame is to be shown when 'resting' and be sure + # that no item in self.sequence >= self.frames or < 0!!! + self.sequence = range(self.frames) + + self.SetClientSize((width, height)) + + EVT_PAINT(self, self.OnPaint) + EVT_UPDATE_THROBBER(self, self.Rotate) + EVT_WINDOW_DESTROY(self, self.OnDestroyWindow) + + self.event = threading.Event() + self.event.set() # we start out in the "resting" state + + + def OnDestroyWindow(self, event): + # this is currently broken due to a bug in wxWindows... hopefully + # it'll be fixed soon. Meanwhile be sure to explicitly call Stop() + # before the throbber is destroyed. + self.Stop() + event.Skip() + + + def Draw(self, dc): + dc.DrawBitmap(self.submaps[self.sequence[self.current]], 0, 0, True) + if self.overlay and self.showOverlay: + dc.DrawBitmap(self.overlay, self.overlayX, self.overlayY, True) + if self.label and self.showLabel: + dc.DrawText(self.label, self.labelX, self.labelY) + dc.SetTextForeground(wxWHITE) + dc.DrawText(self.label, self.labelX-1, self.labelY-1) + + + def OnPaint(self, event): + self.Draw(wxPaintDC(self)) + event.Skip() + + + def UpdateThread(self): + try: + while hasattr(self, 'event') and not self.event.isSet(): + wxPostEvent(self, UpdateThrobberEvent()) + self.event.wait(self.frameDelay) + except wxPyDeadObjectError: # BUG: we were destroyed + return + + + def Rotate(self, event): + if self.event.isSet(): + return + self.current += self.direction + if self.current >= len(self.sequence): + if self.autoReverse: + self.Reverse() + self.current = len(self.sequence) - 1 + else: + self.current = 1 + if self.current < 1: + if self.autoReverse: + self.Reverse() + self.current = 1 + else: + self.current = len(self.sequence) - 1 + self.Draw(wxClientDC(self)) + + + # --------- public methods --------- + def SetFont(self, font): + """Set the font for the label""" + wxPanel.SetFont(self, font) + self.SetLabel(self.label) + self.Draw(wxClientDC(self)) + + + def Rest(self): + """Stop the animation and return to frame 0""" + self.Stop() + self.current = 0 + self.Draw(wxClientDC(self)) + + + def Reverse(self): + """Change the direction of the animation""" + self.direction = -self.direction + + + def Running(self): + """Returns True if the animation is running""" + return not self.event.isSet() + + + def Start(self): + """Start the animation""" + if not self.Running(): + self.event.clear() + thread = threading.Thread(target = self.UpdateThread, + name = "%s-thread" % self.name) + thread.start() + + + def Stop(self): + """Stop the animation""" + if self.event.isSet(): + return + self.event.set() + + + def SetFrameDelay(self, frameDelay = 0.05): + """Delay between each frame""" + self.frameDelay = frameDelay + + + def ToggleOverlay(self, state = None): + """Toggle the overlay image""" + if state is None: + self.showOverlay = not self.showOverlay + else: + self.showOverlay = state + self.Draw(wxClientDC(self)) + + + def ToggleLabel(self, state = None): + """Toggle the label""" + if state is None: + self.showLabel = not self.showLabel + else: + self.showLabel = state + self.Draw(wxClientDC(self)) + + + def SetLabel(self, label): + """Change the text of the label""" + self.label = label + if label: + extentX, extentY = self.GetTextExtent(label) + self.labelX = (self.width - extentX)/2 + self.labelY = (self.height - extentY)/2 + self.Draw(wxClientDC(self)) + + + +# ------------------------------------------------------------------------------ + diff --git a/wxPython/wxPython/lib/timectrl.py b/wxPython/wxPython/lib/timectrl.py new file mode 100644 index 0000000000..52d9c4b4fc --- /dev/null +++ b/wxPython/wxPython/lib/timectrl.py @@ -0,0 +1,843 @@ +#---------------------------------------------------------------------------- +# Name: wxTimeCtrl.py +# Author: Will Sadkin +# Created: 09/19/2002 +# Copyright: (c) 2002 by Will Sadkin, 2002 +# RCS-ID: $Id$ +# License: wxWindows license +#---------------------------------------------------------------------------- +# NOTE: +# This was written way it is because of the lack of masked edit controls +# in wxWindows/wxPython. I would also have preferred to derive this +# control from a wxSpinCtrl rather than wxTextCtrl, but the wxTextCtrl +# component of that control is inaccessible through the interface exposed in +# wxPython. +# +# wxTimeCtrl does not use validators, because it does careful manipulation +# of the cursor in the text window on each keystroke, and validation is +# cursor-position specific, so the control intercepts the key codes before the +# validator would fire. +# + +from wxPython.wx import * +import string + +# wxWindows' wxTextCtrl translates Composite "control key" +# events into single events before returning them to its OnChar +# routine. The doc says that this results in 1 for Ctrl-A, 2 for +# Ctrl-B, etc. However, there are no wxPython or wxWindows +# symbols for them, so I'm defining codes for Ctrl-X (cut) and +# Ctrl-V (paste) here for readability: +WXK_CTRL_X = (ord('X')+1) - ord('A') +WXK_CTRL_V = (ord('V')+1) - ord('A') + +# The following bit of function is for debugging the subsequent code. +# To turn on debugging output, set _debug to 1 +_debug = 0 +_indent = 0 + +if _debug: + def _dbg(*args, **kwargs): + global _indent + + if len(args): + if _indent: print ' ' * 3 * _indent, + for arg in args: print arg, + print + # else do nothing + + # post process args: + for kwarg, value in kwargs.items(): + if kwarg == 'indent' and value: _indent = _indent + 1 + elif kwarg == 'indent' and value == 0: _indent = _indent - 1 + if _indent < 0: _indent = 0 +else: + def _dbg(*args, **kwargs): + pass + + +# This class of event fires whenever the value of the time changes in the control: +wxEVT_TIMEVAL_UPDATED = wxNewId() +def EVT_TIMEUPDATE(win, id, func): + """Used to trap events indicating that the current time has been changed.""" + win.Connect(id, -1, wxEVT_TIMEVAL_UPDATED, func) + +class TimeUpdatedEvent(wxPyCommandEvent): + def __init__(self, id, value ='12:00:00 AM'): + wxPyCommandEvent.__init__(self, wxEVT_TIMEVAL_UPDATED, id) + self.value = value + def GetValue(self): + """Retrieve the value of the time control at the time this event was generated""" + return self.value + + +# Set up all the positions of the cells in the wxTimeCtrl (once at module import): +# Format of control is: +# hh:mm:ss xM +# 1 +# positions: 01234567890 +_listCells = ['hour', 'minute', 'second', 'am_pm'] +_listCellRange = [(0,1,2), (3,4,5), (6,7,8), (9,10,11)] +_listDelimPos = [2,5,8] + +# Create dictionary of cell ranges, indexed by name or position in the range: +_dictCellRange = {} +for i in range(4): + _dictCellRange[_listCells[i]] = _listCellRange[i] +for cell in _listCells: + for i in _dictCellRange[cell]: + _dictCellRange[i] = _dictCellRange[cell] + + +# Create lists of starting and ending positions for each range, and a dictionary of starting +# positions indexed by name +_listStartCellPos = [] +_listEndCellPos = [] +for tup in _listCellRange: + _listStartCellPos.append(tup[0]) # 1st char of cell + _listEndCellPos.append(tup[1]) # last char of cell (not including delimiter) + +_dictStartCellPos = {} +for i in range(4): + _dictStartCellPos[_listCells[i]] = _listStartCellPos[i] + + +class wxTimeCtrl(wxTextCtrl): + def __init__ ( + self, parent, id=-1, value = '12:00:00 AM', + pos = wxDefaultPosition, size = wxDefaultSize, + fmt24hr=0, + spinButton = None, + style = wxTE_PROCESS_TAB, name = "time" + ): + wxTextCtrl.__init__(self, parent, id, value='', + pos=pos, size=size, style=style, name=name) + + self.__fmt24hr = fmt24hr + + if size == wxDefaultSize: + # set appropriate default sizes depending on format: + if self.__fmt24hr: + testText = '00:00:00' + else: + testText = '00:00:00 MM' + _dbg(wxPlatform) + + if wxPlatform != "__WXMSW__": # give it a little extra space + testText += 'M' + if wxPlatform == "__WXMAC__": # give it even a little more... + testText += 'M' + + w, h = self.GetTextExtent(testText) + self.SetClientSize( (w+4, self.GetClientSize().height) ) + + + if self.__fmt24hr: self.__lastCell = 'second' + else: self.__lastCell = 'am_pm' + + # Validate initial value and set if appropriate + try: + self.SetValue(value) + except: + self.SetValue('12:00:00 AM') + + # set initial position and selection state + self.__SetCurrentCell(_dictStartCellPos['hour']) + self.__OnChangePos(None) + + # Set up internal event handlers to change the event reaction behavior of + # the base wxTextCtrl: + EVT_TEXT(self, self.GetId(), self.__OnTextChange) + EVT_SET_FOCUS(self, self.__OnFocus) + EVT_LEFT_UP(self, self.__OnChangePos) + EVT_LEFT_DCLICK(self, self.__OnDoubleClick) + EVT_CHAR(self, self.__OnChar) + + if spinButton: + self.BindSpinButton(spinButton) # bind spin button up/down events to this control + + + def BindSpinButton(self, sb): + """ + This function binds an externally created spin button to the control, so that + up/down events from the button automatically change the control. + """ + _dbg('wxTimeCtrl::BindSpinButton') + self.__spinButton = sb + if self.__spinButton: + # bind event handlers to spin ctrl + EVT_SPIN_UP(self.__spinButton, self.__spinButton.GetId(), self.__OnSpinUp) + EVT_SPIN_DOWN(self.__spinButton, self.__spinButton.GetId(), self.__OnSpinDown) + + + + def __repr__(self): + return "<wxTimeCtrl: %s>" % self.GetValue() + + + + def SetValue(self, value): + """ + Validating SetValue function for time strings, doing 12/24 format conversion as appropriate. + """ + _dbg('wxTimeCtrl::SetValue', indent=1) + dict_range = _dictCellRange # (for brevity) + dict_start = _dictStartCellPos + + fmt12len = dict_range['am_pm'][-1] + fmt24len = dict_range['second'][-1] + try: + separators_correct = value[2] == ':' and value[5] == ':' + len_ok = len(value) in (fmt12len, fmt24len) + + if len(value) > fmt24len: + separators_correct = separators_correct and value[8] == ' ' + hour = int(value[dict_range['hour'][0]:dict_range['hour'][-1]]) + hour_ok = ((hour in range(0,24) and len(value) == fmt24len) + or (hour in range(1,13) and len(value) == fmt12len + and value[dict_start['am_pm']:] in ('AM', 'PM'))) + + minute = int(value[dict_range['minute'][0]:dict_range['minute'][-1]]) + min_ok = minute in range(60) + second = int(value[dict_range['second'][0]:dict_range['second'][-1]]) + sec_ok = second in range(60) + + _dbg('len_ok =', len_ok, 'separators_correct =', separators_correct) + _dbg('hour =', hour, 'hour_ok =', hour_ok, 'min_ok =', min_ok, 'sec_ok =', sec_ok) + + if len_ok and hour_ok and min_ok and sec_ok and separators_correct: + _dbg('valid time string') + + self.__hour = hour + if len(value) == fmt12len: # handle 12 hour format conversion for actual hour: + am = value[dict_start['am_pm']:] == 'AM' + if hour != 12 and not am: + self.__hour = hour = (hour+12) % 24 + elif hour == 12: + if am: self.__hour = hour = 0 + + self.__minute = minute + self.__second = second + + # valid time + need_to_convert = ((self.__fmt24hr and len(value) == fmt12len) + or (not self.__fmt24hr and len(value) == fmt24len)) + _dbg('need_to_convert =', need_to_convert) + + if need_to_convert: #convert to 12/24 hour format as specified: + if self.__fmt24hr and len(value) == fmt12len: + text = '%.2d:%.2d:%.2d' % (hour, minute, second) + else: + if hour > 12: + hour = hour - 12 + am_pm = 'PM' + elif hour == 12: + am_pm = 'PM' + else: + if hour == 0: hour = 12 + am_pm = 'AM' + text = '%2d:%.2d:%.2d %s' % (hour, minute, second, am_pm) + else: + text = value + _dbg('text=', text) + wxTextCtrl.SetValue(self, text) + _dbg('firing TimeUpdatedEvent...') + evt = TimeUpdatedEvent(self.GetId(), text) + evt.SetEventObject(self) + self.GetEventHandler().ProcessEvent(evt) + else: + _dbg('len_ok:', len_ok, 'separators_correct =', separators_correct) + _dbg('hour_ok:', hour_ok, 'min_ok:', min_ok, 'sec_ok:', sec_ok, indent=0) + raise ValueError, 'value is not a valid time string' + + except (TypeError, ValueError): + _dbg(indent=0) + raise ValueError, 'value is not a valid time string' + _dbg(indent=0) + + def SetWxDateTime(self, wxdt): + value = '%2d:%.2d:%.2d' % (wxdt.GetHour(), wxdt.GetMinute(), wxdt.GetSecond()) + self.SetValue(value) + + def GetWxDateTime(self): + t = wxDateTimeFromHMS(self.__hour, self.__minute, self.__second) + return t + + def SetMxDateTime(self, mxdt): + from mx import DateTime + value = '%2d:%.2d:%.2d' % (mxdt.hour, mxdt.minute, mxdt.second) + self.SetValue(value) + + def GetMxDateTime(self): + from mx import DateTime + t = DateTime.Time(self.__hour, self.__minute, self.__second) + return t + +#------------------------------------------------------------------------------------------------------------- +# these are private functions and overrides: + + def __SetCurrentCell(self, pos): + """ + Sets state variables that indicate the current cell and position within the control. + """ + self.__posCurrent = pos + self.__cellStart, self.__cellEnd = _dictCellRange[pos][0], _dictCellRange[pos][-1] + + + def SetInsertionPoint(self, pos): + """ + Records the specified position and associated cell before calling base class' function. + """ + _dbg('wxTimeCtrl::SetInsertionPoint', pos, indent=1) + + # Adjust pos to legal value if not already + if pos < 0: pos = 0 + elif pos in _listDelimPos + [_dictCellRange[self.__lastCell]]: + pos = pos - 1 + if self.__lastCell == 'am_pm' and pos in _dictCellRange[self.__lastCell]: + pos = _dictStartCellPos[self.__lastCell] + + self.__SetCurrentCell(pos) + wxTextCtrl.SetInsertionPoint(self, pos) # (causes EVT_TEXT event to fire) + _dbg(indent=0) + + + def SetSelection(self, sel_start, sel_to): + _dbg('wxTimeCtrl::SetSelection', sel_start, sel_to, indent=1) + + # Adjust selection range to legal extent if not already + if sel_start < 0: + self.SetInsertionPoint(0) + sel_start = self.__posCurrent + + elif sel_start in _listDelimPos + [_dictCellRange[self.__lastCell]]: + self.SetInsertionPoint(sel_start - 1) + sel_start = self.__posCurrent + + if self.__posCurrent != sel_start: # force selection and insertion point to match + self.SetInsertionPoint(sel_start) + + if sel_to not in _dictCellRange[sel_start]: + sel_to = _dictCellRange[sel_start][-1] # limit selection to end of current cell + + self.__bSelection = sel_start != sel_to + self.__posSelectTo = sel_to + wxTextCtrl.SetSelection(self, sel_start, sel_to) + _dbg(indent=0) + + + def __OnFocus(self,event): + """ + This event handler is currently necessary to work around new default + behavior as of wxPython2.3.3; + The TAB key auto selects the entire contents of the wxTextCtrl *after* + the EVT_SET_FOCUS event occurs; therefore we can't query/adjust the selection + *here*, because it hasn't happened yet. So to prevent this behavior, and + preserve the correct selection when the focus event is not due to tab, + we need to pull the following trick: + """ + _dbg('wxTimeCtrl::OnFocus') + wxCallAfter(self.__FixSelection) + event.Skip() + + + def __FixSelection(self): + """ + This gets called after the TAB traversal selection is made, if the + focus event was due to this, but before the EVT_LEFT_* events if + the focus shift was due to a mouse event. + + The trouble is that, a priori, there's no explicit notification of + why the focus event we received. However, the whole reason we need to + do this is because the default behavior on TAB traveral in a wxTextCtrl is + now to select the entire contents of the window, something we don't want. + So we can *now* test the selection range, and if it's "the whole text" + we can assume the cause, change the insertion point to the start of + the control, and deselect. + """ + _dbg('wxTimeCtrl::FixSelection', indent=1) + sel_start, sel_to = self.GetSelection() + if sel_start == 0 and sel_to in _dictCellRange[self.__lastCell]: + # This isn't normally allowed, and so assume we got here by the new + # "tab traversal" behavior, so we need to reset the selection + # and insertion point: + _dbg('entire text selected; resetting selection to start of control') + self.SetInsertionPoint(0) + self.SetSelection(self.__cellStart, self.__cellEnd) + _dbg(indent=0) + + + def __OnTextChange(self, event): + """ + This private event handler is required to retain the current position information of the cursor + after update to the underlying text control is done. + """ + _dbg('wxTimeCtrl::OnTextChange', indent=1) + self.__SetCurrentCell(self.__posCurrent) # ensure cell range vars are set + + # Note: must call self.SetSelection here to preserve insertion point cursor after update! + # (I don't know why, but this does the trick!) + if self.__bSelection: + _dbg('reselecting from ', self.__posCurrent, 'to', self.__posSelectTo) + self.SetSelection(self.__posCurrent, self.__posSelectTo) + else: + self.SetSelection(self.__posCurrent, self.__posCurrent) + event.Skip() + _dbg(indent=0) + + def __OnSpin(self, key): + self.__IncrementValue(key, self.__posCurrent) + self.SetFocus() + self.SetInsertionPoint(self.__posCurrent) + self.SetSelection(self.__posCurrent, self.__posSelectTo) + + def __OnSpinUp(self, event): + """ + Event handler for any bound spin button on EVT_SPIN_UP; + causes control to behave as if up arrow was pressed. + """ + _dbg('wxTimeCtrl::OnSpinUp', indent=1) + self.__OnSpin(WXK_UP) + _dbg(indent=0) + + + def __OnSpinDown(self, event): + """ + Event handler for any bound spin button on EVT_SPIN_DOWN; + causes control to behave as if down arrow was pressed. + """ + _dbg('wxTimeCtrl::OnSpinDown', indent=1) + self.__OnSpin(WXK_DOWN) + _dbg(indent=0) + + + def __OnChangePos(self, event): + """ + Event handler for motion events; this handler + changes limits the selection to the new cell boundaries. + """ + _dbg('wxTimeCtrl::OnChangePos', indent=1) + pos = self.GetInsertionPoint() + self.__SetCurrentCell(pos) + sel_start, sel_to = self.GetSelection() + selection = sel_start != sel_to + if not selection: + # disallow position at end of field: + if pos in _listDelimPos + [_dictCellRange[self.__lastCell][-1]]: + self.SetInsertionPoint(pos-1) + self.__posSelectTo = self.__cellEnd + else: + # only allow selection to end of current cell: + if sel_to < pos: self.__posSelectTo = self.__cellStart + elif sel_to > pos: self.__posSelectTo = self.__cellEnd + + _dbg('new pos =', self.__posCurrent, 'select to ', self.__posSelectTo) + self.SetSelection(self.__posCurrent, self.__posSelectTo) + if event: event.Skip() + _dbg(indent=0) + + + def __OnDoubleClick(self, event): + """ + Event handler for left double-click mouse events; this handler + causes the cell at the double-click point to be selected. + """ + _dbg('wxTimeCtrl::OnDoubleClick', indent=1) + pos = self.GetInsertionPoint() + self.__SetCurrentCell(pos) + if self.__posCurrent != self.__cellStart: + self.SetInsertionPoint(self.__cellStart) + self.SetSelection(self.__cellStart, self.__cellEnd) + _dbg(indent=0) + + + def __OnChar(self, event): + """ + This private event handler is the main control point for the wxTimeCtrl. + It governs whether input characters are accepted and if so, handles them + so as to provide appropriate cursor and selection behavior for the control. + """ + _dbg('wxTimeCtrl::OnChar', indent=1) + + # NOTE: Returning without calling event.Skip() eats the event before it + # gets to the text control... + + key = event.GetKeyCode() + text = self.GetValue() + pos = self.GetInsertionPoint() + if pos != self.__posCurrent: + _dbg("insertion point has moved; resetting current cell") + self.__SetCurrentCell(pos) + self.SetSelection(self.__posCurrent, self.__posCurrent) + + sel_start, sel_to = self.GetSelection() + selection = sel_start != sel_to + _dbg('sel_start=', sel_start, 'sel_to =', sel_to) + if not selection: + self.__bSelection = False # predict unselection of entire region + + _dbg('keycode = ', key) + _dbg('pos = ', pos) + + # don't allow deletion, cut or paste: + if key in (WXK_DELETE, WXK_BACK, WXK_CTRL_X, WXK_CTRL_V): + pass + + elif key == WXK_TAB: # skip to next field if applicable: + _dbg('key == WXK_TAB') + dict_range = _dictCellRange # (for brevity) + dict_start = _dictStartCellPos + if event.ShiftDown(): # tabbing backwords + + ###(NOTE: doesn't work; wxTE_PROCESS_TAB doesn't appear to send us this event!) + + _dbg('event.ShiftDown()') + if pos in dict_range['hour']: # already in 1st field + self.__SetCurrentCell(dict_start['hour']) # ensure we have our member vars set + event.Skip() #then do normal tab processing for the form + _dbg(indent=0) + return + + elif pos in dict_range['minute']: # skip to hours field + new_pos = dict_start['hour'] + elif pos in dict_range['second']: # skip to minutes field + new_pos = dict_start['minute'] + elif pos in dict_range['am_pm']: # skip to seconds field + new_pos = dict_start['second'] + + self.SetInsertionPoint(new_pos) # force insert point to jump to next cell (swallowing TAB) + self.__OnChangePos(None) # update selection accordingly + + else: + # Tabbing forwards through control... + + if pos in dict_range[self.__lastCell]: # already in last field; ensure we have our members set + self.__SetCurrentCell(dict_start[self.__lastCell]) + _dbg('tab in last cell') + event.Skip() # then do normal tab processing for the form + _dbg(indent=0) + return + + if pos in dict_range['second']: # skip to AM/PM field (if not last cell) + new_pos = dict_start['am_pm'] + elif pos in dict_range['minute']: # skip to seconds field + new_pos = dict_start['second'] + elif pos in dict_range['hour']: # skip to minutes field + new_pos = dict_start['minute'] + + self.SetInsertionPoint(new_pos) # force insert point to jump to next cell (swallowing TAB) + self.__OnChangePos(None) # update selection accordingly + + elif key == WXK_LEFT: # move left; set insertion point as appropriate: + _dbg('key == WXK_LEFT') + if event.ShiftDown(): # selecting a range... + _dbg('event.ShiftDown()') + if pos in _listStartCellPos: # can't select pass delimiters + if( sel_to == pos+2 and sel_to != _dictCellRange['am_pm'][-1]): + self.SetSelection(pos, pos+1) # allow deselection of 2nd char in cell if not am/pm + # else ignore event + + elif pos in _listEndCellPos: # can't use normal selection, because position ends up + # at delimeter + _dbg('set selection from', pos-1, 'to', self.__posCurrent) + self.SetInsertionPoint(pos-1) # this selects the previous position + self.SetSelection(self.__posCurrent, pos) + else: + self.SetInsertionPoint(sel_to - 1) # this unselects the last digit + self.SetSelection(self.__posCurrent, pos) + + else: # ... not selecting + if pos == 0: # can't position before position 0 + pass + elif pos in _listStartCellPos: # skip (left) OVER the colon/space: + self.SetInsertionPoint(pos-2) + self.__OnChangePos(None) # set the selection appropriately + else: + self.SetInsertionPoint(pos-1) # reposition the cursor and + self.__OnChangePos(None) # set the selection appropriately + + + elif key == WXK_RIGHT: # move right + _dbg('key == WXK_RIGHT') + if event.ShiftDown(): + _dbg('event.ShiftDown()') + if sel_to in _listDelimPos: # can't select pass delimiters + pass + else: + self.SetSelection(self.__posCurrent, sel_to+1) + else: + if( (self.__lastCell == 'second' + and pos == _dictStartCellPos['second']+1) + or (self.__lastCell == 'am_pm' + and pos == _dictStartCellPos['am_pm']) ): + pass # don't allow cursor past last cell + elif pos in _listEndCellPos: # skip (right) OVER the colon/space: + self.SetInsertionPoint(pos+2) + self.__OnChangePos(None) # set the selection appropriately + else: + self.SetInsertionPoint(pos+1) # reposition the cursor and + self.__OnChangePos(None) # set the selection appropriately + + elif key in (WXK_UP, WXK_DOWN): + _dbg('key in (WXK_UP, WXK_DOWN)') + self.__IncrementValue(key, pos) # increment/decrement as appropriate + + + elif key < WXK_SPACE or key == WXK_DELETE or key > 255: + event.Skip() # non alphanumeric; process normally (Right thing to do?) + + elif chr(key) in ['!', 'c', 'C']: # Special character; sets the value of the control to "now" + _dbg("key == '!'; setting time to 'now'") + now = wxDateTime_Now() + self.SetWxDateTime(now) + + elif chr(key) in string.digits: # let ChangeValue validate and update current position + self.__ChangeValue(chr(key), pos) # handle event (and swallow it) + + elif chr(key) in ('a', 'A', 'p', 'P', ' '): # let ChangeValue validate and update current position + self.__ChangeValue(chr(key), pos) # handle event (and swallow it) + + else: # disallowed char; swallow event + pass + _dbg(indent=0) + + + def __IncrementValue(self, key, pos): + _dbg('wxTimeCtrl::IncrementValue', key, pos, indent=1) + text = self.GetValue() + + sel_start, sel_to = self.GetSelection() + selection = sel_start != sel_to + cell_selected = selection and sel_to -1 != pos + + dict_start = _dictStartCellPos # (for brevity) + + # Determine whether we should change the entire cell or just a portion of it: + if( cell_selected + or (pos in _listStartCellPos and not selection) + or (text[pos] == ' ' and text[pos+1] not in ('1', '2')) + or (text[pos] == '9' and text[pos-1] == ' ' and key == WXK_UP) + or (text[pos] == '1' and text[pos-1] == ' ' and key == WXK_DOWN) + or pos >= dict_start['am_pm']): + + self.__IncrementCell(key, pos) + else: + if key == WXK_UP: inc = 1 + else: inc = -1 + + if pos == dict_start['hour'] and not self.__fmt24hr: + if text[pos] == ' ': digit = '1' # allow ' ' or 1 for 1st digit in 12hr format + else: digit = ' ' + else: + if pos == dict_start['hour']: + if int(text[pos + 1]) >3: mod = 2 # allow for 20-23 + else: mod = 3 # allow 00-19 + elif pos == dict_start['hour'] + 1: + if self.__fmt24hr: + if text[pos - 1] == '2': mod = 4 # allow hours 20-23 + else: mod = 10 # allow hours 00-19 + else: + if text[pos - 1] == '1': mod = 3 # allow hours 10-12 + else: mod = 10 # allow 0-9 + + elif pos in (dict_start['minute'], + dict_start['second']): mod = 6 # allow minutes/seconds 00-59 + else: mod = 10 + + digit = '%d' % ((int(text[pos]) + inc) % mod) + + _dbg("new digit = \'%s\'" % digit) + self.__ChangeValue(digit, pos) + _dbg(indent=0) + + + def __IncrementCell(self, key, pos): + _dbg('wxTimeCtrl::IncrementCell', key, pos, indent=1) + self.__SetCurrentCell(pos) # determine current cell + hour, minute, second = self.__hour, self.__minute, self.__second + text = self.GetValue() + dict_start = _dictStartCellPos # (for brevity) + if key == WXK_UP: inc = 1 + else: inc = -1 + + if self.__cellStart == dict_start['am_pm']: + am = text[dict_start['am_pm']:] == 'AM' + if am: hour = hour + 12 + else: hour = hour - 12 + else: + if self.__cellStart == dict_start['hour']: + hour = (hour + inc) % 24 + elif self.__cellStart == dict_start['minute']: + minute = (minute + inc) % 60 + elif self.__cellStart == dict_start['second']: + second = (second + inc) % 60 + + newvalue = '%.2d:%.2d:%.2d' % (hour, minute, second) + + self.SetValue(newvalue) + self.SetInsertionPoint(self.__cellStart) + self.SetSelection(self.__cellStart, self.__cellEnd) + _dbg(indent=0) + + + def __ChangeValue(self, char, pos): + _dbg('wxTimeCtrl::ChangeValue', "\'" + char + "\'", pos, indent=1) + text = self.GetValue() + + self.__SetCurrentCell(pos) + sel_start, sel_to = self.GetSelection() + self.__posSelectTo = sel_to + self.__bSelection = selection = sel_start != sel_to + cell_selected = selection and sel_to -1 != pos + _dbg('cell_selected =', cell_selected, indent=0) + + dict_start = _dictStartCellPos # (for brevity) + + if pos in _listDelimPos: return # don't allow change of punctuation + + elif( 0 < pos < dict_start['am_pm'] and char not in string.digits): + return # AM/PM not allowed in this position + + # See if we're changing the hour cell, and validate/update appropriately: + # + hour_start = dict_start['hour'] # (ie. 0) + + if pos == hour_start: # if at 1st position, + if self.__fmt24hr: # and using 24 hour format + if cell_selected: # replace cell contents with hour represented by digit + newtext = '%.2d' % int(char) + text[hour_start+2:] + elif char not in ('0', '1', '2'): # return if digit not 0,1, or 2 + return + else: # relace current position + newtext = char + text[pos+1:] + else: # (12 hour format) + if cell_selected: + if char == ' ': return # can't erase entire cell + elif char == '0': # treat 0 as '12' + newtext = '12' + text[hour_start+2:] + else: # replace cell contents with hour represented by digit + newtext = '%2d' % int(char) + text[hour_start+2:] + else: + if char not in ('1', ' '): # can only type a 1 or space + return + if text[pos+1] not in ('0', '1', '2'): # and then, only if other column is 0,1, or 2 + return + if char == ' ' and text[pos+1] == '0': # and char isn't space if 2nd column is 0 + return + else: # ok; replace current position + newtext = char + text[pos+1:] + if char == ' ': self.SetInsertionPoint(pos+1) # move insert point to legal position + + elif pos == hour_start+1: # if editing 2nd position of hour + if( not self.__fmt24hr # and using 12 hour format + and text[hour_start] == '1' # if 1st char is 1, + and char not in ('0', '1', '2')): # disallow anything bug 0,1, or 2 + return + newtext = text[hour_start] + char + text[hour_start+2:] # else any digit ok + + # Do the same sort of validation for minute and second cells + elif pos in (dict_start['minute'], dict_start['second']): + if cell_selected: # if cell selected, replace value + newtext = text[:pos] + '%.2d' % int(char) + text[pos+2:] + elif int(char) > 5: return # else disallow > 59 for minute and second fields + else: + newtext = text[:pos] + char + text[pos+1:] # else ok + + elif pos in (dict_start['minute']+1, dict_start['second']+1): + newtext = text[:pos] + char + text[pos+1:] # all digits ok for 2nd digit of minute/second + + # Process AM/PM cell + elif pos == dict_start['am_pm']: + char = char.upper() + if char not in ('A','P'): return # disallow all but A or P as 1st char of column + newtext = text[:pos] + char + text[pos+1:] + else: return # not a valid position + + _dbg(indent=1) + # update member position vars and set selection to character changed + if not cell_selected: + _dbg('reselecting current digit') + self.__posSelectTo = pos+1 + + _dbg('newtext=', newtext) + self.SetValue(newtext) + self.SetInsertionPoint(self.__posCurrent) + self.SetSelection(self.__posCurrent, self.__posSelectTo) + _dbg(indent=0) + + + def Cut(self): + """ + Override wxTextCtrl::Cut() method, as this operation should not + be allowed for wxTimeCtrls. + """ + return + + + def Paste(self): + """ + Override wxTextCtrl::Paste() method, as this operation should not + be allowed for wxTimeCtrls. + """ + return + + +#---------------------------------------------------------------------------- +# Test jig for wxTimeCtrl: + +if __name__ == '__main__': + import traceback + + class TestPanel(wxPanel): + def __init__(self, parent, id, + pos = wxPyDefaultPosition, size = wxPyDefaultSize, + fmt24hr = 0, test_mx = 0, + style = wxTAB_TRAVERSAL ): + + wxPanel.__init__(self, parent, id, pos, size, style) + + self.test_mx = test_mx + + self.tc = wxTimeCtrl(self, 10, fmt24hr = fmt24hr) + sb = wxSpinButton( self, 20, wxDefaultPosition, wxSize(-1,20), 0 ) + self.tc.BindSpinButton(sb) + + sizer = wxBoxSizer( wxHORIZONTAL ) + sizer.AddWindow( self.tc, 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5 ) + sizer.AddWindow( sb, 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5 ) + + self.SetAutoLayout( True ) + self.SetSizer( sizer ) + sizer.Fit( self ) + sizer.SetSizeHints( self ) + + EVT_TIMEUPDATE(self, self.tc.GetId(), self.OnTimeChange) + + def OnTimeChange(self, event): + _dbg('OnTimeChange: value = ', event.GetValue()) + wxdt = self.tc.GetWxDateTime() + _dbg('wxdt =', wxdt.GetHour(), wxdt.GetMinute(), wxdt.GetSecond()) + if self.test_mx: + mxdt = self.tc.GetMxDateTime() + _dbg('mxdt =', mxdt.hour, mxdt.minute, mxdt.second) + + + class MyApp(wxApp): + def OnInit(self): + import sys + fmt24hr = '24' in sys.argv + test_mx = 'mx' in sys.argv + try: + frame = wxFrame(NULL, -1, "wxTimeCtrl Test", wxPoint(20,20), wxSize(100,100) ) + panel = TestPanel(frame, -1, wxPoint(-1,-1), fmt24hr=fmt24hr, test_mx = test_mx) + frame.Show(True) + except: + traceback.print_exc() + return False + return True + + try: + app = MyApp(0) + app.MainLoop() + except: + traceback.print_exc() diff --git a/wxPython/wxPython/lib/vtk.py b/wxPython/wxPython/lib/vtk.py index 6a6c977185..676932d215 100644 --- a/wxPython/wxPython/lib/vtk.py +++ b/wxPython/wxPython/lib/vtk.py @@ -136,7 +136,7 @@ class wxVTKRenderWindowBase(wxWindow): def OnCreateWindow(self, event): - hdl = self.GetHandle() + hdl = self.GetHandle() try: self._RenderWindow.SetParentInfo(str(hdl)) except: @@ -163,7 +163,7 @@ class wxVTKRenderWindowBase(wxWindow): # Windows. #self._RenderWindow.GetSize() # - self._RenderWindow.SetSize(sz.width, sz.height) + self._RenderWindow.SetSize(sz.width, sz.height) def OnLeftButtonDown(self, event): diff --git a/wxPython/wxPython/lib/wxPlotCanvas.py b/wxPython/wxPython/lib/wxPlotCanvas.py index 926333c92d..0a4ec48da1 100644 --- a/wxPython/wxPython/lib/wxPlotCanvas.py +++ b/wxPython/wxPython/lib/wxPlotCanvas.py @@ -20,7 +20,6 @@ Original comment follows below: """ from wxPython import wx -import string # Not everybody will have Numeric, so let's be cool about it... try: @@ -32,7 +31,7 @@ imported. It probably is not installed (it's not part of the standard Python distribution). See the Python site (http://www.python.org) for information on downloading source or binaries.""" - if wxPlatform == '__WXMSW__': + if wx.wxPlatform == '__WXMSW__': d = wx.wxMessageDialog(wx.NULL, msg, "Numeric not found") if d.ShowModal() == wx.wxID_CANCEL: d = wx.wxMessageDialog(wx.NULL, "I kid you not! Pressing Cancel won't help you!", "Not a joke", wx.wxOK) @@ -172,8 +171,10 @@ class PlotGraphics: class PlotCanvas(wx.wxWindow): - def __init__(self, parent, id = -1): - wx.wxWindow.__init__(self, parent, id, wx.wxPyDefaultPosition, wx.wxPyDefaultSize) + def __init__(self, parent, id=-1, + pos = wx.wxDefaultPosition, size = wx.wxDefaultSize, + style = 0, name = 'plotCanvas'): + wx.wxWindow.__init__(self, parent, id, pos, size, style, name) self.border = (1,1) self.SetClientSizeWH(400,400) self.SetBackgroundColour(wx.wxNamedColour("white")) @@ -429,7 +430,7 @@ if __name__ == '__main__': """As of this writing, printing support in wxPython is shaky at best. Are you sure you want to do this?""", "Danger!", wx.wxYES_NO) if d.ShowModal() == wx.wxID_YES: - psdc = wx.wxPostScriptDC("out.ps", wx.TRUE, self) + psdc = wx.wxPostScriptDC("out.ps", wx.True, self) self.client.redraw(psdc) def OnFileExit(self, event): @@ -455,9 +456,9 @@ Are you sure you want to do this?""", "Danger!", wx.wxYES_NO) class MyApp(wx.wxApp): def OnInit(self): frame = AppFrame(wx.NULL, -1, "wxPlotCanvas") - frame.Show(wx.TRUE) + frame.Show(wx.True) self.SetTopWindow(frame) - return wx.TRUE + return wx.True app = MyApp(0) diff --git a/wxPython/wxPython/lib/wxpTag.py b/wxPython/wxPython/lib/wxpTag.py index 8dbc44a382..1981f5b02d 100644 --- a/wxPython/wxPython/lib/wxpTag.py +++ b/wxPython/wxPython/lib/wxpTag.py @@ -89,7 +89,6 @@ from wxPython.wx import * from wxPython.html import * import wxPython.wx -import string import types #---------------------------------------------------------------------- @@ -146,12 +145,12 @@ class wxpTagHandler(wxHtmlWinTagHandler): if tag.HasParam('WIDTH'): width = tag.GetParam('WIDTH') if width[-1] == '%': - self.ctx.floatWidth = string.atoi(width[:-1], 0) + self.ctx.floatWidth = int(width[:-1], 0) width = self.ctx.floatWidth else: - width = string.atoi(width) + width = int(width) if tag.HasParam('HEIGHT'): - height = string.atoi(tag.GetParam('HEIGHT')) + height = int(tag.GetParam('HEIGHT')) self.ctx.kwargs['size'] = wxSize(width, height) # parse up to the closing tag, and gather any nested Param tags. @@ -163,18 +162,18 @@ class wxpTagHandler(wxHtmlWinTagHandler): obj = apply(self.ctx.classObj, (parent,), self.ctx.kwargs) - obj.Show(true) + obj.Show(True) # add it to the HtmlWindow self.GetParser().GetContainer().InsertCell(wxHtmlWidgetCell(obj, self.ctx.floatWidth)) self.ctx = None - return true + return True def HandleParamTag(self, tag): if not tag.HasParam('NAME'): - return false + return False name = tag.GetParam('NAME') value = "" @@ -185,7 +184,7 @@ class wxpTagHandler(wxHtmlWinTagHandler): if name == 'id': theID = -1 try: - theID = string.atoi(value) + theID = int(value) except ValueError: theID = getattr(self.ctx.classMod, value) value = theID @@ -202,15 +201,15 @@ class wxpTagHandler(wxHtmlWinTagHandler): # convert to wxColour elif value[0] == '#': try: - red = string.atoi('0x'+value[1:3], 16) - green = string.atoi('0x'+value[3:5], 16) - blue = string.atoi('0x'+value[5:], 16) + red = int('0x'+value[1:3], 16) + green = int('0x'+value[3:5], 16) + blue = int('0x'+value[5:], 16) value = wxColor(red, green, blue) except: pass self.ctx.kwargs[str(name)] = value - return false + return False #---------------------------------------------------------------------- @@ -229,7 +228,7 @@ class _Context: # Function to assist with importing packages def _my_import(name): mod = __import__(name) - components = string.split(name, '.') + components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod @@ -241,27 +240,27 @@ def _my_import(name): def _param2dict(param): i = 0; j = 0; s = len(param); d = {} while 1: - while i<s and param[i] == " " : i = i+1 - if i>=s: break - j = i - while j<s and param[j] != "=": j=j+1 - if j+1>=s: - break - word = param[i:j] - i=j+1 - if (param[i] == '"'): - j=i+1 - while j<s and param[j] != '"' : j=j+1 - if j == s: break - val = param[i+1:j] - elif (param[i] != " "): - j=i+1 - while j<s and param[j] != " " : j=j+1 - val = param[i:j] - else: - val = "" - i=j+1 - d[word] = val + while i<s and param[i] == " " : i = i+1 + if i>=s: break + j = i + while j<s and param[j] != "=": j=j+1 + if j+1>=s: + break + word = param[i:j] + i=j+1 + if (param[i] == '"'): + j=i+1 + while j<s and param[j] != '"' : j=j+1 + if j == s: break + val = param[i+1:j] + elif (param[i] != " "): + j=i+1 + while j<s and param[j] != " " : j=j+1 + val = param[i:j] + else: + val = "" + i=j+1 + d[word] = val return d #---------------------------------------------------------------------- diff --git a/wxPython/wxPython/tools/XRCed/CHANGES.txt b/wxPython/wxPython/tools/XRCed/CHANGES.txt new file mode 100644 index 0000000000..3945253906 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/CHANGES.txt @@ -0,0 +1,162 @@ +0.1.0 +----- + +Finally implemented tools panel for almost all controls (except +wxHtmlWindow, wxCalendarCtrl and wxGenericDirCtrl - they are too +rarely used). + +Changed some sizes in panel to better work with different fonts. + +Fixed double-refreshing after Ctrl+R. + +Maybe something else that I've forgot. It's been a looong day... :) + +0.0.9-6 +------- + +Added dialog unit support. + +Dealing with non-specified required values (set to defaults, if exist). + +Added 'minsize' parameter of sizeritem. + +Added '-i' option to turn off translations and use international characters. + +0.0.9-5 +------- + +Mac platform-specific checks. + +0.0.9-4 +------- + +Implemented standard bitmap selection. + +Fixed a bug in FlexGridSizer code. + +0.0.9-3 +------- + +File browsing (for bitmaps/icons, etc.) had a small problem when current +file was not saved yet. + +0.0.9-2 +------- + +Small bug fix for initial don't panic message. + +0.0.9-1 +------- + +Changed program structure, reduced use of global variables (grouped in +module 'globals', which creates an instanse 'g' of class Globals. + +First version of undo/redo working! + +Support for toolbars inside panels and frames. + +Added 'container' submenu for creating Panel, Notebook and ToolBar objects. + +wxMSW-only: added code to switch focus back to main window when test +window is updated. + +0.0.8-2 +------- + +Fixed unicode problem for unicode build. + +0.0.8-1 +------- + +Using WX_2_4_BRANCH. + +Added new controls: wxSpinCtrl, wxGenericDirCtrl, unknown (custom +control), improved wxXRC format suppor (menu styles, etc.). + +Some I18N support: parsing "encoding" attribute in XML header, later +it can be modified in "properties" panel for "XML tree". + +UNIX note: currently XML writing for non-ascii chars works only if +sys.getdefaultencoding() returns good value. To do this, one has to +put following lines to "sitecustomize.py" file: + +# Start code segment +import sys +sys.setdefaultencoding('iso-8859-1') # or whatever +# End code segment + +0.0.7 +----- + +Some command-line arguments. + +"Test window" command and toolbar button. + +New panel interphace (wxHTMLWindow is not used anymore). + +Toggling between embedded and detached panel. + +Cache for already used windows. + +Current top-level control is bold, if test window shown. + +Undo/redo broken. + +CheckListBox does not work unless wxXRC source fixed (in both wxPytnon and +wxWin): + +contrib/src/xrc/xmlrsall.cpp +45,46c45,46 +< AddHandler(new wxListCtrlXmlHandler); +< #if CHECKLISTBOX +--- +> AddHandler(new wxListCtrlXmlHandler); +> #if wxUSE_CHECKLISTBOX + +This is fixed in CVS. + +0.0.6 +----- + +Toolbar, bitmap, icon support (no display yet). + +Changed parameter objects, added support for multiple parameters (like +`growablecols'). + +Fixed double-clicking problem with tree control on Windows. + +Some performance improovements. + + +0.0.5 +----- + +Added notebook with properties page and style page. Fixed some problems +on Windows. + + +0.0.4 +----- + +Some fixes suggested by RD + + +0.0.3 +----- + +Faster preview window refresh. + +Cut/Paste works better. + +Some tree icons. + +Tree item names. + +Bugfixes. + + +0.0.2 +----- + +The first release. + diff --git a/wxPython/wxPython/tools/XRCed/README b/wxPython/wxPython/tools/XRCed/README.txt similarity index 92% rename from wxPython/wxPython/tools/XRCed/README rename to wxPython/wxPython/tools/XRCed/README.txt index 133ee2a2e5..684e17bca5 100644 --- a/wxPython/wxPython/tools/XRCed/README +++ b/wxPython/wxPython/tools/XRCed/README.txt @@ -7,10 +7,11 @@ Installation on UNIX -------------------- -XRCed requires wxGTK and wxPython greater than 2.3.2, and Python 2.2 (it may -work with earlier version, but was not tested). +XRCed requires wxGTK and wxPython greater or equal to 2.3.3, and Python 2.2 +(it may work with earlier version, but was not tested). -Of course wxGTK's XRC library (libwxxrc) must be installed. +Of course wxGTK's XRC library (libwxxrc) and it's python module must +be installed. Installation on Windows ----------------------- diff --git a/wxPython/wxPython/tools/XRCed/TODO b/wxPython/wxPython/tools/XRCed/TODO.txt similarity index 76% rename from wxPython/wxPython/tools/XRCed/TODO rename to wxPython/wxPython/tools/XRCed/TODO.txt index 4b9cc1b2b3..78575cbba7 100644 --- a/wxPython/wxPython/tools/XRCed/TODO +++ b/wxPython/wxPython/tools/XRCed/TODO.txt @@ -1,9 +1,9 @@ TODO for XRCed ============== -- Undo/Redo +- better help -- menu - accel not displayed in preview ++ undo/redo + tree icons @@ -13,7 +13,7 @@ TODO for XRCed + XML indents -? select same notebook pages after update ++ select same notebook pages after update - put some default values in tree ctrl etc. @@ -26,4 +26,4 @@ TODO for XRCed + disable some window creation when it's not valid -- check for memory leaks from wx objects +- selecting object by clicking in test window diff --git a/wxPython/wxPython/tools/XRCed/encode_bitmaps.py b/wxPython/wxPython/tools/XRCed/encode_bitmaps.py new file mode 100644 index 0000000000..56660d3c65 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/encode_bitmaps.py @@ -0,0 +1,27 @@ + +import sys, os, glob +from wxPython.tools import img2py + +output = 'images.py' + +# get the list of PNG files +files = glob.glob('src-images/*.png') + +# Truncate the inages module +open(output, 'w') + +# call img2py on each file +for file in files: + + # extract the basename to be used as the image name + name = os.path.splitext(os.path.basename(file))[0] + + # encode it + if file == files[0]: + cmd = "-u -i -n %s %s %s" % (name, file, output) + else: + cmd = "-a -u -i -n %s %s %s" % (name, file, output) + img2py.main(cmd.split()) + + + diff --git a/wxPython/wxPython/tools/XRCed/globals.py b/wxPython/wxPython/tools/XRCed/globals.py new file mode 100644 index 0000000000..a9147ae687 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/globals.py @@ -0,0 +1,39 @@ +# Name: globals.py +# Purpose: XRC editor, global variables +# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> +# Created: 02.12.2002 +# RCS-ID: $Id$ + +from wxPython.wx import * +from wxPython.xrc import * + +# Global constants + +sysFont = wxSystemSettings_GetFont(wxSYS_SYSTEM_FONT) +labelFont = wxFont(sysFont.GetPointSize(), wxDEFAULT, wxNORMAL, wxBOLD) +modernFont = wxFont(sysFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL) +smallerFont = wxFont(sysFont.GetPointSize()-2, wxDEFAULT, wxNORMAL, wxNORMAL) + +progname = 'XRCed' +version = '0.1.0' + +try: + True +except NameError: + True = 1==1 + False = 1==0 + +# Global variables + +class Globals: + panel = None + tree = None + frame = None + tools = None + undoMan = None + testWin = None + testWinPos = wxDefaultPosition + currentXXX = None + xmlFlags = wxXRC_USE_LOCALE | wxXRC_NO_SUBCLASSING + +g = Globals() diff --git a/wxPython/wxPython/tools/XRCed/images.py b/wxPython/wxPython/tools/XRCed/images.py index 924c55d463..167959b681 100644 --- a/wxPython/wxPython/tools/XRCed/images.py +++ b/wxPython/wxPython/tools/XRCed/images.py @@ -1,368 +1,1675 @@ #---------------------------------------------------------------------- -# This file was generated by img2py.py +# This file was generated by encode_bitmaps.py # -from wxPython.wx import wxBitmapFromXPMData, wxImageFromBitmap -import cPickle, zlib +from wxPython.wx import wxImageFromStream, wxBitmapFromImage +from wxPython.wx import wxEmptyIcon +import cStringIO -def getIconData(): - return cPickle.loads(zlib.decompress( -'x\xda\x9d\x90\xbb\x0e\xc20\x0cEw\xbe\xc2\x12C\x91"Y-\xa2\x82\xd1\x80\xd45C\ -\x97\xac\x88\x11\xa4\xf0\xff\x13\xd7Nh\xa0\xcd\x00\xb8y\xf4\xe6\xf8\x95l\xee\ -\x8fn56\xdb\x1da\xec\xa9kV\x97\xb1\tt\xa5\xd3\xfdr\xbd\x99b\xa8\xf5\xf1\xa0\ -\x9fi\xa7\xba\x85\rI\xcb\x8bg\x1dU\xf7m\xbf\xeb[\xd3\xfe\xa53\'\xd5\xc3a8O\ -\xban_@\x0eL10\x07X\xc4iL[\x8e\x8c\x81 \xe1\xc3\xea\x17\xd4/NPct\x85{0N\xcc\ -\xa5f\xb4\x83\x94\xd6|\xde\x1b\xb2"\x9a\x16\x05\xe6\x10\x81\x08\xe5\x9cZ\x1d\ -K\xcd\xd4\xed\x04-}\xb9\n\n\x12\xdb\xb0\x99\x0e\xe8\x8f\x17\xf2N~\x81\xe2}"^\ -\x16\xd0;\x18\xce\x9c\xcb?oP\x9c\xc7t\xf0\xb1\xfd\x13Z&,9z\x0eS:\x04/\x1bB:\ -\x81Q\x15jM4Z\xaf\x99\xba\xf4\xf5n\xed\x9e\x92\xef)B\x7f\xbem\x81\xfc\x04\ -\x8f\xd5\x99\xcc' )) +def getAutoRefreshData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xf3IDATx\x9c\xb5\x94\xad\x16\xc30\x08\x85\xc9\xceD$\xb2\x8fX\x19Y\x89\ +\xacD\xee\x11\'+\xe76\xb3\xb6\x94AB\xbb\x13\\\x7fr\xbf\xc0\x05\x12"B\xcf\xb8\ +uU\x07\x80{\xf4\xc7\xe7\xb2\xbc\xf5\xbb\x011\xb5\xce\x852\x90\xe2\x0f\xe6*4\ +\x0cX\x0f[\xe2\xf2\xe6-H5\x03K\x9c\x88\x92\x86\x10\x91\x0b\t{0\x96\x12\xaa\ +\xb9\x8e\xe4\xb5\xa9\x97\xbaW\x1e\x0f\x1e\x06Hs\x89(-\xd3\xf1;g\xde\xcaw\n\ +\xa0\x85\x01\x00Vq\xce\x0cc)\x90g\x1f\xe2z0 \xa6\xd5<}\x08\xe7\xfd[+\xdc\x0c\ +Z\xa1K\x04`gpiU\xc8\x12\xbd\xa6\xfa\xbf\xddwQs\xd0j\x93Z^\xbb\xc1\x97\x00\ +\x12$\x9fq>\xf6<g\xde\x80:\x9a&\xcbv\xd5\x06Z\xad\x0cp\xec\xbaS\xab\x82\xc4e\ +tV\xd6\x90\x01\x04Jd\xad\x06o}[\x11\x9e\x03\xcbl\xbda\xff\x02|\x85~ 5\xf1\ +\xd3\x80+\xd1}\xd0>\x19\xfd\x9b\x08\x1e\xad\xb3\x97\x00\x00\x00\x00IEND\xaeB\ +`\x82' -def getIconBitmap(): - return wxBitmapFromXPMData(getIconData()) +def getAutoRefreshBitmap(): + return wxBitmapFromImage(getAutoRefreshImage()) -def getIconImage(): - return wxImageFromBitmap(getIconBitmap()) +def getAutoRefreshImage(): + stream = cStringIO.StringIO(getAutoRefreshData()) + return wxImageFromStream(stream) + +def getAutoRefreshIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getAutoRefreshBitmap()) + return icon #---------------------------------------------------------------------- -def getNewData(): - return cPickle.loads(zlib.decompress( -"x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\ -\x81<eK\x03\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT0'\x02$\xe9f\xe1\xe6\xecf\x01\ -\x95\xc4\x0e\x06ZR\x0f\n\xb0KF\x80\x01B\x16\x9bd\x84\x1e>\x9d0\xbdX$A\xf2\ -\xf9\xc3Z\x12\x010%\x15\xf2\x11` S\x82\x1e\x00-\xd9\x8b\xfa" )) +def getCopyData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xc8IDATx\x9c\xed\x95;\x0b\xc30\x0c\x84\xe5\xe2\xc1\xe3\xfd\xd4\x8c\x195\ +v\xccO\xd5\xa8\xc1\x90\x0e!!\x0fI\xe4Q\x0f\x85\x1e\x08\x8c\x06}\xdc\xd9\xc2\ +\t\x00\xb5\xd4\xab\xe9\xf4?\xe0\x8c\xb2\xd5\x14\x91\xd1\xea\x03HW\x01\xae\ +\x03\xad\xba\xa9\x08|\x0b\xe0A\xafB\x92\xb5\x07"2jU*\xb9,\x83\xa73\x9bC\x80\ +\xc1\x8d.\x04\xecU\xf2\x9b\xb4\xf6\x87^\x04\t#*\xb9l\xca\x93\xd6\x9eD:3\xba\ +\x10`]\xf4\x1a\xbcwaAn9X\x03\xb5\xf6K\x11\x111\xf3\x06\xf2\xc8\xc1\x99\xf8\ +\xccE\x9b\x87\x1c\xc5\x0b\xf8\xacL\x00\x80\xb4\xb7JD\xd4u\xe2\xc2=\xa8\xeb\ +\x80\x99\x8dg7]\xe2c\x07\x91\xe6\x17\xd3\x04\x00\x0cft\x91\xccM\xfe\xa6~\xff\ +\xc3i\x0e\xf8\x00\xb4\xedw\x96)\x01f=\x00\x00\x00\x00IEND\xaeB`\x82' -def getNewBitmap(): - return wxBitmapFromXPMData(getNewData()) +def getCopyBitmap(): + return wxBitmapFromImage(getCopyImage()) -def getNewImage(): - return wxImageFromBitmap(getNewBitmap()) +def getCopyImage(): + stream = cStringIO.StringIO(getCopyData()) + return wxImageFromStream(stream) + +def getCopyIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getCopyBitmap()) + return icon #---------------------------------------------------------------------- -def getOpenData(): - return cPickle.loads(zlib.decompress( -'x\xda\xcd\x92\xb1\n\xc3 \x10\x86\xf7<\xc5A\x07\x0b\x81#IK\xb1\xab\x01\xc7:d\ -\xb95\x84N\r\xbd\xbe\xff\xd4hb\xb5j\xbb\xb6\xbf\x08~|\xde)\xe2~~\xb4\xd5 \ -\xba#t\x078A+\xaaq\x10\x08\x13\xa8y\x9cn\x8e\xccB\xbbsc\x87c\xb2\xac\xa5\xee\ -\x9b\x95a\xe1\x0b\xdf\xaf\x0e\xd8K-\x1d\xd7\x96\x95Tas9\x7f"\x11\xf1\xa3D7\ -\xf1K[Leh\xe7\x97A"1\xe1\x9a\xfcB\xc8\xb4\r4\xb9\xf4\x8eJ\x92C\xdf\xf2\x99\ -\xb5\x8f\xab\x8e+9v\x89\xa4\xd4\xc52so\xf2\x95\xcd\xc5/dB~\xfb\x13\xf0\t\x81\ -T\x87G' )) +def getCutData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xb6IDATx\x9c\xcd\x94\xd1\r\xc4 \x0cC\xcdM\xe0Q3BF`\xd4l\xd0\xfbi\xee*\ +\xd4@@B\xc2R\xff\x1a\xbf\xe2\x98\x16\x92\xd8\xa9\xcfV\xf7c\x00fvm\x05\x00\ +\x80\xaa\xbeBF\xf04@DB\xf3\x08\x9e\x06\x90,\xad\x91\x9b\xd7Z\xbb\xb3%[S7$YZs\ +U-\xd1\xdct\x8b\xda8z\xe6S\x00\x8f\xc9w1\x8af\x1a\xf0\xa6\xd1\xd7\x03S;\x90;\ +\x1a\xbd\x1f\x80\xacC\xc0\xf4\t\x9e\xd1\x98\xc9\xf5\x07/\x02z&\xb5\xf2\xf7\ +\xce\x12\xc0\x07\xdd\xa8\xa7\xe8\xb2\x9d\xf1\xb3k\xe5\xcb\x151\x00\xfd\x13\ +\x0e[\xf4\xcc\xd7\x8d\xbc\x9e\xcfX\xa2\xca\xa6j\x9a1\x8a\x94\xbe\x07\xab:s\ +\xc9G\x01\xbe\xd4=_\xff?J\x99`\x00\x00\x00\x00IEND\xaeB`\x82' -def getOpenBitmap(): - return wxBitmapFromXPMData(getOpenData()) +def getCutBitmap(): + return wxBitmapFromImage(getCutImage()) -def getOpenImage(): - return wxImageFromBitmap(getOpenBitmap()) +def getCutImage(): + stream = cStringIO.StringIO(getCutData()) + return wxImageFromStream(stream) + +def getCutIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getCutBitmap()) + return icon #---------------------------------------------------------------------- -def getSaveData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV72Q02V0U0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xfc\ -\x81<eK\x03\x10\x04\xf3#@|\x0b\x03\x0b\x03\x03\x08_\x01\xc8\xf7\xcb\xcfK\x05\ -s\xf2A\x92n\x16n\xcen\x16PI\xec\x80\xe6\x92z(\x00]2B/\x1f\n\x80L\x7f\xdc\x92\ -z\xf8$#\xe8&\x19\x01\xf3G\x046I\x04\xc0\xa3\x13\x8f\xb1x\xed$Y\x125\xe4\xd1%\ -\x15\xfc\x91\x01]R\x02vI=\x00\xd8\x14\x96@' )) +def getIconData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00 \x00\x00\x00 \x08\x06\x00\ +\x00\x00szz\xf4\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x02\\I\ +DATx\x9c\xedV1\x92\xa40\x0c\xec\xbd\xdaG8p\xb0\xcfpp\xc1>\xc1\x01\x01\xcfPp\ +\xc1>\x81\x80\x80g(\x98`\x9e@0\x81\x9f\xe1\x80`\x9e\xe0\x80*_\xc0\xda\xd8\ +\xc63\xb0{uE\xb2\xaar\x01B\x12m\xa9%\xf3\xe2f\xe7q\xa2\xfc:\xf3\xe3\x00\xf0\ +\n\x00\xc6\x18\x0c\xc3\x00\x00\x18\xfa\x01B\n\x00\xc0\xc7\x9f\x0f\xd8\xc9\ +\x82\x88\xa0\x94\xc20\x0c0\xc6l\x82(\xa5\xd06m\xf4\x0bR\xda\xb7M\x0b\xdd\xe8\ +\xdc\xd9\xcd\xce\xbb\xd9y\xa5\x94\x07\xe0\x89\xc8\xbb\xd9\xf9\xae\xef<\x00\ +\x0f\xc0\x07\x1b\xdd\xe8\xa8+\x97nt\xb4s\xb3\xf3B\x8a\xaa]\x88\x1fV\x040\xde\ +F\x0f\xc0\x0b)\xfcx\x1bc\x80\xf16n\x000s\xd4Yk7@\x03x\xdd\xe8\xe8\x1f\xe2\ +\x971\x91\xa2\tY\x08\xd7rW5\x00\x9f$\xaef\xaa\xb4\x0b\xfa4n\x06 \xddM\x894\r\ +@D\x9e\x99=3g:7;\xcf\xcc\x1b@\xcf\xd6k\xca\x07!\x05\x84\x14\xb8O\xf7H\xae\ +\x9a\x04\xc2\xa6BDU\xdb=\xc9\xda\xd0\x18\x13?\x0e\x00\xd7\xcb\xb5\xeaDD`f0s\ +\x04Y\x03uH\xd2\xf4\xa7\xb5\xc7\'!\xf78\x10R\x9e\xd65\xd8u}\x97\xf9\xd7\xb8\ +\x153\xc0\x17\x861\x06\xba\xd1`\xe6X\x8a\xb6m\xbf\xbc\xa9\xb6Y|\xae\x97k\x9c\ +\x03\xc6\x98x\xcf\xccy\x06jm\x97\xb6\x8d\xb5v7\x03J\xa9l\xb7DT\x9d\x03eg\xc4\ +I\x18j\x99^\x89\x08v\xb213\xe1]:\xf1\x94R\xdb\xe9\x06\xa0\xeb;\x08)v\'\xe1\ +\xcb\xcfa\xf4?\x83\xdf\' T@7\'\x000\x06\x08M\xe4\xe6\xba\xcd\xe9%8\x1d\xc0\ +\xa1\x12\\/K:\xed\xb4<+\xb5\xae \xf7\t\x18\x86\xd5\xe6M\xe6\xef\x1f\xca\xdei\ +5\xde\x9c\x07\xb6KHW\x0c\x9e\xad\x8dR\xeb\xfd\xa3\xf8\xbb\x00\xd2`\xcc\xcb\n\ +:\xdd\x84i\xb8\xea\x88\x96\xe7\x12\xd0\xb7\x00\x84\xc0B.\x99X\x0f\x9b50\xf3\ +\xfa\xacT\xee\x7f$\x03\x878p\x9f\x80\xf7\xdf\xfbv\xe5/\x01\xd1\xda\x86\x8f\ +\xe4\x10\x00\xf1\x84PB\x1e\x89\xf0\x8f\x00\xde$0\xf4\xeb\xc7\x8cY\xb2R\x023&\ +\x9fx\x95?\xf8\xad<\xe3\x80\xb59\xb9\x82^\xc8\x9c\x84]\xbf\xda\x05\xae\x94\ +\xdd\xf3\xed.\xa8\xb5W\x19\xd4\xda\x9cp)\xe8=\x00\xbb\x93\xb0\xeb\x01\xe6<\ +\xd5\xcc\xf9l\x17\xb2nsd\x10\xfd\xfc\x0f\x9c\x0e\xe0/\xa6u\x89KB\x8f8O\x00\ +\x00\x00\x00IEND\xaeB`\x82' -def getSaveBitmap(): - return wxBitmapFromXPMData(getSaveData()) +def getIconBitmap(): + return wxBitmapFromImage(getIconImage()) -def getSaveImage(): - return wxImageFromBitmap(getSaveBitmap()) +def getIconImage(): + stream = cStringIO.StringIO(getIconData()) + return wxImageFromStream(stream) + +def getIconIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getIconBitmap()) + return icon #---------------------------------------------------------------------- -def getCutData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\ -\x81<e\x03 \xb00\x00\xf3#@|K\x03\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT(\x07;\xa0\ -\x96\xa4\x1e^\xc9\x08\x145h\x92z\x102\x02\xab\x9d a\xa0\x1c\x0eI=$9L\xc9\x08\ -\xb8\xa1\x98^\xd1C\xd2\x88U\x12W \xe4\xe7\xeb\xe5\xe7\xe3\x96\x8c\xc8\xcf\ -\x87K\xa3H\x82\xc4#\xc0\x08S\x12&\x03B\xe4H\x82\x0c\x8f\x88\xc0j\'H8\x02{\ -\xf0E \x02\x80\x9a)\x81DI=\x00\x12\xa5\x85\x9f' )) +def getNewData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00uIDATx\x9c\xed\xd5\xbb\n\xc0 \x0c\x05\xd0\x9b\xe2\x90\xf1~\xb2\x9f\x9c1\ +\x83`\xa7v\xf2EEJ\xa9\x01\x17\x03\x1e\x0c\x89\nI\xac\x8cc\xe9\xe9\x1b\x18\ +\x89\xd0J\x9aYn\xe5I\xca\x14\x00\x00\x9e\xbc\xb8\xafAaf\xb9\x87L\x95\xc8\x93\ +wo9\x05hP\x00\xedR>\x06<\xf9\xbd\x00 \xc6XD\xbe\xdf\xa6\x1b\xf8\x01\xd0}*\ +\xaeaZ\x02\x90\x94\xda\x00\x8d\x86\xec/\xf3u\xe0\x04ND$:\xe8\xc5\xf5\x91\x00\ +\x00\x00\x00IEND\xaeB`\x82' -def getCutBitmap(): - return wxBitmapFromXPMData(getCutData()) +def getNewBitmap(): + return wxBitmapFromImage(getNewImage()) -def getCutImage(): - return wxImageFromBitmap(getCutBitmap()) +def getNewImage(): + stream = cStringIO.StringIO(getNewData()) + return wxImageFromStream(stream) + +def getNewIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getNewBitmap()) + return icon #---------------------------------------------------------------------- -def getCopyData(): - return cPickle.loads(zlib.decompress( -'x\xda\xc5\x92\xb1\n\xc20\x10\x86\xf7>\xc5\x81C\x9c\x8e\xb4*\xc4\xd5BF3t\xc9\ -Z\x8a\x93\xc5\xf3\xfd\'\xef.vP\xee\xe6\xfe\t\x81\x9f/\xdf\r!\xc7\xf5\xddwS\ -\x18\xce0\x9c\xe0\x02}\xe8\xe6) ,p[\xe7\xe5\xa9\x8d\xb8\x1d"\'E\xedE\xfa5\ -\xca\xd2\x0e\xdc\xef\xf4zh\xa9\x02s\xcacN_hg_\x88\x1a\x0fV\xce/\xfd\x87\x15\ -\x1d\x88\xbcIc\x9b\x95\xf4 \xcbDl\xb0\x92c\xf2\xf0m\xb2i\xca\xa5\xe2\x98(r1\ -\x1e\xc11\xa1H\x1c\xb3\xc53\x1b\xdcb\xc16\\\xb2\xdfO\xc0\x0f5t\x92\x06' )) +def getOpenData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xc9IDATx\x9c\xed\x951\x0e\xc3 \x0cE?U\x07F\x1f\xaaC\x8f\xe5#p\x9c\x0e=\ +\x94G\x06$:\xa4T\x84\x04C\x11\x0c\x95\xfa\xa5\x88("\xefa;R\x0c\x11ae.K\xe9\ +\x7fAO\xae\xa3/\x8aHL\xf7Ddj\xfb\x86*\x10\x91HD&]I\x96KS\xcc\xac\xcf4\xc1\ +\xcbj\xaa-\xeamA\xb9\xb7\xcci\x05"\x12}\x00\x00\x0f\xc0\xc2*\x93j\xc9\x95\ +\x19lp\xc0\xc3\x07\xc0\x87\xe3\n\x00\xcc\\=}C`w\x92\xf3\xb5\x1d\xa5E{\x98\ +\xd6\xa6<\xddC.\xe1\x8fg\x1b~\xbfm-c\xe6\x8f\xa41\x03|\x05w\xce\x1d\x9e\xab\ +\x15\x8c\xc0\xf3\xd3\x03J\x053\xe0\x802\xe46z\x8b\x06\xaf\n\xde/tKjpU0+\xbf\ +\xff\xc3Y.x\x01\xfcgd\xb8c~\xd8\x9d\x00\x00\x00\x00IEND\xaeB`\x82' -def getCopyBitmap(): - return wxBitmapFromXPMData(getCopyData()) +def getOpenBitmap(): + return wxBitmapFromImage(getOpenImage()) -def getCopyImage(): - return wxImageFromBitmap(getCopyBitmap()) +def getOpenImage(): + stream = cStringIO.StringIO(getOpenData()) + return wxImageFromStream(stream) + +def getOpenIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getOpenBitmap()) + return icon #---------------------------------------------------------------------- def getPasteData(): - return cPickle.loads(zlib.decompress( -'x\xda\xcd\x92\xb1\n\x830\x10\x86w\x9f\xe2\xa0\x83\x85\xc0\x11m\xa1\xe9\x16Z\ -p\xec\r.YE:U\x9a\xbe\xff\xe4]48x\xe9V\xe8\'\xc2\xfd|\xf7g\x88\x1e\xa7OS\xf5u\ -{\x86\xf6\x04\x17h\xeaj\xe8k\x84\x11n\xd30\xbeR2\x9c\x0e\x96q6e\x92|\xb5\xf2\ -\xa4\x1c$w\xae\xbb\xdb%G\xc9\xce\xba\xbc\x0f\x9c\x1f\xf1\xfdL\xc1\xe7\xe5\ -\xce\xadR\xe7\x0f$2\xaa\x14\x81!\xe0\xb6\xb0I\x8c1"\xab\x90\x86\xbd\xe4\x9e \ -\x13\xed\xe5\x8a*7ti\x16\n\xd2\x0b\xc6|\x93\xde\xe8\x92\x0f\x95\x97\x8aM\xee\ -R\xa9)]R\xae\xaf\xd0\x04 \xc6dH\xfbd\x94\xf9\xe9\x9f\x803\xb0L\x99\x05' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xcfIDATx\x9c\xed\x95\xb1\x0e\xc3 \x0cD\x8f\x8a\x81\xd1\x9f\x9a\xb1\xa3G\ +>\xd7#\x03\x12\x1d*R\x02\xa6A$\x0c\x95zR\x14@p\x0f0\x18CDX\xa9\xc7R\xf7?`Dv\ +\xb4\xa3\x88\xa4\xb2NDfd\x9c\xe9\x9d\xa2\xda\x10\x00B|\xff\x9d2\xad\x1eP]\ +\x81\x88$f\xde\xeb\xcc\x8c\x10?\xc6\xb9\\\xf5I\x1a\xe44\x06\xd9<\x1b\x97\xe5\ +\x12\x90!C+\xa8\xa5m\xc9\xa8N\x87\xd6\xb3\xbc\x1dp\x84-\x06\x00@\x88\xcf\xa6\ +\xcdY\x0f@\xa7_\xd8\xdd\x16\xec\xacG}\xea\xa7n\xb2\xb3~\xff\xca6\xa0=IS+\xa8\ +\xb7)\xd7K\xe0%\x80f\xa4\xc5\xa6\x0b "\xa3]\x9a\x1c\xc8\x9e\xd90\xa0\x07\xd9\ +6Qg?\x05\x00\x00f>\xe4\x16"=\x1d|S7\x9b\xde\xa5\xdf\x7f\xd1^\xf7\xdbLY\x05\ +\x8av\xd9\x00\x00\x00\x00IEND\xaeB`\x82' def getPasteBitmap(): - return wxBitmapFromXPMData(getPasteData()) + return wxBitmapFromImage(getPasteImage()) def getPasteImage(): - return wxImageFromBitmap(getPasteBitmap()) + stream = cStringIO.StringIO(getPasteData()) + return wxImageFromStream(stream) -#---------------------------------------------------------------------- -def getTestData(): - return cPickle.loads(zlib.decompress( -'x\xda\x95\xd2=\x0b\xc20\x10\x06\xe0\xbd\xbf\xe2\xc0\xa1N\xa1\x1f\n\xba*t\ -\xf4\x86.\xb7\x96\xe2d\xf1\xfc\xff\x93\xb9$\xcd5M\xa9xY\xf2\xf2\x10r$w\x9c>u\ -\xd1\x97\xcd\t\x9a\x16\xceP\x97\xc5\xd0\x97\x06F\xb8M\xc3\xf8r\x89l:\xb4\x95\ -,\x97Q\xf2\xb5\x92\xe52K\xee.\xdd\xbd\xf2\x19l~\xf0\xfb\x19\xc2v\xfd\x81Fj\ -\x1b\xcd\\9\x12\xd1\x8cD+$f\x0efw\xb4\x8b\xb8D\xb1\xa0nG\xbb\x88\x8a\xde,r@w\ -4A\x07\x8b\xa3\x01\xb5\x95\xd8V\x86Fm\x03M\xb4\x05\xaaF\xcb1\xb9R_h\xd5\x10f\ -\xc8\x1c\x15\xd3_\x89&\x8a+\x04$\xff\x14D\xe8-\x9d\x04\xcb\xa4\x94\xcd\x10\ -\xa2\xd2\xef\x013_\xba\x1d\xa3N' )) - -def getTestBitmap(): - return wxBitmapFromXPMData(getTestData()) - -def getTestImage(): - return wxImageFromBitmap(getTestBitmap()) +def getPasteIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getPasteBitmap()) + return icon #---------------------------------------------------------------------- def getRefreshData(): - return cPickle.loads(zlib.decompress( -'x\xda\xad\xd2\xbb\x0e\xc20\x0c\x05\xd0\xbd_q%\x860]\xf5\xc1\x00?\xc0\xc8\ -\xd2\xc5+Bl\xa8\xed\xffO\xcd\xab\xa9\x01\x17\t\x81\xb3\xc4:\x8a\x15;\xd9?\ -\xa6\xa6\xea]{@\xdb\xa1C\xe3\xaak\xef\x047\xecNuX1\x87\xcf/\xe3p\x8f\t\x03\ -\x9e\x8f\xb5\x8f\x8cv|\x83\x0c\xb1\x81^D\xa9BF\x13\xac\xaa1Y\xd8\x88\x89\xc4\ -\'d\xdal\x94\xd5u\x9f0\x91\x89\xc8d\xa3j\xf7\x9f\xb8t@\x1bY\xae\xfd^6\x9f\ -\xb0&\xb4\x1c\xa5\x8dQY\xaa\x9a\x8f]\x86\xf1\xda\x8a\x88\x14\xc3O\x1f\x8c3\ -\x1dNw\xdd' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xcaIDATx\x9c\xc5\x94\xc1\x11\x84 \x0cE\x93\x1d\x0b\xc8\xd1\x12=RBJ\xc8\ +\x91\x12=\xd2\x81{\x91\x19\xcc\x12\x082\xcc\xfe\x9b"\xff\xc17\t\x12\x11\xac\ +\xd4g\xa9;\x00l\xde\x0f\xcf\x94.\xfdn\'\xc2\xde>\xd7\rJ\xf3(\xd2\x84\xba\x01\ +ys\xcd\xbc<y\x0f\xd2\xbcA\xcd\x9c\x99QC\x98\xd9\x84\xb8\xff\xc1\x11\x82+s-\ +\xb4\xca\xd4\xba\xba\x15\x8f\x05w\x97i\x14\x81(\xf2\x88\xc3\x13S7\xa2\xb2jr\ +\xfe#2\x01;\x11\xe6S\xbd1\xee\x02f\x8d\xb3\x96\x8f\x8a\xff\x02\xce\x94\xaeV\ +\xa7N\x8d\x8a\x11\xa3\xb2\xd2\x86\x00\xdeqp\xaf\xcf5\xda\x11\xc2\xe3\xd9\x13\ +\x8f\x0bP\x1b\r\xd6\xf8\xae\xc9\x9cEZ\xb5\x13\xeb\t;\x05\xb8\x8d~ \xbdf\x1c\ +\x02\xbc\xd1\xf2F\xfb\x02O\x82o\x1e\xb4]1\xc3\x00\x00\x00\x00IEND\xaeB`\x82'\ + def getRefreshBitmap(): - return wxBitmapFromXPMData(getRefreshData()) + return wxBitmapFromImage(getRefreshImage()) def getRefreshImage(): - return wxImageFromBitmap(getRefreshBitmap()) + stream = cStringIO.StringIO(getRefreshData()) + return wxImageFromStream(stream) -#---------------------------------------------------------------------- -def getAutoRefreshData(): - return cPickle.loads(zlib.decompress( -'x\xda\x95\xd2;\x0e\xc20\x0c\x06\xe0\xbd\xa7\xb0\xc4\x10&+-\x1d\xca\x05\x18Y\ -\xba\xfc+Bl\x08s\xff\x89<\x9c\x12\xc9I\xa5:Cc}\x95#;9\xbf\xbf\xe3\xb0\xbai\ -\xa6\xe9B3\x8dnx\xac\x0e\xf4\xa4\xd3\xd5\xc7\x95r\n\xf9]>\xaf\x94HD\xef\x97\ -\xc5g\xe4\x98\xdfB\xe6\xcb\xcf\xed8\x82\x1c\xa3\x83APi\x85\x9c\x0c\xf4\xd7\ -\x1a\xb3\xc5\r\x9a\xc8\xb4\x87\x9c7\x9d\xb2 \t\x01\x8b\x91\x82\x81U\xebV\x00\ -\xfd\xb4PC\xb6\xba\x16;ew1w \xed\xb2\xbc)DLY\x1dM\xea\t\x16u@\xe8\\\x19\x95\ -\xf1w.\xbb\x98i\x05z\xdc\xe17d\x90\x7f\x95\x07\x86\x9f' )) - -def getAutoRefreshBitmap(): - return wxBitmapFromXPMData(getAutoRefreshData()) - -def getAutoRefreshImage(): - return wxImageFromBitmap(getAutoRefreshBitmap()) +def getRefreshIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getRefreshBitmap()) + return icon #---------------------------------------------------------------------- -def getTreeDefaultData(): - return cPickle.loads(zlib.decompress( -"x\xda\xd3\xc8)0\xe4\nV74S04Q0U0T\xe7J\x0cV\x8fPHVp\xcaIL\xce\x06\xf3\xfc\ -\x81<eK\x03K\x13K\x030_\x01\xc8\xf7\xcb\xcfK\x05s\xf4@\x92n\x16n\xcen\x16`~>\ -\x88\xefb\xe0b\xe2\x02S\x8c\n\xc8\x10\xd4\x83\x80\x08T\xc1|\x10\xf0\xa7\xae\ -\xa0?\x18\xa0\nF@\x01\x99\x8e'FP\x0f\x00\xdc\x1bL7" )) +def getSaveData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\x86IDATx\x9c\xed\x95\xb1\n\xc0 \x0cD\xb588\xde\'\xdf\';:\x14\xdaA\x04\ +\xa9\x1a\xdb\xa2\x14\xa5\x07"\x04\xb9\xa7IT\r@\x8d\xd46\xd4}\t\x80)\x05\x9ds\ +\xc7\x1b3\x00\xfa\x1a\xab\x9e\x80\x0c\xb3\xdf\xbd8\xd2\xb5$\xb3\x8duIQ\x04\ +\x944\x07@\xd2\xfc\x80b\x9bF\x91JYcE\x03)\xffM\xc0\x1d\x83\x96\xba\x00\x86tQ\ +z\xd1$-\xdaE\x004)?xiwI5\xa8\x169@\xf2\xc7\xeb\xa9\xf4\xffe~\x0e8\x01v84H\ +\x1c6\xc2\x8f\x00\x00\x00\x00IEND\xaeB`\x82' -def getTreeDefaultBitmap(): - return wxBitmapFromXPMData(getTreeDefaultData()) +def getSaveBitmap(): + return wxBitmapFromImage(getSaveImage()) -def getTreeDefaultImage(): - return wxImageFromBitmap(getTreeDefaultBitmap()) +def getSaveImage(): + stream = cStringIO.StringIO(getSaveData()) + return wxImageFromStream(stream) + +def getSaveIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getSaveBitmap()) + return icon #---------------------------------------------------------------------- -def getTreeRootData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S04Q0V0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3"\x80<e\ -c\x0b\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT(\x07\x15 \x04\xf5\x80\x00Y0\x02\x080\ -\x04\x15"\xb0i\x8f\x80\xe9\x87\xa8\x86\n\xc2\xf4\xa3\x08\x0e\xa8v\x9c~G\x15\ -\xd4\x03\x00\x87\xa5@\xc2' )) +def getTestData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x17\x08\x06\ +\x00\x00\x00\x11!\x8f-\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x01\x15IDATx\x9c\xb5U\xbb\x11\x830\x0c\x95s)Rj\x04\x8f@A\xc18\x8c\xa2\x11\ +\x18\x81qR\xa4\xf0\x08\x8c@I\xc1\x9d\xd3`\xb0\x85l\x8b\x1cQ\x83\x11\xf2\xfbH\ +\x06\x0c"\xc2?\xe3\xf1Wt\x00xj\x8a\xe6y\xf6<\x87\x88F\xb3\xd7\x94Z$\x01_%\ +\x12\x1dXkw`\xe7\\\x91 \xd4N\xd3$\x12\x9d\x1cXk\xfd\xfbs\x80\xbe\nM\\\xd6c\ +\xdd\xb5\x8dHr\xeb\x90\x89\xe8\xd4\xd2\xc4\x01W\x1fBr\x11\xab\x0f!\xb9\xb8\ +\xfd\x98r\x17\xbb\x83\x9cz\x80\xc3\xc1\xb2\xa6k)\xb8\x8b\xaa\x03\x0e\x18\xae\ +\xa5\xe1\xc7.\xf62\xe7\\v\x13W\x1b\x9c\xc8\xf5i\x17T3\xe0@%\xf5<\xd4C\x0e\ +\xa0W\xc0\x13\x02\xcd\xb7E\x03>\x0cCr\xaf\xd6\x13\xcf\xa1FDD\xf2)\xca\xb9\ +\x90\x86,\x05W\x7f"\xd0\x80\xd7\xf2\xb1z\x91 v\x91\x03\x91\x9eK\xea\x0123@DC\ +D\xbekG\x00\x00\x90\xde\xf0\xaem6\xe0~\xcfq\xf5\x00\x95\x1f\xce\xb6\xc9\x8f\ +\xe3x\xca\xf7}\x19XM\x10\x13\t\xb9\xea\xd1V\x13\xfc\x1a_\xfc\x89l\x9f\xd7k\ +\x04?\x00\x00\x00\x00IEND\xaeB`\x82' -def getTreeRootBitmap(): - return wxBitmapFromXPMData(getTreeRootData()) +def getTestBitmap(): + return wxBitmapFromImage(getTestImage()) -def getTreeRootImage(): - return wxImageFromBitmap(getTreeRootBitmap()) +def getTestImage(): + stream = cStringIO.StringIO(getTestData()) + return wxImageFromStream(stream) + +def getTestIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTestBitmap()) + return icon #---------------------------------------------------------------------- -def getTreePanelData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S04Q0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\ -\x81<eK\x03K\x13K\x030_\x01\xc4w\xb3psv\xb3\x00\xf3#@|\x17\x03\x17\x13\x17\ -\x98<\n\xd0\x83\x08F \x83\xfca+\x98\x8f\x02 \x82zh\x00(\xa8\x07\x00&\x96e\ -\x83' )) +def getTreeDefaultData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00QIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b\x1a\x06\xb0\xa0\x0b\xbcx\xf3\ +\xe2?.\xc5\x1c,\x1c\x0c\x02\x02\x02\x8cx\r````\xb8q\xe3\x06\x86\xd8\x81\x03\ +\x07\xb0\x1a:\xf0a@\xfd@d`\xc0\xed_\xa2\x0c\xe0`\xe1 \xc9\x05\x8cC?%Rl\x00\ +\x00\xdc\x00\x0b\x9f\x8dZU\xfe\x00\x00\x00\x00IEND\xaeB`\x82' -def getTreePanelBitmap(): - return wxBitmapFromXPMData(getTreePanelData()) +def getTreeDefaultBitmap(): + return wxBitmapFromImage(getTreeDefaultImage()) -def getTreePanelImage(): - return wxImageFromBitmap(getTreePanelBitmap()) +def getTreeDefaultImage(): + stream = cStringIO.StringIO(getTreeDefaultData()) + return wxImageFromStream(stream) + +def getTreeDefaultIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeDefaultBitmap()) + return icon #---------------------------------------------------------------------- def getTreeDialogData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"\x13\x05Cu\xae\xc4`u\x05\x85d\x05\xa7\x9c\xc4\ -\xe4l0/\x1f\xc8S\xb64\xb04\xb14\x00\xf3\xf5@|\x03 p\xb3\x00\xf3#@|\x17\x03\ -\x17\x13\x17\x03\xa8nT\x00\x11\xd4C\x01$\x0bb53\x02\x05\x0c\x98`>1\x82\xf9`@\ -\xc8LLo\xea\x01\x00\xb5\x9cde' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00IIDATx\x9ccd``\xf8\xcf@\x01`\x81P?\xc8\xd4\xce\xc1\xc0D\x89\xed\x0c\ +\x0c\x0c\x94\x1b\xc0\xc8@\x8d0\xb8p\xe5\x02Y\x9a\rt\x0c\x06A\x18\x8c$\x03\ +\x0e\x1c8@\x1b\x17\xb0\x90b\x1b\xd1\x06888\x10m\x00\xc5I\x19\x00\xe6)\x0cc\ +\xbf\x9c\xcc\xa1\x00\x00\x00\x00IEND\xaeB`\x82' def getTreeDialogBitmap(): - return wxBitmapFromXPMData(getTreeDialogData()) + return wxBitmapFromImage(getTreeDialogImage()) def getTreeDialogImage(): - return wxImageFromBitmap(getTreeDialogBitmap()) + stream = cStringIO.StringIO(getTreeDialogData()) + return wxImageFromStream(stream) + +def getTreeDialogIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeDialogBitmap()) + return icon #---------------------------------------------------------------------- def getTreeFrameData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"c\x05Cu\xae\xc4`u\x05\x85d\x05\xa7\x9c\xc4\ -\xe4l0O\x0f\xc8S6\x00\x027\x0b0?\x02\xc4w1p1q1\x80\xaaF\x05\x10A=\x14@\xb2 V\ -3#P\xc0p\x10\xc4\xf4\xa6\x1e\x00\xe3\x8f`,' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00:IDATx\x9ccd``\xf8\xcf@\x01`\x81P?\xc8\xd4\xce\xc1\xc0D\x89\xed\x0c\ +\x0c\x0c\x94\x1b\xc0\xc8@\x8d0\xb8p\xe5\x02Y\x9a\rt\x0c\x06A\x18\x8c\x1a0,\ +\x0c\xa08)\x03\x00\x90c\x07\x1f\xb3yvF\x00\x00\x00\x00IEND\xaeB`\x82' def getTreeFrameBitmap(): - return wxBitmapFromXPMData(getTreeFrameData()) + return wxBitmapFromImage(getTreeFrameImage()) def getTreeFrameImage(): - return wxImageFromBitmap(getTreeFrameBitmap()) + stream = cStringIO.StringIO(getTreeFrameData()) + return wxImageFromStream(stream) + +def getTreeFrameIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeFrameBitmap()) + return icon + +#---------------------------------------------------------------------- +def getTreeMenuData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00]IDATx\x9cc\x14\x10\x10`\x80\x81\x17o^\xfcg \x02p\xb0p0\x08\x08\x080\ +2000\xb0\xa0K\xde\xb8q\x03\xaf\xe6\x03\x07\x0e\xa0\xf01\x0c\xc0\xa6\x08\x06\ +\x1c\x1c\x1c0\xc4\x98\xf0ZG\x04\xa0\xd8\x00\xac^\xc0\xe6T\x92\x0c\x18\r\x83\ +\xd10\xc0\xe5\x7f\xa2\x0c\xe0`\xe1 I3\x03\x03\x03\x03\x00l\xa5\x16\xbeals=\ +\x00\x00\x00\x00IEND\xaeB`\x82' + +def getTreeMenuBitmap(): + return wxBitmapFromImage(getTreeMenuImage()) + +def getTreeMenuImage(): + stream = cStringIO.StringIO(getTreeMenuData()) + return wxImageFromStream(stream) + +def getTreeMenuIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeMenuBitmap()) + return icon #---------------------------------------------------------------------- def getTreeMenuBarData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"S\x05Cu\xae\xc4`\xf5\x08\x85d\x05\xa7\x9c\xc4\ -\xe4l0\xcf\x1f\xc8S\xb64\xb04\xb14\x00\xf3\x15\x80|\xbf\xfc\xbcT0G\x0f$\xe9f\ -\xe1\xe6\xecf\x01\xe6\xe7\x83\xf8.\x06.&.0\xc5\xa8\x80\x1a\x82z\xa8 \x02"\ -\x98\x8f\x0c\xfca\x82\xfe \x00#I\x17\xc4b\xa6?*\x80\x08F\xa0\x01\x1a\xf9]\ -\x0f\x00\x9b\xde`\xb2' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00bIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4{P\x18\xc0\xf8\xe3\xcf\x8f\xff\ +\xe4j\xe6`\xe1``a```\xb8q\xe3\x06\xc9\x9a\x0f\x1c8\xc0\xc0\xc0\xc0\x001\x00Y\ +\x00\x19888\xe0\x14\x87\x81\x81\x0fD\xb8\x17\x90\x9d\x85\x0cp\x89\xc3\r\x981\ +c\x06E.`d`` ;\x1a\x19\x18\x18\x18\x18G\xf3\x02\x03\x00DO\x13\x93\xa7\xebQk\ +\x00\x00\x00\x00IEND\xaeB`\x82' def getTreeMenuBarBitmap(): - return wxBitmapFromXPMData(getTreeMenuBarData()) + return wxBitmapFromImage(getTreeMenuBarImage()) def getTreeMenuBarImage(): - return wxImageFromBitmap(getTreeMenuBarBitmap()) + stream = cStringIO.StringIO(getTreeMenuBarData()) + return wxImageFromStream(stream) + +def getTreeMenuBarIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeMenuBarBitmap()) + return icon #---------------------------------------------------------------------- -def getTreeToolBarData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"\x0b\x05Cu\xae\xc4`\xf5\x08\x85d\x05\xa7\x9c\ -\xc4\xe4l0\xcf\x1f\xc8S\xb64\xb04\xb14\x00\xf3\x1d@|7\x0b7g\x03\x08_\x19\xc4\ -70\x80\xf3\x15\x80|\xbf\xfc\xbcT0G\x0f\xa6\xd8\xcd\x02\xcc\xd7\x86\xf0\r\x0c\ -\xa0\x8a\xf3A|\x17\x03\x17\x13\x17\x98fT@\rA=T\x10\x01\x11\xccG\x06\xfe0Am\ -\xed\x88|\x07\x87\x88|e\xe5\x08\x02\x82\x11\x11\x11p\xec\x8f\xc7L\x7fT\x00\ -\x11\x8c@\x034\xf2\xbb\x1e\x00\x1c\x05j\x12' )) +def getTreePanelData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00CIDATx\x9c\xed\xd31\x0e\x800\x0cC\xd1W\x94\xa1\xf7?Q\x8e\x91\xa3t@\x82\t\ +1\x131\xf6\xef\xfe^\xec\xb1\xceui2c\n\xa8\xaa\xcf\xe1\xcc\x04G\xb7\xfda\x0b\ +\xb6\xe0\x17A\xf0\xce\xb2\xc3@\xfbLp\x03\xeer\x0c%l\xbc\t6\x00\x00\x00\x00IE\ +ND\xaeB`\x82' -def getTreeToolBarBitmap(): - return wxBitmapFromXPMData(getTreeToolBarData()) +def getTreePanelBitmap(): + return wxBitmapFromImage(getTreePanelImage()) -def getTreeToolBarImage(): - return wxImageFromBitmap(getTreeToolBarBitmap()) +def getTreePanelImage(): + stream = cStringIO.StringIO(getTreePanelData()) + return wxImageFromStream(stream) + +def getTreePanelIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreePanelBitmap()) + return icon #---------------------------------------------------------------------- -def getTreeMenuData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"S\x05Cu\xae\xc4`\xf5\x08\x85d\x05\xa7\x9c\xc4\ -\xe4l0\xcf\x1f\xc8S\xb64\xb04\xb14\x00\xf3\x15\x80|\xbf\xfc\xbcT0G\x0f$\xe9f\ -\xe1\xe6\xecf\x01\xe6\xe7\x83\xf8.\x06.&.0\xc5\nzp\x10\xa1\xa0\x00\x17\xcc\ -\x87\x02\x7f\x14A\x7f0 [p(\x9b\xe9\x0f\x03H\x82\x11\x08\x00\x16\xd4\x03\x00&\ -sj\xf9' )) +def getTreeRootData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00aIDATx\x9c\xed\x93\xcb\r\xc00\x08C\xa1\xea\x00\x1e\x83\xfd\xa7a\x0c6Ho\ +\x88"\x88\x1aq\xado|l\xf1"\x85\x01\xd0Dw\xd54\xb3\x15k\x00\xdc\x06\x88\xc8kY\ +U\xdb\xe5J\x0c\x80Dd\x9d\x1a\xfd\x82n\x901\xa2"\x92\x07D\x94\x93k< \x9bv\x0f\ +W\x06d\xfd\x08\xdf\x11x\xfa\x17\xae\x91\x9b\x88\x1e\xba\x12*2\xab=\t\xe9\x00\ +\x00\x00\x00IEND\xaeB`\x82' -def getTreeMenuBitmap(): - return wxBitmapFromXPMData(getTreeMenuData()) +def getTreeRootBitmap(): + return wxBitmapFromImage(getTreeRootImage()) -def getTreeMenuImage(): - return wxImageFromBitmap(getTreeMenuBitmap()) +def getTreeRootImage(): + stream = cStringIO.StringIO(getTreeRootData()) + return wxImageFromStream(stream) + +def getTreeRootIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeRootBitmap()) + return icon + +#---------------------------------------------------------------------- +def getTreeSizerFlexGridData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00BIDATx\x9cc\x14\x10\x10`\x08\x08\t\xf8\xcf@&`\x8116\xac\xd9\xc0\x88,\ +\x11\x10\x12\xf0\x1f]\x0c\x1d\x04\x84\x04\xfcg"\xd7f\x18\x18x\x03\x18G\x03q\ +\xd4\x00j\x18@qBb\x14\x10\x10\xa0\xc8\x05\x00\xb4+\x16\xba\x9e\xe7\x8fF\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def getTreeSizerFlexGridBitmap(): + return wxBitmapFromImage(getTreeSizerFlexGridImage()) + +def getTreeSizerFlexGridImage(): + stream = cStringIO.StringIO(getTreeSizerFlexGridData()) + return wxImageFromStream(stream) + +def getTreeSizerFlexGridIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeSizerFlexGridBitmap()) + return icon + +#---------------------------------------------------------------------- +def getTreeSizerGridData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00<IDATx\x9cc\x14\x10\x10`\x08\x08\t\xf8\xcf@&`\x8116\xac\xd9\xc0\x88M\ +A@H\xc0\x7f|rL\xe4\xda\x0c\x03\xa3\x06000\x8eF\xe3p0\x80\xe2hd\x14\x10\x10\ +\xa0\xc8\x05\x00M\x98\x16\xba|O\xcc\x02\x00\x00\x00\x00IEND\xaeB`\x82' + +def getTreeSizerGridBitmap(): + return wxBitmapFromImage(getTreeSizerGridImage()) + +def getTreeSizerGridImage(): + stream = cStringIO.StringIO(getTreeSizerGridData()) + return wxImageFromStream(stream) + +def getTreeSizerGridIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeSizerGridBitmap()) + return icon #---------------------------------------------------------------------- def getTreeSizerHData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"#\x05Cu\xae\xc4`u=\x85d\x05e3\x033\x133\x030_\ -\x01\xc8\xf7\xcb\xcfK\x85rP\x01\xa9\x82z\xa8\x00*\x08Q\x01\xa3\x06\xaf 6\xc7\ -S\x12 z\x00\xf8\xc9>T' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00DIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b\x1a\x06\xb00000\x04\x84\ +\x04\xfc\xa7\xc8\x00\x06\x06\x06\x86\rk60bS\x10\x10\x12\xf0\x1f\x9f\xdc\xc0\ +\x87\xc1\xa8\x01T0\x80Q@@\x80\xa2\x84\xc48\xf43\x13\x00\xf5\xfe\x0c\x98\x979\ +f\xc6\x00\x00\x00\x00IEND\xaeB`\x82' def getTreeSizerHBitmap(): - return wxBitmapFromXPMData(getTreeSizerHData()) + return wxBitmapFromImage(getTreeSizerHImage()) def getTreeSizerHImage(): - return wxImageFromBitmap(getTreeSizerHBitmap()) + stream = cStringIO.StringIO(getTreeSizerHData()) + return wxImageFromStream(stream) + +def getTreeSizerHIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeSizerHBitmap()) + return icon #---------------------------------------------------------------------- def getTreeSizerVData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"#\x05Cu\xae\xc4`u=\x85d\x05e3\x033\x133\x030_\ -\x01\xc8\xf7\xcb\xcfK\x85r\x14\x14\xf4`\x00\xc8F\x08*@\xc0\x00\t\x0e\x11\'!\ -\x03\xa0\xa0\x1e\x00\xfaC>*' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00?IDATx\x9cc\x14\x10\x10`@\x06\x01!\x01\xff\x19\x08\x80\rk60\xc2\xd8,\ +\x84\x14\xa0\x03t\x0b\x98\x08\xd9F\x08\x8c\x1a\x80#\x16\x88\x89J\xbc\x06\x8c\ +F#\x9d\r\xa08\x1a\x19\xd1\xb33\xa9\x00\x00&\x0c\x10mXtZ\x83\x00\x00\x00\x00I\ +END\xaeB`\x82' def getTreeSizerVBitmap(): - return wxBitmapFromXPMData(getTreeSizerVData()) + return wxBitmapFromImage(getTreeSizerVImage()) def getTreeSizerVImage(): - return wxImageFromBitmap(getTreeSizerVBitmap()) + stream = cStringIO.StringIO(getTreeSizerVData()) + return wxImageFromStream(stream) + +def getTreeSizerVIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeSizerVBitmap()) + return icon #---------------------------------------------------------------------- def getTreeStaticBoxSizerHData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"c\x05Cu\xae\xc4`u=\x85d\x05\xa7\x9c\xc4\xe4l0\ -/\x02\xc8S630313\x00\xf3\x15\x80|\xbf\xfc\xbcT(\x07\x15\xc0\x05\xf5\xb0\x08\ -\xea!\x8bB\x04#\x14\xf4\xf4\xf4\x14"`\x00.\x08R\x19\x01Q\x08\x17\x84\xf0\x06\ -\x93 *\xc0\x1f \xc4\x08\xea\x01\x00\x0b\xa9Jm' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00dIDATx\x9c\xed\x92A\n\xc00\x08\x045\xe4\x01\xfb4\x0f>3\x07\x9f\xe6\ +\x0f\xecU,\xb4IS\xe8\xa5s\x11\x16\x1c\x16\x91\x01\xd0\x0e\xad\x06\xee\x1e\ +\x8f\x05\xee\x1e\x00xE\xd2\x89\x88D%l\x18\xd7\x06\xa2r+\xea5\xc8\rl\x18gyET\ +\xa2\xd5\xe5<g8\x1dq\x95_\xf0\x82\x80\x01L=\xcc\xa5`\x87\xefop\x00N\x12$g%t;\ +\xe1\x00\x00\x00\x00IEND\xaeB`\x82' def getTreeStaticBoxSizerHBitmap(): - return wxBitmapFromXPMData(getTreeStaticBoxSizerHData()) + return wxBitmapFromImage(getTreeStaticBoxSizerHImage()) def getTreeStaticBoxSizerHImage(): - return wxImageFromBitmap(getTreeStaticBoxSizerHBitmap()) + stream = cStringIO.StringIO(getTreeStaticBoxSizerHData()) + return wxImageFromStream(stream) + +def getTreeStaticBoxSizerHIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeStaticBoxSizerHBitmap()) + return icon #---------------------------------------------------------------------- def getTreeStaticBoxSizerVData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"c\x05Cu\xae\xc4`u=\x85d\x05\xa7\x9c\xc4\xe4l0\ -/\x02\xc8S630313\x00\xf3\x15\x80|\xbf\xfc\xbcT(\x07\x0c\xf4\xa0\xb4\x02\x92\ -\xa0\x1e\\\x14.\x18\xa1\xa0\xa7\xa7\xa7\x10\x11\x11\x81&\x08V\x89&\x08\x01\ -\xb4\x17\x84\x81\xc1`\xbb\x1e\x00U+IU' )) + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00hIDATx\x9cc\x14\x10\x10`\xc0\x05>|\xf8\xf0_@@\x80\x11\xa7\x02\x06\ +\x06\x06&B\x9a?|\xf8\xf0\x9f$\x03\x02B\x02\xe0\x1a\x905\x07\x84\x04\xfc\x87a\ +\xa2\\\xc0\xc0\xc0\xc0\x80\xec\xfc\rk60nX\xb3\x01\xc3;8\r\x80i&;\x0c\x88\x05\ +\xc3\xc0\x00\x16l\x82\xe8QE\xb2\x01\xd8\xa2\x0b\x97\xe1\x03\x1f\x06\x03o\x00\ +\xc5\xb1\x00\x00\xf1\xda$S0&0\x03\x00\x00\x00\x00IEND\xaeB`\x82' def getTreeStaticBoxSizerVBitmap(): - return wxBitmapFromXPMData(getTreeStaticBoxSizerVData()) + return wxBitmapFromImage(getTreeStaticBoxSizerVImage()) def getTreeStaticBoxSizerVImage(): - return wxImageFromBitmap(getTreeStaticBoxSizerVBitmap()) + stream = cStringIO.StringIO(getTreeStaticBoxSizerVData()) + return wxImageFromStream(stream) + +def getTreeStaticBoxSizerVIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeStaticBoxSizerVBitmap()) + return icon #---------------------------------------------------------------------- -def getTreeSizerGridData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"#\x05Cu\xae\xc4`u=\x85d\x05e3\x033\x133\x030_\ -\x01\xc8\xf7\xcb\xcfK\x85p\xf4P\x01TP\x01\x0c`\x14\xbd\x05\x87\x88\x93\xd0\ -\x00PP\x0f\x00!\xb1?\xce' )) +def getTreeToolBarData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\x80IDATx\x9c\xed\x93\xbb\r\x840\x10D\x9f\x91\x03B\x97\xb1\x81\x83-\ +\xc1%\x12\\\xb0\xe5\xb8\x0c\x97B\x80\x04\x11\x1fs\xd2!pr\x01\x13\xf9i4#\xdb\ +\xabu!\x04Z\xd45\xa5\xff\xa2\xc0\x8d\xd38?\r\xf7\xbe\xc7\x03\x94Rn\x87s\xce\ +\xc0\xe1\t\x12\x15\x89\xba\x19"\x8a\xc8\xce*\x8a\x1exU\xf3\x1f\xf8\xf5`\x9f\ +\xa12\xccj\x1eN\xfcU\x90R\xaa\x8c+\xde\n\xcc\xec\xf2\x9a\xbf\xe4\x80\xc7c\ +\x04p\xef.\xb0\x00\xb2\x8f\x1d_"\xe3\xe1\xc9\x00\x00\x00\x00IEND\xaeB`\x82' -def getTreeSizerGridBitmap(): - return wxBitmapFromXPMData(getTreeSizerGridData()) +def getTreeToolBarBitmap(): + return wxBitmapFromImage(getTreeToolBarImage()) -def getTreeSizerGridImage(): - return wxImageFromBitmap(getTreeSizerGridBitmap()) +def getTreeToolBarImage(): + stream = cStringIO.StringIO(getTreeToolBarData()) + return wxImageFromStream(stream) + +def getTreeToolBarIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeToolBarBitmap()) + return icon #---------------------------------------------------------------------- -def getTreeSizerFlexGridData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S\x00"#\x05Cu\xae\xc4`u=\x85d\x05e3\x033\x133\x030_\ -\x01\xc8\xf7\xcb\xcfK\x85p\xf4P\x01TP\x01\x08\xc0\x04\x98A\x1dA\xbaYD/\xc7\ -\xa3\x01\xa0\xa0\x1e\x00>\x91?\xce' )) +def getUndoData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x17\x00\x00\x00\x16\x08\x06\ +\x00\x00\x00+v\x07\x05\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xb6IDATx\x9c\xed\x93\xb1\r\x830\x10E\x9f#\n\xca+3\x02\x03d\x80\x8c\xc1\ +\x18)S\xa6L\xc9\x18\x8c\x91"%\x030\x82\xcb+]X"E\x04\x8a\x901\x08\x07\x89\x82\ +W\x9e\xe4\xf7\xed\xbb\xb3\x11\x11\xb6\xe2\xb4\x99\xf9\x90\xaf\x96\xabj\xb7\ +\x89<E\x0c\x90\xc5\xc4\xcf\xeb\x19\xe7\xe1\xf1\xb6C\x88\x88\x98\xa5r\x13\xda\ +\xf3^\x9cg9\xce;\x00\x9c\x07uP5vqHP\xfe\x1b\x00p\x7f\xd9\xa1~\xbb|kUcg\x03&\ +\xe5}\xc0\xf8\x96\xaa\xda\x95\x85P\xb7:+\x8f\x0e4tXDL\xdd*e!\xb3\x03\x8f\xde\ +<F\xe8Uc\xf6\xfbC\x93z>\x85\xaavI\xab\xf8\x0f\xf6\xdb\xf3C\xbe\x8a\x0fa\xd1E\ +H\xfdNS\x0c\x00\x00\x00\x00IEND\xaeB`\x82' + +def getUndoBitmap(): + return wxBitmapFromImage(getUndoImage()) + +def getUndoImage(): + stream = cStringIO.StringIO(getUndoData()) + return wxImageFromStream(stream) + +def getUndoIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getUndoBitmap()) + return icon -def getTreeSizerFlexGridBitmap(): - return wxBitmapFromXPMData(getTreeSizerFlexGridData()) +#---------------------------------------------------------------------- +def getRedoData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x17\x00\x00\x00\x16\x08\x06\ +\x00\x00\x00+v\x07\x05\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xbfIDATx\x9c\xed\xd4/\x0e\xc20\x14\xc7\xf1\xef\xc8\xc4\x13\x13=\x06r\ +\x129\x81@"v\x00\x04\x87B\xec\x08\x88\x1d\x00\xd1#Lr\x8c\'\x10uE\x90\x92\x10\ +6\xda4, \xf6\x93M\xf3y/\xaf\x7f\nc\x0cse5\x9b\xbc\xe0_\xc7U\xd5\xcf\x86\xa7\ +\x14(s\xb1\xdda\x83\x88\xd0\x9f\xac7\xc6\x14c\xfb\x8b\x94{\x1e\xd0\xa6\xad\ +\x91J\x90R\x00\x90\n\xdc\r\xfa\xce2V \xda\xb9\xaa\xfa\xa6\xad\x01\xb0\xe7\ +\xe1\xb9\xbe?687\r\'\xe1\x8f\x02\x8e\xe1r}A\xfa\xcez`\x12\x86\xc8\x81\xaa\ +\xaa\xaf\xb7\xeb78\xe4\x13\x0c\x91\x99\x87Y\xc7\x90\xa9\xfc\xee\x11\xe5v\x9c\ +\x84\x87\x02)\xafq,I\xf7<7\xff\xf9q-xv\xee"\x1b=\x87\xa0\x01\x91\x87\x00\x00\ +\x00\x00IEND\xaeB`\x82' + +def getRedoBitmap(): + return wxBitmapFromImage(getRedoImage()) + +def getRedoImage(): + stream = cStringIO.StringIO(getRedoData()) + return wxImageFromStream(stream) + +def getRedoIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getRedoBitmap()) + return icon -def getTreeSizerFlexGridImage(): - return wxImageFromBitmap(getTreeSizerFlexGridBitmap()) +#---------------------------------------------------------------------- +def getToolDefaultData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00QIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b\x1a\x06\xb0\xa0\x0b\xbcx\xf3\ +\xe2?.\xc5\x1c,\x1c\x0c\x02\x02\x02\x8cx\r````\xb8q\xe3\x06\x86\xd8\x81\x03\ +\x07\xb0\x1a:\xf0a@\xfd@d`\xc0\xed_\xa2\x0c\xe0`\xe1 \xc9\x05\x8cC?%Rl\x00\ +\x00\xdc\x00\x0b\x9f\x8dZU\xfe\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolDefaultBitmap(): + return wxBitmapFromImage(getToolDefaultImage()) + +def getToolDefaultImage(): + stream = cStringIO.StringIO(getToolDefaultData()) + return wxImageFromStream(stream) + +def getToolDefaultIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolDefaultBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolDialogData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00IIDATx\x9ccd``\xf8\xcf@\x01`\x81P?\xc8\xd4\xce\xc1\xc0D\x89\xed\x0c\ +\x0c\x0c\x94\x1b\xc0\xc8@\x8d0\xb8p\xe5\x02Y\x9a\rt\x0c\x06A\x18\x8c$\x03\ +\x0e\x1c8@\x1b\x17\xb0\x90b\x1b\xd1\x06888\x10m\x00\xc5I\x19\x00\xe6)\x0cc\ +\xbf\x9c\xcc\xa1\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolDialogBitmap(): + return wxBitmapFromImage(getToolDialogImage()) + +def getToolDialogImage(): + stream = cStringIO.StringIO(getToolDialogData()) + return wxImageFromStream(stream) + +def getToolDialogIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolDialogBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolFrameData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00:IDATx\x9ccd``\xf8\xcf@\x01`\x81P?\xc8\xd4\xce\xc1\xc0D\x89\xed\x0c\ +\x0c\x0c\x94\x1b\xc0\xc8@\x8d0\xb8p\xe5\x02Y\x9a\rt\x0c\x06A\x18\x8c\x1a0,\ +\x0c\xa08)\x03\x00\x90c\x07\x1f\xb3yvF\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolFrameBitmap(): + return wxBitmapFromImage(getToolFrameImage()) + +def getToolFrameImage(): + stream = cStringIO.StringIO(getToolFrameData()) + return wxImageFromStream(stream) + +def getToolFrameIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolFrameBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolMenuBarData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00bIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4{P\x18\xc0\xf8\xe3\xcf\x8f\xff\ +\xe4j\xe6`\xe1``a```\xb8q\xe3\x06\xc9\x9a\x0f\x1c8\xc0\xc0\xc0\xc0\x001\x00Y\ +\x00\x19888\xe0\x14\x87\x81\x81\x0fD\xb8\x17\x90\x9d\x85\x0cp\x89\xc3\r\x981\ +c\x06E.`d`` ;\x1a\x19\x18\x18\x18\x18G\xf3\x02\x03\x00DO\x13\x93\xa7\xebQk\ +\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolMenuBarBitmap(): + return wxBitmapFromImage(getToolMenuBarImage()) + +def getToolMenuBarImage(): + stream = cStringIO.StringIO(getToolMenuBarData()) + return wxImageFromStream(stream) + +def getToolMenuBarIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolMenuBarBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolMenuData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00]IDATx\x9cc\x14\x10\x10`\x80\x81\x17o^\xfcg \x02p\xb0p0\x08\x08\x080\ +2000\xb0\xa0K\xde\xb8q\x03\xaf\xe6\x03\x07\x0e\xa0\xf01\x0c\xc0\xa6\x08\x06\ +\x1c\x1c\x1c0\xc4\x98\xf0ZG\x04\xa0\xd8\x00\xac^\xc0\xe6T\x92\x0c\x18\r\x83\ +\xd10\xc0\xe5\x7f\xa2\x0c\xe0`\xe1 I3\x03\x03\x03\x03\x00l\xa5\x16\xbeals=\ +\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolMenuBitmap(): + return wxBitmapFromImage(getToolMenuImage()) + +def getToolMenuImage(): + stream = cStringIO.StringIO(getToolMenuData()) + return wxImageFromStream(stream) + +def getToolMenuIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolMenuBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolPanelData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00CIDATx\x9c\xed\xd31\x0e\x800\x0cC\xd1W\x94\xa1\xf7?Q\x8e\x91\xa3t@\x82\t\ +1\x131\xf6\xef\xfe^\xec\xb1\xceui2c\n\xa8\xaa\xcf\xe1\xcc\x04G\xb7\xfda\x0b\ +\xb6\xe0\x17A\xf0\xce\xb2\xc3@\xfbLp\x03\xeer\x0c%l\xbc\t6\x00\x00\x00\x00IE\ +ND\xaeB`\x82' + +def getToolPanelBitmap(): + return wxBitmapFromImage(getToolPanelImage()) + +def getToolPanelImage(): + stream = cStringIO.StringIO(getToolPanelData()) + return wxImageFromStream(stream) + +def getToolPanelIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolPanelBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolRootData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00aIDATx\x9c\xed\x93\xcb\r\xc00\x08C\xa1\xea\x00\x1e\x83\xfd\xa7a\x0c6Ho\ +\x88"\x88\x1aq\xado|l\xf1"\x85\x01\xd0Dw\xd54\xb3\x15k\x00\xdc\x06\x88\xc8kY\ +U\xdb\xe5J\x0c\x80Dd\x9d\x1a\xfd\x82n\x901\xa2"\x92\x07D\x94\x93k< \x9bv\x0f\ +W\x06d\xfd\x08\xdf\x11x\xfa\x17\xae\x91\x9b\x88\x1e\xba\x12*2\xab=\t\xe9\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def getToolRootBitmap(): + return wxBitmapFromImage(getToolRootImage()) + +def getToolRootImage(): + stream = cStringIO.StringIO(getToolRootData()) + return wxImageFromStream(stream) + +def getToolRootIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolRootBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolCheckBoxData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\n\x00\x00\x00\n\x08\x06\x00\ +\x00\x00\x8d2\xcf\xbd\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00?IDATx\x9cc\xfc\xf1\xe7\xc7\x7f\x06\x02\x80\x83\x85\x83\x81\x85\x81\x81\ +\x81\xe1\xc6\x8d\x1b\x84\xd420\x11Rp\xe0\xc0\x01\xe2\x14\x12m\xe2 P\xc8\x02c\ +\xc0|\x87\x0b0200\x10\x0cp\x06\x06\x06\x06\x00b\x8b\x0c\x1dT!\xdd>\x00\x00\ +\x00\x00IEND\xaeB`\x82' + +def getToolCheckBoxBitmap(): + return wxBitmapFromImage(getToolCheckBoxImage()) + +def getToolCheckBoxImage(): + stream = cStringIO.StringIO(getToolCheckBoxData()) + return wxImageFromStream(stream) + +def getToolCheckBoxIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolCheckBoxBitmap()) + return icon + +#---------------------------------------------------------------------- +def getTreeToolData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00^IDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b\x1a\x06\xb0\xa0\x0b\xbcx\xf3\ +\xe2?>\r\x1c,\x1c\x0c\x02\x02\x02\x8c8\r````\xb8q\xe3\x06V\xcd\x07\x0e\x1c\ +\xc0\x10\xa3\xbe\x17p\xd9\xe8\xe0\xe0\x80U\xcd \x8c\x05d\x80\xcb\xd9\x04\r\ +\xc0\x16\xdaD\x1b\xc0\xc1\xc2A\xb4f\x06\x06\x06\x06\xc6\x01\xcf\x0b\x00"\x92\ +\x0fc\x04\xf8\xbb\xc7\x00\x00\x00\x00IEND\xaeB`\x82' + +def getTreeToolBitmap(): + return wxBitmapFromImage(getTreeToolImage()) + +def getTreeToolImage(): + stream = cStringIO.StringIO(getTreeToolData()) + return wxImageFromStream(stream) + +def getTreeToolIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeToolBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolToolData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\t\x08\x06\x00\ +\x00\x00\xe0\x91\x06\x10\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00LIDATx\x9c\x95\xd0\xb1\r\xc0 \x10C\xd1GD\xc1X\x8c\xce\x18\x8cB\x11)\ +\xa9\x12!qB\xc9\xaf\xae\xf0\xd9\x96\xd38\xc7eC\xc9E\x86\xde{(h\xad\x81c\xe7\ +\xf2\x90\xa3O\xa8\xb5\xbe\xf7\'\xa7\xffqs\xc4"\x9a\xbbD$lw\x82\x1b\xd7\x84\ +\x0f\xdfLT\x19\x1d\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolToolBitmap(): + return wxBitmapFromImage(getToolToolImage()) + +def getToolToolImage(): + stream = cStringIO.StringIO(getToolToolData()) + return wxImageFromStream(stream) + +def getToolToolIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolToolBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolMenuItemData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x0c\x00\x00\x00\t\x08\x06\ +\x00\x00\x00\x06\xb8\xcdT\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00NIDATx\x9cc\xfc\xf1\xe7\xc7\x7f\x06"\x01\x07\x0b\x07\x03\x0b\x03\x03\ +\x03\xc3\x8d\x1b7\x08*>p\xe0\x00\x03\x03\x03\x03\x03\x13\xb1\xa6\xc3\x00\x0b\ +6S\xd0\x81\x83\x83\x03\x9cM\xb2\r\x949\t\xd9j\xbc\x1ap\xb9\x1d\x1b`d`` :\x1e\ +\x18\x18\x18\x18\x00h[\x0f\xdf\xbb\xf3\x12\xf4\x00\x00\x00\x00IEND\xaeB`\x82\ +' + +def getToolMenuItemBitmap(): + return wxBitmapFromImage(getToolMenuItemImage()) + +def getToolMenuItemImage(): + stream = cStringIO.StringIO(getToolMenuItemData()) + return wxImageFromStream(stream) + +def getToolMenuItemIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolMenuItemBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolFlexGridSizerData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00BIDATx\x9cc\x14\x10\x10`\x08\x08\t\xf8\xcf@&`\x8116\xac\xd9\xc0\x88,\ +\x11\x10\x12\xf0\x1f]\x0c\x1d\x04\x84\x04\xfcg"\xd7f\x18\x18x\x03\x18G\x03q\ +\xd4\x00j\x18@qBb\x14\x10\x10\xa0\xc8\x05\x00\xb4+\x16\xba\x9e\xe7\x8fF\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def getToolFlexGridSizerBitmap(): + return wxBitmapFromImage(getToolFlexGridSizerImage()) + +def getToolFlexGridSizerImage(): + stream = cStringIO.StringIO(getToolFlexGridSizerData()) + return wxImageFromStream(stream) + +def getToolFlexGridSizerIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolFlexGridSizerBitmap()) + return icon + +#---------------------------------------------------------------------- +def getTreeMenuItemData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00cIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b\x81\x81\x81\x05\xc6x\xf1\xe6\ +\xc5\x7fb5q\xb0p0\x08\x08\x080\xa2\x18\xc0\xc0\xc0\xc0p\xe3\xc6\r\x82\x9a\ +\x0f\x1c8\x80\xc2\xa7\x9e\x17\xf0\xd9\x02\x03\x0e\x0e\x0e\x18b\x14\xbb\x806^\ +\xc0\xe6T\xa2\x0c\xc0\xe5w\xa2\x0c\xe0`\xe1 Y3\x03\x03\x03\x03\xe3\x80\'e\ +\x8a\r\x00\x00GI\x0fc!\x9f\xc7\x01\x00\x00\x00\x00IEND\xaeB`\x82' + +def getTreeMenuItemBitmap(): + return wxBitmapFromImage(getTreeMenuItemImage()) + +def getTreeMenuItemImage(): + stream = cStringIO.StringIO(getTreeMenuItemData()) + return wxImageFromStream(stream) + +def getTreeMenuItemIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeMenuItemBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolToolBarData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x08\x08\x06\ +\x00\x00\x00\xf0v\x7f\x97\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00lIDATx\x9c\xa5\x91\xb1\r\x800\x0c\x04\x0f\x94\x82Q\\Px\x84\x8c\x98\ +\x82\xc2\xe3d\x8c\x8cB\x81\x04U\x02\x01\x89\x88p\x95\xcf/[\x96<\xac\xdb\xba\ +\xd3\xc9\xe4&\x1c@J\xe9\xf3p\x8c\x11\x8017dVd\xd6\x12\x88("\xa7\xab(z\xf1\ +\xcc\xc8O\\.l\tU`V{\xb8\xf9c\x81\xf7\xbe\nZ^\x16\x98Y\xf3\xcc7\x06\xa0\xfb\ +\x8d\x00\x07:\x91\x1c\xf1\xcb\xec\x06\xb4\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolToolBarBitmap(): + return wxBitmapFromImage(getToolToolBarImage()) + +def getToolToolBarImage(): + stream = cStringIO.StringIO(getToolToolBarData()) + return wxImageFromStream(stream) + +def getToolToolBarIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolToolBarBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolChoiceData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x0c$\xbf\x95\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\x91IDATx\x9c\xbd\x94=\x0e\x80 \x0c\x85\x1f\xa6C\x8f\xc2\xe0\xc0\xfd\ +\'\x8e\xc0\xe0\xc0Q\x18Lt\xc2(P\x84\xc4\xfa-$M\xd3\xd7_L\xda\xd3\x01%\x98\ +\x18\x04\x001F-\r,Z\x81\xbd\xf7}\x01\xb7\xbaO\x84\xd4*\xc8P\xcb\xe8V\x87\xb0\ +\x85\xeb\xbdc\xad\x15\x831q\xe5\xdf\x14xcf)\xaa\x16\xdd\xb3\xceU\x8c\x90\x87\ +Z"\xb6\xe8+\x1e\x02\xad\x9eKv)\xe3\xae\xc0\x08L<\xe5\xff\x10he_\xda%\x1f\t\ +\xf5;\xf8\xef\xd0F\x876\x8b\x01\xa0\xf6]\x03\xc0\t\'\xec0\xc5\xed<\xbeO\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def getToolChoiceBitmap(): + return wxBitmapFromImage(getToolChoiceImage()) + +def getToolChoiceImage(): + stream = cStringIO.StringIO(getToolChoiceData()) + return wxImageFromStream(stream) + +def getToolChoiceIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolChoiceBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolSpacerData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00/IDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b&\x06|\xf8\xf0\xe1?14\x0c0R=\ +\x0c\xd0m $?\xea\x02Z\xba`\xe0\xd2\x01\xa9\x00\x00`~>\'\xaa4\xf4\x95\x00\x00\ +\x00\x00IEND\xaeB`\x82' + +def getToolSpacerBitmap(): + return wxBitmapFromImage(getToolSpacerImage()) + +def getToolSpacerImage(): + stream = cStringIO.StringIO(getToolSpacerData()) + return wxImageFromStream(stream) + +def getToolSpacerIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolSpacerBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolStaticTextData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x16\x00\x00\x00\r\x08\x06\ +\x00\x00\x00\xad\xa5\x9ec\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00kIDATx\x9c\xd5SA\n\xc00\x08\xd3\xb1\x07\xe4\xff\xaf\xcc\x0f\xdcIp%\ +\x0e\xdaQ\xc6r3\xda$\nu\x00\xb6\x03\xc7\x16\xd5O\x84I\xc6S\xbd,\xfc\x16R\x98\ +d\x00p\x95\x92d\xa8mFn*q\x1aVS\xc5I\xe1\x1c43\x1b\x87\x93\xefP\xfbg\x97lf\ +\x13\x85\x9bpM\xab\x8c\xba\xbez/\x13w\xa8\xa7Q\xe7\xaa\xa6\xfe\xbb/}\x01*\ +\x1bS\x8a\xc2\x15\xd1\x9d\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolStaticTextBitmap(): + return wxBitmapFromImage(getToolStaticTextImage()) + +def getToolStaticTextImage(): + stream = cStringIO.StringIO(getToolStaticTextData()) + return wxImageFromStream(stream) + +def getToolStaticTextIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolStaticTextBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolTextCtrlData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x0c$\xbf\x95\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00HIDATx\x9cc\x9c0e\xc2\x7f\x06\x1a\x02\x16\x06\x06\x06\x86\x82\x9c\ +\x02\x9a\x18\xfe\xe3\xcf\x0f\x88\x050\x0e5\xc1\x8d\x1b7\x18\x18\x18\x18\x18\ +\x98\xa8j*\x160j\xc1\xa8\x05\xa3\x16\x0c\x07\x0b\xe0e\x11\xac\xec\xa0\x89\ +\x05\xd4.\xe8\x90\x01\x00\x81\x02\x11\xfb\x02\xab> \x00\x00\x00\x00IEND\xaeB\ +`\x82' + +def getToolTextCtrlBitmap(): + return wxBitmapFromImage(getToolTextCtrlImage()) + +def getToolTextCtrlImage(): + stream = cStringIO.StringIO(getToolTextCtrlData()) + return wxImageFromStream(stream) + +def getToolTextCtrlIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolTextCtrlBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolButtonData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x0c$\xbf\x95\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\x84IDATx\x9c\xc5\x941\n\xc0 \x0cE\x9f\xc5\xc1\xc3t\xe8\xfd\'\x8f\ +\x90\xc1\xc1\xa38\x14\xda\xc9B\xa5\xc6B\r\xfd\xe0`\x82\xff\x91\x18\xe2\xca^\ +\x0e\x8c\x14|\xc0\x03\xe4\x9c\xad\x18,V\xc61F[@\x95\n\xd8\xd6\xedv\xda\x9cv\ +\xaf\xf2\x9a\xb9$\x19\xc6\xb48Lh\x91f\xfe\x19\xd0k\xcb4\x80$A\x92\xa8\xa0\ +\x7f\xa7\xe8\xad\xb4*\xbaS\xf4\xf4H\xfb\xcc\x9e\xba\x80\x91a\x9b3\x1b\xd3\ +\x91\xae\n\xea\xee\x98-\x07\x98\xadk\x80\x13\xd4\x8e1G9C\xf0\xc0\x00\x00\x00\ +\x00IEND\xaeB`\x82' + +def getToolButtonBitmap(): + return wxBitmapFromImage(getToolButtonImage()) + +def getToolButtonImage(): + stream = cStringIO.StringIO(getToolButtonData()) + return wxImageFromStream(stream) + +def getToolButtonIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolButtonBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolBitmapButtonData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x18\x08\x06\ +\x00\x00\x00\xe0w=\xf8\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x02\x05IDATx\x9c\xb5\x96-\x90\xda@\x18\x86\x9f\xebD\xac\xa8X\x81\x88DT\xac\ +\xa8@"N *"N *NT \x10\x88\x13\x88\x8a\x08\x042\xa2"\x02\x11\x89\xa8@\x9c@T ND\ + "*"\x10\x11\x15\x11\'VT\xac@|"3\xad\xa0i\xa7\x1d\x08\xe1\xa6\xbcr\'\xfb>\ +\xfb~\xfb\xf3\xe5F*\xf9\xc1\x95\xa4<\x85\x07P\x14\xc5\xb5\x18\xbc\xba\x96q\ +\x9a\xa6\xd7\x05\xd4\xf2\xda|d\x8c9:\xde\xa6\xb4\x8d\t\x8c1\xbf\xcde/\xe4_s\ +\x9csg\xc1\xad\x00\xf5\xe4l\x9b\x11N\'\xc8\xf7\x04\xe3g`\x97l\x1e\xe7\x8cF\ +\xc3V\x90\xc6\x04\xd96\xc3\xf7\x15\xe1\x83Aw\xfa(=@w4\x83[\x9f\xe8c\x9f\xd1\ +\x87\xd1Y\xc8Q@=!^\xc4\xf8^\x8a\xee\x0c\xc0\xeb\x82\xa7\xe1u\x80\xf2\x14Zk\ +\xc2\xb1\xcf\xfd\xfb\xfb\x97\'\x98\x8e\x03P\x1a\x94\x7f\x18\xa8\x04*A*\x85\ +\xf2@w\x14Z\xab\xc6\x14\x8d\x00\x91\x83\xe1A\n<\x8d\xc8a\x93\x05\x05\x9e\xc2\ +\xd7r\xda\xe0\x14\xa0>~\xd1b\xfd\x0b P9\x90\x12*\xfb\'\x89s\xac\x1e\xd3\xcb\ +\x01\xb5\x92$A*\x0e\x86\x9eB\xa4\x04\x1cT\x82\xb5\x96\xf2\xd91\x8f\xe2\xbf\ +\x16\xf5\xaf\x1a/\x9aR\n%\x02(d_B\xe5\x10qXk\x91\xbd\x10%\x05\x9b\xa7\xa41\ +\xc1I@Q\x14$IL\x9e\xa5t\xdfd\xc4\xb3\x01\xce9\xcag\xcb\xfcS\x8a\xee\x186Oi\ +\xe3\xea\xe1l\x89\x96\xf8]C8\x8b(\xf7}\xa6Q\xc6f+,?oX\x7fY\x9f5oL\x000\xbc\ +\x0bX\xad\xd6\xe4yN8\x9b\xd3\xeb\xf5\x08\xc3\x10\xadu\xeb\'\xfed\x82\xe0]\ +\xc0\xe4a\xca\xf0. \xdb\xa6\x18cX.\x97Xk/\xea\x1f\'\x01\xd6Z\xa2h\xced2\xa5\ +\x7f;\xa0\xd8\x15h\xad[\x1b\xd7:Y\xa2|\x97\xd3{\xdb\xa3\xfc6\xc1\xf7}\xfa\ +\xfd\x01\xf1"\xbe\x18p\xb6\xe1\x88\x08EQ0\x1a\x8f.6\x873\x9b\x9c\xef\xf2\x17\ +\x99\x1e\x05\xd4=\xf4\x7f\xeb\x06\xb8\xdao\x0b\xc0O\x923\xdby\x95O\x1dg\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def getToolBitmapButtonBitmap(): + return wxBitmapFromImage(getToolBitmapButtonImage()) + +def getToolBitmapButtonImage(): + stream = cStringIO.StringIO(getToolBitmapButtonData()) + return wxImageFromStream(stream) + +def getToolBitmapButtonIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolBitmapButtonBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolRadioButtonData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x0b\x00\x00\x00\x0b\x08\x06\ +\x00\x00\x00\xa9\xacw&\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\x86IDATx\x9cu\xd0\xa1\x11\xc30\x0c\x85\xe1_\x9e@ C\x14\x04\x1ad0\x8f\ +\xa0\xc1\n\x02\x03:D\x80\x817HQZUQ\x1f\xb1\xcf\xf7=\xebN\xa2\xaa\xc4\xb4\xd6\ +N3\x93\xf8^2\xe8\xcf\xbf\xd8A\xb2B\xc9\xe0\xfe\xda\xd3B\xc9 \x90\x16\xc4\xcc\ +n\xd0gy,\x98\x19\x00\xa2\xaa\x1c\xfd8\x01\xb6\xe7\x86N\xdf\xed\x8c>\xa8k\x05\ +`\x9ef)\xd7\x05\xa0\xae\x95\xd1G\n??_\xf1\x13"\xbca_\x88\xf0gu\x11D\x08\xf0\ +\x06\x99\xd2L\tb\x83\xa4(\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolRadioButtonBitmap(): + return wxBitmapFromImage(getToolRadioButtonImage()) + +def getToolRadioButtonImage(): + stream = cStringIO.StringIO(getToolRadioButtonData()) + return wxImageFromStream(stream) + +def getToolRadioButtonIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolRadioButtonBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolSpinButtonData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\t\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\xc4HUC\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\x8dIDATx\x9c\x9d\x90\xb1\r\xc30\x0c\x04_\x86\x07\xf8ARx\x04\r\xe4B\xa3\ +\xa8\xf0@\x1aC#\xa8P\xc1\xd2\x85\x01\xa6\xa2c\xcb\x91\x1d\x84\xc07\xe4\x01\ +\xff|G\x12O3\xb4\x8bR\x8b\xdeB\xa5\x16\xcd9CD\xf4+d\x00\x00\xc4%\x9e\xc0\xa1\ +\x05\x00\xc0{\x7f\x02G;\xa4\x94\xfa\xc9\xd7mU\x00\xb7r\x7fU\xd0\xb5\xeb).\ +\xf1c\xd7~g\x8f\x849\x80\xa4\xdb3\xb5\xe0\xf4\x9a@\xd2u3]\xea \xb9\xeb\x98\ +\xe3\xb8\xbfT "j66?\xf5\xf4\x06%\x06t\x8fl^\xaef\x00\x00\x00\x00IEND\xaeB`\ +\x82' + +def getToolSpinButtonBitmap(): + return wxBitmapFromImage(getToolSpinButtonImage()) + +def getToolSpinButtonImage(): + stream = cStringIO.StringIO(getToolSpinButtonData()) + return wxImageFromStream(stream) + +def getToolSpinButtonIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolSpinButtonBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolStaticBoxData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x16\x08\x06\ +\x00\x00\x00\xda}\\\x88\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\xa2IDATx\x9c\xedU1\n\xc30\x0c\x94\x82\x1f\xa0!\x83\x9f\xa8gx\xc8\ +\x032t\xf0\x13=d\xd0\x98\xa1\xe0N*IH\xe5 ZB\xc17\xd9`\xdd\xe9\xc4\t#\x11\x81\ +\x05\x11\xa9D\x84\xe6#\x03\x83\xb7\xf0+\x02\xda\xbd\x88T\xaf@HS\xda\x1533\ +\xc41\x9a#)K\xa99\xe7&93C\xd0\x83B\xc9\xb7\xb3W\x17z\x8fc\xc4\xb2\x94K\xae\ +\xc2\x91x\x0bk4-\x97iJ\xf5\xed\xe0\x8c\xf8,9\x9eD\xdd\x93\xa2O]z\xf6\xe1\xde\ +=\xe8\x02]\xa0\x0b\xfc\x89\x00\xce\x8f\xd9\xfd[\xb5\xc0\xcc\x80\xebs\xfd\x99\ +\x00\x00\xc0\x0b\xb9:<\xe6\x18V\xd1\xdf\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolStaticBoxBitmap(): + return wxBitmapFromImage(getToolStaticBoxImage()) + +def getToolStaticBoxImage(): + stream = cStringIO.StringIO(getToolStaticBoxData()) + return wxImageFromStream(stream) + +def getToolStaticBoxIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolStaticBoxBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolRadioBoxData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x16\x08\x06\ +\x00\x00\x00\xda}\\\x88\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x01\x05IDATx\x9c\xc5\x94!\x12\x830\x10E\x7f:\x1c \x02\xc1Q\x10=\xd0JD\ +\x05\x12Q\x81\xac\xa8\xe0@\x15HD\x0f\x11\x11\xb1\x12\xd1\x99T\x85\x06\x1a\ +\x926\xd0\xe9*\x92a\xdf\xcb\xeel"\xa4\x94\x08\x053\x1b)\xa5\x08\xfe\x14\x88C\ +j\xe2.\x02{zf6\xa9\x82\xac97\xb3d"B\x91\x17\xc1\x96(\xadL\xd7uQ8\x11!\xb3\ +\x1f6,\xdc\xed\xbd\xad\xc2\xae\x8b\xbc\x10J\xab\x8f\xaa\xca\x96`7B\xad\x89U\ +\xd9\x9c\x1b3U\xe0\x03\xfb&\'e\xa2\xfe3E\xee)\xeb\xba6\xbe\xfdM\x82%\xdc\x95\ +\xec&p\xe0\xb3\xf5.\x02\x17>\xdc\x87M\x927\xc1\x12\x0e`\x93d&\xf0\xc1m\xa4Jf\ +\xf7\xa0m[\xa1\xb42\xd5\xa9B\x7f\xeb!\xf3\xd7K\xcb\x9a1>F\x00\xf1K\xb6Z\x81\ +\x9b\\\x1eK\xb0\xe6\t^\x1e\xcb\xaf\xe1^\x81O\x92\n_\x15,%\xa9\xf0\xa0\xc0\ +\x85\xa6\xc2\xa3\x82\xadp\x00\x10\x97\xeb%\xf9\x19\x88\x05\x11A\x8c\x8f\xf1g\ +\x02\x00x\x02J\xca\x8a\xcbs\xe5\x05\x0f\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolRadioBoxBitmap(): + return wxBitmapFromImage(getToolRadioBoxImage()) + +def getToolRadioBoxImage(): + stream = cStringIO.StringIO(getToolRadioBoxData()) + return wxImageFromStream(stream) + +def getToolRadioBoxIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolRadioBoxBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolComboBoxData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x0c$\xbf\x95\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\xc3IDATx\x9c\xb5\x94\xc1\r\xc3 \x0cE\x7f+\x1f<\n\xa3\xe4\xd0\x03\ +\x83\xf4\x90q\x18\x83\x11\x18!\x87\x1e\x18\x85C\xa4\xf6\x04\n\x01SH\xe9\x93P\ +$\xb0\xfe\xc76\xce\xcdZ\xfbF\x07\xcbc\xe9\t\xcb`b\x10\x00h\xad\x9b\x81a\x0f\ +\x00\x00\xef\xfd\xb0\t\x9dEf\xe1\x9c\x03\x00\xdc\xa7\xaaV\xa8\x1a0\xf14\x03\ +\xfa\x1e\x92\xa3\x94\x12\xcf\x8c1X\x9f+\xb6\xd7&\x1b01\xc2\x1e\xd2\xf7\x8c\ +\xf7\x1eJ\xa9\xa2\xe1\xce\xb9B\x1c\xb8\xd8\x83hr\xa4&^\x18\x1co\x1d\xb3\xe8!\ +\xbe\x98\x1aE\x06L\x9cV\x8b\x98\x85T\x9aH\xea\x81Tsi?\x9a\xb4\xc4\xab\x19\ +\x8c\xd2\x12\xcf\x0c\xa4[\xfe:\xe1\x7f\x9f\xe4\xe1Ak\xbd\x18\xd1\xa0\xa7\x0c\ +W\x7f\x1f\x1f\x92\xc6Yif\xadRe\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolComboBoxBitmap(): + return wxBitmapFromImage(getToolComboBoxImage()) + +def getToolComboBoxImage(): + stream = cStringIO.StringIO(getToolComboBoxData()) + return wxImageFromStream(stream) + +def getToolComboBoxIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolComboBoxBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolListBoxData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x16\x00\x00\x00\x18\x08\x06\ +\x00\x00\x00\xfe\xbe\rK\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\x91IDATx\x9c\xe5\x95=\n\xc0 \x0c\x85_\x8b\x83\x87\xed\xe0Q\x1cz8\ +\x8f\x92Ah\x87"H1\xa21:\xb4o\xf3\x87\xe7\xe3\x8b!\x9b?\xfd\x85\t2\x00\xe0\ +\x0e\xa7jJ\x91\x1e\xe3\xb4\xd0P\x08\x01\x00\xb0\xd7.Yc\xc5\x0fT\x8dG\xc4\x1a\ +[cA\x91\xc4\xa9\xd7&Ni\x01\x88S\x1b\xee`\xa4pE\xe3<m\xcb>\xa7u\x8c\xb9T\xbd\ +\rTd\xfc\xe6+\xe9J\xb6x\xb9Y/_`"\xe3\xa6\xef\xf6\x0f\x14\x1fa\xac1M\xe6\xa3H\ +\xb3J\xd5Xk\x90\xe6\xba\x01\xea\xbe>\xf3\x9d/\x83Q\x00\x00\x00\x00IEND\xaeB`\ +\x82' + +def getToolListBoxBitmap(): + return wxBitmapFromImage(getToolListBoxImage()) + +def getToolListBoxImage(): + stream = cStringIO.StringIO(getToolListBoxData()) + return wxImageFromStream(stream) + +def getToolListBoxIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolListBoxBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolStaticLineData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x14\x00\x00\x00\x02\x08\x06\ +\x00\x00\x00X\x06\xfc\x8b\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\x19IDATx\x9cc\x9c0e\xc2\x7f\x06*\x81\x8c\x8c\x0c\x06\x16\x18\x83Z\ +\x00\x00rP\x05)\xab\x92\xb7?\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolStaticLineBitmap(): + return wxBitmapFromImage(getToolStaticLineImage()) + +def getToolStaticLineImage(): + stream = cStringIO.StringIO(getToolStaticLineData()) + return wxImageFromStream(stream) + +def getToolStaticLineIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolStaticLineBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolStaticBitmapData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x0e\x00\x00\x00\x11\x08\x06\ +\x00\x00\x00\xed\xc8\x9d\x9f\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ +\x00\x00\x01\xceIDATx\x9c}\x93\x9f\x93#A\x14\x80\xbf\xa4\x06\x1a\x0e\x1e\x04\ +\x1a\x03\x07\xf9\x13\x02\x07\x03\x07\x03\x07\x81\x85\xc0\xe1\xc2\xc2\xc1\xc0\ +A\xe0 8\xb0\x10X\x08\x0e,\x04\x16\x02\x0b\x07\x07\x81\x85\x81\x85\x81\xc0\ +\xc0A`\xa1!\xd0\x10x\xd0U}\x90\x9d\xb9ds{\xaf\xaa\xab\xba_\xbf\xaf\xdf\xcf\ +\xee\x89\x08\xa7\xe2\xf6.\xf2\x0f\xb1\x03\xdb;=\xf7O\x81\x16\xd2\x83R?\xd7x\ +\xef\xdf}\xb0\'"\x9d\xb2z\xaaX?\x94\xcc\xf2\x11&1\xe8A\xa9\xb6\x9e\xd5cMY\ +\xae\xcf<w`\xf5Ta\xadA\xd8 v\x0c\x08h\x85\x06\xc5\xef=\xb3\xa2\xa1\xbc/;\xb8\ +\xdfz[\xdc-\xb0\xc9\x06\x19\xa4\x90\x0c!\x11\xf8\x90a\x12\x83\x880\xbb\xb6L\ +\xaf\xa6]\xa8I\xbb\xc9\xaf30\x80\xb1GEP\x004\x18L\xa2\xc8\xc0 b\xba|\xbb\xe2\ +\xa8jg\x0c\x06\x12A\xf5X\x1c\xc5@b\xb0\xd2\xdeC\xbfM\xb6\xb8[\xbf\x82\n\xc1\ +\x83\xee \xb8\xa3.(\xea=\xab\x87\xcde;\x96\xcb%\x1a^CL\x0c\xaa;\xc0CP\x9cs\ +\xec^<\xf3b\xd1\x15\xa7\xcb\xd1\x18\x83Q\x05\x0cz\xd8A\xf0\xa8z\x9cs\xe8A)\ +\x96\r?\x7f-\xcf\xfb\x080\xfd:\x89u\xb5a\xf8q\xc4\xe2G\x8a\xf7\x9e\xdd\x8bc~\ +\xbbA\x06#\xd6\x8f\xe7}DD\x10\x11H\x88\x93\xab,\xd6\xdb:V\xd5&f_\xd2\x98\x7f\ +\x9b\xc6\xa6i\xa2\x06\x8d\x1a4\xb6\xb6"\xf2\x17\x9cL\xb2\xa8Ac\xf5\\\xc5\xf4\ +s\x1a\xf3\xefyt{w\x01\xb4\xab\'"\x18cby_\xb2\xb8-\xc8\xb2\x8c\xe6\xf7\x8e\ +\xd5j\x05\x81\xb3\xc1>\x95>\x80s\x8e\xa2\x98ss\x933\xfe\x94\xd2l\x1b\xde\xfe\ +\x9a\xb7\xd2\x15\xc7{\x1f\x87C\x8b\xb5\x96\xf18\xa5,\xcbw\xbd]\x80\xd6\xcaq\ +\x820\xff\x85\x00\xfe\x00df\xf8-\xfbB\xb7\xb6\x00\x00\x00\x00IEND\xaeB`\x82'\ + + +def getToolStaticBitmapBitmap(): + return wxBitmapFromImage(getToolStaticBitmapImage()) + +def getToolStaticBitmapImage(): + stream = cStringIO.StringIO(getToolStaticBitmapData()) + return wxImageFromStream(stream) + +def getToolStaticBitmapIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolStaticBitmapBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolSliderData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x005\xf8\xdc~\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\x80IDATx\x9c\xdd\x92\xb1\r\x800\x10\x03\x0f\x94"#Q0PF\xc8\x08\x19\xcbcd\ +\x94\x14HP \x84\x04\x08>\n4\xb8\xfcO|\xd6\xcb]Ji\xe6C9\x80\x18\xe3\'\xe6e*+\ +\x00@\x12\xc38\x98>z\xe7\x91dz\xeb\x8e\x83\x9c\xb31\x9fM\xfd\xddR\xd2)\xa95\ +\xb9\t\x00\x10B\xa82\xac\x06\xb4\xea\xe7\x80\xd6\xfb\xc3EMaoJmc\x1e\x01\xde\ +\xf9f\xc3[\xc0\x1b\x89/\x01e*\xaf\x1boZ\x00\xcau!\xcd\n\x1f\x13Q\x00\x00\x00\ +\x00IEND\xaeB`\x82' + +def getToolSliderBitmap(): + return wxBitmapFromImage(getToolSliderImage()) + +def getToolSliderImage(): + stream = cStringIO.StringIO(getToolSliderData()) + return wxImageFromStream(stream) + +def getToolSliderIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolSliderBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolGaugeData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x005\xf8\xdc~\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00cIDATx\x9cc\x9c0e\xc2\x7f\x06\x1a\x02\x16\x06\x06\x06\x86\x82\x9c\x02\ +\x9a\x18\xfe\xe3\xcf\x0f\x88\x050\x0e.\xc0\xc1\xc2\xc1p\xe1\xca\x05\xb2,aA\ +\xe6|x\xf3\x81,C\xf0\x01&B\nv\xec\xd9A[\x0b(\x05\xa3\x16\x0c\xbc\x05,\xe8\ +\x02\x94\xa6\x1a\x9c\x16p\xb0pP\xd5`\x0c\x0b\xc8\xcd\xa9DY\x80\xaf\x98\xa0\ +\x14\x00\x00+\xec\x19!J\x0e\x8b\xa6\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolGaugeBitmap(): + return wxBitmapFromImage(getToolGaugeImage()) + +def getToolGaugeImage(): + stream = cStringIO.StringIO(getToolGaugeData()) + return wxImageFromStream(stream) + +def getToolGaugeIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolGaugeBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolScrollBarData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\r\x00\x00\x00\x18\x08\x06\ +\x00\x00\x00!\xf0wT\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xd1IDATx\x9c\xa5\x94\xb1\r\x830\x10E_"\x17\x1e\x85\x11\\P\xdc@)(\x19\ +\x81\x92"\x05\xe3PPx\x04\x0f\x91\x82\x92"RR P8l\xcb(\xaf\x04\x1e\xff\xfc\x0f\ +q\xeb\xba\xee\xc3E\x0c@\xdb\xb6\xc5\xc2\xf2^V\t`\x1c\xc7\xc3MW;\xfc\xe4\xa3\ +\xe2=v\xd1\xd5\x8e\x10\x02"R&m\x02@\xff\xec\xa3\xe2=%\x00\x88HT4(\xf4\xd9b\ +\xec\x92\xab\x1d\xd6\xd8\xe4\x83"\xb2\xbfp\x97\xfc\xe4\x8bRNI9\xac\xb1\xe7$\ +\xe0PB\x8e\xe8\x9e4z\xec"I\xf3_\xe5\xb9\xba\x93Ri\xdd\x07)W\xf90\x0c4\x8f&\ +\xbe\\\xfd\xedm\x13\xfc\n\xa0\xda\xf3\x93\xa7\xaa\xaa\x83\xa4\x85\x93\xa4I\ +\x9d\xf3$mi\xb1\xb1\xb2I!\x84\xa4\x90\x94\xe6\xd7\x9c]\x81\x81\xf5\x0fs\x85/\ +K\xf5c\xf9\x89\xca\xe1|\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolScrollBarBitmap(): + return wxBitmapFromImage(getToolScrollBarImage()) + +def getToolScrollBarImage(): + stream = cStringIO.StringIO(getToolScrollBarData()) + return wxImageFromStream(stream) + +def getToolScrollBarIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolScrollBarBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolTreeCtrlData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00aIDATx\x9c\xed\x93\xcb\r\xc00\x08C\xa1\xea\x00\x1e\x83\xfd\xa7a\x0c6Ho\ +\x88"\x88\x1aq\xado|l\xf1"\x85\x01\xd0Dw\xd54\xb3\x15k\x00\xdc\x06\x88\xc8kY\ +U\xdb\xe5J\x0c\x80Dd\x9d\x1a\xfd\x82n\x901\xa2"\x92\x07D\x94\x93k< \x9bv\x0f\ +W\x06d\xfd\x08\xdf\x11x\xfa\x17\xae\x91\x9b\x88\x1e\xba\x12*2\xab=\t\xe9\x00\ +\x00\x00\x00IEND\xaeB`\x82' + +def getToolTreeCtrlBitmap(): + return wxBitmapFromImage(getToolTreeCtrlImage()) + +def getToolTreeCtrlImage(): + stream = cStringIO.StringIO(getToolTreeCtrlData()) + return wxImageFromStream(stream) + +def getToolTreeCtrlIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolTreeCtrlBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolListCtrlData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x16\x00\x00\x00\x18\x08\x06\ +\x00\x00\x00\xfe\xbe\rK\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00}IDATx\x9cc\x9c0e\xc2\x7f\x06\x1a\x00\x16\x06\x06\x06\x86\x82\x9c\ +\x02\xaa\x1a\xfa\xe3\xcf\x0f\x88\xc10\x0e5\xc0\x8d\x1b7\x18\x18\x18\x18\x18\ +\x98\xa8b\x1a\x16\xc0\x82M\x90\x03\x87bR\xfcD3\x17\x8f\x1aL{\x83\xb1\xa6\nj\ +\xa4\xe8\xa1\x17\x14\x04\r\xe6\xc0\x99](0\x18f(9\x86\xe34\x18\xdd0R\r\xa7o\ +\x18\xe3r\x1d)\xae\xa6w\x06\xa1<\x8b\x0c\xbd\x0c\x02\x0f\nX]EU\x83\xa9U\x91"\ +\x03\x00\x9c{\x16ip\xfa\xbe\x9c\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolListCtrlBitmap(): + return wxBitmapFromImage(getToolListCtrlImage()) + +def getToolListCtrlImage(): + stream = cStringIO.StringIO(getToolListCtrlData()) + return wxImageFromStream(stream) + +def getToolListCtrlIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolListCtrlBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolCheckListData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x18\x08\x06\ +\x00\x00\x00\xe0w=\xf8\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xcdIDATx\x9c\xdd\x951\x0e\xc3 \x0cE\x7f+\x0f\x1c\xb6C\x8e\x92\xa1\x07\ +\xcb\xd0\x81\xa30Dj\x87\x8a\x8a\x82\xbfqhX\xfa\xa5\x0c\xd8\xc1\xcf61\xb9\xac\ +\xf7\xf5\x89\x89\x12\x00Xn\xcb\x94\xe0iOo@^\x9c\xa9\x18#\x00\xe0Z;\x82\x04\ +\x04\t\xea&\xe6c\xef\xab\x00\x80W3R\xa5\n\x00\xda\xac\xac\xaa\xd2\x9e\xa8\ +\x9f\x02\xcaM9\xc8\x88(\xa0\x84\xb0\xe0\xa5\x8fU!\x8dE\t\xd0\x83X\xa2\x00-\ +\xbb\x12\xc2\xa0\xb5\xdd<\x03k\xed\x95\n\xb0\xbe\x98\x1e\xb0\xb67-\xb22\x1d\ +\xa9\xa2\x01\xe4,\xeb~3[\x0f\xee\x9ad\xab\x1d\xf99<hg\xc9\x9c\x83\x9e<\x87\ +\xfe\x13\xc03\x17\xd3[\xf4\xa7g\xa0\xdd;\xb5\xbcC\xf7\x01\xe4\x7f\xe8\xf6\ +\xd8\xbe\xd6\xcc\xe6\x95\x1c\xc9fD/\xb2\x10\x87\xc3dJ"U\x00\x00\x00\x00IEND\ +\xaeB`\x82' + +def getToolCheckListBitmap(): + return wxBitmapFromImage(getToolCheckListImage()) + +def getToolCheckListImage(): + stream = cStringIO.StringIO(getToolCheckListData()) + return wxImageFromStream(stream) + +def getToolCheckListIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolCheckListBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolNotebookData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x18\x08\x06\ +\x00\x00\x00\xe0w=\xf8\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x00\xd8IDATx\x9c\xed\x96!\x12\x830\x10E\x7f:\x11\xc8\x88\n\x8e\x80\xa8\xe0\ +\x08\x1c=\xa2"\x12Q\x91#D \x90\x88\xceP\x95N\x12\x92\xb0K\x87\x8aN\x9f\xdb\ +\xcdN\xfe\xfeea\x10J)\xb8\xc9\xad \xd0^[A\xa9\x0b\x91nr\xab\xb5\x96T<\xcf\ +\xf3\xaa\x94b\x89\xc8\\\xb2\xbf\xf5\x18\x1fc\x94\xd3Z\x03\xc0\xae\xdb\xd4eV\ +\xa0\x86\xb9\x9b\xeay\xear#\xe0\xbb\xcf\xb9\xf0\x0c\xc3\x10\xc5\xde\x9d1[q\ +\xb6\x83\xf4R/\x18\xc6!\x970\x08\xbb\xf6.>%;"\n\xe1\x98J\xddG\x02\xa5\x99\ +\x97\xf2\x87Ft\x06o\x81\xd2\xc6\x94\xf2T\x0eo\x11\xfb\x19p\xa8]\x98"\x96\xe7\ +B\xfe\x16\x01@\xd7u\xe4\xdaF6|\x07\x9cf\x80\x13\xb7\xc8\x8f\xf1{k\xfa\x17\ +\xf8]\x01\t\xf0\xdeL.\x02\x00\xe9\x97\xe5(/\x90\xf2\\\xdd\xe7\xbb{_\x00\x00\ +\x00\x00IEND\xaeB`\x82' + +def getToolNotebookBitmap(): + return wxBitmapFromImage(getToolNotebookImage()) + +def getToolNotebookImage(): + stream = cStringIO.StringIO(getToolNotebookData()) + return wxImageFromStream(stream) + +def getToolNotebookIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolNotebookBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolSpinCtrlData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x18\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x0c$\xbf\x95\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\xebIDATx\x9c\xad\x94\xbd\x11\x84 \x10\x85\x1f7\x06\x86\x1b\x18P\x82\ +eX\x90\x01\x05\\p%\x18\x18X\x8eeP\x02\x81\xc1\x86\x04\xcep\xc1\x1d\xce\xc9\ +\x00\x87?o\x86dY\xdf\xe7\xee\x02b\x18\x07\x87\x13z=_\xa2(\xf1\x0b8\xb4\xecj\ +\x1d\x11!\\\xb1x\xe5Av\xb5E?\xa4\xb5\x8e\xc6\xcdb\x9c\xd6\x1a\xcc\xec\x88h\ +\xab\xeeQ\xe4\xfaG\xde\x1c\x00\x86q\x003omO\x02\xea\xaa>l\x0e\x00]\xd7\xed U\ +\xec\xa3Rs\xafy\x9e\x93{Q\x80]m\x11\xc4,\xc6\xe5\xf2\x98\xd9E\x01\xa5\x92\ +\x8d\x14D\x94\xcd\xb9e\xc89]\xaa\xc0,&yI\xa7i\x82\xea\xd55\x80l\xa4\x08O\x11\ +\xf0\x19\xba\xea\x15\x88H\\n\x91l\xa4h\xdbv\x17\xf3\xe6@f\x06\xa57;Txdo\x19\ +\xb2\xaf\xe2\xb75~o\x9bA\xea\x8d9\x02\t\xdf\xa1\rp\xb6\x1d\xa1Bs\x00x\x03\ +\xf8\x1fx\xe7\xcd\xa8y\xd6\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolSpinCtrlBitmap(): + return wxBitmapFromImage(getToolSpinCtrlImage()) + +def getToolSpinCtrlImage(): + stream = cStringIO.StringIO(getToolSpinCtrlData()) + return wxImageFromStream(stream) + +def getToolSpinCtrlIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolSpinCtrlBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolUnknownData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00dIDATx\x9ccd``\xf8\xcf@\x01`a```\xb8p\xe5\x02Y\x9a\rt\x0c \x06\xe0\ +\x92D\x06\xb8,a"F3.1\x9c\x06 \xdbJ\xc8{x\r \x06`\r\x03R\x02\x95\xa0\x0b`~\')\ +\x10\xd15S\xe4\x02|\xb6\x13m\x00>\x803!\x11\xb2\x99(\x17\x18\xe8\x18\x10\x0c\ +\x87\x81\xf7\x02#\x03\x85\xd9\x19\x00\x180\x1c\x9b3;\xb6\xda\x00\x00\x00\x00\ +IEND\xaeB`\x82' + +def getToolUnknownBitmap(): + return wxBitmapFromImage(getToolUnknownImage()) + +def getToolUnknownImage(): + stream = cStringIO.StringIO(getToolUnknownData()) + return wxImageFromStream(stream) + +def getToolUnknownIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolUnknownBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolBoxSizerData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00DIDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4\x9b\x1a\x06\xb00000\x04\x84\ +\x04\xfc\xa7\xc8\x00\x06\x06\x06\x86\rk60bS\x10\x10\x12\xf0\x1f\x9f\xdc\xc0\ +\x87\xc1\xa8\x01T0\x80Q@@\x80\xa2\x84\xc48\xf43\x13\x00\xf5\xfe\x0c\x98\x979\ +f\xc6\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolBoxSizerBitmap(): + return wxBitmapFromImage(getToolBoxSizerImage()) + +def getToolBoxSizerImage(): + stream = cStringIO.StringIO(getToolBoxSizerData()) + return wxImageFromStream(stream) + +def getToolBoxSizerIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolBoxSizerBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolSeparatorData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x0e\x00\x00\x00\x02\x08\x06\ +\x00\x00\x00h\x8a\xed\xaa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00\x19IDATx\x9cc\x9c0e\xc2\x7f\x06\x12AFF\x06\x03\x0b\x8cA*\x00\x00\ +\xb5q\x05)B\x17\xc1\x07\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolSeparatorBitmap(): + return wxBitmapFromImage(getToolSeparatorImage()) + +def getToolSeparatorImage(): + stream = cStringIO.StringIO(getToolSeparatorData()) + return wxImageFromStream(stream) + +def getToolSeparatorIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolSeparatorBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolStaticBoxSizerData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00dIDATx\x9c\xed\x92A\n\xc00\x08\x045\xe4\x01\xfb4\x0f>3\x07\x9f\xe6\ +\x0f\xecU,\xb4IS\xe8\xa5s\x11\x16\x1c\x16\x91\x01\xd0\x0e\xad\x06\xee\x1e\ +\x8f\x05\xee\x1e\x00xE\xd2\x89\x88D%l\x18\xd7\x06\xa2r+\xea5\xc8\rl\x18gyET\ +\xa2\xd5\xe5<g8\x1dq\x95_\xf0\x82\x80\x01L=\xcc\xa5`\x87\xefop\x00N\x12$g%t;\ +\xe1\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolStaticBoxSizerBitmap(): + return wxBitmapFromImage(getToolStaticBoxSizerImage()) + +def getToolStaticBoxSizerImage(): + stream = cStringIO.StringIO(getToolStaticBoxSizerData()) + return wxImageFromStream(stream) + +def getToolStaticBoxSizerIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolStaticBoxSizerBitmap()) + return icon + +#---------------------------------------------------------------------- +def getToolGridSizerData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\ +\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\ +\x00\x00<IDATx\x9cc\x14\x10\x10`\x08\x08\t\xf8\xcf@&`\x8116\xac\xd9\xc0\x88M\ +A@H\xc0\x7f|rL\xe4\xda\x0c\x03\xa3\x06000\x8eF\xe3p0\x80\xe2hd\x14\x10\x10\ +\xa0\xc8\x05\x00M\x98\x16\xba|O\xcc\x02\x00\x00\x00\x00IEND\xaeB`\x82' + +def getToolGridSizerBitmap(): + return wxBitmapFromImage(getToolGridSizerImage()) + +def getToolGridSizerImage(): + stream = cStringIO.StringIO(getToolGridSizerData()) + return wxImageFromStream(stream) + +def getToolGridSizerIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getToolGridSizerBitmap()) + return icon + +#---------------------------------------------------------------------- +def getTreeSeparatorData(): + return \ +'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x0e\x08\x06\ +\x00\x00\x00&/\x9c\x8a\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\ +\x007IDATx\x9cc\x14\x10\x10`\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16\ +\x18\xa3\xa1\xa5\xe1?\xb1\x9a222\x18$D$\x18Q\x0c\x80I\x90\n\x18G\xd3\xc1 0\ +\x00\x00\xfb\xe8\x05\xb7\x9e\n\x8b\xdd\x00\x00\x00\x00IEND\xaeB`\x82' + +def getTreeSeparatorBitmap(): + return wxBitmapFromImage(getTreeSeparatorImage()) + +def getTreeSeparatorImage(): + stream = cStringIO.StringIO(getTreeSeparatorData()) + return wxImageFromStream(stream) + +def getTreeSeparatorIcon(): + icon = wxEmptyIcon() + icon.CopyFromBitmap(getTreeSeparatorBitmap()) + return icon diff --git a/wxPython/wxPython/tools/XRCed/license.txt b/wxPython/wxPython/tools/XRCed/license.txt new file mode 100644 index 0000000000..933ec7d758 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/license.txt @@ -0,0 +1,23 @@ +Copyright (c) 2002, Roman Rolinsky <rollrom@users.sourceforge.net> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/wxPython/wxPython/tools/XRCed/panel.py b/wxPython/wxPython/tools/XRCed/panel.py new file mode 100644 index 0000000000..b9abd4b2bd --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/panel.py @@ -0,0 +1,365 @@ +# Name: panel.py +# Purpose: XRC editor, Panel class and related +# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> +# Created: 02.12.2002 +# RCS-ID: $Id$ + +from xxx import * # xxx imports globals and params +from undo import * +from wxPython.html import wxHtmlWindow + +# Properties panel containing notebook +class Panel(wxNotebook): + def __init__(self, parent, id = -1): + if wxPlatform != '__WXMAC__': # some problems with this style on macs + wxNotebook.__init__(self, parent, id, style=wxNB_BOTTOM) + else: + wxNotebook.__init__(self, parent, id) + global panel + g.panel = panel = self + self.modified = False + + # Set common button size for parameter buttons + import params + params.buttonSize = self.DLG_SZE(buttonSize) + + # List of child windows + self.pages = [] + # Create scrolled windows for pages + self.page1 = wxScrolledWindow(self, -1) + sizer = wxBoxSizer() + sizer.Add(wxBoxSizer()) # dummy sizer + self.page1.SetAutoLayout(True) + self.page1.SetSizer(sizer) + self.AddPage(self.page1, 'Properties') + # Second page + self.page2 = wxScrolledWindow(self, -1) + sizer = wxBoxSizer() + sizer.Add(wxBoxSizer()) # dummy sizer + self.page2.SetAutoLayout(True) + self.page2.SetSizer(sizer) + # Cache for already used panels + self.pageCache = {} # cached property panels + self.stylePageCache = {} # cached style panels + # Dummy parent window for cache pages + self.cacheParent = wxFrame(None, -1, 'i am invisible') + # Delete child windows and recreate page sizer + def ResetPage(self, page): + topSizer = page.GetSizer() + sizer = topSizer.GetChildren()[0].GetSizer() + for w in page.GetChildren(): + sizer.RemoveWindow(w) + if isinstance(w, ParamPage): + # With SetParent, we wouldn't need this + w.Reparent(self.cacheParent) + else: + w.Destroy() + topSizer.RemoveSizer(sizer) + # Create new windows + sizer = wxBoxSizer(wxVERTICAL) + # Special case - resize html window + if g.conf.panic: + topSizer.Add(sizer, 1, wxEXPAND) + else: + topSizer.Add(sizer, 0, wxALL, 5) + return sizer + def SetData(self, xxx): + self.pages = [] + # First page + # Set cached or new page + # Remove current objects and sizer + sizer = self.ResetPage(self.page1) + if not xxx or (not xxx.allParams and not xxx.hasName): + if g.tree.selection: + sizer.Add(wxStaticText(self.page1, -1, 'This item has no properties.')) + else: # nothing selected + # If first time, show some help + if g.conf.panic: + html = wxHtmlWindow(self.page1, -1, wxDefaultPosition, + wxDefaultSize, wxSUNKEN_BORDER) + html.SetPage(g.helpText) + sizer.Add(html, 1, wxEXPAND) + g.conf.panic = False + else: + sizer.Add(wxStaticText(self.page1, -1, 'Select a tree item.')) + else: + g.currentXXX = xxx.treeObject() + try: + page = self.pageCache[xxx.__class__] + page.Reparent(self.page1) + except KeyError: + page = PropPage(self.page1, xxx.className, xxx) + self.pageCache[xxx.__class__] = page + page.SetValues(xxx) + self.pages.append(page) + sizer.Add(page, 1, wxEXPAND) + if xxx.hasChild: + # Special label for child objects - they may have different GUI + cacheID = (xxx.child.__class__, xxx.__class__) + try: + page = self.pageCache[cacheID] + page.Reparent(self.page1) + except KeyError: + page = PropPage(self.page1, xxx.child.className, xxx.child) + self.pageCache[cacheID] = page + page.SetValues(xxx.child) + self.pages.append(page) + sizer.Add(page, 0, wxEXPAND | wxTOP, 5) + self.page1.Layout() + size = self.page1.GetSizer().GetMinSize() + self.page1.SetScrollbars(1, 1, size.x, size.y, 0, 0, True) + + # Second page + # Create if does not exist + if xxx and xxx.treeObject().hasStyle: + xxx = xxx.treeObject() + # Simplest case: set data if class is the same + sizer = self.ResetPage(self.page2) + try: + page = self.stylePageCache[xxx.__class__] + page.Reparent(self.page2) + except KeyError: + page = StylePage(self.page2, xxx.className + ' style', xxx) + self.stylePageCache[xxx.__class__] = page + page.SetValues(xxx) + self.pages.append(page) + sizer.Add(page, 0, wxEXPAND) + # Add page if not exists + if not self.GetPageCount() == 2: + self.AddPage(self.page2, 'Style') + self.page2.Layout() + size = self.page2.GetSizer().GetMinSize() + self.page2.SetScrollbars(1, 1, size.x, size.y, 0, 0, True) + else: + # Remove page if exists + if self.GetPageCount() == 2: + self.SetSelection(0) + self.page1.Refresh() + self.RemovePage(1) + self.modified = False + def Clear(self): + self.SetData(None) + self.modified = False + # If some parameter has changed + def IsModified(self): + return self.modified + def SetModified(self, value): + # Register undo object when modifying first time + if not self.modified and value: + g.undoMan.RegisterUndo(UndoEdit()) + self.modified = value + def Apply(self): + for p in self.pages: p.Apply() + +################################################################################ + +# General class for notebook pages +class ParamPage(wxPanel): + def __init__(self, parent, xxx): + wxPanel.__init__(self, parent, -1) + self.xxx = xxx + # Register event handlers + for id in paramIDs.values(): + EVT_CHECKBOX(self, id, self.OnCheckParams) + self.checks = {} + self.controls = {} # save python objects + self.controlName = None + + def OnCheckParams(self, evt): + xxx = self.xxx + param = evt.GetEventObject().GetName() + w = self.controls[param] + w.Enable(True) + objElem = xxx.element + if evt.IsChecked(): + # Ad new text node in order of allParams + w.SetValue('') # set empty (default) value + w.SetModified() # mark as changed + elem = g.tree.dom.createElement(param) + # Some classes are special + if param == 'font': + xxx.params[param] = xxxParamFont(xxx.element, elem) + elif param in xxxObject.bitmapTags: + xxx.params[param] = xxxParamBitmap(elem) + else: + xxx.params[param] = xxxParam(elem) + # Find place to put new element: first present element after param + found = False + paramStyles = xxx.allParams + xxx.styles + for p in paramStyles[paramStyles.index(param) + 1:]: + # Content params don't have same type + if xxx.params.has_key(p) and p != 'content': + found = True + break + if found: + nextTextElem = xxx.params[p].node + objElem.insertBefore(elem, nextTextElem) + else: + objElem.appendChild(elem) + else: + # Remove parameter + xxx.params[param].remove() + del xxx.params[param] + w.SetValue('') + w.modified = False # mark as not changed + w.Enable(False) + # Set modified flag (provokes undo storing is necessary) + panel.SetModified(True) + def Apply(self): + xxx = self.xxx + if self.controlName: + name = self.controlName.GetValue() + if xxx.name != name: + xxx.name = name + xxx.element.setAttribute('name', name) + for param, w in self.controls.items(): + if w.modified: + paramObj = xxx.params[param] + value = w.GetValue() + if param in xxx.specials: + xxx.setSpecial(param, value) + else: + paramObj.update(value) + # Save current state + def SaveState(self): + self.origChecks = map(lambda i: (i[0], i[1].GetValue()), self.checks.items()) + self.origControls = map(lambda i: (i[0], i[1].GetValue(), i[1].IsEnabled()), + self.controls.items()) + if self.controlName: + self.origName = self.controlName.GetValue() + # Return original values + def GetState(self): + if self.controlName: + return (self.origChecks, self.origControls, self.origName) + else: + return (self.origChecks, self.origControls) + # Set values from undo data + def SetState(self, state): + for k,v in state[0]: + self.checks[k].SetValue(v) + for k,v,e in state[1]: + self.controls[k].SetValue(v) + self.controls[k].Enable(e) + if e: self.controls[k].modified = True + if self.controlName: + self.controlName.SetValue(state[2]) + +################################################################################ + +# Panel for displaying properties +class PropPage(ParamPage): + def __init__(self, parent, label, xxx): + ParamPage.__init__(self, parent, xxx) + box = wxStaticBox(self, -1, label) + box.SetFont(labelFont) + topSizer = wxStaticBoxSizer(box, wxVERTICAL) + sizer = wxFlexGridSizer(len(xxx.allParams), 2, 1, 1) + sizer.AddGrowableCol(1) + if xxx.hasName: + label = wxStaticText(self, -1, 'XML ID:', size=(100,-1)) + control = ParamText(self, 'XML_name', 200) + sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL), + (control, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW, 5) ]) + self.controlName = control + for param in xxx.allParams: + present = xxx.params.has_key(param) + if param in xxx.required: + label = wxStaticText(self, paramIDs[param], param + ':', + size = (100,-1), name = param) + else: + # Notebook has one very loooooong parameter + if param == 'usenotebooksizer': sParam = 'usesizer:' + else: sParam = param + ':' + label = wxCheckBox(self, paramIDs[param], sParam, + size = (100,-1), name = param) + self.checks[param] = label + try: + typeClass = xxx.paramDict[param] + except KeyError: + try: + # Standart type + typeClass = paramDict[param] + except KeyError: + # Default + typeClass = ParamText + control = typeClass(self, param) + control.Enable(present) + sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL), + (control, 0, wxALIGN_CENTER_VERTICAL | wxGROW) ]) + self.controls[param] = control + topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3) + self.SetAutoLayout(True) + self.SetSizer(topSizer) + topSizer.Fit(self) + def SetValues(self, xxx): + self.xxx = xxx + self.origChecks = [] + self.origControls = [] + # Set values, checkboxes to False, disable defaults + if xxx.hasName: + self.controlName.SetValue(xxx.name) + self.origName = xxx.name + for param in xxx.allParams: + w = self.controls[param] + w.modified = False + try: + value = xxx.params[param].value() + w.Enable(True) + w.SetValue(value) + if not param in xxx.required: + self.checks[param].SetValue(True) + self.origChecks.append((param, True)) + self.origControls.append((param, value, True)) + except KeyError: + self.checks[param].SetValue(False) + w.SetValue('') + w.Enable(False) + self.origChecks.append((param, False)) + self.origControls.append((param, '', False)) + +################################################################################ + +# Style notebook page +class StylePage(ParamPage): + def __init__(self, parent, label, xxx): + ParamPage.__init__(self, parent, xxx) + box = wxStaticBox(self, -1, label) + box.SetFont(labelFont) + topSizer = wxStaticBoxSizer(box, wxVERTICAL) + sizer = wxFlexGridSizer(len(xxx.styles), 2, 1, 1) + sizer.AddGrowableCol(1) + for param in xxx.styles: + present = xxx.params.has_key(param) + check = wxCheckBox(self, paramIDs[param], + param + ':', size = (100,-1), name = param) + check.SetValue(present) + control = paramDict[param](self, name = param) + control.Enable(present) + sizer.AddMany([ (check, 0, wxALIGN_CENTER_VERTICAL), + (control, 0, wxALIGN_CENTER_VERTICAL | wxGROW) ]) + self.checks[param] = check + self.controls[param] = control + topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3) + self.SetAutoLayout(True) + self.SetSizer(topSizer) + topSizer.Fit(self) + # Set data for a cahced page + def SetValues(self, xxx): + self.xxx = xxx + self.origChecks = [] + self.origControls = [] + for param in xxx.styles: + present = xxx.params.has_key(param) + check = self.checks[param] + check.SetValue(present) + w = self.controls[param] + w.modified = False + if present: + value = xxx.params[param].value() + else: + value = '' + w.SetValue(value) + w.Enable(present) + self.origChecks.append((param, present)) + self.origControls.append((param, value, present)) + diff --git a/wxPython/wxPython/tools/XRCed/params.py b/wxPython/wxPython/tools/XRCed/params.py index 30b0ae9072..a0c71474cf 100644 --- a/wxPython/wxPython/tools/XRCed/params.py +++ b/wxPython/wxPython/tools/XRCed/params.py @@ -4,17 +4,11 @@ # Created: 22.08.2001 # RCS-ID: $Id$ -from wxPython.wx import * -from wxPython.xrc import * import string import os.path +from globals import * from types import * - -# Object which is currently processed -currentXXX = None -def SetCurrentXXX(xxx): - global currentXXX - currentXXX = xxx +from wxPython.xrc import * genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', @@ -22,53 +16,54 @@ genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', 'wxNO_FULL_REPAINT_ON_RESIZE'] -buttonSize = (55,-1) +buttonSize = (30,-1) # in dialog units, transformed to pixels in panel ctor # Class that can properly disable children class PPanel(wxPanel): def __init__(self, parent, name): wxPanel.__init__(self, parent, -1, name=name) - self.modified = self.freeze = false + self.modified = self.freeze = False def Enable(self, value): # Something strange is going on with enable so we make sure... for w in self.GetChildren(): w.Enable(value) wxPanel.Enable(self, value) def SetModified(self): - self.modified = true - panel.SetModified(true) + self.modified = True + g.panel.SetModified(True) + # Common method to set modified state + def OnChange(self, evt): + if self.freeze: return + self.SetModified() + evt.Skip() class ParamBinaryOr(PPanel): def __init__(self, parent, name): PPanel.__init__(self, parent, name) self.ID_TEXT_CTRL = wxNewId() self.ID_BUTTON_CHOICES = wxNewId() - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) sizer = wxBoxSizer() self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5) self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize) sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices) EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) - def OnChange(self, evt): - if self.freeze: return - self.SetModified() - evt.Skip() def GetValue(self): return self.text.GetValue() def SetValue(self, value): - self.freeze = true + self.freeze = True self.text.SetValue(value) - self.freeze = false + self.freeze = False def OnButtonChoices(self, evt): dlg = wxDialog(self, -1, 'Choices') topSizer = wxBoxSizer(wxVERTICAL) listBox = wxCheckListBox(dlg, -1, choices=self.values, size=(250,200)) - value = map(string.strip, string.split(self.text.GetValue(), '|')) + value = map(string.strip, self.text.GetValue().split('|')) if value == ['']: value = [] ignored = [] for i in value: @@ -89,7 +84,7 @@ class ParamBinaryOr(PPanel): sizer.Add(0, 0, 1) sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel')) topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10) - dlg.SetAutoLayout(true) + dlg.SetAutoLayout(True) dlg.SetSizer(topSizer) topSizer.Fit(dlg) dlg.Center() @@ -109,7 +104,7 @@ class ParamBinaryOr(PPanel): class ParamFlag(ParamBinaryOr): values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', - 'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', + 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', 'wxALIGN_CENTRE_HORIZONTAL'] equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE', @@ -121,18 +116,18 @@ class ParamFlag(ParamBinaryOr): class ParamStyle(ParamBinaryOr): equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'} def __init__(self, parent, name): - self.values = currentXXX.winStyles + genericStyles + self.values = g.currentXXX.winStyles + genericStyles ParamBinaryOr.__init__(self, parent, name) class ParamNonGenericStyle(ParamBinaryOr): def __init__(self, parent, name): - self.values = currentXXX.winStyles + self.values = g.currentXXX.winStyles ParamBinaryOr.__init__(self, parent, name) class ParamExStyle(ParamBinaryOr): def __init__(self, parent, name): - if currentXXX: - self.values = currentXXX.exStyles # constant at the moment + if g.currentXXX: + self.values = g.currentXXX.exStyles # constant at the moment else: self.values = [] ParamBinaryOr.__init__(self, parent, name) @@ -142,33 +137,29 @@ class ParamColour(PPanel): PPanel.__init__(self, parent, name) self.ID_TEXT_CTRL = wxNewId() self.ID_BUTTON = wxNewId() - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) sizer = wxBoxSizer() self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(65,-1)) sizer.Add(self.text, 0, wxRIGHT, 5) self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(20, 20)) sizer.Add(self.button, 0, wxGROW) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) - self.textModified = false + self.textModified = False EVT_PAINT(self.button, self.OnPaintButton) EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) EVT_LEFT_DOWN(self.button, self.OnLeftDown) def GetValue(self): return self.text.GetValue() def SetValue(self, value): - self.freeze = true + self.freeze = True if not value: value = '#FFFFFF' self.text.SetValue(str(value)) # update text ctrl colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16)) self.button.SetBackgroundColour(colour) self.button.Refresh() - self.freeze = false - def OnChange(self, evt): - if self.freeze: return - self.SetModified() - evt.Skip() + self.freeze = False def OnPaintButton(self, evt): dc = wxPaintDC(self.button) dc.SetBrush(wxTRANSPARENT_BRUSH) @@ -206,23 +197,21 @@ class ParamFont(PPanel): PPanel.__init__(self, parent, name) self.ID_TEXT_CTRL = wxNewId() self.ID_BUTTON_SELECT = wxNewId() - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) sizer = wxBoxSizer() self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5) self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize) sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) - self.textModified = false + self.textModified = False EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect) EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) def OnChange(self, evt): - if self.freeze: return - self.SetModified() - self.textModified = true - evt.Skip() + PPanel.OnChange(self, evt) + self.textModified = True def _defaultValue(self): return ['12', 'default', 'normal', 'normal', '0', '', ''] def GetValue(self): @@ -234,11 +223,11 @@ class ParamFont(PPanel): return self._defaultValue() return self.value def SetValue(self, value): - self.freeze = true # disable other handlers + self.freeze = True # disable other handlers if not value: value = self._defaultValue() self.value = value self.text.SetValue(str(value)) # update text ctrl - self.freeze = false + self.freeze = False def OnButtonSelect(self, evt): if self.textModified: # text has newer value try: @@ -255,23 +244,23 @@ class ParamFont(PPanel): face = '' enc = wxFONTENCODING_DEFAULT # Fall back to default if exceptions - error = false + error = False try: try: size = int(self.value[0]) - except ValueError: error = true + except ValueError: error = True try: family = fontFamiliesXml2wx[self.value[1]] - except KeyError: error = true + except KeyError: error = True try: style = fontStylesXml2wx[self.value[2]] - except KeyError: error = true + except KeyError: error = True try: weight = fontWeightsXml2wx[self.value[3]] - except KeyError: error = true + except KeyError: error = True try: underlined = int(self.value[4]) - except ValueError: error = true + except ValueError: error = True face = self.value[5] mapper = wxFontMapper() if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6]) except IndexError: - error = true + error = True if error: wxLogError('Invalid font specification') if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM font = wxFont(size, family, style, weight, underlined, face, enc) @@ -291,7 +280,7 @@ class ParamFont(PPanel): # Add ignored flags self.SetValue(value) self.SetModified() - self.textModified = false + self.textModified = False dlg.Destroy() ################################################################################ @@ -302,60 +291,108 @@ class ParamInt(PPanel): self.ID_SPIN_CTRL = wxNewId() sizer = wxBoxSizer() self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=wxSize(50,-1)) - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) sizer.Add(self.spin) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) def GetValue(self): return str(self.spin.GetValue()) def SetValue(self, value): - self.freeze = true + self.freeze = True if not value: value = 0 self.spin.SetValue(int(value)) - self.freeze = false - def OnChange(self, evt): - if self.freeze: return - self.SetModified() - evt.Skip() + self.freeze = False + +# Same as int but allows dialog units (XXXd) +class ParamUnit(PPanel): + def __init__(self, parent, name): + PPanel.__init__(self, parent, name) + self.ID_TEXT_CTRL = wxNewId() + self.ID_SPIN_BUTTON = wxNewId() + sizer = wxBoxSizer() + self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(35,-1)) + self.spin = wxSpinButton(self, self.ID_SPIN_BUTTON, style = wxSP_VERTICAL) + self.spin.SetRange(-10000, 10000) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) + sizer.Add(self.text, 0, wxEXPAND | wxRIGHT, 2) + sizer.Add(self.spin) + self.SetAutoLayout(True) + self.SetSizer(sizer) + sizer.Fit(self) + EVT_SPIN_UP(self, self.ID_SPIN_BUTTON, self.OnSpinUp) + EVT_SPIN_DOWN(self, self.ID_SPIN_BUTTON, self.OnSpinDown) + def GetValue(self): + return self.text.GetValue() + def SetValue(self, value): + self.freeze = True + if not value: value = '0' + self.text.SetValue(value) + self.freeze = False + def Change(self, x): + # Check if we are working with dialog units + value = self.text.GetValue() + units = '' + if value[-1].upper() == 'D': + units = value[-1] + value = value[:-1] + try: + intValue = int(value) + x + self.spin.SetValue(intValue) + self.text.SetValue(str(intValue) + units) + self.SetModified() + except: + # !!! Strange, if I use wxLogWarning, event is re-generated + print 'incorrect unit format' + def OnSpinUp(self, evt): + self.Change(1) + def OnSpinDown(self, evt): + self.Change(-1) class ParamText(PPanel): - def __init__(self, parent, name, textWidth=200): + def __init__(self, parent, name, textWidth=-1): PPanel.__init__(self, parent, name) self.ID_TEXT_CTRL = wxNewId() # We use sizer even here to have the same size of text control sizer = wxBoxSizer() - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1)) - sizer.Add(self.text, 0, wxALIGN_CENTER_VERTICAL) - self.SetAutoLayout(true) + if textWidth == -1: option = 1 + else: option = 0 + sizer.Add(self.text, option, wxALIGN_CENTER_VERTICAL) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) def GetValue(self): return self.text.GetValue() def SetValue(self, value): - self.freeze = true # disable other handlers + self.freeze = True # disable other handlers self.text.SetValue(value) - self.freeze = false # disable other handlers - def OnChange(self, evt): - if self.freeze: return - self.SetModified() - evt.Skip() + self.freeze = False # disable other handlers class ParamAccel(ParamText): def __init__(self, parent, name): - ParamText.__init__(self, parent, name, 50) + ParamText.__init__(self, parent, name, 100) class ParamPosSize(ParamText): def __init__(self, parent, name): ParamText.__init__(self, parent, name, 80) +class ParamLabel(ParamText): + def __init__(self, parent, name): + ParamText.__init__(self, parent, name, 200) + +class ParamEncoding(ParamText): + def __init__(self, parent, name): + ParamText.__init__(self, parent, name, 100) + class ContentDialog(wxDialogPtr): def __init__(self, parent, value): - # Is this normal??? - w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT') + # Load from resource + w = g.frame.res.LoadDialog(parent, 'DIALOG_CONTENT') + # Perform initialization with class pointer wxDialogPtr.__init__(self, w.this) self.thisown = 1 self.Center() @@ -363,7 +400,7 @@ class ContentDialog(wxDialogPtr): # Set list items for v in value: self.list.Append(v) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.GetSizer().Fit(self) # Callbacks self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND') @@ -405,8 +442,7 @@ class ContentDialog(wxDialogPtr): class ContentCheckListDialog(wxDialogPtr): def __init__(self, parent, value): - # Is this normal??? - w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST') + w = g.frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST') wxDialogPtr.__init__(self, w.this) self.thisown = 1 self.Center() @@ -417,7 +453,7 @@ class ContentCheckListDialog(wxDialogPtr): self.list.Append(v) self.list.Check(i, ch) i += 1 - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.GetSizer().Fit(self) # Callbacks self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND') @@ -468,23 +504,21 @@ class ParamContent(PPanel): PPanel.__init__(self, parent, name) self.ID_TEXT_CTRL = wxNewId() self.ID_BUTTON_EDIT = wxNewId() - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) sizer = wxBoxSizer() self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5) self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize) sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) - self.textModified = false + self.textModified = False EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) def OnChange(self, evt): - if self.freeze: return - self.SetModified() - self.textModified = true - evt.Skip() + PPanel.OnChange(self, evt) + self.textModified = True def GetValue(self): if self.textModified: # text has newer value try: @@ -494,11 +528,11 @@ class ParamContent(PPanel): return [] return self.value def SetValue(self, value): - self.freeze = true + self.freeze = True if not value: value = [] self.value = value self.text.SetValue(str(value)) # update text ctrl - self.freeze = false + self.freeze = False def OnButtonEdit(self, evt): if self.textModified: # text has newer value try: @@ -514,7 +548,7 @@ class ParamContent(PPanel): # Add ignored flags self.SetValue(value) self.SetModified() - self.textModified = false + self.textModified = False dlg.Destroy() # CheckList content @@ -536,13 +570,13 @@ class ParamContentCheckList(ParamContent): # Add ignored flags self.SetValue(value) self.SetModified() - self.textModified = false + self.textModified = False dlg.Destroy() class IntListDialog(wxDialogPtr): def __init__(self, parent, value): # Is this normal??? - w = frame.res.LoadDialog(parent, 'DIALOG_INTLIST') + w = g.frame.res.LoadDialog(parent, 'DIALOG_INTLIST') wxDialogPtr.__init__(self, w.this) self.thisown = 1 self.Center() @@ -554,7 +588,7 @@ class IntListDialog(wxDialogPtr): wxLogError('Invalid item type') else: self.list.Append(str(v)) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.GetSizer().Fit(self) # Callbacks self.ID_BUTTON_ADD = XMLID('BUTTON_ADD') @@ -571,10 +605,10 @@ class IntListDialog(wxDialogPtr): i = self.list.FindString(s) if i == -1: # ignore non-unique # Find place to insert - found = false + found = False for i in range(self.list.Number()): if int(self.list.GetString(i)) > v: - found = true + found = True break if found: self.list.InsertItems([s], i) else: self.list.Append(s) @@ -605,7 +639,7 @@ class ParamIntList(ParamContent): # Add ignored flags self.SetValue(value) self.SetModified() - self.textModified = false + self.textModified = False dlg.Destroy() # Boxless radiobox @@ -613,22 +647,22 @@ class RadioBox(PPanel): def __init__(self, parent, id, choices, pos=wxDefaultPosition, name='radiobox'): PPanel.__init__(self, parent, name) - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) self.choices = choices topSizer = wxBoxSizer() for i in choices: button = wxRadioButton(self, -1, i, name=i) topSizer.Add(button) EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(topSizer) topSizer.Fit(self) def SetStringSelection(self, value): - self.freeze = true + self.freeze = True for i in self.choices: self.FindWindowByName(i).SetValue(i == value) self.value = value - self.freeze = false + self.freeze = False def OnRadioChoice(self, evt): if self.freeze: return if evt.GetSelection(): @@ -664,59 +698,140 @@ class ParamFile(PPanel): PPanel.__init__(self, parent, name) self.ID_TEXT_CTRL = wxNewId() self.ID_BUTTON_BROWSE = wxNewId() - self.SetBackgroundColour(panel.GetBackgroundColour()) + self.SetBackgroundColour(g.panel.GetBackgroundColour()) sizer = wxBoxSizer() self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5) self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize) sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) - self.SetAutoLayout(true) + self.SetAutoLayout(True) self.SetSizer(sizer) sizer.Fit(self) - self.textModified = false + self.textModified = False EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse) EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) def OnChange(self, evt): - if self.freeze: return - self.SetModified() - self.textModified = true - evt.Skip() + PPanel.OnChange(self, evt) + self.textModified = True def GetValue(self): if self.textModified: # text has newer value return self.text.GetValue() return self.value def SetValue(self, value): - self.freeze = true + self.freeze = True self.value = value self.text.SetValue(value) # update text ctrl - self.freeze = false + self.freeze = False def OnButtonBrowse(self, evt): if self.textModified: # text has newer value self.value = self.text.GetValue() dlg = wxFileDialog(self, - defaultDir = os.path.dirname(self.value), + defaultDir = os.path.abspath(os.path.dirname(self.value)), defaultFile = os.path.basename(self.value)) if dlg.ShowModal() == wxID_OK: - # Make relative - common = os.path.commonprefix([os.path.abspath(frame.dataFile), - dlg.GetPath()]) + # Get common part of selected path and current + if g.frame.dataFile: + curpath = os.path.abspath(g.frame.dataFile) + else: + curpath = os.path.join(os.getcwd(), '') + common = os.path.commonprefix([curpath, dlg.GetPath()]) self.SetValue(dlg.GetPath()[len(common):]) self.SetModified() - self.textModified = false + self.textModified = False + dlg.Destroy() + +class ParamBitmap(PPanel): + def __init__(self, parent, name): + # Load from resource + w = g.frame.res.LoadPanel(parent, 'PANEL_BITMAP') + # Perform initialization with class pointer + wxPanelPtr.__init__(self, w.this) + self.thisown = 1 + self.modified = self.freeze = False + self.SetBackgroundColour(g.panel.GetBackgroundColour()) + self.radio_std = self.FindWindowByName('RADIO_STD') + self.radio_file = self.FindWindowByName('RADIO_FILE') + self.combo = self.FindWindowByName('COMBO_STD') + self.text = self.FindWindowByName('TEXT_FILE') + self.button = self.FindWindowByName('BUTTON_BROWSE') + self.textModified = False + self.SetAutoLayout(True) + self.GetSizer().SetMinSize((260, -1)) + self.GetSizer().Fit(self) + EVT_RADIOBUTTON(self, XMLID('RADIO_STD'), self.OnRadioStd) + EVT_RADIOBUTTON(self, XMLID('RADIO_FILE'), self.OnRadioFile) + EVT_BUTTON(self, XMLID('BUTTON_BROWSE'), self.OnButtonBrowse) + EVT_COMBOBOX(self, XMLID('COMBO_STD'), self.OnCombo) + EVT_TEXT(self, XMLID('COMBO_STD'), self.OnChange) + EVT_TEXT(self, XMLID('TEXT_FILE'), self.OnChange) + def OnRadioStd(self, evt): + self.SetModified() + self.SetValue(['wxART_MISSING_IMAGE','']) + def OnRadioFile(self, evt): + self.SetModified() + self.SetValue(['','']) + def updateRadios(self): + if self.value[0]: + self.radio_std.SetValue(True) + self.text.Enable(False) + self.button.Enable(False) + self.combo.Enable(True) + else: + self.radio_file.SetValue(True) + self.text.Enable(True) + self.button.Enable(True) + self.combo.Enable(False) + def OnChange(self, evt): + PPanel.OnChange(self, evt) + self.textModified = True + def OnCombo(self, evt): + PPanel.OnChange(self, evt) + self.value[0] = self.combo.GetValue() + def GetValue(self): + if self.textModified: # text has newer value + return [self.combo.GetValue(), self.text.GetValue()] + return self.value + def SetValue(self, value): + self.freeze = True + if not value: + self.value = ['', ''] + else: + self.value = value + self.combo.SetValue(self.value[0]) + self.text.SetValue(self.value[1]) # update text ctrl + self.updateRadios() + self.freeze = False + def OnButtonBrowse(self, evt): + if self.textModified: # text has newer value + self.value[1] = self.text.GetValue() + dlg = wxFileDialog(self, + defaultDir = os.path.abspath(os.path.dirname(self.value[1])), + defaultFile = os.path.basename(self.value[1])) + if dlg.ShowModal() == wxID_OK: + # Get common part of selected path and current + if g.frame.dataFile: + curpath = os.path.abspath(g.frame.dataFile) + else: + curpath = os.path.join(os.getcwd(), '') + common = os.path.commonprefix([curpath, dlg.GetPath()]) + self.SetValue(['', dlg.GetPath()[len(common):]]) + self.SetModified() + self.textModified = False dlg.Destroy() paramDict = { 'flag': ParamFlag, 'style': ParamStyle, 'exstyle': ParamExStyle, 'pos': ParamPosSize, 'size': ParamPosSize, - 'border': ParamInt, 'cols': ParamInt, 'rows': ParamInt, - 'vgap': ParamInt, 'hgap': ParamInt, - 'checkable': ParamBool, 'accel': ParamAccel, + 'border': ParamUnit, 'cols': ParamInt, 'rows': ParamInt, + 'vgap': ParamUnit, 'hgap': ParamUnit, + 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool, + 'accel': ParamAccel, 'label': ParamText, 'title': ParamText, 'value': ParamText, 'content': ParamContent, 'selection': ParamInt, 'min': ParamInt, 'max': ParamInt, 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont, 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool, - 'tooltip': ParamText, 'bitmap': ParamFile, 'icon': ParamFile, + 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap, + 'label': ParamLabel, 'encoding': ParamEncoding } - diff --git a/wxPython/wxPython/tools/XRCed/sawfishrc b/wxPython/wxPython/tools/XRCed/sawfishrc new file mode 100644 index 0000000000..7e1f6d94bc --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/sawfishrc @@ -0,0 +1,24 @@ +(require 'sawmill-defaults) + +;;; Define two hooks to reset focus behavior while mapping test window + +(define (xrced-match-window-before w) + (setq prop (aref (get-x-text-property w 'WM_CLASS) 0)) + (cond ((equal prop "_XRCED_T_W") + (setq transients-get-focus-b transients-get-focus) + (setq transients-get-focus nil) + (setq focus-windows-when-mapped-b focus-windows-when-mapped) + (setq focus-windows-when-mapped nil) + ) + ) +) +(define (xrced-match-window-after w) + (setq prop (aref (get-x-text-property w 'WM_CLASS) 0)) + (cond ((equal prop "_XRCED_T_W") + (setq transients-get-focus-b transients-get-focus-b) + (setq focus-windows-when-mapped focus-windows-when-mapped-b) + ) + ) +) +(add-hook 'map-notify-hook xrced-match-window-before) +(add-hook 'map-notify-hook xrced-match-window-after 't) diff --git a/wxPython/wxPython/tools/XRCed/src-images/AutoRefresh.png b/wxPython/wxPython/tools/XRCed/src-images/AutoRefresh.png new file mode 100644 index 0000000000000000000000000000000000000000..d957081d6e356a180c5470d12d023dbae9160c99 GIT binary patch literal 316 zcmV-C0mJ@@P)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004b3#c}2nYxW zd<bNS0002<Nkl<Zc$~GAtro*D2!+YcL?p70SQ%M~tVHe+CoAVRv$m8$Lc0@Oe{#RT z1rj1c&$x9}2Y`F@$LF%V^}7Kvwa$eykm3*KDl`mO4_o5$<}FAy152EUl7<kG3kiEL zmJ+JDj^wqem%3LT4;}_cbBQP|)A2iJ-pY3hpoIYdR&mY@V=0hlAL4p2Ag0wkeF*3M zTPxfQTA@n>U}tb?Rmc*(rux6#cTscDYLi-CyTO+L5+t8-KK49k-heuqCd+o!23oBQ zaO}EMtAfO3bXL}o0R&29tp;y>TM?cE%WS=2{{no4ejqjR(|{|{eb7D`{hJ6Lt+ST^ O0000<MNUMnLSTZo1bnps literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Copy.png b/wxPython/wxPython/tools/XRCed/src-images/Copy.png new file mode 100644 index 0000000000000000000000000000000000000000..9771d6d2169589975733dfba016ea88c776cc0ba GIT binary patch literal 273 zcmV+s0q*{ZP)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004b3#c}2nYxW zd<bNS0002UNkl<Zc%1E(I}5`w420$4!Q=hZj2Sg{%um&*!H^CiArDF9Q4fV42#f}O z+}Xkj0JYSs>GVI~jIz}fk<sb{NLK-_1FgEL2z(3RL9arRwFe?HYE>$^EQ6;rn?r!X zjV=W2Rq~s(_J>{s2_q`GY|4|?o<uq`x)5Mp^cuW(VL@&=SOc~8OA!$<^9J(B!I}8X zMVp5l#S8eXOaOqiw@O6Rb>hN3sOx~4jb}Gq;$sJq<`>fh01Reyk<3m0rhfm!X%6@R XwC#76DFJ3Z00000NkvXXu0mjf26JsC literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Cut.png b/wxPython/wxPython/tools/XRCed/src-images/Cut.png new file mode 100644 index 0000000000000000000000000000000000000000..58d86ce0bd77b9fc3add8b23b0090c0af69587f1 GIT binary patch literal 255 zcmV<b0094qP)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004b3#c}2nYxW zd<bNS0002CNkl<Zc%03Y(GA2P3`5OL;88O|Mqt!z(EDlbD%3zgLc&u28o%P07LwSh z&sO(i0A_Y=1pt7mzCuRuG(bc`^9Y^>kSwi{o7Y;qvn5+oHzZkFb5$+T+;ofDIC|z& z0FTLcF^Xmy@TSq%15-PYI~u(ofUHBn^a-BPn921AF9Lcdwet7Q62J%DsHf<%o$<44 z<;xW@0R0mVTlCD=jl7=ESfa|NYML>Ml)eY6I&;ZK0lw5dU;jT!nP30_002ovPDHLk FV1giTXa@iQ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Icon.png b/wxPython/wxPython/tools/XRCed/src-images/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c6eda50401470437dc3232ed69332be27787aeec GIT binary patch literal 1111 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabRA=0U}gyL32_B-|NsAg{P^+E(9p+^ z9~TuB_4W0wTD8j3(h?{oD=Yi>@&8q;{sUDN75xtl{omIIRQz97_P?biP;eBChQQDc zf%>Dh8yOfFg*;sxLn`L1op^gzvjIoT>}JmZk5&8r?|$cS=kKd!YsGcNy*`{bcyKoM z$XlroiZ0KWJ&5I!(#(qeT%#c}D@LhEZ-T2s<+hwx4a;wye<FHd?ura0j;c$Gsx(60 z%wk-Zooe0A_h8Z{4Ij(L4>vjW2cOwnP|?BMkk+mua%zRZ!-i+^{E^b^UeDH6H>8?y z_B$*~3jX5yvLh~9-odfb$owY58z1c((T6_h-TJuYWPkm&&k-~3GwXb+ZOG349(r4O zrSgWZV{L1)Ht{oL^<?`V)z&Uyi!eK3E||CJv5m$C8ODbBGh3WCN5nJzW?H^yk?&i- z^9Pio?k9ZG+jPt4|FRW#nJ&cMZ)TeHp!u(Y>W`wU^&c%iFnjC}(A{pje;+7*Jzf1= J);T3K0RW8bwr~Id literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/New.png b/wxPython/wxPython/tools/XRCed/src-images/New.png new file mode 100644 index 0000000000000000000000000000000000000000..571af0f44c9979787d22c38644eeb9465ad9a144 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1@!3HD+75jC86icy_X9x!n)NrJ90Qse!E{-7; zbKYLv&2>P5hxNkjM-x8QZJIyFusLCQ*(X<5ua%7A%yK-PT%K!sl3%`*mgv0TH7hdj zsplyX28MZicC2?yOxxM+Gxfye@_b9yi~xqWL3V65Kld^y9E)(-cYm4m55^0%TI&*{ mm?liQ#n9XKM*nl^0~S9Q6{{CVzfJ@?fWgz%&t;ucLK6U4dqbK4 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Open.png b/wxPython/wxPython/tools/XRCed/src-images/Open.png new file mode 100644 index 0000000000000000000000000000000000000000..9cced6acf2948470ab2e6079ee98649c4d8608c7 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1@!3HD+75jC86icy_X9x!n)NrJ90Qo09T^vIy z=DeM1$ah$Q$JIWR-A#U#bN^H2f;oJ)Q{359td@kdus93yO#QXALqq9(qID3DU}CDC z_se=m|8<M?yF7fpyQF0OZqpK&=;5Lk>p9Ik_{^H~CI?Svt<rs!>$r3KnM_tCp;`t8 z{sV`!CTE?TDw$Jo;4u4v_QzZdXJTw?ofFC@ecmd&)U|rXwPiMUo%J5}r%TuE&(%$S z*1yD%xrVj;ob0^SqCE#bUuO1VHGa@w^u(;Hn{7SUJ^d2ztb$Mj?fw4`N9t8D{z*^S Ukz99UF3?j9p00i_>zopr0DqfgOaK4? literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Paste.png b/wxPython/wxPython/tools/XRCed/src-images/Paste.png new file mode 100644 index 0000000000000000000000000000000000000000..5dac646f5a16089de4ef142dc2ad063f5c6c225e GIT binary patch literal 280 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1@!3HD+75jC86icy_X9x!n)NrJ90Qu)VT^vIy z=DeM{k?*hqk4t}7<Hh;2HZFFzyROVEB&!v~w9HY3XKGcDh(iItfrPV5#LDAA-|Z7z z%C;=-ShC5_B`syn%ejkg2{1U-{GV&IRxTj6u|p;8-s>|x0`|vt#(edZdSb$M(?)vw zQ=tip&e|)M=AK;P*M4pD9@&BxT{Z@Xj`PdTM)Er>kH2wO?9CeY+E>f-Hf^r^f68ou zt!J?IitU=$y&tGHq%AqRj9WozaqKLa6Z38wEMUKB7MO0&%D|9j_e4y|R<<VCeD=Mi c_v<gleZTD!$=X$R6X-PtPgg&ebxsLQ0PFH=P5=M^ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Redo.png b/wxPython/wxPython/tools/XRCed/src-images/Redo.png new file mode 100644 index 0000000000000000000000000000000000000000..a2d7e9a5d045bc02c641d7786242d638c643e888 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^;y^6M!3HF?%h*|g6kC$Fy9>jA5L~c#`DCC7XMsm# zF#`j)5C}6~x?A@LD9B#o>FdgViHA{?S&zA5Q8`ek)6>N<q+(8Tf&}Yg2Cjd?K?hvC zxjjt(*z;7YMj5fBT0Pp@Fp<SsQpTBA(xTEr!Xm;#0t757BqZu;5)&fKtL?)!cNqTJ zpS(hm83+#lyZZcLljF)h9v&SYp4ZEg&1Xb>xPQS_SWHIaQN)oINe0Y(hL?Dj9})1H mtaP*?={^4r*2M`+m>CQrm4z;!<%|Y8iow&>&t;ucLK6T(zDra9 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Refresh.png b/wxPython/wxPython/tools/XRCed/src-images/Refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..8180432febbea76d8ef66106ba7c44ab2fcbba63 GIT binary patch literal 275 zcmV+u0qp*XP)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004b3#c}2nYxW zd<bNS0002WNkl<Zc$~$Q!4ZTY3`LV23&_zDJyJqS$dM8~(t&%C8O#z0GR*#)BLBfR z2@(;k)Mu$X0Bqh5&y+6xZYRRtKGzLO^C;4Ux&e7}&AdE$57N9r&77H0Lzvlwxc|Ws zf-7?^w93@Fx)qNFcb91tfhh8b!xK|CqOxjo{v$F0I}zqny)o_rW{tC!kBa{S&XlfJ zr%sKE5u>uwh5+7iaIeob+7ZIz*%OZoP#X=__^!#EMOw8J>j^srxQ%`wy=EK&ywUPT Z`vOmbZyvN=F~a}=002ovPDHLkV1mSmZ2JHJ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Save.png b/wxPython/wxPython/tools/XRCed/src-images/Save.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c686eef4a8f9bc8067575a184f8068b02d840e GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1@!3HD+75jC86icy_X9x!n)NrJ90Qqg6E{-7; zbKXwf$aO%0$7QR9#Xa@=>ef~ww;WkkO5I*0vXotkW#@9w5MGDgD`r<}IU6)t=N2EA zHfH!GwR&Cy&*uAkEiP?U+1y*|8OSolgx%rNpN6E_ZWFyClU<oL|N9=0ZJxG^p{*pa z>Y|G7EmsB;P5X+>a!=D0VwMh{j=x^{<$r1&p9N!?g^7oZ*`a=*ix@mz{an^LB{Ts5 DLW4yP literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Test.png b/wxPython/wxPython/tools/XRCed/src-images/Test.png new file mode 100644 index 0000000000000000000000000000000000000000..c6e7816f4aba0796df5670b773167d8c0edbd6c4 GIT binary patch literal 350 zcmV-k0iphhP)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004b3#c}2nYxW zd<bNS0003MNkl<Zc$~FWyAgvh43%>!QfdT`KtaJcjG_@3fpJo#@Cb}RNx_}dV6cU3 ziyTpd5%T*;1`Hy?KjZONbO3m2ispItJco!zv)7bbBmrL~5*=7;cVOpSks#Dg(<Bm| z99V1p`*VQ43Qb(rW8JllNOJ3tiRjeQ!~s_yLUIwS4<Wg@{g`qWyMvs1fWyJErfVs< zi>d<-7_Oz^$1e6V=UjFZR~wwj^=TJWGvGia^*q!=4xm@S69Ub*MFTzzLvpXy6VIVW zL`3o_%DIq+ECpA8BG7=>^09i6Aa;=hk)BKH0Wvc{L_<WrYexV8klygFZ8qS3&vEqt wl^@Qw$&cfB%J+R4SWOTU3AyUgRulXhU;K$|pVw;yKL7v#07*qoM6N<$g5?yAJ^%m! literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolBitmapButton.png b/wxPython/wxPython/tools/XRCed/src-images/ToolBitmapButton.png new file mode 100644 index 0000000000000000000000000000000000000000..6b052016150bd46079bb6c61ab8ad6c438199e92 GIT binary patch literal 616 zcmV-u0+;=XP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0006nNkl<Zc$~GC zKWGzC9LGPA8(zTS9%RUk86569*{wx~rjxCU?PkD5yHxFxI%v`@6#Uag(-g$i#X49z zMz_llNCqJtBsmA+mO^e2a$w=!a1e)Z1*N&9rTLDJ_r9O^{k^}5!C)|8N=hUWXaHTO zJ1qv+re$2O*QX1Jq)pPvGOcslCn;@g0?V|{%!5Ax?eA^+{r*_+M1W{;v(aR8<00zz zE@rv~UX|Kmk=%pji6F5FnvEt#T2OduB2)7u^#x=~lD%c{=Gh#%`?;}@a{<wSop(E= zH5-}Af|dbI!u2JRnn2ejg*AiKd#jgEkY8H@Awd|!hEPGM2tq+p1DO)&QpBc+1t>K% z97=$u6R6=L2MEvvhOR~%i~>a4uk`i^!T?YZ`k-70duK_M?{jcyUmOsr`o4+^8A3Ec zpj^O*P~mw!+><_~m*syZ^}k{dnh*k^6p$o1bs_Xos!z}JP^ST<ii2IR#wHjE=sI0? z_jWjL*<^0CC~qy``#$bTkK!vEnX<6!&Dhz)m=aa?_AxRRg{{}Pr}I47Zt}IEIQVQ+ z`&Juk9-9DQ<?a$kUuv|E+ibolGJA8D!t(-B%89S|kqH*Fi#*=QvwSB@t6^iBCe@Es zdS35B@5e}h=XsR2i>$BbnY*3E`Qf1J`ozYOMwY14?J#4_;Qo4qkv5p0%TlhCuMQAN zDTVXX;luu?3!9Gxbh@2OnVt)X-q5R70+`yj1>i5=<lG_lg{}Pn0000<MNUMnLSTYD CN+ntV literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolBoxSizer.png b/wxPython/wxPython/tools/XRCed/src-images/ToolBoxSizer.png new file mode 100644 index 0000000000000000000000000000000000000000..b51e6f59ab87123901dd73f9a6c93b6530ece69f GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<hyvfIEGZr zNfr?hNLavP5V&Nv6x#*^AYf@>`Lp~40~;G#8*jFmK~k`QfY1l|`F9SqA6&s0V$cxi j;LxzB<%q=>V_}A`|9EChw@f<*G>^g4)z4*}Q$iB}_R1%Y literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolButton.png b/wxPython/wxPython/tools/XRCed/src-images/ToolButton.png new file mode 100644 index 0000000000000000000000000000000000000000..53af75933cebbc8ff2df03ce37fd3d1dea8e3f28 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1#!3HFGRQ68=Qnj8gjv*Cuj!tppI-tPAqJH%H zmH+c=T`xVqF}c;Nw^eG_gM%#P9y}AHvQ<5loR~HoUL=tdcx>sE2#3ksC#v_&wR?Vd z_N4T6%P!9lZ)es0bjF_9EjN-aAo$7^*1y)S`A<U)=PX+8elNYxgyjs+@0c4i&Xt5- iC_A3TDX?uFqu<6=hANqbFMELwVeoYIb6Mw<&;$T=twx0a literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolCheckBox.png b/wxPython/wxPython/tools/XRCed/src-images/ToolCheckBox.png new file mode 100644 index 0000000000000000000000000000000000000000..d27aa264a99b74ed9be14317c89256e4970dc532 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4*?77*hE&WsJ7FU)g96WCnJfR} zUx^p^&9GWjb|jchJ4osFGDjiC4d>s*gsG=I^N}&HQ*djI`tIaVZE=7#vX4h7FMsPs Ppg9blu6{1-oD!M<NX;Z{ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolCheckList.png b/wxPython/wxPython/tools/XRCed/src-images/ToolCheckList.png new file mode 100644 index 0000000000000000000000000000000000000000..5167d327dd2d74f423d5c1092d47d01978fbbd4a GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz98$4YcLn`K+o#H6epupj}^y5Em z>!>oBs2c_>@t2Od)-PSruRk&5+oWk3oE<Ya_t*u$iVXIe%_k@*IJ4I7#rFt-EoK?l zntYrxCd{mrX-J8;Hcn!1Zh5LH^ktb5OK1IwCU=GtOGKwVf5ov*Q0Dk1g&#Ak0%T9_ zZH)}(5Aa^s{b;#u)s>qc^n9IpfBNp|uj1meXXmQQx_R|qyz=MbmrHjT=Lb}m_g9^` h;h+5UdPwswh8-#GTaUdutO#^FgQu&X%Q~loCIBo}UIzdG literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolChoice.png b/wxPython/wxPython/tools/XRCed/src-images/ToolChoice.png new file mode 100644 index 0000000000000000000000000000000000000000..e14b46de70d2dc8d3339a381e4831f15224a4d8e GIT binary patch literal 193 zcmV;y06zbTP)<h;3K|Lk000e1NJLTq000;O000mO1^@s63?#pm0001pNkl<Zc$~eI zOA5ds3`A#&m#N-=?J2a!u`7$eScRr<BZQF2SEiH_lpqNM0P%`i8aT89d++B0&bm*8 z)GElBk<nR)5X1A9*wc!^NOt~1fj4%RqH9r^b*^HCJk%DkMPE?~jCwBFrHrQnE0Ems vuLMTfw|2=#Lj4Z@JG9lI?Lq)*-!%Z-oR~1Gk(XuR00000NkvXXu0mjfU=vRQ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolComboBox.png b/wxPython/wxPython/tools/XRCed/src-images/ToolComboBox.png new file mode 100644 index 0000000000000000000000000000000000000000..3f6c5a1367283ecac7c33ff271cd56529f2773bf GIT binary patch literal 233 zcmV<F02cp=P)<h;3K|Lk000e1NJLTq000;O000mO0ssI2gGMOA00026Nkl<Zc$}@1 z!41P83`M^ymI<pQ?IO)O=^$0^o+4x%_kc=?agiJKACNHc_}GTl=ZfzduVZJmh=>A! z={A|mA_5@o$-@funR8-h0GHF}l{AQm&VhnwQygL&Tpr7OpSQFbAR-cxJl65Fr#Qqq z>&#qJ;LlNJm8qf}K*dNl)q&<RDIFZqTOCvFqq2gs(;8GPlcF7YWKuq$_VQnQ{coM^ jYDlw82B`B2|BrbANE29Ehzzd|00000NkvXXu0mjf#8hCJ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolDefault.png b/wxPython/wxPython/tools/XRCed/src-images/ToolDefault.png new file mode 100644 index 0000000000000000000000000000000000000000..479a4ca2e295c81b80653a69b75a946f29d20ce8 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DVAa<&kznEsNqQI0P+JpT^vIy z<|K;<2qY|EF$i2TTZ(PN0`5H(pC8%l9hK3M;bCH8>Z#yO0D>KbkJ;L8G%~Yqkh1!a x=<wGeCE>u^_(ePq5*{j?WbJXbR}IQxV7SA;J-;_9^dHc022WQ%mvv4FO#nYCEe8Mq literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolDialog.png b/wxPython/wxPython/tools/XRCed/src-images/ToolDialog.png new file mode 100644 index 0000000000000000000000000000000000000000..af63e8455537f10741a93f18ffc23302a7a5ad5d GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<a>I$IEGZr zNlr;f_;KEWF`+TQ{=}7Y2M@S(zUATJnIe7QghQ{vj)JF5k+XP9c-R~zdQ_PCWGoz{ q#WzeylD^1hVPPSV%W%|FlHr*qPxAgbXBGktW$<+Mb6Mw<&;$U!hAM0T literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolFlexGridSizer.png b/wxPython/wxPython/tools/XRCed/src-images/ToolFlexGridSizer.png new file mode 100644 index 0000000000000000000000000000000000000000..c29ce68d1d22fc95c8cf89c8434b6d1580d5dbfb GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<U4t~IEGZr zNfr?hNZ{b${BhnvEuqoSY|YIB9Xf&nLLcN~d1P5ySpK9dT~Cvcs9=_GXD+<LkR{<z h=#&K1v)}|P!xn9^UGtvzy8%sO@O1TaS?83{1OR;EBsBm4 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolFrame.png b/wxPython/wxPython/tools/XRCed/src-images/ToolFrame.png new file mode 100644 index 0000000000000000000000000000000000000000..87c7d4d93e7a530a1cc53c37f781baa58d4317cf GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Xd^VIEGZr zNlr;f_;KEWF`+TQ{=}7Y2M@S(zUATJnIe7QghQ{vj)JF5k+XP9c-R~zdZY|=cotY_ aGBZp_W|!YwS>^^bg~8L+&t;ucLK6U5`6R;t literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolGauge.png b/wxPython/wxPython/tools/XRCed/src-images/ToolGauge.png new file mode 100644 index 0000000000000000000000000000000000000000..b530de509507e35804ef5b6e0537d76ed4e96aff GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^5<twy!2~3C&GOa+QX!r$jv*CulIIweaxsT8g!26Q z|KFZ_POIkG6DKOZ-U?MZo7A}Z-u^oO&c!ndJacaE?X_Z?$mPbX#1k>Wa>+3fv1SQL qNzEeuI|`424eXjXJmU{yWC&d*vE|W1%jrP#89ZJ6T-G@yGywph^)C4U literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolGridSizer.png b/wxPython/wxPython/tools/XRCed/src-images/ToolGridSizer.png new file mode 100644 index 0000000000000000000000000000000000000000..c56ba9a4ca5d45e89ac7f544779c0b3f5a5aae22 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<lA_<IEGZr zNfr?hNZ{b${BhnvEuqoSY|YIB9lnkZ9tY}cihQ2j;$dFQW?*2@=k~b3py5$Q3Q+Ze b6RZrrGsJe)_@7|{n#17f>gTe~DWM4fEz>0< literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolListBox.png b/wxPython/wxPython/tools/XRCed/src-images/ToolListBox.png new file mode 100644 index 0000000000000000000000000000000000000000..495456d6007cc369c8b73e9f3da89fca1bebbd13 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8gx!2~1=@63_`QuUrLjv*Cuu1;~}I-tPAQr`XF z{^t6d&zG<(itq|8ZZ%WyOu5^mcqaW=l8#r0$EDx}`(juRB;K3&h5M#ZaH7Wq5yAZv z#bZLa8UDBh&7YNY(`!Ym<Ffv{I=|R$m9KBAXe#Ji(-^F6tFWQ<=!@X`t0&AOS*~5* j=k`jh$NNax`eVEwHSM-KHQhV`bP9u~tDnm{r-UW|d&);V literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolListCtrl.png b/wxPython/wxPython/tools/XRCed/src-images/ToolListCtrl.png new file mode 100644 index 0000000000000000000000000000000000000000..a84f8c90d817be1e19bbe0435bd36d75f2ffa097 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^Vn8gx!2~1=@63_`QhA;(jv*CulIIweaxu3yI4S@8 z|NlHw`ox9*Z+*??;o<R_V!_B1ap6aggcgTYKi4`5Qzpg>$t^uk3@vP$E_1l)tn3j{ zR`}Iv!rCo(!m87-l`XL`Q`fQmf=cGZIXl?gFEv%M1aVEuXQ@op2in&>M|4k)@s`6t Pn;AS^{an^LB{Ts5WlT0` literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolMenu.png b/wxPython/wxPython/tools/XRCed/src-images/ToolMenu.png new file mode 100644 index 0000000000000000000000000000000000000000..b081f7b1d443cc5f6dff9534e26044e9fea71776 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<i~otIEGZr zNfr?hNN8vj&yV|)uE12Vp}+vB#K6eFz+l4y?|VB6nb$vKX6IY*!I0;`G7dHw85x5k zGd@JQvn;s5uqN)nvye$V61>e94Gui5U&Qku;h}=3F*6V_<SZ52mzYy*3$%#A)78&q Iol`;+0JvT-+yDRo literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolMenuBar.png b/wxPython/wxPython/tools/XRCed/src-images/ToolMenuBar.png new file mode 100644 index 0000000000000000000000000000000000000000..c2938a0019727bdbd1a6b901eb236d5c03de9592 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<R^K$IEGZr zNfr?hNLavP5V)i|K;poU$LIV1KgoKQ@Gv1EF(DygN8w|(le73`EDitxgCRpCgQSIp z#RHM{#zuaZ9pV$_w(=Bo9_F24n9Sy?mynW>pkOT}DFFoTpP85$T>OP6FMl1F4YZBH M)78&qol`;+01D7FWdHyG literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolMenuItem.png b/wxPython/wxPython/tools/XRCed/src-images/ToolMenuItem.png new file mode 100644 index 0000000000000000000000000000000000000000..f94f622c6bcf46cc62aa9346eb01d22d27e7bfe2 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CJ!3HGRcAO0XQhuH;jv*CulK*^se!QMdiIJU~ zotc}NnfY+9v^j^CUBLqeAcvV*c;m9e4BTeH7aE(JndkU!;+<m2c{6K|RKZSJ>4cPo f1O+QO2_Rs|h~~e)`?Js&pverLu6{1-oD!M<aN;C! literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolNotebook.png b/wxPython/wxPython/tools/XRCed/src-images/ToolNotebook.png new file mode 100644 index 0000000000000000000000000000000000000000..bbb372eeffb064a87742cfff374af8d5b063c03a GIT binary patch literal 253 zcmV<Z00RGsP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0002QNkl<Zc%1E( zO%4Jf4253}ml2LIiB~7l%y@#q<J1LV<kz8NaAEv5gr@Yhr2zr}W@dCiMAYLKqnMf9 z!}a<z0FlV4W;EIqHfya{*dafsB-sGKa$ELXk}3-UqYYNKZflL{G9~-@I(zYZDK4%c z4;lpHeN1u(an_-VPpP)3hqz6x>=S`j&s+9GEgHcl(3+T*y_dsNB)$U)?*itK@GXKq z>;B+G@(Lu$00XBeJdWQR)4#y)3Mk+;QX?SvKXe#Rc>i!;_L~&$00000NkvXXu0mjf DK$B^y literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolPanel.png b/wxPython/wxPython/tools/XRCed/src-images/ToolPanel.png new file mode 100644 index 0000000000000000000000000000000000000000..5e059e5f915d268a48aecb5d1993b49205615dee GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DVAa<&kznEsNqQI0P>wZT^vIy z=DfXZ$k$-N<9soE%EIsVfqfGfmpC+W8VVbJd;c%)&Bk-3nMTQ6D^{I<c!tG&``<+F mZ4bm9Kb+fi*x|QN0rR^e9@U&ZoMu4d7(8A5T-G@yGywo+TrQ&k literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolRadioBox.png b/wxPython/wxPython/tools/XRCed/src-images/ToolRadioBox.png new file mode 100644 index 0000000000000000000000000000000000000000..82588252fc495394c4cbafe45e91823ee18a22d8 GIT binary patch literal 296 zcmV+@0oVSCP)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz0002*Nkl<Zc$~GB z!3~2T6o&uTIDm&vW8y+`l{!P?Rl86VH)yBuzy`0ELV$`W&_6K(%J=bN5Fj2t@J=w7 zoXI7^-u-l{X`Y<Pq7xt@+O;zC{FtL~(Fs(#p<}@rfNqoBCn93zLsgk?K;QU_wJs+V ziLS5;i0#!M8IM=+uY?3<mE(Qnt?^ue1NS6l1R5#_>GX>TZ20T_%98vDd^mtCi6hv8 z>!eDYeIN%(%*_3*$MRfIUu*MBtqOYc#(pKi3hc>E+d!?#z?-%?4c`=ONmAiKfiFpg u?+R>aDm*I4g#!Tj2TsX|PT=stk(v+XvT{cB-x^{70000<MNUMnLSTX@r-Qlx literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolRadioButton.png b/wxPython/wxPython/tools/XRCed/src-images/ToolRadioButton.png new file mode 100644 index 0000000000000000000000000000000000000000..a0fa275ea48a5011a8a57dcd29d347ccfe15fc5a GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqh{hlt4Ar*5<&mZJ$F%W2dXutA6 zvv1BDg#_k9)0Cr|m&{?6j@Z!L>09B!{!UXUJ^j9F;*Yo)7AKp|{fayP($doQyI9Wo z{X3d|nkI|xVO8yp{2<11rpep;S7UCQ!Gvin4U=_R+$|Wlop-xlF0SLQ*eBSqC;j<r yR)xNaMIyrY>{f6~#bs|<shwF-9m&kgxUZc(`50^70z;tF7(8A5T-G@yGywnsf=P)0 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolRoot.png b/wxPython/wxPython/tools/XRCed/src-images/ToolRoot.png new file mode 100644 index 0000000000000000000000000000000000000000..ea5cf2e074e9ec50cc68bcfaea4fd15c4fd18441 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DVAa<&kznEsNqQI0P+((T^vIy z=DeMJn)iSKhx5W$406qXmnZU=dE|E}bx0Mi&9BM%sMN}M!KM7F$!5`PhC6H>C$b|$ zZ$I_oX>duIEA_W2Z-U_>rAh2AQzmEID9kS74`)mH%W+?@;+OckiL*Q8b_r=2t+wTS Q3ABvC)78&qol`;+0K>#LFaQ7m literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolScrollBar.png b/wxPython/wxPython/tools/XRCed/src-images/ToolScrollBar.png new file mode 100644 index 0000000000000000000000000000000000000000..a324aebf15c5c6b40d62aceffa81e06a2462446d GIT binary patch literal 254 zcmV<a00IArP)<h;3K|Lk000e1NJLTq000dD000;W0ssI2u9Dyb0002RNkl<Zc$|%r z%?*Sg5QS$9&8#J0+=P18MmAot9uo<afKBYd4%h<;j?74WCw@MLc@J>@&hSJ}xRjF0 zBft5wsz)7MsL-yO>rux&4)3AGWe5Q5Vk@-c5C9lsDpb)!>$={0$$nExcYxpg={LAQ zEpw^ToVbmM`TW^mF(InXkBZuAaYBE*fXpG{qk8R707%YUcCo;7rth13ojy~!=kyy~ z=wE%AQV8yH;l?jqE?M0u*Nc1PkiZ?kL(E7)^Yaz`0mZC<`L12jNB{r;07*qoM6N<$ Ef{=}I>Hq)$ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolSeparator.png b/wxPython/wxPython/tools/XRCed/src-images/ToolSeparator.png new file mode 100644 index 0000000000000000000000000000000000000000..c09c946e34f2da6aee630cae8397ee0bc1feaa75 GIT binary patch literal 80 zcmeAS@N?(olHy`uVBq!ia0vp^d_c^^!2~3qzo_~Pq{Ka4978JRB+oG_<zg08u-2Z< d>Lj>Wis82mi?hTDp%XwQ44$rjF6*2UngEQ{5|01? literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolSlider.png b/wxPython/wxPython/tools/XRCed/src-images/ToolSlider.png new file mode 100644 index 0000000000000000000000000000000000000000..439c2e74b0d49c9bbe420a359cb7964b11f7c87b GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^5<twy!3HEvf8419QVpIijv*Cu?oK(#*<irq8h>OZ zi}<GWLbk#c4Hra9=2U!8SdroN_GrD&?Eg+bSNc3o5eebFz+Wp^Y<!!Mp|H;+_i>hp z;3JvX^4G<Qk>c+g^g{jHS9Pt5%bL%~;3PhYXENi?UzQ5r|2|Y(R-mG4YPg<3@T6G{ jOT~6$$%L?X`)@N?*eiaLTQxfq=oSV~S3j3^P6<r_dQ(Fj literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolSpacer.png b/wxPython/wxPython/tools/XRCed/src-images/ToolSpacer.png new file mode 100644 index 0000000000000000000000000000000000000000..e1721984cbdc9b71f9379bdee8927d88c14f6895 GIT binary patch literal 229 zcmV<B02=>^P)<h;3K|Lk000e1NJLTq000mG000gM1^@s6CNG?d00022Nkl<Zc$~G7 zF%H8Z3`M^q26w2$K|AC)9EW4%2pKwfsp?7yx`0GYl_*N<#WLS~o(*~LaVDlyw|`;a z?16|BO-k&z&l5Y&wLf|9sr8fH!Fpe@EK4gd0A2ucj1lu~hV36lV8^8^p8#@CEF!%= z8fa1iKvg3nf8cKsl=^b9x+NHvs7YN2;R@hU4cY|)0820!u;cUvotlw|l+9l_8p96S fjC=Wi1V`fy^v6)VLzVbk00000NkvXXu0mjf^(R<C literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolSpinButton.png b/wxPython/wxPython/tools/XRCed/src-images/ToolSpinButton.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2290fd02224b7e3c37539ca69d821e83b30076 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^oIotV!3HFcc!W9wsSHmS$B>FSYbPA!Z7|?r*6+wn zFtPHRu{`>K#WUxnTbQ~8zHjjh%=yuzvi0T#uG{+<Uj%V6?W<Ca(iSN?w?vikhQwiO zpGjxdM88n~(y(67Vg0ShJrYMNXFZ&=BFZMN^3VD|7vEkI*0W?ddOBg!Jl8$`Ksy;c MUHx3vIVCg!09;Bv3jhEB literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolSpinCtrl.png b/wxPython/wxPython/tools/XRCed/src-images/ToolSpinCtrl.png new file mode 100644 index 0000000000000000000000000000000000000000..84d9b1775c9f735fd46e0419c8a9c1822145cc22 GIT binary patch literal 308 zcmV-40n7f0P)<h;3K|Lk000e1NJLTq000;O000mO1^@s63?#pm0002{Nkl<Zc$}@2 z&5eUF5QV>4Z2=t8#HIuzBDo%14s1I}i{cJ&n#h3;W)Hy@VSxpbCvox5`<QvQrK&6C zn8aH9@1jotSGrx!s*iv2t$!Lfg;C#n$xa#ly$9f9ylKnVg>DvV3Zvl`$S=9}_nz#O zJp*1*GzX~aDnV8OBC^{Yz*?IiFl2DlJgRA$#kpC4s&0aq!syz%{F3V|V2g&f$WrK0 zZwYx#hbuULodFgvY5iT}N_QLp;9D=#Qv{FDUFo>~T;=5!`PR!&O;R+6l?>u@uvgO~ z`<9Sn730>#xs<`Qk9!qvL0su{Y@Pr|+YukMs4jGWZrv{?G>=i^)myay0000<MNUMn GLSTZw*N5i- literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolStaticBitmap.png b/wxPython/wxPython/tools/XRCed/src-images/ToolStaticBitmap.png new file mode 100644 index 0000000000000000000000000000000000000000..237c6db2dc3fc7a3334d0ab13b4ff981c3f5da47 GIT binary patch literal 576 zcmV-G0>Ax<P)<h;3K|Lk000e1NJLTq000gE000pP1^@s6?Z};<00069Nkl<Zc$|Hc zF=!J}7{`AXZg>HQJIHXiwSz;_$!;w;G@VSl*y5t#P{~rUOR{L<78Hdn+A0*Ii*c}Y z?0Ox72`Hw6ygPAdmcrdo$bp4>!@)U(J5w6{Pw##2`~Sc1{lE7#=}M+iDwYyv!1Y{h zdY_vnq@?I~#PHjY@p$}C!Q6DP-|JJ~d4M|Kqi78v=x}t<<lg<YD`ZW&l2Wmh^m~15 zOJLw&TFZa|YCse#!t*ip=N{cp-K_0gs?vVl#?l?kLK*aV&`r2jA+HMz!=zEQ*}T1( zwW_C!TD1ZK5cVVxD*&Qckk=JvL1367YdJGVDU~II0No%`6LTU2=mOhF&mouE+<J8g zaRexcLr^1#{fSttP+>^-z_~h(&VC0KGa>7ONR5CHVnq=6jLyciUhHP(WOo!oAd~{~ zL>D87LzEih2Lb9LqV>kZIqqCG$Msxo?`=Cd892;eAF%s$g)j^mo%u9hI+%qL&T&7h z27q)W(v_f-Y}~0N(v`{guV0eN`btuJbT>Kub(*9|bEPZ)j$>oJ!r|v5h9^VnPns;= zSfuf|foYmo-f3peYI!wzxKm^8R+&N1p;#=^`Ov`+d~FsfBL+c0>sgcS?HWrr%XmLL z48xd}pFvB%)k0|@nVYk)Et}<~GF#QHnUyZNnnEds_tWFu`;Y%60sH~F(E5?T$1kk_ O0000<MNUMnLSTYvVG;}g literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolStaticBox.png b/wxPython/wxPython/tools/XRCed/src-images/ToolStaticBox.png new file mode 100644 index 0000000000000000000000000000000000000000..1e99f0a2812cc4ecd380e9f3efeae7ecd41224ac GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1*!3HF6)y8xHsTNNc$B>FSZ>M_mH7M}7Shroi z^t$7^ta(zyk{S{7w&?;~3+HA=ge>8;zBeN$e^UB^B>7`+6VFe&x|+cubZUx))8-vj zqT<aSL35OZl9!}2DBQey^)LGljk9Xn%)CkM=LG!je!sKb`UjWyfg;N%`_v42RX4Cq oJ0Q;zz&B^+itv|mGX9o~Cv#Q2JS5V70o}vk>FVdQ&MBb@0Gd)oBme*a literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolStaticBoxSizer.png b/wxPython/wxPython/tools/XRCed/src-images/ToolStaticBoxSizer.png new file mode 100644 index 0000000000000000000000000000000000000000..1ebbbeb6c81509c3723c4b825ae282ec4e387341 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<fnMLIEGZr zc{|CG>wp0Vi|G@_-zNNa#_aQ-@xKYx+2R@eVrj9Un2gv&#tVFF+1|<Zv%ZsKsBpd1 z+2Nv^BXON=QIYm5(-XWo66uw$A&ag)wMn;-Eu0$vp{aq<$M($9g!cFO1q^;dD(R{v S)(?U9F?hQAxvX<aXaWHA=Qfl8 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolStaticLine.png b/wxPython/wxPython/tools/XRCed/src-images/ToolStaticLine.png new file mode 100644 index 0000000000000000000000000000000000000000..d528076358b8192df456db3c9831201c0ddc3922 GIT binary patch literal 82 zcmeAS@N?(olHy`uVBq!ia0vp^B0$W<!3HEF*#2|_DM?Qk$B>FS$#aZKPt~(&HNIJs f!zL!t9L2y;^McjM!RSOSP!WTttDnm{r-UW|yDAhv literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolStaticText.png b/wxPython/wxPython/tools/XRCed/src-images/ToolStaticText.png new file mode 100644 index 0000000000000000000000000000000000000000..92ee2e0b320fa805f7309c8e07888a9a4a8b3c20 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^VjwmL8<1SPbY3!$%Jp<{45^rNHQ15sfC0zljn`-V zw?A69+?sRU5hwFg5qWO2T^7DNo66p&yJ|ki;S1?slOJwhaLAw}f1Qph&)i(&BJa+_ z2D6R&xQ;LAIAI}E(|X5#b&B?EgF7w7QE4GxZ&uIR;bg~a9d35@e(g){TydXSC1)>B Q09wr8>FVdQ&MBb@0MD&JtN;K2 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolTextCtrl.png b/wxPython/wxPython/tools/XRCed/src-images/ToolTextCtrl.png new file mode 100644 index 0000000000000000000000000000000000000000..f467e531f0a59426272fa345071f0b2d94173a32 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^5<o1#!3HFGRQ68=QXZZzjv*CulIIweo~mb)ViIFx zV{4o9MrM}8zyJU1J6H|)Ob>2-eO&?sW~|845;Mp;xPo=D7!N!5gH*vaZx(d2UeS9o afssMUNJ!;Y?+Z?#nGBw;elF{r5}E*Y7AA@S literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolTool.png b/wxPython/wxPython/tools/XRCed/src-images/ToolTool.png new file mode 100644 index 0000000000000000000000000000000000000000..500d42359ce5d99bccdd38ab69fc5885349f3412 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1SIo6Pjm-TcAhSdAr*6y|9pJT&TMwz;Gu(u z4jd?We2mwmlbM~*00<JVvM}moWJyX$$jHbj@YMY3Fc!`e>5{plCd9yybe#9W&b{qQ QK$93eUHx3vIVCg!0A?~G$p8QV literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolToolBar.png b/wxPython/wxPython/tools/XRCed/src-images/ToolToolBar.png new file mode 100644 index 0000000000000000000000000000000000000000..f6d0fe6809026319925e57a173f5af58b484d495 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQaPS3jv*CumQLKr+hD-M!at=c zFead)rDsOdp~opbJx+}*p-haO9R*X*>qk$sS#x{W<&#g;WE{L+elF+{Y%nxW2}`*q z)S;oYe6>c^$1^AVWAt)3LleTPcl=Cl{JxJXDo$)h<mWTyYzuz(GO$}sl=*o24ciu= Oy$qhNelF{r5}E*H>OB_# literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolTreeCtrl.png b/wxPython/wxPython/tools/XRCed/src-images/ToolTreeCtrl.png new file mode 100644 index 0000000000000000000000000000000000000000..bf90ad53bff0d00f0108ff3859569f2ed6ac604c GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|sYFi~$B>FSZzrGTJz&7$yzmu+ zT=U=Mi9BW=`5j6fQiW^tYjQp+wK86CDZgs6Su~sB4qL~G?8wmDPrY~=TvFyr{cXyd zV7N$W61&Tk$=Nmvv&;Cy*;4*;+!w6)CBAOr><+nILRv<vZ8={8Eo1O>^>bP0l+XkK D3QIIf literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/ToolUnknown.png b/wxPython/wxPython/tools/XRCed/src-images/ToolUnknown.png new file mode 100644 index 0000000000000000000000000000000000000000..5872a0556273565b814f476446ee5848d67d8a59 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|5uPrNAr*6y6BGmuj0_B7_Lfcc zxOyw<mQIB0!yKQ@Gd`?1_9W>dgSo_X>y6n5m@oWwFkmRS#ZYLQ=&!t5?JV1xW5O32 tL=!qKV$vROc8vCxo^GD;US$#^!(@M{CF!T`eFWOU;OXk;vd$@?2>@MyG5Y`j literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeDefault.png b/wxPython/wxPython/tools/XRCed/src-images/TreeDefault.png new file mode 100644 index 0000000000000000000000000000000000000000..479a4ca2e295c81b80653a69b75a946f29d20ce8 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DVAa<&kznEsNqQI0P+JpT^vIy z<|K;<2qY|EF$i2TTZ(PN0`5H(pC8%l9hK3M;bCH8>Z#yO0D>KbkJ;L8G%~Yqkh1!a x=<wGeCE>u^_(ePq5*{j?WbJXbR}IQxV7SA;J-;_9^dHc022WQ%mvv4FO#nYCEe8Mq literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeDialog.png b/wxPython/wxPython/tools/XRCed/src-images/TreeDialog.png new file mode 100644 index 0000000000000000000000000000000000000000..af63e8455537f10741a93f18ffc23302a7a5ad5d GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<a>I$IEGZr zNlr;f_;KEWF`+TQ{=}7Y2M@S(zUATJnIe7QghQ{vj)JF5k+XP9c-R~zdQ_PCWGoz{ q#WzeylD^1hVPPSV%W%|FlHr*qPxAgbXBGktW$<+Mb6Mw<&;$U!hAM0T literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeFrame.png b/wxPython/wxPython/tools/XRCed/src-images/TreeFrame.png new file mode 100644 index 0000000000000000000000000000000000000000..87c7d4d93e7a530a1cc53c37f781baa58d4317cf GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Xd^VIEGZr zNlr;f_;KEWF`+TQ{=}7Y2M@S(zUATJnIe7QghQ{vj)JF5k+XP9c-R~zdZY|=cotY_ aGBZp_W|!YwS>^^bg~8L+&t;ucLK6U5`6R;t literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeMenu.png b/wxPython/wxPython/tools/XRCed/src-images/TreeMenu.png new file mode 100644 index 0000000000000000000000000000000000000000..b081f7b1d443cc5f6dff9534e26044e9fea71776 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<i~otIEGZr zNfr?hNN8vj&yV|)uE12Vp}+vB#K6eFz+l4y?|VB6nb$vKX6IY*!I0;`G7dHw85x5k zGd@JQvn;s5uqN)nvye$V61>e94Gui5U&Qku;h}=3F*6V_<SZ52mzYy*3$%#A)78&q Iol`;+0JvT-+yDRo literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeMenuBar.png b/wxPython/wxPython/tools/XRCed/src-images/TreeMenuBar.png new file mode 100644 index 0000000000000000000000000000000000000000..c2938a0019727bdbd1a6b901eb236d5c03de9592 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<R^K$IEGZr zNfr?hNLavP5V)i|K;poU$LIV1KgoKQ@Gv1EF(DygN8w|(le73`EDitxgCRpCgQSIp z#RHM{#zuaZ9pV$_w(=Bo9_F24n9Sy?mynW>pkOT}DFFoTpP85$T>OP6FMl1F4YZBH M)78&qol`;+01D7FWdHyG literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeMenuItem.png b/wxPython/wxPython/tools/XRCed/src-images/TreeMenuItem.png new file mode 100644 index 0000000000000000000000000000000000000000..28b3f6a5f522ce05b217174650a24a47479a8196 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|sUS}m$B>FS$q5n}2RM@d{P_IX ze&Z~Q2#W_*krPz&?(A?3_}s|M9`M8G$gM8!4GF?7+gaIUWMmAEXp}ML?rAu?(nYf2 n^!pzS%0jbWlr*@$4`5^PZQy@6W6h;<py>>ru6{1-oD!M<Z7nbd literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreePanel.png b/wxPython/wxPython/tools/XRCed/src-images/TreePanel.png new file mode 100644 index 0000000000000000000000000000000000000000..5e059e5f915d268a48aecb5d1993b49205615dee GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DVAa<&kznEsNqQI0P>wZT^vIy z=DfXZ$k$-N<9soE%EIsVfqfGfmpC+W8VVbJd;c%)&Bk-3nMTQ6D^{I<c!tG&``<+F mZ4bm9Kb+fi*x|QN0rR^e9@U&ZoMu4d7(8A5T-G@yGywo+TrQ&k literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeRoot.png b/wxPython/wxPython/tools/XRCed/src-images/TreeRoot.png new file mode 100644 index 0000000000000000000000000000000000000000..ea5cf2e074e9ec50cc68bcfaea4fd15c4fd18441 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DVAa<&kznEsNqQI0P+((T^vIy z=DeMJn)iSKhx5W$406qXmnZU=dE|E}bx0Mi&9BM%sMN}M!KM7F$!5`PhC6H>C$b|$ zZ$I_oX>duIEA_W2Z-U_>rAh2AQzmEID9kS74`)mH%W+?@;+OckiL*Q8b_r=2t+wTS Q3ABvC)78&qol`;+0K>#LFaQ7m literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeSeparator.png b/wxPython/wxPython/tools/XRCed/src-images/TreeSeparator.png new file mode 100644 index 0000000000000000000000000000000000000000..3f31752f12acbd1b4ce6e9c86173d2c3bcc82378 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|DLqdY$B>FSZ%-fO1xm6U-08A) zi}PNS2M^VSKHt^3U)yMBb>{NQt8AW&at?i;!}@a}tDEMU+ed&p89ZJ6T-G@yGywpV C{vt>K literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeSizerFlexGrid.png b/wxPython/wxPython/tools/XRCed/src-images/TreeSizerFlexGrid.png new file mode 100644 index 0000000000000000000000000000000000000000..c29ce68d1d22fc95c8cf89c8434b6d1580d5dbfb GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<U4t~IEGZr zNfr?hNZ{b${BhnvEuqoSY|YIB9Xf&nLLcN~d1P5ySpK9dT~Cvcs9=_GXD+<LkR{<z h=#&K1v)}|P!xn9^UGtvzy8%sO@O1TaS?83{1OR;EBsBm4 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeSizerGrid.png b/wxPython/wxPython/tools/XRCed/src-images/TreeSizerGrid.png new file mode 100644 index 0000000000000000000000000000000000000000..c56ba9a4ca5d45e89ac7f544779c0b3f5a5aae22 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<lA_<IEGZr zNfr?hNZ{b${BhnvEuqoSY|YIB9lnkZ9tY}cihQ2j;$dFQW?*2@=k~b3py5$Q3Q+Ze b6RZrrGsJe)_@7|{n#17f>gTe~DWM4fEz>0< literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeSizerH.png b/wxPython/wxPython/tools/XRCed/src-images/TreeSizerH.png new file mode 100644 index 0000000000000000000000000000000000000000..b51e6f59ab87123901dd73f9a6c93b6530ece69f GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<hyvfIEGZr zNfr?hNLavP5V&Nv6x#*^AYf@>`Lp~40~;G#8*jFmK~k`QfY1l|`F9SqA6&s0V$cxi j;LxzB<%q=>V_}A`|9EChw@f<*G>^g4)z4*}Q$iB}_R1%Y literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeSizerV.png b/wxPython/wxPython/tools/XRCed/src-images/TreeSizerV.png new file mode 100644 index 0000000000000000000000000000000000000000..295f1be910bffc0750e888305e018fd2afeb4794 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<lB3?IEGZr zNfr?hNN`|dRAl@w$<e@@ZDw%jhE9vf0_GC#85}p=IC`WSl*Kwaz4oy6xGB%&U0@+4 ed2zGxN(Kfs9)aA5lBi~&Q4F50elF{r5}E+Ysv*t* literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeStaticBoxSizerH.png b/wxPython/wxPython/tools/XRCed/src-images/TreeStaticBoxSizerH.png new file mode 100644 index 0000000000000000000000000000000000000000..1ebbbeb6c81509c3723c4b825ae282ec4e387341 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<fnMLIEGZr zc{|CG>wp0Vi|G@_-zNNa#_aQ-@xKYx+2R@eVrj9Un2gv&#tVFF+1|<Zv%ZsKsBpd1 z+2Nv^BXON=QIYm5(-XWo66uw$A&ag)wMn;-Eu0$vp{aq<$M($9g!cFO1q^;dD(R{v S)(?U9F?hQAxvX<aXaWHA=Qfl8 literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeStaticBoxSizerV.png b/wxPython/wxPython/tools/XRCed/src-images/TreeStaticBoxSizerV.png new file mode 100644 index 0000000000000000000000000000000000000000..805c87bbc0467680b23f61c9098af7cc51b5db4d GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Y#!gIEGZr zNfr?hNI1Z1SM%dTyn{o7;BqE5Ha0b<S@uAI`6|pzPD~G^CYZ9fu>5IHToiKv2pZn} z;mtNP$cxy_c-Y#4w;@x_nx}*H@Bs#~oTe9nuA3NdEaIO2kXfFMIiKO^Mh1qDw^V`+ T)C`z`b~1Rn`njxgN@xNAerYw- literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeTool.png b/wxPython/wxPython/tools/XRCed/src-images/TreeTool.png new file mode 100644 index 0000000000000000000000000000000000000000..a52b4962671d7cbbe9390f00fd0e8b3a506ea065 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~i!3HGN^yhQ|sSr;W$B>FS$q5pl8U$k>9G@@$ z|6}HZgoh3nk2m>V?3Fg(kY!i!fT2x7IPSY3<Az-fvwQjY_#&<bykWXk#W;O4r&NRP qmO{p!k^=`0G?>dixM=Rc!0<+v|6%^amK{Lz89ZJ6T-G@yGywql|1mEB literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png b/wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png new file mode 100644 index 0000000000000000000000000000000000000000..bae7ec3efc30dc5f1065840bed645deaa61edbab GIT binary patch literal 194 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<X3vSIEGZr zc{|yfuR%e;MZT?RQgT2<K}_FaK@A;?uGUU51w*wTjmHkXlrxyjIa@R;yUL_wr@f%U zv(&igvtC*%4m}^Y-mK=Iz{GGSBUnpdS%cxs)TG%n&+Ojye}PHBa&FaZeeL7Nqx^TU oSUk`3it}bTo6I8cUvC4W!z`K3h#L%BfR14BboFyt=akR{09}DVZ2$lO literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/src-images/Undo.png b/wxPython/wxPython/tools/XRCed/src-images/Undo.png new file mode 100644 index 0000000000000000000000000000000000000000..f030cedc1769d5a516c1015e95b3a510737aec0f GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^;y^6M!3HF?%h*|g6kC$Fy9>jA5L~c#`DCC7XMsm# zF#`j)5C}6~x?A@LD9B#o>FdgViHA{?S$5Bg!-+tlT2B|pkcv6U2@<Tze1Fu#m4(;x zsHOb)pU2MGmL|<PL)E~?B;iQ9fjT$);qUhL5+G3bCo$p2hvvqG-_LM6RdGu3ZEt97 zY+U$-;f_OFl5mH_6`>}v2h2B`9@S52V>s#9a-NCDFe|FzbkLqQVXrP`whSqi#R(z- bf(#5L*6LS|%+`1TbO?i|tDnm{r-UW|sTNA+ literal 0 HcmV?d00001 diff --git a/wxPython/wxPython/tools/XRCed/tools.py b/wxPython/wxPython/tools/XRCed/tools.py new file mode 100644 index 0000000000..718385ed99 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/tools.py @@ -0,0 +1,279 @@ +# Name: tools.py +# Purpose: XRC editor, toolbar +# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> +# Created: 19.03.2003 +# RCS-ID: $Id$ + +from xxx import * # xxx imports globals and params +from tree import ID_NEW + +# Icons +import images + +# Groups of controls +GROUPNUM = 4 +GROUP_WINDOWS, GROUP_MENUS, GROUP_SIZERS, GROUP_CONTROLS = range(GROUPNUM) + +# States depending on current selection and Control/Shift keys +STATE_ROOT, STATE_MENUBAR, STATE_TOOLBAR, STATE_MENU, STATE_ELSE = range(5) + +# Left toolbar for GUI elements +class Tools(wxPanel): + TOOL_SIZE = (30, 30) + def __init__(self, parent): + if wxPlatform == '__WXGTK__': + wxPanel.__init__(self, parent, -1, + style=wxRAISED_BORDER|wxWANTS_CHARS) + else: + wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS) + # Create sizer for groups + self.sizer = wxBoxSizer(wxVERTICAL) + # Data to create buttons + pullDownMenu = g.pullDownMenu + self.groups = [] + self.ctrl = self.shift = False + # Current state (what to enable/disable) + self.state = None + groups = [ + ["Windows", + (ID_NEW.FRAME, images.getToolFrameBitmap()), + (ID_NEW.DIALOG, images.getToolDialogBitmap()), + (ID_NEW.PANEL, images.getToolPanelBitmap())], + ["Menus", + (ID_NEW.TOOL_BAR, images.getToolToolBarBitmap()), + (ID_NEW.MENU_BAR, images.getToolMenuBarBitmap()), + (ID_NEW.MENU, images.getToolMenuBitmap()), + (ID_NEW.TOOL, images.getToolToolBitmap()), + (ID_NEW.MENU_ITEM, images.getToolMenuItemBitmap()), + (ID_NEW.SEPARATOR, images.getToolSeparatorBitmap())], + ["Sizers", + (ID_NEW.BOX_SIZER, images.getToolBoxSizerBitmap()), + (ID_NEW.STATIC_BOX_SIZER, images.getToolStaticBoxSizerBitmap()), + (ID_NEW.GRID_SIZER, images.getToolGridSizerBitmap()), + (ID_NEW.FLEX_GRID_SIZER, images.getToolFlexGridSizerBitmap()), + (ID_NEW.SPACER, images.getToolSpacerBitmap())], + ["Controls", + (ID_NEW.STATIC_TEXT, images.getToolStaticTextBitmap()), + (ID_NEW.STATIC_BITMAP, images.getToolStaticBitmapBitmap()), + (ID_NEW.STATIC_LINE, images.getToolStaticLineBitmap()), + + (ID_NEW.BUTTON, images.getToolButtonBitmap()), + (ID_NEW.BITMAP_BUTTON, images.getToolBitmapButtonBitmap()), + (ID_NEW.STATIC_BOX, images.getToolStaticBoxBitmap()), + + (ID_NEW.TEXT_CTRL, images.getToolTextCtrlBitmap()), + (ID_NEW.COMBO_BOX, images.getToolComboBoxBitmap()), + (ID_NEW.CHOICE, images.getToolChoiceBitmap()), + + (ID_NEW.RADIO_BUTTON, images.getToolRadioButtonBitmap()), + (ID_NEW.CHECK_BOX, images.getToolCheckBoxBitmap()), + (ID_NEW.RADIO_BOX, images.getToolRadioBoxBitmap()), + + (ID_NEW.SPIN_CTRL, images.getToolSpinCtrlBitmap()), + (ID_NEW.SPIN_BUTTON, images.getToolSpinButtonBitmap()), + (ID_NEW.SCROLL_BAR, images.getToolScrollBarBitmap()), + + (ID_NEW.SLIDER, images.getToolSliderBitmap()), + (ID_NEW.GAUGE, images.getToolGaugeBitmap()), + (ID_NEW.TREE_CTRL, images.getToolTreeCtrlBitmap()), + + (ID_NEW.LIST_BOX, images.getToolListBoxBitmap()), + (ID_NEW.CHECK_LIST, images.getToolCheckListBitmap()), + (ID_NEW.LIST_CTRL, images.getToolListCtrlBitmap()), + + (ID_NEW.NOTEBOOK, images.getToolNotebookBitmap()), + + (ID_NEW.UNKNOWN, images.getToolUnknownBitmap())] + ] + for grp in groups: + self.AddGroup(grp[0]) + for b in grp[1:]: + self.AddButton(b[0], b[1], g.pullDownMenu.createMap[b[0]]) + self.SetAutoLayout(True) + self.SetSizerAndFit(self.sizer) + # Allow to be resized in vertical direction only + self.SetSizeHints(self.GetSize()[0], -1) + # Events + EVT_COMMAND_RANGE(self, ID_NEW.PANEL, ID_NEW.LAST, + wxEVT_COMMAND_BUTTON_CLICKED, g.frame.OnCreate) + EVT_KEY_DOWN(self, self.OnKeyDown) + EVT_KEY_UP(self, self.OnKeyUp) + + def AddButton(self, id, image, text): + button = wxBitmapButton(self, id, image, size=self.TOOL_SIZE, + style=wxBU_AUTODRAW|wxNO_BORDER|wxWANTS_CHARS) + EVT_KEY_DOWN(button, self.OnKeyDown) + EVT_KEY_UP(button, self.OnKeyUp) + button.SetToolTipString(text) + self.curSizer.Add(button) + self.groups[-1][1][id] = button + + def AddGroup(self, name): + # Each group is inside box + box = wxStaticBox(self, -1, name, style=wxWANTS_CHARS) + box.SetFont(smallerFont) + boxSizer = wxStaticBoxSizer(box, wxVERTICAL) + boxSizer.Add(0, 4) + self.curSizer = wxGridSizer(0, 3) + boxSizer.Add(self.curSizer) + self.sizer.Add(boxSizer, 0, wxTOP | wxLEFT | wxRIGHT, 4) + self.groups.append((box,{})) + + # Enable/disable group + def EnableGroup(self, gnum, enable = True): + grp = self.groups[gnum] + grp[0].Enable(enable) + for b in grp[1].values(): b.Enable(enable) + + # Enable/disable group item + def EnableGroupItem(self, gnum, id, enable = True): + grp = self.groups[gnum] + grp[1][id].Enable(enable) + + # Enable/disable group items + def EnableGroupItems(self, gnum, ids, enable = True): + grp = self.groups[gnum] + for id in ids: + grp[1][id].Enable(enable) + + # Process key events + def OnKeyDown(self, evt): + if evt.GetKeyCode() == WXK_CONTROL: + g.tree.ctrl = True + elif evt.GetKeyCode() == WXK_SHIFT: + g.tree.shift = True + self.UpdateIfNeeded() + evt.Skip() + + def OnKeyUp(self, evt): + if evt.GetKeyCode() == WXK_CONTROL: + g.tree.ctrl = False + elif evt.GetKeyCode() == WXK_SHIFT: + g.tree.shift = False + self.UpdateIfNeeded() + evt.Skip() + + def OnMouse(self, evt): + # Update control and shift states + g.tree.ctrl = evt.ControlDown() + g.tree.shift = evt.ShiftDown() + self.UpdateIfNeeded() + evt.Skip() + + # Update UI after key presses, if necessary + def UpdateIfNeeded(self): + tree = g.tree + if self.ctrl != tree.ctrl or self.shift != tree.shift: + # Enabling is needed only for ctrl + if self.ctrl != tree.ctrl: self.UpdateUI() + self.ctrl = tree.ctrl + self.shift = tree.shift + if tree.ctrl: + status = 'SBL' + elif tree.shift: + status = 'INS' + else: + status = '' + g.frame.SetStatusText(status, 1) + + # Update interface + def UpdateUI(self): + # Update status bar + pullDownMenu = g.pullDownMenu + tree = g.tree + item = tree.selection + # If nothing selected, disable everything and return + if not item: + # Disable everything + for grp in range(GROUPNUM): + self.EnableGroup(grp, False) + self.state = None + return + if tree.ctrl: needInsert = True + else: needInsert = tree.NeedInsert(item) + # Enable depending on selection + if item == tree.root or needInsert and tree.GetItemParent(item) == tree.root: + state = STATE_ROOT + else: + xxx = tree.GetPyData(item).treeObject() + # Check parent for possible child nodes if inserting sibling + if needInsert: xxx = xxx.parent + if xxx.__class__ == xxxMenuBar: + state = STATE_MENUBAR + elif xxx.__class__ in [xxxToolBar, xxxTool] or \ + xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar: + state = STATE_TOOLBAR + elif xxx.__class__ in [xxxMenu, xxxMenuItem]: + state = STATE_MENU + else: + state = STATE_ELSE + + # Enable depending on selection + if state != self.state: + # Disable everything + for grp in range(GROUPNUM): + self.EnableGroup(grp, False) + # Enable some + if state == STATE_ROOT: + self.EnableGroup(GROUP_WINDOWS, True) + self.EnableGroup(GROUP_MENUS, True) + # But disable items + self.EnableGroupItems(GROUP_MENUS, + [ ID_NEW.TOOL, + ID_NEW.MENU_ITEM, + ID_NEW.SEPARATOR ], + False) + elif state == STATE_MENUBAR: + self.EnableGroup(GROUP_MENUS) + self.EnableGroupItems(GROUP_MENUS, + [ ID_NEW.TOOL_BAR, + ID_NEW.MENU_BAR, + ID_NEW.TOOL ], + False) + elif state == STATE_TOOLBAR: + self.EnableGroup(GROUP_MENUS) + self.EnableGroupItems(GROUP_MENUS, + [ ID_NEW.TOOL_BAR, + ID_NEW.MENU, + ID_NEW.MENU_BAR, + ID_NEW.MENU_ITEM ], + False) + self.EnableGroup(GROUP_CONTROLS) + self.EnableGroupItems(GROUP_CONTROLS, + [ ID_NEW.TREE_CTRL, + ID_NEW.NOTEBOOK ], + False) + elif state == STATE_MENU: + self.EnableGroup(GROUP_MENUS) + self.EnableGroupItems(GROUP_MENUS, + [ ID_NEW.TOOL_BAR, + ID_NEW.MENU_BAR, + ID_NEW.TOOL ], + False) + else: + self.EnableGroup(GROUP_WINDOWS) + self.EnableGroupItems(GROUP_WINDOWS, + [ ID_NEW.FRAME, + ID_NEW.DIALOG ], + False) + self.EnableGroup(GROUP_MENUS) + self.EnableGroupItems(GROUP_MENUS, + [ ID_NEW.MENU_BAR, + ID_NEW.MENU_BAR, + ID_NEW.MENU, + ID_NEW.MENU_ITEM, + ID_NEW.TOOL, + ID_NEW.SEPARATOR ], + False) + self.EnableGroup(GROUP_SIZERS) + self.EnableGroup(GROUP_CONTROLS) + # Special case for notebook (always executed) + if state == STATE_ELSE: + if xxx.__class__ == xxxNotebook: + self.EnableGroup(GROUP_SIZERS, False) + else: + self.EnableGroup(GROUP_SIZERS) + if not (xxx.isSizer or xxx.parent and xxx.parent.isSizer): + self.EnableGroupItem(GROUP_SIZERS, ID_NEW.SPACER, False) + # Save state + self.state = state diff --git a/wxPython/wxPython/tools/XRCed/tree.py b/wxPython/wxPython/tools/XRCed/tree.py new file mode 100644 index 0000000000..4036f5d249 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/tree.py @@ -0,0 +1,839 @@ +# Name: tree.py +# Purpose: XRC editor, XML_tree class +# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> +# Created: 02.12.2002 +# RCS-ID: $Id$ + +from xxx import * # xxx imports globals and params + +# Icons +import images + +class MemoryFile: + def __init__(self, name): + self.name = name + self.buffer = '' + def write(self, data): + self.buffer += data.encode() + def close(self): + wxMemoryFSHandler_AddFile(self.name, self.buffer) + +################################################################################ + +# Redefine writing to include encoding +class MyDocument(minidom.Document): + def __init__(self): + minidom.Document.__init__(self) + self.encoding = '' + def writexml(self, writer, indent="", addindent="", newl="", encoding=""): + if encoding: encdstr = 'encoding="%s"' % encoding + else: encdstr = '' + writer.write('<?xml version="1.0" %s?>\n' % encdstr) + for node in self.childNodes: + node.writexml(writer, indent, addindent, newl) + +################################################################################ + +# Ids for menu commands +class ID_NEW: + PANEL = wxNewId() + DIALOG = wxNewId() + FRAME = wxNewId() + TOOL_BAR = wxNewId() + TOOL = wxNewId() + MENU_BAR = wxNewId() + MENU = wxNewId() + + STATIC_TEXT = wxNewId() + TEXT_CTRL = wxNewId() + + BUTTON = wxNewId() + BITMAP_BUTTON = wxNewId() + RADIO_BUTTON = wxNewId() + SPIN_BUTTON = wxNewId() + + STATIC_BOX = wxNewId() + CHECK_BOX = wxNewId() + RADIO_BOX = wxNewId() + COMBO_BOX = wxNewId() + LIST_BOX = wxNewId() + + STATIC_LINE = wxNewId() + STATIC_BITMAP = wxNewId() + CHOICE = wxNewId() + SLIDER = wxNewId() + GAUGE = wxNewId() + SCROLL_BAR = wxNewId() + TREE_CTRL = wxNewId() + LIST_CTRL = wxNewId() + CHECK_LIST = wxNewId() + NOTEBOOK = wxNewId() + HTML_WINDOW = wxNewId() + CALENDAR_CTRL = wxNewId() + GENERIC_DIR_CTRL = wxNewId() + SPIN_CTRL = wxNewId() + UNKNOWN = wxNewId() + + BOX_SIZER = wxNewId() + STATIC_BOX_SIZER = wxNewId() + GRID_SIZER = wxNewId() + FLEX_GRID_SIZER = wxNewId() + SPACER = wxNewId() + TOOL_BAR = wxNewId() + TOOL = wxNewId() + MENU = wxNewId() + MENU_ITEM = wxNewId() + SEPARATOR = wxNewId() + LAST = wxNewId() + +class PullDownMenu: + ID_EXPAND = wxNewId() + ID_COLLAPSE = wxNewId() + ID_PASTE_SIBLING = wxNewId() + + def __init__(self, parent): + self.ID_DELETE = parent.ID_DELETE + EVT_MENU_RANGE(parent, ID_NEW.PANEL, ID_NEW.LAST, parent.OnCreate) + EVT_MENU(parent, self.ID_COLLAPSE, parent.OnCollapse) + EVT_MENU(parent, self.ID_EXPAND, parent.OnExpand) + EVT_MENU(parent, self.ID_PASTE_SIBLING, parent.OnPaste) + # We connect to tree, but process in frame + EVT_MENU_HIGHLIGHT_ALL(g.tree, parent.OnPullDownHighlight) + + # Mapping from IDs to element names + self.createMap = { + ID_NEW.PANEL: 'wxPanel', + ID_NEW.DIALOG: 'wxDialog', + ID_NEW.FRAME: 'wxFrame', + ID_NEW.TOOL_BAR: 'wxToolBar', + ID_NEW.TOOL: 'tool', + ID_NEW.MENU_BAR: 'wxMenuBar', + ID_NEW.MENU: 'wxMenu', + ID_NEW.MENU_ITEM: 'wxMenuItem', + ID_NEW.SEPARATOR: 'separator', + + ID_NEW.STATIC_TEXT: 'wxStaticText', + ID_NEW.TEXT_CTRL: 'wxTextCtrl', + + ID_NEW.BUTTON: 'wxButton', + ID_NEW.BITMAP_BUTTON: 'wxBitmapButton', + ID_NEW.RADIO_BUTTON: 'wxRadioButton', + ID_NEW.SPIN_BUTTON: 'wxSpinButton', + + ID_NEW.STATIC_BOX: 'wxStaticBox', + ID_NEW.CHECK_BOX: 'wxCheckBox', + ID_NEW.RADIO_BOX: 'wxRadioBox', + ID_NEW.COMBO_BOX: 'wxComboBox', + ID_NEW.LIST_BOX: 'wxListBox', + + ID_NEW.STATIC_LINE: 'wxStaticLine', + ID_NEW.STATIC_BITMAP: 'wxStaticBitmap', + ID_NEW.CHOICE: 'wxChoice', + ID_NEW.SLIDER: 'wxSlider', + ID_NEW.GAUGE: 'wxGauge', + ID_NEW.SCROLL_BAR: 'wxScrollBar', + ID_NEW.TREE_CTRL: 'wxTreeCtrl', + ID_NEW.LIST_CTRL: 'wxListCtrl', + ID_NEW.CHECK_LIST: 'wxCheckList', + ID_NEW.NOTEBOOK: 'wxNotebook', + ID_NEW.HTML_WINDOW: 'wxHtmlWindow', + ID_NEW.CALENDAR_CTRL: 'wxCalendarCtrl', + ID_NEW.GENERIC_DIR_CTRL: 'wxGenericDirCtrl', + ID_NEW.SPIN_CTRL: 'wxSpinCtrl', + + ID_NEW.BOX_SIZER: 'wxBoxSizer', + ID_NEW.STATIC_BOX_SIZER: 'wxStaticBoxSizer', + ID_NEW.GRID_SIZER: 'wxGridSizer', + ID_NEW.FLEX_GRID_SIZER: 'wxFlexGridSizer', + ID_NEW.SPACER: 'spacer', + ID_NEW.UNKNOWN: 'unknown', + } + self.controls = [ + ['control', 'Various controls', + (ID_NEW.STATIC_TEXT, 'Label', 'Create label'), + (ID_NEW.STATIC_BITMAP, 'Bitmap', 'Create bitmap'), + (ID_NEW.STATIC_LINE, 'Line', 'Create line'), + (ID_NEW.TEXT_CTRL, 'TextBox', 'Create text box'), + (ID_NEW.CHOICE, 'Choice', 'Create choice'), + (ID_NEW.SLIDER, 'Slider', 'Create slider'), + (ID_NEW.GAUGE, 'Gauge', 'Create gauge'), + (ID_NEW.SPIN_CTRL, 'SpinCtrl', 'Create spin'), + (ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'), + (ID_NEW.TREE_CTRL, 'TreeCtrl', 'Create tree'), + (ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list'), + (ID_NEW.CHECK_LIST, 'CheckList', 'Create check list'), + (ID_NEW.HTML_WINDOW, 'HtmlWindow', 'Create HTML window'), + (ID_NEW.CALENDAR_CTRL, 'CalendarCtrl', 'Create calendar control'), + (ID_NEW.GENERIC_DIR_CTRL, 'GenericDirCtrl', 'Create generic dir control'), + (ID_NEW.UNKNOWN, 'Unknown', 'Create custom control placeholder'), + ], + ['button', 'Buttons', + (ID_NEW.BUTTON, 'Button', 'Create button'), + (ID_NEW.BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'), + (ID_NEW.RADIO_BUTTON, 'RadioButton', 'Create radio button'), + (ID_NEW.SPIN_BUTTON, 'SpinButton', 'Create spin button'), + ], + ['box', 'Boxes', + (ID_NEW.STATIC_BOX, 'StaticBox', 'Create static box'), + (ID_NEW.CHECK_BOX, 'CheckBox', 'Create check box'), + (ID_NEW.RADIO_BOX, 'RadioBox', 'Create radio box'), + (ID_NEW.COMBO_BOX, 'ComboBox', 'Create combo box'), + (ID_NEW.LIST_BOX, 'ListBox', 'Create list box'), + ], + ['container', 'Containers', + (ID_NEW.PANEL, 'Panel', 'Create panel'), + (ID_NEW.NOTEBOOK, 'Notebook', 'Create notebook control'), + (ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar'), + ], + ['sizer', 'Sizers', + (ID_NEW.BOX_SIZER, 'BoxSizer', 'Create box sizer'), + (ID_NEW.STATIC_BOX_SIZER, 'StaticBoxSizer', + 'Create static box sizer'), + (ID_NEW.GRID_SIZER, 'GridSizer', 'Create grid sizer'), + (ID_NEW.FLEX_GRID_SIZER, 'FlexGridSizer', + 'Create flexgrid sizer'), + (ID_NEW.SPACER, 'Spacer', 'Create spacer'), + ] + ] + self.menuControls = [ + (ID_NEW.MENU, 'Menu', 'Create menu'), + (ID_NEW.MENU_ITEM, 'MenuItem', 'Create menu item'), + (ID_NEW.SEPARATOR, 'Separator', 'Create separator'), + ] + self.toolBarControls = [ + (ID_NEW.TOOL, 'Tool', 'Create tool'), + (ID_NEW.SEPARATOR, 'Separator', 'Create separator'), + ['control', 'Various controls', + (ID_NEW.STATIC_TEXT, 'Label', 'Create label'), + (ID_NEW.STATIC_BITMAP, 'Bitmap', 'Create bitmap'), + (ID_NEW.STATIC_LINE, 'Line', 'Create line'), + (ID_NEW.TEXT_CTRL, 'TextBox', 'Create text box'), + (ID_NEW.CHOICE, 'Choice', 'Create choice'), + (ID_NEW.SLIDER, 'Slider', 'Create slider'), + (ID_NEW.GAUGE, 'Gauge', 'Create gauge'), + (ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'), + (ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list control'), + (ID_NEW.CHECK_LIST, 'CheckList', 'Create check list'), + ], + ['button', 'Buttons', + (ID_NEW.BUTTON, 'Button', 'Create button'), + (ID_NEW.BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'), + (ID_NEW.RADIO_BUTTON, 'RadioButton', 'Create radio button'), + (ID_NEW.SPIN_BUTTON, 'SpinButton', 'Create spin button'), + ], + ['box', 'Boxes', + (ID_NEW.STATIC_BOX, 'StaticBox', 'Create static box'), + (ID_NEW.CHECK_BOX, 'CheckBox', 'Create check box'), + (ID_NEW.RADIO_BOX, 'RadioBox', 'Create radio box'), + (ID_NEW.COMBO_BOX, 'ComboBox', 'Create combo box'), + (ID_NEW.LIST_BOX, 'ListBox', 'Create list box'), + ], + ] + +################################################################################ + +# Set menu to list items. +# Each menu command is a tuple (id, label, help) +# submenus are lists [id, label, help, submenu] +# and separators are any other type +def SetMenu(m, list): + for l in list: + if type(l) == types.TupleType: + apply(m.Append, l) + elif type(l) == types.ListType: + subMenu = wxMenu() + SetMenu(subMenu, l[2:]) + m.AppendMenu(wxNewId(), l[0], subMenu, l[1]) + else: # separator + m.AppendSeparator() + +################################################################################ + +class HighLightBox: + def __init__(self, pos, size): + if size.x == -1: size.x = 0 + if size.y == -1: size.y = 0 + w = g.testWin.panel + l1 = wxWindow(w, -1, pos, wxSize(size.x, 2)) + l1.SetBackgroundColour(wxRED) + l2 = wxWindow(w, -1, pos, wxSize(2, size.y)) + l2.SetBackgroundColour(wxRED) + l3 = wxWindow(w, -1, wxPoint(pos.x + size.x - 2, pos.y), wxSize(2, size.y)) + l3.SetBackgroundColour(wxRED) + l4 = wxWindow(w, -1, wxPoint(pos.x, pos.y + size.y - 2), wxSize(size.x, 2)) + l4.SetBackgroundColour(wxRED) + self.lines = [l1, l2, l3, l4] + # Move highlight to a new position + def Replace(self, pos, size): + if size.x == -1: size.x = 0 + if size.y == -1: size.y = 0 + self.lines[0].SetDimensions(pos.x, pos.y, size.x, 2) + self.lines[1].SetDimensions(pos.x, pos.y, 2, size.y) + self.lines[2].SetDimensions(pos.x + size.x - 2, pos.y, 2, size.y) + self.lines[3].SetDimensions(pos.x, pos.y + size.y - 2, size.x, 2) + # Remove it + def Remove(self): + map(wxWindow.Destroy, self.lines) + g.testWin.highLight = None + +################################################################################ + +class XML_Tree(wxTreeCtrl): + # Constant to define standart window name + stdName = '_XRCED_T_W' + def __init__(self, parent, id): + wxTreeCtrl.__init__(self, parent, id, style = wxTR_HAS_BUTTONS) + self.SetBackgroundColour(wxColour(224, 248, 224)) + EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) + # One works on Linux, another on Windows + if wxPlatform == '__WXGTK__': + EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated) + else: + EVT_LEFT_DCLICK(self, self.OnDClick) + EVT_RIGHT_DOWN(self, self.OnRightDown) + + self.needUpdate = False + self.pendingHighLight = None + self.ctrl = self.shift = False + self.dom = None + # Create image list + il = wxImageList(16, 16, True) + self.rootImage = il.AddIcon(images.getTreeRootIcon()) + xxxObject.image = il.AddIcon(images.getTreeDefaultIcon()) + xxxPanel.image = il.AddIcon(images.getTreePanelIcon()) + xxxDialog.image = il.AddIcon(images.getTreeDialogIcon()) + xxxFrame.image = il.AddIcon(images.getTreeFrameIcon()) + xxxMenuBar.image = il.AddIcon(images.getTreeMenuBarIcon()) + xxxMenu.image = il.AddIcon(images.getTreeMenuIcon()) + xxxMenuItem.image = il.AddIcon(images.getTreeMenuItemIcon()) + xxxToolBar.image = il.AddIcon(images.getTreeToolBarIcon()) + xxxTool.image = il.AddIcon(images.getTreeToolIcon()) + xxxSeparator.image = il.AddIcon(images.getTreeSeparatorIcon()) + xxxSizer.imageH = il.AddIcon(images.getTreeSizerHIcon()) + xxxSizer.imageV = il.AddIcon(images.getTreeSizerVIcon()) + xxxStaticBoxSizer.imageH = il.AddIcon(images.getTreeStaticBoxSizerHIcon()) + xxxStaticBoxSizer.imageV = il.AddIcon(images.getTreeStaticBoxSizerVIcon()) + xxxGridSizer.image = il.AddIcon(images.getTreeSizerGridIcon()) + xxxFlexGridSizer.image = il.AddIcon(images.getTreeSizerFlexGridIcon()) + self.il = il + self.SetImageList(il) + + def RegisterKeyEvents(self): + EVT_KEY_DOWN(self, g.tools.OnKeyDown) + EVT_KEY_UP(self, g.tools.OnKeyUp) + EVT_ENTER_WINDOW(self, g.tools.OnMouse) + EVT_LEAVE_WINDOW(self, g.tools.OnMouse) + + def Unselect(self): + self.selection = None + wxTreeCtrl.Unselect(self) + g.tools.UpdateUI() + + def ExpandAll(self, item): + if self.ItemHasChildren(item): + self.Expand(item) + i, cookie = self.GetFirstChild(item, 0) + children = [] + while i.IsOk(): + children.append(i) + i, cookie = self.GetNextChild(item, cookie) + for i in children: + self.ExpandAll(i) + def CollapseAll(self, item): + if self.ItemHasChildren(item): + i, cookie = self.GetFirstChild(item, 0) + children = [] + while i.IsOk(): + children.append(i) + i, cookie = self.GetNextChild(item, cookie) + for i in children: + self.CollapseAll(i) + self.Collapse(item) + + # Clear tree + def Clear(self): + self.DeleteAllItems() + # Add minimal structure + if self.dom: self.dom.unlink() + self.dom = MyDocument() + self.dummyNode = self.dom.createComment('dummy node') + # Create main node + self.mainNode = self.dom.createElement('resource') + self.dom.appendChild(self.mainNode) + self.rootObj = xxxMainNode(self.dom) + self.root = self.AddRoot('XML tree', self.rootImage, + data=wxTreeItemData(self.rootObj)) + self.SetItemHasChildren(self.root) + self.Expand(self.root) + self.Unselect() + + # Clear old data and set new + def SetData(self, dom): + self.DeleteAllItems() + # Add minimal structure + if self.dom: self.dom.unlink() + self.dom = dom + self.dummyNode = self.dom.createComment('dummy node') + # Find 'resource' child, add it's children + self.mainNode = dom.documentElement + self.rootObj = xxxMainNode(self.dom) + self.root = self.AddRoot('XML tree', self.rootImage, + data=wxTreeItemData(self.rootObj)) + self.SetItemHasChildren(self.root) + nodes = self.mainNode.childNodes[:] + for node in nodes: + if IsObject(node): + self.AddNode(self.root, None, node) + else: + self.mainNode.removeChild(node) + node.unlink() + self.Expand(self.root) + self.Unselect() + + # Add tree item for given parent item if node is DOM element node with + # 'object' tag. xxxParent is parent xxx object + def AddNode(self, itemParent, xxxParent, node): + # Set item data to current node + try: + xxx = MakeXXXFromDOM(xxxParent, node) + except: + print 'ERROR: MakeXXXFromDom(%s, %s)' % (xxxParent, node) + raise + treeObj = xxx.treeObject() + # Append tree item + item = self.AppendItem(itemParent, treeObj.treeName(), + image=treeObj.treeImage(), + data=wxTreeItemData(xxx)) + # Try to find children objects + if treeObj.hasChildren: + nodes = treeObj.element.childNodes[:] + for n in nodes: + if IsObject(n): + self.AddNode(item, treeObj, n) + elif n.nodeType != minidom.Node.ELEMENT_NODE: + treeObj.element.removeChild(n) + n.unlink() + # Insert new item at specific position + def InsertNode(self, itemParent, parent, elem, nextItem): + # Insert in XML tree and wxWin + xxx = MakeXXXFromDOM(parent, elem) + # If nextItem is None, we append to parent, otherwise insert before it + if nextItem.IsOk(): + node = self.GetPyData(nextItem).element + parent.element.insertBefore(elem, node) + # Inserting before is difficult, se we insert after or first child + index = self.ItemIndex(nextItem) + newItem = self.InsertItemBefore(itemParent, index, + xxx.treeName(), image=xxx.treeImage()) + self.SetPyData(newItem, xxx) + else: + parent.element.appendChild(elem) + newItem = self.AppendItem(itemParent, xxx.treeName(), image=xxx.treeImage(), + data=wxTreeItemData(xxx)) + # Add children items + if xxx.hasChildren: + treeObj = xxx.treeObject() + for n in treeObj.element.childNodes: + if IsObject(n): + self.AddNode(newItem, treeObj, n) + return newItem + + # Remove leaf of tree, return it's data object + def RemoveLeaf(self, leaf): + xxx = self.GetPyData(leaf) + node = xxx.element + parent = node.parentNode + parent.removeChild(node) + self.Delete(leaf) + # Reset selection object + self.selection = None + return node + # Find position relative to the top-level window + def FindNodePos(self, item): + # Root at (0,0) + if item == g.testWin.item: return wxPoint(0, 0) + itemParent = self.GetItemParent(item) + # Select NB page + obj = self.FindNodeObject(item) + if self.GetPyData(itemParent).treeObject().__class__ == xxxNotebook: + notebook = self.FindNodeObject(itemParent) + # Find position + for i in range(notebook.GetPageCount()): + if notebook.GetPage(i) == obj: + if notebook.GetSelection() != i: notebook.SetSelection(i) + break + # Find first ancestor which is a wxWindow (not a sizer) + winParent = itemParent + while self.GetPyData(winParent).isSizer: + winParent = self.GetItemParent(winParent) + parentPos = self.FindNodePos(winParent) + # Position (-1,-1) is really (0,0) + pos = obj.GetPosition() + if pos == (-1,-1): pos = (0,0) + return parentPos + pos + # Find window (or sizer) corresponding to a tree item. + def FindNodeObject(self, item): + testWin = g.testWin + # If top-level, return testWin (or panel its panel) + if item == testWin.item: return testWin.panel + itemParent = self.GetItemParent(item) + xxx = self.GetPyData(item).treeObject() + parentWin = self.FindNodeObject(itemParent) + # Top-level sizer? return window's sizer + if xxx.isSizer and isinstance(parentWin, wxWindowPtr): + return parentWin.GetSizer() + # Otherwise get parent's object and it's child + child = parentWin.GetChildren()[self.ItemIndex(item)] + # Return window or sizer for sizer items + if child.GetClassName() == 'wxSizerItem': + if child.IsWindow(): child = child.GetWindow() + elif child.IsSizer(): + child = child.GetSizer() + # Test for notebook sizers + if isinstance(child, wxNotebookSizerPtr): + child = child.GetNotebook() + return child + def OnSelChanged(self, evt): + # Apply changes + # !!! problem with wxGTK - GetOldItem is Ok if nothing selected + #oldItem = evt.GetOldItem() + status = '' + oldItem = self.selection + if oldItem: + xxx = self.GetPyData(oldItem) + # If some data was modified, apply changes + if g.panel.IsModified(): + self.Apply(xxx, oldItem) + #if conf.autoRefresh: + if g.testWin: + if g.testWin.highLight: + g.testWin.highLight.Remove() + self.needUpdate = True + status = 'Changes were applied' + g.frame.SetStatusText(status) + # Generate view + self.selection = evt.GetItem() + if not self.selection.IsOk(): + self.selection = None + return + xxx = self.GetPyData(self.selection) + # Update panel + g.panel.SetData(xxx) + # Update tools + g.tools.UpdateUI() + # Hightlighting is done in OnIdle + self.pendingHighLight = self.selection + # Check if item is in testWin subtree + def IsHighlatable(self, item): + if item == g.testWin.item: return False + while item != self.root: + item = self.GetItemParent(item) + if item == g.testWin.item: return True + return False + # Highlight selected item + def HighLight(self, item): + self.pendingHighLight = None + # Can highlight only with some top-level windows + if not g.testWin or self.GetPyData(g.testWin.item).treeObject().__class__ \ + not in [xxxDialog, xxxPanel, xxxFrame]: + return + # If a control from another window is selected, remove highlight + if not self.IsHighlatable(item): + if g.testWin.highLight: g.testWin.highLight.Remove() + return + # Get window/sizer object + obj, pos = self.FindNodeObject(item), self.FindNodePos(item) + size = obj.GetSize() + # Highlight + # Nagative positions are not working wuite well + if g.testWin.highLight: + g.testWin.highLight.Replace(pos, size) + else: + g.testWin.highLight = HighLightBox(pos, size) + g.testWin.highLight.item = item + def ShowTestWindow(self, item): + xxx = self.GetPyData(item) + if g.panel.IsModified(): + self.Apply(xxx, item) # apply changes + treeObj = xxx.treeObject() + if treeObj.className not in ['wxFrame', 'wxPanel', 'wxDialog', + 'wxMenuBar', 'wxToolBar']: + wxLogMessage('No view for this element (yet)') + return + # Show item in bold + if g.testWin: # Reset old + self.SetItemBold(g.testWin.item, False) + self.CreateTestWin(item) + # Maybe an error occured, so we need to test + if g.testWin: self.SetItemBold(g.testWin.item) + # Double-click on Linux + def OnItemActivated(self, evt): + if evt.GetItem() != self.root: + self.ShowTestWindow(evt.GetItem()) + # Double-click on Windows + def OnDClick(self, evt): + item, flags = self.HitTest(evt.GetPosition()) + if flags in [wxTREE_HITTEST_ONITEMBUTTON, wxTREE_HITTEST_ONITEMLABEL]: + if item != self.root: self.ShowTestWindow(item) + else: + evt.Skip() + # (re)create test window + def CreateTestWin(self, item): + testWin = g.testWin + wxBeginBusyCursor() + wxYield() + # Create a window with this resource + xxx = self.GetPyData(item).treeObject() + # Close old window, remember where it was + highLight = None + if testWin: + pos = testWin.GetPosition() + if item == testWin.item: + # Remember highlight if same top-level window + if testWin.highLight: + highLight = testWin.highLight.item + if xxx.className == 'wxPanel': + if testWin.highLight: + testWin.pendingHighLight = highLight + testWin.highLight.Remove() + testWin.panel.Destroy() + testWin.panel = None + else: + testWin.Destroy() + testWin = g.testWin = None + else: + testWin.Destroy() + testWin = g.testWin = None + else: + pos = g.testWinPos + # Save in memory FS + memFile = MemoryFile('xxx.xrc') + # Create partial XML file - faster for big files + + dom = MyDocument() + mainNode = dom.createElement('resource') + dom.appendChild(mainNode) + + # Remove temporarily from old parent + elem = xxx.element + # Change window id to _XRCED_T_W. This gives some name for + # unnamed windows, and for named gives the possibility to + # write sawfish scripts. + if not xxx.name: + name = 'noname' + else: + name = xxx.name + elem.setAttribute('name', self.stdName) + parent = elem.parentNode + next = elem.nextSibling + parent.replaceChild(self.dummyNode, elem) + # Append to new DOM, write it + mainNode.appendChild(elem) + dom.writexml(memFile, encoding=self.rootObj.params['encoding'].value()) + # Put back in place + mainNode.removeChild(elem) + dom.unlink() + parent.replaceChild(elem, self.dummyNode) + # Remove temporary name or restore changed + if not xxx.name: + elem.removeAttribute('name') + else: + elem.setAttribute('name', xxx.name) + memFile.close() # write to wxMemoryFS + res = wxXmlResource('', g.xmlFlags) + res.Load('memory:xxx.xrc') + if xxx.__class__ == xxxFrame: + # Frame can't have many children, + # but it's first child possibly can... + child = self.GetFirstChild(item, 0)[0] + if child.IsOk() and self.GetPyData(child).__class__ == xxxPanel: + # Clean-up before recursive call or error + wxMemoryFSHandler_RemoveFile('xxx.xrc') + wxEndBusyCursor() + self.CreateTestWin(child) + return + # This currently works under GTK, but not under MSW + testWin = g.testWin = wxPreFrame() + res.LoadOnFrame(testWin, g.frame, self.stdName) + # Create status bar + testWin.CreateStatusBar() + testWin.panel = testWin + testWin.SetPosition(pos) + testWin.Show(True) + elif xxx.__class__ == xxxPanel: + # Create new frame + if not testWin: + testWin = g.testWin = wxFrame(g.frame, -1, 'Panel: ' + name, pos=pos) + testWin.panel = res.LoadPanel(testWin, self.stdName) + testWin.SetClientSize(testWin.panel.GetSize()) + testWin.Show(True) + elif xxx.__class__ == xxxDialog: + testWin = g.testWin = res.LoadDialog(None, self.stdName) + testWin.panel = testWin + testWin.Layout() + testWin.SetPosition(pos) + testWin.Show(True) + elif xxx.__class__ == xxxMenuBar: + testWin = g.testWin = wxFrame(g.frame, -1, 'MenuBar: ' + name, pos=pos) + testWin.panel = None + # Set status bar to display help + testWin.CreateStatusBar() + testWin.menuBar = res.LoadMenuBar(self.stdName) + testWin.SetMenuBar(testWin.menuBar) + testWin.Show(True) + elif xxx.__class__ == xxxToolBar: + testWin = g.testWin = wxFrame(g.frame, -1, 'ToolBar: ' + name, pos=pos) + testWin.panel = None + # Set status bar to display help + testWin.CreateStatusBar() + testWin.toolBar = res.LoadToolBar(testWin, self.stdName) + testWin.SetToolBar(testWin.toolBar) + testWin.Show(True) + wxMemoryFSHandler_RemoveFile('xxx.xrc') + testWin.item = item + EVT_CLOSE(testWin, self.OnCloseTestWin) + EVT_BUTTON(testWin, wxID_OK, self.OnCloseTestWin) + EVT_BUTTON(testWin, wxID_CANCEL, self.OnCloseTestWin) + testWin.highLight = None + if highLight and not self.pendingHighLight: + self.HighLight(highLight) + wxEndBusyCursor() + + def OnCloseTestWin(self, evt): + self.SetItemBold(g.testWin.item, False) + g.testWinPos = g.testWin.GetPosition() + g.testWin.Destroy() + g.testWin = None + + # Return item index in parent + def ItemIndex(self, item): + n = 0 # index of sibling + prev = self.GetPrevSibling(item) + while prev.IsOk(): + prev = self.GetPrevSibling(prev) + n += 1 + return n + + # Full tree index of an item - list of positions + def ItemFullIndex(self, item): + if not item.IsOk(): return None + l = [] + while item != self.root: + l.insert(0, self.ItemIndex(item)) + item = self.GetItemParent(item) + return l + # Get item position from full index + def ItemAtFullIndex(self, index): + if index is None: return wxTreeItemId() + item = self.root + for i in index: + item = self.GetFirstChild(item, 0)[0] + for k in range(i): item = self.GetNextSibling(item) + return item + + # True if next item should be inserted after current (vs. appended to it) + def NeedInsert(self, item): + xxx = self.GetPyData(item) + if item == self.root: return False # root item + if xxx.hasChildren and not self.GetChildrenCount(item, False): + return False + return not (self.IsExpanded(item) and self.GetChildrenCount(item, False)) + + # Pull-down + def OnRightDown(self, evt): + pullDownMenu = g.pullDownMenu + # select this item + pt = evt.GetPosition(); + item, flags = self.HitTest(pt) + if item.Ok() and flags & wxTREE_HITTEST_ONITEM: + self.SelectItem(item) + + # Setup menu + menu = wxMenu() + + item = self.selection + if not item: + menu.Append(g.pullDownMenu.ID_EXPAND, 'Expand', 'Expand tree') + menu.Append(g.pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse tree') + else: +# self.ctrl = evt.ControlDown() # save Ctrl state +# self.shift = evt.ShiftDown() # and Shift too + m = wxMenu() # create menu + if self.ctrl: + needInsert = True + else: + needInsert = self.NeedInsert(item) + if item == self.root or needInsert and self.GetItemParent(item) == self.root: + m.Append(ID_NEW.PANEL, 'Panel', 'Create panel') + m.Append(ID_NEW.DIALOG, 'Dialog', 'Create dialog') + m.Append(ID_NEW.FRAME, 'Frame', 'Create frame') + m.AppendSeparator() + m.Append(ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar') + m.Append(ID_NEW.MENU_BAR, 'MenuBar', 'Create menubar') + m.Append(ID_NEW.MENU, 'Menu', 'Create menu') + else: + xxx = self.GetPyData(item).treeObject() + # Check parent for possible child nodes if inserting sibling + if needInsert: xxx = xxx.parent + if xxx.__class__ == xxxMenuBar: + m.Append(ID_NEW.MENU, 'Menu', 'Create menu') + elif xxx.__class__ in [xxxToolBar, xxxTool] or \ + xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar: + SetMenu(m, pullDownMenu.toolBarControls) + elif xxx.__class__ in [xxxMenu, xxxMenuItem]: + SetMenu(m, pullDownMenu.menuControls) + else: + SetMenu(m, pullDownMenu.controls) + if xxx.__class__ == xxxNotebook: + m.Enable(m.FindItem('sizer'), False) + elif not (xxx.isSizer or xxx.parent and xxx.parent.isSizer): + m.Enable(ID_NEW.SPACER, False) + # Select correct label for create menu + if not needInsert: + if self.shift: + menu.AppendMenu(wxNewId(), 'Insert Child', m, + 'Create child object as the first child') + else: + menu.AppendMenu(wxNewId(), 'Append Child', m, + 'Create child object as the last child') + else: + if self.shift: + menu.AppendMenu(wxNewId(), 'Create Sibling', m, + 'Create sibling before selected object') + else: + menu.AppendMenu(wxNewId(), 'Create Sibling', m, + 'Create sibling after selected object') + menu.AppendSeparator() + # Not using standart IDs because we don't want to show shortcuts + menu.Append(wxID_CUT, 'Cut', 'Cut to the clipboard') + menu.Append(wxID_COPY, 'Copy', 'Copy to the clipboard') + if self.ctrl and item != self.root: + menu.Append(pullDownMenu.ID_PASTE_SIBLING, 'Paste Sibling', + 'Paste from the clipboard as a sibling') + else: + menu.Append(wxID_PASTE, 'Paste', 'Paste from the clipboard') + menu.Append(pullDownMenu.ID_DELETE, + 'Delete', 'Delete object') + if self.ItemHasChildren(item): + menu.AppendSeparator() + menu.Append(pullDownMenu.ID_EXPAND, 'Expand', 'Expand subtree') + menu.Append(pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse subtree') + self.PopupMenu(menu, evt.GetPosition()) + menu.Destroy() + + # Apply changes + def Apply(self, xxx, item): + g.panel.Apply() + # Update tree view + xxx = xxx.treeObject() + if xxx.hasName and self.GetItemText(item) != xxx.name: + self.SetItemText(item, xxx.treeName()) + # Item width may have changed + # !!! Tric to update tree width (wxGTK, ??) + self.SetIndent(self.GetIndent()) + # Change tree icon for sizers + if isinstance(xxx, xxxBoxSizer): + self.SetItemImage(item, xxx.treeImage()) + # Set global modified state + g.frame.modified = True + diff --git a/wxPython/wxPython/tools/XRCed/undo.py b/wxPython/wxPython/tools/XRCed/undo.py new file mode 100644 index 0000000000..ef9083cdc7 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/undo.py @@ -0,0 +1,151 @@ +# Name: undo.py +# Purpose: XRC editor, undo/redo module +# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be> +# Created: 01.12.2002 +# RCS-ID: $Id$ + +from globals import * +#from panel import * + +# Undo/redo classes +class UndoManager: + # Undo/redo stacks + undo = [] + redo = [] + def RegisterUndo(self, undoObj): + self.undo.append(undoObj) + for i in self.redo: i.destroy() + self.redo = [] + def Undo(self): + undoObj = self.undo.pop() + undoObj.undo() + self.redo.append(undoObj) + g.frame.modified = True + g.frame.SetStatusText('Undone') + def Redo(self): + undoObj = self.redo.pop() + undoObj.redo() + self.undo.append(undoObj) + g.frame.modified = True + g.frame.SetStatusText('Redone') + def Clear(self): + for i in self.undo: i.destroy() + self.undo = [] + for i in self.redo: i.destroy() + self.redo = [] + def CanUndo(self): + return not not self.undo + def CanRedo(self): + return not not self.redo + +class UndoCutDelete: + def __init__(self, itemIndex, parent, elem): + self.itemIndex = itemIndex + self.parent = parent + self.elem = elem + def destroy(self): + if self.elem: self.elem.unlink() + def undo(self): + item = g.tree.InsertNode(g.tree.ItemAtFullIndex(self.itemIndex[:-1]), + self.parent, self.elem, + g.tree.ItemAtFullIndex(self.itemIndex)) + # Scroll to show new item (!!! redundant?) + g.tree.EnsureVisible(item) + g.tree.SelectItem(item) + self.elem = None + # Update testWin if needed + if g.testWin and g.tree.IsHighlatable(item): + if g.conf.autoRefresh: + g.tree.needUpdate = True + g.tree.pendingHighLight = item + else: + g.tree.pendingHighLight = None + def redo(self): + item = g.tree.ItemAtFullIndex(self.itemIndex) + # Delete testWin? + if g.testWin: + # If deleting top-level item, delete testWin + if item == g.testWin.item: + g.testWin.Destroy() + g.testWin = None + else: + # Remove highlight, update testWin + if g.testWin.highLight: + g.testWin.highLight.Remove() + g.tree.needUpdate = True + self.elem = g.tree.RemoveLeaf(item) + g.tree.Unselect() + g.panel.Clear() + +class UndoPasteCreate: + def __init__(self, itemParent, parent, item, selected): + self.itemParentIndex = g.tree.ItemFullIndex(itemParent) + self.parent = parent + self.itemIndex = g.tree.ItemFullIndex(item) # pasted item + self.selectedIndex = g.tree.ItemFullIndex(selected) # maybe different from item + self.elem = None + def destroy(self): + if self.elem: self.elem.unlink() + def undo(self): + self.elem = g.tree.RemoveLeaf(g.tree.ItemAtFullIndex(self.itemIndex)) + # Restore old selection + selected = g.tree.ItemAtFullIndex(self.selectedIndex) + g.tree.EnsureVisible(selected) + g.tree.SelectItem(selected) + # Delete testWin? + if g.testWin: + # If deleting top-level item, delete testWin + if selected == g.testWin.item: + g.testWin.Destroy() + g.testWin = None + else: + # Remove highlight, update testWin + if g.testWin.highLight: + g.testWin.highLight.Remove() + g.tree.needUpdate = True + def redo(self): + item = g.tree.InsertNode(g.tree.ItemAtFullIndex(self.itemParentIndex), + self.parent, self.elem, + g.tree.ItemAtFullIndex(self.itemIndex)) + # Scroll to show new item + g.tree.EnsureVisible(item) + g.tree.SelectItem(item) + self.elem = None + # Update testWin if needed + if g.testWin and g.tree.IsHighlatable(item): + if g.conf.autoRefresh: + g.tree.needUpdate = True + g.tree.pendingHighLight = item + else: + g.tree.pendingHighLight = None + +class UndoEdit: + def __init__(self): + self.pages = map(ParamPage.GetState, g.panel.pages) + self.selectedIndex = g.tree.ItemFullIndex(g.tree.GetSelection()) + def destroy(self): + pass + # Update test view + def update(self, selected): + g.tree.Apply(g.tree.GetPyData(selected), selected) + # Update view + if g.testWin: + if g.testWin.highLight: + g.testWin.highLight.Remove() + g.tree.pendingHighLight = selected + if g.testWin: + g.tree.needUpdate = True + def undo(self): + # Restore selection + selected = g.tree.ItemAtFullIndex(self.selectedIndex) + if selected != g.tree.GetSelection(): + g.tree.SelectItem(selected) + # Save current state for redo + map(ParamPage.SaveState, g.panel.pages) + pages = map(ParamPage.GetState, g.panel.pages) + map(ParamPage.SetState, g.panel.pages, self.pages) + self.pages = pages + self.update(selected) + def redo(self): + self.undo() + self.update(g.tree.GetSelection()) diff --git a/wxPython/wxPython/tools/XRCed/xrced.py b/wxPython/wxPython/tools/XRCed/xrced.py index 7d3c4459a5..bc5a8513ad 100644 --- a/wxPython/wxPython/tools/XRCed/xrced.py +++ b/wxPython/wxPython/tools/XRCed/xrced.py @@ -4,45 +4,52 @@ # Created: 20.08.2001 # RCS-ID: $Id$ -from wxPython.wx import * -from wxPython.xrc import * -from wxPython.html import wxHtmlWindow -from xml.dom import minidom -import os -import getopt +""" -# Icons -import images +xrced -- Simple resource editor for XRC format used by wxWindows/wxPython + GUI toolkit. -# Constants +Usage: -# Return code from wxGetOsVersion -wxGTK = 9 + xrced [ -h ] [ -i ] [ -v ] [ XRC-file ] -if wxGetOsVersion()[0] == wxGTK: - labelFont = wxFont(12, wxDEFAULT, wxNORMAL, wxBOLD) - modernFont = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL) -else: - labelFont = wxFont(10, wxDEFAULT, wxNORMAL, wxBOLD) - modernFont = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL) +Options: -progname = 'XRCed' -version = '0.0.7-3' + -h output short usage info and exit + + -i use international character set instead of translations + + -v output version info and exit +""" -# Local modules -from xxx import * -# Globals -testWin = None -testWinPos = wxDefaultPosition +from globals import * +import os, sys, getopt, re, traceback + +# Local modules +from tree import * # imports xxx which imports params +from panel import * +from tools import * +# Cleanup recursive import sideeffects, otherwise we can't create undoMan +import undo +undo.ParamPage = ParamPage +undoMan = g.undoMan = UndoManager() + +# Set application path for loading resources +if __name__ == '__main__': + basePath = os.path.dirname(sys.argv[0]) +else: + basePath = os.path.dirname(__file__) # 1 adds CMD command to Help menu debug = 0 -helpText = """\ -<HTML><H2>Welcome to XRCed!</H2><H3><font color="green">DON'T PANIC :)</font></H3> +g.helpText = """\ +<HTML><H2>Welcome to XRC<font color="blue">ed</font></H2><H3><font color="green">DON'T PANIC :)</font></H3> +Read this note before clicking on anything!<P> To start select tree root, then popup menu with your right mouse button, select "Append Child", and then any command.<P> +Or just press one of the buttons on the tools palette.<P> Enter XML ID, change properties, create children.<P> To test your interface select Test command (View menu).<P> Consult README file for the details.</HTML> @@ -51,927 +58,6 @@ Consult README file for the details.</HTML> defaultIDs = {xxxPanel:'PANEL', xxxDialog:'DIALOG', xxxFrame:'FRAME', xxxMenuBar:'MENUBAR', xxxMenu:'MENU', xxxToolBar:'TOOLBAR'} -# Set menu to list items. -# Each menu command is a tuple (id, label, help) -# submenus are lists [id, label, help, submenu] -# and separators are any other type -def SetMenu(m, list): - for l in list: - if type(l) == types.TupleType: - apply(m.Append, l) - elif type(l) == types.ListType: - subMenu = wxMenu() - SetMenu(subMenu, l[2:]) - m.AppendMenu(wxNewId(), l[0], subMenu, l[1]) - else: # separator - m.AppendSeparator() - -################################################################################ - -# Properties panel containing notebook -class Panel(wxNotebook): - def __init__(self, parent, id = -1): - wxNotebook.__init__(self, parent, id, style=wxNB_BOTTOM) - ##sys.modules['params'].panel = self - import params - params.panel = self - - # List of child windows - self.pages = [] - # Create scrolled windows for pages - self.page1 = wxScrolledWindow(self, -1) - sizer = wxBoxSizer() - sizer.Add(wxBoxSizer()) # dummy sizer - self.page1.SetAutoLayout(true) - self.page1.SetSizer(sizer) - self.AddPage(self.page1, 'Properties') - # Second page - self.page2 = wxScrolledWindow(self, -1) - sizer = wxBoxSizer() - sizer.Add(wxBoxSizer()) # dummy sizer - self.page2.SetAutoLayout(true) - self.page2.SetSizer(sizer) - # Cache for already used panels - self.pageCache = {} # cached property panels - self.stylePageCache = {} # cached style panels - # Dummy parent window for cache pages - self.cacheParent = wxFrame(None, -1, 'non visible') - # Delete child windows and recreate page sizer - def ResetPage(self, page): - topSizer = page.GetSizer() - sizer = topSizer.GetChildren()[0].GetSizer() - for w in page.GetChildren(): - sizer.RemoveWindow(w) - if isinstance(w, ParamPage): - # With SetParent, we wouldn't need this - w.Reparent(self.cacheParent) - else: - w.Destroy() - topSizer.RemoveSizer(sizer) - # Create new windows - sizer = wxBoxSizer(wxVERTICAL) - # Special case - resize html window - if conf.panic: - topSizer.Add(sizer, 1, wxEXPAND) - else: - topSizer.Add(sizer, 0, wxALL, 5) - return sizer - def SetData(self, xxx): - self.pages = [] - # First page - # Set cached or new page - # Remove current objects and sizer - sizer = self.ResetPage(self.page1) - if not xxx or (not xxx.allParams and not xxx.hasName): - if tree.selection: - sizer.Add(wxStaticText(self.page1, -1, 'This item has no properties.')) - else: # nothing selected - # If first time, show some help - if conf.panic: - html = wxHtmlWindow(self.page1, -1, wxDefaultPosition, - wxDefaultSize, wxSUNKEN_BORDER) - html.SetPage(helpText) - sizer.Add(html, 1, wxEXPAND) - conf.panic = false - else: - sizer.Add(wxStaticText(self.page1, -1, 'Select a tree item.')) - else: - SetCurrentXXX(xxx.treeObject()) - try: - page = self.pageCache[xxx.__class__] - page.Reparent(self.page1) - except KeyError: - page = PropPage(self.page1, xxx.className, xxx) - self.pageCache[xxx.__class__] = page - page.SetValues(xxx) - self.pages.append(page) - sizer.Add(page, 1, wxEXPAND) - if xxx.hasChild: - # Special label for child objects - they may have different GUI - cacheID = (xxx.child.__class__, xxx.__class__) - try: - page = self.pageCache[cacheID] - page.Reparent(self.page1) - except KeyError: - page = PropPage(self.page1, xxx.child.className, xxx.child) - self.pageCache[cacheID] = page - page.SetValues(xxx.child) - self.pages.append(page) - sizer.Add(page, 0, wxEXPAND | wxTOP, 5) - self.page1.Layout() - size = self.page1.GetSizer().GetMinSize() - self.page1.SetScrollbars(1, 1, size.x, size.y, 0, 0, true) - - # Second page - # Create if does not exist - if xxx and xxx.treeObject().hasStyle: - xxx = xxx.treeObject() - # Simplest case: set data if class is the same - sizer = self.ResetPage(self.page2) - try: - page = self.stylePageCache[xxx.__class__] - page.Reparent(self.page2) - except KeyError: - page = StylePage(self.page2, xxx.className + ' style', xxx) - self.stylePageCache[xxx.__class__] = page - page.SetValues(xxx) - self.pages.append(page) - sizer.Add(page, 0, wxEXPAND) - # Add page if not exists - if not self.GetPageCount() == 2: - self.AddPage(self.page2, 'Style') - self.page2.Layout() - size = self.page2.GetSizer().GetMinSize() - self.page2.SetScrollbars(1, 1, size.x, size.y, 0, 0, true) - else: - # Remove page if exists - if self.GetPageCount() == 2: - self.SetSelection(0) - self.page1.Refresh() - self.RemovePage(1) - def Clear(self): - self.SetData(None) - # Check if some parameter on some page has changed - def IsModified(self): - for p in self.pages: - if p.IsModified(): return true - return false - # Reset changed state - def SetModified(self, value): - for p in self.pages: p.SetModified(value) - def Apply(self): - for p in self.pages: p.Apply() - -################################################################################ - -# General class for notebook pages -class ParamPage(wxPanel): - def __init__(self, parent, xxx): - wxPanel.__init__(self, parent, -1) - self.xxx = xxx - # Register event handlers - for id in paramIDs.values(): - EVT_CHECKBOX(self, id, self.OnCheckParams) - self.modified = false - self.checks = {} - self.controls = {} # save python objects - self.controlName = None - def OnCheckParams(self, evt): - xxx = self.xxx - param = evt.GetEventObject().GetName() - w = self.controls[param] - objElem = xxx.element - if evt.IsChecked(): - # Ad new text node in order of allParams - w.SetValue('') # set empty (default) value - w.SetModified() # mark as changed - elem = tree.dom.createElement(param) - # Some classes are special - if param == 'font': - xxx.params[param] = xxxParamFont(xxx.element, elem) - else: - xxx.params[param] = xxxParam(elem) - # Find place to put new element: first present element after param - found = false - paramStyles = xxx.allParams + xxx.styles - for p in paramStyles[paramStyles.index(param) + 1:]: - # Content params don't have same type - if xxx.params.has_key(p) and p != 'content': - found = true - break - if found: - nextTextElem = xxx.params[p].node - objElem.insertBefore(elem, nextTextElem) - else: - objElem.appendChild(elem) - else: - # Remove parameter - xxx.params[param].remove() - del xxx.params[param] - w.SetValue('') - w.modified = false # mark as not changed - # Set modified flas - self.SetModified(true) - w.Enable(evt.IsChecked()) - # If some parameter has changed - def IsModified(self): - return self.modified - def SetModified(self, value): - self.modified = value - def Apply(self): - xxx = self.xxx - # !!! Save undo info -# if xxx.undo: xxx.undo.unlink() -# xxx.undo = xxx.element.cloneNode(false) - if self.controlName: - name = self.controlName.GetValue() - if xxx.name != name: - xxx.name = name - xxx.element.setAttribute('name', name) - for param, w in self.controls.items(): - if w.modified: - paramObj = xxx.params[param] - value = w.GetValue() - if param in xxx.specials: - xxx.setSpecial(param, value) - else: - paramObj.update(value) - -################################################################################ - -# Panel for displaying properties -class PropPage(ParamPage): - def __init__(self, parent, label, xxx): - ParamPage.__init__(self, parent, xxx) - box = wxStaticBox(self, -1, label) - box.SetFont(labelFont) - topSizer = wxStaticBoxSizer(box, wxVERTICAL) - sizer = wxFlexGridSizer(len(xxx.allParams), 2, 1, 1) - if xxx.hasName: - label = wxStaticText(self, -1, 'XML ID:', size=(100,-1)) - control = ParamText(self, name='XML_name') - sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL), - (control, 0, wxALIGN_CENTER_VERTICAL) ]) - self.controlName = control - for param in xxx.allParams: - present = param in xxx.params - if param in xxx.required: - label = wxStaticText(self, paramIDs[param], param + ':', - size = (100,-1), name = param) - else: - # Notebook has one very loooooong parameter - if param == 'usenotebooksizer': sParam = 'usesizer:' - else: sParam = param + ':' - label = wxCheckBox(self, paramIDs[param], sParam, - size = (100,-1), name = param) - self.checks[param] = label - try: - typeClass = xxx.paramDict[param] - except KeyError: - try: - # Standart type - typeClass = paramDict[param] - except KeyError: - # Default - typeClass = ParamText - control = typeClass(self, param) - control.Enable(present) - sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL), - (control, 0, wxALIGN_CENTER_VERTICAL) ]) - self.controls[param] = control - topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3) - self.SetAutoLayout(true) - self.SetSizer(topSizer) - topSizer.Fit(self) - def SetValues(self, xxx): - self.xxx = xxx - # Set values, checkboxes to false, disable defaults - if xxx.hasName: - self.controlName.SetValue(xxx.name) - for param in xxx.allParams: - w = self.controls[param] - w.modified = false - try: - value = xxx.params[param].value() - w.Enable(true) - w.SetValue(value) - if not param in xxx.required: - self.checks[param].SetValue(true) - except KeyError: - self.checks[param].SetValue(false) - w.SetValue('') - w.Enable(false) - self.SetModified(false) - -################################################################################ - -# Style notebook page -class StylePage(ParamPage): - def __init__(self, parent, label, xxx): - ParamPage.__init__(self, parent, xxx) - box = wxStaticBox(self, -1, label) - box.SetFont(labelFont) - topSizer = wxStaticBoxSizer(box, wxVERTICAL) - sizer = wxFlexGridSizer(len(xxx.styles), 2, 1, 1) - for param in xxx.styles: - present = param in xxx.params.keys() - check = wxCheckBox(self, paramIDs[param], - param + ':', size = (100,-1), name = param) - check.SetValue(present) - control = paramDict[param](self, name = param) - control.Enable(present) - sizer.AddMany([ (check, 0, wxALIGN_CENTER_VERTICAL), - (control, 0, wxALIGN_CENTER_VERTICAL) ]) - self.checks[param] = check - self.controls[param] = control - topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3) - self.SetAutoLayout(true) - self.SetSizer(topSizer) - topSizer.Fit(self) - # Set data for a cahced page - def SetValues(self, xxx): - self.xxx = xxx - for param in xxx.styles: - present = param in xxx.params.keys() - check = self.checks[param] - check.SetValue(present) - w = self.controls[param] - w.modified = false - if present: - w.SetValue(xxx.params[param].value()) - else: - w.SetValue('') - w.Enable(present) - self.SetModified(false) - -################################################################################ - -class HightLightBox: - def __init__(self, pos, size): - w = testWin.panel - l1 = wxWindow(w, -1, pos, wxSize(size.x, 2)) - l1.SetBackgroundColour(wxRED) - l2 = wxWindow(w, -1, pos, wxSize(2, size.y)) - l2.SetBackgroundColour(wxRED) - l3 = wxWindow(w, -1, wxPoint(pos.x + size.x - 2, pos.y), wxSize(2, size.y)) - l3.SetBackgroundColour(wxRED) - l4 = wxWindow(w, -1, wxPoint(pos.x, pos.y + size.y - 2), wxSize(size.x, 2)) - l4.SetBackgroundColour(wxRED) - self.lines = [l1, l2, l3, l4] - # Move highlight to a new position - def Replace(self, pos, size): - self.lines[0].SetDimensions(pos.x, pos.y, size.x, 2, wxSIZE_ALLOW_MINUS_ONE) - self.lines[1].SetDimensions(pos.x, pos.y, 2, size.y, wxSIZE_ALLOW_MINUS_ONE) - self.lines[2].SetDimensions(pos.x + size.x - 2, pos.y, 2, size.y, - wxSIZE_ALLOW_MINUS_ONE) - self.lines[3].SetDimensions(pos.x, pos.y + size.y - 2, size.x, 2, - wxSIZE_ALLOW_MINUS_ONE) - # Remove it - def Remove(self): - map(wxWindow.Destroy, self.lines) - testWin.highLight = None - -################################################################################ - -class MemoryFile: - def __init__(self, name): - self.name = name - self.buffer = '' - def write(self, data): - self.buffer += data.encode() - def close(self): - wxMemoryFSHandler_AddFile(self.name, self.buffer) - -class XML_Tree(wxTreeCtrl): - def __init__(self, parent, id): - wxTreeCtrl.__init__(self, parent, id, style = wxTR_HAS_BUTTONS) - self.SetBackgroundColour(wxColour(224, 248, 224)) - EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) - # One works on Linux, another on Windows - if wxGetOsVersion()[0] == wxGTK: - EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated) - else: - EVT_LEFT_DCLICK(self, self.OnDClick) - EVT_RIGHT_DOWN(self, self.OnRightDown) - - self.needUpdate = false - self.pendingHighLight = None - self.ctrl = self.shift = false - self.dom = None - # Create image list - il = wxImageList(16, 16, true) - self.rootImage = il.AddIcon(wxIconFromXPMData(images.getTreeRootData())) - xxxObject.image = il.AddIcon(wxIconFromXPMData(images.getTreeDefaultData())) - xxxPanel.image = il.AddIcon(wxIconFromXPMData(images.getTreePanelData())) - xxxDialog.image = il.AddIcon(wxIconFromXPMData(images.getTreeDialogData())) - xxxFrame.image = il.AddIcon(wxIconFromXPMData(images.getTreeFrameData())) - xxxMenuBar.image = il.AddIcon(wxIconFromXPMData(images.getTreeMenuBarData())) - xxxToolBar.image = il.AddIcon(wxIconFromXPMData(images.getTreeToolBarData())) - xxxMenu.image = il.AddIcon(wxIconFromXPMData(images.getTreeMenuData())) - xxxSizer.imageH = il.AddIcon(wxIconFromXPMData(images.getTreeSizerHData())) - xxxSizer.imageV = il.AddIcon(wxIconFromXPMData(images.getTreeSizerVData())) - xxxStaticBoxSizer.imageH = il.AddIcon(wxIconFromXPMData(images.getTreeStaticBoxSizerHData())) - xxxStaticBoxSizer.imageV = il.AddIcon(wxIconFromXPMData(images.getTreeStaticBoxSizerVData())) - xxxGridSizer.image = il.AddIcon(wxIconFromXPMData(images.getTreeSizerGridData())) - xxxFlexGridSizer.image = il.AddIcon(wxIconFromXPMData(images.getTreeSizerFlexGridData())) - self.il = il - self.SetImageList(il) - - def Unselect(self): - self.selection = None - wxTreeCtrl.Unselect(self) - - def ExpandAll(self, item): - if self.ItemHasChildren(item): - self.Expand(item) - i, cookie = self.GetFirstChild(item, 0) - children = [] - while i.IsOk(): - children.append(i) - i, cookie = self.GetNextChild(item, cookie) - for i in children: - self.ExpandAll(i) - def CollapseAll(self, item): - if self.ItemHasChildren(item): - i, cookie = self.GetFirstChild(item, 0) - children = [] - while i.IsOk(): - children.append(i) - i, cookie = self.GetNextChild(item, cookie) - for i in children: - self.CollapseAll(i) - self.Collapse(item) - - # Clear tree - def Clear(self): - self.DeleteAllItems() - # Add minimal structure - if self.dom: self.dom.unlink() - self.dom = minidom.Document() - self.dummyNode = self.dom.createComment('dummy node') - # Create main node - self.mainNode = self.dom.createElement('resource') - self.dom.appendChild(self.mainNode) - xxx = xxxMainNode(None, self.mainNode) - self.root = self.AddRoot('XML tree', self.rootImage, data=wxTreeItemData(xxx)) - self.SetItemHasChildren(self.root) - self.Expand(self.root) - self.Unselect() - - # Clear old data and set new - def SetData(self, dom): - self.DeleteAllItems() - # Add minimal structure - if self.dom: self.dom.unlink() - self.dom = dom - self.dummyNode = self.dom.createComment('dummy node') - # Find 'resource' child, add it's children - self.mainNode = dom.getElementsByTagName('resource')[0] - xxx = xxxMainNode(None, self.mainNode) - self.root = self.AddRoot('XML tree', self.rootImage, data=wxTreeItemData(xxx)) - self.SetItemHasChildren(self.root) - nodes = self.mainNode.childNodes[:] - for node in nodes: - if IsObject(node): - self.AddNode(self.root, None, node) - else: - self.mainNode.removeChild(node) - node.unlink() - self.Expand(self.root) - self.Unselect() - - # Add tree item for given parent item if node is DOM element node with - # 'object' tag. xxxParent is parent xxx object - def AddNode(self, itemParent, xxxParent, node): - # Set item data to current node - try: - xxx = MakeXXXFromDOM(xxxParent, node) - except: - print 'ERROR: MakeXXXFromDom(%s, %s)' % (xxxParent, node) - raise - treeObj = xxx.treeObject() - # Append tree item - item = self.AppendItem(itemParent, treeObj.treeName(), - image=treeObj.treeImage(), - data=wxTreeItemData(xxx)) - # Try to find children objects - if treeObj.hasChildren: - nodes = treeObj.element.childNodes[:] - for n in nodes: - if IsObject(n): - self.AddNode(item, treeObj, n) - elif n.nodeType != minidom.Node.ELEMENT_NODE: - treeObj.element.removeChild(n) - n.unlink() - # Remove leaf of tree, return it's data object - def RemoveLeaf(self, leaf): - xxx = self.GetPyData(leaf) - node = xxx.element - parent = node.parentNode - parent.removeChild(node) - self.Delete(leaf) - # Reset selection object - self.selection = None - return node - # Find position relative to the top-level window - def FindNodePos(self, item): - # Root at (0,0) - if item == testWin.item: return wxPoint(0, 0) - itemParent = self.GetItemParent(item) - # Select NB page - obj = self.FindNodeObject(item) - if self.GetPyData(itemParent).treeObject().__class__ == xxxNotebook: - notebook = self.FindNodeObject(itemParent) - # Find position - for i in range(notebook.GetPageCount()): - if notebook.GetPage(i) == obj: - if notebook.GetSelection() != i: notebook.SetSelection(i) - break - # Find first ancestor which is a wxWindow (not a sizer) - winParent = itemParent - while self.GetPyData(winParent).isSizer: - winParent = self.GetItemParent(winParent) - parentPos = self.FindNodePos(winParent) - # Position (-1,-1) is really (0,0) - pos = obj.GetPosition() - if pos == (-1,-1): pos = (0,0) - return parentPos + pos - # Find window (or sizer) corresponding to a tree item. - def FindNodeObject(self, item): - if item == testWin.item: return testWin.panel - itemParent = self.GetItemParent(item) - # If top-level, return testWin (or panel if wxFrame) - xxx = self.GetPyData(item).treeObject() - parentWin = self.FindNodeObject(itemParent) - # Top-level sizer? return window's sizer - if xxx.isSizer and isinstance(parentWin, wxWindowPtr): - return parentWin.GetSizer() - # Otherwise get parent's object and it's child - n = 0 # index of sibling - prev = self.GetPrevSibling(item) - while prev.IsOk(): - prev = self.GetPrevSibling(prev) - n += 1 - child = parentWin.GetChildren()[n] - # Return window or sizer for sizer items - if child.GetClassName() == 'wxSizerItem': - if child.IsWindow(): child = child.GetWindow() - elif child.IsSizer(): - child = child.GetSizer() - # Test for notebook sizers - if isinstance(child, wxNotebookSizerPtr): - child = child.GetNotebook() - return child - def OnSelChanged(self, evt): - # Apply changes - # !!! problem with wxGTK - GetOldItem is Ok if nothing selected - #oldItem = evt.GetOldItem() - status = '' - oldItem = self.selection - if oldItem: - xxx = self.GetPyData(oldItem) - # If some data was modified, apply changes - if panel.IsModified(): - self.Apply(xxx, oldItem) - #if conf.autoRefresh: - if testWin: - if testWin.highLight and not tree.IsHighlatable(oldItem): - testWin.highLight.Remove() - self.needUpdate = true - status = 'Changes were applied' - frame.SetStatusText(status) - # Generate view - self.selection = evt.GetItem() - if not self.selection.IsOk(): - self.selection = None - return - xxx = self.GetPyData(self.selection) - # Update panel - panel.SetData(xxx) - # Clear flag - panel.SetModified(false) - # Hightlighting is done in OnIdle - tree.pendingHighLight = self.selection - # Check if item is in testWin subtree - def IsHighlatable(self, item): - if item == testWin.item: return false - while item != self.root: - item = self.GetItemParent(item) - if item == testWin.item: return true - return false - # Highlight selected item - def HighLight(self, item): - self.pendingHighLight = None - if not testWin or self.GetPyData(testWin.item).className \ - not in ['wxDialog', 'wxPanel', 'wxFrame']: - return - # Top-level does not have highlight - if item == testWin.item or item == tree.root: - if testWin.highLight: testWin.highLight.Remove() - return - # If a control from another window is selected, remove highlight - if not self.IsHighlatable(item): - if testWin.highLight: testWin.highLight.Remove() - return - # Get window/sizer object - obj, pos = self.FindNodeObject(item), self.FindNodePos(item) - size = obj.GetSize() - # Highlight - # Nagative positions are not working wuite well - if testWin.highLight: - testWin.highLight.Replace(pos, size) - else: - testWin.highLight = HightLightBox(pos, size) - testWin.highLight.item = item - def ShowTestWindow(self, item): - global testWin - xxx = self.GetPyData(item) - if panel.IsModified(): - self.Apply(xxx, item) # apply changes - treeObj = xxx.treeObject() - if treeObj.className not in ['wxFrame', 'wxPanel', 'wxDialog', - 'wxMenuBar', 'wxToolBar']: - wxLogMessage('No view for this element (yet)') - return - if not treeObj.name: - wxLogError("Can't display a noname element!") - return - # Show item in bold - if testWin: - self.SetItemBold(testWin.item, false) - self.SetItemBold(item) - self.CreateTestWin(item) - # Double-click on Linux - def OnItemActivated(self, evt): - if evt.GetItem() != self.root: - self.ShowTestWindow(evt.GetItem()) - # Double-click on Windows - def OnDClick(self, evt): - item, flags = self.HitTest(evt.GetPosition()) - if flags in [wxTREE_HITTEST_ONITEMBUTTON, wxTREE_HITTEST_ONITEMLABEL]: - if item != self.root: self.ShowTestWindow(item) - else: - evt.Skip() - # (re)create test window - def CreateTestWin(self, item): - global testWin - wxBeginBusyCursor() - # Create a window with this resource - xxx = self.GetPyData(item).treeObject() - # Close old window, remember where it was - highLight = None - if testWin: - pos = testWin.GetPosition() - if item == testWin.item: - # Remember highlight if same top-level window - if testWin.highLight: - highLight = testWin.highLight.item - # !!! if 0 is removed, refresh is broken (notebook not deleted?) - if xxx.className == 'wxPanel': - if testWin.highLight: - testWin.pendingHighLight = highLight - testWin.highLight.Remove() - testWin.panel.Destroy() - testWin.panel = None - else: - testWin.Destroy() - testWin = None - else: - testWin.Destroy() - testWin = None - else: - pos = testWinPos - # Save in memory FS - memFile = MemoryFile('xxx.xrc') - # Create partial XML file - faster for big files - - dom = minidom.Document() - mainNode = dom.createElement('resource') - dom.appendChild(mainNode) - - # Remove temporarily from old parent - elem = xxx.element - parent = elem.parentNode - next = elem.nextSibling - parent.replaceChild(self.dummyNode, elem) - # Append to new DOM, write it - mainNode.appendChild(elem) - dom.writexml(memFile) - # Put back in place - mainNode.removeChild(elem) - dom.unlink() - parent.replaceChild(elem, self.dummyNode) - memFile.close() # write to wxMemoryFS - res = wxXmlResource('') - res.Load('memory:xxx.xrc') - if xxx.className == 'wxFrame': - # Create new frame - testWin = wxPreFrame() - res.LoadOnFrame(testWin, frame, xxx.name) - # Create status bar - testWin.CreateStatusBar() - testWin.panel = testWin - testWin.SetPosition(pos) - testWin.Show(true) - elif xxx.className == 'wxPanel': - # Create new frame - if not testWin: - testWin = wxFrame(frame, -1, 'Panel: ' + xxx.name, pos=pos) - testWin.panel = res.LoadPanel(testWin, xxx.name) - testWin.SetClientSize(testWin.panel.GetSize()) - testWin.Show(true) - elif xxx.className == 'wxDialog': - # Create new frame - testWin = res.LoadDialog(None, xxx.name) - testWin.panel = testWin - testWin.Layout() - testWin.SetPosition(pos) - testWin.Show(true) - elif xxx.className == 'wxMenuBar': - testWin = wxFrame(frame, -1, 'MenuBar: ' + xxx.name, pos=pos) - testWin.panel = None - # Set status bar to display help - testWin.CreateStatusBar() - testWin.menuBar = res.LoadMenuBar(xxx.name) - testWin.SetMenuBar(testWin.menuBar) - testWin.Show(true) - elif xxx.className == 'wxToolBar': - testWin = wxFrame(frame, -1, 'ToolBar: ' + xxx.name, pos=pos) - testWin.panel = None - # Set status bar to display help - testWin.CreateStatusBar() - testWin.toolBar = res.LoadToolBar(testWin, xxx.name) - testWin.SetToolBar(testWin.toolBar) - testWin.Show(true) - wxMemoryFSHandler_RemoveFile('xxx.xrc') - testWin.item = item - EVT_CLOSE(testWin, self.OnCloseTestWin) - EVT_BUTTON(testWin, wxID_OK, self.OnCloseTestWin) - EVT_BUTTON(testWin, wxID_CANCEL, self.OnCloseTestWin) - testWin.highLight = None - if highLight and not tree.pendingHighLight: - self.HighLight(highLight) - wxEndBusyCursor() - - def OnCloseTestWin(self, evt): - global testWin, testWinPos - self.SetItemBold(testWin.item, false) - testWinPos = testWin.GetPosition() - testWin.Destroy() - testWin = None - - # Return item index in parent - def ItemIndex(self, parent, item): - i = 0 - it, cookie = self.GetFirstChild(parent, 0) - while it != item: - i += 1 - it, cookie = self.GetNextChild(parent, cookie) - return i - - # True if next item should be inserted after current (vs. appended to it) - def NeedInsert(self, item): - xxx = self.GetPyData(item) - if item == self.root: return false # root item - if xxx.hasChildren and not self.GetChildrenCount(item, false): - return false - return not (self.IsExpanded(item) and self.GetChildrenCount(item, false)) - - # Pull-down - def OnRightDown(self, evt): - # select this item - pt = evt.GetPosition(); - item, flags = self.HitTest(pt) - if item.Ok() and flags & wxTREE_HITTEST_ONITEM: - self.SelectItem(item) - - # Setup menu - menu = wxMenu() - - item = self.selection - if not item: - menu.Append(pullDownMenu.ID_EXPAND, 'Expand', 'Expand tree') - menu.Append(pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse tree') - else: - self.ctrl = evt.ControlDown() # save Ctrl state - self.shift = evt.ShiftDown() # and Shift too - m = wxMenu() # create menu - if self.ctrl: - needInsert = true - else: - needInsert = self.NeedInsert(item) - if item == self.root or needInsert and self.GetItemParent(item) == self.root: - m.Append(pullDownMenu.ID_NEW_PANEL, 'Panel', 'Create panel') - m.Append(pullDownMenu.ID_NEW_DIALOG, 'Dialog', 'Create dialog') - m.Append(pullDownMenu.ID_NEW_FRAME, 'Frame', 'Create frame') - m.AppendSeparator() - m.Append(pullDownMenu.ID_NEW_TOOL_BAR, 'ToolBar', 'Create toolbar') - m.Append(pullDownMenu.ID_NEW_MENU_BAR, 'MenuBar', 'Create menubar') - m.Append(pullDownMenu.ID_NEW_MENU, 'Menu', 'Create menu') - else: - xxx = self.GetPyData(item).treeObject() - # Check parent for possible child nodes if inserting sibling - if needInsert: xxx = xxx.parent - if xxx.__class__ == xxxMenuBar: - m.Append(pullDownMenu.ID_NEW_MENU, 'Menu', 'Create menu') - elif xxx.__class__ in [xxxToolBar, xxxTool] or \ - xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar: - SetMenu(m, pullDownMenu.toolBarControls) - elif xxx.__class__ in [xxxMenu, xxxMenuItem]: - SetMenu(m, pullDownMenu.menuControls) - else: - SetMenu(m, pullDownMenu.controls) - if xxx.__class__ == xxxNotebook: - m.Enable(m.FindItem('sizer'), false) - elif not (xxx.isSizer or xxx.parent and xxx.parent.isSizer): - m.Enable(pullDownMenu.ID_NEW_SPACER, false) - # Select correct label for create menu - if not needInsert: - if self.shift: - menu.AppendMenu(wxNewId(), 'Insert Child', m, - 'Create child object as the first child') - else: - menu.AppendMenu(wxNewId(), 'Append Child', m, - 'Create child object as the last child') - else: - if self.shift: - menu.AppendMenu(wxNewId(), 'Create Sibling', m, - 'Create sibling before selected object') - else: - menu.AppendMenu(wxNewId(), 'Create Sibling', m, - 'Create sibling after selected object') - menu.AppendSeparator() - # Not using standart IDs because we don't want to show shortcuts - menu.Append(wxID_CUT, 'Cut', 'Cut to the clipboard') - menu.Append(wxID_COPY, 'Copy', 'Copy to the clipboard') - if self.ctrl and item != tree.root: - menu.Append(pullDownMenu.ID_PASTE_SIBLING, 'Paste Sibling', - 'Paste from the clipboard as a sibling') - else: - menu.Append(wxID_PASTE, 'Paste', 'Paste from the clipboard') - menu.Append(pullDownMenu.ID_DELETE, - 'Delete', 'Delete object') - if self.ItemHasChildren(item): - menu.AppendSeparator() - menu.Append(pullDownMenu.ID_EXPAND, 'Expand', 'Expand subtree') - menu.Append(pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse subtree') - self.PopupMenu(menu, evt.GetPosition()) - menu.Destroy() - - # Apply changes - def Apply(self, xxx, item): - panel.Apply() - # Update tree view - xxx = xxx.treeObject() - if xxx.hasName and self.GetItemText(item) != xxx.name: - self.SetItemText(item, xxx.treeName()) - # Change tree icon for sizers - if isinstance(xxx, xxxBoxSizer): - self.SetItemImage(item, xxx.treeImage()) - # Set global modified state - frame.modified = true - -class PullDownMenu: - ID_NEW_PANEL = wxNewId() - ID_NEW_DIALOG = wxNewId() - ID_NEW_FRAME = wxNewId() - ID_NEW_TOOL_BAR = wxNewId() - ID_NEW_TOOL = wxNewId() - ID_NEW_MENU_BAR = wxNewId() - ID_NEW_MENU = wxNewId() - - ID_NEW_STATIC_TEXT = wxNewId() - ID_NEW_TEXT_CTRL = wxNewId() - - ID_NEW_BUTTON = wxNewId() - ID_NEW_BITMAP_BUTTON = wxNewId() - ID_NEW_RADIO_BUTTON = wxNewId() - ID_NEW_SPIN_BUTTON = wxNewId() - - ID_NEW_STATIC_BOX = wxNewId() - ID_NEW_CHECK_BOX = wxNewId() - ID_NEW_RADIO_BOX = wxNewId() - ID_NEW_COMBO_BOX = wxNewId() - ID_NEW_LIST_BOX = wxNewId() - - ID_NEW_STATIC_LINE = wxNewId() - ID_NEW_STATIC_BITMAP = wxNewId() - ID_NEW_CHOICE = wxNewId() - ID_NEW_SLIDER = wxNewId() - ID_NEW_GAUGE = wxNewId() - ID_NEW_SCROLL_BAR = wxNewId() - ID_NEW_TREE_CTRL = wxNewId() - ID_NEW_LIST_CTRL = wxNewId() - ID_NEW_CHECK_LIST = wxNewId() - ID_NEW_NOTEBOOK = wxNewId() - ID_NEW_HTML_WINDOW = wxNewId() - ID_NEW_CALENDAR = wxNewId() - - ID_NEW_BOX_SIZER = wxNewId() - ID_NEW_STATIC_BOX_SIZER = wxNewId() - ID_NEW_GRID_SIZER = wxNewId() - ID_NEW_FLEX_GRID_SIZER = wxNewId() - ID_NEW_SPACER = wxNewId() - ID_NEW_TOOL_BAR = wxNewId() - ID_NEW_TOOL = wxNewId() - ID_NEW_MENU = wxNewId() - ID_NEW_MENU_ITEM = wxNewId() - ID_NEW_SEPARATOR = wxNewId() - ID_NEW_LAST = wxNewId() - ID_EXPAND = wxNewId() - ID_COLLAPSE = wxNewId() - ID_PASTE_SIBLING = wxNewId() - - def __init__(self, parent): - self.ID_DELETE = parent.ID_DELETE - EVT_MENU_RANGE(parent, self.ID_NEW_PANEL, - self.ID_NEW_LAST, parent.OnCreate) - EVT_MENU(parent, self.ID_COLLAPSE, parent.OnCollapse) - EVT_MENU(parent, self.ID_EXPAND, parent.OnExpand) - EVT_MENU(parent, self.ID_PASTE_SIBLING, parent.OnPaste) - # We connect to tree, but process in frame - EVT_MENU_HIGHLIGHT_ALL(tree, parent.OnPullDownHighlight) - ################################################################################ # ScrolledMessageDialog - modified from wxPython lib to set fixed-width font @@ -983,12 +69,13 @@ class ScrolledMessageDialog(wxDialog): wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY) text.SetFont(modernFont) dc = wxWindowDC(text) - w, h = dc.GetTextExtent(' ') + # !!! possible bug - GetTextExtent without font returns sysfont dims + w, h = dc.GetFullTextExtent(' ', modernFont)[:2] ok = wxButton(self, wxID_OK, "OK") text.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok))) text.SetSize((w * 80 + 30, h * 40)) ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,))) - self.SetAutoLayout(TRUE) + self.SetAutoLayout(True) self.Fit() self.CenterOnScreen(wxBOTH) @@ -996,16 +83,15 @@ class ScrolledMessageDialog(wxDialog): class Frame(wxFrame): def __init__(self, pos, size): - global frame - frame = self wxFrame.__init__(self, None, -1, '', pos, size) - self.CreateStatusBar() - icon = wxEmptyIcon() - icon.CopyFromBitmap(images.getIconBitmap()) - self.SetIcon(icon) + global frame + frame = g.frame = self + bar = self.CreateStatusBar(2) + bar.SetStatusWidths([-1, 40]) + self.SetIcon(images.getIconIcon()) # Idle flag - self.inIdle = false + self.inIdle = False # Make menus menuBar = wxMenuBar() @@ -1028,13 +114,19 @@ class Frame(wxFrame): menu.Append(wxID_PASTE, '&Paste\tCtrl-V', 'Paste from the clipboard') self.ID_DELETE = wxNewId() menu.Append(self.ID_DELETE, '&Delete\tCtrl-D', 'Delete object') +# menu.AppendSeparator() + ID_SELECT = wxNewId() +# menu.Append(ID_SELECT, '&Select', 'Select object') menuBar.Append(menu, '&Edit') menu = wxMenu() self.ID_EMBED_PANEL = wxNewId() menu.Append(self.ID_EMBED_PANEL, '&Embed Panel', - 'Toggle embedding properties panel in the main window', true) + 'Toggle embedding properties panel in the main window', True) menu.Check(self.ID_EMBED_PANEL, conf.embedPanel) + self.ID_SHOW_TOOLS = wxNewId() + menu.Append(self.ID_SHOW_TOOLS, 'Show &Tools', 'Toggle tools', True) + menu.Check(self.ID_SHOW_TOOLS, conf.showTools) menu.AppendSeparator() self.ID_TEST = wxNewId() menu.Append(self.ID_TEST, '&Test\tF5', 'Test window') @@ -1042,7 +134,7 @@ class Frame(wxFrame): menu.Append(self.ID_REFRESH, '&Refresh\tCtrl-R', 'Refresh test window') self.ID_AUTO_REFRESH = wxNewId() menu.Append(self.ID_AUTO_REFRESH, '&Auto-refresh\tCtrl-A', - 'Toggle auto-refresh mode', true) + 'Toggle auto-refresh mode', True) menu.Check(self.ID_AUTO_REFRESH, conf.autoRefresh) menuBar.Append(menu, '&View') @@ -1066,6 +158,9 @@ class Frame(wxFrame): tb.AddSimpleTool(wxID_OPEN, images.getOpenBitmap(), 'Open', 'Open file') tb.AddSimpleTool(wxID_SAVE, images.getSaveBitmap(), 'Save', 'Save file') tb.AddControl(wxStaticLine(tb, -1, size=(-1,23), style=wxLI_VERTICAL)) + tb.AddSimpleTool(wxID_UNDO, images.getUndoBitmap(), 'Undo', 'Undo') + tb.AddSimpleTool(wxID_REDO, images.getRedoBitmap(), 'Redo', 'Redo') + tb.AddControl(wxStaticLine(tb, -1, size=(-1,23), style=wxLI_VERTICAL)) tb.AddSimpleTool(wxID_CUT, images.getCutBitmap(), 'Cut', 'Cut') tb.AddSimpleTool(wxID_COPY, images.getCopyBitmap(), 'Copy', 'Copy') tb.AddSimpleTool(wxID_PASTE, images.getPasteBitmap(), 'Paste', 'Paste') @@ -1074,8 +169,8 @@ class Frame(wxFrame): tb.AddSimpleTool(self.ID_REFRESH, images.getRefreshBitmap(), 'Refresh', 'Refresh view') tb.AddSimpleTool(self.ID_AUTO_REFRESH, images.getAutoRefreshBitmap(), - 'Auto-refresh', 'Toggle auto-refresh mode', true) - if wxGetOsVersion()[0] == wxGTK: + 'Auto-refresh', 'Toggle auto-refresh mode', True) + if wxPlatform == '__WXGTK__': tb.AddSeparator() # otherwise auto-refresh sticks in status line tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh) tb.Realize() @@ -1091,12 +186,14 @@ class Frame(wxFrame): # Edit EVT_MENU(self, wxID_UNDO, self.OnUndo) EVT_MENU(self, wxID_REDO, self.OnRedo) - EVT_MENU(self, wxID_CUT, self.OnCut) + EVT_MENU(self, wxID_CUT, self.OnCutDelete) EVT_MENU(self, wxID_COPY, self.OnCopy) EVT_MENU(self, wxID_PASTE, self.OnPaste) - EVT_MENU(self, self.ID_DELETE, self.OnDelete) + EVT_MENU(self, self.ID_DELETE, self.OnCutDelete) + EVT_MENU(self, ID_SELECT, self.OnSelect) # View EVT_MENU(self, self.ID_EMBED_PANEL, self.OnEmbedPanel) + EVT_MENU(self, self.ID_SHOW_TOOLS, self.OnShowTools) EVT_MENU(self, self.ID_TEST, self.OnTest) EVT_MENU(self, self.ID_REFRESH, self.OnRefresh) EVT_MENU(self, self.ID_AUTO_REFRESH, self.OnAutoRefresh) @@ -1108,6 +205,8 @@ class Frame(wxFrame): EVT_UPDATE_UI(self, wxID_CUT, self.OnUpdateUI) EVT_UPDATE_UI(self, wxID_COPY, self.OnUpdateUI) EVT_UPDATE_UI(self, wxID_PASTE, self.OnUpdateUI) + EVT_UPDATE_UI(self, wxID_UNDO, self.OnUpdateUI) + EVT_UPDATE_UI(self, wxID_REDO, self.OnUpdateUI) EVT_UPDATE_UI(self, self.ID_DELETE, self.OnUpdateUI) EVT_UPDATE_UI(self, self.ID_TEST, self.OnUpdateUI) EVT_UPDATE_UI(self, self.ID_REFRESH, self.OnUpdateUI) @@ -1115,16 +214,25 @@ class Frame(wxFrame): # Build interface sizer = wxBoxSizer(wxVERTICAL) sizer.Add(wxStaticLine(self, -1), 0, wxEXPAND) + # Horizontal sizer for toolbar and splitter + self.toolsSizer = sizer1 = wxBoxSizer() splitter = wxSplitterWindow(self, -1, style=wxSP_3DSASH) self.splitter = splitter splitter.SetMinimumPaneSize(100) - # Create tree global tree - tree = XML_Tree(splitter, -1) - ##sys.modules['xxx'].tree = tree - import xxx - xxx.tree = tree + g.tree = tree = XML_Tree(splitter, -1) + + # Init pull-down menu data + global pullDownMenu + g.pullDownMenu = pullDownMenu = PullDownMenu(self) + + # Vertical toolbar for GUI buttons + g.tools = tools = Tools(self) + tools.Show(conf.showTools) + if conf.showTools: sizer1.Add(tools, 0, wxEXPAND) + + tree.RegisterKeyEvents() # !!! frame styles are broken # Miniframe for not embedded mode @@ -1133,7 +241,7 @@ class Frame(wxFrame): (conf.panelWidth, conf.panelHeight)) self.miniFrame = miniFrame sizer2 = wxBoxSizer() - miniFrame.SetAutoLayout(true) + miniFrame.SetAutoLayout(True) miniFrame.SetSizer(sizer2) EVT_CLOSE(self.miniFrame, self.OnCloseMiniFrame) # Create panel for parameters @@ -1145,142 +253,23 @@ class Frame(wxFrame): else: panel = Panel(miniFrame) sizer2.Add(panel, 1, wxEXPAND) - miniFrame.Show(true) + miniFrame.Show(True) splitter.Initialize(tree) - sizer.Add(splitter, 1, wxEXPAND) - self.SetAutoLayout(true) + sizer1.Add(splitter, 1, wxEXPAND) + sizer.Add(sizer1, 1, wxEXPAND) + self.SetAutoLayout(True) self.SetSizer(sizer) - # Init pull-down menu data - global pullDownMenu - pullDownMenu = PullDownMenu(self) - # Mapping from IDs to element names - self.createMap = { - pullDownMenu.ID_NEW_PANEL: 'wxPanel', - pullDownMenu.ID_NEW_DIALOG: 'wxDialog', - pullDownMenu.ID_NEW_FRAME: 'wxFrame', - pullDownMenu.ID_NEW_TOOL_BAR: 'wxToolBar', - pullDownMenu.ID_NEW_TOOL: 'tool', - pullDownMenu.ID_NEW_MENU_BAR: 'wxMenuBar', - pullDownMenu.ID_NEW_MENU: 'wxMenu', - pullDownMenu.ID_NEW_MENU_ITEM: 'wxMenuItem', - pullDownMenu.ID_NEW_SEPARATOR: 'separator', - - pullDownMenu.ID_NEW_STATIC_TEXT: 'wxStaticText', - pullDownMenu.ID_NEW_TEXT_CTRL: 'wxTextCtrl', - - pullDownMenu.ID_NEW_BUTTON: 'wxButton', - pullDownMenu.ID_NEW_BITMAP_BUTTON: 'wxBitmapButton', - pullDownMenu.ID_NEW_RADIO_BUTTON: 'wxRadioButton', - pullDownMenu.ID_NEW_SPIN_BUTTON: 'wxSpinButton', - - pullDownMenu.ID_NEW_STATIC_BOX: 'wxStaticBox', - pullDownMenu.ID_NEW_CHECK_BOX: 'wxCheckBox', - pullDownMenu.ID_NEW_RADIO_BOX: 'wxRadioBox', - pullDownMenu.ID_NEW_COMBO_BOX: 'wxComboBox', - pullDownMenu.ID_NEW_LIST_BOX: 'wxListBox', - - pullDownMenu.ID_NEW_STATIC_LINE: 'wxStaticLine', - pullDownMenu.ID_NEW_STATIC_BITMAP: 'wxStaticBitmap', - pullDownMenu.ID_NEW_CHOICE: 'wxChoice', - pullDownMenu.ID_NEW_SLIDER: 'wxSlider', - pullDownMenu.ID_NEW_GAUGE: 'wxGauge', - pullDownMenu.ID_NEW_SCROLL_BAR: 'wxScrollBar', - pullDownMenu.ID_NEW_TREE_CTRL: 'wxTreeCtrl', - pullDownMenu.ID_NEW_LIST_CTRL: 'wxListCtrl', - pullDownMenu.ID_NEW_CHECK_LIST: 'wxCheckList', - pullDownMenu.ID_NEW_NOTEBOOK: 'wxNotebook', - pullDownMenu.ID_NEW_HTML_WINDOW: 'wxHtmlWindow', - pullDownMenu.ID_NEW_CALENDAR: 'wxCalendar', - - pullDownMenu.ID_NEW_BOX_SIZER: 'wxBoxSizer', - pullDownMenu.ID_NEW_STATIC_BOX_SIZER: 'wxStaticBoxSizer', - pullDownMenu.ID_NEW_GRID_SIZER: 'wxGridSizer', - pullDownMenu.ID_NEW_FLEX_GRID_SIZER: 'wxFlexGridSizer', - pullDownMenu.ID_NEW_SPACER: 'spacer', - } - pullDownMenu.controls = [ - ['control', 'Various controls', - (pullDownMenu.ID_NEW_STATIC_TEXT, 'Label', 'Create static label'), - (pullDownMenu.ID_NEW_STATIC_LINE, 'Line', 'Create static line'), - (pullDownMenu.ID_NEW_TEXT_CTRL, 'TextBox', 'Create text box control'), - (pullDownMenu.ID_NEW_CHOICE, 'Choice', 'Create choice control'), - (pullDownMenu.ID_NEW_SLIDER, 'Slider', 'Create slider control'), - (pullDownMenu.ID_NEW_GAUGE, 'Gauge', 'Create gauge control'), - (pullDownMenu.ID_NEW_SCROLL_BAR, 'ScrollBar', 'Create scroll bar'), - (pullDownMenu.ID_NEW_TREE_CTRL, 'TreeCtrl', 'Create tree control'), - (pullDownMenu.ID_NEW_LIST_CTRL, 'ListCtrl', 'Create list control'), - (pullDownMenu.ID_NEW_HTML_WINDOW, 'HtmlWindow', 'Create HTML window'), - (pullDownMenu.ID_NEW_CALENDAR, 'Calendar', 'Create calendar control'), - (pullDownMenu.ID_NEW_PANEL, 'Panel', 'Create panel'), - (pullDownMenu.ID_NEW_NOTEBOOK, 'Notebook', 'Create notebook control'), - ], - ['button', 'Buttons', - (pullDownMenu.ID_NEW_BUTTON, 'Button', 'Create button'), - (pullDownMenu.ID_NEW_BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'), - (pullDownMenu.ID_NEW_RADIO_BUTTON, 'RadioButton', 'Create radio button'), - (pullDownMenu.ID_NEW_SPIN_BUTTON, 'SpinButton', 'Create spin button'), - ], - ['box', 'Boxes', - (pullDownMenu.ID_NEW_STATIC_BOX, 'StaticBox', 'Create static box'), - (pullDownMenu.ID_NEW_CHECK_BOX, 'CheckBox', 'Create check box'), - (pullDownMenu.ID_NEW_RADIO_BOX, 'RadioBox', 'Create radio box'), - (pullDownMenu.ID_NEW_COMBO_BOX, 'ComboBox', 'Create combo box'), - (pullDownMenu.ID_NEW_LIST_BOX, 'ListBox', 'Create list box'), - (pullDownMenu.ID_NEW_CHECK_LIST, 'CheckListBox', - 'Create check list control'), - ], - ['sizer', 'Sizers', - (pullDownMenu.ID_NEW_BOX_SIZER, 'BoxSizer', 'Create box sizer'), - (pullDownMenu.ID_NEW_STATIC_BOX_SIZER, 'StaticBoxSizer', - 'Create static box sizer'), - (pullDownMenu.ID_NEW_GRID_SIZER, 'GridSizer', 'Create grid sizer'), - (pullDownMenu.ID_NEW_FLEX_GRID_SIZER, 'FlexGridSizer', - 'Create flexgrid sizer'), - (pullDownMenu.ID_NEW_SPACER, 'Spacer', 'Create spacer'), - ] - ] - pullDownMenu.menuControls = [ - (pullDownMenu.ID_NEW_MENU, 'Menu', 'Create menu'), - (pullDownMenu.ID_NEW_MENU_ITEM, 'MenuItem', 'Create menu item'), - (pullDownMenu.ID_NEW_SEPARATOR, 'Separator', 'Create separator'), - ] - pullDownMenu.toolBarControls = [ - (pullDownMenu.ID_NEW_TOOL, 'Tool', 'Create tool'), - (pullDownMenu.ID_NEW_SEPARATOR, 'Separator', 'Create separator'), - ['control', 'Various controls', - (pullDownMenu.ID_NEW_STATIC_TEXT, 'Label', 'Create static label'), - (pullDownMenu.ID_NEW_STATIC_LINE, 'Line', 'Create static line'), - (pullDownMenu.ID_NEW_TEXT_CTRL, 'TextBox', 'Create text box control'), - (pullDownMenu.ID_NEW_CHOICE, 'Choice', 'Create choice control'), - (pullDownMenu.ID_NEW_SLIDER, 'Slider', 'Create slider control'), - (pullDownMenu.ID_NEW_GAUGE, 'Gauge', 'Create gauge control'), - (pullDownMenu.ID_NEW_SCROLL_BAR, 'ScrollBar', 'Create scroll bar'), - (pullDownMenu.ID_NEW_LIST_CTRL, 'ListCtrl', 'Create list control'), - ], - ['button', 'Buttons', - (pullDownMenu.ID_NEW_BUTTON, 'Button', 'Create button'), - (pullDownMenu.ID_NEW_BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'), - (pullDownMenu.ID_NEW_RADIO_BUTTON, 'RadioButton', 'Create radio button'), - (pullDownMenu.ID_NEW_SPIN_BUTTON, 'SpinButton', 'Create spin button'), - ], - ['box', 'Boxes', - (pullDownMenu.ID_NEW_STATIC_BOX, 'StaticBox', 'Create static box'), - (pullDownMenu.ID_NEW_CHECK_BOX, 'CheckBox', 'Create check box'), - (pullDownMenu.ID_NEW_RADIO_BOX, 'RadioBox', 'Create radio box'), - (pullDownMenu.ID_NEW_COMBO_BOX, 'ComboBox', 'Create combo box'), - (pullDownMenu.ID_NEW_LIST_BOX, 'ListBox', 'Create list box'), - (pullDownMenu.ID_NEW_CHECK_LIST, 'CheckListBox', - 'Create check list control'), - ], - ] - # Initialize + self.clipboard = None self.Clear() # Other events EVT_IDLE(self, self.OnIdle) EVT_CLOSE(self, self.OnCloseWindow) + EVT_LEFT_DOWN(self, self.OnLeftDown) + EVT_KEY_DOWN(self, tools.OnKeyDown) + EVT_KEY_UP(self, tools.OnKeyUp) def OnNew(self, evt): self.Clear() @@ -1294,12 +283,10 @@ class Frame(wxFrame): self.SetStatusText('Loading...') wxYield() wxBeginBusyCursor() - try: - self.Open(path) + if self.Open(path): self.SetStatusText('Data loaded') - except: + else: self.SetStatusText('Failed') - raise wxEndBusyCursor() dlg.Destroy() @@ -1333,104 +320,74 @@ class Frame(wxFrame): self.Close() def OnUndo(self, evt): - print '*** being implemented' - return - print self.lastOp, self.undo - if self.lastOp == 'DELETE': - parent, prev, elem = self.undo - if prev.IsOk(): - xxx = MakeXXXFromDOM(tree.GetPyData(parent).treeObject(), elem) - item = tree.InsertItem( parent, prev, xxx.treeObject().className, - data=wxTreeItemData(xxx) ) + # Extra check to not mess with idle updating + if undoMan.CanUndo(): + undoMan.Undo() def OnRedo(self, evt): - print '*** being implemented' - - def OnCut(self, evt): - selected = tree.selection - if not selected: return # key pressed event - # Undo info - self.lastOp = 'CUT' - self.undo = [tree.GetItemParent(selected), tree.GetPrevSibling(selected)] - # Delete testWin? - global testWin - if testWin: - # If deleting top-level item, delete testWin - if selected == testWin.item: - testWin.Destroy() - testWin = None - else: - # Remove highlight, update testWin - if not tree.IsHighlatable(selected): - if testWin.highLight: testWin.highLight.Remove() - tree.needUpdate = true - self.clipboard = tree.RemoveLeaf(selected) - tree.pendingHighLight = None - tree.Unselect() - panel.Clear() - self.modified = true - self.SetStatusText('Removed to clipboard') + if undoMan.CanRedo(): + undoMan.Redo() def OnCopy(self, evt): selected = tree.selection if not selected: return # key pressed event xxx = tree.GetPyData(selected) - self.clipboard = xxx.element.cloneNode(true) + self.clipboard = xxx.element.cloneNode(True) self.SetStatusText('Copied') def OnPaste(self, evt): selected = tree.selection if not selected: return # key pressed event # For pasting with Ctrl pressed - if evt.GetId() == pullDownMenu.ID_PASTE_SIBLING: appendChild = false + if evt.GetId() == pullDownMenu.ID_PASTE_SIBLING: appendChild = False else: appendChild = not tree.NeedInsert(selected) xxx = tree.GetPyData(selected) if not appendChild: # If has next item, insert, else append to parent nextItem = tree.GetNextSibling(selected) - if nextItem.IsOk(): - # Insert before nextItem - parentLeaf = tree.GetItemParent(selected) - else: # last child: change selected to parent - appendChild = true - selected = tree.GetItemParent(selected) + parentLeaf = tree.GetItemParent(selected) # Expanded container (must have children) - elif tree.IsExpanded(selected) and tree.GetChildrenCount(selected, false): - appendChild = false + elif tree.IsExpanded(selected) and tree.GetChildrenCount(selected, False): + # Insert as first child nextItem = tree.GetFirstChild(selected, 0)[0] parentLeaf = selected - # Parent should be tree element or None - if appendChild: - parent = tree.GetPyData(selected) else: - parent = tree.GetPyData(parentLeaf) - if parent.hasChild: parent = parent.child + # No children or unexpanded item - appendChild stays True + nextItem = wxTreeItemId() # no next item + parentLeaf = selected + parent = tree.GetPyData(parentLeaf).treeObject() # Create a copy of clipboard element - elem = self.clipboard.cloneNode(true) + elem = self.clipboard.cloneNode(True) # Tempopary xxx object to test things xxx = MakeXXXFromDOM(parent, elem) # Check compatibility - error = false + error = False # Top-level x = xxx.treeObject() - if x.__class__ in [xxxDialog, xxxFrame, xxxMenuBar, xxxToolBar]: - if parent.__class__ != xxxMainNode: error = true + if x.__class__ in [xxxDialog, xxxFrame, xxxMenuBar]: + # Top-level classes + if parent.__class__ != xxxMainNode: error = True + elif x.__class__ == xxxToolBar: + # Toolbar can be top-level of child of panel or frame + if parent.__class__ not in [xxxMainNode, xxxPanel, xxxFrame]: error = True elif x.__class__ == xxxPanel and parent.__class__ == xxxMainNode: pass elif x.__class__ == xxxSpacer: - if not parent.isSizer: error = true + if not parent.isSizer: error = True elif x.__class__ == xxxSeparator: - if not parent.__class__ in [xxxMenu, xxxToolBar]: error = true + if not parent.__class__ in [xxxMenu, xxxToolBar]: error = True elif x.__class__ == xxxTool: - if parent.__class__ != xxxToolBar: error = true + if parent.__class__ != xxxToolBar: error = True + elif x.__class__ == xxxMenu: + if not parent.__class__ in [xxxMainNode, xxxMenuBar, xxxMenu]: error = True elif x.__class__ == xxxMenuItem: - if not parent.__class__ in [xxxMenuBar, xxxMenu]: error = true - elif x.isSizer and parent.__class__ == xxxNotebook: error = true + if not parent.__class__ in [xxxMenuBar, xxxMenu]: error = True + elif x.isSizer and parent.__class__ == xxxNotebook: error = True else: # normal controls can be almost anywhere if parent.__class__ == xxxMainNode or \ - parent.__class__ in [xxxMenuBar, xxxMenu]: error = true + parent.__class__ in [xxxMenuBar, xxxMenu]: error = True if error: if parent.__class__ == xxxMainNode: parentClass = 'root' else: parentClass = parent.className @@ -1444,14 +401,14 @@ class Frame(wxFrame): isChildContainer = isinstance(xxx, xxxChildContainer) if isChildContainer and \ ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) or \ - (isinstance(parent, xxxNotebook) and not isinstance(xxx, xxxNotebookPage)) or \ + (isinstance(parent, xxxNotebook) and not isinstance(xxx, xxxNotebookPage)) or \ not (parent.isSizer or isinstance(parent, xxxNotebook))): elem.removeChild(xxx.child.element) # detach child elem.unlink() # delete child container elem = xxx.child.element # replace # This may help garbage collection xxx.child.parent = None - isChildContainer = false + isChildContainer = False # Parent is sizer or notebook, child is not child container if parent.isSizer and not isChildContainer and not isinstance(xxx, xxxSpacer): # Create sizer item element @@ -1462,71 +419,71 @@ class Frame(wxFrame): pageElem = MakeEmptyDOM('notebookpage') pageElem.appendChild(elem) elem = pageElem - xxx = MakeXXXFromDOM(parent, elem) - # Figure out if we must append a new child or sibling - if appendChild: - parent.element.appendChild(elem) - newItem = tree.AppendItem(selected, xxx.treeName(), image=xxx.treeImage(), - data=wxTreeItemData(xxx)) - else: - node = tree.GetPyData(nextItem).element - parent.element.insertBefore(elem, node) - # Inserting before is difficult, se we insert after or first child - index = tree.ItemIndex(parentLeaf, nextItem) - newItem = tree.InsertItemBefore(parentLeaf, index, - xxx.treeName(), image=xxx.treeImage()) - tree.SetPyData(newItem, xxx) -# newItem = tree.InsertItem(parentLeaf, selected, xxx.treeName(), -# image=xxx.treeImage(), data=wxTreeItemData(xxx)) - # Add children items - if xxx.hasChildren: - treeObj = xxx.treeObject() - for n in treeObj.element.childNodes: - if IsObject(n): - tree.AddNode(newItem, treeObj, n) - # Scroll to show new item + # Insert new node, register undo + newItem = tree.InsertNode(parentLeaf, parent, elem, nextItem) + undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected)) + # Scroll to show new item (!!! redundant?) tree.EnsureVisible(newItem) tree.SelectItem(newItem) if not tree.IsVisible(newItem): tree.ScrollTo(newItem) tree.Refresh() # Update view? - if testWin and tree.IsHighlatable(newItem): + if g.testWin and tree.IsHighlatable(newItem): if conf.autoRefresh: - tree.needUpdate = true + tree.needUpdate = True tree.pendingHighLight = newItem else: tree.pendingHighLight = None - self.modified = true + self.modified = True self.SetStatusText('Pasted') - def OnDelete(self, evt): + def OnCutDelete(self, evt): selected = tree.selection if not selected: return # key pressed event # Undo info - self.lastOp = 'DELETE' - self.undo = [tree.GetItemParent(selected), tree.GetPrevSibling(selected)] + if evt.GetId() == wxID_CUT: + self.lastOp = 'CUT' + status = 'Removed to clipboard' + else: + self.lastOp = 'DELETE' + status = 'Deleted' # Delete testWin? - global testWin - if testWin: + if g.testWin: # If deleting top-level item, delete testWin - if selected == testWin.item: - testWin.Destroy() - testWin = None + if selected == g.testWin.item: + g.testWin.Destroy() + g.testWin = None else: # Remove highlight, update testWin - if not tree.IsHighlatable(selected): - if testWin.highLight: testWin.highLight.Remove() - tree.needUpdate = true - xnode = tree.RemoveLeaf(selected) - # !!! cloneNode is broken, or something is wrong -# self.undo.append(xnode.cloneNode(true)) - xnode.unlink() + if g.testWin.highLight: + g.testWin.highLight.Remove() + tree.needUpdate = True + # Prepare undo data + panel.Apply() + index = tree.ItemFullIndex(selected) + parent = tree.GetPyData(tree.GetItemParent(selected)).treeObject() + elem = tree.RemoveLeaf(selected) + undoMan.RegisterUndo(UndoCutDelete(index, parent, elem)) + if evt.GetId() == wxID_CUT: + if self.clipboard: self.clipboard.unlink() + self.clipboard = elem.cloneNode(True) tree.pendingHighLight = None tree.Unselect() panel.Clear() - self.modified = true - self.SetStatusText('Deleted') + self.modified = True + self.SetStatusText(status) + + def OnSelect(self, evt): + print >> sys.stderr, 'Xperimental function!' + wxYield() + self.SetCursor(wxCROSS_CURSOR) + self.CaptureMouse() + + def OnLeftDown(self, evt): + pos = evt.GetPosition() + self.SetCursor(wxNullCursor) + self.ReleaseMouse() def OnEmbedPanel(self, evt): conf.embedPanel = evt.IsChecked() @@ -1543,7 +500,7 @@ class Frame(wxFrame): # Widen self.SetDimensions(pos.x, pos.y, size.x + sizePanel.x, size.y) self.splitter.SplitVertically(tree, panel, conf.sashPos) - self.miniFrame.Show(false) + self.miniFrame.Show(False) else: conf.sashPos = self.splitter.GetSashPosition() pos = self.GetPosition() @@ -1552,9 +509,9 @@ class Frame(wxFrame): self.splitter.Unsplit(panel) sizer = self.miniFrame.GetSizer() panel.Reparent(self.miniFrame) - panel.Show(true) + panel.Show(True) sizer.Add(panel, 1, wxEXPAND) - self.miniFrame.Show(true) + self.miniFrame.Show(True) self.miniFrame.SetDimensions(conf.panelX, conf.panelY, conf.panelWidth, conf.panelHeight) wxYield() @@ -1562,6 +519,15 @@ class Frame(wxFrame): self.SetDimensions(pos.x, pos.y, max(size.x - sizePanel.x, self.minWidth), size.y) + def OnShowTools(self, evt): + conf.showTools = evt.IsChecked() + g.tools.Show(conf.showTools) + if conf.showTools: + self.toolsSizer.Prepend(g.tools, 0, wxEXPAND) + else: + self.toolsSizer.Remove(g.tools) + self.toolsSizer.Layout() + def OnTest(self, evt): if not tree.selection: return # key pressed event tree.ShowTestWindow(tree.selection) @@ -1573,10 +539,11 @@ class Frame(wxFrame): xxx = tree.GetPyData(selection) if xxx and panel.IsModified(): tree.Apply(xxx, selection) - if testWin: + if g.testWin: # (re)create - tree.CreateTestWin(testWin.item) - tree.needUpdate = false + tree.CreateTestWin(g.testWin.item) + panel.modified = False + tree.needUpdate = False def OnAutoRefresh(self, evt): conf.autoRefresh = evt.IsChecked() @@ -1584,19 +551,22 @@ class Frame(wxFrame): self.tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh) def OnAbout(self, evt): - str = '%s %s\n\nRoman Rolinsky <rolinsky@mema.ucl.ac.be>' % \ - (progname, version) - dlg = wxMessageDialog(self, str, 'About ' + progname, wxOK | wxCENTRE) + str = '''\ +XRCed version %s + +(c) Roman Rolinsky <rollrom@users.sourceforge.net> +Homepage: http://xrced.sourceforge.net\ +''' % version + dlg = wxMessageDialog(self, str, 'About XRCed', wxOK | wxCENTRE) dlg.ShowModal() dlg.Destroy() def OnReadme(self, evt): - text = open(os.path.join(sys.path[0], 'README'), 'r').read() + text = open(os.path.join(basePath, 'README.txt'), 'r').read() dlg = ScrolledMessageDialog(self, text, "XRCed README") dlg.ShowModal() dlg.Destroy() - # Simple emulation of python command line def OnDebugCMD(self, evt): import traceback @@ -1609,13 +579,13 @@ class Frame(wxFrame): except: (etype, value, tb) =sys.exc_info() tblist =traceback.extract_tb(tb)[1:] - msg =string.join(traceback.format_exception_only(etype, value) + msg =' '.join(traceback.format_exception_only(etype, value) +traceback.format_list(tblist)) print msg def OnCreate(self, evt): selected = tree.selection - if tree.ctrl: appendChild = false + if tree.ctrl: appendChild = False else: appendChild = not tree.NeedInsert(selected) xxx = tree.GetPyData(selected) if not appendChild: @@ -1627,27 +597,20 @@ class Frame(wxFrame): else: # If has next item, insert, else append to parent nextItem = tree.GetNextSibling(selected) - if nextItem.IsOk(): - # Insert before nextItem - parentLeaf = tree.GetItemParent(selected) - else: # last child: change selected to parent - appendChild = true - selected = tree.GetItemParent(selected) + parentLeaf = tree.GetItemParent(selected) # Expanded container (must have children) elif tree.shift and tree.IsExpanded(selected) \ - and tree.GetChildrenCount(selected, false): - appendChild = false + and tree.GetChildrenCount(selected, False): nextItem = tree.GetFirstChild(selected, 0)[0] parentLeaf = selected - # Parent should be tree element or None - if appendChild: - parent = tree.GetPyData(selected) else: - parent = tree.GetPyData(parentLeaf) + nextItem = wxTreeItemId() + parentLeaf = selected + parent = tree.GetPyData(parentLeaf) if parent.hasChild: parent = parent.child # Create element - className = self.createMap[evt.GetId()] + className = pullDownMenu.createMap[evt.GetId()] xxx = MakeEmptyXXX(parent, className) # Set default name for top-level windows @@ -1657,38 +620,23 @@ class Frame(wxFrame): xxx.treeObject().name = '%s%d' % (defaultIDs[cl], frame.maxIDs[cl]) xxx.treeObject().element.setAttribute('name', xxx.treeObject().name) - # Figure out if we must append a new child or sibling + # Insert new node, register undo elem = xxx.element - if appendChild: - # Insert newline for debug purposes - parent.element.appendChild(elem) - newItem = tree.AppendItem(selected, xxx.treeName(), image=xxx.treeImage(), - data=wxTreeItemData(xxx)) - else: - node = tree.GetPyData(nextItem).element - parent.element.insertBefore(elem, node) - # !!! There is a different behavious on Win and GTK - # !!! On Win InsertItem(parent, parent, ...) inserts at the end. - index = tree.ItemIndex(parentLeaf, nextItem) - newItem = tree.InsertItemBefore(parentLeaf, index, - xxx.treeName(), image=xxx.treeImage()) -# data=wxTreeItemData(xxx)) # does not work - tree.SetPyData(newItem, xxx) -# newItem = tree.InsertItem(parentLeaf, selected, -# xxx.treeName(), image=xxx.treeImage(), -# data=wxTreeItemData(xxx)) + newItem = tree.InsertNode(parentLeaf, parent, elem, nextItem) + undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected)) tree.EnsureVisible(newItem) tree.SelectItem(newItem) if not tree.IsVisible(newItem): tree.ScrollTo(newItem) tree.Refresh() # Update view? - if testWin and tree.IsHighlatable(newItem): + if g.testWin and tree.IsHighlatable(newItem): if conf.autoRefresh: - tree.needUpdate = true + tree.needUpdate = True tree.pendingHighLight = newItem else: tree.pendingHighLight = None + tree.SetFocus() # Expand/collapse subtree def OnExpand(self, evt): @@ -1709,29 +657,31 @@ class Frame(wxFrame): def OnUpdateUI(self, evt): if evt.GetId() in [wxID_CUT, wxID_COPY, self.ID_DELETE]: - evt.Enable(tree.selection != tree.root) + evt.Enable(tree.selection is not None and tree.selection != tree.root) elif evt.GetId() == wxID_PASTE: evt.Enable((self.clipboard and tree.selection) != None) elif evt.GetId() == self.ID_TEST: - evt.Enable(tree.selection != tree.root) + evt.Enable(tree.selection is not None and tree.selection != tree.root) + elif evt.GetId() == wxID_UNDO: evt.Enable(undoMan.CanUndo()) + elif evt.GetId() == wxID_REDO: evt.Enable(undoMan.CanRedo()) def OnIdle(self, evt): if self.inIdle: return # Recursive call protection - self.inIdle = true + self.inIdle = True if tree.needUpdate: if conf.autoRefresh: - if testWin: + if g.testWin: self.SetStatusText('Refreshing test window...') # (re)create - tree.CreateTestWin(testWin.item) + tree.CreateTestWin(g.testWin.item) wxYield() self.SetStatusText('') - tree.needUpdate = false + tree.needUpdate = False elif tree.pendingHighLight: tree.HighLight(tree.pendingHighLight) else: evt.Skip() - self.inIdle = false + self.inIdle = False # We don't let close panel window def OnCloseMiniFrame(self, evt): @@ -1739,7 +689,7 @@ class Frame(wxFrame): def OnCloseWindow(self, evt): if not self.AskSave(): return - if testWin: testWin.Destroy() + if g.testWin: g.testWin.Destroy() # Destroy cached windows panel.cacheParent.Destroy() if not panel.GetPageCount() == 2: @@ -1755,15 +705,16 @@ class Frame(wxFrame): def Clear(self): self.dataFile = '' - self.clipboard = None - self.modified = false - panel.SetModified(false) + if self.clipboard: + self.clipboard.unlink() + self.clipboard = None + undoMan.Clear() + self.modified = False tree.Clear() panel.Clear() - global testWin - if testWin: - testWin.Destroy() - testWin = None + if g.testWin: + g.testWin.Destroy() + g.testWin = None self.SetTitle(progname) # Numbers for new controls self.maxIDs = {} @@ -1771,18 +722,40 @@ class Frame(wxFrame): self.maxIDs[xxxMenuBar] = self.maxIDs[xxxMenu] = self.maxIDs[xxxToolBar] = 0 def Open(self, path): + if not os.path.exists(path): + wxLogError('File does not exists: %s' % path) + return False # Try to read the file try: - open(path) + f = open(path) self.Clear() + # Parse first line to get encoding (!! hack, I don't know a better way) + line = f.readline() + mo = re.match(r'^<\?xml ([^<>]* )?encoding="(?P<encd>[^<>].*)"\?>', line) # Build wx tree - dom = minidom.parse(path) + f.seek(0) + dom = minidom.parse(f) + # Set encoding global variable and document encoding property + import xxx + if mo: + dom.encoding = xxx.currentEncoding = mo.group('encd') + else: + xxx.currentEncoding = 'iso-8859-1' + dom.encoding = '' + f.close() + # Change dir + dir = os.path.dirname(path) + if dir: os.chdir(dir) tree.SetData(dom) self.dataFile = path self.SetTitle(progname + ': ' + os.path.basename(path)) except: + # Nice exception printing + inf = sys.exc_info() + wxLogError(traceback.format_exception(inf[0], inf[1], None)[-1]) wxLogError('Error reading file: %s' % path) - raise + return False + return True def Indent(self, node, indent = 0): # Copy child list because it will change soon @@ -1804,26 +777,27 @@ class Frame(wxFrame): def Save(self, path): try: # Apply changes - self.OnRefresh(wxCommandEvent()) + if tree.selection and panel.IsModified(): + self.OnRefresh(wxCommandEvent()) f = open(path, 'w') - # Make temporary copy + # Make temporary copy for formatting it # !!! We can't clone dom node, it works only once - #self.domCopy = tree.dom.cloneNode(true) - self.domCopy = minidom.Document() - mainNode = self.domCopy.appendChild(tree.mainNode.cloneNode(true)) + #self.domCopy = tree.dom.cloneNode(True) + self.domCopy = MyDocument() + mainNode = self.domCopy.appendChild(tree.mainNode.cloneNode(True)) self.Indent(mainNode) - self.domCopy.writexml(f) + self.domCopy.writexml(f, encoding=tree.rootObj.params['encoding'].value()) f.close() self.domCopy.unlink() self.domCopy = None - self.modified = false - panel.SetModified(false) + self.modified = False + panel.SetModified(False) except: wxLogError('Error writing file: %s' % path) raise def AskSave(self): - if not (self.modified or panel.IsModified()): return true + if not (self.modified or panel.IsModified()): return True flags = wxICON_EXCLAMATION | wxYES_NO | wxCANCEL | wxCENTRE dlg = wxMessageDialog( self, 'File is modified. Save before exit?', 'Save before too late?', flags ) @@ -1832,34 +806,41 @@ class Frame(wxFrame): if say == wxID_YES: self.OnSaveOrSaveAs(wxCommandEvent(wxID_SAVE)) # If save was successful, modified flag is unset - if not self.modified: return true + if not self.modified: return True elif say == wxID_NO: - self.modified = false - panel.SetModified(false) - return true - return false + self.modified = False + panel.SetModified(False) + return True + return False + + def SaveUndo(self): + pass # !!! ################################################################################ def usage(): - print >> sys.stderr, 'usage: xrced [-dvh] [file]' + print >> sys.stderr, 'usage: xrced [-dhlv] [file]' class App(wxApp): def OnInit(self): - global debug, verbose + global debug # Process comand-line try: - opts, args = getopt.getopt(sys.argv[1:], 'dvh') + opts = args = [] #give empty values in case of exception + opts, args = getopt.getopt(sys.argv[1:], 'dhiv') except getopt.GetoptError: - print >> sys.stderr, 'Unknown option' - usage() - sys.exit(1) + if wxPlatform != '__WXMAC__': # macs have some extra parameters + print >> sys.stderr, 'Unknown option' + usage() + sys.exit(1) for o,a in opts: if o == '-h': usage() sys.exit(0) elif o == '-d': - debug = true + debug = True + elif o == '-i': + g.xmlFlags &= ~wxXRC_USE_LOCALE elif o == '-v': print 'XRCed version', version sys.exit(0) @@ -1867,11 +848,12 @@ class App(wxApp): self.SetAppName('xrced') # Settings global conf - conf = wxConfig(style = wxCONFIG_USE_LOCAL_FILE) - conf.autoRefresh = conf.ReadInt('autorefresh', true) + conf = g.conf = wxConfig(style = wxCONFIG_USE_LOCAL_FILE) + conf.autoRefresh = conf.ReadInt('autorefresh', True) pos = conf.ReadInt('x', -1), conf.ReadInt('y', -1) size = conf.ReadInt('width', 800), conf.ReadInt('height', 600) - conf.embedPanel = conf.ReadInt('embedPanel', true) + conf.embedPanel = conf.ReadInt('embedPanel', True) + conf.showTools = conf.ReadInt('showTools', True) conf.sashPos = conf.ReadInt('sashPos', 200) if not conf.embedPanel: conf.panelX = conf.ReadInt('panelX', -1) @@ -1886,20 +868,17 @@ class App(wxApp): wxInitAllImageHandlers() # Create main frame frame = Frame(pos, size) - frame.Show(true) + frame.Show(True) # Load resources from XRC file (!!! should be transformed to .py later?) - ##sys.modules['params'].frame = frame - import params - params.frame = frame frame.res = wxXmlResource('') - frame.res.Load(os.path.join(sys.path[0], 'xrced.xrc')) + frame.res.Load(os.path.join(basePath, 'xrced.xrc')) # Load file after showing if args: - conf.panic = false + conf.panic = False frame.open = frame.Open(args[0]) - return true + return True def OnExit(self): # Write config @@ -1911,20 +890,22 @@ class App(wxApp): wc.WriteInt('width', conf.width) wc.WriteInt('height', conf.height) wc.WriteInt('embedPanel', conf.embedPanel) + wc.WriteInt('showTools', conf.showTools) if not conf.embedPanel: wc.WriteInt('panelX', conf.panelX) wc.WriteInt('panelY', conf.panelY) wc.WriteInt('sashPos', conf.sashPos) wc.WriteInt('panelWidth', conf.panelWidth) wc.WriteInt('panelHeight', conf.panelHeight) - wc.WriteInt('nopanic', 1) + wc.WriteInt('nopanic', True) wc.Flush() - del conf def main(): - app = App(1) + app = App(0, useBestVisual=False) app.MainLoop() app.OnExit() + global conf + del conf if __name__ == '__main__': main() diff --git a/wxPython/wxPython/tools/XRCed/xrced.xrc b/wxPython/wxPython/tools/XRCed/xrced.xrc index a407461450..f79590b319 100644 --- a/wxPython/wxPython/tools/XRCed/xrced.xrc +++ b/wxPython/wxPython/tools/XRCed/xrced.xrc @@ -23,13 +23,14 @@ <object class="wxButton" name="BUTTON_UP"> <label>Move Up</label> </object> - <flag>wxBOTTOM</flag> + <flag>wxBOTTOM|wxEXPAND</flag> <border>5</border> </object> <object class="sizeritem"> <object class="wxButton" name="BUTTON_DOWN"> <label>Move Down</label> </object> + <flag>wxEXPAND</flag> </object> <object class="spacer"> <size>10,20</size> @@ -39,13 +40,14 @@ <object class="wxButton" name="BUTTON_APPEND"> <label>Append...</label> </object> - <flag>wxBOTTOM</flag> + <flag>wxBOTTOM|wxEXPAND</flag> <border>5</border> </object> <object class="sizeritem"> <object class="wxButton" name="BUTTON_REMOVE"> <label>Remove</label> </object> + <flag>wxEXPAND</flag> </object> </object> <flag>wxALL|wxEXPAND</flag> @@ -80,7 +82,7 @@ <border>10</border> </object> </object> - <style>wxRESIZE_BORDER</style> + <style>wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</style> </object> <object class="wxDialog" name="DIALOG_CONTENT_CHECK_LIST"> <title>Content @@ -105,13 +107,14 @@ - wxBOTTOM + wxBOTTOM|wxEXPAND 5

    + wxEXPAND 10,20 @@ -121,13 +124,14 @@ - wxBOTTOM + wxBOTTOM|wxEXPAND 5 + wxEXPAND
    wxALL|wxEXPAND @@ -162,7 +166,7 @@ 10 - + Numbers @@ -230,6 +234,89 @@ 10 - + + + + + + wxVERTICAL + + + 2 + 2 + + + + + + + + + wxART_ADD_BOOKMARK + wxART_DEL_BOOKMARK + wxART_HELP_SIDE_PANEL + wxART_HELP_SETTINGS + wxART_HELP_BOOK + wxART_HELP_FOLDER + wxART_HELP_PAGE + wxART_GO_BACK + wxART_GO_FORWARD + wxART_GO_UP + wxART_GO_DOWN + wxART_GO_TO_PARENT + wxART_GO_HOME + wxART_FILE_OPEN + wxART_PRINT + wxART_HELP + wxART_TIP + wxART_REPORT_VIEW + wxART_LIST_VIEW + wxART_NEW_DIR + wxART_FOLDER + wxART_GO_DIR_UP + wxART_EXECUTABLE_FILE + wxART_NORMAL_FILE + wxART_TICK_MARK + wxART_CROSS_MARK + wxART_ERROR + wxART_QUESTION + wxART_WARNING + wxART_INFORMATION + wxART_MISSING_IMAGE + + + wxRIGHT|wxEXPAND + 5 + + + + + + + + + wxHORIZONTAL + + + + wxRIGHT|wxEXPAND + 5 + + + + + 30,-1d + + + + wxRIGHT|wxEXPAND + 5 + + 2 + 1 + + wxEXPAND + + \ No newline at end of file diff --git a/wxPython/wxPython/tools/XRCed/xxx.py b/wxPython/wxPython/tools/XRCed/xxx.py index cf141ee949..ac93753e72 100644 --- a/wxPython/wxPython/tools/XRCed/xxx.py +++ b/wxPython/wxPython/tools/XRCed/xxx.py @@ -4,13 +4,14 @@ # Created: 22.08.2001 # RCS-ID: $Id$ -from wxPython.wx import * -from wxPython.xrc import * from xml.dom import minidom -import wxPython.lib.wxpTag - +from globals import * from params import * +currentEncoding = wxLocale_GetSystemEncodingName() +if not currentEncoding: + currentEncoding = 'ascii' + # Base class for interface parameter classes class xxxNode: def __init__(self, node): @@ -26,17 +27,24 @@ class xxxParam(xxxNode): xxxNode.__init__(self, node) if not node.hasChildNodes(): # If does not have child nodes, create empty text node - text = tree.dom.createTextNode('') + text = g.tree.dom.createTextNode('') node.appendChild(text) else: text = node.childNodes[0] # first child must be text node assert text.nodeType == minidom.Node.TEXT_NODE + # Use convertion from unicode to current encoding self.textNode = text # Value returns string - def value(self): - return self.textNode.data - def update(self, value): - self.textNode.data = value + if wxUSE_UNICODE: # no conversion is needed + def value(self): + return self.textNode.data + def update(self, value): + self.textNode.data = value + else: + def value(self): + return self.textNode.data.encode(currentEncoding) + def update(self, value): + self.textNode.data = unicode(value, currentEncoding) # Integer parameter class xxxParamInt(xxxParam): @@ -63,7 +71,7 @@ class xxxParamContent(xxxNode): assert n.tagName == 'item', 'bad content content' if not n.hasChildNodes(): # If does not have child nodes, create empty text node - text = tree.dom.createTextNode('') + text = g.tree.dom.createTextNode('') node.appendChild(text) else: # !!! normalize? @@ -85,8 +93,8 @@ class xxxParamContent(xxxNode): self.node.removeChild(n) l = [] for str in value: - itemElem = tree.dom.createElement('item') - itemText = tree.dom.createTextNode(str) + itemElem = g.tree.dom.createElement('item') + itemText = g.tree.dom.createTextNode(str) itemElem.appendChild(itemText) self.node.appendChild(itemElem) l.append(itemText) @@ -106,9 +114,10 @@ class xxxParamContentCheckList(xxxNode): if n.nodeType == minidom.Node.ELEMENT_NODE: assert n.tagName == 'item', 'bad content content' checked = n.getAttribute('checked') + if not checked: checked = 0 if not n.hasChildNodes(): # If does not have child nodes, create empty text node - text = tree.dom.createTextNode('') + text = g.tree.dom.createTextNode('') node.appendChild(text) else: # !!! normalize? @@ -129,10 +138,11 @@ class xxxParamContentCheckList(xxxNode): for n in childNodes: self.node.removeChild(n) l = [] - for (s,ch) in value: - itemElem = tree.dom.createElement('item') - itemElem.setAttribute('checked', str(ch)) - itemText = tree.dom.createTextNode(s) + for s,ch in value: + itemElem = g.tree.dom.createElement('item') + # Add checked only if True + if ch: itemElem.setAttribute('checked', '1') + itemText = g.tree.dom.createTextNode(s) itemElem.appendChild(itemText) self.node.appendChild(itemElem) l.append((itemText, itemElem)) @@ -143,20 +153,37 @@ class xxxParamContentCheckList(xxxNode): self.l[i][1].setAttribute('checked', str(value[i][1])) self.data = value +# Bitmap parameter +class xxxParamBitmap(xxxParam): + def __init__(self, node): + xxxParam.__init__(self, node) + self.stock_id = node.getAttribute('stock_id') + def value(self): + return [self.stock_id, xxxParam.value(self)] + def update(self, value): + self.stock_id = value[0] + if self.stock_id: + self.node.setAttribute('stock_id', self.stock_id) + else: + self.node.removeAttribute('stock_id') + xxxParam.update(self, value[1]) + ################################################################################ # Classes to interface DOM objects class xxxObject: # Default behavior - hasChildren = false # has children elements? - hasStyle = true # almost everyone - hasName = true # has name attribute? - isSizer = hasChild = false + hasChildren = False # has children elements? + hasStyle = True # almost everyone + hasName = True # has name attribute? + isSizer = hasChild = False allParams = None # Some nodes have no parameters # Style parameters (all optional) styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip'] # Special parameters specials = [] + # Bitmap tags + bitmapTags = ['bitmap', 'bitmap2', 'icon'] # Required paremeters: none by default required = [] # Default parameters with default values @@ -184,7 +211,7 @@ class xxxObject: tag = node.tagName if tag == 'object': continue # do nothing for object children here - if not tag in self.allParams and not tag in self.styles: + if tag not in self.allParams and tag not in self.styles: print 'WARNING: unknown parameter for %s: %s' % \ (self.className, tag) elif tag in self.specials: @@ -196,12 +223,38 @@ class xxxObject: self.params[tag] = xxxParamContent(node) elif tag == 'font': # has children self.params[tag] = xxxParamFont(element, node) + elif tag in self.bitmapTags: + # Can have attributes + self.params[tag] = xxxParamBitmap(node) else: # simple parameter self.params[tag] = xxxParam(node) else: # Remove all other nodes element.removeChild(node) node.unlink() + # Check that all required params are set + for param in self.required: + if not self.params.has_key(param): + # If default is specified, set it + if self.default.has_key(param): + elem = g.tree.dom.createElement(param) + self.params[param] = xxxParam(elem) + # Find place to put new element: first present element after param + found = False + paramStyles = self.allParams + self.styles + for p in paramStyles[paramStyles.index(param) + 1:]: + # Content params don't have same type + if self.params.has_key(p) and p != 'content': + found = True + break + if found: + nextTextElem = self.params[p].node + self.element.insertBefore(elem, nextTextElem) + else: + self.element.appendChild(elem) + else: + wxLogWarning('Required parameter %s of %s missing' % + (param, self.className)) # Returns real tree object def treeObject(self): if self.hasChild: return self.child @@ -244,8 +297,8 @@ class xxxParamFont(xxxObject, xxxNode): v = [] for param in self.allParams: if value[i]: - fontElem = tree.dom.createElement(param) - textNode = tree.dom.createTextNode(value[i]) + fontElem = g.tree.dom.createElement(param) + textNode = g.tree.dom.createTextNode(value[i]) self.params[param] = textNode fontElem.appendChild(textNode) elem.appendChild(fontElem) @@ -258,11 +311,27 @@ class xxxParamFont(xxxObject, xxxNode): ################################################################################ class xxxContainer(xxxObject): - hasChildren = true + hasChildren = True + +# Simulate normal parameter for encoding +class xxxEncoding: + def __init__(self, val): + self.encd = val + def value(self): + return self.encd + def update(self, val): + self.encd = val # Special class for root node class xxxMainNode(xxxContainer): - hasStyle = hasName = false + allParams = ['encoding'] + required = ['encoding'] + default = {'encoding': ''} + hasStyle = hasName = False + def __init__(self, dom): + xxxContainer.__init__(self, None, dom.documentElement) + self.className = 'XML tree' + self.params['encoding'] = xxxEncoding(dom.encoding) ################################################################################ # Top-level windwows @@ -275,12 +344,13 @@ class xxxPanel(xxxContainer): exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] class xxxDialog(xxxContainer): - allParams = ['title', 'pos', 'size', 'style'] + allParams = ['title', 'centered', 'pos', 'size', 'style'] + paramDict = {'centered': ParamBool} required = ['title'] winStyles = ['wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP', 'wxDIALOG_MODAL', 'wxDIALOG_MODELESS', 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX', - 'wxTHICK_FRAME', + 'wxTHICK_FRAME', 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', 'tooltip'] @@ -291,7 +361,7 @@ class xxxFrame(xxxContainer): paramDict = {'centered': ParamBool} required = ['title'] winStyles = ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE', - 'wxSTAY_ON_TOP', + 'wxSTAY_ON_TOP', 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX', 'wxMINIMIZE_BOX', 'wxMAXIMIZE_BOX', 'wxFRAME_FLOAT_ON_PARENT', 'wxFRAME_TOOL_WINDOW', @@ -302,13 +372,14 @@ class xxxFrame(xxxContainer): class xxxTool(xxxObject): allParams = ['bitmap', 'bitmap2', 'toggle', 'tooltip', 'longhelp'] - paramDict = {'bitmap2': ParamFile} - hasStyle = false + required = ['bitmap'] + paramDict = {'bitmap2': ParamBitmap, 'toggle': ParamBool} + hasStyle = False class xxxToolBar(xxxContainer): - allParams = ['bitmapsize', 'margins', 'packing', 'separation', + allParams = ['bitmapsize', 'margins', 'packing', 'separation', 'pos', 'size', 'style'] - hasStyle = false + hasStyle = False paramDict = {'bitmapsize': ParamPosSize, 'margins': ParamPosSize, 'packing': ParamInt, 'separation': ParamInt, 'style': ParamNonGenericStyle} @@ -321,6 +392,7 @@ class xxxBitmap(xxxObject): allParams = ['bitmap'] required = ['bitmap'] +# Just like bitmap class xxxIcon(xxxObject): allParams = ['icon'] required = ['icon'] @@ -331,6 +403,7 @@ class xxxIcon(xxxObject): class xxxStaticText(xxxObject): allParams = ['label', 'pos', 'size', 'style'] required = ['label'] + default = {'label': ''} winStyles = ['wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE'] class xxxStaticLine(xxxObject): @@ -392,7 +465,7 @@ class xxxHtmlWindow(xxxObject): paramDict = {'borders': ParamInt} winStyles = ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO'] -class xxxCalendar(xxxObject): +class xxxCalendarCtrl(xxxObject): allParams = ['pos', 'size', 'style'] class xxxNotebook(xxxContainer): @@ -400,6 +473,12 @@ class xxxNotebook(xxxContainer): paramDict = {'usenotebooksizer': ParamBool} winStyles = ['wxNB_FIXEDWIDTH', 'wxNB_LEFT', 'wxNB_RIGHT', 'wxNB_BOTTOM'] +class xxxGenericDirCtrl(xxxObject): + allParams = ['defaultfolder', 'filter', 'defaultfilter', 'pos', 'size', 'style'] + paramDict = {'defaultfilter': ParamInt} + winStyles = ['wxDIRCTRL_DIR_ONLY', 'wxDIRCTRL_3D_INTERNAL', 'wxDIRCTRL_SELECT_FIRST', + 'wxDIRCTRL_SHOW_FILTERS', 'wxDIRCTRL_EDIT_LABELS'] + ################################################################################ # Buttons @@ -423,7 +502,13 @@ class xxxRadioButton(xxxObject): winStyles = ['wxRB_GROUP'] class xxxSpinButton(xxxObject): - allParams = ['pos', 'size', 'style'] + allParams = ['value', 'min', 'max', 'pos', 'size', 'style'] + paramDict = {'value': ParamInt} + winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP'] + +class xxxSpinCtrl(xxxObject): + allParams = ['value', 'min', 'max', 'pos', 'size', 'style'] + paramDict = {'value': ParamInt} winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP'] ################################################################################ @@ -440,7 +525,8 @@ class xxxRadioBox(xxxObject): winStyles = ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS'] class xxxCheckBox(xxxObject): - allParams = ['label', 'pos', 'size', 'style'] + allParams = ['label', 'checked', 'pos', 'size', 'style'] + paramDict = {'checked': ParamBool} required = ['label'] class xxxComboBox(xxxObject): @@ -462,14 +548,14 @@ class xxxCheckList(xxxObject): 'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER', 'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING'] paramDict = {'content': ParamContentCheckList} - + ################################################################################ # Sizers class xxxSizer(xxxContainer): - hasName = hasStyle = false + hasName = hasStyle = False paramDict = {'orient': ParamOrient} - isSizer = true + isSizer = True class xxxBoxSizer(xxxSizer): allParams = ['orient'] @@ -483,7 +569,6 @@ class xxxBoxSizer(xxxSizer): class xxxStaticBoxSizer(xxxBoxSizer): allParams = ['label', 'orient'] required = ['label', 'orient'] - default = {'orient': 'wxVERTICAL'} class xxxGridSizer(xxxSizer): allParams = ['cols', 'rows', 'vgap', 'hgap'] @@ -492,7 +577,8 @@ class xxxGridSizer(xxxSizer): # For repeated parameters class xxxParamMulti: - def __init__(self): + def __init__(self, node): + self.node = node self.l, self.data = [], [] def append(self, param): self.l.append(param) @@ -511,16 +597,17 @@ class xxxFlexGridSizer(xxxGridSizer): # Special processing for growable* parameters # (they are represented by several nodes) def special(self, tag, node): - if tag not in self.params: - self.params[tag] = xxxParamMulti() + if not self.params.has_key(tag): + # Create new multi-group + self.params[tag] = xxxParamMulti(node) self.params[tag].append(xxxParamInt(node)) def setSpecial(self, param, value): # Straightforward implementation: remove, add again self.params[param].remove() del self.params[param] for i in value: - node = tree.dom.createElement(param) - text = tree.dom.createTextNode(str(i)) + node = g.tree.dom.createElement(param) + text = g.tree.dom.createTextNode(str(i)) node.appendChild(text) self.element.appendChild(node) self.special(param, node) @@ -528,8 +615,8 @@ class xxxFlexGridSizer(xxxGridSizer): # Container with only one child. # Not shown in tree. class xxxChildContainer(xxxObject): - hasName = hasStyle = false - hasChild = true + hasName = hasStyle = False + hasChild = True def __init__(self, parent, element): xxxObject.__init__(self, parent, element) # Must have one child with 'object' tag, but we don't check it @@ -550,8 +637,8 @@ class xxxChildContainer(xxxObject): assert 0, 'no child found' class xxxSizerItem(xxxChildContainer): - allParams = ['option', 'flag', 'border'] - paramDict = {'option': ParamInt} + allParams = ['option', 'flag', 'border', 'minsize'] + paramDict = {'option': ParamInt, 'minsize': ParamPosSize} def __init__(self, parent, element): xxxChildContainer.__init__(self, parent, element) # Remove pos parameter - not needed for sizeritems @@ -574,26 +661,37 @@ class xxxNotebookPage(xxxChildContainer): self.child.allParams.remove('size') class xxxSpacer(xxxObject): - hasName = hasStyle = false + hasName = hasStyle = False allParams = ['size', 'option', 'flag', 'border'] paramDict = {'option': ParamInt} default = {'size': '0,0'} class xxxMenuBar(xxxContainer): - allParams = [] + allParams = ['style'] + paramDict = {'style': ParamNonGenericStyle} # no generic styles + winStyles = ['wxMB_DOCKABLE'] class xxxMenu(xxxContainer): - allParams = ['label'] + allParams = ['label', 'help', 'style'] default = {'label': ''} paramDict = {'style': ParamNonGenericStyle} # no generic styles winStyles = ['wxMENU_TEAROFF'] class xxxMenuItem(xxxObject): - allParams = ['checkable', 'label', 'accel', 'help'] + allParams = ['label', 'bitmap', 'accel', 'help', + 'checkable', 'radio', 'enabled', 'checked'] default = {'label': ''} + hasStyle = False class xxxSeparator(xxxObject): - hasName = hasStyle = false + hasName = hasStyle = False + +################################################################################ +# Unknown control + +class xxxUnknown(xxxObject): + allParams = ['pos', 'size', 'style'] + paramDict = {'style': ParamNonGenericStyle} # no generic styles ################################################################################ @@ -603,7 +701,7 @@ xxxDict = { 'wxFrame': xxxFrame, 'tool': xxxTool, 'wxToolBar': xxxToolBar, - + 'wxBitmap': xxxBitmap, 'wxIcon': xxxIcon, @@ -632,8 +730,10 @@ xxxDict = { 'wxNotebook': xxxNotebook, 'notebookpage': xxxNotebookPage, 'wxHtmlWindow': xxxHtmlWindow, - 'wxCalendar': xxxCalendar, - + 'wxCalendarCtrl': xxxCalendarCtrl, + 'wxGenericDirCtrl': xxxGenericDirCtrl, + 'wxSpinCtrl': xxxSpinCtrl, + 'wxBoxSizer': xxxBoxSizer, 'wxStaticBoxSizer': xxxStaticBoxSizer, 'wxGridSizer': xxxGridSizer, @@ -645,12 +745,14 @@ xxxDict = { 'wxMenu': xxxMenu, 'wxMenuItem': xxxMenuItem, 'separator': xxxSeparator, + + 'unknown': xxxUnknown, } # Create IDs for all parameters of all classes paramIDs = {'fg': wxNewId(), 'bg': wxNewId(), 'exstyle': wxNewId(), 'font': wxNewId(), 'enabled': wxNewId(), 'focused': wxNewId(), 'hidden': wxNewId(), - 'tooltip': wxNewId() + 'tooltip': wxNewId(), 'encoding': wxNewId() } for cl in xxxDict.values(): if cl.allParams: @@ -668,27 +770,27 @@ def IsObject(node): # Make XXX object from some DOM object, selecting correct class def MakeXXXFromDOM(parent, element): try: - return xxxDict[element.getAttribute('class')](parent, element) + klass = xxxDict[element.getAttribute('class')] except KeyError: # Verify that it's not recursive exception - if element.getAttribute('class') not in xxxDict: - print 'ERROR: unknown class:', element.getAttribute('class') + print 'ERROR: unknown class:', element.getAttribute('class') raise + return klass(parent, element) # Make empty DOM element -def MakeEmptyDOM(className): - elem = tree.dom.createElement('object') +def MakeEmptyDOM(className): + elem = g.tree.dom.createElement('object') elem.setAttribute('class', className) # Set required and default parameters xxxClass = xxxDict[className] defaultNotRequired = filter(lambda x, l=xxxClass.required: x not in l, xxxClass.default.keys()) for param in xxxClass.required + defaultNotRequired: - textElem = tree.dom.createElement(param) + textElem = g.tree.dom.createElement(param) try: - textNode = tree.dom.createTextNode(xxxClass.default[param]) + textNode = g.tree.dom.createTextNode(xxxClass.default[param]) except KeyError: - textNode = tree.dom.createTextNode('') + textNode = g.tree.dom.createTextNode('') textElem.appendChild(textNode) elem.appendChild(textElem) return elem diff --git a/wxPython/wxPython/tools/dbg.py b/wxPython/wxPython/tools/dbg.py new file mode 100644 index 0000000000..5556098d1c --- /dev/null +++ b/wxPython/wxPython/tools/dbg.py @@ -0,0 +1,256 @@ +#---------------------------------------------------------------------------- +# Name: dbg.py +# RCS-ID: $Id$ +# Author: Will Sadkin +# Email: wsadkin@nameconnector.com +# Created: 07/11/2002 +# Copyright: (c) 2002 by Will Sadkin, 2002 +# License: wxWindows license +#---------------------------------------------------------------------------- + +""" +This module provides a useful debugging framework that supports +showing nesting of function calls and allows a program to contain +lots of debugging print statements that can easily be turned on +or off to debug the code. It also supports the ability to +have each function indent the debugging statements contained +within it, including those of any other function called within +its scope, thus allowing you to see in what order functions are +being called, and from where. + +This capability is particularly useful in wxPython applications, +where exactly events occur that cause functions to be called is +not entirely clear, and because wxPython programs can't be run +from inside other debugging environments that have their own +message loops. + +This module defines a Logger class, responsible for managing +debugging output. Each Logger instance can be given a name +at construction; if this is done, ':' will precede each +logging output made by that Logger instance. + +The log() function this class provides takes a set of positional +arguments that are printed in order if debugging is enabled +(just like print does), followed by a set of keyword arguments +that control the behavior of the log() function itself on subsequent +calls. The current keyword arguments are: + +indent + When set to a value of 1, this increments the current + indentation level, causing all subsequent dbg() outputs to be + indented by 3 more spaces. When set to a value of 0, + this process is reversed, causing the indent to decrease by + 3 spaces. The default indentation level is 0. + +enable + When set to a value of 1, this turns on dbg() output for + for program importing this module, until told to do otherwise. + When set to a value of 0, dbg output is turned off. (dbg + output is off by default.) + +suspend + When set to a value of 1, this increments the current + "suspension" level. This makes it possible for a function + to temporarily suspend its and any of its dependents' + potential outputs that use the same Logger instance. + When set to a value of 0, the suspension level is + decremented. When the value goes back to 0, potential + logging is resumed (actual output depends on the + "enable" status of the Logger instance in question.) + +wxlog + When set to a value of 1, the output will be sent to the + active wxLog target. + +stream + When set to a non-None value, the current output stream + (default of sys.stdout) is pushed onto a stack of streams, + and is replaced in the dbg system with the specified stream. + When called with a value of None, the previous stream will + be restored (if stacked.) If set to None without previously + changing it will result in no action being taken. + +You can also call the log function implicitly on the Logger +instance, ie. you can type: + from wxPython.tools.dbg import Logger + dbg = Logger() + dbg('something to print') + +Using this fairly simple mechanism, it is possible to get fairly +useful debugging output in a program. Consider the following +code example: + +>>> d = {1:'a', 2:'dictionary', 3:'of', 4:'words'} +>>> dbg = dbg.Logger('module') +>>> dbg(enable=1) +module: dbg enabled +>>> def foo(d): +... dbg('foo', indent=1) +... bar(d) +... dbg('end of foo', indent=0) +... +>>> def bar(d): +... dbg('bar', indent=1) +... dbg('contents of d:', indent=1) +... l = d.items() +... l.sort() +... for key, value in l: +... dbg('%d =' % key, value) +... dbg(indent=0) +... dbg('end of bar', indent=0) +... +>>> foo(d) +module: foo + module: bar + module: contents of d: + module: 1 = a + module: 2 = dictionary + module: 3 = of + module: 4 = words + module: end of bar + module: end of foo +>>> + +""" + + +class Logger: + def __init__(self, name=None): + import sys + self.name = name + self._indent = 0 # current number of indentations + self._dbg = 0 # enable/disable flag + self._suspend = 0 # allows code to "suspend/resume" potential dbg output + self._wxLog = 0 # use wxLogMessage for debug output + self._outstream = sys.stdout # default output stream + self._outstream_stack = [] # for restoration of streams as necessary + + + def IsEnabled(): + return self._dbg + + def IsSuspended(): + return _suspend + + + def log(self, *args, **kwargs): + """ + This function provides a useful framework for generating + optional debugging output that can be displayed at an + arbitrary level of indentation. + """ + if not self._dbg and not 'enable' in kwargs.keys(): + return + + if self._dbg and len(args) and not self._suspend: + # (emulate print functionality) + strs = [str(arg) for arg in args] + output = ' '.join(strs) + if self.name: output = self.name+': ' + output + output = ' ' * 3 * self._indent + output + + if self._wxLog: + from wxPython.wx import wxLogMessage # (if not already imported) + wxLogMessage(output) + else: + self._outstream.write(output + '\n') + self._outstream.flush() + # else do nothing + + # post process args: + for kwarg, value in kwargs.items(): + if kwarg == 'indent': + self.SetIndent(value) + elif kwarg == 'enable': + self.SetEnabled(value) + elif kwarg == 'suspend': + self.SetSuspend(value) + elif kwarg == 'wxlog': + self.SetWxLog(value) + elif kwarg == 'stream': + self.SetStream(value) + + # aliases for the log function + dbg = log # backwards compatible + msg = log # + __call__ = log # this one lets you 'call' the instance directly + + + def SetEnabled(self, value): + if value: + old_dbg = self._dbg + self._dbg = 1 + if not old_dbg: + self.dbg('dbg enabled') + else: + if self._dbg: + self.dbg('dbg disabled') + self._dbg = 0 + + + def SetSuspend(self, value): + if value: + self._suspend += 1 + elif self._suspend > 0: + self._suspend -= 1 + + + def SetIndent(self, value): + if value: + self._indent += 1 + elif self._indent > 0: + self._indent -= 1 + + + def SetWxLog(self, value): + self._wxLog = value + + + def SetStream(self, value): + if value: + self._outstream_stack.append( self._outstream ) + self._outstream = value + elif value is None and len(self._outstream_stack) > 0: + self._outstream = self._outstream_stack.pop(-1) + + +#------------------------------------------------------------ + +if __name__ == "__main__": + from wxPython.wx import * + wxLog_SetActiveTarget( wxLogStderr() ) + logger = Logger('module') + dbg = logger.dbg + dbg(enable=1) + logger('test __call__ interface') + dbg('testing wxLog output to stderr:', wxlog=1, indent=1) + dbg('1,2,3...') + dbg('testing wxLogNull:') + devnull = wxLogNull() + dbg('4,5,6...') # shouldn't print, according to doc... + del devnull + dbg('(resuming to wxLogStdErr)', '7,8,9...', indent=0) + dbg('disabling wxLog output, switching to stderr:') + dbg(wxlog=0, stream=sys.stderr) + dbg(logger._outstream, 'switching back to stdout:') + dbg(stream=None) + dbg(logger._outstream ) + def foo(str): + dbg('foo:', indent=1) + dbg(str, indent=0) + foo('testing dbg inside function') + class bar(Logger): + def __init__(self, name): + Logger.__init__(self, name) + def enable(self, value): + self.dbg(enable=value) + def foo(self, str): + self.dbg('foo:', indent=1) + self.dbg(str, indent=0) + f = bar('class mixin') + f.foo("shouldn't print") + f.enable(1) + f.foo("should print") + dbg('test completed.', enable=0) + dbg('(double-checking ;-)') + diff --git a/wxPython/wxPython/tools/helpviewer.py b/wxPython/wxPython/tools/helpviewer.py new file mode 100644 index 0000000000..0d35e5ae3a --- /dev/null +++ b/wxPython/wxPython/tools/helpviewer.py @@ -0,0 +1,80 @@ +#---------------------------------------------------------------------- +# Name: wxPython.tools.helpviewer +# Purpose: HTML Help viewer +# +# Author: Robin Dunn +# +# Created: 11-Dec-2002 +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- + +""" +helpviewer.py -- Displays HTML Help in a wxHtmlHelpController window. + +Usage: + helpviewer [--cache=path] helpfile [helpfile(s)...] + + Where helpfile is the path to either a .hhp file or a .zip file + which contians a .hhp file. The .hhp files are the same as those + used by Microsoft's HTML Help Workshop for creating CHM files. +""" + + +import sys, os + +#--------------------------------------------------------------------------- + +def main(args=sys.argv): + if len(args) < 2: + print __doc__ + return + + args = args[1:] + cachedir = None + if args[0][:7] == '--cache': + cachedir = os.path.expanduser(args[0].split('=')[1]) + args = args[1:] + + if len(args) == 0: + print __doc__ + return + + from wxPython.wx import wxPySimpleApp, wxConfigBase_Get, \ + wxLog_SetActiveTarget, wxLogStderr, \ + wxLog_SetLogLevel, wxLOG_Error, \ + wxFileSystem_AddHandler, wxZipFSHandler + import wxPython.html + from wxPython.htmlhelp import wxHtmlHelpController + + + app = wxPySimpleApp() + #wxLog_SetActiveTarget(wxLogStderr()) + wxLog_SetLogLevel(wxLOG_Error) + + # Set up the default config so the htmlhelp frame can save its preferences + app.SetVendorName('wxWindows') + app.SetAppName('helpviewer') + cfg = wxConfigBase_Get() + + # Add the Zip filesystem + wxFileSystem_AddHandler(wxZipFSHandler()) + + # Create the viewer + helpctrl = wxHtmlHelpController() + if cachedir: + helpctrl.SetTempDir(cachedir) + + # and add the books + for helpfile in args: + print "Adding %s..." % helpfile + helpctrl.AddBook(helpfile, 1) + + # start it up! + helpctrl.DisplayContents() + app.MainLoop() + + +if __name__ == '__main__': + main() diff --git a/wxPython/wxPython/tools/img2img.py b/wxPython/wxPython/tools/img2img.py index 3ce1e9f7ff..202b731276 100644 --- a/wxPython/wxPython/tools/img2img.py +++ b/wxPython/wxPython/tools/img2img.py @@ -1,7 +1,16 @@ -""" -Common routines for the image converter utilities. -""" -import sys, os, glob, getopt, string +#---------------------------------------------------------------------- +# Name: wxPython.tools.img2img +# Purpose: Common routines for the image converter utilities. +# +# Author: Robin Dunn +# +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- + + +import sys, os, glob, getopt from wxPython.wx import * if wxPlatform == "__WXGTK__": @@ -11,7 +20,7 @@ if wxPlatform == "__WXGTK__": wxInitAllImageHandlers() def convert(file, maskClr, outputDir, outputName, outType, outExt): - if string.lower(os.path.splitext(file)[1]) == ".ico": + if os.path.splitext(file)[1].lower() == ".ico": icon = wxIcon(file, wxBITMAP_TYPE_ICO) img = wxBitmapFromIcon(icon) else: diff --git a/wxPython/wxPython/tools/img2png.py b/wxPython/wxPython/tools/img2png.py index 76e7f6db06..2ddfee329e 100644 --- a/wxPython/wxPython/tools/img2png.py +++ b/wxPython/wxPython/tools/img2png.py @@ -1,4 +1,14 @@ -#!/usr/bin/env python +#---------------------------------------------------------------------- +# Name: wxPython.tools.img2png +# Purpose: Convert an image to PNG format +# +# Author: Robin Dunn +# +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- + """ img2png.py -- convert several image formats to PNG format diff --git a/wxPython/wxPython/tools/img2py.py b/wxPython/wxPython/tools/img2py.py index 1a5bd0ea0b..719b19d483 100644 --- a/wxPython/wxPython/tools/img2py.py +++ b/wxPython/wxPython/tools/img2py.py @@ -1,4 +1,15 @@ -#!/usr/bin/env python +#---------------------------------------------------------------------- +# Name: wxPython.tools.img2py +# Purpose: Convert an image to Python code. +# +# Author: Robin Dunn +# +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- + + """ img2py.py -- Convert an image to PNG format and embed it in a Python module with appropriate code so it can be loaded into @@ -22,6 +33,12 @@ Options: specify a name that should be used to customize the access fucntions, (getNameBitmap, etc.) + -c Maintain a catalog of names that can be used to reference + images. Catalog can be accessed via catalog and index attributes + of the module. If the -n option is specified then + is used for the catalog key and index value, otherwise + the filename without any path or extension is used as the key. + -a This flag specifies that the python_file should be appended to instead of overwritten. This in combination with -n will allow you to put multiple images in one Python source file. @@ -32,9 +49,14 @@ Options: """ +# +# Changes: +# - Cliff Wells +# 20021206: Added catalog (-c) option. +# -import sys, os, glob, getopt, tempfile, string +import sys, os, glob, getopt, tempfile import cPickle, cStringIO, zlib import img2img from wxPython import wx @@ -98,9 +120,10 @@ def main(args): maskClr = None imgName = "" icon = 0 + catalog = 0 try: - opts, fileArgs = getopt.getopt(args, "auin:m:") + opts, fileArgs = getopt.getopt(args, "auicn:m:") except getopt.GetoptError: print __doc__ return @@ -116,6 +139,8 @@ def main(args): maskClr = val elif opt == "-i": icon = 1 + elif opt == "-c": + catalog = 1 if len(fileArgs) != 2: print __doc__ @@ -139,6 +164,33 @@ def main(args): else: out = open(python_file, "w") + if catalog: + pyPath, pyFile = os.path.split(python_file) + imgPath, imgFile = os.path.split(image_file) + + if not imgName: + imgName = os.path.splitext(imgFile)[0] + print "\nWarning: -n not specified. Using filename (%s) for catalog entry." % imgName + + old_index = [] + if append: + # check to see if catalog exists already (file may have been created + # with an earlier version of img2py or without -c option) + oldSysPath = sys.path[:] + sys.path = [pyPath] # make sure we don't import something else by accident + mod = __import__(os.path.splitext(pyFile)[0]) + if 'index' not in dir(mod): + print "\nWarning: %s was originally created without catalog." % python_file + print " Any images already in file will not be cataloged.\n" + out.write("\n# ***************** Catalog starts here *******************") + out.write("\n\ncatalog = {}\n") + out.write("index = []\n\n") + out.write("class ImageClass: pass\n\n") + else: # save a copy of the old index so we can warn about duplicate names + old_index[:] = mod.index[:] + del mod + sys.path = oldSysPath[:] + out.write("#" + "-" * 70 + "\n") if not append: out.write("# This file was generated by %s\n#\n" % sys.argv[0]) @@ -150,6 +202,11 @@ def main(args): else: out.write("import cStringIO\n\n\n") + if catalog: + out.write("catalog = {}\n") + out.write("index = []\n\n") + out.write("class ImageClass: pass\n\n") + if compressed: out.write("def get%sData():\n" " return zlib.decompress(\n%s)\n\n" @@ -173,6 +230,19 @@ def main(args): " return icon\n\n" % tuple([imgName] * 2)) + if catalog: + if imgName in old_index: + print "Warning: %s already in catalog." % imgName + print " Only the last entry will be accessible.\n" + old_index.append(imgName) + out.write("index.append('%s')\n" % imgName) + out.write("catalog['%s'] = ImageClass()\n" % imgName) + out.write("catalog['%s'].getData = get%sData\n" % tuple([imgName] * 2)) + out.write("catalog['%s'].getImage = get%sImage\n" % tuple([imgName] * 2)) + out.write("catalog['%s'].getBitmap = get%sBitmap\n" % tuple([imgName] * 2)) + if icon: + out.write("catalog['%s'].getIcon = get%sIcon\n" % tuple([imgName] * 2)) + out.write("\n\n") if imgName: n_msg = ' using "%s"' % imgName diff --git a/wxPython/wxPython/tools/img2xpm.py b/wxPython/wxPython/tools/img2xpm.py index 2b9a99555c..e49bff180a 100644 --- a/wxPython/wxPython/tools/img2xpm.py +++ b/wxPython/wxPython/tools/img2xpm.py @@ -1,4 +1,14 @@ -#!/usr/bin/env python +#---------------------------------------------------------------------- +# Name: wxPython.tools.img2xpm +# Purpose: Convert an image to XPM format +# +# Author: Robin Dunn +# +# RCS-ID: $Id$ +# Copyright: (c) 2002 by Total Control Software +# Licence: wxWindows license +#---------------------------------------------------------------------- + """ img2xpm.py -- convert several image formats to XPM diff --git a/wxPython/wxSWIG/Modules/pycpp.cxx b/wxPython/wxSWIG/Modules/pycpp.cxx index 256a4399d9..89cd85ffd5 100644 --- a/wxPython/wxSWIG/Modules/pycpp.cxx +++ b/wxPython/wxSWIG/Modules/pycpp.cxx @@ -260,10 +260,15 @@ void PYTHON::cpp_destructor(char *name, char *newname) { else realname = name; } - *pyclass << tab4 << "def __del__(self," << module << "=" << module << "):\n"; + char* dfname = name_destroy(realname); + + *pyclass << tab4 << "def __del__(self, " << "delfunc=" << module<< "." << dfname << "):\n"; emitAddPragmas(*pyclass,"__del__",tab8); - *pyclass << tab8 << "if self.thisown == 1 :\n" - << tab8 << tab4 << module << "." << name_destroy(realname) << "(self)\n"; + *pyclass << tab8 << "if self.thisown == 1:\n" + << tab8 << tab4 << "try:\n" + << tab8 << tab8 << "delfunc(self)\n" + << tab8 << tab4 << "except:\n" + << tab8 << tab8 << "pass\n"; have_destructor = 1; if (doc_entry) { diff --git a/wxPython/wxSWIG/Modules/python.cxx b/wxPython/wxSWIG/Modules/python.cxx index f2c9f41b2b..8d26c6f8f2 100644 --- a/wxPython/wxSWIG/Modules/python.cxx +++ b/wxPython/wxSWIG/Modules/python.cxx @@ -484,9 +484,13 @@ PYTHON::get_pointer(char *iname, char *srcname, char *src, char *dest, // Now get the pointer value from the string and save in dest - f << tab4 << "if (" << src << ") {\n" - << tab8 << "if (" << src << " == Py_None) { " << dest << " = NULL; }\n" - << tab8 << "else if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; + if (t->is_reference) + f << tab4 << "if (" << src << ") {\n" + << tab8 << "if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; + else + f << tab4 << "if (" << src << ") {\n" + << tab8 << "if (" << src << " == Py_None) { " << dest << " = NULL; }\n" + << tab8 << "else if (SWIG_GetPtrObj(" << src << ",(void **) &" << dest << ","; // If we're passing a void pointer, we give the pointer conversion a NULL // pointer, otherwise pass in the expected type. diff --git a/wxPython/wxSWIG/swig_lib/perl5/.cvsignore b/wxPython/wxSWIG/swig_lib/perl5/.cvsignore new file mode 100644 index 0000000000..f3c7a7c5da --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/perl5/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/wxPython/wxSWIG/swig_lib/python/.cvsignore b/wxPython/wxSWIG/swig_lib/python/.cvsignore new file mode 100644 index 0000000000..f3c7a7c5da --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/python/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/wxPython/wxSWIG/swig_lib/python/pyexp.swg b/wxPython/wxSWIG/swig_lib/python/pyexp.swg index a7305579be..fdb93c57ae 100644 --- a/wxPython/wxSWIG/swig_lib/python/pyexp.swg +++ b/wxPython/wxSWIG/swig_lib/python/pyexp.swg @@ -1,3 +1,5 @@ +#include "Python.h" + #include #include /* Definitions for Windows/Unix exporting */ @@ -15,12 +17,9 @@ # define SWIGEXPORT(a) a #endif -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif - extern void SWIG_MakePtr(char *, void *, char *); extern void SWIG_RegisterMapping(char *, char *, void *(*)(void *)); extern char *SWIG_GetPtr(char *, void **, char *); diff --git a/wxPython/wxSWIG/swig_lib/python/python.swg b/wxPython/wxSWIG/swig_lib/python/python.swg index 9fca855598..bbcd168165 100644 --- a/wxPython/wxSWIG/swig_lib/python/python.swg +++ b/wxPython/wxSWIG/swig_lib/python/python.swg @@ -5,11 +5,11 @@ * Contains variable linking and pointer type-checking code. ************************************************************************/ +#include "Python.h" + #include #include -#include "Python.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/wxPython/wxSWIG/swig_lib/tcl/.cvsignore b/wxPython/wxSWIG/swig_lib/tcl/.cvsignore new file mode 100644 index 0000000000..f3c7a7c5da --- /dev/null +++ b/wxPython/wxSWIG/swig_lib/tcl/.cvsignore @@ -0,0 +1 @@ +Makefile -- 2.45.2