Documentgebeurtenissen monitoren

Het monitoren van documentgebeurtenissen kan nuttig zijn in de volgende situaties:

Naast het koppelen van macro's aan gebeurtenissen, kan men gebeurtenissen volgen die optreden in Collabora Office documenten. Application Programming Interface (API) broadcasters verzorgen het aanroepen van de scripts bij gebeurtenissen. Anders dan listeners waarbij alle ondersteunde methoden moeten zijn gedefinieerd, ook al worden ze niet gebruikt, zijn er hier maar twee methoden verplicht naast de hooked scripts voor gebeurtenissen.

Documentgebeurtenissen monitoren

Monitoring wordt hier uitgelegd voor de de programmeertalen Basic en Python met gebruik van objectgeoriënteerd programmeren. Het toekennen van het script OnLoad aan de gebeurtenis Open Document, zorgt voor het beginnen en beëindigen van de documentgebeurtenis monitoring. Menu Extra - Aanpassen tab Gebeurtenissen wordt gebruikt voor het toekennen van scripts.

Het onderscheppen van gebeurtenissen dient om vooraf en achteraf voorwaarden te kunnen zetten in het script voor het loaden en unloaden van bibliotheken en het volgen in de achtergrond van de verwerking van het script. Het gebruik van de module Access2Base.Trace is een voorbeeld van het volgen van de verwerking.

Met Python

Het monitoren van gebeurtenissen begint bij het instantiëren (aanmaken) van het object en stopt bij het door Python vrijgeven van het object. De voorkomende gebeurtenissen worden gemeld op het Access2Base console.

note

De gebeurtenissen OnLoad en OnUnload kunnen worden gebruikt om het pad van Python respectievelijk te bepalen en te wissen. Zij worden beschreven als Open document en Document closed.


# -*- 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):
    """ Documentgebeurtenissen monitoren """
    '''
    aangepast van 'Python-script om OnSave-gebeurtenis te controleren' op
    https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
    '''
    def __init__(self):
        """ Documentgebeurtenissen controleren """
        ''' uitvoer op het Access2Base.Trace console OF
        rapport in 1e blad, 1e kolom voor Calc-documenten '' '
        ctx = uno.getComponentContext()
        smgr = ctx.getServiceManager()
        desktop = smgr.createInstanceWithContext(
        'com.sun.star.frame.Desktop' , ctx)
        self.doc = desktop.CurrentComponent
        #self.row = 0  # uncomment alleen voor Calc-documenten
        Console.setLevel("DEBUG")
        self.listen()  # Start documentgebeurtenissen monitoren

    @property
    def Filename(self) -> str:
        sys_filename = uno.fileUrlToSystemPath(self.doc.URL)
        return os.path.basename(sys_filename)

    def setCell(self, calcDoc, txt: str):
        """ Uitvoer documentgebeurtenissen in 1e kolom van een Calc-document"""
        sheet = calcDoc.getSheets().getByIndex(0)
        sheet.getCellByPosition(0,self.row).setString(txt)
        self.row = self.row + 1

    def listen(self, *args):  # vanaf OnLoad/OnNew
        """ Start monitoren documentgebeurtenissen """
        self.doc.addDocumentEventListener(self)
        Console.log("INFO", "Documentgebeurtenissen worden gelogd", True)

    def sleep(self, *args):  # op zijn laatst bij OnUnload (optioneel)
        """ Stop monitoren documentgebeurtenissen """
        self.doc.removeDocumentEventListener(self)
        Console.log("INFO", "Documentgebeurtenissen zijn gelogd", True)

    def documentEventOccured(self, event: DocumentEvent):
        """ Onderschept alle documentgebeurtenissen """
        #self.setCell(event.Source, event.EventName) # alleen voor Calc-documenten
        Console.log("DEBUG",
            event.EventName+" in "+self.Filename,
            False)

    def disposing(self, event: EventObject):
        """ Alle activiteiten vrijgeven """
        self.sleep()
        Console.show()

def OnLoad(*args):  # 'Open Document'-gebeurtenis
    listener = UiDocument()  # Start het afvangen

def OnUnload(*args):  # De gebeurtenis 'Document gesloten'
    pass  # (optioneel) uitgevoerd bij verwijdering

g_exportedScripts = (OnLoad,)

from com.sun.star.script.provider import XScript
class Console():
    """
    (Achter/Voor)grond console om de programma uitvoering te rapporteren/loggen.
    """
    @staticmethod
    def trace(*args,**kwargs):
        """ Print vrije item-lijst op console """
        scr = Console._a2bScript(script='DebugPrint', module='Compatible')
        scr.invoke((args),(),())
    @staticmethod
    def log(level: str, text: str, msgBox=False):
        """ Zet logbericht op console, optioneel prompt """
        scr = Console._a2bScript(script='TraceLog')
        scr.invoke((level,text,msgBox),(),())
    @staticmethod
    def setLevel(logLevel: str):
        """ Bepaal ondergrens logberichten """
        scr = Console._a2bScript(script='TraceLevel')
        scr.invoke((logLevel,),(),())
    @staticmethod
    def show():
        """ Toon console inhoud/dialoog """
        scr = Console._a2bScript(script='TraceConsole')
        scr.invoke((),(),())
    @staticmethod
    def _a2bScript(script: str, library='Access2Base',
        module='Trace') -> XScript:
        ''' Haal applicatie-gebaseerd Basic-script op'''
        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

Denk aan de verkeerd geschreven methode documentEventOccured die een tikfout overerft van Collabora Office Application Programming Interface (API).


Tippictogram

De gebeurtenissen Programma starten en Programma sluiten kunnen respectievelijk worden gebruikt voor het zetten en vrijgeven van het Python-pad voor gebruikersscripts of voor Collabora Office-scripts. Op een vergelijkbare manier kunnen documentgebaseerde Python-bibliotheken en modules worden geladen en vrijgegeven met de gebeurtenissen Document openen en Document gesloten. Bekijk Python-modules importeren voor meer informatie.


Met Collabora Office BASIC.

Via het menu Extra - Aanpassen tabblad Gebeurtenissen, de gebeurtenis Document openen zorgt voor de initialisatie van ConsoleLogger. De routine documentEventOccured - gezet door de ConsoleLogger - dient als een uniek toegangspunt om alle document-gebeurtenissen af te vangen.

controller.Events module

Option Explicit

Global _obj As Object ' controller.ConsoleLogger instance

Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Document openen <<
    _obj = New ConsoleLogger : _obj.StartAdapter(evt)
End Sub ' controller.OnLoad
Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
    ''' ConsoleLogger uniek toegangspunt '''
     _obj.DocumentEventOccurs(evt)
End Sub ' controller._documentEventOccured

module van klasse controller.ConsoleLogger

Het monitoren van gebeurtenissen begint op het moment dat een ConsoleLogger object is aangemaakt en stopt uiterlijk als het document wordt gesloten. De routine StartAdapter laad de benodigde Basic-bibliotheken, afgevangen gebeurtenissen worden gerapporteerd via de module Access2Base.Trace.

Option Explicit
Option Compatible
Option ClassModule

' ADAPTER design pattern object aanmaken wordt gedaan door de gebeurtenis "Document openen"
Private Const UI_PROMPT = True
Private Const UI_NOPROMPT = False ' Om documentgebeurtenissen te visualiseren, zet dit op True

' MEMBERS
Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
Private _txtMsg As String ' tekstbericht om in console te loggen

' PROPERTIES
Private Property Get FileName As String
    ''' Systeem afhankelijke bestandsnaam '''
    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

' METHODS
Public Sub DocumentEventOccurs(evt As com.sun.star.document.DocumentEvent)
    ''' Documentgebeurtenissen monitoren '''
    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)
    ''' Initialiseren logging documentgebeurtenissen '''
    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 & "Documentgebeurtenissen worden gelogd", 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)
    ''' Beëindig de logging van documentgebeurtenissen '''
    ThisComponent.removeDocumentEventListener( _evtAdapter )
    If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
    Access2Base.Trace.TraceLog("INFO", _txtMsg & "Documentgebeurtenissen zijn gelogd", UI_PROMPT)
    Access2Base.Trace.TraceConsole() ' Afgevangen gebeurtenissendialoog
End Sub ' controller.ConsoleLogger._StopAdapter

' EVENTS
' Hier komt uw eigen code voor de afgevangen gebeurtenissen
warning

Denk aan de spelfout in de methode _documentEventOccured die een tikfout erft van de Collabora Office Application Programming Interface (API).


Documentgebeurtenissen vinden

Het object broadcaster API geeft een lijst gebeurtenissen waar het verantwoordelijk voor is:

Met Python

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import uno, apso_utils as ui

def displayAvailableEvents():
    """ Documentgebeurtenissen tonen """
    '''
    bewerkte versie van DisplayAvailableEvents() gemaakt door 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

De extensie Alternative Python Script Organizer (APSO) wordt gebruikt om informatie over gebeurtenissen op het scherm te tonen.


Met Collabora Office BASIC.

Sub DisplayAvailableEvents
    ''' Documentgebeurtenissen tonen '''
    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

Help ons, alstublieft!