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()