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