2 # Purpose:      Classes for parameter introduction 
   3 # Author:       Roman Rolinsky <rolinsky@mema.ucl.ac.be> 
  11 from wxPython
.xrc 
import * 
  13 genericStyles 
= ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 
  14                  'wxSUNKEN_BORDER', 'wxRAISED_BORDER', 
  15                  'wxSTATIC_BORDER', 'wxNO_BORDER', 
  16                  'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', 
  17                  'wxNO_FULL_REPAINT_ON_RESIZE'] 
  19 buttonSize 
= (35,-1)    # in dialog units, transformed to pixels in panel ctor 
  21 # Class that can properly disable children 
  22 class PPanel(wxPanel
): 
  23     def __init__(self
, parent
, name
): 
  24         wxPanel
.__init
__(self
, parent
, -1, name
=name
) 
  25         self
.SetBackgroundColour(parent
.GetBackgroundColour()) 
  26         self
.SetForegroundColour(parent
.GetForegroundColour()) 
  27         self
.modified 
= self
.freeze 
= False 
  28     def Enable(self
, value
): 
  29         # Something strange is going on with enable so we make sure... 
  30         for w 
in self
.GetChildren(): 
  32         wxPanel
.Enable(self
, value
) 
  33     def SetModified(self
): 
  35         g
.panel
.SetModified(True) 
  36     # Common method to set modified state 
  37     def OnChange(self
, evt
): 
  38         if self
.freeze
: return 
  42 class ParamBinaryOr(PPanel
): 
  43     def __init__(self
, parent
, name
): 
  44         PPanel
.__init
__(self
, parent
, name
) 
  45         self
.ID_TEXT_CTRL 
= wxNewId() 
  46         self
.ID_BUTTON_CHOICES 
= wxNewId() 
  48         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
  49         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5) 
  50         self
.button 
= wxButton(self
, self
.ID_BUTTON_CHOICES
, 'Edit...', size
=buttonSize
) 
  51         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
  52         self
.SetAutoLayout(True) 
  55         EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoices
) 
  56         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
  58         return self
.text
.GetValue() 
  59     def SetValue(self
, value
): 
  61         self
.text
.SetValue(value
) 
  63     def OnButtonChoices(self
, evt
): 
  64         dlg 
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_CHOICES') 
  65         listBox 
= XRCCTRL(dlg
, 'CHECK_LIST') 
  66         listBox
.InsertItems(self
.values
, 0) 
  67         value 
= map(string
.strip
, self
.text
.GetValue().split('|')) 
  68         if value 
== ['']: value 
= [] 
  72                 listBox
.Check(self
.values
.index(i
)) 
  75                 if self
.equal
.has_key(i
): 
  76                     listBox
.Check(self
.values
.index(self
.equal
[i
])) 
  78                     print 'WARNING: unknown flag: %s: ignored.' % i
 
  80         if dlg
.ShowModal() == wxID_OK
: 
  82             for i 
in range(listBox
.GetCount()): 
  83                 if listBox
.IsChecked(i
): 
  84                     value
.append(self
.values
[i
]) 
  88                 self
.SetValue(reduce(lambda a
,b
: a
+'|'+b
, value
)) 
  94 class ParamFlag(ParamBinaryOr
): 
  95     values 
= ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', 
  96               'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', 
  97               'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', 
  98               'wxALIGN_CENTRE_HORIZONTAL'] 
  99     equal 
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE', 
 100              'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', 
 101              'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'} 
 102     def __init__(self
, parent
, name
): 
 103         ParamBinaryOr
.__init
__(self
, parent
, name
) 
 105 class ParamStyle(ParamBinaryOr
): 
 106     equal 
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
 
 107     def __init__(self
, parent
, name
): 
 108         self
.values 
= g
.currentXXX
.winStyles 
+ genericStyles
 
 109         ParamBinaryOr
.__init
__(self
, parent
, name
) 
 111 class ParamNonGenericStyle(ParamBinaryOr
): 
 112     def __init__(self
, parent
, name
): 
 113         self
.values 
= g
.currentXXX
.winStyles
 
 114         ParamBinaryOr
.__init
__(self
, parent
, name
) 
 116 class ParamExStyle(ParamBinaryOr
): 
 117     def __init__(self
, parent
, name
): 
 119             self
.values 
= g
.currentXXX
.exStyles 
# constant at the moment 
 122         ParamBinaryOr
.__init
__(self
, parent
, name
) 
 124 class ParamColour(PPanel
): 
 125     def __init__(self
, parent
, name
): 
 126         PPanel
.__init
__(self
, parent
, name
) 
 127         self
.ID_TEXT_CTRL 
= wxNewId() 
 128         self
.ID_BUTTON 
= wxNewId() 
 130         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(65,-1)) 
 131         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5) 
 132         self
.button 
= wxPanel(self
, self
.ID_BUTTON
, wxDefaultPosition
, wxSize(20, 1)) 
 133         sizer
.Add(self
.button
, 0, wxGROW | wxALIGN_CENTER_VERTICAL
) 
 134         self
.SetAutoLayout(True) 
 137         self
.textModified 
= False 
 138         EVT_PAINT(self
.button
, self
.OnPaintButton
) 
 139         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 140         EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
) 
 142         return self
.text
.GetValue() 
 143     def SetValue(self
, value
): 
 145         if not value
: value 
= '#FFFFFF' 
 146         self
.text
.SetValue(str(value
))  # update text ctrl 
 147         colour 
= wxColour(int(value
[1:3], 16), int(value
[3:5], 16), int(value
[5:7], 16)) 
 148         self
.button
.SetBackgroundColour(colour
) 
 149         self
.button
.Refresh() 
 151     def OnPaintButton(self
, evt
): 
 152         dc 
= wxPaintDC(self
.button
) 
 153         dc
.SetBrush(wxTRANSPARENT_BRUSH
) 
 154         if self
.IsEnabled(): dc
.SetPen(wxBLACK_PEN
) 
 155         else: dc
.SetPen(wxGREY_PEN
) 
 156         size 
= self
.button
.GetSize() 
 157         dc
.DrawRectangle(0, 0, size
.width
, size
.height
) 
 158     def OnLeftDown(self
, evt
): 
 159         data 
= wxColourData() 
 160         data
.SetColour(self
.GetValue()) 
 161         dlg 
= wxColourDialog(self
, data
) 
 162         if dlg
.ShowModal() == wxID_OK
: 
 163             self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get()) 
 167 ################################################################################ 
 169 # Mapping from wx constants ro XML strings 
 170 fontFamiliesWx2Xml 
= {wxDEFAULT
: 'default', wxDECORATIVE
: 'decorative', 
 171                 wxROMAN
: 'roman', wxSCRIPT
: 'script', wxSWISS
: 'swiss', 
 173 fontStylesWx2Xml 
= {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
 
 174 fontWeightsWx2Xml 
= {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
 
 177     for k
,v 
in m
.items(): rm
[v
] = k
 
 179 fontFamiliesXml2wx 
= ReverseMap(fontFamiliesWx2Xml
) 
 180 fontStylesXml2wx 
= ReverseMap(fontStylesWx2Xml
) 
 181 fontWeightsXml2wx 
= ReverseMap(fontWeightsWx2Xml
) 
 183 class ParamFont(PPanel
): 
 184     def __init__(self
, parent
, name
): 
 185         PPanel
.__init
__(self
, parent
, name
) 
 186         self
.ID_TEXT_CTRL 
= wxNewId() 
 187         self
.ID_BUTTON_SELECT 
= wxNewId() 
 189         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(200,-1)) 
 190         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5) 
 191         self
.button 
= wxButton(self
, self
.ID_BUTTON_SELECT
, 'Select...', size
=buttonSize
) 
 192         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 193         self
.SetAutoLayout(True) 
 196         self
.textModified 
= False 
 197         EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
) 
 198         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 199     def OnChange(self
, evt
): 
 200         PPanel
.OnChange(self
, evt
) 
 201         self
.textModified 
= True 
 202     def _defaultValue(self
): 
 203         return ['12', 'default', 'normal', 'normal', '0', '', ''] 
 205         if self
.textModified
:           # text has newer value 
 207                 return eval(self
.text
.GetValue()) 
 209                 wxLogError('Syntax error in parameter value: ' + self
.GetName()) 
 210                 return self
._defaultValue
() 
 212     def SetValue(self
, value
): 
 213         self
.freeze 
= True              # disable other handlers 
 214         if not value
: value 
= self
._defaultValue
() 
 216         self
.text
.SetValue(str(value
))  # update text ctrl 
 218     def OnButtonSelect(self
, evt
): 
 219         if self
.textModified
:           # text has newer value 
 221                 self
.value 
= eval(self
.text
.GetValue()) 
 223                 wxLogError('Syntax error in parameter value: ' + self
.GetName()) 
 224                 self
.value 
= self
._defaultValue
() 
 229         style 
= weight 
= wxNORMAL
 
 232         enc 
= wxFONTENCODING_DEFAULT
 
 233         # Fall back to default if exceptions 
 236             try: size 
= int(self
.value
[0]) 
 237             except ValueError: error 
= True 
 238             try: family 
= fontFamiliesXml2wx
[self
.value
[1]] 
 239             except KeyError: error 
= True 
 240             try: style 
= fontStylesXml2wx
[self
.value
[2]] 
 241             except KeyError: error 
= True 
 242             try: weight 
= fontWeightsXml2wx
[self
.value
[3]] 
 243             except KeyError: error 
= True 
 244             try: underlined 
= int(self
.value
[4]) 
 245             except ValueError: error 
= True 
 247             mapper 
= wxFontMapper() 
 248             if not self
.value
[6]: enc 
= mapper
.CharsetToEncoding(self
.value
[6]) 
 251         if error
: wxLogError('Invalid font specification') 
 252         if enc 
== wxFONTENCODING_DEFAULT
: enc 
= wxFONTENCODING_SYSTEM
 
 253         font 
= wxFont(size
, family
, style
, weight
, underlined
, face
, enc
) 
 255         data
.SetInitialFont(font
) 
 256         dlg 
= wxFontDialog(self
, data
) 
 257         if dlg
.ShowModal() == wxID_OK
: 
 258             font 
= dlg
.GetFontData().GetChosenFont() 
 259             value 
= [str(font
.GetPointSize()), 
 260                      fontFamiliesWx2Xml
.get(font
.GetFamily(), "default"), 
 261                      fontStylesWx2Xml
.get(font
.GetStyle(), "normal"), 
 262                      fontWeightsWx2Xml
.get(font
.GetWeight(), "normal"), 
 263                      str(font
.GetUnderlined()), 
 264                      font
.GetFaceName().encode(), 
 265                      wxFontMapper_GetEncodingName(font
.GetEncoding()).encode() 
 270             self
.textModified 
= False 
 273 ################################################################################ 
 275 class ParamInt(PPanel
): 
 276     def __init__(self
, parent
, name
): 
 277         PPanel
.__init
__(self
, parent
, name
) 
 278         self
.ID_SPIN_CTRL 
= wxNewId() 
 280         self
.spin 
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=(50,-1)) 
 282         self
.SetAutoLayout(True) 
 285         EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
) 
 287         return str(self
.spin
.GetValue()) 
 288     def SetValue(self
, value
): 
 290         if not value
: value 
= 0 
 291         self
.spin
.SetValue(int(value
)) 
 294 # Same as int but allows dialog units (XXXd) 
 295 class ParamUnit(PPanel
): 
 296     def __init__(self
, parent
, name
): 
 297         PPanel
.__init
__(self
, parent
, name
) 
 298         self
.ID_TEXT_CTRL 
= wxNewId() 
 299         self
.ID_SPIN_BUTTON 
= wxNewId() 
 301         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=(35,-1)) 
 302         self
.spin 
= wxSpinButton(self
, self
.ID_SPIN_BUTTON
, style 
= wxSP_VERTICAL
, size
=(-1,1)) 
 303         self
.spin
.SetRange(-10000, 10000) 
 304         sizer
.Add(self
.text
, 0, wxEXPAND | wxRIGHT
, 2) 
 305         sizer
.Add(self
.spin
, 0, wxEXPAND
) 
 306         self
.SetAutoLayout(True) 
 309         EVT_SPIN_UP(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinUp
) 
 310         EVT_SPIN_DOWN(self
, self
.ID_SPIN_BUTTON
, self
.OnSpinDown
) 
 312         return self
.text
.GetValue() 
 313     def SetValue(self
, value
): 
 315         if not value
: value 
= '0' 
 316         self
.text
.SetValue(value
) 
 319         # Check if we are working with dialog units 
 320         value 
= self
.text
.GetValue() 
 322         if value
[-1].upper() == 'D': 
 326             intValue 
= int(value
) + x
 
 327             self
.spin
.SetValue(intValue
) 
 328             self
.text
.SetValue(str(intValue
) + units
) 
 331             # !!! Strange, if I use wxLogWarning, event is re-generated 
 332             print 'incorrect unit format' 
 333     def OnSpinUp(self
, evt
): 
 335     def OnSpinDown(self
, evt
): 
 338 class ParamMultilineText(PPanel
): 
 339     def __init__(self
, parent
, name
, textWidth
=-1): 
 340         PPanel
.__init
__(self
, parent
, name
) 
 341         self
.ID_TEXT_CTRL 
= wxNewId() 
 342         self
.ID_BUTTON_EDIT 
= wxNewId() 
 344         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
 345         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5) 
 346         self
.button 
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
) 
 347         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 348         self
.SetAutoLayout(True) 
 351         EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
) 
 352         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 354         return self
.text
.GetValue() 
 355     def SetValue(self
, value
): 
 356         self
.freeze 
= True              # disable other handlers 
 357         self
.text
.SetValue(value
) 
 358         self
.freeze 
= False             # disable other handlers 
 359     def OnButtonEdit(self
, evt
): 
 360         dlg 
= g
.frame
.res
.LoadDialog(self
, 'DIALOG_TEXT') 
 361         textCtrl 
= XRCCTRL(dlg
, 'TEXT') 
 362         textCtrl
.SetValue(self
.text
.GetValue()) 
 363         if dlg
.ShowModal() == wxID_OK
: 
 364             self
.text
.SetValue(textCtrl
.GetValue()) 
 368 class ParamText(PPanel
): 
 369     def __init__(self
, parent
, name
, textWidth
=-1): 
 370         PPanel
.__init
__(self
, parent
, name
) 
 371         self
.ID_TEXT_CTRL 
= wxNewId() 
 372         # We use sizer even here to have the same size of text control 
 374         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(textWidth
,-1)) 
 375         if textWidth 
== -1: option 
= 1 
 377         sizer
.Add(self
.text
, option
, wxALIGN_CENTER_VERTICAL
) 
 378         self
.SetAutoLayout(True) 
 381         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 383         return self
.text
.GetValue() 
 384     def SetValue(self
, value
): 
 385         self
.freeze 
= True              # disable other handlers 
 386         self
.text
.SetValue(value
) 
 387         self
.freeze 
= False             # disable other handlers 
 389 class ParamAccel(ParamText
): 
 390     def __init__(self
, parent
, name
): 
 391         ParamText
.__init
__(self
, parent
, name
, 100) 
 393 class ParamPosSize(ParamText
): 
 394     def __init__(self
, parent
, name
): 
 395         ParamText
.__init
__(self
, parent
, name
, 80) 
 397 class ParamLabel(ParamText
): 
 398     def __init__(self
, parent
, name
): 
 399         ParamText
.__init
__(self
, parent
, name
, 200) 
 401 class ParamEncoding(ParamText
): 
 402     def __init__(self
, parent
, name
): 
 403         ParamText
.__init
__(self
, parent
, name
, 100) 
 405 class ContentDialog(wxDialog
): 
 406     def __init__(self
, parent
, value
): 
 409         g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT') 
 411         self
._setOORInfo
(self
) 
 412         self
.list = XRCCTRL(self
, 'LIST') 
 416         self
.SetAutoLayout(True) 
 417         self
.GetSizer().Fit(self
) 
 419         self
.ID_BUTTON_APPEND 
= XRCID('BUTTON_APPEND') 
 420         self
.ID_BUTTON_REMOVE 
= XRCID('BUTTON_REMOVE') 
 421         self
.ID_BUTTON_UP 
= XRCID('BUTTON_UP') 
 422         self
.ID_BUTTON_DOWN 
= XRCID('BUTTON_DOWN') 
 423         EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
) 
 424         EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
) 
 425         EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
) 
 426         EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
) 
 427         EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
) 
 428         EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
) 
 429         EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
) 
 430     def OnButtonUp(self
, evt
): 
 431         i 
= self
.list.GetSelection() 
 432         str = self
.list.GetString(i
) 
 434         self
.list.InsertItems([str], i
-1) 
 435         self
.list.SetSelection(i
-1) 
 436     def OnButtonDown(self
, evt
): 
 437         i 
= self
.list.GetSelection() 
 438         str = self
.list.GetString(i
) 
 440         self
.list.InsertItems([str], i
+1) 
 441         self
.list.SetSelection(i
+1) 
 442     def OnButtonAppend(self
, evt
): 
 443         str = wxGetTextFromUser('Enter new item:', 'Append', '', self
) 
 444         self
.list.Append(str) 
 445     def OnButtonRemove(self
, evt
): 
 446         self
.list.Delete(self
.list.GetSelection()) 
 447     def OnUpdateUI(self
, evt
): 
 448         if evt
.GetId() == self
.ID_BUTTON_REMOVE
: 
 449             evt
.Enable(self
.list.GetSelection() != -1) 
 450         elif evt
.GetId() == self
.ID_BUTTON_UP
: 
 451             evt
.Enable(self
.list.GetSelection() > 0) 
 452         elif evt
.GetId() == self
.ID_BUTTON_DOWN
: 
 453             evt
.Enable(self
.list.GetSelection() != -1 and \
 
 454                        self
.list.GetSelection() < self
.list.GetCount() - 1) 
 456 class ContentCheckListDialog(wxDialog
): 
 457     def __init__(self
, parent
, value
): 
 459         g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_CONTENT_CHECK_LIST') 
 461         self
._setOORInfo
(self
) 
 462         self
.list = XRCCTRL(self
, 'CHECK_LIST') 
 467             self
.list.Check(i
, ch
) 
 469         self
.SetAutoLayout(True) 
 470         self
.GetSizer().Fit(self
) 
 472         self
.ID_BUTTON_APPEND 
= XRCID('BUTTON_APPEND') 
 473         self
.ID_BUTTON_REMOVE 
= XRCID('BUTTON_REMOVE') 
 474         self
.ID_BUTTON_UP 
= XRCID('BUTTON_UP') 
 475         self
.ID_BUTTON_DOWN 
= XRCID('BUTTON_DOWN') 
 476         EVT_CHECKLISTBOX(self
, self
.list.GetId(), self
.OnCheck
) 
 477         EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
) 
 478         EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
) 
 479         EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
) 
 480         EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
) 
 481         EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
) 
 482         EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
) 
 483         EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
) 
 484     def OnCheck(self
, evt
): 
 485         # !!! Wrong wxGTK (wxMSW?) behavior: toggling selection if checking 
 486         self
.list.Deselect(evt
.GetSelection()) 
 487     def OnButtonUp(self
, evt
): 
 488         i 
= self
.list.GetSelection() 
 489         str, ch 
= self
.list.GetString(i
), self
.list.IsChecked(i
) 
 491         self
.list.InsertItems([str], i
-1) 
 492         self
.list.Check(i
-1, ch
) 
 493         self
.list.SetSelection(i
-1) 
 494     def OnButtonDown(self
, evt
): 
 495         i 
= self
.list.GetSelection() 
 496         str, ch 
= self
.list.GetString(i
), self
.list.IsChecked(i
) 
 498         self
.list.InsertItems([str], i
+1) 
 499         self
.list.Check(i
+1, ch
) 
 500         self
.list.SetSelection(i
+1) 
 501     def OnButtonAppend(self
, evt
): 
 502         str = wxGetTextFromUser('Enter new item:', 'Append', '', self
) 
 503         self
.list.Append(str) 
 504     def OnButtonRemove(self
, evt
): 
 505         self
.list.Delete(self
.list.GetSelection()) 
 506     def OnUpdateUI(self
, evt
): 
 507         if evt
.GetId() == self
.ID_BUTTON_REMOVE
: 
 508             evt
.Enable(self
.list.GetSelection() != -1) 
 509         elif evt
.GetId() == self
.ID_BUTTON_UP
: 
 510             evt
.Enable(self
.list.GetSelection() > 0) 
 511         elif evt
.GetId() == self
.ID_BUTTON_DOWN
: 
 512             evt
.Enable(self
.list.GetSelection() != -1 and \
 
 513                        self
.list.GetSelection() < self
.list.GetCount() - 1) 
 515 class ParamContent(PPanel
): 
 516     def __init__(self
, parent
, name
): 
 517         PPanel
.__init
__(self
, parent
, name
) 
 518         self
.ID_TEXT_CTRL 
= wxNewId() 
 519         self
.ID_BUTTON_EDIT 
= wxNewId() 
 521         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
 522         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5) 
 523         self
.button 
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...', size
=buttonSize
) 
 524         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 525         self
.SetAutoLayout(True) 
 528         self
.textModified 
= False 
 529         EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
) 
 530         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 531     def OnChange(self
, evt
): 
 532         PPanel
.OnChange(self
, evt
) 
 533         self
.textModified 
= True 
 535         if self
.textModified
:           # text has newer value 
 537                 return eval(self
.text
.GetValue()) 
 539                 wxLogError('Syntax error in parameter value: ' + self
.GetName()) 
 542     def SetValue(self
, value
): 
 544         if not value
: value 
= [] 
 546         self
.text
.SetValue(str(value
))  # update text ctrl 
 548     def OnButtonEdit(self
, evt
): 
 549         if self
.textModified
:           # text has newer value 
 551                 self
.value 
= eval(self
.text
.GetValue()) 
 553                 wxLogError('Syntax error in parameter value: ' + self
.GetName()) 
 555         dlg 
= ContentDialog(self
, self
.value
) 
 556         if dlg
.ShowModal() == wxID_OK
: 
 558             for i 
in range(dlg
.list.GetCount()): 
 559                 value
.append(dlg
.list.GetString(i
)) 
 563             self
.textModified 
= False 
 567 class ParamContentCheckList(ParamContent
): 
 568     def __init__(self
, parent
, name
): 
 569         ParamContent
.__init
__(self
, parent
, name
) 
 570     def OnButtonEdit(self
, evt
): 
 571         if self
.textModified
:           # text has newer value 
 573                 self
.value 
= eval(self
.text
.GetValue()) 
 575                 wxLogError('Syntax error in parameter value: ' + self
.GetName()) 
 577         dlg 
= ContentCheckListDialog(self
, self
.value
) 
 578         if dlg
.ShowModal() == wxID_OK
: 
 580             for i 
in range(dlg
.list.GetCount()): 
 581                 value
.append((dlg
.list.GetString(i
), dlg
.list.IsChecked(i
))) 
 585             self
.textModified 
= False 
 588 class IntListDialog(wxDialog
): 
 589     def __init__(self
, parent
, value
): 
 591         g
.frame
.res
.LoadOnDialog(pre
, parent
, 'DIALOG_INTLIST') 
 593         self
._setOORInfo
(self
) 
 594         self
.list = XRCCTRL(self
, 'LIST') 
 598             if type(v
) != IntType
: 
 599                 wxLogError('Invalid item type') 
 601                 self
.list.Append(str(v
)) 
 602         self
.SetAutoLayout(True) 
 603         self
.GetSizer().Fit(self
) 
 605         self
.ID_BUTTON_ADD 
= XRCID('BUTTON_ADD') 
 606         self
.ID_BUTTON_REMOVE 
= XRCID('BUTTON_REMOVE') 
 607         EVT_BUTTON(self
, self
.ID_BUTTON_ADD
, self
.OnButtonAppend
) 
 608         EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
) 
 609         EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
) 
 610     def OnButtonAppend(self
, evt
): 
 611         s 
= wxGetTextFromUser('Enter new number:', 'Add', '', self
) 
 613         # Check that it's unique 
 616             s 
= str(v
)                  # to be sure 
 617             i 
= self
.list.FindString(s
) 
 618             if i 
== -1:                 # ignore non-unique 
 619                 # Find place to insert 
 621                 for i 
in range(self
.list.GetCount()): 
 622                     if int(self
.list.GetString(i
)) > v
: 
 625                 if found
: self
.list.InsertItems([s
], i
) 
 626                 else: self
.list.Append(s
) 
 628             wxLogError('List item is not an int!') 
 629     def OnButtonRemove(self
, evt
): 
 630         self
.list.Delete(self
.list.GetSelection()) 
 631     def OnUpdateUI(self
, evt
): 
 632         if evt
.GetId() == self
.ID_BUTTON_REMOVE
: 
 633             evt
.Enable(self
.list.GetSelection() != -1) 
 636 class ParamIntList(ParamContent
): 
 637     def __init__(self
, parent
, name
): 
 638         ParamContent
.__init
__(self
, parent
, name
) 
 639     def OnButtonEdit(self
, evt
): 
 640         if self
.textModified
:           # text has newer value 
 642                 self
.value 
= eval(self
.text
.GetValue()) 
 644                 wxLogError('Syntax error in parameter value: ' + self
.GetName()) 
 646         dlg 
= IntListDialog(self
, self
.value
) 
 647         if dlg
.ShowModal() == wxID_OK
: 
 649             for i 
in range(dlg
.list.GetCount()): 
 650                 value
.append(int(dlg
.list.GetString(i
))) 
 654             self
.textModified 
= False 
 658 class RadioBox(PPanel
): 
 659     def __init__(self
, parent
, id, choices
, 
 660                  pos
=wxDefaultPosition
, name
='radiobox'): 
 661         PPanel
.__init
__(self
, parent
, name
) 
 662         self
.choices 
= choices
 
 663         topSizer 
= wxBoxSizer() 
 665             button 
= wxRadioButton(self
, -1, i
, size
=(-1,buttonSize
[1]), name
=i
) 
 666             topSizer
.Add(button
, 0, wxRIGHT
, 5) 
 667             EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
) 
 668         self
.SetAutoLayout(True) 
 669         self
.SetSizer(topSizer
) 
 671     def SetStringSelection(self
, value
): 
 673         for i 
in self
.choices
: 
 674             self
.FindWindowByName(i
).SetValue(i 
== value
) 
 677     def OnRadioChoice(self
, evt
): 
 678         if self
.freeze
: return 
 679         if evt
.GetSelection(): 
 680             self
.value 
= evt
.GetEventObject().GetName() 
 682     def GetStringSelection(self
): 
 685 class ParamBool(RadioBox
): 
 686     values 
= {'yes': '1', 'no': '0'}
 
 687     seulav 
= {'1': 'yes', '0': 'no'}
 
 688     def __init__(self
, parent
, name
): 
 689         RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
) 
 691         return self
.values
[self
.GetStringSelection()] 
 692     def SetValue(self
, value
): 
 693         if not value
: value 
= '1' 
 694         self
.SetStringSelection(self
.seulav
[value
]) 
 696 class ParamOrient(RadioBox
): 
 697     values 
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
 
 698     seulav 
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
 
 699     def __init__(self
, parent
, name
): 
 700         RadioBox
.__init
__(self
, parent
, -1, choices
=self
.values
.keys(), name
=name
) 
 702         return self
.values
[self
.GetStringSelection()] 
 703     def SetValue(self
, value
): 
 704         if not value
: value 
= 'wxHORIZONTAL' 
 705         self
.SetStringSelection(self
.seulav
[value
]) 
 707 class ParamFile(PPanel
): 
 708     def __init__(self
, parent
, name
): 
 709         PPanel
.__init
__(self
, parent
, name
) 
 710         self
.ID_TEXT_CTRL 
= wxNewId() 
 711         self
.ID_BUTTON_BROWSE 
= wxNewId() 
 713         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
 714         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 5) 
 715         self
.button 
= wxButton(self
, self
.ID_BUTTON_BROWSE
, 'Browse...',size
=buttonSize
) 
 716         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 717         self
.SetAutoLayout(True) 
 720         self
.textModified 
= False 
 721         EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
) 
 722         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 723     def OnChange(self
, evt
): 
 724         PPanel
.OnChange(self
, evt
) 
 725         self
.textModified 
= True 
 727         if self
.textModified
:           # text has newer value 
 728             return self
.text
.GetValue() 
 730     def SetValue(self
, value
): 
 733         self
.text
.SetValue(value
)  # update text ctrl 
 735     def OnButtonBrowse(self
, evt
): 
 736         if self
.textModified
:           # text has newer value 
 737             self
.value 
= self
.text
.GetValue() 
 738         dlg 
= wxFileDialog(self
, 
 739                            defaultDir 
= os
.path
.abspath(os
.path
.dirname(self
.value
)), 
 740                            defaultFile 
= os
.path
.basename(self
.value
)) 
 741         if dlg
.ShowModal() == wxID_OK
: 
 742             # Get common part of selected path and current 
 744                 curpath 
= os
.path
.abspath(g
.frame
.dataFile
) 
 746                 curpath 
= os
.path
.join(os
.getcwd(), '') 
 747             common 
= os
.path
.commonprefix([curpath
, dlg
.GetPath()]) 
 748             self
.SetValue(dlg
.GetPath()[len(common
):]) 
 750             self
.textModified 
= False 
 753 class ParamBitmap(PPanel
): 
 754     def __init__(self
, parent
, name
): 
 756         g
.frame
.res
.LoadOnPanel(pre
, parent
, 'PANEL_BITMAP') 
 758         self
._setOORInfo
(self
) 
 759         self
.SetBackgroundColour(parent
.GetBackgroundColour()) 
 760         self
.SetForegroundColour(parent
.GetForegroundColour()) 
 761         self
.modified 
= self
.freeze 
= False 
 762         self
.radio_std 
= XRCCTRL(self
, 'RADIO_STD') 
 763         self
.radio_std
.SetBackgroundColour(parent
.GetBackgroundColour()) 
 764         self
.radio_std
.SetForegroundColour(parent
.GetForegroundColour()) 
 765         self
.radio_file 
= XRCCTRL(self
, 'RADIO_FILE') 
 766         self
.radio_file
.SetBackgroundColour(parent
.GetBackgroundColour()) 
 767         self
.radio_file
.SetForegroundColour(parent
.GetForegroundColour()) 
 768         self
.combo 
= XRCCTRL(self
, 'COMBO_STD') 
 769         self
.text 
= XRCCTRL(self
, 'TEXT_FILE') 
 770         self
.button 
= XRCCTRL(self
, 'BUTTON_BROWSE') 
 771         self
.textModified 
= False 
 772         self
.SetAutoLayout(True) 
 773         self
.GetSizer().SetMinSize((260, -1)) 
 774         self
.GetSizer().Fit(self
) 
 775         EVT_RADIOBUTTON(self
, XRCID('RADIO_STD'), self
.OnRadioStd
) 
 776         EVT_RADIOBUTTON(self
, XRCID('RADIO_FILE'), self
.OnRadioFile
) 
 777         EVT_BUTTON(self
, XRCID('BUTTON_BROWSE'), self
.OnButtonBrowse
) 
 778         EVT_COMBOBOX(self
, XRCID('COMBO_STD'), self
.OnCombo
) 
 779         EVT_TEXT(self
, XRCID('COMBO_STD'), self
.OnChange
) 
 780         EVT_TEXT(self
, XRCID('TEXT_FILE'), self
.OnChange
) 
 781     def OnRadioStd(self
, evt
): 
 783         self
.SetValue(['wxART_MISSING_IMAGE','']) 
 784     def OnRadioFile(self
, evt
): 
 786         self
.SetValue(['','']) 
 787     def updateRadios(self
): 
 789             self
.radio_std
.SetValue(True) 
 790             self
.radio_file
.SetValue(False) 
 791             self
.text
.Enable(False) 
 792             self
.button
.Enable(False) 
 793             self
.combo
.Enable(True) 
 795             self
.radio_std
.SetValue(False) 
 796             self
.radio_file
.SetValue(True) 
 797             self
.text
.Enable(True) 
 798             self
.button
.Enable(True) 
 799             self
.combo
.Enable(False) 
 800     def OnChange(self
, evt
): 
 801         PPanel
.OnChange(self
, evt
) 
 802         self
.textModified 
= True 
 803     def OnCombo(self
, evt
): 
 804         PPanel
.OnChange(self
, evt
) 
 805         self
.value
[0] = self
.combo
.GetValue() 
 807         if self
.textModified
:           # text has newer value 
 808             return [self
.combo
.GetValue(), self
.text
.GetValue()] 
 810     def SetValue(self
, value
): 
 813             self
.value 
= ['', ''] 
 816         self
.combo
.SetValue(self
.value
[0]) 
 817         self
.text
.SetValue(self
.value
[1])  # update text ctrl 
 820     def OnButtonBrowse(self
, evt
): 
 821         if self
.textModified
:           # text has newer value 
 822             self
.value
[1] = self
.text
.GetValue() 
 823         dlg 
= wxFileDialog(self
, 
 824                            defaultDir 
= os
.path
.abspath(os
.path
.dirname(self
.value
[1])), 
 825                            defaultFile 
= os
.path
.basename(self
.value
[1])) 
 826         if dlg
.ShowModal() == wxID_OK
: 
 827             # Get common part of selected path and current 
 829                 curpath 
= os
.path
.abspath(g
.frame
.dataFile
) 
 831                 curpath 
= os
.path
.join(os
.getcwd(), '') 
 832             common 
= os
.path
.commonprefix([curpath
, dlg
.GetPath()]) 
 833             self
.SetValue(['', dlg
.GetPath()[len(common
):]]) 
 835             self
.textModified 
= False 
 840     'style': ParamStyle
, 'exstyle': ParamExStyle
, 
 841     'pos': ParamPosSize
, 'size': ParamPosSize
, 
 842     'border': ParamUnit
, 'cols': ParamInt
, 'rows': ParamInt
, 
 843     'vgap': ParamUnit
, 'hgap': ParamUnit
, 
 844     'checkable': ParamBool
, 'checked': ParamBool
, 'radio': ParamBool
, 
 846     'label': ParamMultilineText
, 'title': ParamText
, 'value': ParamText
, 
 847     'content': ParamContent
, 'selection': ParamInt
, 
 848     'min': ParamInt
, 'max': ParamInt
, 
 849     'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
, 
 850     'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
, 
 851     'tooltip': ParamText
, 'bitmap': ParamBitmap
, 'icon': ParamBitmap
, 
 852     'encoding': ParamEncoding