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