/tags/pyragua-0.2.5/pyragua/PythonSTC.py – Pyragua

root/tags/pyragua-0.2.5/pyragua/PythonSTC.py

Revision 390, 30.4 KB (checked in by ark, 2 years ago)

directorio faltante

Line 
1#!-*- coding:iso8859-1 -*-
2"""
3Este archivo es parte de Pyragua
4
5Pyragua es software libre; lo puedes redistribuir y/o modificar
6bajo los terminos de la Licencia Publica General (GNU GPL) como fue
7publicada por la Free Software Foundation; cualquier versión 2 de la
8Licencia.
9
10Este programa es distribuido con la esperanza de que será útil,
11pero SIN GARANTIA ALGUNA; ni con la garantía explícita de
12MERCABILIDAD o de que SERVIRA PARA UN PROPOSITO EN PARTICULAR.
13Mire la Licencia Pública General de la GNU para más detalles.
14
15Debió recibir una copia de la Licencia Pública General de la GNU junto con
16este programa; sino, escriba a la Free Software Foundation,
17Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18"""
19DEBUG=False
20import wx.stc  as  stc
21import wx
22import keyword
23# Para i18n
24import gettext
25gettext.install("pyragua",unicode=1)
26_ = gettext.gettext
27
28from Utils import *
29
30#Este módulo sirve para buscar cuales son los módulos de una variable
31import wx.py
32
33import os,sys
34
35if wx.Platform == '__WXMSW__':
36    faces = { 'times': 'Times New Roman',
37              'mono' : 'Courier New',
38              'helv' : 'Arial',
39              'other': 'Comic Sans MS',
40              'size' : 10,
41              'size2': 8,
42             }
43else:
44    faces = { 'times': 'Times',
45              'mono' : 'Courier',
46              'helv' : 'Helvetica',
47              'other': 'new century schoolbook',
48              'size' : 12,
49              'size2': 10,
50             }
51
52class PythonSTC(stc.StyledTextCtrl):
53    fold_symbols = 3
54
55    def __init__(self, archivo, ID,
56                 pos=wx.DefaultPosition, size=wx.DefaultSize,
57                 style=0):
58        self.archivo=archivo
59        self.pyragua=self.archivo.pyragua
60        stc.StyledTextCtrl.__init__(self, archivo, ID, pos, size, style)
61        self.Configurar()
62        self.SetModEventMask(stc.STC_MOD_INSERTTEXT | stc.STC_MOD_DELETETEXT | stc.STC_PERFORMED_USER )
63        #Utilizaremos este diccionario para llevar un registro del espacio
64        #de nombres de cada variable para el autocompletar
65        self.namespace={}
66
67    def Configurar(self):
68        u"""Establece los parámetros de configuración del stc"""
69        self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
70        self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
71        self.CmdKeyAssign(ord('K'), stc.STC_SCMOD_CTRL, stc.STC_CMD_LINEDELETE)
72        self.CmdKeyAssign(ord('Z'), stc.STC_SCMOD_CTRL, stc.STC_CMD_UNDO)
73
74        self.SetLexer(stc.STC_LEX_PYTHON)
75        keyword .kwlist+=['True','False','self']
76        self.SetKeyWords(0, " ".join(keyword.kwlist))
77        # esto sirve para resaltar estas palabras ademas de las que estan ya en keyword.kwlist
78        self.CadenaParaComentar='#_'
79
80        self.SetProperty("fold", "1")
81        self.SetProperty("tab.timmy.whinge.level", "1")
82        self.SetMargins(0,0)
83
84        self.SetViewWhiteSpace(False)
85        #self.SetBufferedDraw(False)
86        #self.SetViewEOL(True)
87        #self.SetEOLMode(stc.STC_EOL_CRLF)
88        #self.SetUseAntiAliasing(True)
89        self.TIPO_EOL=stc.STC_EOL_CRLF  #Variable que contiene el tipo de EOL
90        '''stc.STC_EOL_CRLF
91        stc.STC_EOL_CR
92        stc.STC_EOL_LF'''
93        self.SetEOLMode(self.TIPO_EOL)
94        #self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
95        #self.SetEdgeColumn(78)
96        self.TAMESPC=4#tamaño de cada tabulacion
97        self.SetTabWidth(self.TAMESPC)
98        # Setup a margin to hold fold markers
99        #self.SetFoldFlags(16)  ###  WHAT IS THIS VALUE?  WHAT ARE THE OTHER FLAGS?  DOES IT MATTER?
100        self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
101        self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
102        self.SetMarginSensitive(2, True)
103        self.SetMarginWidth(2, 12)
104
105        if self.fold_symbols == 0:
106            # Arrow pointing right for contracted folders, arrow pointing down for expanded
107            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_ARROWDOWN, "black", "black")
108            self.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_ARROW, "black", "black")
109            self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "black", "black")
110            self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "black", "black")
111            self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY,     "white", "black")
112            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY,     "white", "black")
113            self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY,     "white", "black")
114
115        elif self.fold_symbols == 1:
116            # Plus for contracted folders, minus for expanded
117            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_MINUS, "white", "black")
118            self.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_PLUS,  "white", "black")
119            self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "white", "black")
120            self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "white", "black")
121            self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY, "white", "black")
122            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
123            self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
124
125        elif self.fold_symbols == 2:
126            # Like a flattened tree control using circular headers and curved joins
127            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_CIRCLEMINUS,          "white", "#404040")
128            self.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_CIRCLEPLUS,           "white", "#404040")
129            self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_VLINE,                "white", "#404040")
130            self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_LCORNERCURVE,         "white", "#404040")
131            self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_CIRCLEPLUSCONNECTED,  "white", "#404040")
132            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
133            self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE,         "white", "#404040")
134
135        elif self.fold_symbols == 3:
136            # Like a flattened tree control using square headers
137            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_BOXMINUS,          "white", "#808080")
138            self.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_BOXPLUS,           "white", "#808080")
139            self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_VLINE,             "white", "#808080")
140            self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_LCORNER,           "white", "#808080")
141            self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
142            self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
143            self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER,           "white", "#808080")
144
145        self.Bind(stc.EVT_STC_MODIFIED,self.ChangeText)
146        self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
147        self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
148        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
149        self.Bind(wx.EVT_CHAR, self.OnChar)
150
151        # Make some styles,  The lexer defines what each style is used for, we
152        # just have to define what each style looks like.  This set is adapted from
153        # Scintilla sample property files.
154
155        #Copiado del editor del demo de wxpy
156        # Indentation and tab stuff
157        self.SetIndent(self.TAMESPC)               # Proscribed indent size for wx
158        self.SetIndentationGuides(True) # Show indent guides
159        self.SetBackSpaceUnIndents(True)# Backspace unindents rather than delete 1 space
160        self.SetTabIndents(True)        # Tab key indents
161        #self.SetTabWidth(4)             # Proscribed tab size for wx
162        self.SetUseTabs(False)          # Use spaces rather than tabs, or
163
164        # Global default styles for all languages
165        self.StyleSetSpec(stc.STC_STYLE_DEFAULT,     "face:%(helv)s,size:%(size)d" % faces)
166        self.StyleClearAll()  # Reset all to be like the default
167
168        # Global default styles for all languages
169        self.StyleSetSpec(stc.STC_STYLE_DEFAULT,     "face:%(helv)s,size:%(size)d" % faces)
170        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,  "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
171        self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
172        self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,  "fore:#FFFFFF,back:#0000FF,bold")
173        self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,    "fore:#000000,back:#FF0000,bold")
174        # Indentation guide
175        self.StyleSetSpec(wx.stc.STC_STYLE_INDENTGUIDE, "fore:#CDCDCD")
176
177        # Python styles
178        # Default
179        self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
180        # Comments
181        self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
182        # Number
183        self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
184        # String
185        self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
186        # Single quoted string
187        self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
188        # Keyword
189        self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
190        # Triple quotes
191        self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
192        # Triple double quotes
193        self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
194        # Class name definition
195        self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
196        # Function or method name definition
197        self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
198        # Operators
199        self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces)
200        # Identifiers
201        self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
202        # Comment-blocks
203        self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
204        # End of line where string is not closed
205        self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
206
207        self.SetCaretForeground("BLUE")
208    def DesHacer(self,evento):
209        if self.CanUndo()==1 :
210            self.Undo()
211        else:
212            self.DesAcusarModificacion()
213
214    def ReHacer(self,evento):
215        if self.CanRedo() :
216            self.Redo()
217            self.AcusarModificacion()
218
219    def OnCopy(self, evento):
220        self.Copy()
221
222    def OnCut(self, evento):
223        self.Cut()
224
225    def OnPaste(self, evento):
226        self.Paste()
227
228    def Tabular(self,linea):
229        """Determina si la linea de texto debe ser tabulada y cuantos caracteres
230        extras debe poner para completar la tabulación.
231        Tabular(str) --> bool, int"""
232        band=False #Determina si la linea debe ser tabulada
233        m=0#cantidad de espacios extras a colocar en caso de ser necesario
234        ban=True
235        balp=0#balance de parantesis
236        i=0
237        while i<len(linea):#bucle para quitar las cadenas para no confundir algun comentario
238            j=i
239            if linea[i]=='"' and not linea[i:i+3]=='"""':#para quitar las cadenas en comillas dobles
240                j=j+1
241                while j<len(linea) and linea[j]!='"':
242                    j=j+1
243                #if j>=len(linea):
244                    #print 'se salio'#se salio
245                linea= linea[:i]+linea[j+1:]
246                i=i-1
247            elif linea[i:i+3]=='"""':#para quitar las cadenas en triple comilla doble
248                j=j+3
249                while j<len(linea) and linea[j:j+3]!='"""':
250                    j=j+1
251                #print 'i = %d, j = %d'%(i,j)
252                #if j>=len(linea):
253                    #print 'se salio'#se salio
254                linea= linea[:i]+linea[j+3:]
255                i=i-1
256            elif linea[i]=="'" and not linea[i:i+3]=="'''":#para quitar las cadenas en comilla sencilla
257                j=j+1
258                while j<len(linea) and linea[j]!="'":
259                    j=j+1
260                #if j>=len(linea):
261                    #print 'se salio'#se salio
262                linea= linea[:i]+linea[j+1:]
263                i=i-1
264            elif linea[i:i+3]=="'''":#tpara quitar las cadenas en riple comilla sencilla
265                j=j+3
266                while j<len(linea) and linea[j:j+3]!="'''":
267                    j=j+1
268                #print 'i = %d, j = %d'%(i,j)
269                #if j>=len(linea):
270                    #print 'se salio'#se salio
271                linea= linea[:i]+linea[j+3:]
272                i=i-1
273            i=i+1
274        pos=linea.find('#')#se le borran los comentarios #xxxxx
275        if pos >=0:
276            linea=linea[:pos]
277        ppal=(linea.split(' '))[0]#ppal contiene la primera palabra de la linea
278        linea=linea.strip()
279        band=linea.endswith(':')
280        i=len(linea)-1
281        while i>=0:#este ciclo es para saber si quedo algun parentesis abierto sin cerrar al final de la linea
282            x=linea[i]
283            if x=='(':
284                balp=balp-1
285            if x==')':
286                balp=balp+1
287            if balp==-1:
288                band=False
289                m=i
290                break
291            i=i-1
292        palabras=['if', 'while', 'for', 'class', 'try','else','except','def','elif']#las palabras reservadas que llevan tabulacion
293        if m >0:
294            band=False
295        bandera=False
296        for x in palabras:#para determinar si la linea comienza con una palabra correcta para indentar
297            if linea.startswith(x):
298                bandera=True
299        if not bandera and m==0:
300            band=False
301        return band,m
302
303    def NuevaLinea ( self ):
304        """Inserta una nueva linea segun la plataforma
305        """
306        if DEBUG : print "Nueva Línea", self.GetEOLMode()
307        if self.GetEOLMode()==stc.STC_EOL_CRLF:
308            self.AddTextRaw('\r\n')
309        elif self.GetEOLMode()==stc.STC_EOL_CR:
310            self.AddTextRaw('\r')
311        elif self.GetEOLMode()==stc.STC_EOL_LF:
312            self.AddTextRaw('\n')
313
314    def CalcularTab( self ):
315        """Funcion que calcula si al recibir un enter debe hacer una tabulacion extra e inserta la nueva linea.
316        """
317        ESP=' '#un caracter espacio, cuidado al modificar
318        TAB='    '#un caracter tab, cuidado al modificar
319        espacio=' '#el caracter por defecto de la tabulacion
320        m=0#cantidad de espacios extras a colocar en la tabulacion
321        numtabs=0#numero de tabulaciones
322        (linea,pos)=self.GetCurLine()
323        numtabs=self.GetLineIndentation(self.GetCurrentLine())
324        linea=linea[:pos]
325        if pos>=numtabs:
326            if numtabs>0:
327                if len(linea)!=0 :
328                    espacio=linea[0]
329                    if espacio==TAB:#si es una caracter tab?
330                        numtabs=numtabs/self.GetTabWidth()
331            linea=linea.strip()
332            if  len(linea)>0:
333                ban,m=self.Tabular(linea)
334            else:
335                ban=False
336                m=0
337            if ban:
338                if espacio==TAB:
339                    numtabs=numtabs+1
340                else:
341                    numtabs=numtabs+self.GetTabWidth()
342            self.NuevaLinea()
343            self.AddText( ((espacio*numtabs)+(ESP*m)) )
344        else  :
345            self.NuevaLinea()
346            self.AddText( ((espacio*pos)+(ESP*m)) )
347
348    def OnKeyPressed(self, event):
349        """
350        Funcion sobrecargada que se ejecuta cuando alguna tecla es presionada
351        """
352        if self.CallTipActive():
353            self.CallTipCancel()
354
355        #Para que funcione en el wx2.7
356        if callable(event.KeyCode):
357            key = event.KeyCode()
358        else:
359            key = event.KeyCode
360        band=True
361
362        if key == wx.WXK_RETURN and not self.AutoCompActive():
363            #Estamos creando una nueva línea agreguémosla al ClassBrowser
364            #self.AgregarLineaAlClassBrowser()
365            band=False
366            self.CalcularTab()
367        if key == wx.WXK_SPACE and event.ControlDown():
368            pos = self.GetCurrentPos()
369            # Tips
370            if event.ShiftDown():
371                self.CallTipSetBackground("white")
372                self.CallTipShow(pos, 'El editor del Pyragua\n\n'
373                                 'Desarrollado por Pyrhox\n'
374                                 'UTP.')
375            # Code completion
376            else:
377                self.AutoCompletar(event)
378        else:
379            if band:
380                event.Skip()
381
382    def CompletarDosPuntos(self):
383        """Metodo que pone el caracter ':' como ayuda
384        """
385        palabras=['if', 'while', 'for', 'class', 'try','else','except','elif']#las palabras reservadas usadas al antes de ':'
386        (linea,pos)=self.GetCurLine()#devuelve la linea actual y la posicion del cursor en esta linea
387        #Quito la basura
388        linea=linea.strip()
389        if len(linea)==0:
390            return
391        token=self.GetTokens(linea)[-1]#Se toma el ultima palabra de la linea
392        #Vuelvo a quitar la basura
393        token=token.strip()
394        if token=='def':
395            numtabs=self.GetLineIndentation(self.GetCurrentLine())
396            if numtabs>=1:#Esto es un machetazo para saber si la declaracion esta dentro de una clase
397           #si tiene tabulaciones la funcion deberia estar en una clase  por eso el self   (Ley de Charles)
398               pos=self.GetCurrentPos()
399               self.AddText(' ( self ):')
400               self.SetCurrentPos(pos)
401            else:
402               pos=self.GetCurrentPos()
403               self.AddText(' ( ):')
404               self.SetCurrentPos(pos)
405        if token in palabras:
406            pos=self.GetCurrentPos()
407            self.AddText(' :')
408            self.SetCurrentPos(pos)
409    def  TomarTamIdentacion( self, numLinea ):
410        linea=self.GetLine(numLinea)
411        aux_linea=linea.lstrip()
412        tam=len(linea) - len(aux_linea)
413        return tam
414
415    def  STCComentarBloque( self ):
416        """
417        Metodo que comenta agregando el caracter '#_' al inicio de cada linea seleccionada
418        """
419        cad=self.CadenaParaComentar
420        a,b=self.GetSelection()#se toma la posicion inicial y final de la seleccion
421        #a=posicion inicial de la seleccion
422        #b=posicion final de la seleccion
423        A=self.LineFromPosition(a)#se toma el numero de la linea donde inicia la seleccion
424        B=self.LineFromPosition(b)#se toma el numero de la linea donde finaliza la seleccion
425        for x in range(A,B+1) :#recorre las lineas seleccionadas
426            pos=self.PositionFromLine(x)#toma la posicion al inicio de cada linea
427            numtabs=self.TomarTamIdentacion(x)
428            #numtabs=self.GetLineIndentation(x)
429            tamLinea=len( self.GetLine(x).strip() )
430            if tamLinea > 0:
431                if len(cad) > tamLinea:
432                    self.InsertText(pos+numtabs,cad)
433                else:
434                    text=self.GetTextRange( pos+numtabs , pos+numtabs+len(cad) )
435                    if len(text)>0 and (not text==cad) :
436                        self.InsertText(pos+numtabs,cad)
437
438    def  STCDesComentarBloque( self ):
439        """
440        Metodo que descomenta removiendo el caracter '#_' al inicio de cada linea seleccionada
441        """
442        cad=self.CadenaParaComentar
443        a,b=self.GetSelection()#se toma la posicion inicial y final de la seleccion
444        #a=posicion inicial de la seleccion
445        #b=posicion final de la seleccion
446        A=self.LineFromPosition(a)#se toma el numero de la linea donde inicia la seleccion
447        B=self.LineFromPosition(b)#se toma el numero de la linea donde finaliza la seleccion
448        targetstart=self.GetTargetStart()
449        targetend=self.GetTargetEnd()
450        for x in range(A,B+1) :#recorre las lineas seleccionadas
451            pos=self.PositionFromLine(x)#toma la posicion al inicio de cada linea
452            numtabs=self.TomarTamIdentacion(x)
453            #numtabs=self.GetLineIndentation(x)
454            tamLinea=len(self.GetLine(x).strip())
455            if tamLinea>=len(cad) :
456                text=self.GetTextRange(pos+numtabs,pos+numtabs+len(cad))
457                if text==cad :#esta comentada al inicio?
458                    self.SetTargetStart(pos+numtabs)
459                    self.SetTargetEnd(pos+numtabs+len(cad))
460                    self.ReplaceTarget('')#reemplaza el caracter '#_' por el caracter ''
461        self.SetTargetStart(targetstart)
462        self.SetTargetEnd(targetend)
463
464    def ChangeText ( self , evento):
465        #self.AcusarModificacion()
466        evento.Skip()
467
468    def OnChar(self,event):
469        """Evento disparado cuando se recibe un caracter"""
470        #Para que funcione en el wx2.7
471        if callable(event.KeyCode):
472            key = event.KeyCode()
473        else:
474            key = event.KeyCode
475        pos=self.GetCurrentPos()
476        self.AcusarModificacion()
477        if key==ord(' '):#pregunta si escribio un espacio
478            self.CompletarDosPuntos()
479            self.AddText(' ')
480        elif key==ord("."):
481            if not self.AutoCompletar(event):
482                #Un error en el autocompletar
483                #Para que se agregue el caracter presionado
484                event.Skip()
485        else:
486            #Procesar normalmente
487            event.Skip()
488
489    def OnUpdateUI(self, evt):
490        """
491        Reviza si hay parentesis, llaves o corchetes para resaltar.
492        """
493        # check for matching braces
494        braceAtCaret = -1
495        braceOpposite = -1
496        charBefore = None
497        caretPos = self.GetCurrentPos()
498
499        if caretPos > 0:
500            charBefore = self.GetCharAt(caretPos - 1)
501            styleBefore = self.GetStyleAt(caretPos - 1)
502
503        # check before
504        if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
505            braceAtCaret = caretPos - 1
506
507        # check after
508        if braceAtCaret < 0:
509            charAfter = self.GetCharAt(caretPos)
510            styleAfter = self.GetStyleAt(caretPos)
511
512            if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
513                braceAtCaret = caretPos
514
515        if braceAtCaret >= 0:
516            braceOpposite = self.BraceMatch(braceAtCaret)
517
518        if braceAtCaret != -1  and braceOpposite == -1:
519            self.BraceBadLight(braceAtCaret)
520        else:
521            self.BraceHighlight(braceAtCaret, braceOpposite)
522            #pt = self.PointFromPosition(braceOpposite)
523            #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
524            #print pt
525            #self.Refresh(False)
526
527
528    def OnMarginClick(self, evt):
529        """
530        Muestra o esconde el texto de los bloques.
531        """
532        # fold and unfold as needed
533        if evt.GetMargin() == 2:
534            if evt.GetShift() and evt.GetControl():
535                self.FoldAll()
536            else:
537                lineClicked = self.LineFromPosition(evt.GetPosition())
538
539                if self.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
540                    if evt.GetShift():
541                        self.SetFoldExpanded(lineClicked, True)
542                        self.Expand(lineClicked, True, True, 1)
543                    elif evt.GetControl():
544                        if self.GetFoldExpanded(lineClicked):
545                            self.SetFoldExpanded(lineClicked, False)
546                            self.Expand(lineClicked, False, True, 0)
547                        else:
548                            self.SetFoldExpanded(lineClicked, True)
549                            self.Expand(lineClicked, True, True, 100)
550                    else:
551                        self.ToggleFold(lineClicked)
552
553
554    def FoldAll(self):
555        """
556        Esconde todos bloques.
557        """
558        lineCount = self.GetLineCount()
559        expanding = True
560
561        # find out if we are folding or unfolding
562        for lineNum in range(lineCount):
563            if self.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
564                expanding = not self.GetFoldExpanded(lineNum)
565                break
566
567        lineNum = 0
568
569        while lineNum < lineCount:
570            level = self.GetFoldLevel(lineNum)
571            if level & stc.STC_FOLDLEVELHEADERFLAG and \
572               (level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
573
574                if expanding:
575                    self.SetFoldExpanded(lineNum, True)
576                    lineNum = self.Expand(lineNum, True)
577                    lineNum = lineNum - 1
578                else:
579                    lastChild = self.GetLastChild(lineNum, -1)
580                    self.SetFoldExpanded(lineNum, False)
581
582                    if lastChild > lineNum:
583                        self.HideLines(lineNum+1, lastChild)
584
585            lineNum = lineNum + 1
586
587
588
589    def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
590        """
591        Muestra el texto de un bloque.
592        """
593        lastChild = self.GetLastChild(line, level)
594        line = line + 1
595
596        while line <= lastChild:
597            if force:
598                if visLevels > 0:
599                    self.ShowLines(line, line)
600                else:
601                    self.HideLines(line, line)
602            else:
603                if doExpand:
604                    self.ShowLines(line, line)
605
606            if level == -1:
607                level = self.GetFoldLevel(line)
608
609            if level & stc.STC_FOLDLEVELHEADERFLAG:
610                if force:
611                    if visLevels > 1:
612                        self.SetFoldExpanded(line, True)
613                    else:
614                        self.SetFoldExpanded(line, False)
615
616                    line = self.Expand(line, doExpand, force, visLevels-1)
617
618                else:
619                    if doExpand and self.GetFoldExpanded(line):
620                        line = self.Expand(line, True, force, visLevels-1)
621                    else:
622                        line = self.Expand(line, False, force, visLevels-1)
623            else:
624                line = line + 1
625
626        return line
627
628
629
630    def AcusarModificacion(self):
631        """Esta función se encarga de dibujar un * en el nombre de la
632        pestaña del panel para avisar que se ha modificado el archivo"""
633        #La instancia de archivo que me contiene
634        archivo=self.archivo
635        #Este es el notebook donde estoy metido
636        note_book=archivo.padre
637        #Cuando es un archivo nuevo sin guardar no pongo nada
638        if archivo.nombre!="":
639            note_book.SetPageText(note_book.GetSelection(),
640                                  str(note_book.GetSelection()+1)+' '+os.path.basename(archivo.nombre)+' '+"*")
641        #Código para agregar un * cuando se modifica el archivo
642
643    def DesAcusarModificacion(self):
644        """Esta función se encarga de quitar el  * del nombre de la
645        pestaña del panel para avisar que no se ha modificado el archivo"""
646        #La instancia de archivo que me contiene
647        archivo=self.archivo
648        #Este es el notebook donde estoy metido
649        note_book=archivo.padre
650        #Cuando es un archivo nuevo sin guardar no pongo nada
651        if archivo.nombre!="":
652            note_book.SetPageText(note_book.GetSelection(),
653                                  str(note_book.GetSelection()+1)+' '+os.path.basename(archivo.nombre))
654        #Código para quitar el * cuando no se modifica el archivo
655
656    def GetTokens(self,linea):
657        """Toma una cadena de código python y la parte por tokens"""
658        seps=[" ",",","=","(","|"]
659        pal=""
660        tokens=[]
661        for c in linea:
662            if c in seps:
663                tokens.append(pal)
664                pal=""
665            else:
666                pal+=c
667        if pal!="":
668            tokens.append(pal)
669        return tokens
670
671    def AgregarLineaAlClassBrowser ( self ):
672            nombreArchivo=self.archivo.nombre
673            linea=self.GetCurLine()[0]
674            lineaNum=self.GetCurrentLine()
675            self.pyragua.cb.AddLine( nombreArchivo, linea , lineaNum)
676            self.pyragua.finicial.pCodigo.aCodigo.Actualizar()
677
678    ########AUTOCOMPLETAR
679    def ACLimpiarGetToken( self , linea):
680        """Mira la línea actual, la parte por tokens y retorna solo
681        el último token"""
682        #Quito la basura
683        linea.strip()
684        linea=EliminarEOLS(linea)
685        if len(linea)==0 :
686            return False
687
688        #Parto la línea por tokens, y tomo solo el último elemento
689        token=self.GetTokens(linea)[-1]
690        #Vuelvo a quitar la basura
691        token.strip()
692        return token
693
694    def ACQuitarPunto( self, cadena ):
695        "Elimina el el punto final de una cadena"
696        if cadena[-1:]=='.':
697            #Elimino el punto
698            cadena=cadena[:-1]
699        return cadena
700
701    def AutoCompletar(self,evento):
702
703        """Este método se encargará de autocompletar según lo que esté
704        escrito, retorna True si fue capaz de realizarlo"""
705        self.AutoCompSetIgnoreCase(False)
706        (linea,pos)=self.GetCurLine()
707        token=self.ACLimpiarGetToken(linea)
708        token=self.ACQuitarPunto(token)
709
710        objeto=self.ACEvaluar(token,linea)
711
712        if not objeto:
713            return False
714        listaOps=dir(objeto)
715        #Le adiciono a cada elemento el token
716        #listaOps=[token+"."+x for x in listaOps]
717        #self.autoComplete(object=1)
718        if listaOps!=[]:
719            self.AddText(".")
720            self.AutoCompShow(0," ".join(listaOps))
721            return True
722        else:
723            return False
724
725    def ACEvaluar(self,word, linea):
726        """Código tomado del spe, retorna un objeto obtenido con eval,
727        modificado"""
728        #Ya existe la palabra en el namespace, retornar lo que tenemos
729        if word in self.namespace.keys():
730            return self.namespace[word]
731        #Si aún no está evaluar
732        try:
733            objeto=eval(word,self.namespace)
734        except:
735            try:
736                #Aún no ha sido importado, lo importo
737                objeto=__import__(word)
738            except ImportError:
739                #El módulo aún no existe, busco a ver si es uno de los que
740                #se están escribiendo en este momento
741                objeto=None
742            except :
743                print "Error en autocompletar", sys.exc_info
744                return None
745
746        #Agrego el objeto a mi lista
747        self.namespace[word]=objeto
748        return self.namespace[word]
749
750
751    ########FIN AUTOCOMPLETAR
Note: See TracBrowser for help on using the browser.