LibreOffice5(13)unoinsp.py:IDL名から継承図を出力する

2015-12-19

旧ブログ

t f B! P L

前の関連記事:LibreOffice5(12)PythonでLibreOfficeのバージョン番号を得る方法


LibreOffice5(11)unoinsp.py:自作IDLへの対応のunoinsp.pyにさらに機能を追加します。まずはローカルのSDKのIDLリファレンスへのパスを自動取得するようにします。さらに重複したインターフェイスをの出力を抑制しないモードも作成し、最後にpyunoオブジェクトではなくIDL名から継承図を主力できるようにします。

ローカルのSDKのIDLリファレンスへのパスを自動取得する


LibreOffice5(12)PythonでLibreOfficeのバージョン番号を得る方法でLibreOfficeのインストールフォルダへのフルパスが取得できたので、SDKにあるIDLリファレンスへのパスを自動取得するようにします。

unoinsp.py
def obj_test():
    service = "com.sun.star.sheet.AddIn"
    ctx = XSCRIPTCONTEXT.getComponentContext()
    obj = ctx.getServiceManager().createInstanceWithContext(service, ctx)
    import unoinsp
    ins = unoinsp.ObjInsp(XSCRIPTCONTEXT, False)
    ins.wtree(obj)
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    obj_test()
このobj_test.pyを実行するとローカルIDLリファレンスへのリンクが埋め込まれた継承図がデフォルトブラウザに出力されます。

6行目でObjInspをインスタンス化するときに第二引数にFalseを指定しています。

このobj_test.pyではcom.sun.star.sheet.AddInサービスのインスタンスの継承図を出力していますが、拡張機能サービスを登録していない場合はcom.sun.star.sheet.AddInサービスがインスタンス化できないのでuno.RuntimeException: Binary URP bridge disposed during callというエラーが出てきます。

com.sun.star.uno.XInterfaceインターフェイス以外すべてのインターフェイスを出力するモード


すべてのインターフェイスが継承しているcom.sun.star.uno.XInterfaceインターフェイスは除いて重複したインターフェイスも出力するようにしようと思ったのですが、階層構造がぐちゃぐちゃになってしまうので、com.sun.star.uno.XInterfaceインターフェイス以外すべてのインターフェイスを出力しますが、重複したものは除くようなモードを作りました。

unoinsp.py
def obj_test():
    service = "com.sun.star.configuration.ConfigurationProvider"
    ctx = XSCRIPTCONTEXT.getComponentContext()
    obj = ctx.getServiceManager().createInstanceWithContext(service, ctx)
    import unoinsp
    ins = unoinsp.ObjInsp(XSCRIPTCONTEXT, True, True)
    ins.tree(obj)
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    obj_test()
6行目でObjInspをインスタンス化するときに第三引数にTrueを指定しています。

第二引数のTrueはデフォルトのものです。

インスタンス化するサービスをcom.sun.star.configuration.ConfigurationProviderに変更しました。

treeの根に枝をつなげる


unoinsp.py

LibreOffice5(11)unoinsp.py:自作IDLへの対応で対応したはずですが、オブジェクトがサービスを介さずインターフェイスをもっているときは根と枝がつながっていませんでしたので修正しました。

IDL名を引数にしても継承図を出力できるようにする


オブジェクトではなくIDL名を引数にしても継承図が得られるようにしました。

結構あれこれ改造が必要でした。

これを機にに外から参照しない関数名の先頭にアンダーバーをつけました。

unoinsp.py
def obj_test():
    idl = "com.sun.star.configuration.ConfigurationProvider"
    import unoinsp
    ins = unoinsp.ObjInsp(XSCRIPTCONTEXT, True, True)
    ins.tree(idl)
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    obj_test()
これを実行すると以下が得られました。
com.sun.star.configuration.ConfigurationProvider
└─.configuration.ConfigurationProvider
      ├─.lang.XComponent
      │         void  addEventListener( [in] .lang.XEventListener xListener)
      │         void  dispose()
      │         void  removeEventListener( [in] .lang.XEventListener aListener)
      └─.lang.XMultiServiceFactory
                  .uno.XInterface  createInstance( [in] string aServiceSpecifier
                                        ) raises ( .uno.Exception)
                  .uno.XInterface  createInstanceWithArguments( [in] string ServiceSpecifier,
                                                                [in]  [any] Arguments
                                                     ) raises ( .uno.Exception)
                         [string]  getAvailableServiceNames()
unoinsp.py

同じインスタンスを使った時に出力しないインターフェイスの初期化に失敗していたので修正しました。

またLibreOffice5(11)unoinsp.py:自作IDLへの対応で行ったAPIリファレンスへのアンカータグをつけるところで自作IDLへ無駄なアンカータブが多量についていたのも修正しました。

unoinsp.py

メソッドの実行のたびに初期化するように_init()関数を作りました。

IPython Notebookでの使用例


LibreOffice5(10)Calcに関数を追加するPython拡張機能の例その1で使ったpython-tokencounter-calc-addin.oxtを拡張機能マネージャーに登録した状態でlinuxBean14.04(88)LibreOffice5をIPython Notebookから操作するのソケット通信の状態で起動したLibreOfficeを操作する方法で実行しています。
In [1]:
import unopy
XSCRIPTCONTEXT = unopy.connect()
if not XSCRIPTCONTEXT:
    print("Failed to connect.")
    import sys
    sys.exit(0)
In [2]:
import unoinsp
ins = unoinsp.ObjInsp(XSCRIPTCONTEXT, True, True)
In [3]:
ins.itree("com.sun.star.sheet.AddIn")

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)
In [4]:
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
In [5]:
obj = smgr.createInstanceWithContext("com.sun.star.sheet.AddIn", ctx)
ins.itree(obj)

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)
サービス名com.sun.star.sheet.AddInで調べた時とそれをインスタンス化したオブジェクトで調べた時と違う結果になっていることがわかります。

unoinsp.pyではTypeDescriptionオブジェクトが取得できるIDL名にしか対応できないので、実装名ではメソッド一覧などは取得できません。


IDLを定義せず実装名だけしかないオブジェクトのメソッド一覧を得たいときはIPython Notebookでそのオブジェクトのあとにドットを入力した後にTabキーを押すとメソッド一覧が表示されて便利です。

参考にしたサイト


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

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

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ