LibreOffice5(24)unoinsp.py:出力を抑制するインターフェイスの指定方法を追加

前の関連記事:LibreOffice5(23)ダイアログエディタでGUIを作成しPythonで利用する:その3


LibreOffice5(23)ダイアログエディタでGUIを作成しPythonで利用する:その3LibreOffice5(13)unoinsp.py:IDL名から継承図を出力するのunoinsp.pyがうまく動かない点が判明したので修正します。

TypeDescriptionオブジェクトを取得できないサービス名を除外する


pyunoオブジェクトからgetSupportedServiceNames()メソッドで返ってきたサービス名のうちTypeDescriptionオブジェクトを取得できないものを省くようにしました。

これでLibreOffice5(23)ダイアログエディタでGUIを作成しPythonで利用する:その3の最後で躓いた問題は解決しました。

ついでにいろいろ気になっていたところを変更します。

コアインターフェイスすべてをデフォルトでは出力を抑制する


これまで'.uno.XInterface', '.uno.XWeak', '.lang.XTypeProvider'の3つのインターフェイスはデフォルトでは出力を抑制していましたがもうCore Interfaces to Implement - Apache OpenOffice Wikiにある9つのコアインターフェイスはすべて出力抑制することにしました。

'.uno.XInterface', '.lang.XTypeProvider', '.lang.XServiceInfo', '.uno.XWeak', '.lang.XComponent', '.lang.XInitialization', '.lang.XMain', '.uno.XAggregation', '.lang.XUnoTunnel'

この9つのインターフェイスの出力を抑制します。

ローカルのAPIリファレンスへのリンクを指定する方法を変更する


ローカルにインストールしたSDKへのAPIリファレンスへのリンクを貼るときは引数にFalseに指定をしていましたが、あとで何のことか思い出せないので、unoinsp.ObjInsp()の第2引数にFalseとNone以外のものをとりあえず何か指定するとオフライン参照するように変更しました。

またアンカータグに target='_blank'を追加してリンクを新しいタブに開くようにしました。

IPython Notebookのセルからスタートアップフォルダ以下以外のローカルファイルへのリンクが開けず


いまさら気が付きましたがIPython Notebookの出力セルのfile://のリンクはChromeやChromiumでクリックしても新しいタブにはページが開きませんね。

itree()メソッドではなくwtree()メソッドでChromiumのタブに出力した属性ツリーからはちゃんとfile://のリンクが開きます。
<a href="file:///opt/libreoffice5.0/sdk/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1accessibility_1_1XAccessible.html">.accessibility.XAccessible</a>
セルをMarkdownにしてこのようにローカルファイルへのリンクを貼ってみても反応しません。

HTML href link · Issue #6270 · ipython/ipython · GitHub

どうやらJupyter Notebookに画像を表示させる方法の画像ファイルときと同様にIPython Notebookeからはスタートアップフォルダの下層にあるローカルファイル以外にはアクセスできないようです。
%%javascript
location.href= "/opt/libreoffice5.0/sdk/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1accessibility_1_1XAccessible.html;
JavaScriptから呼び出せばうまくいくのではないかと思ってこれをセルに書き込んでえらい目にありました。

404: Not Foundのページに自動的に飛ぶようになってしまってipynbファイルが編集できなくなってしまいました。

ipynbファイルをGeanyで編集して直しました。

ということでitree()メソッドでローカルのAPIリファレンスへリンクを貼る機能は断念します。

出力を抑制するインターフェイスを引数に指定する


メソッドの第2引数にリストで出力を抑制したいインターフェイス名を渡すようにしました。

すでにデフォルトで抑制されているインターフェイスを渡した時は逆に出力するようにしました。

コアインターフェイスの抑制をまとめてとりたいときは"core"を渡すとすべて出力できるようにしました。

インターフェイス名のcom.sun.starは省略してもしなくてもどちらにも対応しています。

unoinsp.py

tree()メソッドだけ出力方法が違うためにややこしいことになっていたのでtree()メソッドでも一旦リストに出力したいものをいれてから最後にprint()することにしました。

またIDL名を引数にするときにcom.sun.starを省略した場合にも対応しました。

unoinsp.py

wtree()メソッドはすごく時間がかかりますが、itree()メソッドは反応が速いので便利です。

unoinsp.py

正規表現を最初にコンパイルしておきました。(LibreOffice(42)UNOオブジェクトの属性1:正規表現パターンを作成参照。)

その他コード整理してみましたがどうも「オブジェクト指向」というのが理解できておらずこれ以上整理できそうにないです。

新しいunoinsp.pyをIPython Notebookで使ってみる


ソケット通信の状態で起動したLibreOfficeに接続します。
In [1]:
import unopy
XSCRIPTCONTEXT = unopy.connect()
if not XSCRIPTCONTEXT:
    print("Failed to connect.")
    import sys
    sys.exit(0)
ObjInspをXSCRIPTCONTEXTを引数にしてインスタンス化します。
In [2]:
import unoinsp
ins = unoinsp.ObjInsp(XSCRIPTCONTEXT)
unoinsp.ObjInsp(XSCRIPTCONTEXT, 1)というような感じでNoneやFalse以外の第2引数を指定するとローカルのSDKのAPIリファレンスへのリンクが張れるのですが、IPython Notebookではスタートアップフォルダより上の階層のフォルダにはアクセスできないのでクリックしても何も反応しません。
ローカルのAPIリファレンスへのリンクを有効にしたいときはwtree()メソッドで新しいタブに属性ツリーを出力すればよいですが、出力されるまでに時間がかかるのが難点です。

まあローカルリンクを有効にしたいときは開発版のSDKを使うときぐらいでしょうけど。
In [3]:
ins.itree(XSCRIPTCONTEXT)

pyuno object
└─.script.provider.XScriptContext
                        .uno.XComponentContext  getComponentContext()
                               .frame.XDesktop  getDesktop()
                                 .frame.XModel  getDocument()
            .document.XScriptInvocationContext  getInvocationContext()
XSCRIPTCONTEXTの属性ツリーを出力させてみました。
デフォルトではコアインターフェイスの出力は抑制されているので、それを解除したいときは第2引数のリストに"core"を指定します。
In [4]:
ins.itree(XSCRIPTCONTEXT, ["core"])

pyuno object
├─.lang.XTypeProvider
│   │   [byte]  getImplementationId()
│   │   [type]  getTypes()
│   └─.uno.XInterface
│               void  acquire()
│                any  queryInterface( [in] type aType)
│               void  release()
└─.script.provider.XScriptContext
                        .uno.XComponentContext  getComponentContext()
                               .frame.XDesktop  getDesktop()
                                 .frame.XModel  getDocument()
            .document.XScriptInvocationContext  getInvocationContext()
コアインターフェイスも出力されました。
ただし重複して出力されないようにしているので.uno.XInterfaceインターフェイスは最初に出力されるインターフェイスにしかでてきません。
コアインターフェイスのうち.uno.XInterfaceインターフェイスだけ出力するようにすれば、上の例の場合は.lang.XTypeProvideは抑制されるので次の.script.provider.XScriptContextインターフェイスの枝 に.uno.XInterfaceインターフェイスがでてくることになります。
In [5]:
ins.itree(XSCRIPTCONTEXT, [".uno.XInterface"])

pyuno object
└─.script.provider.XScriptContext
      │               .uno.XComponentContext  getComponentContext()
      │                      .frame.XDesktop  getDesktop()
      │                        .frame.XModel  getDocument()
      │   .document.XScriptInvocationContext  getInvocationContext()
      └─.uno.XInterface
                  void  acquire()
                   any  queryInterface( [in] type aType)
                  void  release()
In [6]:
ctx = XSCRIPTCONTEXT.getComponentContext()
今度はコンポーネントコンテクストの属性ツリーをみてみます。
In [7]:
ins.itree(ctx)

pyuno object
├─.container.XNameContainer
│   │   void  insertByName( [in] string aName,
│   │                       [in]    any aElement
│   │            ) raises ( .lang.WrappedTargetException,
│   │                       .container.ElementExistException,
│   │                       .lang.IllegalArgumentException)
│   │   void  removeByName( [in] string Name
│   │            ) raises ( .lang.WrappedTargetException,
│   │                       .container.NoSuchElementException)
│   └─.container.XNameReplace
│         │   void  replaceByName( [in] string aName,
│         │                        [in]    any aElement
│         │             ) raises ( .lang.WrappedTargetException,
│         │                        .container.NoSuchElementException,
│         │                        .lang.IllegalArgumentException)
│         └─.container.XNameAccess
│               │        any  getByName( [in] string aName
│               │             ) raises ( .lang.WrappedTargetException,
│               │                        .container.NoSuchElementException)
│               │   [string]  getElementNames()
│               │    boolean  hasByName( [in] string aName)
│               └─.container.XElementAccess
│                              type  getElementType()
│                           boolean  hasElements()
└─.uno.XComponentContext
            .lang.XMultiComponentFactory  getServiceManager()
                                     any  getValueByName( [in] string Name)
コアインターフェイス以外を第2引数のリストに指定するとコアインターフェイスのときとは逆にそのインターフェイスの出力が抑制されることになります。
In [8]:
ins.itree(ctx, [".container.XNameReplace"])

pyuno object
├─.container.XNameContainer
│         void  insertByName( [in] string aName,
│                             [in]    any aElement
│                  ) raises ( .lang.WrappedTargetException,
│                             .container.ElementExistException,
│                             .lang.IllegalArgumentException)
│         void  removeByName( [in] string Name
│                  ) raises ( .lang.WrappedTargetException,
│                             .container.NoSuchElementException)
└─.uno.XComponentContext
            .lang.XMultiComponentFactory  getServiceManager()
                                     any  getValueByName( [in] string Name)
出力の抑制を指定したインターフェイスの枝のインターフェイスも出力抑制されます。
"com.sun.star"は省略してもしなくても同じ結果になります。
In [9]:
ins.itree(ctx, ["com.sun.star.uno.XInterface", "com.sun.star.container.XNameReplace"])

pyuno object
├─.container.XNameContainer
│         void  insertByName( [in] string aName,
│                             [in]    any aElement
│                  ) raises ( .lang.WrappedTargetException,
│                             .container.ElementExistException,
│                             .lang.IllegalArgumentException)
│         void  removeByName( [in] string Name
│                  ) raises ( .lang.WrappedTargetException,
│                             .container.NoSuchElementException)
└─.uno.XComponentContext
      │   .lang.XMultiComponentFactory  getServiceManager()
      │                            any  getValueByName( [in] string Name)
      └─.uno.XInterface
                  void  acquire()
                   any  queryInterface( [in] type aType)
                  void  release()
コアインターフェイスはリストに指定すると出力、それ以外のインターフェイスはリストに指定すると出力抑制になります。

参考にしたサイト


Core Interfaces to Implement - Apache OpenOffice Wiki
UNOコンポーネントのコアインターフェイスは9つあります。

HTML href link · Issue #6270 · ipython/ipython · GitHub
IPython Notebookからはスタートアップフォルダより下層のローカルファイルにはアクセスできないようです。

3.7 set(集合)型 -- set, frozenset
今回の修正にもPythonの集合型をとても便利に使いました。

次の関連記事:LibreOffice5(25)MRI - UNO Object Inspection Tool:その1

PR

0 件のコメント:

コメントを投稿