📄 stctexteditor.py
字号:
def UpdateSampleFont(self):
nativeFont = wx.NativeFontInfo()
nativeFont.FromString(self._textFont.GetNativeFontInfoDesc())
font = wx.NullFont
font.SetNativeFontInfo(nativeFont)
font.SetPointSize(self._sampleTextCtrl.GetFont().GetPointSize()) # Use the standard point size
self._sampleTextCtrl.SetFont(font)
self._sampleTextCtrl.SetForegroundColour(self._textColor)
self._sampleTextCtrl.SetValue(str(self._textFont.GetPointSize()) + _(" pt. ") + self._textFont.GetFaceName())
self._sampleTextCtrl.Refresh()
self.Layout()
## def OnChooseStyle(self, event):
## import STCStyleEditor
## import os
## base = os.path.split(__file__)[0]
## config = os.path.abspath(os.path.join(base, 'stc-styles.rc.cfg'))
##
## dlg = STCStyleEditor.STCStyleEditDlg(None,
## 'Python', 'python',
## #'HTML', 'html',
## #'XML', 'xml',
## config)
## dlg.CenterOnParent()
## try:
## dlg.ShowModal()
## finally:
## dlg.Destroy()
def OnChooseFont(self, event):
data = wx.FontData()
data.EnableEffects(True)
data.SetInitialFont(self._textFont)
data.SetColour(self._textColor)
fontDialog = wx.FontDialog(self, data)
fontDialog.CenterOnParent()
if fontDialog.ShowModal() == wx.ID_OK:
data = fontDialog.GetFontData()
self._textFont = data.GetChosenFont()
self._textColor = data.GetColour()
self.UpdateSampleFont()
fontDialog.Destroy()
def OnOK(self, optionsDialog):
config = wx.ConfigBase_Get()
doViewStuffUpdate = config.ReadInt(self._configPrefix + "EditorViewWhitespace", False) != self._viewWhitespaceCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorViewWhitespace", self._viewWhitespaceCheckBox.GetValue())
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewEOL", False) != self._viewEOLCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorViewEOL", self._viewEOLCheckBox.GetValue())
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewIndentationGuides", False) != self._viewIndentationGuideCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorViewIndentationGuides", self._viewIndentationGuideCheckBox.GetValue())
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewRightEdge", False) != self._viewRightEdgeCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorViewRightEdge", self._viewRightEdgeCheckBox.GetValue())
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewLineNumbers", True) != self._viewLineNumbersCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorViewLineNumbers", self._viewLineNumbersCheckBox.GetValue())
if self._hasFolding:
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewFolding", True) != self._viewFoldingCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorViewFolding", self._viewFoldingCheckBox.GetValue())
if self._hasWordWrap:
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorWordWrap", False) != self._wordWrapCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorWordWrap", self._wordWrapCheckBox.GetValue())
if self._hasTabs:
doViewStuffUpdate = doViewStuffUpdate or not config.ReadInt(self._configPrefix + "EditorUseTabs", True) != self._hasTabsCheckBox.GetValue()
config.WriteInt(self._configPrefix + "EditorUseTabs", not self._hasTabsCheckBox.GetValue())
newIndentWidth = int(self._indentWidthChoice.GetStringSelection())
oldIndentWidth = config.ReadInt(self._configPrefix + "EditorIndentWidth", 4)
if newIndentWidth != oldIndentWidth:
doViewStuffUpdate = True
config.WriteInt(self._configPrefix + "EditorIndentWidth", newIndentWidth)
doFontUpdate = self._originalTextFont != self._textFont or self._originalTextColor != self._textColor
config.Write(self._configPrefix + "EditorFont", self._textFont.GetNativeFontInfoDesc())
config.Write(self._configPrefix + "EditorColor", "%02x%02x%02x" % (self._textColor.Red(), self._textColor.Green(), self._textColor.Blue()))
if doViewStuffUpdate or doFontUpdate:
for document in optionsDialog.GetDocManager().GetDocuments():
if issubclass(document.GetDocumentTemplate().GetDocumentType(), TextDocument):
if doViewStuffUpdate:
document.UpdateAllViews(hint = "ViewStuff")
if doFontUpdate:
document.UpdateAllViews(hint = "Font")
def GetIcon(self):
return getTextIcon()
class TextCtrl(wx.stc.StyledTextCtrl):
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
wx.stc.StyledTextCtrl.__init__(self, parent, id, style=style)
if isinstance(parent, wx.gizmos.DynamicSashWindow):
self._dynSash = parent
self.SetupDSScrollBars()
self.Bind(wx.gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnDSSplit)
self.Bind(wx.gizmos.EVT_DYNAMIC_SASH_UNIFY, self.OnDSUnify)
self._font = None
self._fontColor = None
self.SetVisiblePolicy(wx.stc.STC_VISIBLE_STRICT,1)
self.CmdKeyClear(wx.stc.STC_KEY_ADD, wx.stc.STC_SCMOD_CTRL)
self.CmdKeyClear(wx.stc.STC_KEY_SUBTRACT, wx.stc.STC_SCMOD_CTRL)
self.CmdKeyAssign(wx.stc.STC_KEY_PRIOR, wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
self.CmdKeyAssign(wx.stc.STC_KEY_NEXT, wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
self.Bind(wx.stc.EVT_STC_ZOOM, self.OnUpdateLineNumberMarginWidth) # auto update line num width on zoom
wx.EVT_KEY_DOWN(self, self.OnKeyPressed)
wx.EVT_KILL_FOCUS(self, self.OnKillFocus)
wx.EVT_SET_FOCUS(self, self.OnFocus)
self.SetMargins(0,0)
self.SetUseTabs(0)
self.SetTabWidth(4)
self.SetIndent(4)
self.SetViewWhiteSpace(False)
self.SetEOLMode(wx.stc.STC_EOL_LF)
self.SetEdgeMode(wx.stc.STC_EDGE_NONE)
self.SetEdgeColumn(78)
self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
self.SetMarginWidth(1, self.EstimatedLineNumberMarginWidth())
self.UpdateStyles()
self.SetCaretForeground("BLACK")
self.SetViewDefaults()
font, color = self.GetFontAndColorFromConfig()
self.SetFont(font)
self.SetFontColor(color)
self.MarkerDefineDefault()
# for multisash initialization
if isinstance(parent, wx.lib.multisash.MultiClient):
while parent.GetParent():
parent = parent.GetParent()
if hasattr(parent, "GetView"):
break
if hasattr(parent, "GetView"):
textEditor = parent.GetView()._textEditor
if textEditor:
doc = textEditor.GetDocPointer()
if doc:
self.SetDocPointer(doc)
def OnFocus(self, event):
# wxBug: On Mac, the STC control may fire a focus/kill focus event
# on shutdown even if the control is in an invalid state. So check
# before handling the event.
if self.IsBeingDeleted():
return
self.SetSelBackground(1, "BLUE")
self.SetSelForeground(1, "WHITE")
if hasattr(self, "_dynSash"):
self._dynSash._view.SetCtrl(self)
event.Skip()
def OnKillFocus(self, event):
# wxBug: On Mac, the STC control may fire a focus/kill focus event
# on shutdown even if the control is in an invalid state. So check
# before handling the event.
if self.IsBeingDeleted():
return
self.SetSelBackground(0, "BLUE")
self.SetSelForeground(0, "WHITE")
self.SetSelBackground(1, "#C0C0C0")
# Don't set foreground color, use syntax highlighted default colors.
event.Skip()
def SetViewDefaults(self, configPrefix="Text", hasWordWrap=True, hasTabs=False, hasFolding=False):
config = wx.ConfigBase_Get()
self.SetViewWhiteSpace(config.ReadInt(configPrefix + "EditorViewWhitespace", False))
self.SetViewEOL(config.ReadInt(configPrefix + "EditorViewEOL", False))
self.SetIndentationGuides(config.ReadInt(configPrefix + "EditorViewIndentationGuides", False))
self.SetViewRightEdge(config.ReadInt(configPrefix + "EditorViewRightEdge", False))
self.SetViewLineNumbers(config.ReadInt(configPrefix + "EditorViewLineNumbers", True))
if hasFolding:
self.SetViewFolding(config.ReadInt(configPrefix + "EditorViewFolding", True))
if hasWordWrap:
self.SetWordWrap(config.ReadInt(configPrefix + "EditorWordWrap", False))
if hasTabs: # These methods do not exist in STCTextEditor and are meant for subclasses
self.SetUseTabs(config.ReadInt(configPrefix + "EditorUseTabs", False))
self.SetIndent(config.ReadInt(configPrefix + "EditorIndentWidth", 4))
self.SetTabWidth(config.ReadInt(configPrefix + "EditorIndentWidth", 4))
else:
self.SetUseTabs(True)
self.SetIndent(4)
self.SetTabWidth(4)
def GetDefaultFont(self):
""" Subclasses should override this """
return wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL)
def GetDefaultColor(self):
""" Subclasses should override this """
return wx.BLACK
def GetFontAndColorFromConfig(self, configPrefix = "Text"):
font = self.GetDefaultFont()
config = wx.ConfigBase_Get()
fontData = config.Read(configPrefix + "EditorFont", "")
if fontData:
nativeFont = wx.NativeFontInfo()
nativeFont.FromString(fontData)
font.SetNativeFontInfo(nativeFont)
color = self.GetDefaultColor()
colorData = config.Read(configPrefix + "EditorColor", "")
if colorData:
red = int("0x" + colorData[0:2], 16)
green = int("0x" + colorData[2:4], 16)
blue = int("0x" + colorData[4:6], 16)
color = wx.Color(red, green, blue)
return font, color
def GetFont(self):
return self._font
def SetFont(self, font):
self._font = font
self.StyleSetFont(wx.stc.STC_STYLE_DEFAULT, self._font)
def GetFontColor(self):
return self._fontColor
def SetFontColor(self, fontColor = wx.BLACK):
self._fontColor = fontColor
self.StyleSetForeground(wx.stc.STC_STYLE_DEFAULT, "#%02x%02x%02x" % (self._fontColor.Red(), self._fontColor.Green(), self._fontColor.Blue()))
def UpdateStyles(self):
self.StyleClearAll()
return
def EstimatedLineNumberMarginWidth(self):
MARGIN = 4
baseNumbers = "000"
lineNum = self.GetLineCount()
lineNum = lineNum/100
while lineNum >= 10:
lineNum = lineNum/10
baseNumbers = baseNumbers + "0"
return self.TextWidth(wx.stc.STC_STYLE_LINENUMBER, baseNumbers) + MARGIN
def OnUpdateLineNumberMarginWidth(self, event):
self.UpdateLineNumberMarginWidth()
def UpdateLineNumberMarginWidth(self):
if self.GetViewLineNumbers():
self.SetMarginWidth(1, self.EstimatedLineNumberMarginWidth())
def MarkerDefineDefault(self):
""" This must be called after the textcontrol is instantiated """
self.MarkerDefine(TextView.MARKER_NUM, wx.stc.STC_MARK_ROUNDRECT, wx.BLACK, wx.BLUE)
def OnClear(self):
# Used when Delete key is hit.
sel = self.GetSelection()
# Delete the selection or if no selection, the character after the caret.
if sel[0] == sel[1]:
self.SetSelection(sel[0], sel[0] + 1)
else:
# remove any folded lines also.
startLine = self.LineFromPosition(sel[0])
endLine = self.LineFromPosition(sel[1])
endLineStart = self.PositionFromLine(endLine)
if startLine != endLine and sel[1] - endLineStart == 0:
while not self.GetLineVisible(endLine):
endLine += 1
self.SetSelectionEnd(self.PositionFromLine(endLine))
self.Clear()
def OnPaste(self):
# replace any folded lines also.
sel = self.GetSelection()
startLine = self.LineFromPosition(sel[0])
endLine = self.LineFromPosition(sel[1])
endLineStart = self.PositionFromLine(endLine)
if startLine != endLine and sel[1] - endLineStart == 0:
while not self.GetLineVisible(endLine):
endLine += 1
self.SetSelectionEnd(self.PositionFromLine(endLine))
self.Paste()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -