PyXR

c:\projects\bitpim\src \ fixedwxpTag.py



0001 # This file has been modified from the original from the wxPython
0002 # distribution and remains under that license
0003 #
0004 #  - uses the 'import wx' style naming
0005 #  - you can use other modules to get the values in the id tag
0006 #    (in the library version you have to get it from the same module
0007 #     as you get the widget from)
0008 #
0009 # Hopefully this issue can be fixed in the wxPython code and this
0010 # file removed
0011 
0012 #----------------------------------------------------------------------
0013 # Name:        wxPython.lib.wxpTag
0014 # Purpose:     A wxHtmlTagHandler that knows how to build and place
0015 #              wxPython widgets onto web pages.
0016 #
0017 # Author:      Robin Dunn
0018 #
0019 # Created:     13-Sept-1999
0020 # RCS-ID:      $Id: fixedwxpTag.py 1527 2004-08-25 08:00:32Z rogerb $
0021 # Copyright:   (c) 1999 by Total Control Software
0022 # Licence:     wxWindows license
0023 #----------------------------------------------------------------------
0024 
0025 '''
0026 wxPython.lib.wxpTag
0027 
0028 This module contains a wxHtmlTagHandler that knows how to build
0029 and place wxPython widgets onto wxHtmlWindow web pages.
0030 
0031 You don\'t need to use anything in this module directly, just
0032 importing it will create the tag handler and add it to any
0033 wxHtmlWinParsers created from that time forth.
0034 
0035 Tags of the following form are recognised:
0036 
0037     <WXP class="classname" [module="modulename"] [width="num"] [height="num"]>
0038         <PARAM name="parameterName" value="parameterValue>
0039         ...
0040     </WXP>
0041 
0042 where modulename is the name of a module (possibly in package
0043 notation) to import and classname is the name of a class in that
0044 module to create an instance of.  If the module tag-attribute is not
0045 given or is an empty string, then wxPython.wx is used.  The width and
0046 height attributes are expected to be integers and will be passed to
0047 the __init__ method of the class as a wxSize object named size.
0048 However, if the width attribute ends with the percent (%) symbol then
0049 the value will be used as a percentage of the available width and the
0050 wxHtmlWindow will manage the size.
0051 
0052 The name-value pairs in all the nested PARAM tags are packaged up as
0053 strings into a python dictionary and passed to the __init__ method of
0054 the class as keyword arguments.  This means that they are all
0055 accessible from the __init__ method as regular parameters, or you use
0056 the special Python **kw syntax in your __init__ method to get the
0057 dictionary directly.
0058 
0059 Some parameter values are special and if they are present then they will
0060 be converted from strings to alternate datatypes.  They are:
0061 
0062     id           If the value of id can be converted to an integer, it will
0063                  be.  Otherwise it is assumed to be the name of an integer
0064                  variable in the module.
0065 
0066     colours      Any value of the form "#123ABC" will automatically be
0067                  converted to a wxColour object.
0068 
0069     Py Types     Any value begining with "(", "[" or "{" are expected to
0070                  be a Python tuple, list, or dictionary and eval()
0071                  will be used to convert them to that type.  If the
0072                  eval() fails then the original string value will be
0073                  preserved.
0074 
0075     wx Types     Any value begining with "wx" is expected to be an attempt
0076                  to create a wxPython object, such as a wxSize, etc.
0077                  The eval() will be used to try and construct the
0078                  object and if it fails then the original string value
0079                  will be used instead.
0080 
0081 An example:
0082 
0083     <wxp module="" class="wxButton">
0084         <param name="label" value="Click here">
0085         <param name="id" value="wxID_OK">
0086     </wxp>
0087 
0088 Both the begining and ending WXP tags are required.
0089 
0090 In the future support will be added for another tag that can be
0091 embedded between the two begining and ending WXP tags and will
0092 facilitate calling methods of the widget to help initialize it.
0093 Additionally, support may be added to fetch the module from a web
0094 server as is done with java applets.
0095 
0096 '''
0097 #----------------------------------------------------------------------
0098 
0099 import wx
0100 import wx.html
0101 
0102 import types
0103 
0104 import common
0105 
0106 #----------------------------------------------------------------------
0107 
0108 WXPTAG   = 'WXP'
0109 PARAMTAG = 'PARAM'
0110 
0111 #----------------------------------------------------------------------
0112 
0113 class wxpTagHandler(wx.html.HtmlWinTagHandler):
0114     def __init__(self):
0115         wx.html.HtmlWinTagHandler.__init__(self)
0116         self.ctx = None
0117 
0118     def GetSupportedTags(self):
0119         return WXPTAG+','+PARAMTAG
0120 
0121 
0122     def HandleTag(self, tag):
0123         name = tag.GetName()
0124         if name == WXPTAG:
0125             return self.HandleWxpTag(tag)
0126         elif name == PARAMTAG:
0127             return self.HandleParamTag(tag)
0128         else:
0129             raise ValueError, 'unknown tag: ' + name
0130 
0131 
0132     def HandleWxpTag(self, tag):
0133         # create a new context object
0134         self.ctx = _Context()
0135 
0136         # find and import the module
0137         modName = ''
0138         if tag.HasParam('MODULE'):
0139             modName = tag.GetParam('MODULE')
0140         if modName:
0141             self.ctx.classMod = _my_import(modName)
0142         else:
0143             self.ctx.classMod = wx
0144 
0145         # find and verify the class
0146         if not tag.HasParam('CLASS'):
0147             raise AttributeError, "WXP tag requires a CLASS attribute"
0148 
0149         className = tag.GetParam('CLASS')
0150         self.ctx.classObj = getattr(self.ctx.classMod, className)
0151         if type(self.ctx.classObj) not in ( types.ClassType, types.TypeType):
0152             raise TypeError, "WXP tag attribute CLASS must name a class"
0153 
0154         # now look for width and height
0155         width = -1
0156         height = -1
0157         if tag.HasParam('WIDTH'):
0158             width = tag.GetParam('WIDTH')
0159             if width[-1] == '%':
0160                 self.ctx.floatWidth = int(width[:-1], 0)
0161                 width = self.ctx.floatWidth
0162             else:
0163                 width = int(width)
0164         if tag.HasParam('HEIGHT'):
0165             height = int(tag.GetParam('HEIGHT'))
0166         self.ctx.kwargs['size'] = wx.Size(width, height)
0167 
0168         # parse up to the closing tag, and gather any nested Param tags.
0169         self.ParseInner(tag)
0170 
0171         # create the object
0172         parent = self.GetParser().GetWindow()
0173         if parent:
0174             obj = apply(self.ctx.classObj,
0175                         (parent,),
0176                         self.ctx.kwargs)
0177             obj.Show(True)
0178 
0179             # add it to the HtmlWindow
0180             self.GetParser().GetContainer().InsertCell(wx.html.HtmlWidgetCell(obj, self.ctx.floatWidth))
0181             self.ctx = None
0182 
0183         return True
0184 
0185 
0186     def HandleParamTag(self, tag):
0187         if not tag.HasParam('NAME'):
0188             return False
0189 
0190         name = tag.GetParam('NAME')
0191         value = ""
0192         if tag.HasParam('VALUE'):
0193             value = tag.GetParam('VALUE')
0194 
0195         # check for a param named 'id'
0196         if name == 'id':
0197             theID = -1
0198             try:
0199                 theID = int(value)
0200             except ValueError:
0201                 theID = _getidvalue(self.ctx.classMod, value)
0202             value = theID
0203 
0204 
0205         # check for something that should be evaluated
0206         elif value[0] in '[{(' or value[:2] == 'wx':
0207             saveVal = value
0208             try:
0209                 value = eval(value, self.ctx.classMod.__dict__)
0210             except:
0211                 value = saveVal
0212          # do things the hard way
0213 
0214         # convert to wxColour
0215         elif value[0] == '#':
0216             try:
0217                 red   = int('0x'+value[1:3], 16)
0218                 green = int('0x'+value[3:5], 16)
0219                 blue  = int('0x'+value[5:], 16)
0220                 value = wx.Color(red, green, blue)
0221             except:
0222                 pass
0223 
0224         self.ctx.kwargs[str(name)] = value
0225         return False
0226 
0227 
0228 #----------------------------------------------------------------------
0229 # just a place to hold some values
0230 class _Context:
0231     def __init__(self):
0232         self.kwargs = {}
0233         self.width = -1
0234         self.height = -1
0235         self.classMod = None
0236         self.classObj = None
0237         self.floatWidth = 0
0238 
0239 
0240 #----------------------------------------------------------------------
0241 # Function to assist with importing packages
0242 def _my_import(name):
0243     mod = __import__(name)
0244     components = name.split('.')
0245     for comp in components[1:]:
0246         mod = getattr(mod, comp)
0247     return mod
0248 
0249 def _getidvalue(defaultmodule, name):
0250     # try name by itself
0251     try:
0252         return eval(name)
0253     except NameError:
0254         pass
0255     # ok, try to get it from the module
0256     try:
0257         return getattr(defaultmodule, name)
0258     except AttributeError:
0259         pass
0260     return common.getfullname(name)
0261     
0262 #----------------------------------------------------------------------
0263 # Function to parse a param string (of the form 'item=value item2="value etc"'
0264 # and creates a dictionary
0265 def _param2dict(param):
0266     i = 0; j = 0; s = len(param); d = {}
0267     while 1:
0268         while i<s and param[i] == " " : i = i+1
0269         if i>=s: break
0270         j = i
0271         while j<s and param[j] != "=": j=j+1
0272         if j+1>=s:
0273             break
0274         word = param[i:j]
0275         i=j+1
0276         if (param[i] == '"'):
0277             j=i+1
0278             while j<s and param[j] != '"' : j=j+1
0279             if j == s: break
0280             val = param[i+1:j]
0281         elif (param[i] != " "):
0282             j=i+1
0283             while j<s and param[j] != " " : j=j+1
0284             val = param[i:j]
0285         else:
0286             val = ""
0287         i=j+1
0288         d[word] = val
0289     return d
0290 
0291 #----------------------------------------------------------------------
0292 
0293 
0294 
0295 wx.html.HtmlWinParser_AddTagHandler(wxpTagHandler)
0296 

Generated by PyXR 0.9.4