]> git.saurik.com Git - wxWidgets.git/commitdiff
Moved tools to be a Python package in wxPython.tools, added scripts to
authorRobin Dunn <robin@alldunn.com>
Thu, 8 Aug 2002 18:28:21 +0000 (18:28 +0000)
committerRobin Dunn <robin@alldunn.com>
Thu, 8 Aug 2002 18:28:21 +0000 (18:28 +0000)
import and launch each tool.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16418 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

39 files changed:
wxPython/CHANGES.txt
wxPython/MANIFEST.in
wxPython/distrib/make_installer.py
wxPython/scripts/img2png [new file with mode: 0755]
wxPython/scripts/img2py [new file with mode: 0755]
wxPython/scripts/img2xpm [new file with mode: 0755]
wxPython/scripts/xrced [new file with mode: 0755]
wxPython/setup.py
wxPython/tools/XRCed/CHANGES [deleted file]
wxPython/tools/XRCed/README [deleted file]
wxPython/tools/XRCed/TODO [deleted file]
wxPython/tools/XRCed/images.py [deleted file]
wxPython/tools/XRCed/params.py [deleted file]
wxPython/tools/XRCed/xrced.ico [deleted file]
wxPython/tools/XRCed/xrced.py [deleted file]
wxPython/tools/XRCed/xrced.sh [deleted file]
wxPython/tools/XRCed/xrced.xrc [deleted file]
wxPython/tools/XRCed/xxx.py [deleted file]
wxPython/tools/img2img.py [deleted file]
wxPython/tools/img2png.py [deleted file]
wxPython/tools/img2py.py [deleted file]
wxPython/tools/img2xpm.py [deleted file]
wxPython/wxPython/lib/__init__.py
wxPython/wxPython/tools/XRCed/CHANGES [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/README [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/TODO [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/__init__.py [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/images.py [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/params.py [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/xrced.ico [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/xrced.py [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/xrced.sh [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/xrced.xrc [new file with mode: 0644]
wxPython/wxPython/tools/XRCed/xxx.py [new file with mode: 0644]
wxPython/wxPython/tools/__init__.py [new file with mode: 0644]
wxPython/wxPython/tools/img2img.py [new file with mode: 0644]
wxPython/wxPython/tools/img2png.py [new file with mode: 0644]
wxPython/wxPython/tools/img2py.py [new file with mode: 0644]
wxPython/wxPython/tools/img2xpm.py [new file with mode: 0644]

index 21eb15506d5febb675c26026859539f93c84b8de..579493668d3caa3ef0118e1eeb7b0edf26dc3adb 100644 (file)
@@ -155,6 +155,8 @@ respond to mouse events and etc.
 Changed the wxDateTime.Parse* methods to return an int that will be -1
 on failure, and the index where parsing stopped otherwise.
 
+Moved tools to be a Python package in wxPython.tools, added scripts to
+import and launch each tool.
 
 
 
index 844ec9f2dfff83a19d86459eeb109bdc0cb9b082..11ad108fbd36167da08f14d6eed698ff014aeb3b 100644 (file)
@@ -100,14 +100,16 @@ include src/mac/*.cpp
 include src/mac/*.h
 include src/mac/*.py
 
-include tools/*.py
-include tools/XRCed/CHANGES
-include tools/XRCed/TODO
-include tools/XRCed/README
-include tools/XRCed/*.py
-include tools/XRCed/*.xrc
-include tools/XRCed/*.ico
-include tools/XRCed/*.sh
+include wxPython/tools/*.py
+include wxPython/tools/XRCed/CHANGES
+include wxPython/tools/XRCed/TODO
+include wxPython/tools/XRCed/README
+include wxPython/tools/XRCed/*.py
+include wxPython/tools/XRCed/*.xrc
+include wxPython/tools/XRCed/*.ico
+include wxPython/tools/XRCed/*.sh
+
+include scripts/*
 
 include contrib/glcanvas/*.i
 include contrib/glcanvas/*.py
index 0532fd5bb0cb5c746a0d1a770cb2df7fb550b99b..b7ed38f9a09b58bf49ed824341d29eab9bf9b59c 100644 (file)
@@ -136,14 +136,16 @@ Source: "licence\*.txt";                    DestDir: "{app}\wxPython\docs\licenc
 Source: "%(WXDIR)s\docs\htmlhelp\wx.chm";   DestDir: "{app}\wxPython\docs"; Components: docs
 Source: "%(WXDIR)s\docs\htmlhelp\ogl.chm";  DestDir: "{app}\wxPython\docs"; Components: docs
 
-Source: "tools\*.py";                       DestDir: "{app}\wxPython\tools"; Components: tools
-Source: "tools\XRCed\CHANGES";              DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
-Source: "tools\XRCed\TODO";                 DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
-Source: "tools\XRCed\README";               DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
-Source: "tools\XRCed\*.py";                 DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
-Source: "tools\XRCed\*.xrc";                DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
-Source: "tools\XRCed\*.ico";                DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
-Source: "tools\XRCed\*.sh";                 DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\*.py";              DestDir: "{app}\wxPython\tools"; Components: tools
+Source: "wxPython\tools\XRCed\CHANGES";     DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\XRCed\TODO";        DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\XRCed\README";      DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\XRCed\*.py";        DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\XRCed\*.xrc";       DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\XRCed\*.ico";       DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+Source: "wxPython\tools\XRCed\*.sh";        DestDir: "{app}\wxPython\tools\XRCed"; Components: tools
+
+;; Where to put the scripts on Win32???
 
 Source: "samples\doodle\*.py";              DestDir: "{app}\wxPython\samples\doodle"; Components: samples
 Source: "samples\doodle\*.txt";             DestDir: "{app}\wxPython\samples\doodle"; Components: samples
diff --git a/wxPython/scripts/img2png b/wxPython/scripts/img2png
new file mode 100755 (executable)
index 0000000..690072e
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+from wxPython.tools.img2png import main
+main()
+
diff --git a/wxPython/scripts/img2py b/wxPython/scripts/img2py
new file mode 100755 (executable)
index 0000000..a3ce91b
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+
+import sys
+from wxPython.tools.img2py import main
+main(sys.argv[1:])
+
diff --git a/wxPython/scripts/img2xpm b/wxPython/scripts/img2xpm
new file mode 100755 (executable)
index 0000000..899faf1
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+from wxPython.tools.img2xpm import main
+main()
+
diff --git a/wxPython/scripts/xrced b/wxPython/scripts/xrced
new file mode 100755 (executable)
index 0000000..135192e
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+
+from wxPython.tools.XRCed.xrced import main
+main()
index 3f402d577ecb7c3f425c0c5b1a77225c2bfc3d9c..66226f0fde92fbcba36580220d578f4f35863f7e 100755 (executable)
@@ -904,14 +904,22 @@ if __name__ == "__main__":
                           PKGDIR+'.lib.editor',
                           PKGDIR+'.lib.mixins',
                           PKGDIR+'.lib.PyCrust',
+                          PKGDIR+'.tools',
+                          PKGDIR+'.tools.XRCed',
                           ],
 
               ext_package = PKGDIR,
               ext_modules = wxpExtensions,
 
-              options = { 'build' : { 'build_base' : BUILD_BASE }}
+              options = { 'build' : { 'build_base' : BUILD_BASE }},
 
               ##data_files = TOOLS,
+
+              scripts = ['scripts/img2png',
+                         'scripts/img2xpm',
+                         'scripts/img2py',
+                         'scripts/xrced',
+                         ],
               )
 
     else:
diff --git a/wxPython/tools/XRCed/CHANGES b/wxPython/tools/XRCed/CHANGES
deleted file mode 100644 (file)
index 89b20ff..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-0.0.7
------
-
-Some command-line arguments.
-
-"Test window" command and toolbar button.
-
-New panel interphace (wxHTMLWindow is not used anymore).
-
-Toggling between embedded and detached panel.
-
-Cache for already used windows.
-
-Current top-level control is bold, if test window shown.
-
-Undo/redo broken.
-
-CheckListBox does not work unless wxXRC source fixed (in both wxPytnon and
-wxWin):
-
-contrib/src/xrc/xmlrsall.cpp
-45,46c45,46
-<     AddHandler(new wxListCtrlXmlHandler);
-< #if CHECKLISTBOX
----
->     AddHandler(new wxListCtrlXmlHandler);    
-> #if wxUSE_CHECKLISTBOX
-
-
-0.0.6
------
-
-Toolbar, bitmap, icon support (no display yet).
-
-Changed parameter objects, added support for multiple parameters (like 
-`growablecols').
-
-Fixed double-clicking problem with tree control on Windows.
-
-Some performance improovements.
-
-
-0.0.5
------
-
-Added notebook with properties page and style page. Fixed some problems
-on Windows.
-
-
-0.0.4
------
-
-Some fixes suggested by RD
-
-
-0.0.3
------
-
-Faster preview window refresh.
-
-Cut/Paste works better.
-
-Some tree icons.
-
-Tree item names.
-
-Bugfixes.
-
-
-0.0.2
------
-
-The first release.
-
diff --git a/wxPython/tools/XRCed/README b/wxPython/tools/XRCed/README
deleted file mode 100644 (file)
index 133ee2a..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-********************************************************************************
-
-                                 XRCed README
-
-********************************************************************************
-
-Installation on UNIX
---------------------
-
-XRCed requires wxGTK and wxPython greater than 2.3.2, and Python 2.2 (it may
-work with earlier version, but was not tested).
-
-Of course wxGTK's XRC library (libwxxrc) must be installed.
-
-Installation on Windows
------------------------
-
-Works with wxPython 2.3.2 for Python 2.2.
-
-Short manual
-------------
-
-XRCed's idea is very straightforward: it is a visual tool for editing an XML
-file conforming to XRC format. Every operation performed in XRCed has direct
-correspondence to XML structure. So it is not really a usual point-and-click
-GUI builder, but don't let that scare you.
-
-To start xrced, change to the directory where you installed it and run
-"python2.2 xrced.py".
-
-On UNIX you can edit wrapper script "xrced.sh" to point to your installation
-directory.
-
-To create an object, first you should select some object in the tree (or the
-root item if it's empty) then press the right mouse button and select an
-appropriate command. The pulldown menu is context-dependent on the selected
-object.
-
-XRCed tries to guess if new object should be added as a next sibling or a
-child of current object, depending on the possibility of the object to have
-child objects and expanded state (if tree item is collapsed, new object will
-be sibling). You can change this behavior to create siblings by pressing and
-holding the Shift and Control keys before clicking the mouse.
-
-Pressed Control key while pressing right button makes next item a sibling of
-selected item regardless of its expanded state.
-
-Pressed Shift key changes the place for inserting new child to be before
-selected child, not after as by default.
-
-Panel on the right contains object properties. Properties which are optional
-should be "checked" first. This panel can be made separate by unchecking
-"Embed Panel" in View menu.
-
-All properties can be edited as text, and some are supplied with special
-editing controls.
-
-The names of the properties are exactly as in XRC file, and it's usually not
-hard to guess what they do. XML ID is the name of the window, and must be
-present for top-level windows (though this is not enforced by XRCed).
-
-To display the preview window double-click a top-level object (you should
-assign an XMLID to it first), press "Test" toolbar button or select command
-from View menu, or press F5. After that, if you select a child object, it
-becomes highlighted, and if you change it, preview is updated when you select
-another item or press Ctrl-R (refresh). To turn off automatic update, toggle
-"View->Auto-refresh" or toolbar auto-refresh button (to the right of the
-refresh button).
-
---------------------------------------------------------------------------------
-
-Copyright 2001 Roman Rolinsky <rolinsky@mema.ucl.ac.be>
diff --git a/wxPython/tools/XRCed/TODO b/wxPython/tools/XRCed/TODO
deleted file mode 100644 (file)
index 4b9cc1b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-TODO for XRCed
-==============
-
-- Undo/Redo
-
-- menu - accel not displayed in preview
-
-+ tree icons
-
-- replace object with another, keeping children
-
-+ write tmp file for current dialog/panel/etc.
-
-+ XML indents
-
-? select same notebook pages after update
-
-- put some default values in tree ctrl etc.
-
-- special (fast) update for some values: pos/size, value/content, sizeritem
-  stuff (?), well, as much as possible
-
-- highlighting with better method
-
-- import XRC/WXR files
-
-+ disable some window creation when it's not valid
-
-- check for memory leaks from wx objects
diff --git a/wxPython/tools/XRCed/images.py b/wxPython/tools/XRCed/images.py
deleted file mode 100644 (file)
index 924c55d..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-#----------------------------------------------------------------------
-# This file was generated by img2py.py
-#
-from wxPython.wx import wxBitmapFromXPMData, wxImageFromBitmap
-import cPickle, zlib
-
-
-def getIconData():
-    return cPickle.loads(zlib.decompress(
-'x\xda\x9d\x90\xbb\x0e\xc20\x0cEw\xbe\xc2\x12C\x91"Y-\xa2\x82\xd1\x80\xd45C\
-\x97\xac\x88\x11\xa4\xf0\xff\x13\xd7Nh\xa0\xcd\x00\xb8y\xf4\xe6\xf8\x95l\xee\
-\x8fn56\xdb\x1da\xec\xa9kV\x97\xb1\tt\xa5\xd3\xfdr\xbd\x99b\xa8\xf5\xf1\xa0\
-\x9fi\xa7\xba\x85\rI\xcb\x8bg\x1dU\xf7m\xbf\xeb[\xd3\xfe\xa53\'\xd5\xc3a8O\
-\xban_@\x0eL10\x07X\xc4iL[\x8e\x8c\x81 \xe1\xc3\xea\x17\xd4/NPct\x85{0N\xcc\
-\xa5f\xb4\x83\x94\xd6|\xde\x1b\xb2"\x9a\x16\x05\xe6\x10\x81\x08\xe5\x9cZ\x1d\
-K\xcd\xd4\xed\x04-}\xb9\n\n\x12\xdb\xb0\x99\x0e\xe8\x8f\x17\xf2N~\x81\xe2}"^\
-\x16\xd0;\x18\xce\x9c\xcb?oP\x9c\xc7t\xf0\xb1\xfd\x13Z&,9z\x0eS:\x04/\x1bB:\
-\x81Q\x15jM4Z\xaf\x99\xba\xf4\xf5n\xed\x9e\x92\xef)B\x7f\xbem\x81\xfc\x04\
-\x8f\xd5\x99\xcc' ))
-
-def getIconBitmap():
-    return wxBitmapFromXPMData(getIconData())
-
-def getIconImage():
-    return wxImageFromBitmap(getIconBitmap())
-
-#----------------------------------------------------------------------
-def getNewData():
-    return cPickle.loads(zlib.decompress(
-"x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\
-\x81<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())
-
diff --git a/wxPython/tools/XRCed/params.py b/wxPython/tools/XRCed/params.py
deleted file mode 100644 (file)
index 319034e..0000000
+++ /dev/null
@@ -1,722 +0,0 @@
-# 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,
-    }
-
diff --git a/wxPython/tools/XRCed/xrced.ico b/wxPython/tools/XRCed/xrced.ico
deleted file mode 100644 (file)
index 6c9964d..0000000
Binary files a/wxPython/tools/XRCed/xrced.ico and /dev/null differ
diff --git a/wxPython/tools/XRCed/xrced.py b/wxPython/tools/XRCed/xrced.py
deleted file mode 100644 (file)
index 503c1b1..0000000
+++ /dev/null
@@ -1,1918 +0,0 @@
-# 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()
diff --git a/wxPython/tools/XRCed/xrced.sh b/wxPython/tools/XRCed/xrced.sh
deleted file mode 100644 (file)
index 70f983b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-python2.2 YOUR_PATH_TO_XRCED/xrced.py $*
diff --git a/wxPython/tools/XRCed/xrced.xrc b/wxPython/tools/XRCed/xrced.xrc
deleted file mode 100644 (file)
index a407461..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-<?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
diff --git a/wxPython/tools/XRCed/xxx.py b/wxPython/tools/XRCed/xxx.py
deleted file mode 100644 (file)
index cf141ee..0000000
+++ /dev/null
@@ -1,712 +0,0 @@
-# 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)
-
diff --git a/wxPython/tools/img2img.py b/wxPython/tools/img2img.py
deleted file mode 100644 (file)
index dbefc26..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-"""
-Common routines for the image converter utilities.
-"""
-import sys, os, glob, getopt, string
-from wxPython.wx import *
-
-wxInitAllImageHandlers()
-
-def convert(file, maskClr, outputDir, outputName, outType, outExt):
-    if string.lower(os.path.splitext(file)[1]) == ".ico":
-        icon = wxIcon(file, wxBITMAP_TYPE_ICO)
-        img = wxBitmapFromIcon(icon)
-    else:
-        img = wxBitmap(file, wxBITMAP_TYPE_ANY)
-
-    if not img.Ok():
-        return 0, file + " failed to load!"
-    else:
-        if maskClr:
-            om = img.GetMask()
-            mask = wxMaskColour(img, maskClr)
-            img.SetMask(mask)
-            if om is not None:
-                om.Destroy()
-        if outputName:
-            newname = outputName
-        else:
-            newname = os.path.join(outputDir,
-                                   os.path.basename(os.path.splitext(file)[0]) + outExt)
-        if img.SaveFile(newname, outType):
-            return 1, file + " converted to " + newname
-        else:
-            img = wxImageFromBitmap(img)
-            if img.SaveFile(newname, outType):
-                return 1, "ok"
-            else:
-                return 0, file + " failed to save!"
-
-
-
-
-def main(args, outType, outExt, doc):
-    if not args or ("-h" in args):
-        print doc
-        return
-
-    outputDir = ""
-    maskClr = None
-    outputName = None
-
-    try:
-        opts, fileArgs = getopt.getopt(args, "m:n:o:")
-    except getopt.GetoptError:
-        print __doc__
-        return
-
-    for opt, val in opts:
-        if opt == "-m":
-            maskClr = val
-        elif opt == "-n":
-            outputName = val
-        elif opt == "-o":
-            outputDir = val
-
-    if not fileArgs:
-        print doc
-        return
-
-    for arg in fileArgs:
-        for file in glob.glob(arg):
-            if not os.path.isfile(file):
-                continue
-            ok, msg = convert(file, maskClr, outputDir, outputName,
-                              outType, outExt)
-            print msg
-
diff --git a/wxPython/tools/img2png.py b/wxPython/tools/img2png.py
deleted file mode 100644 (file)
index aea14f2..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-"""
-img2png.py  -- convert several image formats to PNG format
-
-Usage:
-
-    img2png.py [options] image_files...
-
-Options:
-
-    -o <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__)
-
-
diff --git a/wxPython/tools/img2py.py b/wxPython/tools/img2py.py
deleted file mode 100644 (file)
index 21957dc..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-#!/usr/bin/env python
-"""
-img2py.py  --  Convert an image to PNG format and embed it in a Python
-               module with appropriate code so it can be loaded into
-               a program at runtime.  The benefit is that since it is
-               Python source code it can be delivered as a .pyc or
-               'compiled' into the program using freeze, py2exe, etc.
-
-Usage:
-
-    img2py.py [options] image_file python_file
-
-Options:
-
-    -m <#rrggbb>   If the original image has a mask or transparency defined
-                   it will be used by default.  You can use this option to
-                   override the default or provide a new mask by specifying
-                   a colour in the image to mark as transparent.
-
-    -n <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:])
-
diff --git a/wxPython/tools/img2xpm.py b/wxPython/tools/img2xpm.py
deleted file mode 100644 (file)
index e6da69e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-"""
-img2xpm.py  -- convert several image formats to XPM
-
-Usage:
-
-    img2xpm.py [options] image_files...
-
-Options:
-
-    -o <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__)
-
-
index b28b04f643122b019e912540f228c8ed20be9eeb..54e9b268d85896d7c2a293457a98e6eaf36051df 100644 (file)
@@ -1,3 +1,4 @@
+#
 
 
 
diff --git a/wxPython/wxPython/tools/XRCed/CHANGES b/wxPython/wxPython/tools/XRCed/CHANGES
new file mode 100644 (file)
index 0000000..89b20ff
--- /dev/null
@@ -0,0 +1,74 @@
+0.0.7
+-----
+
+Some command-line arguments.
+
+"Test window" command and toolbar button.
+
+New panel interphace (wxHTMLWindow is not used anymore).
+
+Toggling between embedded and detached panel.
+
+Cache for already used windows.
+
+Current top-level control is bold, if test window shown.
+
+Undo/redo broken.
+
+CheckListBox does not work unless wxXRC source fixed (in both wxPytnon and
+wxWin):
+
+contrib/src/xrc/xmlrsall.cpp
+45,46c45,46
+<     AddHandler(new wxListCtrlXmlHandler);
+< #if CHECKLISTBOX
+---
+>     AddHandler(new wxListCtrlXmlHandler);    
+> #if wxUSE_CHECKLISTBOX
+
+
+0.0.6
+-----
+
+Toolbar, bitmap, icon support (no display yet).
+
+Changed parameter objects, added support for multiple parameters (like 
+`growablecols').
+
+Fixed double-clicking problem with tree control on Windows.
+
+Some performance improovements.
+
+
+0.0.5
+-----
+
+Added notebook with properties page and style page. Fixed some problems
+on Windows.
+
+
+0.0.4
+-----
+
+Some fixes suggested by RD
+
+
+0.0.3
+-----
+
+Faster preview window refresh.
+
+Cut/Paste works better.
+
+Some tree icons.
+
+Tree item names.
+
+Bugfixes.
+
+
+0.0.2
+-----
+
+The first release.
+
diff --git a/wxPython/wxPython/tools/XRCed/README b/wxPython/wxPython/tools/XRCed/README
new file mode 100644 (file)
index 0000000..133ee2a
--- /dev/null
@@ -0,0 +1,72 @@
+********************************************************************************
+
+                                 XRCed README
+
+********************************************************************************
+
+Installation on UNIX
+--------------------
+
+XRCed requires wxGTK and wxPython greater than 2.3.2, and Python 2.2 (it may
+work with earlier version, but was not tested).
+
+Of course wxGTK's XRC library (libwxxrc) must be installed.
+
+Installation on Windows
+-----------------------
+
+Works with wxPython 2.3.2 for Python 2.2.
+
+Short manual
+------------
+
+XRCed's idea is very straightforward: it is a visual tool for editing an XML
+file conforming to XRC format. Every operation performed in XRCed has direct
+correspondence to XML structure. So it is not really a usual point-and-click
+GUI builder, but don't let that scare you.
+
+To start xrced, change to the directory where you installed it and run
+"python2.2 xrced.py".
+
+On UNIX you can edit wrapper script "xrced.sh" to point to your installation
+directory.
+
+To create an object, first you should select some object in the tree (or the
+root item if it's empty) then press the right mouse button and select an
+appropriate command. The pulldown menu is context-dependent on the selected
+object.
+
+XRCed tries to guess if new object should be added as a next sibling or a
+child of current object, depending on the possibility of the object to have
+child objects and expanded state (if tree item is collapsed, new object will
+be sibling). You can change this behavior to create siblings by pressing and
+holding the Shift and Control keys before clicking the mouse.
+
+Pressed Control key while pressing right button makes next item a sibling of
+selected item regardless of its expanded state.
+
+Pressed Shift key changes the place for inserting new child to be before
+selected child, not after as by default.
+
+Panel on the right contains object properties. Properties which are optional
+should be "checked" first. This panel can be made separate by unchecking
+"Embed Panel" in View menu.
+
+All properties can be edited as text, and some are supplied with special
+editing controls.
+
+The names of the properties are exactly as in XRC file, and it's usually not
+hard to guess what they do. XML ID is the name of the window, and must be
+present for top-level windows (though this is not enforced by XRCed).
+
+To display the preview window double-click a top-level object (you should
+assign an XMLID to it first), press "Test" toolbar button or select command
+from View menu, or press F5. After that, if you select a child object, it
+becomes highlighted, and if you change it, preview is updated when you select
+another item or press Ctrl-R (refresh). To turn off automatic update, toggle
+"View->Auto-refresh" or toolbar auto-refresh button (to the right of the
+refresh button).
+
+--------------------------------------------------------------------------------
+
+Copyright 2001 Roman Rolinsky <rolinsky@mema.ucl.ac.be>
diff --git a/wxPython/wxPython/tools/XRCed/TODO b/wxPython/wxPython/tools/XRCed/TODO
new file mode 100644 (file)
index 0000000..4b9cc1b
--- /dev/null
@@ -0,0 +1,29 @@
+TODO for XRCed
+==============
+
+- Undo/Redo
+
+- menu - accel not displayed in preview
+
++ tree icons
+
+- replace object with another, keeping children
+
++ write tmp file for current dialog/panel/etc.
+
++ XML indents
+
+? select same notebook pages after update
+
+- put some default values in tree ctrl etc.
+
+- special (fast) update for some values: pos/size, value/content, sizeritem
+  stuff (?), well, as much as possible
+
+- highlighting with better method
+
+- import XRC/WXR files
+
++ disable some window creation when it's not valid
+
+- check for memory leaks from wx objects
diff --git a/wxPython/wxPython/tools/XRCed/__init__.py b/wxPython/wxPython/tools/XRCed/__init__.py
new file mode 100644 (file)
index 0000000..54e9b26
--- /dev/null
@@ -0,0 +1,4 @@
+#
+
+
+
diff --git a/wxPython/wxPython/tools/XRCed/images.py b/wxPython/wxPython/tools/XRCed/images.py
new file mode 100644 (file)
index 0000000..924c55d
--- /dev/null
@@ -0,0 +1,368 @@
+#----------------------------------------------------------------------
+# This file was generated by img2py.py
+#
+from wxPython.wx import wxBitmapFromXPMData, wxImageFromBitmap
+import cPickle, zlib
+
+
+def getIconData():
+    return cPickle.loads(zlib.decompress(
+'x\xda\x9d\x90\xbb\x0e\xc20\x0cEw\xbe\xc2\x12C\x91"Y-\xa2\x82\xd1\x80\xd45C\
+\x97\xac\x88\x11\xa4\xf0\xff\x13\xd7Nh\xa0\xcd\x00\xb8y\xf4\xe6\xf8\x95l\xee\
+\x8fn56\xdb\x1da\xec\xa9kV\x97\xb1\tt\xa5\xd3\xfdr\xbd\x99b\xa8\xf5\xf1\xa0\
+\x9fi\xa7\xba\x85\rI\xcb\x8bg\x1dU\xf7m\xbf\xeb[\xd3\xfe\xa53\'\xd5\xc3a8O\
+\xban_@\x0eL10\x07X\xc4iL[\x8e\x8c\x81 \xe1\xc3\xea\x17\xd4/NPct\x85{0N\xcc\
+\xa5f\xb4\x83\x94\xd6|\xde\x1b\xb2"\x9a\x16\x05\xe6\x10\x81\x08\xe5\x9cZ\x1d\
+K\xcd\xd4\xed\x04-}\xb9\n\n\x12\xdb\xb0\x99\x0e\xe8\x8f\x17\xf2N~\x81\xe2}"^\
+\x16\xd0;\x18\xce\x9c\xcb?oP\x9c\xc7t\xf0\xb1\xfd\x13Z&,9z\x0eS:\x04/\x1bB:\
+\x81Q\x15jM4Z\xaf\x99\xba\xf4\xf5n\xed\x9e\x92\xef)B\x7f\xbem\x81\xfc\x04\
+\x8f\xd5\x99\xcc' ))
+
+def getIconBitmap():
+    return wxBitmapFromXPMData(getIconData())
+
+def getIconImage():
+    return wxImageFromBitmap(getIconBitmap())
+
+#----------------------------------------------------------------------
+def getNewData():
+    return cPickle.loads(zlib.decompress(
+"x\xda\xd3\xc8)0\xe4\nV72Q02V0Q0T\xe7J\x0cV\xd7SHVp\xcaIL\xce\x06\xf3\xf2\
+\x81<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())
+
diff --git a/wxPython/wxPython/tools/XRCed/params.py b/wxPython/wxPython/tools/XRCed/params.py
new file mode 100644 (file)
index 0000000..319034e
--- /dev/null
@@ -0,0 +1,722 @@
+# 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,
+    }
+
diff --git a/wxPython/wxPython/tools/XRCed/xrced.ico b/wxPython/wxPython/tools/XRCed/xrced.ico
new file mode 100644 (file)
index 0000000..6c9964d
Binary files /dev/null and b/wxPython/wxPython/tools/XRCed/xrced.ico differ
diff --git a/wxPython/wxPython/tools/XRCed/xrced.py b/wxPython/wxPython/tools/XRCed/xrced.py
new file mode 100644 (file)
index 0000000..0584f63
--- /dev/null
@@ -0,0 +1,1930 @@
+# 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()
diff --git a/wxPython/wxPython/tools/XRCed/xrced.sh b/wxPython/wxPython/tools/XRCed/xrced.sh
new file mode 100644 (file)
index 0000000..70f983b
--- /dev/null
@@ -0,0 +1 @@
+python2.2 YOUR_PATH_TO_XRCED/xrced.py $*
diff --git a/wxPython/wxPython/tools/XRCed/xrced.xrc b/wxPython/wxPython/tools/XRCed/xrced.xrc
new file mode 100644 (file)
index 0000000..a407461
--- /dev/null
@@ -0,0 +1,235 @@
+<?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
diff --git a/wxPython/wxPython/tools/XRCed/xxx.py b/wxPython/wxPython/tools/XRCed/xxx.py
new file mode 100644 (file)
index 0000000..cf141ee
--- /dev/null
@@ -0,0 +1,712 @@
+# 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)
+
diff --git a/wxPython/wxPython/tools/__init__.py b/wxPython/wxPython/tools/__init__.py
new file mode 100644 (file)
index 0000000..54e9b26
--- /dev/null
@@ -0,0 +1,4 @@
+#
+
+
+
diff --git a/wxPython/wxPython/tools/img2img.py b/wxPython/wxPython/tools/img2img.py
new file mode 100644 (file)
index 0000000..dbefc26
--- /dev/null
@@ -0,0 +1,76 @@
+"""
+Common routines for the image converter utilities.
+"""
+import sys, os, glob, getopt, string
+from wxPython.wx import *
+
+wxInitAllImageHandlers()
+
+def convert(file, maskClr, outputDir, outputName, outType, outExt):
+    if string.lower(os.path.splitext(file)[1]) == ".ico":
+        icon = wxIcon(file, wxBITMAP_TYPE_ICO)
+        img = wxBitmapFromIcon(icon)
+    else:
+        img = wxBitmap(file, wxBITMAP_TYPE_ANY)
+
+    if not img.Ok():
+        return 0, file + " failed to load!"
+    else:
+        if maskClr:
+            om = img.GetMask()
+            mask = wxMaskColour(img, maskClr)
+            img.SetMask(mask)
+            if om is not None:
+                om.Destroy()
+        if outputName:
+            newname = outputName
+        else:
+            newname = os.path.join(outputDir,
+                                   os.path.basename(os.path.splitext(file)[0]) + outExt)
+        if img.SaveFile(newname, outType):
+            return 1, file + " converted to " + newname
+        else:
+            img = wxImageFromBitmap(img)
+            if img.SaveFile(newname, outType):
+                return 1, "ok"
+            else:
+                return 0, file + " failed to save!"
+
+
+
+
+def main(args, outType, outExt, doc):
+    if not args or ("-h" in args):
+        print doc
+        return
+
+    outputDir = ""
+    maskClr = None
+    outputName = None
+
+    try:
+        opts, fileArgs = getopt.getopt(args, "m:n:o:")
+    except getopt.GetoptError:
+        print __doc__
+        return
+
+    for opt, val in opts:
+        if opt == "-m":
+            maskClr = val
+        elif opt == "-n":
+            outputName = val
+        elif opt == "-o":
+            outputDir = val
+
+    if not fileArgs:
+        print doc
+        return
+
+    for arg in fileArgs:
+        for file in glob.glob(arg):
+            if not os.path.isfile(file):
+                continue
+            ok, msg = convert(file, maskClr, outputDir, outputName,
+                              outType, outExt)
+            print msg
+
diff --git a/wxPython/wxPython/tools/img2png.py b/wxPython/wxPython/tools/img2png.py
new file mode 100644 (file)
index 0000000..76e7f6d
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+"""
+img2png.py  -- convert several image formats to PNG format
+
+Usage:
+
+    img2png.py [options] image_files...
+
+Options:
+
+    -o <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()
+
+
+
diff --git a/wxPython/wxPython/tools/img2py.py b/wxPython/wxPython/tools/img2py.py
new file mode 100644 (file)
index 0000000..21957dc
--- /dev/null
@@ -0,0 +1,190 @@
+#!/usr/bin/env python
+"""
+img2py.py  --  Convert an image to PNG format and embed it in a Python
+               module with appropriate code so it can be loaded into
+               a program at runtime.  The benefit is that since it is
+               Python source code it can be delivered as a .pyc or
+               'compiled' into the program using freeze, py2exe, etc.
+
+Usage:
+
+    img2py.py [options] image_file python_file
+
+Options:
+
+    -m <#rrggbb>   If the original image has a mask or transparency defined
+                   it will be used by default.  You can use this option to
+                   override the default or provide a new mask by specifying
+                   a colour in the image to mark as transparent.
+
+    -n <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:])
+
diff --git a/wxPython/wxPython/tools/img2xpm.py b/wxPython/wxPython/tools/img2xpm.py
new file mode 100644 (file)
index 0000000..2b9a995
--- /dev/null
@@ -0,0 +1,37 @@
+#!/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()
+
+
+