监视文档事件

将宏分配给事件旁边,可以监视 Collabora Office 文档所引发的事件。应用程序编程接口 (API) 广播器负责调用事件脚本。与需要定义所有支持的方法 (即使未使用) 的监听器不同, 文档监视器对已挂钩的事件脚本只需要两个方法。

监听文档事件

本文采用 Basic 与 Python 语言,通过面向对象编程来演示监视功能。将 OnLoad 脚本分配给 文档打开 事件, 就足以启动和终止文档事件监视。工具 – 自定义...菜单的事件选项卡用于分配各脚本。

侦听事件有助于在条件之前和之后安放脚本, 如加载与卸载库, 或在后台跟踪脚本处理进度。Access2Base 跟踪 模块的使用就是第二种情况的体现。

使用 Python

事件监视从对象实例化开始, 并在 Python 释放对象时最终停止。引发的事件通过Access2Base 控制台报告。

note

OnLoadOnUnload 事件可用于分别设置和取消设置 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):
    """ 监视文档事件 """
    '''
    改编自「用于监视 OnSave 事件的 Python 脚本」,见于
    https://forum.openoffice.org/en/forum/viewtopic.php?t=68887
    '''
    def __init__(self):
        """ 文档事件监视器 """
        ''' 使用 Access2Base.Trace 控制台报告,*或*
        在 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):
        """ 在 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("INFO", "正在记录文档事件", True)

    def sleep(self, *args):  # 最后执行 OnUnload (可选)
        """ 停止文档事件监视 """
        self.doc.removeDocumentEventListener(self)
        Console.log("INFO", "文档事件已记录", 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()  # Initiates listening

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:
        ''' Grab application-based 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
warning

注意拼写错误的 documentEventOccured 方法, 该错误继承自 Collabora Office 应用程序编程接口 (API)。


提示图标

启动应用程序关闭应用程序事件可分别用于为用户脚本或 Collabora Office 脚本设置和取消设置 Python 路径。类似地, 可以使用文档打开文档关闭 事件来加载和释放基于文档的 Python 库或模块。有关详细信息, 请参阅导入 Python 模块


使用 Collabora Office Basic

Onload脚本分配给文档打开事件可通过工具 – 自定义...菜单事件选项卡进行。事件监视从 ConsoleLogger 对象实例化的那一刻起就开始了,并在 Basic 引擎释放它时终止。 OnLoad事件可加载必要的 Basic 库, 同时使用Access2Base.Trace 报告捕获的事件。

REM controller.Events 模块
Option Explicit
Private _obj As Object ' controller.ConsoleLogger 实例

Sub OnLoad(evt As com.sun.star.document.DocumentEvent) ' >> 文档打开 <<
    _obj = New ConsoleLogger : _obj.Start(evt)
End Sub ' controller.OnLoad
' ----
REM controller.ConsoleLogger 类模块
Option Explicit
Option Compatible
Option ClassModule

'「适配器」设计模式对象,将在 « 文档打开 » 事件中实例化
Private Const UI_PROMPT = True
Private Const UI_NOPROMPT = False ' Set it to True to visualise documents events

' 构造函数/析构函数
Private Sub Class_Initialize()
End Sub ' controller.ConsoleLogger.Initialize
Private Sub Class_Terminate()
End Sub ' controller.ConsoleLogger.Terminate

' 成员
Private _evtAdapter As Object ' com.sun.star.document.XDocumentEventBroadcaster

' PROPERTIES
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

' 方法
Private Sub _documentEventOccured(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" : _Stop(evt)
    End Select
End Sub ' controller.ConsoleLogger._documentEventOccured

Private Sub _disposing(evt As com.sun.star.lang.EventObject)
End Sub ' controller.ConsoleLogger.disposing

Public Sub Start(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")
    Access2Base.Trace.TraceLog("INFO", _
        IIf(IsMissing(evt),"",evt.EventName & "-") & "正在记录文档事件", _
        UI_PROMPT)

    _evtAdapter = CreateUnoListener( "_", "com.sun.star.document.XDocumentEventListener" )
    ThisComponent.addDocumentEventListener( _evtAdapter )
End Sub ' controller.ConsoleLogger.Start

Private Sub _Stop(Optional evt As com.sun.star.document.DocumentEvent)
    ''' 终止文档事件记录 '''
    ThisComponent.removeDocumentEventListener( _evtAdapter )
    Access2Base.Trace.TraceLog("INFO", _
        IIf(IsMissing(evt),"",evt.EventName & "-") & "文档事件已记录", _
        UI_PROMPT)
    Access2Base.Trace.TraceConsole() ' Captured events dialog
End Sub ' controller.ConsoleLogger._Stop

' EVENTS
' 用于已处理事件的代码放在这里
warning

注意拼写错误的 _documentEventOccured 方法, 该错误继承自 Collabora Office 应用程序编程接口 (API)。


探索文档事件

广播器 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

替代 Python 脚本管理器 (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

请支持我们!