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

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


今回はダイアログエディタとは直接関係ない話です。LibreOffice5(22)ダイアログエディタでGUIを作成しPythonで利用する:その2で疑問に思ったDialogProviderサービスのインターフェイスを介さないメソッドについて調べました。

DialogProviderサービスはXInitializationインターフェイスを実装しているのでcreateInstanceWithArgumentsAndContext()でインスタンス化できる

com.sun.star.awt.DialogProviderサービスのインスタンスdpの属性をみてみます。
In [9]:
ins.itree(dp)

pyuno object
├─.awt.ContainerWindowProvider
│   └─.awt.XContainerWindowProvider
│               .awt.XWindow  createContainerWindow( [in]           string URL,
│                                                    [in]           string WindowType,
│                                                    [in] .awt.XWindowPeer xParent,
│                                                    [in]  .uno.XInterface xHandler
│                                         ) raises ( .lang.IllegalArgumentException)
├─.awt.DialogProvider
│   └─.awt.XDialogProvider
│               .awt.XDialog  createDialog( [in] string URL
│                                ) raises ( .lang.IllegalArgumentException)
├─.awt.DialogProvider2
│   └─.awt.XDialogProvider2
│               .awt.XDialog  createDialogWithArguments( [in]              string URL,
│                                                        [in] [.beans.NamedValue] Arguments
│                                             ) raises ( .lang.IllegalArgumentException)
│               .awt.XDialog  createDialogWithHandler( [in]          string URL,
│                                                      [in] .uno.XInterface xHandler
│                                           ) raises ( .lang.IllegalArgumentException)
├─.lang.XInitialization
│         void  initialize( [in] [any] aArguments
│                ) raises ( .uno.Exception)
└─.lang.XServiceInfo
              string  getImplementationName()
            [string]  getSupportedServiceNames()
             boolean  supportsService( [in] string ServiceName)
DialogProviderサービスに加えてContainerWindowProviderサービスとDialogProvider2サービスが実装されています。
さらにそれらサービスが持つインターフェイス以外にXInitializationインターフェイスとXServiceInfoインターフェイスも実装しています。
このXInitializationインターフェイスのinitialize()メソッドが実装されているとcreateInstanceWithArgumentsAndContext()メソッドが使えて サービスをインスタンス化するときに引数を渡せます。 (XInitialization - Apache OpenOffice Wiki)
createInstanceWithArgumentsAndContext()でインスタンス化されるPythonのUNOコンポーネントの作成例をA. Python-UNO - N->N->Nの「コンポーネント」の項に見つけました。
Create Instance with Arguments - Apache OpenOffice Wikiの最後を読むとcreateInstanceWithArgumentsAndContext()でインスタンス化するためにXInitializationインターフェイスの実装は必須ではないようですが、XInitializationインターフェイスが実装されていればとりあえずcreateInstanceWithArgumentsAndContext()でインスタンス化できるといえそうです。
実際にDialogProviderサービスをcreateInstanceWithArgumentsAndContext()でインスタンス化している例をさがしてみるとOOoPython/Dialogs - ...?にありました。
createInstanceWithArgumentsAndContext()でDialogProviderサービスをインスタンス化しているのですが、インスタンス化するときの引数を見比べてみるとこれはDialogProviderサービスのcreateWithModelAndScripting()の引数と一致します。
APIリファレンスにはcreateWithModelAndScripting()メソッドの戻り値の型も解説も書いてありませんが、このメソッドが"create"するのはDialogProviderサービス自身のようです。
これらのメソッドはインターフェイスを介さないのでTypeDescriptionオブジェクトから取得できないようです。
他にも同様の例がないか探してみたところcom.sun.star.ui.dialogs.FilePickerサービスのcreateWithMode()メソッドを見つけました。
Python Marco - File Dialog für Datei Export - LibreOfficeForum.deでDialogProviderサービスと同様にcreateInstanceWithArgumentsAndContext()で引数をつけてインスタンス化されています。
(2017.8.29追記。FilePickerについてLibreOffice5(77)FilePickerのTemplateDescriptionを実行してみるでやりました。)
LibreOffice 4.5 SDK - Developer's Guide ExamplesのDialogComponent.javaではcom.sun.star.awt.DialogProvider2サービスがcreateInstanceWithArgumentsAndContext()でModelを引数にインスタンス化されていますが、APIリファレンスではそれに該当するメソッドはなくこれはDialogProviderサービスのcreateWithModel()メソッドを使っているようです。
APIリファレンスの継承図を見ているだけではDialogProvider2サービスがXDialogProviderインターフェイスを継承しているのはわかりますが、DialogProviderサービスが直接持っているメソッドを継承していることはわかりません。
今回はここまでわかりましたがまだcreateInstanceWithArgumentsAndContext()の使いどころが私には理解できないです。

ダイアログエディタで作成したダイアログのオブジェクトのサポートサービス名に実装サービス名が含まれる

LibreOffice5(22)ダイアログエディタでGUIを作成しPythonで利用する:その2のIn[8]で取得したdlg_crtlの属性を調べてみます。
In [10]:
ins.itree(dlg_ctrl)
---------------------------------------------------------------------------
com.sun.star.container.NoSuchElementExceptionTraceback (most recent call last)
<ipython-input-10-5b37b002d772> in <module>()
----> 1 ins.itree(dlg_ctrl)

/home/pq/.config/libreoffice/4/user/Scripts/python/unoinsp.py in itree(self, obj)
     58         else:
     59             self.lst_output.append(self.root)
---> 60             self._ext_desc(obj)
     61         self.lst_output.append("</tt>")  # 等速フォントのタグを閉じる。
     62         from IPython.display import display, HTML  # IPython Notebook用

/home/pq/.config/libreoffice/4/user/Scripts/python/unoinsp.py in _ext_desc(self, obj)
    120             st_sups = set()  # 親サービスを入れる集合。
    121             if len(st_ss) > 1:  # サポートしているサービス名が複数ある場合。
--> 122                 self.stack = [self.tdm.getByHierarchicalName(i) for i in st_ss]  # サポートサービスのTypeDescriptionオブジェクトをスタックに取得。
    123                 while self.stack:  # スタックがある間実行。
    124                     j = self.stack.pop()  # サービスのTypeDescriptionオブジェクトを取得。

/home/pq/.config/libreoffice/4/user/Scripts/python/unoinsp.py in <listcomp>(.0)
    120             st_sups = set()  # 親サービスを入れる集合。
    121             if len(st_ss) > 1:  # サポートしているサービス名が複数ある場合。
--> 122                 self.stack = [self.tdm.getByHierarchicalName(i) for i in st_ss]  # サポートサービスのTypeDescriptionオブジェクトをスタックに取得。
    123                 while self.stack:  # スタックがある間実行。
    124                     j = self.stack.pop()  # サービスのTypeDescriptionオブジェクトを取得。

com.sun.star.container.NoSuchElementException: stardiv.vcl.control.Dialog
エラーがでて属性ツリーが取得できません。
原因はdlg_ctrlオブジェクトがgetSupportedServiceNames()メソッドでIDLにない実装サービス名のstardiv.vcl.control.Dialogを返すのが原因です。
In [11]:
dlg_ctrl
Out[11]:
pyuno object (com.sun.star.awt.XDialog)0x956bc8c{implementationName=stardiv.Toolkit.UnoDialogControl, supportedServices={com.sun.star.awt.UnoControlDialog,stardiv.vcl.control.Dialog}, supportedInterfaces={com.sun.star.awt.XUnoControlDialog,com.sun.star.awt.XWindowListener,com.sun.star.lang.XTypeProvider,com.sun.star.container.XContainerListener,com.sun.star.util.XChangesListener,com.sun.star.util.XModifyListener,com.sun.star.lang.XTypeProvider,com.sun.star.awt.XUnoControlContainer,com.sun.star.awt.XControlContainer,com.sun.star.container.XContainer,com.sun.star.container.XIdentifierContainer,com.sun.star.lang.XTypeProvider,com.sun.star.awt.XControl,com.sun.star.awt.XWindow2,com.sun.star.awt.XView,com.sun.star.beans.XPropertiesChangeListener,com.sun.star.lang.XServiceInfo,com.sun.star.accessibility.XAccessible,com.sun.star.util.XModeChangeBroadcaster,com.sun.star.awt.XUnitConversion,com.sun.star.awt.XStyleSettingsSupplier,com.sun.star.lang.XTypeProvider,com.sun.star.uno.XWeak,com.sun.star.uno.XAggregation}}
stardiv.vcl.control.Dialog以外にTypeDescriptionオブジェクトを取得できない属性はないようですので実装サービス名は弾くようにunoinsp.pyを修正することにします。

参考にしたサイト


XInitialization - Apache OpenOffice Wiki
createInstanceWithArgumentsAndContext()でインスタンス化するためのインターフェイス。

A. Python-UNO - N->N->N
XInitializationインターフェイスのPythonの実装例。

Create Instance with Arguments - Apache OpenOffice Wiki
JavaでのcreateInstanceWithArgumentsAndContext()の解説ですがFactoryHelperというのがよくわかりません。

OOoPython/Dialogs - ...?
DialogProviderサービスのcreateWithModelAndScripting()メソッドの使用例と思われるもの。

Python Marco - File Dialog für Datei Export - LibreOfficeForum.de
com.sun.star.ui.dialogs.FilePickerサービスのcreateWithMode()メソッドの使用例と思われるもの。

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

PR

0 件のコメント:

コメントを投稿