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:#808080,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:#808080,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 #----------------------------------------------------------------------