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" % \
 
 148         self
.StyleSetSpec(stc
.STC_STYLE_LINENUMBER
, 
 149                           "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % FACES
) 
 150         self
.StyleSetSpec(stc
.STC_STYLE_CONTROLCHAR
, 
 151                           "face:%(mono)s" % faces
) 
 152         self
.StyleSetSpec(stc
.STC_STYLE_BRACELIGHT
, 
 153                           "fore:#0000FF,back:#FFFF88") 
 154         self
.StyleSetSpec(stc
.STC_STYLE_BRACEBAD
, 
 155                           "fore:#FF0000,back:#FFFF88") 
 158         self
.StyleSetSpec(stc
.STC_P_DEFAULT
, 
 159                           "face:%(mono)s" % faces
) 
 160         self
.StyleSetSpec(stc
.STC_P_COMMENTLINE
, 
 161                           "fore:#007F00,face:%(mono)s" % faces
) 
 162         self
.StyleSetSpec(stc
.STC_P_NUMBER
, 
 164         self
.StyleSetSpec(stc
.STC_P_STRING
, 
 165                           "fore:#7F007F,face:%(mono)s" % faces
) 
 166         self
.StyleSetSpec(stc
.STC_P_CHARACTER
, 
 167                           "fore:#7F007F,face:%(mono)s" % faces
) 
 168         self
.StyleSetSpec(stc
.STC_P_WORD
, 
 170         self
.StyleSetSpec(stc
.STC_P_TRIPLE
, 
 172         self
.StyleSetSpec(stc
.STC_P_TRIPLEDOUBLE
, 
 173                           "fore:#000033,back:#FFFFE8") 
 174         self
.StyleSetSpec(stc
.STC_P_CLASSNAME
, 
 176         self
.StyleSetSpec(stc
.STC_P_DEFNAME
, 
 178         self
.StyleSetSpec(stc
.STC_P_OPERATOR
, 
 180         self
.StyleSetSpec(stc
.STC_P_IDENTIFIER
, 
 182         self
.StyleSetSpec(stc
.STC_P_COMMENTBLOCK
, 
 184         self
.StyleSetSpec(stc
.STC_P_STRINGEOL
, 
 185                           "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces
) 
 187     def OnUpdateUI(self
, event
): 
 188         """Check for matching braces.""" 
 189         # If the auto-complete window is up let it do its thing. 
 190         if self
.AutoCompActive() or self
.CallTipActive(): 
 195         caretPos 
= self
.GetCurrentPos() 
 197             charBefore 
= self
.GetCharAt(caretPos 
- 1) 
 198             styleBefore 
= self
.GetStyleAt(caretPos 
- 1) 
 201         if charBefore 
and chr(charBefore
) in '[]{}()' \
 
 202         and styleBefore 
== stc
.STC_P_OPERATOR
: 
 203             braceAtCaret 
= caretPos 
- 1 
 207             charAfter 
= self
.GetCharAt(caretPos
) 
 208             styleAfter 
= self
.GetStyleAt(caretPos
) 
 209             if charAfter 
and chr(charAfter
) in '[]{}()' \
 
 210             and styleAfter 
== stc
.STC_P_OPERATOR
: 
 211                 braceAtCaret 
= caretPos
 
 213         if braceAtCaret 
>= 0: 
 214             braceOpposite 
= self
.BraceMatch(braceAtCaret
) 
 216         if braceAtCaret 
!= -1  and braceOpposite 
== -1: 
 217             self
.BraceBadLight(braceAtCaret
) 
 219             self
.BraceHighlight(braceAtCaret
, braceOpposite
) 
 222         """Return True if text is selected and can be copied.""" 
 223         return self
.GetSelectionStart() != self
.GetSelectionEnd() 
 226         """Return True if text is selected and can be cut.""" 
 227         return self
.CanCopy() and self
.CanEdit() 
 230         """Return True if editing should succeed.""" 
 231         return not self
.GetReadOnly() 
 234         """Return True if pasting should succeed.""" 
 235         return stc
.StyledTextCtrl
.CanPaste(self
) and self
.CanEdit() 
 238     def GetLastPosition(self
): 
 239         return self
.GetLength() 
 241     def GetRange(self
, start
, end
): 
 242         return self
.GetTextRange(start
, end
) 
 244     def GetSelection(self
): 
 245         return self
.GetAnchor(), self
.GetCurrentPos() 
 247     def ShowPosition(self
, pos
): 
 248         line 
= self
.LineFromPosition(pos
) 
 249         #self.EnsureVisible(line) 
 252     def DoFindNext(self
, findData
, findDlg
=None): 
 253         backward 
= not (findData
.GetFlags() & wx
.FR_DOWN
) 
 254         matchcase 
= (findData
.GetFlags() & wx
.FR_MATCHCASE
) != 0 
 255         end 
= self
.GetLastPosition() 
 256         textstring 
= self
.GetRange(0, end
) 
 257         findstring 
= findData
.GetFindString() 
 259             textstring 
= textstring
.lower() 
 260             findstring 
= findstring
.lower() 
 262             start 
= self
.GetSelection()[0] 
 263             loc 
= textstring
.rfind(findstring
, 0, start
) 
 265             start 
= self
.GetSelection()[1] 
 266             loc 
= textstring
.find(findstring
, start
) 
 268         # if it wasn't found then restart at begining 
 269         if loc 
== -1 and start 
!= 0: 
 272                 loc 
= textstring
.rfind(findstring
, 0, start
) 
 275                 loc 
= textstring
.find(findstring
, start
) 
 277         # was it still not found? 
 279             dlg 
= wx
.MessageDialog(self
, 'Unable to find the search text.', 
 281                           wx
.OK | wx
.ICON_INFORMATION
) 
 286                 wx
.CallAfter(findDlg
.SetFocus
) 
 291         # show and select the found text 
 292         self
.ShowPosition(loc
) 
 293         self
.SetSelection(loc
, loc 
+ len(findstring
))