Documentgebeurtenissen

Naast hetkoppelen van macro's aan gebeurtenissen, kan men gebeurtenissen volgen die optreden in LibreOffice 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.

Luisteren naar document-gebeurtenissen

Monitoring wordt hier uitgelegd voor de de programmeertalen Basic en Python met gebruik van object-georiënteerd programmeren. Het toekennen van het OnLoad-script aan de Open Document-gebeurtenis, zorgt voor het beginnen en beëindigen van de documentgebeurtenis monitoring. Extra - Aanpassen menu Gebeurtenissen-tab 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()  # Initiates listening
             
         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:
                 ''' 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

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


Tippictogram

De gebeurtenissen Start application en Close application kunnen respectievelijk worden gebruikt voor het zetten en vrijgeven van het Python-pad voor gebruikerscripts of voor LibreOffice-scripts. Op een vergelijkbare manier kunnen documentgebaseerde Python-bibliotheken en modules worden geladen en vrijgegeven met de gebeurtenissen Open document en Document closed. Bekijk Python-modules importeren voor meer informatie.


Met LibreOffice BASIC.

Het script Onload is gekoppeld aan de gebeurtenis Document openen met Extra - Aanpassen tab Events. Het monitoren van gebeurtenissen begint op het moment dat een object ConsoleLogger is aangemaakt en stopt wanneer het object wordt vrijgegeven door de Basic-engine. De gebeurtenis OnLoad laadt indien nodig de benodigde Basic-bibliotheken, optredende gebeurtenissen worden gemeld via de module Access2Base.Trace.


          REM module controller.Events
          Option Explicit
          Private _obj As Object ' controller.ConsoleLogger instance
              
          Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Open Document <<
              _obj = New ConsoleLogger : _obj.Start(evt)
          End Sub ' controller.OnLoad
          ' ----
          REM klasse module controller.ConsoleLogger
          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 ' Set it to True to visualise documents events
              
          ' CONSTRUCTOR/DESTRUCTOR
          Private Sub Class_Initialize()
          End Sub ' controller.ConsoleLogger.Initialize
          Private Sub Class_Terminate()
          End Sub ' controller.ConsoleLogger.Terminate
              
          ' MEMBERS
          Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
              
          ' 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
          Private Sub _documentEventOccured(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" : _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)
              ''' Initialiseren logging documentgebeurtenissen '''
              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 & "-") & "Documentgebeurtenissen worden gelogd", _
                  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)
              ''' Beëindig de logging van documentgebeurtenissen '''
              ThisComponent.removeDocumentEventListener( _evtAdapter )
              Access2Base.Trace.TraceLog("INFO", _
                  IIf(IsMissing(evt),"",evt.EventName & "-") & "Documentgebeurtenissen zijn gelogd", _
                  UI_PROMPT)
              Access2Base.Trace.TraceConsole() ' Captured events dialog
          End Sub ' controller.ConsoleLogger._Stop
              
          ' 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 LibreOffice 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 LibreOffice 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