2 # 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net) 
   4 # o wx.TheClipboard.Flush() generates a warning on program exit. 
  12 #---------------------------------------------------------------------- 
  18 This editor is provided by a class named wx.StyledTextCtrl.  As 
  19 the name suggests, you can define styles that can be applied to 
  20 sections of text.  This will typically be used for things like 
  21 syntax highlighting code editors, but I'm sure that there are other 
  22 applications as well.  A style is a combination of font, point size, 
  23 foreground and background colours.  The editor can handle 
  24 proportional fonts just as easily as monospaced fonts, and various 
  25 styles can use different sized fonts. 
  27 There are a few canned language lexers and colourizers included, 
  28 (see the next demo) or you can handle the colourization yourself. 
  29 If you do you can simply register an event handler and the editor 
  30 will let you know when the visible portion of the text needs 
  33 wx.StyledTextEditor also supports setting markers in the margin... 
  38 ...and indicators within the text.  You can use these for whatever 
  39 you want in your application.  Cut, Copy, Paste, Drag and Drop of 
  40 text works, as well as virtually unlimited Undo and Redo 
  41 capabilities, (right click to try it out.) 
  44 if wx
.Platform 
== '__WXMSW__': 
  46     face2 
= 'Times New Roman' 
  56 #---------------------------------------------------------------------- 
  57 # This shows how to catch the Modified event from the wx.StyledTextCtrl 
  59 class MySTC(stc
.StyledTextCtrl
): 
  60     def __init__(self
, parent
, ID
, log
): 
  61         stc
.StyledTextCtrl
.__init
__(self
, parent
, ID
) 
  64         self
.Bind(stc
.EVT_STC_DO_DROP
, self
.OnDoDrop
) 
  65         self
.Bind(stc
.EVT_STC_DRAG_OVER
, self
.OnDragOver
) 
  66         self
.Bind(stc
.EVT_STC_START_DRAG
, self
.OnStartDrag
) 
  67         self
.Bind(stc
.EVT_STC_MODIFIED
, self
.OnModified
) 
  69         self
.Bind(wx
.EVT_WINDOW_DESTROY
, self
.OnDestroy
) 
  71     def OnDestroy(self
, evt
): 
  72         # This is how the clipboard contents can be preserved after 
  74         wx
.TheClipboard
.Flush() 
  78     def OnStartDrag(self
, evt
): 
  79         self
.log
.write("OnStartDrag: %d, %s\n" 
  80                        % (evt
.GetDragAllowMove(), evt
.GetDragText())) 
  82         if debug 
and evt
.GetPosition() < 250: 
  83             evt
.SetDragAllowMove(False)     # you can prevent moving of text (only copy) 
  84             evt
.SetDragText("DRAGGED TEXT") # you can change what is dragged 
  85             #evt.SetDragText("")             # or prevent the drag with empty text 
  88     def OnDragOver(self
, evt
): 
  90             "OnDragOver: x,y=(%d, %d)  pos: %d  DragResult: %d\n" 
  91             % (evt
.GetX(), evt
.GetY(), evt
.GetPosition(), evt
.GetDragResult()) 
  94         if debug 
and evt
.GetPosition() < 250: 
  95             evt
.SetDragResult(wx
.DragNone
)   # prevent dropping at the beginning of the buffer 
  98     def OnDoDrop(self
, evt
): 
  99         self
.log
.write("OnDoDrop: x,y=(%d, %d)  pos: %d  DragResult: %d\n" 
 101                        % (evt
.GetX(), evt
.GetY(), evt
.GetPosition(), evt
.GetDragResult(), 
 104         if debug 
and evt
.GetPosition() < 500: 
 105             evt
.SetDragText("DROPPED TEXT")  # Can change text if needed 
 106             #evt.SetDragResult(wx.DragNone)  # Can also change the drag operation, but it 
 107                                              # is probably better to do it in OnDragOver so 
 108                                              # there is visual feedback 
 110             #evt.SetPosition(25)             # Can also change position, but I'm not sure why 
 111                                              # you would want to... 
 116     def OnModified(self
, evt
): 
 117         self
.log
.write("""OnModified 
 122         Text:         %s\n""" % ( self
.transModType(evt
.GetModificationType()), 
 126                                   repr(evt
.GetText()) )) 
 129     def transModType(self
, modType
): 
 131         table 
= [(stc
.STC_MOD_INSERTTEXT
, "InsertText"), 
 132                  (stc
.STC_MOD_DELETETEXT
, "DeleteText"), 
 133                  (stc
.STC_MOD_CHANGESTYLE
, "ChangeStyle"), 
 134                  (stc
.STC_MOD_CHANGEFOLD
, "ChangeFold"), 
 135                  (stc
.STC_PERFORMED_USER
, "UserFlag"), 
 136                  (stc
.STC_PERFORMED_UNDO
, "Undo"), 
 137                  (stc
.STC_PERFORMED_REDO
, "Redo"), 
 138                  (stc
.STC_LASTSTEPINUNDOREDO
, "Last-Undo/Redo"), 
 139                  (stc
.STC_MOD_CHANGEMARKER
, "ChangeMarker"), 
 140                  (stc
.STC_MOD_BEFOREINSERT
, "B4-Insert"), 
 141                  (stc
.STC_MOD_BEFOREDELETE
, "B4-Delete") 
 144         for flag
,text 
in table
: 
 156 #---------------------------------------------------------------------- 
 160 def runTest(frame
, nb
, log
): 
 162         ed 
= p 
= MySTC(nb
, -1, log
) 
 165         p 
= wx
.Panel(nb
, -1, style
=wx
.NO_FULL_REPAINT_ON_RESIZE
) 
 166         ed 
= MySTC(p
, -1, log
) 
 167         s 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 168         s
.Add(ed
, 1, wx
.EXPAND
) 
 170         p
.SetAutoLayout(True) 
 173     #ed.SetBufferedDraw(False) 
 175     #ed.SetScrollWidth(800) 
 176     #ed.SetWrapMode(True) 
 177     #ed.SetUseAntiAliasing(False)     
 180     #ed.CmdKeyClear(stc.STC_KEY_BACK, 
 181     #               stc.STC_SCMOD_CTRL) 
 182     #ed.CmdKeyAssign(stc.STC_KEY_BACK, 
 183     #                stc.STC_SCMOD_CTRL, 
 184     #                stc.STC_CMD_DELWORDLEFT) 
 190         decode 
= codecs
.lookup("utf-8")[1] 
 192         ed
.GotoPos(ed
.GetLength()) 
 193         ed
.AddText("\n\nwx.StyledTextCtrl can also do Unicode:\n") 
 194         uniline 
= ed
.GetCurrentLine() 
 195         unitext
, l 
= decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - ' 
 196                             '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 ' 
 197                             '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n') 
 198         ed
.AddText('\tRussian: ') 
 202     #    #ed.StyleSetFontEncoding(stc.STC_STYLE_DEFAULT, wx.FONTENCODING_KOI8) 
 203     #    #text = u'\u041f\u0438\u0442\u043e\u043d - \u043b\u0443\u0447\u0448\u0438\u0439 \u044f\u0437\u044b\u043a \n\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f!' 
 204     #    #text = text.encode('koi8-r') 
 205     #    #ed.StyleSetFontEncoding(stc.STC_STYLE_DEFAULT, wx.FONTENCODING_BIG5) 
 206     #    #text = u'Python \u662f\u6700\u597d\u7684\u7de8\u7a0b\u8a9e\u8a00\uff01' 
 207     #    #text = text.encode('big5') 
 208     #    ed.GotoPos(ed.GetLength()) 
 209     #    ed.AddText('\n\n' + text) 
 214     ed
.StyleSetSpec(stc
.STC_STYLE_DEFAULT
, "size:%d,face:%s" % (pb
, face3
)) 
 216     ed
.StyleSetSpec(1, "size:%d,bold,face:%s,fore:#0000FF" % (pb
, face1
)) 
 217     ed
.StyleSetSpec(2, "face:%s,italic,fore:#FF0000,size:%d" % (face2
, pb
)) 
 218     ed
.StyleSetSpec(3, "face:%s,bold,size:%d" % (face2
, pb
)) 
 219     ed
.StyleSetSpec(4, "face:%s,size:%d" % (face1
, pb
-1)) 
 221     # Now set some text to those styles...  Normally this would be 
 222     # done in an event handler that happens when text needs displayed. 
 223     ed
.StartStyling(98, 0xff) 
 224     ed
.SetStyling(6, 1)  # set style for 6 characters using style 1 
 226     ed
.StartStyling(190, 0xff) 
 229     ed
.StartStyling(310, 0xff) 
 235     # line numbers in the margin 
 236     ed
.SetMarginType(0, stc
.STC_MARGIN_NUMBER
) 
 237     ed
.SetMarginWidth(0, 22) 
 238     ed
.StyleSetSpec(stc
.STC_STYLE_LINENUMBER
, "size:%d,face:%s" % (pb
-2, face1
)) 
 241     ed
.SetMarginType(1, stc
.STC_MARGIN_SYMBOL
) 
 242     ed
.MarkerDefine(0, stc
.STC_MARK_ROUNDRECT
, "#CCFF00", "RED") 
 243     ed
.MarkerDefine(1, stc
.STC_MARK_CIRCLE
, "FOREST GREEN", "SIENNA") 
 244     ed
.MarkerDefine(2, stc
.STC_MARK_SHORTARROW
, "blue", "blue") 
 245     ed
.MarkerDefine(3, stc
.STC_MARK_ARROW
, "#00FF00", "#00FF00") 
 247     # put some markers on some lines 
 255     # and finally, an indicator or two 
 256     ed
.IndicatorSetStyle(0, stc
.STC_INDIC_SQUIGGLE
) 
 257     ed
.IndicatorSetForeground(0, wx
.RED
) 
 258     ed
.IndicatorSetStyle(1, stc
.STC_INDIC_DIAGONAL
) 
 259     ed
.IndicatorSetForeground(1, wx
.BLUE
) 
 260     ed
.IndicatorSetStyle(2, stc
.STC_INDIC_STRIKE
) 
 261     ed
.IndicatorSetForeground(2, wx
.RED
) 
 263     ed
.StartStyling(836, stc
.STC_INDICS_MASK
) 
 264     ed
.SetStyling(10, stc
.STC_INDIC0_MASK
) 
 265     ed
.SetStyling(10, stc
.STC_INDIC1_MASK
) 
 266     ed
.SetStyling(10, stc
.STC_INDIC2_MASK | stc
.STC_INDIC1_MASK
) 
 271         print "GetTextLength(): ", ed
.GetTextLength(), len(ed
.GetText()) 
 272         print "GetText(): ", repr(ed
.GetText()) 
 274         print "GetStyledText(98, 104): ", repr(ed
.GetStyledText(98, 104)), len(ed
.GetStyledText(98, 104)) 
 276         print "GetCurLine(): ", repr(ed
.GetCurLine()) 
 278         print "GetCurLine(): ", repr(ed
.GetCurLine()) 
 280         print "GetLine(1): ", repr(ed
.GetLine(1)) 
 282         ed
.SetSelection(25, 35) 
 283         print "GetSelectedText(): ", repr(ed
.GetSelectedText()) 
 284         print "GetTextRange(25, 35): ", repr(ed
.GetTextRange(25, 35)) 
 285         print "FindText(0, max, 'indicators'): ", 
 286         print ed
.FindText(0, ed
.GetTextLength(), "indicators") 
 289             start 
= ed
.PositionFromLine(uniline
) 
 290             print "GetTextRange(%d, %d): " % (start
, end
), 
 291             print repr(ed
.GetTextRange(start
, end
)) 
 294     wx
.CallAfter(ed
.GotoPos
, 0) 
 299 #---------------------------------------------------------------------- 
 304 Once again, no docs yet.  <b>Sorry.</b>  But <a href="data/stc.h.html">this</a> 
 305 and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should 
 311 if __name__ 
== '__main__': 
 314     run
.main(['', os
.path
.basename(sys
.argv
[0])] + sys
.argv
[1:])