前の関連記事:LibreOffice(44)UNOオブジェクトの属性3:Writerドキュメントに出力
いまだにマクロの新しいコード一行を作るために色々検索して答えを探さないとうまくできません。早くAPIリファレンスをみてメソッドがわかっただけでさっとコードが書けるようになりたいですね。
getメソッドで得られるのはインターフェイス?オブジェクト?
#libreoffice45.py def libreoffice45(): XSCRIPTCONTEXT.getDocument().getCurrentController().getViewCursor().jumpToFirstPage()Writerドキュメントを開いているときにこのマクロを実行するとドキュメントの先頭が見えるようにドキュメントをスクロールさせます。
LibreOffice(44)UNOオブジェクトの属性3:Writerドキュメントに出力のobj_atr()の最後でも使っています。
まずXSCRIPTCONTEXTをLibreOffice 4.2 SDK APIで検索するとcom.sun.star.script.provider.XScriptContextインターフェイスがでてきます。
このcom.sun.star.script.provider.XScriptContextインターフェイスにはgetDocument()メソッドがあります。
getDocument()メソッドはcom.sun.star.frame.XModelインターフェイスを返します。
com.sun.star.frame.XModelインターフェイスをみるとgetCurrentController()メソッドがあります。
getCurrentController()メソッドはcom.sun.star.frame.XControllerインターフェイスを返します。
この調子でcom.sun.star.frame.XControllerインターフェイスにはgetViewCursor()メソッドがあると期待するのですが、com.sun.star.frame.XControllerインターフェイスにはgetViewCursor()メソッドはありません。
とりあえずgetViewCursorで検索するとgetViewCursor()メソッドはcom.sun.star.text.XTextViewCursorSupplierインターフェイスのメソッドであることがわかります。
getViewCursor()はcom.sun.star.text.XTextViewCursorインターフェイスを返します。
ところがまたcom.sun.star.text.XTextViewCursorインターフェイスにはjumpToFirstPage()メソッドがありません。
jumpToFirstPageで検索するとjumpToFirstPage()メソッドはcom.sun.star.text.XPageCursorインターフェイスであることがわかります。
とりあえずここまでの関係をLibreOffice(8)統一モデリング言語UML(Unified Modeling Language)の学習で学習したUMLのクラス図と依存関係を使って図にしてみると以下のようになります。
LibreOffice(14)デベロッパーガイド2 サービスマネジャとファクトリーでみたようにUNOオブジェクトはサービスをインスタンス化して生成されるので、上のクラス図の「?」にはサービス名が入るはずです。
LibreOffice(11)LibreOfficeのオブジェクトとUNOのインターフェイスでみたようにインターフェイスはUNOオブジェクトがもっている属性とメソッドの集合のことで、上図では今回のマクロで関係のあるインターフェイスとメソッドのみ表示しています。
デベロッパーガイドにもgetメソッドではオブジェクトが手に入ると書いてあります。(
2.4 OpenOffice.org でオブジェクトを手に入れる方法 Objects that are provided by other objects)
なのでgetメソッドの戻り値がサービスであれば納得できます。
ところがAPIリファレンスではgetメソッドの戻り値はインターフェイスになっています。
例えばgetDocument()メソッドのところには以下のように書いてあります。
- Returns
- com::sun::star::frame::XModel interface
そこがよく理解できないのですよね。
でも、「このインターフェイスを型にもつオブジェクトが返る」、と解釈すれば納得できます。
そもそも「型」というのはLibreOffice(13)デベロッパーガイド1 ほとんどの例はJavaででてきたようにJavaではオブジェクトにも型があってJavaではそれぞれ型変換しないといけません。
それを「型」といい、単に「オブジェクトがもっているインターフェイスの一つ」のようにみえますが、型のインターフェイスを直接オブジェクトがもたずにそのインターフェイスを継承したインターフェイスをもつときもあります。
その場合は、型は「オブジェクトがもっているインターフェイスの一つ」に一致しません。
APIリファレンスの継承図をたどってインスタンスの元のサービスを突き止める
getメソッドで得られるオブジェクトのインスタンス化の元になるサービスを突き止めて「?」を埋めていきます。
まずはcom.sun.star.script.provider.XScriptContextインターフェイスをもつオブジェクト。
APIリファレンスの継承図をみてもこれ以上遡れませんのでデベロッパーズガイドをみます。
BeanShell, JavaScript, Java, Python macros are supplied with a variable of type com.sun.star.script.provider.XScriptContext which can be used to access the OpenOffice.org API.XScriptContextインターフェイスをもつオブジェクトはデベロッパーガイドのScripting Frameworkの章にこう書いてあって、XSCRIPTCONTEXTはLibreOffice(5)PythonでLibreOfficeが動く仕組み:UNOでみた1つ目のLibreOfficeの中のScripting Frameworkで動くモードで与えられるグローバル変数です。
Using the OpenOffice.org API from macros
ということでこれはサービスをインスタンス化して生成されたオブジェクトではなく、最初から与えられた変数になるので、「?」にはXSCRIPTCONTEXTを入れます。
次にXScriptContextインターフェイスのgetDocument()メソッドで返されるcom.sun.star.frame.XModelインターフェイスをもつオブジェクト。
com.sun.star.frame.XModelはLibreOfficeドキュメント共通のインターフェイスなので、継承図をみるとこのインターフェイスを継承しているサービスは多数あります。
getDocument()メソッドで返されるオブジェクトが、どのサービスのインスタンスなのかはどのドキュメントでマクロを起動したかで決まります。
今回はWriterで起動したのでどのサービスのインスタンスかはデベロッパーズガイドのDocument Specific Featuresの一覧をみればcom.sun.star.text.TextDocumentサービスであることがわかります。
ところがcom.sun.star.frame.XModelの継承図にはTextDocumentはでてきません。
これはcom.sun.star.text.TextDocumentサービスの継承図をみるとcom.sun.star.text.GenericTextDocumentサービスを継承しているのがわかるので、TextDocumentはGenericTextDocumentを通じてXModelを継承しているとわかります。
ということでXSCRIPTCONTEXT.getDocument()で得られるオブジェクトはcom.sun.star.text.TextDocumentのインスタンスになります。
APIリファレンスだけでは関連がわからないところがある
今度はgetCurrentController()で得られるオブジェクトのサービスをみつけます。
getCurrentController()メソッドはcom.sun.star.frame.XControllerインターフェイスを返します。
ところがcom.sun.star.frame.XControllerを継承しているサービスやインターフェイスを継承図で全部みてもcom.sun.star.text.TextDocumentサービスとの関連がみつけられません。
com.sun.star.text.TextDocumentのインスタンスはモデルになるのでLibreOffice(32)デベロッパーガイド4:コンポーネントフレームワークでみたようにgetCurrentController()ではそのコントローラを得られるはずです。
ということでデベロッパーガイドのDocument Specific Controller Services 特定のコントローラー・サービスのドキュメント化をみるとcom.sun.star.text.TextDocumentからはcon.sun.star.text.TextDocumentViewサービスであるとわかります。
まあこれでAPIリファレンスだけではコマンドの関連は見つけられず、デベロッパーガイドも併せて読まないといけないとわかりました。
ところがそれでもまだわからないのは、con.sun.star.text.TextDocumentViewサービスにcom.sun.star.frame.XControllerインターフェイスを見つけられないことです。
ちょっといろいろAPIリファレンスをたどっても見つけられなかったのでLibreOffice(44)UNOオブジェクトの属性3:Writerドキュメントに出力で作ったobj_atr()関数で、XSCRIPTCONTEXT.getDocument().getCurrentController()の結果をみました。
ちゃんとcom.sun.star.frame.XControllerインターフェイスを継承していますね。
使えるインターフェイス(supportedInterfaces)の一覧にcom.sun.star.frame.XControllerを継承しているcon.sun.star.frame.XController2インターフェイスもあります。
getViewCursor()メソッドをもつcom.sun.star.text.XTextViewCursorSupplierインターフェイスも一覧にあります。
TextDocumentViewサービスがXTextViewCursorSupplierインターフェイスを継承しているのはAPIリファレンスの継承図でも確認できます。
これでここまで「?」が埋まりました。
あとはcom.sun.star.text.XTextViewCursorSupplierインターフェイスのgetViewCursor()メソッドで得られるオブジェクトについて調べます。
デベロッパーガイドではオブジェクトの得方がわかりにくいけどAPIリファレンスでもわかりにくい
com.sun.star.text.XTextViewCursorSupplierインターフェイスのgetViewCursor()メソッドで得られるオブジェクトの型はcon.sun.star.text.XTextViewCursorインターフェイスです。
APIリファレンスの継承図を見てもXTextViewCursorをもっているサービス名がわかりません。
ひとつ上流のcom.sun.star.text.XTextCursorの継承図を見てみます。
XTextCursorインターフェイスをもっているサービスはcon.sun.star.tex.t.TextCursor、con.sun.star.tex.t.TextLayoutCursor、con.sun.star.text.TextViewCursorであることがわかります。
このうちjumpToFirstPage()メソッドをもつcom.sun.star.text.XPageCursorインターフェイスをもつサービスが正解のはずです。
それぞれ継承図をみるとTextLayoutCursorサービスとTextViewCursorサービスにXPageCursorインターフェイスがあります。
TextLayoutCursorサービスはTextViewCursorサービスに継承されています。
LibreOffice(14)デベロッパーガイド2 サービスマネジャとファクトリーでみたようにOpenOffice.org 2.0以前はインターフェイスが多重継承できなかったので、インターフェイスの多重継承を実現するためにサービスにサービスを継承させていたようです。
TextLayoutCursorサービスは単にそのためのサービスと考えると最後の「?」に入るサービスはTextViewCursorと考えられます。
これで全部オブジェクトがわかりましたね。
デベロッパーガイドにはTextViewCursorの解説があります。(TextViewCursor
7.5.2 テキスト・ビュー・カーソル) (getTextViewCursor()はgetViewCursor()に変更になったようです。)
こうやって順番にたどり着いてデベロッパーガイドの項を読むと使い方がさらに詳しくわかるのですが、いきなりデベロッパーガイドの項目を読んでもそのオブジェクトの得方がわからないのでなかなか応用できないのですよね。
APIリファレンスとデベロッパーガイドを両方参考にするとこうやってオブジェクトがわかって他の使えるメソッドもわかって応用できるのですが結構大変です。
オブジェクトの属性を直接確認できるツールは便利
上で継承したインターフェイスの確認に使ったLibreOffice(44)UNOオブジェクトの属性3:Writerドキュメントに出力で作ったobj_atr()関数を利用すると、直接オブジェクトから型やサービス名、インターフェイス一覧を得られるので便利ですね。
しかし、複数のサービス名があるときや、メソッドを知るためにはやはりAPIリファレンスを見る必要があります。
参考にしたサイト
Apache OpenOffice Developer's Guide - Apache OpenOffice Wiki
PDF版の表紙にOpenOffice.org 3.1 Developer's Guideと書いてあります。
Developer's Guide
OpenOffice Developer's Guideの日本語版。OpenOffice.org 2.0より前のもののようです。
LibreOffice: Namespace List
LibreOffice 4.2 SDK APIの入り口com.sun.star。
0 件のコメント:
コメントを投稿