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