Collabora Office 21.06 帮助
在将宏分配给事件旁边,可以监视 Collabora Office 文档所引发的事件。应用程序编程接口 (API) 广播器负责调用事件脚本。与需要定义所有支持的方法 (即使未使用) 的监听器不同, 文档监视器对已挂钩的事件脚本只需要两个方法。
本文采用 Basic 与 Python 语言,通过面向对象编程来演示监视功能。将 OnLoad 脚本分配给 文档打开 事件, 就足以启动和终止文档事件监视。 菜单的 选项卡用于分配各脚本。
侦听事件有助于在条件之前和之后安放脚本, 如加载与卸载库, 或在后台跟踪脚本处理进度。Access2Base 跟踪 模块的使用就是第二种情况的体现。
事件监视从对象实例化开始, 并在 Python 释放对象时最终停止。引发的事件通过Access2Base 控制台报告。
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):
""" 监视文档事件 """
'''
改编自「用于监视 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
注意拼写错误的 documentEventOccured 方法, 该错误继承自 Collabora Office 应用程序编程接口 (API)。
启动应用程序和关闭应用程序事件可分别用于为用户脚本或 Collabora Office 脚本设置和取消设置 Python 路径。类似地, 可以使用文档打开 和 文档关闭 事件来加载和释放基于文档的 Python 库或模块。有关详细信息, 请参阅导入 Python 模块。
将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
' 用于已处理事件的代码放在这里
注意拼写错误的 _documentEventOccured 方法, 该错误继承自 Collabora Office 应用程序编程接口 (API)。
广播器 API 对象提供了它所负责的事件列表:
# -*- 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,)
「替代 Python 脚本管理器 (APSO)」扩展程序用于在屏幕上渲染事件信息。
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