Indhold

# Lytning til dokumenthændelser

Lytning til dokumenthændelser kan hjælpe i følgende situationer:

- Identifikation af et nyt dokument på åbningstidspunktet, i modsætning til de eksisterende, og udførelse af en dedikeret opsætning.

- Kontrol af behandlingen af forespørgsler om lagring, kopiering og udskrivning af kopier, eller forespørgsler om brevfletning.

- Opdatering af indholdsfortegnelser, indekser eller tabelindførsler i et Writer-dokument, når dokumentet skal lukkes

- Import af matematiske Python-pakker, før du åbner et Calc-dokument. Frigør disse pakker, når dokumentet lukkes.

Udover at knytte makroer til hændelser kan man overvåge hændelser iværksat af LibreOffice-dokumenter. Applikations programmeringsgrænseflade (API) -sendere står for at kalde hændelses-scripts. I modsætning til listerners, som skal definere alle understøttede metoder, også ubrugte, behøver dokumentmonitorer samt krogede hændelses-scripts kun to metoder.

## Overvågning af dokumenthændelser

Overvågning vises hermed for sprogene Basic og Python med objekt-orienteret programmering. Tildeling af scriptet OnLoad til hændelsen Open Document er tilstrækkelig til initiere og terminere dokumentovervågning. Menuen Funktioner ▸ Tilpas, fanebladet Hændelser bruges til at tildele begge scripts.

Aflytning af hændelser hjælper med at sætte før- og efter-betingelser, såsom ind- og ud-læsning af biblioteker eller sporing af script-behandling i baggrunden. Brug af modulet Access2Base.Trace illustrerer denne sidste kontekst.

### Med Python

Overvågning af hændelser begynder med objektinstantiering og slutter i sidste ende, når Python frigiver objektet. Iværksatte hændelser rapporteres med Access2Base konsolen.

Hændelserne OnLoad og OnUnload kan bruges til respektivt at sætte og ophæve stien til Python-programmer. De beskrives som Åbn dokument og Dokument lukket.

             # -*- 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):
                 """ Overvåg dokumenthændelser """
                 '''
                 omformet fra 'Python-script til at overvåge OnSave-hændelse' på
                 https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
                 '''
                 def __init__(self):
                     """ Dokumenthændelses monitor """
                     ''' rapporter med Access2Base.Trace-konsolen ELLER
                     rapport på Ark 1, første kolonne for Calc-dokumenter '''
                     ctx = uno.getComponentContext()
                     smgr = ctx.getServiceManager()
                     desktop = smgr.createInstanceWithContext(
                     'com.sun.star.frame.Desktop' , ctx)
                     self.doc = desktop.CurrentComponent
                     #self.row = 0  # udkommenter alene for Calc-dokumenter
                     Console.setLevel("DEBUG")
                     self.listen()  # Start overvågning af doc. events

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

                 def setCell(self, calcDoc, txt: str):
                     """ Vis dokumenthændelser i første kolonne af et Calc-regneark """
                     sheet = calcDoc.getSheets().getByIndex(0)
                     sheet.getCellByPosition(0,self.row).setString(txt)
                     self.row = self.row + 1

                 def listen(self, *args):  # OnLoad/OnNew som det tidligste
                     """ Start overvågning af dokumenthændelser """
                     self.doc.addDocumentEventListener(self)
                     Console.log("INFO", "Dokumenthændelser bliver logget", True)

                 def sleep(self, *args):  # OnUnload som det seneste (valgfri)
                     """ Stop overvågning af dokumenthændelser """
                     self.doc.removeDocumentEventListener(self)
                     Console.log("INFO", "Dokumenthændelser er blevet logget", True)

                 def documentEventOccured(self, event: DocumentEvent):
                     """ Overvåger alle dokumenthændelser """
                     #self.setCell(event.Source, event.EventName) # kun for Calc-dokumenter
                     Console.log("DEBUG",
                         event.EventName+" in "+self.Filename,
                         False)

                 def disposing(self, event: EventObject):
                     """ Frigiver alle aktiviteter """
                     self.sleep()
                     Console.show()

             def OnLoad(*args):  # 'Åbn dokument'-hændelse
                 listener = UiDocument()  # Initierer lytning

             def OnUnload(*args):  # 'Dokument er blevet lukket'-hændelse
                 pass  # (valgfri) udført ved afslutning

             g_exportedScripts = (OnLoad,)

             from com.sun.star.script.provider import XScript
             class Console():
                 """
                 (Bag-/For-)grundskonsol til rapportering/logning af program.
                 """
                 @staticmethod
                 def trace(*args,**kwargs):
                     """ Skriv liste over fire elementer til konsolen """
                     scr = Console._a2bScript(script='DebugPrint', module='Compatible')
                     scr.invoke((args),(),())
                 @staticmethod
                 def log(level: str, text: str, msgBox=False):
                     """ Tilføj logningsbesked til konsolen, valgfrit bruger-prompt """
                     scr = Console._a2bScript(script='TraceLog')
                     scr.invoke((level,text,msgBox),(),())
                 @staticmethod
                 def setLevel(logLevel: str):
                     """ Sæt nedre grænse for logningbeskeder lower limit """
                     scr = Console._a2bScript(script='TraceLevel')
                     scr.invoke((logLevel,),(),())
                 @staticmethod
                 def show():
                     """ Vis konsolindhold/-dialog """
                     scr = Console._a2bScript(script='TraceConsole')
                     scr.invoke((),(),())
                 @staticmethod
                 def _a2bScript(script: str, library='Access2Base',
                     module='Trace') -> XScript:
                     ''' Grib fat i applikationsbaseret 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

Pas på den fejlstavede documentEventOccured-metode, som arver en trykfejl fra LibreOffice API (Applikations programmerings brugerflade)

Hændelserne Start applikation og Luk applikation kan bruges til henholdsvis at sætte og ophæve Python-stien til bruger-scripts eller LibreOffice scripts. På samme måde kan dokument-baserede Python-biblioteker eller -moduler indlæses og frigives med hændelserne Åbn dokument og Dokument lukket. Se flere oplysninger på Import af Python-moduler.

### Med LibreOffice Basic

Med menuen Funktioner ▸ Tilpas, fanebladet Hændelser udløser hændelsen Åbn dokument en ConsoleLogger-initialisering. Rutinen _documentEventOccured – sat af ConsoleLogger – fungerer som et entydigt indgangspunkt til at fange alle dokumenthændelser.

#### controller.Events module

            Option Explicit

            Global _obj As Object ' eksemplar af controller.ConsoleLogger

            Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Åbn dokument <<
                _obj = New ConsoleLogger : _obj.StartAdapter(evt)
            End Sub ' controller.OnLoad
            Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
                ''' ConsoleLogger unikt indgangspunkt '''
                 _obj.DocumentEventOccurs(evt)
            End Sub ' controller._documentEventOccured

#### controller.ConsoleLogger-klassemodul

Hændelsesovervågning begynder i det øjeblik et ConsoleLogger-objekt instantieres og stopper ultimativt, når dokumentet lukkes. Rutinen StartAdapter indlæser nødvendige Basic-biblioteker, mens opfangede hændelser rapporteres med modulet Access2Base.Trace.

              Option Explicit
              Option Compatible
              Option ClassModule

              ' Design-mønster-objektet ADAPTER skal instantieres i hændelsen "Åbn dokument"
              Private Const UI_PROMPT = True
              Private Const UI_NOPROMPT = False ' Sættes til True for at visualisere dokumenthændelser

              ' MEMBERS
              Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
              Private _txtMsg As String ' tekstbesked at logge i konsollen

              ' EGENSKABER
              Private Property Get FileName As String
                  ''' System-afhængigt filnavn '''
                  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

              ' METODER
              Public Sub DocumentEventOccurs(evt As com.sun.star.document.DocumentEvent)
                  ''' Overvåg dokumenthændelser '''
                  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)
                  ''' Initialisér logning af dokumenthændelser '''
                  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 & "Dokumenthændelser logges", 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)
                  ''' Afslut logning af dokumenthændelser '''
                  ThisComponent.removeDocumentEventListener( _evtAdapter )
                  If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
                  Access2Base.Trace.TraceLog("INFO", _txtMsg & "Dokumenthændelserer logget", UI_PROMPT)
                  Access2Base.Trace.TraceConsole() ' Dialogen opfangede hændelser
              End Sub ' controller.ConsoleLogger._StopAdapter

              ' HÆNDELSER
              ' Din kode til håndterede hændelser skrives her

På på den fejlstavede _documentEventOccured-metode, som arver en trykfejl fra LibreOffice API (Applikations programerings-brugerflade).

## Opdagelse af dokumenthændelser

Senderen API-objekt omfatter listen over de hændelser den er ansvarlig for:

### Med Python

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

             import uno, apso_utils as ui

             def displayAvailableEvents():
                 """ Vis dokumenthændelser """
                 '''
                 tilpasset efter DisplayAvailableEvents() af 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,)

Udvidelsen Alternative Python Script Organizer (APSO = Alternativ Python-Script Organisator) bruges til at levere hændelsesinformation på skærmen.

### Med LibreOffice Basic

             Sub DisplayAvailableEvents
                 ''' Vis dokumenthændelser '''
                 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

Relaterede emner

Oprettelse af Hændelses-Aflyttere

Import af Pythonmoduler

Oprette en dialoghåndtering

Python programmeringseksempler

Programmering med Python-scripts

Kald Basic-makroer fra Python

Støt os venligst!