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)
41 sizer
.Add(wxBoxSizer()) # dummy sizer
42 self
.page2
.SetAutoLayout(True)
43 self
.page2
.SetSizer(sizer
)
44 # Cache for already used panels
45 self
.pageCache
= {} # cached property panels
46 self
.stylePageCache
= {} # cached style panels
47 # Dummy parent window for cache pages
48 self
.cacheParent
= wxFrame(None, -1, 'i am invisible')
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
):
56 # With SetParent, we wouldn't need this
57 w
.Reparent(self
.cacheParent
)
60 topSizer
.RemoveSizer(sizer
)
62 sizer
= wxBoxSizer(wxVERTICAL
)
63 # Special case - resize html window
65 topSizer
.Add(sizer
, 1, wxEXPAND
)
67 topSizer
.Add(sizer
, 0, wxALL
, 5)
69 def SetData(self
, xxx
):
72 # Set cached or new page
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()
91 page
= self
.pageCache
[xxx
.__class
__]
92 page
.box
.SetLabel(xxx
.panelName())
93 page
.Reparent(self
.page1
)
95 page
= PropPage(self
.page1
, xxx
.panelName(), xxx
)
96 self
.pageCache
[xxx
.__class
__] = page
98 self
.pages
.append(page
)
99 sizer
.Add(page
, 1, wxEXPAND
)
101 # Special label for child objects - they may have different GUI
102 cacheID
= (xxx
.child
.__class
__, xxx
.__class
__)
104 page
= self
.pageCache
[cacheID
]
105 page
.box
.SetLabel(xxx
.child
.panelName())
106 page
.Reparent(self
.page1
)
108 page
= PropPage(self
.page1
, xxx
.child
.panelName(), xxx
.child
)
109 self
.pageCache
[cacheID
] = page
110 page
.SetValues(xxx
.child
)
111 self
.pages
.append(page
)
112 sizer
.Add(page
, 0, wxEXPAND | wxTOP
, 5)
114 size
= self
.page1
.GetSizer().GetMinSize()
115 self
.page1
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True)
118 # Create if does not exist
119 if xxx
and xxx
.treeObject().hasStyle
:
120 xxx
= xxx
.treeObject()
121 # Simplest case: set data if class is the same
122 sizer
= self
.ResetPage(self
.page2
)
124 page
= self
.stylePageCache
[xxx
.__class
__]
125 page
.Reparent(self
.page2
)
127 page
= StylePage(self
.page2
, xxx
.className
+ ' style', xxx
)
128 self
.stylePageCache
[xxx
.__class
__] = page
130 self
.pages
.append(page
)
131 sizer
.Add(page
, 0, wxEXPAND
)
132 # Add page if not exists
133 if not self
.GetPageCount() == 2:
134 self
.AddPage(self
.page2
, 'Style')
136 size
= self
.page2
.GetSizer().GetMinSize()
137 self
.page2
.SetScrollbars(1, 1, size
.width
, size
.height
, 0, 0, True)
139 # Remove page if exists
140 if self
.GetPageCount() == 2:
144 self
.modified
= False
147 self
.modified
= False
148 # If some parameter has changed
149 def IsModified(self
):
151 def SetModified(self
, value
):
152 # Register undo object when modifying first time
153 if not self
.modified
and value
:
154 g
.undoMan
.RegisterUndo(UndoEdit())
155 self
.modified
= value
157 for p
in self
.pages
: p
.Apply()
159 ################################################################################
161 # General class for notebook pages
162 class ParamPage(wxPanel
):
163 def __init__(self
, parent
, xxx
):
164 wxPanel
.__init
__(self
, parent
, -1)
166 # Register event handlers
167 for id in paramIDs
.values():
168 EVT_CHECKBOX(self
, id, self
.OnCheckParams
)
170 self
.controls
= {} # save python objects
171 self
.controlName
= None
173 def OnCheckParams(self
, evt
):
175 param
= evt
.GetEventObject().GetName()
176 w
= self
.controls
[param
]
178 objElem
= xxx
.element
180 # Ad new text node in order of allParams
181 w
.SetValue('') # set empty (default) value
182 w
.SetModified() # mark as changed
183 elem
= g
.tree
.dom
.createElement(param
)
184 # Some classes are special
186 xxx
.params
[param
] = xxxParamFont(xxx
.element
, elem
)
187 elif param
in xxxObject
.bitmapTags
:
188 xxx
.params
[param
] = xxxParamBitmap(elem
)
190 xxx
.params
[param
] = xxxParam(elem
)
191 # Find place to put new element: first present element after param
193 paramStyles
= xxx
.allParams
+ xxx
.styles
194 for p
in paramStyles
[paramStyles
.index(param
) + 1:]:
195 # Content params don't have same type
196 if xxx
.params
.has_key(p
) and p
!= 'content':
200 nextTextElem
= xxx
.params
[p
].node
201 objElem
.insertBefore(elem
, nextTextElem
)
203 objElem
.appendChild(elem
)
206 xxx
.params
[param
].remove()
207 del xxx
.params
[param
]
209 w
.modified
= False # mark as not changed
211 # Set modified flag (provokes undo storing is necessary)
212 panel
.SetModified(True)
216 name
= self
.controlName
.GetValue()
219 xxx
.element
.setAttribute('name', name
)
220 for param
, w
in self
.controls
.items():
222 paramObj
= xxx
.params
[param
]
224 if param
in xxx
.specials
:
225 xxx
.setSpecial(param
, value
)
227 paramObj
.update(value
)
230 self
.origChecks
= map(lambda i
: (i
[0], i
[1].GetValue()), self
.checks
.items())
231 self
.origControls
= map(lambda i
: (i
[0], i
[1].GetValue(), i
[1].IsEnabled()),
232 self
.controls
.items())
234 self
.origName
= self
.controlName
.GetValue()
235 # Return original values
238 return (self
.origChecks
, self
.origControls
, self
.origName
)
240 return (self
.origChecks
, self
.origControls
)
241 # Set values from undo data
242 def SetState(self
, state
):
244 self
.checks
[k
].SetValue(v
)
245 for k
,v
,e
in state
[1]:
246 self
.controls
[k
].SetValue(v
)
247 self
.controls
[k
].Enable(e
)
248 if e
: self
.controls
[k
].modified
= True
250 self
.controlName
.SetValue(state
[2])
252 ################################################################################
254 # Panel for displaying properties
255 class PropPage(ParamPage
):
256 def __init__(self
, parent
, label
, xxx
):
257 ParamPage
.__init
__(self
, parent
, xxx
)
258 self
.box
= wxStaticBox(self
, -1, label
)
259 self
.box
.SetFont(labelFont
)
260 topSizer
= wxStaticBoxSizer(self
.box
, wxVERTICAL
)
261 sizer
= wxFlexGridSizer(len(xxx
.allParams
), 2, 1, 1)
262 sizer
.AddGrowableCol(1)
264 label
= wxStaticText(self
, -1, 'XML ID:', size
=(100,-1))
265 control
= ParamText(self
, 'XML_name', 200)
266 sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
),
267 (control
, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW
, 5) ])
268 self
.controlName
= control
269 for param
in xxx
.allParams
:
270 present
= xxx
.params
.has_key(param
)
271 if param
in xxx
.required
:
272 label
= wxStaticText(self
, paramIDs
[param
], param
+ ':',
273 size
= (100,-1), name
= param
)
275 # Notebook has one very loooooong parameter
276 if param
== 'usenotebooksizer': sParam
= 'usesizer:'
277 else: sParam
= param
+ ':'
278 label
= wxCheckBox(self
, paramIDs
[param
], sParam
,
279 size
= (100,-1), name
= param
)
280 self
.checks
[param
] = label
282 typeClass
= xxx
.paramDict
[param
]
286 typeClass
= paramDict
[param
]
289 typeClass
= ParamText
290 control
= typeClass(self
, param
)
291 control
.Enable(present
)
292 sizer
.AddMany([ (label
, 0, wxALIGN_CENTER_VERTICAL
),
293 (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ])
294 self
.controls
[param
] = control
295 topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3)
296 self
.SetAutoLayout(True)
297 self
.SetSizer(topSizer
)
299 def SetValues(self
, xxx
):
302 self
.origControls
= []
303 # Set values, checkboxes to False, disable defaults
305 self
.controlName
.SetValue(xxx
.name
)
306 self
.origName
= xxx
.name
307 for param
in xxx
.allParams
:
308 w
= self
.controls
[param
]
311 value
= xxx
.params
[param
].value()
314 if not param
in xxx
.required
:
315 self
.checks
[param
].SetValue(True)
316 self
.origChecks
.append((param
, True))
317 self
.origControls
.append((param
, value
, True))
319 self
.checks
[param
].SetValue(False)
322 self
.origChecks
.append((param
, False))
323 self
.origControls
.append((param
, '', False))
325 ################################################################################
327 # Style notebook page
328 class StylePage(ParamPage
):
329 def __init__(self
, parent
, label
, xxx
):
330 ParamPage
.__init
__(self
, parent
, xxx
)
331 box
= wxStaticBox(self
, -1, label
)
332 box
.SetFont(labelFont
)
333 topSizer
= wxStaticBoxSizer(box
, wxVERTICAL
)
334 sizer
= wxFlexGridSizer(len(xxx
.styles
), 2, 1, 1)
335 sizer
.AddGrowableCol(1)
336 for param
in xxx
.styles
:
337 present
= xxx
.params
.has_key(param
)
338 check
= wxCheckBox(self
, paramIDs
[param
],
339 param
+ ':', size
= (100,-1), name
= param
)
340 check
.SetValue(present
)
341 control
= paramDict
[param
](self
, name
= param
)
342 control
.Enable(present
)
343 sizer
.AddMany([ (check
, 0, wxALIGN_CENTER_VERTICAL
),
344 (control
, 0, wxALIGN_CENTER_VERTICAL | wxGROW
) ])
345 self
.checks
[param
] = check
346 self
.controls
[param
] = control
347 topSizer
.Add(sizer
, 1, wxALL | wxEXPAND
, 3)
348 self
.SetAutoLayout(True)
349 self
.SetSizer(topSizer
)
351 # Set data for a cahced page
352 def SetValues(self
, xxx
):
355 self
.origControls
= []
356 for param
in xxx
.styles
:
357 present
= xxx
.params
.has_key(param
)
358 check
= self
.checks
[param
]
359 check
.SetValue(present
)
360 w
= self
.controls
[param
]
363 value
= xxx
.params
[param
].value()
368 self
.origChecks
.append((param
, present
))
369 self
.origControls
.append((param
, value
, present
))