X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ec873c943d71f0d5f13e3398557071448cda6c23..a4027e74873007e3430af3bd77019bcab76f6c04:/wxPython/samples/ide/activegrid/tool/CodeEditor.py?ds=inline diff --git a/wxPython/samples/ide/activegrid/tool/CodeEditor.py b/wxPython/samples/ide/activegrid/tool/CodeEditor.py deleted file mode 100644 index 72a5dd2c4f..0000000000 --- a/wxPython/samples/ide/activegrid/tool/CodeEditor.py +++ /dev/null @@ -1,972 +0,0 @@ -#---------------------------------------------------------------------------- -# 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$ -# 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() - 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") - - # 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, wx.stc.STC_MARGIN_SYMBOL) - self.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS) - self.SetMarginSensitive(2, True) - - self.SetMarginSensitive(1, False) - self.SetMarginMask(1, 0x4) - - self.SetMarginSensitive(0, True) - self.SetMarginType(0, wx.stc.STC_MARGIN_SYMBOL) - self.SetMarginMask(0, 0x3) - self.SetMarginWidth(0, 12) - - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, wx.stc.STC_MARK_BOXPLUSCONNECTED, "white", "black") - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "black") - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER, "white", "black") - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL, wx.stc.STC_MARK_LCORNER, "white", "black") - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB, wx.stc.STC_MARK_VLINE, "white", "black") - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, wx.stc.STC_MARK_BOXPLUS, "white", "black") - self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, wx.stc.STC_MARK_BOXMINUS, "white", "black") - # Define the current line marker - self.MarkerDefine(CodeCtrl.CURRENT_LINE_MARKER_NUM, wx.stc.STC_MARK_SHORTARROW, wx.BLACK, (255,255,128)) - # Define the breakpoint marker - self.MarkerDefine(CodeCtrl.BREAKPOINT_MARKER_NUM, wx.stc.STC_MARK_CIRCLE, wx.BLACK, (255,0,0)) - - if _WINDOWS and clearTab: # should test to see if menu item exists, if it does, add this workaround - self.CmdKeyClear(wx.stc.STC_KEY_TAB, 0) # menu item "Indent Lines" from CodeService.InstallControls() generates another INDENT_LINES_ID event, so we'll explicitly disable the tab processing in the editor - - wx.stc.EVT_STC_MARGINCLICK(self, self.GetId(), self.OnMarginClick) - wx.EVT_KEY_DOWN(self, self.OnKeyPressed) - if self.GetMatchingBraces(): - wx.stc.EVT_STC_UPDATEUI(self, self.GetId(), self.OnUpdateUI) - - self.StyleClearAll() - self.UpdateStyles() - - - def OnRightUp(self, event): - #Hold onto the current line number, no way to get it later. - self._rightClickPosition = self.PositionFromPoint(event.GetPosition()) - self._rightClickLine = self.LineFromPosition(self._rightClickPosition) - self.PopupMenu(self.CreatePopupMenu(), event.GetPosition()) - self._rightClickLine = -1 - self._rightClickPosition = -1 - - - def CreatePopupMenu(self): - TOGGLEBREAKPOINT_ID = wx.NewId() - TOGGLEMARKER_ID = wx.NewId() - SYNCTREE_ID = wx.NewId() - - menu = wx.Menu() - - self.Bind(wx.EVT_MENU, self.OnPopSyncOutline, id=SYNCTREE_ID) - item = wx.MenuItem(menu, SYNCTREE_ID, _("Find in Outline View")) - menu.AppendItem(item) - menu.AppendSeparator() - self.Bind(wx.EVT_MENU, self.OnPopToggleBP, id=TOGGLEBREAKPOINT_ID) - item = wx.MenuItem(menu, TOGGLEBREAKPOINT_ID, _("Toggle Breakpoint")) - menu.AppendItem(item) - self.Bind(wx.EVT_MENU, self.OnPopToggleMarker, id=TOGGLEMARKER_ID) - item = wx.MenuItem(menu, TOGGLEMARKER_ID, _("Toggle Bookmark")) - menu.AppendItem(item) - menu.AppendSeparator() - - itemIDs = [wx.ID_UNDO, wx.ID_REDO, None, - wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE, wx.ID_CLEAR, None, wx.ID_SELECTALL] - - menuBar = wx.GetApp().GetTopWindow().GetMenuBar() - for itemID in itemIDs: - if not itemID: - menu.AppendSeparator() - else: - item = menuBar.FindItemById(itemID) - if item: - menu.Append(itemID, item.GetLabel()) - wx.EVT_MENU(self, itemID, self.DSProcessEvent) # wxHack: for customized right mouse menu doesn't work with new DynamicSashWindow - wx.EVT_UPDATE_UI(self, itemID, self.DSProcessUpdateUIEvent) # wxHack: for customized right mouse menu doesn't work with new DynamicSashWindow - return menu - - - def OnPopToggleBP(self, event): - """ Toggle break point on right click line, not current line """ - import DebuggerService - wx.GetApp().GetService(DebuggerService.DebuggerService).OnToggleBreakpoint(event, line=self._rightClickLine) - - - def OnPopToggleMarker(self, event): - """ Toggle marker on right click line, not current line """ - wx.GetApp().GetDocumentManager().GetCurrentView().MarkerToggle(lineNum = self._rightClickLine) - - - def OnPopSyncOutline(self, event): - wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(wx.GetApp().GetDocumentManager().GetCurrentView(), position=self._rightClickPosition) - - - def HasSelection(self): - return self.GetSelectionStart() - self.GetSelectionEnd() != 0 - - - def ClearCurrentLineMarkers(self): - self.MarkerDeleteAll(CodeCtrl.CURRENT_LINE_MARKER_NUM) - - - def ClearCurrentBreakpoinMarkers(self): - self.MarkerDeleteAll(CodeCtrl.BREAKPOINT_MARKER_NUM) - - - def GetDefaultFont(self): - if wx.Platform == '__WXMSW__': - font = "Courier New" - else: - font = "Courier" - return wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font) - - - def GetMatchingBraces(self): - """ Overwrite this method for language specific braces """ - return "[]{}()" - - - def CanWordWrap(self): - return False - - - def SetFont(self, font): - self._font = font - - - def SetFontColor(self, fontColor): - self._fontColor = fontColor - - - def UpdateStyles(self): - - if not self.GetFont(): - return - - faces = { 'font' : self.GetFont().GetFaceName(), - 'size' : self.GetFont().GetPointSize(), - 'size2': self.GetFont().GetPointSize() - 2, - 'color' : "%02x%02x%02x" % (self.GetFontColor().Red(), self.GetFontColor().Green(), self.GetFontColor().Blue()) - } - - # Global default styles for all languages - self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(font)s,fore:#FFFFFF,size:%(size)d" % faces) - self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER, "face:%(font)s,back:#C0C0C0,face:%(font)s,size:%(size2)d" % faces) - self.StyleSetSpec(wx.stc.STC_STYLE_CONTROLCHAR, "face:%(font)s" % faces) - self.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT, "face:%(font)s,fore:#000000,back:#70FFFF,size:%(size)d" % faces) - self.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD, "face:%(font)s,fore:#000000,back:#FF0000,size:%(size)d" % faces) - - - def OnKeyPressed(self, event): - if self.CallTipActive(): - self.CallTipCancel() - key = event.KeyCode() - if False: # key == wx.WXK_SPACE 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 = string.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, string.join(kw)) - elif key == wx.WXK_RETURN: - self.DoIndent() - else: - STCTextEditor.TextCtrl.OnKeyPressed(self, event) - - - def DoIndent(self): - self.AddText('\n') - self.EnsureCaretVisible() - # Need to do a default one for all languges - - - def OnMarginClick(self, evt): - # fold and unfold as needed - if evt.GetMargin() == 2: - if evt.GetShift() and evt.GetControl(): - lineCount = self.GetLineCount() - expanding = True - - # find out if we are folding or unfolding - for lineNum in range(lineCount): - if self.GetFoldLevel(lineNum) & wx.stc.STC_FOLDLEVELHEADERFLAG: - expanding = not self.GetFoldExpanded(lineNum) - break; - - self.ToggleFoldAll(expanding) - else: - lineClicked = self.LineFromPosition(evt.GetPosition()) - if self.GetFoldLevel(lineClicked) & wx.stc.STC_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) - - elif evt.GetMargin() == 0: - #This is used to toggle breakpoints via the debugger service. - import DebuggerService - db_service = wx.GetApp().GetService(DebuggerService.DebuggerService) - if db_service: - db_service.OnToggleBreakpoint(evt, line=self.LineFromPosition(evt.GetPosition())) - - - def OnUpdateUI(self, evt): - braces = self.GetMatchingBraces() - - # 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 braces: - braceAtCaret = caretPos - 1 - - # check after - if braceAtCaret < 0: - charAfter = self.GetCharAt(caretPos) - styleAfter = self.GetStyleAt(caretPos) - if charAfter and chr(charAfter) in braces: - braceAtCaret = caretPos - - if braceAtCaret >= 0: - braceOpposite = self.BraceMatch(braceAtCaret) - - if braceAtCaret != -1 and braceOpposite == -1: - self.BraceBadLight(braceAtCaret) - else: - self.BraceHighlight(braceAtCaret, braceOpposite) - - evt.Skip() - - - def ToggleFoldAll(self, expand = True, topLevelOnly = False): - i = 0 - lineCount = self.GetLineCount() - while i < lineCount: - if not topLevelOnly or (topLevelOnly and self.GetFoldLevel(i) & wx.stc.STC_FOLDLEVELNUMBERMASK == wx.stc.STC_FOLDLEVELBASE): - if (expand and self.CanLineExpand(i)) or (not expand and self.CanLineCollapse(i)): - self.ToggleFold(i) - i = i + 1 - - - def CanLineExpand(self, line): - return not self.GetFoldExpanded(line) - - - def CanLineCollapse(self, line): - return self.GetFoldExpanded(line) and self.GetFoldLevel(line) & wx.stc.STC_FOLDLEVELHEADERFLAG - - - 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 & wx.stc.STC_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 - -