Top > OOobbs3 > 60
** [[OOobbs3/60]] [#sd4110b9]
-''サマリ'': イベントでマクロを実行するサービス
-''環境'': General
-''状態'': 投稿
-''投稿者'': [[はにゃ?]]
-''投稿日'': 2011-08-18 (木) 01:02:44
*** 質問 [#h373eca6]
あるフォーラムでの書き込みで、「ツール - カスタマイズ - イベントにマクロを登録せずに実行したい」といった質問を見たので書いてみたもの。
私は使いませんが、ここに置いておきます。

イベントマクロの登録は誰かに上書きされたりすると実行されなくなりますが、/org.openoffice.Office.Jobs に登録したサービスを実行するイベントは普通は上書き、削除されません。

次のサービスを拡張機能からインストールします。manifest/META-INF.xml に次のように追加します。
  <manifest:file-entry manifest:full-path="executor.py" 
   manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/>

executor.py
#code(python){{

import unohelper

IMPLE_NAME = "mytools.script.EventMacroExecutor"

from com.sun.star.lang import XServiceInfo
from com.sun.star.task import XJob

from com.sun.star.document import DocumentEvent

class EventMacroExecutor(unohelper.Base, XServiceInfo, XJob):
	
	DOCUMENT_EVENTS = ("OnCreate", 
		"OnLoadFinished", "OnNew", "OnLoad", 
		"OnSave", "OnSaveAs", "OnSaveAsDone", 
		"OnPrepareunload", "OnFocus", "OnUnfocus", 
		"OnPrint", "OnModifyChanged", 
		"OnCopyTo", "OnCopyToDone", 
		"OnViewCreated", "OnPrepareViewClosing", 
		"OnVisAreaChanged", "OnCreate", "OnLoadFinished", 
		"OnSaveAsFailed", "OnSaveFailed", "OnCopyToFailed", 
		"TitleChanged", "OnMailMerge", "OnPageCountChange")
	APPLICATION_EVENTS = ("OnStartApp", "OnCloseApp", 
		"OnUnload", "OnViewClosed")
	
	def __init__(self, ctx, *args):
		self.ctx = ctx
	
	# XServiceInfo
	def getImplementationName(self):
		return IMPLE_NAME
	def supportsService(self, name):
		return name == IMPLE_NAME
	def getSupportedServiceNames(self):
		return IMPLE_NAME,
	
	
	def check_context(self, doc, context):
		if len(context) == 0:
			return True
		
		mod_manager = self.ctx.getServiceManager().createInstanceWithContext(
			"com.sun.star.frame.ModuleManager", self.ctx)
		identifier = mod_manager.identify(doc)
		return identifier in context
	
	
	# XJob
	def execute(self, args):
		""" Event executed. """
		event_name = ""
		doc = None
		url = ""
		context = []
		
		for arg in args:
			name = arg.Name
			#print(name)
			if name == "JobConfig": # Arguments
				options = arg.Value
				for option in options:
					name = option.Name
					if name == "URL":
						url = option.Value
					elif name == "Context":
						context = option.Value.split(",")
			elif name == "Environment":
				envs = arg.Value
				#print(envs)
				for env in envs:
					name = env.Name
					if name == "EnvType" and env.Value == "DOCUMENTEVENT":
						pass#print(env.Value)
					elif name == "Model":
						doc = env.Value
					elif name == "EventName":
						event_name = env.Value
		#
		valid = True
		if event_name in self.DOCUMENT_EVENTS:
			if not self.check_context(doc, context):
				valid = False
		else:
			# elif event_name in self.APPLICATION_EVENTS:
			doc = None
		if valid:
			# execute macro
			sp = doc.getScriptProvider()
			script = sp.getScript(url)
			#if not script:
			#	print("no script")
			ev = DocumentEvent(doc, event_name, None, None)
			script.invoke((ev,), (), ())


g_ImplementationHelper = unohelper.ImplementationHelper()
g_ImplementationHelper.addImplementation(
	EventMacroExecutor, IMPLE_NAME, (IMPLE_NAME,),)

}}

そして、イベントで実行したいマクロを指定するコンフィグレーションを追加します。以下は設定の一例です。

  <manifest:file-entry manifest:full-path="Jobs.xcu"
   manifest:media-type="application/vnd.sun.star.configuration-data"/>

Jobs.xcu
#code(xcu){{
<?xml version="1.0"?>
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:install="http://openoffice.org/2004/installation" oor:name="Jobs" 
oor:package="org.openoffice.Office">
<!-- ジョブの定義です。 -->
<node oor:name="Jobs">
	<!-- oor:name を独自のものに適宜書き換えます -->
	<node oor:name="mytools.script.EventExample" oor:op="replace">
		<!-- 上記のコードが提供するサービスで、マクロを実行します。 -->
		<prop oor:name="Service">
			<value>mytools.script.EventMacroExecutor</value>
		</prop>
		<!-- マクロの URL と実行するドキュメントのタイプを指定します。 -->
		<node oor:name="Arguments">
			<!-- マクロの URL -->
			<prop oor:name="URL" oor:type="xs:string" oor:op="replace">
				<value>vnd.sun.star.script:Standard.Module1.Hello?language=Basic&location=application</value>
			</prop>
			<!-- 実行するドキュメントのタイプ。複数指定は , 区切り -->
			<prop oor:name="Context" oor:type="xs:string" oor:op="replace">
				<value>com.sun.star.text.TextDocument,com.sun.star.sheet.SpreadsheetDocument</value>
			</prop>
		</node>
	</node>
</node>
<!-- イベントの定義 -->
<node oor:name="Events">
	<!-- oor:name にイベントの種類を指定します。 -->
	<node oor:name="OnViewCreated" oor:op="fuse">
		<node oor:name="JobList">
			<!-- 実行するジョブのノード名を指定します。 -->
			<node oor:name="mytools.script.EventExample" oor:op="replace"/>
		</node>
	</node>
</node>
</oor:component-data>
}}

複数のジョブを登録するには独自の名前を付けたノードを複数子記述してください。イベントを増やす場合にはイベント名のノードを増やしてください。イベント名の一覧は [[OOoBasic/Generic/Events]] にあります。

ToDo
- 設定ファイルを出力するマクロを書き始めたが、フォームの作成が面倒で放置状態。
*** 回答 [#rf8bfc6c]

#comment


*** 感想,コメント,メモ [#g6e41506]

#comment

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes