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
)
16 self
.SetBackgroundColour(parent
.GetBackgroundColour())
18 wxNotebook
.__init
__(self
, parent
, id)
20 g
.panel
= panel
= self
23 # Set common button size for parameter buttons
24 bTmp
= wxButton(self
, -1, '')
26 params
.buttonSize
= (self
.DLG_SZE(buttonSize
)[0], bTmp
.GetSize()[1])
30 # List of child windows
32 # Create scrolled windows for pages
33 self
.page1
= wxScrolledWindow(self
, -1)
35 sizer
.Add(wxBoxSizer()) # dummy sizer
36 self
.page1
.SetAutoLayout(True)
37 self
.page1
.SetSizer(sizer
)
38 self
.AddPage(self
.page1
, 'Properties')
40 self
.page2
= wxScrolledWindow(self
, -1)
43 sizer
.Add(wxBoxSizer()) # dummy sizer
44 self
.page2
.SetAutoLayout(True)
45 self
.page2
.SetSizer(sizer
)
46 # Cache for already used panels
47 self
.pageCache
= {} # cached property panels
48 self
.stylePageCache
= {} # cached style panels
50 # Delete child windows and recreate page sizer
51 def ResetPage(self
, page
):
52 topSizer
= page
.GetSizer()
53 sizer
= topSizer
.GetChildren()[0].GetSizer()
54 for w
in page
.GetChildren():
56 if isinstance(w
, ParamPage
):
61 topSizer
.Remove(sizer
)
63 sizer
= wxBoxSizer(wxVERTICAL
)
64 # Special case - resize html window
66 topSizer
.Add(sizer
, 1, wxEXPAND
)
68 topSizer
.Add(sizer
, 0, wxALL
, 5)
71 def SetData(self
, xxx
):
74 # Remove current objects and sizer
75 sizer
= self
.ResetPage(self
.page1
)
76 if not xxx
or (not xxx
.allParams
and not xxx
.hasName
):
78 sizer
.Add(wxStaticText(self
.page1
, -1, 'This item has no properties.'))
79 else: # nothing selected
80 # If first time, show some help
82 html
= wxHtmlWindow(self
.page1
, -1, wxDefaultPosition
,
83 wxDefaultSize
, wxSUNKEN_BORDER
)
84 html
.SetPage(g
.helpText
)
85 sizer
.Add(html
, 1, wxEXPAND
)
88 sizer
.Add(wxStaticText(self
.page1
, -1, 'Select a tree item.'))
90 g
.currentXXX
= xxx
.treeObject()
91 # Normal or SizerItem page
92 isGBSizerItem
= isinstance(xxx
.parent
, xxxGridBagSizer
)
93 cacheID
= (xxx
.__class
__, isGBSizerItem
)
95 page
= self
.pageCache
[cacheID
]
96 page
.box
.SetLabel(xxx
.panelName())
99 page
= PropPage(self
.page1
, xxx
.panelName(), xxx
)
100 self
.pageCache
[cacheID
] = page
102 self
.pages
.append(page
)
103 sizer
.Add(page
, 1, wxEXPAND
)
105 # Special label for child objects - they may have different GUI
106 cacheID
= (xxx
.child
.__class
__, xxx
.__class
__)
108 page
= self
.pageCache
[cacheID
]
109 page
.box
.SetLabel(xxx
.child
.panelName())
112 page
= PropPage(self
.page1
, xxx
.child
.panelName(), xxx
.child
)
113 self
.pageCache
[cacheID
] = page
114 page
.SetValues(xxx
.child
)
115 self
.pages
.append(page
)
116 sizer
.Add(page
, 0, wxEXPAND | wxTOP
, 5)
118 size
= self
.page1
.GetSizer().GetMinSize()
119 self
.page1
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True)
122 # Create if does not exist
123 if xxx
and xxx
.treeObject().hasStyle
:
124 xxx
= xxx
.treeObject()
125 # Simplest case: set data if class is the same
126 sizer
= self
.ResetPage(self
.page2
)
128 page
= self
.stylePageCache
[xxx
.__class
__]
131 page
= StylePage(self
.page2
, xxx
.className
+ ' style', xxx
)
132 self
.stylePageCache
[xxx
.__class
__] = page
134 self
.pages
.append(page
)
135 sizer
.Add(page
, 0, wxEXPAND
)
136 # Add page if not exists
137 if not self
.GetPageCount() == 2:
138 self
.AddPage(self
.page2
, 'Style')
140 if 'wxGTK' in wx
.PlatformInfo
:
141 self
.page2
.Show(True)
142 size
= self
.page2
.GetSizer().GetMinSize()
143 self
.page2
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True)
145 # Remove page if exists
146 if self
.GetPageCount() == 2:
150 self
.modified
= False
154 self
.modified
= False
156 # If some parameter has changed
157 def IsModified(self
):
160 def SetModified(self
, value
):
161 # Register undo object when modifying first time
162 if not self
.modified
and value
:
163 g
.undoMan
.RegisterUndo(UndoEdit())
164 self
.modified
= value
167 for p
in self
.pages
: p
.Apply()
169 ################################################################################
171 # General class for notebook pages
172 class ParamPage(wxPanel
):
173 def __init__(self
, parent
, xxx
):
174 wxPanel
.__init
__(self
, parent
, -1)
175 self
.SetBackgroundColour(parent
.GetBackgroundColour())
176 self
.SetForegroundColour(parent
.GetForegroundColour())
178 # Register event handlers
179 for id in paramIDs
.values():
180 EVT_CHECKBOX(self
, id, self
.OnCheckParams
)
182 self
.controls
= {} # save python objects
183 self
.controlName
= None
185 def OnCheckParams(self
, evt
):
187 param
= evt
.GetEventObject().GetName()
188 w
= self
.controls
[param
]
190 objElem
= xxx
.element
192 # Ad new text node in order of allParams
193 w
.SetValue('') # set empty (default) value
194 w
.SetModified() # mark as changed
195 elem
= g
.tree
.dom
.createElement(param
)
196 # Some classes are special
198 xxx
.params
[param
] = xxxParamFont(xxx
.element
, elem
)
199 elif param
in xxxObject
.bitmapTags
:
200 xxx
.params
[param
] = xxxParamBitmap(elem
)
202 xxx
.params
[param
] = xxxParam(elem
)
203 # Find place to put new element: first present element after param
206 paramStyles
= xxx
.allParams
+ xxx
.styles
208 paramStyles
= xxx
.allParams
209 for p
in paramStyles
[paramStyles
.index(param
) + 1:]:
210 # Content params don't have same type
211 if xxx
.params
.has_key(p
) and p
!= 'content':
215 nextTextElem
= xxx
.params
[p
].node
216 objElem
.insertBefore(elem
, nextTextElem
)
218 objElem
.appendChild(elem
)
221 xxx
.params
[param
].remove()
222 del xxx
.params
[param
]
224 w
.modified
= False # mark as not changed
226 # Set modified flag (provokes undo storing is necessary)
227 panel
.SetModified(True)
231 name
= self
.controlName
.GetValue()
234 xxx
.element
.setAttribute('name', name
)
235 for param
, w
in self
.controls
.items():
237 paramObj
= xxx
.params
[param
]
239 if param
in xxx
.specials
:
240 xxx
.setSpecial(param
, value
)
242 paramObj
.update(value
)
245 self
.origChecks
= map(lambda i
: (i
[0], i
[1].GetValue()), self
.checks
.items())
246 self
.origControls
= map(lambda i
: (i
[0], i
[1].GetValue(), i
[1].IsEnabled()),
247 self
.controls
.items())
249 self
.origName
= self
.controlName
.GetValue()
250 # Return original values
253 return (self
.origChecks
, self
.origControls
, self
.origName
)
255 return (self
.origChecks
, self
.origControls
)
256 # Set values from undo data
257 def SetState(self
, state
):
259 self
.checks
[k
].SetValue(v
)
260 for k
,v
,e
in state
[1]:
261 self
.controls
[k
].SetValue(v
)
262 self
.controls
[k
].Enable(e
)
263 if e
: self
.controls
[k
].modified
= True
265 self
.controlName
.SetValue(state
[2])
267 ################################################################################
271 # Panel for displaying properties
272 class PropPage(ParamPage
):
273 def __init__(self
, parent
, label
, xxx
):
274 ParamPage
.__init
__(self
, parent
, xxx
)
275 self
.box
= wxStaticBox(self
, -1, label
)
276 self
.box
.SetFont(g
.labelFont())
277 topSizer
= wxStaticBoxSizer(self
.box
, wxVERTICAL
)
278 sizer
= wxFlexGridSizer(len(xxx
.allParams
), 2, 1, 1)
279 sizer
.AddGrowableCol(1)
281 label
= wxStaticText(self
, -1, 'XML ID:', size
=(LABEL_WIDTH
,-1))
282 control
= ParamText(self
, 'XML_name', 200)
283 sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
),
284 (control
, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW
, 5) ])
285 self
.controlName
= control
286 for param
in xxx
.allParams
:
287 present
= xxx
.params
.has_key(param
)
288 if param
in xxx
.required
:
289 label
= wxStaticText(self
, paramIDs
[param
], param
+ ':',
290 size
= (LABEL_WIDTH
,-1), name
= param
)
292 # Notebook has one very loooooong parameter
293 if param
== 'usenotebooksizer': sParam
= 'usesizer:'
294 else: sParam
= param
+ ':'
295 label
= wxCheckBox(self
, paramIDs
[param
], sParam
,
296 size
= (LABEL_WIDTH
,-1), name
= param
)
297 self
.checks
[param
] = label
299 typeClass
= xxx
.paramDict
[param
]
303 typeClass
= paramDict
[param
]
306 typeClass
= ParamText
307 control
= typeClass(self
, param
)
308 control
.Enable(present
)
309 sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
),
310 (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ])
311 self
.controls
[param
] = control
312 topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3)
313 self
.SetAutoLayout(True)
314 self
.SetSizer(topSizer
)
316 def SetValues(self
, xxx
):
319 self
.origControls
= []
320 # Set values, checkboxes to False, disable defaults
322 self
.controlName
.SetValue(xxx
.name
)
323 self
.origName
= xxx
.name
324 for param
in xxx
.allParams
:
325 w
= self
.controls
[param
]
328 value
= xxx
.params
[param
].value()
331 if not param
in xxx
.required
:
332 self
.checks
[param
].SetValue(True)
333 self
.origChecks
.append((param
, True))
334 self
.origControls
.append((param
, value
, True))
336 self
.checks
[param
].SetValue(False)
339 self
.origChecks
.append((param
, False))
340 self
.origControls
.append((param
, '', False))
342 ################################################################################
344 # Style notebook page
345 class StylePage(ParamPage
):
346 def __init__(self
, parent
, label
, xxx
):
347 ParamPage
.__init
__(self
, parent
, xxx
)
348 box
= wxStaticBox(self
, -1, label
)
349 box
.SetFont(g
.labelFont())
350 topSizer
= wxStaticBoxSizer(box
, wxVERTICAL
)
351 sizer
= wxFlexGridSizer(len(xxx
.styles
), 2, 1, 1)
352 sizer
.AddGrowableCol(1)
353 for param
in xxx
.styles
:
354 present
= xxx
.params
.has_key(param
)
355 check
= wxCheckBox(self
, paramIDs
[param
],
356 param
+ ':', size
= (LABEL_WIDTH
,-1), name
= param
)
357 check
.SetValue(present
)
358 control
= paramDict
[param
](self
, name
= param
)
359 control
.Enable(present
)
360 sizer
.AddMany([ (check
, 0, wxALIGN_CENTER_VERTICAL
),
361 (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ])
362 self
.checks
[param
] = check
363 self
.controls
[param
] = control
364 topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3)
365 self
.SetAutoLayout(True)
366 self
.SetSizer(topSizer
)
368 # Set data for a cahced page
369 def SetValues(self
, xxx
):
372 self
.origControls
= []
373 for param
in xxx
.styles
:
374 present
= xxx
.params
.has_key(param
)
375 check
= self
.checks
[param
]
376 check
.SetValue(present
)
377 w
= self
.controls
[param
]
380 value
= xxx
.params
[param
].value()
385 self
.origChecks
.append((param
, present
))
386 self
.origControls
.append((param
, value
, present
))