#C:/Python27/python # -*- coding: utf-8 -*- import sys sys.path.append(sys.exec_prefix) sltversion="4.1.19" #Constantes que indican la plataforma esLinux=False esMac=False miHOME='APPDATA' pyLIB=sys.exec_prefix+"\\lib" if sys.platform.lower().find('linux')>=0: esLinux=True miHOME='HOME' pyLIB=sys.exec_prefix+"/lib" sys.path.append(pyLIB) import os # 1. Obtener srvPath if esLinux: srvPath="/usr/share/salt-server" else: srvPath=os.environ['PROGRAMFILES'] + "/salt4" srvPath=os.path.abspath(srvPath) srvPath2=os.path.abspath(os.environ[miHOME]+"/salt4") #alternativo # 2. Obtener usrPath usrPath=os.path.abspath(os.environ[miHOME]+"/.salt4") try: if os.environ['USERNAME']=='root': usrPath=os.path.abspath("/root/.salt4") except: pass try: if os.environ['USER']=='root': usrPath=os.path.abspath("/root/.salt4") except: pass if not os.path.exists(usrPath): os.mkdir(usrPath) # 3. Buscar archivo de configuracion if not os.path.exists(os.path.abspath(srvPath+'/sltsrv.config')) and os.path.exists(os.path.abspath(srvPath2+'/sltsrv.config')): srvPath=srvPath2 # 4. Copiar config si es necesario _config=os.path.abspath('/var/lib/salt/sltsrv.config') if not os.path.exists(_config): _config=os.path.abspath(srvPath+'/sltsrv.config') if os.path.exists(_config): if os.path.exists(os.path.abspath(usrPath+'/sltsrv.config')): fsrv=open(_config,'rb') fusr=open(os.path.abspath(usrPath+'/sltsrv.config'),'rb') cfgsrv=eval(fsrv.read()) cfgusr=eval(fusr.read()) fsrv.close() fusr.close() if not 'entorn' in cfgsrv or not 'entorn' in cfgusr or not 'sltinitime' in cfgsrv['entorn'] or not 'sltinitime' in cfgusr['entorn'] or cfgsrv['entorn']['sltinitime']!=cfgusr['entorn']['sltinitime']: import shutil shutil.copy(_config,os.path.abspath(usrPath+'/sltsrv.config')) try: for root,dirs, files in os.walk(usrPath): for name in files: if name[0:3]=='tmp': os.remove(os.path.join(root,name)) except: pass else: import shutil shutil.copy(_config,os.path.abspath(usrPath+'/sltsrv.config')) try: for root,dirs, files in os.walk(usrPath): for name in files: if name[0:3]=='tmp': os.remove(os.path.join(root,name)) except: pass # Leer configuracion f=open(os.path.abspath(usrPath+'/sltsrv.config'),'rb') scfg=f.read() f.close() cfg=eval(scfg) if 'entorn' in cfg: if 'sltsrvpaths' in cfg['entorn']: sys.path.extend(cfg['entorn']['sltsrvpaths']) ooopath=sys.executable bn=os.path.basename(ooopath) ooopath=os.path.dirname(ooopath) ooopathpy="" while bn!="": if bn.lower()=="program": ooopath=os.path.abspath(ooopath+"/program") break elif bn.lower().find("python-")>-1: ooopathpy=os.path.abspath(ooopath+"/"+bn) bn=os.path.basename(ooopath) ooopath=os.path.dirname(ooopath) #if ooopathpy!="": # sys.path.append(os.path.abspath(ooopathpy+"/lib")) # sys.path.append(os.path.abspath(ooopathpy)) #else: # sys.path.append(os.path.abspath(ooopath+"/python-core-2.3.4/lib")) # sys.path.append(os.path.abspath(ooopath+"/python-core-2.3.4")) #sys.path.append(ooopath) import uno try: import unohelper except: pass import socket import codecs import platform import doooLib import syslog from com.sun.star.task import XJobExecutor # ---------------------------------------------- # Definiciones de Salt # ---------------------------------------------- #Busqueda de palabras #Constantes usadas en PalabraAnt y PalabraSig EST_INI = 0 #'Estado inicial EST_ESP = 1 #'Espacios (viene de INI o TXT) EST_TXT = 2 #'Texto (viene de INI) EST_ESPTXT = 3 #'Texto (viene de ESP) #Constantes que definen la estructura de cada elemento de colTx tx_paltext=0 tx_nordori=1 tx_carfinpal=2 tx_italica=3 tx_italicaori=4 #Apostrofe tipografico apotpgr=chr(146) if esLinux: apotpgr="\xe2\x80\x99" def Llog(msg): syslog.syslog(syslog.LOG_DEBUG,str(msg)) def PalabraSig(doc,lscurs=[]): _ret = None # # Obtener la primera palabra siguiente a la posicion de partida # # Entrada: doc: documento (sltDoc) # El cursor se queda con la palabra encontrada seleccionada # # Salida: lscurs: Lista de cursores para traduccion adicional (si hay) # # Retorno: Palabra encontrada ("" si no hay mas palabras), # caracter de fin de palabra # Fin de parrafo no/si(0/1) # VB2PY (UntranslatedCode) On Error GoTo PalabraSig_ME finpar=0 c="" estado=EST_INI cesp=u",.;:{}/[]<>?¿¡!ªº()%\"" + ucode(chr(145)) + ucode(chr(146)) + ucode(chr(147)) + ucode(chr(148)) + ucode(chr(132)) + ucode(chr(171)) + ucode(chr(187)) + ucode(chr(188)) + ucode(chr(10)) + ucode(chr(12)) + ucode(chr(9)) + ucode(chr(11)) + ucode(chr(160)) + ucode(chr(150)) + ucode(chr(151)) + ucode(chr(215)) + ucode(chr(247)) #Buscar palabra siguiente (pi y pf) doc.cur.collapseToEnd() if doc.cur.Footnote!=None: tc=doc.cur.Footnote.Text.createTextCursor() tc.gotoStart(0) lscurs.append(tc) doc.cur.goRight(1,0) elif doc.cur.Endnote!=None: tc=doc.cur.Endnote.Text.createTextCursor() tc.gotoStart(0) lscurs.append(tc) while doc.cur.Endnote!=None: doc.cur.goRight(1,0) ret=doc.NextChar() while ret==True and finpar <=1: if len(doc.Char())==0: ret=doc.NextChar() if not ret: finpar=1 c = doc.cur.String[-1] #FiltroApo(c, txDOC, pf) if estado==EST_INI: if escesp(c,cesp): estado=EST_ESPTXT break elif c==" ": doc.cur.collapseToEnd() else: estado=EST_TXT elif estado== EST_TXT: if escesp(c,cesp): doc.cur.goLeft(1,1) estado=EST_ESPTXT break elif c==" ": doc.cur.goLeft(1,1) estado=EST_ESPTXT break elif doc.cur.Footnote!=None: estado=EST_ESPTXT break elif doc.cur.Endnote!=None: estado=EST_ESPTXT break if finpar==1: #ya era fin de parrafo break ret=doc.NextChar() cf = c if estado == EST_ESPTXT: #Solo hay nueva palabra si hemos llegado al estado TXT desde ESP _ret = doc.Char() elif not ret: #No habia mas caracteres finpar=True _ret=doc.Char() elif doc.isEnd() and len(doc.Char())>0: #.. o es la ultima finpar=True _ret=doc.Char() else: _ret = '' #Tratamos numbering p=_ret.find('.') if p==-1: p=_ret.find(')') if p>0: _ret=_ret[p+1:] return _ret,cf,finpar def sltDate(): #Fecha del addon if os.path.exists(os.path.abspath(__file__)): return time.localtime(os.stat(os.path.abspath(__file__))[8]) else: return None def FiltroApo(c, tx, p): # # Comprobar si se trata de un caracter ' usado como # comillas o como apostrofe. Para ser apóstrofe ha de # ser sel tipo letra'letra, siendo letra una caracter # entre a y z. Si es un carácter ' usado como comillas # cambiarlo por " # # Entrada: c: Carácter actual (puede modificarlo) # tx: TXTextControl que contiene el texto # a analizar # p: Posición del carácter a analizar (la # primera posición del texto es la 1) # # if c == '\'': EsApo = False if p > 1 and p < Len(tx): _select11 = LCase(Mid(tx, p - 1, 1)) if ('a' <= _select11 <= 'z') or (_select11 == 'à') or (_select11 == 'á') or (_select11 == 'è') or (_select11 == 'é') or (_select11 == 'í') or (_select11 == 'ò') or (_select11 == 'ó') or (_select11 == 'ú'): _select12 = LCase(Mid(tx, p + 1, 1)) if ('a' <= _select12 <= 'z') or (_select12 == 'à') or (_select12 == 'á') or (_select12 == 'è') or (_select12 == 'é') or (_select12 == 'í') or (_select12 == 'ò') or (_select12 == 'ó') or (_select12 == 'ú'): EsApo = True if not EsApo: #Actua como comillas c = '"' def ucode(s): return str(s)#,'utf-8') def ucodeSiLinux(s): chars_w_l=[("\xc2\x92","\xe2\x80\x99")] try: if esLinux: # Es interesante saber por que se ha comentado esta linea # en tiempos ignotos era necesario hacer una conversion entre lo que devolvia el server # y nuestro script en el cliente. Antes todo era bytes y ahora ya son strings, si intentamos # codificar un string sobre un string, python3 no lo soporta. #s=str(s, encoding='UTF-8') for ch_w_l in chars_w_l: s=s.replace(ch_w_l[0],ch_w_l[1]) except Exception as e: Llog(str(e)) return s def msg(mod,txt): #sacar texto en el propio documento texto=mod.Text cursor=texto.createTextCursor() cursor.gotoEnd(0) cursor.String=txt def uts(s): #Pasar cadena unicode a string i=0 t="" while i255: c=quitarFF(c) t=t+chr(ord(c)) i=i+1 return t def quitarFF(pal): #Eliminar caracteres unicode superiores a 255 n=ord(pal) if n==8216 or n==8219 or n==8224: ret="'" elif n==8221: ret=chr(148) elif n==8220: ret=chr(147) elif n==8217: ret=chr(146) else: ret="_" return ret def escesp(c,cesp): #Ver si hay que considerar el caracter como un caracter especial if ord(c)>255: n=ord(c) if n==8216 or n==8217 or n==8219 or n==8224: return False else: return True elif cesp.find(c)>-1: return True else: return False def isnumber(s): #Comprobar si el contenido de la cadena s es un número #Retorno: True, si es un número # False, si no es un número return uts(s).replace(".","").replace(",","").replace(" ","").replace("\t","").replace("'","").isdigit() def Query(datos): #Petición al servidor, esperando su respuesta #Entrada: datos: Datos a enviar al servidor #Retorno: Respuesta del servidor (o None) import urllib params = urllib.urlencode({'salt4msg': datos}) #f = urllib.urlopen("http://192.168.163.153/?%s" % params) #fsrv = urllib.urlopen("http://localhost/salt/?%s" % params) # Con Tomcat fsrv = urllib.urlopen("http://localhost:8080/?%s" % params) # Sin Tomcat #f = urllib.urlopen("http://salt.desar.cult.gva.es/?%s" % params) datos=fsrv.read() if datos==None or datos[0]=="<": datos=None #No hay servidor import os,time f=open(os.path.abspath(usrPath+'/sltsrv.config'),'rb') scfg=f.read() f.close() cfg=eval(scfg) if 'entorn' in cfg: if 'sltsrvexe' in cfg['entorn']: if 'sltsrvpath' in cfg['entorn']: sltsrvpath=os.path.abspath(cfg['entorn']['sltsrvpath']) os.chdir(sltsrvpath) if 'sltsrvexe' in cfg['entorn']: sltsrvargs=cfg['entorn']['sltsrvexe'] sltsrvexe=os.path.abspath(sltsrvargs[0]) if esLinux: modo=os.P_NOWAIT else: modo=os.P_DETACH os.spawnve(modo,sltsrvexe,sltsrvargs,os.environ) i=5 while i>0: time.sleep(2) import urllib fsrv = urllib.urlopen("http://localhost/salt/?%s" % params) datos=fsrv.read() if datos==None or datos[0]=="<": i=i-1 datos=None else: break if datos==None or datos[0]=="<": msg=MsgWindow('Cal iniciar el servidor Salt4') else: msg=MsgWindow('Cal iniciar el servidor Salt4') return datos def socketConnect(): #return "web" # Conexion a de web service (sltsrw) try: sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM) sck.connect(('localhost',20001)) except: #iniciar server import os,time f=open(os.path.abspath(usrPath+'/sltsrv.config'),'rb') scfg=f.read() f.close() cfg=eval(scfg) if 'entorn' in cfg: if 'sltsrvexe' in cfg['entorn']: if 'sltsrvpath' in cfg['entorn']: sltsrvpath=os.path.abspath(cfg['entorn']['sltsrvpath']) os.chdir(sltsrvpath) if 'sltsrvexe' in cfg['entorn']: sltsrvargs=cfg['entorn']['sltsrvexe'] sltsrvexe=os.path.abspath(sltsrvargs[0]) if esLinux: modo=os.P_NOWAIT else: modo=os.P_DETACH os.spawnve(modo,sltsrvexe,sltsrvargs,os.environ) i=5 while i>0: try: time.sleep(2) sck.connect(('localhost',20001)) except: i=i-1 else: break if i<=0: msg=MsgWindow('Cal iniciar el servidor Salt4') sck=None else: msg=MsgWindow('Cal iniciar el servidor Salt4') sck=None return sck def ListaDoc(doc,mod,colTx,colPalDu,comando): # # Pasar lista de palabras al documento. # Se pasan al documento párrafos completos # doc: documento # mod: currentComponent (para crear Anotaciones) # colTx: lista de palabras # colPalDu:lista de palabras dudosas # comando: comando ejecutado # doc.gotoStart() #inicio del párrafo i=0 j=0 pal,cf,fp=PalabraSig(doc) while pal != "": #and j=len(colTx): #Sobran palabras en el documento hayespsig=True doc.cur.String="" if doc.cur.goRight(1,1)==True: if doc.cur.String!=" ": hayespsig=False doc.cur.collapseToStart() if doc.cur.goLeft(1,1) == True: if doc.cur.String==" " and hayespsig: #Eliminar espacio anterior doc.cur.String="" else: doc.cur.collapseToEnd() elif colTx[j][tx_nordori]>i: #Eliminar palabra del documento hayespsig=True doc.cur.String="" if doc.cur.goRight(1,1)==True: if doc.cur.String!=" ": hayespsig=False doc.cur.collapseToStart() if doc.cur.goLeft(1,1) == True: if doc.cur.String==" " and hayespsig: #Eliminar espacio anterior doc.cur.String="" else: doc.cur.collapseToEnd() elif colTx[j][tx_nordori]==i: #Sustituir/insertar palabras if j in colPalDu and mod!=None: #Hay que anotar palabra dudosa nota=mod.createInstance("com.sun.star.text.TextField.Annotation") nota.Author="Salt4"+"."+colPalDu[j]['dtr']+"."+ comando nota.Content="_clau=" + colPalDu[j]['Clave'] + "_\n" + colPalDu[j]['Info'] #mod.Text.insertTextContent(doc.cur, nota, False) doc.cur.Text.insertTextContent(doc.cur, nota, False) pal=colTx[j][tx_paltext] while j < len(colTx)-1: if colTx[j + 1][tx_nordori] == i: j = j + 1 pal = pal + ' ' + colTx[j][tx_paltext] else: break #doc.cur.String=pal if pal!="_": pal=ucodeSiLinux(pal) doc.cur.String=pal j = j + 1 doc.cur.collapseToEnd() #Siguiente palabra i=i+1 pal,cf,fp=PalabraSig(doc) def DocLista(doc,colTx,lscurs=[]): # # Obtener una lista de palabras a partir de un documento # # Entrada: doc: documento cuyas palabras hay que pasar a la lista. # # Funcionamiento: Se pasan a la lista párrafos completos o sentencias si porsent=True # # Salida: colTx: Lista de palabras del documento # doc.gotoStart() #inicio del párrafo colTx = [] i=0 pal,cf,fp=PalabraSig(doc,lscurs) while pal != "": #Hay nueva palabra if len(pal)==1 and ord(pal)>255: pal=quitarFF(pal) if len(cf)==1 and ord(cf)>255: cf=quitarFF(cf) pal=uts(pal) txpal=(pal,i,uts(cf),0,0) colTx.append(txpal) #Siguiente palabra (si no es fin de párrafo) #if cur.isEndOfParagraph() or fp==1: if doc.isEnd() or fp==1: break i = i + 1 pal,cf,fp = PalabraSig(doc,lscurs) return colTx def xTrad(model,vcursor,comando): #1. Crea la ventana oPro (indicador de progreso) #2. Llama a Trad en otro thread #Los dos threads se comunican a traves de un evento para "cancelar proceso" sck=socketConnect() oPro=ProWindow() if sck!=None: sck.close() import threading t=threading.Thread(target=Trad,args=(model,vcursor,args,oPro)) t.start() def Trad(model,vcursor,comando,oPro): #Traducir el documento actual o una parte de al #Entrada: model: # vcursor: view cursor en el documento a traducir # comando: traduccion directa o inversa # oPro: StatusIndicator (proceso) #Traduccion por parrafos #Se traduce desde el parrafo en el que este el cursor. #Si hay seleccion se traduce solo la parte seleccionada ti=time.clock() try: text=vcursor.getText() cur=text.createTextCursorByRange(vcursor.getStart()) i=n=0 essel=False sel=model.getCurrentSelection() while i0: essel=True n=n+sel.getByIndex(i).getString().count(' ')+1 i=i+1 doc=sltDoc(model,cur,unit='s') oPro.start("Salt",100) sck=socketConnect() if doc.ProcStart(): #1. Traduccion del documento if not essel: TradCur(doc,comando,sck,oPro,u"Salt [document]") else: #2. Traducir seleccion doc.wordstot=(float(n))*1.1 i=0 while i0: text=sel.getByIndex(i).getText() cur=text.createTextCursorByRange(sel.getByIndex(i).getStart()) curfin=text.createTextCursorByRange(sel.getByIndex(i).getEnd()) doc.Refresh(cur,curfin) TradCur(doc,comando,sck,oPro,u"Salt [selecció]") i=i+1 #3. Traduccion de notas a pie de pagina if doc.ProcSeguir() and not essel: tbs=model.getFootnotes() i=0 n=tbs.getCount() while i0: #Refrescar barra de progreso doc.addNumWords(len(colTx)) oPro.setValue(100-doc.percentPte()) oPro.setText(oProText) #1. La palabra saltstop en el texto detiene el proceso if colTx[0][0].lower()=='saltstop': st=sltEstado(doc.model) st.Stop() break #2. Orden de traducción datos=str((comando,(colTx,colPalDu))).encode('latin-1') if sck=="web": datos=Query(datos).encode('latin-1') else: sck.send(datos) datos=sck.recv(128000).decode('latin-1') comandorec,(colTx,colPalDu)=eval(datos) #3. Actualizar documento (si no lo anula el servidor) if comandorec!="void": doc.Sync() try: doc.ListaDoc(colTx,colPalDu,comando) except Exception as e: Llog(str(e)) #doc.Sync2() ret=doc.cur.gotoNextWord(0) #if ret==True: #ret=not doc.isEnd() #if ret==True: #ret=doc.gotoStart() except Exception as e: break def _Trad_(model,vcursor,comando,oPro): #Traducir el documento actual o una parte de él #Entrada: model: # vcursor: view cursor en el documento a traducir # comando: traducción directa o inversa # oPro: StatusIndicator (proceso) #Traducción por párrafos #Se traduce desde el párrafo en el que está el cursor. #Si hay selección se traduce sólo la parte seleccionada fintrad=False saltatrad=False try: text=vcursor.getText() cur=text.createTextCursorByRange(vcursor.getStart()) if len(vcursor.String)>0: #Marcar inicio y fin de range selcur=text.createTextCursorByRange(vcursor.getStart()) selcur.gotoRange(vcursor.getEnd(),1) else: selcur=None doc=sltDoc(model,cur,unit='s',selcur=selcur) #sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #sck.connect(('localhost',20001)) oPro.start("Salt",100) sck=socketConnect() ret=doc.gotoStart() while ret==True and sck!=None: #1. Obtener lista de palabras lscurs=[] colPalDu={} colTx=[] doc.Marca() colTx=DocLista(doc,colTx,lscurs) if len(colTx)>0: #0. Posición actual doc.addNumWords(len(colTx)) oPro.setValue(100-doc.percentPte()) oPro.setText("Salt [document]") #1. Comprobar palabras de control if colTx[0][0].lower()=='saltstop': fintrad=True break elif colTx[0][0].lower()=='saltsalt': sdes=model.createSearchDescriptor() sdes.SearchString="Saltcont" rdes=model.findNext(doc.cur.getEnd(),sdes) doc.cur.gotoRange(rdes.getEnd(),0) else: #2. Orden de traducción datos=str((comando,(colTx,colPalDu))).encode('latin-1') sck.send(datos) datos=sck.recv(128000).decode('latin-1') comandorec,(colTx,colPalDu)=eval(datos) #3. Actualizar documento (si no lo anula el servidor) if comandorec!="void": doc.Sync() ListaDoc(doc,model,colTx,colPalDu,comando) #4. Traducción de notas al pie if lscurs!=None: for cur in lscurs: _TradAux_(model,cur,comando,sck) ret=doc.Next() if ret==True: ret=doc.gotoStart() #5. Traducción de tablas (solo si no es selección) if not fintrad: # and not doc.esRange(): tbs=model.getTextTables() i=0 n=tbs.getCount() while i=0: #sys.path.append(root) #sys.path.append(root+'/program/python-core-2.3.4') #sys.path.append(root+'/program/python-core-2.3.4/lib') #fin1=True #if fin1 and fin2: #break def Rev(oCtv,comando): #Revisión de un documento oCtv.BuscaNotas() if not oCtv.Siguiente(ini=-1): oCtv.windowClose() class sltDoc: """Documento para traducir o revisar. Pueden estar formado por sentencias o párrafos o cualquier otra unidad """ def __init__(self,model,cur,unit="p",pos=False,curfin=None): #unit indica si la unidad de proceso son sentencias o párrafos #pos indica si hay que mantener la posición del cursor #curfin !=None: se trata de una selección y no podemos pasar más allá de curfin self.cnor='abcdefghijklmnñopqrstuvwxyzABCDEFGHIJKLMNÑOPQRSTUVWXYZáéíóúàèòïüÁÉÍÓÚÀÈÒÏÜ' try: self.cesp=",.;:{}[]<>?¿¡!()\'%\"" + '\u0027'# + ucode(chr(145)) + ucode(chr(146)) + ucode(chr(147)) + ucode(chr(148)) + ucode(chr(132)) + ucode(chr(188)) + ucode(chr(10)) + ucode(chr(12)) + ucode(chr(13))+ ucode(chr(9)) + ucode(chr(11)) + ucode(chr(160)) + ucode(chr(150)) + ucode(chr(151)) + ucode(chr(215)) + ucode(chr(247)) + ucode('\xab') + ucode('\xbb') + '\u201c' + '\u201d' + '\u2013' + '\u2014' + '\u2022' #+ ucode(chr(171)) + ucode(chr(187)) except Exception as e: pass self.model=model self.cur=cur #cursor en el documento text=self.cur.getText() self.dcur=text.createTextCursorByRange(self.cur.getStart()) #duplicado de cur self.unit=unit[0] #frase virtual: s (entence), p (aragrph) self.poscursor=0 self.tr=None self.curfin=curfin self.wordspro=float(0) self.wordstot=(float(model.WordCount))*1.1 self.paleliminada=False self.nounicarizda=False def Refresh(self,cur,curfin=None): self.cur=cur text=self.cur.getText() self.dcur=text.createTextCursorByRange(self.cur.getStart()) #duplicado de cur self.curfin=curfin def listaGrobjs(self): #Obtener la lista de graficos incluidos en el mismo documento "como caracter" #Retorno: Lista (o []) #ASCHAR=uno.getConstantByName("com.sun.star.text.TextContentAnchorType.AS_CHARACTER") gros=self.model.getGraphicObjects() i=0 lista=[] while i=0: ##No podemos entrar dos veces en la misma posición #ret=self.cur.gotoNextWord(0) #Si hay imágenes, saltarlas self.cur.collapseToStart() ret=self.cur.goRight(1,1) while ret and len(self.cur.String)==0: #Responde True pero no avanza: es una imagen: saltarla self.cur.collapseToEnd() ret=self.cur.goRight(1,1) self.cur.collapseToStart() #ret=self.cur.gotoNextWord(0) ret=self.cur.gotoNextSentence(0) if not ret: #ret=self.cur.goRight(2,0) # lo que había ret=self.cur.goRight(1,1) while ret: #hemos podido ir 1 caracter a la derecha ... if len(self.cur.String)>0: #a) el caracter está seleccionado: lo normal self.cur.collapseToEnd() break else: #b) no hay caracter: es imagen (saltar) self.cur.collapseToEnd() ret=self.cur.goRight(1,1) self.cur.collapseToEnd() if ret and self.selcur!=None: #Comprobar que no nos salimos de una selección (range) text=self.cur.getText() rcur=text.createTextCursorByRange(self.cur) rcur.collapseToEnd() if text.compareRegionStarts(rcur,self.selcur.getEnd())==-1: #Fuera de range ret=False if ret==True: ret=self.gotoStart(0) return ret def NextWord(self): #Ir a la siguiente palabra (excepto si se ha eliminado una palabra) if not self.paleliminada: ret=self.cur.gotoNextWord(0) else: ret=True self.paleliminada=False self.nounicarizda=True return ret def NextChar(self): #Siguiente caracter, manteniendo los anteriores #Devuelve False si no hay más caracteres o es eop/eos #n=len(self.cur.String) trs=self.cur.getStart() self.cur.collapseToEnd() eop=self.isEnd() if not eop: eop=self.cur.isEndOfParagraph() #self.cur.goLeft(n,0) #self.cur.goRight(n,1) self.cur.gotoRange(trs,1) if not eop: #text=self.cur.getText() #rcur=text.createTextCursorByRange(self.cur) lenpal=len(self.cur.String) ret=self.cur.goRight(1,1) if ret: if len(self.cur.String)==lenpal: #Responde True pero no avanza: es una imagen, considerar como eop/eos ret=False #if lenpal>0: #Para no incluir la imagen junto a la palabra self.cur.goLeft(1,1) #self.cur.gotoRange(rcur,1) else: ret=False return ret def Char(self): #Devuelve el caracter o selección actual return self.cur.String def isEnd(self): #Ver si es fin de frase #Retorno: True si es fin de frase ret=False if self.unit=="s": ret=self.cur.isEndOfSentence() if ret: #evitar el caso núm. self.dcur.gotoRange(self.cur.getEnd(),0) self.dcur.gotoStartOfWord(1) if uts(self.dcur.String).lower()=="n\xfam.": #parche para evitar que detecte endOfSentence por el punto ret=False if not ret: ret=self.cur.isEndOfParagraph() else: ret=self.cur.isEndOfParagraph() return ret def isEndSel(self): #Ver si es fin de seleccionn #Retorno: True si es fin de seleccion ret=False if self.curfin!=None: text=self.cur.getText() #rcur=text.createTextCursorByRange(self.cur) #rcur.collapseToEnd() if text.compareRegionStarts(self.cur.getStart(),self.curfin.getEnd())!=1: #Fuera de range ret=True return ret def addNumWords(self,n): #Anyadir al contador de palabras procesadas self.wordspro=self.wordspro+n def percentPte(self): #Devuelve el % de palabras pte hasta el final del documento if self.wordspro>self.wordstot: self.wordspro=self.wordstot n=100*((self.wordstot-self.wordspro)/self.wordstot) if n<=0: n=1 if n>=100: n=99 return n def Content(self): #Devuelve el contenido (texto) de la frase self.gotoStart(0) self.gotoEnd(1) return self.cur.String def Caracs(self): self.cur.gotoStart(0) ret=self.cur.goRight(1,1) while ret: print (uts(self.cur.String)) if self.isEnd(): print ('EOF1') self.cur.collapseToEnd() if self.isEnd(): print ('EOF2') ret=self.cur.goRight(1,1) def Marca(self): #Guardar la posicion del cursor self.tr=self.cur.getStart() def Sync(self): self.cur.gotoRange(self.tr,0) def Marca2(self): #Guardar la posicion del cursor self.tr2=self.cur.getStart() def Sync2(self): if self.tr2!=None: self.cur.gotoRange(self.tr2,0) def esMarca2(self): #Comprueba si self.cur ha alcanzado Marca2 (self.tr2) #Retorno: True si self.cur ha alcanzado a self.tr2; si no lo ha alcanzado False if self.tr2!=None: if self.cur.getText().compareRegionStarts(self.cur.getStart(),self.tr2)==1: return False else: return True def ProcStart(self): #Inicio de proceso: anotar marca 'en proceso' #Retorno: True si podemos seguir; False si no podemos seguir _ret=True try: descri=self.model.DocumentProperties.Description except Exception as e: descri="" if len(descri)>=8: if descri[-8:]=="Saltstop": #Quitar parca stop y poner marca 'en proceso' descri=descri[0:-8]+"Saltstop" self.model.DocumentProperties.Description=descri elif descri[-8:]=="Saltproc": #Ya hay un procso en marcha _ret=False #descri=descri+"Saltproc" #self.model.DocumentInfo.Description=descri else: #Poner marca 'en proceso' (si no esta ya puesta) descri=descri+"Saltproc" # LliureX self.model.DocumentProperties.Description=descri return _ret def ProcEnd(self): #Fin del proceso: quitar marcas descri=self.model.DocumentProperties.Description if len(descri)>=8: if descri[-8:]=="Saltstop" or descri[-8:]=="Saltproc": #Quitar marca descri=descri[0:-8] self.model.DocumentProperties.Description=descri def ProcSeguir(self): #Comprobar si se debe seguir o cancelar el proceso #Retorno: True: seguir proceso; False: cancelar _ret=True descri=self.model.DocumentProperties.Description # Self document info search if len(descri)>=8: if descri[-8:]=="Saltstop": _ret=False return _ret def DocLista(self,colTx): # # Obtener una lista de palabras a partir del documento actual # # Funcionamiento: Se pasan a la lista parrafos completos o sentencias si porsent=True # # Salida: colTx: Lista de palabras del documento # colTx = [] i=0 _ret=True #ret=self.cur.gotoStartOfWord(0) ret=True while ret: #Hay nueva palabra _ret=self.cur.gotoEndOfWord(1) if _ret: pal=self.cur.String self.dcur.gotoRange(self.cur.getEnd(),0) if self.dcur.goRight(1,1): cf=uts(self.dcur.String) else: cf=" " if cf=="-": self.dcur.goRight(1,1) if (self.cnor).find(self.dcur.String[-1])!=-1: #Guion dentro de la palabra (xxx-xxx) _ret=self.cur.gotoNextWord(1) _ret=self.cur.gotoEndOfWord(1) pal=self.cur.String self.dcur.gotoRange(self.cur.getEnd(),0) if self.dcur.goRight(1,1): cf=uts(self.dcur.String) else: cf=" " else: #Pueden ser notas _ret=True pal="" self.dcur.gotoRange(self.cur.getStart(),0) ret=self.dcur.gotoNextWord(0) text=self.cur.getText() while ret and self.cur.goRight(1,0): if text.compareRegionStarts(self.cur.getEnd(),self.dcur.getStart())!=1: break elif self.cur.Footnote!=None or self.cur.Endnote!=None: #es nota #self.cur.gotoStartOfWord(1) self.dcur.gotoRange(self.cur.getEnd(),0) self.cur.gotoStartOfWord(0) self.cur.gotoRange(self.dcur.getEnd(),1) pal=self.cur.String cf=" " _ret=False break if pal=="": self.cur.gotoStartOfWord(0) if self.cur.gotoEndOfWord(1): pal=self.cur.String if pal!="": self.dcur.gotoRange(self.cur.getEnd(),0) if self.dcur.goRight(1,1): cf=uts(self.dcur.String) else: cf=" " else: break else: break #break self.dcur.gotoRange(self.cur.getStart(),0) self.dcur.collapseToStart() self.dcur.goLeft(1,1) if self.dcur.String!="" and self.cesp.find(self.dcur.String)>-1: #palabra unicaracter a la izda palesp=uts(self.dcur.String) txpal=(palesp,i,palesp,0,0) colTx.append(txpal) i=i+1 palesp="" self.dcur.gotoRange(self.cur.getEnd(),0) self.dcur.collapseToEnd() self.dcur.goRight(1,1) if self.dcur.String!="" and self.cesp.find(self.dcur.String)>-1: if uts(self.dcur.String)!='\n' and uts(self.dcur.String)!='\r' and uts(self.dcur.String)!='\t': #palabra unicaracter a la dcha palesp=uts(self.dcur.String) cf=palesp #elif self.dcur.String=="-": ##es guión: tratar como una sola palabra... #if self.dcur.gotoEndOfWord(1): ##...si no es guión usado como paréntesis #if self.dcur.String.find(" ")==-1: #self.cur.gotoRange(self.dcur.getEnd(),1) #pal=self.cur.String #cf=" " _p=pal.find(')') if _p==-1: _p=pal.rfind('.') if _p==-1: _p=pal.rfind(' ') if len(pal)>0 and _p>0 and pal.find("www")==-1 and pal.find("http")==-1 and pal.find("@")==-1: if pal.find(u".\xba")>0 or pal.find(u".\xaa")>0: #casos n.º n.ª 7.º 7.ª > nº nª 7º 7ª pal=pal.replace(".","") elif pal[-1]=="." and pal[0:-1].isdigit(): # caso xx. saltar todo pal="" elif isnumber(pal[_p+1:]): #caso .xx saltar todo #pal="" pass elif len(pal)>0 and _p>0 and _p-1: #pal=pal[_p:].lstrip() #casos x.x Palabra, provisinalmente desactivado #if len(pal)>0 and self.cesp.find(pal[0])>-1: while len(pal)>0 and (self.cesp+u'-').find(pal[0])>-1: #El primer caracter de pal es car especial (ej: ¡) ci=uts(pal[0]) pal=pal[1:] txpal=(ci,i,ci,0,0) colTx.append(txpal) i=i+1 if len(pal)>0 and self.cesp.find(pal[-1])>-1: #El último car de pal es caracter de fin (ej: un .) if len(pal)>1: cf=uts(pal[-1]) pal=uts(pal[0:-1]) #self.cur.goLeft(1,1) #n=1 while len(pal)>0 and '1234567890'.find(pal[-1])>-1 and cf!='\xba' and cf!='\xaa': #Eliminar números (son notas?) pal=uts(pal[0:-1]) #self.cur.goLeft(1,1) #n=n+1 #self.cur.collapseToEnd() #self.cur.goRight(n,0) if pal!="": txpal=(pal,i,cf,0,0) colTx.append(txpal) i=i+1 txpal=(cf,i,cf,0,0) colTx.append(txpal) i=i+1 else: pal=uts(pal) txpal=(pal,i,pal,0,0) colTx.append(txpal) i=i+1 elif len(pal)>0: #caso normal #el replace es por si hay guión automático de separación de palabras pal=uts(pal.strip()).replace("\xad","") txpal=(pal,i,cf,0,0) colTx.append(txpal) i=i+1 if palesp!="": #palabra unicaracter a la dcha txpal=(palesp,i,palesp,0,0) colTx.append(txpal) i=i+1 self.cur.gotoRange(self.dcur.getEnd(),0) #Siguiente palabra (si no es fin de párrafo o frase) self.cur.collapseToEnd() self.Marca2() if self.isEnd() or self.isEndSel(): break ret=self.cur.gotoNextWord(0) if ret and not _ret: #Volver una palabra atrás para no perder la siguiente palabra self.cur.gotoPreviousWord(0) return colTx def ListaDoc(self,colTx,colPalDu,comando): # # Pasar lista de palabras al documento. # Se pasan al documento parrafos completos # colTx: lista de palabras # colPalDu:lista de palabras dudosas # comando: comando ejecutado # También usa: # self.doc: documento actual # self.model: currentComponent (para crear Anotaciones) # i=0 j=0 _ret=True #ret=self.cur.gotoStartOfWord(0) ret=True while ret: #Hay nueva palabra _ret=self.cur.gotoEndOfWord(1) if _ret: pal=self.cur.String self.dcur.gotoRange(self.cur.getEnd(),0) if self.dcur.goRight(1,1): cf=uts(self.dcur.String) else: cf=" " if cf=="-": self.dcur.goRight(1,1) if (self.cnor).find(self.dcur.String[-1])!=-1: #Guion dentro de la palabra (xxx-xxx) _ret=self.cur.gotoNextWord(1) _ret=self.cur.gotoEndOfWord(1) pal=self.cur.String self.dcur.gotoRange(self.cur.getEnd(),0) if self.dcur.goRight(1,1): cf=uts(self.dcur.String) else: cf=" " else: #Pueden ser notas pal="" self.dcur.gotoRange(self.cur.getStart(),0) ret=self.dcur.gotoNextWord(0) text=self.cur.getText() while ret and self.cur.goRight(1,0): if text.compareRegionStarts(self.cur.getEnd(),self.dcur.getStart())!=1: break elif self.cur.Footnote!=None or self.cur.Endnote!=None: #es nota #self.cur.gotoStartOfWord(1) self.dcur.gotoRange(self.cur.getEnd(),0) self.cur.gotoStartOfWord(0) self.cur.gotoRange(self.dcur.getEnd(),1) pal=self.cur.String break if pal=="": self.cur.gotoStartOfWord(0) if self.cur.gotoEndOfWord(1): pal=self.cur.String if pal!="": self.dcur.gotoRange(self.cur.getEnd(),0) if self.dcur.goRight(1,1): cf=uts(self.dcur.String) else: cf=" " else: break else: break #break self.dcur.gotoRange(self.cur.getStart(),0) self.dcur.collapseToStart() self.dcur.goLeft(1,1) #if not self.nounicarizda and self.dcur.String!="" and self.cesp.find(self.dcur.String)>-1: if self.dcur.String!="" and self.cesp.find(self.dcur.String)>-1: #palabra unicaracter a la izda palesp=uts(self.dcur.String) j=self.ListaDocPal(self.dcur,colTx,colPalDu,comando,i,j) i=i+1 self.nounicarizda=False palesp="" self.dcur.gotoRange(self.cur.getEnd(),0) self.dcur.collapseToEnd() self.dcur.goRight(1,1) if self.dcur.String!="" and self.cesp.find(self.dcur.String)>-1: if uts(self.dcur.String)!='\n' and uts(self.dcur.String)!='\r' and uts(self.dcur.String)!='\t': #palabra unicaracter a la dcha palesp=uts(self.dcur.String) #elif self.dcur.String=="-": ##es guión: tratar como una sola palabra... #if self.dcur.gotoEndOfWord(1): ##...si no es guión usado como paréntesis #if self.dcur.String.find(" ")==-1: #self.cur.gotoRange(self.dcur.getEnd(),1) #pal=self.cur.String _p=pal.find(')') if _p==-1: _p=pal.rfind('.') if _p==-1: _p=pal.rfind(' ') if len(pal)>0 and _p>0 and pal.find("www")==-1 and pal.find("http")==-1 and pal.find("@")==-1: if pal.find(u".\xba")>0 or pal.find(u".\xaa")>0: #casos n.º n.ª 7.º 7.ª > nº nª 7º 7ª pal=pal.replace(".","") elif pal[-1]=="." and pal[0:-1].isdigit(): # caso xx. saltar todo pal="" elif isnumber(pal[_p+1:]): #caso .xx saltar todo #pal="" pass elif len(pal)>0 and _p>0 and _p0 and self.cesp.find(pal[0])>-1: while len(pal)>0 and (self.cesp+u'-').find(pal[0])>-1: #El primer caracter de pal es car especial (ej: ¡) text=self.cur.getText() _cur=text.createTextCursorByRange(self.cur.getEnd()) self.cur.collapseToStart() self.cur.goRight(1,1) j=self.ListaDocPal(self.cur,colTx,colPalDu,comando,i,j) i=i+1 self.cur.collapseToEnd() self.cur.gotoRange(_cur.getEnd(),1) pal=self.cur.String if len(pal)>0 and self.cesp.find(pal[-1])>-1: #El último car de pal es caracter de fin (ej: un .) if len(pal)>1: cf=uts(pal[-1]) pal=uts(pal[0:-1]) self.cur.goLeft(1,1) n=0 while len(self.cur.String)>1 and '1234567890'.find(self.cur.String[-1])>-1 and cf!='\xba' and cf!='\xaa': #Eliminar números (son notas?) pal=uts(pal[0:-1]) self.cur.goLeft(1,1) n=n+1 if self.cur.String!="": j=self.ListaDocPal(self.cur,colTx,colPalDu,comando,i,j) i=i+1 self.cur.collapseToEnd() self.cur.goRight(n,0) self.cur.goRight(1,1) j=self.ListaDocPal(self.cur,colTx,colPalDu,comando,i,j) i=i+1 else: pal=uts(pal) j=self.ListaDocPal(self.cur,colTx,colPalDu,comando,i,j) i=i+1 elif len(pal)>0: #caso normal pal=uts(pal) j=self.ListaDocPal(self.cur,colTx,colPalDu,comando,i,j) i=i+1 if palesp!="": #palabra unicaracter a la dcha #self.cur.gotoRange(self.dcur.getStart(),0) #self.cur.gotoRange(self.dcur.getEnd(),1) j=self.ListaDocPal(self.dcur,colTx,colPalDu,comando,i,j) i=i+1 self.cur.gotoRange(self.dcur.getEnd(),0) #Siguiente palabra (si no es fin de párrafo o frase) self.cur.collapseToEnd() if self.isEnd() or self.isEndSel() or self.esMarca2(): break #ret=self.cur.gotoNextWord(0) ret=self.NextWord() if ret and not _ret: #Volver una palabra atrás para no perder la siguiente palabra self.cur.gotoPreviousWord(0) def ListaDocPal(self,cur,colTx,colPalDu,comando,i,j): #Trata una palabra para actualizar el documento #self.model es el modelo #cur contiene la palabra a actualizar (en el documento) #i es el indice de la palabra en el documento #j es el indice en colTx #Retorno: j (lo modifica esta funcion) self.paleliminada=False palendoc=cur.String if j>=len(colTx): #Sobran palabras en el documento hayespsig=False haypuntosig=False elimespacio=True cur.String="" self.paleliminada=True if cur.goLeft(1,1): if len(cur.String)==1 and ord(cur.String)>32: elimespacio=False cur.collapseToEnd() if elimespacio: if cur.goRight(1,1)==True and cur.String==" ": cur.String="" else: cur.collapseToStart() if cur.goLeft(1,1)==True and cur.String==" " and palendoc!=u"\xa1" and palendoc!=u"\xbf": cur.String="" else: cur.collapseToEnd() #if cur.goRight(1,1)==True: #if self.cesp.find(cur.String)>-1: #haypuntosig=True #elif cur.String==" ": #hayespsig=True #cur.collapseToStart() #if cur.goLeft(1,1) == True: #if cur.String==" " and (hayespsig or haypuntosig): ##Eliminar espacio anterior #cur.String="" #else: #cur.collapseToEnd() elif colTx[j][tx_nordori]>i: #Eliminar palabra del documento hayespant=False hayespsig=False haypuntosig=False elimespacio=True cur.String="" self.paleliminada=True if cur.goLeft(1,1): if len(cur.String)==1 and ord(cur.String)>32 and ord(cur.String)<256 and "([{".find(cur.String)==-1: elimespacio=False cur.collapseToEnd() if elimespacio: if cur.goRight(1,1)==True and cur.String==" ": if cur.goRight(1,1)==True: if ord(cur.String[-1])>256: cur.collapseToEnd() else: cur.goLeft(1,1) cur.String="" else: cur.collapseToStart() if cur.goLeft(1,1)==True and cur.String==" " and palendoc!=u"\xa1" and palendoc!=u"\xbf": cur.String="" else: cur.collapseToEnd() #if cur.goRight(1,1)==True: #if self.cesp.find(cur.String)>-1: #haypuntosig=True #elif cur.String==" ": #hayespsig=True #cur.collapseToStart() #if cur.goLeft(1,1) == True: #if cur.String==" " and (hayespsig or haypuntosig): ##Eliminar espacio anterior #cur.String="" #else: #cur.collapseToEnd() elif colTx[j][tx_nordori]==i: #Sustituir/insertar palabras if j in colPalDu and self.model!=None: #Hay que anotar palabra dudosa nota=self.model.createInstance("com.sun.star.text.TextField.Annotation") nota.Author="Salt4"+"."+colPalDu[j]['dtr']+"."+ comando contenido="_clau=" + colPalDu[j]['Clave'] + "_\n" + colPalDu[j]['Info'] nota.Content=ucodeSiLinux(contenido) #self.model.Text.insertTextContent(doc.cur, nota, False) cur.Text.insertTextContent(cur, nota, False) pal=colTx[j][tx_paltext] #1.Sustituir if pal!="_" and pal!=uts(cur.String): pal=ucodeSiLinux(pal) #pal=pal.replace("'",apotpgr) palori=cur.String cur.String=pal self.ListaDocPalComas(cur,palori,colTx,j) j=j+1 #2.Insertar while j <= len(colTx)-1: if colTx[j][tx_nordori] == i: pal=ucodeSiLinux(' ') cur.collapseToEnd() cur.String=pal cur.collapseToEnd() if j in colPalDu and self.model!=None: #Hay que anotar palabra dudosa nota=self.model.createInstance("com.sun.star.text.TextField.Annotation") nota.Author="Salt4"+"."+colPalDu[j]['dtr']+"."+ comando contenido="_clau=" + colPalDu[j]['Clave'] + "_\n" + colPalDu[j]['Info'] nota.Content=ucodeSiLinux(contenido) #self.model.Text.insertTextContent(doc.cur, nota, False) cur.Text.insertTextContent(cur, nota, False) pal=colTx[j][tx_paltext] pal = ucodeSiLinux(pal) #pal=pal.replace("'",apotpgr) cur.collapseToEnd() palori=cur.String cur.String=pal self.ListaDocPalComas(cur,palori,colTx,j) cur.collapseToEnd() #cur.getText().insertString(cur.getEnd(),pal,True) j = j + 1 else: break #while j < len(colTx)-1: #if colTx[j + 1][tx_nordori] == i: #j = j + 1 #pal = pal + ' ' + colTx[j][tx_paltext] #else: #break ##doc.cur.String=pal #if pal!="_" and pal!=uts(cur.String): #pal=ucodeSiLinux(pal) #cur.String=pal ##cur.getText().insertString(cur.getEnd(),pal,False) ##cur.String="" ##cur.goRight(len(pal),1) #j = j + 1 return j def ListaDocPalComas(self,cur,palori,colTx,j): #Comprobación de espacios antes de "coma" #Entrada: cur: Cursor actual después de realizarse la sustitución de la palabra # palori: Palabra original, antes de realizar la sustitución de la palabra # colTx: Lista de palabras # j: Palabra actual de la lista if cur.String == "," or cur.String == "." or cur.String == ";" or cur.String == "?" or cur.String == "!" or cur.String == u'\u201d': #La nueva palabra es una coma ... _cur=cur.getText().createTextCursorByRange(cur.getStart()) _cur.gotoRange(cur.getStart(),0) _cur.goLeft(1,1) if _cur.String == " ": # ... si hay espacio anterior, quitarlo _cur.String="" elif palori == "," or palori == "." or palori == ";" or palori == "?" or palori == "!" or palori == u'\u201d': #La palabra sustituida era una coma ... if cur.String != "," and cur.String != "." and cur.String != ";" and cur.String != "?" and cur.String != "!" and cur.String != u'\u201d': # ... y la nueva no ... _cur=cur.getText().createTextCursorByRange(cur.getStart()) _cur.gotoRange(cur.getStart(),0) _cur.goLeft(1,1) if _cur.String != " ": # ... si no hay espacio anterior, anyadirlo _cur.collapseToEnd() _cur.String=" " #elif cur.String == u'\u201c' and palori!=u'\u201c': ##La nueva palabra es una doble comilla de inicio ... #_cur=cur.getText().createTextCursorByRange(cur.getStart()) #_cur.gotoRange(cur.getEnd(),0) #_cur.goRight(1,1) #if _cur.String == " ": ## ... si hay espacio posterior, quitarlo #_cur.String="" elif palori == u'\u201c' or palori==u'¡' or palori==u'¿': #La palabra sustituida era una doble comilla de inicio ... if cur.String != u'\u201c' and cur.String != u'¡' and cur.String != u'¿': # ... y la nueva no ... _cur=cur.getText().createTextCursorByRange(cur.getStart()) _cur.gotoRange(cur.getEnd(),0) _cur.goRight(1,1) if _cur.String != " ": # ... si no hay espacio posterior, anyadirlo _cur.collapseToStart() _cur.String=" " else: #Comprobar si hay que eliminar un espacio anterior if j>0 and colTx[j-1][tx_paltext]=='\x93': _cur=cur.getText().createTextCursorByRange(cur.getStart()) _cur.gotoRange(cur.getStart(),0) _cur.goLeft(1,1) if _cur.String == " ": # ... si hay espacio posterior, quitarlo _cur.String="" # end of class sltDoc class sltEstado: #Permite controlar el estado de los procesos de Traduccion y correccion def __init__(self,model): #diccionario de procesos activos: {'Titulo':estado,...} #estado puede ser: 'enproceso','stop' self.model=model def Stop(self): #Poner marca de que hay que cancelar el proceso descri=self.model.DocumentInfo.Description Llog("stop "+str(descri)) if len(descri)>=8: if descri[-8:]=="Saltproc": #Estas en proceso: poner la marca de detener descri=descri[0:-8]+"Saltstop" self.model.DocumentInfo.Description=descri def Info(self): #Informacion sobre este proceso return self.model.DocumentInfo.Description # end of class sltEstado class ooUNOext: #simular la clase ooUNOobj llamada desde sltooo_extern (test) def __init__(self, ctx): #component context self.ctx=ctx def Llog(msg): syslog.syslog(syslog.LOG_DEBUG,str(msg)) def action(self,args): smgr = self.ctx.ServiceManager doooLib.getServiceManager(sMan=smgr) doooLib.getDesktop() # retrieve the desktop object desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", self.ctx ) # get current document model model = desktop.getCurrentComponent() # access the document's text property #text = model.Text # create a cursor #cursor = text.createTextCursor() #Cursor vcursorsupplier=model.getCurrentController() vcursor=vcursorsupplier.getViewCursor() Llog(str(args)) #Funcion a realizar if args=="trad" or args=="tradi" or args=="corr": #oPro=ProWindow(model) oPro=vcursorsupplier.getStatusIndicator() #Trad(model,vcursor,args,oPro) Trad(model,vcursor,args,oPro) elif args=="startrev": #import threading ##Escuchar peticiones #t=threading.Thread(target=ListenFields,args=(model,)) #t.setDaemon(True) #t.start() ListenFields(model) elif args=="rev": oTest=CtvWindow(model) oTest.BuscaNotas() if not oTest.Siguiente(ini=-1): oTest.windowClose() oTest.cmbSubs_clicked(None) oTest.Espera() elif args=="config": #Opcions de configiracio oTest=ConfigWindow() #oTest.cmbActu_clicked(None) oTest.Espera() elif args=="ajuda": Ajuda(desktop) elif args=="stop": Llog("STOP Inicial") msg=MsgWindow(str(procesos.Info(model))) #global varglobal #print str(model) elif args=="verbs": oTest=VerbsWindow(model) oTest.Load() oTest.Espera() elif args=="mouse": ListenFields(model) Espera() # implement a UNO component by deriving from the standard unohelper.Base class # and from the interface(s) you want to implement. class ooUNOobj( unohelper.Base, XJobExecutor ): def __init__( self, ctx ): # store the component context for later use self.ctx = ctx def trigger( self, args ): # note: args[0] == "HelloWorld", see below config settings # retrieve the desktop object desktop = self.ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", self.ctx ) doooLib.getServiceManager(sMan=self.ctx.ServiceManager) # get current document model model = desktop.getCurrentComponent() # access the document's text property #text = model.Text # create a cursor #cursor = text.createTextCursor() #Cursor vcursorsupplier=model.getCurrentController() vcursor=vcursorsupplier.getViewCursor() #Funcion a realizar if args=="trad" or args=="tradi" or args=="corr": #Realizar orden #oPro=ProWindow(model) oPro=vcursorsupplier.getStatusIndicator() import threading t=threading.Thread(target=Trad,args=(model,vcursor,args,oPro)) #t.setDaemon(False) t.start() #Trad(model,cur,args) #elif args=="rev": #oCtv=CtvWindow(model) #import threading #t=threading.Thread(target=Rev,args=(oCtv,args)) elif args=="rev": #Rev(model) #ListenFields(model) oCtv=CtvWindow(model) oCtv.BuscaNotas() if not oCtv.Siguiente(ini=-1): oCtv.windowClose() #oCtv.Espera() elif args=="config": #Opcions de configiracio oConfig=ConfigWindow() elif args=="ajuda": #Ayuda en linea Ajuda(desktop) elif args=="stop": #Detener proceso st=sltEstado(model) st.Stop() from doooWindowLib import DBListenerWindow import time class ConfigWindow(DBListenerWindow): def __init__(self): DBListenerWindow.__init__( self, u"Opcions de configuració" ) self.setWindowPosSize(100,100,515,645) self.addFixedText( "lblOrtografia", 10, 10, 200, 14, u"Ortografia i morfosintaxi:" ) self.addGroupBox("grpDemostra",10,30,200,55,u"Demostratius") self.addOptionButton("optDemostra2",10+10,30+20,200-20,20,u"Simples(este,eixe)", itemListenerProc = self.optDemostra2_clicked) self.addOptionButton("optDemostra1",10+10,30+50,200-20,20,u"Reforçats(aquest,aqueix)", itemListenerProc = self.optDemostra1_clicked) self.addGroupBox("grpIncoac",10,110,200,55,u"Incoatius") self.addOptionButton("optIncoac2",10+10,110+20,200-20,20,u"Increment -ix (patix)", itemListenerProc = self.optIncoac2_clicked) self.addOptionButton("optIncoac1",10+10,110+50,200-20,20,u"Increment -eix (pateix)", itemListenerProc = self.optIncoac2_clicked) self.addGroupBox("grpPlu",10,190,200,55,u"Plural de -sc, -st i -xt") self.addOptionButton("optPlu1",10+10,190+20,200-20,20,u"Terminació -os (foscos)") self.addOptionButton("optPlu2",10+10,190+50,200-20,20,u"Terminació -s (foscs)") self.addGroupBox("grpAcc",10,270,200,55,u"Accentuació") self.addOptionButton("optAcc1",10+10,270+20,200-20,20,u"(café)") self.addOptionButton("optAcc2",10+10,270+50,200-20,20,u"(cafè)") self.addGroupBox("grpTop",10,350,200,55,u"Topònims") self.addOptionButton("optTopOfi",10+10,350+20,200-20,20,u"Oficials (Cheste)") self.addOptionButton("optTopHist",10+10,350+50,200-20,20,u"Històrics (Xest)") self.addFixedText( "lblRevisio", 220, 10, 200, 14, u"Revisió:" ) self.addGroupBox("grpPaDes",220,30,200,55,u"Paraules desconegudes") self.addOptionButton("optIgnPaDes",220+10,30+20,200-20,20,u"Ignorar") self.addOptionButton("optDetPaDes",220+10,30+50,200-20,20,u"Detectar") self.addGroupBox("grpNpDes",220,110,200,55,u"Noms propis desconeguts") self.addOptionButton("optIgnNpDes",220+10,110+20,200-20,20,u"Ignorar") self.addOptionButton("optDetNpDes",220+10,110+50,200-20,20,u"Detectar") self.addGroupBox("grpMa",220,190,200,55,u"Ús de majúscules") self.addOptionButton("optIgnMa",220+10,190+20,200-20,20,u"Ignorar") self.addOptionButton("optDetMa",220+10,190+50,200-20,20,u"Detectar") self.addGroupBox("grpDSem",220,270,200,55,u"Doblets semàntics") self.addOptionButton("optIgnDSem",220+10,270+20,200-20,20,u"Ignorar") self.addOptionButton("optDetDSem",220+10,270+50,200-20,20,u"Detectar") self.addGroupBox("grpOpConfig",220,350,200,55,u"Op. de configuració") self.addOptionButton("optIgnOpConfig",220+10,350+20,200-20,20,u"Ignorar") self.addOptionButton("optDetOpConfig",220+10,350+50,200-20,20,u"Detectar") self.addGroupBox("grpCfgVoid",10,430,410,80,u"Ajustar traducció de frases en altres llengües(llatí...)") self.addFixedText( "lblCfgVoid1", 20, 460, 200, 14, u"No traduir si la frase té més de" ) self.addEdit( "txtNPalTot", 250, 460, 100, 14, "",textListenerProc=self.txtNPalTot_changed ) self.setEditEditable("txtNPalTot",True) self.addFixedText( "lblCfgVoid1b", 20, 480, 175, 14, u"paraules i n'hi ha més d'un" ) self.addEdit( "txtPercent", 200, 480, 22, 14, "", textListenerProc=self.txtPercent_changed ) self.setEditEditable("txtPercent",True) self.addFixedText( "lblCfgVoid1c", 225, 480, 14, 14, u"%" ) self.addFixedText( "lblCfgVoid2", 20, 500, 250, 14, u"de paraules desconegudes." ) self.addButton( "cmbNoVoid", 10+30+250, 450+40, 100, 20, u"Traduir sempre", actionListenerProc = self.cmbNoVoid_clicked ) self.addGroupBox("grpVers",10,530,410,30,u"Versió de l'addon") self.addFixedText( "lblVers", 10+30, 530+20, 300, 12, u"Salt 4.0" ) self.addButton( "cmbActu", 10+50, 580, 100, 30, u"Actualitzar", actionListenerProc = self.cmbActu_clicked ) self.addButton( "cmbCancel", 220+50, 580, 100, 30, u"Cancel·lar", actionListenerProc = self.cmbCancel_clicked ) self.setEnable("grpAcc",False) self.setEnable("optAcc1",False) self.setEnable("optAcc2",False) wpos={'left':100,'top':100,'width':515,'height':645} self.setWindowPosSize( wpos['left'], wpos['top'], 515, 645 ) self.terminar=False #Acceso al servidor para cargar/salvar configuración self.sck=socketConnect() if self.sck==None: self.terminar=True self.windowClose() else: #Cargar configuración actual scfg="" datos=str(("cfgload","")).encode('utf-8') self.sck.send(datos) datos=self.sck.recv(128000).decode('utf-8') comandorec,scfg=eval(datos) self.cfg=eval(scfg) if 'config' in self.cfg: if 'demostratius' in self.cfg['config']: self.setOptTrue(self.cfg['config']['demostratius']==1,'optDemostra2','optDemostra1') if 'incoatius' in self.cfg['config']: self.setOptTrue(self.cfg['config']['incoatius']==1,'optIncoac2','optIncoac1') if 'plural' in self.cfg['config']: self.setOptTrue(self.cfg['config']['plural']==1,'optPlu1','optPlu2') if 'acc' in self.cfg['config']: self.setOptTrue(self.cfg['config']['acc']==1,'optAcc1','optAcc2') if 'top' in self.cfg['config']: self.setOptTrue(self.cfg['config']['top']==1,'optTopOfi','optTopHist') if 'pades' in self.cfg['config']: self.setOptTrue(self.cfg['config']['pades']==1,'optIgnPaDes','optDetPaDes') if 'npdes' in self.cfg['config']: self.setOptTrue(self.cfg['config']['npdes']==1,'optIgnNpDes','optDetNpDes') if 'maj' in self.cfg['config']: self.setOptTrue(self.cfg['config']['maj']==1,'optIgnMa','optDetMa') if 'dsem' in self.cfg['config']: self.setOptTrue(self.cfg['config']['dsem']==1,'optIgnDSem','optDetDSem') if 'opconfig' in self.cfg['config']: self.setOptTrue(self.cfg['config']['opconfig']==1,'optIgnOpConfig','optDetOpConfig') if 'void_npalmin' in self.cfg['config']: txt=str(self.cfg['config']['void_npalmin']) self.setEditText("txtNPalTot",txt) if 'void_percent' in self.cfg['config']: txt=str(self.cfg['config']['void_percent']) self.setEditText("txtPercent",txt) #Acc está en función de otras opciones self.OptActivarAcc() #Versión del addon txt="Addon salt " +sltversion #+ str(sltDate()) self.setFixedTextText("lblVers",txt) #Eventos def txtNPalTot_changed(self,oTextEvent): txt=self.getEditText("txtNPalTot") if len(txt)>0: if not txt[-1].isdigit(): #Sólo números txt=txt[0:-1] self.setEditText("txtNPalTot",txt) elif int(txt)>9999: txt='9999' self.setEditText("txtNPalTot",txt) def txtPercent_changed(self,oTextEvent): txt=self.getEditText("txtPercent") if len(txt)>0: if not txt[-1].isdigit(): #Sólo números txt=txt[0:-1] self.setEditText("txtPercent",txt) elif int(txt)>100: txt='100' self.setEditText("txtPercent",txt) def cmbActu_clicked( self, oActionEvent ): """This is called when the Actu button is clicked.""" #Actualizar los datos de configuración if 'config' in self.cfg: self.cfg['config']['demostratius']=self.getOptVal('optDemostra2') self.cfg['config']['incoatius']=self.getOptVal('optIncoac2') self.cfg['config']['plural']=self.getOptVal('optPlu1') self.cfg['config']['acc']=self.getOptVal('optAcc1') self.cfg['config']['top']=self.getOptVal('optTopOfi') self.cfg['config']['pades']=self.getOptVal('optIgnPaDes') self.cfg['config']['npdes']=self.getOptVal('optIgnNpDes') self.cfg['config']['maj']=self.getOptVal('optIgnMa') self.cfg['config']['dsem']=self.getOptVal('optIgnDSem') self.cfg['config']['opconfig']=self.getOptVal('optIgnOpConfig') txt=self.getEditText("txtNPalTot") if not txt.isdigit(): txt='9999' self.cfg['config']['void_npalmin']=int(txt) txt=self.getEditText("txtPercent") if not txt.isdigit(): txt='100' self.cfg['config']['void_percent']=int(txt) scfg=str(self.cfg) datos=str(("cfgsave",scfg)).encode('utf-8') self.sck.send(datos) datos=self.sck.recv(128000).decode('utf-8') self.terminar=True self.windowClose() def cmbCancel_clicked( self, oActionEvent ): """This is called when the Cancel button is clicked.""" self.terminar=True self.windowClose() def cmbNoVoid_clicked( self, oActionEvent ): """This is called when the button is clicked.""" self.setEditText("txtNPalTot",'9999') self.setEditText("txtPercent",'100') def optDemostra2_clicked(self,oActionEvent): self.OptActivarAcc() def optDemostra1_clicked(self,oActionEvent): self.OptActivarAcc() def optIncoac2_clicked(self,oActionEvent): self.OptActivarAcc() def optIncoac1_clicked(self,oActionEvent): self.OptActivarAcc() def windowClosed(self,oActionEvent): self.terminar=True self.sck.close() rect=self.getWindowPosSize() self.wp["configwindow"]=str({'left':rect.X,'top':rect.Y,'width':rect.Width,'height':rect.Height}) self.wp.sync() selp.wp.close() #Métodos def Espera(self): while not self.terminar: time.sleep(1) def OptActivarAcc(self): #Activar/desactivar la elección cafè/café if self.getOptionButtonState("optDemostra1")==True and self.getOptionButtonState("optIncoac1")==True: self.setEnable("grpAcc",True) self.setEnable("optAcc1",True) self.setEnable("optAcc2",True) else: self.setOptionButtonState("optAcc1",True) self.setEnable("grpAcc",False) self.setEnable("optAcc1",False) self.setEnable("optAcc2",False) def setOptTrue(self,cnd,optSiTrue,optSiFalse): # Poner un opt True según una condición: # Si cnd==True, el botón llamado optSiTrue se pone True # Si cnd == False, el botón llamado optSiFalse se pone True if cnd: self.setOptionButtonState(optSiTrue,True) else: self.setOptionButtonState(optSiFalse,True) def getOptVal(self,opt): #Devuelve el valor asociado al OptionButton cuyo nombre es opt en el fichero de configuración #Si opt==True: devuelve 1 #Si opt==False: devuelve 2 if self.getOptionButtonState(opt)==True: return 1 else: return 2 class CtvWindow(DBListenerWindow): def __init__(self,model): DBListenerWindow.__init__( self, u"Paraules dubtoses de:"+model.getCurrentController().getFrame().Title ) self.addFixedText( "lblPaDubt", 6, 2, 120, 12, u"Paraula dubtosa:" ) self.addFixedText( "lblPaPro", 6, 34, 120, 12, u"Proposta de canvi:" ) self.addFixedText( "lblAlt", 6, 56, 86, 12, u"Alternatives:" ) self.addFixedText( "lblTipErr", 6, 196, 86, 12, u"Tipus d'error:" ) self.addEdit( "txtMens", 122, 196, 253, 16, "" ) self.setEditEditable("txtMens",False) self.addEdit( "txtPalErr", 122, 5, 253, 16, "" ) self.setEditEditable("txtPalErr",False) self.addEdit( "txtPal", 122, 34, 253, 16, "" ) self.setEditEditable("txtPal",True) self.addButton( "cmbSubs", 382, 4, 120, 20, u"Substituir", actionListenerProc = self.cmbSubs_clicked ) self.addButton( "cmbSubsSempre", 382, 35, 120, 20, u"Substituir sempre", actionListenerProc = self.cmbSubsSempre_clicked ) self.addButton( "cmbIgno", 382, 66, 120, 20, u"Ignorar", actionListenerProc = self.cmbIgno_clicked ) self.addButton( "cmbIgnoSempre", 382, 97, 120, 20, u"Ignorar sempre", actionListenerProc = self.cmbIgnoSempre_clicked ) self.addButton( "cmbElimMarques", 382, 128, 120, 20, u"Eliminar marques", actionListenerProc = self.cmbElimMarques_clicked ) self.addButton( "cmbCancel", 382, 156, 120, 20, u"Cancel·lar", actionListenerProc = self.cmbCancel_clicked ) self.addCheckBox( "chkAfegir", 382, 182, 130, 20, u"Afegir a dic. pers.", itemListenerProc = self.chkAfegir_clicked ) self.addCheckBox( "chkCont", 382, 202, 130, 20, u"Continuar revisió", itemListenerProc = self.chkCont_clicked ) self.addListBox( "lbxAlt", 6, 75,369, 83, bDropdown=False,itemListenerProc = self.lbxAlt_clicked ) wpos={'left':0x100,'top':0x200,'width':0x23c,'height':0x0e0} self.setWindowPosSize( wpos['left'], wpos['top'], 620, 0x0e0 ) #self.setWindowPosSize( wpos['left'], wpos['top'], 0x23c, 0x0e0 ) #variables para acceder al documento self.model=model self.oDocView=None self.oNotas=None self.oNota=None self.curNota=None self.oAnchor=None self.oText=None self.lsNotas=[] self.iNotas=0 #Informació sobre la paraula dudosa actual self._prauclau_ = "clau" self._praunumalts_ = "numalts" #Núm. de alternativas self._prautxtdu_ = "txtdu" #Texto dudoso self._prautxtpro_ = "txtpro" #Texto propuesto '(corresponde a la primera alternativa) self._praualt_ = "alt" #Las diferentes alternativas se identifican como $altn= self._praudescrierror_ = "error" #Texto que describe el tipo de error self._praunpretro_ = "npretro" #Núm. palabras a retroceder para corregir en el proceso de revisión (si 0 no corregir) self._praucolor_ = "txtcolor" #Color original del texto dudoso self.praucom="" #Comando que produjo la anotación self.prauclau="" #Palabra(s) en el documento self.praunumalts=0 self.prautxtdu="" self.prautxtpro="" self.prautxtpal="" #Alternativa propuesta self.praudescrierror="" self.praunpretro=0 self.praudtr="" #Traducción directa o inversa self.cmd="" self.continuar=True self.afegir=False self.terminar=False #Acceso al servidor para revisar frases self.sck=socketConnect() if self.sck==None: self.terminar=True self.windowClose() #Eventos def cmbSubs_clicked(self, oActionEvent): #Actualizar información self.cmd="cmbSubs" self.LeeCtv() #Localizar palabra en el documento cur=self.DamePalEnNota() #Eliminar anotación self.oText.removeTextContent(self.oNota) self.lsNotas.pop(self.iNotas) #Substituir palabra en el documento self.Substituir(cur) #Ver si hay que añadir al dicc. personal (TODO) #Seguir o terminar if self.continuar: if not self.Siguiente(ini=-2): self.windowClose() else: self.windowClose() def cmbSubsSempre_clicked(self, oActionEvent): #Actualizar información self.cmd="cmbSubsSempre" self.LeeCtv() #Localizar palabra en el documento cur=self.DamePalEnNota() #Eliminar anotación self.oText.removeTextContent(self.oNota) self.lsNotas.pop(self.iNotas) #Substituir palabra en el documento self.Substituir(cur) #Sustituir todas las que sean iguales i=0 txtclau=self.prauclau txtpro=self.prautxtpro txtdubt=self.prautxtdu iactual=self.iNotas while i=0 and i-1, buscar este número de anotación # Si ini==-1, buscar desde el cursor "del ratón" # Si ini==-2, buscar siguiente #Retorno: True, si se ha encontrado anotación; False, si no hay anotaciones _ret=False if len(self.lsNotas)==0: self.oNota=self.oAnchor=self.oText=self.curNota=None return _ret haynotas=False oNota=None oAnchor=None oText=None cur=None vcur=self.model.getCurrentController().getViewCursor() if ini==-1: #Obtener cursor del ratón text=vcur.getText() rcur=text.createTextCursorByRange(vcur.getStart()) self.iNotas=0 while self.iNotas=0: oNota,oAnchor,oText,cur=self.lsNotas[self.iNotas] if oNota==None: self.iNotas=0 oNota,oAnchor,oText,cur=self.lsNotas[self.iNotas] if oNota!=None: #Comprobar que la nota sigue existiendo try: info=oNota.Content except: #Ha habido error: la nota ya no existe self.lsNotas.pop(self.iNotas) _ret=self.Siguiente() return _ret _ret=True self.oNota=oNota self.oAnchor=oAnchor self.oText=oText self.praudtr=self.oNota.Author[6:7] self.praucom=self.oNota.Author[8:] info=self.oNota.Content self.InfoCtv(info) cur=self.DamePalEnNota() cur.CharContoured=True self.curNota=cur #Que se vea la palabra dudosa vcur.gotoRange(cur.getStart(),0) return _ret def Siguiente_(self,ini=-1): #Buscar la siguiente anotación en el documento #Entrada: Si ini>-1, buscar desde esa posición # Si ini<0, buscar desde el cursor "del ratón" #Retorno: True, si se ha encontrado anotación; False, si no hay anotaciones _ret=False haynotas=False oNotaActual=None oAnchorActual=None oTextActual=None curactual=None if ini<0: #Obtener cursor del ratón vcur=self.model.getCurrentController().getViewCursor() rcur=vcur.getText().createTextCursorByRange(vcur.getStart()) rcur.gotoStart(1) lenanterior=len(rcur.String) else: lenanterior=ini #Analizar notas self.oNotas=self.model.getTextFields().createEnumeration() while self.oNotas.hasMoreElements(): self.oNota=self.oNotas.nextElement() if self.oNota.supportsService("com.sun.star.text.TextField.Annotation"): if self.oNota.Author[0:4]=="Salt": self.praudtr=self.oNota.Author[6:7] self.praucom=self.oNota.Author[8:] haynotas=True #Obtener cursor "de la nota" self.oAnchor=self.oNota.getAnchor() self.oText=self.oAnchor.getText() cur=self.oText.createTextCursorByRange(self.oAnchor.getStart()) cur.gotoStart(1) if len(cur.String)>lenanterior: #Puede ser esta if oNotaActual!=None: if len(curactual.String)>len(cur.String): #Este es mejor oNotaActual=self.oNota oAnchorActual=self.oAnchor oTextActual=self.oText curactual=cur else: oNotaActual=self.oNota oAnchorActual=self.oAnchor oTextActual=self.oText curactual=cur if oNotaActual!=None: #Procesar esta nota _ret=True self.oNota=oNotaActual self.oAnchor=oAnchorActual self.oText=oTextActual info=self.oNota.Content self.InfoCtv(info) cur=self.DamePalEnNota() cur.CharContoured=True self.curNota=cur #Que se vea la palabra dudosa vcur.gotoRange(cur.getStart(),0) elif haynotas: #Si no hemos encontrado ninguna, probar desde el principio _ret=self.Siguiente(ini=0) else: _ret=False return _ret def InfoLeer(self,info,cod): #' Leer un elemento de la información adicional que se #' guarda junto a cada texto dudoso, en el proceso #' automático #' #' Entrada: info: String de información adicional #' cod: Código a buscar #' #' Retorno: Texto informativo correspondiente a #' cod, si existe ese elemento en Info #' (en caso contrario "") txt="" pi=info.find("_"+cod+"=") if pi>=0: pi=pi+len(cod)+2 pf=info.find("_",pi) if pf>=0: txt=info[pi:pf] else: txt=info[pi:] return txt def InfoCtv(self,info): #Pasar a la ventana la información sobre la palabra dudosa contenida en info self.prauclau=self.InfoLeer(info,self._prauclau_) txt=self.InfoLeer(info,self._praunumalts_) if txt.isdigit(): self.praunumalts=int(txt) else: self.praunumalts=0 self.prautxtdu=self.InfoLeer(info,self._prautxtdu_) self.setEditText("txtPalErr",self.prautxtdu) self.prautxtpro=self.InfoLeer(info,self._prautxtpro_) self.prautxtpal=self.prautxtpro self.setEditText("txtPal",self.prautxtpal) self.removeListBoxItems("lbxAlt",0,self.getListBoxItemCount("lbxAlt")) for i in range(1,self.praunumalts+1): txt=self.InfoLeer(info,self._praualt_ + str(i)) self.addListBoxItem("lbxAlt",txt) self.praudescrierror=self.InfoLeer(info,self._praudescrierror_) self.setEditText("txtMens",self.praudescrierror) txt=self.InfoLeer(info,self._praunpretro_) if txt.isdigit(): self.praunpretro=int(txt) else: self.praunpretro=0 self.setCheckBoxState("chkCont",self.continuar) def LeeCtv(self): #Actualiza determinadas variables a partir de la informacion en CtvWindow self.prautxtpro=self.getEditText("txtPal") self.afegir=self.getCheckBoxState("chkAfegir") self.continuar=self.getCheckBoxState("chkCont") def DamePalEnLista(self,txt): #' #' Nos da una palabra sin los caracteres informativos de lbxAlt #' #' Entrada: txt: Texto al que queremos quitar caracteres informativos #' #' Retorno: Texto sin los caracteres informativos ("" si empieza por esp) pal="" if len(txt)>0: if txt[0]!=" ": pal=txt p=pal.find(".") if p>=0: pal=pal[p+1:] p=pal.find("[") if p>=0: pal=pal[0:p].strip() else: pal=pal.strip() return pal def DamePalEnNota(self): #Obtener la palabra correspondiente a la anotación actual #Retorno: cursor con el texto de la anotación actual seleccionado cur=self.oText.createTextCursorByRange(self.oAnchor.getStart()) cur.goRight(1,0) #saltar anotación doc=sltDoc(self.model,cur,pos=True) pal,cf,fp=PalabraSig(doc) if self.prauclau.lower()!=doc.cur.String.lower(): p=doc.cur.String.lower().find(self.prauclau.lower()) if p>0: p=len(doc.cur.String)-p doc.cur.collapseToEnd() doc.cur.goLeft(p,1) if self.prauclau.find(" ")>=0: #Hay que sustituir más de una palabra p=self.prauclau.lower().find(doc.cur.String.lower()) if p>=0: nizda=p ncent=len(doc.cur.String) ndcha=len(self.prauclau)-nizda-ncent if nizda>0 or ndcha>0: if nizda>0 and self.oText.compareRegionStarts(self.oAnchor.getStart(),doc.cur.getStart())==1: nizda=nizda+1 if ndcha>0 and self.oText.compareRegionStarts(self.oAnchor.getStart(),doc.cur.getEnd())==-1: ndcha=ndcha+1 doc.cur.collapseToStart() doc.cur.goLeft(nizda,0) doc.cur.goRight(nizda+ncent+ndcha,1) return doc.cur def Substituir(self,cur): #Substituir la palabra actual #cur=self.DamePalEnNota() cur.CharContoured=False if self.prauclau.lower()==cur.String.lower(): cur.String=self.prautxtpro #Revisar frase modificada if self.praucom=="trad" or self.praucom=="tradi": if self.praudtr=="i": comando="revi" else: comando="rev" self.Rev(cur,comando,self.sck) def Rev(self,cur,comando,sck): #Revisar frase modificada #Entrada: # cur: cursor en el documento a revisar # comando: revision directa o inversa ('rev','revi') # sck: Socket con el servidor Salt selcur=self.RevSelec(cur) cur.gotoRange(selcur.getStart(),0) doc=sltDoc(self.model,cur,unit='s',curfin=selcur.getEnd()) #sck=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #sck.connect(('localhost',20001)) #ret=doc.gotoStart() ret=True while ret==True and sck!=None and not doc.isEndSel(): #1. Obtener lista de palabras colPalDu={} colTx=[] doc.Marca() colTx=doc.DocLista(colTx) if len(colTx)>0: #2. Orden de correcion de la frase datos=str((comando,(colTx,colPalDu))).encode('latin-1') sck.send(datos) datos=sck.recv(128000).decode('latin-1') comandorec,(colTx,colPalDu)=eval(datos) #3. Actualizar documento if comandorec!="void": colPalDu={} doc.Sync() doc.ListaDoc(colTx,colPalDu,comando) ret=doc.cur.gotoNextWord(0) def RevSelec(self,cur,n=2): #Obtener una selección (rango) a revisar a partir de la palabra actual en cur #n es el número de palabras a cada lado #No puede sobrepasar notas ni hacia delante ni hacia atrás #Retorno:cursor que tiene seleccionado el rango nacur=npcur=None text=cur.getText() if self.iNotas>0: if text==self.lsNotas[self.iNotas-1][2]: nacur=self.lsNotas[self.iNotas-1][3] nacur.goRight(1,0) if self.iNotas0 and (reta or retb): reta=rcura.gotoPreviousWord(1) retp=rcurp.gotoEndOfWord(1) if n>1: retp=rcurp.gotoNextWord(1) #Comprobar que no sobrepasamos notas if nacur!=None: if text.compareRegionStarts(nacur,rcura)==1: raok=rcura.getStart() else: raok=rcura.getStart() if npcur!=None: if text.compareRegionEnds(rcurp,npcur)==1: rpok=rcurp.getEnd() else: rpok=rcurp.getEnd() n=n-1 selcur=text.createTextCursorByRange(raok) selcur.gotoRange(rpok,1) return selcur # end of class CtvWindow class ProWindow(DBListenerWindow): def __init__(self,model): #DBListenerWindow.__init__( self, "Processant" ,nWindowAttributes=uno.getConstantByName("com.sun.star.awt.WindowAttribute.SHOW")+uno.getConstantByName("com.sun.star.awt.WindowAttribute.MOVEABLE")) DBListenerWindow.__init__( self, "Processant:"+model.getCurrentController().getFrame().Title) #self.addProgressBar("prbPro",5,10,300,16) self.addImageControl("imgPro1",5,10,300,16,nBorder=2) self.addImageControl("imgPro2",5,10,0,16,nBorder=2) self.setImageControlBackgroundColor("imgPro2",int(255)) #self.addFixedText("txtPro",5,10,300,16) #self.setFixedTextAlignment("txtPro",1) self.addButton( "cmbCancel", 310, 10, 60, 16, "Cancel·lar", actionListenerProc = self.cmbCancel_clicked ) wpos={'left':100,'top':200,'width':460,'height':40} self.setWindowPosSize( wpos['left'], wpos['top'], wpos['width'], wpos['height'] ) #La barra de progreso por defecto entre 0 y 100 #self.setProgressRange("prbPro",0,100) self.Min=0 self.Max=100 self.terminar=False #Eventos def cmbCancel_clicked( self, oActionEvent ): """This is called when the Cancel button is clicked.""" self.terminar=True def windowClosed(self,oActionEvent): self.terminar=True rect=self.getWindowPosSize() self.wp["prowindow"]=str({'left':rect.X,'top':rect.Y,'width':rect.Width,'height':rect.Height}) self.wp.sync() selp.wp.close() def windowClosing(self,oActionEvent): pass #Métodos def Close(self): #Cerrar ventana self.windowClose() def Cancel(self): #Devuelve True si hay que terminar (proceso cancelado) return self.terminar def MinMax(self,min,max): #Asigna los valores mínimo y máximo de la barra de progreso #self.setProgressRange("prbPro",min,max) #self.setProgressValue("prbPro",min) self.Min=min self.Max=max def Value(self,valor): #Asigna un valor a la barra de progreso #self.setProgressValue("prbPro",valor) rect1=self.getControl("imgPro1").getPosSize() w2=(valor/(self.Max-self.Min))*rect1.Width if w2<0: w2=0 if w2>rect1.Width: w2=rect1.Width rect2=self.getControl("imgPro2").getPosSize() self.setSize("imgPro2",w2,rect2.Height) #self.setFixedTextText("txtPro",str(int(valor)) + " %") #self.windowToFront() # end of class ProWindow class MsgWindow(DBListenerWindow): def __init__(self,msg): DBListenerWindow.__init__( self, u"Missatge de Salt") self.addFixedText("txtMsg",5,10,300,16,msg) self.setFixedTextAlignment("txtMsg",1) self.addButton( "cmbCancel", 310, 10, 60, 16, u"Cancel·lar", actionListenerProc = self.cmbCancel_clicked ) wpos={'left':100,'top':200,'width':460,'height':40} self.setWindowPosSize( wpos['left'], wpos['top'], 460, 40 ) self.windowToFront() #Eventos def cmbCancel_clicked( self, oActionEvent ): """This is called when the Cancel button is clicked.""" self.windowClose() def windowClosed(self,oActionEvent): rect=self.getWindowPosSize() self.wp["msgwindow"]=str({'left':rect.X,'top':rect.Y,'width':rect.Width,'height':rect.Height}) self.wp.sync() selp.wp.close() pass # end of class MsgWindow class CtvMouse: def __init__(self): pass def RegisterMouseClickHandler(self): pass # end of class CtvMouse # pythonloader looks for a static g_ImplementationHelper variable g_ImplementationHelper = unohelper.ImplementationHelper() # g_ImplementationHelper.addImplementation( \ ooUNOobj, # UNO object class "org.openoffice.Office.addon.salt.trad.ooUNOobj", # implementation name # Change this name for your own # script ("com.sun.star.task.Job",),) # list of implemented services # (the only service)