]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/wxpTag.py
8dbb7109d4ab910ac16e91e7534f395f9237b1be
[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 print 'wxpTagHandler'
104 wxHtmlWinTagHandler.__init__(self)
105 self.ctx = None
106
107 def GetSupportedTags(self):
108 print 'wxpTagHandler.GetSupportedTags'
109 return WXPTAG+','+PARAMTAG
110
111
112 def HandleTag(self, tag):
113 print 'wxpTagHandler.HandleTag'
114 name = tag.GetName()
115 if name == WXPTAG:
116 return self.HandleWxpTag(tag)
117 elif name == PARAMTAG:
118 return self.HandleParamTag(tag)
119 else:
120 raise ValueError, 'unknown tag: ' + name
121
122
123 def HandleWxpTag(self, tag):
124 # create a new context object
125 self.ctx = _Context()
126
127 # find and import the module
128 modName = ''
129 if tag.HasParam('MODULE'):
130 modName = tag.GetParam('MODULE')
131 if modName:
132 self.ctx.classMod = _my_import(modName)
133 else:
134 self.ctx.classMod = wxPython.wx
135
136 # find and verify the class
137 if not tag.HasParam('CLASS'):
138 raise AttributeError, "WXP tag requires a CLASS attribute"
139
140 className = tag.GetParam('CLASS')
141 self.ctx.classObj = getattr(self.ctx.classMod, className)
142 if type(self.ctx.classObj) not in [ types.ClassType, types.TypeType]:
143 raise TypeError, "WXP tag attribute CLASS must name a class"
144
145 # now look for width and height
146 width = -1
147 height = -1
148 if tag.HasParam('WIDTH'):
149 width = tag.GetParam('WIDTH')
150 if width[-1] == '%':
151 self.ctx.floatWidth = int(width[:-1], 0)
152 width = self.ctx.floatWidth
153 else:
154 width = int(width)
155 if tag.HasParam('HEIGHT'):
156 height = int(tag.GetParam('HEIGHT'))
157 self.ctx.kwargs['size'] = wxSize(width, height)
158
159 # parse up to the closing tag, and gather any nested Param tags.
160 self.ParseInner(tag)
161
162 # create the object
163 parent = self.GetParser().GetWindow()
164 if parent:
165 obj = apply(self.ctx.classObj,
166 (parent,),
167 self.ctx.kwargs)
168 obj.Show(True)
169
170 # add it to the HtmlWindow
171 self.GetParser().GetContainer().InsertCell(wxHtmlWidgetCell(obj, self.ctx.floatWidth))
172 self.ctx = None
173
174 return True
175
176
177 def HandleParamTag(self, tag):
178 if not tag.HasParam('NAME'):
179 return False
180
181 name = tag.GetParam('NAME')
182 value = ""
183 if tag.HasParam('VALUE'):
184 value = tag.GetParam('VALUE')
185
186 # check for a param named 'id'
187 if name == 'id':
188 theID = -1
189 try:
190 theID = int(value)
191 except ValueError:
192 theID = getattr(self.ctx.classMod, value)
193 value = theID
194
195
196 # check for something that should be evaluated
197 elif value[0] in '[{(' or value[:2] == 'wx':
198 saveVal = value
199 try:
200 value = eval(value, self.ctx.classMod.__dict__)
201 except:
202 value = saveVal
203
204 # convert to wxColour
205 elif value[0] == '#':
206 try:
207 red = int('0x'+value[1:3], 16)
208 green = int('0x'+value[3:5], 16)
209 blue = int('0x'+value[5:], 16)
210 value = wxColor(red, green, blue)
211 except:
212 pass
213
214 self.ctx.kwargs[str(name)] = value
215 return False
216
217
218 #----------------------------------------------------------------------
219 # just a place to hold some values
220 class _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
232 def _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
243 def _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
273 wxHtmlWinParser_AddTagHandler(wxpTagHandler)