Spis treści

# Nałuchiwanie zdarzeń w dokumencie

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

- Zidentyfikowanie nowego dokumentu w momencie otwarcia, w przeciwieństwie do istniejących, i wykonanie dedykowanej konfiguracji.

- Kontrolowanie przetwarzania żądań zapisania, kopiowania dokumentów, drukowania lub korespondencji seryjnej.

- Przeliczanie spisu treści, indeksów lub wpisów w tabeli dokumentu programu Writer, gdy dokument ma zostać zamknięty

- Importowanie pakietów matematycznych Pythona przed otwarciem dokumentu programu Calc. Zwolnienie tych pakietów po zamknięciu dokumentu.

Oprócz przypisywania makr do zdarzeń, można monitorować zdarzenia wywoływane przez dokumenty LibreOffice. Rozgłaszacze API (Application Programming Interface) są odpowiedzialni za wywoływanie skryptów zdarzeń. W przeciwieństwie do detektorów, które wymagają zdefiniowania wszystkich obsługiwanych metod, nawet jeśli nie są używane, monitory dokumentów wymagają tylko dwóch metod obok przechwyconych skryptów zdarzeń.

## 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.

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 """
                 '''
                 przystosowano ze „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

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

Zdarzenia Uruchom aplikację i Zamknij aplikację mogą odpowiednio służyć do ustawiania i wyłączania ścieżki Pythona dla skryptów użytkownika lub skryptów LibreOffice. W podobny sposób biblioteki lub moduły Pythona oparte na dokumentach mogą być ładowane i zwalniane przy użyciu zdarzeń Otwórz dokument i Zamknij dokument. Zobacz Importowanie modułów Pythona, aby uzyskać więcej informacji.

### 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

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():
                 """ Wyświetl zdarzenia dokumentu """
                 '''
                 przystosowano z DisplayAvailableEvents() autorstwa A. Pitonyaka
                 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,)

Rozszerzenie Alternative Python Script Organizer (APSO) służy do renderowania informacji o zdarzeniach na ekran

### Za pomocą języka LibreOffice Basic

             Sub DisplayAvailableEvents
                 ''' Wyświetl zdarzenia dokumentu '''
                 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

Tematy pokrewne

Tworzenie detektorów zdarzeń

Importowanie modułów Pythona

Tworzenie okna dialogowego z modułem obsługi

Przykłady programowania w Pythonie

Programowanie za pomocą skryptów Pythona

Wywoływanie makr Basic z Pythona