1 #----------------------------------------------------------------------------- 
   2 # Name:        STCStyleEditor.py 
   3 # Purpose:     Style editor for the wxStyledTextCtrl 
   5 # Author:      Riaan Booysen 
   9 # Copyright:   (c) 2001 - 2002 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
.help import * 
  57 from wxPython
.lib
.anchors 
import LayoutAnchors
 
  58 from wxPython
.stc 
import * 
  60 settingsIdNames 
= {-1: 'Selection', -2: 'Caret', -3: 'Edge'}
 
  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
, 
  71  wxID_STCSTYLEEDITDLGBGCOLBTN
, wxID_STCSTYLEEDITDLGBGCOLCB
, 
  72  wxID_STCSTYLEEDITDLGBGCOLDEFCB
, wxID_STCSTYLEEDITDLGBGCOLOKBTN
, 
  73  wxID_STCSTYLEEDITDLGCANCELBTN
, wxID_STCSTYLEEDITDLGCONTEXTHELPBUTTON1
, 
  74  wxID_STCSTYLEEDITDLGELEMENTLB
, wxID_STCSTYLEEDITDLGFACECB
, 
  75  wxID_STCSTYLEEDITDLGFACEDEFCB
, wxID_STCSTYLEEDITDLGFACEOKBTN
, 
  76  wxID_STCSTYLEEDITDLGFGCOLBTN
, wxID_STCSTYLEEDITDLGFGCOLCB
, 
  77  wxID_STCSTYLEEDITDLGFGCOLDEFCB
, wxID_STCSTYLEEDITDLGFGCOLOKBTN
, 
  78  wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, wxID_STCSTYLEEDITDLGOKBTN
, 
  79  wxID_STCSTYLEEDITDLGPANEL1
, wxID_STCSTYLEEDITDLGPANEL2
, 
  80  wxID_STCSTYLEEDITDLGPANEL3
, wxID_STCSTYLEEDITDLGPANEL4
, 
  81  wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, wxID_STCSTYLEEDITDLGSIZECB
, 
  82  wxID_STCSTYLEEDITDLGSIZEOKBTN
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, 
  83  wxID_STCSTYLEEDITDLGSTATICBOX1
, wxID_STCSTYLEEDITDLGSTATICBOX2
, 
  84  wxID_STCSTYLEEDITDLGSTATICLINE1
, wxID_STCSTYLEEDITDLGSTATICTEXT2
, 
  85  wxID_STCSTYLEEDITDLGSTATICTEXT3
, wxID_STCSTYLEEDITDLGSTATICTEXT4
, 
  86  wxID_STCSTYLEEDITDLGSTATICTEXT6
, wxID_STCSTYLEEDITDLGSTATICTEXT7
, 
  87  wxID_STCSTYLEEDITDLGSTATICTEXT8
, wxID_STCSTYLEEDITDLGSTATICTEXT9
, 
  88  wxID_STCSTYLEEDITDLGSTC
, wxID_STCSTYLEEDITDLGSTYLEDEFST
, 
  89  wxID_STCSTYLEEDITDLGTABOLDCB
, wxID_STCSTYLEEDITDLGTABOLDDEFCB
, 
  90  wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
, 
  91  wxID_STCSTYLEEDITDLGTAITALICCB
, wxID_STCSTYLEEDITDLGTAITALICDEFCB
, 
  92  wxID_STCSTYLEEDITDLGTASIZEDEFCB
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, 
  93  wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
, 
  94 ] = map(lambda _init_ctrls
: wxNewId(), range(47)) 
  96 class STCStyleEditDlg(wxDialog
): 
  97     """ Style editor for the wxStyledTextCtrl """ 
  98     _custom_classes 
= {'wxWindow' : ['wxStyledTextCtrl']}
 
  99     def _init_utils(self
): 
 100         # generated method, don't edit 
 103     def _init_ctrls(self
, prnt
): 
 104         # generated method, don't edit 
 105         wxDialog
.__init
__(self
, id=wxID_STCSTYLEEDITDLG
, name
='STCStyleEditDlg', 
 106               parent
=prnt
, pos
=wxPoint(583, 291), size
=wxSize(459, 482), 
 107               style
=wxWANTS_CHARS | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
, 
 108               title
=self
.stc_title
) 
 110         self
.SetClientSize(wxSize(451, 455)) 
 111         self
.SetAutoLayout(True) 
 112         self
.SetSizeHints(425, 400, -1, -1) 
 114         EVT_SIZE(self
, self
.OnStcstyleeditdlgSize
) 
 116         self
.speedsettingCh 
= wxChoice(choices
=[], 
 117               id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, name
='speedsettingCh', 
 118               parent
=self
, pos
=wxPoint(96, 28), size
=wxSize(346, 21), style
=0, 
 119               validator
=wxDefaultValidator
) 
 120         self
.speedsettingCh
.SetConstraints(LayoutAnchors(self
.speedsettingCh
, 
 121               True, True, True, False)) 
 122         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.') 
 123         EVT_CHOICE(self
.speedsettingCh
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, 
 124               self
.OnSpeedsettingchChoice
) 
 126         self
.elementLb 
= wxListBox(choices
=[], id=wxID_STCSTYLEEDITDLGELEMENTLB
, 
 127               name
='elementLb', parent
=self
, pos
=wxPoint(8, 72), 
 128               size
=wxSize(160, 112), style
=0, validator
=wxDefaultValidator
) 
 129         self
.elementLb
.SetConstraints(LayoutAnchors(self
.elementLb
, True, True, 
 131         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.') 
 132         EVT_LISTBOX(self
.elementLb
, wxID_STCSTYLEEDITDLGELEMENTLB
, 
 133               self
.OnElementlbListbox
) 
 135         self
.addCommonItemBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
, 
 136               label
='Add', name
='addCommonItemBtn', parent
=self
, pos
=wxPoint(8, 
 137               184), size
=wxSize(80, 17), style
=0) 
 138         self
.addCommonItemBtn
.SetToolTipString('Add new Common definition') 
 139         EVT_BUTTON(self
.addCommonItemBtn
, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
, 
 140               self
.OnAddsharebtnButton
) 
 142         self
.removeCommonItemBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, 
 143               label
='Remove', name
='removeCommonItemBtn', parent
=self
, 
 144               pos
=wxPoint(88, 184), size
=wxSize(80, 17), style
=0) 
 145         self
.removeCommonItemBtn
.SetToolTipString('Remove the selected Common definition') 
 146         EVT_BUTTON(self
.removeCommonItemBtn
, 
 147               wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, 
 148               self
.OnRemovesharebtnButton
) 
 150         self
.styleDefST 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTYLEDEFST
, 
 151               label
='(nothing selected)', name
='styleDefST', parent
=self
, 
 152               pos
=wxPoint(96, 8), size
=wxSize(366, 16), 
 153               style
=wxST_NO_AUTORESIZE
) 
 154         self
.styleDefST
.SetFont(wxFont(self
.style_font_size
, wxSWISS
, wxNORMAL
, 
 156         self
.styleDefST
.SetConstraints(LayoutAnchors(self
.styleDefST
, True, 
 159         self
.staticLine1 
= wxStaticLine(id=wxID_STCSTYLEEDITDLGSTATICLINE1
, 
 160               name
='staticLine1', parent
=self
, pos
=wxPoint(48, 62), 
 161               size
=wxSize(120, 2), style
=wxLI_HORIZONTAL
) 
 162         self
.staticLine1
.SetConstraints(LayoutAnchors(self
.staticLine1
, True, 
 165         self
.staticText6 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT6
, 
 166               label
='Style', name
='staticText6', parent
=self
, pos
=wxPoint(8, 
 167               56), size
=wxSize(40, 13), style
=0) 
 169         self
.staticText8 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT8
, 
 170               label
='Style def:', name
='staticText8', parent
=self
, 
 171               pos
=wxPoint(8, 8), size
=wxSize(88, 13), style
=0) 
 173         self
.staticText9 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT9
, 
 174               label
='SpeedSetting:', name
='staticText9', parent
=self
, 
 175               pos
=wxPoint(8, 32), size
=wxSize(88, 13), style
=0) 
 177         self
.panel3 
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL3
, name
='panel3', 
 178               parent
=self
, pos
=wxPoint(176, 56), size
=wxSize(146, 104), 
 179               style
=wxTAB_TRAVERSAL
) 
 180         self
.panel3
.SetConstraints(LayoutAnchors(self
.panel3
, False, True, True, 
 183         self
.panel4 
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL4
, name
='panel4', 
 184               parent
=self
, pos
=wxPoint(330, 56), size
=wxSize(114, 104), 
 185               style
=wxTAB_TRAVERSAL
) 
 186         self
.panel4
.SetConstraints(LayoutAnchors(self
.panel4
, False, True, True, 
 189         self
.panel1 
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL1
, name
='panel1', 
 190               parent
=self
, pos
=wxPoint(176, 161), size
=wxSize(143, 40), 
 191               style
=wxTAB_TRAVERSAL
) 
 192         self
.panel1
.SetConstraints(LayoutAnchors(self
.panel1
, False, True, True, 
 195         self
.panel2 
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL2
, name
='panel2', 
 196               parent
=self
, pos
=wxPoint(330, 162), size
=wxSize(112, 40), 
 197               style
=wxTAB_TRAVERSAL
) 
 198         self
.panel2
.SetConstraints(LayoutAnchors(self
.panel2
, False, True, True, 
 201         self
.stc 
= wxStyledTextCtrl(id=wxID_STCSTYLEEDITDLGSTC
, name
='stc', 
 202               parent
=self
, pos
=wxPoint(8, 208), size
=wxSize(435, 207), 
 203               style
=wxSUNKEN_BORDER
) 
 204         self
.stc
.SetConstraints(LayoutAnchors(self
.stc
, True, True, True, True)) 
 205         self
.stc
.SetHelpText('The style preview window. Click or move the cursor over a spesific style to select the style for editing in the editors above.') 
 206         EVT_LEFT_UP(self
.stc
, self
.OnUpdateUI
) 
 207         EVT_KEY_UP(self
.stc
, self
.OnUpdateUI
) 
 209         self
.contextHelpButton1 
= wxContextHelpButton(parent
=self
, 
 210               pos
=wxPoint(8, 423), size
=wxSize(24, 24), style
=wxBU_AUTODRAW
) 
 211         self
.contextHelpButton1
.SetConstraints(LayoutAnchors(self
.contextHelpButton1
, 
 212               True, False, False, True)) 
 214         self
.okBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGOKBTN
, label
='OK', 
 215               name
='okBtn', parent
=self
, pos
=wxPoint(282, 423), size
=wxSize(75, 
 217         self
.okBtn
.SetConstraints(LayoutAnchors(self
.okBtn
, False, False, True, 
 219         self
.okBtn
.SetToolTipString('Save changes to the config file') 
 220         EVT_BUTTON(self
.okBtn
, wxID_STCSTYLEEDITDLGOKBTN
, self
.OnOkbtnButton
) 
 222         self
.cancelBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGCANCELBTN
, 
 223               label
='Cancel', name
='cancelBtn', parent
=self
, pos
=wxPoint(366, 
 224               423), size
=wxSize(75, 23), style
=0) 
 225         self
.cancelBtn
.SetConstraints(LayoutAnchors(self
.cancelBtn
, False, 
 227         self
.cancelBtn
.SetToolTipString('Close dialog without saving changes') 
 228         EVT_BUTTON(self
.cancelBtn
, wxID_STCSTYLEEDITDLGCANCELBTN
, 
 229               self
.OnCancelbtnButton
) 
 231         self
.staticText4 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT4
, 
 232               label
='Face:', name
='staticText4', parent
=self
.panel1
, 
 233               pos
=wxPoint(0, 0), size
=wxSize(48, 13), style
=0) 
 235         self
.fixedWidthChk 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, 
 236               label
='', name
='fixedWidthChk', parent
=self
.panel1
, pos
=wxPoint(0, 
 237               23), size
=wxSize(13, 19), style
=0) 
 238         self
.fixedWidthChk
.SetToolTipString('Check this for Fixed Width fonts') 
 239         EVT_CHECKBOX(self
.fixedWidthChk
, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, 
 240               self
.OnFixedwidthchkCheckbox
) 
 242         self
.faceCb 
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGFACECB
, 
 243               name
='faceCb', parent
=self
.panel1
, pos
=wxPoint(17, 18), 
 244               size
=wxSize(105, 21), style
=0, validator
=wxDefaultValidator
, 
 247         self
.staticText7 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT7
, 
 248               label
='Size:', name
='staticText7', parent
=self
.panel2
, 
 249               pos
=wxPoint(0, 0), size
=wxSize(40, 13), style
=0) 
 251         self
.sizeCb 
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGSIZECB
, 
 252               name
='sizeCb', parent
=self
.panel2
, pos
=wxPoint(0, 17), 
 253               size
=wxSize(91, 21), style
=0, validator
=wxDefaultValidator
, 
 256         self
.sizeOkBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGSIZEOKBTN
, label
='ok', 
 257               name
='sizeOkBtn', parent
=self
.panel2
, pos
=wxPoint(90, 17), 
 258               size
=wxSize(21, 21), style
=0) 
 260         self
.faceOkBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGFACEOKBTN
, label
='ok', 
 261               name
='faceOkBtn', parent
=self
.panel1
, pos
=wxPoint(122, 18), 
 262               size
=wxSize(21, 21), style
=0) 
 264         self
.fgColBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGFGCOLBTN
, 
 265               label
='Foreground', name
='fgColBtn', parent
=self
.panel3
, 
 266               pos
=wxPoint(8, 16), size
=wxSize(72, 16), style
=0) 
 267         EVT_BUTTON(self
.fgColBtn
, wxID_STCSTYLEEDITDLGFGCOLBTN
, 
 268               self
.OnFgcolbtnButton
) 
 270         self
.fgColCb 
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGFGCOLCB
, 
 271               name
='fgColCb', parent
=self
.panel3
, pos
=wxPoint(8, 32), 
 272               size
=wxSize(89, 21), style
=0, validator
=wxDefaultValidator
, 
 275         self
.fgColOkBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGFGCOLOKBTN
, 
 276               label
='ok', name
='fgColOkBtn', parent
=self
.panel3
, pos
=wxPoint(96, 
 277               32), size
=wxSize(21, 21), style
=0) 
 279         self
.staticText3 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT3
, 
 280               label
='default', name
='staticText3', parent
=self
.panel3
, 
 281               pos
=wxPoint(100, 16), size
=wxSize(37, 16), style
=0) 
 283         self
.fgColDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGFGCOLDEFCB
, 
 284               label
='checkBox1', name
='fgColDefCb', parent
=self
.panel3
, 
 285               pos
=wxPoint(120, 31), size
=wxSize(16, 16), style
=0) 
 287         self
.bgColBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGBGCOLBTN
, 
 288               label
='Background', name
='bgColBtn', parent
=self
.panel3
, 
 289               pos
=wxPoint(8, 56), size
=wxSize(72, 16), style
=0) 
 290         EVT_BUTTON(self
.bgColBtn
, wxID_STCSTYLEEDITDLGBGCOLBTN
, 
 291               self
.OnBgcolbtnButton
) 
 293         self
.bgColCb 
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGBGCOLCB
, 
 294               name
='bgColCb', parent
=self
.panel3
, pos
=wxPoint(8, 72), 
 295               size
=wxSize(89, 21), style
=0, validator
=wxDefaultValidator
, 
 298         self
.bgColOkBtn 
= wxButton(id=wxID_STCSTYLEEDITDLGBGCOLOKBTN
, 
 299               label
='ok', name
='bgColOkBtn', parent
=self
.panel3
, pos
=wxPoint(96, 
 300               72), size
=wxSize(21, 21), style
=0) 
 302         self
.staticBox2 
= wxStaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX2
, 
 303               label
='Text attributes', name
='staticBox2', parent
=self
.panel4
, 
 304               pos
=wxPoint(0, 0), size
=wxSize(112, 99), style
=0) 
 305         self
.staticBox2
.SetConstraints(LayoutAnchors(self
.staticBox2
, False, 
 307         self
.staticBox2
.SetHelpText('Text attribute flags.') 
 309         self
.staticText2 
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT2
, 
 310               label
='default', name
='staticText2', parent
=self
.panel4
, 
 311               pos
=wxPoint(68, 11), size
=wxSize(37, 16), style
=0) 
 313         self
.taBoldDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTABOLDDEFCB
, 
 314               label
='checkBox1', name
='taBoldDefCb', parent
=self
.panel4
, 
 315               pos
=wxPoint(88, 27), size
=wxSize(16, 16), style
=0) 
 317         self
.taItalicDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAITALICDEFCB
, 
 318               label
='checkBox1', name
='taItalicDefCb', parent
=self
.panel4
, 
 319               pos
=wxPoint(88, 43), size
=wxSize(16, 16), style
=0) 
 321         self
.taUnderlinedDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
, 
 322               label
='checkBox1', name
='taUnderlinedDefCb', parent
=self
.panel4
, 
 323               pos
=wxPoint(88, 59), size
=wxSize(16, 16), style
=0) 
 325         self
.taEOLfilledDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
, 
 326               label
='checkBox1', name
='taEOLfilledDefCb', parent
=self
.panel4
, 
 327               pos
=wxPoint(88, 75), size
=wxSize(16, 16), style
=0) 
 329         self
.taEOLfilledCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, 
 330               label
='EOL filled', name
='taEOLfilledCb', parent
=self
.panel4
, 
 331               pos
=wxPoint(8, 75), size
=wxSize(72, 16), style
=0) 
 332         EVT_CHECKBOX(self
.taEOLfilledCb
, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, 
 333               self
.OnTaeoffilledcbCheckbox
) 
 335         self
.taUnderlinedCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, 
 336               label
='Underlined', name
='taUnderlinedCb', parent
=self
.panel4
, 
 337               pos
=wxPoint(8, 59), size
=wxSize(72, 16), style
=0) 
 338         EVT_CHECKBOX(self
.taUnderlinedCb
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
, 
 339               self
.OnTaunderlinedcbCheckbox
) 
 341         self
.taItalicCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAITALICCB
, 
 342               label
='Italic', name
='taItalicCb', parent
=self
.panel4
, 
 343               pos
=wxPoint(8, 43), size
=wxSize(72, 16), style
=0) 
 344         EVT_CHECKBOX(self
.taItalicCb
, wxID_STCSTYLEEDITDLGTAITALICCB
, 
 345               self
.OnTaitaliccbCheckbox
) 
 347         self
.taBoldCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTABOLDCB
, 
 348               label
='Bold', name
='taBoldCb', parent
=self
.panel4
, pos
=wxPoint(8, 
 349               27), size
=wxSize(72, 16), style
=0) 
 350         EVT_CHECKBOX(self
.taBoldCb
, wxID_STCSTYLEEDITDLGTABOLDCB
, 
 351               self
.OnTaboldcbCheckbox
) 
 353         self
.bgColDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGBGCOLDEFCB
, 
 354               label
='checkBox1', name
='bgColDefCb', parent
=self
.panel3
, 
 355               pos
=wxPoint(120, 71), size
=wxSize(16, 16), style
=0) 
 357         self
.staticBox1 
= wxStaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX1
, 
 358               label
='Colour', name
='staticBox1', parent
=self
.panel3
, 
 359               pos
=wxPoint(0, 0), size
=wxSize(142, 99), style
=0) 
 360         self
.staticBox1
.SetConstraints(LayoutAnchors(self
.staticBox1
, False, 
 363         self
.faceDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGFACEDEFCB
, 
 364               label
='checkBox1', name
='faceDefCb', parent
=self
.panel1
, 
 365               pos
=wxPoint(120, 0), size
=wxSize(16, 16), style
=0) 
 367         self
.taSizeDefCb 
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTASIZEDEFCB
, 
 368               label
='checkBox1', name
='taSizeDefCb', parent
=self
.panel2
, 
 369               pos
=wxPoint(88, 0), size
=wxSize(16, 16), style
=0) 
 371     def __init__(self
, parent
, langTitle
, lang
, configFile
, STCsToUpdate
=()): 
 372         global commonPropDefs
 
 373         commonPropDefs 
= {'fore': '#888888', 
 375                           'face': wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT
).GetFaceName()} 
 377         self
.stc_title 
= 'wxStyledTextCtrl Style Editor' 
 378         self
.stc_title 
= 'wxStyledTextCtrl Style Editor - %s' % langTitle
 
 379         if wxPlatform 
== '__WXMSW__': 
 380             self
.style_font_size 
= 8 
 382             self
.style_font_size 
= 10 
 383         self
._init
_ctrls
(parent
) 
 385         self
.configFile 
= configFile
 
 390         self
.STCsToUpdate 
= STCsToUpdate
 
 391         self
._blockUpdate 
= False 
 394         for combo
, okBtn
, evtRet
, evtCB
, evtRDC 
in ( 
 395          (self
.fgColCb
, self
.fgColOkBtn
, self
.OnfgColRet
, self
.OnfgColCombobox
, self
.OnGotoCommonDef
), 
 396          (self
.bgColCb
, self
.bgColOkBtn
, self
.OnbgColRet
, self
.OnbgColCombobox
, self
.OnGotoCommonDef
), 
 397          (self
.faceCb
, self
.faceOkBtn
, self
.OnfaceRet
, self
.OnfaceCombobox
, self
.OnGotoCommonDef
), 
 398          (self
.sizeCb
, self
.sizeOkBtn
, self
.OnsizeRet
, self
.OnsizeCombobox
, self
.OnGotoCommonDef
)): 
 399             self
.bindComboEvts(combo
, okBtn
, evtRet
, evtCB
, evtRDC
) 
 401         (self
.config
, self
.commonDefs
, self
.styleIdNames
, self
.styles
, 
 402          self
.styleGroupNames
, self
.predefStyleGroups
, 
 403          self
.otherLangStyleGroupNames
, self
.otherLangStyleGroups
, 
 404          self
.displaySrc
, self
.lexer
, self
.keywords
, self
.braceInfo
) = \
 
 405               initFromConfig(configFile
, lang
) 
 407         self
.currSpeedSetting 
= 'style.%s'%self
.lang
 
 408         for grp 
in [self
.currSpeedSetting
]+self
.styleGroupNames
: 
 409             self
.speedsettingCh
.Append(grp
) 
 410         self
.speedsettingCh
.SetSelection(0) 
 413         self
.stc
.SetMarginType(margin
, wxSTC_MARGIN_NUMBER
) 
 414         self
.stc
.SetMarginWidth(margin
, 25) 
 415         self
.stc
.SetMarginSensitive(margin
, True) 
 416         EVT_STC_MARGINCLICK(self
.stc
, wxID_STCSTYLEEDITDLGSTC
, self
.OnMarginClick
) 
 418         self
.stc
.SetUseTabs(False) 
 419         self
.stc
.SetTabWidth(4) 
 420         self
.stc
.SetIndentationGuides(True) 
 421         self
.stc
.SetEdgeMode(wxSTC_EDGE_BACKGROUND
) 
 422         self
.stc
.SetEdgeColumn(44) 
 426         self
.populateStyleSelector() 
 428         self
.defNames
, self
.defValues 
= parseProp(\
 
 429               self
.styleDict
.get(wxSTC_STYLE_DEFAULT
, '')) 
 430         self
.stc
.SetText(self
.displaySrc
) 
 431         self
.stc
.EmptyUndoBuffer() 
 432         self
.stc
.SetCurrentPos(self
.stc
.GetTextLength()) 
 433         self
.stc
.SetAnchor(self
.stc
.GetTextLength()) 
 435         self
.populateCombosWithCommonDefs() 
 437         # Logical grouping of controls and the property they edit 
 438         self
.allCtrls 
= [((self
.fgColBtn
, self
.fgColCb
, self
.fgColOkBtn
), self
.fgColDefCb
, 
 439                              'fore', wxID_STCSTYLEEDITDLGFGCOLDEFCB
), 
 440                          ((self
.bgColBtn
, self
.bgColCb
, self
.bgColOkBtn
), self
.bgColDefCb
, 
 441                              'back', wxID_STCSTYLEEDITDLGBGCOLDEFCB
), 
 442                          (self
.taBoldCb
, self
.taBoldDefCb
, 
 443                              'bold', wxID_STCSTYLEEDITDLGTABOLDDEFCB
), 
 444                          (self
.taItalicCb
, self
.taItalicDefCb
, 
 445                              'italic', wxID_STCSTYLEEDITDLGTAITALICDEFCB
), 
 446                          (self
.taUnderlinedCb
, self
.taUnderlinedDefCb
, 
 447                              'underline', wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
), 
 448                          (self
.taEOLfilledCb
, self
.taEOLfilledDefCb
, 
 449                              'eolfilled', wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
), 
 450                          ((self
.sizeCb
, self
.sizeOkBtn
), self
.taSizeDefCb
, 
 451                              'size', wxID_STCSTYLEEDITDLGTASIZEDEFCB
), 
 452                          ((self
.faceCb
, self
.faceOkBtn
, self
.fixedWidthChk
), self
.faceDefCb
, 
 453                              'face', wxID_STCSTYLEEDITDLGFACEDEFCB
)] 
 455         self
.clearCtrls(disableDefs
=True) 
 456         # centralised default checkbox event handler 
 458         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 459             self
.chbIdMap
[wid
] = ctrl
, chb
, prop
, wid
 
 460             EVT_CHECKBOX(chb
, wid
, self
.OnDefaultCheckBox
) 
 461             chb
.SetToolTipString('Toggle defaults') 
 465 #---Property methods------------------------------------------------------------ 
 466     def getCtrlForProp(self
, findprop
): 
 467         for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 470         raise Exception('PropNotFound', findprop
) 
 472     def editProp(self
, on
, prop
, val
=''): 
 473         oldstyle 
= self
.rememberStyles() 
 475             if not self
.names
.count(prop
): 
 476                 self
.names
.append(prop
) 
 477             self
.values
[prop
] = val
 
 479             try: self
.names
.remove(prop
) 
 480             except ValueError: pass 
 481             try: del self
.values
[prop
] 
 482             except KeyError: pass 
 487         except KeyError, errkey
: 
 488             wxLogError('Name not found in Common definition, '\
 
 489                 'please enter valid reference. (%s)'%errkey
) 
 490             self
.restoreStyles(oldstyle
) 
 493 #---Control population methods-------------------------------------------------- 
 495         if self
._blockUpdate
: return 
 496         self
.styles
, self
.styleDict
, self
.styleNumIdxMap 
= \
 
 497               setSTCStyles(self
.stc
, self
.styles
, self
.styleIdNames
, 
 498               self
.commonDefs
, self
.lang
, self
.lexer
, self
.keywords
) 
 500     def updateStyle(self
): 
 501         # called after a control edited self.names, self.values 
 502         # Special case for saving common defs settings 
 503         if self
.styleNum 
== 'common': 
 504             strVal 
= self
.style
[2] = self
.values
.values()[0] 
 505             if self
.style
[1] == 'size': self
.style
[2] = int(strVal
) 
 507             self
.commonDefs
[self
.style
[0]] = self
.style
[2] 
 508             self
.styleDefST
.SetLabel(strVal
) 
 510             self
.style 
= writePropVal(self
.names
, self
.values
) 
 511             styleDecl 
= writeProp(self
.styleNum
, self
.style
, self
.lang
) 
 512             self
.styles
[self
.styleNumIdxMap
[self
.styleNum
]] = styleDecl
 
 513             self
.styleDefST
.SetLabel(self
.style
) 
 516     def findInStyles(self
, txt
, styles
): 
 518             if string
.find(style
, txt
) != -1: 
 522     def rememberStyles(self
): 
 523         return self
.names
[:], copy
.copy(self
.values
) 
 525     def restoreStyles(self
, style
): 
 526         self
.names
, self
.values 
= style
 
 529     def clearCtrls(self
, isDefault
=False, disableDefs
=False): 
 530         self
._blockUpdate 
= True 
 532             for ctrl
, chb
, prop
, wid 
in self
.allCtrls
: 
 533                 if prop 
in ('fore', 'back'): 
 534                     cbtn
, txt
, btn 
= ctrl
 
 535                     cbtn
.SetBackgroundColour(\
 
 536                           wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
)) 
 537                     cbtn
.SetForegroundColour(wxColour(255, 255, 255)) 
 538                     cbtn
.Enable(isDefault
) 
 540                     txt
.Enable(isDefault
) 
 541                     btn
.Enable(isDefault
) 
 545                     cmb
.Enable(isDefault
) 
 546                     btn
.Enable(isDefault
) 
 550                     cmb
.Enable(isDefault
) 
 551                     btn
.Enable(isDefault
) 
 552                     chk
.Enable(isDefault
) 
 554                 elif prop 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 556                     ctrl
.Enable(isDefault
) 
 558                 chb
.Enable(not isDefault 
and not disableDefs
) 
 561             self
._blockUpdate 
= False 
 563     def populateProp(self
, items
, default
, forceDisable
=False): 
 564         self
._blockUpdate 
= True 
 566             for name
, val 
in items
: 
 568                     ctrl
, chb 
= self
.getCtrlForProp(name
) 
 570                     if name 
in ('fore', 'back'): 
 571                         cbtn
, txt
, btn 
= ctrl
 
 572                         repval 
= val
%self
.commonDefs
 
 573                         cbtn
.SetBackgroundColour(strToCol(repval
)) 
 574                         cbtn
.SetForegroundColour(wxColour(0, 0, 0)) 
 575                         cbtn
.Enable(not forceDisable
) 
 577                         txt
.Enable(not forceDisable
) 
 578                         btn
.Enable(not forceDisable
) 
 579                         chb
.SetValue(default
) 
 583                         cmb
.Enable(not forceDisable
) 
 584                         btn
.Enable(not forceDisable
) 
 585                         chb
.SetValue(default
) 
 589                         cmb
.Enable(not forceDisable
) 
 590                         btn
.Enable(not forceDisable
) 
 591                         chk
.Enable(not forceDisable
) 
 592                         chb
.SetValue(default
) 
 593                     elif name 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 594                         ctrl
.Enable(not forceDisable
) 
 596                         chb
.SetValue(default
) 
 598             self
._blockUpdate 
= False 
 600     def valIsCommonDef(self
, val
): 
 601         return len(val
) >= 5 and val
[:2] == '%(' 
 603     def populateCtrls(self
): 
 604         self
.clearCtrls(self
.styleNum 
== wxSTC_STYLE_DEFAULT
, 
 605             disableDefs
=self
.styleNum 
< 0) 
 607         # handle colour controls for settings 
 608         if self
.styleNum 
< 0: 
 609             self
.fgColDefCb
.Enable(True) 
 610             if self
.styleNum 
== -1: 
 611                 self
.bgColDefCb
.Enable(True) 
 613         # populate with default style 
 614         self
.populateProp(self
.defValues
.items(), True, 
 615             self
.styleNum 
!= wxSTC_STYLE_DEFAULT
) 
 616         # override with current settings 
 617         self
.populateProp(self
.values
.items(), False) 
 619     def getCommonDefPropType(self
, commonDefName
): 
 620         val 
= self
.commonDefs
[commonDefName
] 
 621         if type(val
) == type(0): return 'size' 
 622         if len(val
) == 7 and val
[0] == '#': return 'fore' 
 625     def bindComboEvts(self
, combo
, btn
, btnEvtMeth
, comboEvtMeth
, rdclickEvtMeth
): 
 626         EVT_COMBOBOX(combo
, combo
.GetId(), comboEvtMeth
) 
 627         EVT_BUTTON(btn
, btn
.GetId(), btnEvtMeth
) 
 628         EVT_RIGHT_DCLICK(combo
, rdclickEvtMeth
) 
 629         combo
.SetToolTipString('Select from list or click "ok" button on the right to change a manual entry, right double-click \n'\
 
 630             'the drop down button to select Common definition in the Style Editor (if applicable)') 
 631         btn
.SetToolTipString('Accept value') 
 633     def populateCombosWithCommonDefs(self
, fixedWidthOnly
=None): 
 634         self
._blockUpdate 
= True 
 636             commonDefs 
= {'fore': [], 'face': [], 'size': []}
 
 638             if self
.elementLb
.GetSelection() < self
.commonDefsStartIdx
: 
 639                 for common 
in self
.commonDefs
.keys(): 
 640                     prop 
= self
.getCommonDefPropType(common
) 
 641                     commonDefs
[prop
].append('%%(%s)%s'%(common
, 
 642                                                        prop
=='size' and 'd' or 's')) 
 645             currFg
, currBg 
= self
.fgColCb
.GetValue(), self
.bgColCb
.GetValue() 
 646             self
.fgColCb
.Clear(); self
.bgColCb
.Clear() 
 647             for colCommonDef 
in commonDefs
['fore']: 
 648                 self
.fgColCb
.Append(colCommonDef
) 
 649                 self
.bgColCb
.Append(colCommonDef
) 
 650             self
.fgColCb
.SetValue(currFg
); self
.bgColCb
.SetValue(currBg
) 
 653             if fixedWidthOnly 
is None: 
 654                 fixedWidthOnly 
= self
.fixedWidthChk
.GetValue() 
 655             fontEnum 
= wxFontEnumerator() 
 656             fontEnum
.EnumerateFacenames(fixedWidthOnly
=fixedWidthOnly
) 
 657             fontNameList 
= fontEnum
.GetFacenames() 
 659             currFace 
= self
.faceCb
.GetValue() 
 661             for colCommonDef 
in ['']+fontNameList
+commonDefs
['face']: 
 662                 self
.faceCb
.Append(colCommonDef
) 
 663             self
.faceCb
.SetValue(currFace
) 
 665             # Size (XXX add std font sizes) 
 666             currSize 
= self
.sizeCb
.GetValue() 
 668             for colCommonDef 
in commonDefs
['size']: 
 669                 self
.sizeCb
.Append(colCommonDef
) 
 670             self
.sizeCb
.SetValue(currSize
) 
 672             self
._blockUpdate 
= False 
 674     def populateStyleSelector(self
): 
 675         numStyles 
= self
.styleIdNames
.items() 
 677         self
.styleNumLookup 
= {} 
 682         for num
, name 
in numStyles
: 
 683             if num 
== wxSTC_STYLE_DEFAULT
: 
 684                 self
.elementLb
.InsertItems([name
, '----Language----'], 0) 
 685                 self
.elementLb
.Append('----Standard----') 
 686                 stdStart 
= stdPos 
= self
.elementLb
.GetCount() 
 689                 if num 
>= 33 and num 
< 40: 
 690                     self
.elementLb
.InsertItems([name
], stdStart 
+ stdOffset
) 
 691                     stdOffset 
= stdOffset 
+ 1 
 694                     self
.elementLb
.InsertItems([name
], stdStart 
+ extrOffset 
-1) 
 695                     extrOffset 
= extrOffset 
+ 1 
 698                     self
.elementLb
.Append(name
) 
 699             self
.styleNumLookup
[name
] = num
 
 702         self
.elementLb
.Append('----Settings----') 
 703         settings 
= settingsIdNames
.items() 
 704         settings
.sort();settings
.reverse() 
 705         for num
, name 
in settings
: 
 706             self
.elementLb
.Append(name
) 
 707             self
.styleNumLookup
[name
] = num
 
 710         self
.elementLb
.Append('----Common----') 
 711         self
.commonDefsStartIdx 
= self
.elementLb
.GetCount() 
 712         for common 
in self
.commonDefs
.keys(): 
 713             tpe 
= type(self
.commonDefs
[common
]) 
 714             self
.elementLb
.Append('%('+common
+')'+(tpe 
is type('') and 's' or 'd')) 
 715             self
.styleNumLookup
[common
] = num
 
 717 #---Colour methods-------------------------------------------------------------- 
 718     def getColourDlg(self
, colour
, title
=''): 
 719         data 
= wxColourData() 
 720         data
.SetColour(colour
) 
 721         data
.SetChooseFull(True) 
 722         dlg 
= wxColourDialog(self
, data
) 
 725             if dlg
.ShowModal() == wxID_OK
: 
 726                 data 
= dlg
.GetColourData() 
 727                 return data
.GetColour() 
 732     colDlgTitles 
= {'fore': 'Foreground', 'back': 'Background'}
 
 733     def editColProp(self
, colBtn
, colCb
, prop
): 
 734         col 
= self
.getColourDlg(colBtn
.GetBackgroundColour(), 
 735               self
.colDlgTitles
[prop
]+ ' colour') 
 737             colBtn
.SetForegroundColour(wxColour(0, 0, 0)) 
 738             colBtn
.SetBackgroundColour(col
) 
 739             colStr 
= colToStr(col
) 
 740             colCb
.SetValue(colStr
) 
 741             self
.editProp(True, prop
, colStr
) 
 743     def OnFgcolbtnButton(self
, event
): 
 744         self
.editColProp(self
.fgColBtn
, self
.fgColCb
, 'fore') 
 746     def OnBgcolbtnButton(self
, event
): 
 747         self
.editColProp(self
.bgColBtn
, self
.bgColCb
, 'back') 
 749     def editColTCProp(self
, colCb
, colBtn
, prop
, val
=None): 
 751             colStr 
= colCb
.GetValue() 
 755             col 
= strToCol(colStr
%self
.commonDefs
) 
 756         if self
.editProp(colStr
!='', prop
, colStr
): 
 758                 colBtn
.SetForegroundColour(wxColour(0, 0, 0)) 
 759                 colBtn
.SetBackgroundColour(col
) 
 761                 colBtn
.SetForegroundColour(wxColour(255, 255, 255)) 
 762                 colBtn
.SetBackgroundColour(\
 
 763                       wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
)) 
 765     def OnfgColRet(self
, event
): 
 766         try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore') 
 767         except AssertionError: wxLogError('Not a valid colour value') 
 769     def OnfgColCombobox(self
, event
): 
 770         if self
._blockUpdate
: return 
 771         try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore', event
.GetString()) 
 772         except AssertionError: wxLogError('Not a valid colour value') 
 774     def OnbgColRet(self
, event
): 
 775         try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back') 
 776         except AssertionError: wxLogError('Not a valid colour value') 
 778     def OnbgColCombobox(self
, event
): 
 779         if self
._blockUpdate
: return 
 780         try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back', event
.GetString()) 
 781         except AssertionError: wxLogError('Not a valid colour value') 
 783 #---Text attribute events------------------------------------------------------- 
 784     def OnTaeoffilledcbCheckbox(self
, event
): 
 785         self
.editProp(event
.IsChecked(), 'eolfilled') 
 787     def OnTaitaliccbCheckbox(self
, event
): 
 788         self
.editProp(event
.IsChecked(), 'italic') 
 790     def OnTaboldcbCheckbox(self
, event
): 
 791         self
.editProp(event
.IsChecked(), 'bold') 
 793     def OnTaunderlinedcbCheckbox(self
, event
): 
 794         self
.editProp(event
.IsChecked(), 'underline') 
 796     def OnGotoCommonDef(self
, event
): 
 797         val 
= event
.GetEventObject().GetValue() 
 798         if self
.valIsCommonDef(val
): 
 799             idx 
= self
.elementLb
.FindString(val
) 
 801                 self
.elementLb
.SetSelection(idx
, True) 
 802                 self
.OnElementlbListbox(None) 
 804     def OnfaceRet(self
, event
): 
 805         self
.setFace(self
.faceCb
.GetValue()) 
 807     def OnfaceCombobox(self
, event
): 
 808         if self
._blockUpdate
: return 
 809         self
.setFace(event
.GetString()) 
 811     def setFace(self
, val
): 
 812         try: val
%self
.commonDefs
 
 813         except KeyError: wxLogError('Invalid common definition') 
 814         else: self
.editProp(val
!='', 'face', val
) 
 816     def OnsizeRet(self
, event
): 
 817         self
.setSize(self
.sizeCb
.GetValue()) 
 819     def OnsizeCombobox(self
, event
): 
 820         if self
._blockUpdate
: return 
 821         self
.setSize(event
.GetString()) 
 823     def setSize(self
, val
): 
 824         try: int(val
%self
.commonDefs
) 
 825         except ValueError: wxLogError('Not a valid integer size value') 
 826         except KeyError: wxLogError('Invalid common definition') 
 827         else: self
.editProp(val
!='', 'size', val
) 
 829 #---Main GUI events------------------------------------------------------------- 
 830     def OnElementlbListbox(self
, event
): 
 831         isCommon 
= self
.elementLb
.GetSelection() >= self
.commonDefsStartIdx
 
 832         self
.removeCommonItemBtn
.Enable(isCommon
) 
 834         styleIdent 
= self
.elementLb
.GetStringSelection() 
 835         # common definition selected 
 837             common 
= styleIdent
[2:-2] 
 838             prop 
= self
.getCommonDefPropType(common
) 
 839             self
.clearCtrls(disableDefs
=True) 
 841                 self
.fgColBtn
.Enable(True) 
 842                 self
.fgColCb
.Enable(True) 
 843                 self
.fgColOkBtn
.Enable(True) 
 845                 self
.faceCb
.Enable(True) 
 846                 self
.fixedWidthChk
.Enable(True) 
 847                 self
.faceOkBtn
.Enable(True) 
 849                 self
.sizeCb
.Enable(True) 
 850                 self
.sizeOkBtn
.Enable(True) 
 852             commonDefVal 
= str(self
.commonDefs
[common
]) 
 853             self
.styleDefST
.SetLabel(commonDefVal
) 
 854             self
.populateProp( [(prop
, commonDefVal
)], True) 
 856             self
.styleNum 
= 'common' 
 857             self
.style 
= [common
, prop
, commonDefVal
] 
 858             self
.names
, self
.values 
= [prop
], {prop: commonDefVal}
 
 860         # normal style element selected 
 861         elif len(styleIdent
) >=2 and styleIdent
[:2] != '--': 
 862             self
.styleNum 
= self
.styleNumLookup
[styleIdent
] 
 863             self
.style 
= self
.styleDict
[self
.styleNum
] 
 864             self
.names
, self
.values 
= parseProp(self
.style
) 
 865             if self
.styleNum 
== wxSTC_STYLE_DEFAULT
: 
 866                 self
.defNames
, self
.defValues 
= \
 
 867                       self
.names
, self
.values
 
 869             self
.checkBraces(self
.styleNum
) 
 871             self
.styleDefST
.SetLabel(self
.style
) 
 876             self
.clearCtrls(disableDefs
=True) 
 878                 self
.styleDefST
.SetLabel(styleCategoryDescriptions
[styleIdent
]) 
 880         self
.populateCombosWithCommonDefs() 
 882     def OnDefaultCheckBox(self
, event
): 
 883         if self
.chbIdMap
.has_key(event
.GetId()): 
 884             ctrl
, chb
, prop
, wid 
= self
.chbIdMap
[event
.GetId()] 
 885             restore 
= not event
.IsChecked() 
 886             if prop 
in ('fore', 'back'): 
 887                 cbtn
, cmb
, btn 
= ctrl
 
 892                     colStr 
= cmb
.GetValue() 
 893                     #if prop == 'fore': colStr = self.fgColCb.GetValue() 
 894                     #else: colStr = self.bgColCb.GetValue() 
 895                     if colStr
: self
.editProp(True, prop
, colStr
) 
 897                     self
.editProp(False, prop
) 
 901                 if val
: self
.editProp(restore
, prop
, val
) 
 906                 val 
= cmb
.GetStringSelection() 
 907                 if val
: self
.editProp(restore
, prop
, val
) 
 911             elif prop 
in ('bold', 'italic', 'underline', 'eolfilled'): 
 913                 if ctrl
.GetValue(): self
.editProp(restore
, prop
) 
 915     def OnOkbtnButton(self
, event
): 
 916         # write styles and common defs to the config 
 919             writeStylesToConfig(self
.config
, 'style.%s'%self
.lang
, self
.styles
) 
 920             self
.config
.SetPath('') 
 921             self
.config
.Write(commonDefsFile
, `self
.commonDefs`
) 
 924             for stc 
in self
.STCsToUpdate
: 
 925                 setSTCStyles(stc
, self
.styles
, self
.styleIdNames
, self
.commonDefs
, 
 926                       self
.lang
, self
.lexer
, self
.keywords
) 
 929         self
.EndModal(wxID_OK
) 
 931     def OnCancelbtnButton(self
, event
): 
 932         self
.EndModal(wxID_CANCEL
) 
 934     def OnCommondefsbtnButton(self
, event
): 
 935         dlg 
= wxTextEntryDialog(self
, 'Edit common definitions dictionary', 
 936               'Common definitions', pprint
.pformat(self
.commonDefs
), 
 937               style
=wxTE_MULTILINE | wxOK | wxCANCEL | wxCENTRE
) 
 939             if dlg
.ShowModal() == wxID_OK
: 
 940                 answer 
= eval(dlg
.GetValue()) 
 941                 assert type(answer
) is type({}), 'Not a valid dictionary' 
 942                 oldDefs 
= self
.commonDefs
 
 943                 self
.commonDefs 
= answer
 
 946                 except KeyError, badkey
: 
 947                     wxLogError(str(badkey
)+' not defined but required, \n'\
 
 948                           'reverting to previous common definition') 
 949                     self
.commonDefs 
= oldDefs
 
 951                 self
.populateCombosWithCommonDefs() 
 956     def OnSpeedsettingchChoice(self
, event
): 
 957         group 
= event
.GetString() 
 959             userStyles 
= 'style.%s'%self
.lang
 
 960             if self
.currSpeedSetting 
== userStyles
: 
 961                 self
.predefStyleGroups
[userStyles
] = self
.styles
 
 962             self
.styles 
= self
.predefStyleGroups
[group
] 
 964             self
.defNames
, self
.defValues 
= parseProp(\
 
 965                   self
.styleDict
.get(wxSTC_STYLE_DEFAULT
, '')) 
 966             self
.OnElementlbListbox(None) 
 967             self
.currSpeedSetting 
= group
 
 969     def OnFixedwidthchkCheckbox(self
, event
): 
 970         self
.populateCombosWithCommonDefs(event
.Checked()) 
 972     def OnAddsharebtnButton(self
, event
): 
 973         dlg 
= CommonDefDlg(self
) 
 975             if dlg
.ShowModal() == wxID_OK
: 
 976                 prop
, name 
= dlg
.result
 
 977                 if not self
.commonDefs
.has_key(name
): 
 978                     self
.commonDefs
[name
] = commonPropDefs
[prop
] 
 979                     self
.elementLb
.Append('%('+name
+')'+\
 
 980                      (type(commonPropDefs
[prop
]) is type('') and 's' or 'd')) 
 981                     self
.elementLb
.SetSelection(self
.elementLb
.GetCount()-1, True) 
 982                     self
.populateCombosWithCommonDefs() 
 983                     self
.OnElementlbListbox(None) 
 987     def OnRemovesharebtnButton(self
, event
): 
 988         ownGroup 
= 'style.%s'%self
.lang
 
 989         comDef 
= self
.elementLb
.GetStringSelection() 
 991         # Search ALL styles before removing 
 992         srchDct 
= {ownGroup: self.styles}
 
 993         srchDct
.update(self
.predefStyleGroups
) 
 994         srchDct
.update(self
.otherLangStyleGroups
) 
 997         for grpName
, styles 
in srchDct
.items(): 
 998             if self
.findInStyles(comDef
, styles
): 
 999                 matchList
.append(grpName
) 
1002             wxLogError('Aborted: '+comDef
+' is still used in the styles of the \n'\
 
1003                   'following groups in the config file (stc-styles.rc.cfg):\n'+ \
 
1004                   string
.join(matchList
, '\n')) 
1006             del self
.commonDefs
[comDef
[2:-2]] 
1008             self
.populateCombosWithCommonDefs() 
1009             selIdx 
= self
.elementLb
.GetSelection() 
1010             self
.elementLb
.Delete(selIdx
) 
1011             if selIdx 
== self
.elementLb
.GetCount(): 
1013             self
.elementLb
.SetSelection(selIdx
, True) 
1014             self
.OnElementlbListbox(None) 
1016 #---STC events------------------------------------------------------------------ 
1017     def OnUpdateUI(self
, event
): 
1018         styleBefore 
= self
.stc
.GetStyleAt(self
.stc
.GetCurrentPos()) 
1019         if self
.styleIdNames
.has_key(styleBefore
): 
1020             self
.elementLb
.SetStringSelection(self
.styleIdNames
[styleBefore
], 
1023             self
.elementLb
.SetSelection(0, False) 
1024             self
.styleDefST
.SetLabel('Style %d not defined, sorry.'%styleBefore
) 
1025         self
.OnElementlbListbox(None) 
1028     def checkBraces(self
, style
): 
1029         if style 
== wxSTC_STYLE_BRACELIGHT 
and self
.braceInfo
.has_key('good'): 
1030             line
, col 
= self
.braceInfo
['good'] 
1031             pos 
= self
.stc
.PositionFromLine(line
-1) + col
 
1032             braceOpposite 
= self
.stc
.BraceMatch(pos
) 
1033             if braceOpposite 
!= -1: 
1034                 self
.stc
.BraceHighlight(pos
, braceOpposite
) 
1035         elif style 
== wxSTC_STYLE_BRACEBAD 
and self
.braceInfo
.has_key('bad'): 
1036             line
, col 
= self
.braceInfo
['bad'] 
1037             pos 
= self
.stc
.PositionFromLine(line
-1) + col
 
1038             self
.stc
.BraceBadLight(pos
) 
1040             self
.stc
.BraceBadLight(-1) 
1043     def OnStcstyleeditdlgSize(self
, event
): 
1045         # Without this refresh, resizing leaves artifacts 
1049     def OnMarginClick(self
, event
): 
1050         self
.elementLb
.SetStringSelection('Line numbers', True) 
1051         self
.OnElementlbListbox(None) 
1054 #---Common definition dialog---------------------------------------------------- 
1056 [wxID_COMMONDEFDLG
, wxID_COMMONDEFDLGCANCELBTN
, wxID_COMMONDEFDLGCOMDEFNAMETC
, wxID_COMMONDEFDLGOKBTN
, wxID_COMMONDEFDLGPROPTYPERBX
, wxID_COMMONDEFDLGSTATICBOX1
] = map(lambda _init_ctrls
: wxNewId(), range(6)) 
1058 class CommonDefDlg(wxDialog
): 
1059     def _init_ctrls(self
, prnt
): 
1060         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') 
1061         self
.SetClientSize(wxSize(184, 200)) 
1063         self
.propTypeRBx 
= wxRadioBox(choices 
= ['Colour value', 'Font face', 'Size value'], id = wxID_COMMONDEFDLGPROPTYPERBX
, label 
= 'Property type', majorDimension 
= 1, name 
= 'propTypeRBx', parent 
= self
, point 
= wxPoint(8, 8), size 
= wxSize(168, 92), style 
= wxRA_SPECIFY_COLS
, validator 
= wxDefaultValidator
) 
1064         self
.propTypeRBx
.SetSelection(self
._propTypeIdx
) 
1066         self
.staticBox1 
= wxStaticBox(id = wxID_COMMONDEFDLGSTATICBOX1
, label 
= 'Name', name 
= 'staticBox1', parent 
= self
, pos 
= wxPoint(8, 108), size 
= wxSize(168, 46), style 
= 0) 
1068         self
.comDefNameTC 
= wxTextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC
, name 
= 'comDefNameTC', parent 
= self
, pos 
= wxPoint(16, 124), size 
= wxSize(152, 21), style 
= 0, value 
= '') 
1069         self
.comDefNameTC
.SetLabel(self
._comDefName
) 
1071         self
.okBtn 
= wxButton(id = wxID_COMMONDEFDLGOKBTN
, label 
= 'OK', name 
= 'okBtn', parent 
= self
, pos 
= wxPoint(8, 164), size 
= wxSize(80, 23), style 
= 0) 
1072         EVT_BUTTON(self
.okBtn
, wxID_COMMONDEFDLGOKBTN
, self
.OnOkbtnButton
) 
1074         self
.cancelBtn 
= wxButton(id = wxID_COMMONDEFDLGCANCELBTN
, label 
= 'Cancel', name 
= 'cancelBtn', parent 
= self
, pos 
= wxPoint(96, 164), size 
= wxSize(80, 23), style 
= 0) 
1075         EVT_BUTTON(self
.cancelBtn
, wxID_COMMONDEFDLGCANCELBTN
, self
.OnCancelbtnButton
) 
1077     def __init__(self
, parent
, name
='', propIdx
=0): 
1078         self
._comDefName 
= '' 
1079         self
._comDefName 
= name
 
1080         self
._propTypeIdx 
= 0 
1081         self
._propTypeIdx 
= propIdx
 
1082         self
._init
_ctrls
(parent
) 
1084         self
.propMap 
= {0: 'fore', 1: 'face', 2: 'size'}
 
1085         self
.result 
= ( '', '' ) 
1089     def OnOkbtnButton(self
, event
): 
1090         self
.result 
= ( self
.propMap
[self
.propTypeRBx
.GetSelection()], 
1091                         self
.comDefNameTC
.GetValue() ) 
1092         self
.EndModal(wxID_OK
) 
1094     def OnCancelbtnButton(self
, event
): 
1095         self
.result 
= ( '', '' ) 
1096         self
.EndModal(wxID_CANCEL
) 
1098 #---Functions useful outside of the editor---------------------------------- 
1100 def setSelectionColour(stc
, style
): 
1101     names
, values 
= parseProp(style
) 
1103         stc
.SetSelForeground(True, strToCol(values
['fore'])) 
1105         stc
.SetSelBackground(True, strToCol(values
['back'])) 
1107 def setCursorColour(stc
, style
): 
1108     names
, values 
= parseProp(style
) 
1110         stc
.SetCaretForeground(strToCol(values
['fore'])) 
1112 def setEdgeColour(stc
, style
): 
1113     names
, values 
= parseProp(style
) 
1115         stc
.SetEdgeColour(strToCol(values
['fore'])) 
1117 def strToCol(strCol
): 
1118     assert len(strCol
) == 7 and strCol
[0] == '#', 'Not a valid colour string' 
1119     return wxColour(string
.atoi('0x'+strCol
[1:3], 16), 
1120                     string
.atoi('0x'+strCol
[3:5], 16), 
1121                     string
.atoi('0x'+strCol
[5:7], 16)) 
1123     return '#%s%s%s' % (string
.zfill(string
.upper(hex(col
.Red())[2:]), 2), 
1124                         string
.zfill(string
.upper(hex(col
.Green())[2:]), 2), 
1125                         string
.zfill(string
.upper(hex(col
.Blue())[2:]), 2)) 
1127 def writeProp(num
, style
, lang
): 
1129         return 'style.%s.%s='%(lang
, string
.zfill(`num`
, 3)) + style
 
1131         return 'setting.%s.%d='%(lang
, num
) + style
 
1133 def writePropVal(names
, values
): 
1137             res
.append(values
[name
] and name
+':'+values
[name
] or name
) 
1138     return string
.join(res
, ',') 
1140 def parseProp(prop
): 
1141     items 
= string
.split(prop
, ',') 
1145         nameVal 
= string
.split(item
, ':') 
1146         names
.append(string
.strip(nameVal
[0])) 
1147         if len(nameVal
) == 1: 
1148             values
[nameVal
[0]] = '' 
1150             values
[nameVal
[0]] = string
.strip(nameVal
[1]) 
1151     return names
, values
 
1153 def parsePropLine(prop
): 
1154     name
, value 
= string
.split(prop
, '=') 
1155     return int(string
.split(name
, '.')[-1]), value
 
1157 def setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
): 
1158     #wxLogMessage('Set style') 
1162     # build style dict based on given styles 
1163     for numStyle 
in styles
: 
1164         num
, style 
= parsePropLine(numStyle
) 
1165         styleDict
[num
] = style
 
1167     # Add blank style entries for undefined styles 
1169     styleItems 
= styleIdNames
.items() + settingsIdNames
.items() 
1172     for num
, name 
in styleItems
: 
1173         styleNumIdxMap
[num
] = idx
 
1174         if not styleDict
.has_key(num
): 
1176         newStyles
.append(writeProp(num
, styleDict
[num
], lang
)) 
1179     # Set background colour to reduce flashing effect on refresh or page switch 
1181     if styleDict
.has_key(0): prop 
= styleDict
[0] 
1182     else: prop 
= styleDict
[wxSTC_STYLE_DEFAULT
] 
1183     names
, vals 
= parseProp(prop
) 
1185         bkCol 
= strToCol(vals
['back']) 
1188     stc
.SetBackgroundColour(bkCol
) 
1190     # Set the styles on the wxSTC 
1192     stc
.StyleResetDefault() 
1193     stc
.ClearDocumentStyle() 
1195     stc
.SetKeyWords(0, keywords
) 
1196     stc
.StyleSetSpec(wxSTC_STYLE_DEFAULT
, 
1197           styleDict
[wxSTC_STYLE_DEFAULT
] % commonDefs
) 
1200     for num
, style 
in styleDict
.items(): 
1202             stc
.StyleSetSpec(num
, style 
% commonDefs
) 
1204             setSelectionColour(stc
, style 
% commonDefs
) 
1206             setCursorColour(stc
, style 
% commonDefs
) 
1208             setEdgeColour(stc
, style 
% commonDefs
) 
1210     stc
.Colourise(0, stc
.GetTextLength()) 
1213     return newStyles
, styleDict
, styleNumIdxMap
 
1215 #---Config reading and writing ------------------------------------------------- 
1216 commonDefsFile 
= 'common.defs.%s'%(wxPlatform 
== '__WXMSW__' and 'msw' or 'gtk') 
1218 def readPyValFromConfig(conf
, name
): 
1219     return eval(string
.replace(conf
.Read(name
), '\r\n', '\n')+'\n') 
1221 def initFromConfig(configFile
, lang
): 
1222     cfg 
= wxFileConfig(localFilename
=configFile
, style
=wxCONFIG_USE_LOCAL_FILE
) 
1223     cfg
.SetExpandEnvVars(False) 
1225     # read in all group names for this language 
1226     groupPrefix 
= 'style.%s'%lang
 
1227     gpLen 
= len(groupPrefix
) 
1228     predefStyleGroupNames
, otherLangStyleGroupNames 
= [], [] 
1229     cont
, val
, idx 
= cfg
.GetFirstGroup() 
1231         if val 
!= groupPrefix 
and len(val
) >= 5 and val
[:5] == 'style': 
1232             if len(val
) > gpLen 
and val
[:gpLen
] == groupPrefix
: 
1233                 predefStyleGroupNames
.append(val
) 
1235                 otherLangStyleGroupNames
.append(val
) 
1237         cont
, val
, idx 
= cfg
.GetNextGroup(idx
) 
1239     # read in common elements 
1240     commonDefs 
= readPyValFromConfig(cfg
, commonDefsFile
) 
1241     assert type(commonDefs
) is type({}), \
 
1242           'Common definitions (%s) not a valid dict'%commonDefsFile
 
1244     commonStyleIdNames 
= readPyValFromConfig(cfg
, 'common.styleidnames') 
1245     assert type(commonStyleIdNames
) is type({}), \
 
1246           'Common definitions (%s) not a valid dict'%'common.styleidnames' 
1248     # Lang spesific settings 
1250     styleIdNames 
= readPyValFromConfig(cfg
, 'styleidnames') 
1251     assert type(commonStyleIdNames
) is type({}), \
 
1252           'Not a valid dict [%s] styleidnames)'%lang
 
1253     styleIdNames
.update(commonStyleIdNames
) 
1254     braceInfo 
= readPyValFromConfig(cfg
, 'braces') 
1255     assert type(commonStyleIdNames
) is type({}), \
 
1256           'Not a valid dict [%s] braces)'%lang
 
1258     displaySrc 
= cfg
.Read('displaysrc') 
1259     lexer 
= readPyValFromConfig(cfg
, 'lexer') 
1260     keywords 
= cfg
.Read('keywords') 
1264     # read in current styles 
1265     styles 
= readStylesFromConfig(cfg
, groupPrefix
) 
1267     # read in predefined styles 
1268     predefStyleGroups 
= {} 
1269     for group 
in predefStyleGroupNames
: 
1270         predefStyleGroups
[group
] = readStylesFromConfig(cfg
, group
) 
1272     # read in all other style sections 
1273     otherLangStyleGroups 
= {} 
1274     for group 
in otherLangStyleGroupNames
: 
1275         otherLangStyleGroups
[group
] = readStylesFromConfig(cfg
, group
) 
1277     return (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
, 
1278             predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
, 
1279             displaySrc
, lexer
, keywords
, braceInfo
) 
1281 def readStylesFromConfig(config
, group
): 
1283     config
.SetPath(group
) 
1285     cont
, val
, idx 
= config
.GetFirstEntry() 
1287         styles
.append(val
+'='+config
.Read(val
)) 
1288         cont
, val
, idx 
= config
.GetNextEntry(idx
) 
1293 def writeStylesToConfig(config
, group
, styles
): 
1295     config
.DeleteGroup(group
) 
1296     config
.SetPath(group
) 
1298     for style 
in styles
: 
1299         name
, value 
= string
.split(style
, '=') 
1300         config
.Write(name
, string
.strip(value
)) 
1304 #------------------------------------------------------------------------------- 
1305 def initSTC(stc
, config
, lang
): 
1306     """ Main module entry point. Initialise a wxSTC from given config file.""" 
1307     (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
, 
1308      predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
, 
1309      displaySrc
, lexer
, keywords
, braceInfo
) = initFromConfig(config
, lang
) 
1311     setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
) 
1313 #------------------------------------------------------------------------------- 
1314 if __name__ 
== '__main__': 
1315     from wxPython
.help import * 
1317     app 
= wxPySimpleApp() 
1319     provider 
= wxSimpleHelpProvider() 
1320     wxHelpProvider_Set(provider
) 
1322     base 
= os
.path
.split(__file__
)[0] 
1323     config 
= os
.path
.abspath(os
.path
.join(base
, 'stc-styles.rc.cfg')) 
1325         f 
= wxFrame(None, -1, 'Test frame (double click for editor)') 
1326         stc 
= wxStyledTextCtrl(f
, -1) 
1327         def OnDblClick(evt
, stc
=stc
): 
1328             dlg 
= STCStyleEditDlg(None, 'Python', 'python', config
, (stc
,)) 
1329             try: dlg
.ShowModal() 
1330             finally: dlg
.Destroy() 
1331         stc
.SetText(open('STCStyleEditor.py').read()) 
1332         EVT_LEFT_DCLICK(stc
, OnDblClick
) 
1333         initSTC(stc
, config
, 'python') 
1337         dlg 
= STCStyleEditDlg(None, 
1343             #'Properties', 'prop', 
1345         try: dlg
.ShowModal() 
1346         finally: dlg
.Destroy()