2 # Purpose:      XRC editor, Panel class and related 
   3 # Author:       Roman Rolinsky <rolinsky@mema.ucl.ac.be> 
   7 from xxx 
import *                       # xxx imports globals and params 
   9 from wxPython
.html 
import wxHtmlWindow
 
  11 # Properties panel containing notebook 
  12 class Panel(wxNotebook
): 
  13     def __init__(self
, parent
, id = -1): 
  14         if wxPlatform 
!= '__WXMAC__':   # some problems with this style on macs 
  15             wxNotebook
.__init
__(self
, parent
, id, style
=wxNB_BOTTOM
) 
  17             wxNotebook
.__init
__(self
, parent
, id) 
  19         g
.panel 
= panel 
= self
 
  22         # Set common button size for parameter buttons 
  23         bTmp 
= wxButton(self
, -1, '') 
  25         params
.buttonSize 
= (self
.DLG_SZE(buttonSize
)[0], bTmp
.GetSize()[1]) 
  29         # List of child windows 
  31         # Create scrolled windows for pages 
  32         self
.page1 
= wxScrolledWindow(self
, -1) 
  34         sizer
.Add(wxBoxSizer())         # dummy sizer 
  35         self
.page1
.SetAutoLayout(True) 
  36         self
.page1
.SetSizer(sizer
) 
  37         self
.AddPage(self
.page1
, 'Properties') 
  39         self
.page2 
= wxScrolledWindow(self
, -1) 
  42         sizer
.Add(wxBoxSizer())         # dummy sizer 
  43         self
.page2
.SetAutoLayout(True) 
  44         self
.page2
.SetSizer(sizer
) 
  45         # Cache for already used panels 
  46         self
.pageCache 
= {}             # cached property panels 
  47         self
.stylePageCache 
= {}        # cached style panels 
  49     # Delete child windows and recreate page sizer 
  50     def ResetPage(self
, page
): 
  51         topSizer 
= page
.GetSizer() 
  52         sizer 
= topSizer
.GetChildren()[0].GetSizer() 
  53         for w 
in page
.GetChildren(): 
  55             if isinstance(w
, ParamPage
): 
  60         topSizer
.Remove(sizer
) 
  62         sizer 
= wxBoxSizer(wxVERTICAL
) 
  63         # Special case - resize html window 
  65             topSizer
.Add(sizer
, 1, wxEXPAND
) 
  67             topSizer
.Add(sizer
, 0, wxALL
, 5) 
  70     def SetData(self
, xxx
): 
  73         # Remove current objects and sizer 
  74         sizer 
= self
.ResetPage(self
.page1
) 
  75         if not xxx 
or (not xxx
.allParams 
and not xxx
.hasName
): 
  77                 sizer
.Add(wxStaticText(self
.page1
, -1, 'This item has no properties.')) 
  78             else:                       # nothing selected 
  79                 # If first time, show some help 
  81                     html 
= wxHtmlWindow(self
.page1
, -1, wxDefaultPosition
, 
  82                                         wxDefaultSize
, wxSUNKEN_BORDER
) 
  83                     html
.SetPage(g
.helpText
) 
  84                     sizer
.Add(html
, 1, wxEXPAND
) 
  87                     sizer
.Add(wxStaticText(self
.page1
, -1, 'Select a tree item.')) 
  89             g
.currentXXX 
= xxx
.treeObject() 
  90             # Normal or SizerItem page 
  91             isGBSizerItem 
= isinstance(xxx
.parent
, xxxGridBagSizer
) 
  92             cacheID 
= (xxx
.__class
__, isGBSizerItem
)             
  94                 page 
= self
.pageCache
[cacheID
] 
  95                 page
.box
.SetLabel(xxx
.panelName()) 
  98                 page 
= PropPage(self
.page1
, xxx
.panelName(), xxx
) 
  99                 self
.pageCache
[cacheID
] = page
 
 101             self
.pages
.append(page
) 
 102             sizer
.Add(page
, 1, wxEXPAND
) 
 104                 # Special label for child objects - they may have different GUI 
 105                 cacheID 
= (xxx
.child
.__class
__, xxx
.__class
__) 
 107                     page 
= self
.pageCache
[cacheID
] 
 108                     page
.box
.SetLabel(xxx
.child
.panelName()) 
 111                     page 
= PropPage(self
.page1
, xxx
.child
.panelName(), xxx
.child
) 
 112                     self
.pageCache
[cacheID
] = page
 
 113                 page
.SetValues(xxx
.child
) 
 114                 self
.pages
.append(page
) 
 115                 sizer
.Add(page
, 0, wxEXPAND | wxTOP
, 5) 
 117         size 
= self
.page1
.GetSizer().GetMinSize() 
 118         self
.page1
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True) 
 121         # Create if does not exist 
 122         if xxx 
and xxx
.treeObject().hasStyle
: 
 123             xxx 
= xxx
.treeObject() 
 124             # Simplest case: set data if class is the same 
 125             sizer 
= self
.ResetPage(self
.page2
) 
 127                 page 
= self
.stylePageCache
[xxx
.__class
__] 
 130                 page 
= StylePage(self
.page2
, xxx
.className 
+ ' style', xxx
) 
 131                 self
.stylePageCache
[xxx
.__class
__] = page
 
 133             self
.pages
.append(page
) 
 134             sizer
.Add(page
, 0, wxEXPAND
) 
 135             # Add page if not exists 
 136             if not self
.GetPageCount() == 2: 
 137                 self
.AddPage(self
.page2
, 'Style') 
 139             if 'wxGTK' in wx
.PlatformInfo
: 
 140                 self
.page2
.Show(True) 
 141             size 
= self
.page2
.GetSizer().GetMinSize() 
 142             self
.page2
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True) 
 144             # Remove page if exists 
 145             if self
.GetPageCount() == 2: 
 149         self
.modified 
= False 
 153         self
.modified 
= False 
 155     # If some parameter has changed 
 156     def IsModified(self
): 
 159     def SetModified(self
, value
): 
 160         # Register undo object when modifying first time 
 161         if not self
.modified 
and value
: 
 162            g
.undoMan
.RegisterUndo(UndoEdit()) 
 163         self
.modified 
= value
 
 166         for p 
in self
.pages
: p
.Apply() 
 168 ################################################################################ 
 170 # General class for notebook pages 
 171 class ParamPage(wxPanel
): 
 172     def __init__(self
, parent
, xxx
): 
 173         wxPanel
.__init
__(self
, parent
, -1) 
 174         self
.SetBackgroundColour(parent
.GetBackgroundColour()) 
 175         self
.SetForegroundColour(parent
.GetForegroundColour()) 
 177         # Register event handlers 
 178         for id in paramIDs
.values(): 
 179             EVT_CHECKBOX(self
, id, self
.OnCheckParams
) 
 181         self
.controls 
= {}              # save python objects 
 182         self
.controlName 
= None 
 184     def OnCheckParams(self
, evt
): 
 186         param 
= evt
.GetEventObject().GetName() 
 187         w 
= self
.controls
[param
] 
 189         objElem 
= xxx
.element
 
 191             # Ad  new text node in order of allParams 
 192             w
.SetValue('')              # set empty (default) value 
 193             w
.SetModified()             # mark as changed 
 194             elem 
= g
.tree
.dom
.createElement(param
) 
 195             # Some classes are special 
 197                 xxx
.params
[param
] = xxxParamFont(xxx
.element
, elem
) 
 198             elif param 
in xxxObject
.bitmapTags
: 
 199                 xxx
.params
[param
] = xxxParamBitmap(elem
) 
 201                 xxx
.params
[param
] = xxxParam(elem
) 
 202             # Find place to put new element: first present element after param 
 205                 paramStyles 
= xxx
.allParams 
+ xxx
.styles
 
 207                 paramStyles 
= xxx
.allParams 
 
 208             for p 
in paramStyles
[paramStyles
.index(param
) + 1:]: 
 209                 # Content params don't have same type 
 210                 if xxx
.params
.has_key(p
) and p 
!= 'content': 
 214                 nextTextElem 
= xxx
.params
[p
].node
 
 215                 objElem
.insertBefore(elem
, nextTextElem
) 
 217                 objElem
.appendChild(elem
) 
 220             xxx
.params
[param
].remove() 
 221             del xxx
.params
[param
] 
 223             w
.modified 
= False          # mark as not changed 
 225         # Set modified flag (provokes undo storing is necessary) 
 226         panel
.SetModified(True) 
 230             name 
= self
.controlName
.GetValue() 
 233                 xxx
.element
.setAttribute('name', name
) 
 234         for param
, w 
in self
.controls
.items(): 
 236                 paramObj 
= xxx
.params
[param
] 
 238                 if param 
in xxx
.specials
: 
 239                     xxx
.setSpecial(param
, value
) 
 241                     paramObj
.update(value
) 
 244         self
.origChecks 
= map(lambda i
: (i
[0], i
[1].GetValue()), self
.checks
.items()) 
 245         self
.origControls 
= map(lambda i
: (i
[0], i
[1].GetValue(), i
[1].IsEnabled()), 
 246                             self
.controls
.items()) 
 248             self
.origName 
= self
.controlName
.GetValue() 
 249     # Return original values 
 252             return (self
.origChecks
, self
.origControls
, self
.origName
) 
 254             return (self
.origChecks
, self
.origControls
) 
 255     # Set values from undo data 
 256     def SetState(self
, state
): 
 258             self
.checks
[k
].SetValue(v
) 
 259         for k
,v
,e 
in state
[1]: 
 260             self
.controls
[k
].SetValue(v
) 
 261             self
.controls
[k
].Enable(e
) 
 262             if e
: self
.controls
[k
].modified 
= True 
 264             self
.controlName
.SetValue(state
[2]) 
 266 ################################################################################ 
 270 # Panel for displaying properties 
 271 class PropPage(ParamPage
): 
 272     def __init__(self
, parent
, label
, xxx
): 
 273         ParamPage
.__init
__(self
, parent
, xxx
) 
 274         self
.box 
= wxStaticBox(self
, -1, label
) 
 275         self
.box
.SetFont(g
.labelFont()) 
 276         topSizer 
= wxStaticBoxSizer(self
.box
, wxVERTICAL
) 
 277         sizer 
= wxFlexGridSizer(len(xxx
.allParams
), 2, 1, 1) 
 278         sizer
.AddGrowableCol(1) 
 280             label 
= wxStaticText(self
, -1, 'XML ID:', size
=(LABEL_WIDTH
,-1)) 
 281             control 
= ParamText(self
, 'XML_name', 200) 
 282             sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
), 
 283                             (control
, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW
, 5) ]) 
 284             self
.controlName 
= control
 
 285         for param 
in xxx
.allParams
: 
 286             present 
= xxx
.params
.has_key(param
) 
 287             if param 
in xxx
.required
: 
 288                 label 
= wxStaticText(self
, paramIDs
[param
], param 
+ ':', 
 289                                      size 
= (LABEL_WIDTH
,-1), name 
= param
) 
 291                 # Notebook has one very loooooong parameter 
 292                 if param 
== 'usenotebooksizer': sParam 
= 'usesizer:' 
 293                 else: sParam 
= param 
+ ':' 
 294                 label 
= wxCheckBox(self
, paramIDs
[param
], sParam
, 
 295                                    size 
= (LABEL_WIDTH
,-1), name 
= param
) 
 296                 self
.checks
[param
] = label
 
 298                 typeClass 
= xxx
.paramDict
[param
] 
 302                     typeClass 
= paramDict
[param
] 
 305                     typeClass 
= ParamText
 
 306             control 
= typeClass(self
, param
) 
 307             control
.Enable(present
) 
 308             sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
), 
 309                             (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ]) 
 310             self
.controls
[param
] = control
 
 311         topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3) 
 312         self
.SetAutoLayout(True) 
 313         self
.SetSizer(topSizer
) 
 315     def SetValues(self
, xxx
): 
 318         self
.origControls 
= [] 
 319         # Set values, checkboxes to False, disable defaults 
 321             self
.controlName
.SetValue(xxx
.name
) 
 322             self
.origName 
= xxx
.name
 
 323         for param 
in xxx
.allParams
: 
 324             w 
= self
.controls
[param
] 
 327                 value 
= xxx
.params
[param
].value() 
 330                 if not param 
in xxx
.required
: 
 331                     self
.checks
[param
].SetValue(True) 
 332                     self
.origChecks
.append((param
, True)) 
 333                 self
.origControls
.append((param
, value
, True)) 
 335                 self
.checks
[param
].SetValue(False) 
 338                 self
.origChecks
.append((param
, False)) 
 339                 self
.origControls
.append((param
, '', False)) 
 341 ################################################################################ 
 343 # Style notebook page 
 344 class StylePage(ParamPage
): 
 345     def __init__(self
, parent
, label
, xxx
): 
 346         ParamPage
.__init
__(self
, parent
, xxx
) 
 347         box 
= wxStaticBox(self
, -1, label
) 
 348         box
.SetFont(g
.labelFont()) 
 349         topSizer 
= wxStaticBoxSizer(box
, wxVERTICAL
) 
 350         sizer 
= wxFlexGridSizer(len(xxx
.styles
), 2, 1, 1) 
 351         sizer
.AddGrowableCol(1) 
 352         for param 
in xxx
.styles
: 
 353             present 
= xxx
.params
.has_key(param
) 
 354             check 
= wxCheckBox(self
, paramIDs
[param
], 
 355                                param 
+ ':', size 
= (LABEL_WIDTH
,-1), name 
= param
) 
 356             check
.SetValue(present
) 
 357             control 
= paramDict
[param
](self
, name 
= param
) 
 358             control
.Enable(present
) 
 359             sizer
.AddMany([ (check
, 0, wxALIGN_CENTER_VERTICAL
), 
 360                             (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ]) 
 361             self
.checks
[param
] = check
 
 362             self
.controls
[param
] = control
 
 363         topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3) 
 364         self
.SetAutoLayout(True) 
 365         self
.SetSizer(topSizer
) 
 367     # Set data for a cahced page 
 368     def SetValues(self
, xxx
): 
 371         self
.origControls 
= [] 
 372         for param 
in xxx
.styles
: 
 373             present 
= xxx
.params
.has_key(param
) 
 374             check 
= self
.checks
[param
] 
 375             check
.SetValue(present
) 
 376             w 
= self
.controls
[param
] 
 379                 value 
= xxx
.params
[param
].value() 
 384             self
.origChecks
.append((param
, present
)) 
 385             self
.origControls
.append((param
, value
, present
))