]> git.saurik.com Git - wxWidgets.git/blame - wxPython/tools/XRCed/xxx.py
fixed typo (missing comma) in MIME test
[wxWidgets.git] / wxPython / tools / XRCed / xxx.py
CommitLineData
a40b5e84 1# Name: xxx.py ('xxx' is easy to distinguish from 'wx' :) )
09f3d4e6
RD
2# Purpose: XML interface classes
3# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
4# Created: 22.08.2001
a40b5e84 5# RCS-ID: $Id$
09f3d4e6
RD
6
7from wxPython.wx import *
8from wxPython.xrc import *
9from xml.dom import minidom
10import wxPython.lib.wxpTag
11
12from params import *
13
32ce09e2
RD
14# Parameter value class
15class xxxParam:
16 # Standard use: for text nodes
17 def __init__(self, node):
18 self.node = node
19 if not node.hasChildNodes():
20 # If does not have child nodes, create empty text node
21 text = tree.dom.createTextNode('')
22 node.appendChild(text)
23 else:
24 text = node.childNodes[0] # first child must be text node
25 assert text.nodeType == minidom.Node.TEXT_NODE
26 self.textNode = text
27 # Value returns string
28 def value(self):
18fc9fa3 29 return self.textNode.data
32ce09e2
RD
30 def update(self, value):
31 self.textNode.data = value
32 def remove(self):
33 self.node.parentNode.removeChild(self.node)
34 self.node.unlink()
35
18fc9fa3
RD
36# Integer parameter
37class xxxParamInt(xxxParam):
38 # Standard use: for text nodes
39 def __init__(self, node):
40 xxxParam.__init__(self, node)
41 # Value returns string
42 def value(self):
43 try:
44 return int(self.textNode.data)
45 except ValueError:
46 return -1 # invalid value
47 def update(self, value):
48 self.textNode.data = str(value)
49
32ce09e2
RD
50# Content parameter
51class xxxParamContent:
52 def __init__(self, node):
53 self.node = node
54 data, l = [], [] # data is needed to quicker value retrieval
55 nodes = node.childNodes[:] # make a copy of the child list
56 for n in nodes:
57 if n.nodeType == minidom.Node.ELEMENT_NODE:
58 assert n.tagName == 'item', 'bad content content'
59 if not n.hasChildNodes():
60 # If does not have child nodes, create empty text node
61 text = tree.dom.createTextNode('')
62 node.appendChild(text)
63 else:
64 # !!! normalize?
65 text = n.childNodes[0] # first child must be text node
66 assert text.nodeType == minidom.Node.TEXT_NODE
67 l.append(text)
f0c20d94 68 data.append(str(text.data))
32ce09e2
RD
69 else: # remove other
70 node.removeChild(n)
71 n.unlink()
72 self.l, self.data = l, data
73 def value(self):
74 return self.data
75 def update(self, value):
76 # If number if items is not the same, recreate children
77 if len(value) != len(self.l): # remove first if number of items has changed
f0c20d94
RD
78 childNodes = self.node.childNodes[:]
79 for n in childNodes:
32ce09e2
RD
80 self.node.removeChild(n)
81 l = []
82 for str in value:
83 itemElem = tree.dom.createElement('item')
84 itemText = tree.dom.createTextNode(str)
85 itemElem.appendChild(itemText)
86 self.node.appendChild(itemElem)
87 l.append(itemText)
f0c20d94 88 self.l = l
32ce09e2
RD
89 else:
90 for i in range(len(value)):
91 self.l[i].data = value[i]
92 self.data = value
93
f0c20d94
RD
94# Content parameter for checklist
95class xxxParamContentCheckList:
96 def __init__(self, node):
97 self.node = node
98 data, l = [], [] # data is needed to quicker value retrieval
99 nodes = node.childNodes[:] # make a copy of the child list
100 for n in nodes:
101 if n.nodeType == minidom.Node.ELEMENT_NODE:
102 assert n.tagName == 'item', 'bad content content'
103 checked = n.getAttribute('checked')
104 if not n.hasChildNodes():
105 # If does not have child nodes, create empty text node
106 text = tree.dom.createTextNode('')
107 node.appendChild(text)
108 else:
109 # !!! normalize?
110 text = n.childNodes[0] # first child must be text node
111 assert text.nodeType == minidom.Node.TEXT_NODE
112 l.append((text, n))
113 data.append((str(text.data), int(checked)))
114 else: # remove other
115 node.removeChild(n)
116 n.unlink()
117 self.l, self.data = l, data
118 def value(self):
119 return self.data
120 def update(self, value):
121 # If number if items is not the same, recreate children
122 if len(value) != len(self.l): # remove first if number of items has changed
123 childNodes = self.node.childNodes[:]
124 for n in childNodes:
125 self.node.removeChild(n)
126 l = []
127 for (s,ch) in value:
128 itemElem = tree.dom.createElement('item')
129 itemElem.setAttribute('checked', str(ch))
130 itemText = tree.dom.createTextNode(s)
131 itemElem.appendChild(itemText)
132 self.node.appendChild(itemElem)
133 l.append((itemText, itemElem))
134 self.l = l
18fc9fa3
RD
135 else:
136 for i in range(len(value)):
137 self.l[i][0].data = value[i][0]
138 self.l[i][1].setAttribute('checked', str(value[i][1]))
f0c20d94
RD
139 self.data = value
140
32ce09e2
RD
141################################################################################
142
09f3d4e6
RD
143# Classes to interface DOM objects
144class xxxObject:
09f3d4e6
RD
145 # Default behavior
146 hasChildren = false # has children elements?
a40b5e84 147 hasStyle = true # almost everyone
09f3d4e6
RD
148 hasName = true # has name attribute?
149 isSizer = hasChild = false
f0c20d94 150 allParams = None # Some nodes have no parameters
a40b5e84
RD
151 # Style parameters (all optional)
152 styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip']
32ce09e2
RD
153 # Special parameters
154 specials = []
09f3d4e6
RD
155 # Required paremeters: none by default
156 required = []
157 # Default parameters with default values
158 default = {}
159 # Parameter types
160 paramDict = {}
a40b5e84
RD
161 # Window styles and extended styles
162 winStyles = []
09f3d4e6 163 # Tree icon index
a40b5e84 164 #image = -1
09f3d4e6
RD
165 # Construct a new xxx object from DOM element
166 # parent is parent xxx object (or None if none), element is DOM element object
167 def __init__(self, parent, element):
168 self.parent = parent
169 self.element = element
170 self.undo = None
171 # Get attributes
172 self.className = element.getAttribute('class')
173 if self.hasName: self.name = element.getAttribute('name')
174 # Set parameters (text element children)
175 self.params = {}
176 nodes = element.childNodes[:]
177 for node in nodes:
178 if node.nodeType == minidom.Node.ELEMENT_NODE:
32ce09e2
RD
179 tag = node.tagName
180 if tag == 'object':
09f3d4e6 181 continue # do nothing for object children here
32ce09e2 182 if not tag in self.allParams and not tag in self.styles:
09f3d4e6 183 print 'WARNING: unknown parameter for %s: %s' % \
32ce09e2
RD
184 (self.className, tag)
185 elif tag in self.specials:
186 self.special(tag, node)
187 elif tag == 'content':
f0c20d94
RD
188 if self.className == 'wxCheckList':
189 self.params[tag] = xxxParamContentCheckList(node)
190 else:
191 self.params[tag] = xxxParamContent(node)
32ce09e2 192 elif tag == 'font': # has children
18fc9fa3 193 self.params[tag] = xxxParamFont(element, node)
09f3d4e6 194 else: # simple parameter
32ce09e2 195 self.params[tag] = xxxParam(node)
09f3d4e6
RD
196 else:
197 # Remove all other nodes
198 element.removeChild(node)
199 node.unlink()
09f3d4e6
RD
200 # Returns real tree object
201 def treeObject(self):
202 if self.hasChild: return self.child
203 return self
204 # Returns tree image index
205 def treeImage(self):
206 if self.hasChild: return self.child.treeImage()
207 return self.image
208 # Class name plus wx name
209 def treeName(self):
210 if self.hasChild: return self.child.treeName()
211 if self.hasName and self.name: return self.className + ' "' + self.name + '"'
212 return self.className
213
214################################################################################
215
18fc9fa3
RD
216# This is a little special
217class xxxParamFont(xxxObject):
a40b5e84
RD
218 allParams = ['size', 'style', 'weight', 'family', 'underlined',
219 'face', 'encoding']
220 def __init__(self, parent, element):
221 xxxObject.__init__(self, parent, element)
18fc9fa3 222 self.parentNode = parent # required to behave similar to DOM node
32ce09e2
RD
223 v = []
224 for p in self.allParams:
225 try:
18fc9fa3 226 v.append(str(self.params[p].value()))
32ce09e2
RD
227 except KeyError:
228 v.append('')
229 self.data = v
230 def update(self, value):
a40b5e84
RD
231 # `value' is a list of strings corresponding to all parameters
232 elem = self.element
18fc9fa3
RD
233 # Remove old elements first
234 childNodes = elem.childNodes[:]
235 for node in childNodes: elem.removeChild(node)
a40b5e84
RD
236 i = 0
237 self.params.clear()
32ce09e2 238 v = []
a40b5e84
RD
239 for param in self.allParams:
240 if value[i]:
241 fontElem = tree.dom.createElement(param)
242 textNode = tree.dom.createTextNode(value[i])
243 self.params[param] = textNode
244 fontElem.appendChild(textNode)
245 elem.appendChild(fontElem)
32ce09e2 246 v.append(value[i])
a40b5e84 247 i += 1
32ce09e2 248 self.data = v
18fc9fa3
RD
249 def value(self):
250 return self.data
251 def remove(self):
252 self.parentNode.removeChild(self.element)
253 self.element.unlink()
a40b5e84
RD
254
255################################################################################
256
09f3d4e6
RD
257class xxxContainer(xxxObject):
258 hasChildren = true
259
f0c20d94
RD
260# Special class for root node
261class xxxMainNode(xxxContainer):
262 hasStyle = hasName = false
263
09f3d4e6 264################################################################################
f0c20d94 265# Top-level windwows
09f3d4e6
RD
266
267class xxxPanel(xxxContainer):
268 allParams = ['pos', 'size', 'style']
a40b5e84
RD
269 styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle',
270 'tooltip']
32ce09e2 271 winStyles = ['wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN']
a40b5e84 272 exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY']
09f3d4e6
RD
273
274class xxxDialog(xxxContainer):
275 allParams = ['title', 'pos', 'size', 'style']
276 required = ['title']
32ce09e2
RD
277 winStyles = ['wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP',
278 'wxDIALOG_MODAL', 'wxDIALOG_MODELESS',
279 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX',
280 'wxTHICK_FRAME',
281 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN']
a40b5e84
RD
282 styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle',
283 'tooltip']
284 exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY']
09f3d4e6
RD
285
286class xxxFrame(xxxContainer):
287 allParams = ['title', 'centered', 'pos', 'size', 'style']
288 paramDict = {'centered': ParamBool}
289 required = ['title']
32ce09e2
RD
290 winStyles = ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE',
291 'wxSTAY_ON_TOP',
292 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER',
293 'wxRESIZE_BOX', 'wxMINIMIZE_BOX', 'wxMAXIMIZE_BOX',
294 'wxFRAME_FLOAT_ON_PARENT', 'wxFRAME_TOOL_WINDOW',
295 'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN']
a40b5e84
RD
296 styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle',
297 'tooltip']
298 exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY']
09f3d4e6 299
32ce09e2
RD
300class xxxTool(xxxObject):
301 allParams = ['bitmap', 'bitmap2', 'toggle', 'tooltip', 'longhelp']
302 paramDict = {'bitmap2': ParamFile}
303 hasStyle = false
304
305class xxxToolBar(xxxContainer):
306 allParams = ['bitmapsize', 'margins', 'packing', 'separation',
307 'pos', 'size', 'style']
308 hasStyle = false
309 paramDict = {'bitmapsize': ParamPosSize, 'margins': ParamPosSize,
310 'packing': ParamInt, 'separation': ParamInt,
311 'style': ParamNonGenericStyle}
312 winStyles = ['wxTB_FLAT', 'wxTB_DOCKABLE', 'wxTB_VERTICAL', 'wxTB_HORIZONTAL']
313
314################################################################################
315# Bitmap, Icon
316
317class xxxBitmap(xxxObject):
318 allParams = ['bitmap']
319 required = ['bitmap']
320
321class xxxIcon(xxxObject):
322 allParams = ['icon']
323 required = ['icon']
324
09f3d4e6
RD
325################################################################################
326# Controls
327
328class xxxStaticText(xxxObject):
329 allParams = ['label', 'pos', 'size', 'style']
330 required = ['label']
a40b5e84 331 winStyles = ['wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE']
09f3d4e6
RD
332
333class xxxStaticLine(xxxObject):
334 allParams = ['pos', 'size', 'style']
a40b5e84 335 winStyles = ['wxLI_HORIZONTAL', 'wxLI_VERTICAL']
09f3d4e6 336
32ce09e2
RD
337class xxxStaticBitmap(xxxObject):
338 allParams = ['bitmap', 'pos', 'size', 'style']
339 required = ['bitmap']
340
09f3d4e6
RD
341class xxxTextCtrl(xxxObject):
342 allParams = ['value', 'pos', 'size', 'style']
a40b5e84 343 winStyles = ['wxTE_PROCESS_ENTER', 'wxTE_PROCESS_TAB', 'wxTE_MULTILINE',
32ce09e2 344 'wxTE_PASSWORD', 'wxTE_READONLY', 'wxHSCROLL']
09f3d4e6
RD
345
346class xxxChoice(xxxObject):
347 allParams = ['content', 'selection', 'pos', 'size', 'style']
348 required = ['content']
32ce09e2 349 winStyles = ['wxCB_SORT']
09f3d4e6
RD
350
351class xxxSlider(xxxObject):
352 allParams = ['value', 'min', 'max', 'pos', 'size', 'style',
353 'tickfreq', 'pagesize', 'linesize', 'thumb', 'tick',
354 'selmin', 'selmax']
355 paramDict = {'value': ParamInt, 'tickfreq': ParamInt, 'pagesize': ParamInt,
356 'linesize': ParamInt, 'thumb': ParamInt, 'thumb': ParamInt,
357 'tick': ParamInt, 'selmin': ParamInt, 'selmax': ParamInt}
358 required = ['value', 'min', 'max']
a40b5e84 359 winStyles = ['wxSL_HORIZONTAL', 'wxSL_VERTICAL', 'wxSL_AUTOTICKS', 'wxSL_LABELS',
32ce09e2
RD
360 'wxSL_LEFT', 'wxSL_RIGHT', 'wxSL_TOP', 'wxSL_BOTTOM',
361 'wxSL_BOTH', 'wxSL_SELRANGE']
09f3d4e6
RD
362
363class xxxGauge(xxxObject):
364 allParams = ['range', 'pos', 'size', 'style', 'value', 'shadow', 'bezel']
365 paramDict = {'range': ParamInt, 'value': ParamInt,
366 'shadow': ParamInt, 'bezel': ParamInt}
a40b5e84 367 winStyles = ['wxGA_HORIZONTAL', 'wxGA_VERTICAL', 'wxGA_PROGRESSBAR', 'wxGA_SMOOTH']
09f3d4e6
RD
368
369class xxxScrollBar(xxxObject):
370 allParams = ['pos', 'size', 'style', 'value', 'thumbsize', 'range', 'pagesize']
371 paramDict = {'value': ParamInt, 'range': ParamInt, 'thumbsize': ParamInt,
372 'pagesize': ParamInt}
a40b5e84 373 winStyles = ['wxSB_HORIZONTAL', 'wxSB_VERTICAL']
09f3d4e6
RD
374
375class xxxListCtrl(xxxObject):
376 allParams = ['pos', 'size', 'style']
a40b5e84 377 winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON',
09f3d4e6
RD
378 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE',
379 'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER',
380 'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING']
381
09f3d4e6
RD
382class xxxTreeCtrl(xxxObject):
383 allParams = ['pos', 'size', 'style']
a40b5e84 384 winStyles = ['wxTR_HAS_BUTTONS', 'wxTR_NO_LINES', 'wxTR_LINES_AT_ROOT',
09f3d4e6
RD
385 'wxTR_EDIT_LABELS', 'wxTR_MULTIPLE']
386
387class xxxHtmlWindow(xxxObject):
388 allParams = ['pos', 'size', 'style', 'borders', 'url', 'htmlcode']
389 paramDict = {'borders': ParamInt}
a40b5e84 390 winStyles = ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO']
09f3d4e6
RD
391
392class xxxCalendar(xxxObject):
393 allParams = ['pos', 'size', 'style']
394
395class xxxNotebook(xxxContainer):
396 allParams = ['usenotebooksizer', 'pos', 'size', 'style']
397 paramDict = {'usenotebooksizer': ParamBool}
a40b5e84 398 winStyles = ['wxNB_FIXEDWIDTH', 'wxNB_LEFT', 'wxNB_RIGHT', 'wxNB_BOTTOM']
09f3d4e6
RD
399
400################################################################################
401# Buttons
402
403class xxxButton(xxxObject):
404 allParams = ['label', 'default', 'pos', 'size', 'style']
405 paramDict = {'default': ParamBool}
406 required = ['label']
a40b5e84 407 winStyles = ['wxBU_LEFT', 'wxBU_TOP', 'wxBU_RIGHT', 'wxBU_BOTTOM']
09f3d4e6
RD
408
409class xxxBitmapButton(xxxObject):
410 allParams = ['bitmap', 'selected', 'focus', 'disabled', 'default',
411 'pos', 'size', 'style']
412 required = ['bitmap']
32ce09e2
RD
413 winStyles = ['wxBU_AUTODRAW', 'wxBU_LEFT', 'wxBU_TOP',
414 'wxBU_RIGHT', 'wxBU_BOTTOM']
09f3d4e6
RD
415
416class xxxRadioButton(xxxObject):
417 allParams = ['label', 'value', 'pos', 'size', 'style']
418 paramDict = {'value': ParamBool}
419 required = ['label']
a40b5e84 420 winStyles = ['wxRB_GROUP']
09f3d4e6
RD
421
422class xxxSpinButton(xxxObject):
423 allParams = ['pos', 'size', 'style']
a40b5e84 424 winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP']
09f3d4e6
RD
425
426################################################################################
427# Boxes
428
429class xxxStaticBox(xxxObject):
430 allParams = ['label', 'pos', 'size', 'style']
431 required = ['label']
432
433class xxxRadioBox(xxxObject):
434 allParams = ['label', 'content', 'selection', 'dimension', 'pos', 'size', 'style']
435 paramDict = {'dimension': ParamInt}
436 required = ['label', 'content']
a40b5e84 437 winStyles = ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS']
09f3d4e6
RD
438
439class xxxCheckBox(xxxObject):
440 allParams = ['label', 'pos', 'size', 'style']
441 required = ['label']
442
443class xxxComboBox(xxxObject):
444 allParams = ['content', 'selection', 'value', 'pos', 'size', 'style']
445 required = ['content']
32ce09e2 446 winStyles = ['wxCB_SIMPLE', 'wxCB_SORT', 'wxCB_READONLY', 'wxCB_DROPDOWN']
09f3d4e6
RD
447
448class xxxListBox(xxxObject):
449 allParams = ['content', 'selection', 'pos', 'size', 'style']
450 required = ['content']
a40b5e84 451 winStyles = ['wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL',
09f3d4e6
RD
452 'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT']
453
f0c20d94
RD
454class xxxCheckList(xxxObject):
455 allParams = ['content', 'pos', 'size', 'style']
456 required = ['content']
457 winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON',
458 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE',
459 'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER',
460 'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING']
461 paramDict = {'content': ParamContentCheckList}
462
09f3d4e6
RD
463################################################################################
464# Sizers
465
466class xxxSizer(xxxContainer):
a40b5e84 467 hasName = hasStyle = false
09f3d4e6
RD
468 paramDict = {'orient': ParamOrient}
469 isSizer = true
470
471class xxxBoxSizer(xxxSizer):
472 allParams = ['orient']
473 required = ['orient']
474 default = {'orient': 'wxVERTICAL'}
475 # Tree icon depends on orientation
476 def treeImage(self):
32ce09e2 477 if self.params['orient'].value() == 'wxHORIZONTAL': return self.imageH
09f3d4e6
RD
478 else: return self.imageV
479
480class xxxStaticBoxSizer(xxxBoxSizer):
481 allParams = ['label', 'orient']
482 required = ['label', 'orient']
483 default = {'orient': 'wxVERTICAL'}
484
485class xxxGridSizer(xxxSizer):
486 allParams = ['cols', 'rows', 'vgap', 'hgap']
487 required = ['cols']
488 default = {'cols': '2', 'rows': '2'}
489
32ce09e2
RD
490# For repeated parameters
491class xxxParamMulti:
492 def __init__(self):
493 self.l, self.data = [], []
494 def append(self, param):
495 self.l.append(param)
496 self.data.append(param.value())
497 def value(self):
498 return self.data
499 def remove(self):
500 for param in self.l:
501 param.remove()
502 self.l, self.data = [], []
503
09f3d4e6 504class xxxFlexGridSizer(xxxGridSizer):
32ce09e2
RD
505 specials = ['growablecols', 'growablerows']
506 allParams = ['cols', 'rows', 'vgap', 'hgap'] + specials
18fc9fa3 507 paramDict = {'growablecols':ParamIntList, 'growablerows':ParamIntList}
32ce09e2
RD
508 # Special processing for growable* parameters
509 # (they are represented by several nodes)
510 def special(self, tag, node):
18fc9fa3 511 if tag not in self.params:
32ce09e2 512 self.params[tag] = xxxParamMulti()
18fc9fa3 513 self.params[tag].append(xxxParamInt(node))
32ce09e2
RD
514 def setSpecial(self, param, value):
515 # Straightforward implementation: remove, add again
516 self.params[param].remove()
517 del self.params[param]
18fc9fa3 518 for i in value:
32ce09e2 519 node = tree.dom.createElement(param)
18fc9fa3 520 text = tree.dom.createTextNode(str(i))
32ce09e2
RD
521 node.appendChild(text)
522 self.element.appendChild(node)
523 self.special(param, node)
09f3d4e6
RD
524
525# Container with only one child.
526# Not shown in tree.
527class xxxChildContainer(xxxObject):
a40b5e84 528 hasName = hasStyle = false
09f3d4e6
RD
529 hasChild = true
530 def __init__(self, parent, element):
531 xxxObject.__init__(self, parent, element)
532 # Must have one child with 'object' tag, but we don't check it
533 nodes = element.childNodes[:] # create copy
534 for node in nodes:
535 if node.nodeType == minidom.Node.ELEMENT_NODE:
536 if node.tagName == 'object':
537 # Create new xxx object for child node
538 self.child = MakeXXXFromDOM(self, node)
539 self.child.parent = parent
540 # Copy hasChildren and isSizer attributes
541 self.hasChildren = self.child.hasChildren
542 self.isSizer = self.child.isSizer
543 return # success
544 else:
545 element.removeChild(node)
546 node.unlink()
547 assert 0, 'no child found'
09f3d4e6
RD
548
549class xxxSizerItem(xxxChildContainer):
550 allParams = ['option', 'flag', 'border']
551 paramDict = {'option': ParamInt}
552 def __init__(self, parent, element):
553 xxxChildContainer.__init__(self, parent, element)
f0c20d94 554 # Remove pos parameter - not needed for sizeritems
09f3d4e6
RD
555 if 'pos' in self.child.allParams:
556 self.child.allParams = self.child.allParams[:]
557 self.child.allParams.remove('pos')
558
559class xxxNotebookPage(xxxChildContainer):
560 allParams = ['label', 'selected']
561 paramDict = {'selected': ParamBool}
562 required = ['label']
563 def __init__(self, parent, element):
564 xxxChildContainer.__init__(self, parent, element)
565 # pos and size dont matter for notebookpages
566 if 'pos' in self.child.allParams:
567 self.child.allParams = self.child.allParams[:]
568 self.child.allParams.remove('pos')
569 if 'size' in self.child.allParams:
570 self.child.allParams = self.child.allParams[:]
571 self.child.allParams.remove('size')
572
573class xxxSpacer(xxxObject):
a40b5e84 574 hasName = hasStyle = false
09f3d4e6
RD
575 allParams = ['size', 'option', 'flag', 'border']
576 paramDict = {'option': ParamInt}
577 default = {'size': '0,0'}
578
579class xxxMenuBar(xxxContainer):
580 allParams = []
581
582class xxxMenu(xxxContainer):
583 allParams = ['label']
584 default = {'label': ''}
32ce09e2
RD
585 paramDict = {'style': ParamNonGenericStyle} # no generic styles
586 winStyles = ['wxMENU_TEAROFF']
09f3d4e6
RD
587
588class xxxMenuItem(xxxObject):
589 allParams = ['checkable', 'label', 'accel', 'help']
590 default = {'label': ''}
591
592class xxxSeparator(xxxObject):
a40b5e84 593 hasName = hasStyle = false
09f3d4e6 594
a40b5e84
RD
595################################################################################
596
09f3d4e6
RD
597xxxDict = {
598 'wxPanel': xxxPanel,
599 'wxDialog': xxxDialog,
600 'wxFrame': xxxFrame,
32ce09e2
RD
601 'tool': xxxTool,
602 'wxToolBar': xxxToolBar,
09f3d4e6 603
32ce09e2
RD
604 'wxBitmap': xxxBitmap,
605 'wxIcon': xxxIcon,
606
09f3d4e6
RD
607 'wxButton': xxxButton,
608 'wxBitmapButton': xxxBitmapButton,
609 'wxRadioButton': xxxRadioButton,
610 'wxSpinButton': xxxSpinButton,
611
612 'wxStaticBox': xxxStaticBox,
32ce09e2 613 'wxStaticBitmap': xxxStaticBitmap,
09f3d4e6
RD
614 'wxRadioBox': xxxRadioBox,
615 'wxComboBox': xxxComboBox,
616 'wxCheckBox': xxxCheckBox,
617 'wxListBox': xxxListBox,
618
619 'wxStaticText': xxxStaticText,
620 'wxStaticLine': xxxStaticLine,
621 'wxTextCtrl': xxxTextCtrl,
622 'wxChoice': xxxChoice,
623 'wxSlider': xxxSlider,
624 'wxGauge': xxxGauge,
625 'wxScrollBar': xxxScrollBar,
626 'wxTreeCtrl': xxxTreeCtrl,
627 'wxListCtrl': xxxListCtrl,
628 'wxCheckList': xxxCheckList,
629 'wxNotebook': xxxNotebook,
630 'notebookpage': xxxNotebookPage,
631 'wxHtmlWindow': xxxHtmlWindow,
632 'wxCalendar': xxxCalendar,
633
634 'wxBoxSizer': xxxBoxSizer,
635 'wxStaticBoxSizer': xxxStaticBoxSizer,
636 'wxGridSizer': xxxGridSizer,
637 'wxFlexGridSizer': xxxFlexGridSizer,
638 'sizeritem': xxxSizerItem,
639 'spacer': xxxSpacer,
640
641 'wxMenuBar': xxxMenuBar,
642 'wxMenu': xxxMenu,
643 'wxMenuItem': xxxMenuItem,
644 'separator': xxxSeparator,
645 }
646
a40b5e84
RD
647# Create IDs for all parameters of all classes
648paramIDs = {'fg': wxNewId(), 'bg': wxNewId(), 'exstyle': wxNewId(), 'font': wxNewId(),
649 'enabled': wxNewId(), 'focused': wxNewId(), 'hidden': wxNewId(),
650 'tooltip': wxNewId()
651 }
652for cl in xxxDict.values():
f0c20d94
RD
653 if cl.allParams:
654 for param in cl.allParams + cl.paramDict.keys():
655 if not paramIDs.has_key(param):
656 paramIDs[param] = wxNewId()
a40b5e84
RD
657
658################################################################################
09f3d4e6
RD
659# Helper functions
660
661# Test for object elements
662def IsObject(node):
663 return node.nodeType == minidom.Node.ELEMENT_NODE and node.tagName == 'object'
664
665# Make XXX object from some DOM object, selecting correct class
666def MakeXXXFromDOM(parent, element):
32ce09e2
RD
667 try:
668 return xxxDict[element.getAttribute('class')](parent, element)
669 except KeyError:
670 # Verify that it's not recursive exception
f0c20d94 671 if element.getAttribute('class') not in xxxDict:
32ce09e2
RD
672 print 'ERROR: unknown class:', element.getAttribute('class')
673 raise
09f3d4e6
RD
674
675# Make empty DOM element
676def MakeEmptyDOM(className):
677 elem = tree.dom.createElement('object')
678 elem.setAttribute('class', className)
679 # Set required and default parameters
680 xxxClass = xxxDict[className]
681 defaultNotRequired = filter(lambda x, l=xxxClass.required: x not in l,
682 xxxClass.default.keys())
683 for param in xxxClass.required + defaultNotRequired:
684 textElem = tree.dom.createElement(param)
685 try:
686 textNode = tree.dom.createTextNode(xxxClass.default[param])
687 except KeyError:
688 textNode = tree.dom.createTextNode('')
689 textElem.appendChild(textNode)
690 elem.appendChild(textElem)
691 return elem
692
693# Make empty XXX object
694def MakeEmptyXXX(parent, className):
695 # Make corresponding DOM object first
696 elem = MakeEmptyDOM(className)
697 # If parent is a sizer, we should create sizeritem object, except for spacers
698 if parent:
699 if parent.isSizer and className != 'spacer':
700 sizerItemElem = MakeEmptyDOM('sizeritem')
701 sizerItemElem.appendChild(elem)
702 elem = sizerItemElem
703 elif isinstance(parent, xxxNotebook):
704 pageElem = MakeEmptyDOM('notebookpage')
705 pageElem.appendChild(elem)
706 elem = pageElem
707 # Now just make object
708 return MakeXXXFromDOM(parent, elem)
709