Слушане на събития в документ

Слушането на събития в документ може да ви помогне в следните ситуации:

Освен да присвоявате макроси на събития, може също така да наблюдавате събитията, породени от документи на Collabora Office. Скриптовете за събития се извикват от разпространители (broadcasters) в приложния програмен интерфейс (API). За разлика от слушателите (listeners), които изискват дефиниране на всички поддържани методи, наблюдателите на документи (document monitors) изискват само два метода плюс закачените скриптове за събития.

Наблюдение на събития в документ

Наблюдението е илюстрирано тук с обектноориентирано програмиране на езиците Basic и Python. Присвояването на скрипта OnLoad на събитието Отваряне на документ е достатъчно за стартиране и прекратяване на следенето на събития в документа. За присвояване на скриптове на събития се използва командата Инструменти - Персонализиране, раздел Събития.

Прехващането на събития помага за задаване на пред- и следусловия в скриптовете, например зареждане и освобождаване на библиотеки, или за проследяване работата на скрипт във фонов режим. Употребата на Access2Base.Trace е показана във втория контекст.

С Python

Наблюдението на събития започва от създаването на обект и приключва, когато Python освободи обекта. Възникналите събития се докладват чрез конзолата на Access2Base.

note

Събитията OnLoad и OnUnload могат да се използват съответно за задаване и изчистване на пътя за програми на Python. Те са описани като Отваряне на документ и Затворен документ.


# -*- 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):
    """ Наблюдение на събития в документ """
    '''
    адаптирано от „Скрипт на Python за наблюдение на събитието OnSave“ на
    https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
    '''
    def __init__(self):
        """ Наблюдател на събития в документ """
        ''' докладване чрез конзолата на Access2Base.Trace ИЛИ
        в лист 1, колона 1 за документи на Calc '''
        ctx = uno.getComponentContext()
        smgr = ctx.getServiceManager()
        desktop = smgr.createInstanceWithContext(
        'com.sun.star.frame.Desktop' , ctx)
        self.doc = desktop.CurrentComponent
        #self.row = 0  # извадете от коментар само за документи на Calc
        Console.setLevel("DEBUG")
        self.listen()  # Започване наблюдение на събития в док.

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

    def setCell(self, calcDoc, txt: str):
        """ Извеждане събитията в колона 1 на ел. таблица в Calc """
        sheet = calcDoc.getSheets().getByIndex(0)
        sheet.getCellByPosition(0,self.row).setString(txt)
        self.row = self.row + 1

    def listen(self, *args):  # OnLoad/OnNew възможно най-рано
        """ Започване наблюдението на събития """
        self.doc.addDocumentEventListener(self)
        Console.log("ИНФОРМАЦИЯ", "Събитията в документа се регистрират", True)

    def sleep(self, *args):  # OnUnload най-късно (незадължително)
        """ Спиране наблюдението на събития """
        self.doc.removeDocumentEventListener(self)
        Console.log("ИНФОРМАЦИЯ", "Регистрирането на събития приключи", True)

    def documentEventOccured(self, event: DocumentEvent):
        """ Прехваща всички събития в док. """
        #self.setCell(event.Source, event.EventName) # само в док. на Calc
        Console.log("DEBUG",
            event.EventName+" in "+self.Filename,
            False)

    def disposing(self, event: EventObject):
        """ Освобождаване на всичко """
        self.sleep()
        Console.show()

def OnLoad(*args):  # Събитие „Отваряне на документ“
    listener = UiDocument()  # Започва слушане

def OnUnload(*args):  # Събитие „Документът е затворен“
    pass  # (незадължително) изпълнявано при освобождаване

g_exportedScripts = (OnLoad,)

from com.sun.star.script.provider import XScript
class Console():
    """
    Конзола на заден/преден план за докладване/регистриране изпълнението на програмата.
    """
    @staticmethod
    def trace(*args,**kwargs):
        """ Отпечатване на списък от елементи в конзолата """
        scr = Console._a2bScript(script='DebugPrint', module='Compatible')
        scr.invoke((args),(),())
    @staticmethod
    def log(level: str, text: str, msgBox=False):
        """ Доб. съобщение в конзолата, възм. подкана към потребителя """
        scr = Console._a2bScript(script='TraceLog')
        scr.invoke((level,text,msgBox),(),())
    @staticmethod
    def setLevel(logLevel: str):
        """ Зад. долна граница на съобщенията"""
        scr = Console._a2bScript(script='TraceLevel')
        scr.invoke((logLevel,),(),())
    @staticmethod
    def show():
        """ Показване съдържание в конзолата/диалог """
        scr = Console._a2bScript(script='TraceConsole')
        scr.invoke((),(),())
    @staticmethod
    def _a2bScript(script: str, library='Access2Base',
        module='Trace') -> XScript:
        ''' Получаване на скрипт на 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

Имайте предвид правописната грешка в името на метода documentEventOccured, наследена от програмния интерфейс (API) на Collabora Office.


Икона Съвет

Събитията Стартиране на приложение и Затваряне на приложение могат да се използват съответно за задаване и изчистване на пътя на Python за потребителски скриптове или скриптове на Collabora Office. По подобен начин базираните на документи библиотеки или модули на Python могат да се зареждат и освобождават чрез събитията Отваряне на документ и Затворен документ. За повече информация вижте Импортиране на модули на Python.


С Collabora Office Basic

Чрез менюто Инструменти - Персонализиране, раздел Събития, събитието Отваряне на документ предизвиква инициализация на ConsoleLogger. Подпрограмата _documentEventOccured, зададена от ConsoleLogger, служи като единствена входна точка за прехващане на всички събития в документа.

Модул controller.Events

Option Explicit

Global _obj As Object ' Екземпляр на controller.ConsoleLogger

Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> Отваряне на документ <<
    _obj = New ConsoleLogger : _obj.StartAdapter(evt)
End Sub ' controller.OnLoad
Sub _documentEventOccured(evt As com.sun.star.document.DocumentEvent)
    ''' Единствена входна точка на ConsoleLogger '''
     _obj.DocumentEventOccurs(evt)
End Sub ' controller._documentEventOccured

Модул на класа controller.ConsoleLogger

Наблюдението на събития започва от момента, в който се създаде екземпляр на ConsoleLogger, и спира при затваряне на документа. Подпрограмата StartAdapter зарежда необходимите библиотеки на Basic, а прехванатите събития се докладват чрез модула Access2Base.Trace.

Option Explicit
Option Compatible
Option ClassModule

' АДАПТЕР – обект, който се създава при събитието „Отваряне на документ“
Private Const UI_PROMPT = True
Private Const UI_NOPROMPT = False ' Задайте True, за да се визуализират събитията от документите

' ЧЛЕНОВЕ
Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster
Private _txtMsg As String ' текстово съобщение за показване в конзолата

' СВОЙСТВА
Private Property Get FileName As String
    ''' Зависимо от системата име на файл '''
    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

' МЕТОДИ
Public Sub DocumentEventOccurs(evt As com.sun.star.document.DocumentEvent)
    ''' Наблюдение на събития в документ '''
    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)
    ''' Инициализиране регистрирането на събития '''
    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("ИНФОРМАЦИЯ", _txtMsg & "Събитията в документа се регистрират", 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)
    ''' Прекратяване регистрирането на събития '''
    ThisComponent.removeDocumentEventListener( _evtAdapter )
    If IsMissing(evt) Then _txtMsg = "" Else _txtMsg = evt.EventName & "-"
    Access2Base.Trace.TraceLog("ИНФОРМАЦИЯ", _txtMsg & "Регистрирането на събития приключи", UI_PROMPT)
    Access2Base.Trace.TraceConsole() ' Диалог за прехванати събития
End Sub ' controller.ConsoleLogger._StopAdapter

' СЪБИТИЯ
' Тук ще бъде вашият код за обработка на събития
warning

Имайте предвид правописната грешка в името на метода _documentEventOccured, наследена от програмния интерфейс (API) на Collabora Office.


Откриване на събития в документ

Обектът разпространител от API предоставя списък на събитията, които поддържа:

С Python

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

import uno, apso_utils as ui

def displayAvailableEvents():
    """ Показване на събитията, свързани с документ """
    '''
    адаптирано от DisplayAvailableEvents() от 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

Разширението Alternative Python Script Organizer (APSO) се използва за показване на информацията за събитията на екрана.


С Collabora Office Basic

Sub DisplayAvailableEvents
    ''' Показване на събитията, свързани с документ '''
    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

Моля, подкрепете ни!