Module fixedwxpTag
[hide private]
[frames] | no frames]

Source Code for Module fixedwxpTag

  1  # This file has been modified from the original from the wxPython 
  2  # distribution and remains under that license 
  3  # 
  4  #  - uses the 'import wx' style naming 
  5  #  - you can use other modules to get the values in the id tag 
  6  #    (in the library version you have to get it from the same module 
  7  #     as you get the widget from) 
  8  # 
  9  # Hopefully this issue can be fixed in the wxPython code and this 
 10  # file removed 
 11   
 12  #---------------------------------------------------------------------- 
 13  # Name:        wxPython.lib.wxpTag 
 14  # Purpose:     A wxHtmlTagHandler that knows how to build and place 
 15  #              wxPython widgets onto web pages. 
 16  # 
 17  # Author:      Robin Dunn 
 18  # 
 19  # Created:     13-Sept-1999 
 20  # RCS-ID:      $Id: fixedwxpTag.py 1527 2004-08-25 08:00:32Z rogerb $ 
 21  # Copyright:   (c) 1999 by Total Control Software 
 22  # Licence:     wxWindows license 
 23  #---------------------------------------------------------------------- 
 24   
 25  ''' 
 26  wxPython.lib.wxpTag 
 27   
 28  This module contains a wxHtmlTagHandler that knows how to build 
 29  and place wxPython widgets onto wxHtmlWindow web pages. 
 30   
 31  You don\'t need to use anything in this module directly, just 
 32  importing it will create the tag handler and add it to any 
 33  wxHtmlWinParsers created from that time forth. 
 34   
 35  Tags of the following form are recognised: 
 36   
 37      <WXP class="classname" [module="modulename"] [width="num"] [height="num"]> 
 38          <PARAM name="parameterName" value="parameterValue> 
 39          ... 
 40      </WXP> 
 41   
 42  where modulename is the name of a module (possibly in package 
 43  notation) to import and classname is the name of a class in that 
 44  module to create an instance of.  If the module tag-attribute is not 
 45  given or is an empty string, then wxPython.wx is used.  The width and 
 46  height attributes are expected to be integers and will be passed to 
 47  the __init__ method of the class as a wxSize object named size. 
 48  However, if the width attribute ends with the percent (%) symbol then 
 49  the value will be used as a percentage of the available width and the 
 50  wxHtmlWindow will manage the size. 
 51   
 52  The name-value pairs in all the nested PARAM tags are packaged up as 
 53  strings into a python dictionary and passed to the __init__ method of 
 54  the class as keyword arguments.  This means that they are all 
 55  accessible from the __init__ method as regular parameters, or you use 
 56  the special Python **kw syntax in your __init__ method to get the 
 57  dictionary directly. 
 58   
 59  Some parameter values are special and if they are present then they will 
 60  be converted from strings to alternate datatypes.  They are: 
 61   
 62      id           If the value of id can be converted to an integer, it will 
 63                   be.  Otherwise it is assumed to be the name of an integer 
 64                   variable in the module. 
 65   
 66      colours      Any value of the form "#123ABC" will automatically be 
 67                   converted to a wxColour object. 
 68   
 69      Py Types     Any value begining with "(", "[" or "{" are expected to 
 70                   be a Python tuple, list, or dictionary and eval() 
 71                   will be used to convert them to that type.  If the 
 72                   eval() fails then the original string value will be 
 73                   preserved. 
 74   
 75      wx Types     Any value begining with "wx" is expected to be an attempt 
 76                   to create a wxPython object, such as a wxSize, etc. 
 77                   The eval() will be used to try and construct the 
 78                   object and if it fails then the original string value 
 79                   will be used instead. 
 80   
 81  An example: 
 82   
 83      <wxp module="" class="wxButton"> 
 84          <param name="label" value="Click here"> 
 85          <param name="id" value="wxID_OK"> 
 86      </wxp> 
 87   
 88  Both the begining and ending WXP tags are required. 
 89   
 90  In the future support will be added for another tag that can be 
 91  embedded between the two begining and ending WXP tags and will 
 92  facilitate calling methods of the widget to help initialize it. 
 93  Additionally, support may be added to fetch the module from a web 
 94  server as is done with java applets. 
 95   
 96  ''' 
 97  #---------------------------------------------------------------------- 
 98   
 99  import wx 
100  import wx.html 
101   
102  import types 
103   
104  import common 
105   
106  #---------------------------------------------------------------------- 
107   
108  WXPTAG   = 'WXP' 
109  PARAMTAG = 'PARAM' 
110   
111  #---------------------------------------------------------------------- 
112   
113 -class wxpTagHandler(wx.html.HtmlWinTagHandler):
114 - def __init__(self):
115 wx.html.HtmlWinTagHandler.__init__(self) 116 self.ctx = None
117
118 - def GetSupportedTags(self):
119 return WXPTAG+','+PARAMTAG
120 121
122 - def HandleTag(self, tag):
123 name = tag.GetName() 124 if name == WXPTAG: 125 return self.HandleWxpTag(tag) 126 elif name == PARAMTAG: 127 return self.HandleParamTag(tag) 128 else: 129 raise ValueError, 'unknown tag: ' + name
130 131
132 - def HandleWxpTag(self, tag):
133 # create a new context object 134 self.ctx = _Context() 135 136 # find and import the module 137 modName = '' 138 if tag.HasParam('MODULE'): 139 modName = tag.GetParam('MODULE') 140 if modName: 141 self.ctx.classMod = _my_import(modName) 142 else: 143 self.ctx.classMod = wx 144 145 # find and verify the class 146 if not tag.HasParam('CLASS'): 147 raise AttributeError, "WXP tag requires a CLASS attribute" 148 149 className = tag.GetParam('CLASS') 150 self.ctx.classObj = getattr(self.ctx.classMod, className) 151 if type(self.ctx.classObj) not in ( types.ClassType, types.TypeType): 152 raise TypeError, "WXP tag attribute CLASS must name a class" 153 154 # now look for width and height 155 width = -1 156 height = -1 157 if tag.HasParam('WIDTH'): 158 width = tag.GetParam('WIDTH') 159 if width[-1] == '%': 160 self.ctx.floatWidth = int(width[:-1], 0) 161 width = self.ctx.floatWidth 162 else: 163 width = int(width) 164 if tag.HasParam('HEIGHT'): 165 height = int(tag.GetParam('HEIGHT')) 166 self.ctx.kwargs['size'] = wx.Size(width, height) 167 168 # parse up to the closing tag, and gather any nested Param tags. 169 self.ParseInner(tag) 170 171 # create the object 172 parent = self.GetParser().GetWindow() 173 if parent: 174 obj = apply(self.ctx.classObj, 175 (parent,), 176 self.ctx.kwargs) 177 obj.Show(True) 178 179 # add it to the HtmlWindow 180 self.GetParser().GetContainer().InsertCell(wx.html.HtmlWidgetCell(obj, self.ctx.floatWidth)) 181 self.ctx = None 182 183 return True
184 185
186 - def HandleParamTag(self, tag):
187 if not tag.HasParam('NAME'): 188 return False 189 190 name = tag.GetParam('NAME') 191 value = "" 192 if tag.HasParam('VALUE'): 193 value = tag.GetParam('VALUE') 194 195 # check for a param named 'id' 196 if name == 'id': 197 theID = -1 198 try: 199 theID = int(value) 200 except ValueError: 201 theID = _getidvalue(self.ctx.classMod, value) 202 value = theID 203 204 205 # check for something that should be evaluated 206 elif value[0] in '[{(' or value[:2] == 'wx': 207 saveVal = value 208 try: 209 value = eval(value, self.ctx.classMod.__dict__) 210 except: 211 value = saveVal 212 # do things the hard way 213 214 # convert to wxColour 215 elif value[0] == '#': 216 try: 217 red = int('0x'+value[1:3], 16) 218 green = int('0x'+value[3:5], 16) 219 blue = int('0x'+value[5:], 16) 220 value = wx.Color(red, green, blue) 221 except: 222 pass 223 224 self.ctx.kwargs[str(name)] = value 225 return False
226 227 228 #---------------------------------------------------------------------- 229 # just a place to hold some values
230 -class _Context:
231 - def __init__(self):
232 self.kwargs = {} 233 self.width = -1 234 self.height = -1 235 self.classMod = None 236 self.classObj = None 237 self.floatWidth = 0
238 239 240 #---------------------------------------------------------------------- 241 # Function to assist with importing packages
242 -def _my_import(name):
243 mod = __import__(name) 244 components = name.split('.') 245 for comp in components[1:]: 246 mod = getattr(mod, comp) 247 return mod
248
249 -def _getidvalue(defaultmodule, name):
250 # try name by itself 251 try: 252 return eval(name) 253 except NameError: 254 pass 255 # ok, try to get it from the module 256 try: 257 return getattr(defaultmodule, name) 258 except AttributeError: 259 pass 260 return common.getfullname(name)
261 262 #---------------------------------------------------------------------- 263 # Function to parse a param string (of the form 'item=value item2="value etc"' 264 # and creates a dictionary
265 -def _param2dict(param):
266 i = 0; j = 0; s = len(param); d = {} 267 while 1: 268 while i<s and param[i] == " " : i = i+1 269 if i>=s: break 270 j = i 271 while j<s and param[j] != "=": j=j+1 272 if j+1>=s: 273 break 274 word = param[i:j] 275 i=j+1 276 if (param[i] == '"'): 277 j=i+1 278 while j<s and param[j] != '"' : j=j+1 279 if j == s: break 280 val = param[i+1:j] 281 elif (param[i] != " "): 282 j=i+1 283 while j<s and param[j] != " " : j=j+1 284 val = param[i:j] 285 else: 286 val = "" 287 i=j+1 288 d[word] = val 289 return d
290 291 #---------------------------------------------------------------------- 292 293 294 295 wx.html.HtmlWinParser_AddTagHandler(wxpTagHandler) 296