1 """EditWindow class.""" 
   3 __author__ 
= "Patrick K. O'Brien <pobrien@orbtech.com>" 
   5 __revision__ 
= "$Revision$"[11:-2] 
  16 from version 
import VERSION
 
  19 if 'wxMSW' in wx
.PlatformInfo
: 
  20     FACES 
= { 'times'     : 'Times New Roman', 
  21               'mono'      : 'Courier New', 
  23               'lucida'    : 'Lucida Console', 
  24               'other'     : 'Comic Sans MS', 
  27               'backcol'   : '#FFFFFF', 
  28               'calltipbg' : '#FFFFB8', 
  29               'calltipfg' : '#404040', 
  32 elif 'wxGTK' in wx
.PlatformInfo 
and 'gtk2' in wx
.PlatformInfo
: 
  33     FACES 
= { 'times'     : 'Serif', 
  36               'other'     : 'new century schoolbook', 
  39               'backcol'   : '#FFFFFF', 
  40               'calltipbg' : '#FFFFB8', 
  41               'calltipfg' : '#404040', 
  44 elif 'wxMac' in wx
.PlatformInfo
: 
  45     FACES 
= { 'times'     : 'Lucida Grande', 
  46               'mono'      : 'Courier New', 
  48               'other'     : 'new century schoolbook', 
  51               'backcol'   : '#FFFFFF', 
  52               'calltipbg' : '#FFFFB8', 
  53               'calltipfg' : '#404040', 
  57     FACES 
= { 'times'     : 'Times', 
  60               'other'     : 'new century schoolbook', 
  63               'backcol'   : '#FFFFFF', 
  64               'calltipbg' : '#FFFFB8', 
  65               'calltipfg' : '#404040', 
  69 class EditWindow(stc
.StyledTextCtrl
): 
  70     """EditWindow based on StyledTextCtrl.""" 
  72     revision 
= __revision__
 
  74     def __init__(self
, parent
, id=-1, pos
=wx
.DefaultPosition
, 
  75                  size
=wx
.DefaultSize
, style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
): 
  76         """Create EditWindow instance.""" 
  77         stc
.StyledTextCtrl
.__init
__(self
, parent
, id, pos
, size
, style
) 
  79         stc
.EVT_STC_UPDATEUI(self
, id, self
.OnUpdateUI
) 
  80         dispatcher
.connect(receiver
=self
._fontsizer
, signal
='FontIncrease') 
  81         dispatcher
.connect(receiver
=self
._fontsizer
, signal
='FontDecrease') 
  82         dispatcher
.connect(receiver
=self
._fontsizer
, signal
='FontDefault') 
  84     def _fontsizer(self
, signal
): 
  85         """Receiver for Font* signals.""" 
  87         if signal 
== 'FontIncrease': 
  89         elif signal 
== 'FontDecrease': 
  91         elif signal 
== 'FontDefault': 
  97         self
.setDisplayLineNumbers(False) 
  99         self
.SetLexer(stc
.STC_LEX_PYTHON
) 
 100         self
.SetKeyWords(0, ' '.join(keyword
.kwlist
)) 
 102         self
.setStyles(FACES
) 
 103         self
.SetViewWhiteSpace(False) 
 105         self
.SetUseTabs(False) 
 106         # Do we want to automatically pop up command completion options? 
 107         self
.autoComplete 
= True 
 108         self
.autoCompleteIncludeMagic 
= True 
 109         self
.autoCompleteIncludeSingle 
= True 
 110         self
.autoCompleteIncludeDouble 
= True 
 111         self
.autoCompleteCaseInsensitive 
= True 
 112         self
.AutoCompSetIgnoreCase(self
.autoCompleteCaseInsensitive
) 
 113         self
.autoCompleteAutoHide 
= False 
 114         self
.AutoCompSetAutoHide(self
.autoCompleteAutoHide
) 
 115         self
.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`') 
 116         # Do we want to automatically pop up command argument help? 
 117         self
.autoCallTip 
= True 
 118         self
.callTipInsert 
= True 
 119         self
.CallTipSetBackground(FACES
['calltipbg']) 
 120         self
.CallTipSetForeground(FACES
['calltipfg']) 
 121         self
.SetWrapMode(False) 
 123             self
.SetEndAtLastLine(False) 
 124         except AttributeError: 
 127     def setDisplayLineNumbers(self
, state
): 
 128         self
.lineNumbers 
= state
 
 130             self
.SetMarginType(1, stc
.STC_MARGIN_NUMBER
) 
 131             self
.SetMarginWidth(1, 40) 
 133             # Leave a small margin so the feature hidden lines marker can be seen 
 134             self
.SetMarginType(1, 0) 
 135             self
.SetMarginWidth(1, 10) 
 137     def setStyles(self
, faces
): 
 138         """Configure font size, typeface and color for lexer.""" 
 141         self
.StyleSetSpec(stc
.STC_STYLE_DEFAULT
, 
 142                           "face:%(mono)s,size:%(size)d,back:%(backcol)s" % \
 
 146         self
.SetSelForeground(True, wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_HIGHLIGHTTEXT
)) 
 147         self
.SetSelBackground(True, wx
.SystemSettings
.GetColour(wx
.SYS_COLOUR_HIGHLIGHT
)) 
 150         self
.StyleSetSpec(stc
.STC_STYLE_LINENUMBER
, 
 151                           "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % FACES
) 
 152         self
.StyleSetSpec(stc
.STC_STYLE_CONTROLCHAR
, 
 153                           "face:%(mono)s" % faces
) 
 154         self
.StyleSetSpec(stc
.STC_STYLE_BRACELIGHT
, 
 155                           "fore:#0000FF,back:#FFFF88") 
 156         self
.StyleSetSpec(stc
.STC_STYLE_BRACEBAD
, 
 157                           "fore:#FF0000,back:#FFFF88") 
 160         self
.StyleSetSpec(stc
.STC_P_DEFAULT
, 
 161                           "face:%(mono)s" % faces
) 
 162         self
.StyleSetSpec(stc
.STC_P_COMMENTLINE
, 
 163                           "fore:#007F00,face:%(mono)s" % faces
) 
 164         self
.StyleSetSpec(stc
.STC_P_NUMBER
, 
 166         self
.StyleSetSpec(stc
.STC_P_STRING
, 
 167                           "fore:#7F007F,face:%(mono)s" % faces
) 
 168         self
.StyleSetSpec(stc
.STC_P_CHARACTER
, 
 169                           "fore:#7F007F,face:%(mono)s" % faces
) 
 170         self
.StyleSetSpec(stc
.STC_P_WORD
, 
 172         self
.StyleSetSpec(stc
.STC_P_TRIPLE
, 
 174         self
.StyleSetSpec(stc
.STC_P_TRIPLEDOUBLE
, 
 175                           "fore:#000033,back:#FFFFE8") 
 176         self
.StyleSetSpec(stc
.STC_P_CLASSNAME
, 
 178         self
.StyleSetSpec(stc
.STC_P_DEFNAME
, 
 180         self
.StyleSetSpec(stc
.STC_P_OPERATOR
, 
 182         self
.StyleSetSpec(stc
.STC_P_IDENTIFIER
, 
 184         self
.StyleSetSpec(stc
.STC_P_COMMENTBLOCK
, 
 186         self
.StyleSetSpec(stc
.STC_P_STRINGEOL
, 
 187                           "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces
) 
 189     def OnUpdateUI(self
, event
): 
 190         """Check for matching braces.""" 
 191         # If the auto-complete window is up let it do its thing. 
 192         if self
.AutoCompActive() or self
.CallTipActive(): 
 197         caretPos 
= self
.GetCurrentPos() 
 199             charBefore 
= self
.GetCharAt(caretPos 
- 1) 
 200             styleBefore 
= self
.GetStyleAt(caretPos 
- 1) 
 203         if charBefore 
and chr(charBefore
) in '[]{}()' \
 
 204         and styleBefore 
== stc
.STC_P_OPERATOR
: 
 205             braceAtCaret 
= caretPos 
- 1 
 209             charAfter 
= self
.GetCharAt(caretPos
) 
 210             styleAfter 
= self
.GetStyleAt(caretPos
) 
 211             if charAfter 
and chr(charAfter
) in '[]{}()' \
 
 212             and styleAfter 
== stc
.STC_P_OPERATOR
: 
 213                 braceAtCaret 
= caretPos
 
 215         if braceAtCaret 
>= 0: 
 216             braceOpposite 
= self
.BraceMatch(braceAtCaret
) 
 218         if braceAtCaret 
!= -1  and braceOpposite 
== -1: 
 219             self
.BraceBadLight(braceAtCaret
) 
 221             self
.BraceHighlight(braceAtCaret
, braceOpposite
) 
 224         """Return True if text is selected and can be copied.""" 
 225         return self
.GetSelectionStart() != self
.GetSelectionEnd() 
 228         """Return True if text is selected and can be cut.""" 
 229         return self
.CanCopy() and self
.CanEdit() 
 232         """Return True if editing should succeed.""" 
 233         return not self
.GetReadOnly() 
 236         """Return True if pasting should succeed.""" 
 237         return stc
.StyledTextCtrl
.CanPaste(self
) and self
.CanEdit() 
 240     def GetLastPosition(self
): 
 241         return self
.GetLength() 
 243     def GetRange(self
, start
, end
): 
 244         return self
.GetTextRange(start
, end
) 
 246     def GetSelection(self
): 
 247         return self
.GetAnchor(), self
.GetCurrentPos() 
 249     def ShowPosition(self
, pos
): 
 250         line 
= self
.LineFromPosition(pos
) 
 251         #self.EnsureVisible(line) 
 254     def DoFindNext(self
, findData
, findDlg
=None): 
 255         backward 
= not (findData
.GetFlags() & wx
.FR_DOWN
) 
 256         matchcase 
= (findData
.GetFlags() & wx
.FR_MATCHCASE
) != 0 
 257         end 
= self
.GetLastPosition() 
 258         textstring 
= self
.GetRange(0, end
) 
 259         findstring 
= findData
.GetFindString() 
 261             textstring 
= textstring
.lower() 
 262             findstring 
= findstring
.lower() 
 264             start 
= self
.GetSelection()[0] 
 265             loc 
= textstring
.rfind(findstring
, 0, start
) 
 267             start 
= self
.GetSelection()[1] 
 268             loc 
= textstring
.find(findstring
, start
) 
 270         # if it wasn't found then restart at begining 
 271         if loc 
== -1 and start 
!= 0: 
 274                 loc 
= textstring
.rfind(findstring
, 0, start
) 
 277                 loc 
= textstring
.find(findstring
, start
) 
 279         # was it still not found? 
 281             dlg 
= wx
.MessageDialog(self
, 'Unable to find the search text.', 
 283                           wx
.OK | wx
.ICON_INFORMATION
) 
 288                 wx
.CallAfter(findDlg
.SetFocus
) 
 293         # show and select the found text 
 294         self
.ShowPosition(loc
) 
 295         self
.SetSelection(loc
, loc 
+ len(findstring
))