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.
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
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
--- /dev/null
+#!/usr/bin/env python
+
+from wxPython.tools.img2png import main
+main()
+
--- /dev/null
+#!/usr/bin/env python
+
+import sys
+from wxPython.tools.img2py import main
+main(sys.argv[1:])
+
--- /dev/null
+#!/usr/bin/env python
+
+from wxPython.tools.img2xpm import main
+main()
+
--- /dev/null
+#!/usr/bin/env python
+
+from wxPython.tools.XRCed.xrced import main
+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:
+++ /dev/null
-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.
-
+++ /dev/null
-********************************************************************************
-
- 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 <rolinsky@mema.ucl.ac.be>
+++ /dev/null
-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
+++ /dev/null
-#----------------------------------------------------------------------
-# 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<eK\x03\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT0'\x02$\xe9f\xe1\xe6\xecf\x01\
-\x95\xc4\x0e\x06ZR\x0f\n\xb0KF\x80\x01B\x16\x9bd\x84\x1e>\x9d0\xbdX$A\xf2\
-\xf9\xc3Z\x12\x010%\x15\xf2\x11` S\x82\x1e\x00-\xd9\x8b\xfa" ))
-
-def 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<eK\x03\x10\x04\xf3#@|\x0b\x03\x0b\x03\x03\x08_\x01\xc8\xf7\xcb\xcfK\x05\
-s\xf2A\x92n\x16n\xcen\x16PI\xec\x80\xe6\x92z(\x00]2B/\x1f\n\x80L\x7f\xdc\x92\
-z\xf8$#\xe8&\x19\x01\xf3G\x046I\x04\xc0\xa3\x13\x8f\xb1x\xed$Y\x125\xe4\xd1%\
-\x15\xfc\x91\x01]R\x02vI=\x00\xd8\x14\x96@' ))
-
-def getSaveBitmap():
- return wxBitmapFromXPMData(getSaveData())
-
-def getSaveImage():
- return wxImageFromBitmap(getSaveBitmap())
-
-#----------------------------------------------------------------------
-def getCutData():
- return cPickle.loads(zlib.decompress(
-'x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\
-\x81<e\x03 \xb00\x00\xf3#@|K\x03\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT(\x07;\xa0\
-\x96\xa4\x1e^\xc9\x08\x145h\x92z\x102\x02\xab\x9d a\xa0\x1c\x0eI=$9L\xc9\x08\
-\xb8\xa1\x98^\xd1C\xd2\x88U\x12W \xe4\xe7\xeb\xe5\xe7\xe3\x96\x8c\xc8\xcf\
-\x87K\xa3H\x82\xc4#\xc0\x08S\x12&\x03B\xe4H\x82\x0c\x8f\x88\xc0j\'H8\x02{\
-\xf0E \x02\x80\x9a)\x81DI=\x00\x12\xa5\x85\x9f' ))
-
-def getCutBitmap():
- return wxBitmapFromXPMData(getCutData())
-
-def getCutImage():
- return wxImageFromBitmap(getCutBitmap())
-
-#----------------------------------------------------------------------
-def getCopyData():
- return cPickle.loads(zlib.decompress(
-'x\xda\xc5\x92\xb1\n\xc20\x10\x86\xf7>\xc5\x81C\x9c\x8e\xb4*\xc4\xd5BF3t\xc9\
-Z\x8a\x93\xc5\xf3\xfd\'\xef.vP\xee\xe6\xfe\t\x81\x9f/\xdf\r!\xc7\xf5\xddwS\
-\x18\xce0\x9c\xe0\x02}\xe8\xe6) ,p[\xe7\xe5\xa9\x8d\xb8\x1d"\'E\xedE\xfa5\
-\xca\xd2\x0e\xdc\xef\xf4zh\xa9\x02s\xcacN_hg_\x88\x1a\x0fV\xce/\xfd\x87\x15\
-\x1d\x88\xbcIc\x9b\x95\xf4 \xcbDl\xb0\x92c\xf2\xf0m\xb2i\xca\xa5\xe2\x98(r1\
-\x1e\xc11\xa1H\x1c\xb3\xc53\x1b\xdcb\xc16\\\xb2\xdfO\xc0\x0f5t\x92\x06' ))
-
-def 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<eK\x03K\x13K\x030_\x01\xc8\xf7\xcb\xcfK\x05s\xf4@\x92n\x16n\xcen\x16`~>\
-\x88\xefb\xe0b\xe2\x02S\x8c\n\xc8\x10\xd4\x83\x80\x08T\xc1|\x10\xf0\xa7\xae\
-\xa0?\x18\xa0\nF@\x01\x99\x8e'FP\x0f\x00\xdc\x1bL7" ))
-
-def 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"\x80<e\
-c\x0b\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT(\x07\x15 \x04\xf5\x80\x00Y0\x02\x080\
-\x04\x15"\xb0i\x8f\x80\xe9\x87\xa8\x86\n\xc2\xf4\xa3\x08\x0e\xa8v\x9c~G\x15\
-\xd4\x03\x00\x87\xa5@\xc2' ))
-
-def getTreeRootBitmap():
- return wxBitmapFromXPMData(getTreeRootData())
-
-def getTreeRootImage():
- return wxImageFromBitmap(getTreeRootBitmap())
-
-#----------------------------------------------------------------------
-def getTreePanelData():
- return cPickle.loads(zlib.decompress(
-'x\xda\xd3\xc8)0\xe4\nV74S04Q0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\
-\x81<eK\x03K\x13K\x030_\x01\xc4w\xb3psv\xb3\x00\xf3#@|\x17\x03\x17\x13\x17\
-\x98<\n\xd0\x83\x08F \x83\xfca+\x98\x8f\x02 \x82zh\x00(\xa8\x07\x00&\x96e\
-\x83' ))
-
-def getTreePanelBitmap():
- return wxBitmapFromXPMData(getTreePanelData())
-
-def getTreePanelImage():
- return wxImageFromBitmap(getTreePanelBitmap())
-
-#----------------------------------------------------------------------
-def getTreeDialogData():
- return cPickle.loads(zlib.decompress(
-'x\xda\xd3\xc8)0\xe4\nV74S\x00"\x13\x05Cu\xae\xc4`u\x05\x85d\x05\xa7\x9c\xc4\
-\xe4l0/\x1f\xc8S\xb64\xb04\xb14\x00\xf3\xf5@|\x03 p\xb3\x00\xf3#@|\x17\x03\
-\x17\x13\x17\x03\xa8nT\x00\x11\xd4C\x01$\x0bb53\x02\x05\x0c\x98`>1\x82\xf9`@\
-\xc8LLo\xea\x01\x00\xb5\x9cde' ))
-
-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())
-
+++ /dev/null
-# Name: params.py
-# Purpose: Classes for parameter introduction
-# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
-# 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,
- }
-
+++ /dev/null
-# Name: xrced.py
-# Purpose: XRC editor, main module
-# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
-# 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 = """\
-<HTML><H2>Welcome to XRCed!</H2><H3><font color="green">DON'T PANIC :)</font></H3>
-To start select tree root, then popup menu with your right mouse button,
-select "Append Child", and then any command.<P>
-Enter XML ID, change properties, create children.<P>
-To test your interface select Test command (View menu).<P>
-Consult README file for the details.</HTML>
-"""
-
-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 <rolinsky@mema.ucl.ac.be>' % \
- (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()
+++ /dev/null
-python2.2 YOUR_PATH_TO_XRCED/xrced.py $*
+++ /dev/null
-<?xml version="1.0" ?>
-<resource>
- <object class="wxDialog" name="DIALOG_CONTENT">
- <title>Content</title>
- <size>250,300</size>
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxHORIZONTAL</orient>
- <object class="sizeritem">
- <object class="wxListBox" name="LIST">
- <content/>
- </object>
- <option>1</option>
- <flag>wxTOP|wxBOTTOM|wxLEFT|wxEXPAND</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_UP">
- <label>Move Up</label>
- </object>
- <flag>wxBOTTOM</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_DOWN">
- <label>Move Down</label>
- </object>
- </object>
- <object class="spacer">
- <size>10,20</size>
- <option>1</option>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_APPEND">
- <label>Append...</label>
- </object>
- <flag>wxBOTTOM</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_REMOVE">
- <label>Remove</label>
- </object>
- </object>
- </object>
- <flag>wxALL|wxEXPAND</flag>
- <border>5</border>
- </object>
- </object>
- <option>1</option>
- <flag>wxEXPAND</flag>
- </object>
- <object class="sizeritem">
- <object class="wxStaticLine"/>
- <flag>wxEXPAND</flag>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxHORIZONTAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="wxID_OK">
- <label>OK</label>
- <default>1</default>
- </object>
- <flag>wxRIGHT</flag>
- <border>10</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="wxID_CANCEL">
- <label>Cancel</label>
- </object>
- </object>
- </object>
- <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
- <border>10</border>
- </object>
- </object>
- <style>wxRESIZE_BORDER</style>
- </object>
- <object class="wxDialog" name="DIALOG_CONTENT_CHECK_LIST">
- <title>Content</title>
- <size>250,300</size>
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxHORIZONTAL</orient>
- <object class="sizeritem">
- <object class="wxCheckList" name="CHECK_LIST">
- <content/>
- </object>
- <option>1</option>
- <flag>wxTOP|wxBOTTOM|wxLEFT|wxEXPAND</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_UP">
- <label>Move Up</label>
- </object>
- <flag>wxBOTTOM</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_DOWN">
- <label>Move Down</label>
- </object>
- </object>
- <object class="spacer">
- <size>10,20</size>
- <option>1</option>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_APPEND">
- <label>Append...</label>
- </object>
- <flag>wxBOTTOM</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_REMOVE">
- <label>Remove</label>
- </object>
- </object>
- </object>
- <flag>wxALL|wxEXPAND</flag>
- <border>5</border>
- </object>
- </object>
- <option>1</option>
- <flag>wxEXPAND</flag>
- </object>
- <object class="sizeritem">
- <object class="wxStaticLine"/>
- <flag>wxEXPAND</flag>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxHORIZONTAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="wxID_OK">
- <label>OK</label>
- <default>1</default>
- </object>
- <flag>wxRIGHT</flag>
- <border>10</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="wxID_CANCEL">
- <label>Cancel</label>
- </object>
- </object>
- </object>
- <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
- <border>10</border>
- </object>
- </object>
- <style>wxRESIZE_BORDER</style>
- </object>
- <object class="wxDialog" name="DIALOG_INTLIST">
- <title>Numbers</title>
- <size>100,300</size>
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxListBox" name="LIST">
- <content/>
- <size>80,100</size>
- <style>wxLB_SORT</style>
- </object>
- <option>1</option>
- <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
- <border>10</border>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_ADD">
- <label>Add...</label>
- </object>
- <flag>wxBOTTOM</flag>
- <border>3</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="BUTTON_REMOVE">
- <label>Remove</label>
- </object>
- </object>
- </object>
- <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
- <border>5</border>
- </object>
- </object>
- <option>1</option>
- <flag>wxEXPAND</flag>
- </object>
- <object class="sizeritem">
- <object class="wxStaticLine"/>
- <flag>wxEXPAND</flag>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="wxID_OK">
- <label>OK</label>
- <default>1</default>
- </object>
- <flag>wxBOTTOM</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="wxID_CANCEL">
- <label>Cancel</label>
- </object>
- </object>
- </object>
- <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
- <border>10</border>
- </object>
- </object>
- <style>wxRESIZE_BORDER</style>
- </object>
-</resource>
\ No newline at end of file
+++ /dev/null
-# Name: xxx.py ('xxx' is easy to distinguish from 'wx' :) )
-# Purpose: XML interface classes
-# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
-# 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)
-
+++ /dev/null
-"""
-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
-
+++ /dev/null
-#!/usr/bin/env python
-"""
-img2png.py -- convert several image formats to PNG format
-
-Usage:
-
- img2png.py [options] image_files...
-
-Options:
-
- -o <dir> 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 <name> 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__)
-
-
+++ /dev/null
-#!/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 <name> 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:])
-
+++ /dev/null
-#!/usr/bin/env python
-"""
-img2xpm.py -- convert several image formats to XPM
-
-Usage:
-
- img2xpm.py [options] image_files...
-
-Options:
-
- -o <dir> 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 <name> 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__)
-
-
--- /dev/null
+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.
+
--- /dev/null
+********************************************************************************
+
+ 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 <rolinsky@mema.ucl.ac.be>
--- /dev/null
+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
--- /dev/null
+#----------------------------------------------------------------------
+# 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<eK\x03\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT0'\x02$\xe9f\xe1\xe6\xecf\x01\
+\x95\xc4\x0e\x06ZR\x0f\n\xb0KF\x80\x01B\x16\x9bd\x84\x1e>\x9d0\xbdX$A\xf2\
+\xf9\xc3Z\x12\x010%\x15\xf2\x11` S\x82\x1e\x00-\xd9\x8b\xfa" ))
+
+def 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<eK\x03\x10\x04\xf3#@|\x0b\x03\x0b\x03\x03\x08_\x01\xc8\xf7\xcb\xcfK\x05\
+s\xf2A\x92n\x16n\xcen\x16PI\xec\x80\xe6\x92z(\x00]2B/\x1f\n\x80L\x7f\xdc\x92\
+z\xf8$#\xe8&\x19\x01\xf3G\x046I\x04\xc0\xa3\x13\x8f\xb1x\xed$Y\x125\xe4\xd1%\
+\x15\xfc\x91\x01]R\x02vI=\x00\xd8\x14\x96@' ))
+
+def getSaveBitmap():
+ return wxBitmapFromXPMData(getSaveData())
+
+def getSaveImage():
+ return wxImageFromBitmap(getSaveBitmap())
+
+#----------------------------------------------------------------------
+def getCutData():
+ return cPickle.loads(zlib.decompress(
+'x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\
+\x81<e\x03 \xb00\x00\xf3#@|K\x03\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT(\x07;\xa0\
+\x96\xa4\x1e^\xc9\x08\x145h\x92z\x102\x02\xab\x9d a\xa0\x1c\x0eI=$9L\xc9\x08\
+\xb8\xa1\x98^\xd1C\xd2\x88U\x12W \xe4\xe7\xeb\xe5\xe7\xe3\x96\x8c\xc8\xcf\
+\x87K\xa3H\x82\xc4#\xc0\x08S\x12&\x03B\xe4H\x82\x0c\x8f\x88\xc0j\'H8\x02{\
+\xf0E \x02\x80\x9a)\x81DI=\x00\x12\xa5\x85\x9f' ))
+
+def getCutBitmap():
+ return wxBitmapFromXPMData(getCutData())
+
+def getCutImage():
+ return wxImageFromBitmap(getCutBitmap())
+
+#----------------------------------------------------------------------
+def getCopyData():
+ return cPickle.loads(zlib.decompress(
+'x\xda\xc5\x92\xb1\n\xc20\x10\x86\xf7>\xc5\x81C\x9c\x8e\xb4*\xc4\xd5BF3t\xc9\
+Z\x8a\x93\xc5\xf3\xfd\'\xef.vP\xee\xe6\xfe\t\x81\x9f/\xdf\r!\xc7\xf5\xddwS\
+\x18\xce0\x9c\xe0\x02}\xe8\xe6) ,p[\xe7\xe5\xa9\x8d\xb8\x1d"\'E\xedE\xfa5\
+\xca\xd2\x0e\xdc\xef\xf4zh\xa9\x02s\xcacN_hg_\x88\x1a\x0fV\xce/\xfd\x87\x15\
+\x1d\x88\xbcIc\x9b\x95\xf4 \xcbDl\xb0\x92c\xf2\xf0m\xb2i\xca\xa5\xe2\x98(r1\
+\x1e\xc11\xa1H\x1c\xb3\xc53\x1b\xdcb\xc16\\\xb2\xdfO\xc0\x0f5t\x92\x06' ))
+
+def 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<eK\x03K\x13K\x030_\x01\xc8\xf7\xcb\xcfK\x05s\xf4@\x92n\x16n\xcen\x16`~>\
+\x88\xefb\xe0b\xe2\x02S\x8c\n\xc8\x10\xd4\x83\x80\x08T\xc1|\x10\xf0\xa7\xae\
+\xa0?\x18\xa0\nF@\x01\x99\x8e'FP\x0f\x00\xdc\x1bL7" ))
+
+def 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"\x80<e\
+c\x0b\x10\x04\xf3\x15\x80|\xbf\xfc\xbcT(\x07\x15 \x04\xf5\x80\x00Y0\x02\x080\
+\x04\x15"\xb0i\x8f\x80\xe9\x87\xa8\x86\n\xc2\xf4\xa3\x08\x0e\xa8v\x9c~G\x15\
+\xd4\x03\x00\x87\xa5@\xc2' ))
+
+def getTreeRootBitmap():
+ return wxBitmapFromXPMData(getTreeRootData())
+
+def getTreeRootImage():
+ return wxImageFromBitmap(getTreeRootBitmap())
+
+#----------------------------------------------------------------------
+def getTreePanelData():
+ return cPickle.loads(zlib.decompress(
+'x\xda\xd3\xc8)0\xe4\nV74S04Q0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\
+\x81<eK\x03K\x13K\x030_\x01\xc4w\xb3psv\xb3\x00\xf3#@|\x17\x03\x17\x13\x17\
+\x98<\n\xd0\x83\x08F \x83\xfca+\x98\x8f\x02 \x82zh\x00(\xa8\x07\x00&\x96e\
+\x83' ))
+
+def getTreePanelBitmap():
+ return wxBitmapFromXPMData(getTreePanelData())
+
+def getTreePanelImage():
+ return wxImageFromBitmap(getTreePanelBitmap())
+
+#----------------------------------------------------------------------
+def getTreeDialogData():
+ return cPickle.loads(zlib.decompress(
+'x\xda\xd3\xc8)0\xe4\nV74S\x00"\x13\x05Cu\xae\xc4`u\x05\x85d\x05\xa7\x9c\xc4\
+\xe4l0/\x1f\xc8S\xb64\xb04\xb14\x00\xf3\xf5@|\x03 p\xb3\x00\xf3#@|\x17\x03\
+\x17\x13\x17\x03\xa8nT\x00\x11\xd4C\x01$\x0bb53\x02\x05\x0c\x98`>1\x82\xf9`@\
+\xc8LLo\xea\x01\x00\xb5\x9cde' ))
+
+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())
+
--- /dev/null
+# Name: params.py
+# Purpose: Classes for parameter introduction
+# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
+# 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,
+ }
+
--- /dev/null
+# Name: xrced.py
+# Purpose: XRC editor, main module
+# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
+# 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 = """\
+<HTML><H2>Welcome to XRCed!</H2><H3><font color="green">DON'T PANIC :)</font></H3>
+To start select tree root, then popup menu with your right mouse button,
+select "Append Child", and then any command.<P>
+Enter XML ID, change properties, create children.<P>
+To test your interface select Test command (View menu).<P>
+Consult README file for the details.</HTML>
+"""
+
+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 <rolinsky@mema.ucl.ac.be>' % \
+ (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()
--- /dev/null
+python2.2 YOUR_PATH_TO_XRCED/xrced.py $*
--- /dev/null
+<?xml version="1.0" ?>
+<resource>
+ <object class="wxDialog" name="DIALOG_CONTENT">
+ <title>Content</title>
+ <size>250,300</size>
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <object class="wxListBox" name="LIST">
+ <content/>
+ </object>
+ <option>1</option>
+ <flag>wxTOP|wxBOTTOM|wxLEFT|wxEXPAND</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_UP">
+ <label>Move Up</label>
+ </object>
+ <flag>wxBOTTOM</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_DOWN">
+ <label>Move Down</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>10,20</size>
+ <option>1</option>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_APPEND">
+ <label>Append...</label>
+ </object>
+ <flag>wxBOTTOM</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_REMOVE">
+ <label>Remove</label>
+ </object>
+ </object>
+ </object>
+ <flag>wxALL|wxEXPAND</flag>
+ <border>5</border>
+ </object>
+ </object>
+ <option>1</option>
+ <flag>wxEXPAND</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticLine"/>
+ <flag>wxEXPAND</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_OK">
+ <label>OK</label>
+ <default>1</default>
+ </object>
+ <flag>wxRIGHT</flag>
+ <border>10</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_CANCEL">
+ <label>Cancel</label>
+ </object>
+ </object>
+ </object>
+ <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+ <border>10</border>
+ </object>
+ </object>
+ <style>wxRESIZE_BORDER</style>
+ </object>
+ <object class="wxDialog" name="DIALOG_CONTENT_CHECK_LIST">
+ <title>Content</title>
+ <size>250,300</size>
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <object class="wxCheckList" name="CHECK_LIST">
+ <content/>
+ </object>
+ <option>1</option>
+ <flag>wxTOP|wxBOTTOM|wxLEFT|wxEXPAND</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_UP">
+ <label>Move Up</label>
+ </object>
+ <flag>wxBOTTOM</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_DOWN">
+ <label>Move Down</label>
+ </object>
+ </object>
+ <object class="spacer">
+ <size>10,20</size>
+ <option>1</option>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_APPEND">
+ <label>Append...</label>
+ </object>
+ <flag>wxBOTTOM</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_REMOVE">
+ <label>Remove</label>
+ </object>
+ </object>
+ </object>
+ <flag>wxALL|wxEXPAND</flag>
+ <border>5</border>
+ </object>
+ </object>
+ <option>1</option>
+ <flag>wxEXPAND</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticLine"/>
+ <flag>wxEXPAND</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxHORIZONTAL</orient>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_OK">
+ <label>OK</label>
+ <default>1</default>
+ </object>
+ <flag>wxRIGHT</flag>
+ <border>10</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_CANCEL">
+ <label>Cancel</label>
+ </object>
+ </object>
+ </object>
+ <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+ <border>10</border>
+ </object>
+ </object>
+ <style>wxRESIZE_BORDER</style>
+ </object>
+ <object class="wxDialog" name="DIALOG_INTLIST">
+ <title>Numbers</title>
+ <size>100,300</size>
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxListBox" name="LIST">
+ <content/>
+ <size>80,100</size>
+ <style>wxLB_SORT</style>
+ </object>
+ <option>1</option>
+ <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+ <border>10</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_ADD">
+ <label>Add...</label>
+ </object>
+ <flag>wxBOTTOM</flag>
+ <border>3</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="BUTTON_REMOVE">
+ <label>Remove</label>
+ </object>
+ </object>
+ </object>
+ <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+ <border>5</border>
+ </object>
+ </object>
+ <option>1</option>
+ <flag>wxEXPAND</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxStaticLine"/>
+ <flag>wxEXPAND</flag>
+ </object>
+ <object class="sizeritem">
+ <object class="wxBoxSizer">
+ <orient>wxVERTICAL</orient>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_OK">
+ <label>OK</label>
+ <default>1</default>
+ </object>
+ <flag>wxBOTTOM</flag>
+ <border>5</border>
+ </object>
+ <object class="sizeritem">
+ <object class="wxButton" name="wxID_CANCEL">
+ <label>Cancel</label>
+ </object>
+ </object>
+ </object>
+ <flag>wxALL|wxALIGN_CENTRE_HORIZONTAL</flag>
+ <border>10</border>
+ </object>
+ </object>
+ <style>wxRESIZE_BORDER</style>
+ </object>
+</resource>
\ No newline at end of file
--- /dev/null
+# Name: xxx.py ('xxx' is easy to distinguish from 'wx' :) )
+# Purpose: XML interface classes
+# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
+# 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)
+
--- /dev/null
+"""
+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
+
--- /dev/null
+#!/usr/bin/env python
+"""
+img2png.py -- convert several image formats to PNG format
+
+Usage:
+
+ img2png.py [options] image_files...
+
+Options:
+
+ -o <dir> 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 <name> 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()
+
+
+
--- /dev/null
+#!/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 <name> 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:])
+
--- /dev/null
+#!/usr/bin/env python
+"""
+img2xpm.py -- convert several image formats to XPM
+
+Usage:
+
+ img2xpm.py [options] image_files...
+
+Options:
+
+ -o <dir> 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 <name> 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()
+
+
+