diff --git a/wxPython/wx/tools/XRCed/CHANGES.txt b/wxPython/wx/tools/XRCed/CHANGES.txt
index 9936ba3cb6..212c61507f 100644
--- a/wxPython/wx/tools/XRCed/CHANGES.txt
+++ b/wxPython/wx/tools/XRCed/CHANGES.txt
@@ -1,8 +1,27 @@
-0.1.8-5
+0.1.8-5 (under construction)
-------
-Implemented comment object for simple one-line comments. No
-validation is performed.
+Preferences for default "sizeritem" parameters for new panels and
+controls can be configured ("File">"Preferences...").
+
+Implemented comment object for including simple one-line comments and
+comment directives as tree nodes. No validation is performed for a
+valid XML string so comments must not contain "-->". Comment directive
+is a special comment starting with '%' character, followed by a line
+of python code. It is executed using 'exec' when the resource file is
+opened. This is useful to import plugin modules containing custom
+handlers which are specific to the resource file, hovewer this is of
+course a security hole if you use foreign XRC files. A warning is
+displayed if the preference option 'ask' is selected (by default).
+
+Added support for custom controls and plugin modules. Refer to this
+wxPythonWiki for the details:
+ http://wiki.wxpython.org/index.cgi/XRCed#custom
+
+Tool panel sections can be collapsed/expanded by clicking on the
+label of a tool group.
+
+Some undo/redo and other fixes.
0.1.8-4
-------
diff --git a/wxPython/wx/tools/XRCed/xrced.py b/wxPython/wx/tools/XRCed/xrced.py
index c41e9592cc..c2a5b36daf 100644
--- a/wxPython/wx/tools/XRCed/xrced.py
+++ b/wxPython/wx/tools/XRCed/xrced.py
@@ -484,6 +484,7 @@ class Frame(wx.Frame):
if dlg.FindWindowById(id).IsChecked():
d[p] = str(c.GetValue())
elif p in d: del d[p]
+ g.conf.allowExec = ('ask', 'yes', 'no')[dlg.radio_allow_exec.GetSelection()]
dlg.Destroy()
def OnExit(self, evt):
@@ -1396,6 +1397,8 @@ Homepage: http://xrced.sourceforge.net\
g.pullDownMenu.custom = self.custom[:]
# Remove modules imported from comment directives
map(sys.modules.pop, [m for m in sys.modules if m not in self.modules])
+ xxxParamComment.locals = {} # clear local namespace
+ xxxParamComment.allow = None # clear execution state
def SetModified(self, state=True):
self.modified = state
@@ -1513,9 +1516,6 @@ Homepage: http://xrced.sourceforge.net\
return True
return False
- def SaveUndo(self):
- pass # !!!
-
################################################################################
class PythonOptions(wx.Dialog):
@@ -1632,6 +1632,13 @@ class PrefsDialog(wx.Dialog):
except KeyError:
c.Enable(False)
+ self.radio_allow_exec = xrc.XRCCTRL(self, 'radio_allow_exec')
+ try:
+ radio = {'ask': 0, 'yes':1, 'no':2}[g.conf.allowExec]
+ except KeyError:
+ radio = 0
+ self.radio_allow_exec.SetSelection(radio)
+
def OnCheck(self, evt):
self.checkControls[evt.GetId()][0].Enable(evt.IsChecked())
evt.Skip()
@@ -1707,6 +1714,7 @@ Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion)
conf.panelHeight = conf.ReadInt('panelHeight', 200)
conf.panic = not conf.HasEntry('nopanic')
# Preferences
+ conf.allowExec = conf.Read('Prefs/allowExec', 'ask')
p = 'Prefs/sizeritem_defaults_panel'
if conf.HasEntry(p):
sys.modules['xxx'].xxxSizerItem.defaults_panel = ReadDictFromString(conf.Read(p))
@@ -1770,14 +1778,16 @@ Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion)
wc.WriteInt('sashPos', conf.sashPos)
wc.WriteInt('panelWidth', conf.panelWidth)
wc.WriteInt('panelHeight', conf.panelHeight)
- wc.WriteInt('nopanic', True)
+ wc.WriteInt('nopanic', 1)
wc.Write('recentFiles', '|'.join(conf.recentfiles.values()[-5:]))
# Preferences
wc.DeleteGroup('Prefs')
+ wc.Write('Prefs/allowExec', conf.allowExec)
v = sys.modules['xxx'].xxxSizerItem.defaults_panel
if v: wc.Write('Prefs/sizeritem_defaults_panel', DictToString(v))
v = sys.modules['xxx'].xxxSizerItem.defaults_control
if v: wc.Write('Prefs/sizeritem_defaults_control', DictToString(v))
+
wc.Flush()
def main():
diff --git a/wxPython/wx/tools/XRCed/xrced.xrc b/wxPython/wx/tools/XRCed/xrced.xrc
index 29601a4f97..14b4191e19 100644
--- a/wxPython/wx/tools/XRCed/xrced.xrc
+++ b/wxPython/wx/tools/XRCed/xrced.xrc
@@ -677,6 +677,18 @@
wxALL5
+
0,10
diff --git a/wxPython/wx/tools/XRCed/xxx.py b/wxPython/wx/tools/XRCed/xxx.py
index de19e8910b..39d44271c2 100644
--- a/wxPython/wx/tools/XRCed/xxx.py
+++ b/wxPython/wx/tools/XRCed/xxx.py
@@ -1023,14 +1023,29 @@ def custom(klassName, klass='unknown'):
g.pullDownMenu.addCustom(klassName)
class xxxParamComment(xxxParam):
+ locals = {} # namespace for comment directives
+ allow = None # undefined initial state for current file
def __init__(self, node):
xxxNode.__init__(self, node)
self.textNode = node
- # Parse "pragma" comments
- if node.data and node.data[0] == '%':
+ # Parse "pragma" comments if enabled
+ if node.data and node.data[0] == '%' and g.conf.allowExec != 'no' and \
+ xxxParamComment.allow is not False:
+ # Show warning
+ if g.conf.allowExec == 'ask' and xxxParamComment.allow is None:
+ flags = wx.ICON_EXCLAMATION | wx.YES_NO | wx.CENTRE
+ dlg = wx.MessageDialog(g.frame, '''
+This file contains executable %comment directives. Allow to execute?''',
+ 'Warning', flags)
+ say = dlg.ShowModal()
+ dlg.Destroy()
+ if say == wx.ID_YES:
+ xxxParamComment.allow = True
+ else:
+ xxxParamComment.allow = False
try:
code = node.data[1:]
- exec code in globals()
+ exec code in globals(), self.locals
except:
wx.LogError('exec error: "%s"' % code)
print traceback.print_exc()