1 #----------------------------------------------------------------------------- 
   2 # Name:        STCStyleEditor.py 
   3 # Purpose:     Style editor for the wxStyledTextCtrl 
   5 # Author:      Riaan Booysen 
   9 # Copyright:   (c) 2001 - 2005 Riaan Booysen 
  10 # Licence:     wxWidgets license 
  11 #----------------------------------------------------------------------------- 
  12 #Boa:Dialog:STCStyleEditDlg 
  14 """ Style editor for the wxStyledTextCtrl. 
  16 Reads in property style definitions from a config file. 
  17 Modified styled can be saved (and optionally applied to a given list of STCs) 
  19 It can also maintain a Common definition dictionary of font names, colours and 
  20 sizes which can be shared across multiple language style definitions. 
  21 This is also used to store platform specific settings as fonts and sizes 
  24 The following items are defined in the stc-styles.rc.cfg file. 
  26 common.defs.msw - Common definition dictionary used on wxMSW 
  27 common.defs.gtk - Common definition dictionary used on wxGTK 
  28 common.defs.mac - Common definition dictionary used on wxMAC 
  29 common.styleidnames - STC styles shared by all languages 
  31 Each supported language defines the following groups: 
  33 displaysrc - Example source to display in the editor 
  34 braces - Dictionary defining the (line, column) for showing 'good' and 'bad' 
  35          brace matching (both keys optional) 
  36 keywords - Space separated list of keywords 
  37 lexer - wxSTC constant for the language lexer 
  38 styleidnames - Dictionary of language specific style numbers and names 
  40 [style.<language>] - The users current style values 
  41 [style.<language>.default] - Default style values (can be reverted from) 
  43 0 or more predefined style groups or 'themes' 
  44 [style.<language>.<predefined name>] 
  46 Currently the following languages are supported: 
  47     python, html, xml, cpp, text, props 
  48 Other languages can be added by just defining the above settings for them in 
  49 the config file (if wxSTC implements them). 
  51 Use the initSTC function to initialise your wxSTC from a config file. 
  54 import os
, sys
, string
, pprint
, copy
 
  57 from wx
.lib
.anchors 
import LayoutAnchors
 
  59 import wxPython
.stc 
# needed names from 2.4 for config files 
  61 settingsIdNames 
= {-1: 'Selection', -2: 'Caret', -3: 'Edge'}
 
  63 commonPropDefs 
= {'fore': '#888888', 'size': 8, 
  66 styleCategoryDescriptions 
= { 
  67  '----Language----': 'Styles specific to the language', 
  68  '----Standard----': 'Styles shared by all languages', 
  69  '----Settings----': 'Properties set by STC methods', 
  70  '----Common----': 'User definable values that can be shared between languages'} 
  72 platformSettings 
= {'__WXMSW__': ('msw', 8), 
  73                      '__WXGTK__': ('gtk', 10), 
  74                      '__WXMAC__': ('mac', 11)} 
  76 [wxID_STCSTYLEEDITDLG
, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
,  
  77  wxID_STCSTYLEEDITDLGBGCOLBTN
, wxID_STCSTYLEEDITDLGBGCOLCB
,  
  78  wxID_STCSTYLEEDITDLGBGCOLDEFCB
, wxID_STCSTYLEEDITDLGBGCOLOKBTN
,  
  79  wxID_STCSTYLEEDITDLGCANCELBTN
, wxID_STCSTYLEEDITDLGCONTEXTHELPBUTTON1
,  
  80  wxID_STCSTYLEEDITDLGELEMENTLB
, wxID_STCSTYLEEDITDLGFACECB
,  
  81  wxID_STCSTYLEEDITDLGFACEDEFCB
, wxID_STCSTYLEEDITDLGFACEOKBTN
,  
  82  wxID_STCSTYLEEDITDLGFGCOLBTN
, wxID_STCSTYLEEDITDLGFGCOLCB
,  
  83  wxID_STCSTYLEEDITDLGFGCOLDEFCB
, wxID_STCSTYLEEDITDLGFGCOLOKBTN
,  
  84  wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, wxID_STCSTYLEEDITDLGOKBTN
,  
  85  wxID_STCSTYLEEDITDLGPANEL1
, wxID_STCSTYLEEDITDLGPANEL2
,  
  86  wxID_STCSTYLEEDITDLGPANEL3
, wxID_STCSTYLEEDITDLGPANEL4
,  
  87  wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, wxID_STCSTYLEEDITDLGSIZECB
,  
  88  wxID_STCSTYLEEDITDLGSIZEOKBTN
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
,  
  89  wxID_STCSTYLEEDITDLGSTATICBOX1
, wxID_STCSTYLEEDITDLGSTATICBOX2
,  
  90  wxID_STCSTYLEEDITDLGSTATICLINE1
, wxID_STCSTYLEEDITDLGSTATICTEXT2
,  
  91  wxID_STCSTYLEEDITDLGSTATICTEXT3
, wxID_STCSTYLEEDITDLGSTATICTEXT4
,  
  92  wxID_STCSTYLEEDITDLGSTATICTEXT6
, wxID_STCSTYLEEDITDLGSTATICTEXT7
,  
  93  wxID_STCSTYLEEDITDLGSTATICTEXT8
, wxID_STCSTYLEEDITDLGSTATICTEXT9
,  
  94  wxID_STCSTYLEEDITDLGSTC
, wxID_STCSTYLEEDITDLGSTYLEDEFST
,  
  95  wxID_STCSTYLEEDITDLGTABOLDCB
, wxID_STCSTYLEEDITDLGTABOLDDEFCB
,  
  96  wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
,  
  97  wxID_STCSTYLEEDITDLGTAITALICCB
, wxID_STCSTYLEEDITDLGTAITALICDEFCB
,  
  98  wxID_STCSTYLEEDITDLGTASIZEDEFCB
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
,  
  99  wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
,  
 100 ] = [wx
.NewId() for _init_ctrls 
in range(47)] 
 102 class STCStyleEditDlg(wx
.Dialog
): 
 103     """ Style editor for the wxStyledTextCtrl """ 
 104     _custom_classes 
= {'wx.Window': ['wx.stc.StyledTextCtrl'],}
 
 105     def _init_ctrls(self
, prnt
): 
 106         # generated method, don't edit 
 107         wx
.Dialog
.__init
__(self
, id=wxID_STCSTYLEEDITDLG
, 
 108               name
='STCStyleEditDlg', parent
=prnt
, pos
=wx
.Point(567, 292), 
 109               size
=wx
.Size(493, 482), 
 110               style
=wx
.WANTS_CHARS | wx
.DEFAULT_DIALOG_STYLE | wx
.RESIZE_BORDER
, 
 111               title
=self
.stc_title
) 
 112         self
.SetClientSize(wx
.Size(485, 455)) 
 113         self
.SetAutoLayout(True) 
 114         self
.SetSizeHints(425, 400, -1, -1) 
 116         self
.Bind(wx
.EVT_SIZE
, self
.OnStcstyleeditdlgSize
) 
 118         self
.speedsettingCh 
= wx
.Choice(choices
=[], 
 119               id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, name
='speedsettingCh', 
 120               parent
=self
, pos
=wx
.Point(96, 28), size
=wx
.Size(380, 21), 
 122         self
.speedsettingCh
.SetConstraints(LayoutAnchors(self
.speedsettingCh
, 
 123               True, True, True, False)) 
 124         self
.speedsettingCh
.SetHelpText('The speed setting allows you to revert to one of the predefined style sets. This will overwrite your current settings when tha dialog is posted.') 
 125         self
.speedsettingCh
.Bind(wx
.EVT_CHOICE
, self
.OnSpeedsettingchChoice
, 
 126               id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
) 
 128         self
.elementLb 
= wx
.ListBox(choices
=[], 
 129               id=wxID_STCSTYLEEDITDLGELEMENTLB
, name
='elementLb', parent
=self
, 
 130               pos
=wx
.Point(8, 70), size
=wx
.Size(175, 128), style
=0) 
 131         self
.elementLb
.SetConstraints(LayoutAnchors(self
.elementLb
, True, True, 
 133         self
.elementLb
.SetHelpText('Select a style here to edit it. Common definitions can be added and maintained here.  A common definition is a property that can be shared between styles and special cased per platform.') 
 134         self
.elementLb
.Bind(wx
.EVT_LISTBOX
, self
.OnElementlbListbox
, 
 135               id=wxID_STCSTYLEEDITDLGELEMENTLB
) 
 137         self
.addCommonItemBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
, 
 138               label
='Add', name
='addCommonItemBtn', parent
=self
, pos
=wx
.Point(8, 
 139               200), size
=wx
.Size(88, 17), style
=0) 
 140         self
.addCommonItemBtn
.SetToolTipString('Add new Common definition') 
 141         self
.addCommonItemBtn
.Bind(wx
.EVT_BUTTON
, self
.OnAddsharebtnButton
, 
 142               id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
) 
 144         self
.removeCommonItemBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, 
 145               label
='Remove', name
='removeCommonItemBtn', parent
=self
, 
 146               pos
=wx
.Point(96, 200), size
=wx
.Size(88, 17), style
=0) 
 147         self
.removeCommonItemBtn
.SetToolTipString('Remove the selected Common definition') 
 148         self
.removeCommonItemBtn
.Bind(wx
.EVT_BUTTON
, 
 149               self
.OnRemovesharebtnButton
, 
 150               id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
) 
 152         self
.styleDefST 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTYLEDEFST
, 
 153               label
='(nothing selected)', name
='styleDefST', parent
=self
, 
 154               pos
=wx
.Point(96, 8), size
=wx
.Size(376, 16), 
 155               style
=wx
.ST_NO_AUTORESIZE
) 
 156         self
.styleDefST
.SetFont(wx
.Font(self
.style_font_size
, wx
.SWISS
, 
 157               wx
.NORMAL
, wx
.BOLD
, False, '')) 
 158         self
.styleDefST
.SetConstraints(LayoutAnchors(self
.styleDefST
, True, 
 161         self
.staticLine1 
= wx
.StaticLine(id=wxID_STCSTYLEEDITDLGSTATICLINE1
, 
 162               name
='staticLine1', parent
=self
, pos
=wx
.Point(48, 64), 
 163               size
=wx
.Size(135, 0), style
=wx
.LI_HORIZONTAL
) 
 164         self
.staticLine1
.SetConstraints(LayoutAnchors(self
.staticLine1
, True, 
 167         self
.staticText6 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT6
, 
 168               label
='Style', name
='staticText6', parent
=self
, pos
=wx
.Point(8, 
 169               56), size
=wx
.Size(40, 13), style
=0) 
 171         self
.staticText8 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT8
, 
 172               label
='Style def:', name
='staticText8', parent
=self
, 
 173               pos
=wx
.Point(8, 8), size
=wx
.Size(88, 13), style
=0) 
 175         self
.staticText9 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT9
, 
 176               label
='SpeedSetting:', name
='staticText9', parent
=self
, 
 177               pos
=wx
.Point(8, 32), size
=wx
.Size(88, 13), style
=0) 
 179         self
.panel3 
= wx
.Panel(id=wxID_STCSTYLEEDITDLGPANEL3
, name
='panel3', 
 180               parent
=self
, pos
=wx
.Point(199, 56), size
=wx
.Size(160, 120), 
 181               style
=wx
.TAB_TRAVERSAL
) 
 182         self
.panel3
.SetConstraints(LayoutAnchors(self
.panel3
, False, True, True, 
 185         self
.panel4 
= wx
.Panel(id=wxID_STCSTYLEEDITDLGPANEL4
, name
='panel4', 
 186               parent
=self
, pos
=wx
.Point(364, 56), size
=wx
.Size(114, 120), 
 187               style
=wx
.TAB_TRAVERSAL
) 
 188         self
.panel4
.SetConstraints(LayoutAnchors(self
.panel4
, False, True, True, 
 191         self
.panel1 
= wx
.Panel(id=wxID_STCSTYLEEDITDLGPANEL1
, name
='panel1', 
 192               parent
=self
, pos
=wx
.Point(202, 177), size
=wx
.Size(149, 40), 
 193               style
=wx
.TAB_TRAVERSAL
) 
 194         self
.panel1
.SetConstraints(LayoutAnchors(self
.panel1
, False, True, True, 
 197         self
.panel2 
= wx
.Panel(id=wxID_STCSTYLEEDITDLGPANEL2
, name
='panel2', 
 198               parent
=self
, pos
=wx
.Point(364, 178), size
=wx
.Size(112, 40), 
 199               style
=wx
.TAB_TRAVERSAL
) 
 200         self
.panel2
.SetConstraints(LayoutAnchors(self
.panel2
, False, True, True, 
 203         self
.stc 
= wx
.stc
.StyledTextCtrl(id=wxID_STCSTYLEEDITDLGSTC
, name
='stc', 
 204               parent
=self
, pos
=wx
.Point(8, 224), size
=wx
.Size(469, 191), 
 205               style
=wx
.SUNKEN_BORDER
) 
 206         self
.stc
.SetConstraints(LayoutAnchors(self
.stc
, True, True, True, True)) 
 207         self
.stc
.SetHelpText('The style preview window. Click or move the cursor over a specific style to select the style for editing in the editors above.') 
 208         self
.stc
.Bind(wx
.EVT_LEFT_UP
, self
.OnUpdateUI
) 
 209         self
.stc
.Bind(wx
.EVT_KEY_UP
, self
.OnUpdateUI
) 
 211         self
.contextHelpButton1 
= wx
.ContextHelpButton(parent
=self
, 
 212               pos
=wx
.Point(8, 423), size
=wx
.Size(24, 24), style
=wx
.BU_AUTODRAW
) 
 213         self
.contextHelpButton1
.SetConstraints(LayoutAnchors(self
.contextHelpButton1
, 
 214               True, False, False, True)) 
 216         self
.okBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGOKBTN
, label
='OK', 
 217               name
='okBtn', parent
=self
, pos
=wx
.Point(316, 423), 
 218               size
=wx
.Size(75, 23), style
=0) 
 219         self
.okBtn
.SetConstraints(LayoutAnchors(self
.okBtn
, False, False, True, 
 221         self
.okBtn
.SetToolTipString('Save changes to the config file') 
 222         self
.okBtn
.Bind(wx
.EVT_BUTTON
, self
.OnOkbtnButton
, 
 223               id=wxID_STCSTYLEEDITDLGOKBTN
) 
 225         self
.cancelBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGCANCELBTN
, 
 226               label
='Cancel', name
='cancelBtn', parent
=self
, pos
=wx
.Point(400, 
 227               423), size
=wx
.Size(75, 23), style
=0) 
 228         self
.cancelBtn
.SetConstraints(LayoutAnchors(self
.cancelBtn
, False, 
 230         self
.cancelBtn
.SetToolTipString('Close dialog without saving changes') 
 231         self
.cancelBtn
.Bind(wx
.EVT_BUTTON
, self
.OnCancelbtnButton
, 
 232               id=wxID_STCSTYLEEDITDLGCANCELBTN
) 
 234         self
.staticText4 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT4
, 
 235               label
='Face:', name
='staticText4', parent
=self
.panel1
, 
 236               pos
=wx
.Point(0, 0), size
=wx
.Size(48, 13), style
=0) 
 238         self
.fixedWidthChk 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, 
 239               label
='', name
='fixedWidthChk', parent
=self
.panel1
, 
 240               pos
=wx
.Point(0, 23), size
=wx
.Size(16, 19), style
=0) 
 241         self
.fixedWidthChk
.SetToolTipString('Check this for Fixed Width fonts') 
 242         self
.fixedWidthChk
.Bind(wx
.EVT_CHECKBOX
, self
.OnFixedwidthchkCheckbox
, 
 243               id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
) 
 245         self
.faceCb 
= wx
.ComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGFACECB
, 
 246               name
='faceCb', parent
=self
.panel1
, pos
=wx
.Point(17, 18), 
 247               size
=wx
.Size(101, 21), style
=0, value
='') 
 249         self
.staticText7 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT7
, 
 250               label
='Size:', name
='staticText7', parent
=self
.panel2
, 
 251               pos
=wx
.Point(0, 0), size
=wx
.Size(40, 13), style
=0) 
 253         self
.sizeCb 
= wx
.ComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGSIZECB
, 
 254               name
='sizeCb', parent
=self
.panel2
, pos
=wx
.Point(0, 17), 
 255               size
=wx
.Size(80, 21), style
=0, value
='') 
 257         self
.sizeOkBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGSIZEOKBTN
, label
='ok', 
 258               name
='sizeOkBtn', parent
=self
.panel2
, pos
=wx
.Point(80, 17), 
 259               size
=wx
.Size(32, 21), style
=0) 
 261         self
.faceOkBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGFACEOKBTN
, label
='ok', 
 262               name
='faceOkBtn', parent
=self
.panel1
, pos
=wx
.Point(117, 18), 
 263               size
=wx
.Size(32, 21), style
=0) 
 265         self
.fgColBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGFGCOLBTN
, 
 266               label
='Foreground', name
='fgColBtn', parent
=self
.panel3
, 
 267               pos
=wx
.Point(8, 16), size
=wx
.Size(96, 16), style
=0) 
 268         self
.fgColBtn
.Bind(wx
.EVT_BUTTON
, self
.OnFgcolbtnButton
, 
 269               id=wxID_STCSTYLEEDITDLGFGCOLBTN
) 
 271         self
.fgColCb 
= wx
.ComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGFGCOLCB
, 
 272               name
='fgColCb', parent
=self
.panel3
, pos
=wx
.Point(8, 32), 
 273               size
=wx
.Size(96, 21), style
=0, value
='') 
 275         self
.fgColOkBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGFGCOLOKBTN
, 
 276               label
='ok', name
='fgColOkBtn', parent
=self
.panel3
, 
 277               pos
=wx
.Point(104, 32), size
=wx
.Size(32, 21), style
=0) 
 279         self
.staticText3 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT3
, 
 280               label
='default', name
='staticText3', parent
=self
.panel3
, 
 281               pos
=wx
.Point(112, 15), size
=wx
.Size(38, 16), style
=0) 
 283         self
.fgColDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGFGCOLDEFCB
, 
 284               label
='checkBox1', name
='fgColDefCb', parent
=self
.panel3
, 
 285               pos
=wx
.Point(136, 31), size
=wx
.Size(16, 16), style
=0) 
 287         self
.bgColBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGBGCOLBTN
, 
 288               label
='Background', name
='bgColBtn', parent
=self
.panel3
, 
 289               pos
=wx
.Point(8, 64), size
=wx
.Size(96, 16), style
=0) 
 290         self
.bgColBtn
.Bind(wx
.EVT_BUTTON
, self
.OnBgcolbtnButton
, 
 291               id=wxID_STCSTYLEEDITDLGBGCOLBTN
) 
 293         self
.bgColCb 
= wx
.ComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGBGCOLCB
, 
 294               name
='bgColCb', parent
=self
.panel3
, pos
=wx
.Point(8, 80), 
 295               size
=wx
.Size(96, 21), style
=0, value
='') 
 297         self
.bgColOkBtn 
= wx
.Button(id=wxID_STCSTYLEEDITDLGBGCOLOKBTN
, 
 298               label
='ok', name
='bgColOkBtn', parent
=self
.panel3
, 
 299               pos
=wx
.Point(104, 80), size
=wx
.Size(32, 21), style
=0) 
 301         self
.staticBox2 
= wx
.StaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX2
, 
 302               label
='Text attributes', name
='staticBox2', parent
=self
.panel4
, 
 303               pos
=wx
.Point(0, 0), size
=wx
.Size(112, 112), style
=0) 
 304         self
.staticBox2
.SetConstraints(LayoutAnchors(self
.staticBox2
, False, 
 306         self
.staticBox2
.SetHelpText('Text attribute flags.') 
 308         self
.staticText2 
= wx
.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT2
, 
 309               label
='default', name
='staticText2', parent
=self
.panel4
, 
 310               pos
=wx
.Point(64, 12), size
=wx
.Size(40, 16), style
=0) 
 312         self
.taBoldDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTABOLDDEFCB
, 
 313               label
='checkBox1', name
='taBoldDefCb', parent
=self
.panel4
, 
 314               pos
=wx
.Point(88, 27), size
=wx
.Size(16, 16), style
=0) 
 316         self
.taItalicDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTAITALICDEFCB
, 
 317               label
='checkBox1', name
='taItalicDefCb', parent
=self
.panel4
, 
 318               pos
=wx
.Point(88, 48), size
=wx
.Size(16, 16), style
=0) 
 320         self
.taUnderlinedDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
, 
 321               label
='checkBox1', name
='taUnderlinedDefCb', parent
=self
.panel4
, 
 322               pos
=wx
.Point(88, 70), size
=wx
.Size(16, 16), style
=0) 
 324         self
.taEOLfilledDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
, 
 325               label
='checkBox1', name
='taEOLfilledDefCb', parent
=self
.panel4
, 
 326               pos
=wx
.Point(88, 92), size
=wx
.Size(16, 16), style
=0) 
 328         self
.taEOLfilledCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, 
 329               label
='EOL filled', name
='taEOLfilledCb', parent
=self
.panel4
, 
 330               pos
=wx
.Point(8, 92), size
=wx
.Size(80, 16), style
=0) 
 331         self
.taEOLfilledCb
.Bind(wx
.EVT_CHECKBOX
, self
.OnTaeoffilledcbCheckbox
, 
 332               id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
) 
 334         self
.taUnderlinedCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, 
 335               label
='Underlined', name
='taUnderlinedCb', parent
=self
.panel4
, 
 336               pos
=wx
.Point(8, 70), size
=wx
.Size(80, 16), style
=0) 
 337         self
.taUnderlinedCb
.Bind(wx
.EVT_CHECKBOX
, self
.OnTaunderlinedcbCheckbox
, 
 338               id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
) 
 340         self
.taItalicCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTAITALICCB
, 
 341               label
='Italic', name
='taItalicCb', parent
=self
.panel4
, 
 342               pos
=wx
.Point(8, 48), size
=wx
.Size(80, 16), style
=0) 
 343         self
.taItalicCb
.Bind(wx
.EVT_CHECKBOX
, self
.OnTaitaliccbCheckbox
, 
 344               id=wxID_STCSTYLEEDITDLGTAITALICCB
) 
 346         self
.taBoldCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTABOLDCB
, 
 347               label
='Bold', name
='taBoldCb', parent
=self
.panel4
, pos
=wx
.Point(8, 
 348               27), size
=wx
.Size(80, 16), style
=0) 
 349         self
.taBoldCb
.Bind(wx
.EVT_CHECKBOX
, self
.OnTaboldcbCheckbox
, 
 350               id=wxID_STCSTYLEEDITDLGTABOLDCB
) 
 352         self
.bgColDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGBGCOLDEFCB
, 
 353               label
='checkBox1', name
='bgColDefCb', parent
=self
.panel3
, 
 354               pos
=wx
.Point(136, 79), size
=wx
.Size(16, 16), style
=0) 
 356         self
.staticBox1 
= wx
.StaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX1
, 
 357               label
='Colour', name
='staticBox1', parent
=self
.panel3
, 
 358               pos
=wx
.Point(0, 0), size
=wx
.Size(157, 112), style
=0) 
 359         self
.staticBox1
.SetConstraints(LayoutAnchors(self
.staticBox1
, False, 
 362         self
.faceDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGFACEDEFCB
, 
 363               label
='checkBox1', name
='faceDefCb', parent
=self
.panel1
, 
 364               pos
=wx
.Point(117, 0), size
=wx
.Size(16, 16), style
=0) 
 366         self
.taSizeDefCb 
= wx
.CheckBox(id=wxID_STCSTYLEEDITDLGTASIZEDEFCB
, 
 367               label
='checkBox1', name
='taSizeDefCb', parent
=self
.panel2
, 
 368               pos
=wx
.Point(80, 0), size
=wx
.Size(16, 16), style
=0) 
 370     def __init__(self
, parent
, langTitle
, lang
, configFile
, STCsToUpdate
=()): 
 371         self
.stc_title 
= 'wxStyledTextCtrl Style Editor' 
 372         self
.stc_title 
= 'wxStyledTextCtrl Style Editor - %s' % langTitle
 
 373         self
.style_font_size 
= 8 
 374         self
.style_font_size 
= platformSettings
[wx
.Platform
][1] 
 375         self
._init
_ctrls
(parent
) 
 377         self
.configFile 
= configFile
 
 382         self
.STCsToUpdate 
= STCsToUpdate
 
 383         self
._blockUpdate 
= False 
 385         global commonPropDefs 
 
 386         commonPropDefs 
= {'fore': '#888888', 'size': 8, 
 387                           'face': wx
.SystemSettings
.GetFont(wx
.SYS_DEFAULT_GUI_FONT
).GetFaceName()} 
 389         for combo
, okBtn
, evtRet
, evtCB
, evtRDC 
in ( 
 390          (self
.fgColCb
, self
.fgColOkBtn
, self
.OnfgColRet
, self
.OnfgColCombobox
, self
.OnGotoCommonDef
), 
 391          (self
.bgColCb
, self
.bgColOkBtn
, self
.OnbgColRet
, self
.OnbgColCombobox
, self
.OnGotoCommonDef
), 
 392          (self
.faceCb
, self
.faceOkBtn
, self
.OnfaceRet
, self
.OnfaceCombobox
, self
.OnGotoCommonDef
), 
 393          (self
.sizeCb
, self
.sizeOkBtn
, self
.OnsizeRet
, self
.OnsizeCombobox
, self
.OnGotoCommonDef
)): 
 394             self
.bindComboEvts(combo
, okBtn
, evtRet
, evtCB
, evtRDC
) 
 396         (self
.config
, self
.commonDefs
, self
.styleIdNames
, self
.styles
, 
 397          self
.styleGroupNames
, self
.predefStyleGroups
, 
 398          self
.otherLangStyleGroupNames
, self
.otherLangStyleGroups
, 
 399          self
.displaySrc
, self
.lexer
, self
.keywords
, self
.braceInfo
) = \
 
 400               initFromConfig(configFile
, lang
) 
 402         self
.currSpeedSetting 
= 'style.%s'%self
.lang
 
 403         for grp 
in [self
.currSpeedSetting
]+self
.styleGroupNames
: 
 404             self
.speedsettingCh
.Append(grp
) 
 405         self
.speedsettingCh
.SetSelection(0) 
 408         self
.stc
.SetMarginType(margin
, wx
.stc
.STC_MARGIN_NUMBER
) 
 409         self
.stc
.SetMarginWidth(margin
, 25) 
 410         self
.stc
.SetMarginSensitive(margin
, True) 
 411         self
.stc
.Bind(wx
.stc
.EVT_STC_MARGINCLICK
, self
.OnMarginClick
, id=wxID_STCSTYLEEDITDLGSTC
) 
 413         self
.stc
.SetUseTabs(False) 
 414         self
.stc
.SetTabWidth(4) 
 415         self
.stc
.SetIndentationGuides(True) 
 416         self
.stc
.SetEdgeMode(wx
.stc
.STC_EDGE_BACKGROUND
) 
 417         self
.stc
.SetEdgeColumn(44) 
 421         self
.populateStyleSelector() 
 423         self
.defNames
, self
.defValues 
= parseProp(\
 
 424               self
.styleDict
.get(wx
.stc
.STC_STYLE_DEFAULT
, '')) 
 425         self
.stc
.SetText(self
.displaySrc
) 
 426         self
.stc
.EmptyUndoBuffer() 
 427         self
.stc
.SetCurrentPos(self
.stc
.GetTextLength()) 
 428         self
.stc
.SetAnchor(self
.stc
.GetTextLength()) 
 430         self
.populateCombosWithCommonDefs() 
 432         # Logical grouping of controls and the property they edit 
 433         self
.allCtrls 
= [((self
.fgColBtn
, self
.fgColCb
, self
.fgColOkBtn
), self
.fgColDefCb
, 
 434                              'fore', wxID_STCSTYLEEDITDLGFGCOLDEFCB
), 
 435                          ((self
.bgColBtn
, self
.bgColCb
, self
.bgColOkBtn
), self
.bgColDefCb
, 
 436                              'back', wxID_STCSTYLEEDITDLGBGCOLDEFCB
), 
 437                          (self
.taBoldCb
, self
.taBoldDefCb
, 
 438                              'bold', wxID_STCSTYLEEDITDLGTABOLDDEFCB
), 
 439                          (self
.taItalicCb
, self
.taItalicDefCb
, 
 440                              'italic', wxID_STCSTYLEEDITDLGTAITALICDEFCB
), 
 441                          (self
.taUnderlinedCb
, self
.taUnderlinedDefCb
, 
 442                              'underline', wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
), 
 443                          (self
.taEOLfilledCb
, self
.taEOLfilledDefCb
, 
 444                              'eolfilled', wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
), 
 445                          ((self
.sizeCb
, self
.sizeOkBtn
), self
.taSizeDefCb
, 
 446                              'size', wxID_STCSTYLEEDITDLGTASIZEDEFCB
), 
 447                          ((self
.faceCb
, self
.faceOkBtn
, self
.fixedWidthChk
), self
.faceDefCb
, 
 448                              'face', wxID_STCSTYLEEDITDLGFACEDEFCB
)] 
 450         self
.clearCtrls(disableDefs
=True) 
 451         # centralised default checkbox event handler 
 453         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 454             self
.chbIdMap
[wid
] = ctrl
, chb
, prop
, wid
 
 455             chb
.Bind(wx
.EVT_CHECKBOX
, self
.OnDefaultCheckBox
, id=wid
) 
 456             chb
.SetToolTipString('Toggle defaults') 
 460 #---Property methods------------------------------------------------------------ 
 461     def getCtrlForProp(self
, findprop
): 
 462         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 465         raise Exception('PropNotFound', findprop
) 
 467     def editProp(self
, on
, prop
, val
=''): 
 468         oldstyle 
= self
.rememberStyles() 
 470             if not self
.names
.count(prop
): 
 471                 self
.names
.append(prop
) 
 472             self
.values
[prop
] = val
 
 474             try: self
.names
.remove(prop
) 
 475             except ValueError: pass 
 476             try: del self
.values
[prop
] 
 477             except KeyError: pass 
 482         except KeyError, errkey
: 
 483             wx
.LogError('Name not found in Common definition, '\
 
 484                 'please enter valid reference. (%s)'%errkey
) 
 485             self
.restoreStyles(oldstyle
) 
 488 #---Control population methods-------------------------------------------------- 
 490         if self
._blockUpdate
: return 
 491         self
.styles
, self
.styleDict
, self
.styleNumIdxMap 
= \
 
 492               setSTCStyles(self
.stc
, self
.styles
, self
.styleIdNames
, 
 493               self
.commonDefs
, self
.lang
, self
.lexer
, self
.keywords
) 
 495     def updateStyle(self
): 
 496         # called after a control edited self.names, self.values 
 497         # Special case for saving common defs settings 
 498         if self
.styleNum 
== 'common': 
 502             strVal 
= self
.style
[2] = self
.values
.values()[0] 
 503             if self
.style
[1] == 'size': self
.style
[2] = int(strVal
) 
 505             self
.commonDefs
[self
.style
[0]] = self
.style
[2] 
 506             self
.styleDefST
.SetLabel(strVal
) 
 508             self
.style 
= writePropVal(self
.names
, self
.values
) 
 509             styleDecl 
= writeProp(self
.styleNum
, self
.style
, self
.lang
) 
 510             self
.styles
[self
.styleNumIdxMap
[self
.styleNum
]] = styleDecl
 
 511             self
.styleDefST
.SetLabel(self
.style
) 
 514     def findInStyles(self
, txt
, styles
): 
 516             if style
.find(txt
) != -1: 
 520     def rememberStyles(self
): 
 521         return self
.names
[:], copy
.copy(self
.values
) 
 523     def restoreStyles(self
, style
): 
 524         self
.names
, self
.values 
= style
 
 527     def clearCtrls(self
, isDefault
=False, disableDefs
=False): 
 528         self
._blockUpdate 
= True 
 530             for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 531                 if prop 
in ('fore', 'back'): 
 532                     cbtn
, txt
, btn 
= ctrl
 
 533                     cbtn
.SetBackgroundColour(\
 
 534                           wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_BTNFACE
)) 
 535                     cbtn
.SetForegroundColour(wx
.Colour(255, 255, 255)) 
 536                     cbtn
.Enable(isDefault
) 
 538                     txt
.Enable(isDefault
) 
 539                     btn
.Enable(isDefault
) 
 543                     cmb
.Enable(isDefault
) 
 544                     btn
.Enable(isDefault
) 
 548                     cmb
.Enable(isDefault
) 
 549                     btn
.Enable(isDefault
) 
 550                     chk
.Enable(isDefault
) 
 552                 elif prop 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 554                     ctrl
.Enable(isDefault
) 
 556                 chb
.Enable(not isDefault 
and not disableDefs
) 
 559             self
._blockUpdate 
= False 
 561     def populateProp(self
, items
, default
, forceDisable
=False): 
 562         self
._blockUpdate 
= True 
 564             for name
, val 
in items
: 
 566                     ctrl
, chb 
= self
.getCtrlForProp(name
) 
 568                     if name 
in ('fore', 'back'): 
 569                         cbtn
, txt
, btn 
= ctrl
 
 570                         repval 
= val
%self
.commonDefs
 
 571                         cbtn
.SetBackgroundColour(strToCol(repval
)) 
 572                         cbtn
.SetForegroundColour(wx
.Colour(0, 0, 0)) 
 573                         cbtn
.Enable(not forceDisable
) 
 575                         txt
.Enable(not forceDisable
) 
 576                         btn
.Enable(not forceDisable
) 
 577                         chb
.SetValue(default
) 
 581                         cmb
.Enable(not forceDisable
) 
 582                         btn
.Enable(not forceDisable
) 
 583                         chb
.SetValue(default
) 
 587                         cmb
.Enable(not forceDisable
) 
 588                         btn
.Enable(not forceDisable
) 
 589                         chk
.Enable(not forceDisable
) 
 590                         chb
.SetValue(default
) 
 591                     elif name 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 592                         ctrl
.Enable(not forceDisable
) 
 594                         chb
.SetValue(default
) 
 596             self
._blockUpdate 
= False 
 598     def valIsCommonDef(self
, val
): 
 599         return len(val
) >= 5 and val
[:2] == '%(' 
 601     def populateCtrls(self
): 
 602         self
.clearCtrls(self
.styleNum 
== wx
.stc
.STC_STYLE_DEFAULT
, 
 603             disableDefs
=self
.styleNum 
< 0) 
 605         # handle colour controls for settings 
 606         if self
.styleNum 
< 0: 
 607             self
.fgColDefCb
.Enable(True) 
 608             if self
.styleNum 
== -1: 
 609                 self
.bgColDefCb
.Enable(True) 
 611         # populate with default style 
 612         self
.populateProp(self
.defValues
.items(), True, 
 613             self
.styleNum 
!= wx
.stc
.STC_STYLE_DEFAULT
) 
 614         # override with current settings 
 615         self
.populateProp(self
.values
.items(), False) 
 617     def getCommonDefPropType(self
, commonDefName
): 
 618         val 
= self
.commonDefs
[commonDefName
] 
 619         if type(val
) == type(0): return 'size' 
 620         if len(val
) == 7 and val
[0] == '#': return 'fore' 
 623     def bindComboEvts(self
, combo
, btn
, btnEvtMeth
, comboEvtMeth
, rdclickEvtMeth
): 
 624         combo
.Bind(wx
.EVT_COMBOBOX
, comboEvtMeth
, id=combo
.GetId()) 
 625         btn
.Bind(wx
.EVT_BUTTON
, btnEvtMeth
, id=btn
.GetId()) 
 626         combo
.Bind(wx
.EVT_RIGHT_DCLICK
, rdclickEvtMeth
) 
 627         combo
.SetToolTipString('Select from list or click "ok" button on the right to change a manual entry, right double-click \n'\
 
 628             'the drop down button to select Common definition in the Style Editor (if applicable)') 
 629         btn
.SetToolTipString('Accept value') 
 631     def populateCombosWithCommonDefs(self
, fixedWidthOnly
=None): 
 632         self
._blockUpdate 
= True 
 634             commonDefs 
= {'fore': [], 'face': [], 'size': []}
 
 636             if self
.elementLb
.GetSelection() < self
.commonDefsStartIdx
: 
 637                 for common 
in self
.commonDefs
.keys(): 
 638                     prop 
= self
.getCommonDefPropType(common
) 
 639                     commonDefs
[prop
].append('%%(%s)%s'%(common
, 
 640                                                        prop
=='size' and 'd' or 's')) 
 643             currFg
, currBg 
= self
.fgColCb
.GetValue(), self
.bgColCb
.GetValue() 
 644             self
.fgColCb
.Clear(); self
.bgColCb
.Clear() 
 645             for colCommonDef 
in commonDefs
['fore']: 
 646                 self
.fgColCb
.Append(colCommonDef
) 
 647                 self
.bgColCb
.Append(colCommonDef
) 
 648             self
.fgColCb
.SetValue(currFg
); self
.bgColCb
.SetValue(currBg
) 
 651             if fixedWidthOnly 
is None: 
 652                 fixedWidthOnly 
= self
.fixedWidthChk
.GetValue() 
 653             fontEnum 
= wx
.FontEnumerator() 
 654             fontEnum
.EnumerateFacenames(fixedWidthOnly
=fixedWidthOnly
) 
 655             fontNameList 
= fontEnum
.GetFacenames() 
 658             currFace 
= self
.faceCb
.GetValue() 
 660             for colCommonDef 
in fontNameList
+commonDefs
['face']: 
 661                 self
.faceCb
.Append(colCommonDef
) 
 662             self
.faceCb
.SetValue(currFace
) 
 664             # Size (XXX add std font sizes) 
 665             currSize 
= self
.sizeCb
.GetValue() 
 667             for colCommonDef 
in commonDefs
['size']: 
 668                 self
.sizeCb
.Append(colCommonDef
) 
 669             self
.sizeCb
.SetValue(currSize
) 
 671             self
._blockUpdate 
= False 
 673     def populateStyleSelector(self
): 
 674         numStyles 
= self
.styleIdNames
.items() 
 676         self
.styleNumLookup 
= {} 
 681         for num
, name 
in numStyles
: 
 682             if num 
== wx
.stc
.STC_STYLE_DEFAULT
: 
 683                 self
.elementLb
.InsertItems([name
, '----Language----'], 0) 
 684                 self
.elementLb
.Append('----Standard----') 
 685                 stdStart 
= stdPos 
= self
.elementLb
.GetCount() 
 688                 if num 
>= 33 and num 
< 40: 
 689                     self
.elementLb
.InsertItems([name
], stdStart 
+ stdOffset
) 
 690                     stdOffset 
= stdOffset 
+ 1 
 693                     self
.elementLb
.InsertItems([name
], stdStart 
+ extrOffset 
-1) 
 694                     extrOffset 
= extrOffset 
+ 1 
 697                     self
.elementLb
.Append(name
) 
 698             self
.styleNumLookup
[name
] = num
 
 701         self
.elementLb
.Append('----Settings----') 
 702         settings 
= settingsIdNames
.items() 
 703         settings
.sort();settings
.reverse() 
 704         for num
, name 
in settings
: 
 705             self
.elementLb
.Append(name
) 
 706             self
.styleNumLookup
[name
] = num
 
 709         self
.elementLb
.Append('----Common----') 
 710         self
.commonDefsStartIdx 
= self
.elementLb
.GetCount() 
 711         for common 
in self
.commonDefs
.keys(): 
 712             tpe 
= type(self
.commonDefs
[common
]) 
 713             self
.elementLb
.Append('%('+common
+')'+(tpe 
is type('') and 's' or 'd')) 
 714             self
.styleNumLookup
[common
] = num
 
 716 #---Colour methods-------------------------------------------------------------- 
 717     def getColourDlg(self
, colour
, title
=''): 
 718         data 
= wx
.ColourData() 
 719         data
.SetColour(colour
) 
 720         data
.SetChooseFull(True) 
 721         dlg 
= wx
.ColourDialog(self
, data
) 
 724             if dlg
.ShowModal() == wx
.ID_OK
: 
 725                 data 
= dlg
.GetColourData() 
 726                 return data
.GetColour() 
 731     colDlgTitles 
= {'fore': 'Foreground', 'back': 'Background'}
 
 732     def editColProp(self
, colBtn
, colCb
, prop
): 
 733         col 
= self
.getColourDlg(colBtn
.GetBackgroundColour(), 
 734               self
.colDlgTitles
[prop
]+ ' colour') 
 736             colBtn
.SetForegroundColour(wx
.Colour(0, 0, 0)) 
 737             colBtn
.SetBackgroundColour(col
) 
 738             colStr 
= colToStr(col
) 
 739             colCb
.SetValue(colStr
) 
 740             self
.editProp(True, prop
, colStr
) 
 742     def OnFgcolbtnButton(self
, event
): 
 743         self
.editColProp(self
.fgColBtn
, self
.fgColCb
, 'fore') 
 745     def OnBgcolbtnButton(self
, event
): 
 746         self
.editColProp(self
.bgColBtn
, self
.bgColCb
, 'back') 
 748     def editColTCProp(self
, colCb
, colBtn
, prop
, val
=None): 
 750             colStr 
= colCb
.GetValue() 
 754             col 
= strToCol(colStr
%self
.commonDefs
) 
 755         if self
.editProp(colStr
!='', prop
, colStr
): 
 757                 colBtn
.SetForegroundColour(wx
.Colour(0, 0, 0)) 
 758                 colBtn
.SetBackgroundColour(col
) 
 760                 colBtn
.SetForegroundColour(wx
.Colour(255, 255, 255)) 
 761                 colBtn
.SetBackgroundColour(\
 
 762                       wxSystemSettings
.GetColour(wx
.SYS_COLOUR_BTNFACE
)) 
 764     def OnfgColRet(self
, event
): 
 765         try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore') 
 766         except AssertionError: wx
.LogError('Not a valid colour value') 
 768     def OnfgColCombobox(self
, event
): 
 769         if self
._blockUpdate
: return 
 770         try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore', event
.GetString()) 
 771         except AssertionError: wx
.LogError('Not a valid colour value') 
 773     def OnbgColRet(self
, event
): 
 774         try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back') 
 775         except AssertionError: wx
.LogError('Not a valid colour value') 
 777     def OnbgColCombobox(self
, event
): 
 778         if self
._blockUpdate
: return 
 779         try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back', event
.GetString()) 
 780         except AssertionError: wx
.LogError('Not a valid colour value') 
 782 #---Text attribute events------------------------------------------------------- 
 783     def OnTaeoffilledcbCheckbox(self
, event
): 
 784         self
.editProp(event
.IsChecked(), 'eolfilled') 
 786     def OnTaitaliccbCheckbox(self
, event
): 
 787         self
.editProp(event
.IsChecked(), 'italic') 
 789     def OnTaboldcbCheckbox(self
, event
): 
 790         self
.editProp(event
.IsChecked(), 'bold') 
 792     def OnTaunderlinedcbCheckbox(self
, event
): 
 793         self
.editProp(event
.IsChecked(), 'underline') 
 795     def OnGotoCommonDef(self
, event
): 
 796         val 
= event
.GetEventObject().GetValue() 
 797         if self
.valIsCommonDef(val
): 
 798             idx 
= self
.elementLb
.FindString(val
) 
 800                 self
.elementLb
.SetSelection(idx
, True) 
 801                 self
.OnElementlbListbox(None) 
 803     def OnfaceRet(self
, event
): 
 804         self
.setFace(self
.faceCb
.GetValue()) 
 806     def OnfaceCombobox(self
, event
): 
 807         if self
._blockUpdate
: return 
 808         self
.setFace(event
.GetString()) 
 810     def setFace(self
, val
): 
 811         try: val
%self
.commonDefs
 
 812         except KeyError: wx
.LogError('Invalid common definition') 
 813         else: self
.editProp(val
!='', 'face', val
) 
 815     def OnsizeRet(self
, event
): 
 816         self
.setSize(self
.sizeCb
.GetValue()) 
 818     def OnsizeCombobox(self
, event
): 
 819         if self
._blockUpdate
: return 
 820         self
.setSize(event
.GetString()) 
 822     def setSize(self
, val
): 
 823         try: int(val
%self
.commonDefs
) 
 824         except ValueError: wx
.LogError('Not a valid integer size value') 
 825         except KeyError: wx
.LogError('Invalid common definition') 
 826         else: self
.editProp(val
!='', 'size', val
) 
 828 #---Main GUI events------------------------------------------------------------- 
 829     def OnElementlbListbox(self
, event
): 
 830         isCommon 
= self
.elementLb
.GetSelection() >= self
.commonDefsStartIdx
 
 831         self
.removeCommonItemBtn
.Enable(isCommon
) 
 833         styleIdent 
= self
.elementLb
.GetStringSelection() 
 834         # common definition selected 
 836             common 
= styleIdent
[2:-2] 
 837             prop 
= self
.getCommonDefPropType(common
) 
 838             self
.clearCtrls(disableDefs
=True) 
 840                 self
.fgColBtn
.Enable(True) 
 841                 self
.fgColCb
.Enable(True) 
 842                 self
.fgColOkBtn
.Enable(True) 
 844                 self
.faceCb
.Enable(True) 
 845                 self
.fixedWidthChk
.Enable(True) 
 846                 self
.faceOkBtn
.Enable(True) 
 848                 self
.sizeCb
.Enable(True) 
 849                 self
.sizeOkBtn
.Enable(True) 
 851             commonDefVal 
= str(self
.commonDefs
[common
]) 
 852             self
.styleDefST
.SetLabel(commonDefVal
) 
 853             self
.populateProp( [(prop
, commonDefVal
)], True) 
 855             self
.styleNum 
= 'common' 
 856             self
.style 
= [common
, prop
, commonDefVal
] 
 857             self
.names
, self
.values 
= [prop
], {prop: commonDefVal}
 
 859         # normal style element selected 
 860         elif len(styleIdent
) >=2 and styleIdent
[:2] != '--': 
 861             self
.styleNum 
= self
.styleNumLookup
[styleIdent
] 
 862             self
.style 
= self
.styleDict
[self
.styleNum
] 
 863             self
.names
, self
.values 
= parseProp(self
.style
) 
 864             if self
.styleNum 
== wx
.stc
.STC_STYLE_DEFAULT
: 
 865                 self
.defNames
, self
.defValues 
= \
 
 866                       self
.names
, self
.values
 
 868             self
.checkBraces(self
.styleNum
) 
 870             self
.styleDefST
.SetLabel(self
.style
) 
 875             self
.clearCtrls(disableDefs
=True) 
 877                 self
.styleDefST
.SetLabel(styleCategoryDescriptions
[styleIdent
]) 
 879         self
.populateCombosWithCommonDefs() 
 881     def OnDefaultCheckBox(self
, event
): 
 882         if self
.chbIdMap
.has_key(event
.GetId()): 
 883             ctrl
, chb
, prop
, wid 
= self
.chbIdMap
[event
.GetId()] 
 884             restore 
= not event
.IsChecked() 
 885             if prop 
in ('fore', 'back'): 
 886                 cbtn
, cmb
, btn 
= ctrl
 
 891                     colStr 
= cmb
.GetValue() 
 892                     #if prop == 'fore': colStr = self.fgColCb.GetValue() 
 893                     #else: colStr = self.bgColCb.GetValue() 
 894                     if colStr
: self
.editProp(True, prop
, colStr
) 
 896                     self
.editProp(False, prop
) 
 900                 if val
: self
.editProp(restore
, prop
, val
) 
 905                 val 
= cmb
.GetStringSelection() 
 906                 if val
: self
.editProp(restore
, prop
, val
) 
 910             elif prop 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 912                 if ctrl
.GetValue(): self
.editProp(restore
, prop
) 
 914     def OnOkbtnButton(self
, event
): 
 915         # write styles and common defs to the config 
 918             writeStylesToConfig(self
.config
, 'style.%s'%self
.lang
, self
.styles
) 
 919             self
.config
.SetPath('') 
 920             self
.config
.Write(commonDefsFile
, `self
.commonDefs`
) 
 923             for stc 
in self
.STCsToUpdate
: 
 924                 setSTCStyles(stc
, self
.styles
, self
.styleIdNames
, self
.commonDefs
, 
 925                       self
.lang
, self
.lexer
, self
.keywords
) 
 928         self
.EndModal(wx
.ID_OK
) 
 930     def OnCancelbtnButton(self
, event
): 
 931         self
.EndModal(wx
.ID_CANCEL
) 
 933     def OnCommondefsbtnButton(self
, event
): 
 934         dlg 
= wx
.TextEntryDialog(self
, 'Edit common definitions dictionary', 
 935               'Common definitions', pprint
.pformat(self
.commonDefs
), 
 936               style
=wx
.TE_MULTILINE | wx
.OK | wx
.CANCEL | wx
.CENTRE
) 
 938             if dlg
.ShowModal() == wx
.ID_OK
: 
 939                 answer 
= eval(dlg
.GetValue(), stc
.__dict
__) 
 940                 assert type(answer
) is type({}), 'Not a valid dictionary' 
 941                 oldDefs 
= self
.commonDefs
 
 942                 self
.commonDefs 
= answer
 
 945                 except KeyError, badkey
: 
 946                     wx
.LogError(str(badkey
)+' not defined but required, \n'\
 
 947                           'reverting to previous common definition') 
 948                     self
.commonDefs 
= oldDefs
 
 950                 self
.populateCombosWithCommonDefs() 
 955     def OnSpeedsettingchChoice(self
, event
): 
 956         group 
= event
.GetString() 
 958             userStyles 
= 'style.%s'%self
.lang
 
 959             if self
.currSpeedSetting 
== userStyles
: 
 960                 self
.predefStyleGroups
[userStyles
] = self
.styles
 
 961             self
.styles 
= self
.predefStyleGroups
[group
] 
 963             self
.defNames
, self
.defValues 
= parseProp(\
 
 964                   self
.styleDict
.get(wx
.stc
.STC_STYLE_DEFAULT
, '')) 
 965             self
.OnElementlbListbox(None) 
 966             self
.currSpeedSetting 
= group
 
 968     def OnFixedwidthchkCheckbox(self
, event
): 
 969         self
.populateCombosWithCommonDefs(event
.IsChecked()) 
 971     def OnAddsharebtnButton(self
, event
): 
 972         dlg 
= CommonDefDlg(self
) 
 974             if dlg
.ShowModal() == wx
.ID_OK
: 
 975                 prop
, name 
= dlg
.result
 
 976                 if not self
.commonDefs
.has_key(name
): 
 977                     self
.commonDefs
[name
] = commonPropDefs
[prop
] 
 978                     self
.elementLb
.Append('%('+name
+')'+\
 
 979                      (type(commonPropDefs
[prop
]) is type('') and 's' or 'd')) 
 980                     self
.elementLb
.SetSelection(self
.elementLb
.GetCount()-1, True) 
 981                     self
.populateCombosWithCommonDefs() 
 982                     self
.OnElementlbListbox(None) 
 986     def OnRemovesharebtnButton(self
, event
): 
 987         ownGroup 
= 'style.%s'%self
.lang
 
 988         comDef 
= self
.elementLb
.GetStringSelection() 
 990         # Search ALL styles before removing 
 991         srchDct 
= {ownGroup: self.styles}
 
 992         srchDct
.update(self
.predefStyleGroups
) 
 993         srchDct
.update(self
.otherLangStyleGroups
) 
 996         for grpName
, styles 
in srchDct
.items(): 
 997             if self
.findInStyles(comDef
, styles
): 
 998                 matchList
.append(grpName
) 
1001             wx
.LogError('Aborted: '+comDef
+' is still used in the styles of the \n'\
 
1002                   'following groups in the config file (stc-styles.rc.cfg):\n'+ \
 
1003                   '\n'.join(matchList
)) 
1005             del self
.commonDefs
[comDef
[2:-2]] 
1007             self
.populateCombosWithCommonDefs() 
1008             selIdx 
= self
.elementLb
.GetSelection() 
1009             self
.elementLb
.Delete(selIdx
) 
1010             if selIdx 
== self
.elementLb
.GetCount(): 
1012             self
.elementLb
.SetSelection(selIdx
, True) 
1013             self
.OnElementlbListbox(None) 
1015 #---STC events------------------------------------------------------------------ 
1016     def OnUpdateUI(self
, event
): 
1017         styleBefore 
= self
.stc
.GetStyleAt(self
.stc
.GetCurrentPos()) 
1018         if self
.styleIdNames
.has_key(styleBefore
): 
1019             self
.elementLb
.SetStringSelection(self
.styleIdNames
[styleBefore
], 
1022             self
.elementLb
.SetSelection(0, False) 
1023             self
.styleDefST
.SetLabel('Style %d not defined, sorry.'%styleBefore
) 
1024         self
.OnElementlbListbox(None) 
1027     def checkBraces(self
, style
): 
1028         if style 
== wx
.stc
.STC_STYLE_BRACELIGHT 
and self
.braceInfo
.has_key('good'): 
1029             line
, col 
= self
.braceInfo
['good'] 
1030             pos 
= self
.stc
.PositionFromLine(line
-1) + col
 
1031             braceOpposite 
= self
.stc
.BraceMatch(pos
) 
1032             if braceOpposite 
!= -1: 
1033                 self
.stc
.BraceHighlight(pos
, braceOpposite
) 
1034         elif style 
== wx
.stc
.STC_STYLE_BRACEBAD 
and self
.braceInfo
.has_key('bad'): 
1035             line
, col 
= self
.braceInfo
['bad'] 
1036             pos 
= self
.stc
.PositionFromLine(line
-1) + col
 
1037             self
.stc
.BraceBadLight(pos
) 
1039             self
.stc
.BraceBadLight(-1) 
1042     def OnStcstyleeditdlgSize(self
, event
): 
1044         # Without this refresh, resizing leaves artifacts 
1048     def OnMarginClick(self
, event
): 
1049         self
.elementLb
.SetStringSelection('Line numbers', True) 
1050         self
.OnElementlbListbox(None) 
1053 #---Common definition dialog---------------------------------------------------- 
1055 [wxID_COMMONDEFDLG
, wxID_COMMONDEFDLGCANCELBTN
, wxID_COMMONDEFDLGCOMDEFNAMETC
, wxID_COMMONDEFDLGOKBTN
, wxID_COMMONDEFDLGPROPTYPERBX
, wxID_COMMONDEFDLGSTATICBOX1
] = [wx
.NewId() for _init_ctrls 
in range(6)] 
1057 class CommonDefDlg(wx
.Dialog
): 
1058     def _init_ctrls(self
, prnt
): 
1059         wx
.Dialog
.__init
__(self
, id = wxID_COMMONDEFDLG
, name 
= 'CommonDefDlg', parent 
= prnt
, pos 
= wx
.Point(398, 249), size 
= wx
.Size(192, 220), style
= wx
.DEFAULT_DIALOG_STYLE
, title 
= 'Common definition') 
1060         self
.SetClientSize(wx
.Size(184, 200)) 
1062         self
.propTypeRBx 
= wx
.RadioBox(choices 
= ['Colour value', 'Font face', 'Size value'], id = wxID_COMMONDEFDLGPROPTYPERBX
, label 
= 'Property type', majorDimension 
= 1, name 
= 'propTypeRBx', parent 
= self
, point 
= wx
.Point(8, 8), size 
= wx
.Size(168, 92), style
= wx
.RA_SPECIFY_COLS
) 
1063         self
.propTypeRBx
.SetSelection(self
._propTypeIdx
) 
1065         self
.staticBox1 
= wx
.StaticBox(id = wxID_COMMONDEFDLGSTATICBOX1
, label 
= 'Name', name 
= 'staticBox1', parent 
= self
, pos 
= wx
.Point(8, 108), size 
= wx
.Size(168, 46), style 
= 0) 
1067         self
.comDefNameTC 
= wx
.TextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC
, name 
= 'comDefNameTC', parent 
= self
, pos 
= wx
.Point(16, 124), size 
= wx
.Size(152, 21), style 
= 0, value 
= '') 
1068         self
.comDefNameTC
.SetLabel(self
._comDefName
) 
1070         self
.okBtn 
= wx
.Button(id = wxID_COMMONDEFDLGOKBTN
, label 
= 'OK', name 
= 'okBtn', parent 
= self
, pos 
= wx
.Point(8, 164), size 
= wx
.Size(80, 23), style 
= 0) 
1071         self
.okBtn
.Bind(wx
.EVT_BUTTON
, self
.OnOkbtnButton
, id=wxID_COMMONDEFDLGOKBTN
) 
1073         self
.cancelBtn 
= wx
.Button(id = wxID_COMMONDEFDLGCANCELBTN
, label 
= 'Cancel', name 
= 'cancelBtn', parent 
= self
, pos 
= wx
.Point(96, 164), size 
= wx
.Size(80, 23), style 
= 0) 
1074         self
.cancelBtn
.Bind(wx
.EVT_BUTTON
, self
.OnCancelbtnButton
, id=wxID_COMMONDEFDLGCANCELBTN
) 
1076     def __init__(self
, parent
, name
='', propIdx
=0): 
1077         self
._comDefName 
= '' 
1078         self
._comDefName 
= name
 
1079         self
._propTypeIdx 
= 0 
1080         self
._propTypeIdx 
= propIdx
 
1081         self
._init
_ctrls
(parent
) 
1083         self
.propMap 
= {0: 'fore', 1: 'face', 2: 'size'}
 
1084         self
.result 
= ( '', '' ) 
1086         self
.Center(wx
.BOTH
) 
1088     def OnOkbtnButton(self
, event
): 
1089         self
.result 
= ( self
.propMap
[self
.propTypeRBx
.GetSelection()], 
1090                         self
.comDefNameTC
.GetValue() ) 
1091         self
.EndModal(wx
.ID_OK
) 
1093     def OnCancelbtnButton(self
, event
): 
1094         self
.result 
= ( '', '' ) 
1095         self
.EndModal(wx
.ID_CANCEL
) 
1097 #---Functions useful outside of the editor---------------------------------- 
1099 def setSelectionColour(stc
, style
): 
1100     names
, values 
= parseProp(style
) 
1102         stc
.SetSelForeground(True, strToCol(values
['fore'])) 
1104         stc
.SetSelBackground(True, strToCol(values
['back'])) 
1106 def setCursorColour(stc
, style
): 
1107     names
, values 
= parseProp(style
) 
1109         stc
.SetCaretForeground(strToCol(values
['fore'])) 
1111 def setEdgeColour(stc
, style
): 
1112     names
, values 
= parseProp(style
) 
1114         stc
.SetEdgeColour(strToCol(values
['fore'])) 
1116 def strToCol(strCol
): 
1117     assert len(strCol
) == 7 and strCol
[0] == '#', 'Not a valid colour string: '+strCol
 
1118     return wx
.Colour(string
.atoi('0x'+strCol
[1:3], 16), 
1119                     string
.atoi('0x'+strCol
[3:5], 16), 
1120                     string
.atoi('0x'+strCol
[5:7], 16)) 
1122     return '#%s%s%s' % (string
.zfill(string
.upper(hex(col
.Red())[2:]), 2), 
1123                         string
.zfill(string
.upper(hex(col
.Green())[2:]), 2), 
1124                         string
.zfill(string
.upper(hex(col
.Blue())[2:]), 2)) 
1126 def writeProp(num
, style
, lang
): 
1128         return 'style.%s.%s='%(lang
, string
.zfill(`num`
, 3)) + style
 
1130         return 'setting.%s.%d='%(lang
, num
) + style
 
1132 def writePropVal(names
, values
): 
1136             res
.append(values
[name
] and name
+':'+values
[name
] or name
) 
1137     return ','.join(res
) 
1139 def parseProp(prop
): 
1140     items 
= prop
.split(',') 
1144         nameVal 
= item
.split(':') 
1145         names
.append(nameVal
[0].strip()) 
1146         if len(nameVal
) == 1: 
1147             values
[nameVal
[0]] = '' 
1149             values
[nameVal
[0]] = nameVal
[1].strip() 
1150     return names
, values
 
1152 def parsePropLine(prop
): 
1153     name
, value 
= prop
.split('=') 
1154     return int(name
.split('.')[-1]), value
 
1156 def setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
): 
1160     # build style dict based on given styles 
1161     for numStyle 
in styles
: 
1162         num
, style 
= parsePropLine(numStyle
) 
1163         styleDict
[num
] = style
 
1165     # Add blank style entries for undefined styles 
1167     styleItems 
= styleIdNames
.items() + settingsIdNames
.items() 
1170     for num
, name 
in styleItems
: 
1171         styleNumIdxMap
[num
] = idx
 
1172         if not styleDict
.has_key(num
): 
1174         newStyles
.append(writeProp(num
, styleDict
[num
], lang
)) 
1177     # Set background colour to reduce flashing effect on refresh or page switch 
1179     if styleDict
.has_key(0): prop 
= styleDict
[0] 
1180     else: prop 
= styleDict
[wx
.stc
.STC_STYLE_DEFAULT
] 
1181     names
, vals 
= parseProp(prop
) 
1183         bkCol 
= strToCol(vals
['back']%commonDefs
) 
1186     stc
.SetBackgroundColour(bkCol
) 
1188     # Set the styles on the wxSTC 
1189     stc
.StyleResetDefault() 
1190     stc
.ClearDocumentStyle() 
1192     stc
.SetKeyWords(0, keywords
) 
1193     stc
.StyleSetSpec(wx
.stc
.STC_STYLE_DEFAULT
, 
1194           styleDict
[wx
.stc
.STC_STYLE_DEFAULT
] % commonDefs
) 
1197     for num
, style 
in styleDict
.items(): 
1199             stc
.StyleSetSpec(num
, style 
% commonDefs
) 
1201             setSelectionColour(stc
, style 
% commonDefs
) 
1203             setCursorColour(stc
, style 
% commonDefs
) 
1205             setEdgeColour(stc
, style 
% commonDefs
) 
1207     stc
.Colourise(0, stc
.GetTextLength()) 
1209     return newStyles
, styleDict
, styleNumIdxMap
 
1211 #---Config reading and writing ------------------------------------------------- 
1212 commonDefsFile 
= 'common.defs.%s'%(platformSettings
[wx
.Platform
][0]) 
1214 def readPyValFromConfig(conf
, name
): 
1216     #ns.update(wx.stc.__dict__) 
1217     ns
.update(wxPython
.stc
.__dict
__) 
1219     value 
= conf
.Read(name
).replace('\r\n', '\n')+'\n' 
1221         return eval(value
, ns
) 
1226 def initFromConfig(configFile
, lang
): 
1227     if not os
.path
.exists(configFile
): 
1228         raise Exception, 'Config file %s not found'%configFile
 
1229     cfg 
= wx
.FileConfig(localFilename
=configFile
, style
= wx
.CONFIG_USE_LOCAL_FILE
) 
1230     cfg
.SetExpandEnvVars(False) 
1232     # read in all group names for this language 
1233     groupPrefix 
= 'style.%s'%lang
 
1234     gpLen 
= len(groupPrefix
) 
1235     predefStyleGroupNames
, otherLangStyleGroupNames 
= [], [] 
1236     cont
, val
, idx 
= cfg
.GetFirstGroup() 
1238         if val 
!= groupPrefix 
and len(val
) >= 5 and val
[:5] == 'style': 
1239             if len(val
) > gpLen 
and val
[:gpLen
] == groupPrefix
: 
1240                 predefStyleGroupNames
.append(val
) 
1242                 otherLangStyleGroupNames
.append(val
) 
1244         cont
, val
, idx 
= cfg
.GetNextGroup(idx
) 
1246     # read in common elements 
1247     commonDefs 
= readPyValFromConfig(cfg
, commonDefsFile
) 
1248     assert type(commonDefs
) is type({}), \
 
1249           'Common definitions (%s) not a valid dict'%commonDefsFile
 
1251     commonStyleIdNames 
= readPyValFromConfig(cfg
, 'common.styleidnames') 
1252     assert type(commonStyleIdNames
) is type({}), \
 
1253           'Common definitions (%s) not a valid dict'%'common.styleidnames' 
1255     # Lang specific settings 
1257     styleIdNames 
= readPyValFromConfig(cfg
, 'styleidnames') 
1258     assert type(commonStyleIdNames
) is type({}), \
 
1259           'Not a valid dict [%s] styleidnames)'%lang
 
1260     styleIdNames
.update(commonStyleIdNames
) 
1261     braceInfo 
= readPyValFromConfig(cfg
, 'braces') 
1262     assert type(commonStyleIdNames
) is type({}), \
 
1263           'Not a valid dict [%s] braces)'%lang
 
1265     displaySrc 
= cfg
.Read('displaysrc') 
1266     lexer 
= readPyValFromConfig(cfg
, 'lexer') 
1267     keywords 
= cfg
.Read('keywords') 
1271     # read in current styles 
1272     styles 
= readStylesFromConfig(cfg
, groupPrefix
) 
1274     # read in predefined styles 
1275     predefStyleGroups 
= {} 
1276     for group 
in predefStyleGroupNames
: 
1277         predefStyleGroups
[group
] = readStylesFromConfig(cfg
, group
) 
1279     # read in all other style sections 
1280     otherLangStyleGroups 
= {} 
1281     for group 
in otherLangStyleGroupNames
: 
1282         otherLangStyleGroups
[group
] = readStylesFromConfig(cfg
, group
) 
1284     return (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
, 
1285             predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
, 
1286             displaySrc
, lexer
, keywords
, braceInfo
) 
1288 def readStylesFromConfig(config
, group
): 
1290     config
.SetPath(group
) 
1292     cont
, val
, idx 
= config
.GetFirstEntry() 
1294         styles
.append(val
+'='+config
.Read(val
)) 
1295         cont
, val
, idx 
= config
.GetNextEntry(idx
) 
1300 def writeStylesToConfig(config
, group
, styles
): 
1302     config
.DeleteGroup(group
) 
1303     config
.SetPath(group
) 
1305     for style 
in styles
: 
1306         name
, value 
= style
.split('=') 
1307         config
.Write(name
, value
.strip()) 
1311 #------------------------------------------------------------------------------- 
1312 def initSTC(stc
, config
, lang
): 
1313     """ Main module entry point. Initialise a wxSTC from given config file.""" 
1314     (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
, 
1315      predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
, 
1316      displaySrc
, lexer
, keywords
, braceInfo
) = initFromConfig(config
, lang
) 
1318     setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
) 
1320 #------------------------------------------------------------------------------- 
1321 if __name__ 
== '__main__': 
1322     app 
= wx
.PySimpleApp() 
1324     provider 
= wx
.SimpleHelpProvider() 
1325     wx
.HelpProvider
.Set(provider
) 
1327     home 
= os
.environ
.get('HOME') 
1329         home 
= os
.path
.join(home
, '.boa-constructor') 
1330         if not os
.path
.exists(home
): 
1335     config 
= os
.path
.abspath(os
.path
.join(home
, 'stc-styles.rc.cfg')) 
1337         f 
= wx
.Frame(None, -1, 'Test frame (double click for editor)') 
1338         stc 
= wx
.stc
.StyledTextCtrl(f
, -1) 
1339         def OnDblClick(evt
, stc
=stc
): 
1340             dlg 
= STCStyleEditDlg(None, 'Python', 'python', config
, (stc
,)) 
1341             try: dlg
.ShowModal() 
1342             finally: dlg
.Destroy() 
1343         stc
.SetText(open('STCStyleEditor.py').read()) 
1344         stc
.Bind(wx
.EVT_LEFT_DCLICK
, OnDblClick
) 
1345         initSTC(stc
, config
, 'python') 
1349         dlg 
= STCStyleEditDlg(None, 
1355             #'Properties', 'prop', 
1357         try: dlg
.ShowModal() 
1358         finally: dlg
.Destroy()