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

📄 codeeditor.py

📁 Wxpython Implemented on Windows CE, Source code
💻 PY
📖 第 1 页 / 共 3 页
字号:
        self.GetCtrl().AutoCompSetAutoHide(0)
        self.GetCtrl().AutoCompSetChooseSingle(True)
        self.GetCtrl().AutoCompSetIgnoreCase(True)
        context, hint = self.GetAutoCompleteHint()
        replaceList, replaceLen = self.GetAutoCompleteKeywordList(context, hint)
        if replaceList and len(replaceList) != 0: 
            self.GetCtrl().AutoCompShow(replaceLen, replaceList)


    def GetAutoCompleteHint(self):
        """ Replace this method with Editor specific method """
        pos = self.GetCtrl().GetCurrentPos()
        if pos == 0:
            return None, None
        if chr(self.GetCtrl().GetCharAt(pos - 1)) == '.':
            pos = pos - 1
            hint = None
        else:
            hint = ''
            
        validLetters = string.letters + string.digits + '_.'
        word = ''
        while (True):
            pos = pos - 1
            if pos < 0:
                break
            char = chr(self.GetCtrl().GetCharAt(pos))
            if char not in validLetters:
                break
            word = char + word
            
        context = word
        if hint is not None:            
            lastDot = word.rfind('.')
            if lastDot != -1:
                context = word[0:lastDot]
                hint = word[lastDot+1:]
                    
        return context, hint
        

    def GetAutoCompleteDefaultKeywords(self):
        """ Replace this method with Editor specific keywords """
        return ['Put', 'Editor Specific', 'Keywords', 'Here']


    def GetAutoCompleteKeywordList(self, context, hint):            
        """ Replace this method with Editor specific keywords """
        kw = self.GetAutoCompleteDefaultKeywords()
        
        if hint and len(hint):
            lowerHint = hint.lower()
            filterkw = filter(lambda item: item.lower().startswith(lowerHint), kw)  # remove variables and methods that don't match hint
            kw = filterkw

        if hint:
            replaceLen = len(hint)
        else:
            replaceLen = 0
            
        kw.sort(CaseInsensitiveCompare)
        return " ".join(kw), replaceLen
        

    def OnCleanWhiteSpace(self):
        newText = ""
        for lineNo in self._GetSelectedLineNumbers():
            lineText = string.rstrip(self.GetCtrl().GetLine(lineNo))
            indent = 0
            lstrip = 0
            for char in lineText:
                if char == '\t':
                    indent = indent + self.GetCtrl().GetIndent()
                    lstrip = lstrip + 1
                elif char in string.whitespace:
                    indent = indent + 1
                    lstrip = lstrip + 1
                else:
                    break
            if self.GetCtrl().GetUseTabs():
                indentText = (indent / self.GetCtrl().GetIndent()) * '\t' + (indent % self.GetCtrl().GetIndent()) * ' '
            else:
                indentText = indent * ' '
            lineText = indentText + lineText[lstrip:] + '\n'
            newText = newText + lineText
        self._ReplaceSelectedLines(newText)


    def OnSetIndentWidth(self):
        dialog = wx.TextEntryDialog(self._GetParentFrame(), _("Enter new indent width (2-10):"), _("Set Indent Width"), "%i" % self.GetCtrl().GetIndent())
        dialog.CenterOnParent()
        if dialog.ShowModal() == wx.ID_OK:
            try:
                indent = int(dialog.GetValue())
                if indent >= 2 and indent <= 10:
                    self.GetCtrl().SetIndent(indent)
                    self.GetCtrl().SetTabWidth(indent)
            except:
                pass
        dialog.Destroy()


    def GetIndentWidth(self):
        return self.GetCtrl().GetIndent()
                

    def OnCommentLines(self):
        newText = ""
        for lineNo in self._GetSelectedLineNumbers():
            lineText = self.GetCtrl().GetLine(lineNo)
            if (len(lineText) > 1 and lineText[0] == '#') or (len(lineText) > 2 and lineText[:2] == '##'):
                newText = newText + lineText
            else:
                newText = newText + "##" + lineText
        self._ReplaceSelectedLines(newText)


    def OnUncommentLines(self):
        newText = ""
        for lineNo in self._GetSelectedLineNumbers():
            lineText = self.GetCtrl().GetLine(lineNo)
            if len(lineText) >= 2 and lineText[:2] == "##":
                lineText = lineText[2:]
            elif len(lineText) >= 1 and lineText[:1] == "#":
                lineText = lineText[1:]
            newText = newText + lineText
        self._ReplaceSelectedLines(newText)


    def _GetSelectedLineNumbers(self):
        selStart, selEnd = self._GetPositionsBoundingSelectedLines()
        return range(self.GetCtrl().LineFromPosition(selStart), self.GetCtrl().LineFromPosition(selEnd))


    def _GetPositionsBoundingSelectedLines(self):
        startPos = self.GetCtrl().GetCurrentPos()
        endPos = self.GetCtrl().GetAnchor()
        if startPos > endPos:
            temp = endPos
            endPos = startPos
            startPos = temp
        if endPos == self.GetCtrl().PositionFromLine(self.GetCtrl().LineFromPosition(endPos)):
            endPos = endPos - 1  # If it's at the very beginning of a line, use the line above it as the ending line
        selStart = self.GetCtrl().PositionFromLine(self.GetCtrl().LineFromPosition(startPos))
        selEnd = self.GetCtrl().PositionFromLine(self.GetCtrl().LineFromPosition(endPos) + 1)
        return selStart, selEnd


    def _ReplaceSelectedLines(self, text):
        if len(text) == 0:
            return
        selStart, selEnd = self._GetPositionsBoundingSelectedLines()
        self.GetCtrl().SetSelection(selStart, selEnd)
        self.GetCtrl().ReplaceSelection(text)
        self.GetCtrl().SetSelection(selStart + len(text), selStart)


    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)
        else:
            import DebuggerService
            dbg_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
            if dbg_service:
                dbg_service.SetCurrentBreakpointMarkers(self)


class CodeService(STCTextEditor.TextService):


    def __init__(self):
        STCTextEditor.TextService.__init__(self)


    def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
        # TODO NEED TO DO INSTANCEOF CHECK HERE FOR SDI
        #if document and document.GetDocumentTemplate().GetDocumentType() != TextDocument:
        #    return
        if not document and wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
            return

        viewMenu = menuBar.GetMenu(menuBar.FindMenu(_("&View")))
        isWindows = (wx.Platform == '__WXMSW__')

        if not menuBar.FindItemById(EXPAND_TEXT_ID):  # check if below menu items have been already been installed
            foldingMenu = wx.Menu()
            if isWindows:
                foldingMenu.Append(EXPAND_TEXT_ID, _("&Expand\tNumpad-Plus"), _("Expands a collapsed block of text"))
            else:
                foldingMenu.Append(EXPAND_TEXT_ID, _("&Expand"), _("Expands a collapsed block of text"))

            wx.EVT_MENU(frame, EXPAND_TEXT_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, EXPAND_TEXT_ID, frame.ProcessUpdateUIEvent)
            
            if isWindows:
                foldingMenu.Append(COLLAPSE_TEXT_ID, _("&Collapse\tNumpad+Minus"), _("Collapse a block of text"))
            else:
                foldingMenu.Append(COLLAPSE_TEXT_ID, _("&Collapse"), _("Collapse a block of text"))
            wx.EVT_MENU(frame, COLLAPSE_TEXT_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, COLLAPSE_TEXT_ID, frame.ProcessUpdateUIEvent)
            
            if isWindows:
                foldingMenu.Append(EXPAND_TOP_ID, _("Expand &Top Level\tCtrl+Numpad+Plus"), _("Expands the top fold levels in the document"))
            else:
                foldingMenu.Append(EXPAND_TOP_ID, _("Expand &Top Level"), _("Expands the top fold levels in the document"))
            wx.EVT_MENU(frame, EXPAND_TOP_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, EXPAND_TOP_ID, frame.ProcessUpdateUIEvent)
            
            if isWindows:
                foldingMenu.Append(COLLAPSE_TOP_ID, _("Collapse Top &Level\tCtrl+Numpad+Minus"), _("Collapses the top fold levels in the document"))
            else:
                foldingMenu.Append(COLLAPSE_TOP_ID, _("Collapse Top &Level"), _("Collapses the top fold levels in the document"))
            wx.EVT_MENU(frame, COLLAPSE_TOP_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, COLLAPSE_TOP_ID, frame.ProcessUpdateUIEvent)
            
            if isWindows:
                foldingMenu.Append(EXPAND_ALL_ID, _("Expand &All\tShift+Numpad+Plus"), _("Expands all of the fold levels in the document"))
            else:
                foldingMenu.Append(EXPAND_ALL_ID, _("Expand &All"), _("Expands all of the fold levels in the document"))
            wx.EVT_MENU(frame, EXPAND_ALL_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, EXPAND_ALL_ID, frame.ProcessUpdateUIEvent)
            
            if isWindows:
                foldingMenu.Append(COLLAPSE_ALL_ID, _("Colla&pse All\tShift+Numpad+Minus"), _("Collapses all of the fold levels in the document"))
            else:
                foldingMenu.Append(COLLAPSE_ALL_ID, _("Colla&pse All"), _("Collapses all of the fold levels in the document"))
            wx.EVT_MENU(frame, COLLAPSE_ALL_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, COLLAPSE_ALL_ID, frame.ProcessUpdateUIEvent)
            
            viewMenu.AppendMenu(FOLDING_ID, _("&Folding"), foldingMenu)
            wx.EVT_UPDATE_UI(frame, FOLDING_ID, frame.ProcessUpdateUIEvent)

        formatMenuIndex = menuBar.FindMenu(_("&Format"))
        if formatMenuIndex > -1:
            formatMenu = menuBar.GetMenu(formatMenuIndex)
        else:
            formatMenu = wx.Menu()
        if not menuBar.FindItemById(CHECK_CODE_ID):  # check if below menu items have been already been installed
            formatMenu.AppendSeparator()
            formatMenu.Append(CHECK_CODE_ID, _("&Check Code"), _("Checks the document for syntax and indentation errors"))
            wx.EVT_MENU(frame, CHECK_CODE_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, CHECK_CODE_ID, frame.ProcessUpdateUIEvent)
            formatMenu.Append(AUTO_COMPLETE_ID, _("&Auto Complete\tCtrl+Space"), _("Provides suggestions on how to complete the current statement"))
            wx.EVT_MENU(frame, AUTO_COMPLETE_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, AUTO_COMPLETE_ID, frame.ProcessUpdateUIEvent)
            formatMenu.Append(CLEAN_WHITESPACE, _("Clean &Whitespace"), _("Converts leading spaces to tabs or vice versa per 'use tabs' and clears trailing spaces"))
            wx.EVT_MENU(frame, CLEAN_WHITESPACE, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, CLEAN_WHITESPACE, frame.ProcessUpdateUIEvent)
            formatMenu.AppendSeparator()
            formatMenu.Append(INDENT_LINES_ID, _("&Indent Lines\tTab"), _("Indents the selected lines one indent width"))
            wx.EVT_MENU(frame, INDENT_LINES_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, INDENT_LINES_ID, frame.ProcessUpdateUIEvent)
            formatMenu.Append(DEDENT_LINES_ID, _("&Dedent Lines\tShift+Tab"), _("Dedents the selected lines one indent width"))
            wx.EVT_MENU(frame, DEDENT_LINES_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, DEDENT_LINES_ID, frame.ProcessUpdateUIEvent)
            formatMenu.Append(COMMENT_LINES_ID, _("Comment &Lines\tCtrl+Q"), _("Comments out the selected lines be prefixing each one with a comment indicator"))
            wx.EVT_MENU(frame, COMMENT_LINES_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, COMMENT_LINES_ID, frame.ProcessUpdateUIEvent)
            formatMenu.Append(UNCOMMENT_LINES_ID, _("&Uncomment Lines\tCtrl+Shift+Q"), _("Removes comment prefixes from each of the selected lines"))
            wx.EVT_MENU(frame, UNCOMMENT_LINES_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, UNCOMMENT_LINES_ID, frame.ProcessUpdateUIEvent)
            formatMenu.AppendSeparator()
            formatMenu.AppendCheckItem(USE_TABS_ID, _("Use &Tabs"), _("Toggles use of tabs or whitespaces for indents"))
            wx.EVT_MENU(frame, USE_TABS_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, USE_TABS_ID, frame.ProcessUpdateUIEvent)
            formatMenu.Append(SET_INDENT_WIDTH_ID, _("&Set Indent Width..."), _("Sets the indent width"))
            wx.EVT_MENU(frame, SET_INDENT_WIDTH_ID, frame.ProcessEvent)
            wx.EVT_UPDATE_UI(frame, SET_INDENT_WIDTH_ID, frame.ProcessUpdateUIEvent)
        if formatMenuIndex == -1:
            viewMenuIndex = menuBar.FindMenu(_("&View"))
            menuBar.Insert(viewMenuIndex + 1, formatMenu, _("&Format"))

##        accelTable = wx.AcceleratorTable([
##            (wx.ACCEL_NORMAL, wx.WXK_TAB, INDENT_LINES_ID),
##            (wx.ACCEL_SHIFT, wx.WXK_TAB, DEDENT_LINES_ID),
##            eval(_("wx.ACCEL_CTRL, ord('Q'), COMMENT_LINES_ID")),
##            eval(_("wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord('Q'), UNCOMMENT_LINES_ID"))
##            ])
##        frame.SetAcceleratorTable(accelTable)

    def ProcessUpdateUIEvent(self, event):
        id = event.GetId()
        if (id == EXPAND_TEXT_ID
        or id == COLLAPSE_TEXT_ID
        or id == EXPAND_TOP_ID
        or id == COLLAPSE_TOP_ID
        or id == EXPAND_ALL_ID
        or id == COLLAPSE_ALL_ID
        or id == CHECK_CODE_ID
        or id == AUTO_COMPLETE_ID
        or id == CLEAN_WHITESPACE
        or id == SET_INDENT_WIDTH_ID
        or id == USE_TABS_ID
        or id == INDENT_LINES_ID
        or id == DEDENT_LINES_ID
        or id == COMMENT_LINES_ID
        or id == UNCOMMENT_LINES_ID
        or id == FOLDING_ID):
            event.Enable(False)
            return True
        else:
            return STCTextEditor.TextService.ProcessUpdateUIEvent(self, event)


class CodeCtrl(STCTextEditor.TextCtrl):
    CURRENT_LINE_MARKER_NUM = 2
    BREAKPOINT_MARKER_NUM = 1
    CURRENT_LINE_MARKER_MASK = 0x4
    BREAKPOINT_MARKER_MASK = 0x2
    
            
    def __init__(self, parent, id=-1, style = wx.NO_FULL_REPAINT_ON_RESIZE, clearTab=True):
        STCTextEditor.TextCtrl.__init__(self, parent, id, style)
        
        self.UsePopUp(False)
        self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
        self.SetProperty("fold", "1")

⌨️ 快捷键说明

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