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
))