Poslušanje dogodkov dokumenta

Poslušanje dogodkov dokumenta je lahko v pomoč v sledečih situacijah:

Poleg dodeljevanja makrov dogodkom lahko spremljamo dogodke, ki jih prožijo dokumenti Collabora Office. Oddajniki API (Application Programming Interface) so odgovorni za klicanje skriptov dogodkov. Za razliko od poslušalcev, ki zahtevajo določitev vseh podprtih metod, tudi če ostanejo neuporabljene, zahtevajo spremljevalniki dokumentov le dve metodi poleg skriptov, vezanih na dogodke.

Spremljanje dogodkov dokumenta

Spremljanje je tu ilustrirano z jezikoma Basic in Python z uporabo objektnega programiranja. Za dodeljevanje skripta OnLoad dogodku Open Document (Odpri dokument) zadostuje, da iniciirate in zaključite spremljanje dogodka dokumenta. Prek menijskega ukaza Orodja – Prilagodi in zavihka Dogodki lahko dodelite posamične skripte.

Prestrezanje dogodkov pomaga pri nastavljanju pred- in po-pogojev skriptov, kot je nalaganje in odlaganje knjižnic ali sledenje obdelovanja skripta v ozadju. Uporaba modula Access2Base.Trace ilustrira ta drugi kontekst.

S Pythonom

Sledenje dogodkom se prične z instanciranjem predmeta in se konča, ko Python predmet sprosti. Poročanje o povzročenih dogodkih poteka prek konzole Access2Base.

note

Dogodke OnLoad in OnUnload lahko uporabimo za določitev oz. oddoločitev poti programov Python. Opisani sta kot Dokument odprt (ang. Open document) in Dokument zaprt (ang. 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):
    """ Spremljaj dogodke dokumenta """
    '''
    prilagojeno iz »Skript Python za spremljanje dogodka OnSave« v
    https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
    '''
    def __init__(self):
        """ Spremljevalnik dogodkov dokumenta """
        ''' poročaj z uporabo konzole Access2Base.Trace ALI
        poročaj v 1. delovnem listu, 1. stolpcu v dokumentih Calc '''
        ctx = uno.getComponentContext()
        smgr = ctx.getServiceManager()
        desktop = smgr.createInstanceWithContext(
        'com.sun.star.frame.Desktop' , ctx)
        self.doc = desktop.CurrentComponent
        #self.row = 0  # odstrani znak komentarja le za dokumente Calc
        Console.setLevel("DEBUG")
        self.listen()  # Začni spremljati dogodke dokumenta

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

    def setCell(self, calcDoc, txt: str):
        """ Dogodki dokumenta se izpišejo v 1. stolpec preglednice Calc """
        sheet = calcDoc.getSheets().getByIndex(0)
        sheet.getCellByPosition(0,self.row).setString(txt)
        self.row = self.row + 1

    def listen(self, *args):  # Čimprej OnLoad/OnNew
        """ Začni spremljati dogodke dokumenta """
        self.doc.addDocumentEventListener(self)
        Console.log("INFO", "Dogodki dokumenta se beležijo", True)

    def sleep(self, *args):  # Čim kasneje OnUnload (neobvezno)
        """ Prenehaj spremljati dogodke dokumenta """
        self.doc.removeDocumentEventListener(self)
        Console.log("INFO", "Dogodki dokumenta so zabeleženi", True)

    def documentEventOccured(self, event: DocumentEvent):
        """ Prestrezi vse dogodke dokumenta """
        #self.setCell(event.Source, event.EventName) # samo za dokumente Calc
        Console.log("DEBUG",
            event.EventName+" in "+self.Filename,
            False)

    def disposing(self, event: EventObject):
        """ Sprosti vse dejavnosti """
        self.sleep()
        Console.show()

def OnLoad(*args):  # Dogodek »Odpri dokument«
    listener = UiDocument()  # Inicializira poslušanje

def OnUnload(*args):  # Dogodek »Dokument se je zaprl«
    pass  # (neobvezno) izvršeno, ko je zavržen

g_exportedScripts = (OnLoad,)

from com.sun.star.script.provider import XScript
class Console():
    """
    konzola v ospredju/ozadju za poročanje/beleženje izvajanja programa.
    """
    @staticmethod
    def trace(*args,**kwargs):
        """ Izpiši seznam prostih elementov v konzoli """
        scr = Console._a2bScript(script='DebugPrint', module='Compatible')
        scr.invoke((args),(),())
    @staticmethod
    def log(level: str, text: str, msgBox=False):
        """ Pripni sporočilo dnevnika v konzolo, neobvezno pobaraj uporabnika """
        scr = Console._a2bScript(script='TraceLog')
        scr.invoke((level,text,msgBox),(),())
    @staticmethod
    def setLevel(logLevel: str):
        """ Določi spodnjo mejo beleženja sporočil """
        scr = Console._a2bScript(script='TraceLevel')
        scr.invoke((logLevel,),(),())
    @staticmethod
    def show():
        """ Prikaži vsebino/pogovorno okno konzole """
        scr = Console._a2bScript(script='TraceConsole')
        scr.invoke((),(),())
    @staticmethod
    def _a2bScript(script: str, library='Access2Base',
        module='Trace') -> XScript:
        ''' Pograbi na programu temelječ skript v Basicu '''
        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

Bodite pozorni na napačno črkovanje metode documentEventOccured, ki deduje tipkarsko napako iz vmesnika API Collabora Office.


Ikona namiga

Dogodka Zaženi program (angl. Start application) in Zapri program (angl. Close application) lahko uporabljamo za določitev oz. preklic poti Pythona za skripte uporabnika ali Collabora Office. Na analogen način lahko knjižnice ali module Python na temelju dokumenta naložimo in sprostimo z uporabo dogodkov Odpri dokument (angl. Open document) in Zapri dokument (angl. Document closed). Za podrobnosti glejte Uvažanje modulov Python.


Z Collabora Office Basicom

Ob uporabi menijskega ukaza Orodja – Prilagodi in nato zavihka Dogodki dogodek Odpri dokument sproži inicializacijo ConsoleLogger. Podprogram _documentEventOccured, ki ga vzpostavi ConsoleLogger, služi kot značilna vstopna točka za lovljenje vseh dogodkov dokumenta.

Modul controller.Events

Option Explicit

Global _obj As Object ' instanca controller.ConsoleLogger

Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Odpri dokument <<
    _obj = New ConsoleLogger : _obj.StartAdapter(evt)
End Sub ' controller.OnLoad
Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
    ''' Značilna vstopna točka ConsoleLogger '''
     _obj.DocumentEventOccurs(evt)
End Sub ' controller._documentEventOccured

Modul razredov controller.ConsoleLogger

Spremljanje dogodkov se prične s trenutkom, ko je inicializiran predmet ConsoleLogger, in se povsem konča ob zaprtju dokumenta. Podprogram StartAdapter naloži potrebne knjižnice Basic, medtem ko o ujetih dogodkih poroča z uporabo modula Access2Base.Trace.

Option Explicit
Option Compatible
Option ClassModule

' predmet vzorca oblikovanja ADAPTER, ki bo instanciiran v dogodku »Odpri dokument«
Private Const UI_PROMPT = True
Private Const UI_NOPROMPT = False ' Nastavite na True, da vizualizira dogodke dokumenta

' ČLANI
Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
Private _txtMsg As String ' besedilo sporočila za beleženje v konzoli

' LASTNOSTI
Private Property Get FileName As String
    ''' Sistemsko-odvisno ime datoteke '''
    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

' METODE
Public Sub DocumentEventOccurs(evt As com.sun.star.document.DocumentEvent)
    ''' Spremljaj dogodke dokumenta '''
    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)
    ''' Inicializiraj beleženje dogodkov dokumenta '''
    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 & "Dogodki dokumenta se beležijo", 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)
    ''' Zaključi beleženje dogodkov dokumenta '''
    ThisComponent.removeDocumentEventListener( _evtAdapter )
    If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
    Access2Base.Trace.TraceLog("INFO", _txtMsg & "Dogodki dokumenta so zabeleženi", UI_PROMPT)
    Access2Base.Trace.TraceConsole() ' Pogovorno okno zabeleženih dogodkov
End Sub ' controller.ConsoleLogger._StopAdapter

' DOGODKI
' Tukaj sledi vaša koda za obravnavane dogodke
warning

Bodite pozorni na napačno črkovanje metode documentEventOccured, ki deduje tipkarsko napako iz vmesnika API Collabora Office.


Odkrivanje dogodkov dokumentov

Predmet oddajalnika API ponuja seznam dogodkov, za katere je odgovoren:

S Pythonom

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

import uno, apso_utils as ui

def displayAvailableEvents():
    """ Pokaži dogodke dokumenta """
    '''
    prirejeno po DisplayAvailableEvents(), ki ga je napisal 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

Razširitev APSO (Alternative Python Script Organizer) se uporablja za upodobitev podatkov o dogodkih na zaslonu.


Z Collabora Office Basicom

Sub DisplayAvailableEvents
    ''' Pokaži dogodke dokumenta '''
    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

Podprite nas!