]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/tools/XRCed/params.py
wcslen and wcscmp replacements for systems that lack them, such as djgpp
[wxWidgets.git] / wxPython / wx / tools / XRCed / params.py
1 # Name: params.py
2 # Purpose: Classes for parameter introduction
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
4 # Created: 22.08.2001
5 # RCS-ID: $Id$
6
7 import string
8 import os.path
9 from globals import *
10 from types import *
11 from wxPython.xrc import *
12
13 genericStyles = [
14 'wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 'wxSUNKEN_BORDER',
15 'wxRAISED_BORDER', 'wxSTATIC_BORDER', 'wxNO_BORDER',
16 'wxTRANSPARENT_WINDOW', 'wxTAB_TRAVERSAL',
17 'wxWANTS_CHARS',
18 'wxNO_FULL_REPAINT_ON_RESIZE',
19 'wxVSCROLL', 'wxHSCROLL', 'wxALWAYS_SHOW_SB',
20 'wxCLIP_CHILDREN',
21 'wxFULL_REPAINT_ON_RESIZE'
22 ]
23
24 genericExStyles = [
25 'wxWS_EX_VALIDATE_RECURSIVELY',
26 'wxWS_EX_BLOCK_EVENTS',
27 'wxWS_EX_TRANSIENT',
28 'wxFRAME_EX_CONTEXTHELP',
29 'wxWS_EX_PROCESS_IDLE',
30 'wxWS_EX_PROCESS_UI_UPDATES'
31 ]
32
33 buttonSize = (35,-1) # in dialog units, transformed to pixels in panel ctor
34
35 # Class that can properly disable children
36 class PPanel(wxPanel):
37 def __init__(self, parent, name):
38 wxPanel.__init__(self, parent, -1, name=name)
39 self.modified = self.freeze = False
40 def Enable(self, value):
41 # Something strange is going on with enable so we make sure...
42 for w in self.GetChildren():
43 w.Enable(value)
44 wxPanel.Enable(self, value)
45 def SetModified(self):
46 self.modified = True
47 g.panel.SetModified(True)
48 # Common method to set modified state
49 def OnChange(self, evt):
50 if self.freeze: return
51 self.SetModified()
52 evt.Skip()
53
54 class ParamBinaryOr(PPanel):
55 def __init__(self, parent, name):
56 PPanel.__init__(self, parent, name)
57 self.ID_TEXT_CTRL = wxNewId()
58 self.ID_BUTTON_CHOICES = wxNewId()
59 sizer = wxBoxSizer()
60 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
61 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
62 self.button = wxButton(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize)
63 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
64 self.SetAutoLayout(True)
65 self.SetSizer(sizer)
66 sizer.Fit(self)
67 EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices)
68 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
69 def GetValue(self):
70 return self.text.GetValue()
71 def SetValue(self, value):
72 self.freeze = True
73 self.text.SetValue(value)
74 self.freeze = False
75 def OnButtonChoices(self, evt):
76 dlg = g.frame.res.LoadDialog(self, 'DIALOG_CHOICES')
77 listBox = XRCCTRL(dlg, 'CHECK_LIST')
78 listBox.InsertItems(self.values, 0)
79 value = map(string.strip, self.text.GetValue().split('|'))
80 if value == ['']: value = []
81 ignored = []
82 for i in value:
83 try:
84 listBox.Check(self.values.index(i))
85 except ValueError:
86 # Try to find equal
87 if self.equal.has_key(i):
88 listBox.Check(self.values.index(self.equal[i]))
89 else:
90 print 'WARNING: unknown flag: %s: ignored.' % i
91 ignored.append(i)
92 if dlg.ShowModal() == wxID_OK:
93 value = []
94 for i in range(listBox.GetCount()):
95 if listBox.IsChecked(i):
96 value.append(self.values[i])
97 # Add ignored flags
98 value.extend(ignored)
99 if value:
100 self.SetValue(reduce(lambda a,b: a+'|'+b, value))
101 else:
102 self.SetValue('')
103 self.SetModified()
104 dlg.Destroy()
105
106 class ParamFlag(ParamBinaryOr):
107 values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
108 'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
109 'wxFIXED_MINSIZE',
110 'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
111 'wxALIGN_CENTRE_HORIZONTAL',
112 ]
113 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
114 'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL',
115 'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'}
116 def __init__(self, parent, name):
117 ParamBinaryOr.__init__(self, parent, name)
118
119 class ParamStyle(ParamBinaryOr):
120 equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
121 def __init__(self, parent, name):
122 self.values = g.currentXXX.winStyles + genericStyles
123 ParamBinaryOr.__init__(self, parent, name)
124
125 class ParamNonGenericStyle(ParamBinaryOr):
126 def __init__(self, parent, name):
127 self.values = g.currentXXX.winStyles
128 ParamBinaryOr.__init__(self, parent, name)
129
130 class ParamExStyle(ParamBinaryOr):
131 def __init__(self, parent, name):
132 if g.currentXXX:
133 self.values = g.currentXXX.exStyles + genericExStyles
134 else:
135 self.values = []
136 ParamBinaryOr.__init__(self, parent, name)
137
138 class ParamColour(PPanel):
139 def __init__(self, parent, name):
140 PPanel.__init__(self, parent, name)
141 self.ID_TEXT_CTRL = wxNewId()
142 self.ID_BUTTON = wxNewId()
143 sizer = wxBoxSizer()
144 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(65,-1))
145 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
146 self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(20, 1))
147 sizer.Add(self.button, 0, wxGROW | wxALIGN_CENTER_VERTICAL)
148 self.SetAutoLayout(True)
149 self.SetSizer(sizer)
150 sizer.Fit(self)
151 self.textModified = False
152 EVT_PAINT(self.button, self.OnPaintButton)
153 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
154 EVT_LEFT_DOWN(self.button, self.OnLeftDown)
155 def GetValue(self):
156 return self.text.GetValue()
157 def SetValue(self, value):
158 self.freeze = True
159 if not value: value = '#FFFFFF'
160 self.text.SetValue(str(value)) # update text ctrl
161 colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
162 self.button.SetBackgroundColour(colour)
163 self.button.Refresh()
164 self.freeze = False
165 def OnPaintButton(self, evt):
166 dc = wxPaintDC(self.button)
167 dc.SetBrush(wxTRANSPARENT_BRUSH)
168 if self.IsEnabled(): dc.SetPen(wxBLACK_PEN)
169 else: dc.SetPen(wxGREY_PEN)
170 size = self.button.GetSize()
171 dc.DrawRectangle(0, 0, size.width, size.height)
172 def OnLeftDown(self, evt):
173 data = wxColourData()
174 data.SetColour(self.GetValue())
175 dlg = wxColourDialog(self, data)
176 if dlg.ShowModal() == wxID_OK:
177 self.SetValue('#%02X%02X%02X' % dlg.GetColourData().GetColour().Get())
178 self.SetModified()
179 dlg.Destroy()
180
181 ################################################################################
182
183 # Mapping from wx constants ro XML strings
184 fontFamiliesWx2Xml = {wxDEFAULT: 'default', wxDECORATIVE: 'decorative',
185 wxROMAN: 'roman', wxSCRIPT: 'script', wxSWISS: 'swiss',
186 wxMODERN: 'modern'}
187 fontStylesWx2Xml = {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
188 fontWeightsWx2Xml = {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
189 def ReverseMap(m):
190 rm = {}
191 for k,v in m.items(): rm[v] = k
192 return rm
193 fontFamiliesXml2wx = ReverseMap(fontFamiliesWx2Xml)
194 fontStylesXml2wx = ReverseMap(fontStylesWx2Xml)
195 fontWeightsXml2wx = ReverseMap(fontWeightsWx2Xml)
196
197 class ParamFont(PPanel):
198 def __init__(self, parent, name):
199 PPanel.__init__(self, parent, name)
200 self.ID_TEXT_CTRL = wxNewId()
201 self.ID_BUTTON_SELECT = wxNewId()
202 sizer = wxBoxSizer()
203 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(200,-1))
204 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
205 self.button = wxButton(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize)
206 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
207 self.SetAutoLayout(True)
208 self.SetSizer(sizer)
209 sizer.Fit(self)
210 self.textModified = False
211 EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
212 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
213 def OnChange(self, evt):
214 PPanel.OnChange(self, evt)
215 self.textModified = True
216 def _defaultValue(self):
217 return ['12', 'default', 'normal', 'normal', '0', '', '']
218 def GetValue(self):
219 if self.textModified: # text has newer value
220 try:
221 return eval(self.text.GetValue())
222 except SyntaxError:
223 wxLogError('Syntax error in parameter value: ' + self.GetName())
224 return self._defaultValue()
225 return self.value
226 def SetValue(self, value):
227 self.freeze = True # disable other handlers
228 if not value: value = self._defaultValue()
229 self.value = value
230 self.text.SetValue(str(value)) # update text ctrl
231 self.freeze = False
232 def OnButtonSelect(self, evt):
233 if self.textModified: # text has newer value
234 try:
235 self.value = eval(self.text.GetValue())
236 except SyntaxError:
237 wxLogError('Syntax error in parameter value: ' + self.GetName())
238 self.value = self._defaultValue()
239 # Make initial font
240 # Default values
241 size = 12
242 family = wxDEFAULT
243 style = weight = wxNORMAL
244 underlined = 0
245 face = ''
246 enc = wxFONTENCODING_DEFAULT
247 # Fall back to default if exceptions
248 error = False
249 try:
250 try: size = int(self.value[0])
251 except ValueError: error = True; wxLogError('Invalid size specification')
252 try: family = fontFamiliesXml2wx[self.value[1]]
253 except KeyError: error = True; wxLogError('Invalid family specification')
254 try: style = fontStylesXml2wx[self.value[2]]
255 except KeyError: error = True; wxLogError('Invalid style specification')
256 try: weight = fontWeightsXml2wx[self.value[3]]
257 except KeyError: error = True; wxLogError('Invalid weight specification')
258 try: underlined = bool(self.value[4])
259 except ValueError: error = True; wxLogError('Invalid underlined flag specification')
260 face = self.value[5]
261 except IndexError:
262 error = True
263 mapper = wxFontMapper()
264 if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
265
266 if error: wxLogError('Invalid font specification')
267 if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM
268 font = wxFont(size, family, style, weight, underlined, face, enc)
269 data = wxFontData()
270 data.SetInitialFont(font)
271 dlg = wxFontDialog(self, data)
272 if dlg.ShowModal() == wxID_OK:
273 font = dlg.GetFontData().GetChosenFont()
274 print font.GetEncoding()
275 if font.GetEncoding() == wxFONTENCODING_SYSTEM:
276 encName = ''
277 else:
278 encName = wxFontMapper_GetEncodingName(font.GetEncoding()).encode()
279 value = [str(font.GetPointSize()),
280 fontFamiliesWx2Xml.get(font.GetFamily(), "default"),
281 fontStylesWx2Xml.get(font.GetStyle(), "normal"),
282 fontWeightsWx2Xml.get(font.GetWeight(), "normal"),
283 str(int(font.GetUnderlined())),
284 font.GetFaceName().encode(),
285 encName
286 ]
287 # Add ignored flags
288 self.SetValue(value)
289 self.SetModified()
290 self.textModified = False
291 dlg.Destroy()
292
293 ################################################################################
294
295 class ParamInt(PPanel):
296 def __init__(self, parent, name):
297 PPanel.__init__(self, parent, name)
298 self.ID_SPIN_CTRL = wxNewId()
299 sizer = wxBoxSizer()
300 self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=(50,-1))
301 sizer.Add(self.spin)
302 self.SetAutoLayout(True)
303 self.SetSizer(sizer)
304 sizer.Fit(self)
305 EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
306 def GetValue(self):
307 return str(self.spin.GetValue())
308 def SetValue(self, value):
309 self.freeze = True
310 if not value: value = 0
311 self.spin.SetValue(int(value))
312 self.freeze = False
313
314 # Same as int but allows dialog units (XXXd)
315 class ParamUnit(PPanel):
316 def __init__(self, parent, name):
317 PPanel.__init__(self, parent, name)
318 self.ID_TEXT_CTRL = wxNewId()
319 self.ID_SPIN_BUTTON = wxNewId()
320 sizer = wxBoxSizer()
321 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(35,-1))
322 self.spin = wxSpinButton(self, self.ID_SPIN_BUTTON, style = wxSP_VERTICAL, size=(-1,1))
323 self.spin.SetRange(-10000, 10000)
324 sizer.Add(self.text, 0, wxEXPAND | wxRIGHT, 2)
325 sizer.Add(self.spin, 0, wxEXPAND)
326 self.SetAutoLayout(True)
327 self.SetSizer(sizer)
328 sizer.Fit(self)
329 EVT_SPIN_UP(self, self.ID_SPIN_BUTTON, self.OnSpinUp)
330 EVT_SPIN_DOWN(self, self.ID_SPIN_BUTTON, self.OnSpinDown)
331 def GetValue(self):
332 return self.text.GetValue()
333 def SetValue(self, value):
334 self.freeze = True
335 if not value: value = '0'
336 self.text.SetValue(value)
337 self.freeze = False
338 def Change(self, x):
339 # Check if we are working with dialog units
340 value = self.text.GetValue()
341 units = ''
342 if value[-1].upper() == 'D':
343 units = value[-1]
344 value = value[:-1]
345 try:
346 intValue = int(value) + x
347 self.spin.SetValue(intValue)
348 self.text.SetValue(str(intValue) + units)
349 self.SetModified()
350 except:
351 # !!! Strange, if I use wxLogWarning, event is re-generated
352 print 'incorrect unit format'
353 def OnSpinUp(self, evt):
354 self.Change(1)
355 def OnSpinDown(self, evt):
356 self.Change(-1)
357
358 class ParamMultilineText(PPanel):
359 def __init__(self, parent, name, textWidth=-1):
360 PPanel.__init__(self, parent, name)
361 self.ID_TEXT_CTRL = wxNewId()
362 self.ID_BUTTON_EDIT = wxNewId()
363 sizer = wxBoxSizer()
364 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
365 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
366 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
367 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
368 self.SetAutoLayout(True)
369 self.SetSizer(sizer)
370 sizer.Fit(self)
371 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
372 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
373 def GetValue(self):
374 return self.text.GetValue()
375 def SetValue(self, value):
376 self.freeze = True # disable other handlers
377 self.text.SetValue(value)
378 self.freeze = False # disable other handlers
379 def OnButtonEdit(self, evt):
380 dlg = g.frame.res.LoadDialog(self, 'DIALOG_TEXT')
381 textCtrl = XRCCTRL(dlg, 'TEXT')
382 textCtrl.SetValue(self.text.GetValue())
383 if dlg.ShowModal() == wxID_OK:
384 self.text.SetValue(textCtrl.GetValue())
385 self.SetModified()
386 dlg.Destroy()
387
388 class ParamText(PPanel):
389 def __init__(self, parent, name, textWidth=-1):
390 PPanel.__init__(self, parent, name)
391 self.ID_TEXT_CTRL = wxNewId()
392 # We use sizer even here to have the same size of text control
393 sizer = wxBoxSizer()
394 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1))
395 if textWidth == -1: option = 1
396 else: option = 0
397 sizer.Add(self.text, option, wxALIGN_CENTER_VERTICAL)
398 self.SetAutoLayout(True)
399 self.SetSizer(sizer)
400 sizer.Fit(self)
401 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
402 def GetValue(self):
403 return self.text.GetValue()
404 def SetValue(self, value):
405 self.freeze = True # disable other handlers
406 self.text.SetValue(value)
407 self.freeze = False # disable other handlers
408
409 class ParamAccel(ParamText):
410 def __init__(self, parent, name):
411 ParamText.__init__(self, parent, name, 100)
412
413 class ParamPosSize(ParamText):
414 def __init__(self, parent, name):
415 ParamText.__init__(self, parent, name, 80)
416
417 class ParamLabel(ParamText):
418 def __init__(self, parent, name):
419 ParamText.__init__(self, parent, name, 200)
420
421 class ParamEncoding(ParamText):
422 def __init__(self, parent, name):
423 ParamText.__init__(self, parent, name, 100)
424
425 class ContentDialog(wxDialog):
426 def __init__(self, parent, value):
427 # Load from resource
428 pre = wxPreDialog()
429 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT')
430 self.this = pre.this
431 self._setOORInfo(self)
432 self.list = XRCCTRL(self, 'LIST')
433 # Set list items
434 for v in value:
435 self.list.Append(v)
436 self.SetAutoLayout(True)
437 self.GetSizer().Fit(self)
438 # Callbacks
439 self.ID_BUTTON_APPEND = XRCID('BUTTON_APPEND')
440 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
441 self.ID_BUTTON_UP = XRCID('BUTTON_UP')
442 self.ID_BUTTON_DOWN = XRCID('BUTTON_DOWN')
443 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
444 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
445 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
446 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
447 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
448 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
449 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
450 def OnButtonUp(self, evt):
451 i = self.list.GetSelection()
452 str = self.list.GetString(i)
453 self.list.Delete(i)
454 self.list.InsertItems([str], i-1)
455 self.list.SetSelection(i-1)
456 def OnButtonDown(self, evt):
457 i = self.list.GetSelection()
458 str = self.list.GetString(i)
459 self.list.Delete(i)
460 self.list.InsertItems([str], i+1)
461 self.list.SetSelection(i+1)
462 def OnButtonAppend(self, evt):
463 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
464 self.list.Append(str)
465 def OnButtonRemove(self, evt):
466 self.list.Delete(self.list.GetSelection())
467 def OnUpdateUI(self, evt):
468 if evt.GetId() == self.ID_BUTTON_REMOVE:
469 evt.Enable(self.list.GetSelection() != -1)
470 elif evt.GetId() == self.ID_BUTTON_UP:
471 evt.Enable(self.list.GetSelection() > 0)
472 elif evt.GetId() == self.ID_BUTTON_DOWN:
473 evt.Enable(self.list.GetSelection() != -1 and \
474 self.list.GetSelection() < self.list.GetCount() - 1)
475
476 class ContentCheckListDialog(wxDialog):
477 def __init__(self, parent, value):
478 pre = wxPreDialog()
479 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_CONTENT_CHECK_LIST')
480 self.this = pre.this
481 self._setOORInfo(self)
482 self.list = XRCCTRL(self, 'CHECK_LIST')
483 # Set list items
484 i = 0
485 for v,ch in value:
486 self.list.Append(v)
487 self.list.Check(i, ch)
488 i += 1
489 self.SetAutoLayout(True)
490 self.GetSizer().Fit(self)
491 # Callbacks
492 self.ID_BUTTON_APPEND = XRCID('BUTTON_APPEND')
493 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
494 self.ID_BUTTON_UP = XRCID('BUTTON_UP')
495 self.ID_BUTTON_DOWN = XRCID('BUTTON_DOWN')
496 EVT_CHECKLISTBOX(self, self.list.GetId(), self.OnCheck)
497 EVT_BUTTON(self, self.ID_BUTTON_UP, self.OnButtonUp)
498 EVT_BUTTON(self, self.ID_BUTTON_DOWN, self.OnButtonDown)
499 EVT_BUTTON(self, self.ID_BUTTON_APPEND, self.OnButtonAppend)
500 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
501 EVT_UPDATE_UI(self, self.ID_BUTTON_UP, self.OnUpdateUI)
502 EVT_UPDATE_UI(self, self.ID_BUTTON_DOWN, self.OnUpdateUI)
503 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
504 def OnCheck(self, evt):
505 # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking
506 self.list.Deselect(evt.GetSelection())
507 def OnButtonUp(self, evt):
508 i = self.list.GetSelection()
509 str, ch = self.list.GetString(i), self.list.IsChecked(i)
510 self.list.Delete(i)
511 self.list.InsertItems([str], i-1)
512 self.list.Check(i-1, ch)
513 self.list.SetSelection(i-1)
514 def OnButtonDown(self, evt):
515 i = self.list.GetSelection()
516 str, ch = self.list.GetString(i), self.list.IsChecked(i)
517 self.list.Delete(i)
518 self.list.InsertItems([str], i+1)
519 self.list.Check(i+1, ch)
520 self.list.SetSelection(i+1)
521 def OnButtonAppend(self, evt):
522 str = wxGetTextFromUser('Enter new item:', 'Append', '', self)
523 self.list.Append(str)
524 def OnButtonRemove(self, evt):
525 self.list.Delete(self.list.GetSelection())
526 def OnUpdateUI(self, evt):
527 if evt.GetId() == self.ID_BUTTON_REMOVE:
528 evt.Enable(self.list.GetSelection() != -1)
529 elif evt.GetId() == self.ID_BUTTON_UP:
530 evt.Enable(self.list.GetSelection() > 0)
531 elif evt.GetId() == self.ID_BUTTON_DOWN:
532 evt.Enable(self.list.GetSelection() != -1 and \
533 self.list.GetSelection() < self.list.GetCount() - 1)
534
535 class ParamContent(PPanel):
536 def __init__(self, parent, name):
537 PPanel.__init__(self, parent, name)
538 self.ID_TEXT_CTRL = wxNewId()
539 self.ID_BUTTON_EDIT = wxNewId()
540 sizer = wxBoxSizer()
541 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
542 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
543 self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize)
544 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
545 self.SetAutoLayout(True)
546 self.SetSizer(sizer)
547 sizer.Fit(self)
548 self.textModified = False
549 EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
550 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
551 def OnChange(self, evt):
552 PPanel.OnChange(self, evt)
553 self.textModified = True
554 def GetValue(self):
555 if self.textModified: # text has newer value
556 try:
557 return eval(self.text.GetValue())
558 except SyntaxError:
559 wxLogError('Syntax error in parameter value: ' + self.GetName())
560 return []
561 return self.value
562 def SetValue(self, value):
563 self.freeze = True
564 if not value: value = []
565 self.value = value
566 self.text.SetValue(str(value)) # update text ctrl
567 self.freeze = False
568 def OnButtonEdit(self, evt):
569 if self.textModified: # text has newer value
570 try:
571 self.value = eval(self.text.GetValue())
572 except SyntaxError:
573 wxLogError('Syntax error in parameter value: ' + self.GetName())
574 self.value = []
575 dlg = ContentDialog(self, self.value)
576 if dlg.ShowModal() == wxID_OK:
577 value = []
578 for i in range(dlg.list.GetCount()):
579 value.append(dlg.list.GetString(i))
580 # Add ignored flags
581 self.SetValue(value)
582 self.SetModified()
583 self.textModified = False
584 dlg.Destroy()
585
586 # CheckList content
587 class ParamContentCheckList(ParamContent):
588 def __init__(self, parent, name):
589 ParamContent.__init__(self, parent, name)
590 def OnButtonEdit(self, evt):
591 if self.textModified: # text has newer value
592 try:
593 self.value = eval(self.text.GetValue())
594 except SyntaxError:
595 wxLogError('Syntax error in parameter value: ' + self.GetName())
596 self.value = []
597 dlg = ContentCheckListDialog(self, self.value)
598 if dlg.ShowModal() == wxID_OK:
599 value = []
600 for i in range(dlg.list.GetCount()):
601 value.append((dlg.list.GetString(i), dlg.list.IsChecked(i)))
602 # Add ignored flags
603 self.SetValue(value)
604 self.SetModified()
605 self.textModified = False
606 dlg.Destroy()
607
608 class IntListDialog(wxDialog):
609 def __init__(self, parent, value):
610 pre = wxPreDialog()
611 g.frame.res.LoadOnDialog(pre, parent, 'DIALOG_INTLIST')
612 self.this = pre.this
613 self._setOORInfo(self)
614 self.list = XRCCTRL(self, 'LIST')
615 # Set list items
616 value.sort()
617 for v in value:
618 if type(v) != IntType:
619 wxLogError('Invalid item type')
620 else:
621 self.list.Append(str(v))
622 self.SetAutoLayout(True)
623 self.GetSizer().Fit(self)
624 # Callbacks
625 self.ID_BUTTON_ADD = XRCID('BUTTON_ADD')
626 self.ID_BUTTON_REMOVE = XRCID('BUTTON_REMOVE')
627 EVT_BUTTON(self, self.ID_BUTTON_ADD, self.OnButtonAppend)
628 EVT_BUTTON(self, self.ID_BUTTON_REMOVE, self.OnButtonRemove)
629 EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI)
630 def OnButtonAppend(self, evt):
631 s = wxGetTextFromUser('Enter new number:', 'Add', '', self)
632 if not s: return
633 # Check that it's unique
634 try:
635 v = int(s)
636 s = str(v) # to be sure
637 i = self.list.FindString(s)
638 if i == -1: # ignore non-unique
639 # Find place to insert
640 found = False
641 for i in range(self.list.GetCount()):
642 if int(self.list.GetString(i)) > v:
643 found = True
644 break
645 if found: self.list.InsertItems([s], i)
646 else: self.list.Append(s)
647 except ValueError:
648 wxLogError('List item is not an int!')
649 def OnButtonRemove(self, evt):
650 self.list.Delete(self.list.GetSelection())
651 def OnUpdateUI(self, evt):
652 if evt.GetId() == self.ID_BUTTON_REMOVE:
653 evt.Enable(self.list.GetSelection() != -1)
654
655 # For growable list
656 class ParamIntList(ParamContent):
657 def __init__(self, parent, name):
658 ParamContent.__init__(self, parent, name)
659 def OnButtonEdit(self, evt):
660 if self.textModified: # text has newer value
661 try:
662 self.value = eval(self.text.GetValue())
663 except SyntaxError:
664 wxLogError('Syntax error in parameter value: ' + self.GetName())
665 self.value = []
666 dlg = IntListDialog(self, self.value)
667 if dlg.ShowModal() == wxID_OK:
668 value = []
669 for i in range(dlg.list.GetCount()):
670 value.append(int(dlg.list.GetString(i)))
671 # Add ignored flags
672 self.SetValue(value)
673 self.SetModified()
674 self.textModified = False
675 dlg.Destroy()
676
677 # Boxless radiobox
678 class RadioBox(PPanel):
679 def __init__(self, parent, id, choices,
680 pos=wxDefaultPosition, name='radiobox'):
681 PPanel.__init__(self, parent, name)
682 self.choices = choices
683 topSizer = wxBoxSizer()
684 for i in choices:
685 button = wxRadioButton(self, -1, i, size=(-1,buttonSize[1]), name=i)
686 topSizer.Add(button, 0, wxRIGHT, 5)
687 EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice)
688 self.SetAutoLayout(True)
689 self.SetSizer(topSizer)
690 topSizer.Fit(self)
691 def SetStringSelection(self, value):
692 self.freeze = True
693 for i in self.choices:
694 self.FindWindowByName(i).SetValue(i == value)
695 self.value = value
696 self.freeze = False
697 def OnRadioChoice(self, evt):
698 if self.freeze: return
699 if evt.GetSelection():
700 self.value = evt.GetEventObject().GetName()
701 self.SetModified()
702 def GetStringSelection(self):
703 return self.value
704
705 class ParamBool(RadioBox):
706 values = {'yes': '1', 'no': '0'}
707 seulav = {'1': 'yes', '0': 'no'}
708 def __init__(self, parent, name):
709 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
710 def GetValue(self):
711 return self.values[self.GetStringSelection()]
712 def SetValue(self, value):
713 if not value: value = '1'
714 self.SetStringSelection(self.seulav[value])
715
716 class ParamOrient(RadioBox):
717 values = {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
718 seulav = {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
719 def __init__(self, parent, name):
720 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
721 def GetValue(self):
722 return self.values[self.GetStringSelection()]
723 def SetValue(self, value):
724 if not value: value = 'wxHORIZONTAL'
725 self.SetStringSelection(self.seulav[value])
726
727 class ParamOrientation(RadioBox):
728 values = {'horizontal': 'horizontal', 'vertical': 'vertical'}
729 seulav = {'horizontal': 'horizontal', 'vertical': 'vertical'}
730 def __init__(self, parent, name):
731 RadioBox.__init__(self, parent, -1, choices=self.values.keys(), name=name)
732 def GetValue(self):
733 return self.values[self.GetStringSelection()]
734 def SetValue(self, value):
735 if not value: value = 'vertical'
736 self.SetStringSelection(self.seulav[value])
737
738 class ParamFile(PPanel):
739 def __init__(self, parent, name):
740 PPanel.__init__(self, parent, name)
741 self.ID_TEXT_CTRL = wxNewId()
742 self.ID_BUTTON_BROWSE = wxNewId()
743 sizer = wxBoxSizer()
744 self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1))
745 sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5)
746 self.button = wxButton(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize)
747 sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
748 self.SetAutoLayout(True)
749 self.SetSizer(sizer)
750 sizer.Fit(self)
751 self.textModified = False
752 EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
753 EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
754 def OnChange(self, evt):
755 PPanel.OnChange(self, evt)
756 self.textModified = True
757 def GetValue(self):
758 if self.textModified: # text has newer value
759 return self.text.GetValue()
760 return self.value
761 def SetValue(self, value):
762 self.freeze = True
763 self.value = value
764 self.text.SetValue(value) # update text ctrl
765 self.freeze = False
766 def OnButtonBrowse(self, evt):
767 if self.textModified: # text has newer value
768 self.value = self.text.GetValue()
769 dlg = wxFileDialog(self,
770 defaultDir = os.path.abspath(os.path.dirname(self.value)),
771 defaultFile = os.path.basename(self.value))
772 if dlg.ShowModal() == wxID_OK:
773 # Get common part of selected path and current
774 if g.frame.dataFile:
775 curpath = os.path.abspath(g.frame.dataFile)
776 else:
777 curpath = os.path.join(os.getcwd(), '')
778 common = os.path.commonprefix([curpath, dlg.GetPath()])
779 self.SetValue(dlg.GetPath()[len(common):])
780 self.SetModified()
781 self.textModified = False
782 dlg.Destroy()
783
784 class ParamBitmap(PPanel):
785 def __init__(self, parent, name):
786 pre = wxPrePanel()
787 g.frame.res.LoadOnPanel(pre, parent, 'PANEL_BITMAP')
788 self.this = pre.this
789 self._setOORInfo(self)
790 self.modified = self.freeze = False
791 self.radio_std = XRCCTRL(self, 'RADIO_STD')
792 self.radio_file = XRCCTRL(self, 'RADIO_FILE')
793 self.combo = XRCCTRL(self, 'COMBO_STD')
794 self.text = XRCCTRL(self, 'TEXT_FILE')
795 self.button = XRCCTRL(self, 'BUTTON_BROWSE')
796 self.textModified = False
797 self.SetAutoLayout(True)
798 self.GetSizer().SetMinSize((260, -1))
799 self.GetSizer().Fit(self)
800 EVT_RADIOBUTTON(self, XRCID('RADIO_STD'), self.OnRadioStd)
801 EVT_RADIOBUTTON(self, XRCID('RADIO_FILE'), self.OnRadioFile)
802 EVT_BUTTON(self, XRCID('BUTTON_BROWSE'), self.OnButtonBrowse)
803 EVT_COMBOBOX(self, XRCID('COMBO_STD'), self.OnCombo)
804 EVT_TEXT(self, XRCID('COMBO_STD'), self.OnChange)
805 EVT_TEXT(self, XRCID('TEXT_FILE'), self.OnChange)
806 def OnRadioStd(self, evt):
807 self.SetModified()
808 self.SetValue(['wxART_MISSING_IMAGE',''])
809 def OnRadioFile(self, evt):
810 self.SetModified()
811 self.SetValue(['',''])
812 def updateRadios(self):
813 if self.value[0]:
814 self.radio_std.SetValue(True)
815 self.radio_file.SetValue(False)
816 self.text.Enable(False)
817 self.button.Enable(False)
818 self.combo.Enable(True)
819 else:
820 self.radio_std.SetValue(False)
821 self.radio_file.SetValue(True)
822 self.text.Enable(True)
823 self.button.Enable(True)
824 self.combo.Enable(False)
825 def OnChange(self, evt):
826 PPanel.OnChange(self, evt)
827 self.textModified = True
828 def OnCombo(self, evt):
829 PPanel.OnChange(self, evt)
830 self.value[0] = self.combo.GetValue()
831 def GetValue(self):
832 if self.textModified: # text has newer value
833 return [self.combo.GetValue(), self.text.GetValue()]
834 return self.value
835 def SetValue(self, value):
836 self.freeze = True
837 if not value:
838 self.value = ['', '']
839 else:
840 self.value = value
841 self.combo.SetValue(self.value[0])
842 self.text.SetValue(self.value[1]) # update text ctrl
843 self.updateRadios()
844 self.freeze = False
845 def OnButtonBrowse(self, evt):
846 if self.textModified: # text has newer value
847 self.value[1] = self.text.GetValue()
848 dlg = wxFileDialog(self,
849 defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
850 defaultFile = os.path.basename(self.value[1]))
851 if dlg.ShowModal() == wxID_OK:
852 # Get common part of selected path and current
853 if g.frame.dataFile:
854 curpath = os.path.abspath(g.frame.dataFile)
855 else:
856 curpath = os.path.join(os.getcwd(), '')
857 common = os.path.commonprefix([curpath, dlg.GetPath()])
858 self.SetValue(['', dlg.GetPath()[len(common):]])
859 self.SetModified()
860 self.textModified = False
861 dlg.Destroy()
862
863 paramDict = {
864 'flag': ParamFlag,
865 'style': ParamStyle, 'exstyle': ParamExStyle,
866 'pos': ParamPosSize, 'size': ParamPosSize,
867 'cellpos': ParamPosSize, 'cellspan': ParamPosSize,
868 'border': ParamUnit, 'cols': ParamInt, 'rows': ParamInt,
869 'vgap': ParamUnit, 'hgap': ParamUnit,
870 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
871 'accel': ParamAccel,
872 'label': ParamMultilineText, 'title': ParamText, 'value': ParamText,
873 'content': ParamContent, 'selection': ParamInt,
874 'min': ParamInt, 'max': ParamInt,
875 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont,
876 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool,
877 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap,
878 'encoding': ParamEncoding
879 }