LibreOffice5(14)Calcに関数を追加するPython拡張機能の例その2

前の関連記事:LibreOffice5(13)unoinsp.py:IDL名から継承図を出力する


LibreOffice5(10)Calcに関数を追加するPython拡張機能の例その1でpython-tokencounter-calc-addin.oxtをみてようやくインターフェイスを定義して実装する方法がみえてきまた。この拡張機能の実装のtokencounter.pyを詳しくみてみます。

インターフェイスを定義して実装するのはそのメソッドのみ


新しいインターフェイスの定義にはまずidlファイルを書いてそれをidlcでurdにコンパイルしてregmergeでurdファイルをrdbファイルにするのはLibreOffice(65)Writing UNO componentsのThumbs Exampleその1LibreOffice(66)Writing UNO componentsのThumbs Exampleその2でやった通りです。

このrdbファイルをmanifest.xmlでmedia-typeを"application/vnd.sun.star.uno-typelibrary;type=RDB"として登録することでその定義したインターフェイスをPythonでインポートできるようになります。

すべてのインターフェイスの型はcom.sun.star.uno.XInterfaceですので、XTokenCounter.idlの中でもorg.openoffice.addin.sample.XTokenCounterの型はcom.sun.star.uno.XInterfaceと定義しており、そのためXTokenCounter.idlの中でcom/sun/star/uno/XInterface.idlをincludeしています。

org.openoffice.addin.sample.XTokenCounterインターフェイスはtokencount()メソッドだけをもちます。

rdbファイルにしたまではまだorg.openoffice.addin.sample.XTokenCounterインターフェイスの仕様をきめてPythonスクリプトにインポートできるようにしただけなので、tokencounter.pyで実際にorg.openoffice.addin.sample.XTokenCounterをインポートしてそれを継承したクラスでそのtokencount()メソッドをPythonで実装します。

それでtokencounter.pyをみてみるとTokenCounterクラスはorg.openoffice.addin.sample.XTokenCounterインターフェイス以外にunohelper.Baseとcom.sun.star.sheet.XAddInインターフェイスとcom.sun.star.lang.XServiceNameインターフェイスを継承しています。

tokencounter.pyのTokenCounterクラスが実装しているメソッドをみると、tokencount()メソッド以外はすべてXTokenCounterインターフェイスが継承しているメソッドになります。

com.sun.star.sheet.XAddInインターフェイスとcom.sun.star.lang.XServiceNameインターフェイスのメソッドだけでなく、com.sun.star.sheet.XAddInインターフェイスが継承しているcom.sun.star.lang.XLocalizableインターフェイスのメソッドも実装しています。

自作IDLの実装とはクラスでしているわけではなく、IDLで定義したインターフェイスをクラスで継承してその中のメソッドの一つとして実装すればよいようです。

拡張機能で定義しているメソッド

com.sun.star.sheet.AddIn
└─.sheet.AddIn
      ├─.lang.XServiceName
      │         string  getServiceName()
      ├─.sheet.XAddIn
      │   │   string  getArgumentDescription( [in] string aProgrammaticFunctionName,
      │   │                                   [in]   long nArgument)
      │   │   string  getDisplayArgumentName( [in] string aProgrammaticFunctionName,
      │   │                                   [in]   long nArgument)
      │   │   string  getDisplayCategoryName( [in] string aProgrammaticFunctionName)
      │   │   string  getDisplayFunctionName( [in] string aProgrammaticName)
      │   │   string  getFunctionDescription( [in] string aProgrammaticName)
      │   │   string  getProgrammaticCategoryName( [in] string aProgrammaticFunctionName)
      │   │   string  getProgrammaticFuntionName( [in] string aDisplayName)
      │   └─.lang.XLocalizable
      │               .lang.Locale  getLocale()
      │                       void  setLocale( [in] .lang.Locale eLocale)
      └─.sheet.XCompatibilityNames
                  [.sheet.LocalizedName]  getCompatibilityNames( [in] string aProgrammaticName)
com.sun.star.sheet.AddInサービスのメソッドをAPIリファレンスでみるとこのようになっていますがpython-tokencounter-calc-addin.oxtを拡張機能マネージャーに追加して、com.sun.star.sheet.AddInサービスをインスタンス化したオブジェクトのメソッドをみてみると追加されたものとなくなっているものがあることがわかります。
pyuno object
├─.lang.XServiceName
│         string  getServiceName()
├─.lang.XTypeProvider
│         [byte]  getImplementationId()
│         [type]  getTypes()
├─.sheet.XAddIn
│   │   string  getArgumentDescription( [in] string aProgrammaticFunctionName,
│   │                                   [in]   long nArgument)
│   │   string  getDisplayArgumentName( [in] string aProgrammaticFunctionName,
│   │                                   [in]   long nArgument)
│   │   string  getDisplayCategoryName( [in] string aProgrammaticFunctionName)
│   │   string  getDisplayFunctionName( [in] string aProgrammaticName)
│   │   string  getFunctionDescription( [in] string aProgrammaticName)
│   │   string  getProgrammaticCategoryName( [in] string aProgrammaticFunctionName)
│   │   string  getProgrammaticFuntionName( [in] string aDisplayName)
│   └─.lang.XLocalizable
│               .lang.Locale  getLocale()
│                       void  setLocale( [in] .lang.Locale eLocale)
└─org.openoffice.addin.sample.XTokenCounter
            long  tokencount( [in] string str)
python-tokencounter-calc-addin.oxtのtokencounter.pyで実装しているメソッドだけ表示されていることがわかります。

しかしよく見るとtokencounter.pyではgetDisplayCategoryName()であるべきところがgetDisplayArgumentName()が実装されています。

この程度の間違いでは関数の動作には問題ないようですが、訂正しないと本来のgetDisplayArgumentName()の戻り値が化けて###と表示されてしまいます。

Service Names - Apache OpenOffice Wikiを読むとSpreadsheet Add-Insは com.sun.star.sheet.AddInというサービス名以外にもうひとつ(Calcの)関数固有のサービス名を実装している必要があると書いてあります。

com.sun.star.lang.XServiceInfoインターフェイスがその関数固有のサービス名を扱えるだけでなくcom.sun.star.lang.XServiceNameインターフェイスのメソッドが関数固有のサービス名を返すことができます。

OOobbs2/79 - ...?の例ではXServiceInfoインターフェイスも継承しています。

XCompatibilityNamesインターフェイスがオブジェクトからなくなっています。

XTypeProviderインターフェイスのメソッドはTokenCounterクラスが継承したunohelper.Baseで実装されています。

XCompatibilityNamesインターフェイスがなくても動くならXAddInインターフェイスを削ったらどうなるかやってみたら動きませんでした。

XLocalizableインターフェイスのメソッドを削っただけでも動きませんでしたのでこの例の実装が最低限必要なもののようです。

com.sun.star.sheet.XAddInインターフェイスのメソッドの戻り値はどこに利用されているか


com.sun.star.sheet.XAddInインターフェイスの7つのメソッドの実装の殆どは単に文字列を返しているだけです。

それぞれどこにでてくるのか調べてみました。

まず挿入→関数、の関数ウィザードにでてくる表示への対応をみてみます。


それぞれのメソッドについてこのパネルに該当するところをみていきます。

メソッド名のコロンに続く値は実際にtokencounter.pyで返している値です。

getProgrammaticCategoryName(): "Add-In" 

「分類項目」の「アドイン」に該当します。LibreOffice: XAddIn Interface Referenceにカテゴリ名一覧があります。

getDisplayCategoryName()も"Add-In"を返していますがこれは変更してもどこに反映されているのかわかりませんでした。

上述しているようにtokencounter.pyではgetDisplayArgumentName()と間違って書いてあるのでgetDisplayCategoryName()と訂正しないといけません。

getDisplayFunctionName(): aProgrammaticName

「関数名」に該当。

getDisplayArgumentName(): "Text"

引数の部分に該当しますが、書いたままの値が表示されるようです。

getFunctionDescription(): "Counts the number of token separated by whitespace in the target field"

「関数の解説」

「次へ」ボタンをクリックすると引数の解説パネルになります。


getArgumentDescription(): "Field, which contains the tokens to count"

引数の解説。

以下はパネルにはでてこないものです。

getProgrammaticFuntionName(): aProgrammaticName IDLのメソッド名をそのまま返します。

参考にしたサイト


Python-UNO bridge
python-tokencounter-calc-addin.oxt の例について詳しくみました。

LibreOffice: Main Page
LibreOffice APIリファレンス。

Spreadsheet Add-Ins - Apache OpenOffice Wiki
Calcにアドイン関数を追加する方法。

OOobbs2/79 - ...?
OpenOfficeでのアドイン関数の実装例。

次の関連記事:LibreOffice5(15)Javaの例をデバッグ情報を追加してビルドする

PR

0 件のコメント:

コメントを投稿