hasName = True # has name attribute?
isSizer = hasChild = False
isElement = True
- allParams = None # Some nodes have no parameters
+ allParams = [] # Some nodes have no parameters
# Style parameters (all optional)
styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip']
# Special parameters
else: obj = self
obj.name = name
obj.node.setAttribute('name', name)
+ # Set normal (text) params
+ def set(self, param, value):
+ try:
+ self.params[param].update(value)
+ except KeyError:
+ elem = g.tree.dom.createElement(param)
+ p = xxxParam(elem)
+ p.update(value)
+ self.params[param] = p
+ self.node.appendChild(elem)
# Special processing for growablecols-like parameters
# represented by several nodes
def special(self, tag, node):
class xxxSizerItem(xxxChildContainer):
allParams = ['option', 'flag', 'border', 'minsize', 'ratio']
paramDict = {'option': ParamInt, 'minsize': ParamPosSize, 'ratio': ParamPosSize}
- #default = {'cellspan': '1,1'}
+ defaults_panel = {}
+ defaults_control = {}
def __init__(self, parent, element, refElem=None):
# For GridBag sizer items, extra parameters added
if isinstance(parent, xxxGridBagSizer):
################################################################################
# Comment
-_handlers = []
-_CFuncPtr = None
+_handlers = [] # custom handler classes/funcs
+def getHandlers():
+ return _handlers
+def setHandlers(handlers):
+ global _handlers
+ _handlers = handlers
+_CFuncPtr = None # ctypes function type
def register(hndlr):
+ """Register hndlr function or XmlResourceHandler class."""
if _CFuncPtr and isinstance(hndlr, _CFuncPtr):
_handlers.append(hndlr)
return
_handlers.append(hndlr)
def load_dl(path, localname=''):
+ """Load shared/dynamic library into xxx namespace.
+
+ If path is not absolute or relative, try to find in the module's directory.
+ """
+ if not localname:
+ localname = os.path.basename(os.path.splitext(path)[0])
try:
import ctypes
global _CFuncPtr
- _CFuncPtr = ctypes._CFuncPtr
+ _CFuncPtr = ctypes._CFuncPtr # use as a flag of loaded ctypes
+ #if not os.path.dirname(path) and os.path.isfile(path):
+
except ImportError:
wx.LogError('ctypes module not found')
+ globals()[localname] = None
return
try:
dl = ctypes.CDLL(path)
- if not localname:
- localname = os.path.basename(os.path.splitext(dl._name)[0])
globals()[localname] = dl
+ # Register AddXmlHandlers() if exists
+ try:
+ register(dl.AddXmlHandlers)
+ except:
+ pass
except:
- wx.LogError('error loading dynamic library: %s', path)
+ wx.LogError('error loading dynamic library: %s' % path)
print traceback.print_exc()
# Called when creating test window
-def addHandlers(res):
+def addHandlers():
for h in _handlers:
if _CFuncPtr and isinstance(h, _CFuncPtr):
try:
print traceback.print_exc()
else:
try:
- res.AddHandler(apply(h, ()))
+ xrc.XmlResource.Get().AddHandler(apply(h, ()))
except:
wx.LogError('error adding XmlHandler: "%s"' % h)
print traceback.print_exc()
-def clearHandlers():
- global _handlers
- _handlers = []
+def custom(klassName, klass='unknown'):
+ """Define custom control based on xrcClass.
+
+ klass: new object name
+ xrcClass: name of an existing XRC object class or
+ a class object defining class parameters.
+ """
+ if type(klass) is str:
+ # Copy correct xxx class under new name
+ kl = xxxDict[klass]
+ xxxClass = types.ClassType('xxx' + klassName, kl.__bases__, kl.__dict__)
+ else:
+ xxxClass = klass
+ # Register param IDs
+ for param in klass.allParams + klass.paramDict.keys():
+ if not paramIDs.has_key(param):
+ paramIDs[param] = wx.NewId()
+ # Insert in dictionaty
+ xxxDict[klassName] = xxxClass
+ # Add to menu
+ 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()
################################################################################
+# Mapping of XRC names to xxx classes
xxxDict = {
'wxPanel': xxxPanel,
'wxDialog': xxxDialog,
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
+ # Special handling, e.g. if parent is a sizer, we should create
+ # sizeritem object, except for spacers, etc.
if parent:
if parent.isSizer and className != 'spacer':
sizerItemElem = MakeEmptyDOM(parent.itemTag)
pageElem.appendChild(elem)
elem = pageElem
# Now just make object
- return MakeXXXFromDOM(parent, elem)
+ xxx = MakeXXXFromDOM(parent, elem)
+ # Special defaults for new panels and controls
+ if isinstance(xxx, xxxSizerItem):
+ if isinstance(xxx.child, xxxContainer) and not xxx.child.isSizer:
+ for param,v in xxxSizerItem.defaults_panel.items():
+ xxx.set(param, v)
+ elif isinstance(xxx.child, xxxObject):
+ for param,v in xxxSizerItem.defaults_control.items():
+ xxx.set(param, v)
+ return xxx
# Make empty DOM element for reference
def MakeEmptyRefDOM(ref):