]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/tools/XRCed/xxx.py
searching for plugins in XRCEDPATH
[wxWidgets.git] / wxPython / wx / tools / XRCed / xxx.py
index 4144307da09fcdc6e2d46ffa353916a4f16e57b7..cdbc54c0307f7d8166e83a75beefb7706709fa61 100644 (file)
@@ -7,6 +7,7 @@
 from xml.dom import minidom
 from globals import *
 from params import *
+import traceback, types
 
 # Base class for interface parameter classes
 class xxxNode:
@@ -189,6 +190,7 @@ class xxxObject:
     hasStyle = True                     # almost everyone
     hasName = True                      # has name attribute?
     isSizer = hasChild = False
+    isElement = True
     allParams = None                    # Some nodes have no parameters
     # Style parameters (all optional)
     styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip']
@@ -210,7 +212,7 @@ class xxxObject:
     # parent is parent xxx object (or None if none), element is DOM element object
     def __init__(self, parent, element, refElem=None):
         self.parent = parent
-        self.element = element
+        self.node = element
         self.refElem = refElem
         self.undo = None
         # Reference are dereferenced
@@ -230,33 +232,32 @@ class xxxObject:
         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
+        for n in element.childNodes[:]:
+            if n.nodeType == minidom.Node.ELEMENT_NODE:
+                tag = n.tagName
                 if tag in ['object', 'object_ref']:
                     continue            # do nothing for object children here
                 elif tag not in self.allParams and tag not in self.styles:
                     print 'WARNING: unknown parameter for %s: %s' % \
                           (self.className, tag)
                 elif tag in self.specials:
-                    self.special(tag, node)
+                    self.special(tag, n)
                 elif tag == 'content':
                     if self.className == 'wxCheckListBox':
-                        self.params[tag] = xxxParamContentCheckList(node)
+                        self.params[tag] = xxxParamContentCheckList(n)
                     else:
-                        self.params[tag] = xxxParamContent(node)
+                        self.params[tag] = xxxParamContent(n)
                 elif tag == 'font': # has children
-                    self.params[tag] = xxxParamFont(element, node)
+                    self.params[tag] = xxxParamFont(element, n)
                 elif tag in self.bitmapTags:
                     # Can have attributes
-                    self.params[tag] = xxxParamBitmap(node)
+                    self.params[tag] = xxxParamBitmap(n)
                 else:                   # simple parameter
-                    self.params[tag] = xxxParam(node)
-            elif node.nodeType == minidom.Node.TEXT_NODE and node.data.isspace():
+                    self.params[tag] = xxxParam(n)
+            elif n.nodeType == minidom.Node.TEXT_NODE and n.data.isspace():
                 # Remove empty text nodes
-                element.removeChild(node)
-                node.unlink()
+                element.removeChild(n)
+                n.unlink()
 
         # Check that all required params are set
         for param in self.required:
@@ -281,9 +282,9 @@ class xxxObject:
                             break
                     if found:
                         nextTextElem = self.params[p].node
-                        self.element.insertBefore(elem, nextTextElem)
+                        self.node.insertBefore(elem, nextTextElem)
                     else:
-                        self.element.appendChild(elem)
+                        self.node.appendChild(elem)
                 else:
                     wx.LogWarning('Required parameter %s of %s missing' %
                                  (param, self.className))
@@ -313,7 +314,24 @@ class xxxObject:
         if self.hasChild: obj = self.child
         else: obj = self
         obj.name = name
-        obj.element.setAttribute('name', name)
+        obj.node.setAttribute('name', name)
+    # Special processing for growablecols-like parameters
+    # represented by several nodes
+    def special(self, tag, node):
+        if not self.params.has_key(tag):
+            # Create new multi-group
+            self.params[tag] = xxxParamMulti(node)
+        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 = g.tree.dom.createElement(param)
+            text = g.tree.dom.createTextNode(str(i))
+            node.appendChild(text)
+            self.node.appendChild(node)
+            self.special(param, node)
 
 # Imitation of FindResource/DoFindResource from xmlres.cpp
 def DoFindResource(parent, name, classname, recursive):
@@ -360,7 +378,7 @@ class xxxParamFont(xxxObject, xxxNode):
         self.data = v
     def update(self, value):
         # `value' is a list of strings corresponding to all parameters
-        elem = self.element
+        elem = self.node
         # Remove old elements first
         childNodes = elem.childNodes[:]
         for node in childNodes: elem.removeChild(node)
@@ -638,6 +656,16 @@ class xxxDateCtrl(xxxObject):
     winStyles = ['wxDP_DEFAULT', 'wxDP_SPIN', 'wxDP_DROPDOWN',
                  'wxDP_ALLOWNONE', 'wxDP_SHOWCENTURY']
 
+class xxxGrid(xxxObject):
+    allParams = ['pos', 'size', 'style']
+
+class xxxFilePickerCtrl(xxxObject):
+    allParams = ['value', 'message', 'wildcard', 'pos', 'size', 'style']
+    winStyles = ['wxFLP_OPEN', 'wxFLP_SAVE', 'wxFLP_OVERWRITE_PROMPT',
+                 'wxFLP_FILE_MUST_EXIST', 'wxFLP_CHANGE_DIR',
+                 'wxFLP_DEFAULT_STYLE']
+
+
 ################################################################################
 # Buttons
 
@@ -771,45 +799,11 @@ 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 not self.params.has_key(tag):
-            # Create new multi-group
-            self.params[tag] = xxxParamMulti(node)
-        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 = g.tree.dom.createElement(param)
-            text = g.tree.dom.createTextNode(str(i))
-            node.appendChild(text)
-            self.element.appendChild(node)
-            self.special(param, node)
 
 class xxxGridBagSizer(xxxSizer):
     specials = ['growablecols', 'growablerows']
     allParams = ['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 not self.params.has_key(tag):
-            # Create new multi-group
-            self.params[tag] = xxxParamMulti(node)
-        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 = g.tree.dom.createElement(param)
-            text = g.tree.dom.createTextNode(str(i))
-            node.appendChild(text)
-            self.element.appendChild(node)
-            self.special(param, node)
+    paramDict = {'growablecols': ParamIntList, 'growablerows': ParamIntList}
 
 # Container with only one child.
 # Not shown in tree.
@@ -923,7 +917,128 @@ class xxxUnknown(xxxObject):
     winStyles = ['wxNO_FULL_REPAINT_ON_RESIZE']
 
 ################################################################################
+# Comment
+
+_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
+    if not isinstance(hndlr, type):
+        wx.LogError('handler is not a type: %s' % hndlr)
+    elif not issubclass(hndlr, wx.xrc.XmlResourceHandler):
+        wx.LogError('handler is not a XmlResourceHandler: %s' % hndlr)
+    else:
+        _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    # 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)
+        globals()[localname] = dl
+        # Register AddXmlHandlers() if exists
+        try:
+            register(dl.AddXmlHandlers)
+        except:
+            pass
+    except:
+        wx.LogError('error loading dynamic library: %s' % path)
+        print traceback.print_exc()
+
+# Called when creating test window
+def addHandlers():
+    for h in _handlers:
+        if _CFuncPtr and isinstance(h, _CFuncPtr):
+            try:
+                apply(h, ())
+            except:
+                wx.LogError('error calling DL func: "%s"' % h)
+                print traceback.print_exc()
+        else:
+            try:
+                xrc.XmlResource.Get().AddHandler(apply(h, ()))
+            except:
+                wx.LogError('error adding XmlHandler: "%s"' % h)
+                print traceback.print_exc()
+
+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):
+    def __init__(self, node):
+        xxxNode.__init__(self, node)
+        self.textNode = node
+        # Parse "pragma" comments
+        if node.data and node.data[0] == '%':
+            try:
+                code = node.data[1:]
+                exec code in globals()
+            except:
+                wx.LogError('exec error: "%s"' % code)
+                print traceback.print_exc()
+
+class xxxComment(xxxObject):
+    hasStyle = hasName = False
+    allParams = required = ['comment']
+    
+    def __init__(self, parent, node):
+        self.parent = parent
+        self.node = node
+        self.isElement = False
+        self.undo = None
+        self.className = 'comment'
+        self.ref = self.subclass = None
+        self.params = {'comment': xxxParamComment(node)}
+        
+    def treeName(self):
+        # Replace newlines by \n to avoid tree item resizing
+        return self.params['comment'].value().replace('\n', r'\n')
+
+################################################################################
+
+# Mapping of XRC names to xxx classes
 xxxDict = {
     'wxPanel': xxxPanel,
     'wxDialog': xxxDialog,
@@ -973,6 +1088,8 @@ xxxDict = {
     'wxGenericDirCtrl': xxxGenericDirCtrl,
     'wxSpinCtrl': xxxSpinCtrl,
     'wxScrolledWindow': xxxScrolledWindow,
+    'wxGrid': xxxGrid,
+    'wxFilePickerCtrl': xxxFilePickerCtrl,
     'wxDatePickerCtrl': xxxDateCtrl,
 
     'wxBoxSizer': xxxBoxSizer,
@@ -990,13 +1107,15 @@ xxxDict = {
     'separator': xxxSeparator,
 
     'unknown': xxxUnknown,
+    'comment': xxxComment,
     }
 
 # Create IDs for all parameters of all classes
 paramIDs = {'fg': wx.NewId(), 'bg': wx.NewId(), 'exstyle': wx.NewId(), 'font': wx.NewId(),
             'enabled': wx.NewId(), 'focused': wx.NewId(), 'hidden': wx.NewId(),
             'tooltip': wx.NewId(), 'encoding': wx.NewId(),
-            'cellpos': wx.NewId(), 'cellspan': wx.NewId()
+            'cellpos': wx.NewId(), 'cellspan': wx.NewId(),
+            'text': wx.NewId()
             }
 for cl in xxxDict.values():
     if cl.allParams:
@@ -1009,25 +1128,29 @@ for cl in xxxDict.values():
 
 # Test for object elements
 def IsObject(node):
-    return node.nodeType == minidom.Node.ELEMENT_NODE and node.tagName in ['object', 'object_ref']
+    return node.nodeType == minidom.Node.ELEMENT_NODE and \
+           node.tagName in ['object', 'object_ref'] or \
+           node.nodeType == minidom.Node.COMMENT_NODE
 
 # Make XXX object from some DOM object, selecting correct class
-def MakeXXXFromDOM(parent, element):
-    if element.tagName == 'object_ref':
-        ref = element.getAttribute('ref')
+def MakeXXXFromDOM(parent, node):
+    if node.nodeType == minidom.Node.COMMENT_NODE:
+        return xxxComment(parent, node)
+    if node.tagName == 'object_ref':
+        ref = node.getAttribute('ref')
         refElem = FindResource(ref)
         if refElem: cls = refElem.getAttribute('class')
-        else: return xxxUnknown(parent, element)
+        else: return xxxUnknown(parent, node)
     else:
         refElem = None
-        cls = element.getAttribute('class')
+        cls = node.getAttribute('class')
     try:
         klass = xxxDict[cls]
     except KeyError:
         # If we encounter a weird class, use unknown template
-        print 'WARNING: unsupported class:', element.getAttribute('class')
+        print 'WARNING: unsupported class:', node.getAttribute('class')
         klass = xxxUnknown
-    return klass(parent, element, refElem)
+    return klass(parent, node, refElem)
 
 # Make empty DOM element
 def MakeEmptyDOM(className):
@@ -1107,3 +1230,15 @@ def MakeEmptyRefXXX(parent, ref):
     #xxx.allParams.remove('label')
     return xxx
 
+# Make empty comment node
+def MakeEmptyCommentDOM():
+    node = g.tree.dom.createComment('')
+    return node
+
+# Make empty xxxComment
+def MakeEmptyCommentXXX(parent):
+    node = MakeEmptyCommentDOM()
+    # Now just make object
+    xxx = MakeXXXFromDOM(parent, node)
+    return xxx
+