Files
wxWidgets/wxPython/demo/wxStyledTextCtrl_2.py
Robin Dunn 64dfb023eb Switched to using True/False in the wxPython lib and demo instead of
true/false or TRUE/FALSE to prepare for the new boolean type and
constants being added to Python.  Added code to wx.py to test for the
existence of the new constants and to create suitable values if not
present.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@19335 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2003-02-26 18:38:37 +00:00

348 lines
13 KiB
Python

from wxPython.wx import *
from wxPython.stc import *
import keyword
#----------------------------------------------------------------------
demoText = """\
## This version of the editor has been set up to edit Python source
## code. Here is a copy of wxPython/demo/Main.py to play with.
"""
#----------------------------------------------------------------------
if wxPlatform == '__WXMSW__':
faces = { 'times': 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 10,
'size2': 8,
}
else:
faces = { 'times': 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other': 'new century schoolbook',
'size' : 12,
'size2': 10,
}
#----------------------------------------------------------------------
class PythonSTC(wxStyledTextCtrl):
def __init__(self, parent, ID):
wxStyledTextCtrl.__init__(self, parent, ID,
style = wxNO_FULL_REPAINT_ON_RESIZE)
self.CmdKeyAssign(ord('B'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN)
self.CmdKeyAssign(ord('N'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT)
self.SetLexer(wxSTC_LEX_PYTHON)
self.SetKeyWords(0, " ".join(keyword.kwlist))
self.SetProperty("fold", "1")
self.SetProperty("tab.timmy.whinge.level", "1")
self.SetMargins(0,0)
self.SetViewWhiteSpace(False)
#self.SetBufferedDraw(False)
self.SetEdgeMode(wxSTC_EDGE_BACKGROUND)
self.SetEdgeColumn(78)
# Setup a margin to hold fold markers
#self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
self.SetMarginType(2, wxSTC_MARGIN_SYMBOL)
self.SetMarginMask(2, wxSTC_MASK_FOLDERS)
self.SetMarginSensitive(2, True)
self.SetMarginWidth(2, 12)
if 0: # simple folder marks, like the old version
self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_ARROW, "navy", "navy")
self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_ARROWDOWN, "navy", "navy")
# Set these to an invisible mark
self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BACKGROUND, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_BACKGROUND, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_BACKGROUND, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_BACKGROUND, "white", "black")
else: # more involved "outlining" folder marks
self.MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUSCONNECTED, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS, "white", "black")
self.MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS, "white", "black")
EVT_STC_UPDATEUI(self, ID, self.OnUpdateUI)
EVT_STC_MARGINCLICK(self, ID, self.OnMarginClick)
# Make some styles, The lexer defines what each style is used for, we
# just have to define what each style looks like. This set is adapted from
# Scintilla sample property files.
self.StyleClearAll()
# Global default styles for all languages
self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
self.StyleSetSpec(wxSTC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
self.StyleSetSpec(wxSTC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
self.StyleSetSpec(wxSTC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
# Python styles
# White space
self.StyleSetSpec(wxSTC_P_DEFAULT, "fore:#808080,face:%(helv)s,size:%(size)d" % faces)
# Comment
self.StyleSetSpec(wxSTC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
# Number
self.StyleSetSpec(wxSTC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
# String
self.StyleSetSpec(wxSTC_P_STRING, "fore:#7F007F,italic,face:%(times)s,size:%(size)d" % faces)
# Single quoted string
self.StyleSetSpec(wxSTC_P_CHARACTER, "fore:#7F007F,italic,face:%(times)s,size:%(size)d" % faces)
# Keyword
self.StyleSetSpec(wxSTC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
# Triple quotes
self.StyleSetSpec(wxSTC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
# Triple double quotes
self.StyleSetSpec(wxSTC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
# Class name definition
self.StyleSetSpec(wxSTC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
# Function or method name definition
self.StyleSetSpec(wxSTC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
# Operators
self.StyleSetSpec(wxSTC_P_OPERATOR, "bold,size:%(size)d" % faces)
# Identifiers
self.StyleSetSpec(wxSTC_P_IDENTIFIER, "fore:#808080,face:%(helv)s,size:%(size)d" % faces)
# Comment-blocks
self.StyleSetSpec(wxSTC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
# End of line where string is not closed
self.StyleSetSpec(wxSTC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
self.SetCaretForeground("BLUE")
EVT_KEY_DOWN(self, self.OnKeyPressed)
def OnKeyPressed(self, event):
if self.CallTipActive():
self.CallTipCancel()
key = event.KeyCode()
if key == 32 and event.ControlDown():
pos = self.GetCurrentPos()
# Tips
if event.ShiftDown():
self.CallTipSetBackground("yellow")
self.CallTipShow(pos, 'param1, param2')
# Code completion
else:
#lst = []
#for x in range(50000):
# lst.append('%05d' % x)
#st = " ".join(lst)
#print len(st)
#self.AutoCompShow(0, st)
kw = keyword.kwlist[:]
kw.append("zzzzzz")
kw.append("aaaaa")
kw.append("__init__")
kw.append("zzaaaaa")
kw.append("zzbaaaa")
kw.append("this_is_a_longer_value")
kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")
kw.sort() # Python sorts are case sensitive
self.AutoCompSetIgnoreCase(False) # so this needs to match
self.AutoCompShow(0, " ".join(kw))
else:
event.Skip()
def OnUpdateUI(self, evt):
# check for matching braces
braceAtCaret = -1
braceOpposite = -1
charBefore = None
caretPos = self.GetCurrentPos()
if caretPos > 0:
charBefore = self.GetCharAt(caretPos - 1)
styleBefore = self.GetStyleAt(caretPos - 1)
# check before
if charBefore and chr(charBefore) in "[]{}()" and styleBefore == wxSTC_P_OPERATOR:
braceAtCaret = caretPos - 1
# check after
if braceAtCaret < 0:
charAfter = self.GetCharAt(caretPos)
styleAfter = self.GetStyleAt(caretPos)
if charAfter and chr(charAfter) in "[]{}()" and styleAfter == wxSTC_P_OPERATOR:
braceAtCaret = caretPos
if braceAtCaret >= 0:
braceOpposite = self.BraceMatch(braceAtCaret)
if braceAtCaret != -1 and braceOpposite == -1:
self.BraceBadLight(braceAtCaret)
else:
self.BraceHighlight(braceAtCaret, braceOpposite)
#pt = self.PointFromPosition(braceOpposite)
#self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
#print pt
#self.Refresh(False)
def OnMarginClick(self, evt):
# fold and unfold as needed
if evt.GetMargin() == 2:
if evt.GetShift() and evt.GetControl():
self.FoldAll()
else:
lineClicked = self.LineFromPosition(evt.GetPosition())
if self.GetFoldLevel(lineClicked) & wxSTC_FOLDLEVELHEADERFLAG:
if evt.GetShift():
self.SetFoldExpanded(lineClicked, True)
self.Expand(lineClicked, True, True, 1)
elif evt.GetControl():
if self.GetFoldExpanded(lineClicked):
self.SetFoldExpanded(lineClicked, False)
self.Expand(lineClicked, False, True, 0)
else:
self.SetFoldExpanded(lineClicked, True)
self.Expand(lineClicked, True, True, 100)
else:
self.ToggleFold(lineClicked)
def FoldAll(self):
lineCount = self.GetLineCount()
expanding = True
# find out if we are folding or unfolding
for lineNum in range(lineCount):
if self.GetFoldLevel(lineNum) & wxSTC_FOLDLEVELHEADERFLAG:
expanding = not self.GetFoldExpanded(lineNum)
break;
lineNum = 0
while lineNum < lineCount:
level = self.GetFoldLevel(lineNum)
if level & wxSTC_FOLDLEVELHEADERFLAG and \
(level & wxSTC_FOLDLEVELNUMBERMASK) == wxSTC_FOLDLEVELBASE:
if expanding:
self.SetFoldExpanded(lineNum, True)
lineNum = self.Expand(lineNum, True)
lineNum = lineNum - 1
else:
lastChild = self.GetLastChild(lineNum, -1)
self.SetFoldExpanded(lineNum, False)
if lastChild > lineNum:
self.HideLines(lineNum+1, lastChild)
lineNum = lineNum + 1
def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
lastChild = self.GetLastChild(line, level)
line = line + 1
while line <= lastChild:
if force:
if visLevels > 0:
self.ShowLines(line, line)
else:
self.HideLines(line, line)
else:
if doExpand:
self.ShowLines(line, line)
if level == -1:
level = self.GetFoldLevel(line)
if level & wxSTC_FOLDLEVELHEADERFLAG:
if force:
if visLevels > 1:
self.SetFoldExpanded(line, True)
else:
self.SetFoldExpanded(line, False)
line = self.Expand(line, doExpand, force, visLevels-1)
else:
if doExpand and self.GetFoldExpanded(line):
line = self.Expand(line, True, force, visLevels-1)
else:
line = self.Expand(line, False, force, visLevels-1)
else:
line = line + 1;
return line
#----------------------------------------------------------------------
_USE_PANEL = 1
def runTest(frame, nb, log):
if not _USE_PANEL:
ed = p = PythonSTC(nb, -1)
else:
p = wxPanel(nb, -1, style = wxNO_FULL_REPAINT_ON_RESIZE)
ed = PythonSTC(p, -1)
s = wxBoxSizer(wxHORIZONTAL)
s.Add(ed, 1, wxEXPAND)
p.SetSizer(s)
p.SetAutoLayout(True)
ed.SetText(demoText + open('Main.py').read())
ed.EmptyUndoBuffer()
ed.Colourise(0, -1)
# line numbers in the margin
ed.SetMarginType(1, wxSTC_MARGIN_NUMBER)
ed.SetMarginWidth(1, 25)
return p
#----------------------------------------------------------------------
overview = """\
<html><body>
Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a>
and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should
be helpful.
</body><html>
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])])
#----------------------------------------------------------------------
#----------------------------------------------------------------------