Top > OOobbs2 > 79

OOobbs2/79 Edit

  • サマリ: Py-UNO で Calc アドイン関数
  • 環境: Calc
  • 状態: 投稿
  • 投稿者: はにゃ??
  • 投稿日: 2007-10-17 (水) 14:31:59

質問 Edit

Py-UNO では UNO コンポーネントを作成できるのでアドイン関数が作成できます (OOo Basic でも作成できますが)。

回答 Edit

必要なものは

  • IDL ファイル
  • Python-UNO コンポーネントファイル
  • META-INF/manifest.xml

まず、関数の仕様を決めます (以下の使用はかなり適当なものです)。

  • POWEROFNUMBER(number; value) 値の累乗を返します
  • POWEROFTWO(Value) 2 の累乗を返します

引数および返り値は long 型にして整数のみとします。

次に、サービス名とインターフェース名を決めます。関数はインターフェースのメソッドとして実装し、そのインターフェースを備えたサービスを作成します。

  • サービス名: mytools.sheet.addin.MyAddInFn
  • インターフェース名: mytools.sheet.addin.XMyAddInFn

インターフェース名が決まれば、IDL ファイルを書きます。

  • XMyAddInFn.idl
    #ifndef _MYTOOLS_SHEET_ADDIN_XMYADDINFN_IDL_
    #define _MYTOOLS_SHEET_ADDIN_XMYADDINFN_IDL_
    
    #include <com/sun/star/uno/XInterface.idl>
    
    module mytools {
    	module sheet {
    		module addin {
    			interface XMyAddInFn : com::sun::star::uno::XInterface
    			{
    				long powerOfTwo( [in] long nValue );
    				
    				long powerOfNumber( [in] long nValue, [in] long nNumber )
    			};
    		};
    	};
    };
    #endif

idlc と regmerge を使って rdb (uno typelibrary)ファイルを作成しておきます。

つぎに、Py-UNO コンポーネントを書きます。

アドイン関数のサービスは DevGuide によると以下のインターフェースが必要です。(XLocalizable は書かれていないが、無いと Calc がクラッシュします)

  • 実装するアドイン関数のインターフェース
  • XAddIn
  • XServiceName
  • XServiceInfo
  • XTypeProvider
  • XLocalizable

XTypeProvider は unohelper.Base を継承してやれば実装してもらえます。

  • MyAddInFn.py
    import uno
    import unohelper
    
    from mytools.sheet.addin import XMyAddInFn
    from com.sun.star.sheet import XAddIn
    from com.sun.star.lang import XLocalizable, XServiceName, XServiceInfo
    
    class MyAddInFn(unohelper.Base,XMyAddInFn,XAddIn,XLocalizable,XServiceName,XServiceInfo):
    	def __init__(self,ctx):
    		self.ctx = ctx
    		self.aAddInFnService = "mytools.sheet.addin.MyAddInFn"
    		self.aAddInService = "com.sun.star.sheet.AddIn"
    		self.aImplName = "MyAddInFn"
    		
    		self.aFunctionNames = ("powerOfTwo","powerOfNumber")
    		
    		self.aDisplayFunctionNames = {
    			self.aFunctionNames[0]: "PowerOfTwo", 
    			self.aFunctionNames[1]: "PowerOfNumber"}
    		
    		self.aArguments = {
    			self.aFunctionNames[0]: ("Value",),
    			self.aFunctionNames[1]: ("Number","Value")}
    		
    		self.FunctionDescriptions = {
    			self.aFunctionNames[0]: "The value power of two.", 
    			self.aFunctionNames[1]: "The value power of the number."}
    		
    		self.aArgumentsDescriptions = {
    			self.aFunctionNames[0]: ("The value power of two.",),
    			self.aFunctionNames[1]: ("The number is powered by the value.",
    				"The value power of the Number.")}
    		
    	
    	# XMyAddInFn
    	
    	def powerOfTwo(self,nValue):
    		return pow(2,nValue)
    	
    	# XMyAddInFn
    	
    	def powerOfNumber(self,nNumber,nValue):
    		return pow(nNumber,nValue)
    	
    	
    	# XAddIn
    	
    	def getProgrammaticFuntionName(self,aDisplayName):
    		for (aKey,aName) in self.aDisplayFunctionNames.iteritems():
    			if aName == aDisplayName:
    				return aKey
    		return ""
    	
    	def getDisplayFunctionName(self,aProgrammaticName):
    		if self.aDisplayFunctionNames.has_key(aProgrammaticName):
    			return self.aDisplayFunctionNames[aProgrammaticName]
    		return ""
    	
    	def getFunctionDescription(self,aProgrammaticName):
    		if self.FunctionDescriptions.has_key(aProgrammaticName):
    			return self.FunctionDescriptions[aProgrammaticName]
    		return ""
    	
    	def getDisplayArgumentName(self,aProgrammaticFunctionName,nArgument):
    		if self.aArguments.has_key(aProgrammaticFunctionName):
    			return self.aArguments[aProgrammaticFunctionName][nArgument]
    		return ""
    	
    	def getArgumentDescription(self,aProgrammaticFunctionName,nArgument):
    		if self.aArgumentsDescriptions.has_key(aProgrammaticFunctionName):
    			return self.aArgumentsDescriptions[aProgrammaticFunctionName][nArgument]
    		return ""
    	
    	def getProgrammaticCategoryName(self,aProgrammaticFunctionName):
    		return ("Add-In")
    	
    	def getDisplayCategoryName(self,aProgrammaticFunctionName):
    		return ("Add-In")
    	
    	
    	# XLocalizable
    	
    	def setLocale(self,eLocale):
    		pass
    	
    	def getLocale(self):
    		return uno.createUnoStruct("com.sun.star.lang.Locale")
    	
    	
    	# XServiceName
    	
    	def getServiceName(self):
    		return self.aAddInFnService
    	
    	
    	# XServiceInfo
    	
    	def getImplementationName(self):
    		return self.aImplName
    	
    	def supportsService(self,ServiceName):
    		return (ServiceName in (self.aAddInService,self.aAddInFnService))
    	
    	def getSupportedServiceNames(self):
    		return (self.aAddInFnService,self.aAddInService)
    
    
    
    g_ImplementationHelper = unohelper.ImplementationHelper()
    g_ImplementationHelper.addImplementation(
    	MyAddInFn,"mytools.sheet.addin.MyAddInFn",
    	("com.sun.star.sheet.AddIn",),)

META-INF/manifest.xml ファイルを作成します。

  • META-INF/manifest.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <manifest:manifest>
     <manifest:file-entry manifest:full-path="MyAddInFn.py" 
     manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/>
     <manifest:file-entry manifest:full-path="MyAddInFn.rdb" 
     manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"/>
    </manifest:manifest>

次のファイルから拡張機能パッケージを作成します。

MyAddInFn.py
MyAddInFn.rdb
META-INF/manifest.xml
(description.xml オプション)

パッケージを拡張機能マネージャからインストールした後、OOo を再起動します。

Add-In カテゴリに関数が追加されています。

PyFn.png

パッケージfileMyAddInFn.oxt 入れる必要の無い idl ファイルも入っています。


感想,コメント,メモ Edit



Attach file: fileMyAddInFn.oxt 1206 download [Information] filePyFn.png 535 download [Information]

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