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