Monitorar eventos de documentos

Além de atribuir macros a eventos, você pode monitorar eventos ativados por documentos do LibreOffice. Os broadcasters da Application Programming Interface (API) são responsáveis pelas chamadas a macros de eventos. Diferente dos listeners que requerem a definição de todos os métodos suportados, mesmo que não utilizados, a monitoração de documentos requer somente dois métodos além dos scripts de eventos conectados.

Ouvir eventos de documentos

A monitoração é ilustrada abaixo para as linguagens Basic e Python utilizando a programação orientada a objetos. Atribuir o script OnLoad ao evento Abrir documento, é o bastante para iniciar e terminar a monitoração de eventos do documento. A aba Eventos do menu Ferramentas - Personalizar é utilizada para especificar ambos os scripts.

Interceptar eventos ajuda a definir pré e pós-condições tais como carregar e descarregar bibliotecas ou rastrear processamento de scripts que rodam em modo silencioso. O módulo Access2Base.Trace ilustra o segundo contexto.

Com Python

A monitoração de eventos começa da instanciação do objeto e termina quando o Python libera o objeto. Eventos levantados são reportados utilizando a console do Access2Base.

note

Os eventos OnLoad e OnUnload podem ser utilizados, respectivamente, para configurar e desconfigurar caminhos de programas python. Eles são descritos como Abrir documento e Documento fechado.



         # -*- coding: utf-8 -*-
         from __future__ import unicode_literals
             
         import os.path, uno, unohelper
         from com.sun.star.document import DocumentEvent, \
             XDocumentEventListener as AdapterPattern
         from com.sun.star.lang import EventObject
             
         class UiDocument(unohelper.Base, AdapterPattern):
             """ Monitorar eventos de documento """
             '''
             adaptado de 'Python script to monitor OnSave event' de
             https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
             '''
             def __init__(self):
                 """ Monitorar eventos de documento """
                 ''' reportar utilizando a console Access2Base.Trace OU
                 reportar na 1ª planilha, 1ª coluna para documentos do Calc '''
                 ctx = uno.getComponentContext()
                 smgr = ctx.getServiceManager()
                 desktop = smgr.createInstanceWithContext(
                 'com.sun.star.frame.Desktop' , ctx)
                 self.doc = desktop.CurrentComponent
                 #self.row = 0  # descomente somente para documentos do Calc
                 Console.setLevel("DEBUG")
                 self.listen()  # Comece a monitorar eventos de documento
             
             @property
             def Filename(self) -> str:
                 sys_filename = uno.fileUrlToSystemPath(self.doc.URL)
                 return os.path.basename(sys_filename)
             
             def setCell(self, calcDoc, txt: str):
                 """ Saída dos eventos de doc na 1ª coluna de uma planilha Calc """
                 sheet = calcDoc.getSheets().getByIndex(0)
                 sheet.getCellByPosition(0,self.row).setString(txt)
                 self.row = self.row + 1
             
             def listen(self, *args):  # OnLoad/OnNew o mais cedo
                 """ Começar monitoração de eventos de documento """
                 self.doc.addDocumentEventListener(self)
                 Console.log("INFO", "Os eventos de documento estão sendo registrados", True)
             
             def sleep(self, *args):  # OnUnload por último (opcional)
                 """ Encerrar monitoração de eventos de documento """
                 self.doc.removeDocumentEventListener(self)
                 Console.log("INFO", "Os eventos de documento foram registrados", True)
             
             def documentEventOccured(self, event: DocumentEvent):
                 """ Interceptar todos os eventos de documento """
                 #self.setCell(event.Source, event.EventName) # somente para documentos do Calc
                 Console.log("DEBUG",
                     event.EventName+" in "+self.Filename,
                     False)
             
             def disposing(self, event: EventObject):
                 """ Liberar todas as atividades """
                 self.sleep()
                 Console.show()
             
         def OnLoad(*args):  # evento 'Abrir documento'
             listener = UiDocument()  # Initiates listening
             
         def OnUnload(*args):  # evento 'Documento foi fechado'
             pass  # (opcional) executado quando dispensado
             
         g_exportedScripts = (OnLoad,)
             
         from com.sun.star.script.provider import XScript
         class Console():
             """
             Console de foreground ou background para reportar ou registrar execução de programa.
             """
             @staticmethod
             def trace(*args,**kwargs):
                 """ Console de foreground ou background para reportar ou registrar execução de programa. """
                 scr = Console._a2bScript(script='DebugPrint', module='Compatible')
                 scr.invoke((args),(),())
             @staticmethod
             def log(level: str, text: str, msgBox=False):
                 """ Anexa a mensagem de registro na console, prompt de usuário opcional """
                 scr = Console._a2bScript(script='TraceLog')
                 scr.invoke((level,text,msgBox),(),())
             @staticmethod
             def setLevel(logLevel: str):
                 """ Define limite inferior para mensagens de registro """
                 scr = Console._a2bScript(script='TraceLevel')
                 scr.invoke((logLevel,),(),())
             @staticmethod
             def show():
                 """ Exibe o conteúdo ou diálogo da console """
                 scr = Console._a2bScript(script='TraceConsole')
                 scr.invoke((),(),())
             @staticmethod
             def _a2bScript(script: str, library='Access2Base',
                 module='Trace') -> XScript:
                 ''' Grab application-based Basic script '''
                 sm = uno.getComponentContext().ServiceManager
                 mspf = sm.createInstanceWithContext(
                     "com.sun.star.script.provider.MasterScriptProviderFactory",
                     uno.getComponentContext())
                 scriptPro = mspf.createScriptProvider("")
                 scriptName = "vnd.sun.star.script:"+library+"."+module+"."+script+"?language=Basic&location=application"
                 xScript = scriptPro.getScript(scriptName)
                 return xScript
      
warning

Note o erro no nome do método documentEventOccured que herda um erro da LibreOffice Application Programming Interface (API).


Ícone Dica

Os eventos Inciar aplicação e Fechar aplicação podem ser respectivamente utilizados para configurar e desconfigurar caminhos Python para scripts de usuários ou scripts de LibreOffice. De forma similar, bibliotecas ou módulos Python baseados em documentos podem ser carregados e descarregados utilizando os eventos Abrir documento e Documento fechado. Consulte Importar módulos Python para mais informações.


Com LibreOffice Basic

O script Onload é atribuído ao evento Abrir documento utilizando a aba Eventos do menu Ferramentas - Personalizar. A monitoração de eventos inicia no momento em que um objeto ConsoleLogger é instanciado e encerra apenas quando o motor do Basic o libera. O evento OnLoad carrega as bibliotecas do Basic necessárias, enquanto eventos capturados são reportados utilizando o módulo Access2Base.Trace.


          REM Módulo controller.Events
          Option Explicit
          Private _obj As Object ' instância do controller.ConsoleLogger
              
          Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Abrir documento <<
              _obj = New ConsoleLogger : _obj.Start(evt)
          End Sub ' controller.OnLoad
          ' ----
          REM Módulo de classe controller.ConsoleLogger
          Option Explicit
          Option Compatible
          Option ClassModule
              
          ' objeto de padrão de design ADAPTER a ser instanciado no evento "Abrir documento"
          Private Const UI_PROMPT = True
          Private Const UI_NOPROMPT = False ' Set it to True to visualise documents events
              
          ' CONSTRUTOR/DESTRUTOR
          Private Sub Class_Initialize()
          End Sub ' controller.ConsoleLogger.Initialize
          Private Sub Class_Terminate()
          End Sub ' controller.ConsoleLogger.Terminate
              
          ' MEMBROS
          Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
              
          ' PROPERTIES
          Private Property Get FileName As String
              ''' nome de arquivo dependente do Sistema '''
              Const _LIBRARY = "Tools" : With GlobalScope.BasicLibraries
                  If Not .IsLibraryLoaded(_LIBRARY) Then .LoadLibrary(_LIBRARY)
              End With
              Filename = Tools.Strings.FilenameOutofPath(ThisComponent.URL)
          End Property ' controller.ConsoleLogger.Filename
              
          ' MÉTODOS
          Private Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
              ''' Monitorar eventos de documento '''
              Access2Base.Trace.TraceLog("DEBUG", _
                  evt.EventName &" in "& Filename(evt.Source.URL), _
                  UI_NOPROMPT)
              Select Case evt.EventName
                  Case "OnUnload" : _Stop(evt)
              End Select
          End Sub ' controller.ConsoleLogger._documentEventOccured
              
          Private Sub _disposing(evt As com.sun.star.lang.EventObject)
          End Sub ' controller.ConsoleLogger.disposing
              
          Public Sub Start(Optional evt As com.sun.star.document.DocumentEvent)
              ''' Inicializar registros de eventos de documento '''
              Const _LIBRARY = "Access2Base" : With GlobalScope.BasicLibraries
                  If Not .IsLibraryLoaded(_LIBRARY) Then .LoadLibrary(_LIBRARY)
              End With : Access2Base.Trace.TraceLevel("DEBUG")
              Access2Base.Trace.TraceLog("INFO", _
                  IIf(IsMissing(evt),"",evt.EventName & "-") & "Eventos de documento estão sendo registrados", _
                  UI_PROMPT)
              
              _evtAdapter = CreateUnoListener( "_", "com.sun.star.document.XDocumentEventListener" )
              ThisComponent.addDocumentEventListener( _evtAdapter )
          End Sub ' controller.ConsoleLogger.Start
              
          Private Sub _Stop(Optional evt As com.sun.star.document.DocumentEvent)
              ''' Encerrar registro de eventos de documento '''
              ThisComponent.removeDocumentEventListener( _evtAdapter )
              Access2Base.Trace.TraceLog("INFO", _
                  IIf(IsMissing(evt),"",evt.EventName & "-") & "Eventos de documento foram registrados", _
                  UI_PROMPT)
              Access2Base.Trace.TraceConsole() ' Captured events dialog
          End Sub ' controller.ConsoleLogger._Stop
              
          ' EVENTS
          ' Seu código para tratar eventos segue aqui
      
warning

Note o erro no nome do método documentEventOccured que herda um erro da LibreOffice Application Programming Interface (API).


Descobrir eventos de documento

O objeto API broadcaster fornece a lista de eventos dos quais é responsável:

Com Python


         # -*- coding: utf-8 -*-
         from __future__ import unicode_literals
             
         import uno, apso_utils as ui
             
         def displayAvailableEvents():
             """ Exibe eventos de documento """
             '''
             adaptado de DisplayAvailableEvents() por A. Pitonyak
             https://forum.openoffice.org/en/forum/viewtopic.php?&t=43689
             '''
             ctx = XSCRIPTCONTEXT.getComponentContext()
             smgr = ctx.ServiceManager
             geb = smgr.createInstanceWithContext(
                 "com.sun.star.frame.GlobalEventBroadcaster", ctx)
             events = geb.Events.getElementNames()
             ui.msgbox('; '.join(events))
             
         g_exportedScripts = (displayAvailableEvents,)
      
note

A extensão Alternative Python Script Organizer (APSO) é utilizada para mostrar informações de eventos na tela.


Com LibreOffice Basic


         Sub DisplayAvailableEvents
             ''' Exibe eventos de documento '''
             Dim geb As Object ' com.sun.star.frame.GlobalEventBroadcaster
             Dim events() As String
             geb = CreateUnoService("com.sun.star.frame.GlobalEventBroadcaster")
             events = geb.Events.ElementNames()
             MsgBox Join(events, "; ")
         End Sub
      

♥ Doe para nosso projeto! ♥