From: Robin Dunn Date: Thu, 8 Aug 2002 18:28:21 +0000 (+0000) Subject: Moved tools to be a Python package in wxPython.tools, added scripts to X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f6f98ecccd755993c8ba6354281fad271917be25 Moved tools to be a Python package in wxPython.tools, added scripts to import and launch each tool. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16418 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/wxPython/CHANGES.txt b/wxPython/CHANGES.txt index 21eb15506d..579493668d 100644 --- a/wxPython/CHANGES.txt +++ b/wxPython/CHANGES.txt @@ -155,6 +155,8 @@ respond to mouse events and etc. Changed the wxDateTime.Parse* methods to return an int that will be -1 on failure, and the index where parsing stopped otherwise. +Moved tools to be a Python package in wxPython.tools, added scripts to +import and launch each tool. diff --git a/wxPython/MANIFEST.in b/wxPython/MANIFEST.in index 844ec9f2df..11ad108fbd 100644 --- a/wxPython/MANIFEST.in +++ b/wxPython/MANIFEST.in @@ -100,14 +100,16 @@ include src/mac/*.cpp include src/mac/*.h include src/mac/*.py -include tools/*.py -include tools/XRCed/CHANGES -include tools/XRCed/TODO -include tools/XRCed/README -include tools/XRCed/*.py -include tools/XRCed/*.xrc -include tools/XRCed/*.ico -include tools/XRCed/*.sh +include wxPython/tools/*.py +include wxPython/tools/XRCed/CHANGES +include wxPython/tools/XRCed/TODO +include wxPython/tools/XRCed/README +include wxPython/tools/XRCed/*.py +include wxPython/tools/XRCed/*.xrc +include wxPython/tools/XRCed/*.ico +include wxPython/tools/XRCed/*.sh + +include scripts/* include contrib/glcanvas/*.i include contrib/glcanvas/*.py diff --git a/wxPython/distrib/make_installer.py b/wxPython/distrib/make_installer.py index 0532fd5bb0..b7ed38f9a0 100644 --- a/wxPython/distrib/make_installer.py +++ b/wxPython/distrib/make_installer.py @@ -136,14 +136,16 @@ Source: "licence\*.txt"; DestDir: "{app}\wxPython\docs\licenc Source: "%(WXDIR)s\docs\htmlhelp\wx.chm"; DestDir: "{app}\wxPython\docs"; Components: docs Source: "%(WXDIR)s\docs\htmlhelp\ogl.chm"; DestDir: "{app}\wxPython\docs"; Components: docs -Source: "tools\*.py"; DestDir: "{app}\wxPython\tools"; Components: tools -Source: "tools\XRCed\CHANGES"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools -Source: "tools\XRCed\TODO"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools -Source: "tools\XRCed\README"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools -Source: "tools\XRCed\*.py"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools -Source: "tools\XRCed\*.xrc"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools -Source: "tools\XRCed\*.ico"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools -Source: "tools\XRCed\*.sh"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\*.py"; DestDir: "{app}\wxPython\tools"; Components: tools +Source: "wxPython\tools\XRCed\CHANGES"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\XRCed\TODO"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\XRCed\README"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\XRCed\*.py"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\XRCed\*.xrc"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\XRCed\*.ico"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools +Source: "wxPython\tools\XRCed\*.sh"; DestDir: "{app}\wxPython\tools\XRCed"; Components: tools + +;; Where to put the scripts on Win32??? Source: "samples\doodle\*.py"; DestDir: "{app}\wxPython\samples\doodle"; Components: samples Source: "samples\doodle\*.txt"; DestDir: "{app}\wxPython\samples\doodle"; Components: samples diff --git a/wxPython/scripts/img2png b/wxPython/scripts/img2png new file mode 100755 index 0000000000..690072ec46 --- /dev/null +++ b/wxPython/scripts/img2png @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from wxPython.tools.img2png import main +main() + diff --git a/wxPython/scripts/img2py b/wxPython/scripts/img2py new file mode 100755 index 0000000000..a3ce91bbd3 --- /dev/null +++ b/wxPython/scripts/img2py @@ -0,0 +1,6 @@ +#!/usr/bin/env python + +import sys +from wxPython.tools.img2py import main +main(sys.argv[1:]) + diff --git a/wxPython/scripts/img2xpm b/wxPython/scripts/img2xpm new file mode 100755 index 0000000000..899faf12f2 --- /dev/null +++ b/wxPython/scripts/img2xpm @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +from wxPython.tools.img2xpm import main +main() + diff --git a/wxPython/scripts/xrced b/wxPython/scripts/xrced new file mode 100755 index 0000000000..135192e440 --- /dev/null +++ b/wxPython/scripts/xrced @@ -0,0 +1,4 @@ +#!/usr/bin/env python + +from wxPython.tools.XRCed.xrced import main +main() diff --git a/wxPython/setup.py b/wxPython/setup.py index 3f402d577e..66226f0fde 100755 --- a/wxPython/setup.py +++ b/wxPython/setup.py @@ -904,14 +904,22 @@ if __name__ == "__main__": PKGDIR+'.lib.editor', PKGDIR+'.lib.mixins', PKGDIR+'.lib.PyCrust', + PKGDIR+'.tools', + PKGDIR+'.tools.XRCed', ], ext_package = PKGDIR, ext_modules = wxpExtensions, - options = { 'build' : { 'build_base' : BUILD_BASE }} + options = { 'build' : { 'build_base' : BUILD_BASE }}, ##data_files = TOOLS, + + scripts = ['scripts/img2png', + 'scripts/img2xpm', + 'scripts/img2py', + 'scripts/xrced', + ], ) else: diff --git a/wxPython/tools/XRCed/CHANGES b/wxPython/tools/XRCed/CHANGES deleted file mode 100644 index 89b20ff696..0000000000 --- a/wxPython/tools/XRCed/CHANGES +++ /dev/null @@ -1,74 +0,0 @@ -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 - - -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/tools/XRCed/README b/wxPython/tools/XRCed/README deleted file mode 100644 index 133ee2a2e5..0000000000 --- a/wxPython/tools/XRCed/README +++ /dev/null @@ -1,72 +0,0 @@ -******************************************************************************** - - XRCed README - -******************************************************************************** - -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). - -Of course wxGTK's XRC library (libwxxrc) must be installed. - -Installation on Windows ------------------------ - -Works with wxPython 2.3.2 for Python 2.2. - -Short manual ------------- - -XRCed's idea is very straightforward: it is a visual tool for editing an XML -file conforming to XRC format. Every operation performed in XRCed has direct -correspondence to XML structure. So it is not really a usual point-and-click -GUI builder, but don't let that scare you. - -To start xrced, change to the directory where you installed it and run -"python2.2 xrced.py". - -On UNIX you can edit wrapper script "xrced.sh" to point to your installation -directory. - -To create an object, first you should select some object in the tree (or the -root item if it's empty) then press the right mouse button and select an -appropriate command. The pulldown menu is context-dependent on the selected -object. - -XRCed tries to guess if new object should be added as a next sibling or a -child of current object, depending on the possibility of the object to have -child objects and expanded state (if tree item is collapsed, new object will -be sibling). You can change this behavior to create siblings by pressing and -holding the Shift and Control keys before clicking the mouse. - -Pressed Control key while pressing right button makes next item a sibling of -selected item regardless of its expanded state. - -Pressed Shift key changes the place for inserting new child to be before -selected child, not after as by default. - -Panel on the right contains object properties. Properties which are optional -should be "checked" first. This panel can be made separate by unchecking -"Embed Panel" in View menu. - -All properties can be edited as text, and some are supplied with special -editing controls. - -The names of the properties are exactly as in XRC file, and it's usually not -hard to guess what they do. XML ID is the name of the window, and must be -present for top-level windows (though this is not enforced by XRCed). - -To display the preview window double-click a top-level object (you should -assign an XMLID to it first), press "Test" toolbar button or select command -from View menu, or press F5. After that, if you select a child object, it -becomes highlighted, and if you change it, preview is updated when you select -another item or press Ctrl-R (refresh). To turn off automatic update, toggle -"View->Auto-refresh" or toolbar auto-refresh button (to the right of the -refresh button). - --------------------------------------------------------------------------------- - -Copyright 2001 Roman Rolinsky diff --git a/wxPython/tools/XRCed/TODO b/wxPython/tools/XRCed/TODO deleted file mode 100644 index 4b9cc1b2b3..0000000000 --- a/wxPython/tools/XRCed/TODO +++ /dev/null @@ -1,29 +0,0 @@ -TODO for XRCed -============== - -- Undo/Redo - -- menu - accel not displayed in preview - -+ tree icons - -- replace object with another, keeping children - -+ write tmp file for current dialog/panel/etc. - -+ XML indents - -? select same notebook pages after update - -- put some default values in tree ctrl etc. - -- special (fast) update for some values: pos/size, value/content, sizeritem - stuff (?), well, as much as possible - -- highlighting with better method - -- import XRC/WXR files - -+ disable some window creation when it's not valid - -- check for memory leaks from wx objects diff --git a/wxPython/tools/XRCed/images.py b/wxPython/tools/XRCed/images.py deleted file mode 100644 index 924c55d463..0000000000 --- a/wxPython/tools/XRCed/images.py +++ /dev/null @@ -1,368 +0,0 @@ -#---------------------------------------------------------------------- -# This file was generated by img2py.py -# -from wxPython.wx import wxBitmapFromXPMData, wxImageFromBitmap -import cPickle, zlib - - -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 getIconBitmap(): - return wxBitmapFromXPMData(getIconData()) - -def getIconImage(): - return wxImageFromBitmap(getIconBitmap()) - -#---------------------------------------------------------------------- -def getNewData(): - return cPickle.loads(zlib.decompress( -"x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\ -\x81\x9d0\xbdX$A\xf2\ -\xf9\xc3Z\x12\x010%\x15\xf2\x11` S\x82\x1e\x00-\xd9\x8b\xfa" )) - -def getNewBitmap(): - return wxBitmapFromXPMData(getNewData()) - -def getNewImage(): - return wxImageFromBitmap(getNewBitmap()) - -#---------------------------------------------------------------------- -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 getOpenBitmap(): - return wxBitmapFromXPMData(getOpenData()) - -def getOpenImage(): - return wxImageFromBitmap(getOpenBitmap()) - -#---------------------------------------------------------------------- -def getSaveData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV72Q02V0U0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xfc\ -\x81\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 getCopyBitmap(): - return wxBitmapFromXPMData(getCopyData()) - -def getCopyImage(): - return wxImageFromBitmap(getCopyBitmap()) - -#---------------------------------------------------------------------- -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' )) - -def getPasteBitmap(): - return wxBitmapFromXPMData(getPasteData()) - -def getPasteImage(): - return wxImageFromBitmap(getPasteBitmap()) - -#---------------------------------------------------------------------- -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 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' )) - -def getRefreshBitmap(): - return wxBitmapFromXPMData(getRefreshData()) - -def getRefreshImage(): - return wxImageFromBitmap(getRefreshBitmap()) - -#---------------------------------------------------------------------- -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 getTreeDefaultData(): - return cPickle.loads(zlib.decompress( -"x\xda\xd3\xc8)0\xe4\nV74S04Q0U0T\xe7J\x0cV\x8fPHVp\xcaIL\xce\x06\xf3\xfc\ -\x81\ -\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 getTreeDefaultBitmap(): - return wxBitmapFromXPMData(getTreeDefaultData()) - -def getTreeDefaultImage(): - return wxImageFromBitmap(getTreeDefaultBitmap()) - -#---------------------------------------------------------------------- -def getTreeRootData(): - return cPickle.loads(zlib.decompress( -'x\xda\xd3\xc8)0\xe4\nV74S04Q0V0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3"\x801\x82\xf9`@\ -\xc8LLo\xea\x01\x00\xb5\x9cde' )) - -def getTreeDialogBitmap(): - return wxBitmapFromXPMData(getTreeDialogData()) - -def getTreeDialogImage(): - return wxImageFromBitmap(getTreeDialogBitmap()) - -#---------------------------------------------------------------------- -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`,' )) - -def getTreeFrameBitmap(): - return wxBitmapFromXPMData(getTreeFrameData()) - -def getTreeFrameImage(): - return wxImageFromBitmap(getTreeFrameBitmap()) - -#---------------------------------------------------------------------- -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' )) - -def getTreeMenuBarBitmap(): - return wxBitmapFromXPMData(getTreeMenuBarData()) - -def getTreeMenuBarImage(): - return wxImageFromBitmap(getTreeMenuBarBitmap()) - -#---------------------------------------------------------------------- -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 getTreeToolBarBitmap(): - return wxBitmapFromXPMData(getTreeToolBarData()) - -def getTreeToolBarImage(): - return wxImageFromBitmap(getTreeToolBarBitmap()) - -#---------------------------------------------------------------------- -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 getTreeMenuBitmap(): - return wxBitmapFromXPMData(getTreeMenuData()) - -def getTreeMenuImage(): - return wxImageFromBitmap(getTreeMenuBitmap()) - -#---------------------------------------------------------------------- -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' )) - -def getTreeSizerHBitmap(): - return wxBitmapFromXPMData(getTreeSizerHData()) - -def getTreeSizerHImage(): - return wxImageFromBitmap(getTreeSizerHBitmap()) - -#---------------------------------------------------------------------- -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>*' )) - -def getTreeSizerVBitmap(): - return wxBitmapFromXPMData(getTreeSizerVData()) - -def getTreeSizerVImage(): - return wxImageFromBitmap(getTreeSizerVBitmap()) - -#---------------------------------------------------------------------- -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' )) - -def getTreeStaticBoxSizerHBitmap(): - return wxBitmapFromXPMData(getTreeStaticBoxSizerHData()) - -def getTreeStaticBoxSizerHImage(): - return wxImageFromBitmap(getTreeStaticBoxSizerHBitmap()) - -#---------------------------------------------------------------------- -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' )) - -def getTreeStaticBoxSizerVBitmap(): - return wxBitmapFromXPMData(getTreeStaticBoxSizerVData()) - -def getTreeStaticBoxSizerVImage(): - return wxImageFromBitmap(getTreeStaticBoxSizerVBitmap()) - -#---------------------------------------------------------------------- -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 getTreeSizerGridBitmap(): - return wxBitmapFromXPMData(getTreeSizerGridData()) - -def getTreeSizerGridImage(): - return wxImageFromBitmap(getTreeSizerGridBitmap()) - -#---------------------------------------------------------------------- -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 getTreeSizerFlexGridBitmap(): - return wxBitmapFromXPMData(getTreeSizerFlexGridData()) - -def getTreeSizerFlexGridImage(): - return wxImageFromBitmap(getTreeSizerFlexGridBitmap()) - diff --git a/wxPython/tools/XRCed/params.py b/wxPython/tools/XRCed/params.py deleted file mode 100644 index 319034e02e..0000000000 --- a/wxPython/tools/XRCed/params.py +++ /dev/null @@ -1,722 +0,0 @@ -# Name: params.py -# Purpose: Classes for parameter introduction -# Author: Roman Rolinsky -# Created: 22.08.2001 -# RCS-ID: $Id$ - -from wxPython.wx import * -from wxPython.xrc import * -import string -import os.path -from types import * - -# Object which is currently processed -currentXXX = None -def SetCurrentXXX(xxx): - global currentXXX - currentXXX = xxx - -genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', - 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', - 'wxSTATIC_BORDER', 'wxNO_BORDER', - 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', - 'wxNO_FULL_REPAINT_ON_RESIZE'] - -buttonSize = (55,-1) - -# 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 - 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) - -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()) - 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.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.text.SetValue(value) - 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(), '|')) - if value == ['']: value = [] - ignored = [] - for i in value: - try: - listBox.Check(self.values.index(i)) - except ValueError: - # Try to find equal - if self.equal.has_key(i): - listBox.Check(self.values.index(self.equal[i])) - else: - print 'WARNING: unknown flag: %s: ignored.' % i - ignored.append(i) - topSizer.Add(listBox, 1, wxEXPAND) - sizer = wxBoxSizer() - buttonOk = wxButton(dlg, wxID_OK, 'OK') - buttonOk.SetDefault() - sizer.Add(buttonOk, 0, wxRIGHT, 10) - sizer.Add(0, 0, 1) - sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel')) - topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10) - dlg.SetAutoLayout(true) - dlg.SetSizer(topSizer) - topSizer.Fit(dlg) - dlg.Center() - if dlg.ShowModal() == wxID_OK: - value = [] - for i in range(listBox.Number()): - if listBox.IsChecked(i): - value.append(self.values[i]) - # Add ignored flags - value.extend(ignored) - if value: - self.SetValue(reduce(lambda a,b: a+'|'+b, value)) - else: - self.SetValue('') - self.SetModified() - dlg.Destroy() - -class ParamFlag(ParamBinaryOr): - values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', - 'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', - 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', - 'wxALIGN_CENTRE_HORIZONTAL'] - equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE', - 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', - 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'} - def __init__(self, parent, name): - ParamBinaryOr.__init__(self, parent, name) - -class ParamStyle(ParamBinaryOr): - equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'} - def __init__(self, parent, name): - self.values = currentXXX.winStyles + genericStyles - ParamBinaryOr.__init__(self, parent, name) - -class ParamNonGenericStyle(ParamBinaryOr): - def __init__(self, parent, name): - self.values = 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 - else: - self.values = [] - ParamBinaryOr.__init__(self, parent, name) - -class ParamColour(PPanel): - def __init__(self, parent, name): - PPanel.__init__(self, parent, name) - self.ID_TEXT_CTRL = wxNewId() - self.ID_BUTTON = wxNewId() - self.SetBackgroundColour(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(40, -1)) - sizer.Add(self.button, 0, wxGROW) - self.SetAutoLayout(true) - self.SetSizer(sizer) - sizer.Fit(self) - 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 - 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() - def OnPaintButton(self, evt): - dc = wxPaintDC(self.button) - dc.SetBrush(wxTRANSPARENT_BRUSH) - if self.IsEnabled(): dc.SetPen(wxBLACK_PEN) - else: dc.SetPen(wxGREY_PEN) - size = self.button.GetSize() - dc.DrawRectangle(0, 0, size.x, size.y) - def OnLeftDown(self, evt): - data = wxColourData() - data.SetColour(self.GetValue()) - dlg = wxColourDialog(self, data) - if dlg.ShowModal() == wxID_OK: - self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get()) - self.SetModified() - dlg.Destroy() - -################################################################################ - -# Mapping from wx constants ro XML strings -fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative', - wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss', - wxMODERN: 'modern'} -fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'} -fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'} -def ReverseMap(m): - rm = {} - for k,v in m.items(): rm[v] = k - return rm -fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml) -fontStylesXml2wx = ReverseMap(fontStylesWx2Xml) -fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml) - -class ParamFont(PPanel): - def __init__(self, parent, name): - PPanel.__init__(self, parent, name) - self.ID_TEXT_CTRL = wxNewId() - self.ID_BUTTON_SELECT = wxNewId() - self.SetBackgroundColour(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.SetSizer(sizer) - sizer.Fit(self) - 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() - def _defaultValue(self): - return ['12', 'default', 'normal', 'normal', '0', '', ''] - def GetValue(self): - if self.textModified: # text has newer value - try: - return eval(self.text.GetValue()) - except SyntaxError: - wxLogError('Syntax error in parameter value: ' + self.GetName()) - return self._defaultValue() - return self.value - def SetValue(self, value): - 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 - def OnButtonSelect(self, evt): - if self.textModified: # text has newer value - try: - self.value = eval(self.text.GetValue()) - except SyntaxError: - wxLogError('Syntax error in parameter value: ' + self.GetName()) - self.value = self._defaultValue() - # Make initial font - # Default values - size = 12 - family = wxDEFAULT - style = weight = wxNORMAL - underlined = 0 - face = '' - enc = wxFONTENCODING_DEFAULT - # Fall back to default if exceptions - error = false - try: - try: size = int(self.value[0]) - except ValueError: error = true - try: family = fontFamiliesXml2wx[self.value[1]] - except KeyError: error = true - try: style = fontStylesXml2wx[self.value[2]] - except KeyError: error = true - try: weight = fontWeightsXml2wx[self.value[3]] - except KeyError: error = true - try: underlined = int(self.value[4]) - 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 - if error: wxLogError('Invalid font specification') - if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM - font = wxFont(size, family, style, weight, underlined, face, enc) - data = wxFontData() - data.SetInitialFont(font) - dlg = wxFontDialog(self, data) - if dlg.ShowModal() == wxID_OK: - font = dlg.GetFontData().GetChosenFont() - value = [str(font.GetPointSize()), - fontFamiliesWx2Xml.get(font.GetFamily(), "default"), - fontStylesWx2Xml.get(font.GetStyle(), "normal"), - fontWeightsWx2Xml.get(font.GetWeight(), "normal"), - str(font.GetUnderlined()), - font.GetFaceName(), - wxFontMapper_GetEncodingName(font.GetEncoding()) - ] - # Add ignored flags - self.SetValue(value) - self.SetModified() - self.textModified = false - dlg.Destroy() - -################################################################################ - -class ParamInt(PPanel): - def __init__(self, parent, name): - PPanel.__init__(self, parent, name) - self.ID_SPIN_CTRL = wxNewId() - sizer = wxBoxSizer() - self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=wxSize(50,-1)) - self.SetBackgroundColour(panel.GetBackgroundColour()) - sizer.Add(self.spin) - 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 - 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() - -class ParamText(PPanel): - def __init__(self, parent, name, textWidth=200): - 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.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1)) - sizer.Add(self.text, 0, 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.text.SetValue(value) - self.freeze = false # disable other handlers - def OnChange(self, evt): - if self.freeze: return - self.SetModified() - evt.Skip() - -class ParamAccel(ParamText): - def __init__(self, parent, name): - ParamText.__init__(self, parent, name, 50) - -class ParamPosSize(ParamText): - def __init__(self, parent, name): - ParamText.__init__(self, parent, name, 80) - -class ContentDialog(wxDialogPtr): - def __init__(self, parent, value): - # Is this normal??? - w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT') - wxDialogPtr.__init__(self, w.this) - self.thisown = 1 - self.Center() - self.list = self.FindWindowByName('LIST') - # Set list items - for v in value: - self.list.Append(v) - self.SetAutoLayout(true) - self.GetSizer().Fit(self) - # Callbacks - self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND') - self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE') - self.ID_BUTTON_UP = XMLID('BUTTON_UP') - self.ID_BUTTON_DOWN = XMLID('BUTTON_DOWN') - EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) - EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) - EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) - EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) - EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) - EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) - EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) - def OnButtonUp(self, evt): - i = self.list.GetSelection() - str = self.list.GetString(i) - self.list.Delete(i) - self.list.InsertItems([str], i-1) - self.list.SetSelection(i-1) - def OnButtonDown(self, evt): - i = self.list.GetSelection() - str = self.list.GetString(i) - self.list.Delete(i) - self.list.InsertItems([str], i+1) - self.list.SetSelection(i+1) - def OnButtonAppend(self, evt): - str = wxGetTextFromUser('Enter new item:', 'Append', '', self) - self.list.Append(str) - def OnButtonRemove(self, evt): - self.list.Delete(self.list.GetSelection()) - def OnUpdateUI(self, evt): - if evt.GetId() == self.ID_BUTTON_REMOVE: - evt.Enable(self.list.GetSelection() != -1) - elif evt.GetId() == self.ID_BUTTON_UP: - evt.Enable(self.list.GetSelection() > 0) - elif evt.GetId() == self.ID_BUTTON_DOWN: - evt.Enable(self.list.GetSelection() != -1 and \ - self.list.GetSelection() < self.list.Number() - 1) - -class ContentCheckListDialog(wxDialogPtr): - def __init__(self, parent, value): - # Is this normal??? - w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST') - wxDialogPtr.__init__(self, w.this) - self.thisown = 1 - self.Center() - self.list = self.FindWindowByName('CHECK_LIST') - # Set list items - i = 0 - for v,ch in value: - self.list.Append(v) - self.list.Check(i, ch) - i += 1 - self.SetAutoLayout(true) - self.GetSizer().Fit(self) - # Callbacks - self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND') - self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE') - self.ID_BUTTON_UP = XMLID('BUTTON_UP') - self.ID_BUTTON_DOWN = XMLID('BUTTON_DOWN') - EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck) - EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) - EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) - EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) - EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) - EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) - EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) - EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) - def OnCheck(self, evt): - # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking - self.list.Deselect(evt.GetSelection()) - def OnButtonUp(self, evt): - i = self.list.GetSelection() - str, ch = self.list.GetString(i), self.list.IsChecked(i) - self.list.Delete(i) - self.list.InsertItems([str], i-1) - self.list.Check(i-1, ch) - self.list.SetSelection(i-1) - def OnButtonDown(self, evt): - i = self.list.GetSelection() - str, ch = self.list.GetString(i), self.list.IsChecked(i) - self.list.Delete(i) - self.list.InsertItems([str], i+1) - self.list.Check(i+1, ch) - self.list.SetSelection(i+1) - def OnButtonAppend(self, evt): - str = wxGetTextFromUser('Enter new item:', 'Append', '', self) - self.list.Append(str) - def OnButtonRemove(self, evt): - self.list.Delete(self.list.GetSelection()) - def OnUpdateUI(self, evt): - if evt.GetId() == self.ID_BUTTON_REMOVE: - evt.Enable(self.list.GetSelection() != -1) - elif evt.GetId() == self.ID_BUTTON_UP: - evt.Enable(self.list.GetSelection() > 0) - elif evt.GetId() == self.ID_BUTTON_DOWN: - evt.Enable(self.list.GetSelection() != -1 and \ - self.list.GetSelection() < self.list.Number() - 1) - -class ParamContent(PPanel): - def __init__(self, parent, name): - PPanel.__init__(self, parent, name) - self.ID_TEXT_CTRL = wxNewId() - self.ID_BUTTON_EDIT = wxNewId() - self.SetBackgroundColour(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.SetSizer(sizer) - sizer.Fit(self) - 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() - def GetValue(self): - if self.textModified: # text has newer value - try: - return eval(self.text.GetValue()) - except SyntaxError: - wxLogError('Syntax error in parameter value: ' + self.GetName()) - return [] - return self.value - def SetValue(self, value): - self.freeze = true - if not value: value = [] - self.value = value - self.text.SetValue(str(value)) # update text ctrl - self.freeze = false - def OnButtonEdit(self, evt): - if self.textModified: # text has newer value - try: - self.value = eval(self.text.GetValue()) - except SyntaxError: - wxLogError('Syntax error in parameter value: ' + self.GetName()) - self.value = [] - dlg = ContentDialog(self, self.value) - if dlg.ShowModal() == wxID_OK: - value = [] - for i in range(dlg.list.Number()): - value.append(dlg.list.GetString(i)) - # Add ignored flags - self.SetValue(value) - self.SetModified() - self.textModified = false - dlg.Destroy() - -# CheckList content -class ParamContentCheckList(ParamContent): - def __init__(self, parent, name): - ParamContent.__init__(self, parent, name) - def OnButtonEdit(self, evt): - if self.textModified: # text has newer value - try: - self.value = eval(self.text.GetValue()) - except SyntaxError: - wxLogError('Syntax error in parameter value: ' + self.GetName()) - self.value = [] - dlg = ContentCheckListDialog(self, self.value) - if dlg.ShowModal() == wxID_OK: - value = [] - for i in range(dlg.list.Number()): - value.append((dlg.list.GetString(i), dlg.list.IsChecked(i))) - # Add ignored flags - self.SetValue(value) - self.SetModified() - self.textModified = false - dlg.Destroy() - -class IntListDialog(wxDialogPtr): - def __init__(self, parent, value): - # Is this normal??? - w = frame.res.LoadDialog(parent, 'DIALOG_INTLIST') - wxDialogPtr.__init__(self, w.this) - self.thisown = 1 - self.Center() - self.list = self.FindWindowByName('LIST') - # Set list items - value.sort() - for v in value: - if type(v) != IntType: - wxLogError('Invalid item type') - else: - self.list.Append(str(v)) - self.SetAutoLayout(true) - self.GetSizer().Fit(self) - # Callbacks - self.ID_BUTTON_ADD = XMLID('BUTTON_ADD') - self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE') - EVT_BUTTON(self, self.ID_BUTTON_ADD, self.OnButtonAppend) - EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) - EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) - def OnButtonAppend(self, evt): - s = wxGetTextFromUser('Enter new number:', 'Add', '', self) - # Check that it's unique - try: - v = int(s) - s = str(v) # to be sure - i = self.list.FindString(s) - if i == -1: # ignore non-unique - # Find place to insert - found = false - for i in range(self.list.Number()): - if int(self.list.GetString(i)) > v: - found = true - break - if found: self.list.InsertItems([s], i) - else: self.list.Append(s) - except ValueError: - wxLogError('List item is not an int!') - def OnButtonRemove(self, evt): - self.list.Delete(self.list.GetSelection()) - def OnUpdateUI(self, evt): - if evt.GetId() == self.ID_BUTTON_REMOVE: - evt.Enable(self.list.GetSelection() != -1) - -# For growable list -class ParamIntList(ParamContent): - def __init__(self, parent, name): - ParamContent.__init__(self, parent, name) - def OnButtonEdit(self, evt): - if self.textModified: # text has newer value - try: - self.value = eval(self.text.GetValue()) - except SyntaxError: - wxLogError('Syntax error in parameter value: ' + self.GetName()) - self.value = [] - dlg = IntListDialog(self, self.value) - if dlg.ShowModal() == wxID_OK: - value = [] - for i in range(dlg.list.Number()): - value.append(int(dlg.list.GetString(i))) - # Add ignored flags - self.SetValue(value) - self.SetModified() - self.textModified = false - dlg.Destroy() - -# Boxless radiobox -class RadioBox(PPanel): - def __init__(self, parent, id, choices, - pos=wxDefaultPosition, name='radiobox'): - PPanel.__init__(self, parent, name) - self.SetBackgroundColour(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.SetSizer(topSizer) - topSizer.Fit(self) - def SetStringSelection(self, value): - self.freeze = true - for i in self.choices: - self.FindWindowByName(i).SetValue(i == value) - self.value = value - self.freeze = false - def OnRadioChoice(self, evt): - if self.freeze: return - if evt.GetSelection(): - self.value = evt.GetEventObject().GetName() - self.SetModified() - def GetStringSelection(self): - return self.value - -class ParamBool(RadioBox): - values = {'yes': '1', 'no': '0'} - seulav = {'1': 'yes', '0': 'no'} - def __init__(self, parent, name): - RadioBox.__init__(self, parent, -1, choices = self.values.keys(), name=name) - def GetValue(self): - return self.values[self.GetStringSelection()] - def SetValue(self, value): - if not value: value = '1' - self.SetStringSelection(self.seulav[value]) - -class ParamOrient(RadioBox): - values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'} - seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'} - def __init__(self, parent, name): - RadioBox.__init__(self, parent, -1, choices = self.values.keys(), name=name) - def GetValue(self): - return self.values[self.GetStringSelection()] - def SetValue(self, value): - if not value: value = 'wxHORIZONTAL' - self.SetStringSelection(self.seulav[value]) - -class ParamFile(PPanel): - def __init__(self, parent, name): - PPanel.__init__(self, parent, name) - self.ID_TEXT_CTRL = wxNewId() - self.ID_BUTTON_BROWSE = wxNewId() - self.SetBackgroundColour(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.SetSizer(sizer) - sizer.Fit(self) - 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() - 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.value = value - self.text.SetValue(value) # update text ctrl - 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), - defaultFile = os.path.basename(self.value)) - if dlg.ShowModal() == wxID_OK: - # Make relative - common = os.path.commonprefix([os.path.abspath(frame.dataFile), - 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, - '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, - } - diff --git a/wxPython/tools/XRCed/xrced.ico b/wxPython/tools/XRCed/xrced.ico deleted file mode 100644 index 6c9964d2fb..0000000000 Binary files a/wxPython/tools/XRCed/xrced.ico and /dev/null differ diff --git a/wxPython/tools/XRCed/xrced.py b/wxPython/tools/XRCed/xrced.py deleted file mode 100644 index 503c1b1b0f..0000000000 --- a/wxPython/tools/XRCed/xrced.py +++ /dev/null @@ -1,1918 +0,0 @@ -# Name: xrced.py -# Purpose: XRC editor, main module -# Author: Roman Rolinsky -# 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 - -# Constants - -# Return code from wxGetOsVersion -wxGTK = 9 - -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) - -progname = 'XRCed' -version = '0.0.7-3' - -# Local modules -from xxx import * - -# Globals -testWin = None -testWinPos = wxDefaultPosition - -# 1 adds CMD command to Help menu -debug = 0 - -helpText = """\ -

Welcome to XRCed!

DON'T PANIC :)

-To start select tree root, then popup menu with your right mouse button, -select "Append Child", and then any command.

-Enter XML ID, change properties, create children.

-To test your interface select Test command (View menu).

-Consult README file for the details. -""" - -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 - # 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.LoadFrame(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 -class ScrolledMessageDialog(wxDialog): - def __init__(self, parent, msg, caption, pos = wxDefaultPosition, size = (500,300)): - from wxPython.lib.layoutf import Layoutf - wxDialog.__init__(self, parent, -1, caption, pos, size) - text = wxTextCtrl(self, -1, msg, wxDefaultPosition, - wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY) - text.SetFont(modernFont) - dc = wxWindowDC(text) - w, h = dc.GetTextExtent(' ') - 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.Fit() - self.CenterOnScreen(wxBOTH) - -################################################################################ - -class Frame(wxFrame): - def __init__(self, pos, size): - global frame - frame = self - wxFrame.__init__(self, None, -1, '', pos, size) - self.CreateStatusBar() - icon = wxIcon(os.path.join(sys.path[0], 'xrced.ico'), wxBITMAP_TYPE_ICO) - self.SetIcon(icon) - - # Idle flag - self.inIdle = false - - # Make menus - menuBar = wxMenuBar() - - menu = wxMenu() - menu.Append(wxID_NEW, '&New\tCtrl-N', 'New file') - menu.Append(wxID_OPEN, '&Open...\tCtrl-O', 'Open XRC file') - menu.Append(wxID_SAVE, '&Save\tCtrl-S', 'Save XRC file') - menu.Append(wxID_SAVEAS, 'Save &As...', 'Save XRC file under different name') - menu.AppendSeparator() - menu.Append(wxID_EXIT, '&Quit\tCtrl-Q', 'Exit application') - menuBar.Append(menu, '&File') - - menu = wxMenu() - menu.Append(wxID_UNDO, '&Undo\tCtrl-Z', 'Undo') - menu.Append(wxID_REDO, '&Redo\tCtrl-Y', 'Redo') - menu.AppendSeparator() - menu.Append(wxID_CUT, 'Cut\tCtrl-X', 'Cut to the clipboard') - menu.Append(wxID_COPY, '&Copy\tCtrl-C', 'Copy to the clipboard') - 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') - 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) - menu.Check(self.ID_EMBED_PANEL, conf.embedPanel) - menu.AppendSeparator() - self.ID_TEST = wxNewId() - menu.Append(self.ID_TEST, '&Test\tF5', 'Test window') - self.ID_REFRESH = wxNewId() - 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) - menu.Check(self.ID_AUTO_REFRESH, conf.autoRefresh) - menuBar.Append(menu, '&View') - - menu = wxMenu() - menu.Append(wxID_ABOUT, '&About...', 'About XCRed') - self.ID_README = wxNewId() - menu.Append(self.ID_README, '&Readme...', 'View the README file') - if debug: - self.ID_DEBUG_CMD = wxNewId() - menu.Append(self.ID_DEBUG_CMD, 'CMD', 'Python command line') - EVT_MENU(self, self.ID_DEBUG_CMD, self.OnDebugCMD) - menuBar.Append(menu, '&Help') - - self.menuBar = menuBar - self.SetMenuBar(menuBar) - - # Create toolbar - tb = self.CreateToolBar(wxTB_HORIZONTAL | wxNO_BORDER | wxTB_FLAT) - tb.SetToolBitmapSize((24, 23)) - tb.AddSimpleTool(wxID_NEW, images.getNewBitmap(), 'New', 'New file') - 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_CUT, images.getCutBitmap(), 'Cut', 'Cut') - tb.AddSimpleTool(wxID_COPY, images.getCopyBitmap(), 'Copy', 'Copy') - tb.AddSimpleTool(wxID_PASTE, images.getPasteBitmap(), 'Paste', 'Paste') - tb.AddControl(wxStaticLine(tb, -1, size=(-1,23), style=wxLI_VERTICAL)) - tb.AddSimpleTool(self.ID_TEST, images.getTestBitmap(), 'Test', 'Test window') - 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: - tb.AddSeparator() # otherwise auto-refresh sticks in status line - tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh) - tb.Realize() - self.tb = tb - self.minWidth = tb.GetSize()[0] # minimal width is the size of toolbar - - # File - EVT_MENU(self, wxID_NEW, self.OnNew) - EVT_MENU(self, wxID_OPEN, self.OnOpen) - EVT_MENU(self, wxID_SAVE, self.OnSaveOrSaveAs) - EVT_MENU(self, wxID_SAVEAS, self.OnSaveOrSaveAs) - EVT_MENU(self, wxID_EXIT, self.OnExit) - # 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_COPY, self.OnCopy) - EVT_MENU(self, wxID_PASTE, self.OnPaste) - EVT_MENU(self, self.ID_DELETE, self.OnDelete) - # View - EVT_MENU(self, self.ID_EMBED_PANEL, self.OnEmbedPanel) - 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) - # Help - EVT_MENU(self, wxID_ABOUT, self.OnAbout) - EVT_MENU(self, self.ID_README, self.OnReadme) - - # Update events - 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, self.ID_DELETE, self.OnUpdateUI) - EVT_UPDATE_UI(self, self.ID_TEST, self.OnUpdateUI) - EVT_UPDATE_UI(self, self.ID_REFRESH, self.OnUpdateUI) - - # Build interface - sizer = wxBoxSizer(wxVERTICAL) - sizer.Add(wxStaticLine(self, -1), 0, wxEXPAND) - 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 - # !!! frame styles are broken - # Miniframe for not embedded mode - miniFrame = wxFrame(self, -1, 'Properties Panel', - (conf.panelX, conf.panelY), - (conf.panelWidth, conf.panelHeight)) - self.miniFrame = miniFrame - sizer2 = wxBoxSizer() - miniFrame.SetAutoLayout(true) - miniFrame.SetSizer(sizer2) - EVT_CLOSE(self.miniFrame, self.OnCloseMiniFrame) - # Create panel for parameters - global panel - if conf.embedPanel: - panel = Panel(splitter) - # Set plitter windows - splitter.SplitVertically(tree, panel, conf.sashPos) - else: - panel = Panel(miniFrame) - sizer2.Add(panel, 1, wxEXPAND) - miniFrame.Show(true) - splitter.Initialize(tree) - sizer.Add(splitter, 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.Clear() - - # Other events - EVT_IDLE(self, self.OnIdle) - EVT_CLOSE(self, self.OnCloseWindow) - - def OnNew(self, evt): - self.Clear() - - def OnOpen(self, evt): - if not self.AskSave(): return - dlg = wxFileDialog(self, 'Open', os.path.dirname(self.dataFile), - '', '*.xrc', wxOPEN | wxCHANGE_DIR) - if dlg.ShowModal() == wxID_OK: - path = dlg.GetPath() - self.SetStatusText('Loading...') - wxYield() - wxBeginBusyCursor() - try: - self.Open(path) - self.SetStatusText('Data loaded') - except: - self.SetStatusText('Failed') - raise - wxEndBusyCursor() - dlg.Destroy() - - def OnSaveOrSaveAs(self, evt): - if evt.GetId() == wxID_SAVEAS or not self.dataFile: - if self.dataFile: defaultName = '' - else: defaultName = 'UNTITLED.xrc' - dlg = wxFileDialog(self, 'Save As', os.path.dirname(self.dataFile), - defaultName, '*.xrc', - wxSAVE | wxOVERWRITE_PROMPT | wxCHANGE_DIR) - if dlg.ShowModal() == wxID_OK: - path = dlg.GetPath() - dlg.Destroy() - else: - dlg.Destroy() - return - else: - path = self.dataFile - self.SetStatusText('Saving...') - wxYield() - wxBeginBusyCursor() - try: - self.Save(path) - self.dataFile = path - self.SetStatusText('Data saved') - except IOError: - self.SetStatusText('Failed') - wxEndBusyCursor() - - def OnExit(self, evt): - 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) ) - - 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') - - 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.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 - 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) - # Expanded container (must have children) - elif tree.IsExpanded(selected) and tree.GetChildrenCount(selected, false): - appendChild = 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) - if parent.hasChild: parent = parent.child - - # Create a copy of clipboard element - elem = self.clipboard.cloneNode(true) - # Tempopary xxx object to test things - xxx = MakeXXXFromDOM(parent, elem) - - # Check compatibility - error = false - # Top-level - x = xxx.treeObject() - if x.__class__ in [xxxDialog, xxxFrame, xxxMenuBar, xxxToolBar]: - if parent.__class__ != xxxMainNode: error = true - elif x.__class__ == xxxPanel and parent.__class__ == xxxMainNode: - pass - elif x.__class__ == xxxSpacer: - if not parent.isSizer: error = true - elif x.__class__ == xxxSeparator: - if not parent.__class__ in [xxxMenu, xxxToolBar]: error = true - elif x.__class__ == xxxTool: - if parent.__class__ != xxxToolBar: error = true - elif x.__class__ == xxxMenuItem: - 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 - if error: - if parent.__class__ == xxxMainNode: parentClass = 'root' - else: parentClass = parent.className - wxLogError('Incompatible parent/child: parent is %s, child is %s!' % - (parentClass, x.className)) - return - - # Check parent and child relationships. - # If parent is sizer or notebook, child is of wrong class or - # parent is normal window, child is child container then detach child. - isChildContainer = isinstance(xxx, xxxChildContainer) - if isChildContainer and \ - ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) 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 - # 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 - sizerItemElem = MakeEmptyDOM('sizeritem') - sizerItemElem.appendChild(elem) - elem = sizerItemElem - elif isinstance(parent, xxxNotebook) and not isChildContainer: - 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 - 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 conf.autoRefresh: - tree.needUpdate = true - tree.pendingHighLight = newItem - else: - tree.pendingHighLight = None - self.modified = true - self.SetStatusText('Pasted') - - def OnDelete(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)] - # 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 - xnode = tree.RemoveLeaf(selected) - # !!! cloneNode is broken, or something is wrong -# self.undo.append(xnode.cloneNode(true)) - xnode.unlink() - tree.pendingHighLight = None - tree.Unselect() - panel.Clear() - self.modified = true - self.SetStatusText('Deleted') - - def OnEmbedPanel(self, evt): - conf.embedPanel = evt.IsChecked() - if conf.embedPanel: - # Remember last dimentions - conf.panelX, conf.panelY = self.miniFrame.GetPosition() - conf.panelWidth, conf.panelHeight = self.miniFrame.GetSize() - size = self.GetSize() - pos = self.GetPosition() - sizePanel = panel.GetSize() - panel.Reparent(self.splitter) - self.miniFrame.GetSizer().RemoveWindow(panel) - wxYield() - # Widen - self.SetDimensions(pos.x, pos.y, size.x + sizePanel.x, size.y) - self.splitter.SplitVertically(tree, panel, conf.sashPos) - self.miniFrame.Show(false) - else: - conf.sashPos = self.splitter.GetSashPosition() - pos = self.GetPosition() - size = self.GetSize() - sizePanel = panel.GetSize() - self.splitter.Unsplit(panel) - sizer = self.miniFrame.GetSizer() - panel.Reparent(self.miniFrame) - panel.Show(true) - sizer.Add(panel, 1, wxEXPAND) - self.miniFrame.Show(true) - self.miniFrame.SetDimensions(conf.panelX, conf.panelY, - conf.panelWidth, conf.panelHeight) - wxYield() - # Reduce width - self.SetDimensions(pos.x, pos.y, - max(size.x - sizePanel.x, self.minWidth), size.y) - - def OnTest(self, evt): - if not tree.selection: return # key pressed event - tree.ShowTestWindow(tree.selection) - - def OnRefresh(self, evt): - # If modified, apply first - selection = tree.selection - if selection: - xxx = tree.GetPyData(selection) - if xxx and panel.IsModified(): - tree.Apply(xxx, selection) - if testWin: - # (re)create - tree.CreateTestWin(testWin.item) - tree.needUpdate = false - - def OnAutoRefresh(self, evt): - conf.autoRefresh = evt.IsChecked() - self.menuBar.Check(self.ID_AUTO_REFRESH, conf.autoRefresh) - self.tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh) - - def OnAbout(self, evt): - str = '%s %s\n\nRoman Rolinsky ' % \ - (progname, version) - dlg = wxMessageDialog(self, str, 'About ' + progname, wxOK | wxCENTRE) - dlg.ShowModal() - dlg.Destroy() - - def OnReadme(self, evt): - text = open(os.path.join(sys.path[0], 'README'), 'r').read() - dlg = ScrolledMessageDialog(self, text, "XRCed README") - dlg.ShowModal() - dlg.Destroy() - - - # Simple emulation of python command line - def OnDebugCMD(self, evt): - import traceback - while 1: - try: - exec raw_input('C:\> ') - except EOFError: - print '^D' - break - except: - (etype, value, tb) =sys.exc_info() - tblist =traceback.extract_tb(tb)[1:] - msg =string.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 - else: appendChild = not tree.NeedInsert(selected) - xxx = tree.GetPyData(selected) - if not appendChild: - # If insert before - if tree.shift: - # If has previous item, insert after it, else append to parent - nextItem = selected - parentLeaf = tree.GetItemParent(selected) - 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) - # Expanded container (must have children) - elif tree.shift and tree.IsExpanded(selected) \ - and tree.GetChildrenCount(selected, false): - appendChild = 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) - if parent.hasChild: parent = parent.child - - # Create element - className = self.createMap[evt.GetId()] - xxx = MakeEmptyXXX(parent, className) - - # Set default name for top-level windows - if parent.__class__ == xxxMainNode: - cl = xxx.treeObject().__class__ - frame.maxIDs[cl] += 1 - 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 - 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)) - 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 conf.autoRefresh: - tree.needUpdate = true - tree.pendingHighLight = newItem - else: - tree.pendingHighLight = None - - # Expand/collapse subtree - def OnExpand(self, evt): - if tree.selection: tree.ExpandAll(tree.selection) - else: tree.ExpandAll(tree.root) - def OnCollapse(self, evt): - if tree.selection: tree.CollapseAll(tree.selection) - else: tree.CollapseAll(tree.root) - - def OnPullDownHighlight(self, evt): - menuId = evt.GetMenuId() - if menuId != -1: - menu = evt.GetEventObject() - help = menu.GetHelpString(menuId) - self.SetStatusText(help) - else: - self.SetStatusText('') - - def OnUpdateUI(self, evt): - if evt.GetId() in [wxID_CUT, wxID_COPY, self.ID_DELETE]: - evt.Enable(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) - - def OnIdle(self, evt): - if self.inIdle: return # Recursive call protection - self.inIdle = true - if tree.needUpdate: - if conf.autoRefresh: - if testWin: - self.SetStatusText('Refreshing test window...') - # (re)create - tree.CreateTestWin(testWin.item) - wxYield() - self.SetStatusText('') - tree.needUpdate = false - elif tree.pendingHighLight: - tree.HighLight(tree.pendingHighLight) - else: - evt.Skip() - self.inIdle = false - - # We don't let close panel window - def OnCloseMiniFrame(self, evt): - return - - def OnCloseWindow(self, evt): - if not self.AskSave(): return - if testWin: testWin.Destroy() - # Destroy cached windows - panel.cacheParent.Destroy() - if not panel.GetPageCount() == 2: - panel.page2.Destroy() - conf.x, conf.y = self.GetPosition() - conf.width, conf.height = self.GetSize() - if conf.embedPanel: - conf.sashPos = self.splitter.GetSashPosition() - else: - conf.panelX, conf.panelY = self.miniFrame.GetPosition() - conf.panelWidth, conf.panelHeight = self.miniFrame.GetSize() - evt.Skip() - - def Clear(self): - self.dataFile = '' - self.clipboard = None - self.modified = false - panel.SetModified(false) - tree.Clear() - panel.Clear() - global testWin - if testWin: - testWin.Destroy() - testWin = None - self.SetTitle(progname) - # Numbers for new controls - self.maxIDs = {} - self.maxIDs[xxxPanel] = self.maxIDs[xxxDialog] = self.maxIDs[xxxFrame] = \ - self.maxIDs[xxxMenuBar] = self.maxIDs[xxxMenu] = self.maxIDs[xxxToolBar] = 0 - - def Open(self, path): - # Try to read the file - try: - open(path) - self.Clear() - # Build wx tree - dom = minidom.parse(path) - tree.SetData(dom) - self.dataFile = path - self.SetTitle(progname + ': ' + os.path.basename(path)) - except: - wxLogError('Error reading file: %s' % path) - raise - - def Indent(self, node, indent = 0): - # Copy child list because it will change soon - children = node.childNodes[:] - # Main node doesn't need to be indented - if indent: - text = self.domCopy.createTextNode('\n' + ' ' * indent) - node.parentNode.insertBefore(text, node) - if children: - # Append newline after last child, except for text nodes - if children[-1].nodeType == minidom.Node.ELEMENT_NODE: - text = self.domCopy.createTextNode('\n' + ' ' * indent) - node.appendChild(text) - # Indent children which are elements - for n in children: - if n.nodeType == minidom.Node.ELEMENT_NODE: - self.Indent(n, indent + 2) - - def Save(self, path): - try: - # Apply changes - self.OnRefresh(wxCommandEvent()) - f = open(path, 'w') - # Make temporary copy - # !!! 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.Indent(mainNode) - self.domCopy.writexml(f) - f.close() - self.domCopy.unlink() - self.domCopy = None - 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 - flags = wxICON_EXCLAMATION | wxYES_NO | wxCANCEL | wxCENTRE - dlg = wxMessageDialog( self, 'File is modified. Save before exit?', - 'Save before too late?', flags ) - say = dlg.ShowModal() - dlg.Destroy() - if say == wxID_YES: - self.OnSaveOrSaveAs(wxCommandEvent(wxID_SAVE)) - # If save was successful, modified flag is unset - if not self.modified: return true - elif say == wxID_NO: - self.modified = false - panel.SetModified(false) - return true - return false - -################################################################################ - -def usage(): - print >> sys.stderr, 'usage: xrced [-dvh] [file]' - -class App(wxApp): - def OnInit(self): - global debug, verbose - # Process comand-line - try: - opts, args = getopt.getopt(sys.argv[1:], 'dvh') - except getopt.GetoptError: - 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 - elif o == '-v': - print 'XRCed version', version - sys.exit(0) - - self.SetAppName('xrced') - # Settings - global conf - 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.sashPos = conf.ReadInt('sashPos', 200) - if not conf.embedPanel: - conf.panelX = conf.ReadInt('panelX', -1) - conf.panelY = conf.ReadInt('panelY', -1) - else: - conf.panelX = conf.panelY = -1 - conf.panelWidth = conf.ReadInt('panelWidth', 200) - conf.panelHeight = conf.ReadInt('panelHeight', 200) - conf.panic = not conf.HasEntry('nopanic') - # Add handlers - wxFileSystem_AddHandler(wxMemoryFSHandler()) - wxInitAllImageHandlers() - # Create main frame - frame = Frame(pos, size) - frame.Show(true) - # Load resources from XRC file (!!! should be transformed to .py later?) - sys.modules['params'].frame = frame - frame.res = wxXmlResource('') - frame.res.Load(os.path.join(sys.path[0], 'xrced.xrc')) - - # Load file after showing - if args: - conf.panic = false - frame.open = frame.Open(args[0]) - - return true - - def OnExit(self): - # Write config - wc = wxConfigBase_Get() - wc.WriteInt('autorefresh', conf.autoRefresh) - wc.WriteInt('x', conf.x) - wc.WriteInt('y', conf.y) - wc.WriteInt('width', conf.width) - wc.WriteInt('height', conf.height) - wc.WriteInt('embedPanel', conf.embedPanel) - 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.Flush() - -def main(): - app = App() - app.MainLoop() - app.OnExit() - -if __name__ == '__main__': - main() diff --git a/wxPython/tools/XRCed/xrced.sh b/wxPython/tools/XRCed/xrced.sh deleted file mode 100644 index 70f983bb14..0000000000 --- a/wxPython/tools/XRCed/xrced.sh +++ /dev/null @@ -1 +0,0 @@ -python2.2 YOUR_PATH_TO_XRCED/xrced.py $* diff --git a/wxPython/tools/XRCed/xrced.xrc b/wxPython/tools/XRCed/xrced.xrc deleted file mode 100644 index a407461450..0000000000 --- a/wxPython/tools/XRCed/xrced.xrc +++ /dev/null @@ -1,235 +0,0 @@ - - - - Content - 250,300 - - wxVERTICAL - - - wxHORIZONTAL - - - - - - wxTOP|wxBOTTOM|wxLEFT|wxEXPAND - 5 - - - - wxVERTICAL - - - - - wxBOTTOM - 5 - - - - - - - - 10,20 - - - - - - - wxBOTTOM - 5 - - - - - - - - wxALL|wxEXPAND - 5 - - - - wxEXPAND - - - - wxEXPAND - - - - wxHORIZONTAL - - - - 1 - - wxRIGHT - 10 - - - - - - - - wxALL|wxALIGN_CENTRE_HORIZONTAL - 10 - - - - - - Content - 250,300 - - wxVERTICAL - - - wxHORIZONTAL - - - - - - wxTOP|wxBOTTOM|wxLEFT|wxEXPAND - 5 - - - - wxVERTICAL - - - - - wxBOTTOM - 5 - - - - - - - - 10,20 - - - - - - - wxBOTTOM - 5 - - - - - - - - wxALL|wxEXPAND - 5 - - - - wxEXPAND - - - - wxEXPAND - - - - wxHORIZONTAL - - - - 1 - - wxRIGHT - 10 - - - - - - - - wxALL|wxALIGN_CENTRE_HORIZONTAL - 10 - - - - - - Numbers - 100,300 - - wxVERTICAL - - - wxVERTICAL - - - - 80,100 - - - - wxALL|wxALIGN_CENTRE_HORIZONTAL - 10 - - - - wxVERTICAL - - - - - wxBOTTOM - 3 - - - - - - - - wxALL|wxALIGN_CENTRE_HORIZONTAL - 5 - - - - wxEXPAND - - - - wxEXPAND - - - - wxVERTICAL - - - - 1 - - wxBOTTOM - 5 - - - - - - - - wxALL|wxALIGN_CENTRE_HORIZONTAL - 10 - - - - - \ No newline at end of file diff --git a/wxPython/tools/XRCed/xxx.py b/wxPython/tools/XRCed/xxx.py deleted file mode 100644 index cf141ee949..0000000000 --- a/wxPython/tools/XRCed/xxx.py +++ /dev/null @@ -1,712 +0,0 @@ -# Name: xxx.py ('xxx' is easy to distinguish from 'wx' :) ) -# Purpose: XML interface classes -# Author: Roman Rolinsky -# 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 params import * - -# Base class for interface parameter classes -class xxxNode: - def __init__(self, node): - self.node = node - def remove(self): - self.node.parentNode.removeChild(self.node) - self.node.unlink() - -# Generic (text) parameter class -class xxxParam(xxxNode): - # Standard use: for text nodes - def __init__(self, node): - xxxNode.__init__(self, node) - if not node.hasChildNodes(): - # If does not have child nodes, create empty text node - text = tree.dom.createTextNode('') - node.appendChild(text) - else: - text = node.childNodes[0] # first child must be text node - assert text.nodeType == minidom.Node.TEXT_NODE - self.textNode = text - # Value returns string - def value(self): - return self.textNode.data - def update(self, value): - self.textNode.data = value - -# Integer parameter -class xxxParamInt(xxxParam): - # Standard use: for text nodes - def __init__(self, node): - xxxParam.__init__(self, node) - # Value returns string - def value(self): - try: - return int(self.textNode.data) - except ValueError: - return -1 # invalid value - def update(self, value): - self.textNode.data = str(value) - -# Content parameter -class xxxParamContent(xxxNode): - def __init__(self, node): - xxxNode.__init__(self, node) - data, l = [], [] # data is needed to quicker value retrieval - nodes = node.childNodes[:] # make a copy of the child list - for n in nodes: - if n.nodeType == minidom.Node.ELEMENT_NODE: - 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('') - node.appendChild(text) - else: - # !!! normalize? - text = n.childNodes[0] # first child must be text node - assert text.nodeType == minidom.Node.TEXT_NODE - l.append(text) - data.append(str(text.data)) - else: # remove other - node.removeChild(n) - n.unlink() - self.l, self.data = l, data - def value(self): - return self.data - def update(self, value): - # If number if items is not the same, recreate children - if len(value) != len(self.l): # remove first if number of items has changed - childNodes = self.node.childNodes[:] - for n in childNodes: - self.node.removeChild(n) - l = [] - for str in value: - itemElem = tree.dom.createElement('item') - itemText = tree.dom.createTextNode(str) - itemElem.appendChild(itemText) - self.node.appendChild(itemElem) - l.append(itemText) - self.l = l - else: - for i in range(len(value)): - self.l[i].data = value[i] - self.data = value - -# Content parameter for checklist -class xxxParamContentCheckList(xxxNode): - def __init__(self, node): - xxxNode.__init__(self, node) - data, l = [], [] # data is needed to quicker value retrieval - nodes = node.childNodes[:] # make a copy of the child list - for n in nodes: - if n.nodeType == minidom.Node.ELEMENT_NODE: - assert n.tagName == 'item', 'bad content content' - checked = n.getAttribute('checked') - if not n.hasChildNodes(): - # If does not have child nodes, create empty text node - text = tree.dom.createTextNode('') - node.appendChild(text) - else: - # !!! normalize? - text = n.childNodes[0] # first child must be text node - assert text.nodeType == minidom.Node.TEXT_NODE - l.append((text, n)) - data.append((str(text.data), int(checked))) - else: # remove other - node.removeChild(n) - n.unlink() - self.l, self.data = l, data - def value(self): - return self.data - def update(self, value): - # If number if items is not the same, recreate children - if len(value) != len(self.l): # remove first if number of items has changed - childNodes = self.node.childNodes[:] - 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) - itemElem.appendChild(itemText) - self.node.appendChild(itemElem) - l.append((itemText, itemElem)) - self.l = l - else: - for i in range(len(value)): - self.l[i][0].data = value[i][0] - self.l[i][1].setAttribute('checked', str(value[i][1])) - self.data = value - -################################################################################ - -# 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 - allParams = None # Some nodes have no parameters - # Style parameters (all optional) - styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip'] - # Special parameters - specials = [] - # Required paremeters: none by default - required = [] - # Default parameters with default values - default = {} - # Parameter types - paramDict = {} - # Window styles and extended styles - winStyles = [] - # Tree icon index - #image = -1 - # Construct a new xxx object from DOM element - # parent is parent xxx object (or None if none), element is DOM element object - def __init__(self, parent, element): - self.parent = parent - self.element = element - self.undo = None - # Get attributes - self.className = element.getAttribute('class') - if self.hasName: self.name = element.getAttribute('name') - # Set parameters (text element children) - self.params = {} - nodes = element.childNodes[:] - for node in nodes: - if node.nodeType == minidom.Node.ELEMENT_NODE: - 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: - print 'WARNING: unknown parameter for %s: %s' % \ - (self.className, tag) - elif tag in self.specials: - self.special(tag, node) - elif tag == 'content': - if self.className == 'wxCheckList': - self.params[tag] = xxxParamContentCheckList(node) - else: - self.params[tag] = xxxParamContent(node) - elif tag == 'font': # has children - self.params[tag] = xxxParamFont(element, node) - else: # simple parameter - self.params[tag] = xxxParam(node) - else: - # Remove all other nodes - element.removeChild(node) - node.unlink() - # Returns real tree object - def treeObject(self): - if self.hasChild: return self.child - return self - # Returns tree image index - def treeImage(self): - if self.hasChild: return self.child.treeImage() - return self.image - # Class name plus wx name - def treeName(self): - if self.hasChild: return self.child.treeName() - if self.hasName and self.name: return self.className + ' "' + self.name + '"' - return self.className - -################################################################################ - -# This is a little special: it is both xxxObject and xxxNode -class xxxParamFont(xxxObject, xxxNode): - allParams = ['size', 'style', 'weight', 'family', 'underlined', - 'face', 'encoding'] - def __init__(self, parent, element): - xxxObject.__init__(self, parent, element) - xxxNode.__init__(self, element) - self.parentNode = parent # required to behave similar to DOM node - v = [] - for p in self.allParams: - try: - v.append(str(self.params[p].value())) - except KeyError: - v.append('') - self.data = v - def update(self, value): - # `value' is a list of strings corresponding to all parameters - elem = self.element - # Remove old elements first - childNodes = elem.childNodes[:] - for node in childNodes: elem.removeChild(node) - i = 0 - self.params.clear() - v = [] - for param in self.allParams: - if value[i]: - fontElem = tree.dom.createElement(param) - textNode = tree.dom.createTextNode(value[i]) - self.params[param] = textNode - fontElem.appendChild(textNode) - elem.appendChild(fontElem) - v.append(value[i]) - i += 1 - self.data = v - def value(self): - return self.data - -################################################################################ - -class xxxContainer(xxxObject): - hasChildren = true - -# Special class for root node -class xxxMainNode(xxxContainer): - hasStyle = hasName = false - -################################################################################ -# Top-level windwows - -class xxxPanel(xxxContainer): - allParams = ['pos', 'size', 'style'] - styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', - 'tooltip'] - winStyles = ['wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] - exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] - -class xxxDialog(xxxContainer): - allParams = ['title', 'pos', 'size', 'style'] - required = ['title'] - winStyles = ['wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP', - 'wxDIALOG_MODAL', 'wxDIALOG_MODELESS', - 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX', - 'wxTHICK_FRAME', - 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] - styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', - 'tooltip'] - exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] - -class xxxFrame(xxxContainer): - allParams = ['title', 'centered', 'pos', 'size', 'style'] - paramDict = {'centered': ParamBool} - required = ['title'] - winStyles = ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE', - 'wxSTAY_ON_TOP', - 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', - 'wxRESIZE_BOX', 'wxMINIMIZE_BOX', 'wxMAXIMIZE_BOX', - 'wxFRAME_FLOAT_ON_PARENT', 'wxFRAME_TOOL_WINDOW', - 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] - styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', - 'tooltip'] - exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] - -class xxxTool(xxxObject): - allParams = ['bitmap', 'bitmap2', 'toggle', 'tooltip', 'longhelp'] - paramDict = {'bitmap2': ParamFile} - hasStyle = false - -class xxxToolBar(xxxContainer): - allParams = ['bitmapsize', 'margins', 'packing', 'separation', - 'pos', 'size', 'style'] - hasStyle = false - paramDict = {'bitmapsize': ParamPosSize, 'margins': ParamPosSize, - 'packing': ParamInt, 'separation': ParamInt, - 'style': ParamNonGenericStyle} - winStyles = ['wxTB_FLAT', 'wxTB_DOCKABLE', 'wxTB_VERTICAL', 'wxTB_HORIZONTAL'] - -################################################################################ -# Bitmap, Icon - -class xxxBitmap(xxxObject): - allParams = ['bitmap'] - required = ['bitmap'] - -class xxxIcon(xxxObject): - allParams = ['icon'] - required = ['icon'] - -################################################################################ -# Controls - -class xxxStaticText(xxxObject): - allParams = ['label', 'pos', 'size', 'style'] - required = ['label'] - winStyles = ['wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE'] - -class xxxStaticLine(xxxObject): - allParams = ['pos', 'size', 'style'] - winStyles = ['wxLI_HORIZONTAL', 'wxLI_VERTICAL'] - -class xxxStaticBitmap(xxxObject): - allParams = ['bitmap', 'pos', 'size', 'style'] - required = ['bitmap'] - -class xxxTextCtrl(xxxObject): - allParams = ['value', 'pos', 'size', 'style'] - winStyles = ['wxTE_PROCESS_ENTER', 'wxTE_PROCESS_TAB', 'wxTE_MULTILINE', - 'wxTE_PASSWORD', 'wxTE_READONLY', 'wxHSCROLL'] - -class xxxChoice(xxxObject): - allParams = ['content', 'selection', 'pos', 'size', 'style'] - required = ['content'] - winStyles = ['wxCB_SORT'] - -class xxxSlider(xxxObject): - allParams = ['value', 'min', 'max', 'pos', 'size', 'style', - 'tickfreq', 'pagesize', 'linesize', 'thumb', 'tick', - 'selmin', 'selmax'] - paramDict = {'value': ParamInt, 'tickfreq': ParamInt, 'pagesize': ParamInt, - 'linesize': ParamInt, 'thumb': ParamInt, 'thumb': ParamInt, - 'tick': ParamInt, 'selmin': ParamInt, 'selmax': ParamInt} - required = ['value', 'min', 'max'] - winStyles = ['wxSL_HORIZONTAL', 'wxSL_VERTICAL', 'wxSL_AUTOTICKS', 'wxSL_LABELS', - 'wxSL_LEFT', 'wxSL_RIGHT', 'wxSL_TOP', 'wxSL_BOTTOM', - 'wxSL_BOTH', 'wxSL_SELRANGE'] - -class xxxGauge(xxxObject): - allParams = ['range', 'pos', 'size', 'style', 'value', 'shadow', 'bezel'] - paramDict = {'range': ParamInt, 'value': ParamInt, - 'shadow': ParamInt, 'bezel': ParamInt} - winStyles = ['wxGA_HORIZONTAL', 'wxGA_VERTICAL', 'wxGA_PROGRESSBAR', 'wxGA_SMOOTH'] - -class xxxScrollBar(xxxObject): - allParams = ['pos', 'size', 'style', 'value', 'thumbsize', 'range', 'pagesize'] - paramDict = {'value': ParamInt, 'range': ParamInt, 'thumbsize': ParamInt, - 'pagesize': ParamInt} - winStyles = ['wxSB_HORIZONTAL', 'wxSB_VERTICAL'] - -class xxxListCtrl(xxxObject): - allParams = ['pos', 'size', 'style'] - winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON', - 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', - 'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER', - 'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING'] - -class xxxTreeCtrl(xxxObject): - allParams = ['pos', 'size', 'style'] - winStyles = ['wxTR_HAS_BUTTONS', 'wxTR_NO_LINES', 'wxTR_LINES_AT_ROOT', - 'wxTR_EDIT_LABELS', 'wxTR_MULTIPLE'] - -class xxxHtmlWindow(xxxObject): - allParams = ['pos', 'size', 'style', 'borders', 'url', 'htmlcode'] - paramDict = {'borders': ParamInt} - winStyles = ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO'] - -class xxxCalendar(xxxObject): - allParams = ['pos', 'size', 'style'] - -class xxxNotebook(xxxContainer): - allParams = ['usenotebooksizer', 'pos', 'size', 'style'] - paramDict = {'usenotebooksizer': ParamBool} - winStyles = ['wxNB_FIXEDWIDTH', 'wxNB_LEFT', 'wxNB_RIGHT', 'wxNB_BOTTOM'] - -################################################################################ -# Buttons - -class xxxButton(xxxObject): - allParams = ['label', 'default', 'pos', 'size', 'style'] - paramDict = {'default': ParamBool} - required = ['label'] - winStyles = ['wxBU_LEFT', 'wxBU_TOP', 'wxBU_RIGHT', 'wxBU_BOTTOM'] - -class xxxBitmapButton(xxxObject): - allParams = ['bitmap', 'selected', 'focus', 'disabled', 'default', - 'pos', 'size', 'style'] - required = ['bitmap'] - winStyles = ['wxBU_AUTODRAW', 'wxBU_LEFT', 'wxBU_TOP', - 'wxBU_RIGHT', 'wxBU_BOTTOM'] - -class xxxRadioButton(xxxObject): - allParams = ['label', 'value', 'pos', 'size', 'style'] - paramDict = {'value': ParamBool} - required = ['label'] - winStyles = ['wxRB_GROUP'] - -class xxxSpinButton(xxxObject): - allParams = ['pos', 'size', 'style'] - winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP'] - -################################################################################ -# Boxes - -class xxxStaticBox(xxxObject): - allParams = ['label', 'pos', 'size', 'style'] - required = ['label'] - -class xxxRadioBox(xxxObject): - allParams = ['label', 'content', 'selection', 'dimension', 'pos', 'size', 'style'] - paramDict = {'dimension': ParamInt} - required = ['label', 'content'] - winStyles = ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS'] - -class xxxCheckBox(xxxObject): - allParams = ['label', 'pos', 'size', 'style'] - required = ['label'] - -class xxxComboBox(xxxObject): - allParams = ['content', 'selection', 'value', 'pos', 'size', 'style'] - required = ['content'] - winStyles = ['wxCB_SIMPLE', 'wxCB_SORT', 'wxCB_READONLY', 'wxCB_DROPDOWN'] - -class xxxListBox(xxxObject): - allParams = ['content', 'selection', 'pos', 'size', 'style'] - required = ['content'] - winStyles = ['wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL', - 'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT'] - -class xxxCheckList(xxxObject): - allParams = ['content', 'pos', 'size', 'style'] - required = ['content'] - winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON', - 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', - '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 - paramDict = {'orient': ParamOrient} - isSizer = true - -class xxxBoxSizer(xxxSizer): - allParams = ['orient'] - required = ['orient'] - default = {'orient': 'wxVERTICAL'} - # Tree icon depends on orientation - def treeImage(self): - if self.params['orient'].value() == 'wxHORIZONTAL': return self.imageH - else: return self.imageV - -class xxxStaticBoxSizer(xxxBoxSizer): - allParams = ['label', 'orient'] - required = ['label', 'orient'] - default = {'orient': 'wxVERTICAL'} - -class xxxGridSizer(xxxSizer): - allParams = ['cols', 'rows', 'vgap', 'hgap'] - required = ['cols'] - default = {'cols': '2', 'rows': '2'} - -# For repeated parameters -class xxxParamMulti: - def __init__(self): - self.l, self.data = [], [] - def append(self, param): - self.l.append(param) - self.data.append(param.value()) - def value(self): - return self.data - def remove(self): - for param in self.l: - param.remove() - self.l, self.data = [], [] - -class xxxFlexGridSizer(xxxGridSizer): - specials = ['growablecols', 'growablerows'] - allParams = ['cols', 'rows', 'vgap', 'hgap'] + specials - paramDict = {'growablecols':ParamIntList, 'growablerows':ParamIntList} - # 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() - 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.appendChild(text) - self.element.appendChild(node) - self.special(param, node) - -# Container with only one child. -# Not shown in tree. -class xxxChildContainer(xxxObject): - 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 - nodes = element.childNodes[:] # create copy - for node in nodes: - if node.nodeType == minidom.Node.ELEMENT_NODE: - if node.tagName == 'object': - # Create new xxx object for child node - self.child = MakeXXXFromDOM(self, node) - self.child.parent = parent - # Copy hasChildren and isSizer attributes - self.hasChildren = self.child.hasChildren - self.isSizer = self.child.isSizer - return # success - else: - element.removeChild(node) - node.unlink() - assert 0, 'no child found' - -class xxxSizerItem(xxxChildContainer): - allParams = ['option', 'flag', 'border'] - paramDict = {'option': ParamInt} - def __init__(self, parent, element): - xxxChildContainer.__init__(self, parent, element) - # Remove pos parameter - not needed for sizeritems - if 'pos' in self.child.allParams: - self.child.allParams = self.child.allParams[:] - self.child.allParams.remove('pos') - -class xxxNotebookPage(xxxChildContainer): - allParams = ['label', 'selected'] - paramDict = {'selected': ParamBool} - required = ['label'] - def __init__(self, parent, element): - xxxChildContainer.__init__(self, parent, element) - # pos and size dont matter for notebookpages - if 'pos' in self.child.allParams: - self.child.allParams = self.child.allParams[:] - self.child.allParams.remove('pos') - if 'size' in self.child.allParams: - self.child.allParams = self.child.allParams[:] - self.child.allParams.remove('size') - -class xxxSpacer(xxxObject): - hasName = hasStyle = false - allParams = ['size', 'option', 'flag', 'border'] - paramDict = {'option': ParamInt} - default = {'size': '0,0'} - -class xxxMenuBar(xxxContainer): - allParams = [] - -class xxxMenu(xxxContainer): - allParams = ['label'] - default = {'label': ''} - paramDict = {'style': ParamNonGenericStyle} # no generic styles - winStyles = ['wxMENU_TEAROFF'] - -class xxxMenuItem(xxxObject): - allParams = ['checkable', 'label', 'accel', 'help'] - default = {'label': ''} - -class xxxSeparator(xxxObject): - hasName = hasStyle = false - -################################################################################ - -xxxDict = { - 'wxPanel': xxxPanel, - 'wxDialog': xxxDialog, - 'wxFrame': xxxFrame, - 'tool': xxxTool, - 'wxToolBar': xxxToolBar, - - 'wxBitmap': xxxBitmap, - 'wxIcon': xxxIcon, - - 'wxButton': xxxButton, - 'wxBitmapButton': xxxBitmapButton, - 'wxRadioButton': xxxRadioButton, - 'wxSpinButton': xxxSpinButton, - - 'wxStaticBox': xxxStaticBox, - 'wxStaticBitmap': xxxStaticBitmap, - 'wxRadioBox': xxxRadioBox, - 'wxComboBox': xxxComboBox, - 'wxCheckBox': xxxCheckBox, - 'wxListBox': xxxListBox, - - 'wxStaticText': xxxStaticText, - 'wxStaticLine': xxxStaticLine, - 'wxTextCtrl': xxxTextCtrl, - 'wxChoice': xxxChoice, - 'wxSlider': xxxSlider, - 'wxGauge': xxxGauge, - 'wxScrollBar': xxxScrollBar, - 'wxTreeCtrl': xxxTreeCtrl, - 'wxListCtrl': xxxListCtrl, - 'wxCheckList': xxxCheckList, - 'wxNotebook': xxxNotebook, - 'notebookpage': xxxNotebookPage, - 'wxHtmlWindow': xxxHtmlWindow, - 'wxCalendar': xxxCalendar, - - 'wxBoxSizer': xxxBoxSizer, - 'wxStaticBoxSizer': xxxStaticBoxSizer, - 'wxGridSizer': xxxGridSizer, - 'wxFlexGridSizer': xxxFlexGridSizer, - 'sizeritem': xxxSizerItem, - 'spacer': xxxSpacer, - - 'wxMenuBar': xxxMenuBar, - 'wxMenu': xxxMenu, - 'wxMenuItem': xxxMenuItem, - 'separator': xxxSeparator, - } - -# 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() - } -for cl in xxxDict.values(): - if cl.allParams: - for param in cl.allParams + cl.paramDict.keys(): - if not paramIDs.has_key(param): - paramIDs[param] = wxNewId() - -################################################################################ -# Helper functions - -# Test for object elements -def IsObject(node): - return node.nodeType == minidom.Node.ELEMENT_NODE and node.tagName == 'object' - -# Make XXX object from some DOM object, selecting correct class -def MakeXXXFromDOM(parent, element): - try: - return xxxDict[element.getAttribute('class')](parent, element) - except KeyError: - # Verify that it's not recursive exception - if element.getAttribute('class') not in xxxDict: - print 'ERROR: unknown class:', element.getAttribute('class') - raise - -# Make empty DOM element -def MakeEmptyDOM(className): - elem = 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) - try: - textNode = tree.dom.createTextNode(xxxClass.default[param]) - except KeyError: - textNode = tree.dom.createTextNode('') - textElem.appendChild(textNode) - elem.appendChild(textElem) - return elem - -# Make empty XXX object -def MakeEmptyXXX(parent, className): - # Make corresponding DOM object first - elem = MakeEmptyDOM(className) - # If parent is a sizer, we should create sizeritem object, except for spacers - if parent: - if parent.isSizer and className != 'spacer': - sizerItemElem = MakeEmptyDOM('sizeritem') - sizerItemElem.appendChild(elem) - elem = sizerItemElem - elif isinstance(parent, xxxNotebook): - pageElem = MakeEmptyDOM('notebookpage') - pageElem.appendChild(elem) - elem = pageElem - # Now just make object - return MakeXXXFromDOM(parent, elem) - diff --git a/wxPython/tools/img2img.py b/wxPython/tools/img2img.py deleted file mode 100644 index dbefc261a4..0000000000 --- a/wxPython/tools/img2img.py +++ /dev/null @@ -1,76 +0,0 @@ -""" -Common routines for the image converter utilities. -""" -import sys, os, glob, getopt, string -from wxPython.wx import * - -wxInitAllImageHandlers() - -def convert(file, maskClr, outputDir, outputName, outType, outExt): - if string.lower(os.path.splitext(file)[1]) == ".ico": - icon = wxIcon(file, wxBITMAP_TYPE_ICO) - img = wxBitmapFromIcon(icon) - else: - img = wxBitmap(file, wxBITMAP_TYPE_ANY) - - if not img.Ok(): - return 0, file + " failed to load!" - else: - if maskClr: - om = img.GetMask() - mask = wxMaskColour(img, maskClr) - img.SetMask(mask) - if om is not None: - om.Destroy() - if outputName: - newname = outputName - else: - newname = os.path.join(outputDir, - os.path.basename(os.path.splitext(file)[0]) + outExt) - if img.SaveFile(newname, outType): - return 1, file + " converted to " + newname - else: - img = wxImageFromBitmap(img) - if img.SaveFile(newname, outType): - return 1, "ok" - else: - return 0, file + " failed to save!" - - - - -def main(args, outType, outExt, doc): - if not args or ("-h" in args): - print doc - return - - outputDir = "" - maskClr = None - outputName = None - - try: - opts, fileArgs = getopt.getopt(args, "m:n:o:") - except getopt.GetoptError: - print __doc__ - return - - for opt, val in opts: - if opt == "-m": - maskClr = val - elif opt == "-n": - outputName = val - elif opt == "-o": - outputDir = val - - if not fileArgs: - print doc - return - - for arg in fileArgs: - for file in glob.glob(arg): - if not os.path.isfile(file): - continue - ok, msg = convert(file, maskClr, outputDir, outputName, - outType, outExt) - print msg - diff --git a/wxPython/tools/img2png.py b/wxPython/tools/img2png.py deleted file mode 100644 index aea14f2694..0000000000 --- a/wxPython/tools/img2png.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python -""" -img2png.py -- convert several image formats to PNG format - -Usage: - - img2png.py [options] image_files... - -Options: - - -o The directory to place the .png file(s), defaults to - the current directory. - - -m <#rrggbb> If the original image has a mask or transparency defined - it will be used by default. You can use this option to - override the default or provide a new mask by specifying - a colour in the image to mark as transparent. - - -n A filename to write the .png data to. Defaults to the - basename of the image file + '.png' This option overrides - the -o option. -""" - - -import sys -import img2img -from wxPython import wx - -img2img.main(sys.argv[1:], wx.wxBITMAP_TYPE_PNG, ".png", __doc__) - - diff --git a/wxPython/tools/img2py.py b/wxPython/tools/img2py.py deleted file mode 100644 index 21957dc8bc..0000000000 --- a/wxPython/tools/img2py.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python -""" -img2py.py -- Convert an image to PNG format and embed it in a Python - module with appropriate code so it can be loaded into - a program at runtime. The benefit is that since it is - Python source code it can be delivered as a .pyc or - 'compiled' into the program using freeze, py2exe, etc. - -Usage: - - img2py.py [options] image_file python_file - -Options: - - -m <#rrggbb> If the original image has a mask or transparency defined - it will be used by default. You can use this option to - override the default or provide a new mask by specifying - a colour in the image to mark as transparent. - - -n Normally generic names (getBitmap, etc.) are used for the - image access functions. If you use this option you can - specify a name that should be used to customize the access - fucntions, (getNameBitmap, etc.) - - -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. - - -u Don't use compression. Leaves the data uncompressed. - - -i Also output a function to return the image as a wxIcon. - -""" - - - -import sys, os, glob, getopt, tempfile, string -import cPickle, cStringIO, zlib -import img2img -from wxPython import wx - - -def crunch_data(data, compressed): - # compress it? - if compressed: - data = zlib.compress(data, 9) - - # convert to a printable format, so it can be in a Python source file - data = repr(data) - - # This next bit is borrowed from PIL. It is used to wrap the text intelligently. - fp = cStringIO.StringIO() - data = data + " " # buffer for the +1 test - c = i = 0 - word = "" - octdigits = "01234567" - hexdigits = "0123456789abcdef" - while i < len(data): - if data[i] != "\\": - word = data[i] - i = i + 1 - else: - if data[i+1] in octdigits: - for n in range(2, 5): - if data[i+n] not in octdigits: - break - word = data[i:i+n] - i = i + n - elif data[i+1] == 'x': - for n in range(2, 5): - if data[i+n] not in hexdigits: - break - word = data[i:i+n] - i = i + n - else: - word = data[i:i+2] - i = i + 2 - - l = len(word) - if c + l >= 78-1: - fp.write("\\\n") - c = 0 - fp.write(word) - c = c + l - - # return the formatted compressed data - return fp.getvalue() - - - -def main(args): - if not args or ("-h" in args): - print __doc__ - return - - append = 0 - compressed = 1 - maskClr = None - imgName = "" - icon = 0 - - try: - opts, fileArgs = getopt.getopt(args, "auin:m:") - except getopt.GetoptError: - print __doc__ - return - - for opt, val in opts: - if opt == "-a": - append = 1 - elif opt == "-u": - compressed = 0 - elif opt == "-n": - imgName = val - elif opt == "-m": - maskClr = val - elif opt == "-i": - icon = 1 - - if len(fileArgs) != 2: - print __doc__ - return - - image_file, python_file = fileArgs - - # convert the image file to a temporary file - tfname = tempfile.mktemp() - ok, msg = img2img.convert(image_file, maskClr, None, tfname, wx.wxBITMAP_TYPE_PNG, ".png") - if not ok: - print msg - return - - data = open(tfname, "rb").read() - data = crunch_data(data, compressed) - os.unlink(tfname) - - if append: - out = open(python_file, "a") - else: - out = open(python_file, "w") - - out.write("#" + "-" * 70 + "\n") - if not append: - out.write("# This file was generated by %s\n#\n" % sys.argv[0]) - out.write("from wxPython.wx import wxImageFromStream, wxBitmapFromImage\n") - if icon: - out.write("from wxPython.wx import wxEmptyIcon\n") - if compressed: - out.write("import cStringIO, zlib\n\n\n") - else: - out.write("import cStringIO\n\n\n") - - if compressed: - out.write("def get%sData():\n" - " return zlib.decompress(\n%s)\n\n" - % (imgName, data)) - else: - out.write("def get%sData():\n" - " return %s\n\n" - % (imgName, data)) - - - out.write("def get%sBitmap():\n" - " return wxBitmapFromImage(get%sImage())\n\n" - "def get%sImage():\n" - " stream = cStringIO.StringIO(get%sData())\n" - " return wxImageFromStream(stream)\n\n" - % tuple([imgName] * 4)) - if icon: - out.write("def get%sIcon():\n" - " icon = wxEmptyIcon()\n" - " icon.CopyFromBitmap(get%sBitmap())\n" - " return icon\n\n" - % tuple([imgName] * 2)) - - - if imgName: - n_msg = ' using "%s"' % imgName - else: - n_msg = "" - if maskClr: - m_msg = " with mask %s" % maskClr - else: - m_msg = "" - print "Embedded %s%s into %s%s" % (image_file, n_msg, python_file, m_msg) - - -if __name__ == "__main__": - main(sys.argv[1:]) - diff --git a/wxPython/tools/img2xpm.py b/wxPython/tools/img2xpm.py deleted file mode 100644 index e6da69e8d8..0000000000 --- a/wxPython/tools/img2xpm.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python -""" -img2xpm.py -- convert several image formats to XPM - -Usage: - - img2xpm.py [options] image_files... - -Options: - - -o The directory to place the .xpm file(s), defaults to - the current directory. - - -m <#rrggbb> If the original image has a mask or transparency defined - it will be used by default. You can use this option to - override the default or provide a new mask by specifying - a colour in the image to mark as transparent. - - -n A filename to write the .xpm data to. Defaults to the - basename of the image file + '.xpm' This option overrides - the -o option. -""" - - -import sys -import img2img -from wxPython import wx - -img2img.main(sys.argv[1:], wx.wxBITMAP_TYPE_XPM, ".xpm", __doc__) - - diff --git a/wxPython/wxPython/lib/__init__.py b/wxPython/wxPython/lib/__init__.py index b28b04f643..54e9b268d8 100644 --- a/wxPython/wxPython/lib/__init__.py +++ b/wxPython/wxPython/lib/__init__.py @@ -1,3 +1,4 @@ +# diff --git a/wxPython/wxPython/tools/XRCed/CHANGES b/wxPython/wxPython/tools/XRCed/CHANGES new file mode 100644 index 0000000000..89b20ff696 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/CHANGES @@ -0,0 +1,74 @@ +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 + + +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 new file mode 100644 index 0000000000..133ee2a2e5 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/README @@ -0,0 +1,72 @@ +******************************************************************************** + + XRCed README + +******************************************************************************** + +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). + +Of course wxGTK's XRC library (libwxxrc) must be installed. + +Installation on Windows +----------------------- + +Works with wxPython 2.3.2 for Python 2.2. + +Short manual +------------ + +XRCed's idea is very straightforward: it is a visual tool for editing an XML +file conforming to XRC format. Every operation performed in XRCed has direct +correspondence to XML structure. So it is not really a usual point-and-click +GUI builder, but don't let that scare you. + +To start xrced, change to the directory where you installed it and run +"python2.2 xrced.py". + +On UNIX you can edit wrapper script "xrced.sh" to point to your installation +directory. + +To create an object, first you should select some object in the tree (or the +root item if it's empty) then press the right mouse button and select an +appropriate command. The pulldown menu is context-dependent on the selected +object. + +XRCed tries to guess if new object should be added as a next sibling or a +child of current object, depending on the possibility of the object to have +child objects and expanded state (if tree item is collapsed, new object will +be sibling). You can change this behavior to create siblings by pressing and +holding the Shift and Control keys before clicking the mouse. + +Pressed Control key while pressing right button makes next item a sibling of +selected item regardless of its expanded state. + +Pressed Shift key changes the place for inserting new child to be before +selected child, not after as by default. + +Panel on the right contains object properties. Properties which are optional +should be "checked" first. This panel can be made separate by unchecking +"Embed Panel" in View menu. + +All properties can be edited as text, and some are supplied with special +editing controls. + +The names of the properties are exactly as in XRC file, and it's usually not +hard to guess what they do. XML ID is the name of the window, and must be +present for top-level windows (though this is not enforced by XRCed). + +To display the preview window double-click a top-level object (you should +assign an XMLID to it first), press "Test" toolbar button or select command +from View menu, or press F5. After that, if you select a child object, it +becomes highlighted, and if you change it, preview is updated when you select +another item or press Ctrl-R (refresh). To turn off automatic update, toggle +"View->Auto-refresh" or toolbar auto-refresh button (to the right of the +refresh button). + +-------------------------------------------------------------------------------- + +Copyright 2001 Roman Rolinsky diff --git a/wxPython/wxPython/tools/XRCed/TODO b/wxPython/wxPython/tools/XRCed/TODO new file mode 100644 index 0000000000..4b9cc1b2b3 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/TODO @@ -0,0 +1,29 @@ +TODO for XRCed +============== + +- Undo/Redo + +- menu - accel not displayed in preview + ++ tree icons + +- replace object with another, keeping children + ++ write tmp file for current dialog/panel/etc. + ++ XML indents + +? select same notebook pages after update + +- put some default values in tree ctrl etc. + +- special (fast) update for some values: pos/size, value/content, sizeritem + stuff (?), well, as much as possible + +- highlighting with better method + +- import XRC/WXR files + ++ disable some window creation when it's not valid + +- check for memory leaks from wx objects diff --git a/wxPython/wxPython/tools/XRCed/__init__.py b/wxPython/wxPython/tools/XRCed/__init__.py new file mode 100644 index 0000000000..54e9b268d8 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/__init__.py @@ -0,0 +1,4 @@ +# + + + diff --git a/wxPython/wxPython/tools/XRCed/images.py b/wxPython/wxPython/tools/XRCed/images.py new file mode 100644 index 0000000000..924c55d463 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/images.py @@ -0,0 +1,368 @@ +#---------------------------------------------------------------------- +# This file was generated by img2py.py +# +from wxPython.wx import wxBitmapFromXPMData, wxImageFromBitmap +import cPickle, zlib + + +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 getIconBitmap(): + return wxBitmapFromXPMData(getIconData()) + +def getIconImage(): + return wxImageFromBitmap(getIconBitmap()) + +#---------------------------------------------------------------------- +def getNewData(): + return cPickle.loads(zlib.decompress( +"x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\ +\x81\x9d0\xbdX$A\xf2\ +\xf9\xc3Z\x12\x010%\x15\xf2\x11` S\x82\x1e\x00-\xd9\x8b\xfa" )) + +def getNewBitmap(): + return wxBitmapFromXPMData(getNewData()) + +def getNewImage(): + return wxImageFromBitmap(getNewBitmap()) + +#---------------------------------------------------------------------- +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 getOpenBitmap(): + return wxBitmapFromXPMData(getOpenData()) + +def getOpenImage(): + return wxImageFromBitmap(getOpenBitmap()) + +#---------------------------------------------------------------------- +def getSaveData(): + return cPickle.loads(zlib.decompress( +'x\xda\xd3\xc8)0\xe4\nV72Q02V0U0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xfc\ +\x81\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 getCopyBitmap(): + return wxBitmapFromXPMData(getCopyData()) + +def getCopyImage(): + return wxImageFromBitmap(getCopyBitmap()) + +#---------------------------------------------------------------------- +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' )) + +def getPasteBitmap(): + return wxBitmapFromXPMData(getPasteData()) + +def getPasteImage(): + return wxImageFromBitmap(getPasteBitmap()) + +#---------------------------------------------------------------------- +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 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' )) + +def getRefreshBitmap(): + return wxBitmapFromXPMData(getRefreshData()) + +def getRefreshImage(): + return wxImageFromBitmap(getRefreshBitmap()) + +#---------------------------------------------------------------------- +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 getTreeDefaultData(): + return cPickle.loads(zlib.decompress( +"x\xda\xd3\xc8)0\xe4\nV74S04Q0U0T\xe7J\x0cV\x8fPHVp\xcaIL\xce\x06\xf3\xfc\ +\x81\ +\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 getTreeDefaultBitmap(): + return wxBitmapFromXPMData(getTreeDefaultData()) + +def getTreeDefaultImage(): + return wxImageFromBitmap(getTreeDefaultBitmap()) + +#---------------------------------------------------------------------- +def getTreeRootData(): + return cPickle.loads(zlib.decompress( +'x\xda\xd3\xc8)0\xe4\nV74S04Q0V0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3"\x801\x82\xf9`@\ +\xc8LLo\xea\x01\x00\xb5\x9cde' )) + +def getTreeDialogBitmap(): + return wxBitmapFromXPMData(getTreeDialogData()) + +def getTreeDialogImage(): + return wxImageFromBitmap(getTreeDialogBitmap()) + +#---------------------------------------------------------------------- +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`,' )) + +def getTreeFrameBitmap(): + return wxBitmapFromXPMData(getTreeFrameData()) + +def getTreeFrameImage(): + return wxImageFromBitmap(getTreeFrameBitmap()) + +#---------------------------------------------------------------------- +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' )) + +def getTreeMenuBarBitmap(): + return wxBitmapFromXPMData(getTreeMenuBarData()) + +def getTreeMenuBarImage(): + return wxImageFromBitmap(getTreeMenuBarBitmap()) + +#---------------------------------------------------------------------- +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 getTreeToolBarBitmap(): + return wxBitmapFromXPMData(getTreeToolBarData()) + +def getTreeToolBarImage(): + return wxImageFromBitmap(getTreeToolBarBitmap()) + +#---------------------------------------------------------------------- +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 getTreeMenuBitmap(): + return wxBitmapFromXPMData(getTreeMenuData()) + +def getTreeMenuImage(): + return wxImageFromBitmap(getTreeMenuBitmap()) + +#---------------------------------------------------------------------- +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' )) + +def getTreeSizerHBitmap(): + return wxBitmapFromXPMData(getTreeSizerHData()) + +def getTreeSizerHImage(): + return wxImageFromBitmap(getTreeSizerHBitmap()) + +#---------------------------------------------------------------------- +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>*' )) + +def getTreeSizerVBitmap(): + return wxBitmapFromXPMData(getTreeSizerVData()) + +def getTreeSizerVImage(): + return wxImageFromBitmap(getTreeSizerVBitmap()) + +#---------------------------------------------------------------------- +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' )) + +def getTreeStaticBoxSizerHBitmap(): + return wxBitmapFromXPMData(getTreeStaticBoxSizerHData()) + +def getTreeStaticBoxSizerHImage(): + return wxImageFromBitmap(getTreeStaticBoxSizerHBitmap()) + +#---------------------------------------------------------------------- +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' )) + +def getTreeStaticBoxSizerVBitmap(): + return wxBitmapFromXPMData(getTreeStaticBoxSizerVData()) + +def getTreeStaticBoxSizerVImage(): + return wxImageFromBitmap(getTreeStaticBoxSizerVBitmap()) + +#---------------------------------------------------------------------- +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 getTreeSizerGridBitmap(): + return wxBitmapFromXPMData(getTreeSizerGridData()) + +def getTreeSizerGridImage(): + return wxImageFromBitmap(getTreeSizerGridBitmap()) + +#---------------------------------------------------------------------- +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 getTreeSizerFlexGridBitmap(): + return wxBitmapFromXPMData(getTreeSizerFlexGridData()) + +def getTreeSizerFlexGridImage(): + return wxImageFromBitmap(getTreeSizerFlexGridBitmap()) + diff --git a/wxPython/wxPython/tools/XRCed/params.py b/wxPython/wxPython/tools/XRCed/params.py new file mode 100644 index 0000000000..319034e02e --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/params.py @@ -0,0 +1,722 @@ +# Name: params.py +# Purpose: Classes for parameter introduction +# Author: Roman Rolinsky +# Created: 22.08.2001 +# RCS-ID: $Id$ + +from wxPython.wx import * +from wxPython.xrc import * +import string +import os.path +from types import * + +# Object which is currently processed +currentXXX = None +def SetCurrentXXX(xxx): + global currentXXX + currentXXX = xxx + +genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', + 'wxSUNKEN_BORDER', 'wxRAISED_BORDER', + 'wxSTATIC_BORDER', 'wxNO_BORDER', + 'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', + 'wxNO_FULL_REPAINT_ON_RESIZE'] + +buttonSize = (55,-1) + +# 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 + 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) + +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()) + 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.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.text.SetValue(value) + 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(), '|')) + if value == ['']: value = [] + ignored = [] + for i in value: + try: + listBox.Check(self.values.index(i)) + except ValueError: + # Try to find equal + if self.equal.has_key(i): + listBox.Check(self.values.index(self.equal[i])) + else: + print 'WARNING: unknown flag: %s: ignored.' % i + ignored.append(i) + topSizer.Add(listBox, 1, wxEXPAND) + sizer = wxBoxSizer() + buttonOk = wxButton(dlg, wxID_OK, 'OK') + buttonOk.SetDefault() + sizer.Add(buttonOk, 0, wxRIGHT, 10) + sizer.Add(0, 0, 1) + sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel')) + topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10) + dlg.SetAutoLayout(true) + dlg.SetSizer(topSizer) + topSizer.Fit(dlg) + dlg.Center() + if dlg.ShowModal() == wxID_OK: + value = [] + for i in range(listBox.Number()): + if listBox.IsChecked(i): + value.append(self.values[i]) + # Add ignored flags + value.extend(ignored) + if value: + self.SetValue(reduce(lambda a,b: a+'|'+b, value)) + else: + self.SetValue('') + self.SetModified() + dlg.Destroy() + +class ParamFlag(ParamBinaryOr): + values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', + 'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', + 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', + 'wxALIGN_CENTRE_HORIZONTAL'] + equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE', + 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', + 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'} + def __init__(self, parent, name): + ParamBinaryOr.__init__(self, parent, name) + +class ParamStyle(ParamBinaryOr): + equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'} + def __init__(self, parent, name): + self.values = currentXXX.winStyles + genericStyles + ParamBinaryOr.__init__(self, parent, name) + +class ParamNonGenericStyle(ParamBinaryOr): + def __init__(self, parent, name): + self.values = 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 + else: + self.values = [] + ParamBinaryOr.__init__(self, parent, name) + +class ParamColour(PPanel): + def __init__(self, parent, name): + PPanel.__init__(self, parent, name) + self.ID_TEXT_CTRL = wxNewId() + self.ID_BUTTON = wxNewId() + self.SetBackgroundColour(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(40, -1)) + sizer.Add(self.button, 0, wxGROW) + self.SetAutoLayout(true) + self.SetSizer(sizer) + sizer.Fit(self) + 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 + 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() + def OnPaintButton(self, evt): + dc = wxPaintDC(self.button) + dc.SetBrush(wxTRANSPARENT_BRUSH) + if self.IsEnabled(): dc.SetPen(wxBLACK_PEN) + else: dc.SetPen(wxGREY_PEN) + size = self.button.GetSize() + dc.DrawRectangle(0, 0, size.x, size.y) + def OnLeftDown(self, evt): + data = wxColourData() + data.SetColour(self.GetValue()) + dlg = wxColourDialog(self, data) + if dlg.ShowModal() == wxID_OK: + self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get()) + self.SetModified() + dlg.Destroy() + +################################################################################ + +# Mapping from wx constants ro XML strings +fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative', + wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss', + wxMODERN: 'modern'} +fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'} +fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'} +def ReverseMap(m): + rm = {} + for k,v in m.items(): rm[v] = k + return rm +fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml) +fontStylesXml2wx = ReverseMap(fontStylesWx2Xml) +fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml) + +class ParamFont(PPanel): + def __init__(self, parent, name): + PPanel.__init__(self, parent, name) + self.ID_TEXT_CTRL = wxNewId() + self.ID_BUTTON_SELECT = wxNewId() + self.SetBackgroundColour(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.SetSizer(sizer) + sizer.Fit(self) + 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() + def _defaultValue(self): + return ['12', 'default', 'normal', 'normal', '0', '', ''] + def GetValue(self): + if self.textModified: # text has newer value + try: + return eval(self.text.GetValue()) + except SyntaxError: + wxLogError('Syntax error in parameter value: ' + self.GetName()) + return self._defaultValue() + return self.value + def SetValue(self, value): + 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 + def OnButtonSelect(self, evt): + if self.textModified: # text has newer value + try: + self.value = eval(self.text.GetValue()) + except SyntaxError: + wxLogError('Syntax error in parameter value: ' + self.GetName()) + self.value = self._defaultValue() + # Make initial font + # Default values + size = 12 + family = wxDEFAULT + style = weight = wxNORMAL + underlined = 0 + face = '' + enc = wxFONTENCODING_DEFAULT + # Fall back to default if exceptions + error = false + try: + try: size = int(self.value[0]) + except ValueError: error = true + try: family = fontFamiliesXml2wx[self.value[1]] + except KeyError: error = true + try: style = fontStylesXml2wx[self.value[2]] + except KeyError: error = true + try: weight = fontWeightsXml2wx[self.value[3]] + except KeyError: error = true + try: underlined = int(self.value[4]) + 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 + if error: wxLogError('Invalid font specification') + if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM + font = wxFont(size, family, style, weight, underlined, face, enc) + data = wxFontData() + data.SetInitialFont(font) + dlg = wxFontDialog(self, data) + if dlg.ShowModal() == wxID_OK: + font = dlg.GetFontData().GetChosenFont() + value = [str(font.GetPointSize()), + fontFamiliesWx2Xml.get(font.GetFamily(), "default"), + fontStylesWx2Xml.get(font.GetStyle(), "normal"), + fontWeightsWx2Xml.get(font.GetWeight(), "normal"), + str(font.GetUnderlined()), + font.GetFaceName(), + wxFontMapper_GetEncodingName(font.GetEncoding()) + ] + # Add ignored flags + self.SetValue(value) + self.SetModified() + self.textModified = false + dlg.Destroy() + +################################################################################ + +class ParamInt(PPanel): + def __init__(self, parent, name): + PPanel.__init__(self, parent, name) + self.ID_SPIN_CTRL = wxNewId() + sizer = wxBoxSizer() + self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=wxSize(50,-1)) + self.SetBackgroundColour(panel.GetBackgroundColour()) + sizer.Add(self.spin) + 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 + 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() + +class ParamText(PPanel): + def __init__(self, parent, name, textWidth=200): + 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.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1)) + sizer.Add(self.text, 0, 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.text.SetValue(value) + self.freeze = false # disable other handlers + def OnChange(self, evt): + if self.freeze: return + self.SetModified() + evt.Skip() + +class ParamAccel(ParamText): + def __init__(self, parent, name): + ParamText.__init__(self, parent, name, 50) + +class ParamPosSize(ParamText): + def __init__(self, parent, name): + ParamText.__init__(self, parent, name, 80) + +class ContentDialog(wxDialogPtr): + def __init__(self, parent, value): + # Is this normal??? + w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT') + wxDialogPtr.__init__(self, w.this) + self.thisown = 1 + self.Center() + self.list = self.FindWindowByName('LIST') + # Set list items + for v in value: + self.list.Append(v) + self.SetAutoLayout(true) + self.GetSizer().Fit(self) + # Callbacks + self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND') + self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE') + self.ID_BUTTON_UP = XMLID('BUTTON_UP') + self.ID_BUTTON_DOWN = XMLID('BUTTON_DOWN') + EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) + EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) + EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) + EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) + EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) + EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) + EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) + def OnButtonUp(self, evt): + i = self.list.GetSelection() + str = self.list.GetString(i) + self.list.Delete(i) + self.list.InsertItems([str], i-1) + self.list.SetSelection(i-1) + def OnButtonDown(self, evt): + i = self.list.GetSelection() + str = self.list.GetString(i) + self.list.Delete(i) + self.list.InsertItems([str], i+1) + self.list.SetSelection(i+1) + def OnButtonAppend(self, evt): + str = wxGetTextFromUser('Enter new item:', 'Append', '', self) + self.list.Append(str) + def OnButtonRemove(self, evt): + self.list.Delete(self.list.GetSelection()) + def OnUpdateUI(self, evt): + if evt.GetId() == self.ID_BUTTON_REMOVE: + evt.Enable(self.list.GetSelection() != -1) + elif evt.GetId() == self.ID_BUTTON_UP: + evt.Enable(self.list.GetSelection() > 0) + elif evt.GetId() == self.ID_BUTTON_DOWN: + evt.Enable(self.list.GetSelection() != -1 and \ + self.list.GetSelection() < self.list.Number() - 1) + +class ContentCheckListDialog(wxDialogPtr): + def __init__(self, parent, value): + # Is this normal??? + w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST') + wxDialogPtr.__init__(self, w.this) + self.thisown = 1 + self.Center() + self.list = self.FindWindowByName('CHECK_LIST') + # Set list items + i = 0 + for v,ch in value: + self.list.Append(v) + self.list.Check(i, ch) + i += 1 + self.SetAutoLayout(true) + self.GetSizer().Fit(self) + # Callbacks + self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND') + self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE') + self.ID_BUTTON_UP = XMLID('BUTTON_UP') + self.ID_BUTTON_DOWN = XMLID('BUTTON_DOWN') + EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck) + EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp) + EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown) + EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend) + EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) + EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI) + EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI) + EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) + def OnCheck(self, evt): + # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking + self.list.Deselect(evt.GetSelection()) + def OnButtonUp(self, evt): + i = self.list.GetSelection() + str, ch = self.list.GetString(i), self.list.IsChecked(i) + self.list.Delete(i) + self.list.InsertItems([str], i-1) + self.list.Check(i-1, ch) + self.list.SetSelection(i-1) + def OnButtonDown(self, evt): + i = self.list.GetSelection() + str, ch = self.list.GetString(i), self.list.IsChecked(i) + self.list.Delete(i) + self.list.InsertItems([str], i+1) + self.list.Check(i+1, ch) + self.list.SetSelection(i+1) + def OnButtonAppend(self, evt): + str = wxGetTextFromUser('Enter new item:', 'Append', '', self) + self.list.Append(str) + def OnButtonRemove(self, evt): + self.list.Delete(self.list.GetSelection()) + def OnUpdateUI(self, evt): + if evt.GetId() == self.ID_BUTTON_REMOVE: + evt.Enable(self.list.GetSelection() != -1) + elif evt.GetId() == self.ID_BUTTON_UP: + evt.Enable(self.list.GetSelection() > 0) + elif evt.GetId() == self.ID_BUTTON_DOWN: + evt.Enable(self.list.GetSelection() != -1 and \ + self.list.GetSelection() < self.list.Number() - 1) + +class ParamContent(PPanel): + def __init__(self, parent, name): + PPanel.__init__(self, parent, name) + self.ID_TEXT_CTRL = wxNewId() + self.ID_BUTTON_EDIT = wxNewId() + self.SetBackgroundColour(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.SetSizer(sizer) + sizer.Fit(self) + 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() + def GetValue(self): + if self.textModified: # text has newer value + try: + return eval(self.text.GetValue()) + except SyntaxError: + wxLogError('Syntax error in parameter value: ' + self.GetName()) + return [] + return self.value + def SetValue(self, value): + self.freeze = true + if not value: value = [] + self.value = value + self.text.SetValue(str(value)) # update text ctrl + self.freeze = false + def OnButtonEdit(self, evt): + if self.textModified: # text has newer value + try: + self.value = eval(self.text.GetValue()) + except SyntaxError: + wxLogError('Syntax error in parameter value: ' + self.GetName()) + self.value = [] + dlg = ContentDialog(self, self.value) + if dlg.ShowModal() == wxID_OK: + value = [] + for i in range(dlg.list.Number()): + value.append(dlg.list.GetString(i)) + # Add ignored flags + self.SetValue(value) + self.SetModified() + self.textModified = false + dlg.Destroy() + +# CheckList content +class ParamContentCheckList(ParamContent): + def __init__(self, parent, name): + ParamContent.__init__(self, parent, name) + def OnButtonEdit(self, evt): + if self.textModified: # text has newer value + try: + self.value = eval(self.text.GetValue()) + except SyntaxError: + wxLogError('Syntax error in parameter value: ' + self.GetName()) + self.value = [] + dlg = ContentCheckListDialog(self, self.value) + if dlg.ShowModal() == wxID_OK: + value = [] + for i in range(dlg.list.Number()): + value.append((dlg.list.GetString(i), dlg.list.IsChecked(i))) + # Add ignored flags + self.SetValue(value) + self.SetModified() + self.textModified = false + dlg.Destroy() + +class IntListDialog(wxDialogPtr): + def __init__(self, parent, value): + # Is this normal??? + w = frame.res.LoadDialog(parent, 'DIALOG_INTLIST') + wxDialogPtr.__init__(self, w.this) + self.thisown = 1 + self.Center() + self.list = self.FindWindowByName('LIST') + # Set list items + value.sort() + for v in value: + if type(v) != IntType: + wxLogError('Invalid item type') + else: + self.list.Append(str(v)) + self.SetAutoLayout(true) + self.GetSizer().Fit(self) + # Callbacks + self.ID_BUTTON_ADD = XMLID('BUTTON_ADD') + self.ID_BUTTON_REMOVE = XMLID('BUTTON_REMOVE') + EVT_BUTTON(self, self.ID_BUTTON_ADD, self.OnButtonAppend) + EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove) + EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) + def OnButtonAppend(self, evt): + s = wxGetTextFromUser('Enter new number:', 'Add', '', self) + # Check that it's unique + try: + v = int(s) + s = str(v) # to be sure + i = self.list.FindString(s) + if i == -1: # ignore non-unique + # Find place to insert + found = false + for i in range(self.list.Number()): + if int(self.list.GetString(i)) > v: + found = true + break + if found: self.list.InsertItems([s], i) + else: self.list.Append(s) + except ValueError: + wxLogError('List item is not an int!') + def OnButtonRemove(self, evt): + self.list.Delete(self.list.GetSelection()) + def OnUpdateUI(self, evt): + if evt.GetId() == self.ID_BUTTON_REMOVE: + evt.Enable(self.list.GetSelection() != -1) + +# For growable list +class ParamIntList(ParamContent): + def __init__(self, parent, name): + ParamContent.__init__(self, parent, name) + def OnButtonEdit(self, evt): + if self.textModified: # text has newer value + try: + self.value = eval(self.text.GetValue()) + except SyntaxError: + wxLogError('Syntax error in parameter value: ' + self.GetName()) + self.value = [] + dlg = IntListDialog(self, self.value) + if dlg.ShowModal() == wxID_OK: + value = [] + for i in range(dlg.list.Number()): + value.append(int(dlg.list.GetString(i))) + # Add ignored flags + self.SetValue(value) + self.SetModified() + self.textModified = false + dlg.Destroy() + +# Boxless radiobox +class RadioBox(PPanel): + def __init__(self, parent, id, choices, + pos=wxDefaultPosition, name='radiobox'): + PPanel.__init__(self, parent, name) + self.SetBackgroundColour(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.SetSizer(topSizer) + topSizer.Fit(self) + def SetStringSelection(self, value): + self.freeze = true + for i in self.choices: + self.FindWindowByName(i).SetValue(i == value) + self.value = value + self.freeze = false + def OnRadioChoice(self, evt): + if self.freeze: return + if evt.GetSelection(): + self.value = evt.GetEventObject().GetName() + self.SetModified() + def GetStringSelection(self): + return self.value + +class ParamBool(RadioBox): + values = {'yes': '1', 'no': '0'} + seulav = {'1': 'yes', '0': 'no'} + def __init__(self, parent, name): + RadioBox.__init__(self, parent, -1, choices = self.values.keys(), name=name) + def GetValue(self): + return self.values[self.GetStringSelection()] + def SetValue(self, value): + if not value: value = '1' + self.SetStringSelection(self.seulav[value]) + +class ParamOrient(RadioBox): + values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'} + seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'} + def __init__(self, parent, name): + RadioBox.__init__(self, parent, -1, choices = self.values.keys(), name=name) + def GetValue(self): + return self.values[self.GetStringSelection()] + def SetValue(self, value): + if not value: value = 'wxHORIZONTAL' + self.SetStringSelection(self.seulav[value]) + +class ParamFile(PPanel): + def __init__(self, parent, name): + PPanel.__init__(self, parent, name) + self.ID_TEXT_CTRL = wxNewId() + self.ID_BUTTON_BROWSE = wxNewId() + self.SetBackgroundColour(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.SetSizer(sizer) + sizer.Fit(self) + 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() + 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.value = value + self.text.SetValue(value) # update text ctrl + 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), + defaultFile = os.path.basename(self.value)) + if dlg.ShowModal() == wxID_OK: + # Make relative + common = os.path.commonprefix([os.path.abspath(frame.dataFile), + 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, + '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, + } + diff --git a/wxPython/wxPython/tools/XRCed/xrced.ico b/wxPython/wxPython/tools/XRCed/xrced.ico new file mode 100644 index 0000000000..6c9964d2fb Binary files /dev/null and b/wxPython/wxPython/tools/XRCed/xrced.ico differ diff --git a/wxPython/wxPython/tools/XRCed/xrced.py b/wxPython/wxPython/tools/XRCed/xrced.py new file mode 100644 index 0000000000..0584f63043 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/xrced.py @@ -0,0 +1,1930 @@ +# Name: xrced.py +# Purpose: XRC editor, main module +# Author: Roman Rolinsky +# 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 + +# Constants + +# Return code from wxGetOsVersion +wxGTK = 9 + +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) + +progname = 'XRCed' +version = '0.0.7-3' + +# Local modules +from xxx import * + +# Globals +testWin = None +testWinPos = wxDefaultPosition + +# 1 adds CMD command to Help menu +debug = 0 + +helpText = """\ +

Welcome to XRCed!

DON'T PANIC :)

+To start select tree root, then popup menu with your right mouse button, +select "Append Child", and then any command.

+Enter XML ID, change properties, create children.

+To test your interface select Test command (View menu).

+Consult README file for the details. +""" + +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.LoadFrame(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 +class ScrolledMessageDialog(wxDialog): + def __init__(self, parent, msg, caption, pos = wxDefaultPosition, size = (500,300)): + from wxPython.lib.layoutf import Layoutf + wxDialog.__init__(self, parent, -1, caption, pos, size) + text = wxTextCtrl(self, -1, msg, wxDefaultPosition, + wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY) + text.SetFont(modernFont) + dc = wxWindowDC(text) + w, h = dc.GetTextExtent(' ') + 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.Fit() + self.CenterOnScreen(wxBOTH) + +################################################################################ + +class Frame(wxFrame): + def __init__(self, pos, size): + global frame + frame = self + wxFrame.__init__(self, None, -1, '', pos, size) + self.CreateStatusBar() + progpath = os.path.split(__file__)[0] + icon = wxIcon(os.path.join(progpath, 'xrced.ico'), wxBITMAP_TYPE_ICO) + self.SetIcon(icon) + + # Idle flag + self.inIdle = false + + # Make menus + menuBar = wxMenuBar() + + menu = wxMenu() + menu.Append(wxID_NEW, '&New\tCtrl-N', 'New file') + menu.Append(wxID_OPEN, '&Open...\tCtrl-O', 'Open XRC file') + menu.Append(wxID_SAVE, '&Save\tCtrl-S', 'Save XRC file') + menu.Append(wxID_SAVEAS, 'Save &As...', 'Save XRC file under different name') + menu.AppendSeparator() + menu.Append(wxID_EXIT, '&Quit\tCtrl-Q', 'Exit application') + menuBar.Append(menu, '&File') + + menu = wxMenu() + menu.Append(wxID_UNDO, '&Undo\tCtrl-Z', 'Undo') + menu.Append(wxID_REDO, '&Redo\tCtrl-Y', 'Redo') + menu.AppendSeparator() + menu.Append(wxID_CUT, 'Cut\tCtrl-X', 'Cut to the clipboard') + menu.Append(wxID_COPY, '&Copy\tCtrl-C', 'Copy to the clipboard') + 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') + 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) + menu.Check(self.ID_EMBED_PANEL, conf.embedPanel) + menu.AppendSeparator() + self.ID_TEST = wxNewId() + menu.Append(self.ID_TEST, '&Test\tF5', 'Test window') + self.ID_REFRESH = wxNewId() + 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) + menu.Check(self.ID_AUTO_REFRESH, conf.autoRefresh) + menuBar.Append(menu, '&View') + + menu = wxMenu() + menu.Append(wxID_ABOUT, '&About...', 'About XCRed') + self.ID_README = wxNewId() + menu.Append(self.ID_README, '&Readme...', 'View the README file') + if debug: + self.ID_DEBUG_CMD = wxNewId() + menu.Append(self.ID_DEBUG_CMD, 'CMD', 'Python command line') + EVT_MENU(self, self.ID_DEBUG_CMD, self.OnDebugCMD) + menuBar.Append(menu, '&Help') + + self.menuBar = menuBar + self.SetMenuBar(menuBar) + + # Create toolbar + tb = self.CreateToolBar(wxTB_HORIZONTAL | wxNO_BORDER | wxTB_FLAT) + tb.SetToolBitmapSize((24, 23)) + tb.AddSimpleTool(wxID_NEW, images.getNewBitmap(), 'New', 'New file') + 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_CUT, images.getCutBitmap(), 'Cut', 'Cut') + tb.AddSimpleTool(wxID_COPY, images.getCopyBitmap(), 'Copy', 'Copy') + tb.AddSimpleTool(wxID_PASTE, images.getPasteBitmap(), 'Paste', 'Paste') + tb.AddControl(wxStaticLine(tb, -1, size=(-1,23), style=wxLI_VERTICAL)) + tb.AddSimpleTool(self.ID_TEST, images.getTestBitmap(), 'Test', 'Test window') + 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: + tb.AddSeparator() # otherwise auto-refresh sticks in status line + tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh) + tb.Realize() + self.tb = tb + self.minWidth = tb.GetSize()[0] # minimal width is the size of toolbar + + # File + EVT_MENU(self, wxID_NEW, self.OnNew) + EVT_MENU(self, wxID_OPEN, self.OnOpen) + EVT_MENU(self, wxID_SAVE, self.OnSaveOrSaveAs) + EVT_MENU(self, wxID_SAVEAS, self.OnSaveOrSaveAs) + EVT_MENU(self, wxID_EXIT, self.OnExit) + # 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_COPY, self.OnCopy) + EVT_MENU(self, wxID_PASTE, self.OnPaste) + EVT_MENU(self, self.ID_DELETE, self.OnDelete) + # View + EVT_MENU(self, self.ID_EMBED_PANEL, self.OnEmbedPanel) + 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) + # Help + EVT_MENU(self, wxID_ABOUT, self.OnAbout) + EVT_MENU(self, self.ID_README, self.OnReadme) + + # Update events + 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, self.ID_DELETE, self.OnUpdateUI) + EVT_UPDATE_UI(self, self.ID_TEST, self.OnUpdateUI) + EVT_UPDATE_UI(self, self.ID_REFRESH, self.OnUpdateUI) + + # Build interface + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(wxStaticLine(self, -1), 0, wxEXPAND) + 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 + + # !!! frame styles are broken + # Miniframe for not embedded mode + miniFrame = wxFrame(self, -1, 'Properties Panel', + (conf.panelX, conf.panelY), + (conf.panelWidth, conf.panelHeight)) + self.miniFrame = miniFrame + sizer2 = wxBoxSizer() + miniFrame.SetAutoLayout(true) + miniFrame.SetSizer(sizer2) + EVT_CLOSE(self.miniFrame, self.OnCloseMiniFrame) + # Create panel for parameters + global panel + if conf.embedPanel: + panel = Panel(splitter) + # Set plitter windows + splitter.SplitVertically(tree, panel, conf.sashPos) + else: + panel = Panel(miniFrame) + sizer2.Add(panel, 1, wxEXPAND) + miniFrame.Show(true) + splitter.Initialize(tree) + sizer.Add(splitter, 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.Clear() + + # Other events + EVT_IDLE(self, self.OnIdle) + EVT_CLOSE(self, self.OnCloseWindow) + + def OnNew(self, evt): + self.Clear() + + def OnOpen(self, evt): + if not self.AskSave(): return + dlg = wxFileDialog(self, 'Open', os.path.dirname(self.dataFile), + '', '*.xrc', wxOPEN | wxCHANGE_DIR) + if dlg.ShowModal() == wxID_OK: + path = dlg.GetPath() + self.SetStatusText('Loading...') + wxYield() + wxBeginBusyCursor() + try: + self.Open(path) + self.SetStatusText('Data loaded') + except: + self.SetStatusText('Failed') + raise + wxEndBusyCursor() + dlg.Destroy() + + def OnSaveOrSaveAs(self, evt): + if evt.GetId() == wxID_SAVEAS or not self.dataFile: + if self.dataFile: defaultName = '' + else: defaultName = 'UNTITLED.xrc' + dlg = wxFileDialog(self, 'Save As', os.path.dirname(self.dataFile), + defaultName, '*.xrc', + wxSAVE | wxOVERWRITE_PROMPT | wxCHANGE_DIR) + if dlg.ShowModal() == wxID_OK: + path = dlg.GetPath() + dlg.Destroy() + else: + dlg.Destroy() + return + else: + path = self.dataFile + self.SetStatusText('Saving...') + wxYield() + wxBeginBusyCursor() + try: + self.Save(path) + self.dataFile = path + self.SetStatusText('Data saved') + except IOError: + self.SetStatusText('Failed') + wxEndBusyCursor() + + def OnExit(self, evt): + 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) ) + + 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') + + 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.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 + 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) + # Expanded container (must have children) + elif tree.IsExpanded(selected) and tree.GetChildrenCount(selected, false): + appendChild = 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) + if parent.hasChild: parent = parent.child + + # Create a copy of clipboard element + elem = self.clipboard.cloneNode(true) + # Tempopary xxx object to test things + xxx = MakeXXXFromDOM(parent, elem) + + # Check compatibility + error = false + # Top-level + x = xxx.treeObject() + if x.__class__ in [xxxDialog, xxxFrame, xxxMenuBar, xxxToolBar]: + if parent.__class__ != xxxMainNode: error = true + elif x.__class__ == xxxPanel and parent.__class__ == xxxMainNode: + pass + elif x.__class__ == xxxSpacer: + if not parent.isSizer: error = true + elif x.__class__ == xxxSeparator: + if not parent.__class__ in [xxxMenu, xxxToolBar]: error = true + elif x.__class__ == xxxTool: + if parent.__class__ != xxxToolBar: error = true + elif x.__class__ == xxxMenuItem: + 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 + if error: + if parent.__class__ == xxxMainNode: parentClass = 'root' + else: parentClass = parent.className + wxLogError('Incompatible parent/child: parent is %s, child is %s!' % + (parentClass, x.className)) + return + + # Check parent and child relationships. + # If parent is sizer or notebook, child is of wrong class or + # parent is normal window, child is child container then detach child. + isChildContainer = isinstance(xxx, xxxChildContainer) + if isChildContainer and \ + ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) 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 + # 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 + sizerItemElem = MakeEmptyDOM('sizeritem') + sizerItemElem.appendChild(elem) + elem = sizerItemElem + elif isinstance(parent, xxxNotebook) and not isChildContainer: + 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 + 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 conf.autoRefresh: + tree.needUpdate = true + tree.pendingHighLight = newItem + else: + tree.pendingHighLight = None + self.modified = true + self.SetStatusText('Pasted') + + def OnDelete(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)] + # 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 + xnode = tree.RemoveLeaf(selected) + # !!! cloneNode is broken, or something is wrong +# self.undo.append(xnode.cloneNode(true)) + xnode.unlink() + tree.pendingHighLight = None + tree.Unselect() + panel.Clear() + self.modified = true + self.SetStatusText('Deleted') + + def OnEmbedPanel(self, evt): + conf.embedPanel = evt.IsChecked() + if conf.embedPanel: + # Remember last dimentions + conf.panelX, conf.panelY = self.miniFrame.GetPosition() + conf.panelWidth, conf.panelHeight = self.miniFrame.GetSize() + size = self.GetSize() + pos = self.GetPosition() + sizePanel = panel.GetSize() + panel.Reparent(self.splitter) + self.miniFrame.GetSizer().RemoveWindow(panel) + wxYield() + # Widen + self.SetDimensions(pos.x, pos.y, size.x + sizePanel.x, size.y) + self.splitter.SplitVertically(tree, panel, conf.sashPos) + self.miniFrame.Show(false) + else: + conf.sashPos = self.splitter.GetSashPosition() + pos = self.GetPosition() + size = self.GetSize() + sizePanel = panel.GetSize() + self.splitter.Unsplit(panel) + sizer = self.miniFrame.GetSizer() + panel.Reparent(self.miniFrame) + panel.Show(true) + sizer.Add(panel, 1, wxEXPAND) + self.miniFrame.Show(true) + self.miniFrame.SetDimensions(conf.panelX, conf.panelY, + conf.panelWidth, conf.panelHeight) + wxYield() + # Reduce width + self.SetDimensions(pos.x, pos.y, + max(size.x - sizePanel.x, self.minWidth), size.y) + + def OnTest(self, evt): + if not tree.selection: return # key pressed event + tree.ShowTestWindow(tree.selection) + + def OnRefresh(self, evt): + # If modified, apply first + selection = tree.selection + if selection: + xxx = tree.GetPyData(selection) + if xxx and panel.IsModified(): + tree.Apply(xxx, selection) + if testWin: + # (re)create + tree.CreateTestWin(testWin.item) + tree.needUpdate = false + + def OnAutoRefresh(self, evt): + conf.autoRefresh = evt.IsChecked() + self.menuBar.Check(self.ID_AUTO_REFRESH, conf.autoRefresh) + self.tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh) + + def OnAbout(self, evt): + str = '%s %s\n\nRoman Rolinsky ' % \ + (progname, version) + dlg = wxMessageDialog(self, str, 'About ' + progname, wxOK | wxCENTRE) + dlg.ShowModal() + dlg.Destroy() + + def OnReadme(self, evt): + text = open(os.path.join(sys.path[0], 'README'), 'r').read() + dlg = ScrolledMessageDialog(self, text, "XRCed README") + dlg.ShowModal() + dlg.Destroy() + + + # Simple emulation of python command line + def OnDebugCMD(self, evt): + import traceback + while 1: + try: + exec raw_input('C:\> ') + except EOFError: + print '^D' + break + except: + (etype, value, tb) =sys.exc_info() + tblist =traceback.extract_tb(tb)[1:] + msg =string.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 + else: appendChild = not tree.NeedInsert(selected) + xxx = tree.GetPyData(selected) + if not appendChild: + # If insert before + if tree.shift: + # If has previous item, insert after it, else append to parent + nextItem = selected + parentLeaf = tree.GetItemParent(selected) + 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) + # Expanded container (must have children) + elif tree.shift and tree.IsExpanded(selected) \ + and tree.GetChildrenCount(selected, false): + appendChild = 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) + if parent.hasChild: parent = parent.child + + # Create element + className = self.createMap[evt.GetId()] + xxx = MakeEmptyXXX(parent, className) + + # Set default name for top-level windows + if parent.__class__ == xxxMainNode: + cl = xxx.treeObject().__class__ + frame.maxIDs[cl] += 1 + 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 + 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)) + 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 conf.autoRefresh: + tree.needUpdate = true + tree.pendingHighLight = newItem + else: + tree.pendingHighLight = None + + # Expand/collapse subtree + def OnExpand(self, evt): + if tree.selection: tree.ExpandAll(tree.selection) + else: tree.ExpandAll(tree.root) + def OnCollapse(self, evt): + if tree.selection: tree.CollapseAll(tree.selection) + else: tree.CollapseAll(tree.root) + + def OnPullDownHighlight(self, evt): + menuId = evt.GetMenuId() + if menuId != -1: + menu = evt.GetEventObject() + help = menu.GetHelpString(menuId) + self.SetStatusText(help) + else: + self.SetStatusText('') + + def OnUpdateUI(self, evt): + if evt.GetId() in [wxID_CUT, wxID_COPY, self.ID_DELETE]: + evt.Enable(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) + + def OnIdle(self, evt): + if self.inIdle: return # Recursive call protection + self.inIdle = true + if tree.needUpdate: + if conf.autoRefresh: + if testWin: + self.SetStatusText('Refreshing test window...') + # (re)create + tree.CreateTestWin(testWin.item) + wxYield() + self.SetStatusText('') + tree.needUpdate = false + elif tree.pendingHighLight: + tree.HighLight(tree.pendingHighLight) + else: + evt.Skip() + self.inIdle = false + + # We don't let close panel window + def OnCloseMiniFrame(self, evt): + return + + def OnCloseWindow(self, evt): + if not self.AskSave(): return + if testWin: testWin.Destroy() + # Destroy cached windows + panel.cacheParent.Destroy() + if not panel.GetPageCount() == 2: + panel.page2.Destroy() + conf.x, conf.y = self.GetPosition() + conf.width, conf.height = self.GetSize() + if conf.embedPanel: + conf.sashPos = self.splitter.GetSashPosition() + else: + conf.panelX, conf.panelY = self.miniFrame.GetPosition() + conf.panelWidth, conf.panelHeight = self.miniFrame.GetSize() + evt.Skip() + + def Clear(self): + self.dataFile = '' + self.clipboard = None + self.modified = false + panel.SetModified(false) + tree.Clear() + panel.Clear() + global testWin + if testWin: + testWin.Destroy() + testWin = None + self.SetTitle(progname) + # Numbers for new controls + self.maxIDs = {} + self.maxIDs[xxxPanel] = self.maxIDs[xxxDialog] = self.maxIDs[xxxFrame] = \ + self.maxIDs[xxxMenuBar] = self.maxIDs[xxxMenu] = self.maxIDs[xxxToolBar] = 0 + + def Open(self, path): + # Try to read the file + try: + open(path) + self.Clear() + # Build wx tree + dom = minidom.parse(path) + tree.SetData(dom) + self.dataFile = path + self.SetTitle(progname + ': ' + os.path.basename(path)) + except: + wxLogError('Error reading file: %s' % path) + raise + + def Indent(self, node, indent = 0): + # Copy child list because it will change soon + children = node.childNodes[:] + # Main node doesn't need to be indented + if indent: + text = self.domCopy.createTextNode('\n' + ' ' * indent) + node.parentNode.insertBefore(text, node) + if children: + # Append newline after last child, except for text nodes + if children[-1].nodeType == minidom.Node.ELEMENT_NODE: + text = self.domCopy.createTextNode('\n' + ' ' * indent) + node.appendChild(text) + # Indent children which are elements + for n in children: + if n.nodeType == minidom.Node.ELEMENT_NODE: + self.Indent(n, indent + 2) + + def Save(self, path): + try: + # Apply changes + self.OnRefresh(wxCommandEvent()) + f = open(path, 'w') + # Make temporary copy + # !!! 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.Indent(mainNode) + self.domCopy.writexml(f) + f.close() + self.domCopy.unlink() + self.domCopy = None + 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 + flags = wxICON_EXCLAMATION | wxYES_NO | wxCANCEL | wxCENTRE + dlg = wxMessageDialog( self, 'File is modified. Save before exit?', + 'Save before too late?', flags ) + say = dlg.ShowModal() + dlg.Destroy() + if say == wxID_YES: + self.OnSaveOrSaveAs(wxCommandEvent(wxID_SAVE)) + # If save was successful, modified flag is unset + if not self.modified: return true + elif say == wxID_NO: + self.modified = false + panel.SetModified(false) + return true + return false + +################################################################################ + +def usage(): + print >> sys.stderr, 'usage: xrced [-dvh] [file]' + +class App(wxApp): + def OnInit(self): + global debug, verbose + # Process comand-line + try: + opts, args = getopt.getopt(sys.argv[1:], 'dvh') + except getopt.GetoptError: + 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 + elif o == '-v': + print 'XRCed version', version + sys.exit(0) + + self.SetAppName('xrced') + # Settings + global conf + 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.sashPos = conf.ReadInt('sashPos', 200) + if not conf.embedPanel: + conf.panelX = conf.ReadInt('panelX', -1) + conf.panelY = conf.ReadInt('panelY', -1) + else: + conf.panelX = conf.panelY = -1 + conf.panelWidth = conf.ReadInt('panelWidth', 200) + conf.panelHeight = conf.ReadInt('panelHeight', 200) + conf.panic = not conf.HasEntry('nopanic') + # Add handlers + wxFileSystem_AddHandler(wxMemoryFSHandler()) + wxInitAllImageHandlers() + # Create main frame + frame = Frame(pos, size) + 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')) + + # Load file after showing + if args: + conf.panic = false + frame.open = frame.Open(args[0]) + + return true + + def OnExit(self): + # Write config + global conf + wc = wxConfigBase_Get() + wc.WriteInt('autorefresh', conf.autoRefresh) + wc.WriteInt('x', conf.x) + wc.WriteInt('y', conf.y) + wc.WriteInt('width', conf.width) + wc.WriteInt('height', conf.height) + wc.WriteInt('embedPanel', conf.embedPanel) + 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.Flush() + del conf + +def main(): + app = App() + app.MainLoop() + app.OnExit() + +if __name__ == '__main__': + main() diff --git a/wxPython/wxPython/tools/XRCed/xrced.sh b/wxPython/wxPython/tools/XRCed/xrced.sh new file mode 100644 index 0000000000..70f983bb14 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/xrced.sh @@ -0,0 +1 @@ +python2.2 YOUR_PATH_TO_XRCED/xrced.py $* diff --git a/wxPython/wxPython/tools/XRCed/xrced.xrc b/wxPython/wxPython/tools/XRCed/xrced.xrc new file mode 100644 index 0000000000..a407461450 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/xrced.xrc @@ -0,0 +1,235 @@ + + + + Content + 250,300 + + wxVERTICAL + + + wxHORIZONTAL + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxEXPAND + 5 + + + + wxVERTICAL + + + + + wxBOTTOM + 5 + + + + + + + + 10,20 + + + + + + + wxBOTTOM + 5 + + + + + + + + wxALL|wxEXPAND + 5 + + + + wxEXPAND + + + + wxEXPAND + + + + wxHORIZONTAL + + + + 1 + + wxRIGHT + 10 + + + + + + + + wxALL|wxALIGN_CENTRE_HORIZONTAL + 10 + + + + + + Content + 250,300 + + wxVERTICAL + + + wxHORIZONTAL + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxEXPAND + 5 + + + + wxVERTICAL + + + + + wxBOTTOM + 5 + + + + + + + + 10,20 + + + + + + + wxBOTTOM + 5 + + + + + + + + wxALL|wxEXPAND + 5 + + + + wxEXPAND + + + + wxEXPAND + + + + wxHORIZONTAL + + + + 1 + + wxRIGHT + 10 + + + + + + + + wxALL|wxALIGN_CENTRE_HORIZONTAL + 10 + + + + + + Numbers + 100,300 + + wxVERTICAL + + + wxVERTICAL + + + + 80,100 + + + + wxALL|wxALIGN_CENTRE_HORIZONTAL + 10 + + + + wxVERTICAL + + + + + wxBOTTOM + 3 + + + + + + + + wxALL|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + wxEXPAND + + + + wxEXPAND + + + + wxVERTICAL + + + + 1 + + wxBOTTOM + 5 + + + + + + + + wxALL|wxALIGN_CENTRE_HORIZONTAL + 10 + + + + + \ No newline at end of file diff --git a/wxPython/wxPython/tools/XRCed/xxx.py b/wxPython/wxPython/tools/XRCed/xxx.py new file mode 100644 index 0000000000..cf141ee949 --- /dev/null +++ b/wxPython/wxPython/tools/XRCed/xxx.py @@ -0,0 +1,712 @@ +# Name: xxx.py ('xxx' is easy to distinguish from 'wx' :) ) +# Purpose: XML interface classes +# Author: Roman Rolinsky +# 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 params import * + +# Base class for interface parameter classes +class xxxNode: + def __init__(self, node): + self.node = node + def remove(self): + self.node.parentNode.removeChild(self.node) + self.node.unlink() + +# Generic (text) parameter class +class xxxParam(xxxNode): + # Standard use: for text nodes + def __init__(self, node): + xxxNode.__init__(self, node) + if not node.hasChildNodes(): + # If does not have child nodes, create empty text node + text = tree.dom.createTextNode('') + node.appendChild(text) + else: + text = node.childNodes[0] # first child must be text node + assert text.nodeType == minidom.Node.TEXT_NODE + self.textNode = text + # Value returns string + def value(self): + return self.textNode.data + def update(self, value): + self.textNode.data = value + +# Integer parameter +class xxxParamInt(xxxParam): + # Standard use: for text nodes + def __init__(self, node): + xxxParam.__init__(self, node) + # Value returns string + def value(self): + try: + return int(self.textNode.data) + except ValueError: + return -1 # invalid value + def update(self, value): + self.textNode.data = str(value) + +# Content parameter +class xxxParamContent(xxxNode): + def __init__(self, node): + xxxNode.__init__(self, node) + data, l = [], [] # data is needed to quicker value retrieval + nodes = node.childNodes[:] # make a copy of the child list + for n in nodes: + if n.nodeType == minidom.Node.ELEMENT_NODE: + 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('') + node.appendChild(text) + else: + # !!! normalize? + text = n.childNodes[0] # first child must be text node + assert text.nodeType == minidom.Node.TEXT_NODE + l.append(text) + data.append(str(text.data)) + else: # remove other + node.removeChild(n) + n.unlink() + self.l, self.data = l, data + def value(self): + return self.data + def update(self, value): + # If number if items is not the same, recreate children + if len(value) != len(self.l): # remove first if number of items has changed + childNodes = self.node.childNodes[:] + for n in childNodes: + self.node.removeChild(n) + l = [] + for str in value: + itemElem = tree.dom.createElement('item') + itemText = tree.dom.createTextNode(str) + itemElem.appendChild(itemText) + self.node.appendChild(itemElem) + l.append(itemText) + self.l = l + else: + for i in range(len(value)): + self.l[i].data = value[i] + self.data = value + +# Content parameter for checklist +class xxxParamContentCheckList(xxxNode): + def __init__(self, node): + xxxNode.__init__(self, node) + data, l = [], [] # data is needed to quicker value retrieval + nodes = node.childNodes[:] # make a copy of the child list + for n in nodes: + if n.nodeType == minidom.Node.ELEMENT_NODE: + assert n.tagName == 'item', 'bad content content' + checked = n.getAttribute('checked') + if not n.hasChildNodes(): + # If does not have child nodes, create empty text node + text = tree.dom.createTextNode('') + node.appendChild(text) + else: + # !!! normalize? + text = n.childNodes[0] # first child must be text node + assert text.nodeType == minidom.Node.TEXT_NODE + l.append((text, n)) + data.append((str(text.data), int(checked))) + else: # remove other + node.removeChild(n) + n.unlink() + self.l, self.data = l, data + def value(self): + return self.data + def update(self, value): + # If number if items is not the same, recreate children + if len(value) != len(self.l): # remove first if number of items has changed + childNodes = self.node.childNodes[:] + 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) + itemElem.appendChild(itemText) + self.node.appendChild(itemElem) + l.append((itemText, itemElem)) + self.l = l + else: + for i in range(len(value)): + self.l[i][0].data = value[i][0] + self.l[i][1].setAttribute('checked', str(value[i][1])) + self.data = value + +################################################################################ + +# 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 + allParams = None # Some nodes have no parameters + # Style parameters (all optional) + styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip'] + # Special parameters + specials = [] + # Required paremeters: none by default + required = [] + # Default parameters with default values + default = {} + # Parameter types + paramDict = {} + # Window styles and extended styles + winStyles = [] + # Tree icon index + #image = -1 + # Construct a new xxx object from DOM element + # parent is parent xxx object (or None if none), element is DOM element object + def __init__(self, parent, element): + self.parent = parent + self.element = element + self.undo = None + # Get attributes + self.className = element.getAttribute('class') + if self.hasName: self.name = element.getAttribute('name') + # Set parameters (text element children) + self.params = {} + nodes = element.childNodes[:] + for node in nodes: + if node.nodeType == minidom.Node.ELEMENT_NODE: + 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: + print 'WARNING: unknown parameter for %s: %s' % \ + (self.className, tag) + elif tag in self.specials: + self.special(tag, node) + elif tag == 'content': + if self.className == 'wxCheckList': + self.params[tag] = xxxParamContentCheckList(node) + else: + self.params[tag] = xxxParamContent(node) + elif tag == 'font': # has children + self.params[tag] = xxxParamFont(element, node) + else: # simple parameter + self.params[tag] = xxxParam(node) + else: + # Remove all other nodes + element.removeChild(node) + node.unlink() + # Returns real tree object + def treeObject(self): + if self.hasChild: return self.child + return self + # Returns tree image index + def treeImage(self): + if self.hasChild: return self.child.treeImage() + return self.image + # Class name plus wx name + def treeName(self): + if self.hasChild: return self.child.treeName() + if self.hasName and self.name: return self.className + ' "' + self.name + '"' + return self.className + +################################################################################ + +# This is a little special: it is both xxxObject and xxxNode +class xxxParamFont(xxxObject, xxxNode): + allParams = ['size', 'style', 'weight', 'family', 'underlined', + 'face', 'encoding'] + def __init__(self, parent, element): + xxxObject.__init__(self, parent, element) + xxxNode.__init__(self, element) + self.parentNode = parent # required to behave similar to DOM node + v = [] + for p in self.allParams: + try: + v.append(str(self.params[p].value())) + except KeyError: + v.append('') + self.data = v + def update(self, value): + # `value' is a list of strings corresponding to all parameters + elem = self.element + # Remove old elements first + childNodes = elem.childNodes[:] + for node in childNodes: elem.removeChild(node) + i = 0 + self.params.clear() + v = [] + for param in self.allParams: + if value[i]: + fontElem = tree.dom.createElement(param) + textNode = tree.dom.createTextNode(value[i]) + self.params[param] = textNode + fontElem.appendChild(textNode) + elem.appendChild(fontElem) + v.append(value[i]) + i += 1 + self.data = v + def value(self): + return self.data + +################################################################################ + +class xxxContainer(xxxObject): + hasChildren = true + +# Special class for root node +class xxxMainNode(xxxContainer): + hasStyle = hasName = false + +################################################################################ +# Top-level windwows + +class xxxPanel(xxxContainer): + allParams = ['pos', 'size', 'style'] + styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', + 'tooltip'] + winStyles = ['wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] + exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] + +class xxxDialog(xxxContainer): + allParams = ['title', 'pos', 'size', 'style'] + required = ['title'] + winStyles = ['wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP', + 'wxDIALOG_MODAL', 'wxDIALOG_MODELESS', + 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX', + 'wxTHICK_FRAME', + 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] + styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', + 'tooltip'] + exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] + +class xxxFrame(xxxContainer): + allParams = ['title', 'centered', 'pos', 'size', 'style'] + paramDict = {'centered': ParamBool} + required = ['title'] + winStyles = ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE', + 'wxSTAY_ON_TOP', + 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', + 'wxRESIZE_BOX', 'wxMINIMIZE_BOX', 'wxMAXIMIZE_BOX', + 'wxFRAME_FLOAT_ON_PARENT', 'wxFRAME_TOOL_WINDOW', + 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN'] + styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', + 'tooltip'] + exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY'] + +class xxxTool(xxxObject): + allParams = ['bitmap', 'bitmap2', 'toggle', 'tooltip', 'longhelp'] + paramDict = {'bitmap2': ParamFile} + hasStyle = false + +class xxxToolBar(xxxContainer): + allParams = ['bitmapsize', 'margins', 'packing', 'separation', + 'pos', 'size', 'style'] + hasStyle = false + paramDict = {'bitmapsize': ParamPosSize, 'margins': ParamPosSize, + 'packing': ParamInt, 'separation': ParamInt, + 'style': ParamNonGenericStyle} + winStyles = ['wxTB_FLAT', 'wxTB_DOCKABLE', 'wxTB_VERTICAL', 'wxTB_HORIZONTAL'] + +################################################################################ +# Bitmap, Icon + +class xxxBitmap(xxxObject): + allParams = ['bitmap'] + required = ['bitmap'] + +class xxxIcon(xxxObject): + allParams = ['icon'] + required = ['icon'] + +################################################################################ +# Controls + +class xxxStaticText(xxxObject): + allParams = ['label', 'pos', 'size', 'style'] + required = ['label'] + winStyles = ['wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE'] + +class xxxStaticLine(xxxObject): + allParams = ['pos', 'size', 'style'] + winStyles = ['wxLI_HORIZONTAL', 'wxLI_VERTICAL'] + +class xxxStaticBitmap(xxxObject): + allParams = ['bitmap', 'pos', 'size', 'style'] + required = ['bitmap'] + +class xxxTextCtrl(xxxObject): + allParams = ['value', 'pos', 'size', 'style'] + winStyles = ['wxTE_PROCESS_ENTER', 'wxTE_PROCESS_TAB', 'wxTE_MULTILINE', + 'wxTE_PASSWORD', 'wxTE_READONLY', 'wxHSCROLL'] + +class xxxChoice(xxxObject): + allParams = ['content', 'selection', 'pos', 'size', 'style'] + required = ['content'] + winStyles = ['wxCB_SORT'] + +class xxxSlider(xxxObject): + allParams = ['value', 'min', 'max', 'pos', 'size', 'style', + 'tickfreq', 'pagesize', 'linesize', 'thumb', 'tick', + 'selmin', 'selmax'] + paramDict = {'value': ParamInt, 'tickfreq': ParamInt, 'pagesize': ParamInt, + 'linesize': ParamInt, 'thumb': ParamInt, 'thumb': ParamInt, + 'tick': ParamInt, 'selmin': ParamInt, 'selmax': ParamInt} + required = ['value', 'min', 'max'] + winStyles = ['wxSL_HORIZONTAL', 'wxSL_VERTICAL', 'wxSL_AUTOTICKS', 'wxSL_LABELS', + 'wxSL_LEFT', 'wxSL_RIGHT', 'wxSL_TOP', 'wxSL_BOTTOM', + 'wxSL_BOTH', 'wxSL_SELRANGE'] + +class xxxGauge(xxxObject): + allParams = ['range', 'pos', 'size', 'style', 'value', 'shadow', 'bezel'] + paramDict = {'range': ParamInt, 'value': ParamInt, + 'shadow': ParamInt, 'bezel': ParamInt} + winStyles = ['wxGA_HORIZONTAL', 'wxGA_VERTICAL', 'wxGA_PROGRESSBAR', 'wxGA_SMOOTH'] + +class xxxScrollBar(xxxObject): + allParams = ['pos', 'size', 'style', 'value', 'thumbsize', 'range', 'pagesize'] + paramDict = {'value': ParamInt, 'range': ParamInt, 'thumbsize': ParamInt, + 'pagesize': ParamInt} + winStyles = ['wxSB_HORIZONTAL', 'wxSB_VERTICAL'] + +class xxxListCtrl(xxxObject): + allParams = ['pos', 'size', 'style'] + winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON', + 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', + 'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER', + 'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING'] + +class xxxTreeCtrl(xxxObject): + allParams = ['pos', 'size', 'style'] + winStyles = ['wxTR_HAS_BUTTONS', 'wxTR_NO_LINES', 'wxTR_LINES_AT_ROOT', + 'wxTR_EDIT_LABELS', 'wxTR_MULTIPLE'] + +class xxxHtmlWindow(xxxObject): + allParams = ['pos', 'size', 'style', 'borders', 'url', 'htmlcode'] + paramDict = {'borders': ParamInt} + winStyles = ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO'] + +class xxxCalendar(xxxObject): + allParams = ['pos', 'size', 'style'] + +class xxxNotebook(xxxContainer): + allParams = ['usenotebooksizer', 'pos', 'size', 'style'] + paramDict = {'usenotebooksizer': ParamBool} + winStyles = ['wxNB_FIXEDWIDTH', 'wxNB_LEFT', 'wxNB_RIGHT', 'wxNB_BOTTOM'] + +################################################################################ +# Buttons + +class xxxButton(xxxObject): + allParams = ['label', 'default', 'pos', 'size', 'style'] + paramDict = {'default': ParamBool} + required = ['label'] + winStyles = ['wxBU_LEFT', 'wxBU_TOP', 'wxBU_RIGHT', 'wxBU_BOTTOM'] + +class xxxBitmapButton(xxxObject): + allParams = ['bitmap', 'selected', 'focus', 'disabled', 'default', + 'pos', 'size', 'style'] + required = ['bitmap'] + winStyles = ['wxBU_AUTODRAW', 'wxBU_LEFT', 'wxBU_TOP', + 'wxBU_RIGHT', 'wxBU_BOTTOM'] + +class xxxRadioButton(xxxObject): + allParams = ['label', 'value', 'pos', 'size', 'style'] + paramDict = {'value': ParamBool} + required = ['label'] + winStyles = ['wxRB_GROUP'] + +class xxxSpinButton(xxxObject): + allParams = ['pos', 'size', 'style'] + winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP'] + +################################################################################ +# Boxes + +class xxxStaticBox(xxxObject): + allParams = ['label', 'pos', 'size', 'style'] + required = ['label'] + +class xxxRadioBox(xxxObject): + allParams = ['label', 'content', 'selection', 'dimension', 'pos', 'size', 'style'] + paramDict = {'dimension': ParamInt} + required = ['label', 'content'] + winStyles = ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS'] + +class xxxCheckBox(xxxObject): + allParams = ['label', 'pos', 'size', 'style'] + required = ['label'] + +class xxxComboBox(xxxObject): + allParams = ['content', 'selection', 'value', 'pos', 'size', 'style'] + required = ['content'] + winStyles = ['wxCB_SIMPLE', 'wxCB_SORT', 'wxCB_READONLY', 'wxCB_DROPDOWN'] + +class xxxListBox(xxxObject): + allParams = ['content', 'selection', 'pos', 'size', 'style'] + required = ['content'] + winStyles = ['wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL', + 'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT'] + +class xxxCheckList(xxxObject): + allParams = ['content', 'pos', 'size', 'style'] + required = ['content'] + winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON', + 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', + '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 + paramDict = {'orient': ParamOrient} + isSizer = true + +class xxxBoxSizer(xxxSizer): + allParams = ['orient'] + required = ['orient'] + default = {'orient': 'wxVERTICAL'} + # Tree icon depends on orientation + def treeImage(self): + if self.params['orient'].value() == 'wxHORIZONTAL': return self.imageH + else: return self.imageV + +class xxxStaticBoxSizer(xxxBoxSizer): + allParams = ['label', 'orient'] + required = ['label', 'orient'] + default = {'orient': 'wxVERTICAL'} + +class xxxGridSizer(xxxSizer): + allParams = ['cols', 'rows', 'vgap', 'hgap'] + required = ['cols'] + default = {'cols': '2', 'rows': '2'} + +# For repeated parameters +class xxxParamMulti: + def __init__(self): + self.l, self.data = [], [] + def append(self, param): + self.l.append(param) + self.data.append(param.value()) + def value(self): + return self.data + def remove(self): + for param in self.l: + param.remove() + self.l, self.data = [], [] + +class xxxFlexGridSizer(xxxGridSizer): + specials = ['growablecols', 'growablerows'] + allParams = ['cols', 'rows', 'vgap', 'hgap'] + specials + paramDict = {'growablecols':ParamIntList, 'growablerows':ParamIntList} + # 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() + 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.appendChild(text) + self.element.appendChild(node) + self.special(param, node) + +# Container with only one child. +# Not shown in tree. +class xxxChildContainer(xxxObject): + 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 + nodes = element.childNodes[:] # create copy + for node in nodes: + if node.nodeType == minidom.Node.ELEMENT_NODE: + if node.tagName == 'object': + # Create new xxx object for child node + self.child = MakeXXXFromDOM(self, node) + self.child.parent = parent + # Copy hasChildren and isSizer attributes + self.hasChildren = self.child.hasChildren + self.isSizer = self.child.isSizer + return # success + else: + element.removeChild(node) + node.unlink() + assert 0, 'no child found' + +class xxxSizerItem(xxxChildContainer): + allParams = ['option', 'flag', 'border'] + paramDict = {'option': ParamInt} + def __init__(self, parent, element): + xxxChildContainer.__init__(self, parent, element) + # Remove pos parameter - not needed for sizeritems + if 'pos' in self.child.allParams: + self.child.allParams = self.child.allParams[:] + self.child.allParams.remove('pos') + +class xxxNotebookPage(xxxChildContainer): + allParams = ['label', 'selected'] + paramDict = {'selected': ParamBool} + required = ['label'] + def __init__(self, parent, element): + xxxChildContainer.__init__(self, parent, element) + # pos and size dont matter for notebookpages + if 'pos' in self.child.allParams: + self.child.allParams = self.child.allParams[:] + self.child.allParams.remove('pos') + if 'size' in self.child.allParams: + self.child.allParams = self.child.allParams[:] + self.child.allParams.remove('size') + +class xxxSpacer(xxxObject): + hasName = hasStyle = false + allParams = ['size', 'option', 'flag', 'border'] + paramDict = {'option': ParamInt} + default = {'size': '0,0'} + +class xxxMenuBar(xxxContainer): + allParams = [] + +class xxxMenu(xxxContainer): + allParams = ['label'] + default = {'label': ''} + paramDict = {'style': ParamNonGenericStyle} # no generic styles + winStyles = ['wxMENU_TEAROFF'] + +class xxxMenuItem(xxxObject): + allParams = ['checkable', 'label', 'accel', 'help'] + default = {'label': ''} + +class xxxSeparator(xxxObject): + hasName = hasStyle = false + +################################################################################ + +xxxDict = { + 'wxPanel': xxxPanel, + 'wxDialog': xxxDialog, + 'wxFrame': xxxFrame, + 'tool': xxxTool, + 'wxToolBar': xxxToolBar, + + 'wxBitmap': xxxBitmap, + 'wxIcon': xxxIcon, + + 'wxButton': xxxButton, + 'wxBitmapButton': xxxBitmapButton, + 'wxRadioButton': xxxRadioButton, + 'wxSpinButton': xxxSpinButton, + + 'wxStaticBox': xxxStaticBox, + 'wxStaticBitmap': xxxStaticBitmap, + 'wxRadioBox': xxxRadioBox, + 'wxComboBox': xxxComboBox, + 'wxCheckBox': xxxCheckBox, + 'wxListBox': xxxListBox, + + 'wxStaticText': xxxStaticText, + 'wxStaticLine': xxxStaticLine, + 'wxTextCtrl': xxxTextCtrl, + 'wxChoice': xxxChoice, + 'wxSlider': xxxSlider, + 'wxGauge': xxxGauge, + 'wxScrollBar': xxxScrollBar, + 'wxTreeCtrl': xxxTreeCtrl, + 'wxListCtrl': xxxListCtrl, + 'wxCheckList': xxxCheckList, + 'wxNotebook': xxxNotebook, + 'notebookpage': xxxNotebookPage, + 'wxHtmlWindow': xxxHtmlWindow, + 'wxCalendar': xxxCalendar, + + 'wxBoxSizer': xxxBoxSizer, + 'wxStaticBoxSizer': xxxStaticBoxSizer, + 'wxGridSizer': xxxGridSizer, + 'wxFlexGridSizer': xxxFlexGridSizer, + 'sizeritem': xxxSizerItem, + 'spacer': xxxSpacer, + + 'wxMenuBar': xxxMenuBar, + 'wxMenu': xxxMenu, + 'wxMenuItem': xxxMenuItem, + 'separator': xxxSeparator, + } + +# 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() + } +for cl in xxxDict.values(): + if cl.allParams: + for param in cl.allParams + cl.paramDict.keys(): + if not paramIDs.has_key(param): + paramIDs[param] = wxNewId() + +################################################################################ +# Helper functions + +# Test for object elements +def IsObject(node): + return node.nodeType == minidom.Node.ELEMENT_NODE and node.tagName == 'object' + +# Make XXX object from some DOM object, selecting correct class +def MakeXXXFromDOM(parent, element): + try: + return xxxDict[element.getAttribute('class')](parent, element) + except KeyError: + # Verify that it's not recursive exception + if element.getAttribute('class') not in xxxDict: + print 'ERROR: unknown class:', element.getAttribute('class') + raise + +# Make empty DOM element +def MakeEmptyDOM(className): + elem = 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) + try: + textNode = tree.dom.createTextNode(xxxClass.default[param]) + except KeyError: + textNode = tree.dom.createTextNode('') + textElem.appendChild(textNode) + elem.appendChild(textElem) + return elem + +# Make empty XXX object +def MakeEmptyXXX(parent, className): + # Make corresponding DOM object first + elem = MakeEmptyDOM(className) + # If parent is a sizer, we should create sizeritem object, except for spacers + if parent: + if parent.isSizer and className != 'spacer': + sizerItemElem = MakeEmptyDOM('sizeritem') + sizerItemElem.appendChild(elem) + elem = sizerItemElem + elif isinstance(parent, xxxNotebook): + pageElem = MakeEmptyDOM('notebookpage') + pageElem.appendChild(elem) + elem = pageElem + # Now just make object + return MakeXXXFromDOM(parent, elem) + diff --git a/wxPython/wxPython/tools/__init__.py b/wxPython/wxPython/tools/__init__.py new file mode 100644 index 0000000000..54e9b268d8 --- /dev/null +++ b/wxPython/wxPython/tools/__init__.py @@ -0,0 +1,4 @@ +# + + + diff --git a/wxPython/wxPython/tools/img2img.py b/wxPython/wxPython/tools/img2img.py new file mode 100644 index 0000000000..dbefc261a4 --- /dev/null +++ b/wxPython/wxPython/tools/img2img.py @@ -0,0 +1,76 @@ +""" +Common routines for the image converter utilities. +""" +import sys, os, glob, getopt, string +from wxPython.wx import * + +wxInitAllImageHandlers() + +def convert(file, maskClr, outputDir, outputName, outType, outExt): + if string.lower(os.path.splitext(file)[1]) == ".ico": + icon = wxIcon(file, wxBITMAP_TYPE_ICO) + img = wxBitmapFromIcon(icon) + else: + img = wxBitmap(file, wxBITMAP_TYPE_ANY) + + if not img.Ok(): + return 0, file + " failed to load!" + else: + if maskClr: + om = img.GetMask() + mask = wxMaskColour(img, maskClr) + img.SetMask(mask) + if om is not None: + om.Destroy() + if outputName: + newname = outputName + else: + newname = os.path.join(outputDir, + os.path.basename(os.path.splitext(file)[0]) + outExt) + if img.SaveFile(newname, outType): + return 1, file + " converted to " + newname + else: + img = wxImageFromBitmap(img) + if img.SaveFile(newname, outType): + return 1, "ok" + else: + return 0, file + " failed to save!" + + + + +def main(args, outType, outExt, doc): + if not args or ("-h" in args): + print doc + return + + outputDir = "" + maskClr = None + outputName = None + + try: + opts, fileArgs = getopt.getopt(args, "m:n:o:") + except getopt.GetoptError: + print __doc__ + return + + for opt, val in opts: + if opt == "-m": + maskClr = val + elif opt == "-n": + outputName = val + elif opt == "-o": + outputDir = val + + if not fileArgs: + print doc + return + + for arg in fileArgs: + for file in glob.glob(arg): + if not os.path.isfile(file): + continue + ok, msg = convert(file, maskClr, outputDir, outputName, + outType, outExt) + print msg + diff --git a/wxPython/wxPython/tools/img2png.py b/wxPython/wxPython/tools/img2png.py new file mode 100644 index 0000000000..76e7f6db06 --- /dev/null +++ b/wxPython/wxPython/tools/img2png.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +""" +img2png.py -- convert several image formats to PNG format + +Usage: + + img2png.py [options] image_files... + +Options: + + -o The directory to place the .png file(s), defaults to + the current directory. + + -m <#rrggbb> If the original image has a mask or transparency defined + it will be used by default. You can use this option to + override the default or provide a new mask by specifying + a colour in the image to mark as transparent. + + -n A filename to write the .png data to. Defaults to the + basename of the image file + '.png' This option overrides + the -o option. +""" + + +import sys +import img2img +from wxPython import wx + +def main(): + img2img.main(sys.argv[1:], wx.wxBITMAP_TYPE_PNG, ".png", __doc__) + +if __name__ == '__main__': + main() + + + diff --git a/wxPython/wxPython/tools/img2py.py b/wxPython/wxPython/tools/img2py.py new file mode 100644 index 0000000000..21957dc8bc --- /dev/null +++ b/wxPython/wxPython/tools/img2py.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python +""" +img2py.py -- Convert an image to PNG format and embed it in a Python + module with appropriate code so it can be loaded into + a program at runtime. The benefit is that since it is + Python source code it can be delivered as a .pyc or + 'compiled' into the program using freeze, py2exe, etc. + +Usage: + + img2py.py [options] image_file python_file + +Options: + + -m <#rrggbb> If the original image has a mask or transparency defined + it will be used by default. You can use this option to + override the default or provide a new mask by specifying + a colour in the image to mark as transparent. + + -n Normally generic names (getBitmap, etc.) are used for the + image access functions. If you use this option you can + specify a name that should be used to customize the access + fucntions, (getNameBitmap, etc.) + + -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. + + -u Don't use compression. Leaves the data uncompressed. + + -i Also output a function to return the image as a wxIcon. + +""" + + + +import sys, os, glob, getopt, tempfile, string +import cPickle, cStringIO, zlib +import img2img +from wxPython import wx + + +def crunch_data(data, compressed): + # compress it? + if compressed: + data = zlib.compress(data, 9) + + # convert to a printable format, so it can be in a Python source file + data = repr(data) + + # This next bit is borrowed from PIL. It is used to wrap the text intelligently. + fp = cStringIO.StringIO() + data = data + " " # buffer for the +1 test + c = i = 0 + word = "" + octdigits = "01234567" + hexdigits = "0123456789abcdef" + while i < len(data): + if data[i] != "\\": + word = data[i] + i = i + 1 + else: + if data[i+1] in octdigits: + for n in range(2, 5): + if data[i+n] not in octdigits: + break + word = data[i:i+n] + i = i + n + elif data[i+1] == 'x': + for n in range(2, 5): + if data[i+n] not in hexdigits: + break + word = data[i:i+n] + i = i + n + else: + word = data[i:i+2] + i = i + 2 + + l = len(word) + if c + l >= 78-1: + fp.write("\\\n") + c = 0 + fp.write(word) + c = c + l + + # return the formatted compressed data + return fp.getvalue() + + + +def main(args): + if not args or ("-h" in args): + print __doc__ + return + + append = 0 + compressed = 1 + maskClr = None + imgName = "" + icon = 0 + + try: + opts, fileArgs = getopt.getopt(args, "auin:m:") + except getopt.GetoptError: + print __doc__ + return + + for opt, val in opts: + if opt == "-a": + append = 1 + elif opt == "-u": + compressed = 0 + elif opt == "-n": + imgName = val + elif opt == "-m": + maskClr = val + elif opt == "-i": + icon = 1 + + if len(fileArgs) != 2: + print __doc__ + return + + image_file, python_file = fileArgs + + # convert the image file to a temporary file + tfname = tempfile.mktemp() + ok, msg = img2img.convert(image_file, maskClr, None, tfname, wx.wxBITMAP_TYPE_PNG, ".png") + if not ok: + print msg + return + + data = open(tfname, "rb").read() + data = crunch_data(data, compressed) + os.unlink(tfname) + + if append: + out = open(python_file, "a") + else: + out = open(python_file, "w") + + out.write("#" + "-" * 70 + "\n") + if not append: + out.write("# This file was generated by %s\n#\n" % sys.argv[0]) + out.write("from wxPython.wx import wxImageFromStream, wxBitmapFromImage\n") + if icon: + out.write("from wxPython.wx import wxEmptyIcon\n") + if compressed: + out.write("import cStringIO, zlib\n\n\n") + else: + out.write("import cStringIO\n\n\n") + + if compressed: + out.write("def get%sData():\n" + " return zlib.decompress(\n%s)\n\n" + % (imgName, data)) + else: + out.write("def get%sData():\n" + " return %s\n\n" + % (imgName, data)) + + + out.write("def get%sBitmap():\n" + " return wxBitmapFromImage(get%sImage())\n\n" + "def get%sImage():\n" + " stream = cStringIO.StringIO(get%sData())\n" + " return wxImageFromStream(stream)\n\n" + % tuple([imgName] * 4)) + if icon: + out.write("def get%sIcon():\n" + " icon = wxEmptyIcon()\n" + " icon.CopyFromBitmap(get%sBitmap())\n" + " return icon\n\n" + % tuple([imgName] * 2)) + + + if imgName: + n_msg = ' using "%s"' % imgName + else: + n_msg = "" + if maskClr: + m_msg = " with mask %s" % maskClr + else: + m_msg = "" + print "Embedded %s%s into %s%s" % (image_file, n_msg, python_file, m_msg) + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/wxPython/wxPython/tools/img2xpm.py b/wxPython/wxPython/tools/img2xpm.py new file mode 100644 index 0000000000..2b9a99555c --- /dev/null +++ b/wxPython/wxPython/tools/img2xpm.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +""" +img2xpm.py -- convert several image formats to XPM + +Usage: + + img2xpm.py [options] image_files... + +Options: + + -o The directory to place the .xpm file(s), defaults to + the current directory. + + -m <#rrggbb> If the original image has a mask or transparency defined + it will be used by default. You can use this option to + override the default or provide a new mask by specifying + a colour in the image to mark as transparent. + + -n A filename to write the .xpm data to. Defaults to the + basename of the image file + '.xpm' This option overrides + the -o option. +""" + + +import sys +import img2img +from wxPython import wx + +def main(): + img2img.main(sys.argv[1:], wx.wxBITMAP_TYPE_XPM, ".xpm", __doc__) + + +if __name__ == '__main__': + main() + + +