]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/wxpTag.py
newevent module now returns a PyEventBinder instead of a function
[wxWidgets.git] / wxPython / wx / 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 types
93
94 #----------------------------------------------------------------------
95
96 WXPTAG = 'WXP'
97 PARAMTAG = 'PARAM'
98
99 #----------------------------------------------------------------------
100
101 class wxpTagHandler(wxHtmlWinTagHandler):
102 def __init__(self):
103 wxHtmlWinTagHandler.__init__(self)
104 self.ctx = None
105
106 def GetSupportedTags(self):
107 return WXPTAG+','+PARAMTAG
108
109
110 def HandleTag(self, tag):
111 name = tag.GetName()
112 if name == WXPTAG:
113 return self.HandleWxpTag(tag)
114 elif name == PARAMTAG:
115 return self.HandleParamTag(tag)
116 else:
117 raise ValueError, 'unknown tag: ' + name
118
119
120 def HandleWxpTag(self, tag):
121 # create a new context object
122 self.ctx = _Context()
123
124 # find and import the module
125 modName = ''
126 if tag.HasParam('MODULE'):
127 modName = tag.GetParam('MODULE')
128 if modName:
129 self.ctx.classMod = _my_import(modName)
130 else:
131 self.ctx.classMod = wxPython.wx
132
133 # find and verify the class
134 if not tag.HasParam('CLASS'):
135 raise AttributeError, "WXP tag requires a CLASS attribute"
136
137 className = tag.GetParam('CLASS')
138 self.ctx.classObj = getattr(self.ctx.classMod, className)
139 if type(self.ctx.classObj) not in [ types.ClassType, types.TypeType]:
140 raise TypeError, "WXP tag attribute CLASS must name a class"
141
142 # now look for width and height
143 width = -1
144 height = -1
145 if tag.HasParam('WIDTH'):
146 width = tag.GetParam('WIDTH')
147 if width[-1] == '%':
148 self.ctx.floatWidth = int(width[:-1], 0)
149 width = self.ctx.floatWidth
150 else:
151 width = int(width)
152 if tag.HasParam('HEIGHT'):
153 height = int(tag.GetParam('HEIGHT'))
154 self.ctx.kwargs['size'] = wxSize(width, height)
155
156 # parse up to the closing tag, and gather any nested Param tags.
157 self.ParseInner(tag)
158
159 # create the object
160 parent = self.GetParser().GetWindow()
161 if parent:
162 obj = apply(self.ctx.classObj,
163 (parent,),
164 self.ctx.kwargs)
165 obj.Show(True)
166
167 # add it to the HtmlWindow
168 self.GetParser().GetContainer().InsertCell(wxHtmlWidgetCell(obj, self.ctx.floatWidth))
169 self.ctx = None
170
171 return True
172
173
174 def HandleParamTag(self, tag):
175 if not tag.HasParam('NAME'):
176 return False
177
178 name = tag.GetParam('NAME')
179 value = ""
180 if tag.HasParam('VALUE'):
181 value = tag.GetParam('VALUE')
182
183 # check for a param named 'id'
184 if name == 'id':
185 theID = -1
186 try:
187 theID = int(value)
188 except ValueError:
189 theID = getattr(self.ctx.classMod, value)
190 value = theID
191
192
193 # check for something that should be evaluated
194 elif value[0] in '[{(' or value[:2] == 'wx':
195 saveVal = value
196 try:
197 value = eval(value, self.ctx.classMod.__dict__)
198 except:
199 value = saveVal
200
201 # convert to wxColour
202 elif value[0] == '#':
203 try:
204 red = int('0x'+value[1:3], 16)
205 green = int('0x'+value[3:5], 16)
206 blue = int('0x'+value[5:], 16)
207 value = wxColor(red, green, blue)
208 except:
209 pass
210
211 self.ctx.kwargs[str(name)] = value
212 return False
213
214
215 #----------------------------------------------------------------------
216 # just a place to hold some values
217 class _Context:
218 def __init__(self):
219 self.kwargs = {}
220 self.width = -1
221 self.height = -1
222 self.classMod = None
223 self.classObj = None
224 self.floatWidth = 0
225
226
227 #----------------------------------------------------------------------
228 # Function to assist with importing packages
229 def _my_import(name):
230 mod = __import__(name)
231 components = name.split('.')
232 for comp in components[1:]:
233 mod = getattr(mod, comp)
234 return mod
235
236
237 #----------------------------------------------------------------------
238 # Function to parse a param string (of the form 'item=value item2="value etc"'
239 # and creates a dictionary
240 def _param2dict(param):
241 i = 0; j = 0; s = len(param); d = {}
242 while 1:
243 while i<s and param[i] == " " : i = i+1
244 if i>=s: break
245 j = i
246 while j<s and param[j] != "=": j=j+1
247 if j+1>=s:
248 break
249 word = param[i:j]
250 i=j+1
251 if (param[i] == '"'):
252 j=i+1
253 while j<s and param[j] != '"' : j=j+1
254 if j == s: break
255 val = param[i+1:j]
256 elif (param[i] != " "):
257 j=i+1
258 while j<s and param[j] != " " : j=j+1
259 val = param[i:j]
260 else:
261 val = ""
262 i=j+1
263 d[word] = val
264 return d
265
266 #----------------------------------------------------------------------
267
268
269
270 wxHtmlWinParser_AddTagHandler(wxpTagHandler)