Putting draft of wxImplDC and the wxDC using it
[wxWidgets.git] / wxPython / wx / tools / XRCed / xxx.py
index 1ee0ffa5a37a2abebf0ede07e68e7f71f2925d25..147240efc1335e9c9dae973e42095a27e6e9307c 100644 (file)
@@ -191,7 +191,7 @@ class xxxObject:
     hasName = True                      # has name attribute?
     isSizer = hasChild = False
     isElement = True
     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
     # Style parameters (all optional)
     styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip']
     # Special parameters
@@ -315,6 +315,16 @@ class xxxObject:
         else: obj = self
         obj.name = name
         obj.node.setAttribute('name', name)
         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):
     # Special processing for growablecols-like parameters
     # represented by several nodes
     def special(self, tag, node):
@@ -837,7 +847,8 @@ class xxxChildContainer(xxxObject):
 class xxxSizerItem(xxxChildContainer):
     allParams = ['option', 'flag', 'border', 'minsize', 'ratio']
     paramDict = {'option': ParamInt, 'minsize': ParamPosSize, 'ratio': ParamPosSize}
 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):
     def __init__(self, parent, element, refElem=None):
         # For GridBag sizer items, extra parameters added
         if isinstance(parent, xxxGridBagSizer):
@@ -919,10 +930,16 @@ class xxxUnknown(xxxObject):
 ################################################################################
 # Comment
 
 ################################################################################
 # 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):
 
 def register(hndlr):
+    """Register hndlr function or XmlResourceHandler class."""
     if _CFuncPtr and isinstance(hndlr, _CFuncPtr):
         _handlers.append(hndlr)
         return
     if _CFuncPtr and isinstance(hndlr, _CFuncPtr):
         _handlers.append(hndlr)
         return
@@ -934,24 +951,36 @@ def register(hndlr):
         _handlers.append(hndlr)
 
 def load_dl(path, localname=''):
         _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
     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')
     except ImportError:
         wx.LogError('ctypes module not found')
+        globals()[localname] = None
         return
     try:
         dl = ctypes.CDLL(path)
         return
     try:
         dl = ctypes.CDLL(path)
-        if not localname:
-            localname = os.path.basename(os.path.splitext(dl._name)[0])
         globals()[localname] = dl
         globals()[localname] = dl
+        # Register AddXmlHandlers() if exists
+        try:
+            register(dl.AddXmlHandlers)
+        except:
+            pass
     except:
     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
         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:
     for h in _handlers:
         if _CFuncPtr and isinstance(h, _CFuncPtr):
             try:
@@ -961,24 +990,57 @@ def addHandlers(res):
                 print traceback.print_exc()
         else:
             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()
 
             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):
 
 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
     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:]
             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()
             except:
                 wx.LogError('exec error: "%s"' % code)
                 print traceback.print_exc()
@@ -1002,6 +1064,7 @@ class xxxComment(xxxObject):
 
 ################################################################################
 
 
 ################################################################################
 
+# Mapping of XRC names to xxx classes
 xxxDict = {
     'wxPanel': xxxPanel,
     'wxDialog': xxxDialog,
 xxxDict = {
     'wxPanel': xxxPanel,
     'wxDialog': xxxDialog,
@@ -1137,7 +1200,8 @@ def MakeEmptyDOM(className):
 def MakeEmptyXXX(parent, className):
     # Make corresponding DOM object first
     elem = MakeEmptyDOM(className)
 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)
     if parent:
         if parent.isSizer and className != 'spacer':
             sizerItemElem = MakeEmptyDOM(parent.itemTag)
@@ -1156,7 +1220,16 @@ def MakeEmptyXXX(parent, className):
             pageElem.appendChild(elem)
             elem = pageElem
     # Now just make object
             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):
 
 # Make empty DOM element for reference
 def MakeEmptyRefDOM(ref):