1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
|
#----------------------------------------------------------------------
# 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
#
'''
wx.lib.wxpTag
This module contains a wxHtmlTagHandler that knows how to build
and place wxPython widgets onto wxHtmlWindow web pages.
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().GetWindowInterface().GetHTMLWindow()
if parent:
obj = 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.Colour(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
#----------------------------------------------------------------------
# Add our handler class to the collection of tag handlers maintained
# by wxWidgets.
wx.html.HtmlWinParser_AddTagHandler(wxpTagHandler)
|