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