+"""EditWindow class."""
-"""Renamer stub: provides a way to drop the wx prefix from wxPython objects."""
+__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
+__cvsid__ = "$Id$"
+__revision__ = "$Revision$"[11:-2]
-from wx import _rename
-from wxPython.py import editwindow
-_rename(globals(), editwindow.__dict__, modulename='py.editwindow')
-del editwindow
-del _rename
+import wx
+from wx import stc
+
+import keyword
+import os
+import sys
+import time
+
+import dispatcher
+from version import VERSION
+
+
+if 'wxMSW' in wx.PlatformInfo:
+ FACES = { 'times' : 'Times New Roman',
+ 'mono' : 'Courier New',
+ 'helv' : 'Arial',
+ 'lucida' : 'Lucida Console',
+ 'other' : 'Comic Sans MS',
+ 'size' : 10,
+ 'lnsize' : 8,
+ 'backcol' : '#FFFFFF',
+ 'calltipbg' : '#FFFFB8',
+ 'calltipfg' : '#404040',
+ }
+
+elif 'wxGTK' in wx.PlatformInfo and 'gtk2' in wx.PlatformInfo:
+ FACES = { 'times' : 'Serif',
+ 'mono' : 'Monospace',
+ 'helv' : 'Sans',
+ 'other' : 'new century schoolbook',
+ 'size' : 10,
+ 'lnsize' : 9,
+ 'backcol' : '#FFFFFF',
+ 'calltipbg' : '#FFFFB8',
+ 'calltipfg' : '#404040',
+ }
+
+elif 'wxMac' in wx.PlatformInfo:
+ FACES = { 'times' : 'Lucida Grande',
+ 'mono' : 'Courier New',
+ 'helv' : 'Geneva',
+ 'other' : 'new century schoolbook',
+ 'size' : 13,
+ 'lnsize' : 10,
+ 'backcol' : '#FFFFFF',
+ 'calltipbg' : '#FFFFB8',
+ 'calltipfg' : '#404040',
+ }
+
+else: # GTK1, etc.
+ FACES = { 'times' : 'Times',
+ 'mono' : 'Courier',
+ 'helv' : 'Helvetica',
+ 'other' : 'new century schoolbook',
+ 'size' : 12,
+ 'lnsize' : 10,
+ 'backcol' : '#FFFFFF',
+ 'calltipbg' : '#FFFFB8',
+ 'calltipfg' : '#404040',
+ }
+
+
+class EditWindow(stc.StyledTextCtrl):
+ """EditWindow based on StyledTextCtrl."""
+
+ revision = __revision__
+
+ def __init__(self, parent, id=-1, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=wx.CLIP_CHILDREN | wx.SUNKEN_BORDER):
+ """Create EditWindow instance."""
+ stc.StyledTextCtrl.__init__(self, parent, id, pos, size, style)
+ self.__config()
+ stc.EVT_STC_UPDATEUI(self, id, self.OnUpdateUI)
+ dispatcher.connect(receiver=self._fontsizer, signal='FontIncrease')
+ dispatcher.connect(receiver=self._fontsizer, signal='FontDecrease')
+ dispatcher.connect(receiver=self._fontsizer, signal='FontDefault')
+
+ def _fontsizer(self, signal):
+ """Receiver for Font* signals."""
+ size = self.GetZoom()
+ if signal == 'FontIncrease':
+ size += 1
+ elif signal == 'FontDecrease':
+ size -= 1
+ elif signal == 'FontDefault':
+ size = 0
+ self.SetZoom(size)
+
+ def __config(self):
+ """Configure shell based on user preferences."""
+ self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
+ self.SetMarginWidth(1, 40)
+
+ self.SetLexer(stc.STC_LEX_PYTHON)
+ self.SetKeyWords(0, ' '.join(keyword.kwlist))
+
+ self.setStyles(FACES)
+ self.SetViewWhiteSpace(False)
+ self.SetTabWidth(4)
+ self.SetUseTabs(False)
+ # Do we want to automatically pop up command completion options?
+ self.autoComplete = True
+ self.autoCompleteIncludeMagic = True
+ self.autoCompleteIncludeSingle = True
+ self.autoCompleteIncludeDouble = True
+ self.autoCompleteCaseInsensitive = True
+ self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive)
+ self.autoCompleteAutoHide = False
+ self.AutoCompSetAutoHide(self.autoCompleteAutoHide)
+ self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
+ # Do we want to automatically pop up command argument help?
+ self.autoCallTip = True
+ self.CallTipSetBackground(FACES['calltipbg'])
+ self.CallTipSetForeground(FACES['calltipfg'])
+ self.SetWrapMode(False)
+ try:
+ self.SetEndAtLastLine(False)
+ except AttributeError:
+ pass
+
+ def setStyles(self, faces):
+ """Configure font size, typeface and color for lexer."""
+
+ # Default style
+ self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
+ "face:%(mono)s,size:%(size)d,back:%(backcol)s" % \
+ faces)
+
+ self.StyleClearAll()
+
+ # Built in styles
+ self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
+ "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
+ self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
+ "face:%(mono)s" % faces)
+ self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
+ "fore:#0000FF,back:#FFFF88")
+ self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
+ "fore:#FF0000,back:#FFFF88")
+
+ # Python styles
+ self.StyleSetSpec(stc.STC_P_DEFAULT,
+ "face:%(mono)s" % faces)
+ self.StyleSetSpec(stc.STC_P_COMMENTLINE,
+ "fore:#007F00,face:%(mono)s" % faces)
+ self.StyleSetSpec(stc.STC_P_NUMBER,
+ "")
+ self.StyleSetSpec(stc.STC_P_STRING,
+ "fore:#7F007F,face:%(mono)s" % faces)
+ self.StyleSetSpec(stc.STC_P_CHARACTER,
+ "fore:#7F007F,face:%(mono)s" % faces)
+ self.StyleSetSpec(stc.STC_P_WORD,
+ "fore:#00007F,bold")
+ self.StyleSetSpec(stc.STC_P_TRIPLE,
+ "fore:#7F0000")
+ self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
+ "fore:#000033,back:#FFFFE8")
+ self.StyleSetSpec(stc.STC_P_CLASSNAME,
+ "fore:#0000FF,bold")
+ self.StyleSetSpec(stc.STC_P_DEFNAME,
+ "fore:#007F7F,bold")
+ self.StyleSetSpec(stc.STC_P_OPERATOR,
+ "")
+ self.StyleSetSpec(stc.STC_P_IDENTIFIER,
+ "")
+ self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
+ "fore:#7F7F7F")
+ self.StyleSetSpec(stc.STC_P_STRINGEOL,
+ "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
+
+ def OnUpdateUI(self, event):
+ """Check for matching braces."""
+ # If the auto-complete window is up let it do its thing.
+ if self.AutoCompActive() or self.CallTipActive():
+ return
+ 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 '[]{}()' \
+ and styleBefore == stc.STC_P_OPERATOR:
+ braceAtCaret = caretPos - 1
+
+ # Check after.
+ if braceAtCaret < 0:
+ charAfter = self.GetCharAt(caretPos)
+ styleAfter = self.GetStyleAt(caretPos)
+ if charAfter and chr(charAfter) in '[]{}()' \
+ and styleAfter == stc.STC_P_OPERATOR:
+ braceAtCaret = caretPos
+
+ if braceAtCaret >= 0:
+ braceOpposite = self.BraceMatch(braceAtCaret)
+
+ if braceAtCaret != -1 and braceOpposite == -1:
+ self.BraceBadLight(braceAtCaret)
+ else:
+ self.BraceHighlight(braceAtCaret, braceOpposite)
+
+ def CanCopy(self):
+ """Return True if text is selected and can be copied."""
+ return self.GetSelectionStart() != self.GetSelectionEnd()
+
+ def CanCut(self):
+ """Return True if text is selected and can be cut."""
+ return self.CanCopy() and self.CanEdit()
+
+ def CanEdit(self):
+ """Return True if editing should succeed."""
+ return not self.GetReadOnly()
+
+ def CanPaste(self):
+ """Return True if pasting should succeed."""
+ return stc.StyledTextCtrl.CanPaste(self) and self.CanEdit()