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