LibreOffice5(43)UNOIDLの引数の型の例を増やす

LibreOffice5(42)UNOIDLの引数の型の例:文字列を渡すのUNOIDLtypeプロジェクトの例を使い回します。

前の関連記事:LibreOffice5(42)UNOIDLの引数の型の例:文字列を渡す


UNOIDLtypeプロジェクトのサービス名、実装サービス名、メソッド名、クラス名を変更


変更するソースファイルはidlファイルとcomponent.pyファイルです。

idlフォルダにあるidlファイル名の変更、idlファイルの中身の変更、これは新しいUNOIDLの定義にあわせてごっそり変更しないといけません。

component.pyもidlファイルで定義したインターフェイスのインポート、IMPLE_NAME、SERVICE_NAME、クラス名、g_ImplementationHelper.addImplementation()の第一引数のクラス名、を変更しました。

メソッド名は今回はこのままにしておきました。

動作確認用のTestPythonComponent.pyのインスタンス化するUNOコンポーネントのサービス名を変更しました。

今度はtoolsフォルダを変更します。

step1settings.pyのLSTの実装サービス名とサービス名を変更しました。

あとはstep2createRDB.py、step4createManifest.py、step5createOXT.py、step6depoyOXT.pyを順に実行します。

これがエラーをなくすのにとても苦労しました。

UNOIDLtype/TestPythonComponent.py at 38e399935e05f825c8af1feeec414eef0aece3cf · p--q/UNOIDLtype

解決を困難にしていた原因は自作したPyUNOコンポーネントの実行確認をするTestPythonComponent.pyでLibreOfficeをバックグラウンドで起動したままエラーで終了するとLibreOfficeが起動できなくなることでした。

ということでtry文を導入してエラーがでてもsoffice.binの終了処理を実行するようにしました。

これでようやくエラーの同定ができるようになりました。

結局真の原因は単に名前の変更抜けでした、、、変更箇所が多いのがそもそもの原因です。

idlファイルの行末の;も忘れがちです。

ちなみに、Eclipseを起動してから少し落ち着いてから、TestPythonComponent.pyを実行しないと、LibreOfficeの起動に時間がかかって、そのせいでエラーがでることもありました。

これを機会にGit(25)すでにEclipseのGit Flowで管理しているリポジトリの.gitignoreを変更するの手順で、.gitignoreに*.bkを追加しました。

UNOIDLのインターフェイスのメソッドの追加


既存のインターフェイスにメソッドを追加するのは簡単です。

編集が必要なのはインターフェイスを定義したidlファイルXUnoInsp.idlと実装を定義しているcomponent.pyにメソッド追加します。

実行例をTestPythonComponent.pyに追加します。

idlファイルにメソッドを追加するときは引数の型と戻り値の型を指定する必要があります

Pythonのデータに該当する型についてはUNO Type Mappings - N->N->NUNO Type mappingを参考にします。

引数にリストは渡せずタプルに変換して渡します。

p--q/UNOIDLtype

スクリプトを作ってしまえば、コンパイルが必要なソースでもいろいろ試すのは簡単ですね。

IDLを定義するための参考にした資料


Thumbs Example

idlファイルの書き方はLibreOffice SDK API Reference
LibreOffice(65)Writing UNO componentsのThumbs Exampleその1の/opt/libreoffice5.2/sdk/examples/DevelopersGuide/Components/Thumbs/org/openoffice/testにあるidlファイルを参考にしました。

これはサービスとインターフェイスをそれぞれのidlファイルで定義しています。

それぞれのidlファイルをidlcでurdファイルにコンパイルしています。

そしてこれらurdファイルをregmergeでrdbファイルにまとめています(LibreOffice(66)Writing UNO componentsのThumbs Exampleその2参照。)

このrdbファイルを拡張機能のファイルに使います。

python-tokencounter-calc-addin.oxt

Pythonの例としてはLibreOffice5(10)Calcに関数を追加するPython拡張機能の例その1でpython-tokencounter-calc-addin.oxtをやりました。

python-tokencounter-calc-addin.oxtをアーカイブマネージャーで開くとidlフォルダの中にXTokenCounter.idlがあります。

これはCalcのアドインを作るもので、インターフェイスの定義だけです。

idlファイルではCore InterfacesのうちXInterfaceインターフェイスのidlファイルをincludeし、戻り値のあるメソッドを一つ新たに定義しています。

XInterfaceインターフェイスはインターフェイスが必ず備えないといけないインターフェイスです。

どのインターフェイスも備えているので、どれか一つインターフェイスを継承すればXInterfaceインターフェイスを備えることができます。

pyファイルではidlファイルで定義したXTokenCounterインターフェイス以外にunohelper.BaseとXAddIn、 Core InterfacesXServiceNameを継承してそのメソッドを実装しています。

XInterfaceインターフェイスはどの例でも実装せずにどれもIDLファイルで継承しています。

LibreOffice5(14)Calcに関数を追加するPython拡張機能の例その2で確認したインスタンスの結果を見るとCore InterfacesXTypeProviderインターフェイスも実装しています。

このXTypeProviderインターフェイスはunohelper.Baseで実装されています。

MRI

 LibreOffice5(25)MRI - UNO Object Inspection Tool:その1で使ったMRIもPythonで書いたUNOコンポーネントです。

hanya/MRI: An object introspection tool for OpenOffice APIの MRI/idl/mytools/Mri.idlにidlファイルがあります。

これは新たにサービスを定義してそのサービスがXIntrospectionインターフェイスを継承してそのメソッドを上書きしています。

これもLibreOffice5(26)MRI - UNO Object Inspection Tool:その2で確認したように、XTypeProviderはunohelper.Baseによって実装し、MRIそのものはXServiceNameを実装しています。

XJobExecutorインターフェイスのtrigger()メソッドを実装している例でもあります。

JobについてはLibreOffice5(16)イベント駆動する拡張機能のJavaの例:AsyncJob.oxt その1XAsyncJobのJavaの実装の例もやりました。

Jobs関連の拡張機能はメソッドを実装するだけでIDLを定義しなくても拡張機能が作れますが、その代わりJobを呼び出すきっかけになるxcuファイルを定義しないといけません。

 EasyDev

 LibreOffice5(12)PythonでLibreOfficeのバージョン番号を得る方法で使ったEasyDevもUNOコンポーネントのPythonでの実装例です。

 これのidlファイルはUniversoLibreMexicoAC/easydev: Tool for easy develop macros in LibreOffice... with Pythonの easydev/source/XEasyDev.idlです。

この例ではいままでみてきたのと違って一つのidlファイルに複数のインターフェイスを定義し最後にサービスも定義しています。

idlファイルでincludeしているのはこれまでと同じくXInterfaceインターフェイスだけです。

メソッドも多数定義してありとても参考になります。

メソッドだけでなくstructの定義もあります。

idlファイル名はIDLの定義とは関係無いようです。

一つのファイルで済むのならその方が扱いやすいです。

うーん、これはLibreOffice(14)デベロッパーガイド2 サービスマネジャとファクトリーで学習したold-style serviceですね。

Objects, Interfaces, and Services - Apache OpenOffice Wikiにnew-style serviceとold-style serviceのIDLの定義の例が載っています。

ということでやっぱりサービスとインターフェイスが1対1のnew-style serviceを使うことにします。

よくみたらMRIのMri.idlではひとつのidlファイルでサービスとそのインターフェイスのメソッドを定義していますね。

でもサービスとインターフェイスは1対1なのでnew-style serviceになります。

LibreOffice(65)Writing UNO componentsのThumbs Exampleその1のJavaの例のようにモジュールの階層をフォルダで再現しなくてもよいようです。

これはMRIもそうなっています。

インスタンス化するときに入力するのが面倒なのでMRIのようにmodule階層は浅くしようと思います。

参考にしたサイト


python - How to print the full traceback without halting the program? - Stack Overflow
try...except文でtracebackを表示させる方法。

UNO Type Mappings - N->N->N
UNOIDLとPythonの型の対応表。

UNO Type mapping
UNOIDLとPythonの型の対応表。

LibreOffice SDK API Reference
APIの解説にidlファイルへのリンクもあります。

GitHub - hanya/MRI: An object introspection tool for OpenOffice API
MRI/idl/mytools/Mri.idlにidlファイルがあります。

GitHub - UniversoLibreMexicoAC/easydev: Tool for easy develop macros in LibreOffice... with Python
easydev/source/XEasyDev.idlにidlファイルがあります。

Objects, Interfaces, and Services - Apache OpenOffice Wiki
上記のeasydevのidlファイルはold-style serviceになります。

次の関連記事:LibreOffice5(44)createInstanceWithArgumentsAndContext()でインスタンス化

PR

0 件のコメント:

コメントを投稿