1 #----------------------------------------------------------------------------- 
   2 # Name:        STCStyleEditor.py 
   3 # Purpose:     Style editor for the wxStyledTextCtrl 
   5 # Author:      Riaan Booysen 
   9 # Copyright:   (c) 2001 Riaan Booysen 
  10 # Licence:     wxWindows 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 spesific 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.styleidnames - STC styles shared by all languages 
  30 Each supported language defines the following groups: 
  32 displaysrc - Example source to display in the editor 
  33 braces - Dictionary defining the (line, column) for showing 'good' and 'bad' 
  34          brace matching (both keys optional) 
  35 keywords - Space separated list of keywords 
  36 lexer - wxSTC constant for the language lexer 
  37 styleidnames - Dictionary of language spesific style numbers and names 
  39 [style.<language>] - The users current style values 
  40 [style.<language>.default] - Default style values (can be reverted from) 
  42 0 or more predefined style groups or 'themes' 
  43 [style.<language>.<predefined name>] 
  45 Currently the following languages are supported:  
  46     python, html, xml, cpp, text, props 
  47 Other languages can be added by just defining the above settings for them in 
  48 the config file (if wxSTC implements them). 
  50 Use the initSTC function to initialise your wxSTC from a config file. 
  53 import os
, sys
, string
, pprint
, copy
 
  55 from wxPython
.wx 
import * 
  56 from wxPython
.lib
.anchors 
import LayoutAnchors
 
  57 from wxPython
.stc 
import * 
  59 settingsIdNames 
= {-1: 'Selection', -2: 'Caret', -3: 'Edge'}
 
  61 commonPropDefs 
= {'fore': '#888888', 'size': 8,  
  62   'face': wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT
).GetFaceName()} 
  64 styleCategoryDescriptions 
= { 
  65 '-----Language-----': 'Styles spesific to the language', 
  66 '-----Standard-----': 'Styles shared by all languages', 
  67 '-----Settings-----': 'Properties set by STC methods',  
  68 '-----Common-----': 'User definable values that can be shared between languages'} 
  70 [wxID_STCSTYLEEDITDLG
, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
, wxID_STCSTYLEEDITDLGBGCOLBTN
, wxID_STCSTYLEEDITDLGBGCOLCB
, wxID_STCSTYLEEDITDLGBGCOLDEFCB
, wxID_STCSTYLEEDITDLGCANCELBTN
, wxID_STCSTYLEEDITDLGCOMMONDEFSBTN
, wxID_STCSTYLEEDITDLGELEMENTLB
, wxID_STCSTYLEEDITDLGFACECB
, wxID_STCSTYLEEDITDLGFACEDEFCB
, wxID_STCSTYLEEDITDLGFGCOLBTN
, wxID_STCSTYLEEDITDLGFGCOLCB
, wxID_STCSTYLEEDITDLGFGCOLDEFCB
, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, wxID_STCSTYLEEDITDLGOKBTN
, wxID_STCSTYLEEDITDLGPANEL1
, wxID_STCSTYLEEDITDLGPANEL2
, wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, wxID_STCSTYLEEDITDLGSIZECB
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, wxID_STCSTYLEEDITDLGSTATICBOX1
, wxID_STCSTYLEEDITDLGSTATICBOX2
, wxID_STCSTYLEEDITDLGSTATICLINE1
, wxID_STCSTYLEEDITDLGSTATICTEXT2
, wxID_STCSTYLEEDITDLGSTATICTEXT3
, wxID_STCSTYLEEDITDLGSTATICTEXT4
, wxID_STCSTYLEEDITDLGSTATICTEXT6
, wxID_STCSTYLEEDITDLGSTATICTEXT7
, wxID_STCSTYLEEDITDLGSTATICTEXT8
, wxID_STCSTYLEEDITDLGSTATICTEXT9
, wxID_STCSTYLEEDITDLGSTC
, wxID_STCSTYLEEDITDLGSTYLEDEFST
, wxID_STCSTYLEEDITDLGTABOLDCB
, wxID_STCSTYLEEDITDLGTABOLDDEFCB
, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
, wxID_STCSTYLEEDITDLGTAITALICCB
, wxID_STCSTYLEEDITDLGTAITALICDEFCB
, wxID_STCSTYLEEDITDLGTASIZEDEFCB
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
] = map(lambda _init_ctrls
: wxNewId(), range(41)) 
  72 class STCStyleEditDlg(wxDialog
): 
  73     """ Style editor for the wxStyledTextCtrl """ 
  74     _custom_classes 
= {'wxWindow' : ['wxStyledTextCtrl']}
 
  75     def _init_utils(self
):  
  78     def _init_ctrls(self
, prnt
):  
  79         wxDialog
.__init
__(self
, id = wxID_STCSTYLEEDITDLG
, name 
= 'STCStyleEditDlg', parent 
= prnt
, pos 
= wxPoint(416, 307), size 
= wxSize(425, 481), style 
= wxWANTS_CHARS | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
, title 
= self
.stc_title
) 
  81         self
.SetClientSize(wxSize(417, 454)) 
  82         self
.SetAutoLayout(true
) 
  83         self
.SetSizeHints(425, 400, -1, -1) 
  84         EVT_SIZE(self
, self
.OnStcstyleeditdlgSize
) 
  86         self
.staticBox2 
= wxStaticBox(id = wxID_STCSTYLEEDITDLGSTATICBOX2
, label 
= 'Text attributes', name 
= 'staticBox2', parent 
= self
, pos 
= wxPoint(296, 56), size 
= wxSize(112, 99), style 
= 0) 
  87         self
.staticBox2
.SetConstraints(LayoutAnchors(self
.staticBox2
, false
, true
, true
, false
)) 
  89         self
.staticBox1 
= wxStaticBox(id = wxID_STCSTYLEEDITDLGSTATICBOX1
, label 
= 'Colour', name 
= 'staticBox1', parent 
= self
, pos 
= wxPoint(157, 56), size 
= wxSize(128, 99), style 
= 0) 
  90         self
.staticBox1
.SetConstraints(LayoutAnchors(self
.staticBox1
, false
, true
, true
, false
)) 
  92         self
.elementLb 
= wxListBox(choices 
= [], id = wxID_STCSTYLEEDITDLGELEMENTLB
, name 
= 'elementLb', parent 
= self
, pos 
= wxPoint(8, 72), size 
= wxSize(144, 112), style 
= 0, validator 
= wxDefaultValidator
) 
  93         self
.elementLb
.SetConstraints(LayoutAnchors(self
.elementLb
, true
, true
, true
, false
)) 
  94         EVT_LISTBOX(self
.elementLb
, wxID_STCSTYLEEDITDLGELEMENTLB
, self
.OnElementlbListbox
) 
  96         self
.styleDefST 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTYLEDEFST
, label 
= '(nothing selected)', name 
= 'styleDefST', parent 
= self
, pos 
= wxPoint(56, 8), size 
= wxSize(352, 16), style 
= wxST_NO_AUTORESIZE
) 
  97         self
.styleDefST
.SetFont(wxFont(8, wxSWISS
, wxNORMAL
, wxBOLD
, false
, self
.sys_font
)) 
  98         self
.styleDefST
.SetConstraints(LayoutAnchors(self
.styleDefST
, true
, true
, true
, false
)) 
 100         self
.taEOLfilledCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, label 
= 'EOL filled', name 
= 'taEOLfilledCb', parent 
= self
.staticBox2
, pos 
= wxPoint(8, 75), size 
= wxSize(72, 16), style 
= 0) 
 101         self
.taEOLfilledCb
.SetValue(false
) 
 102         EVT_CHECKBOX(self
.taEOLfilledCb
, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, self
.OnTaeoffilledcbCheckbox
) 
 104         self
.staticText2 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT2
, label 
= 'default', name 
= 'staticText2', parent 
= self
.staticBox2
, pos 
= wxPoint(72, 11), size 
= wxSize(32, 16), style 
= 0) 
 106         self
.taItalicCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTAITALICCB
, label 
= 'Italic', name 
= 'taItalicCb', parent 
= self
.staticBox2
, pos 
= wxPoint(8, 43), size 
= wxSize(72, 16), style 
= 0) 
 107         EVT_CHECKBOX(self
.taItalicCb
, wxID_STCSTYLEEDITDLGTAITALICCB
, self
.OnTaitaliccbCheckbox
) 
 109         self
.taUnderlinedDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
, label 
= 'checkBox1', name 
= 'taUnderlinedDefCb', parent 
= self
.staticBox2
, pos 
= wxPoint(88, 59), size 
= wxSize(16, 16), style 
= 0) 
 111         self
.taBoldDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTABOLDDEFCB
, label 
= 'checkBox1', name 
= 'taBoldDefCb', parent 
= self
.staticBox2
, pos 
= wxPoint(88, 27), size 
= wxSize(16, 16), style 
= 0) 
 113         self
.taItalicDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTAITALICDEFCB
, label 
= 'checkBox1', name 
= 'taItalicDefCb', parent 
= self
.staticBox2
, pos 
= wxPoint(88, 43), size 
= wxSize(16, 16), style 
= 0) 
 115         self
.taBoldCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTABOLDCB
, label 
= 'Bold', name 
= 'taBoldCb', parent 
= self
.staticBox2
, pos 
= wxPoint(8, 27), size 
= wxSize(72, 16), style 
= 0) 
 116         EVT_CHECKBOX(self
.taBoldCb
, wxID_STCSTYLEEDITDLGTABOLDCB
, self
.OnTaboldcbCheckbox
) 
 118         self
.taEOLfilledDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
, label 
= 'checkBox1', name 
= 'taEOLfilledDefCb', parent 
= self
.staticBox2
, pos 
= wxPoint(88, 75), size 
= wxSize(16, 16), style 
= 0) 
 120         self
.taUnderlinedCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, label 
= 'Underlined', name 
= 'taUnderlinedCb', parent 
= self
.staticBox2
, pos 
= wxPoint(8, 59), size 
= wxSize(72, 16), style 
= 0) 
 121         EVT_CHECKBOX(self
.taUnderlinedCb
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, self
.OnTaunderlinedcbCheckbox
) 
 123         self
.fgColDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGFGCOLDEFCB
, label 
= 'checkBox1', name 
= 'fgColDefCb', parent 
= self
.staticBox1
, pos 
= wxPoint(104, 31), size 
= wxSize(16, 16), style 
= 0) 
 125         self
.staticText3 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT3
, label 
= 'default', name 
= 'staticText3', parent 
= self
.staticBox1
, pos 
= wxPoint(88, 16), size 
= wxSize(32, 16), style 
= 0) 
 127         self
.bgColDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGBGCOLDEFCB
, label 
= 'checkBox1', name 
= 'bgColDefCb', parent 
= self
.staticBox1
, pos 
= wxPoint(104, 71), size 
= wxSize(16, 16), style 
= 0) 
 129         self
.fgColBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGFGCOLBTN
, label 
= 'Foreground', name 
= 'fgColBtn', parent 
= self
.staticBox1
, pos 
= wxPoint(8, 16), size 
= wxSize(72, 16), style 
= 0) 
 130         EVT_BUTTON(self
.fgColBtn
, wxID_STCSTYLEEDITDLGFGCOLBTN
, self
.OnFgcolbtnButton
) 
 132         self
.bgColBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGBGCOLBTN
, label 
= 'Background', name 
= 'bgColBtn', parent 
= self
.staticBox1
, pos 
= wxPoint(8, 56), size 
= wxSize(72, 16), style 
= 0) 
 133         EVT_BUTTON(self
.bgColBtn
, wxID_STCSTYLEEDITDLGBGCOLBTN
, self
.OnBgcolbtnButton
) 
 135         self
.staticLine1 
= wxStaticLine(id = wxID_STCSTYLEEDITDLGSTATICLINE1
, name 
= 'staticLine1', parent 
= self
, pos 
= wxPoint(36, 62), size 
= wxSize(115, 2), style 
= wxLI_HORIZONTAL
) 
 136         self
.staticLine1
.SetConstraints(LayoutAnchors(self
.staticLine1
, true
, true
, true
, false
)) 
 138         self
.staticText6 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT6
, label 
= 'Style', name 
= 'staticText6', parent 
= self
, pos 
= wxPoint(8, 56), size 
= wxSize(23, 13), style 
= 0) 
 140         self
.okBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGOKBTN
, label 
= 'OK', name 
= 'okBtn', parent 
= self
, pos 
= wxPoint(248, 422), size 
= wxSize(75, 23), style 
= 0) 
 141         self
.okBtn
.SetConstraints(LayoutAnchors(self
.okBtn
, false
, false
, true
, true
)) 
 142         self
.okBtn
.SetToolTipString('Save changes to the config file') 
 143         EVT_BUTTON(self
.okBtn
, wxID_STCSTYLEEDITDLGOKBTN
, self
.OnOkbtnButton
) 
 145         self
.cancelBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGCANCELBTN
, label 
= 'Cancel', name 
= 'cancelBtn', parent 
= self
, pos 
= wxPoint(332, 422), size 
= wxSize(75, 23), style 
= 0) 
 146         self
.cancelBtn
.SetConstraints(LayoutAnchors(self
.cancelBtn
, false
, false
, true
, true
)) 
 147         self
.cancelBtn
.SetToolTipString('Close dialog without saving changes') 
 148         EVT_BUTTON(self
.cancelBtn
, wxID_STCSTYLEEDITDLGCANCELBTN
, self
.OnCancelbtnButton
) 
 150         self
.commonDefsBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGCOMMONDEFSBTN
, label 
= 'Common definitions', name 
= 'commonDefsBtn', parent 
= self
, pos 
= wxPoint(8, 422), size 
= wxSize(104, 23), style 
= 0) 
 151         self
.commonDefsBtn
.SetConstraints(LayoutAnchors(self
.commonDefsBtn
, true
, false
, false
, true
)) 
 152         self
.commonDefsBtn
.SetToolTipString('Directly edit the common definitions dictionary') 
 153         self
.commonDefsBtn
.Show(false
) 
 154         EVT_BUTTON(self
.commonDefsBtn
, wxID_STCSTYLEEDITDLGCOMMONDEFSBTN
, self
.OnCommondefsbtnButton
) 
 156         self
.staticText8 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT8
, label 
= 'Style def:', name 
= 'staticText8', parent 
= self
, pos 
= wxPoint(8, 8), size 
= wxSize(44, 13), style 
= 0) 
 158         self
.staticText9 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT9
, label 
= 'SpeedSetting:', name 
= 'staticText9', parent 
= self
, pos 
= wxPoint(8, 32), size 
= wxSize(67, 13), style 
= 0) 
 160         self
.speedsettingCh 
= wxChoice(choices 
= [], id = wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, name 
= 'speedsettingCh', parent 
= self
, pos 
= wxPoint(88, 28), size 
= wxSize(320, 21), style 
= 0, validator 
= wxDefaultValidator
) 
 161         self
.speedsettingCh
.SetConstraints(LayoutAnchors(self
.speedsettingCh
, true
, true
, true
, false
)) 
 162         EVT_CHOICE(self
.speedsettingCh
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, self
.OnSpeedsettingchChoice
) 
 164         self
.stc 
= wxStyledTextCtrl(id = wxID_STCSTYLEEDITDLGSTC
, name 
= 'stc', parent 
= self
, pos 
= wxPoint(8, 208), size 
= wxSize(401, 206), style 
= wxSUNKEN_BORDER
) 
 165         self
.stc
.SetConstraints(LayoutAnchors(self
.stc
, true
, true
, true
, true
)) 
 166         EVT_LEFT_UP(self
.stc
, self
.OnUpdateUI
) 
 167         EVT_KEY_UP(self
.stc
, self
.OnUpdateUI
) 
 169         self
.panel1 
= wxPanel(id = wxID_STCSTYLEEDITDLGPANEL1
, name 
= 'panel1', parent 
= self
, pos 
= wxPoint(157, 161), size 
= wxSize(128, 40), style 
= wxTAB_TRAVERSAL
) 
 170         self
.panel1
.SetConstraints(LayoutAnchors(self
.panel1
, false
, true
, true
, false
)) 
 172         self
.staticText4 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT4
, label 
= 'Face:', name 
= 'staticText4', parent 
= self
.panel1
, pos 
= wxPoint(0, 0), size 
= wxSize(27, 13), style 
= 0) 
 174         self
.faceDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGFACEDEFCB
, label 
= 'checkBox1', name 
= 'faceDefCb', parent 
= self
.panel1
, pos 
= wxPoint(104, 0), size 
= wxSize(16, 16), style 
= 0) 
 176         self
.fixedWidthChk 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, label 
= '', name 
= 'fixedWidthChk', parent 
= self
.panel1
, pos 
= wxPoint(0, 23), size 
= wxSize(13, 19), style 
= 0) 
 177         self
.fixedWidthChk
.SetValue(false
) 
 178         self
.fixedWidthChk
.SetToolTipString('Check this for Fixed Width fonts') 
 179         EVT_CHECKBOX(self
.fixedWidthChk
, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, self
.OnFixedwidthchkCheckbox
) 
 181         self
.addCommonItemBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
, label 
= 'Add', name 
= 'addCommonItemBtn', parent 
= self
, pos 
= wxPoint(8, 184), size 
= wxSize(72, 16), style 
= 0) 
 182         self
.addCommonItemBtn
.SetToolTipString('Add new Common definition') 
 183         EVT_BUTTON(self
.addCommonItemBtn
, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
, self
.OnAddsharebtnButton
) 
 185         self
.removeCommonItemBtn 
= wxButton(id = wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, label 
= 'Remove', name 
= 'removeCommonItemBtn', parent 
= self
, pos 
= wxPoint(80, 184), size 
= wxSize(72, 16), style 
= 0) 
 186         self
.removeCommonItemBtn
.Enable(false
) 
 187         self
.removeCommonItemBtn
.SetToolTipString('Remove the selected Common definition') 
 188         EVT_BUTTON(self
.removeCommonItemBtn
, wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, self
.OnRemovesharebtnButton
) 
 190         self
.panel2 
= wxPanel(id = wxID_STCSTYLEEDITDLGPANEL2
, name 
= 'panel2', parent 
= self
, pos 
= wxPoint(296, 162), size 
= wxSize(112, 40), style 
= wxTAB_TRAVERSAL
) 
 191         self
.panel2
.SetConstraints(LayoutAnchors(self
.panel2
, false
, true
, true
, false
)) 
 193         self
.staticText7 
= wxStaticText(id = wxID_STCSTYLEEDITDLGSTATICTEXT7
, label 
= 'Size:', name 
= 'staticText7', parent 
= self
.panel2
, pos 
= wxPoint(0, 0), size 
= wxSize(23, 13), style 
= 0) 
 195         self
.taSizeDefCb 
= wxCheckBox(id = wxID_STCSTYLEEDITDLGTASIZEDEFCB
, label 
= 'checkBox1', name 
= 'taSizeDefCb', parent 
= self
.panel2
, pos 
= wxPoint(88, 0), size 
= wxSize(16, 16), style 
= 0) 
 197         self
.sizeCb 
= wxComboBox(choices 
= [], id = wxID_STCSTYLEEDITDLGSIZECB
, name 
= 'sizeCb', parent 
= self
.panel2
, pos 
= wxPoint(0, 17), size 
= wxSize(112, 21), style 
= 0, validator 
= wxDefaultValidator
, value 
= '') 
 198         self
.sizeCb
.SetLabel('') 
 200         self
.faceCb 
= wxComboBox(choices 
= [], id = wxID_STCSTYLEEDITDLGFACECB
, name 
= 'faceCb', parent 
= self
.panel1
, pos 
= wxPoint(17, 18), size 
= wxSize(111, 21), style 
= 0, validator 
= wxDefaultValidator
, value 
= '') 
 201         self
.faceCb
.SetLabel('') 
 203         self
.fgColCb 
= wxComboBox(choices 
= [], id = wxID_STCSTYLEEDITDLGFGCOLCB
, name 
= 'fgColCb', parent 
= self
.staticBox1
, pos 
= wxPoint(8, 32), size 
= wxSize(91, 21), style 
= 0, validator 
= wxDefaultValidator
, value 
= '') 
 204         self
.fgColCb
.SetLabel('') 
 206         self
.bgColCb 
= wxComboBox(choices 
= [], id = wxID_STCSTYLEEDITDLGBGCOLCB
, name 
= 'bgColCb', parent 
= self
.staticBox1
, pos 
= wxPoint(8, 72), size 
= wxSize(91, 21), style 
= 0, validator 
= wxDefaultValidator
, value 
= '') 
 207         self
.bgColCb
.SetLabel('') 
 209     def __init__(self
, parent
, langTitle
, lang
, configFile
, STCsToUpdate
=()):  
 210         self
.stc_title 
= 'wxStyledTextCtrl Style Editor' 
 211         self
.stc_title 
= 'wxStyledTextCtrl Style Editor - %s' % langTitle
 
 212         self
.sys_font 
= wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT
).GetFaceName() 
 213         self
._init
_ctrls
(parent
) 
 215         self
._onUpdateUI 
= false
 
 217         self
.configFile 
= configFile
 
 221         self
.STCsToUpdate 
= STCsToUpdate
 
 223         for combo
, evtRet
, evtRDC 
in (  
 224               (self
.fgColCb
, self
.OnfgColRet
, self
.OnGotoCommonDef
), 
 225               (self
.bgColCb
, self
.OnbgColRet
, self
.OnGotoCommonDef
), 
 226               (self
.faceCb
, self
.OnfaceRet
, self
.OnGotoCommonDef
), 
 227               (self
.sizeCb
, self
.OnsizeRet
, self
.OnGotoCommonDef
)): 
 228             self
.bindComboEvts(combo
, evtRet
, evtRDC
) 
 230         (self
.config
, self
.commonDefs
, self
.styleIdNames
, self
.styles
,  
 231          self
.styleGroupNames
, self
.predefStyleGroups
,  
 232          self
.otherLangStyleGroupNames
, self
.otherLangStyleGroups
, 
 233          self
.displaySrc
, self
.lexer
, self
.keywords
, self
.braceInfo
) = \
 
 234               initFromConfig(configFile
, lang
)     
 236         self
.currSpeedSetting 
= 'style.%s'%self
.lang
 
 237         for grp 
in [self
.currSpeedSetting
]+self
.styleGroupNames
: 
 238             self
.speedsettingCh
.Append(grp
) 
 239         self
.speedsettingCh
.SetSelection(0) 
 242         self
.stc
.SetMarginType(margin
, wxSTC_MARGIN_NUMBER
) 
 243         self
.stc
.SetMarginWidth(margin
, 25) 
 244         self
.stc
.SetMarginSensitive(margin
, true
) 
 245         EVT_STC_MARGINCLICK(self
.stc
, wxID_STCSTYLEEDITDLGSTC
, self
.OnMarginClick
) 
 247         self
.stc
.SetUseTabs(false
) 
 248         self
.stc
.SetTabWidth(4) 
 249         self
.stc
.SetIndentationGuides(true
) 
 250         self
.stc
.SetEdgeMode(wxSTC_EDGE_BACKGROUND
) 
 251         self
.stc
.SetEdgeColumn(44) 
 255         self
.populateStyleSelector() 
 257         self
.defNames
, self
.defValues 
= parseProp(\
 
 258               self
.styleDict
.get(wxSTC_STYLE_DEFAULT
, '')) 
 260         self
.stc
.SetText(self
.displaySrc
) 
 261         self
.stc
.EmptyUndoBuffer() 
 262         self
.stc
.SetCurrentPos(self
.stc
.GetTextLength()) 
 263         self
.stc
.SetAnchor(self
.stc
.GetTextLength()) 
 265         self
.populateCombosWithCommonDefs() 
 267         # Logical grouping of controls and the property they edit 
 268         self
.allCtrls 
= [((self
.fgColBtn
, self
.fgColCb
), self
.fgColDefCb
,  
 269                              'fore', wxID_STCSTYLEEDITDLGFGCOLDEFCB
), 
 270                          ((self
.bgColBtn
, self
.bgColCb
), self
.bgColDefCb
,  
 271                              'back', wxID_STCSTYLEEDITDLGBGCOLDEFCB
), 
 272                          (self
.taBoldCb
, self
.taBoldDefCb
,  
 273                              'bold', wxID_STCSTYLEEDITDLGTABOLDDEFCB
), 
 274                          (self
.taItalicCb
, self
.taItalicDefCb
,  
 275                              'italic', wxID_STCSTYLEEDITDLGTAITALICDEFCB
),  
 276                          (self
.taUnderlinedCb
, self
.taUnderlinedDefCb
,  
 277                              'underline', wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
), 
 278                          (self
.taEOLfilledCb
, self
.taEOLfilledDefCb
,  
 279                              'eolfilled', wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
), 
 280                          (self
.sizeCb
, self
.taSizeDefCb
,  
 281                              'size', wxID_STCSTYLEEDITDLGTASIZEDEFCB
), 
 282                          ((self
.faceCb
, self
.fixedWidthChk
), self
.faceDefCb
,  
 283                              'face', wxID_STCSTYLEEDITDLGFACEDEFCB
)] 
 285         self
.clearCtrls(disableDefs
=true
) 
 286         # centralised default checkbox event handler 
 288         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 289             self
.chbIdMap
[wid
] = ctrl
, chb
, prop
, wid
 
 290             EVT_CHECKBOX(chb
, wid
, self
.OnDefaultCheckBox
) 
 291             chb
.SetToolTipString('Toggle defaults') 
 294         self
._onUpdateUI 
= true
 
 296 #---Property methods------------------------------------------------------------ 
 297     def getCtrlForProp(self
, findprop
): 
 298         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 301         raise Exception('PropNotFound', findprop
) 
 303     def editProp(self
, on
, prop
, val
=''): 
 304         oldstyle 
= self
.rememberStyles() 
 306             if not self
.names
.count(prop
): 
 307                 self
.names
.append(prop
) 
 308             self
.values
[prop
] = val
 
 310             try: self
.names
.remove(prop
) 
 311             except ValueError: pass 
 312             try: del self
.values
[prop
] 
 313             except KeyError: pass 
 318         except KeyError, errkey
: 
 319             wxLogError('Name not found in Common definition, '\
 
 320                 'please enter valid reference. (%s)'%errkey
) 
 321             self
.restoreStyles(oldstyle
) 
 324 #---Control population methods-------------------------------------------------- 
 326         self
.styles
, self
.styleDict
, self
.styleNumIdxMap 
= \
 
 327               setSTCStyles(self
.stc
, self
.styles
, self
.styleIdNames
,  
 328               self
.commonDefs
, self
.lang
, self
.lexer
, self
.keywords
) 
 330     def updateStyle(self
): 
 331         # called after a control edited self.names, self.values 
 332         # Special case for saving common defs settings 
 333         if self
.styleNum 
== 'common': 
 334             strVal 
= self
.style
[2] = self
.values
.values()[0] 
 335             if self
.style
[1] == 'size': self
.style
[2] = int(strVal
) 
 337             self
.commonDefs
[self
.style
[0]] = self
.style
[2] 
 338             self
.styleDefST
.SetLabel(strVal
) 
 340             self
.style 
= writePropVal(self
.names
, self
.values
) 
 341             styleDecl 
= writeProp(self
.styleNum
, self
.style
, self
.lang
) 
 342             self
.styles
[self
.styleNumIdxMap
[self
.styleNum
]] = styleDecl
 
 343             self
.styleDefST
.SetLabel(self
.style
) 
 346     def findInStyles(self
, txt
, styles
): 
 348             if string
.find(style
, txt
) != -1: 
 352     def rememberStyles(self
): 
 353         return self
.names
[:], copy
.copy(self
.values
) 
 355     def restoreStyles(self
, style
): 
 356         self
.names
, self
.values 
= style
 
 359     def clearCtrls(self
, isDefault
=false
, disableDefs
=false
): 
 360         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 361             if prop 
in ('fore', 'back'): 
 363                 btn
.SetBackgroundColour(\
 
 364                       wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
)) 
 365                 btn
.SetForegroundColour(wxColour(255, 255, 255)) 
 366                 btn
.Enable(isDefault
) 
 368                 txt
.Enable(isDefault
) 
 371                 ctrl
.Enable(isDefault
) 
 374                 ctrl
[0].Enable(isDefault
) 
 375                 ctrl
[1].Enable(isDefault
) 
 376                 ctrl
[1].SetValue(false
) 
 377             elif prop 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 379                 ctrl
.Enable(isDefault
) 
 381             chb
.Enable(not isDefault 
and not disableDefs
) 
 384     def populateProp(self
, items
, default
, forceDisable
=false
): 
 385         for name
, val 
in items
: 
 387                 ctrl
, chb 
= self
.getCtrlForProp(name
) 
 389                 if name 
in ('fore', 'back'): 
 391                     repval 
= val
%self
.commonDefs
 
 392                     btn
.SetBackgroundColour(strToCol(repval
)) 
 393                     btn
.SetForegroundColour(wxColour(0, 0, 0)) 
 394                     btn
.Enable(not forceDisable
) 
 396                     txt
.Enable(not forceDisable
) 
 397                     chb
.SetValue(default
) 
 400                     ctrl
.Enable(not forceDisable
) 
 401                     chb
.SetValue(default
) 
 403                     ctrl
[0].SetValue(val
) 
 404                     ctrl
[0].Enable(not forceDisable
) 
 405                     ctrl
[1].Enable(not forceDisable
) 
 406                     chb
.SetValue(default
) 
 407                 elif name 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 408                     ctrl
.Enable(not forceDisable
) 
 410                     chb
.SetValue(default
) 
 412     def valIsCommonDef(self
, val
): 
 413         return len(val
) >= 5 and val
[:2] == '%(' 
 415     def populateCtrls(self
): 
 416         self
.clearCtrls(self
.styleNum 
== wxSTC_STYLE_DEFAULT
, 
 417             disableDefs
=self
.styleNum 
< 0) 
 419         # handle colour controls for settings 
 420         if self
.styleNum 
< 0: 
 421             self
.fgColDefCb
.Enable(true
) 
 422             if self
.styleNum 
== -1: 
 423                 self
.bgColDefCb
.Enable(true
) 
 425         # populate with default style 
 426         self
.populateProp(self
.defValues
.items(), true
,  
 427             self
.styleNum 
!= wxSTC_STYLE_DEFAULT
) 
 428         # override with current settings 
 429         self
.populateProp(self
.values
.items(), false
) 
 431     def getCommonDefPropType(self
, commonDefName
): 
 432         val 
= self
.commonDefs
[commonDefName
] 
 433         if type(val
) == type(0): return 'size' 
 434         if len(val
) == 7 and val
[0] == '#': return 'fore' 
 437     def bindComboEvts(self
, combo
, returnEvtMeth
, rdclickEvtMeth
): 
 439         EVT_MENU(self
, wId
, returnEvtMeth
) 
 440         combo
.SetAcceleratorTable(wxAcceleratorTable([(0, WXK_RETURN
, wId
)])) 
 441         EVT_RIGHT_DCLICK(combo
, rdclickEvtMeth
) 
 442         combo
.SetToolTipString('Select or press Enter to change, right double-click \n'\
 
 443             'the drop down button to select Common definition (if applicable)') 
 445     def populateCombosWithCommonDefs(self
, fixedWidthOnly
=None): 
 446         commonDefs 
= {'fore': [], 'face': [], 'size': []}
 
 448         if self
.elementLb
.GetSelection() < self
.commonDefsStartIdx
: 
 449             for common 
in self
.commonDefs
.keys(): 
 450                 prop 
= self
.getCommonDefPropType(common
) 
 451                 commonDefs
[prop
].append('%%(%s)%s'%(common
,  
 452                                                    prop
=='size' and 'd' or 's')) 
 455         currFg
, currBg 
= self
.fgColCb
.GetValue(), self
.bgColCb
.GetValue() 
 456         self
.fgColCb
.Clear(); self
.bgColCb
.Clear() 
 457         for colCommonDef 
in commonDefs
['fore']: 
 458             self
.fgColCb
.Append(colCommonDef
) 
 459             self
.bgColCb
.Append(colCommonDef
) 
 460         self
.fgColCb
.SetValue(currFg
); self
.bgColCb
.SetValue(currBg
) 
 463         if fixedWidthOnly 
is None: 
 464             fixedWidthOnly 
= self
.fixedWidthChk
.GetValue() 
 465         fontEnum 
= wxFontEnumerator() 
 466         fontEnum
.EnumerateFacenames(fixedWidthOnly
=fixedWidthOnly
) 
 467         fontNameList 
= fontEnum
.GetFacenames() 
 469         currFace 
= self
.faceCb
.GetValue() 
 471         for colCommonDef 
in ['']+fontNameList
+commonDefs
['face']: 
 472             self
.faceCb
.Append(colCommonDef
) 
 473         self
.faceCb
.SetValue(currFace
) 
 475         # Size (XXX add std font sizes) 
 476         currSize 
= self
.sizeCb
.GetValue() 
 478         for colCommonDef 
in commonDefs
['size']: 
 479             self
.sizeCb
.Append(colCommonDef
) 
 480         self
.sizeCb
.SetValue(currSize
) 
 482     def populateStyleSelector(self
): 
 483         numStyles 
= self
.styleIdNames
.items() 
 485         self
.styleNumLookup 
= {} 
 490         for num
, name 
in numStyles
: 
 491             if num 
== wxSTC_STYLE_DEFAULT
: 
 492                 self
.elementLb
.InsertItems([name
, '-----Language-----'], 0) 
 493                 self
.elementLb
.Append('-----Standard-----') 
 494                 stdStart 
= stdPos 
= self
.elementLb
.Number() 
 497                 if num 
>= 33 and num 
< 40: 
 498                     self
.elementLb
.InsertItems([name
], stdStart 
+ stdOffset
) 
 499                     stdOffset 
= stdOffset 
+ 1 
 502                     self
.elementLb
.InsertItems([name
], stdStart 
+ extrOffset 
-1) 
 503                     extrOffset 
= extrOffset 
+ 1 
 506                     self
.elementLb
.Append(name
) 
 507             self
.styleNumLookup
[name
] = num
 
 510         self
.elementLb
.Append('-----Settings-----') 
 511         settings 
= settingsIdNames
.items() 
 512         settings
.sort();settings
.reverse() 
 513         for num
, name 
in settings
: 
 514             self
.elementLb
.Append(name
) 
 515             self
.styleNumLookup
[name
] = num
 
 518         self
.elementLb
.Append('-----Common-----') 
 519         self
.commonDefsStartIdx 
= self
.elementLb
.Number() 
 520         for common 
in self
.commonDefs
.keys(): 
 521             tpe 
= type(self
.commonDefs
[common
]) 
 522             self
.elementLb
.Append('%('+common
+')'+(tpe 
is type('') and 's' or 'd')) 
 523             self
.styleNumLookup
[common
] = num
 
 525 #---Colour methods-------------------------------------------------------------- 
 526     def getColourDlg(self
, colour
, title
=''): 
 527         data 
= wxColourData() 
 528         data
.SetColour(colour
) 
 529         data
.SetChooseFull(true
) 
 530         dlg 
= wxColourDialog(self
, data
) 
 533             if dlg
.ShowModal() == wxID_OK
: 
 534                 data 
= dlg
.GetColourData() 
 535                 return data
.GetColour() 
 540     colDlgTitles 
= {'fore': 'Foreground', 'back': 'Background'}
 
 541     def editColProp(self
, colBtn
, colCb
, prop
): 
 542         col 
= self
.getColourDlg(colBtn
.GetBackgroundColour(),  
 543               self
.colDlgTitles
[prop
]+ ' colour') 
 545             colBtn
.SetForegroundColour(wxColour(0, 0, 0)) 
 546             colBtn
.SetBackgroundColour(col
) 
 547             colStr 
= colToStr(col
) 
 548             colCb
.SetValue(colStr
) 
 549             self
.editProp(true
, prop
, colStr
) 
 551     def OnFgcolbtnButton(self
, event
): 
 552         self
.editColProp(self
.fgColBtn
, self
.fgColCb
, 'fore') 
 554     def OnBgcolbtnButton(self
, event
): 
 555         self
.editColProp(self
.bgColBtn
, self
.bgColCb
, 'back') 
 557     def editColTCProp(self
, colCb
, colBtn
, prop
): 
 558         colStr 
= colCb
.GetValue() 
 560             col 
= strToCol(colStr
%self
.commonDefs
) 
 561         if self
.editProp(colStr
!='', prop
, colStr
): 
 563                 colBtn
.SetForegroundColour(wxColour(0, 0, 0)) 
 564                 colBtn
.SetBackgroundColour(col
) 
 566                 colBtn
.SetForegroundColour(wxColour(255, 255, 255)) 
 567                 colBtn
.SetBackgroundColour(\
 
 568                       wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
)) 
 570     def OnfgColRet(self
, event
): 
 571         try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore') 
 572         except AssertionError: wxLogError('Not a valid colour value') 
 574     def OnbgColRet(self
, event
): 
 575         try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back') 
 576         except AssertionError: wxLogError('Not a valid colour value') 
 578 #---Text attribute events------------------------------------------------------- 
 579     def OnTaeoffilledcbCheckbox(self
, event
): 
 580         self
.editProp(event
.IsChecked(), 'eolfilled') 
 582     def OnTaitaliccbCheckbox(self
, event
): 
 583         self
.editProp(event
.IsChecked(), 'italic') 
 585     def OnTaboldcbCheckbox(self
, event
): 
 586         self
.editProp(event
.IsChecked(), 'bold') 
 588     def OnTaunderlinedcbCheckbox(self
, event
): 
 589         self
.editProp(event
.IsChecked(), 'underline') 
 591     def OnGotoCommonDef(self
, event
): 
 592         val 
= event
.GetEventObject().GetValue() 
 593         if self
.valIsCommonDef(val
): 
 594             idx 
= self
.elementLb
.FindString(val
) 
 596                 self
.elementLb
.SetSelection(idx
, true
) 
 597                 self
.OnElementlbListbox(None) 
 599     def OnfaceRet(self
, event
): 
 600         val 
= self
.faceCb
.GetValue() 
 601         try: val
%self
.commonDefs
 
 602         except KeyError: wxLogError('Invalid common definition') 
 603         else: self
.editProp(val
!='', 'face', val
) 
 605     def OnsizeRet(self
, event
): 
 606         val 
= self
.sizeCb
.GetValue() 
 607         try: int(val
%self
.commonDefs
) 
 608         except ValueError: wxLogError('Not a valid integer size value') 
 609         except KeyError: wxLogError('Invalid common definition') 
 610         else: self
.editProp(val
!='', 'size', val
) 
 612 #---Main GUI events------------------------------------------------------------- 
 613     def OnElementlbListbox(self
, event
): 
 614         isCommon 
= self
.elementLb
.GetSelection() >= self
.commonDefsStartIdx
 
 615         self
.removeCommonItemBtn
.Enable(isCommon
) 
 617         styleIdent 
= self
.elementLb
.GetStringSelection() 
 618         # common definition selected 
 620             common 
= styleIdent
[2:-2] 
 621             prop 
= self
.getCommonDefPropType(common
) 
 622             self
.clearCtrls(disableDefs
=true
) 
 624                 self
.fgColBtn
.Enable(true
) 
 625                 self
.fgColCb
.Enable(true
) 
 627                 self
.faceCb
.Enable(true
) 
 628                 self
.fixedWidthChk
.Enable(true
) 
 630                 self
.sizeCb
.Enable(true
) 
 632             commonDefVal 
= str(self
.commonDefs
[common
]) 
 633             self
.styleDefST
.SetLabel(commonDefVal
) 
 634             self
.populateProp( [(prop
, commonDefVal
)], true
) 
 636             self
.styleNum 
= 'common' 
 637             self
.style 
= [common
, prop
, commonDefVal
] 
 638             self
.names
, self
.values 
= [prop
], {prop: commonDefVal}
 
 640         # normal style element selected 
 641         elif len(styleIdent
) >=2 and styleIdent
[:2] != '--': 
 642             self
.styleNum 
= self
.styleNumLookup
[styleIdent
] 
 643             self
.style 
= self
.styleDict
[self
.styleNum
] 
 644             self
.names
, self
.values 
= parseProp(self
.style
) 
 646             if self
.styleNum 
== wxSTC_STYLE_DEFAULT
: 
 647                 self
.defNames
, self
.defValues 
= \
 
 648                       self
.names
, self
.values
 
 650             self
.checkBraces(self
.styleNum
) 
 652             self
.styleDefST
.SetLabel(self
.style
) 
 657             self
.clearCtrls(disableDefs
=true
) 
 659                 self
.styleDefST
.SetLabel(styleCategoryDescriptions
[styleIdent
]) 
 661         self
.populateCombosWithCommonDefs() 
 663     def OnDefaultCheckBox(self
, event
): 
 664         self
._onUpdateUI 
= false
 
 666             if self
.chbIdMap
.has_key(event
.GetId()): 
 667                 ctrl
, chb
, prop
, wid 
= self
.chbIdMap
[event
.GetId()] 
 668                 restore 
= not event
.IsChecked() 
 669                 if prop 
in ('fore', 'back'): 
 670                     ctrl
[0].Enable(restore
) 
 671                     ctrl
[1].Enable(restore
) 
 674                         colStr 
= ctrl
[1].GetValue() 
 675                         #if prop == 'fore': colStr = self.fgColCb.GetValue() 
 676                         #else: colStr = self.bgColCb.GetValue() 
 677                         if colStr
: self
.editProp(true
, prop
, colStr
) 
 679                         self
.editProp(false
, prop
) 
 681                     val 
= ctrl
.GetValue() 
 682                     if val
: self
.editProp(restore
, prop
, val
) 
 685                     val 
= ctrl
[0].GetStringSelection() 
 686                     if val
: self
.editProp(restore
, prop
, val
) 
 687                     ctrl
[0].Enable(restore
) 
 688                     ctrl
[1].Enable(restore
) 
 689                 elif prop 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 691                     if ctrl
.GetValue(): self
.editProp(restore
, prop
) 
 693             self
._onUpdateUI 
= true
 
 695     def OnOkbtnButton(self
, event
): 
 696         # write styles and common defs to the config 
 697         writeStylesToConfig(self
.config
, 'style.%s'%self
.lang
, self
.styles
) 
 698         self
.config
.SetPath('') 
 699         self
.config
.Write(commonDefsFile
, `self
.commonDefs`
) 
 702         for stc 
in self
.STCsToUpdate
: 
 703             setSTCStyles(stc
, self
.styles
, self
.styleIdNames
, self
.commonDefs
,  
 704                   self
.lang
, self
.lexer
, self
.keywords
) 
 706         self
.EndModal(wxID_OK
) 
 708     def OnCancelbtnButton(self
, event
): 
 709         self
.EndModal(wxID_CANCEL
) 
 711     def OnCommondefsbtnButton(self
, event
): 
 712         dlg 
= wxTextEntryDialog(self
, 'Edit common definitions dictionary',  
 713               'Common definitions', pprint
.pformat(self
.commonDefs
), 
 714               style
=wxTE_MULTILINE | wxOK | wxCANCEL | wxCENTRE
) 
 716             if dlg
.ShowModal() == wxID_OK
: 
 717                 answer 
= eval(dlg
.GetValue()) 
 718                 assert type(answer
) is type({}), 'Not a valid dictionary' 
 719                 oldDefs 
= self
.commonDefs
 
 720                 self
.commonDefs 
= answer
 
 723                 except KeyError, badkey
: 
 724                     wxLogError(str(badkey
)+' not defined but required, \n'\
 
 725                           'reverting to previous common definition') 
 726                     self
.commonDefs 
= oldDefs
 
 728                 self
.populateCombosWithCommonDefs() 
 733     def OnSpeedsettingchChoice(self
, event
): 
 734         group 
= event
.GetString() 
 736             userStyles 
= 'style.%s'%self
.lang
 
 737             if self
.currSpeedSetting 
== userStyles
: 
 738                 self
.predefStyleGroups
[userStyles
] = self
.styles
 
 739             self
.styles 
= self
.predefStyleGroups
[group
] 
 741             self
.defNames
, self
.defValues 
= parseProp(\
 
 742                   self
.styleDict
.get(wxSTC_STYLE_DEFAULT
, '')) 
 743             self
.OnElementlbListbox(None) 
 744             self
.currSpeedSetting 
= group
 
 746     def OnFixedwidthchkCheckbox(self
, event
): 
 747         self
.populateCombosWithCommonDefs(event
.Checked()) 
 749     def OnAddsharebtnButton(self
, event
): 
 750         dlg 
= CommonDefDlg(self
) 
 752             if dlg
.ShowModal() == wxID_OK
: 
 753                 prop
, name 
= dlg
.result
 
 754                 if not self
.commonDefs
.has_key(name
): 
 755                     self
.commonDefs
[name
] = commonPropDefs
[prop
] 
 756                     self
.elementLb
.Append('%('+name
+')'+\
 
 757                      (type(commonPropDefs
[prop
]) is type('') and 's' or 'd')) 
 758                     self
.elementLb
.SetSelection(self
.elementLb
.Number()-1, true
) 
 759                     self
.populateCombosWithCommonDefs() 
 760                     self
.OnElementlbListbox(None) 
 764     def OnRemovesharebtnButton(self
, event
): 
 765         ownGroup 
= 'style.%s'%self
.lang
 
 766         comDef 
= self
.elementLb
.GetStringSelection()         
 768         # Search ALL styles before removing 
 769         srchDct 
= {ownGroup: self.styles}
 
 770         srchDct
.update(self
.predefStyleGroups
) 
 771         srchDct
.update(self
.otherLangStyleGroups
) 
 774         for grpName
, styles 
in srchDct
.items(): 
 775             if self
.findInStyles(comDef
, styles
): 
 776                 matchList
.append(grpName
) 
 779             wxLogError('Aborted: '+comDef
+' is still used in the styles of the \n'\
 
 780                   'following groups in the config file (stc-styles.rc.cfg):\n'+ \
 
 781                   string
.join(matchList
, '\n')) 
 783             del self
.commonDefs
[comDef
[2:-2]] 
 785             self
.populateCombosWithCommonDefs() 
 786             selIdx 
= self
.elementLb
.GetSelection() 
 787             self
.elementLb
.Delete(selIdx
) 
 788             if selIdx 
== self
.elementLb
.Number(): 
 790             self
.elementLb
.SetSelection(selIdx
, true
) 
 791             self
.OnElementlbListbox(None) 
 793 #---STC events------------------------------------------------------------------ 
 794     def OnUpdateUI(self
, event
): 
 796             styleBefore 
= self
.stc
.GetStyleAt(self
.stc
.GetCurrentPos()) 
 797             if self
.styleIdNames
.has_key(styleBefore
): 
 798                 self
.elementLb
.SetStringSelection(self
.styleIdNames
[styleBefore
],  
 801                 self
.elementLb
.SetSelection(0, false
) 
 802                 self
.styleDefST
.SetLabel('Style %d not defined, sorry.'%styleBefore
) 
 803             self
.OnElementlbListbox(None) 
 806     def checkBraces(self
, style
): 
 807         if style 
== wxSTC_STYLE_BRACELIGHT 
and self
.braceInfo
.has_key('good'): 
 808             line
, col 
= self
.braceInfo
['good'] 
 809             pos 
= self
.stc
.PositionFromLine(line
-1) + col
 
 810             braceOpposite 
= self
.stc
.BraceMatch(pos
) 
 811             if braceOpposite 
!= -1: 
 812                 self
.stc
.BraceHighlight(pos
, braceOpposite
) 
 813         elif style 
== wxSTC_STYLE_BRACEBAD 
and self
.braceInfo
.has_key('bad'): 
 814             line
, col 
= self
.braceInfo
['bad'] 
 815             pos 
= self
.stc
.PositionFromLine(line
-1) + col
 
 816             self
.stc
.BraceBadLight(pos
) 
 818             self
.stc
.BraceBadLight(-1) 
 821     def OnStcstyleeditdlgSize(self
, event
): 
 823         # Without this refresh, resizing leaves artifacts 
 827     def OnMarginClick(self
, event
): 
 828         self
.elementLb
.SetStringSelection('Line numbers', true
) 
 829         self
.OnElementlbListbox(None) 
 832 #---Common definition dialog---------------------------------------------------- 
 834 [wxID_COMMONDEFDLG
, wxID_COMMONDEFDLGCANCELBTN
, wxID_COMMONDEFDLGCOMDEFNAMETC
, wxID_COMMONDEFDLGOKBTN
, wxID_COMMONDEFDLGPROPTYPERBX
, wxID_COMMONDEFDLGSTATICBOX1
] = map(lambda _init_ctrls
: wxNewId(), range(6)) 
 836 class CommonDefDlg(wxDialog
): 
 837     def _init_ctrls(self
, prnt
): 
 838         wxDialog
.__init
__(self
, id = wxID_COMMONDEFDLG
, name 
= 'CommonDefDlg', parent 
= prnt
, pos 
= wxPoint(398, 249), size 
= wxSize(192, 220), style 
= wxDEFAULT_DIALOG_STYLE
, title 
= 'Common definition') 
 839         self
.SetClientSize(wxSize(184, 175)) 
 841         self
.propTypeRBx 
= wxRadioBox(choices 
= ['Colour value', 'Font face', 'Size value'], id = wxID_COMMONDEFDLGPROPTYPERBX
, label 
= 'Common definition property type', majorDimension 
= 1, name 
= 'propTypeRBx', parent 
= self
, point 
= wxPoint(8, 8), size 
= wxSize(168, 72), style 
= wxRA_SPECIFY_COLS
, validator 
= wxDefaultValidator
) 
 842         self
.propTypeRBx
.SetSelection(self
._propTypeIdx
) 
 844         self
.staticBox1 
= wxStaticBox(id = wxID_COMMONDEFDLGSTATICBOX1
, label 
= 'Name', name 
= 'staticBox1', parent 
= self
, pos 
= wxPoint(8, 88), size 
= wxSize(168, 46), style 
= 0) 
 846         self
.comDefNameTC 
= wxTextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC
, name 
= 'comDefNameTC', parent 
= self
, pos 
= wxPoint(16, 104), size 
= wxSize(152, 21), style 
= 0, value 
= '') 
 847         self
.comDefNameTC
.SetLabel(self
._comDefName
) 
 849         self
.okBtn 
= wxButton(id = wxID_COMMONDEFDLGOKBTN
, label 
= 'OK', name 
= 'okBtn', parent 
= self
, pos 
= wxPoint(8, 144), size 
= wxSize(80, 23), style 
= 0) 
 850         EVT_BUTTON(self
.okBtn
, wxID_COMMONDEFDLGOKBTN
, self
.OnOkbtnButton
) 
 852         self
.cancelBtn 
= wxButton(id = wxID_COMMONDEFDLGCANCELBTN
, label 
= 'Cancel', name 
= 'cancelBtn', parent 
= self
, pos 
= wxPoint(96, 144), size 
= wxSize(80, 23), style 
= 0) 
 853         EVT_BUTTON(self
.cancelBtn
, wxID_COMMONDEFDLGCANCELBTN
, self
.OnCancelbtnButton
) 
 855     def __init__(self
, parent
, name
='', propIdx
=0): 
 856         self
._comDefName 
= '' 
 857         self
._comDefName 
= name
 
 858         self
._propTypeIdx 
= 0 
 859         self
._propTypeIdx 
= propIdx
 
 860         self
._init
_ctrls
(parent
) 
 862         self
.propMap 
= {0: 'fore', 1: 'face', 2: 'size'}                
 
 863         self
.result 
= ( '', '' ) 
 867     def OnOkbtnButton(self
, event
): 
 868         self
.result 
= ( self
.propMap
[self
.propTypeRBx
.GetSelection()], 
 869                         self
.comDefNameTC
.GetValue() ) 
 870         self
.EndModal(wxID_OK
) 
 872     def OnCancelbtnButton(self
, event
): 
 873         self
.result 
= ( '', '' ) 
 874         self
.EndModal(wxID_CANCEL
) 
 876 #---Functions useful outside of the editor---------------------------------- 
 878 def setSelectionColour(stc
, style
): 
 879     names
, values 
= parseProp(style
) 
 881         stc
.SetSelForeground(true
, strToCol(values
['fore'])) 
 883         stc
.SetSelBackground(true
, strToCol(values
['back'])) 
 885 def setCursorColour(stc
, style
): 
 886     names
, values 
= parseProp(style
) 
 888         stc
.SetCaretForeground(strToCol(values
['fore'])) 
 890 def setEdgeColour(stc
, style
): 
 891     names
, values 
= parseProp(style
) 
 893         stc
.SetEdgeColour(strToCol(values
['fore'])) 
 895 def strToCol(strCol
): 
 896     assert len(strCol
) == 7 and strCol
[0] == '#', 'Not a valid colour string' 
 897     return wxColour(string
.atoi('0x'+strCol
[1:3], 16),  
 898                     string
.atoi('0x'+strCol
[3:5], 16),  
 899                     string
.atoi('0x'+strCol
[5:7], 16)) 
 901     return '#%s%s%s' % (string
.zfill(string
.upper(hex(col
.Red())[2:]), 2),  
 902                         string
.zfill(string
.upper(hex(col
.Green())[2:]), 2), 
 903                         string
.zfill(string
.upper(hex(col
.Blue())[2:]), 2)) 
 905 def writeProp(num
, style
, lang
): 
 907         return 'style.%s.%s='%(lang
, string
.zfill(`num`
, 3)) + style
 
 909         return 'setting.%s.%d='%(lang
, num
) + style
 
 911 def writePropVal(names
, values
): 
 915             res
.append(values
[name
] and name
+':'+values
[name
] or name
) 
 916     return string
.join(res
, ',') 
 919     items 
= string
.split(prop
, ',') 
 923         nameVal 
= string
.split(item
, ':') 
 924         names
.append(string
.strip(nameVal
[0])) 
 925         if len(nameVal
) == 1: 
 926             values
[nameVal
[0]] = '' 
 928             values
[nameVal
[0]] = string
.strip(nameVal
[1]) 
 931 def parsePropLine(prop
): 
 932     name
, value 
= string
.split(prop
, '=') 
 933     return int(string
.split(name
, '.')[-1]), value
 
 935 def setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
): 
 939     # build style dict based on given styles 
 940     for numStyle 
in styles
: 
 941         num
, style 
= parsePropLine(numStyle
) 
 942         styleDict
[num
] = style
 
 944     # Add blank style entries for undefined styles 
 946     styleItems 
= styleIdNames
.items() + settingsIdNames
.items() 
 949     for num
, name 
in styleItems
: 
 950         styleNumIdxMap
[num
] = idx
 
 951         if not styleDict
.has_key(num
): 
 953         newStyles
.append(writeProp(num
, styleDict
[num
], lang
)) 
 956     # Set the styles on the wxSTC 
 957     stc
.StyleResetDefault() 
 958     stc
.ClearDocumentStyle() 
 960     stc
.SetKeyWords(0, keywords
) 
 961     stc
.StyleSetSpec(wxSTC_STYLE_DEFAULT
,  
 962           styleDict
[wxSTC_STYLE_DEFAULT
] % commonDefs
) 
 965     for num
, style 
in styleDict
.items(): 
 967             stc
.StyleSetSpec(num
, style 
% commonDefs
) 
 969             setSelectionColour(stc
, style 
% commonDefs
) 
 971             setCursorColour(stc
, style 
% commonDefs
) 
 973             setEdgeColour(stc
, style 
% commonDefs
) 
 975     stc
.Colourise(0, stc
.GetTextLength()) 
 977     return newStyles
, styleDict
, styleNumIdxMap
 
 979 #---Config reading and writing ------------------------------------------------- 
 980 commonDefsFile 
= 'common.defs.%s'%(wxPlatform 
== '__WXMSW__' and 'msw' or 'gtk') 
 982 def initFromConfig(configFile
, lang
): 
 983     cfg 
= wxFileConfig(localFilename
=configFile
, style
=wxCONFIG_USE_LOCAL_FILE
) 
 984     cfg
.SetExpandEnvVars(false
) 
 986     # read in all group names for this language 
 987     groupPrefix 
= 'style.%s'%lang
 
 988     gpLen 
= len(groupPrefix
) 
 989     predefStyleGroupNames
, otherLangStyleGroupNames 
= [], [] 
 990     cont
, val
, idx 
= cfg
.GetFirstGroup() 
 992         if val 
!= groupPrefix 
and len(val
) >= 5 and val
[:5] == 'style': 
 993             if len(val
) > gpLen 
and val
[:gpLen
] == groupPrefix
: 
 994                 predefStyleGroupNames
.append(val
) 
 996                 otherLangStyleGroupNames
.append(val
) 
 998         cont
, val
, idx 
= cfg
.GetNextGroup(idx
) 
1000     # read in common elements 
1001     commonDefs 
= eval(cfg
.Read(commonDefsFile
)) 
1002     assert type(commonDefs
) is type({}), \
 
1003           'Common definitions (%s) not a valid dict'%commonDefsFile
 
1005     commonStyleIdNames 
= eval(cfg
.Read('common.styleidnames')) 
1006     assert type(commonStyleIdNames
) is type({}), \
 
1007           'Common definitions (%s) not a valid dict'%'common.styleidnames' 
1009     # Lang spesific settings 
1011     styleIdNames 
= eval(cfg
.Read('styleidnames')) 
1012     assert type(commonStyleIdNames
) is type({}), \
 
1013           'Not a valid dict [%s] styleidnames)'%lang
 
1014     styleIdNames
.update(commonStyleIdNames
) 
1015     braceInfo 
= eval(cfg
.Read('braces')) 
1016     assert type(commonStyleIdNames
) is type({}), \
 
1017           'Not a valid dict [%s] braces)'%lang
 
1019     displaySrc 
= cfg
.Read('displaysrc') 
1020     lexer 
= eval(cfg
.Read('lexer')) 
1021     keywords 
= cfg
.Read('keywords') 
1025     # read in current styles 
1026     styles 
= readStylesFromConfig(cfg
, groupPrefix
) 
1028     # read in predefined styles  
1029     predefStyleGroups 
= {} 
1030     for group 
in predefStyleGroupNames
: 
1031         predefStyleGroups
[group
] = readStylesFromConfig(cfg
, group
) 
1033     # read in all other style sections 
1034     otherLangStyleGroups 
= {} 
1035     for group 
in otherLangStyleGroupNames
: 
1036         otherLangStyleGroups
[group
] = readStylesFromConfig(cfg
, group
) 
1038     return (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
,  
1039             predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
, 
1040             displaySrc
, lexer
, keywords
, braceInfo
) 
1042 def readStylesFromConfig(config
, group
): 
1044     config
.SetPath(group
)                 
1046     cont
, val
, idx 
= config
.GetFirstEntry() 
1048         styles
.append(val
+'='+config
.Read(val
)) 
1049         cont
, val
, idx 
= config
.GetNextEntry(idx
) 
1054 def writeStylesToConfig(config
, group
, styles
): 
1056     config
.DeleteGroup(group
) 
1057     config
.SetPath(group
) 
1059     for style 
in styles
: 
1060         name
, value 
= string
.split(style
, '=') 
1061         config
.Write(name
, string
.strip(value
)) 
1065 #------------------------------------------------------------------------------- 
1066 def initSTC(stc
, config
, lang
): 
1067     """ Main module entry point. Initialise a wxSTC from given config file.""" 
1068     (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
,  
1069      predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
, 
1070      displaySrc
, lexer
, keywords
, braceInfo
) = initFromConfig(config
, lang
) 
1072     setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
) 
1074 #------------------------------------------------------------------------------- 
1075 if __name__ 
== '__main__': 
1076     app 
= wxPySimpleApp() 
1077     config 
= os
.path
.abspath('stc-styles.rc.cfg') 
1080         f 
= wxFrame(None, -1, 'Test frame (double click for editor)') 
1081         stc 
= wxStyledTextCtrl(f
, -1) 
1082         def OnDblClick(evt
, stc
=stc
): 
1083             dlg 
= STCStyleEditDlg(None, 'Python', 'python', config
, (stc
,)) 
1084             try: dlg
.ShowModal() 
1085             finally: dlg
.Destroy() 
1086         stc
.SetText(open('STCStyleEditor.py').read()) 
1087         EVT_LEFT_DCLICK(stc
, OnDblClick
) 
1088         initSTC(stc
, config
, 'python') 
1092         dlg 
= STCStyleEditDlg(None,  
1098             #'Properties', 'prop',   
1100         try: dlg
.ShowModal() 
1101         finally: dlg
.Destroy()