]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/wxpTag.py
Workaround the lack of a wx.EVT_FIND_CLOSE on Windows when doing a
[wxWidgets.git] / wxPython / wx / lib / wxpTag.py
index 03fca45e9e0a8c1db637f39e0efc3cd09f483d7c..5de374e9901b52bb7433bf408f823681ce709da3 100644 (file)
+#----------------------------------------------------------------------
+# Name:        wxPython.lib.wxpTag
+# Purpose:     A wxHtmlTagHandler that knows how to build and place
+#              wxPython widgets onto web pages.
+#
+# Author:      Robin Dunn
+#
+# Created:     13-Sept-1999
+# RCS-ID:      $Id$
+# Copyright:   (c) 1999 by Total Control Software
+# Licence:     wxWindows license
+#----------------------------------------------------------------------
+# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for V2.5 compatability
+#
 
-"""Renamer stub: provides a way to drop the wx prefix from wxPython objects."""
+'''
+wxPython.lib.wxpTag
 
-__cvsid__ = "$Id$"
-__revision__ = "$Revision$"[11:-2]
+This module contains a wxHtmlTagHandler that knows how to build
+and place wxPython widgets onto wxHtmlWindow web pages.
 
-from wx import _rename
-from wxPython.lib import wxpTag
-_rename(globals(), wxpTag.__dict__, modulename='lib.wxpTag')
-del wxpTag
-del _rename
+You don\'t need to use anything in this module directly, just
+importing it will create the tag handler and add it to any
+wxHtmlWinParsers created from that time forth.
+
+Tags of the following form are recognised:
+
+    <WXP class="classname" [module="modulename"] [width="num"] [height="num"]>
+        <PARAM name="parameterName" value="parameterValue>
+        ...
+    </WXP>
+
+where modulename is the name of a module (possibly in package
+notation) to import and classname is the name of a class in that
+module to create an instance of.  If the module tag-attribute is not
+given or is an empty string, then wx is used.  The width and height
+attributes are expected to be integers and will be passed to the
+__init__ method of the class as a wxSize object named size.  However,
+if the width attribute ends with the percent (%) symbol then the value
+will be used as a percentage of the available width and the
+wxHtmlWindow will manage the size.
+
+The name-value pairs in all the nested PARAM tags are packaged up as
+strings into a python dictionary and passed to the __init__ method of
+the class as keyword arguments.  This means that they are all
+accessible from the __init__ method as regular parameters, or you use
+the special Python **kw syntax in your __init__ method to get the
+dictionary directly.
+
+Some parameter values are special and if they are present then they will
+be converted from strings to alternate datatypes.  They are:
+
+    id           If the value of id can be converted to an integer, it will
+                 be.  Otherwise it is assumed to be the name of an integer
+                 variable in the module.
+
+    colours      Any value of the form "#123ABC" will automatically be
+                 converted to a wxColour object.
+
+    Py Types     Any value begining with "(", "[" or "{" are expected to
+                 be a Python tuple, list, or dictionary and eval()
+                 will be used to convert them to that type.  If the
+                 eval() fails then the original string value will be
+                 preserved.
+
+    wx Types     Any value begining with "wx" is expected to be an attempt
+                 to create a wxPython object, such as a wxSize, etc.
+                 The eval() will be used to try and construct the
+                 object and if it fails then the original string value
+                 will be used instead.
+
+An example:
+
+    <wxp module="wx" class="Button">
+        <param name="label" value="Click here">
+        <param name="id" value="ID_OK">
+    </wxp>
+
+Both the begining and ending WXP tags are required.
+
+In the future support will be added for another tag that can be
+embedded between the two begining and ending WXP tags and will
+facilitate calling methods of the widget to help initialize it.
+Additionally, support may be added to fetch the module from a web
+server as is done with java applets.
+
+'''
+#----------------------------------------------------------------------
+
+import  types
+
+import  wx
+import  wx.html
+
+
+#----------------------------------------------------------------------
+
+WXPTAG   = 'WXP'
+PARAMTAG = 'PARAM'
+
+#----------------------------------------------------------------------
+
+class wxpTagHandler(wx.html.HtmlWinTagHandler):
+    def __init__(self):
+        wx.html.HtmlWinTagHandler.__init__(self)
+        self.ctx = None
+
+    def GetSupportedTags(self):
+        return WXPTAG+','+PARAMTAG
+
+
+    def HandleTag(self, tag):
+        name = tag.GetName()
+        if name == WXPTAG:
+            return self.HandleWxpTag(tag)
+        elif name == PARAMTAG:
+            return self.HandleParamTag(tag)
+        else:
+            raise ValueError, 'unknown tag: ' + name
+
+
+    def HandleWxpTag(self, tag):
+        # create a new context object
+        self.ctx = _Context()
+
+        # find and import the module
+        modName = ''
+        if tag.HasParam('MODULE'):
+            modName = tag.GetParam('MODULE')
+        if modName:
+            self.ctx.classMod = _my_import(modName)
+        else:
+            self.ctx.classMod = wx
+
+        # find and verify the class
+        if not tag.HasParam('CLASS'):
+            raise AttributeError, "WXP tag requires a CLASS attribute"
+
+        className = tag.GetParam('CLASS')
+        self.ctx.classObj = getattr(self.ctx.classMod, className)
+        if type(self.ctx.classObj) not in [ types.ClassType, types.TypeType]:
+            raise TypeError, "WXP tag attribute CLASS must name a class"
+
+        # now look for width and height
+        width = -1
+        height = -1
+        if tag.HasParam('WIDTH'):
+            width = tag.GetParam('WIDTH')
+            if width[-1] == '%':
+                self.ctx.floatWidth = int(width[:-1], 0)
+                width = self.ctx.floatWidth
+            else:
+                width = int(width)
+        if tag.HasParam('HEIGHT'):
+            height = int(tag.GetParam('HEIGHT'))
+        self.ctx.kwargs['size'] = wx.Size(width, height)
+
+        # parse up to the closing tag, and gather any nested Param tags.
+        self.ParseInner(tag)
+
+        # create the object
+        parent = self.GetParser().GetWindow()
+        if parent:
+            obj = apply(self.ctx.classObj,
+                        (parent,),
+                        self.ctx.kwargs)
+            obj.Show(True)
+
+            # add it to the HtmlWindow
+            self.GetParser().GetContainer().InsertCell(
+                wx.html.HtmlWidgetCell(obj, self.ctx.floatWidth))
+            self.ctx = None
+
+        return True
+
+
+    def HandleParamTag(self, tag):
+        if not tag.HasParam('NAME'):
+            return False
+
+        name = tag.GetParam('NAME')
+        value = ""
+        if tag.HasParam('VALUE'):
+            value = tag.GetParam('VALUE')
+
+        # check for a param named 'id'
+        if name == 'id':
+            theID = -1
+            try:
+                theID = int(value)
+            except ValueError:
+                theID = getattr(self.ctx.classMod, value)
+            value = theID
+
+
+        # check for something that should be evaluated
+        elif value and value[0] in '[{(' or value[:2] == 'wx':
+            saveVal = value
+            try:
+                value = eval(value, self.ctx.classMod.__dict__)
+            except:
+                value = saveVal
+
+        # convert to wx.Colour
+        elif value and value[0] == '#':
+            try:
+                red   = int('0x'+value[1:3], 16)
+                green = int('0x'+value[3:5], 16)
+                blue  = int('0x'+value[5:], 16)
+                value = wx.Color(red, green, blue)
+            except:
+                pass
+
+        if self.ctx:
+          self.ctx.kwargs[str(name)] = value
+        return False
+
+
+#----------------------------------------------------------------------
+# just a place to hold some values
+class _Context:
+    def __init__(self):
+        self.kwargs = {}
+        self.width = -1
+        self.height = -1
+        self.classMod = None
+        self.classObj = None
+        self.floatWidth = 0
+
+
+#----------------------------------------------------------------------
+# Function to assist with importing packages
+def _my_import(name):
+    mod = __import__(name)
+    components = name.split('.')
+    for comp in components[1:]:
+        mod = getattr(mod, comp)
+    return mod
+
+
+#----------------------------------------------------------------------
+# Function to parse a param string (of the form 'item=value item2="value etc"'
+# and creates a dictionary
+def _param2dict(param):
+    i = 0; j = 0; s = len(param); d = {}
+    while 1:
+        while i<s and param[i] == " " : i = i+1
+        if i>=s: break
+        j = i
+        while j<s and param[j] != "=": j=j+1
+        if j+1>=s:
+            break
+        word = param[i:j]
+        i=j+1
+        if (param[i] == '"'):
+            j=i+1
+            while j<s and param[j] != '"' : j=j+1
+            if j == s: break
+            val = param[i+1:j]
+        elif (param[i] != " "):
+            j=i+1
+            while j<s and param[j] != " " : j=j+1
+            val = param[i:j]
+        else:
+            val = ""
+        i=j+1
+        d[word] = val
+    return d
+
+#----------------------------------------------------------------------
+
+
+
+wx.html.HtmlWinParser_AddTagHandler(wxpTagHandler)