]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/py/editwindow.py
use wx.CallAfter to set the insertion point
[wxWidgets.git] / wxPython / wx / py / editwindow.py
1 """EditWindow class."""
2
3 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
4 __cvsid__ = "$Id$"
5 __revision__ = "$Revision$"[11:-2]
6
7 import wx
8 from wx import stc
9
10 import keyword
11 import os
12 import sys
13 import time
14
15 import dispatcher
16 from version import VERSION
17
18
19 if 'wxMSW' in wx.PlatformInfo:
20 FACES = { 'times' : 'Times New Roman',
21 'mono' : 'Courier New',
22 'helv' : 'Arial',
23 'lucida' : 'Lucida Console',
24 'other' : 'Comic Sans MS',
25 'size' : 10,
26 'lnsize' : 8,
27 'backcol' : '#FFFFFF',
28 'calltipbg' : '#FFFFB8',
29 'calltipfg' : '#404040',
30 }
31
32 elif 'wxGTK' in wx.PlatformInfo and 'gtk2' in wx.PlatformInfo:
33 FACES = { 'times' : 'Serif',
34 'mono' : 'Monospace',
35 'helv' : 'Sans',
36 'other' : 'new century schoolbook',
37 'size' : 10,
38 'lnsize' : 9,
39 'backcol' : '#FFFFFF',
40 'calltipbg' : '#FFFFB8',
41 'calltipfg' : '#404040',
42 }
43
44 elif 'wxMac' in wx.PlatformInfo:
45 FACES = { 'times' : 'Lucida Grande',
46 'mono' : 'Courier New',
47 'helv' : 'Geneva',
48 'other' : 'new century schoolbook',
49 'size' : 13,
50 'lnsize' : 10,
51 'backcol' : '#FFFFFF',
52 'calltipbg' : '#FFFFB8',
53 'calltipfg' : '#404040',
54 }
55
56 else: # GTK1, etc.
57 FACES = { 'times' : 'Times',
58 'mono' : 'Courier',
59 'helv' : 'Helvetica',
60 'other' : 'new century schoolbook',
61 'size' : 12,
62 'lnsize' : 10,
63 'backcol' : '#FFFFFF',
64 'calltipbg' : '#FFFFB8',
65 'calltipfg' : '#404040',
66 }
67
68
69 class EditWindow(stc.StyledTextCtrl):
70 """EditWindow based on StyledTextCtrl."""
71
72 revision = __revision__
73
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)
78 self.__config()
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')
83
84 def _fontsizer(self, signal):
85 """Receiver for Font* signals."""
86 size = self.GetZoom()
87 if signal == 'FontIncrease':
88 size += 1
89 elif signal == 'FontDecrease':
90 size -= 1
91 elif signal == 'FontDefault':
92 size = 0
93 self.SetZoom(size)
94
95 def __config(self):
96 """Configure shell based on user preferences."""
97 self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
98 self.SetMarginWidth(1, 40)
99
100 self.SetLexer(stc.STC_LEX_PYTHON)
101 self.SetKeyWords(0, ' '.join(keyword.kwlist))
102
103 self.setStyles(FACES)
104 self.SetViewWhiteSpace(False)
105 self.SetTabWidth(4)
106 self.SetUseTabs(False)
107 # Do we want to automatically pop up command completion options?
108 self.autoComplete = True
109 self.autoCompleteIncludeMagic = True
110 self.autoCompleteIncludeSingle = True
111 self.autoCompleteIncludeDouble = True
112 self.autoCompleteCaseInsensitive = True
113 self.AutoCompSetIgnoreCase(self.autoCompleteCaseInsensitive)
114 self.autoCompleteAutoHide = False
115 self.AutoCompSetAutoHide(self.autoCompleteAutoHide)
116 self.AutoCompStops(' .,;:([)]}\'"\\<>%^&+-=*/|`')
117 # Do we want to automatically pop up command argument help?
118 self.autoCallTip = True
119 self.CallTipSetBackground(FACES['calltipbg'])
120 self.CallTipSetForeground(FACES['calltipfg'])
121 self.SetWrapMode(False)
122 try:
123 self.SetEndAtLastLine(False)
124 except AttributeError:
125 pass
126
127 def setStyles(self, faces):
128 """Configure font size, typeface and color for lexer."""
129
130 # Default style
131 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
132 "face:%(mono)s,size:%(size)d,back:%(backcol)s" % \
133 faces)
134
135 self.StyleClearAll()
136
137 # Built in styles
138 self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,
139 "back:#C0C0C0,face:%(mono)s,size:%(lnsize)d" % faces)
140 self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR,
141 "face:%(mono)s" % faces)
142 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
143 "fore:#0000FF,back:#FFFF88")
144 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
145 "fore:#FF0000,back:#FFFF88")
146
147 # Python styles
148 self.StyleSetSpec(stc.STC_P_DEFAULT,
149 "face:%(mono)s" % faces)
150 self.StyleSetSpec(stc.STC_P_COMMENTLINE,
151 "fore:#007F00,face:%(mono)s" % faces)
152 self.StyleSetSpec(stc.STC_P_NUMBER,
153 "")
154 self.StyleSetSpec(stc.STC_P_STRING,
155 "fore:#7F007F,face:%(mono)s" % faces)
156 self.StyleSetSpec(stc.STC_P_CHARACTER,
157 "fore:#7F007F,face:%(mono)s" % faces)
158 self.StyleSetSpec(stc.STC_P_WORD,
159 "fore:#00007F,bold")
160 self.StyleSetSpec(stc.STC_P_TRIPLE,
161 "fore:#7F0000")
162 self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE,
163 "fore:#000033,back:#FFFFE8")
164 self.StyleSetSpec(stc.STC_P_CLASSNAME,
165 "fore:#0000FF,bold")
166 self.StyleSetSpec(stc.STC_P_DEFNAME,
167 "fore:#007F7F,bold")
168 self.StyleSetSpec(stc.STC_P_OPERATOR,
169 "")
170 self.StyleSetSpec(stc.STC_P_IDENTIFIER,
171 "")
172 self.StyleSetSpec(stc.STC_P_COMMENTBLOCK,
173 "fore:#7F7F7F")
174 self.StyleSetSpec(stc.STC_P_STRINGEOL,
175 "fore:#000000,face:%(mono)s,back:#E0C0E0,eolfilled" % faces)
176
177 def OnUpdateUI(self, event):
178 """Check for matching braces."""
179 # If the auto-complete window is up let it do its thing.
180 if self.AutoCompActive() or self.CallTipActive():
181 return
182 braceAtCaret = -1
183 braceOpposite = -1
184 charBefore = None
185 caretPos = self.GetCurrentPos()
186 if caretPos > 0:
187 charBefore = self.GetCharAt(caretPos - 1)
188 styleBefore = self.GetStyleAt(caretPos - 1)
189
190 # Check before.
191 if charBefore and chr(charBefore) in '[]{}()' \
192 and styleBefore == stc.STC_P_OPERATOR:
193 braceAtCaret = caretPos - 1
194
195 # Check after.
196 if braceAtCaret < 0:
197 charAfter = self.GetCharAt(caretPos)
198 styleAfter = self.GetStyleAt(caretPos)
199 if charAfter and chr(charAfter) in '[]{}()' \
200 and styleAfter == stc.STC_P_OPERATOR:
201 braceAtCaret = caretPos
202
203 if braceAtCaret >= 0:
204 braceOpposite = self.BraceMatch(braceAtCaret)
205
206 if braceAtCaret != -1 and braceOpposite == -1:
207 self.BraceBadLight(braceAtCaret)
208 else:
209 self.BraceHighlight(braceAtCaret, braceOpposite)
210
211 def CanCopy(self):
212 """Return True if text is selected and can be copied."""
213 return self.GetSelectionStart() != self.GetSelectionEnd()
214
215 def CanCut(self):
216 """Return True if text is selected and can be cut."""
217 return self.CanCopy() and self.CanEdit()
218
219 def CanEdit(self):
220 """Return True if editing should succeed."""
221 return not self.GetReadOnly()
222
223 def CanPaste(self):
224 """Return True if pasting should succeed."""
225 return stc.StyledTextCtrl.CanPaste(self) and self.CanEdit()