]> git.saurik.com Git - wxWidgets.git/blame - wxPython/samples/StyleEditor/STCStyleEditor.py
Modified form of Patch #1611222, adds wxSearchCtrl (generic & native carbon HISearchF...
[wxWidgets.git] / wxPython / samples / StyleEditor / STCStyleEditor.py
CommitLineData
00b6c4e3
RD
1#-----------------------------------------------------------------------------
2# Name: STCStyleEditor.py
3# Purpose: Style editor for the wxStyledTextCtrl
4#
5# Author: Riaan Booysen
6#
7# Created: 2001/08/20
8# RCS-ID: $Id$
1e19321b
RD
9# Copyright: (c) 2001 - 2005 Riaan Booysen
10# Licence: wxWidgets license
00b6c4e3
RD
11#-----------------------------------------------------------------------------
12#Boa:Dialog:STCStyleEditDlg
13
14""" Style editor for the wxStyledTextCtrl.
15
16Reads in property style definitions from a config file.
17Modified styled can be saved (and optionally applied to a given list of STCs)
18
1114f46e 19It can also maintain a Common definition dictionary of font names, colours and
00b6c4e3 20sizes which can be shared across multiple language style definitions.
1e19321b 21This is also used to store platform specific settings as fonts and sizes
00b6c4e3
RD
22vary with platform.
23
24The following items are defined in the stc-styles.rc.cfg file.
25
26common.defs.msw - Common definition dictionary used on wxMSW
27common.defs.gtk - Common definition dictionary used on wxGTK
1e19321b 28common.defs.mac - Common definition dictionary used on wxMAC
00b6c4e3
RD
29common.styleidnames - STC styles shared by all languages
30
31Each supported language defines the following groups:
32[<language>]
33displaysrc - Example source to display in the editor
34braces - Dictionary defining the (line, column) for showing 'good' and 'bad'
35 brace matching (both keys optional)
36keywords - Space separated list of keywords
37lexer - wxSTC constant for the language lexer
1e19321b 38styleidnames - Dictionary of language specific style numbers and names
00b6c4e3
RD
39
40[style.<language>] - The users current style values
41[style.<language>.default] - Default style values (can be reverted from)
42
430 or more predefined style groups or 'themes'
44[style.<language>.<predefined name>]
45
1114f46e 46Currently the following languages are supported:
00b6c4e3
RD
47 python, html, xml, cpp, text, props
48Other languages can be added by just defining the above settings for them in
49the config file (if wxSTC implements them).
50
51Use the initSTC function to initialise your wxSTC from a config file.
52"""
53
54import os, sys, string, pprint, copy
55
1e19321b
RD
56import wx
57from wx.lib.anchors import LayoutAnchors
58import wx.stc
59import wxPython.stc # needed names from 2.4 for config files
00b6c4e3
RD
60
61settingsIdNames = {-1: 'Selection', -2: 'Caret', -3: 'Edge'}
62
1e19321b
RD
63commonPropDefs = {'fore': '#888888', 'size': 8,
64 'face': ''}
00b6c4e3
RD
65
66styleCategoryDescriptions = {
1e19321b 67 '----Language----': 'Styles specific to the language',
1e4a197e
RD
68 '----Standard----': 'Styles shared by all languages',
69 '----Settings----': 'Properties set by STC methods',
70 '----Common----': 'User definable values that can be shared between languages'}
71
1e19321b
RD
72platformSettings = {'__WXMSW__': ('msw', 8),
73 '__WXGTK__': ('gtk', 10),
74 '__WXMAC__': ('mac', 11)}
75
76[wxID_STCSTYLEEDITDLG, wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN,
77 wxID_STCSTYLEEDITDLGBGCOLBTN, wxID_STCSTYLEEDITDLGBGCOLCB,
78 wxID_STCSTYLEEDITDLGBGCOLDEFCB, wxID_STCSTYLEEDITDLGBGCOLOKBTN,
79 wxID_STCSTYLEEDITDLGCANCELBTN, wxID_STCSTYLEEDITDLGCONTEXTHELPBUTTON1,
80 wxID_STCSTYLEEDITDLGELEMENTLB, wxID_STCSTYLEEDITDLGFACECB,
81 wxID_STCSTYLEEDITDLGFACEDEFCB, wxID_STCSTYLEEDITDLGFACEOKBTN,
82 wxID_STCSTYLEEDITDLGFGCOLBTN, wxID_STCSTYLEEDITDLGFGCOLCB,
83 wxID_STCSTYLEEDITDLGFGCOLDEFCB, wxID_STCSTYLEEDITDLGFGCOLOKBTN,
84 wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK, wxID_STCSTYLEEDITDLGOKBTN,
85 wxID_STCSTYLEEDITDLGPANEL1, wxID_STCSTYLEEDITDLGPANEL2,
86 wxID_STCSTYLEEDITDLGPANEL3, wxID_STCSTYLEEDITDLGPANEL4,
87 wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN, wxID_STCSTYLEEDITDLGSIZECB,
88 wxID_STCSTYLEEDITDLGSIZEOKBTN, wxID_STCSTYLEEDITDLGSPEEDSETTINGCH,
89 wxID_STCSTYLEEDITDLGSTATICBOX1, wxID_STCSTYLEEDITDLGSTATICBOX2,
90 wxID_STCSTYLEEDITDLGSTATICLINE1, wxID_STCSTYLEEDITDLGSTATICTEXT2,
91 wxID_STCSTYLEEDITDLGSTATICTEXT3, wxID_STCSTYLEEDITDLGSTATICTEXT4,
92 wxID_STCSTYLEEDITDLGSTATICTEXT6, wxID_STCSTYLEEDITDLGSTATICTEXT7,
93 wxID_STCSTYLEEDITDLGSTATICTEXT8, wxID_STCSTYLEEDITDLGSTATICTEXT9,
94 wxID_STCSTYLEEDITDLGSTC, wxID_STCSTYLEEDITDLGSTYLEDEFST,
95 wxID_STCSTYLEEDITDLGTABOLDCB, wxID_STCSTYLEEDITDLGTABOLDDEFCB,
96 wxID_STCSTYLEEDITDLGTAEOLFILLEDCB, wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB,
97 wxID_STCSTYLEEDITDLGTAITALICCB, wxID_STCSTYLEEDITDLGTAITALICDEFCB,
98 wxID_STCSTYLEEDITDLGTASIZEDEFCB, wxID_STCSTYLEEDITDLGTAUNDERLINEDCB,
99 wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB,
100] = [wx.NewId() for _init_ctrls in range(47)]
101
102class STCStyleEditDlg(wx.Dialog):
00b6c4e3 103 """ Style editor for the wxStyledTextCtrl """
1e19321b 104 _custom_classes = {'wx.Window': ['wx.stc.StyledTextCtrl'],}
1114f46e 105 def _init_ctrls(self, prnt):
1e4a197e 106 # generated method, don't edit
1e19321b
RD
107 wx.Dialog.__init__(self, id=wxID_STCSTYLEEDITDLG,
108 name='STCStyleEditDlg', parent=prnt, pos=wx.Point(567, 292),
109 size=wx.Size(493, 482),
110 style=wx.WANTS_CHARS | wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
1e4a197e 111 title=self.stc_title)
1e19321b 112 self.SetClientSize(wx.Size(485, 455))
1e4a197e 113 self.SetAutoLayout(True)
00b6c4e3 114 self.SetSizeHints(425, 400, -1, -1)
1e19321b
RD
115 self.Center(wx.BOTH)
116 self.Bind(wx.EVT_SIZE, self.OnStcstyleeditdlgSize)
00b6c4e3 117
1e19321b 118 self.speedsettingCh = wx.Choice(choices=[],
1e4a197e 119 id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH, name='speedsettingCh',
1e19321b
RD
120 parent=self, pos=wx.Point(96, 28), size=wx.Size(380, 21),
121 style=0)
1e4a197e
RD
122 self.speedsettingCh.SetConstraints(LayoutAnchors(self.speedsettingCh,
123 True, True, True, False))
124 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.')
1e19321b
RD
125 self.speedsettingCh.Bind(wx.EVT_CHOICE, self.OnSpeedsettingchChoice,
126 id=wxID_STCSTYLEEDITDLGSPEEDSETTINGCH)
1e4a197e 127
1e19321b
RD
128 self.elementLb = wx.ListBox(choices=[],
129 id=wxID_STCSTYLEEDITDLGELEMENTLB, name='elementLb', parent=self,
130 pos=wx.Point(8, 70), size=wx.Size(175, 128), style=0)
1e4a197e
RD
131 self.elementLb.SetConstraints(LayoutAnchors(self.elementLb, True, True,
132 True, False))
133 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.')
1e19321b
RD
134 self.elementLb.Bind(wx.EVT_LISTBOX, self.OnElementlbListbox,
135 id=wxID_STCSTYLEEDITDLGELEMENTLB)
1e4a197e 136
1e19321b
RD
137 self.addCommonItemBtn = wx.Button(id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN,
138 label='Add', name='addCommonItemBtn', parent=self, pos=wx.Point(8,
139 200), size=wx.Size(88, 17), style=0)
1e4a197e 140 self.addCommonItemBtn.SetToolTipString('Add new Common definition')
1e19321b
RD
141 self.addCommonItemBtn.Bind(wx.EVT_BUTTON, self.OnAddsharebtnButton,
142 id=wxID_STCSTYLEEDITDLGADDCOMMONITEMBTN)
00b6c4e3 143
1e19321b 144 self.removeCommonItemBtn = wx.Button(id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN,
1e4a197e 145 label='Remove', name='removeCommonItemBtn', parent=self,
1e19321b 146 pos=wx.Point(96, 200), size=wx.Size(88, 17), style=0)
1e4a197e 147 self.removeCommonItemBtn.SetToolTipString('Remove the selected Common definition')
1e19321b
RD
148 self.removeCommonItemBtn.Bind(wx.EVT_BUTTON,
149 self.OnRemovesharebtnButton,
150 id=wxID_STCSTYLEEDITDLGREMOVECOMMONITEMBTN)
1e4a197e 151
1e19321b 152 self.styleDefST = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTYLEDEFST,
1e4a197e 153 label='(nothing selected)', name='styleDefST', parent=self,
1e19321b
RD
154 pos=wx.Point(96, 8), size=wx.Size(376, 16),
155 style=wx.ST_NO_AUTORESIZE)
156 self.styleDefST.SetFont(wx.Font(self.style_font_size, wx.SWISS,
157 wx.NORMAL, wx.BOLD, False, ''))
1e4a197e
RD
158 self.styleDefST.SetConstraints(LayoutAnchors(self.styleDefST, True,
159 True, True, False))
160
1e19321b
RD
161 self.staticLine1 = wx.StaticLine(id=wxID_STCSTYLEEDITDLGSTATICLINE1,
162 name='staticLine1', parent=self, pos=wx.Point(48, 64),
163 size=wx.Size(135, 0), style=wx.LI_HORIZONTAL)
1e4a197e
RD
164 self.staticLine1.SetConstraints(LayoutAnchors(self.staticLine1, True,
165 True, True, False))
166
1e19321b
RD
167 self.staticText6 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT6,
168 label='Style', name='staticText6', parent=self, pos=wx.Point(8,
169 56), size=wx.Size(40, 13), style=0)
1e4a197e 170
1e19321b 171 self.staticText8 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT8,
1e4a197e 172 label='Style def:', name='staticText8', parent=self,
1e19321b 173 pos=wx.Point(8, 8), size=wx.Size(88, 13), style=0)
1e4a197e 174
1e19321b 175 self.staticText9 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT9,
1e4a197e 176 label='SpeedSetting:', name='staticText9', parent=self,
1e19321b 177 pos=wx.Point(8, 32), size=wx.Size(88, 13), style=0)
1e4a197e 178
1e19321b
RD
179 self.panel3 = wx.Panel(id=wxID_STCSTYLEEDITDLGPANEL3, name='panel3',
180 parent=self, pos=wx.Point(199, 56), size=wx.Size(160, 120),
181 style=wx.TAB_TRAVERSAL)
1e4a197e
RD
182 self.panel3.SetConstraints(LayoutAnchors(self.panel3, False, True, True,
183 False))
184
1e19321b
RD
185 self.panel4 = wx.Panel(id=wxID_STCSTYLEEDITDLGPANEL4, name='panel4',
186 parent=self, pos=wx.Point(364, 56), size=wx.Size(114, 120),
187 style=wx.TAB_TRAVERSAL)
1e4a197e
RD
188 self.panel4.SetConstraints(LayoutAnchors(self.panel4, False, True, True,
189 False))
190
1e19321b
RD
191 self.panel1 = wx.Panel(id=wxID_STCSTYLEEDITDLGPANEL1, name='panel1',
192 parent=self, pos=wx.Point(202, 177), size=wx.Size(149, 40),
193 style=wx.TAB_TRAVERSAL)
1e4a197e
RD
194 self.panel1.SetConstraints(LayoutAnchors(self.panel1, False, True, True,
195 False))
196
1e19321b
RD
197 self.panel2 = wx.Panel(id=wxID_STCSTYLEEDITDLGPANEL2, name='panel2',
198 parent=self, pos=wx.Point(364, 178), size=wx.Size(112, 40),
199 style=wx.TAB_TRAVERSAL)
1e4a197e
RD
200 self.panel2.SetConstraints(LayoutAnchors(self.panel2, False, True, True,
201 False))
202
1e19321b
RD
203 self.stc = wx.stc.StyledTextCtrl(id=wxID_STCSTYLEEDITDLGSTC, name='stc',
204 parent=self, pos=wx.Point(8, 224), size=wx.Size(469, 191),
205 style=wx.SUNKEN_BORDER)
1e4a197e 206 self.stc.SetConstraints(LayoutAnchors(self.stc, True, True, True, True))
1e19321b
RD
207 self.stc.SetHelpText('The style preview window. Click or move the cursor over a specific style to select the style for editing in the editors above.')
208 self.stc.Bind(wx.EVT_LEFT_UP, self.OnUpdateUI)
209 self.stc.Bind(wx.EVT_KEY_UP, self.OnUpdateUI)
00b6c4e3 210
1e19321b
RD
211 self.contextHelpButton1 = wx.ContextHelpButton(parent=self,
212 pos=wx.Point(8, 423), size=wx.Size(24, 24), style=wx.BU_AUTODRAW)
1e4a197e
RD
213 self.contextHelpButton1.SetConstraints(LayoutAnchors(self.contextHelpButton1,
214 True, False, False, True))
00b6c4e3 215
1e19321b
RD
216 self.okBtn = wx.Button(id=wxID_STCSTYLEEDITDLGOKBTN, label='OK',
217 name='okBtn', parent=self, pos=wx.Point(316, 423),
218 size=wx.Size(75, 23), style=0)
1e4a197e
RD
219 self.okBtn.SetConstraints(LayoutAnchors(self.okBtn, False, False, True,
220 True))
00b6c4e3 221 self.okBtn.SetToolTipString('Save changes to the config file')
1e19321b
RD
222 self.okBtn.Bind(wx.EVT_BUTTON, self.OnOkbtnButton,
223 id=wxID_STCSTYLEEDITDLGOKBTN)
00b6c4e3 224
1e19321b
RD
225 self.cancelBtn = wx.Button(id=wxID_STCSTYLEEDITDLGCANCELBTN,
226 label='Cancel', name='cancelBtn', parent=self, pos=wx.Point(400,
227 423), size=wx.Size(75, 23), style=0)
1e4a197e
RD
228 self.cancelBtn.SetConstraints(LayoutAnchors(self.cancelBtn, False,
229 False, True, True))
00b6c4e3 230 self.cancelBtn.SetToolTipString('Close dialog without saving changes')
1e19321b
RD
231 self.cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancelbtnButton,
232 id=wxID_STCSTYLEEDITDLGCANCELBTN)
00b6c4e3 233
1e19321b 234 self.staticText4 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT4,
1e4a197e 235 label='Face:', name='staticText4', parent=self.panel1,
1e19321b 236 pos=wx.Point(0, 0), size=wx.Size(48, 13), style=0)
00b6c4e3 237
1e19321b
RD
238 self.fixedWidthChk = wx.CheckBox(id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK,
239 label='', name='fixedWidthChk', parent=self.panel1,
240 pos=wx.Point(0, 23), size=wx.Size(16, 19), style=0)
00b6c4e3 241 self.fixedWidthChk.SetToolTipString('Check this for Fixed Width fonts')
1e19321b
RD
242 self.fixedWidthChk.Bind(wx.EVT_CHECKBOX, self.OnFixedwidthchkCheckbox,
243 id=wxID_STCSTYLEEDITDLGFIXEDWIDTHCHK)
1e4a197e 244
1e19321b
RD
245 self.faceCb = wx.ComboBox(choices=[], id=wxID_STCSTYLEEDITDLGFACECB,
246 name='faceCb', parent=self.panel1, pos=wx.Point(17, 18),
247 size=wx.Size(101, 21), style=0, value='')
1e4a197e 248
1e19321b 249 self.staticText7 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT7,
1e4a197e 250 label='Size:', name='staticText7', parent=self.panel2,
1e19321b 251 pos=wx.Point(0, 0), size=wx.Size(40, 13), style=0)
1e4a197e 252
1e19321b
RD
253 self.sizeCb = wx.ComboBox(choices=[], id=wxID_STCSTYLEEDITDLGSIZECB,
254 name='sizeCb', parent=self.panel2, pos=wx.Point(0, 17),
255 size=wx.Size(80, 21), style=0, value='')
1e4a197e 256
1e19321b
RD
257 self.sizeOkBtn = wx.Button(id=wxID_STCSTYLEEDITDLGSIZEOKBTN, label='ok',
258 name='sizeOkBtn', parent=self.panel2, pos=wx.Point(80, 17),
259 size=wx.Size(32, 21), style=0)
1e4a197e 260
1e19321b
RD
261 self.faceOkBtn = wx.Button(id=wxID_STCSTYLEEDITDLGFACEOKBTN, label='ok',
262 name='faceOkBtn', parent=self.panel1, pos=wx.Point(117, 18),
263 size=wx.Size(32, 21), style=0)
1e4a197e 264
1e19321b 265 self.fgColBtn = wx.Button(id=wxID_STCSTYLEEDITDLGFGCOLBTN,
1e4a197e 266 label='Foreground', name='fgColBtn', parent=self.panel3,
1e19321b
RD
267 pos=wx.Point(8, 16), size=wx.Size(96, 16), style=0)
268 self.fgColBtn.Bind(wx.EVT_BUTTON, self.OnFgcolbtnButton,
269 id=wxID_STCSTYLEEDITDLGFGCOLBTN)
1e4a197e 270
1e19321b
RD
271 self.fgColCb = wx.ComboBox(choices=[], id=wxID_STCSTYLEEDITDLGFGCOLCB,
272 name='fgColCb', parent=self.panel3, pos=wx.Point(8, 32),
273 size=wx.Size(96, 21), style=0, value='')
1e4a197e 274
1e19321b
RD
275 self.fgColOkBtn = wx.Button(id=wxID_STCSTYLEEDITDLGFGCOLOKBTN,
276 label='ok', name='fgColOkBtn', parent=self.panel3,
277 pos=wx.Point(104, 32), size=wx.Size(32, 21), style=0)
1e4a197e 278
1e19321b 279 self.staticText3 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT3,
1e4a197e 280 label='default', name='staticText3', parent=self.panel3,
1e19321b 281 pos=wx.Point(112, 15), size=wx.Size(38, 16), style=0)
1e4a197e 282
1e19321b 283 self.fgColDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGFGCOLDEFCB,
1e4a197e 284 label='checkBox1', name='fgColDefCb', parent=self.panel3,
1e19321b 285 pos=wx.Point(136, 31), size=wx.Size(16, 16), style=0)
1e4a197e 286
1e19321b 287 self.bgColBtn = wx.Button(id=wxID_STCSTYLEEDITDLGBGCOLBTN,
1e4a197e 288 label='Background', name='bgColBtn', parent=self.panel3,
1e19321b
RD
289 pos=wx.Point(8, 64), size=wx.Size(96, 16), style=0)
290 self.bgColBtn.Bind(wx.EVT_BUTTON, self.OnBgcolbtnButton,
291 id=wxID_STCSTYLEEDITDLGBGCOLBTN)
1e4a197e 292
1e19321b
RD
293 self.bgColCb = wx.ComboBox(choices=[], id=wxID_STCSTYLEEDITDLGBGCOLCB,
294 name='bgColCb', parent=self.panel3, pos=wx.Point(8, 80),
295 size=wx.Size(96, 21), style=0, value='')
1e4a197e 296
1e19321b
RD
297 self.bgColOkBtn = wx.Button(id=wxID_STCSTYLEEDITDLGBGCOLOKBTN,
298 label='ok', name='bgColOkBtn', parent=self.panel3,
299 pos=wx.Point(104, 80), size=wx.Size(32, 21), style=0)
1e4a197e 300
1e19321b 301 self.staticBox2 = wx.StaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX2,
1e4a197e 302 label='Text attributes', name='staticBox2', parent=self.panel4,
1e19321b 303 pos=wx.Point(0, 0), size=wx.Size(112, 112), style=0)
1e4a197e
RD
304 self.staticBox2.SetConstraints(LayoutAnchors(self.staticBox2, False,
305 True, True, False))
306 self.staticBox2.SetHelpText('Text attribute flags.')
307
1e19321b 308 self.staticText2 = wx.StaticText(id=wxID_STCSTYLEEDITDLGSTATICTEXT2,
1e4a197e 309 label='default', name='staticText2', parent=self.panel4,
1e19321b 310 pos=wx.Point(64, 12), size=wx.Size(40, 16), style=0)
1e4a197e 311
1e19321b 312 self.taBoldDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTABOLDDEFCB,
1e4a197e 313 label='checkBox1', name='taBoldDefCb', parent=self.panel4,
1e19321b 314 pos=wx.Point(88, 27), size=wx.Size(16, 16), style=0)
1e4a197e 315
1e19321b 316 self.taItalicDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTAITALICDEFCB,
1e4a197e 317 label='checkBox1', name='taItalicDefCb', parent=self.panel4,
1e19321b 318 pos=wx.Point(88, 48), size=wx.Size(16, 16), style=0)
1e4a197e 319
1e19321b 320 self.taUnderlinedDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB,
1e4a197e 321 label='checkBox1', name='taUnderlinedDefCb', parent=self.panel4,
1e19321b 322 pos=wx.Point(88, 70), size=wx.Size(16, 16), style=0)
1e4a197e 323
1e19321b 324 self.taEOLfilledDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB,
1e4a197e 325 label='checkBox1', name='taEOLfilledDefCb', parent=self.panel4,
1e19321b 326 pos=wx.Point(88, 92), size=wx.Size(16, 16), style=0)
1e4a197e 327
1e19321b 328 self.taEOLfilledCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB,
1e4a197e 329 label='EOL filled', name='taEOLfilledCb', parent=self.panel4,
1e19321b
RD
330 pos=wx.Point(8, 92), size=wx.Size(80, 16), style=0)
331 self.taEOLfilledCb.Bind(wx.EVT_CHECKBOX, self.OnTaeoffilledcbCheckbox,
332 id=wxID_STCSTYLEEDITDLGTAEOLFILLEDCB)
1e4a197e 333
1e19321b 334 self.taUnderlinedCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB,
1e4a197e 335 label='Underlined', name='taUnderlinedCb', parent=self.panel4,
1e19321b
RD
336 pos=wx.Point(8, 70), size=wx.Size(80, 16), style=0)
337 self.taUnderlinedCb.Bind(wx.EVT_CHECKBOX, self.OnTaunderlinedcbCheckbox,
338 id=wxID_STCSTYLEEDITDLGTAUNDERLINEDCB)
1e4a197e 339
1e19321b 340 self.taItalicCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTAITALICCB,
1e4a197e 341 label='Italic', name='taItalicCb', parent=self.panel4,
1e19321b
RD
342 pos=wx.Point(8, 48), size=wx.Size(80, 16), style=0)
343 self.taItalicCb.Bind(wx.EVT_CHECKBOX, self.OnTaitaliccbCheckbox,
344 id=wxID_STCSTYLEEDITDLGTAITALICCB)
1e4a197e 345
1e19321b
RD
346 self.taBoldCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTABOLDCB,
347 label='Bold', name='taBoldCb', parent=self.panel4, pos=wx.Point(8,
348 27), size=wx.Size(80, 16), style=0)
349 self.taBoldCb.Bind(wx.EVT_CHECKBOX, self.OnTaboldcbCheckbox,
350 id=wxID_STCSTYLEEDITDLGTABOLDCB)
1e4a197e 351
1e19321b 352 self.bgColDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGBGCOLDEFCB,
1e4a197e 353 label='checkBox1', name='bgColDefCb', parent=self.panel3,
1e19321b 354 pos=wx.Point(136, 79), size=wx.Size(16, 16), style=0)
1e4a197e 355
1e19321b 356 self.staticBox1 = wx.StaticBox(id=wxID_STCSTYLEEDITDLGSTATICBOX1,
1e4a197e 357 label='Colour', name='staticBox1', parent=self.panel3,
1e19321b 358 pos=wx.Point(0, 0), size=wx.Size(157, 112), style=0)
1e4a197e
RD
359 self.staticBox1.SetConstraints(LayoutAnchors(self.staticBox1, False,
360 True, True, False))
361
1e19321b 362 self.faceDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGFACEDEFCB,
1e4a197e 363 label='checkBox1', name='faceDefCb', parent=self.panel1,
1e19321b 364 pos=wx.Point(117, 0), size=wx.Size(16, 16), style=0)
1e4a197e 365
1e19321b 366 self.taSizeDefCb = wx.CheckBox(id=wxID_STCSTYLEEDITDLGTASIZEDEFCB,
1e4a197e 367 label='checkBox1', name='taSizeDefCb', parent=self.panel2,
1e19321b 368 pos=wx.Point(80, 0), size=wx.Size(16, 16), style=0)
00b6c4e3 369
1114f46e 370 def __init__(self, parent, langTitle, lang, configFile, STCsToUpdate=()):
00b6c4e3
RD
371 self.stc_title = 'wxStyledTextCtrl Style Editor'
372 self.stc_title = 'wxStyledTextCtrl Style Editor - %s' % langTitle
1e19321b
RD
373 self.style_font_size = 8
374 self.style_font_size = platformSettings[wx.Platform][1]
00b6c4e3 375 self._init_ctrls(parent)
00b6c4e3
RD
376 self.lang = lang
377 self.configFile = configFile
378 self.style = ''
1e4a197e 379 self.styleNum = 0
00b6c4e3
RD
380 self.names = []
381 self.values = {}
382 self.STCsToUpdate = STCsToUpdate
1e4a197e 383 self._blockUpdate = False
1e19321b
RD
384
385 global commonPropDefs
386 commonPropDefs = {'fore': '#888888', 'size': 8,
387 'face': wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT).GetFaceName()}
1e4a197e
RD
388
389 for combo, okBtn, evtRet, evtCB, evtRDC in (
390 (self.fgColCb, self.fgColOkBtn, self.OnfgColRet, self.OnfgColCombobox, self.OnGotoCommonDef),
391 (self.bgColCb, self.bgColOkBtn, self.OnbgColRet, self.OnbgColCombobox, self.OnGotoCommonDef),
392 (self.faceCb, self.faceOkBtn, self.OnfaceRet, self.OnfaceCombobox, self.OnGotoCommonDef),
393 (self.sizeCb, self.sizeOkBtn, self.OnsizeRet, self.OnsizeCombobox, self.OnGotoCommonDef)):
394 self.bindComboEvts(combo, okBtn, evtRet, evtCB, evtRDC)
1114f46e
RD
395
396 (self.config, self.commonDefs, self.styleIdNames, self.styles,
397 self.styleGroupNames, self.predefStyleGroups,
00b6c4e3
RD
398 self.otherLangStyleGroupNames, self.otherLangStyleGroups,
399 self.displaySrc, self.lexer, self.keywords, self.braceInfo) = \
1114f46e
RD
400 initFromConfig(configFile, lang)
401
00b6c4e3
RD
402 self.currSpeedSetting = 'style.%s'%self.lang
403 for grp in [self.currSpeedSetting]+self.styleGroupNames:
404 self.speedsettingCh.Append(grp)
405 self.speedsettingCh.SetSelection(0)
1114f46e 406
00b6c4e3 407 margin = 0
1e19321b 408 self.stc.SetMarginType(margin, wx.stc.STC_MARGIN_NUMBER)
00b6c4e3 409 self.stc.SetMarginWidth(margin, 25)
1e4a197e 410 self.stc.SetMarginSensitive(margin, True)
1e19321b 411 self.stc.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick, id=wxID_STCSTYLEEDITDLGSTC)
00b6c4e3 412
1e4a197e 413 self.stc.SetUseTabs(False)
00b6c4e3 414 self.stc.SetTabWidth(4)
1e4a197e 415 self.stc.SetIndentationGuides(True)
1e19321b 416 self.stc.SetEdgeMode(wx.stc.STC_EDGE_BACKGROUND)
00b6c4e3 417 self.stc.SetEdgeColumn(44)
1114f46e 418
00b6c4e3
RD
419 self.setStyles()
420
421 self.populateStyleSelector()
422
423 self.defNames, self.defValues = parseProp(\
1e19321b 424 self.styleDict.get(wx.stc.STC_STYLE_DEFAULT, ''))
00b6c4e3
RD
425 self.stc.SetText(self.displaySrc)
426 self.stc.EmptyUndoBuffer()
427 self.stc.SetCurrentPos(self.stc.GetTextLength())
428 self.stc.SetAnchor(self.stc.GetTextLength())
429
430 self.populateCombosWithCommonDefs()
431
432 # Logical grouping of controls and the property they edit
1e4a197e 433 self.allCtrls = [((self.fgColBtn, self.fgColCb, self.fgColOkBtn), self.fgColDefCb,
00b6c4e3 434 'fore', wxID_STCSTYLEEDITDLGFGCOLDEFCB),
1e4a197e 435 ((self.bgColBtn, self.bgColCb, self.bgColOkBtn), self.bgColDefCb,
00b6c4e3 436 'back', wxID_STCSTYLEEDITDLGBGCOLDEFCB),
1114f46e 437 (self.taBoldCb, self.taBoldDefCb,
00b6c4e3 438 'bold', wxID_STCSTYLEEDITDLGTABOLDDEFCB),
1114f46e
RD
439 (self.taItalicCb, self.taItalicDefCb,
440 'italic', wxID_STCSTYLEEDITDLGTAITALICDEFCB),
441 (self.taUnderlinedCb, self.taUnderlinedDefCb,
00b6c4e3 442 'underline', wxID_STCSTYLEEDITDLGTAUNDERLINEDDEFCB),
1114f46e 443 (self.taEOLfilledCb, self.taEOLfilledDefCb,
00b6c4e3 444 'eolfilled', wxID_STCSTYLEEDITDLGTAEOLFILLEDDEFCB),
1e4a197e 445 ((self.sizeCb, self.sizeOkBtn), self.taSizeDefCb,
00b6c4e3 446 'size', wxID_STCSTYLEEDITDLGTASIZEDEFCB),
1e4a197e 447 ((self.faceCb, self.faceOkBtn, self.fixedWidthChk), self.faceDefCb,
00b6c4e3
RD
448 'face', wxID_STCSTYLEEDITDLGFACEDEFCB)]
449
1e4a197e 450 self.clearCtrls(disableDefs=True)
00b6c4e3
RD
451 # centralised default checkbox event handler
452 self.chbIdMap = {}
453 for ctrl, chb, prop, wid in self.allCtrls:
454 self.chbIdMap[wid] = ctrl, chb, prop, wid
1e19321b 455 chb.Bind(wx.EVT_CHECKBOX, self.OnDefaultCheckBox, id=wid)
00b6c4e3 456 chb.SetToolTipString('Toggle defaults')
1114f46e 457
1e19321b 458 self.Center(wx.BOTH)
1114f46e 459
00b6c4e3
RD
460#---Property methods------------------------------------------------------------
461 def getCtrlForProp(self, findprop):
462 for ctrl, chb, prop, wid in self.allCtrls:
463 if findprop == prop:
464 return ctrl, chb
465 raise Exception('PropNotFound', findprop)
1114f46e 466
00b6c4e3
RD
467 def editProp(self, on, prop, val=''):
468 oldstyle = self.rememberStyles()
469 if on:
470 if not self.names.count(prop):
471 self.names.append(prop)
472 self.values[prop] = val
473 else:
474 try: self.names.remove(prop)
475 except ValueError: pass
476 try: del self.values[prop]
477 except KeyError: pass
1114f46e 478
00b6c4e3
RD
479 try:
480 self.updateStyle()
1e4a197e 481 return True
00b6c4e3 482 except KeyError, errkey:
1e19321b 483 wx.LogError('Name not found in Common definition, '\
00b6c4e3
RD
484 'please enter valid reference. (%s)'%errkey)
485 self.restoreStyles(oldstyle)
1e4a197e 486 return False
00b6c4e3
RD
487
488#---Control population methods--------------------------------------------------
489 def setStyles(self):
1e4a197e 490 if self._blockUpdate: return
00b6c4e3 491 self.styles, self.styleDict, self.styleNumIdxMap = \
1114f46e 492 setSTCStyles(self.stc, self.styles, self.styleIdNames,
00b6c4e3 493 self.commonDefs, self.lang, self.lexer, self.keywords)
1114f46e 494
00b6c4e3
RD
495 def updateStyle(self):
496 # called after a control edited self.names, self.values
497 # Special case for saving common defs settings
498 if self.styleNum == 'common':
1e19321b
RD
499 #if not self.values:
500 # return
501
00b6c4e3
RD
502 strVal = self.style[2] = self.values.values()[0]
503 if self.style[1] == 'size': self.style[2] = int(strVal)
1114f46e 504
00b6c4e3
RD
505 self.commonDefs[self.style[0]] = self.style[2]
506 self.styleDefST.SetLabel(strVal)
507 else:
508 self.style = writePropVal(self.names, self.values)
509 styleDecl = writeProp(self.styleNum, self.style, self.lang)
510 self.styles[self.styleNumIdxMap[self.styleNum]] = styleDecl
511 self.styleDefST.SetLabel(self.style)
512 self.setStyles()
1114f46e 513
00b6c4e3
RD
514 def findInStyles(self, txt, styles):
515 for style in styles:
1e19321b 516 if style.find(txt) != -1:
1e4a197e
RD
517 return True
518 return False
00b6c4e3
RD
519
520 def rememberStyles(self):
521 return self.names[:], copy.copy(self.values)
522
523 def restoreStyles(self, style):
524 self.names, self.values = style
525 self.updateStyle()
526
1e4a197e
RD
527 def clearCtrls(self, isDefault=False, disableDefs=False):
528 self._blockUpdate = True
529 try:
530 for ctrl, chb, prop, wid in self.allCtrls:
531 if prop in ('fore', 'back'):
532 cbtn, txt, btn = ctrl
533 cbtn.SetBackgroundColour(\
1e19321b
RD
534 wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
535 cbtn.SetForegroundColour(wx.Colour(255, 255, 255))
1e4a197e
RD
536 cbtn.Enable(isDefault)
537 txt.SetValue('')
538 txt.Enable(isDefault)
539 btn.Enable(isDefault)
540 elif prop == 'size':
541 cmb, btn = ctrl
542 cmb.SetValue('')
543 cmb.Enable(isDefault)
544 btn.Enable(isDefault)
545 elif prop == 'face':
546 cmb, btn, chk = ctrl
547 cmb.SetValue('')
548 cmb.Enable(isDefault)
549 btn.Enable(isDefault)
550 chk.Enable(isDefault)
551 chk.SetValue(False)
552 elif prop in ('bold', 'italic', 'underline', 'eolfilled'):
553 ctrl.SetValue(False)
554 ctrl.Enable(isDefault)
555
556 chb.Enable(not isDefault and not disableDefs)
557 chb.SetValue(True)
558 finally:
559 self._blockUpdate = False
560
561 def populateProp(self, items, default, forceDisable=False):
562 self._blockUpdate = True
563 try:
564 for name, val in items:
565 if name:
566 ctrl, chb = self.getCtrlForProp(name)
567
568 if name in ('fore', 'back'):
569 cbtn, txt, btn = ctrl
570 repval = val%self.commonDefs
571 cbtn.SetBackgroundColour(strToCol(repval))
1e19321b 572 cbtn.SetForegroundColour(wx.Colour(0, 0, 0))
1e4a197e
RD
573 cbtn.Enable(not forceDisable)
574 txt.SetValue(val)
575 txt.Enable(not forceDisable)
576 btn.Enable(not forceDisable)
577 chb.SetValue(default)
578 elif name == 'size':
579 cmb, btn = ctrl
580 cmb.SetValue(val)
581 cmb.Enable(not forceDisable)
582 btn.Enable(not forceDisable)
583 chb.SetValue(default)
584 elif name == 'face':
585 cmb, btn, chk = ctrl
586 cmb.SetValue(val)
587 cmb.Enable(not forceDisable)
588 btn.Enable(not forceDisable)
589 chk.Enable(not forceDisable)
590 chb.SetValue(default)
591 elif name in ('bold', 'italic', 'underline', 'eolfilled'):
592 ctrl.Enable(not forceDisable)
593 ctrl.SetValue(True)
594 chb.SetValue(default)
595 finally:
596 self._blockUpdate = False
1114f46e 597
00b6c4e3
RD
598 def valIsCommonDef(self, val):
599 return len(val) >= 5 and val[:2] == '%('
1114f46e 600
00b6c4e3 601 def populateCtrls(self):
1e19321b 602 self.clearCtrls(self.styleNum == wx.stc.STC_STYLE_DEFAULT,
00b6c4e3
RD
603 disableDefs=self.styleNum < 0)
604
605 # handle colour controls for settings
606 if self.styleNum < 0:
1e4a197e 607 self.fgColDefCb.Enable(True)
00b6c4e3 608 if self.styleNum == -1:
1e4a197e 609 self.bgColDefCb.Enable(True)
1114f46e 610
00b6c4e3 611 # populate with default style
1e4a197e 612 self.populateProp(self.defValues.items(), True,
1e19321b 613 self.styleNum != wx.stc.STC_STYLE_DEFAULT)
00b6c4e3 614 # override with current settings
1e4a197e 615 self.populateProp(self.values.items(), False)
1114f46e 616
00b6c4e3
RD
617 def getCommonDefPropType(self, commonDefName):
618 val = self.commonDefs[commonDefName]
619 if type(val) == type(0): return 'size'
620 if len(val) == 7 and val[0] == '#': return 'fore'
621 return 'face'
622
1e4a197e 623 def bindComboEvts(self, combo, btn, btnEvtMeth, comboEvtMeth, rdclickEvtMeth):
1e19321b
RD
624 combo.Bind(wx.EVT_COMBOBOX, comboEvtMeth, id=combo.GetId())
625 btn.Bind(wx.EVT_BUTTON, btnEvtMeth, id=btn.GetId())
626 combo.Bind(wx.EVT_RIGHT_DCLICK, rdclickEvtMeth)
1e4a197e
RD
627 combo.SetToolTipString('Select from list or click "ok" button on the right to change a manual entry, right double-click \n'\
628 'the drop down button to select Common definition in the Style Editor (if applicable)')
629 btn.SetToolTipString('Accept value')
00b6c4e3
RD
630
631 def populateCombosWithCommonDefs(self, fixedWidthOnly=None):
1e4a197e
RD
632 self._blockUpdate = True
633 try:
634 commonDefs = {'fore': [], 'face': [], 'size': []}
635
636 if self.elementLb.GetSelection() < self.commonDefsStartIdx:
637 for common in self.commonDefs.keys():
638 prop = self.getCommonDefPropType(common)
639 commonDefs[prop].append('%%(%s)%s'%(common,
640 prop=='size' and 'd' or 's'))
641
642 # Colours
643 currFg, currBg = self.fgColCb.GetValue(), self.bgColCb.GetValue()
644 self.fgColCb.Clear(); self.bgColCb.Clear()
645 for colCommonDef in commonDefs['fore']:
646 self.fgColCb.Append(colCommonDef)
647 self.bgColCb.Append(colCommonDef)
648 self.fgColCb.SetValue(currFg); self.bgColCb.SetValue(currBg)
649
650 # Font
651 if fixedWidthOnly is None:
652 fixedWidthOnly = self.fixedWidthChk.GetValue()
1e19321b 653 fontEnum = wx.FontEnumerator()
1e4a197e
RD
654 fontEnum.EnumerateFacenames(fixedWidthOnly=fixedWidthOnly)
655 fontNameList = fontEnum.GetFacenames()
1e19321b 656 fontNameList.sort()
1e4a197e
RD
657
658 currFace = self.faceCb.GetValue()
659 self.faceCb.Clear()
1e19321b 660 for colCommonDef in fontNameList+commonDefs['face']:
1e4a197e
RD
661 self.faceCb.Append(colCommonDef)
662 self.faceCb.SetValue(currFace)
663
664 # Size (XXX add std font sizes)
665 currSize = self.sizeCb.GetValue()
666 self.sizeCb.Clear()
667 for colCommonDef in commonDefs['size']:
668 self.sizeCb.Append(colCommonDef)
669 self.sizeCb.SetValue(currSize)
670 finally:
671 self._blockUpdate = False
00b6c4e3
RD
672
673 def populateStyleSelector(self):
674 numStyles = self.styleIdNames.items()
675 numStyles.sort()
676 self.styleNumLookup = {}
677 stdStart = -1
678 stdOffset = 0
679 extrOffset = 0
680 # add styles
681 for num, name in numStyles:
1e19321b 682 if num == wx.stc.STC_STYLE_DEFAULT:
1e4a197e
RD
683 self.elementLb.InsertItems([name, '----Language----'], 0)
684 self.elementLb.Append('----Standard----')
1f443284 685 stdStart = stdPos = self.elementLb.GetCount()
00b6c4e3
RD
686 else:
687 # std styles
688 if num >= 33 and num < 40:
689 self.elementLb.InsertItems([name], stdStart + stdOffset)
690 stdOffset = stdOffset + 1
691 # extra styles
1114f46e 692 elif num >= 40:
00b6c4e3
RD
693 self.elementLb.InsertItems([name], stdStart + extrOffset -1)
694 extrOffset = extrOffset + 1
695 # normal lang styles
696 else:
697 self.elementLb.Append(name)
698 self.styleNumLookup[name] = num
699
700 # add settings
1e4a197e 701 self.elementLb.Append('----Settings----')
00b6c4e3
RD
702 settings = settingsIdNames.items()
703 settings.sort();settings.reverse()
704 for num, name in settings:
705 self.elementLb.Append(name)
706 self.styleNumLookup[name] = num
707
708 # add definitions
1e4a197e 709 self.elementLb.Append('----Common----')
1f443284 710 self.commonDefsStartIdx = self.elementLb.GetCount()
00b6c4e3
RD
711 for common in self.commonDefs.keys():
712 tpe = type(self.commonDefs[common])
713 self.elementLb.Append('%('+common+')'+(tpe is type('') and 's' or 'd'))
714 self.styleNumLookup[common] = num
1114f46e 715
00b6c4e3
RD
716#---Colour methods--------------------------------------------------------------
717 def getColourDlg(self, colour, title=''):
1e19321b 718 data = wx.ColourData()
00b6c4e3 719 data.SetColour(colour)
1e4a197e 720 data.SetChooseFull(True)
1e19321b 721 dlg = wx.ColourDialog(self, data)
00b6c4e3
RD
722 try:
723 dlg.SetTitle(title)
1e19321b 724 if dlg.ShowModal() == wx.ID_OK:
00b6c4e3
RD
725 data = dlg.GetColourData()
726 return data.GetColour()
727 finally:
728 dlg.Destroy()
729 return None
730
731 colDlgTitles = {'fore': 'Foreground', 'back': 'Background'}
732 def editColProp(self, colBtn, colCb, prop):
1114f46e 733 col = self.getColourDlg(colBtn.GetBackgroundColour(),
00b6c4e3 734 self.colDlgTitles[prop]+ ' colour')
1114f46e 735 if col:
1e19321b 736 colBtn.SetForegroundColour(wx.Colour(0, 0, 0))
00b6c4e3
RD
737 colBtn.SetBackgroundColour(col)
738 colStr = colToStr(col)
739 colCb.SetValue(colStr)
1e4a197e 740 self.editProp(True, prop, colStr)
00b6c4e3
RD
741
742 def OnFgcolbtnButton(self, event):
743 self.editColProp(self.fgColBtn, self.fgColCb, 'fore')
744
745 def OnBgcolbtnButton(self, event):
746 self.editColProp(self.bgColBtn, self.bgColCb, 'back')
747
1e4a197e
RD
748 def editColTCProp(self, colCb, colBtn, prop, val=None):
749 if val is None:
750 colStr = colCb.GetValue()
751 else:
752 colStr = val
1114f46e 753 if colStr:
00b6c4e3
RD
754 col = strToCol(colStr%self.commonDefs)
755 if self.editProp(colStr!='', prop, colStr):
1114f46e 756 if colStr:
1e19321b 757 colBtn.SetForegroundColour(wx.Colour(0, 0, 0))
00b6c4e3
RD
758 colBtn.SetBackgroundColour(col)
759 else:
1e19321b 760 colBtn.SetForegroundColour(wx.Colour(255, 255, 255))
00b6c4e3 761 colBtn.SetBackgroundColour(\
1e19321b 762 wxSystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
00b6c4e3
RD
763
764 def OnfgColRet(self, event):
765 try: self.editColTCProp(self.fgColCb, self.fgColBtn, 'fore')
1e19321b 766 except AssertionError: wx.LogError('Not a valid colour value')
00b6c4e3 767
1e4a197e
RD
768 def OnfgColCombobox(self, event):
769 if self._blockUpdate: return
770 try: self.editColTCProp(self.fgColCb, self.fgColBtn, 'fore', event.GetString())
1e19321b 771 except AssertionError: wx.LogError('Not a valid colour value')
1e4a197e 772
00b6c4e3
RD
773 def OnbgColRet(self, event):
774 try: self.editColTCProp(self.bgColCb, self.bgColBtn, 'back')
1e19321b 775 except AssertionError: wx.LogError('Not a valid colour value')
00b6c4e3 776
1e4a197e
RD
777 def OnbgColCombobox(self, event):
778 if self._blockUpdate: return
779 try: self.editColTCProp(self.bgColCb, self.bgColBtn, 'back', event.GetString())
1e19321b 780 except AssertionError: wx.LogError('Not a valid colour value')
1e4a197e 781
00b6c4e3
RD
782#---Text attribute events-------------------------------------------------------
783 def OnTaeoffilledcbCheckbox(self, event):
784 self.editProp(event.IsChecked(), 'eolfilled')
785
786 def OnTaitaliccbCheckbox(self, event):
787 self.editProp(event.IsChecked(), 'italic')
788
789 def OnTaboldcbCheckbox(self, event):
790 self.editProp(event.IsChecked(), 'bold')
791
792 def OnTaunderlinedcbCheckbox(self, event):
793 self.editProp(event.IsChecked(), 'underline')
794
795 def OnGotoCommonDef(self, event):
796 val = event.GetEventObject().GetValue()
797 if self.valIsCommonDef(val):
798 idx = self.elementLb.FindString(val)
799 if idx != -1:
1e4a197e 800 self.elementLb.SetSelection(idx, True)
00b6c4e3
RD
801 self.OnElementlbListbox(None)
802
803 def OnfaceRet(self, event):
1e4a197e
RD
804 self.setFace(self.faceCb.GetValue())
805
806 def OnfaceCombobox(self, event):
807 if self._blockUpdate: return
808 self.setFace(event.GetString())
809
810 def setFace(self, val):
00b6c4e3 811 try: val%self.commonDefs
1e19321b 812 except KeyError: wx.LogError('Invalid common definition')
00b6c4e3
RD
813 else: self.editProp(val!='', 'face', val)
814
815 def OnsizeRet(self, event):
1e4a197e
RD
816 self.setSize(self.sizeCb.GetValue())
817
818 def OnsizeCombobox(self, event):
819 if self._blockUpdate: return
820 self.setSize(event.GetString())
821
822 def setSize(self, val):
00b6c4e3 823 try: int(val%self.commonDefs)
1e19321b
RD
824 except ValueError: wx.LogError('Not a valid integer size value')
825 except KeyError: wx.LogError('Invalid common definition')
00b6c4e3
RD
826 else: self.editProp(val!='', 'size', val)
827
828#---Main GUI events-------------------------------------------------------------
829 def OnElementlbListbox(self, event):
830 isCommon = self.elementLb.GetSelection() >= self.commonDefsStartIdx
831 self.removeCommonItemBtn.Enable(isCommon)
832
833 styleIdent = self.elementLb.GetStringSelection()
834 # common definition selected
835 if isCommon:
836 common = styleIdent[2:-2]
837 prop = self.getCommonDefPropType(common)
1e4a197e 838 self.clearCtrls(disableDefs=True)
00b6c4e3 839 if prop == 'fore':
1e4a197e
RD
840 self.fgColBtn.Enable(True)
841 self.fgColCb.Enable(True)
842 self.fgColOkBtn.Enable(True)
00b6c4e3 843 elif prop == 'face':
1e4a197e
RD
844 self.faceCb.Enable(True)
845 self.fixedWidthChk.Enable(True)
846 self.faceOkBtn.Enable(True)
00b6c4e3 847 elif prop == 'size':
1e4a197e
RD
848 self.sizeCb.Enable(True)
849 self.sizeOkBtn.Enable(True)
00b6c4e3
RD
850
851 commonDefVal = str(self.commonDefs[common])
852 self.styleDefST.SetLabel(commonDefVal)
1e4a197e 853 self.populateProp( [(prop, commonDefVal)], True)
00b6c4e3
RD
854
855 self.styleNum = 'common'
856 self.style = [common, prop, commonDefVal]
857 self.names, self.values = [prop], {prop: commonDefVal}
1114f46e 858
00b6c4e3
RD
859 # normal style element selected
860 elif len(styleIdent) >=2 and styleIdent[:2] != '--':
861 self.styleNum = self.styleNumLookup[styleIdent]
862 self.style = self.styleDict[self.styleNum]
863 self.names, self.values = parseProp(self.style)
1e19321b 864 if self.styleNum == wx.stc.STC_STYLE_DEFAULT:
00b6c4e3
RD
865 self.defNames, self.defValues = \
866 self.names, self.values
867
868 self.checkBraces(self.styleNum)
1114f46e 869
00b6c4e3 870 self.styleDefST.SetLabel(self.style)
1114f46e 871
00b6c4e3
RD
872 self.populateCtrls()
873 # separator selected
874 else:
1e4a197e 875 self.clearCtrls(disableDefs=True)
00b6c4e3
RD
876 if styleIdent:
877 self.styleDefST.SetLabel(styleCategoryDescriptions[styleIdent])
878
879 self.populateCombosWithCommonDefs()
1114f46e 880
00b6c4e3 881 def OnDefaultCheckBox(self, event):
1e4a197e
RD
882 if self.chbIdMap.has_key(event.GetId()):
883 ctrl, chb, prop, wid = self.chbIdMap[event.GetId()]
884 restore = not event.IsChecked()
885 if prop in ('fore', 'back'):
886 cbtn, cmb, btn = ctrl
887 cbtn.Enable(restore)
888 cmb.Enable(restore)
889 btn.Enable(restore)
890 if restore:
891 colStr = cmb.GetValue()
892 #if prop == 'fore': colStr = self.fgColCb.GetValue()
893 #else: colStr = self.bgColCb.GetValue()
894 if colStr: self.editProp(True, prop, colStr)
895 else:
896 self.editProp(False, prop)
897 elif prop == 'size':
898 cmb, btn = ctrl
899 val = cmb.GetValue()
900 if val: self.editProp(restore, prop, val)
901 cmb.Enable(restore)
902 btn.Enable(restore)
903 elif prop == 'face':
904 cmb, btn, chk = ctrl
905 val = cmb.GetStringSelection()
906 if val: self.editProp(restore, prop, val)
907 cmb.Enable(restore)
908 btn.Enable(restore)
909 chk.Enable(restore)
910 elif prop in ('bold', 'italic', 'underline', 'eolfilled'):
911 ctrl.Enable(restore)
912 if ctrl.GetValue(): self.editProp(restore, prop)
00b6c4e3
RD
913
914 def OnOkbtnButton(self, event):
915 # write styles and common defs to the config
1e19321b 916 wx.BeginBusyCursor()
1e4a197e
RD
917 try:
918 writeStylesToConfig(self.config, 'style.%s'%self.lang, self.styles)
919 self.config.SetPath('')
920 self.config.Write(commonDefsFile, `self.commonDefs`)
921 self.config.Flush()
922
923 for stc in self.STCsToUpdate:
924 setSTCStyles(stc, self.styles, self.styleIdNames, self.commonDefs,
925 self.lang, self.lexer, self.keywords)
926 finally:
1e19321b
RD
927 wx.EndBusyCursor()
928 self.EndModal(wx.ID_OK)
00b6c4e3
RD
929
930 def OnCancelbtnButton(self, event):
1e19321b 931 self.EndModal(wx.ID_CANCEL)
00b6c4e3
RD
932
933 def OnCommondefsbtnButton(self, event):
1e19321b 934 dlg = wx.TextEntryDialog(self, 'Edit common definitions dictionary',
00b6c4e3 935 'Common definitions', pprint.pformat(self.commonDefs),
1e19321b 936 style=wx.TE_MULTILINE | wx.OK | wx.CANCEL | wx.CENTRE)
00b6c4e3 937 try:
1e19321b
RD
938 if dlg.ShowModal() == wx.ID_OK:
939 answer = eval(dlg.GetValue(), stc.__dict__)
00b6c4e3
RD
940 assert type(answer) is type({}), 'Not a valid dictionary'
941 oldDefs = self.commonDefs
942 self.commonDefs = answer
943 try:
944 self.setStyles()
945 except KeyError, badkey:
1e19321b 946 wx.LogError(str(badkey)+' not defined but required, \n'\
00b6c4e3
RD
947 'reverting to previous common definition')
948 self.commonDefs = oldDefs
949 self.setStyles()
950 self.populateCombosWithCommonDefs()
1114f46e 951
00b6c4e3
RD
952 finally:
953 dlg.Destroy()
954
955 def OnSpeedsettingchChoice(self, event):
956 group = event.GetString()
957 if group:
958 userStyles = 'style.%s'%self.lang
959 if self.currSpeedSetting == userStyles:
960 self.predefStyleGroups[userStyles] = self.styles
961 self.styles = self.predefStyleGroups[group]
962 self.setStyles()
963 self.defNames, self.defValues = parseProp(\
1e19321b 964 self.styleDict.get(wx.stc.STC_STYLE_DEFAULT, ''))
00b6c4e3
RD
965 self.OnElementlbListbox(None)
966 self.currSpeedSetting = group
967
968 def OnFixedwidthchkCheckbox(self, event):
1e19321b 969 self.populateCombosWithCommonDefs(event.IsChecked())
00b6c4e3
RD
970
971 def OnAddsharebtnButton(self, event):
972 dlg = CommonDefDlg(self)
973 try:
1e19321b 974 if dlg.ShowModal() == wx.ID_OK:
00b6c4e3
RD
975 prop, name = dlg.result
976 if not self.commonDefs.has_key(name):
977 self.commonDefs[name] = commonPropDefs[prop]
978 self.elementLb.Append('%('+name+')'+\
979 (type(commonPropDefs[prop]) is type('') and 's' or 'd'))
1f443284 980 self.elementLb.SetSelection(self.elementLb.GetCount()-1, True)
00b6c4e3
RD
981 self.populateCombosWithCommonDefs()
982 self.OnElementlbListbox(None)
983 finally:
984 dlg.Destroy()
985
986 def OnRemovesharebtnButton(self, event):
987 ownGroup = 'style.%s'%self.lang
1114f46e
RD
988 comDef = self.elementLb.GetStringSelection()
989
00b6c4e3
RD
990 # Search ALL styles before removing
991 srchDct = {ownGroup: self.styles}
992 srchDct.update(self.predefStyleGroups)
993 srchDct.update(self.otherLangStyleGroups)
994
995 matchList = []
996 for grpName, styles in srchDct.items():
997 if self.findInStyles(comDef, styles):
998 matchList.append(grpName)
999
1000 if matchList:
1e19321b 1001 wx.LogError('Aborted: '+comDef+' is still used in the styles of the \n'\
00b6c4e3 1002 'following groups in the config file (stc-styles.rc.cfg):\n'+ \
1e19321b 1003 '\n'.join(matchList))
00b6c4e3
RD
1004 else:
1005 del self.commonDefs[comDef[2:-2]]
1006 self.setStyles()
1007 self.populateCombosWithCommonDefs()
1008 selIdx = self.elementLb.GetSelection()
1009 self.elementLb.Delete(selIdx)
1f443284 1010 if selIdx == self.elementLb.GetCount():
00b6c4e3 1011 selIdx = selIdx - 1
1e4a197e 1012 self.elementLb.SetSelection(selIdx, True)
00b6c4e3
RD
1013 self.OnElementlbListbox(None)
1014
1015#---STC events------------------------------------------------------------------
1016 def OnUpdateUI(self, event):
1e4a197e
RD
1017 styleBefore = self.stc.GetStyleAt(self.stc.GetCurrentPos())
1018 if self.styleIdNames.has_key(styleBefore):
1019 self.elementLb.SetStringSelection(self.styleIdNames[styleBefore],
1020 True)
1021 else:
1022 self.elementLb.SetSelection(0, False)
1023 self.styleDefST.SetLabel('Style %d not defined, sorry.'%styleBefore)
1024 self.OnElementlbListbox(None)
00b6c4e3
RD
1025 event.Skip()
1026
1027 def checkBraces(self, style):
1e19321b 1028 if style == wx.stc.STC_STYLE_BRACELIGHT and self.braceInfo.has_key('good'):
00b6c4e3
RD
1029 line, col = self.braceInfo['good']
1030 pos = self.stc.PositionFromLine(line-1) + col
1031 braceOpposite = self.stc.BraceMatch(pos)
1032 if braceOpposite != -1:
1033 self.stc.BraceHighlight(pos, braceOpposite)
1e19321b 1034 elif style == wx.stc.STC_STYLE_BRACEBAD and self.braceInfo.has_key('bad'):
00b6c4e3
RD
1035 line, col = self.braceInfo['bad']
1036 pos = self.stc.PositionFromLine(line-1) + col
1037 self.stc.BraceBadLight(pos)
1038 else:
1039 self.stc.BraceBadLight(-1)
1040 return
1041
1042 def OnStcstyleeditdlgSize(self, event):
1043 self.Layout()
1044 # Without this refresh, resizing leaves artifacts
1045 self.Refresh(1)
1046 event.Skip()
1047
1048 def OnMarginClick(self, event):
1e4a197e 1049 self.elementLb.SetStringSelection('Line numbers', True)
00b6c4e3
RD
1050 self.OnElementlbListbox(None)
1051
1114f46e 1052
00b6c4e3
RD
1053#---Common definition dialog----------------------------------------------------
1054
1e19321b 1055[wxID_COMMONDEFDLG, wxID_COMMONDEFDLGCANCELBTN, wxID_COMMONDEFDLGCOMDEFNAMETC, wxID_COMMONDEFDLGOKBTN, wxID_COMMONDEFDLGPROPTYPERBX, wxID_COMMONDEFDLGSTATICBOX1] = [wx.NewId() for _init_ctrls in range(6)]
00b6c4e3 1056
1e19321b 1057class CommonDefDlg(wx.Dialog):
00b6c4e3 1058 def _init_ctrls(self, prnt):
1e19321b
RD
1059 wx.Dialog.__init__(self, id = wxID_COMMONDEFDLG, name = 'CommonDefDlg', parent = prnt, pos = wx.Point(398, 249), size = wx.Size(192, 220), style= wx.DEFAULT_DIALOG_STYLE, title = 'Common definition')
1060 self.SetClientSize(wx.Size(184, 200))
00b6c4e3 1061
1e19321b 1062 self.propTypeRBx = wx.RadioBox(choices = ['Colour value', 'Font face', 'Size value'], id = wxID_COMMONDEFDLGPROPTYPERBX, label = 'Property type', majorDimension = 1, name = 'propTypeRBx', parent = self, point = wx.Point(8, 8), size = wx.Size(168, 92), style= wx.RA_SPECIFY_COLS)
00b6c4e3
RD
1063 self.propTypeRBx.SetSelection(self._propTypeIdx)
1064
1e19321b 1065 self.staticBox1 = wx.StaticBox(id = wxID_COMMONDEFDLGSTATICBOX1, label = 'Name', name = 'staticBox1', parent = self, pos = wx.Point(8, 108), size = wx.Size(168, 46), style = 0)
00b6c4e3 1066
1e19321b 1067 self.comDefNameTC = wx.TextCtrl(id = wxID_COMMONDEFDLGCOMDEFNAMETC, name = 'comDefNameTC', parent = self, pos = wx.Point(16, 124), size = wx.Size(152, 21), style = 0, value = '')
00b6c4e3
RD
1068 self.comDefNameTC.SetLabel(self._comDefName)
1069
1e19321b
RD
1070 self.okBtn = wx.Button(id = wxID_COMMONDEFDLGOKBTN, label = 'OK', name = 'okBtn', parent = self, pos = wx.Point(8, 164), size = wx.Size(80, 23), style = 0)
1071 self.okBtn.Bind(wx.EVT_BUTTON, self.OnOkbtnButton, id=wxID_COMMONDEFDLGOKBTN)
00b6c4e3 1072
1e19321b
RD
1073 self.cancelBtn = wx.Button(id = wxID_COMMONDEFDLGCANCELBTN, label = 'Cancel', name = 'cancelBtn', parent = self, pos = wx.Point(96, 164), size = wx.Size(80, 23), style = 0)
1074 self.cancelBtn.Bind(wx.EVT_BUTTON, self.OnCancelbtnButton, id=wxID_COMMONDEFDLGCANCELBTN)
00b6c4e3
RD
1075
1076 def __init__(self, parent, name='', propIdx=0):
1077 self._comDefName = ''
1078 self._comDefName = name
1079 self._propTypeIdx = 0
1080 self._propTypeIdx = propIdx
1081 self._init_ctrls(parent)
1114f46e
RD
1082
1083 self.propMap = {0: 'fore', 1: 'face', 2: 'size'}
00b6c4e3
RD
1084 self.result = ( '', '' )
1085
1e19321b 1086 self.Center(wx.BOTH)
00b6c4e3
RD
1087
1088 def OnOkbtnButton(self, event):
1089 self.result = ( self.propMap[self.propTypeRBx.GetSelection()],
1090 self.comDefNameTC.GetValue() )
1e19321b 1091 self.EndModal(wx.ID_OK)
00b6c4e3
RD
1092
1093 def OnCancelbtnButton(self, event):
1094 self.result = ( '', '' )
1e19321b 1095 self.EndModal(wx.ID_CANCEL)
1114f46e 1096
00b6c4e3 1097#---Functions useful outside of the editor----------------------------------
1114f46e 1098
00b6c4e3
RD
1099def setSelectionColour(stc, style):
1100 names, values = parseProp(style)
1101 if 'fore' in names:
1e4a197e 1102 stc.SetSelForeground(True, strToCol(values['fore']))
00b6c4e3 1103 if 'back' in names:
1e4a197e 1104 stc.SetSelBackground(True, strToCol(values['back']))
00b6c4e3
RD
1105
1106def setCursorColour(stc, style):
1107 names, values = parseProp(style)
1108 if 'fore' in names:
1109 stc.SetCaretForeground(strToCol(values['fore']))
1110
1111def setEdgeColour(stc, style):
1112 names, values = parseProp(style)
1113 if 'fore' in names:
1114 stc.SetEdgeColour(strToCol(values['fore']))
1115
1116def strToCol(strCol):
1e19321b
RD
1117 assert len(strCol) == 7 and strCol[0] == '#', 'Not a valid colour string: '+strCol
1118 return wx.Colour(string.atoi('0x'+strCol[1:3], 16),
1114f46e 1119 string.atoi('0x'+strCol[3:5], 16),
00b6c4e3
RD
1120 string.atoi('0x'+strCol[5:7], 16))
1121def colToStr(col):
1114f46e 1122 return '#%s%s%s' % (string.zfill(string.upper(hex(col.Red())[2:]), 2),
00b6c4e3
RD
1123 string.zfill(string.upper(hex(col.Green())[2:]), 2),
1124 string.zfill(string.upper(hex(col.Blue())[2:]), 2))
1125
1126def writeProp(num, style, lang):
1127 if num >= 0:
1128 return 'style.%s.%s='%(lang, string.zfill(`num`, 3)) + style
1129 else:
1130 return 'setting.%s.%d='%(lang, num) + style
1131
1132def writePropVal(names, values):
1133 res = []
1134 for name in names:
1135 if name:
1136 res.append(values[name] and name+':'+values[name] or name)
1e19321b 1137 return ','.join(res)
00b6c4e3
RD
1138
1139def parseProp(prop):
1e19321b 1140 items = prop.split(',')
00b6c4e3
RD
1141 names = []
1142 values = {}
1143 for item in items:
1e19321b
RD
1144 nameVal = item.split(':')
1145 names.append(nameVal[0].strip())
00b6c4e3
RD
1146 if len(nameVal) == 1:
1147 values[nameVal[0]] = ''
1148 else:
1e19321b 1149 values[nameVal[0]] = nameVal[1].strip()
00b6c4e3 1150 return names, values
1114f46e 1151
00b6c4e3 1152def parsePropLine(prop):
1e19321b
RD
1153 name, value = prop.split('=')
1154 return int(name.split('.')[-1]), value
00b6c4e3
RD
1155
1156def setSTCStyles(stc, styles, styleIdNames, commonDefs, lang, lexer, keywords):
1157 styleDict = {}
1158 styleNumIdxMap = {}
1159
1160 # build style dict based on given styles
1161 for numStyle in styles:
1162 num, style = parsePropLine(numStyle)
1163 styleDict[num] = style
1164
1165 # Add blank style entries for undefined styles
1166 newStyles = []
1167 styleItems = styleIdNames.items() + settingsIdNames.items()
1168 styleItems.sort()
1169 idx = 0
1170 for num, name in styleItems:
1171 styleNumIdxMap[num] = idx
1172 if not styleDict.has_key(num):
1173 styleDict[num] = ''
1174 newStyles.append(writeProp(num, styleDict[num], lang))
1175 idx = idx + 1
1176
1e4a197e
RD
1177 # Set background colour to reduce flashing effect on refresh or page switch
1178 bkCol = None
1179 if styleDict.has_key(0): prop = styleDict[0]
1e19321b 1180 else: prop = styleDict[wx.stc.STC_STYLE_DEFAULT]
1e4a197e
RD
1181 names, vals = parseProp(prop)
1182 if 'back' in names:
1e19321b 1183 bkCol = strToCol(vals['back']%commonDefs)
1e4a197e 1184 if bkCol is None:
1e19321b 1185 bkCol = wx.WHITE
1e4a197e
RD
1186 stc.SetBackgroundColour(bkCol)
1187
00b6c4e3
RD
1188 # Set the styles on the wxSTC
1189 stc.StyleResetDefault()
1190 stc.ClearDocumentStyle()
1191 stc.SetLexer(lexer)
1192 stc.SetKeyWords(0, keywords)
1e19321b
RD
1193 stc.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT,
1194 styleDict[wx.stc.STC_STYLE_DEFAULT] % commonDefs)
00b6c4e3
RD
1195 stc.StyleClearAll()
1196
1197 for num, style in styleDict.items():
1198 if num >= 0:
1199 stc.StyleSetSpec(num, style % commonDefs)
1200 elif num == -1:
1201 setSelectionColour(stc, style % commonDefs)
1202 elif num == -2:
1203 setCursorColour(stc, style % commonDefs)
1204 elif num == -3:
1205 setEdgeColour(stc, style % commonDefs)
1206
1207 stc.Colourise(0, stc.GetTextLength())
1114f46e 1208
00b6c4e3
RD
1209 return newStyles, styleDict, styleNumIdxMap
1210
1211#---Config reading and writing -------------------------------------------------
1e19321b 1212commonDefsFile = 'common.defs.%s'%(platformSettings[wx.Platform][0])
00b6c4e3 1213
1e4a197e 1214def readPyValFromConfig(conf, name):
1e19321b
RD
1215 ns = {}
1216 #ns.update(wx.stc.__dict__)
1217 ns.update(wxPython.stc.__dict__)
1218 ns['wx'] = wx
1219 value = conf.Read(name).replace('\r\n', '\n')+'\n'
1220 try:
1221 return eval(value, ns)
1222 except:
1223 print value
1224 raise
1e4a197e 1225
00b6c4e3 1226def initFromConfig(configFile, lang):
1e19321b
RD
1227 if not os.path.exists(configFile):
1228 raise Exception, 'Config file %s not found'%configFile
1229 cfg = wx.FileConfig(localFilename=configFile, style= wx.CONFIG_USE_LOCAL_FILE)
1e4a197e 1230 cfg.SetExpandEnvVars(False)
00b6c4e3
RD
1231
1232 # read in all group names for this language
1233 groupPrefix = 'style.%s'%lang
1234 gpLen = len(groupPrefix)
1235 predefStyleGroupNames, otherLangStyleGroupNames = [], []
1236 cont, val, idx = cfg.GetFirstGroup()
1237 while cont:
1238 if val != groupPrefix and len(val) >= 5 and val[:5] == 'style':
1239 if len(val) > gpLen and val[:gpLen] == groupPrefix:
1240 predefStyleGroupNames.append(val)
1241 else:
1242 otherLangStyleGroupNames.append(val)
1114f46e 1243
00b6c4e3 1244 cont, val, idx = cfg.GetNextGroup(idx)
1114f46e 1245
00b6c4e3 1246 # read in common elements
1e4a197e 1247 commonDefs = readPyValFromConfig(cfg, commonDefsFile)
00b6c4e3
RD
1248 assert type(commonDefs) is type({}), \
1249 'Common definitions (%s) not a valid dict'%commonDefsFile
1250
1e4a197e 1251 commonStyleIdNames = readPyValFromConfig(cfg, 'common.styleidnames')
00b6c4e3
RD
1252 assert type(commonStyleIdNames) is type({}), \
1253 'Common definitions (%s) not a valid dict'%'common.styleidnames'
1254
1e19321b 1255 # Lang specific settings
1114f46e 1256 cfg.SetPath(lang)
1e4a197e 1257 styleIdNames = readPyValFromConfig(cfg, 'styleidnames')
00b6c4e3
RD
1258 assert type(commonStyleIdNames) is type({}), \
1259 'Not a valid dict [%s] styleidnames)'%lang
1260 styleIdNames.update(commonStyleIdNames)
1e4a197e 1261 braceInfo = readPyValFromConfig(cfg, 'braces')
00b6c4e3
RD
1262 assert type(commonStyleIdNames) is type({}), \
1263 'Not a valid dict [%s] braces)'%lang
1114f46e 1264
00b6c4e3 1265 displaySrc = cfg.Read('displaysrc')
1e4a197e 1266 lexer = readPyValFromConfig(cfg, 'lexer')
00b6c4e3
RD
1267 keywords = cfg.Read('keywords')
1268
1269 cfg.SetPath('')
1270
1271 # read in current styles
1272 styles = readStylesFromConfig(cfg, groupPrefix)
1273
1114f46e 1274 # read in predefined styles
00b6c4e3
RD
1275 predefStyleGroups = {}
1276 for group in predefStyleGroupNames:
1277 predefStyleGroups[group] = readStylesFromConfig(cfg, group)
1278
1279 # read in all other style sections
1280 otherLangStyleGroups = {}
1281 for group in otherLangStyleGroupNames:
1282 otherLangStyleGroups[group] = readStylesFromConfig(cfg, group)
1114f46e
RD
1283
1284 return (cfg, commonDefs, styleIdNames, styles, predefStyleGroupNames,
00b6c4e3
RD
1285 predefStyleGroups, otherLangStyleGroupNames, otherLangStyleGroups,
1286 displaySrc, lexer, keywords, braceInfo)
1287
1288def readStylesFromConfig(config, group):
1289 config.SetPath('')
1114f46e 1290 config.SetPath(group)
00b6c4e3
RD
1291 styles = []
1292 cont, val, idx = config.GetFirstEntry()
1293 while cont:
1294 styles.append(val+'='+config.Read(val))
1295 cont, val, idx = config.GetNextEntry(idx)
1296 config.SetPath('')
1297
1298 return styles
1299
1300def writeStylesToConfig(config, group, styles):
1301 config.SetPath('')
1302 config.DeleteGroup(group)
1303 config.SetPath(group)
1304
1305 for style in styles:
1e19321b
RD
1306 name, value = style.split('=')
1307 config.Write(name, value.strip())
00b6c4e3
RD
1308
1309 config.SetPath('')
1310
1311#-------------------------------------------------------------------------------
1312def initSTC(stc, config, lang):
1313 """ Main module entry point. Initialise a wxSTC from given config file."""
1114f46e 1314 (cfg, commonDefs, styleIdNames, styles, predefStyleGroupNames,
00b6c4e3
RD
1315 predefStyleGroups, otherLangStyleGroupNames, otherLangStyleGroups,
1316 displaySrc, lexer, keywords, braceInfo) = initFromConfig(config, lang)
1114f46e 1317
00b6c4e3
RD
1318 setSTCStyles(stc, styles, styleIdNames, commonDefs, lang, lexer, keywords)
1319
1320#-------------------------------------------------------------------------------
1321if __name__ == '__main__':
1e19321b 1322 app = wx.PySimpleApp()
1e4a197e 1323
1e19321b
RD
1324 provider = wx.SimpleHelpProvider()
1325 wx.HelpProvider.Set(provider)
1114f46e 1326
1e19321b
RD
1327 home = os.environ.get('HOME')
1328 if home:
1329 home = os.path.join(home, '.boa-constructor')
1330 if not os.path.exists(home):
1331 home = '.'
1332 else:
1333 home = '.'
1e4a197e 1334
1e19321b 1335 config = os.path.abspath(os.path.join(home, 'stc-styles.rc.cfg'))
00b6c4e3 1336 if 0:
1e19321b
RD
1337 f = wx.Frame(None, -1, 'Test frame (double click for editor)')
1338 stc = wx.stc.StyledTextCtrl(f, -1)
00b6c4e3
RD
1339 def OnDblClick(evt, stc=stc):
1340 dlg = STCStyleEditDlg(None, 'Python', 'python', config, (stc,))
1341 try: dlg.ShowModal()
1342 finally: dlg.Destroy()
1343 stc.SetText(open('STCStyleEditor.py').read())
1e19321b 1344 stc.Bind(wx.EVT_LEFT_DCLICK, OnDblClick)
00b6c4e3 1345 initSTC(stc, config, 'python')
1e4a197e 1346 f.Show(True)
00b6c4e3
RD
1347 app.MainLoop()
1348 else:
1114f46e 1349 dlg = STCStyleEditDlg(None,
00b6c4e3
RD
1350 'Python', 'python',
1351 #'HTML', 'html',
1352 #'XML', 'xml',
1114f46e
RD
1353 #'C++', 'cpp',
1354 #'Text', 'text',
1355 #'Properties', 'prop',
00b6c4e3
RD
1356 config)
1357 try: dlg.ShowModal()
1358 finally: dlg.Destroy()