Acompanhar eventos de documento

Acompanhar eventos de documento pode ser útil nas seguintes situações:

Além de atribuir macros a eventos, você pode monitorar eventos ativados por documentos do Collabora Office. 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.

Monitorar eventos de documento

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 definir ou desfazer a definição de 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()  # Inicialização do listener

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:
        ''' Obtém o script Basic baseado na aplicação '''
        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 Collabora Office Application Programming Interface (API).


Ícone Dica

Os eventos Inciar aplicação e Fechar aplicação podem ser respectivamente utilizados para definir e cancelar a definição de caminhos Python para scripts de usuários ou scripts do Collabora Office. 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 Collabora Office Basic

Usando o menu Ferramentas - Personalizar na aba Eventos o evento Ao abrir documento dispara a inicialização do ConsoleLogger. A rotina _documentEventOccured - definida por ConsoleLogger - atua como o único ponto de entrada para capturar todos os eventos de documento.

Módulo controller.Events

Option Explicit

Global _obj As Object ' Instância de controller.ConsoleLogger

Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Abrir documento <<
    _obj = New ConsoleLogger : _obj.StartAdapter(evt)
End Sub ' controller.OnLoad
Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
    ''' Ponto de entrada único do ConsoleLogger '''
     _obj.DocumentEventOccurs(evt)
End Sub ' controller._documentEventOccured

Módulo de classe controller.ConsoleLogger

O monitoramento de eventos se inicia no momento que um objeto ConsoleLogger é instanciado e a finalização do monitoramento ocorre quando o documento é fechado. A rotina StartAdapter carrega as bibliotecas Basic necessárias e os eventos capturados são reportados usando o módulo Access2Base.Trace.

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 ' Defina como True para visualizar os eventos de documento

' MEMBROS
Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
Private _txtMsg As String ' Mensagem de texto a registrar no console

' PROPRIEDADES
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
Public Sub DocumentEventOccurs(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" : _StopAdapter(evt)
    End Select
End Sub ' controller.ConsoleLogger.DocumentEventOccurs

Public Sub StartAdapter(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")
    If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
    Access2Base.Trace.TraceLog("INFO", _txtMsg & "Eventos de documento estão sendo registrados", UI_PROMPT)
    _evtAdapter = CreateUnoListener( "_", "com.sun.star.document.XDocumentEventListener" )
    ThisComponent.addDocumentEventListener( _evtAdapter )
End Sub ' controller.ConsoleLogger.StartAdapter

Private Sub _StopAdapter(Optional evt As com.sun.star.document.DocumentEvent)
    ''' Encerrar registro de eventos de documento '''
    ThisComponent.removeDocumentEventListener( _evtAdapter )
    If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
    Access2Base.Trace.TraceLog("INFO", _txtMsg & "Eventos de documento foram registrados", UI_PROMPT)
    Access2Base.Trace.TraceConsole() ' Diálogo com os eventos capturados
End Sub ' controller.ConsoleLogger._StopAdapter

' EVENTOS
' Seu código para tratar eventos segue aqui
warning

Note o erro no nome do método documentEventOccured que herda um erro da Collabora Office 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 Collabora Office 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! ♥