📄 stctexteditor.py
字号:
#----------------------------------------------------------------------------
# Name: STCTextEditor.py
# Purpose: Text Editor for wx.lib.pydocview tbat uses the Styled Text Control
#
# Author: Peter Yared, Morgan Hua
#
# Created: 8/10/03
# CVS-ID: $Id: STCTextEditor.py,v 1.7 2006/04/20 06:25:58 RD Exp $
# Copyright: (c) 2003-2006 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import wx
import wx.stc
import wx.lib.docview
import wx.lib.multisash
import wx.lib.pydocview
import string
import FindService
import os
import sys
_ = wx.GetTranslation
#----------------------------------------------------------------------------
# Constants
#----------------------------------------------------------------------------
TEXT_ID = wx.NewId()
VIEW_WHITESPACE_ID = wx.NewId()
VIEW_EOL_ID = wx.NewId()
VIEW_INDENTATION_GUIDES_ID = wx.NewId()
VIEW_RIGHT_EDGE_ID = wx.NewId()
VIEW_LINE_NUMBERS_ID = wx.NewId()
ZOOM_ID = wx.NewId()
ZOOM_NORMAL_ID = wx.NewId()
ZOOM_IN_ID = wx.NewId()
ZOOM_OUT_ID = wx.NewId()
CHOOSE_FONT_ID = wx.NewId()
WORD_WRAP_ID = wx.NewId()
TEXT_STATUS_BAR_ID = wx.NewId()
#----------------------------------------------------------------------------
# Classes
#----------------------------------------------------------------------------
class TextDocument(wx.lib.docview.Document):
def __init__(self):
wx.lib.docview.Document .__init__(self)
self._inModify = False
def SaveObject(self, fileObject):
view = self.GetFirstView()
fileObject.write(view.GetValue())
view.SetModifyFalse()
return True
def LoadObject(self, fileObject):
view = self.GetFirstView()
data = fileObject.read()
view.SetValue(data)
view.SetModifyFalse()
return True
def IsModified(self):
view = self.GetFirstView()
if view:
return view.IsModified()
return False
def Modify(self, modify):
if self._inModify:
return
self._inModify = True
view = self.GetFirstView()
if not modify and view:
view.SetModifyFalse()
wx.lib.docview.Document.Modify(self, modify) # this must called be after the SetModifyFalse call above.
self._inModify = False
def OnCreateCommandProcessor(self):
# Don't create a command processor, it has its own
pass
# Use this to override MultiClient.Select to prevent yellow background.
def MultiClientSelectBGNotYellow(a):
a.GetParent().multiView.UnSelect()
a.selected = True
#a.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
a.Refresh()
class TextView(wx.lib.docview.View):
MARKER_NUM = 0
MARKER_MASK = 0x1
#----------------------------------------------------------------------------
# Overridden methods
#----------------------------------------------------------------------------
def __init__(self):
wx.lib.docview.View.__init__(self)
self._textEditor = None
self._markerCount = 0
self._commandProcessor = None
self._dynSash = None
def GetCtrlClass(self):
""" Used in split window to instantiate new instances """
return TextCtrl
def GetCtrl(self):
if wx.Platform == "__WXMAC__":
# look for active one first
self._textEditor = self._GetActiveCtrl(self._dynSash)
if self._textEditor == None: # it is possible none are active
# look for any existing one
self._textEditor = self._FindCtrl(self._dynSash)
return self._textEditor
def SetCtrl(self, ctrl):
self._textEditor = ctrl
def OnCreatePrintout(self):
""" for Print Preview and Print """
return TextPrintout(self, self.GetDocument().GetPrintableName())
def OnCreate(self, doc, flags):
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags, style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
# wxBug: DynamicSashWindow doesn't work on Mac, so revert to
# multisash implementation
if wx.Platform == "__WXMAC__":
wx.lib.multisash.MultiClient.Select = MultiClientSelectBGNotYellow
self._dynSash = wx.lib.multisash.MultiSash(frame, -1)
self._dynSash.SetDefaultChildClass(self.GetCtrlClass()) # wxBug: MultiSash instantiates the first TextCtrl with this call
self._textEditor = self.GetCtrl() # wxBug: grab the TextCtrl from the MultiSash datastructure
else:
self._dynSash = wx.gizmos.DynamicSashWindow(frame, -1, style=wx.CLIP_CHILDREN)
self._dynSash._view = self
self._textEditor = self.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
wx.EVT_LEFT_DOWN(self._textEditor, self.OnLeftClick)
self._textEditor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModify)
self._CreateSizer(frame)
self.Activate()
frame.Show(True)
frame.Layout()
return True
def OnModify(self, event):
self.GetDocument().Modify(self._textEditor.GetModify())
def _CreateSizer(self, frame):
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self._dynSash, 1, wx.EXPAND)
frame.SetSizer(sizer)
def OnLeftClick(self, event):
self.Activate()
event.Skip()
def OnUpdate(self, sender = None, hint = None):
if wx.lib.docview.View.OnUpdate(self, sender, hint):
return
if hint == "ViewStuff":
self.GetCtrl().SetViewDefaults()
elif hint == "Font":
font, color = self.GetCtrl().GetFontAndColorFromConfig()
self.GetCtrl().SetFont(font)
self.GetCtrl().SetFontColor(color)
def OnActivateView(self, activate, activeView, deactiveView):
if activate and self.GetCtrl():
# In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop
if self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
self.SetFocus()
else:
wx.CallAfter(self.SetFocus)
def SetFocus(self):
if self.GetCtrl():
self.GetCtrl().SetFocus()
def OnClose(self, deleteWindow = True):
if not wx.lib.docview.View.OnClose(self, deleteWindow):
return False
self.Activate(False)
if deleteWindow and self.GetFrame():
self.GetFrame().Destroy()
return True
def ProcessEvent(self, event):
id = event.GetId()
if id == wx.ID_UNDO:
self.GetCtrl().Undo()
return True
elif id == wx.ID_REDO:
self.GetCtrl().Redo()
return True
elif id == wx.ID_CUT:
self.GetCtrl().Cut()
return True
elif id == wx.ID_COPY:
self.GetCtrl().Copy()
return True
elif id == wx.ID_PASTE:
self.GetCtrl().OnPaste()
return True
elif id == wx.ID_CLEAR:
self.GetCtrl().OnClear()
return True
elif id == wx.ID_SELECTALL:
self.GetCtrl().SetSelection(0, -1)
return True
elif id == VIEW_WHITESPACE_ID:
self.GetCtrl().SetViewWhiteSpace(not self.GetCtrl().GetViewWhiteSpace())
return True
elif id == VIEW_EOL_ID:
self.GetCtrl().SetViewEOL(not self.GetCtrl().GetViewEOL())
return True
elif id == VIEW_INDENTATION_GUIDES_ID:
self.GetCtrl().SetIndentationGuides(not self.GetCtrl().GetIndentationGuides())
return True
elif id == VIEW_RIGHT_EDGE_ID:
self.GetCtrl().SetViewRightEdge(not self.GetCtrl().GetViewRightEdge())
return True
elif id == VIEW_LINE_NUMBERS_ID:
self.GetCtrl().SetViewLineNumbers(not self.GetCtrl().GetViewLineNumbers())
return True
elif id == ZOOM_NORMAL_ID:
self.GetCtrl().SetZoom(0)
return True
elif id == ZOOM_IN_ID:
self.GetCtrl().CmdKeyExecute(wx.stc.STC_CMD_ZOOMIN)
return True
elif id == ZOOM_OUT_ID:
self.GetCtrl().CmdKeyExecute(wx.stc.STC_CMD_ZOOMOUT)
return True
elif id == CHOOSE_FONT_ID:
self.OnChooseFont()
return True
elif id == WORD_WRAP_ID:
self.GetCtrl().SetWordWrap(not self.GetCtrl().GetWordWrap())
return True
elif id == FindService.FindService.FIND_ID:
self.OnFind()
return True
elif id == FindService.FindService.FIND_PREVIOUS_ID:
self.DoFind(forceFindPrevious = True)
return True
elif id == FindService.FindService.FIND_NEXT_ID:
self.DoFind(forceFindNext = True)
return True
elif id == FindService.FindService.REPLACE_ID:
self.OnFind(replace = True)
return True
elif id == FindService.FindService.FINDONE_ID:
self.DoFind()
return True
elif id == FindService.FindService.REPLACEONE_ID:
self.DoFind(replace = True)
return True
elif id == FindService.FindService.REPLACEALL_ID:
self.DoFind(replaceAll = True)
return True
elif id == FindService.FindService.GOTO_LINE_ID:
self.OnGotoLine(event)
return True
else:
return wx.lib.docview.View.ProcessEvent(self, event)
def ProcessUpdateUIEvent(self, event):
if not self.GetCtrl():
return False
id = event.GetId()
if id == wx.ID_UNDO:
event.Enable(self.GetCtrl().CanUndo())
event.SetText(_("&Undo\tCtrl+Z")) # replace menu string
return True
elif id == wx.ID_REDO:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -