Listening to Document Events

Nałuchiwanie zdarzeń w dokumencie może pomóc w następujących sytuacjach:

Next to assigning macros to events, one can monitor events raised by LibreOffice documents. Application Programming Interface (API) broadcasters are responsible for calling event scripts. Unlike listeners that require to define all supported methods, even if unused, document monitors require only two methods next to hooked event scripts.

Monitorowanie zdarzeń w dokumencie

Monitorowanie jest tutaj zilustrowane dla języków Basic i Python przy użyciu programowania obiektowego. Przypisanie skryptu OnLoad do zdarzenia Otwórz dokument wystarczy do zainicjowania i zakończenia monitorowania zdarzeń dokumentu. Menu Narzędzia - Dostosuj karta Zdarzenia służy do przypisania obu skryptów.

Przechwytywanie zdarzeń pomaga w ustawianiu warunków wstępnych i końcowych skryptów, takich jak ładowanie i wyładowywanie bibliotek lub śledzenie przetwarzania skryptu w tle. Wykorzystanie modułu Access2Base.Trace ilustruje ten drugi kontekst.

Za pomocą języka Python

Monitorowanie zdarzeń rozpoczyna się od utworzenia instancji obiektu i ostatecznie kończy się, gdy Python zwolni obiekt. Wywołane zdarzenia są zgłaszane za pomocą konsoli Access2Base.

note

Zdarzenia OnLoad i OnUnload mogą być używane do odpowiednio ustawiania i usuwania ścieżki programów Pythona. Są one opisane jako Otwórz dokument i Dokument zamknięty.



         # -*- 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):
             """ Monitoruj zdarzenia dokumentu """
             '''
             zaadaptowane z „Skryptu Pythona do monitorowania zdarzenia OnSave” pod adresem
             https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
             '''
             def __init__(self):
                 """ Monitor zdarzeń dokumentu """
                 ''' raport za pomocą konsoli Access2Base.Trace LUB
                 raport w 1. arkuszu, 1. kolumnie dla dokumentów Calc '''
                 ctx = uno.getComponentContext()
                 smgr = ctx.getServiceManager()
                 desktop = smgr.createInstanceWithContext(
                 'com.sun.star.frame.Desktop' , ctx)
                 self.doc = desktop.CurrentComponent
                 #self.row = 0  odkomentowanie tylko dla dokumentów programu Calc
                 Console.setLevel("DEBUG")
                 self.listen()  # Rozpocznij monitorowanie zdzarzenia dokumentu
             
             @property
             def Filename(self) -> str:
                 sys_filename = uno.fileUrlToSystemPath(self.doc.URL)
                 return os.path.basename(sys_filename)
             
             def setCell(self, calcDoc, txt: str):
                 """ Wypisz zdarzenia dokumentu w pierwszej kolumnie arkusza kalkulacyjnego Calc """
                 sheet = calcDoc.getSheets().getByIndex(0)
                 sheet.getCellByPosition(0,self.row).setString(txt)
                 self.row = self.row + 1
             
             def listen(self, *args):  # OnLoad/OnNew najwcześniej
                 """ Rozpocznij monitorowanie zdarzeń dokumentu """
                 self.doc.addDocumentEventListener(self)
                 Console.log("INFO", "Zdarzenia dotyczące dokumentów są rejestrowane", True)
             
             def sleep(self, *args):  # OnUnload najpóźniej (opcjonalnie)
                 """ Zatrzymaj monitorowanie zdarzeń dokumentu """
                 self.doc.removeDocumentEventListener(self)
                 Console.log("INFO", "Zdarzenia dotyczące dokumentów zostały zarejestrowane", True)
             
             def documentEventOccured(self, event: DocumentEvent):
                 """ Przechwytuje wszystkie zdarzenia dokumentu """
                 #self.setCell(event.Source, event.EventName) # tylko dla dokumentów Calc
                 Console.log("DEBUG",
                     event.EventName+" in "+self.Filename,
                     False)
             
             def disposing(self, event: EventObject):
                 """ Zwolnij wszystkie działania """
                 self.sleep()
                 Console.show()
             
         def OnLoad(*args):  # Zdarzenie 'Otwórz dokument'
             listener = UiDocument()  # Inicjuje nasłuchiwanie
             
         def OnUnload(*args):  # Zdarzenie 'Dokument został zamknięty'
             pass  # (opcjonalnie) wykonywane w przypadku utylizacji
             
         g_exportedScripts = (OnLoad,)
             
         from com.sun.star.script.provider import XScript
         class Console():
             """
             Konsola tła lub pierwszego planu do nagrywania wykonywania programu.
             """
             @staticmethod
             def trace(*args,**kwargs):
                 """ Wypisz w konsoli wolną listę elementów """
                 scr = Console._a2bScript(script='DebugPrint', module='Compatible')
                 scr.invoke((args),(),())
             @staticmethod
             def log(level: str, text: str, msgBox=False):
                 """ Dołącz komunikat dziennika do konsoli, opcjonalny monit użytkownika """
                 scr = Console._a2bScript(script='TraceLog')
                 scr.invoke((level,text,msgBox),(),())
             @staticmethod
             def setLevel(logLevel: str):
                 """ Ustaw dolny limit komunikatów dziennika """
                 scr = Console._a2bScript(script='TraceLevel')
                 scr.invoke((logLevel,),(),())
             @staticmethod
             def show():
                 """ Wyświetl zawartość/okno konsoli """
                 scr = Console._a2bScript(script='TraceConsole')
                 scr.invoke((),(),())
             @staticmethod
             def _a2bScript(script: str, library='Access2Base',
                 module='Trace') -> XScript:
                 ''' Chwyć oparty na aplikacji skrypt Basic '''
                 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

Zwróć uwagę na błędnie napisaną metodę documentEventOccured, która dziedziczy literówkę z API (Application Programming Interface) LibreOffice.


Ikona wskazówki

Start application and Close application events can respectively be used to set and to unset Python path for user scripts or LibreOffice scripts. In a similar fashion, document based Python libraries or modules can be loaded and released using Open document and Document closed events. Refer to Importing Python Modules for more information.


Za pomocą języka LibreOffice Basic

Po ustawieniu na karcie Zdarzenia z menu Narzędzia - Dostosuj zdarzenie Otwórz dokument wyzwala inicjalizację instancji dla ConsoleLogger. Podprocedura _documentEventOccured, która ustawia ConsoleLogger, służy jako pojedynczy punkt wejścia do przechwytywania wszystkich zdarzeń w dokumencie.

Moduł controller.Events


        Option Explicit
        
        Instancja Global _obj As Object ' controller.ConsoleLogger
        
        Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Otwórz dokument <<
            _obj = New ConsoleLogger : _obj.StartAdapter(evt)
        End Sub ' controller.OnLoad
        Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
            ''' Unikalny punkt wejścia ConsoleLogger'''
             _obj.DocumentEventOccurs(evt)
        End Sub ' controller._documentEventOccured
      

Moduł klasy controller.ConsoleLogger

Monitorowanie zdarzeń rozpoczyna się od momentu utworzenia instancji obiektu ConsoleLogger i ostatecznie zatrzymuje się po zamknięciu dokumentu. Procedura StartAdapter wymaga ładowania bibliotek Basic, natomiast przechwycone zdarzenia są raportowane za pomocą modułu Access2Base.Trace.


          Option Explicit
          Option Compatible
          Option ClassModule
              
          ' Obiekt wzorca projektowego ADAPTER, który ma zostać utworzony w zdarzeniu "Otwórz dokument".
          Private Const UI_PROMPT = True
          Private Const UI_NOPROMPT = False ' Ustaw wartość True, aby wizualizować zdarzenia w dokumentach
              
          ' CZŁONKOWIE
          Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
          Private _txtMsg As String ' Wiadomość tekstowa do rejestrowania w konsoli
              
          ' WŁAŚCIWOŚCI
          Private Property Get FileName As String
              ''' Nazwa pliku zależna od systemu '''
              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
              
          ' METODY
          Public Sub DocumentEventOccurs(evt As com.sun.star.document.DocumentEvent)
              ''' Monitoruj zdarzenia dokumentu '''
              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)
              ''' Zainicjuj rejestrowanie zdarzeń dokumentu '''
              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 & "Zdarzenia dokumentu są rejestrowane", 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)
              ''' Zakończ rejestrowanie zdarzeń dokumentu '''
              ThisComponent.removeDocumentEventListener( _evtAdapter )
              If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
              Access2Base.Trace.TraceLog("INFO", _txtMsg & "Zdarzenia dokumentu zostały zarejestrowane", UI_PROMPT)
              Access2Base.Trace.TraceConsole() ' Okno dialogowe z przechwyconymi zdarzeniami
          End Sub ' controller.ConsoleLogger._StopAdapter
              
          ' ZDARZENIA
          ' Twój kod obsługiwanych zdarzeń znajduje się tutaj
      
warning

Zwróć uwagę na błędnie napisaną metodę _documentEventOccured, która dziedziczy literówkę z API (Application Programming Interface) LibreOffice.


Odkrywanie zdarzeń dokumentów

Obiekt API nadawcy udostępnia listę zdarzeń, za które jest odpowiedzialny:

Za pomocą języka Python


         # -*- coding: utf-8 -*-
         from __future__ import unicode_literals
             
         import uno, apso_utils as ui
             
         def displayAvailableEvents():
             """ Display document events """
             '''
             adapted from DisplayAvailableEvents() by 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

The Alternative Python Script Organizer (APSO) extension is used to render events information on screen.


Za pomocą języka LibreOffice Basic


         Sub DisplayAvailableEvents
             ''' Display document events '''
             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