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