|
16 | 16 | # See the License for the specific language governing permissions and |
17 | 17 | # limitations under the License. |
18 | 18 |
|
19 | | -from __future__ import absolute_import |
20 | 19 |
|
21 | | -# |
22 | | -# from StyledTextCtrl_2 import PythonSTC |
23 | | -# ----------------------------------------------------------------- |
24 | | -# Define Python style |
25 | | -import keyword |
26 | 20 | import os |
27 | 21 | import sys |
28 | 22 |
|
29 | 23 | import wx |
30 | 24 | import wx.stc as stc |
| 25 | +from .pythoneditor import PythonSTC |
31 | 26 | from wx import Colour |
32 | 27 |
|
33 | | -if wx.Platform == '__WXMSW__': |
34 | | - faces = {'times': 'Times New Roman', |
35 | | - 'mono': 'Courier New', |
36 | | - 'helv': 'Arial', |
37 | | - 'other': 'Comic Sans MS', |
38 | | - 'size': 10, |
39 | | - 'size2': 8, |
40 | | - } |
41 | | -elif wx.Platform == '__WXMAC__': |
42 | | - faces = {'times': 'Times New Roman', |
43 | | - 'mono': 'Monaco', |
44 | | - 'helv': 'Arial', |
45 | | - 'other': 'Comic Sans MS', |
46 | | - 'size': 12, |
47 | | - 'size2': 10, |
48 | | - } |
49 | | -else: |
50 | | - faces = {'times': 'Times', |
51 | | - 'mono': 'Courier', |
52 | | - 'helv': 'Helvetica', |
53 | | - 'other': 'new century schoolbook', |
54 | | - 'size': 12, |
55 | | - 'size2': 10, |
56 | | - } |
57 | | - |
58 | 28 | # --------------------------------------------------------------------------- |
59 | 29 | # This is how you pre-establish a file filter so that the dialog |
60 | 30 | # only shows the extension(s) you want it to. |
|
66 | 36 | "YAML file (*.yaml)|*.yaml" |
67 | 37 | # ---------------------------------------------------------------------- |
68 | 38 |
|
69 | | - |
70 | | -class PythonSTC(stc.StyledTextCtrl): |
71 | | - |
72 | | - fold_symbols = 2 |
73 | | - |
74 | | - def __init__(self, parent, idd, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): |
75 | | - stc.StyledTextCtrl.__init__(self, parent, idd, pos, size, style) |
76 | | - |
77 | | - self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN) |
78 | | - self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT) |
79 | | - |
80 | | - self.SetLexer(stc.STC_LEX_PYTHON) |
81 | | - self.SetKeyWords(0, " ".join(keyword.kwlist)) |
82 | | - |
83 | | - self.SetProperty("fold", "1") |
84 | | - self.SetProperty("tab.timmy.whinge.level", "1") |
85 | | - self.SetMargins(0, 0) |
86 | | - |
87 | | - self.SetViewWhiteSpace(False) |
88 | | - self.SetEdgeMode(stc.STC_EDGE_BACKGROUND) |
89 | | - self.SetEdgeColumn(78) |
90 | | - |
91 | | - # Set up a margin to hold fold markers |
92 | | - # self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER? |
93 | | - self.SetMarginType(2, stc.STC_MARGIN_SYMBOL) |
94 | | - self.SetMarginMask(2, stc.STC_MASK_FOLDERS) |
95 | | - self.SetMarginSensitive(2, True) |
96 | | - self.SetMarginWidth(2, 12) |
97 | | - |
98 | | - if self.fold_symbols == 0: |
99 | | - # Arrow pointing right for contracted folders, arrow pointing down for expanded |
100 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black") |
101 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_ARROW, "black", "black") |
102 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black") |
103 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "black", "black") |
104 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black") |
105 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black") |
106 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black") |
107 | | - |
108 | | - elif self.fold_symbols == 1: |
109 | | - # Plus for contracted folders, minus for expanded |
110 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black") |
111 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_PLUS, "white", "black") |
112 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "white", "black") |
113 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black") |
114 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black") |
115 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black") |
116 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black") |
117 | | - |
118 | | - elif self.fold_symbols == 2: |
119 | | - # Like a flattened tree control using circular headers and curved joins |
120 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_CIRCLEMINUS, "white", "#404040") |
121 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_CIRCLEPLUS, "white", "#404040") |
122 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#404040") |
123 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040") |
124 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040") |
125 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040") |
126 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE, "white", "#404040") |
127 | | - |
128 | | - elif self.fold_symbols == 3: |
129 | | - # Like a flattened tree control using square headers |
130 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "#808080") |
131 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "#808080") |
132 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#808080") |
133 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080") |
134 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080") |
135 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080") |
136 | | - self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080") |
137 | | - |
138 | | - self.Bind(stc.EVT_STC_UPDATEUI, self.on_update_ui) |
139 | | - self.Bind(stc.EVT_STC_MARGINCLICK, self.on_margin_click) |
140 | | - self.Bind(wx.EVT_KEY_DOWN, self.on_key_pressed) |
141 | | - |
142 | | - # Make some styles, The lexer defines what each style is used for, we |
143 | | - # just have to define what each style looks like. This set is adapted from |
144 | | - # Scintilla sample property files. |
145 | | - |
146 | | - # Global default styles for all languages |
147 | | - self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces) |
148 | | - self.StyleClearAll() # Reset all to be like the default |
149 | | - |
150 | | - # Global default styles for all languages |
151 | | - self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces) |
152 | | - self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces) |
153 | | - self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces) |
154 | | - self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold") |
155 | | - self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold") |
156 | | - |
157 | | - # Python styles |
158 | | - # Default |
159 | | - self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces) |
160 | | - # Comments |
161 | | - self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces) |
162 | | - # Number |
163 | | - self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
164 | | - # String |
165 | | - self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces) |
166 | | - # Single quoted string |
167 | | - self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces) |
168 | | - # Keyword |
169 | | - self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
170 | | - # Triple quotes |
171 | | - self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces) |
172 | | - # Triple double quotes |
173 | | - self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces) |
174 | | - # Class name definition |
175 | | - self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces) |
176 | | - # Function or method name definition |
177 | | - self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces) |
178 | | - # Operators |
179 | | - self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces) |
180 | | - # Identifiers |
181 | | - self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces) |
182 | | - # Comment-blocks |
183 | | - self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces) |
184 | | - # End of line where string is not closed |
185 | | - self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces) |
186 | | - |
187 | | - self.SetCaretForeground("BLUE") |
188 | | - |
189 | | - # register some images for use in the AutoComplete box. |
190 | | - # self.RegisterImage(1, Smiles.GetBitmap()) # DEBUG was images. |
191 | | - self.RegisterImage(1, wx.ArtProvider.GetBitmap(wx.ART_FLOPPY, size=(16, 16))) |
192 | | - self.RegisterImage(2, wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16, 16))) |
193 | | - self.RegisterImage(3, wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16, 16))) |
194 | | - |
195 | | - def on_key_pressed(self, event): |
196 | | - if self.CallTipActive(): |
197 | | - self.CallTipCancel() |
198 | | - key = event.GetKeyCode() |
199 | | - |
200 | | - if key == 32 and event.ControlDown(): |
201 | | - pos = self.GetCurrentPos() |
202 | | - |
203 | | - # Tips |
204 | | - if event.ShiftDown(): |
205 | | - self.CallTipSetBackground("yellow") |
206 | | - self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n' |
207 | | - 'show some suff, maybe parameters..\n\n' |
208 | | - 'fubar(param1, param2)') |
209 | | - # Code completion |
210 | | - else: |
211 | | - kw = list(keyword.kwlist[:]) |
212 | | - kw.append("zzzzzz?2") |
213 | | - kw.append("aaaaa?2") |
214 | | - kw.append("__init__?3") |
215 | | - kw.append("zzaaaaa?2") |
216 | | - kw.append("zzbaaaa?2") |
217 | | - kw.append("this_is_a_longer_value") |
218 | | - # kw.append("this_is_a_much_much_much_much_much_much_much_longer_value") |
219 | | - |
220 | | - kw.sort() # Python sorts are case-sensitive |
221 | | - self.AutoCompSetIgnoreCase(False) # so this needs to match |
222 | | - |
223 | | - # Images are specified with an appended "?type" |
224 | | - for i in range(len(kw)): |
225 | | - if kw[i] in keyword.kwlist: |
226 | | - kw[i] = kw[i] + "?1" |
227 | | - |
228 | | - self.AutoCompShow(0, " ".join(kw)) |
229 | | - else: |
230 | | - event.Skip() |
231 | | - |
232 | | - def on_update_ui(self, evt): |
233 | | - _ = evt |
234 | | - # check for matching braces |
235 | | - brace_at_caret = -1 |
236 | | - brace_opposite = -1 |
237 | | - char_before = style_before = None |
238 | | - caret_pos = self.GetCurrentPos() |
239 | | - |
240 | | - if caret_pos > 0: |
241 | | - char_before = self.GetCharAt(caret_pos - 1) |
242 | | - style_before = self.GetStyleAt(caret_pos - 1) |
243 | | - |
244 | | - # check before |
245 | | - if char_before and chr(char_before) in "[]{}()" and style_before == stc.STC_P_OPERATOR: |
246 | | - brace_at_caret = caret_pos - 1 |
247 | | - |
248 | | - # check after |
249 | | - if brace_at_caret < 0: |
250 | | - char_after = self.GetCharAt(caret_pos) |
251 | | - style_after = self.GetStyleAt(caret_pos) |
252 | | - |
253 | | - if char_after and chr(char_after) in "[]{}()" and style_after == stc.STC_P_OPERATOR: |
254 | | - brace_at_caret = caret_pos |
255 | | - |
256 | | - if brace_at_caret >= 0: |
257 | | - brace_opposite = self.BraceMatch(brace_at_caret) |
258 | | - |
259 | | - if brace_at_caret != -1 and brace_opposite == -1: |
260 | | - self.BraceBadLight(brace_at_caret) |
261 | | - else: |
262 | | - self.BraceHighlight(brace_at_caret, brace_opposite) |
263 | | - |
264 | | - def on_margin_click(self, evt): |
265 | | - # fold and unfold as needed |
266 | | - if evt.GetMargin() == 2: |
267 | | - if evt.GetShift() and evt.GetControl(): |
268 | | - self.FoldAll() |
269 | | - else: |
270 | | - line_clicked = self.LineFromPosition(evt.GetPosition()) |
271 | | - |
272 | | - if self.GetFoldLevel(line_clicked) & stc.STC_FOLDLEVELHEADERFLAG: |
273 | | - if evt.GetShift(): |
274 | | - self.SetFoldExpanded(line_clicked, True) |
275 | | - self.Expand(line_clicked, True, True, 1) |
276 | | - elif evt.GetControl(): |
277 | | - if self.GetFoldExpanded(line_clicked): |
278 | | - self.SetFoldExpanded(line_clicked, False) |
279 | | - self.Expand(line_clicked, False, True, 0) |
280 | | - else: |
281 | | - self.SetFoldExpanded(line_clicked, True) |
282 | | - self.Expand(line_clicked, True, True, 100) |
283 | | - else: |
284 | | - self.ToggleFold(line_clicked) |
285 | | - |
286 | | - def FoldAll(self, action=None): |
287 | | - line_count = self.GetLineCount() |
288 | | - expanding = True |
289 | | - |
290 | | - # find out if we are folding or unfolding |
291 | | - for line_num in range(line_count): |
292 | | - if self.GetFoldLevel(line_num) & stc.STC_FOLDLEVELHEADERFLAG: |
293 | | - expanding = not self.GetFoldExpanded(line_num) |
294 | | - break |
295 | | - |
296 | | - line_num = 0 |
297 | | - |
298 | | - while line_num < line_count: |
299 | | - level = self.GetFoldLevel(line_num) |
300 | | - if level & stc.STC_FOLDLEVELHEADERFLAG and \ |
301 | | - (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE: |
302 | | - |
303 | | - if expanding: |
304 | | - self.SetFoldExpanded(line_num, True) |
305 | | - line_num = self.Expand(line_num, True) |
306 | | - line_num = line_num - 1 |
307 | | - else: |
308 | | - last_child = self.GetLastChild(line_num, -1) |
309 | | - self.SetFoldExpanded(line_num, False) |
310 | | - |
311 | | - if last_child > line_num: |
312 | | - self.HideLines(line_num+1, last_child) |
313 | | - |
314 | | - line_num = line_num + 1 |
315 | | - |
316 | | - def Expand(self, line, do_expand, force=False, vis_levels=0, level=-1): |
317 | | - last_child = self.GetLastChild(line, level) |
318 | | - line = line + 1 |
319 | | - |
320 | | - while line <= last_child: |
321 | | - if force: |
322 | | - if vis_levels > 0: |
323 | | - self.ShowLines(line, line) |
324 | | - else: |
325 | | - self.HideLines(line, line) |
326 | | - else: |
327 | | - if do_expand: |
328 | | - self.ShowLines(line, line) |
329 | | - |
330 | | - if level == -1: |
331 | | - level = self.GetFoldLevel(line) |
332 | | - |
333 | | - if level & stc.STC_FOLDLEVELHEADERFLAG: |
334 | | - if force: |
335 | | - if vis_levels > 1: |
336 | | - self.SetFoldExpanded(line, True) |
337 | | - else: |
338 | | - self.SetFoldExpanded(line, False) |
339 | | - |
340 | | - line = self.Expand(line, do_expand, force, vis_levels - 1) |
341 | | - |
342 | | - else: |
343 | | - if do_expand and self.GetFoldExpanded(line): |
344 | | - line = self.Expand(line, True, force, vis_levels - 1) |
345 | | - else: |
346 | | - line = self.Expand(line, False, force, vis_levels - 1) |
347 | | - else: |
348 | | - line = line + 1 |
349 | | - |
350 | | - return line |
351 | | - |
352 | | -# ---------------------------------------------------------------------- |
353 | | - |
354 | | - |
355 | 39 | class SourceCodeEditor(PythonSTC): |
356 | 40 | def __init__(self, parent, style=wx.BORDER_NONE): |
357 | 41 | PythonSTC.__init__(self, parent, -1, style=style) |
|
0 commit comments