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
24 params
.buttonSize
= self
.DLG_SZE(buttonSize
)
26 # List of child windows
28 # Create scrolled windows for pages
29 self
.page1
= wxScrolledWindow(self
, -1)
31 sizer
.Add(wxBoxSizer()) # dummy sizer
32 self
.page1
.SetAutoLayout(True)
33 self
.page1
.SetSizer(sizer
)
34 self
.AddPage(self
.page1
, 'Properties')
36 self
.page2
= wxScrolledWindow(self
, -1)
38 sizer
.Add(wxBoxSizer()) # dummy sizer
39 self
.page2
.SetAutoLayout(True)
40 self
.page2
.SetSizer(sizer
)
41 # Cache for already used panels
42 self
.pageCache
= {} # cached property panels
43 self
.stylePageCache
= {} # cached style panels
44 # Dummy parent window for cache pages
45 self
.cacheParent
= wxFrame(None, -1, 'i am invisible')
46 # Delete child windows and recreate page sizer
47 def ResetPage(self
, page
):
48 topSizer
= page
.GetSizer()
49 sizer
= topSizer
.GetChildren()[0].GetSizer()
50 for w
in page
.GetChildren():
52 if isinstance(w
, ParamPage
):
53 # With SetParent, we wouldn't need this
54 w
.Reparent(self
.cacheParent
)
57 topSizer
.RemoveSizer(sizer
)
59 sizer
= wxBoxSizer(wxVERTICAL
)
60 # Special case - resize html window
62 topSizer
.Add(sizer
, 1, wxEXPAND
)
64 topSizer
.Add(sizer
, 0, wxALL
, 5)
66 def SetData(self
, xxx
):
69 # Set cached or new page
70 # Remove current objects and sizer
71 sizer
= self
.ResetPage(self
.page1
)
72 if not xxx
or (not xxx
.allParams
and not xxx
.hasName
):
74 sizer
.Add(wxStaticText(self
.page1
, -1, 'This item has no properties.'))
75 else: # nothing selected
76 # If first time, show some help
78 html
= wxHtmlWindow(self
.page1
, -1, wxDefaultPosition
,
79 wxDefaultSize
, wxSUNKEN_BORDER
)
80 html
.SetPage(g
.helpText
)
81 sizer
.Add(html
, 1, wxEXPAND
)
84 sizer
.Add(wxStaticText(self
.page1
, -1, 'Select a tree item.'))
86 g
.currentXXX
= xxx
.treeObject()
88 page
= self
.pageCache
[xxx
.__class
__]
89 page
.Reparent(self
.page1
)
91 page
= PropPage(self
.page1
, xxx
.className
, xxx
)
92 self
.pageCache
[xxx
.__class
__] = page
94 self
.pages
.append(page
)
95 sizer
.Add(page
, 1, wxEXPAND
)
97 # Special label for child objects - they may have different GUI
98 cacheID
= (xxx
.child
.__class
__, xxx
.__class
__)
100 page
= self
.pageCache
[cacheID
]
101 page
.Reparent(self
.page1
)
103 page
= PropPage(self
.page1
, xxx
.child
.className
, xxx
.child
)
104 self
.pageCache
[cacheID
] = page
105 page
.SetValues(xxx
.child
)
106 self
.pages
.append(page
)
107 sizer
.Add(page
, 0, wxEXPAND | wxTOP
, 5)
109 size
= self
.page1
.GetSizer().GetMinSize()
110 self
.page1
.SetScrollbars(1, 1, size
.x
, size
.y
, 0, 0, True)
113 # Create if does not exist
114 if xxx
and xxx
.treeObject().hasStyle
:
115 xxx
= xxx
.treeObject()
116 # Simplest case: set data if class is the same
117 sizer
= self
.ResetPage(self
.page2
)
119 page
= self
.stylePageCache
[xxx
.__class
__]
120 page
.Reparent(self
.page2
)
122 page
= StylePage(self
.page2
, xxx
.className
+ ' style', xxx
)
123 self
.stylePageCache
[xxx
.__class
__] = page
125 self
.pages
.append(page
)
126 sizer
.Add(page
, 0, wxEXPAND
)
127 # Add page if not exists
128 if not self
.GetPageCount() == 2:
129 self
.AddPage(self
.page2
, 'Style')
131 size
= self
.page2
.GetSizer().GetMinSize()
132 self
.page2
.SetScrollbars(1, 1, size
.x
, size
.y
, 0, 0, True)
134 # Remove page if exists
135 if self
.GetPageCount() == 2:
139 self
.modified
= False
142 self
.modified
= False
143 # If some parameter has changed
144 def IsModified(self
):
146 def SetModified(self
, value
):
147 # Register undo object when modifying first time
148 if not self
.modified
and value
:
149 g
.undoMan
.RegisterUndo(UndoEdit())
150 self
.modified
= value
152 for p
in self
.pages
: p
.Apply()
154 ################################################################################
156 # General class for notebook pages
157 class ParamPage(wxPanel
):
158 def __init__(self
, parent
, xxx
):
159 wxPanel
.__init
__(self
, parent
, -1)
161 # Register event handlers
162 for id in paramIDs
.values():
163 EVT_CHECKBOX(self
, id, self
.OnCheckParams
)
165 self
.controls
= {} # save python objects
166 self
.controlName
= None
168 def OnCheckParams(self
, evt
):
170 param
= evt
.GetEventObject().GetName()
171 w
= self
.controls
[param
]
173 objElem
= xxx
.element
175 # Ad new text node in order of allParams
176 w
.SetValue('') # set empty (default) value
177 w
.SetModified() # mark as changed
178 elem
= g
.tree
.dom
.createElement(param
)
179 # Some classes are special
181 xxx
.params
[param
] = xxxParamFont(xxx
.element
, elem
)
182 elif param
in xxxObject
.bitmapTags
:
183 xxx
.params
[param
] = xxxParamBitmap(elem
)
185 xxx
.params
[param
] = xxxParam(elem
)
186 # Find place to put new element: first present element after param
188 paramStyles
= xxx
.allParams
+ xxx
.styles
189 for p
in paramStyles
[paramStyles
.index(param
) + 1:]:
190 # Content params don't have same type
191 if xxx
.params
.has_key(p
) and p
!= 'content':
195 nextTextElem
= xxx
.params
[p
].node
196 objElem
.insertBefore(elem
, nextTextElem
)
198 objElem
.appendChild(elem
)
201 xxx
.params
[param
].remove()
202 del xxx
.params
[param
]
204 w
.modified
= False # mark as not changed
206 # Set modified flag (provokes undo storing is necessary)
207 panel
.SetModified(True)
211 name
= self
.controlName
.GetValue()
214 xxx
.element
.setAttribute('name', name
)
215 for param
, w
in self
.controls
.items():
217 paramObj
= xxx
.params
[param
]
219 if param
in xxx
.specials
:
220 xxx
.setSpecial(param
, value
)
222 paramObj
.update(value
)
225 self
.origChecks
= map(lambda i
: (i
[0], i
[1].GetValue()), self
.checks
.items())
226 self
.origControls
= map(lambda i
: (i
[0], i
[1].GetValue(), i
[1].IsEnabled()),
227 self
.controls
.items())
229 self
.origName
= self
.controlName
.GetValue()
230 # Return original values
233 return (self
.origChecks
, self
.origControls
, self
.origName
)
235 return (self
.origChecks
, self
.origControls
)
236 # Set values from undo data
237 def SetState(self
, state
):
239 self
.checks
[k
].SetValue(v
)
240 for k
,v
,e
in state
[1]:
241 self
.controls
[k
].SetValue(v
)
242 self
.controls
[k
].Enable(e
)
243 if e
: self
.controls
[k
].modified
= True
245 self
.controlName
.SetValue(state
[2])
247 ################################################################################
249 # Panel for displaying properties
250 class PropPage(ParamPage
):
251 def __init__(self
, parent
, label
, xxx
):
252 ParamPage
.__init
__(self
, parent
, xxx
)
253 box
= wxStaticBox(self
, -1, label
)
254 box
.SetFont(labelFont
)
255 topSizer
= wxStaticBoxSizer(box
, wxVERTICAL
)
256 sizer
= wxFlexGridSizer(len(xxx
.allParams
), 2, 1, 1)
257 sizer
.AddGrowableCol(1)
259 label
= wxStaticText(self
, -1, 'XML ID:', size
=(100,-1))
260 control
= ParamText(self
, 'XML_name', 200)
261 sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
),
262 (control
, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW
, 5) ])
263 self
.controlName
= control
264 for param
in xxx
.allParams
:
265 present
= xxx
.params
.has_key(param
)
266 if param
in xxx
.required
:
267 label
= wxStaticText(self
, paramIDs
[param
], param
+ ':',
268 size
= (100,-1), name
= param
)
270 # Notebook has one very loooooong parameter
271 if param
== 'usenotebooksizer': sParam
= 'usesizer:'
272 else: sParam
= param
+ ':'
273 label
= wxCheckBox(self
, paramIDs
[param
], sParam
,
274 size
= (100,-1), name
= param
)
275 self
.checks
[param
] = label
277 typeClass
= xxx
.paramDict
[param
]
281 typeClass
= paramDict
[param
]
284 typeClass
= ParamText
285 control
= typeClass(self
, param
)
286 control
.Enable(present
)
287 sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
),
288 (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ])
289 self
.controls
[param
] = control
290 topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3)
291 self
.SetAutoLayout(True)
292 self
.SetSizer(topSizer
)
294 def SetValues(self
, xxx
):
297 self
.origControls
= []
298 # Set values, checkboxes to False, disable defaults
300 self
.controlName
.SetValue(xxx
.name
)
301 self
.origName
= xxx
.name
302 for param
in xxx
.allParams
:
303 w
= self
.controls
[param
]
306 value
= xxx
.params
[param
].value()
309 if not param
in xxx
.required
:
310 self
.checks
[param
].SetValue(True)
311 self
.origChecks
.append((param
, True))
312 self
.origControls
.append((param
, value
, True))
314 self
.checks
[param
].SetValue(False)
317 self
.origChecks
.append((param
, False))
318 self
.origControls
.append((param
, '', False))
320 ################################################################################
322 # Style notebook page
323 class StylePage(ParamPage
):
324 def __init__(self
, parent
, label
, xxx
):
325 ParamPage
.__init
__(self
, parent
, xxx
)
326 box
= wxStaticBox(self
, -1, label
)
327 box
.SetFont(labelFont
)
328 topSizer
= wxStaticBoxSizer(box
, wxVERTICAL
)
329 sizer
= wxFlexGridSizer(len(xxx
.styles
), 2, 1, 1)
330 sizer
.AddGrowableCol(1)
331 for param
in xxx
.styles
:
332 present
= xxx
.params
.has_key(param
)
333 check
= wxCheckBox(self
, paramIDs
[param
],
334 param
+ ':', size
= (100,-1), name
= param
)
335 check
.SetValue(present
)
336 control
= paramDict
[param
](self
, name
= param
)
337 control
.Enable(present
)
338 sizer
.AddMany([ (check
, 0, wxALIGN_CENTER_VERTICAL
),
339 (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ])
340 self
.checks
[param
] = check
341 self
.controls
[param
] = control
342 topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3)
343 self
.SetAutoLayout(True)
344 self
.SetSizer(topSizer
)
346 # Set data for a cahced page
347 def SetValues(self
, xxx
):
350 self
.origControls
= []
351 for param
in xxx
.styles
:
352 present
= xxx
.params
.has_key(param
)
353 check
= self
.checks
[param
]
354 check
.SetValue(present
)
355 w
= self
.controls
[param
]
358 value
= xxx
.params
[param
].value()
363 self
.origChecks
.append((param
, present
))
364 self
.origControls
.append((param
, value
, present
))