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