2 from wxPython
.wx
import *
3 from wxPython
.stc
import *
7 #----------------------------------------------------------------------
10 ## This version of the editor has been set up to edit Python source
11 ## code. Here is a copy of wxPython/demo/Main.py to play with.
16 #----------------------------------------------------------------------
19 if wxPlatform
== '__WXMSW__':
20 faces
= { 'times': 'Times New Roman',
21 'mono' : 'Courier New',
23 'other': 'Comic Sans MS',
28 faces
= { 'times': 'Times',
31 'other': 'new century schoolbook',
37 #----------------------------------------------------------------------
39 class PythonSTC(wxStyledTextCtrl
):
40 def __init__(self
, parent
, ID
):
41 wxStyledTextCtrl
.__init
__(self
, parent
, ID
,
42 style
= wxNO_FULL_REPAINT_ON_RESIZE
)
44 self
.CmdKeyAssign(ord('B'), wxSTC_SCMOD_CTRL
, wxSTC_CMD_ZOOMIN
)
45 self
.CmdKeyAssign(ord('N'), wxSTC_SCMOD_CTRL
, wxSTC_CMD_ZOOMOUT
)
47 self
.SetLexer(wxSTC_LEX_PYTHON
)
48 self
.SetKeyWords(0, " ".join(keyword
.kwlist
))
50 self
.SetProperty("fold", "1")
51 self
.SetProperty("tab.timmy.whinge.level", "1")
54 self
.SetViewWhiteSpace(False)
55 #self.SetBufferedDraw(False)
56 #self.SetViewEOL(True)
58 self
.SetEdgeMode(wxSTC_EDGE_BACKGROUND
)
59 self
.SetEdgeColumn(78)
61 # Setup a margin to hold fold markers
62 #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
63 self
.SetMarginType(2, wxSTC_MARGIN_SYMBOL
)
64 self
.SetMarginMask(2, wxSTC_MASK_FOLDERS
)
65 self
.SetMarginSensitive(2, True)
66 self
.SetMarginWidth(2, 12)
68 if 0: # simple folder marks, like the old version
69 self
.MarkerDefine(wxSTC_MARKNUM_FOLDER
, wxSTC_MARK_ARROW
, "navy", "navy")
70 self
.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN
, wxSTC_MARK_ARROWDOWN
, "navy", "navy")
71 # Set these to an invisible mark
72 self
.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID
, wxSTC_MARK_BACKGROUND
, "white", "black")
73 self
.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL
, wxSTC_MARK_BACKGROUND
, "white", "black")
74 self
.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB
, wxSTC_MARK_BACKGROUND
, "white", "black")
75 self
.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL
, wxSTC_MARK_BACKGROUND
, "white", "black")
77 else: # more involved "outlining" folder marks
78 self
.MarkerDefine(wxSTC_MARKNUM_FOLDEREND
, wxSTC_MARK_BOXPLUSCONNECTED
, "white", "black")
79 self
.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID
, wxSTC_MARK_BOXMINUSCONNECTED
, "white", "black")
80 self
.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL
, wxSTC_MARK_TCORNER
, "white", "black")
81 self
.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL
, wxSTC_MARK_LCORNER
, "white", "black")
82 self
.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB
, wxSTC_MARK_VLINE
, "white", "black")
83 self
.MarkerDefine(wxSTC_MARKNUM_FOLDER
, wxSTC_MARK_BOXPLUS
, "white", "black")
84 self
.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN
, wxSTC_MARK_BOXMINUS
, "white", "black")
87 EVT_STC_UPDATEUI(self
, ID
, self
.OnUpdateUI
)
88 EVT_STC_MARGINCLICK(self
, ID
, self
.OnMarginClick
)
89 EVT_KEY_DOWN(self
, self
.OnKeyPressed
)
92 # Make some styles, The lexer defines what each style is used for, we
93 # just have to define what each style looks like. This set is adapted from
94 # Scintilla sample property files.
98 # Global default styles for all languages
99 self
.StyleSetSpec(wxSTC_STYLE_DEFAULT
, "face:%(helv)s,size:%(size)d" % faces
)
100 self
.StyleSetSpec(wxSTC_STYLE_LINENUMBER
, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces
)
101 self
.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR
, "face:%(other)s" % faces
)
102 self
.StyleSetSpec(wxSTC_STYLE_BRACELIGHT
, "fore:#FFFFFF,back:#0000FF,bold")
103 self
.StyleSetSpec(wxSTC_STYLE_BRACEBAD
, "fore:#000000,back:#FF0000,bold")
107 self
.StyleSetSpec(wxSTC_P_DEFAULT
, "fore:#000000,face:%(helv)s,size:%(size)d" % faces
)
109 self
.StyleSetSpec(wxSTC_P_COMMENTLINE
, "fore:#007F00,face:%(other)s,size:%(size)d" % faces
)
111 self
.StyleSetSpec(wxSTC_P_NUMBER
, "fore:#007F7F,size:%(size)d" % faces
)
113 self
.StyleSetSpec(wxSTC_P_STRING
, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces
)
114 # Single quoted string
115 self
.StyleSetSpec(wxSTC_P_CHARACTER
, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces
)
117 self
.StyleSetSpec(wxSTC_P_WORD
, "fore:#00007F,bold,size:%(size)d" % faces
)
119 self
.StyleSetSpec(wxSTC_P_TRIPLE
, "fore:#7F0000,size:%(size)d" % faces
)
120 # Triple double quotes
121 self
.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE
, "fore:#7F0000,size:%(size)d" % faces
)
122 # Class name definition
123 self
.StyleSetSpec(wxSTC_P_CLASSNAME
, "fore:#0000FF,bold,underline,size:%(size)d" % faces
)
124 # Function or method name definition
125 self
.StyleSetSpec(wxSTC_P_DEFNAME
, "fore:#007F7F,bold,size:%(size)d" % faces
)
127 self
.StyleSetSpec(wxSTC_P_OPERATOR
, "bold,size:%(size)d" % faces
)
129 self
.StyleSetSpec(wxSTC_P_IDENTIFIER
, "fore:#000000,face:%(helv)s,size:%(size)d" % faces
)
131 self
.StyleSetSpec(wxSTC_P_COMMENTBLOCK
, "fore:#7F7F7F,size:%(size)d" % faces
)
132 # End of line where string is not closed
133 self
.StyleSetSpec(wxSTC_P_STRINGEOL
, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces
)
135 self
.SetCaretForeground("BLUE")
138 # register some images for use in the AutoComplete box.
139 self
.RegisterImage(1, images
.getSmilesBitmap())
140 self
.RegisterImage(2, images
.getFile1Bitmap())
141 self
.RegisterImage(3, images
.getCopy2Bitmap())
146 def OnKeyPressed(self
, event
):
147 if self
.CallTipActive():
149 key
= event
.KeyCode()
150 if key
== 32 and event
.ControlDown():
151 pos
= self
.GetCurrentPos()
153 if event
.ShiftDown():
154 self
.CallTipSetBackground("yellow")
155 self
.CallTipShow(pos
, 'lots of of text: blah, blah, blah\n\n'
156 'show some suff, maybe parameters..\n\n'
157 'fubar(param1, param2)')
161 #for x in range(50000):
162 # lst.append('%05d' % x)
165 #self.AutoCompShow(0, st)
167 kw
= keyword
.kwlist
[:]
168 kw
.append("zzzzzz?2")
170 kw
.append("__init__?3")
171 kw
.append("zzaaaaa?2")
172 kw
.append("zzbaaaa?2")
173 kw
.append("this_is_a_longer_value")
174 #kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")
176 kw
.sort() # Python sorts are case sensitive
177 self
.AutoCompSetIgnoreCase(False) # so this needs to match
179 # Images are specified with a appended "?type"
180 for i
in range(len(kw
)):
181 if kw
[i
] in keyword
.kwlist
:
184 self
.AutoCompShow(0, " ".join(kw
))
189 def OnUpdateUI(self
, evt
):
190 # check for matching braces
194 caretPos
= self
.GetCurrentPos()
196 charBefore
= self
.GetCharAt(caretPos
- 1)
197 styleBefore
= self
.GetStyleAt(caretPos
- 1)
200 if charBefore
and chr(charBefore
) in "[]{}()" and styleBefore
== wxSTC_P_OPERATOR
:
201 braceAtCaret
= caretPos
- 1
205 charAfter
= self
.GetCharAt(caretPos
)
206 styleAfter
= self
.GetStyleAt(caretPos
)
207 if charAfter
and chr(charAfter
) in "[]{}()" and styleAfter
== wxSTC_P_OPERATOR
:
208 braceAtCaret
= caretPos
210 if braceAtCaret
>= 0:
211 braceOpposite
= self
.BraceMatch(braceAtCaret
)
213 if braceAtCaret
!= -1 and braceOpposite
== -1:
214 self
.BraceBadLight(braceAtCaret
)
216 self
.BraceHighlight(braceAtCaret
, braceOpposite
)
217 #pt = self.PointFromPosition(braceOpposite)
218 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
223 def OnMarginClick(self
, evt
):
224 # fold and unfold as needed
225 if evt
.GetMargin() == 2:
226 if evt
.GetShift() and evt
.GetControl():
229 lineClicked
= self
.LineFromPosition(evt
.GetPosition())
230 if self
.GetFoldLevel(lineClicked
) & wxSTC_FOLDLEVELHEADERFLAG
:
232 self
.SetFoldExpanded(lineClicked
, True)
233 self
.Expand(lineClicked
, True, True, 1)
234 elif evt
.GetControl():
235 if self
.GetFoldExpanded(lineClicked
):
236 self
.SetFoldExpanded(lineClicked
, False)
237 self
.Expand(lineClicked
, False, True, 0)
239 self
.SetFoldExpanded(lineClicked
, True)
240 self
.Expand(lineClicked
, True, True, 100)
242 self
.ToggleFold(lineClicked
)
246 lineCount
= self
.GetLineCount()
249 # find out if we are folding or unfolding
250 for lineNum
in range(lineCount
):
251 if self
.GetFoldLevel(lineNum
) & wxSTC_FOLDLEVELHEADERFLAG
:
252 expanding
= not self
.GetFoldExpanded(lineNum
)
256 while lineNum
< lineCount
:
257 level
= self
.GetFoldLevel(lineNum
)
258 if level
& wxSTC_FOLDLEVELHEADERFLAG
and \
259 (level
& wxSTC_FOLDLEVELNUMBERMASK
) == wxSTC_FOLDLEVELBASE
:
262 self
.SetFoldExpanded(lineNum
, True)
263 lineNum
= self
.Expand(lineNum
, True)
264 lineNum
= lineNum
- 1
266 lastChild
= self
.GetLastChild(lineNum
, -1)
267 self
.SetFoldExpanded(lineNum
, False)
268 if lastChild
> lineNum
:
269 self
.HideLines(lineNum
+1, lastChild
)
271 lineNum
= lineNum
+ 1
275 def Expand(self
, line
, doExpand
, force
=False, visLevels
=0, level
=-1):
276 lastChild
= self
.GetLastChild(line
, level
)
278 while line
<= lastChild
:
281 self
.ShowLines(line
, line
)
283 self
.HideLines(line
, line
)
286 self
.ShowLines(line
, line
)
289 level
= self
.GetFoldLevel(line
)
291 if level
& wxSTC_FOLDLEVELHEADERFLAG
:
294 self
.SetFoldExpanded(line
, True)
296 self
.SetFoldExpanded(line
, False)
297 line
= self
.Expand(line
, doExpand
, force
, visLevels
-1)
300 if doExpand
and self
.GetFoldExpanded(line
):
301 line
= self
.Expand(line
, True, force
, visLevels
-1)
303 line
= self
.Expand(line
, False, force
, visLevels
-1)
310 #----------------------------------------------------------------------
314 def runTest(frame
, nb
, log
):
316 ed
= p
= PythonSTC(nb
, -1)
318 p
= wxPanel(nb
, -1, style
= wxNO_FULL_REPAINT_ON_RESIZE
)
319 ed
= PythonSTC(p
, -1)
320 s
= wxBoxSizer(wxHORIZONTAL
)
321 s
.Add(ed
, 1, wxEXPAND
)
323 p
.SetAutoLayout(True)
326 ed
.SetText(demoText
+ open('Main.py').read())
330 # line numbers in the margin
331 ed
.SetMarginType(1, wxSTC_MARGIN_NUMBER
)
332 ed
.SetMarginWidth(1, 25)
338 #----------------------------------------------------------------------
343 Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
344 and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
350 if __name__
== '__main__':
353 run
.main(['', os
.path
.basename(sys
.argv
[0])])
359 #----------------------------------------------------------------------
360 #----------------------------------------------------------------------