2 # Purpose:      Classes for parameter introduction 
   3 # Author:       Roman Rolinsky <rolinsky@mema.ucl.ac.be> 
   7 from wxPython
.wx 
import * 
   8 from wxPython
.xrc 
import * 
  12 # Object which is currently processed 
  14 def SetCurrentXXX(xxx
): 
  18 genericStyles 
= ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER', 
  19                  'wxSUNKEN_BORDER', 'wxRAISED_BORDER', 
  20                  'wxSTATIC_BORDER', 'wxNO_BORDER', 
  21                  'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS', 
  22                  'wxNO_FULL_REPAINT_ON_RESIZE'] 
  24 # Class that can properly disable children 
  25 class PPanel(wxPanel
): 
  26     def __init__(self
, parent
, id, name
): 
  27         wxPanel
.__init
__(self
, parent
, id, name
=name
) 
  28         self
.modified 
= self
.freeze 
= false
 
  29     def Enable(self
, value
): 
  30         # Something strange is going on with enable so we make sure... 
  31         for w 
in self
.GetChildren(): 
  33         wxPanel
.Enable(self
, value
) 
  34     def SetModified(self
): 
  36         panel
.SetModified(true
)         
  38 class ParamBinaryOr(PPanel
): 
  39     def __init__(self
, parent
, id, size
, name
): 
  40         PPanel
.__init
__(self
, parent
, id, name
) 
  41         self
.ID_TEXT_CTRL 
= wxNewId() 
  42         self
.ID_BUTTON_CHOICES 
= wxNewId() 
  43         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
  45         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
  46         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 10) 
  47         self
.button 
= wxButton(self
, self
.ID_BUTTON_CHOICES
, 'Edit...') 
  48         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
  49         self
.SetAutoLayout(true
) 
  52         EVT_BUTTON(self
, self
.ID_BUTTON_CHOICES
, self
.OnButtonChoices
) 
  53         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
  54     def OnChange(self
, evt
): 
  55         if self
.freeze
: return 
  59         return self
.text
.GetValue() 
  60     def SetValue(self
, value
): 
  62         self
.text
.SetValue(value
) 
  64     def OnButtonChoices(self
, evt
): 
  65         dlg 
= wxDialog(self
, -1, 'Choices') 
  66         topSizer 
= wxBoxSizer(wxVERTICAL
) 
  67         listBox 
= wxCheckListBox(dlg
, -1, choices
=self
.values
, size
=(250,200)) 
  68         value 
= map(string
.strip
, string
.split(self
.text
.GetValue(), '|')) 
  69         if value 
== ['']: value 
= [] 
  73                 listBox
.Check(self
.values
.index(i
)) 
  76                 if self
.equal
.has_key(i
): 
  77                     listBox
.Check(self
.values
.index(self
.equal
[i
])) 
  79                     print 'WARNING: unknown flag: %s: ignored.' % i
 
  81         topSizer
.Add(listBox
, 1, wxEXPAND
) 
  83         buttonOk 
= wxButton(dlg
, wxID_OK
, 'OK') 
  85         sizer
.Add(buttonOk
, 0, wxRIGHT
, 10) 
  87         sizer
.Add(wxButton(dlg
, wxID_CANCEL
, 'Cancel')) 
  88         topSizer
.Add(sizer
, 0, wxALL | wxEXPAND
, 10) 
  89         dlg
.SetAutoLayout(true
) 
  90         dlg
.SetSizer(topSizer
) 
  93         if dlg
.ShowModal() == wxID_OK
:  
  95             for i 
in range(listBox
.Number()): 
  96                 if listBox
.IsChecked(i
): 
  97                     value
.append(self
.values
[i
]) 
 100             self
.SetValue(reduce(lambda a
,b
: a
+'|'+b
, value
)) 
 104 class ParamFlag(ParamBinaryOr
): 
 105     values 
= ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL', 
 106               'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT', 
 107               'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL', 
 108               'wxALIGN_CENTRE_HORIZONTAL'] 
 109     equal 
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE', 
 110              'wxALIGN_CENTER_VERTICAL': 'wxALIGN_CENTRE_VERTICAL', 
 111              'wxALIGN_CENTER_HORIZONTAL': 'wxALIGN_CENTRE_HORIZONTAL'} 
 112     def __init__(self
, parent
, id, size
, name
): 
 113         ParamBinaryOr
.__init
__(self
, parent
, id, size
, name
) 
 115 class ParamStyle(ParamBinaryOr
): 
 116     equal 
= {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
 
 117     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 118         self
.values 
= currentXXX
.winStyles 
+ genericStyles
 
 119         ParamBinaryOr
.__init
__(self
, parent
, id, size
, name
) 
 121 class ParamNonGenericStyle(ParamBinaryOr
): 
 122     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 123         self
.values 
= currentXXX
.winStyles
 
 124         ParamBinaryOr
.__init
__(self
, parent
, id, size
, name
) 
 126 class ParamExStyle(ParamBinaryOr
): 
 127     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 129             self
.values 
= currentXXX
.exStyles 
# constant at the moment 
 132         ParamBinaryOr
.__init
__(self
, parent
, id, size
, name
) 
 134 class ParamColour(PPanel
): 
 135     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 136         PPanel
.__init
__(self
, parent
, id, name
) 
 137         self
.ID_TEXT_CTRL 
= wxNewId() 
 138         self
.ID_BUTTON 
= wxNewId() 
 139         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 141         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(60,-1)) 
 142         sizer
.Add(self
.text
, 0, wxRIGHT
, 10) 
 143         self
.button 
= wxPanel(self
, self
.ID_BUTTON
, wxDefaultPosition
, wxSize(40, -1)) 
 144         sizer
.Add(self
.button
, 0, wxGROW
) 
 145         self
.SetAutoLayout(true
) 
 148         self
.textModified 
= false
 
 149         EVT_PAINT(self
.button
, self
.OnPaintButton
) 
 150         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 151         EVT_LEFT_DOWN(self
.button
, self
.OnLeftDown
) 
 154     def SetValue(self
, value
): 
 156         if not value
: value 
= '#FFFFFF' 
 158         self
.text
.SetValue(str(value
))  # update text ctrl 
 159         colour 
= wxColour(int(value
[1:3], 16), int(value
[3:5], 16), int(value
[5:7], 16)) 
 160         self
.button
.SetBackgroundColour(colour
) 
 161         self
.button
.Refresh() 
 163     def OnChange(self
, evt
): 
 164         if self
.freeze
: return 
 166         self
.textModified 
= true
 
 168     def OnPaintButton(self
, evt
): 
 169         dc 
= wxPaintDC(self
.button
) 
 170         dc
.SetBrush(wxTRANSPARENT_BRUSH
) 
 171         if self
.IsEnabled(): dc
.SetPen(wxBLACK_PEN
) 
 172         else: dc
.SetPen(wxGREY_PEN
) 
 173         size 
= self
.button
.GetSize() 
 174         dc
.DrawRectangle(0, 0, size
.x
, size
.y
) 
 175     def OnLeftDown(self
, evt
): 
 176         dlg 
= wxColourDialog(self
) 
 177         if dlg
.ShowModal() == wxID_OK
: 
 178             self
.SetValue('#%02X%02X%02X' % dlg
.GetColourData().GetColour().Get()) 
 180             self
.textModified 
= false
 
 183 ################################################################################ 
 185 # Mapping from wx constants ro XML strings 
 186 fontFamiliesWx2Xml 
= {wxDEFAULT
: 'default', wxDECORATIVE
: 'decorative', 
 187                 wxROMAN
: 'roman', wxSCRIPT
: 'script', wxSWISS
: 'swiss', 
 189 fontStylesWx2Xml 
= {wxNORMAL: 'normal', wxSLANT: 'slant', wxITALIC: 'italic'}
 
 190 fontWeightsWx2Xml 
= {wxNORMAL: 'normal', wxLIGHT: 'light', wxBOLD: 'bold'}
 
 193     for k
,v 
in m
.items(): rm
[v
] = k
 
 195 fontFamiliesXml2wx 
= ReverseMap(fontFamiliesWx2Xml
) 
 196 fontStylesXml2wx 
= ReverseMap(fontStylesWx2Xml
) 
 197 fontWeightsXml2wx 
= ReverseMap(fontWeightsWx2Xml
) 
 199 class ParamFont(PPanel
): 
 200     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 201         PPanel
.__init
__(self
, parent
, id, name
) 
 202         self
.ID_TEXT_CTRL 
= wxNewId() 
 203         self
.ID_BUTTON_SELECT 
= wxNewId() 
 204         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 206         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
 207         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 10) 
 208         self
.button 
= wxButton(self
, self
.ID_BUTTON_SELECT
, 'Select...') 
 209         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 210         self
.SetAutoLayout(true
) 
 213         self
.textModified 
= false
 
 214         EVT_BUTTON(self
, self
.ID_BUTTON_SELECT
, self
.OnButtonSelect
) 
 215         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 216     def OnChange(self
, evt
): 
 217         if self
.freeze
: return 
 219         self
.textModified 
= true
 
 222         if self
.textModified
:           # text has newer value 
 223             return eval(self
.text
.GetValue()) 
 225     def SetValue(self
, value
): 
 226         self
.freeze 
= true              
# disable other handlers 
 227         if not value
: value 
= [''] * 7 
 229         self
.text
.SetValue(str(value
))  # update text ctrl 
 231     def OnButtonSelect(self
, evt
): 
 232         if self
.textModified
:           # text has newer value 
 233             self
.value 
= eval(self
.text
.GetValue()) 
 235         try: size 
= int(self
.value
[0]) 
 236         except ValueError: size 
= 12 
 237         try: family 
= fontFamiliesXml2wx
[self
.value
[1]] 
 238         except KeyError: family 
= wxDEFAULT
 
 239         try: style 
= fontStylesXml2wx
[self
.value
[2]] 
 240         except KeyError: style 
= wxNORMAL
 
 241         try: weight 
= fontWeightsXml2wx
[self
.value
[3]] 
 242         except KeyError: weight 
= wxNORMAL
 
 243         try: underlined 
= int(self
.value
[4]) 
 244         except ValueError: underlined 
= 0 
 246         mapper 
= wxFontMapper() 
 247         enc 
= wxFONTENCODING_DEFAULT
 
 248         if not self
.value
[6]: enc 
= mapper
.CharsetToEncoding(self
.value
[6]) 
 249         if enc 
== wxFONTENCODING_DEFAULT
: enc 
= wxFONTENCODING_SYSTEM
 
 250         font 
= wxFont(size
, family
, style
, weight
, underlined
, face
, enc
) 
 252         data
.SetInitialFont(font
) 
 253         dlg 
= wxFontDialog(self
, data
) 
 254         if dlg
.ShowModal() == wxID_OK
: 
 255             font 
= dlg
.GetFontData().GetChosenFont() 
 256             value 
= [str(font
.GetPointSize()), fontFamiliesWx2Xml
[font
.GetFamily()], 
 257                      fontStylesWx2Xml
[font
.GetStyle()], 
 258                      fontWeightsWx2Xml
[font
.GetWeight()], 
 259                      str(font
.GetUnderlined()), font
.GetFaceName(), 
 260                      wxFontMapper_GetEncodingName(font
.GetEncoding())] 
 264             self
.textModified 
= false
 
 267 ################################################################################ 
 269 class ParamInt(PPanel
): 
 270     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 271         PPanel
.__init
__(self
, parent
, id, name
) 
 272         self
.ID_SPIN_CTRL 
= wxNewId() 
 274         self
.spin 
= wxSpinCtrl(self
, self
.ID_SPIN_CTRL
, size
=wxSize(50,-1)) 
 275         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 277         self
.SetAutoLayout(true
) 
 280         EVT_SPINCTRL(self
, self
.ID_SPIN_CTRL
, self
.OnChange
) 
 282         return str(self
.spin
.GetValue()) 
 283     def SetValue(self
, value
): 
 285         if not value
: value 
= 0 
 286         self
.spin
.SetValue(int(value
)) 
 288     def OnChange(self
, evt
): 
 289         if self
.freeze
: return 
 293 class ParamText(PPanel
): 
 294     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= '', textWidth
=200): 
 295         PPanel
.__init
__(self
, parent
, id, name
) 
 296         self
.ID_TEXT_CTRL 
= wxNewId() 
 297         # We use sizer even here to have the same size of text control 
 299         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 300         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(textWidth
,-1)) 
 301         sizer
.Add(self
.text
, 0, wxALIGN_CENTER_VERTICAL
) 
 302         self
.SetAutoLayout(true
) 
 305         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 307         return self
.text
.GetValue() 
 308     def SetValue(self
, value
): 
 309         self
.freeze 
= true              
# disable other handlers 
 310         self
.text
.SetValue(value
) 
 311         self
.freeze 
= false             
# disable other handlers 
 312     def OnChange(self
, evt
): 
 313         if self
.freeze
: return 
 317 class ParamAccel(ParamText
): 
 318     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 319         ParamText
.__init
__(self
, parent
, id, size
, name
, 50) 
 321 class ParamPosSize(ParamText
): 
 322     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 323         ParamText
.__init
__(self
, parent
, id, size
, name
, 80) 
 325 class ContentDialog(wxDialog
): 
 326     def __init__(self
, parent
, value
): 
 328         # Use another constructor 
 329         w 
= frame
.res
.LoadDialog(parent
, 'ID_DIALOG_CONTENT') 
 333         #frame.res.LoadOnDialog(self, parent, 'ID_DIALOG_CONTENT') 
 335         self
.list = self
.FindWindowByName('ID_LIST') 
 339         self
.SetAutoLayout(true
) 
 340         # !!! self.SetSizer(sizer) 
 341         self
.GetSizer().Fit(self
) 
 343         self
.ID_BUTTON_APPEND 
= XMLID('ID_BUTTON_APPEND') 
 344         self
.ID_BUTTON_REMOVE 
= XMLID('ID_BUTTON_REMOVE') 
 345         self
.ID_BUTTON_UP 
= XMLID('ID_BUTTON_UP') 
 346         self
.ID_BUTTON_DOWN 
= XMLID('ID_BUTTON_DOWN') 
 347         EVT_BUTTON(self
, self
.ID_BUTTON_UP
, self
.OnButtonUp
) 
 348         EVT_BUTTON(self
, self
.ID_BUTTON_DOWN
, self
.OnButtonDown
) 
 349         EVT_BUTTON(self
, self
.ID_BUTTON_APPEND
, self
.OnButtonAppend
) 
 350         EVT_BUTTON(self
, self
.ID_BUTTON_REMOVE
, self
.OnButtonRemove
) 
 351         EVT_UPDATE_UI(self
, self
.ID_BUTTON_UP
, self
.OnUpdateUI
) 
 352         EVT_UPDATE_UI(self
, self
.ID_BUTTON_DOWN
, self
.OnUpdateUI
) 
 353         EVT_UPDATE_UI(self
, self
.ID_BUTTON_REMOVE
, self
.OnUpdateUI
) 
 354     def OnButtonUp(self
, evt
): 
 355         i 
= self
.list.GetSelection() 
 356         str = self
.list.GetString(i
) 
 358         self
.list.InsertItems([str], i
-1) 
 359         self
.list.SetSelection(i
-1) 
 360     def OnButtonDown(self
, evt
): 
 361         i 
= self
.list.GetSelection() 
 362         str = self
.list.GetString(i
) 
 364         self
.list.InsertItems([str], i
+1) 
 365         self
.list.SetSelection(i
+1) 
 366     def OnButtonAppend(self
, evt
): 
 367         str = wxGetTextFromUser('Enter new item:', 'Append', '', self
) 
 368         self
.list.Append(str) 
 369     def OnButtonRemove(self
, evt
): 
 370         self
.list.Delete(self
.list.GetSelection()) 
 371     def OnUpdateUI(self
, evt
): 
 372         if evt
.GetId() == self
.ID_BUTTON_REMOVE
: 
 373             evt
.Enable(self
.list.GetSelection() != -1) 
 374         elif evt
.GetId() == self
.ID_BUTTON_UP
: 
 375             evt
.Enable(self
.list.GetSelection() > 0) 
 376         elif evt
.GetId() == self
.ID_BUTTON_DOWN
: 
 377             evt
.Enable(self
.list.GetSelection() != -1 and \
 
 378                        self
.list.GetSelection() < self
.list.Number() - 1) 
 380 class ParamContent(PPanel
): 
 381     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 382         PPanel
.__init
__(self
, parent
, id, name
) 
 383         self
.ID_TEXT_CTRL 
= wxNewId() 
 384         self
.ID_BUTTON_EDIT 
= wxNewId() 
 385         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 387         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
 388         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 10) 
 389         self
.button 
= wxButton(self
, self
.ID_BUTTON_EDIT
, 'Edit...') 
 390         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 391         self
.SetAutoLayout(true
) 
 394         self
.textModified 
= false
 
 395         EVT_BUTTON(self
, self
.ID_BUTTON_EDIT
, self
.OnButtonEdit
) 
 396         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 397     def OnChange(self
, evt
): 
 398         if self
.freeze
: return         
 400         self
.textModified 
= true
 
 403         if self
.textModified
:           # text has newer value 
 404             return eval(self
.text
.GetValue()) 
 406     def SetValue(self
, value
): 
 409         self
.text
.SetValue(str(value
))  # update text ctrl 
 411     def OnButtonEdit(self
, evt
): 
 412         if self
.textModified
:           # text has newer value 
 413             self
.value 
= eval(self
.text
.GetValue()) 
 414         dlg 
= ContentDialog(self
, self
.value
) 
 415         if dlg
.ShowModal() == wxID_OK
: 
 417             for i 
in range(dlg
.list.Number()): 
 418                 value
.append(dlg
.list.GetString(i
)) 
 422             self
.textModified 
= false
 
 426 class RadioBox(PPanel
): 
 427     def __init__(self
, parent
, id, choices
, 
 428                  pos
=wxDefaultPosition
, size
=wxDefaultSize
, name
='radiobox'): 
 429         PPanel
.__init
__(self
, parent
, id, name
) 
 430         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 431         self
.choices 
= choices
 
 432         topSizer 
= wxBoxSizer() 
 434             button 
= wxRadioButton(self
, -1, i
, name
=i
) 
 436             EVT_RADIOBUTTON(self
, button
.GetId(), self
.OnRadioChoice
) 
 437         self
.SetAutoLayout(true
) 
 438         self
.SetSizer(topSizer
) 
 440     def SetStringSelection(self
, value
): 
 442         for i 
in self
.choices
: 
 443             self
.FindWindowByName(i
).SetValue(i 
== value
) 
 446     def OnRadioChoice(self
, evt
): 
 447         if self
.freeze
: return 
 448         if evt
.GetSelection(): 
 449             self
.value 
= evt
.GetEventObject().GetName() 
 451     def GetStringSelection(self
): 
 454 class ParamBool(RadioBox
): 
 455     values 
= {'yes': '1', 'no': '0'}
 
 456     seulav 
= {'1': 'yes', '0': 'no'}
 
 457     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 458         RadioBox
.__init
__(self
, parent
, id, choices 
= self
.values
.keys(), name
=name
) 
 460         return self
.values
[self
.GetStringSelection()] 
 461     def SetValue(self
, value
): 
 462         if not value
: value 
= '1' 
 463         self
.SetStringSelection(self
.seulav
[value
]) 
 465 class ParamOrient(RadioBox
): 
 466     values 
= {'horizontal': 'wxHORIZONTAL', 'vertical': 'wxVERTICAL'}
 
 467     seulav 
= {'wxHORIZONTAL': 'horizontal', 'wxVERTICAL': 'vertical'}
 
 468     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''): 
 469         RadioBox
.__init
__(self
, parent
, id, choices 
= self
.values
.keys(), name
=name
) 
 471         return self
.values
[self
.GetStringSelection()] 
 472     def SetValue(self
, value
): 
 473         if not value
: value 
= 'wxHORIZONTAL' 
 474         self
.SetStringSelection(self
.seulav
[value
]) 
 476 class ParamFile(PPanel
): 
 477     def __init__(self
, parent
, id = -1, size 
= wxDefaultSize
, name 
= ''):     
 478         PPanel
.__init
__(self
, parent
, id, name
) 
 479         self
.ID_TEXT_CTRL 
= wxNewId() 
 480         self
.ID_BUTTON_BROWSE 
= wxNewId() 
 481         self
.SetBackgroundColour(panel
.GetBackgroundColour()) 
 483         self
.text 
= wxTextCtrl(self
, self
.ID_TEXT_CTRL
, size
=wxSize(200,-1)) 
 484         sizer
.Add(self
.text
, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL
, 10) 
 485         self
.button 
= wxButton(self
, self
.ID_BUTTON_BROWSE
, 'Browse...') 
 486         sizer
.Add(self
.button
, 0, wxALIGN_CENTER_VERTICAL
) 
 487         self
.SetAutoLayout(true
) 
 490         self
.textModified 
= false
 
 491         EVT_BUTTON(self
, self
.ID_BUTTON_BROWSE
, self
.OnButtonBrowse
) 
 492         EVT_TEXT(self
, self
.ID_TEXT_CTRL
, self
.OnChange
) 
 493     def OnChange(self
, evt
): 
 494         if self
.freeze
: return         
 496         self
.textModified 
= true
 
 499         if self
.textModified
:           # text has newer value 
 500             return eval(self
.text
.GetValue()) 
 502     def SetValue(self
, value
): 
 505         self
.text
.SetValue(value
)  # update text ctrl 
 507     def OnButtonBrowse(self
, evt
): 
 508         if self
.textModified
:           # text has newer value 
 509             self
.value 
= self
.text
.GetValue() 
 510         dlg 
= wxFileDialog(self
, 
 511                            defaultDir 
= os
.path
.abspath(os
.path
.dirname(self
.value
)), 
 512                            defaultFile 
= os
.path
.basename(self
.value
)) 
 513         if dlg
.ShowModal() == wxID_OK
: 
 515             common 
= os
.path
.commonprefix([frame
.dataFile
, dlg
.GetPath()]) 
 516             self
.SetValue(dlg
.GetPath()[len(common
):]) 
 518             self
.textModified 
= false
 
 523     'style': ParamStyle
, 'exstyle': ParamExStyle
, 
 524     'pos': ParamPosSize
, 'size': ParamPosSize
, 
 525     'border': ParamInt
, 'cols': ParamInt
, 'rows': ParamInt
, 
 526     'vgap': ParamInt
, 'hgap': ParamInt
, 
 527     'checkable': ParamBool
, 'accel': ParamAccel
, 
 528     'label': ParamText
, 'title': ParamText
, 'value': ParamText
, 
 529     'content': ParamContent
, 'selection': ParamInt
, 
 530     'min': ParamInt
, 'max': ParamInt
, 
 531     'fg': ParamColour
, 'bg': ParamColour
, 'font': ParamFont
, 
 532     'enabled': ParamBool
, 'focused': ParamBool
, 'hidden': ParamBool
, 
 533     'tooltip': ParamText
, 'bitmap': ParamFile
, 'icon': ParamFile
,