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'}
62 commonPropDefs
= {'fore': '#888888', 'size': 8,
63 'face': wxSystemSettings_GetSystemFont(wxSYS_DEFAULT_GUI_FONT
).GetFaceName()}
65 styleCategoryDescriptions
= {
66 '----Language----': 'Styles spesific to the language',
67 '----Standard----': 'Styles shared by all languages',
68 '----Settings----': 'Properties set by STC methods',
69 '----Common----': 'User definable values that can be shared between languages'}
71 [wxID_STCSTYLEEDITDLG
, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
,
72 wxID_STCSTYLEEDITDLGBGCOLBTN
, wxID_STCSTYLEEDITDLGBGCOLCB
,
73 wxID_STCSTYLEEDITDLGBGCOLDEFCB
, wxID_STCSTYLEEDITDLGBGCOLOKBTN
,
74 wxID_STCSTYLEEDITDLGCANCELBTN
, wxID_STCSTYLEEDITDLGCONTEXTHELPBUTTON1
,
75 wxID_STCSTYLEEDITDLGELEMENTLB
, wxID_STCSTYLEEDITDLGFACECB
,
76 wxID_STCSTYLEEDITDLGFACEDEFCB
, wxID_STCSTYLEEDITDLGFACEOKBTN
,
77 wxID_STCSTYLEEDITDLGFGCOLBTN
, wxID_STCSTYLEEDITDLGFGCOLCB
,
78 wxID_STCSTYLEEDITDLGFGCOLDEFCB
, wxID_STCSTYLEEDITDLGFGCOLOKBTN
,
79 wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
, wxID_STCSTYLEEDITDLGOKBTN
,
80 wxID_STCSTYLEEDITDLGPANEL1
, wxID_STCSTYLEEDITDLGPANEL2
,
81 wxID_STCSTYLEEDITDLGPANEL3
, wxID_STCSTYLEEDITDLGPANEL4
,
82 wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
, wxID_STCSTYLEEDITDLGSIZECB
,
83 wxID_STCSTYLEEDITDLGSIZEOKBTN
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
,
84 wxID_STCSTYLEEDITDLGSTATICBOX1
, wxID_STCSTYLEEDITDLGSTATICBOX2
,
85 wxID_STCSTYLEEDITDLGSTATICLINE1
, wxID_STCSTYLEEDITDLGSTATICTEXT2
,
86 wxID_STCSTYLEEDITDLGSTATICTEXT3
, wxID_STCSTYLEEDITDLGSTATICTEXT4
,
87 wxID_STCSTYLEEDITDLGSTATICTEXT6
, wxID_STCSTYLEEDITDLGSTATICTEXT7
,
88 wxID_STCSTYLEEDITDLGSTATICTEXT8
, wxID_STCSTYLEEDITDLGSTATICTEXT9
,
89 wxID_STCSTYLEEDITDLGSTC
, wxID_STCSTYLEEDITDLGSTYLEDEFST
,
90 wxID_STCSTYLEEDITDLGTABOLDCB
, wxID_STCSTYLEEDITDLGTABOLDDEFCB
,
91 wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
,
92 wxID_STCSTYLEEDITDLGTAITALICCB
, wxID_STCSTYLEEDITDLGTAITALICDEFCB
,
93 wxID_STCSTYLEEDITDLGTASIZEDEFCB
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
,
94 wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
,
95 ] = map(lambda _init_ctrls
: wxNewId(), range(47))
97 class STCStyleEditDlg(wxDialog
):
98 """ Style editor for the wxStyledTextCtrl """
99 _custom_classes
= {'wxWindow' : ['wxStyledTextCtrl']}
100 def _init_utils(self
):
101 # generated method, don't edit
104 def _init_ctrls(self
, prnt
):
105 # generated method, don't edit
106 wxDialog
.__init
__(self
, id=wxID_STCSTYLEEDITDLG
, name
='STCStyleEditDlg',
107 parent
=prnt
, pos
=wxPoint(583, 291), size
=wxSize(459, 482),
108 style
=wxWANTS_CHARS | wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER
,
109 title
=self
.stc_title
)
111 self
.SetClientSize(wxSize(451, 455))
112 self
.SetAutoLayout(True)
113 self
.SetSizeHints(425, 400, -1, -1)
115 EVT_SIZE(self
, self
.OnStcstyleeditdlgSize
)
117 self
.speedsettingCh
= wxChoice(choices
=[],
118 id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
, name
='speedsettingCh',
119 parent
=self
, pos
=wxPoint(96, 28), size
=wxSize(346, 21), style
=0,
120 validator
=wxDefaultValidator
)
121 self
.speedsettingCh
.SetConstraints(LayoutAnchors(self
.speedsettingCh
,
122 True, True, True, False))
123 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.')
124 EVT_CHOICE(self
.speedsettingCh
, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH
,
125 self
.OnSpeedsettingchChoice
)
127 self
.elementLb
= wxListBox(choices
=[], id=wxID_STCSTYLEEDITDLGELEMENTLB
,
128 name
='elementLb', parent
=self
, pos
=wxPoint(8, 72),
129 size
=wxSize(160, 112), style
=0, validator
=wxDefaultValidator
)
130 self
.elementLb
.SetConstraints(LayoutAnchors(self
.elementLb
, True, True,
132 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.')
133 EVT_LISTBOX(self
.elementLb
, wxID_STCSTYLEEDITDLGELEMENTLB
,
134 self
.OnElementlbListbox
)
136 self
.addCommonItemBtn
= wxButton(id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
,
137 label
='Add', name
='addCommonItemBtn', parent
=self
, pos
=wxPoint(8,
138 184), size
=wxSize(80, 17), style
=0)
139 self
.addCommonItemBtn
.SetToolTipString('Add new Common definition')
140 EVT_BUTTON(self
.addCommonItemBtn
, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN
,
141 self
.OnAddsharebtnButton
)
143 self
.removeCommonItemBtn
= wxButton(id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
,
144 label
='Remove', name
='removeCommonItemBtn', parent
=self
,
145 pos
=wxPoint(88, 184), size
=wxSize(80, 17), style
=0)
146 self
.removeCommonItemBtn
.SetToolTipString('Remove the selected Common definition')
147 EVT_BUTTON(self
.removeCommonItemBtn
,
148 wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN
,
149 self
.OnRemovesharebtnButton
)
151 self
.styleDefST
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTYLEDEFST
,
152 label
='(nothing selected)', name
='styleDefST', parent
=self
,
153 pos
=wxPoint(96, 8), size
=wxSize(366, 16),
154 style
=wxST_NO_AUTORESIZE
)
155 self
.styleDefST
.SetFont(wxFont(self
.style_font_size
, wxSWISS
, wxNORMAL
,
157 self
.styleDefST
.SetConstraints(LayoutAnchors(self
.styleDefST
, True,
160 self
.staticLine1
= wxStaticLine(id=wxID_STCSTYLEEDITDLGSTATICLINE1
,
161 name
='staticLine1', parent
=self
, pos
=wxPoint(48, 62),
162 size
=wxSize(120, 2), style
=wxLI_HORIZONTAL
)
163 self
.staticLine1
.SetConstraints(LayoutAnchors(self
.staticLine1
, True,
166 self
.staticText6
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT6
,
167 label
='Style', name
='staticText6', parent
=self
, pos
=wxPoint(8,
168 56), size
=wxSize(40, 13), style
=0)
170 self
.staticText8
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT8
,
171 label
='Style def:', name
='staticText8', parent
=self
,
172 pos
=wxPoint(8, 8), size
=wxSize(88, 13), style
=0)
174 self
.staticText9
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT9
,
175 label
='SpeedSetting:', name
='staticText9', parent
=self
,
176 pos
=wxPoint(8, 32), size
=wxSize(88, 13), style
=0)
178 self
.panel3
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL3
, name
='panel3',
179 parent
=self
, pos
=wxPoint(176, 56), size
=wxSize(146, 104),
180 style
=wxTAB_TRAVERSAL
)
181 self
.panel3
.SetConstraints(LayoutAnchors(self
.panel3
, False, True, True,
184 self
.panel4
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL4
, name
='panel4',
185 parent
=self
, pos
=wxPoint(330, 56), size
=wxSize(114, 104),
186 style
=wxTAB_TRAVERSAL
)
187 self
.panel4
.SetConstraints(LayoutAnchors(self
.panel4
, False, True, True,
190 self
.panel1
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL1
, name
='panel1',
191 parent
=self
, pos
=wxPoint(176, 161), size
=wxSize(143, 40),
192 style
=wxTAB_TRAVERSAL
)
193 self
.panel1
.SetConstraints(LayoutAnchors(self
.panel1
, False, True, True,
196 self
.panel2
= wxPanel(id=wxID_STCSTYLEEDITDLGPANEL2
, name
='panel2',
197 parent
=self
, pos
=wxPoint(330, 162), size
=wxSize(112, 40),
198 style
=wxTAB_TRAVERSAL
)
199 self
.panel2
.SetConstraints(LayoutAnchors(self
.panel2
, False, True, True,
202 self
.stc
= wxStyledTextCtrl(id=wxID_STCSTYLEEDITDLGSTC
, name
='stc',
203 parent
=self
, pos
=wxPoint(8, 208), size
=wxSize(435, 207),
204 style
=wxSUNKEN_BORDER
)
205 self
.stc
.SetConstraints(LayoutAnchors(self
.stc
, True, True, True, True))
206 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.')
207 EVT_LEFT_UP(self
.stc
, self
.OnUpdateUI
)
208 EVT_KEY_UP(self
.stc
, self
.OnUpdateUI
)
210 self
.contextHelpButton1
= wxContextHelpButton(parent
=self
,
211 pos
=wxPoint(8, 423), size
=wxSize(24, 24), style
=wxBU_AUTODRAW
)
212 self
.contextHelpButton1
.SetConstraints(LayoutAnchors(self
.contextHelpButton1
,
213 True, False, False, True))
215 self
.okBtn
= wxButton(id=wxID_STCSTYLEEDITDLGOKBTN
, label
='OK',
216 name
='okBtn', parent
=self
, pos
=wxPoint(282, 423), size
=wxSize(75,
218 self
.okBtn
.SetConstraints(LayoutAnchors(self
.okBtn
, False, False, True,
220 self
.okBtn
.SetToolTipString('Save changes to the config file')
221 EVT_BUTTON(self
.okBtn
, wxID_STCSTYLEEDITDLGOKBTN
, self
.OnOkbtnButton
)
223 self
.cancelBtn
= wxButton(id=wxID_STCSTYLEEDITDLGCANCELBTN
,
224 label
='Cancel', name
='cancelBtn', parent
=self
, pos
=wxPoint(366,
225 423), size
=wxSize(75, 23), style
=0)
226 self
.cancelBtn
.SetConstraints(LayoutAnchors(self
.cancelBtn
, False,
228 self
.cancelBtn
.SetToolTipString('Close dialog without saving changes')
229 EVT_BUTTON(self
.cancelBtn
, wxID_STCSTYLEEDITDLGCANCELBTN
,
230 self
.OnCancelbtnButton
)
232 self
.staticText4
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT4
,
233 label
='Face:', name
='staticText4', parent
=self
.panel1
,
234 pos
=wxPoint(0, 0), size
=wxSize(48, 13), style
=0)
236 self
.fixedWidthChk
= wxCheckBox(id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
,
237 label
='', name
='fixedWidthChk', parent
=self
.panel1
, pos
=wxPoint(0,
238 23), size
=wxSize(13, 19), style
=0)
239 self
.fixedWidthChk
.SetToolTipString('Check this for Fixed Width fonts')
240 EVT_CHECKBOX(self
.fixedWidthChk
, wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK
,
241 self
.OnFixedwidthchkCheckbox
)
243 self
.faceCb
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGFACECB
,
244 name
='faceCb', parent
=self
.panel1
, pos
=wxPoint(17, 18),
245 size
=wxSize(105, 21), style
=0, validator
=wxDefaultValidator
,
248 self
.staticText7
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT7
,
249 label
='Size:', name
='staticText7', parent
=self
.panel2
,
250 pos
=wxPoint(0, 0), size
=wxSize(40, 13), style
=0)
252 self
.sizeCb
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGSIZECB
,
253 name
='sizeCb', parent
=self
.panel2
, pos
=wxPoint(0, 17),
254 size
=wxSize(91, 21), style
=0, validator
=wxDefaultValidator
,
257 self
.sizeOkBtn
= wxButton(id=wxID_STCSTYLEEDITDLGSIZEOKBTN
, label
='ok',
258 name
='sizeOkBtn', parent
=self
.panel2
, pos
=wxPoint(90, 17),
259 size
=wxSize(21, 21), style
=0)
261 self
.faceOkBtn
= wxButton(id=wxID_STCSTYLEEDITDLGFACEOKBTN
, label
='ok',
262 name
='faceOkBtn', parent
=self
.panel1
, pos
=wxPoint(122, 18),
263 size
=wxSize(21, 21), style
=0)
265 self
.fgColBtn
= wxButton(id=wxID_STCSTYLEEDITDLGFGCOLBTN
,
266 label
='Foreground', name
='fgColBtn', parent
=self
.panel3
,
267 pos
=wxPoint(8, 16), size
=wxSize(72, 16), style
=0)
268 EVT_BUTTON(self
.fgColBtn
, wxID_STCSTYLEEDITDLGFGCOLBTN
,
269 self
.OnFgcolbtnButton
)
271 self
.fgColCb
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGFGCOLCB
,
272 name
='fgColCb', parent
=self
.panel3
, pos
=wxPoint(8, 32),
273 size
=wxSize(89, 21), style
=0, validator
=wxDefaultValidator
,
276 self
.fgColOkBtn
= wxButton(id=wxID_STCSTYLEEDITDLGFGCOLOKBTN
,
277 label
='ok', name
='fgColOkBtn', parent
=self
.panel3
, pos
=wxPoint(96,
278 32), size
=wxSize(21, 21), style
=0)
280 self
.staticText3
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT3
,
281 label
='default', name
='staticText3', parent
=self
.panel3
,
282 pos
=wxPoint(100, 16), size
=wxSize(37, 16), style
=0)
284 self
.fgColDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGFGCOLDEFCB
,
285 label
='checkBox1', name
='fgColDefCb', parent
=self
.panel3
,
286 pos
=wxPoint(120, 31), size
=wxSize(16, 16), style
=0)
288 self
.bgColBtn
= wxButton(id=wxID_STCSTYLEEDITDLGBGCOLBTN
,
289 label
='Background', name
='bgColBtn', parent
=self
.panel3
,
290 pos
=wxPoint(8, 56), size
=wxSize(72, 16), style
=0)
291 EVT_BUTTON(self
.bgColBtn
, wxID_STCSTYLEEDITDLGBGCOLBTN
,
292 self
.OnBgcolbtnButton
)
294 self
.bgColCb
= wxComboBox(choices
=[], id=wxID_STCSTYLEEDITDLGBGCOLCB
,
295 name
='bgColCb', parent
=self
.panel3
, pos
=wxPoint(8, 72),
296 size
=wxSize(89, 21), style
=0, validator
=wxDefaultValidator
,
299 self
.bgColOkBtn
= wxButton(id=wxID_STCSTYLEEDITDLGBGCOLOKBTN
,
300 label
='ok', name
='bgColOkBtn', parent
=self
.panel3
, pos
=wxPoint(96,
301 72), size
=wxSize(21, 21), style
=0)
303 self
.staticBox2
= wxStaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX2
,
304 label
='Text attributes', name
='staticBox2', parent
=self
.panel4
,
305 pos
=wxPoint(0, 0), size
=wxSize(112, 99), style
=0)
306 self
.staticBox2
.SetConstraints(LayoutAnchors(self
.staticBox2
, False,
308 self
.staticBox2
.SetHelpText('Text attribute flags.')
310 self
.staticText2
= wxStaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT2
,
311 label
='default', name
='staticText2', parent
=self
.panel4
,
312 pos
=wxPoint(68, 11), size
=wxSize(37, 16), style
=0)
314 self
.taBoldDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTABOLDDEFCB
,
315 label
='checkBox1', name
='taBoldDefCb', parent
=self
.panel4
,
316 pos
=wxPoint(88, 27), size
=wxSize(16, 16), style
=0)
318 self
.taItalicDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAITALICDEFCB
,
319 label
='checkBox1', name
='taItalicDefCb', parent
=self
.panel4
,
320 pos
=wxPoint(88, 43), size
=wxSize(16, 16), style
=0)
322 self
.taUnderlinedDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
,
323 label
='checkBox1', name
='taUnderlinedDefCb', parent
=self
.panel4
,
324 pos
=wxPoint(88, 59), size
=wxSize(16, 16), style
=0)
326 self
.taEOLfilledDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
,
327 label
='checkBox1', name
='taEOLfilledDefCb', parent
=self
.panel4
,
328 pos
=wxPoint(88, 75), size
=wxSize(16, 16), style
=0)
330 self
.taEOLfilledCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
,
331 label
='EOL filled', name
='taEOLfilledCb', parent
=self
.panel4
,
332 pos
=wxPoint(8, 75), size
=wxSize(72, 16), style
=0)
333 EVT_CHECKBOX(self
.taEOLfilledCb
, wxID_STCSTYLEEDITDLGTAEOLFILLEDCB
,
334 self
.OnTaeoffilledcbCheckbox
)
336 self
.taUnderlinedCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
,
337 label
='Underlined', name
='taUnderlinedCb', parent
=self
.panel4
,
338 pos
=wxPoint(8, 59), size
=wxSize(72, 16), style
=0)
339 EVT_CHECKBOX(self
.taUnderlinedCb
, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB
,
340 self
.OnTaunderlinedcbCheckbox
)
342 self
.taItalicCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTAITALICCB
,
343 label
='Italic', name
='taItalicCb', parent
=self
.panel4
,
344 pos
=wxPoint(8, 43), size
=wxSize(72, 16), style
=0)
345 EVT_CHECKBOX(self
.taItalicCb
, wxID_STCSTYLEEDITDLGTAITALICCB
,
346 self
.OnTaitaliccbCheckbox
)
348 self
.taBoldCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTABOLDCB
,
349 label
='Bold', name
='taBoldCb', parent
=self
.panel4
, pos
=wxPoint(8,
350 27), size
=wxSize(72, 16), style
=0)
351 EVT_CHECKBOX(self
.taBoldCb
, wxID_STCSTYLEEDITDLGTABOLDCB
,
352 self
.OnTaboldcbCheckbox
)
354 self
.bgColDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGBGCOLDEFCB
,
355 label
='checkBox1', name
='bgColDefCb', parent
=self
.panel3
,
356 pos
=wxPoint(120, 71), size
=wxSize(16, 16), style
=0)
358 self
.staticBox1
= wxStaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX1
,
359 label
='Colour', name
='staticBox1', parent
=self
.panel3
,
360 pos
=wxPoint(0, 0), size
=wxSize(142, 99), style
=0)
361 self
.staticBox1
.SetConstraints(LayoutAnchors(self
.staticBox1
, False,
364 self
.faceDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGFACEDEFCB
,
365 label
='checkBox1', name
='faceDefCb', parent
=self
.panel1
,
366 pos
=wxPoint(120, 0), size
=wxSize(16, 16), style
=0)
368 self
.taSizeDefCb
= wxCheckBox(id=wxID_STCSTYLEEDITDLGTASIZEDEFCB
,
369 label
='checkBox1', name
='taSizeDefCb', parent
=self
.panel2
,
370 pos
=wxPoint(88, 0), size
=wxSize(16, 16), style
=0)
372 def __init__(self
, parent
, langTitle
, lang
, configFile
, STCsToUpdate
=()):
373 self
.stc_title
= 'wxStyledTextCtrl Style Editor'
374 self
.stc_title
= 'wxStyledTextCtrl Style Editor - %s' % langTitle
375 if wxPlatform
== '__WXMSW__':
376 self
.style_font_size
= 8
378 self
.style_font_size
= 10
379 self
._init
_ctrls
(parent
)
381 self
.configFile
= configFile
386 self
.STCsToUpdate
= STCsToUpdate
387 self
._blockUpdate
= False
390 for combo
, okBtn
, evtRet
, evtCB
, evtRDC
in (
391 (self
.fgColCb
, self
.fgColOkBtn
, self
.OnfgColRet
, self
.OnfgColCombobox
, self
.OnGotoCommonDef
),
392 (self
.bgColCb
, self
.bgColOkBtn
, self
.OnbgColRet
, self
.OnbgColCombobox
, self
.OnGotoCommonDef
),
393 (self
.faceCb
, self
.faceOkBtn
, self
.OnfaceRet
, self
.OnfaceCombobox
, self
.OnGotoCommonDef
),
394 (self
.sizeCb
, self
.sizeOkBtn
, self
.OnsizeRet
, self
.OnsizeCombobox
, self
.OnGotoCommonDef
)):
395 self
.bindComboEvts(combo
, okBtn
, evtRet
, evtCB
, evtRDC
)
397 (self
.config
, self
.commonDefs
, self
.styleIdNames
, self
.styles
,
398 self
.styleGroupNames
, self
.predefStyleGroups
,
399 self
.otherLangStyleGroupNames
, self
.otherLangStyleGroups
,
400 self
.displaySrc
, self
.lexer
, self
.keywords
, self
.braceInfo
) = \
401 initFromConfig(configFile
, lang
)
403 self
.currSpeedSetting
= 'style.%s'%self
.lang
404 for grp
in [self
.currSpeedSetting
]+self
.styleGroupNames
:
405 self
.speedsettingCh
.Append(grp
)
406 self
.speedsettingCh
.SetSelection(0)
409 self
.stc
.SetMarginType(margin
, wxSTC_MARGIN_NUMBER
)
410 self
.stc
.SetMarginWidth(margin
, 25)
411 self
.stc
.SetMarginSensitive(margin
, True)
412 EVT_STC_MARGINCLICK(self
.stc
, wxID_STCSTYLEEDITDLGSTC
, self
.OnMarginClick
)
414 self
.stc
.SetUseTabs(False)
415 self
.stc
.SetTabWidth(4)
416 self
.stc
.SetIndentationGuides(True)
417 self
.stc
.SetEdgeMode(wxSTC_EDGE_BACKGROUND
)
418 self
.stc
.SetEdgeColumn(44)
422 self
.populateStyleSelector()
424 self
.defNames
, self
.defValues
= parseProp(\
425 self
.styleDict
.get(wxSTC_STYLE_DEFAULT
, ''))
426 self
.stc
.SetText(self
.displaySrc
)
427 self
.stc
.EmptyUndoBuffer()
428 self
.stc
.SetCurrentPos(self
.stc
.GetTextLength())
429 self
.stc
.SetAnchor(self
.stc
.GetTextLength())
431 self
.populateCombosWithCommonDefs()
433 # Logical grouping of controls and the property they edit
434 self
.allCtrls
= [((self
.fgColBtn
, self
.fgColCb
, self
.fgColOkBtn
), self
.fgColDefCb
,
435 'fore', wxID_STCSTYLEEDITDLGFGCOLDEFCB
),
436 ((self
.bgColBtn
, self
.bgColCb
, self
.bgColOkBtn
), self
.bgColDefCb
,
437 'back', wxID_STCSTYLEEDITDLGBGCOLDEFCB
),
438 (self
.taBoldCb
, self
.taBoldDefCb
,
439 'bold', wxID_STCSTYLEEDITDLGTABOLDDEFCB
),
440 (self
.taItalicCb
, self
.taItalicDefCb
,
441 'italic', wxID_STCSTYLEEDITDLGTAITALICDEFCB
),
442 (self
.taUnderlinedCb
, self
.taUnderlinedDefCb
,
443 'underline', wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB
),
444 (self
.taEOLfilledCb
, self
.taEOLfilledDefCb
,
445 'eolfilled', wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB
),
446 ((self
.sizeCb
, self
.sizeOkBtn
), self
.taSizeDefCb
,
447 'size', wxID_STCSTYLEEDITDLGTASIZEDEFCB
),
448 ((self
.faceCb
, self
.faceOkBtn
, self
.fixedWidthChk
), self
.faceDefCb
,
449 'face', wxID_STCSTYLEEDITDLGFACEDEFCB
)]
451 self
.clearCtrls(disableDefs
=True)
452 # centralised default checkbox event handler
454 for ctrl
, chb
, prop
, wid
in self
.allCtrls
:
455 self
.chbIdMap
[wid
] = ctrl
, chb
, prop
, wid
456 EVT_CHECKBOX(chb
, wid
, self
.OnDefaultCheckBox
)
457 chb
.SetToolTipString('Toggle defaults')
461 #---Property methods------------------------------------------------------------
462 def getCtrlForProp(self
, findprop
):
463 for ctrl
, chb
, prop
, wid
in self
.allCtrls
:
466 raise Exception('PropNotFound', findprop
)
468 def editProp(self
, on
, prop
, val
=''):
469 oldstyle
= self
.rememberStyles()
471 if not self
.names
.count(prop
):
472 self
.names
.append(prop
)
473 self
.values
[prop
] = val
475 try: self
.names
.remove(prop
)
476 except ValueError: pass
477 try: del self
.values
[prop
]
478 except KeyError: pass
483 except KeyError, errkey
:
484 wxLogError('Name not found in Common definition, '\
485 'please enter valid reference. (%s)'%errkey
)
486 self
.restoreStyles(oldstyle
)
489 #---Control population methods--------------------------------------------------
491 if self
._blockUpdate
: return
492 self
.styles
, self
.styleDict
, self
.styleNumIdxMap
= \
493 setSTCStyles(self
.stc
, self
.styles
, self
.styleIdNames
,
494 self
.commonDefs
, self
.lang
, self
.lexer
, self
.keywords
)
496 def updateStyle(self
):
497 # called after a control edited self.names, self.values
498 # Special case for saving common defs settings
499 if self
.styleNum
== 'common':
500 strVal
= self
.style
[2] = self
.values
.values()[0]
501 if self
.style
[1] == 'size': self
.style
[2] = int(strVal
)
503 self
.commonDefs
[self
.style
[0]] = self
.style
[2]
504 self
.styleDefST
.SetLabel(strVal
)
506 self
.style
= writePropVal(self
.names
, self
.values
)
507 styleDecl
= writeProp(self
.styleNum
, self
.style
, self
.lang
)
508 self
.styles
[self
.styleNumIdxMap
[self
.styleNum
]] = styleDecl
509 self
.styleDefST
.SetLabel(self
.style
)
512 def findInStyles(self
, txt
, styles
):
514 if string
.find(style
, txt
) != -1:
518 def rememberStyles(self
):
519 return self
.names
[:], copy
.copy(self
.values
)
521 def restoreStyles(self
, style
):
522 self
.names
, self
.values
= style
525 def clearCtrls(self
, isDefault
=False, disableDefs
=False):
526 self
._blockUpdate
= True
528 for ctrl
, chb
, prop
, wid
in self
.allCtrls
:
529 if prop
in ('fore', 'back'):
530 cbtn
, txt
, btn
= ctrl
531 cbtn
.SetBackgroundColour(\
532 wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
))
533 cbtn
.SetForegroundColour(wxColour(255, 255, 255))
534 cbtn
.Enable(isDefault
)
536 txt
.Enable(isDefault
)
537 btn
.Enable(isDefault
)
541 cmb
.Enable(isDefault
)
542 btn
.Enable(isDefault
)
546 cmb
.Enable(isDefault
)
547 btn
.Enable(isDefault
)
548 chk
.Enable(isDefault
)
550 elif prop
in ('bold', 'italic', 'underline', 'eolfilled'):
552 ctrl
.Enable(isDefault
)
554 chb
.Enable(not isDefault
and not disableDefs
)
557 self
._blockUpdate
= False
559 def populateProp(self
, items
, default
, forceDisable
=False):
560 self
._blockUpdate
= True
562 for name
, val
in items
:
564 ctrl
, chb
= self
.getCtrlForProp(name
)
566 if name
in ('fore', 'back'):
567 cbtn
, txt
, btn
= ctrl
568 repval
= val
%self
.commonDefs
569 cbtn
.SetBackgroundColour(strToCol(repval
))
570 cbtn
.SetForegroundColour(wxColour(0, 0, 0))
571 cbtn
.Enable(not forceDisable
)
573 txt
.Enable(not forceDisable
)
574 btn
.Enable(not forceDisable
)
575 chb
.SetValue(default
)
579 cmb
.Enable(not forceDisable
)
580 btn
.Enable(not forceDisable
)
581 chb
.SetValue(default
)
585 cmb
.Enable(not forceDisable
)
586 btn
.Enable(not forceDisable
)
587 chk
.Enable(not forceDisable
)
588 chb
.SetValue(default
)
589 elif name
in ('bold', 'italic', 'underline', 'eolfilled'):
590 ctrl
.Enable(not forceDisable
)
592 chb
.SetValue(default
)
594 self
._blockUpdate
= False
596 def valIsCommonDef(self
, val
):
597 return len(val
) >= 5 and val
[:2] == '%('
599 def populateCtrls(self
):
600 self
.clearCtrls(self
.styleNum
== wxSTC_STYLE_DEFAULT
,
601 disableDefs
=self
.styleNum
< 0)
603 # handle colour controls for settings
604 if self
.styleNum
< 0:
605 self
.fgColDefCb
.Enable(True)
606 if self
.styleNum
== -1:
607 self
.bgColDefCb
.Enable(True)
609 # populate with default style
610 self
.populateProp(self
.defValues
.items(), True,
611 self
.styleNum
!= wxSTC_STYLE_DEFAULT
)
612 # override with current settings
613 self
.populateProp(self
.values
.items(), False)
615 def getCommonDefPropType(self
, commonDefName
):
616 val
= self
.commonDefs
[commonDefName
]
617 if type(val
) == type(0): return 'size'
618 if len(val
) == 7 and val
[0] == '#': return 'fore'
621 def bindComboEvts(self
, combo
, btn
, btnEvtMeth
, comboEvtMeth
, rdclickEvtMeth
):
622 EVT_COMBOBOX(combo
, combo
.GetId(), comboEvtMeth
)
623 EVT_BUTTON(btn
, btn
.GetId(), btnEvtMeth
)
624 EVT_RIGHT_DCLICK(combo
, rdclickEvtMeth
)
625 combo
.SetToolTipString('Select from list or click "ok" button on the right to change a manual entry, right double-click \n'\
626 'the drop down button to select Common definition in the Style Editor (if applicable)')
627 btn
.SetToolTipString('Accept value')
629 def populateCombosWithCommonDefs(self
, fixedWidthOnly
=None):
630 self
._blockUpdate
= True
632 commonDefs
= {'fore': [], 'face': [], 'size': []}
634 if self
.elementLb
.GetSelection() < self
.commonDefsStartIdx
:
635 for common
in self
.commonDefs
.keys():
636 prop
= self
.getCommonDefPropType(common
)
637 commonDefs
[prop
].append('%%(%s)%s'%(common
,
638 prop
=='size' and 'd' or 's'))
641 currFg
, currBg
= self
.fgColCb
.GetValue(), self
.bgColCb
.GetValue()
642 self
.fgColCb
.Clear(); self
.bgColCb
.Clear()
643 for colCommonDef
in commonDefs
['fore']:
644 self
.fgColCb
.Append(colCommonDef
)
645 self
.bgColCb
.Append(colCommonDef
)
646 self
.fgColCb
.SetValue(currFg
); self
.bgColCb
.SetValue(currBg
)
649 if fixedWidthOnly
is None:
650 fixedWidthOnly
= self
.fixedWidthChk
.GetValue()
651 fontEnum
= wxFontEnumerator()
652 fontEnum
.EnumerateFacenames(fixedWidthOnly
=fixedWidthOnly
)
653 fontNameList
= fontEnum
.GetFacenames()
655 currFace
= self
.faceCb
.GetValue()
657 for colCommonDef
in ['']+fontNameList
+commonDefs
['face']:
658 self
.faceCb
.Append(colCommonDef
)
659 self
.faceCb
.SetValue(currFace
)
661 # Size (XXX add std font sizes)
662 currSize
= self
.sizeCb
.GetValue()
664 for colCommonDef
in commonDefs
['size']:
665 self
.sizeCb
.Append(colCommonDef
)
666 self
.sizeCb
.SetValue(currSize
)
668 self
._blockUpdate
= False
670 def populateStyleSelector(self
):
671 numStyles
= self
.styleIdNames
.items()
673 self
.styleNumLookup
= {}
678 for num
, name
in numStyles
:
679 if num
== wxSTC_STYLE_DEFAULT
:
680 self
.elementLb
.InsertItems([name
, '----Language----'], 0)
681 self
.elementLb
.Append('----Standard----')
682 stdStart
= stdPos
= self
.elementLb
.Number()
685 if num
>= 33 and num
< 40:
686 self
.elementLb
.InsertItems([name
], stdStart
+ stdOffset
)
687 stdOffset
= stdOffset
+ 1
690 self
.elementLb
.InsertItems([name
], stdStart
+ extrOffset
-1)
691 extrOffset
= extrOffset
+ 1
694 self
.elementLb
.Append(name
)
695 self
.styleNumLookup
[name
] = num
698 self
.elementLb
.Append('----Settings----')
699 settings
= settingsIdNames
.items()
700 settings
.sort();settings
.reverse()
701 for num
, name
in settings
:
702 self
.elementLb
.Append(name
)
703 self
.styleNumLookup
[name
] = num
706 self
.elementLb
.Append('----Common----')
707 self
.commonDefsStartIdx
= self
.elementLb
.Number()
708 for common
in self
.commonDefs
.keys():
709 tpe
= type(self
.commonDefs
[common
])
710 self
.elementLb
.Append('%('+common
+')'+(tpe
is type('') and 's' or 'd'))
711 self
.styleNumLookup
[common
] = num
713 #---Colour methods--------------------------------------------------------------
714 def getColourDlg(self
, colour
, title
=''):
715 data
= wxColourData()
716 data
.SetColour(colour
)
717 data
.SetChooseFull(True)
718 dlg
= wxColourDialog(self
, data
)
721 if dlg
.ShowModal() == wxID_OK
:
722 data
= dlg
.GetColourData()
723 return data
.GetColour()
728 colDlgTitles
= {'fore': 'Foreground', 'back': 'Background'}
729 def editColProp(self
, colBtn
, colCb
, prop
):
730 col
= self
.getColourDlg(colBtn
.GetBackgroundColour(),
731 self
.colDlgTitles
[prop
]+ ' colour')
733 colBtn
.SetForegroundColour(wxColour(0, 0, 0))
734 colBtn
.SetBackgroundColour(col
)
735 colStr
= colToStr(col
)
736 colCb
.SetValue(colStr
)
737 self
.editProp(True, prop
, colStr
)
739 def OnFgcolbtnButton(self
, event
):
740 self
.editColProp(self
.fgColBtn
, self
.fgColCb
, 'fore')
742 def OnBgcolbtnButton(self
, event
):
743 self
.editColProp(self
.bgColBtn
, self
.bgColCb
, 'back')
745 def editColTCProp(self
, colCb
, colBtn
, prop
, val
=None):
747 colStr
= colCb
.GetValue()
751 col
= strToCol(colStr
%self
.commonDefs
)
752 if self
.editProp(colStr
!='', prop
, colStr
):
754 colBtn
.SetForegroundColour(wxColour(0, 0, 0))
755 colBtn
.SetBackgroundColour(col
)
757 colBtn
.SetForegroundColour(wxColour(255, 255, 255))
758 colBtn
.SetBackgroundColour(\
759 wxSystemSettings_GetSystemColour(wxSYS_COLOUR_BTNFACE
))
761 def OnfgColRet(self
, event
):
762 try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore')
763 except AssertionError: wxLogError('Not a valid colour value')
765 def OnfgColCombobox(self
, event
):
766 if self
._blockUpdate
: return
767 try: self
.editColTCProp(self
.fgColCb
, self
.fgColBtn
, 'fore', event
.GetString())
768 except AssertionError: wxLogError('Not a valid colour value')
770 def OnbgColRet(self
, event
):
771 try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back')
772 except AssertionError: wxLogError('Not a valid colour value')
774 def OnbgColCombobox(self
, event
):
775 if self
._blockUpdate
: return
776 try: self
.editColTCProp(self
.bgColCb
, self
.bgColBtn
, 'back', event
.GetString())
777 except AssertionError: wxLogError('Not a valid colour value')
779 #---Text attribute events-------------------------------------------------------
780 def OnTaeoffilledcbCheckbox(self
, event
):
781 self
.editProp(event
.IsChecked(), 'eolfilled')
783 def OnTaitaliccbCheckbox(self
, event
):
784 self
.editProp(event
.IsChecked(), 'italic')
786 def OnTaboldcbCheckbox(self
, event
):
787 self
.editProp(event
.IsChecked(), 'bold')
789 def OnTaunderlinedcbCheckbox(self
, event
):
790 self
.editProp(event
.IsChecked(), 'underline')
792 def OnGotoCommonDef(self
, event
):
793 val
= event
.GetEventObject().GetValue()
794 if self
.valIsCommonDef(val
):
795 idx
= self
.elementLb
.FindString(val
)
797 self
.elementLb
.SetSelection(idx
, True)
798 self
.OnElementlbListbox(None)
800 def OnfaceRet(self
, event
):
801 self
.setFace(self
.faceCb
.GetValue())
803 def OnfaceCombobox(self
, event
):
804 if self
._blockUpdate
: return
805 self
.setFace(event
.GetString())
807 def setFace(self
, val
):
808 try: val
%self
.commonDefs
809 except KeyError: wxLogError('Invalid common definition')
810 else: self
.editProp(val
!='', 'face', val
)
812 def OnsizeRet(self
, event
):
813 self
.setSize(self
.sizeCb
.GetValue())
815 def OnsizeCombobox(self
, event
):
816 if self
._blockUpdate
: return
817 self
.setSize(event
.GetString())
819 def setSize(self
, val
):
820 try: int(val
%self
.commonDefs
)
821 except ValueError: wxLogError('Not a valid integer size value')
822 except KeyError: wxLogError('Invalid common definition')
823 else: self
.editProp(val
!='', 'size', val
)
825 #---Main GUI events-------------------------------------------------------------
826 def OnElementlbListbox(self
, event
):
827 isCommon
= self
.elementLb
.GetSelection() >= self
.commonDefsStartIdx
828 self
.removeCommonItemBtn
.Enable(isCommon
)
830 styleIdent
= self
.elementLb
.GetStringSelection()
831 # common definition selected
833 common
= styleIdent
[2:-2]
834 prop
= self
.getCommonDefPropType(common
)
835 self
.clearCtrls(disableDefs
=True)
837 self
.fgColBtn
.Enable(True)
838 self
.fgColCb
.Enable(True)
839 self
.fgColOkBtn
.Enable(True)
841 self
.faceCb
.Enable(True)
842 self
.fixedWidthChk
.Enable(True)
843 self
.faceOkBtn
.Enable(True)
845 self
.sizeCb
.Enable(True)
846 self
.sizeOkBtn
.Enable(True)
848 commonDefVal
= str(self
.commonDefs
[common
])
849 self
.styleDefST
.SetLabel(commonDefVal
)
850 self
.populateProp( [(prop
, commonDefVal
)], True)
852 self
.styleNum
= 'common'
853 self
.style
= [common
, prop
, commonDefVal
]
854 self
.names
, self
.values
= [prop
], {prop: commonDefVal}
856 # normal style element selected
857 elif len(styleIdent
) >=2 and styleIdent
[:2] != '--':
858 self
.styleNum
= self
.styleNumLookup
[styleIdent
]
859 self
.style
= self
.styleDict
[self
.styleNum
]
860 self
.names
, self
.values
= parseProp(self
.style
)
861 if self
.styleNum
== wxSTC_STYLE_DEFAULT
:
862 self
.defNames
, self
.defValues
= \
863 self
.names
, self
.values
865 self
.checkBraces(self
.styleNum
)
867 self
.styleDefST
.SetLabel(self
.style
)
872 self
.clearCtrls(disableDefs
=True)
874 self
.styleDefST
.SetLabel(styleCategoryDescriptions
[styleIdent
])
876 self
.populateCombosWithCommonDefs()
878 def OnDefaultCheckBox(self
, event
):
879 if self
.chbIdMap
.has_key(event
.GetId()):
880 ctrl
, chb
, prop
, wid
= self
.chbIdMap
[event
.GetId()]
881 restore
= not event
.IsChecked()
882 if prop
in ('fore', 'back'):
883 cbtn
, cmb
, btn
= ctrl
888 colStr
= cmb
.GetValue()
889 #if prop == 'fore': colStr = self.fgColCb.GetValue()
890 #else: colStr = self.bgColCb.GetValue()
891 if colStr
: self
.editProp(True, prop
, colStr
)
893 self
.editProp(False, prop
)
897 if val
: self
.editProp(restore
, prop
, val
)
902 val
= cmb
.GetStringSelection()
903 if val
: self
.editProp(restore
, prop
, val
)
907 elif prop
in ('bold', 'italic', 'underline', 'eolfilled'):
909 if ctrl
.GetValue(): self
.editProp(restore
, prop
)
911 def OnOkbtnButton(self
, event
):
912 # write styles and common defs to the config
915 writeStylesToConfig(self
.config
, 'style.%s'%self
.lang
, self
.styles
)
916 self
.config
.SetPath('')
917 self
.config
.Write(commonDefsFile
, `self
.commonDefs`
)
920 for stc
in self
.STCsToUpdate
:
921 setSTCStyles(stc
, self
.styles
, self
.styleIdNames
, self
.commonDefs
,
922 self
.lang
, self
.lexer
, self
.keywords
)
925 self
.EndModal(wxID_OK
)
927 def OnCancelbtnButton(self
, event
):
928 self
.EndModal(wxID_CANCEL
)
930 def OnCommondefsbtnButton(self
, event
):
931 dlg
= wxTextEntryDialog(self
, 'Edit common definitions dictionary',
932 'Common definitions', pprint
.pformat(self
.commonDefs
),
933 style
=wxTE_MULTILINE | wxOK | wxCANCEL | wxCENTRE
)
935 if dlg
.ShowModal() == wxID_OK
:
936 answer
= eval(dlg
.GetValue())
937 assert type(answer
) is type({}), 'Not a valid dictionary'
938 oldDefs
= self
.commonDefs
939 self
.commonDefs
= answer
942 except KeyError, badkey
:
943 wxLogError(str(badkey
)+' not defined but required, \n'\
944 'reverting to previous common definition')
945 self
.commonDefs
= oldDefs
947 self
.populateCombosWithCommonDefs()
952 def OnSpeedsettingchChoice(self
, event
):
953 group
= event
.GetString()
955 userStyles
= 'style.%s'%self
.lang
956 if self
.currSpeedSetting
== userStyles
:
957 self
.predefStyleGroups
[userStyles
] = self
.styles
958 self
.styles
= self
.predefStyleGroups
[group
]
960 self
.defNames
, self
.defValues
= parseProp(\
961 self
.styleDict
.get(wxSTC_STYLE_DEFAULT
, ''))
962 self
.OnElementlbListbox(None)
963 self
.currSpeedSetting
= group
965 def OnFixedwidthchkCheckbox(self
, event
):
966 self
.populateCombosWithCommonDefs(event
.Checked())
968 def OnAddsharebtnButton(self
, event
):
969 dlg
= CommonDefDlg(self
)
971 if dlg
.ShowModal() == wxID_OK
:
972 prop
, name
= dlg
.result
973 if not self
.commonDefs
.has_key(name
):
974 self
.commonDefs
[name
] = commonPropDefs
[prop
]
975 self
.elementLb
.Append('%('+name
+')'+\
976 (type(commonPropDefs
[prop
]) is type('') and 's' or 'd'))
977 self
.elementLb
.SetSelection(self
.elementLb
.Number()-1, True)
978 self
.populateCombosWithCommonDefs()
979 self
.OnElementlbListbox(None)
983 def OnRemovesharebtnButton(self
, event
):
984 ownGroup
= 'style.%s'%self
.lang
985 comDef
= self
.elementLb
.GetStringSelection()
987 # Search ALL styles before removing
988 srchDct
= {ownGroup: self.styles}
989 srchDct
.update(self
.predefStyleGroups
)
990 srchDct
.update(self
.otherLangStyleGroups
)
993 for grpName
, styles
in srchDct
.items():
994 if self
.findInStyles(comDef
, styles
):
995 matchList
.append(grpName
)
998 wxLogError('Aborted: '+comDef
+' is still used in the styles of the \n'\
999 'following groups in the config file (stc-styles.rc.cfg):\n'+ \
1000 string
.join(matchList
, '\n'))
1002 del self
.commonDefs
[comDef
[2:-2]]
1004 self
.populateCombosWithCommonDefs()
1005 selIdx
= self
.elementLb
.GetSelection()
1006 self
.elementLb
.Delete(selIdx
)
1007 if selIdx
== self
.elementLb
.Number():
1009 self
.elementLb
.SetSelection(selIdx
, True)
1010 self
.OnElementlbListbox(None)
1012 #---STC events------------------------------------------------------------------
1013 def OnUpdateUI(self
, event
):
1014 styleBefore
= self
.stc
.GetStyleAt(self
.stc
.GetCurrentPos())
1015 if self
.styleIdNames
.has_key(styleBefore
):
1016 self
.elementLb
.SetStringSelection(self
.styleIdNames
[styleBefore
],
1019 self
.elementLb
.SetSelection(0, False)
1020 self
.styleDefST
.SetLabel('Style %d not defined, sorry.'%styleBefore
)
1021 self
.OnElementlbListbox(None)
1024 def checkBraces(self
, style
):
1025 if style
== wxSTC_STYLE_BRACELIGHT
and self
.braceInfo
.has_key('good'):
1026 line
, col
= self
.braceInfo
['good']
1027 pos
= self
.stc
.PositionFromLine(line
-1) + col
1028 braceOpposite
= self
.stc
.BraceMatch(pos
)
1029 if braceOpposite
!= -1:
1030 self
.stc
.BraceHighlight(pos
, braceOpposite
)
1031 elif style
== wxSTC_STYLE_BRACEBAD
and self
.braceInfo
.has_key('bad'):
1032 line
, col
= self
.braceInfo
['bad']
1033 pos
= self
.stc
.PositionFromLine(line
-1) + col
1034 self
.stc
.BraceBadLight(pos
)
1036 self
.stc
.BraceBadLight(-1)
1039 def OnStcstyleeditdlgSize(self
, event
):
1041 # Without this refresh, resizing leaves artifacts
1045 def OnMarginClick(self
, event
):
1046 self
.elementLb
.SetStringSelection('Line numbers', True)
1047 self
.OnElementlbListbox(None)
1050 #---Common definition dialog----------------------------------------------------
1052 [wxID_COMMONDEFDLG
, wxID_COMMONDEFDLGCANCELBTN
, wxID_COMMONDEFDLGCOMDEFNAMETC
, wxID_COMMONDEFDLGOKBTN
, wxID_COMMONDEFDLGPROPTYPERBX
, wxID_COMMONDEFDLGSTATICBOX1
] = map(lambda _init_ctrls
: wxNewId(), range(6))
1054 class CommonDefDlg(wxDialog
):
1055 def _init_ctrls(self
, prnt
):
1056 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')
1057 self
.SetClientSize(wxSize(184, 200))
1059 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
)
1060 self
.propTypeRBx
.SetSelection(self
._propTypeIdx
)
1062 self
.staticBox1
= wxStaticBox(id = wxID_COMMONDEFDLGSTATICBOX1
, label
= 'Name', name
= 'staticBox1', parent
= self
, pos
= wxPoint(8, 108), size
= wxSize(168, 46), style
= 0)
1064 self
.comDefNameTC
= wxTextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC
, name
= 'comDefNameTC', parent
= self
, pos
= wxPoint(16, 124), size
= wxSize(152, 21), style
= 0, value
= '')
1065 self
.comDefNameTC
.SetLabel(self
._comDefName
)
1067 self
.okBtn
= wxButton(id = wxID_COMMONDEFDLGOKBTN
, label
= 'OK', name
= 'okBtn', parent
= self
, pos
= wxPoint(8, 164), size
= wxSize(80, 23), style
= 0)
1068 EVT_BUTTON(self
.okBtn
, wxID_COMMONDEFDLGOKBTN
, self
.OnOkbtnButton
)
1070 self
.cancelBtn
= wxButton(id = wxID_COMMONDEFDLGCANCELBTN
, label
= 'Cancel', name
= 'cancelBtn', parent
= self
, pos
= wxPoint(96, 164), size
= wxSize(80, 23), style
= 0)
1071 EVT_BUTTON(self
.cancelBtn
, wxID_COMMONDEFDLGCANCELBTN
, self
.OnCancelbtnButton
)
1073 def __init__(self
, parent
, name
='', propIdx
=0):
1074 self
._comDefName
= ''
1075 self
._comDefName
= name
1076 self
._propTypeIdx
= 0
1077 self
._propTypeIdx
= propIdx
1078 self
._init
_ctrls
(parent
)
1080 self
.propMap
= {0: 'fore', 1: 'face', 2: 'size'}
1081 self
.result
= ( '', '' )
1085 def OnOkbtnButton(self
, event
):
1086 self
.result
= ( self
.propMap
[self
.propTypeRBx
.GetSelection()],
1087 self
.comDefNameTC
.GetValue() )
1088 self
.EndModal(wxID_OK
)
1090 def OnCancelbtnButton(self
, event
):
1091 self
.result
= ( '', '' )
1092 self
.EndModal(wxID_CANCEL
)
1094 #---Functions useful outside of the editor----------------------------------
1096 def setSelectionColour(stc
, style
):
1097 names
, values
= parseProp(style
)
1099 stc
.SetSelForeground(True, strToCol(values
['fore']))
1101 stc
.SetSelBackground(True, strToCol(values
['back']))
1103 def setCursorColour(stc
, style
):
1104 names
, values
= parseProp(style
)
1106 stc
.SetCaretForeground(strToCol(values
['fore']))
1108 def setEdgeColour(stc
, style
):
1109 names
, values
= parseProp(style
)
1111 stc
.SetEdgeColour(strToCol(values
['fore']))
1113 def strToCol(strCol
):
1114 assert len(strCol
) == 7 and strCol
[0] == '#', 'Not a valid colour string'
1115 return wxColour(string
.atoi('0x'+strCol
[1:3], 16),
1116 string
.atoi('0x'+strCol
[3:5], 16),
1117 string
.atoi('0x'+strCol
[5:7], 16))
1119 return '#%s%s%s' % (string
.zfill(string
.upper(hex(col
.Red())[2:]), 2),
1120 string
.zfill(string
.upper(hex(col
.Green())[2:]), 2),
1121 string
.zfill(string
.upper(hex(col
.Blue())[2:]), 2))
1123 def writeProp(num
, style
, lang
):
1125 return 'style.%s.%s='%(lang
, string
.zfill(`num`
, 3)) + style
1127 return 'setting.%s.%d='%(lang
, num
) + style
1129 def writePropVal(names
, values
):
1133 res
.append(values
[name
] and name
+':'+values
[name
] or name
)
1134 return string
.join(res
, ',')
1136 def parseProp(prop
):
1137 items
= string
.split(prop
, ',')
1141 nameVal
= string
.split(item
, ':')
1142 names
.append(string
.strip(nameVal
[0]))
1143 if len(nameVal
) == 1:
1144 values
[nameVal
[0]] = ''
1146 values
[nameVal
[0]] = string
.strip(nameVal
[1])
1147 return names
, values
1149 def parsePropLine(prop
):
1150 name
, value
= string
.split(prop
, '=')
1151 return int(string
.split(name
, '.')[-1]), value
1153 def setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
):
1154 #wxLogMessage('Set style')
1158 # build style dict based on given styles
1159 for numStyle
in styles
:
1160 num
, style
= parsePropLine(numStyle
)
1161 styleDict
[num
] = style
1163 # Add blank style entries for undefined styles
1165 styleItems
= styleIdNames
.items() + settingsIdNames
.items()
1168 for num
, name
in styleItems
:
1169 styleNumIdxMap
[num
] = idx
1170 if not styleDict
.has_key(num
):
1172 newStyles
.append(writeProp(num
, styleDict
[num
], lang
))
1175 # Set background colour to reduce flashing effect on refresh or page switch
1177 if styleDict
.has_key(0): prop
= styleDict
[0]
1178 else: prop
= styleDict
[wxSTC_STYLE_DEFAULT
]
1179 names
, vals
= parseProp(prop
)
1181 bkCol
= strToCol(vals
['back'])
1184 stc
.SetBackgroundColour(bkCol
)
1186 # Set the styles on the wxSTC
1188 stc
.StyleResetDefault()
1189 stc
.ClearDocumentStyle()
1191 stc
.SetKeyWords(0, keywords
)
1192 stc
.StyleSetSpec(wxSTC_STYLE_DEFAULT
,
1193 styleDict
[wxSTC_STYLE_DEFAULT
] % commonDefs
)
1196 for num
, style
in styleDict
.items():
1198 stc
.StyleSetSpec(num
, style
% commonDefs
)
1200 setSelectionColour(stc
, style
% commonDefs
)
1202 setCursorColour(stc
, style
% commonDefs
)
1204 setEdgeColour(stc
, style
% commonDefs
)
1206 stc
.Colourise(0, stc
.GetTextLength())
1209 return newStyles
, styleDict
, styleNumIdxMap
1211 #---Config reading and writing -------------------------------------------------
1212 commonDefsFile
= 'common.defs.%s'%(wxPlatform
== '__WXMSW__' and 'msw' or 'gtk')
1214 def readPyValFromConfig(conf
, name
):
1215 return eval(string
.replace(conf
.Read(name
), '\r\n', '\n')+'\n')
1217 def initFromConfig(configFile
, lang
):
1218 cfg
= wxFileConfig(localFilename
=configFile
, style
=wxCONFIG_USE_LOCAL_FILE
)
1219 cfg
.SetExpandEnvVars(False)
1221 # read in all group names for this language
1222 groupPrefix
= 'style.%s'%lang
1223 gpLen
= len(groupPrefix
)
1224 predefStyleGroupNames
, otherLangStyleGroupNames
= [], []
1225 cont
, val
, idx
= cfg
.GetFirstGroup()
1227 if val
!= groupPrefix
and len(val
) >= 5 and val
[:5] == 'style':
1228 if len(val
) > gpLen
and val
[:gpLen
] == groupPrefix
:
1229 predefStyleGroupNames
.append(val
)
1231 otherLangStyleGroupNames
.append(val
)
1233 cont
, val
, idx
= cfg
.GetNextGroup(idx
)
1235 # read in common elements
1236 commonDefs
= readPyValFromConfig(cfg
, commonDefsFile
)
1237 assert type(commonDefs
) is type({}), \
1238 'Common definitions (%s) not a valid dict'%commonDefsFile
1240 commonStyleIdNames
= readPyValFromConfig(cfg
, 'common.styleidnames')
1241 assert type(commonStyleIdNames
) is type({}), \
1242 'Common definitions (%s) not a valid dict'%'common.styleidnames'
1244 # Lang spesific settings
1246 styleIdNames
= readPyValFromConfig(cfg
, 'styleidnames')
1247 assert type(commonStyleIdNames
) is type({}), \
1248 'Not a valid dict [%s] styleidnames)'%lang
1249 styleIdNames
.update(commonStyleIdNames
)
1250 braceInfo
= readPyValFromConfig(cfg
, 'braces')
1251 assert type(commonStyleIdNames
) is type({}), \
1252 'Not a valid dict [%s] braces)'%lang
1254 displaySrc
= cfg
.Read('displaysrc')
1255 lexer
= readPyValFromConfig(cfg
, 'lexer')
1256 keywords
= cfg
.Read('keywords')
1260 # read in current styles
1261 styles
= readStylesFromConfig(cfg
, groupPrefix
)
1263 # read in predefined styles
1264 predefStyleGroups
= {}
1265 for group
in predefStyleGroupNames
:
1266 predefStyleGroups
[group
] = readStylesFromConfig(cfg
, group
)
1268 # read in all other style sections
1269 otherLangStyleGroups
= {}
1270 for group
in otherLangStyleGroupNames
:
1271 otherLangStyleGroups
[group
] = readStylesFromConfig(cfg
, group
)
1273 return (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
,
1274 predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
,
1275 displaySrc
, lexer
, keywords
, braceInfo
)
1277 def readStylesFromConfig(config
, group
):
1279 config
.SetPath(group
)
1281 cont
, val
, idx
= config
.GetFirstEntry()
1283 styles
.append(val
+'='+config
.Read(val
))
1284 cont
, val
, idx
= config
.GetNextEntry(idx
)
1289 def writeStylesToConfig(config
, group
, styles
):
1291 config
.DeleteGroup(group
)
1292 config
.SetPath(group
)
1294 for style
in styles
:
1295 name
, value
= string
.split(style
, '=')
1296 config
.Write(name
, string
.strip(value
))
1300 #-------------------------------------------------------------------------------
1301 def initSTC(stc
, config
, lang
):
1302 """ Main module entry point. Initialise a wxSTC from given config file."""
1303 (cfg
, commonDefs
, styleIdNames
, styles
, predefStyleGroupNames
,
1304 predefStyleGroups
, otherLangStyleGroupNames
, otherLangStyleGroups
,
1305 displaySrc
, lexer
, keywords
, braceInfo
) = initFromConfig(config
, lang
)
1307 setSTCStyles(stc
, styles
, styleIdNames
, commonDefs
, lang
, lexer
, keywords
)
1309 #-------------------------------------------------------------------------------
1310 if __name__
== '__main__':
1311 from wxPython
.help import *
1313 app
= wxPySimpleApp()
1315 provider
= wxSimpleHelpProvider()
1316 wxHelpProvider_Set(provider
)
1318 home
= os
.environ
.get('HOME')
1319 if home
: home
= os
.path
.join(home
, '.boa')
1320 config
= os
.path
.abspath(os
.path
.join(home
, 'stc-styles.rc.cfg'))
1322 f
= wxFrame(None, -1, 'Test frame (double click for editor)')
1323 stc
= wxStyledTextCtrl(f
, -1)
1324 def OnDblClick(evt
, stc
=stc
):
1325 dlg
= STCStyleEditDlg(None, 'Python', 'python', config
, (stc
,))
1326 try: dlg
.ShowModal()
1327 finally: dlg
.Destroy()
1328 stc
.SetText(open('STCStyleEditor.py').read())
1329 EVT_LEFT_DCLICK(stc
, OnDblClick
)
1330 initSTC(stc
, config
, 'python')
1334 dlg
= STCStyleEditDlg(None,
1340 #'Properties', 'prop',
1342 try: dlg
.ShowModal()
1343 finally: dlg
.Destroy()