20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 #You should have received a copy of the GNU General Public |
22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from wxPython.wx import * |
|
26 from wxPython.stc import * |
|
27 import wx |
25 import wx |
|
26 import wx.stc |
28 from types import * |
27 from types import * |
29 |
28 |
30 import re |
29 import re |
31 |
30 |
32 #------------------------------------------------------------------------------- |
31 #------------------------------------------------------------------------------- |
39 LETTERS = ['_'] |
38 LETTERS = ['_'] |
40 for i in xrange(26): |
39 for i in xrange(26): |
41 LETTERS.append(chr(ord('a') + i)) |
40 LETTERS.append(chr(ord('a') + i)) |
42 LETTERS.append(chr(ord('A') + i)) |
41 LETTERS.append(chr(ord('A') + i)) |
43 |
42 |
44 [wxSTC_PLC_WORD, wxSTC_PLC_COMMENT, wxSTC_PLC_NUMBER, wxSTC_PLC_VARIABLE, |
43 [STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_VARIABLE, |
45 wxSTC_PLC_FUNCTION, wxSTC_PLC_JUMP] = range(6) |
44 STC_PLC_FUNCTION, STC_PLC_JUMP] = range(6) |
46 [SPACE, WORD, NUMBER, COMMENT] = range(4) |
45 [SPACE, WORD, NUMBER, COMMENT] = range(4) |
47 |
46 |
48 [wxID_TEXTVIEWER, |
47 [ID_TEXTVIEWER, |
49 ] = [wx.NewId() for _init_ctrls in range(1)] |
48 ] = [wx.NewId() for _init_ctrls in range(1)] |
50 |
49 |
51 if wx.Platform == '__WXMSW__': |
50 if wx.Platform == '__WXMSW__': |
52 faces = { 'times': 'Times New Roman', |
51 faces = { 'times': 'Times New Roman', |
53 'mono' : 'Courier New', |
52 'mono' : 'Courier New', |
88 else: |
87 else: |
89 return i + 1 |
88 return i + 1 |
90 else: |
89 else: |
91 return None |
90 return None |
92 |
91 |
93 class TextViewer(wxStyledTextCtrl): |
92 class TextViewer(wx.stc.StyledTextCtrl): |
94 |
93 |
95 def __init__(self, parent, window, controler): |
94 def __init__(self, parent, window, controler): |
96 wxStyledTextCtrl.__init__(self, parent, wxID_TEXTVIEWER, style=0) |
95 wx.stc.StyledTextCtrl.__init__(self, parent, ID_TEXTVIEWER, style=0) |
97 |
96 |
98 self.CmdKeyAssign(ord('+'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN) |
97 self.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN) |
99 self.CmdKeyAssign(ord('-'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT) |
98 self.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT) |
100 |
99 |
101 self.SetViewWhiteSpace(False) |
100 self.SetViewWhiteSpace(False) |
102 |
101 |
103 self.SetLexer(wxSTC_LEX_CONTAINER) |
102 self.SetLexer(wx.stc.STC_LEX_CONTAINER) |
104 |
103 |
105 # Global default styles for all languages |
104 # Global default styles for all languages |
106 self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) |
105 self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) |
107 self.StyleClearAll() # Reset all to be like the default |
106 self.StyleClearAll() # Reset all to be like the default |
108 |
107 |
109 self.StyleSetSpec(wxSTC_STYLE_LINENUMBER, "back:#C0C0C0,size:%(size)d" % faces) |
108 self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,size:%(size)d" % faces) |
110 self.SetSelBackground(1, "#E0E0E0") |
109 self.SetSelBackground(1, "#E0E0E0") |
111 |
110 |
112 # Highlighting styles |
111 # Highlighting styles |
113 self.StyleSetSpec(wxSTC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
112 self.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
114 self.StyleSetSpec(wxSTC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) |
113 self.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) |
115 self.StyleSetSpec(wxSTC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) |
114 self.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) |
116 self.StyleSetSpec(wxSTC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) |
115 self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) |
117 self.StyleSetSpec(wxSTC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
116 self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
118 self.StyleSetSpec(wxSTC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces) |
117 self.StyleSetSpec(STC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces) |
119 |
118 |
120 # Indicators styles |
119 # Indicators styles |
121 self.IndicatorSetStyle(0, wxSTC_INDIC_SQUIGGLE) |
120 self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE) |
122 self.IndicatorSetForeground(0, wxRED) |
121 self.IndicatorSetForeground(0, wx.RED) |
123 |
122 |
124 # Line numbers in the margin |
123 # Line numbers in the margin |
125 self.SetMarginType(1, wxSTC_MARGIN_NUMBER) |
124 self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER) |
126 self.SetMarginWidth(1, 50) |
125 self.SetMarginWidth(1, 50) |
127 |
126 |
128 # Indentation size |
127 # Indentation size |
129 self.SetTabWidth(2) |
128 self.SetTabWidth(2) |
130 self.SetUseTabs(0) |
129 self.SetUseTabs(0) |
139 self.CurrentAction = None |
138 self.CurrentAction = None |
140 |
139 |
141 self.Parent = window |
140 self.Parent = window |
142 self.Controler = controler |
141 self.Controler = controler |
143 |
142 |
144 self.SetModEventMask(wxSTC_MOD_BEFOREINSERT|wxSTC_MOD_BEFOREDELETE) |
143 self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE) |
145 |
144 |
146 EVT_KEY_DOWN(self, self.OnKeyDown) |
145 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) |
147 EVT_STC_STYLENEEDED(self, wxID_TEXTVIEWER, self.OnStyleNeeded) |
146 self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWER) |
148 EVT_STC_DO_DROP(self, wxID_TEXTVIEWER, self.OnDoDrop) |
147 self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER) |
149 EVT_KILL_FOCUS(self, self.OnKillFocus) |
148 self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) |
150 EVT_STC_MODIFIED(self, wxID_TEXTVIEWER, self.OnModification) |
149 self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWER) |
151 |
150 |
152 def OnModification(self, event): |
151 def OnModification(self, event): |
153 if not self.DisableEvents: |
152 if not self.DisableEvents: |
154 mod_type = event.GetModificationType() |
153 mod_type = event.GetModificationType() |
155 if not (mod_type&wxSTC_PERFORMED_UNDO or mod_type&wxSTC_PERFORMED_REDO): |
154 if not (mod_type&wx.stc.STC_PERFORMED_UNDO or mod_type&wx.stc.STC_PERFORMED_REDO): |
156 if mod_type&wxSTC_MOD_BEFOREINSERT: |
155 if mod_type&wx.stc.STC_MOD_BEFOREINSERT: |
157 if self.CurrentAction == None: |
156 if self.CurrentAction == None: |
158 self.StartBuffering() |
157 self.StartBuffering() |
159 elif self.CurrentAction[0] != "Add" or self.CurrentAction[1] != event.GetPosition() - 1: |
158 elif self.CurrentAction[0] != "Add" or self.CurrentAction[1] != event.GetPosition() - 1: |
160 self.Controler.EndBuffering() |
159 self.Controler.EndBuffering() |
161 self.StartBuffering() |
160 self.StartBuffering() |
162 self.CurrentAction = ("Add", event.GetPosition()) |
161 self.CurrentAction = ("Add", event.GetPosition()) |
163 elif mod_type&wxSTC_MOD_BEFOREDELETE: |
162 elif mod_type&wx.stc.STC_MOD_BEFOREDELETE: |
164 if self.CurrentAction == None: |
163 if self.CurrentAction == None: |
165 self.StartBuffering() |
164 self.StartBuffering() |
166 elif self.CurrentAction[0] != "Delete" or self.CurrentAction[1] != event.GetPosition() + 1: |
165 elif self.CurrentAction[0] != "Delete" or self.CurrentAction[1] != event.GetPosition() + 1: |
167 self.Controler.EndBuffering() |
166 self.Controler.EndBuffering() |
168 self.StartBuffering() |
167 self.StartBuffering() |
254 while i < end_pos: |
253 while i < end_pos: |
255 char = chr(self.GetCharAt(i)).upper() |
254 char = chr(self.GetCharAt(i)).upper() |
256 line += char |
255 line += char |
257 if char == NEWLINE: |
256 if char == NEWLINE: |
258 if state == COMMENT: |
257 if state == COMMENT: |
259 self.SetStyling(i - start_pos + 1, wxSTC_PLC_COMMENT) |
258 self.SetStyling(i - start_pos + 1, STC_PLC_COMMENT) |
260 elif state == NUMBER: |
259 elif state == NUMBER: |
261 self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER) |
260 self.SetStyling(i - start_pos, STC_PLC_NUMBER) |
262 elif state == WORD: |
261 elif state == WORD: |
263 if word in self.Keywords: |
262 if word in self.Keywords: |
264 self.SetStyling(i - start_pos, wxSTC_PLC_WORD) |
263 self.SetStyling(i - start_pos, STC_PLC_WORD) |
265 elif word in self.Variables: |
264 elif word in self.Variables: |
266 self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE) |
265 self.SetStyling(i - start_pos, STC_PLC_VARIABLE) |
267 elif word in self.Functions: |
266 elif word in self.Functions: |
268 self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION) |
267 self.SetStyling(i - start_pos, STC_PLC_FUNCTION) |
269 elif word in self.Jumps: |
268 elif word in self.Jumps: |
270 self.SetStyling(i - start_pos, wxSTC_PLC_JUMP) |
269 self.SetStyling(i - start_pos, STC_PLC_JUMP) |
271 else: |
270 else: |
272 self.SetStyling(i - start_pos, 31) |
271 self.SetStyling(i - start_pos, 31) |
273 if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i: |
272 if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i: |
274 self.StartStyling(start_pos, wxSTC_INDICS_MASK) |
273 self.StartStyling(start_pos, wx.stc.STC_INDICS_MASK) |
275 self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK) |
274 self.SetStyling(i - start_pos, wx.stc.STC_INDIC0_MASK) |
276 self.StartStyling(i, 0xff) |
275 self.StartStyling(i, 0xff) |
277 else: |
276 else: |
278 self.SetStyling(i - start_pos, 31) |
277 self.SetStyling(i - start_pos, 31) |
279 start_pos = i |
278 start_pos = i |
280 state = SPACE |
279 state = SPACE |
307 if state == WORD and char != '.': |
306 if state == WORD and char != '.': |
308 word += char |
307 word += char |
309 else: |
308 else: |
310 if state == WORD: |
309 if state == WORD: |
311 if word in self.Keywords: |
310 if word in self.Keywords: |
312 self.SetStyling(i - start_pos, wxSTC_PLC_WORD) |
311 self.SetStyling(i - start_pos, STC_PLC_WORD) |
313 elif word in self.Variables: |
312 elif word in self.Variables: |
314 self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE) |
313 self.SetStyling(i - start_pos, STC_PLC_VARIABLE) |
315 elif word in self.Functions: |
314 elif word in self.Functions: |
316 self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION) |
315 self.SetStyling(i - start_pos, STC_PLC_FUNCTION) |
317 elif word in self.Jumps: |
316 elif word in self.Jumps: |
318 self.SetStyling(i - start_pos, wxSTC_PLC_JUMP) |
317 self.SetStyling(i - start_pos, STC_PLC_JUMP) |
319 else: |
318 else: |
320 self.SetStyling(i - start_pos, 31) |
319 self.SetStyling(i - start_pos, 31) |
321 if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i: |
320 if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i: |
322 self.StartStyling(start_pos, wxSTC_INDICS_MASK) |
321 self.StartStyling(start_pos, wx.stc.STC_INDICS_MASK) |
323 self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK) |
322 self.SetStyling(i - start_pos, wx.stc.STC_INDIC0_MASK) |
324 self.StartStyling(i, 0xff) |
323 self.StartStyling(i, 0xff) |
325 word = "" |
324 word = "" |
326 start_pos = i |
325 start_pos = i |
327 state = SPACE |
326 state = SPACE |
328 elif state == NUMBER: |
327 elif state == NUMBER: |
329 self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER) |
328 self.SetStyling(i - start_pos, STC_PLC_NUMBER) |
330 start_pos = i |
329 start_pos = i |
331 state = SPACE |
330 state = SPACE |
332 i += 1 |
331 i += 1 |
333 if state == COMMENT: |
332 if state == COMMENT: |
334 self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT) |
333 self.SetStyling(i - start_pos + 2, STC_PLC_COMMENT) |
335 elif state == NUMBER: |
334 elif state == NUMBER: |
336 self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER) |
335 self.SetStyling(i - start_pos, STC_PLC_NUMBER) |
337 elif state == WORD: |
336 elif state == WORD: |
338 if word in self.Keywords: |
337 if word in self.Keywords: |
339 self.SetStyling(i - start_pos, wxSTC_PLC_WORD) |
338 self.SetStyling(i - start_pos, STC_PLC_WORD) |
340 elif word in self.Variables: |
339 elif word in self.Variables: |
341 self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE) |
340 self.SetStyling(i - start_pos, STC_PLC_VARIABLE) |
342 elif word in self.Functions: |
341 elif word in self.Functions: |
343 self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION) |
342 self.SetStyling(i - start_pos, STC_PLC_FUNCTION) |
344 elif word in self.Jumps: |
343 elif word in self.Jumps: |
345 self.SetStyling(i - start_pos, wxSTC_PLC_JUMP) |
344 self.SetStyling(i - start_pos, STC_PLC_JUMP) |
346 else: |
345 else: |
347 self.SetStyling(i - start_pos, 31) |
346 self.SetStyling(i - start_pos, 31) |
348 else: |
347 else: |
349 self.SetStyling(i - start_pos, 31) |
348 self.SetStyling(i - start_pos, 31) |
350 event.Skip() |
349 event.Skip() |
351 |
350 |
352 def Cut(self): |
351 def Cut(self): |
353 self.ResetBuffer() |
352 self.ResetBuffer() |
354 self.CmdKeyExecute(wxSTC_CMD_CUT) |
353 self.CmdKeyExecute(wx.stc.STC_CMD_CUT) |
355 self.RefreshBuffer() |
354 self.RefreshBuffer() |
356 |
355 |
357 def Copy(self): |
356 def Copy(self): |
358 self.CmdKeyExecute(wxSTC_CMD_COPY) |
357 self.CmdKeyExecute(wx.stc.STC_CMD_COPY) |
359 |
358 |
360 def Paste(self): |
359 def Paste(self): |
361 self.ResetBuffer() |
360 self.ResetBuffer() |
362 self.CmdKeyExecute(wxSTC_CMD_PASTE) |
361 self.CmdKeyExecute(wx.stc.STC_CMD_PASTE) |
363 self.RefreshBuffer() |
362 self.RefreshBuffer() |
364 |
363 |
365 def RefreshModel(self): |
364 def RefreshModel(self): |
366 if self.TextChanged: |
365 if self.TextChanged: |
367 self.RefreshJumpList() |
366 self.RefreshJumpList() |