⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codeeditor.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 3 页
字号:
#----------------------------------------------------------------------------
# Name:         CodeEditor.py
# Purpose:      Abstract Code Editor for pydocview tbat uses the Styled Text Control
#
# Author:       Peter Yared
#
# Created:      8/10/03
# CVS-ID:       $Id: CodeEditor.py,v 1.6 2006/04/20 06:26:01 RD Exp $
# Copyright:    (c) 2004-2005 ActiveGrid, Inc.
# License:      wxWindows License
#----------------------------------------------------------------------------


import STCTextEditor
import wx
import wx.lib.docview
import OutlineService
import os
import re
import string
import sys
import MarkerService
from UICommon import CaseInsensitiveCompare
_ = wx.GetTranslation
if wx.Platform == '__WXMSW__':
    _WINDOWS = True
else:
    _WINDOWS = False


EXPAND_TEXT_ID = wx.NewId()
COLLAPSE_TEXT_ID = wx.NewId()
EXPAND_TOP_ID = wx.NewId()
COLLAPSE_TOP_ID = wx.NewId()
EXPAND_ALL_ID = wx.NewId()
COLLAPSE_ALL_ID = wx.NewId()
CHECK_CODE_ID = wx.NewId()
AUTO_COMPLETE_ID = wx.NewId()
CLEAN_WHITESPACE = wx.NewId()
COMMENT_LINES_ID = wx.NewId()
UNCOMMENT_LINES_ID = wx.NewId()
INDENT_LINES_ID = wx.NewId()
DEDENT_LINES_ID = wx.NewId()
USE_TABS_ID = wx.NewId()
SET_INDENT_WIDTH_ID = wx.NewId()
FOLDING_ID = wx.NewId()


class CodeDocument(STCTextEditor.TextDocument):
    pass    


class CodeView(STCTextEditor.TextView):


    #----------------------------------------------------------------------------
    # Overridden methods
    #----------------------------------------------------------------------------


    def GetCtrlClass(self):
        """ Used in split window to instantiate new instances """
        return CodeCtrl


    def ProcessEvent(self, event):
        id = event.GetId()
        if id == EXPAND_TEXT_ID:
            self.GetCtrl().ToggleFold(self.GetCtrl().GetCurrentLine())
            return True
        elif id == COLLAPSE_TEXT_ID:
            self.GetCtrl().ToggleFold(self.GetCtrl().GetCurrentLine())
            return True
        elif id == EXPAND_TOP_ID:
            self.GetCtrl().ToggleFoldAll(expand = True, topLevelOnly = True)
            return True
        elif id == COLLAPSE_TOP_ID:
            self.GetCtrl().ToggleFoldAll(expand = False, topLevelOnly = True)
            return True
        elif id == EXPAND_ALL_ID:
            self.GetCtrl().ToggleFoldAll(expand = True)
            return True
        elif id == COLLAPSE_ALL_ID:
            self.GetCtrl().ToggleFoldAll(expand = False)
            return True
        elif id == CHECK_CODE_ID:
            self.OnCheckCode()
            return True
        elif id == AUTO_COMPLETE_ID:
            self.OnAutoComplete()
            return True
        elif id == CLEAN_WHITESPACE:
            self.OnCleanWhiteSpace()
            return True
        elif id == SET_INDENT_WIDTH_ID:
            self.OnSetIndentWidth()
            return True
        elif id == USE_TABS_ID:
            self.GetCtrl().SetUseTabs(not self.GetCtrl().GetUseTabs())
            return True
        elif id == INDENT_LINES_ID:
            self.GetCtrl().CmdKeyExecute(wx.stc.STC_CMD_TAB)
            return True
        elif id == DEDENT_LINES_ID:
            self.GetCtrl().CmdKeyExecute(wx.stc.STC_CMD_BACKTAB)
            return True
        elif id == COMMENT_LINES_ID:
            self.OnCommentLines()
            return True
        elif id == UNCOMMENT_LINES_ID:
            self.OnUncommentLines()
            return True
        else:
            return STCTextEditor.TextView.ProcessEvent(self, event)


    def ProcessUpdateUIEvent(self, event):
        if not self.GetCtrl():
            return False
        id = event.GetId()
        if id == EXPAND_TEXT_ID:
            if self.GetCtrl().GetViewFolding():
                event.Enable(self.GetCtrl().CanLineExpand(self.GetCtrl().GetCurrentLine()))
            else:
                event.Enable(False)
            return True
        elif id == COLLAPSE_TEXT_ID:
            if self.GetCtrl().GetViewFolding():
                event.Enable(self.GetCtrl().CanLineCollapse(self.GetCtrl().GetCurrentLine()))
            else:
                event.Enable(False)
            return True
        elif (id == EXPAND_TOP_ID
        or id == COLLAPSE_TOP_ID
        or id == EXPAND_ALL_ID
        or id == COLLAPSE_ALL_ID):
            if self.GetCtrl().GetViewFolding():
                event.Enable(self.GetCtrl().GetTextLength() > 0)
            else:
                event.Enable(False)
            return True            
        elif (id == AUTO_COMPLETE_ID
        or id == CLEAN_WHITESPACE
        or id == INDENT_LINES_ID
        or id == DEDENT_LINES_ID
        or id == COMMENT_LINES_ID
        or id == UNCOMMENT_LINES_ID):
            event.Enable(self.GetCtrl().GetTextLength() > 0)
            return True
        elif id == CHECK_CODE_ID:
            event.Enable(False)
            return True
        elif id == SET_INDENT_WIDTH_ID:
            event.Enable(True)
            return True
        elif id == FOLDING_ID:
            event.Enable(self.GetCtrl().GetViewFolding())
            return True
        elif id == USE_TABS_ID:
            event.Enable(True)
            event.Check(self.GetCtrl().GetUseTabs())
            return True
        else:
            return STCTextEditor.TextView.ProcessUpdateUIEvent(self, event)


    #----------------------------------------------------------------------------
    # Methods for OutlineService
    #----------------------------------------------------------------------------

    def OnChangeFilename(self):
        wx.lib.docview.View.OnChangeFilename(self)
        self.LoadOutline(force=True)
        

    def ClearOutline(self):
        outlineService = wx.GetApp().GetService(OutlineService.OutlineService)
        if not outlineService:
            return

        outlineView = outlineService.GetView()
        if not outlineView:
            return

        outlineView.ClearTreeCtrl()


    def LoadOutline(self, force=False):
        outlineService = wx.GetApp().GetService(OutlineService.OutlineService)
        if not outlineService:
            return
        outlineService.LoadOutline(self, force=force)


    def DoLoadOutlineCallback(self, force=False):
        outlineService = wx.GetApp().GetService(OutlineService.OutlineService)
        if not outlineService:
            return False

        outlineView = outlineService.GetView()
        if not outlineView:
            return False

        treeCtrl = outlineView.GetTreeCtrl()
        if not treeCtrl:
            return False

        view = treeCtrl.GetCallbackView()
        newCheckSum = self.GenCheckSum()
        if not force:
            if view and view is self:
                if self._checkSum == newCheckSum:
                    return False
        self._checkSum = newCheckSum

        treeCtrl.DeleteAllItems()

        document = self.GetDocument()
        if not document:
            return True

        filename = document.GetFilename()
        if filename:
            rootItem = treeCtrl.AddRoot(os.path.basename(filename))
            treeCtrl.SetDoSelectCallback(rootItem, self, (0,0))
        else:
            return True

        text = self.GetValue()
        if not text:
            return True

        CLASS_PATTERN = 'class[ \t]+\w+.*?:'
        DEF_PATTERN = 'def[ \t]+\w+\(.*?\)'
        classPat = re.compile(CLASS_PATTERN, re.M|re.S)
        defPat= re.compile(DEF_PATTERN, re.M|re.S)
        pattern = re.compile('^[ \t]*((' + CLASS_PATTERN + ')|('+ DEF_PATTERN +'.*?:)).*?$', re.M|re.S)

        iter = pattern.finditer(text)
        indentStack = [(0, rootItem)]
        for pattern in iter:
            line = pattern.string[pattern.start(0):pattern.end(0)]
            classLine = classPat.search(line)
            if classLine:
                indent = classLine.start(0)
                itemStr = classLine.string[classLine.start(0):classLine.end(0)-1]  # don't take the closing ':'
                itemStr = itemStr.replace("\n", "").replace("\r", "").replace(",\\", ",").replace("  ", "")  # remove line continuations and spaces from outline view
            else:
                defLine = defPat.search(line)
                if defLine:
                    indent = defLine.start(0)
                    itemStr = defLine.string[defLine.start(0):defLine.end(0)]
                    itemStr = itemStr.replace("\n", "").replace("\r", "").replace(",\\", ",").replace("  ", "")  # remove line continuations and spaces from outline view

            if indent == 0:
                parentItem = rootItem
            else:
                lastItem = indentStack.pop()
                while lastItem[0] >= indent:
                    lastItem = indentStack.pop()
                indentStack.append(lastItem)
                parentItem = lastItem[1]

            item = treeCtrl.AppendItem(parentItem, itemStr)
            treeCtrl.SetDoSelectCallback(item, self, (pattern.end(0), pattern.start(0) + indent))  # select in reverse order because we want the cursor to be at the start of the line so it wouldn't scroll to the right
            indentStack.append((indent, item))

        treeCtrl.Expand(rootItem)

        return True


    def DoSelectCallback(self, data):
        if data:
            self.EnsureVisibleEnforcePolicy(self.LineFromPosition(data[0]))
            # wxBug: need to select in reverse order (end, start) to place cursor at begining of line,
            #        otherwise, display is scrolled over to the right hard and is hard to view
            self.SetSelection(data[1], data[0])


##    def checksum(self, bytes):        
##        def rotate_right(c):
##            if c&1:
##                return (c>>1)|0x8000
##            else:
##                return c>>1
##                
##        result = 0
##        for ch in bytes:
##            ch = ord(ch) & 0xFF
##            result = (rotate_right(result)+ch) & 0xFFFF
##        return result
##

    def GenCheckSum(self):
        """ Poor man's checksum.  We'll assume most changes will change the length of the file.
        """
        text = self.GetValue()
        if text:
            return len(text)
        else:
            return 0


    #----------------------------------------------------------------------------
    # Format methods
    #----------------------------------------------------------------------------

    def OnCheckCode(self):
        """ Need to overshadow this for each specific subclass """
        if 0:
            try:
                code = self.GetCtrl().GetText()
                codeObj = compile(code, self.GetDocument().GetFilename(), 'exec')
                self._GetParentFrame().SetStatusText(_("The file successfully compiled"))
            except SyntaxError, (message, (fileName, line, col, text)):
                pos = self.GetCtrl().PositionFromLine(line - 1) + col - 1
                self.GetCtrl().SetSelection(pos, pos)
                self._GetParentFrame().SetStatusText(_("Syntax Error: %s") % message)
            except:
                self._GetParentFrame().SetStatusText("%s: %s" % (sys.exc_info()[0], sys.exc_info()[1]))


    def OnAutoComplete(self):
        self.GetCtrl().AutoCompCancel()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -