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> 
   7 from xml
.dom 
import minidom
 
  10 import traceback
, types
 
  12 # Base class for interface parameter classes 
  14     def __init__(self
, node
): 
  17         self
.node
.parentNode
.removeChild(self
.node
) 
  20 # Generic (text) parameter class 
  21 class xxxParam(xxxNode
): 
  22     # Standard use: for text nodes 
  23     def __init__(self
, node
): 
  24         xxxNode
.__init
__(self
, node
) 
  25         if not node
.hasChildNodes(): 
  26             # If does not have child nodes, create empty text node 
  27             text 
= g
.tree
.dom
.createTextNode('') 
  28             node
.appendChild(text
) 
  30             text 
= node
.childNodes
[0] # first child must be text node 
  31             assert text
.nodeType 
== minidom
.Node
.TEXT_NODE
 
  32             # Append other text nodes if present and delete them 
  34             for n 
in node
.childNodes
[1:]: 
  35                 if n
.nodeType 
== minidom
.Node
.TEXT_NODE
: 
  40             if extraText
: text
.data 
= text
.data 
+ extraText
 
  41         # Use convertion from unicode to current encoding 
  43     # Value returns string 
  44     if wx
.USE_UNICODE
:   # no conversion is needed 
  46             return self
.textNode
.data
 
  47         def update(self
, value
): 
  48             self
.textNode
.data 
= value
 
  52                 return self
.textNode
.data
.encode(g
.currentEncoding
) 
  54                 return self
.textNode
.data
.encode() 
  55         def update(self
, value
): 
  56             try: # handle exception if encoding is wrong 
  57                 self
.textNode
.data 
= unicode(value
, g
.currentEncoding
) 
  58             except UnicodeDecodeError: 
  59                 self
.textNode
.data 
= unicode(value
) 
  60                 #wx.LogMessage("Unicode error: set encoding in file\nglobals.py to something appropriate") 
  63 class xxxParamInt(xxxParam
): 
  64     # Standard use: for text nodes 
  65     def __init__(self
, node
): 
  66         xxxParam
.__init
__(self
, node
) 
  67     # Value returns string 
  70             return int(self
.textNode
.data
) 
  72             return -1                   # invalid value 
  73     def update(self
, value
): 
  74         self
.textNode
.data 
= str(value
) 
  77 class xxxParamContent(xxxNode
): 
  78     def __init__(self
, node
): 
  79         xxxNode
.__init
__(self
, node
) 
  80         data
, l 
= [], []                # data is needed to quicker value retrieval 
  81         nodes 
= node
.childNodes
[:]      # make a copy of the child list 
  83             if n
.nodeType 
== minidom
.Node
.ELEMENT_NODE
: 
  84                 assert n
.tagName 
== 'item', 'bad content content' 
  85                 if not n
.hasChildNodes(): 
  86                     # If does not have child nodes, create empty text node 
  87                     text 
= g
.tree
.dom
.createTextNode('') 
  88                     node
.appendChild(text
) 
  91                     text 
= n
.childNodes
[0] # first child must be text node 
  92                     assert text
.nodeType 
== minidom
.Node
.TEXT_NODE
 
  94                 data
.append(text
.data
) 
  98         self
.l
, self
.data 
= l
, data
 
 101     def update(self
, value
): 
 102         # If number if items is not the same, recreate children 
 103         if len(value
) != len(self
.l
):   # remove first if number of items has changed 
 104             childNodes 
= self
.node
.childNodes
[:] 
 106                 self
.node
.removeChild(n
) 
 109                 itemElem 
= g
.tree
.dom
.createElement('item') 
 110                 itemText 
= g
.tree
.dom
.createTextNode(str) 
 111                 itemElem
.appendChild(itemText
) 
 112                 self
.node
.appendChild(itemElem
) 
 116             for i 
in range(len(value
)): 
 117                 self
.l
[i
].data 
= value
[i
] 
 120 # Content parameter for checklist 
 121 class xxxParamContentCheckList(xxxNode
): 
 122     def __init__(self
, node
): 
 123         xxxNode
.__init
__(self
, node
) 
 124         data
, l 
= [], []                # data is needed to quicker value retrieval 
 125         nodes 
= node
.childNodes
[:]      # make a copy of the child list 
 127             if n
.nodeType 
== minidom
.Node
.ELEMENT_NODE
: 
 128                 assert n
.tagName 
== 'item', 'bad content content' 
 129                 checked 
= n
.getAttribute('checked') 
 130                 if not checked
: checked 
= 0 
 131                 if not n
.hasChildNodes(): 
 132                     # If does not have child nodes, create empty text node 
 133                     text 
= g
.tree
.dom
.createTextNode('') 
 134                     node
.appendChild(text
) 
 137                     text 
= n
.childNodes
[0] # first child must be text node 
 138                     assert text
.nodeType 
== minidom
.Node
.TEXT_NODE
 
 140                 data
.append((str(text
.data
), int(checked
))) 
 144         self
.l
, self
.data 
= l
, data
 
 147     def update(self
, value
): 
 148         # If number if items is not the same, recreate children 
 149         if len(value
) != len(self
.l
):   # remove first if number of items has changed 
 150             childNodes 
= self
.node
.childNodes
[:] 
 152                 self
.node
.removeChild(n
) 
 155                 itemElem 
= g
.tree
.dom
.createElement('item') 
 156                 # Add checked only if True 
 157                 if ch
: itemElem
.setAttribute('checked', '1') 
 158                 itemText 
= g
.tree
.dom
.createTextNode(s
) 
 159                 itemElem
.appendChild(itemText
) 
 160                 self
.node
.appendChild(itemElem
) 
 161                 l
.append((itemText
, itemElem
)) 
 164             for i 
in range(len(value
)): 
 165                 self
.l
[i
][0].data 
= value
[i
][0] 
 166                 self
.l
[i
][1].setAttribute('checked', str(value
[i
][1])) 
 170 class xxxParamBitmap(xxxParam
): 
 171     def __init__(self
, node
): 
 172         xxxParam
.__init
__(self
, node
) 
 173         self
.stock_id 
= node
.getAttribute('stock_id') 
 175         return [self
.stock_id
, xxxParam
.value(self
)] 
 176     def update(self
, value
): 
 177         self
.stock_id 
= value
[0] 
 179             self
.node
.setAttribute('stock_id', self
.stock_id
) 
 180         elif self
.node
.hasAttribute('stock_id'): 
 181             self
.node
.removeAttribute('stock_id') 
 182         xxxParam
.update(self
, value
[1]) 
 184 ################################################################################ 
 186 # Classes to interface DOM objects 
 189     hasChildren 
= False                 # has children elements? 
 190     hasStyle 
= True                     # almost everyone 
 191     hasName 
= True                      # has name attribute? 
 192     isSizer 
= hasChild 
= False 
 194     allParams 
= []                     # Some nodes have no parameters 
 195     # Style parameters (all optional) 
 196     styles 
= ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip'] 
 200     bitmapTags 
= ['bitmap', 'bitmap2', 'icon'] 
 201     # Required paremeters: none by default 
 203     # Default parameters with default values 
 207     # Window styles and extended styles 
 211     # Construct a new xxx object from DOM element 
 212     # parent is parent xxx object (or None if none), element is DOM element object 
 213     def __init__(self
, parent
, element
, refElem
=None): 
 216         self
.refElem 
= refElem
 
 218         # Reference are dereferenced 
 219         if element
.tagName 
== 'object_ref': 
 220             # Find original object 
 221             self
.ref 
= element
.getAttribute('ref') 
 223                 self
.className 
= self
.refElem
.getAttribute('class') 
 225                 self
.className 
= 'xxxUnknown' 
 230             self
.className 
= element
.getAttribute('class') 
 231         self
.subclass 
= element
.getAttribute('subclass') 
 232         if self
.hasName
: self
.name 
= element
.getAttribute('name') 
 233         # Set parameters (text element children) 
 235         for n 
in element
.childNodes
[:]: 
 236             if n
.nodeType 
== minidom
.Node
.ELEMENT_NODE
: 
 238                 if tag 
in ['object', 'object_ref']: 
 239                     continue            # do nothing for object children here 
 240                 elif tag 
not in self
.allParams 
and tag 
not in self
.styles
: 
 241                     print 'WARNING: unknown parameter for %s: %s' % \
 
 242                           (self
.className
, tag
) 
 243                 elif tag 
in self
.specials
: 
 245                 elif tag 
== 'content': 
 246                     if self
.className 
== 'wxCheckListBox': 
 247                         self
.params
[tag
] = xxxParamContentCheckList(n
) 
 249                         self
.params
[tag
] = xxxParamContent(n
) 
 250                 elif tag 
== 'font': # has children 
 251                     self
.params
[tag
] = xxxParamFont(element
, n
) 
 252                 elif tag 
in self
.bitmapTags
: 
 253                     # Can have attributes 
 254                     self
.params
[tag
] = xxxParamBitmap(n
) 
 255                 else:                   # simple parameter 
 256                     self
.params
[tag
] = xxxParam(n
) 
 257             elif n
.nodeType 
== minidom
.Node
.TEXT_NODE 
and n
.data
.isspace(): 
 258                 # Remove empty text nodes 
 259                 element
.removeChild(n
) 
 262         # Check that all required params are set 
 263         for param 
in self
.required
: 
 264             if not self
.params
.has_key(param
): 
 265                 # If default is specified, set it 
 266                 if self
.default
.has_key(param
): 
 267                     elem 
= g
.tree
.dom
.createElement(param
) 
 268                     if param 
== 'content': 
 269                         if self
.className 
== 'wxCheckListBox': 
 270                             self
.params
[param
] = xxxParamContentCheckList(elem
) 
 272                             self
.params
[param
] = xxxParamContent(elem
) 
 274                         self
.params
[param
] = xxxParam(elem
) 
 275                     # Find place to put new element: first present element after param 
 277                     paramStyles 
= self
.allParams 
+ self
.styles
 
 278                     for p 
in paramStyles
[paramStyles
.index(param
) + 1:]: 
 279                         # Content params don't have same type 
 280                         if self
.params
.has_key(p
) and p 
!= 'content': 
 284                         nextTextElem 
= self
.params
[p
].node
 
 285                         self
.node
.insertBefore(elem
, nextTextElem
) 
 287                         self
.node
.appendChild(elem
) 
 289                     wx
.LogWarning('Required parameter %s of %s missing' % 
 290                                  (param
, self
.className
)) 
 291     # Returns real tree object 
 292     def treeObject(self
): 
 293         if self
.hasChild
: return self
.child
 
 295     # Returns tree image index 
 297         if self
.hasChild
: return self
.child
.treeImage() 
 299     # Class name plus wx name 
 301         if self
.hasChild
: return self
.child
.treeName() 
 302         if self
.subclass
: className 
= self
.subclass
 
 303         else: className 
= self
.className
 
 304         if self
.hasName 
and self
.name
: return className 
+ ' "' + self
.name 
+ '"' 
 306     # Class name or subclass 
 308         if self
.subclass
: name 
= self
.subclass 
+ '(' + self
.className 
+ ')' 
 309         name 
= self
.className
 
 310         if self
.ref
: name 
= 'ref: ' + self
.ref 
+ ', ' + name
 
 312     # Sets name of tree object 
 313     def setTreeName(self
, name
): 
 314         if self
.hasChild
: obj 
= self
.child
 
 317         obj
.node
.setAttribute('name', name
) 
 318     # Set normal (text) params 
 319     def set(self
, param
, value
): 
 321             self
.params
[param
].update(value
) 
 323             elem 
= g
.tree
.dom
.createElement(param
) 
 326             self
.params
[param
] = p
 
 327             self
.node
.appendChild(elem
) 
 328     # Special processing for growablecols-like parameters 
 329     # represented by several nodes 
 330     def special(self
, tag
, node
): 
 331         if not self
.params
.has_key(tag
): 
 332             # Create new multi-group 
 333             self
.params
[tag
] = xxxParamMulti(node
) 
 334         self
.params
[tag
].append(xxxParamInt(node
)) 
 335     def setSpecial(self
, param
, value
): 
 336         # Straightforward implementation: remove, add again 
 337         self
.params
[param
].remove() 
 338         del self
.params
[param
] 
 340             node 
= g
.tree
.dom
.createElement(param
) 
 341             text 
= g
.tree
.dom
.createTextNode(str(i
)) 
 342             node
.appendChild(text
) 
 343             self
.node
.appendChild(node
) 
 344             self
.special(param
, node
) 
 346 # Imitation of FindResource/DoFindResource from xmlres.cpp 
 347 def DoFindResource(parent
, name
, classname
, recursive
): 
 348     for n 
in parent
.childNodes
: 
 349         if n
.nodeType 
== minidom
.Node
.ELEMENT_NODE 
and \
 
 350                n
.tagName 
in ['object', 'object_ref'] and \
 
 351                n
.getAttribute('name') == name
: 
 352             cls 
= n
.getAttribute('class') 
 353             if not classname 
or cls 
== classname
:  return n
 
 354             if not cls 
or n
.tagName 
== 'object_ref': 
 355                 refName 
= n
.getAttribute('ref') 
 356                 if not refName
:  continue 
 357                 refNode 
= FindResource(refName
) 
 358                 if refName 
and refNode
.getAttribute('class') == classname
: 
 361         for n 
in parent
.childNodes
: 
 362             if n
.nodeType 
== minidom
.Node
.ELEMENT_NODE 
and \
 
 363                    n
.tagName 
in ['object', 'object_ref']: 
 364                 found 
= DoFindResource(n
, name
, classname
, True) 
 365                 if found
:  return found
 
 366 def FindResource(name
, classname
='', recursive
=True): 
 367     found 
= DoFindResource(g
.tree
.mainNode
, name
, classname
, recursive
) 
 368     if found
:  return found
 
 369     wx
.LogError('XRC resource "%s" not found!' % name
) 
 372 ################################################################################ 
 374 # This is a little special: it is both xxxObject and xxxNode 
 375 class xxxParamFont(xxxObject
, xxxNode
): 
 376     allParams 
= ['size', 'family', 'style', 'weight', 'underlined', 
 378     def __init__(self
, parent
, element
): 
 379         xxxObject
.__init
__(self
, parent
, element
) 
 380         xxxNode
.__init
__(self
, element
) 
 381         self
.parentNode 
= parent       
# required to behave similar to DOM node 
 383         for p 
in self
.allParams
: 
 385                 v
.append(str(self
.params
[p
].value())) 
 389     def update(self
, value
): 
 390         # `value' is a list of strings corresponding to all parameters 
 392         # Remove old elements first 
 393         childNodes 
= elem
.childNodes
[:] 
 394         for node 
in childNodes
: elem
.removeChild(node
) 
 398         for param 
in self
.allParams
: 
 400                 fontElem 
= g
.tree
.dom
.createElement(param
) 
 401                 textNode 
= g
.tree
.dom
.createTextNode(value
[i
]) 
 402                 self
.params
[param
] = textNode
 
 403                 fontElem
.appendChild(textNode
) 
 404                 elem
.appendChild(fontElem
) 
 411 ################################################################################ 
 413 class xxxContainer(xxxObject
): 
 417 # Simulate normal parameter for encoding 
 420         return g
.currentEncoding
 
 421     def update(self
, val
): 
 422         g
.currentEncoding 
= val
 
 424 # Special class for root node 
 425 class xxxMainNode(xxxContainer
): 
 426     allParams 
= ['encoding'] 
 427     hasStyle 
= hasName 
= False 
 428     def __init__(self
, dom
): 
 429         xxxContainer
.__init
__(self
, None, dom
.documentElement
) 
 430         self
.className 
= 'XML tree' 
 431         # Reset required parameters after processing XML, because encoding is 
 433         self
.required 
= ['encoding'] 
 434         self
.params
['encoding'] = xxxEncoding() 
 436 ################################################################################ 
 439 class xxxPanel(xxxContainer
): 
 440     allParams 
= ['pos', 'size', 'style'] 
 441     winStyles 
= ['wxNO_3D', 'wxTAB_TRAVERSAL'] 
 442     styles 
= ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', 
 445 class xxxDialog(xxxContainer
): 
 446     allParams 
= ['title', 'centered', 'pos', 'size', 'style'] 
 447     paramDict 
= {'centered': ParamBool}
 
 449     default 
= {'title': ''}
 
 450     winStyles 
= ['wxDEFAULT_DIALOG_STYLE', 'wxCAPTION',  
 451                  'wxSTAY_ON_TOP', 'wxSYSTEM_MENU', 'wxTHICK_FRAME', 
 452                  'wxRESIZE_BORDER', 'wxRESIZE_BOX', 'wxCLOSE_BOX', 
 453                  'wxMAXIMIZE_BOX', 'wxMINIMIZE_BOX', 
 454                  'wxDIALOG_MODAL', 'wxDIALOG_MODELESS', 'wxDIALOG_NO_PARENT' 
 455                  'wxNO_3D', 'wxTAB_TRAVERSAL']                  
 456     exStyles 
= ['wxWS_EX_VALIDATE_RECURSIVELY', 'wxDIALOG_EX_METAL'] 
 457     styles 
= ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', 
 460 class xxxFrame(xxxContainer
): 
 461     allParams 
= ['title', 'centered', 'pos', 'size', 'style'] 
 462     paramDict 
= {'centered': ParamBool}
 
 464     default 
= {'title': ''}
 
 465     winStyles 
= ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE', 'wxCAPTION',  
 466                  'wxSTAY_ON_TOP', 'wxSYSTEM_MENU', 'wxTHICK_FRAME', 
 467                  'wxRESIZE_BORDER', 'wxRESIZE_BOX', 'wxCLOSE_BOX', 
 468                  'wxMAXIMIZE_BOX', 'wxMINIMIZE_BOX', 
 469                  'wxFRAME_NO_TASKBAR', 'wxFRAME_SHAPED', 'wxFRAME_TOOL_WINDOW', 
 470                  'wxFRAME_FLOAT_ON_PARENT', 
 471                  'wxNO_3D', 'wxTAB_TRAVERSAL']                  
 472     exStyles 
= ['wxWS_EX_VALIDATE_RECURSIVELY', 'wxFRAME_EX_METAL'] 
 473     styles 
= ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle', 
 476 class xxxTool(xxxObject
): 
 477     allParams 
= ['bitmap', 'bitmap2', 'radio', 'toggle', 'tooltip', 'longhelp', 'label'] 
 478     required 
= ['bitmap'] 
 479     paramDict 
= {'bitmap2': ParamBitmap, 'radio': ParamBool, 'toggle': ParamBool}
 
 482 class xxxToolBar(xxxContainer
): 
 483     allParams 
= ['bitmapsize', 'margins', 'packing', 'separation', 'dontattachtoframe', 
 484                  'pos', 'size', 'style'] 
 486     paramDict 
= {'bitmapsize': ParamPosSize
, 'margins': ParamPosSize
, 
 487                  'packing': ParamUnit
, 'separation': ParamUnit
, 
 488                  'dontattachtoframe': ParamBool
, 'style': ParamNonGenericStyle
} 
 489     winStyles 
= ['wxTB_FLAT', 'wxTB_DOCKABLE', 'wxTB_VERTICAL', 'wxTB_HORIZONTAL', 
 490                  'wxTB_3DBUTTONS','wxTB_TEXT', 'wxTB_NOICONS', 'wxTB_NODIVIDER', 
 491                  'wxTB_NOALIGN', 'wxTB_HORZ_LAYOUT', 'wxTB_HORZ_TEXT'] 
 493 class xxxStatusBar(xxxObject
): 
 495     allParams 
= ['fields', 'widths', 'styles', 'style'] 
 496     paramDict 
= {'fields': ParamIntNN
, 'widths': ParamText
, 'styles': ParamText
, 
 497                  'style': ParamNonGenericStyle
} 
 498     winStyles 
= ['wxST_SIZEGRIP'] 
 500 class xxxWizard(xxxContainer
): 
 501     allParams 
= ['title', 'bitmap', 'pos'] 
 503     default 
= {'title': ''}
 
 505     exStyles 
= ['wxWIZARD_EX_HELPBUTTON'] 
 506     styles 
= ['fg', 'bg', 'font', 'exstyle'] 
 508 class xxxWizardPage(xxxContainer
): 
 509     allParams 
= ['bitmap'] 
 513 class xxxWizardPageSimple(xxxContainer
): 
 514     allParams 
= ['bitmap'] 
 518 ################################################################################ 
 521 class xxxBitmap(xxxObject
): 
 522     allParams 
= ['bitmap'] 
 523     required 
= ['bitmap'] 
 526 class xxxIcon(xxxObject
): 
 529 ################################################################################ 
 532 class xxxStaticText(xxxObject
): 
 533     allParams 
= ['label', 'pos', 'size', 'style'] 
 535     default 
= {'label': ''}
 
 536     winStyles 
= ['wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE'] 
 538 class xxxStaticLine(xxxObject
): 
 539     allParams 
= ['pos', 'size', 'style'] 
 540     winStyles 
= ['wxLI_HORIZONTAL', 'wxLI_VERTICAL'] 
 542 class xxxStaticBitmap(xxxObject
): 
 543     allParams 
= ['bitmap', 'pos', 'size', 'style'] 
 544     required 
= ['bitmap'] 
 546 class xxxTextCtrl(xxxObject
): 
 547     allParams 
= ['value', 'pos', 'size', 'style'] 
 548     winStyles 
= ['wxTE_NO_VSCROLL', 
 550                  'wxTE_PROCESS_ENTER', 
 566     paramDict 
= {'value': ParamMultilineText}
 
 568 class xxxChoice(xxxObject
): 
 569     allParams 
= ['content', 'selection', 'pos', 'size', 'style'] 
 570     required 
= ['content'] 
 571     default 
= {'content': '[]'}
 
 572     winStyles 
= ['wxCB_SORT'] 
 574 class xxxSlider(xxxObject
): 
 575     allParams 
= ['value', 'min', 'max', 'pos', 'size', 'style', 
 576                  'tickfreq', 'pagesize', 'linesize', 'thumb', 'tick', 
 578     paramDict 
= {'value': ParamInt
, 'tickfreq': ParamIntNN
, 'pagesize': ParamIntNN
, 
 579                  'linesize': ParamIntNN
, 'thumb': ParamUnit
,  
 580                  'tick': ParamInt
, 'selmin': ParamInt
, 'selmax': ParamInt
} 
 581     required 
= ['value', 'min', 'max'] 
 582     winStyles 
= ['wxSL_HORIZONTAL', 'wxSL_VERTICAL', 'wxSL_AUTOTICKS', 'wxSL_LABELS', 
 583                  'wxSL_LEFT', 'wxSL_RIGHT', 'wxSL_TOP', 'wxSL_BOTTOM', 
 584                  'wxSL_BOTH', 'wxSL_SELRANGE', 'wxSL_INVERSE'] 
 586 class xxxGauge(xxxObject
): 
 587     allParams 
= ['range', 'pos', 'size', 'style', 'value', 'shadow', 'bezel'] 
 588     paramDict 
= {'range': ParamIntNN
, 'value': ParamIntNN
, 
 589                  'shadow': ParamIntNN
, 'bezel': ParamIntNN
} 
 590     winStyles 
= ['wxGA_HORIZONTAL', 'wxGA_VERTICAL', 'wxGA_PROGRESSBAR', 'wxGA_SMOOTH'] 
 592 class xxxScrollBar(xxxObject
): 
 593     allParams 
= ['pos', 'size', 'style', 'value', 'thumbsize', 'range', 'pagesize'] 
 594     paramDict 
= {'value': ParamIntNN
, 'range': ParamIntNN
, 'thumbsize': ParamIntNN
, 
 595                  'pagesize': ParamIntNN
} 
 596     winStyles 
= ['wxSB_HORIZONTAL', 'wxSB_VERTICAL'] 
 598 class xxxListCtrl(xxxObject
): 
 599     allParams 
= ['pos', 'size', 'style'] 
 600     winStyles 
= ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON', 
 601                  'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', 
 602                  'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER', 
 603                  'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING', 
 604                  'wxLC_VIRTUAL', 'wxLC_HRULES', 'wxLC_VRULES', 'wxLC_NO_SORT_HEADER'] 
 606 class xxxTreeCtrl(xxxObject
): 
 607     allParams 
= ['pos', 'size', 'style'] 
 608     winStyles 
= ['wxTR_EDIT_LABELS', 
 611                  'wxTR_TWIST_BUTTONS', 
 613                  'wxTR_FULL_ROW_HIGHLIGHT', 
 614                  'wxTR_LINES_AT_ROOT', 
 617                  'wxTR_HAS_VARIABLE_ROW_HEIGHT', 
 621                  'wxTR_DEFAULT_STYLE'] 
 623 class xxxHtmlWindow(xxxObject
): 
 624     allParams 
= ['pos', 'size', 'style', 'borders', 'url', 'htmlcode'] 
 625     paramDict 
= {'htmlcode':ParamMultilineText}
 
 626     winStyles 
= ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO', 'wxHW_NO_SELECTION'] 
 628 class xxxCalendarCtrl(xxxObject
): 
 629     allParams 
= ['pos', 'size', 'style'] 
 630     winStyles 
= ['wxCAL_SUNDAY_FIRST', 'wxCAL_MONDAY_FIRST', 'wxCAL_SHOW_HOLIDAYS', 
 631                  'wxCAL_NO_YEAR_CHANGE', 'wxCAL_NO_MONTH_CHANGE', 
 632                  'wxCAL_SEQUENTIAL_MONTH_SELECTION', 'wxCAL_SHOW_SURROUNDING_WEEKS'] 
 634 class xxxNotebook(xxxContainer
): 
 635     allParams 
= ['pos', 'size', 'style'] 
 636     winStyles 
= ['wxNB_TOP', 'wxNB_LEFT', 'wxNB_RIGHT', 'wxNB_BOTTOM', 
 637                  'wxNB_FIXEDWIDTH', 'wxNB_MULTILINE', 'wxNB_NOPAGETHEME', 'wxNB_FLAT'] 
 639 class xxxChoicebook(xxxContainer
): 
 640     allParams 
= ['pos', 'size', 'style'] 
 641     winStyles 
= ['wxCHB_DEFAULT', 'wxCHB_LEFT', 'wxCHB_RIGHT', 'wxCHB_TOP', 'wxCHB_BOTTOM'] 
 643 class xxxListbook(xxxContainer
): 
 644     allParams 
= ['pos', 'size', 'style'] 
 645     winStyles 
= ['wxLB_DEFAULT', 'wxLB_LEFT', 'wxLB_RIGHT', 'wxLB_TOP', 'wxLB_BOTTOM'] 
 647 class xxxSplitterWindow(xxxContainer
): 
 648     allParams 
= ['orientation', 'sashpos', 'minsize', 'pos', 'size', 'style'] 
 649     paramDict 
= {'orientation': ParamOrientation, 'sashpos': ParamUnit, 'minsize': ParamUnit }
 
 650     winStyles 
= ['wxSP_3D', 'wxSP_3DSASH', 'wxSP_3DBORDER',  
 651                  'wxSP_FULLSASH', 'wxSP_NOBORDER', 'wxSP_PERMIT_UNSPLIT', 'wxSP_LIVE_UPDATE', 
 654 class xxxGenericDirCtrl(xxxObject
): 
 655     allParams 
= ['defaultfolder', 'filter', 'defaultfilter', 'pos', 'size', 'style'] 
 656     paramDict 
= {'defaultfilter': ParamIntNN}
 
 657     winStyles 
= ['wxDIRCTRL_DIR_ONLY', 'wxDIRCTRL_3D_INTERNAL', 'wxDIRCTRL_SELECT_FIRST', 
 658                  'wxDIRCTRL_SHOW_FILTERS'] 
 660 class xxxScrolledWindow(xxxContainer
): 
 661     allParams 
= ['pos', 'size', 'style'] 
 662     winStyles 
= ['wxHSCROLL', 'wxVSCROLL', 'wxNO_3D', 'wxTAB_TRAVERSAL'] 
 664 class xxxDateCtrl(xxxObject
): 
 665     allParams 
= ['pos', 'size', 'style', 'borders'] 
 666     winStyles 
= ['wxDP_DEFAULT', 'wxDP_SPIN', 'wxDP_DROPDOWN', 
 667                  'wxDP_ALLOWNONE', 'wxDP_SHOWCENTURY'] 
 669 class xxxGrid(xxxObject
): 
 670     allParams 
= ['pos', 'size', 'style'] 
 672 class xxxFilePickerCtrl(xxxObject
): 
 673     allParams 
= ['value', 'message', 'wildcard', 'pos', 'size', 'style'] 
 674     winStyles 
= ['wxFLP_OPEN', 'wxFLP_SAVE', 'wxFLP_OVERWRITE_PROMPT', 
 675                  'wxFLP_FILE_MUST_EXIST', 'wxFLP_CHANGE_DIR', 
 676                  'wxFLP_DEFAULT_STYLE'] 
 679 ################################################################################ 
 682 class xxxButton(xxxObject
): 
 683     allParams 
= ['label', 'default', 'pos', 'size', 'style'] 
 684     paramDict 
= {'default': ParamBool}
 
 686     winStyles 
= ['wxBU_LEFT', 'wxBU_TOP', 'wxBU_RIGHT', 'wxBU_BOTTOM', 'wxBU_EXACTFIT', 
 689 class xxxBitmapButton(xxxObject
): 
 690     allParams 
= ['bitmap', 'selected', 'focus', 'disabled', 'default', 
 691                  'pos', 'size', 'style'] 
 692     paramDict 
= {'selected': ParamBitmap
, 'focus': ParamBitmap
, 'disabled': ParamBitmap
, 
 693                  'default': ParamBool
} 
 694     required 
= ['bitmap'] 
 695     winStyles 
= ['wxBU_AUTODRAW', 'wxBU_LEFT', 'wxBU_RIGHT', 
 696                  'wxBU_TOP', 'wxBU_BOTTOM'] 
 698 class xxxRadioButton(xxxObject
): 
 699     allParams 
= ['label', 'value', 'pos', 'size', 'style'] 
 700     paramDict 
= {'value': ParamBool}
 
 702     winStyles 
= ['wxRB_GROUP', 'wxRB_SINGLE'] 
 704 class xxxSpinButton(xxxObject
): 
 705     allParams 
= ['value', 'min', 'max', 'pos', 'size', 'style'] 
 706     paramDict 
= {'value': ParamInt}
 
 707     winStyles 
= ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP'] 
 709 class xxxSpinCtrl(xxxObject
): 
 710     allParams 
= ['value', 'min', 'max', 'pos', 'size', 'style'] 
 711     paramDict 
= {'value': ParamInt}
 
 712     winStyles 
= ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP'] 
 714 class xxxToggleButton(xxxObject
): 
 715     allParams 
= ['label', 'checked', 'pos', 'size', 'style'] 
 716     paramDict 
= {'checked': ParamBool}
 
 719 ################################################################################ 
 722 class xxxStaticBox(xxxObject
): 
 723     allParams 
= ['label', 'pos', 'size', 'style'] 
 726 class xxxRadioBox(xxxObject
): 
 727     allParams 
= ['label', 'content', 'selection', 'dimension', 'pos', 'size', 'style'] 
 728     paramDict 
= {'dimension': ParamIntNN}
 
 729     required 
= ['label', 'content'] 
 730     default 
= {'content': '[]'}
 
 731     winStyles 
= ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS', 'wxRA_HORIZONTAL', 
 734 class xxxCheckBox(xxxObject
): 
 735     allParams 
= ['label', 'checked', 'pos', 'size', 'style'] 
 736     paramDict 
= {'checked': ParamBool}
 
 737     winStyles 
= ['wxCHK_2STATE', 'wxCHK_3STATE', 'wxCHK_ALLOW_3RD_STATE_FOR_USER', 
 741 class xxxComboBox(xxxObject
): 
 742     allParams 
= ['content', 'selection', 'value', 'pos', 'size', 'style'] 
 743     required 
= ['content'] 
 744     default 
= {'content': '[]'}
 
 745     winStyles 
= ['wxCB_SIMPLE', 'wxCB_SORT', 'wxCB_READONLY', 'wxCB_DROPDOWN'] 
 747 class xxxListBox(xxxObject
): 
 748     allParams 
= ['content', 'selection', 'pos', 'size', 'style'] 
 749     required 
= ['content'] 
 750     default 
= {'content': '[]'}
 
 751     winStyles 
= ['wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL', 
 752                  'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT'] 
 754 class xxxCheckList(xxxObject
): 
 755     allParams 
= ['content', 'pos', 'size', 'style'] 
 756     required 
= ['content'] 
 757     default 
= {'content': '[]'}
 
 758     winStyles 
= ['wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL', 
 759                  'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT'] 
 760     paramDict 
= {'content': ParamContentCheckList}
 
 762 ################################################################################ 
 765 class xxxSizer(xxxContainer
): 
 766     hasName 
= hasStyle 
= False 
 767     paramDict 
= {'orient': ParamOrient}
 
 769     itemTag 
= 'sizeritem'               # different for some sizers 
 771 class xxxBoxSizer(xxxSizer
): 
 772     allParams 
= ['orient'] 
 773     required 
= ['orient'] 
 774     default 
= {'orient': 'wxVERTICAL'}
 
 775     # Tree icon depends on orientation 
 777         if self
.params
['orient'].value() == 'wxHORIZONTAL': return self
.imageH
 
 778         else: return self
.imageV
 
 780 class xxxStaticBoxSizer(xxxBoxSizer
): 
 781     allParams 
= ['label', 'orient'] 
 782     required 
= ['label', 'orient'] 
 784 class xxxGridSizer(xxxSizer
): 
 785     allParams 
= ['cols', 'rows', 'vgap', 'hgap'] 
 787     default 
= {'cols': '2', 'rows': '2'}
 
 789 class xxxStdDialogButtonSizer(xxxSizer
): 
 793 # For repeated parameters 
 795     def __init__(self
, node
): 
 797         self
.l
, self
.data 
= [], [] 
 798     def append(self
, param
): 
 800         self
.data
.append(param
.value()) 
 806         self
.l
, self
.data 
= [], [] 
 808 class xxxFlexGridSizer(xxxGridSizer
): 
 809     specials 
= ['growablecols', 'growablerows'] 
 810     allParams 
= ['cols', 'rows', 'vgap', 'hgap'] + specials
 
 811     paramDict 
= {'growablecols': ParamIntList, 'growablerows': ParamIntList}
 
 813 class xxxGridBagSizer(xxxSizer
): 
 814     specials 
= ['growablecols', 'growablerows'] 
 815     allParams 
= ['vgap', 'hgap'] + specials
 
 816     paramDict 
= {'growablecols': ParamIntList, 'growablerows': ParamIntList}
 
 818 # Container with only one child. 
 820 class xxxChildContainer(xxxObject
): 
 821     hasName 
= hasStyle 
= False 
 823     def __init__(self
, parent
, element
, refElem
=None): 
 824         xxxObject
.__init
__(self
, parent
, element
, refElem
) 
 825         # Must have one child with 'object' tag, but we don't check it 
 826         nodes 
= element
.childNodes
[:]   # create copy 
 828             if node
.nodeType 
== minidom
.Node
.ELEMENT_NODE
: 
 829                 if node
.tagName 
in ['object', 'object_ref']: 
 830                     # Create new xxx object for child node 
 831                     self
.child 
= MakeXXXFromDOM(self
, node
) 
 832                     self
.child
.parent 
= parent
 
 833                     # Copy hasChildren and isSizer attributes 
 834                     self
.hasChildren 
= self
.child
.hasChildren
 
 835                     self
.isSizer 
= self
.child
.isSizer
 
 838                 element
.removeChild(node
) 
 840         assert 0, 'no child found' 
 841     def resetChild(self
, xxx
): 
 842         '''Reset child info (for replacing with another class).''' 
 844         self
.hasChildren 
= xxx
.hasChildren
 
 845         self
.isSizer 
= xxx
.isSizer        
 
 847 class xxxSizerItem(xxxChildContainer
): 
 848     allParams 
= ['option', 'flag', 'border', 'minsize', 'ratio'] 
 849     paramDict 
= {'option': ParamInt, 'minsize': ParamPosSize, 'ratio': ParamPosSize}
 
 851     defaults_control 
= {} 
 852     def __init__(self
, parent
, element
, refElem
=None): 
 853         # For GridBag sizer items, extra parameters added 
 854         if isinstance(parent
, xxxGridBagSizer
): 
 855             self
.allParams 
= self
.allParams 
+ ['cellpos', 'cellspan'] 
 856         xxxChildContainer
.__init
__(self
, parent
, element
, refElem
) 
 857         # Remove pos parameter - not needed for sizeritems 
 858         if 'pos' in self
.child
.allParams
: 
 859             self
.child
.allParams 
= self
.child
.allParams
[:] 
 860             self
.child
.allParams
.remove('pos') 
 861     def resetChild(self
, xxx
): 
 862         xxxChildContainer
.resetChild(self
, xxx
) 
 863         # Remove pos parameter - not needed for sizeritems 
 864         if 'pos' in self
.child
.allParams
: 
 865             self
.child
.allParams 
= self
.child
.allParams
[:] 
 866             self
.child
.allParams
.remove('pos')         
 868 class xxxSizerItemButton(xxxSizerItem
): 
 871     def __init__(self
, parent
, element
, refElem
=None): 
 872         xxxChildContainer
.__init
__(self
, parent
, element
, refElem
=None) 
 873         # Remove pos parameter - not needed for sizeritems 
 874         if 'pos' in self
.child
.allParams
: 
 875             self
.child
.allParams 
= self
.child
.allParams
[:] 
 876             self
.child
.allParams
.remove('pos') 
 878 class xxxPage(xxxChildContainer
): 
 879     allParams 
= ['label', 'selected'] 
 880     paramDict 
= {'selected': ParamBool}
 
 882     def __init__(self
, parent
, element
, refElem
=None): 
 883         xxxChildContainer
.__init
__(self
, parent
, element
, refElem
) 
 884         # pos and size dont matter for notebookpages 
 885         if 'pos' in self
.child
.allParams
: 
 886             self
.child
.allParams 
= self
.child
.allParams
[:] 
 887             self
.child
.allParams
.remove('pos') 
 888         if 'size' in self
.child
.allParams
: 
 889             self
.child
.allParams 
= self
.child
.allParams
[:] 
 890             self
.child
.allParams
.remove('size') 
 892 class xxxSpacer(xxxObject
): 
 893     hasName 
= hasStyle 
= False 
 894     allParams 
= ['size', 'option', 'flag', 'border'] 
 895     paramDict 
= {'option': ParamInt}
 
 896     default 
= {'size': '0,0'}
 
 897     def __init__(self
, parent
, element
, refElem
=None): 
 898         # For GridBag sizer items, extra parameters added 
 899         if isinstance(parent
, xxxGridBagSizer
): 
 900             self
.allParams 
= self
.allParams 
+ ['cellpos', 'cellspan'] 
 901         xxxObject
.__init
__(self
, parent
, element
, refElem
) 
 903 class xxxMenuBar(xxxContainer
): 
 904     allParams 
= ['style'] 
 905     paramDict 
= {'style': ParamNonGenericStyle}    
# no generic styles 
 906     winStyles 
= ['wxMB_DOCKABLE'] 
 908 class xxxMenu(xxxContainer
): 
 909     allParams 
= ['label', 'help', 'style'] 
 910     default 
= {'label': ''}
 
 911     paramDict 
= {'style': ParamNonGenericStyle}    
# no generic styles 
 912     winStyles 
= ['wxMENU_TEAROFF'] 
 914 class xxxMenuItem(xxxObject
): 
 915     allParams 
= ['label', 'bitmap', 'accel', 'help', 
 916                  'checkable', 'radio', 'enabled', 'checked'] 
 917     default 
= {'label': ''}
 
 920 class xxxSeparator(xxxObject
): 
 921     hasName 
= hasStyle 
= False 
 923 ################################################################################ 
 926 class xxxUnknown(xxxObject
): 
 927     allParams 
= ['pos', 'size', 'style'] 
 928     winStyles 
= ['wxNO_FULL_REPAINT_ON_RESIZE'] 
 930 ################################################################################ 
 933 _handlers 
= []                          # custom handler classes/funcs 
 936 def setHandlers(handlers
): 
 939 _CFuncPtr 
= None                        # ctypes function type 
 942     """Register hndlr function or XmlResourceHandler class.""" 
 943     if _CFuncPtr 
and isinstance(hndlr
, _CFuncPtr
): 
 944         _handlers
.append(hndlr
) 
 946     if not isinstance(hndlr
, type): 
 947         wx
.LogError('handler is not a type: %s' % hndlr
) 
 948     elif not issubclass(hndlr
, wx
.xrc
.XmlResourceHandler
): 
 949         wx
.LogError('handler is not a XmlResourceHandler: %s' % hndlr
) 
 951         _handlers
.append(hndlr
) 
 953 def load_dl(path
, localname
=''): 
 954     """Load shared/dynamic library into xxx namespace. 
 956     If path is not absolute or relative, try to find in the module's directory. 
 959         localname 
= os
.path
.basename(os
.path
.splitext(path
)[0]) 
 963         _CFuncPtr 
= ctypes
._CFuncPtr    
# use as a flag of loaded ctypes 
 964         #if not os.path.dirname(path) and os.path.isfile(path): 
 967         wx
.LogError('ctypes module not found') 
 968         globals()[localname
] = None 
 971         dl 
= ctypes
.CDLL(path
) 
 972         globals()[localname
] = dl
 
 973         # Register AddXmlHandlers() if exists 
 975             register(dl
.AddXmlHandlers
) 
 979         wx
.LogError('error loading dynamic library: %s' % path
) 
 980         print traceback
.print_exc() 
 982 # Called when creating test window 
 985         if _CFuncPtr 
and isinstance(h
, _CFuncPtr
): 
 989                 wx
.LogError('error calling DL func: "%s"' % h
) 
 990                 print traceback
.print_exc() 
 993                 xrc
.XmlResource
.Get().AddHandler(apply(h
, ())) 
 995                 wx
.LogError('error adding XmlHandler: "%s"' % h
) 
 996                 print traceback
.print_exc() 
 998 def custom(klassName
, klass
='unknown'): 
 999     """Define custom control based on xrcClass. 
1001     klass: new object name 
1002     xrcClass: name of an existing XRC object class or 
1003               a class object defining class parameters. 
1005     if type(klass
) is str: 
1006         # Copy correct xxx class under new name 
1008         xxxClass 
= types
.ClassType('xxx' + klassName
, kl
.__bases
__, kl
.__dict
__) 
1011         # Register param IDs 
1012         for param 
in klass
.allParams 
+ klass
.paramDict
.keys(): 
1013             if not paramIDs
.has_key(param
): 
1014                 paramIDs
[param
] = wx
.NewId() 
1015     # Insert in dictionaty 
1016     xxxDict
[klassName
] = xxxClass
 
1018     g
.pullDownMenu
.addCustom(klassName
) 
1020 class xxxParamComment(xxxParam
): 
1021     locals = {}                         # namespace for comment directives 
1022     allow 
= None                        # undefined initial state for current file 
1023     def __init__(self
, node
): 
1024         xxxNode
.__init
__(self
, node
) 
1025         self
.textNode 
= node
 
1026         # Parse "pragma" comments if enabled 
1027         if node
.data 
and node
.data
[0] == '%' and g
.conf
.allowExec 
!= 'no' and \
 
1028                xxxParamComment
.allow 
is not False: 
1030             if g
.conf
.allowExec 
== 'ask' and xxxParamComment
.allow 
is None: 
1031                 flags 
= wx
.ICON_EXCLAMATION | wx
.YES_NO | wx
.CENTRE
 
1032                 dlg 
= wx
.MessageDialog(g
.frame
, ''' 
1033 This file contains executable %comment directives. Allow to execute?''', 
1035                 say 
= dlg
.ShowModal() 
1037                 if say 
== wx
.ID_YES
: 
1038                     xxxParamComment
.allow 
= True 
1040                     xxxParamComment
.allow 
= False 
1042                 code 
= node
.data
[1:] 
1043                 exec code 
in globals(), self
.locals 
1045                 wx
.LogError('exec error: "%s"' % code
) 
1046                 print traceback
.print_exc() 
1048 class xxxComment(xxxObject
): 
1049     hasStyle 
= hasName 
= False 
1050     allParams 
= required 
= ['comment'] 
1052     def __init__(self
, parent
, node
): 
1053         self
.parent 
= parent
 
1055         self
.isElement 
= False 
1057         self
.className 
= 'comment' 
1058         self
.ref 
= self
.subclass 
= None 
1059         self
.params 
= {'comment': xxxParamComment(node)}
 
1062         # Replace newlines by \n to avoid tree item resizing 
1063         return self
.params
['comment'].value().replace('\n', r
'\n') 
1065 ################################################################################ 
1067 # Mapping of XRC names to xxx classes 
1069     'wxPanel': xxxPanel
, 
1070     'wxDialog': xxxDialog
, 
1071     'wxFrame': xxxFrame
, 
1073     'wxToolBar': xxxToolBar
, 
1074     'wxStatusBar': xxxStatusBar
, 
1075     'wxWizard': xxxWizard
, 
1076     'wxWizardPage': xxxWizardPage
, 
1077     'wxWizardPageSimple': xxxWizardPageSimple
, 
1079     'wxBitmap': xxxBitmap
, 
1082     'wxButton': xxxButton
, 
1083     'wxBitmapButton': xxxBitmapButton
, 
1084     'wxRadioButton': xxxRadioButton
, 
1085     'wxSpinButton': xxxSpinButton
, 
1086     'wxToggleButton' : xxxToggleButton
, 
1088     'wxStaticBox': xxxStaticBox
, 
1089     'wxStaticBitmap': xxxStaticBitmap
, 
1090     'wxRadioBox': xxxRadioBox
, 
1091     'wxComboBox': xxxComboBox
, 
1092     'wxCheckBox': xxxCheckBox
, 
1093     'wxListBox': xxxListBox
, 
1095     'wxStaticText': xxxStaticText
, 
1096     'wxStaticLine': xxxStaticLine
, 
1097     'wxTextCtrl': xxxTextCtrl
, 
1098     'wxChoice': xxxChoice
, 
1099     'wxSlider': xxxSlider
, 
1100     'wxGauge': xxxGauge
, 
1101     'wxScrollBar': xxxScrollBar
, 
1102     'wxTreeCtrl': xxxTreeCtrl
, 
1103     'wxListCtrl': xxxListCtrl
, 
1104     'wxCheckListBox': xxxCheckList
, 
1105     'notebookpage': xxxPage
, 
1106     'choicebookpage': xxxPage
, 
1107     'listbookpage': xxxPage
, 
1108     'wxNotebook': xxxNotebook
, 
1109     'wxChoicebook': xxxChoicebook
, 
1110     'wxListbook': xxxListbook
, 
1111     'wxSplitterWindow': xxxSplitterWindow
, 
1112     'wxHtmlWindow': xxxHtmlWindow
, 
1113     'wxCalendarCtrl': xxxCalendarCtrl
, 
1114     'wxGenericDirCtrl': xxxGenericDirCtrl
, 
1115     'wxSpinCtrl': xxxSpinCtrl
, 
1116     'wxScrolledWindow': xxxScrolledWindow
, 
1118     'wxFilePickerCtrl': xxxFilePickerCtrl
, 
1119     'wxDatePickerCtrl': xxxDateCtrl
, 
1121     'wxBoxSizer': xxxBoxSizer
, 
1122     'wxStaticBoxSizer': xxxStaticBoxSizer
, 
1123     'wxGridSizer': xxxGridSizer
, 
1124     'wxFlexGridSizer': xxxFlexGridSizer
, 
1125     'wxGridBagSizer': xxxGridBagSizer
, 
1126     'wxStdDialogButtonSizer': xxxStdDialogButtonSizer
, 
1127     'sizeritem': xxxSizerItem
, 'button': xxxSizerItemButton
, 
1128     'spacer': xxxSpacer
, 
1130     'wxMenuBar': xxxMenuBar
, 
1132     'wxMenuItem': xxxMenuItem
, 
1133     'separator': xxxSeparator
, 
1135     'unknown': xxxUnknown
, 
1136     'comment': xxxComment
, 
1139 # Create IDs for all parameters of all classes 
1140 paramIDs 
= {'fg': wx
.NewId(), 'bg': wx
.NewId(), 'exstyle': wx
.NewId(), 'font': wx
.NewId(), 
1141             'enabled': wx
.NewId(), 'focused': wx
.NewId(), 'hidden': wx
.NewId(), 
1142             'tooltip': wx
.NewId(), 'encoding': wx
.NewId(), 
1143             'cellpos': wx
.NewId(), 'cellspan': wx
.NewId(), 
1146 for cl 
in xxxDict
.values(): 
1148         for param 
in cl
.allParams 
+ cl
.paramDict
.keys(): 
1149             if not paramIDs
.has_key(param
): 
1150                 paramIDs
[param
] = wx
.NewId() 
1152 ################################################################################ 
1155 # Test for object elements 
1157     return node
.nodeType 
== minidom
.Node
.ELEMENT_NODE 
and \
 
1158            node
.tagName 
in ['object', 'object_ref'] or \
 
1159            node
.nodeType 
== minidom
.Node
.COMMENT_NODE
 
1161 # Make XXX object from some DOM object, selecting correct class 
1162 def MakeXXXFromDOM(parent
, node
): 
1163     if node
.nodeType 
== minidom
.Node
.COMMENT_NODE
: 
1164         return xxxComment(parent
, node
) 
1165     if node
.tagName 
== 'object_ref': 
1166         ref 
= node
.getAttribute('ref') 
1167         refElem 
= FindResource(ref
) 
1168         if refElem
: cls 
= refElem
.getAttribute('class') 
1169         else: return xxxUnknown(parent
, node
) 
1172         cls 
= node
.getAttribute('class') 
1174         klass 
= xxxDict
[cls
] 
1176         # If we encounter a weird class, use unknown template 
1177         print 'WARNING: unsupported class:', node
.getAttribute('class') 
1179     return klass(parent
, node
, refElem
) 
1181 # Make empty DOM element 
1182 def MakeEmptyDOM(className
): 
1183     elem 
= g
.tree
.dom
.createElement('object') 
1184     elem
.setAttribute('class', className
) 
1185     # Set required and default parameters 
1186     xxxClass 
= xxxDict
[className
] 
1187     defaultNotRequired 
= filter(lambda x
, l
=xxxClass
.required
: x 
not in l
, 
1188                                 xxxClass
.default
.keys()) 
1189     for param 
in xxxClass
.required 
+ defaultNotRequired
: 
1190         textElem 
= g
.tree
.dom
.createElement(param
) 
1192             textNode 
= g
.tree
.dom
.createTextNode(xxxClass
.default
[param
]) 
1194             textNode 
= g
.tree
.dom
.createTextNode('') 
1195         textElem
.appendChild(textNode
) 
1196         elem
.appendChild(textElem
) 
1199 # Make empty XXX object 
1200 def MakeEmptyXXX(parent
, className
): 
1201     # Make corresponding DOM object first 
1202     elem 
= MakeEmptyDOM(className
) 
1203     # Special handling, e.g. if parent is a sizer, we should create 
1204     # sizeritem object, except for spacers, etc. 
1206         if parent
.isSizer 
and className 
!= 'spacer': 
1207             sizerItemElem 
= MakeEmptyDOM(parent
.itemTag
) 
1208             sizerItemElem
.appendChild(elem
) 
1209             elem 
= sizerItemElem
 
1210         elif isinstance(parent
, xxxNotebook
): 
1211             pageElem 
= MakeEmptyDOM('notebookpage') 
1212             pageElem
.appendChild(elem
) 
1214         elif isinstance(parent
, xxxChoicebook
): 
1215             pageElem 
= MakeEmptyDOM('choicebookpage') 
1216             pageElem
.appendChild(elem
) 
1218         elif isinstance(parent
, xxxListbook
): 
1219             pageElem 
= MakeEmptyDOM('listbookpage') 
1220             pageElem
.appendChild(elem
) 
1222     # Now just make object 
1223     xxx 
= MakeXXXFromDOM(parent
, elem
) 
1224     # Special defaults for new panels and controls 
1225     if isinstance(xxx
, xxxSizerItem
): 
1226         if isinstance(xxx
.child
, xxxContainer
) and not xxx
.child
.isSizer
: 
1227             for param
,v 
in xxxSizerItem
.defaults_panel
.items(): 
1229         elif isinstance(xxx
.child
, xxxObject
): 
1230             for param
,v 
in xxxSizerItem
.defaults_control
.items(): 
1234 # Make empty DOM element for reference 
1235 def MakeEmptyRefDOM(ref
): 
1236     elem 
= g
.tree
.dom
.createElement('object_ref') 
1237     elem
.setAttribute('ref', ref
) 
1240 # Make empty XXX object 
1241 def MakeEmptyRefXXX(parent
, ref
): 
1242     # Make corresponding DOM object first 
1243     elem 
= MakeEmptyRefDOM(ref
) 
1244     # If parent is a sizer, we should create sizeritem object, except for spacers 
1247             sizerItemElem 
= MakeEmptyDOM(parent
.itemTag
) 
1248             sizerItemElem
.appendChild(elem
) 
1249             elem 
= sizerItemElem
 
1250         elif isinstance(parent
, xxxNotebook
): 
1251             pageElem 
= MakeEmptyDOM('notebookpage') 
1252             pageElem
.appendChild(elem
) 
1254         elif isinstance(parent
, xxxChoicebook
): 
1255             pageElem 
= MakeEmptyDOM('choicebookpage') 
1256             pageElem
.appendChild(elem
) 
1258         elif isinstance(parent
, xxxListbook
): 
1259             pageElem 
= MakeEmptyDOM('listbookpage') 
1260             pageElem
.appendChild(elem
) 
1262     # Now just make object 
1263     xxx 
= MakeXXXFromDOM(parent
, elem
) 
1264     # Label is not used for references 
1265     xxx
.allParams 
= xxx
.allParams
[:] 
1266     #xxx.allParams.remove('label') 
1269 # Make empty comment node 
1270 def MakeEmptyCommentDOM(): 
1271     node 
= g
.tree
.dom
.createComment('') 
1274 # Make empty xxxComment 
1275 def MakeEmptyCommentXXX(parent
): 
1276     node 
= MakeEmptyCommentDOM() 
1277     # Now just make object 
1278     xxx 
= MakeXXXFromDOM(parent
, node
)