-
-
Save p--q/a45198b8be4e9ae20105 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def libreoffice52(): | |
# obj = XSCRIPTCONTEXT.getDocument() # 調査対象のオブジェクトを取得。old-styleサービスの例。LibreOfficeドキュメントを開いておく必要がある。 | |
obj = XSCRIPTCONTEXT.getDesktop().getCurrentFrame().getContainerWindow().getToolkit() # 調査対象のオブジェクトを取得。new-styleサービスの例。 | |
# obj = XSCRIPTCONTEXT.getComponentContext() # 調査対象のオブジェクトを取得。サービスがないオブジェクトの例。 | |
ObjInsp(obj).get_dic() | |
class ObjInsp: | |
def __init__(self, obj): | |
self.s_dic = dict() # サービス辞書。key:子サービス名、value:親サービスのタプル。以下辞書のvalueは全てXTypeDescriptionオブジェクトのタプル。 | |
self.sa_dic = dict() # サービス属性辞書。key:サービス名、value:サービスの属性のタプル。 | |
self.i_dic = dict() # インターフェイス辞書。key:子インターフェイス名または子サービス名、value:親インターフェイスのタプル。 | |
self.im_dic = dict() # メソッド辞書。key:インターフェイス名、value:インターフェイスのメソッドのタプル。 | |
self.s_omi = {'com.sun.star.uno.XInterface', 'com.sun.star.uno.XWeak', 'com.sun.star.lang.XTypeProvider'} # 結果を出力しないインターフェイス名の集合。'com.sun.star.uno.XInterface'は必ず指定が必要。 | |
self.tdm = XSCRIPTCONTEXT.getComponentContext().getByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager') # TypeDescriptionManagerをシングルトンでインスタンス化。 | |
if hasattr(obj, "getSupportedServiceNames"): # hasattr()は属性の有無をチェックするPythonの組み込み関数。 | |
t_ss = obj.getSupportedServiceNames() # サポートしているサービス名のタプルを取得。 | |
if t_ss: # サポートしているサービス名がある場合。 | |
for ss in t_ss: # 各サービス名について親のサービスを得る。 | |
std = self.tdm.getByHierarchicalName(ss) # サービス名からXServiceTypeDescription2インターフェイスをもつオブジェクトを取得。 | |
self.sa_dic_g(std) # サービス属性辞書追加関数。 | |
self.i_dic_g2(std) # サービスからインターフェイス辞書追加関数。 | |
t_std = std.getMandatoryServices()+std.getOptionalServices() # 直に継承しているサービス(親サービス)のタプルを得る。 | |
if t_std: self.s_dic[std.Name] = t_std # 親サービスがあるときサービス辞書に追加。 | |
lst_buf = t_std # バッファリストに親サービスのタプルを代入。有無をみるだけなのでリストに変換しない。 | |
while lst_buf: # バッファリストがある間継続。 | |
lst_buf = list() # バッファリストを初期化。 | |
for std in t_std: # 各親サービスについて。 | |
self.sa_dic_g(std) # サービス属性辞書追加関数。 | |
self.i_dic_g2(std) # サービスからインターフェイス辞書追加関数。 | |
t_std = std.getMandatoryServices()+std.getOptionalServices() # さらなる親サービスを取得。 | |
if t_std: # 親サービスがあるなら。 | |
self.s_dic[std.Name] = t_std # サービス辞書に追加。 | |
lst_buf.extend(t_std) # バッファリストに親サービスのタプルを追加。 | |
t_std = lst_buf # バッファリストから次の階層のサービスのリストを得る。 | |
self.lst_des(t_ss) # サービス名からサービスの末裔を得る関数。 | |
else: # サポートしているサービスがないときはインターフェイス名一覧を得る。 | |
if hasattr(obj, "getTypes"): | |
lst_si = obj.getTypes() | |
if lst_si: # サポートしているインターフェイスがあるとき。 | |
s_si = set([i.typeName for i in obj.getTypes()]) # インターフェイス名一覧を集合型に変換。 | |
self.lst_des = s_si.intersection(s_si ^ self.s_omi) # s_omiのインターフェイス名を除いてインターフェイス名(=末裔)をリストで取得。 | |
if self.lst_des: # 残ったインターフェイスのリストがあるとき | |
lst_itd = list(map(self.tdm.getByHierarchicalName, self.lst_des)) # lst_siの要素のインターフェイス名からXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。 | |
self.i_dic_g(lst_itd) | |
def sa_dic_g(self, std): # サービス辞書追加関数。 | |
t_sp = std.Properties # サービスからXPropertyTypeDescriptionインターフェイスをもつオブジェクトのタプルを取得。 | |
if t_sp: self.sa_dic[std.Name] = t_sp # サービス属性辞書に追加。 | |
def im_dic_g(self, itd): # メソッド辞書追加関数。 | |
t_im = itd.Members # XInterfaceMemberTypeDescription型のオブジェクトのタプルを取得。メンバーがメソッドならXInterfaceMethodTypeDescriptionインターフェイスをもつ、属性ならXInterfaceAttributeTypeDescription2 インターフェイスをもつ。 | |
if t_im: self.im_dic[itd.Name] = t_im # メソッドがあるならメソッド辞書に追加。 | |
def lst_des(self, t_ss): # サービス名からサービスの末裔を得る関数。 | |
if self.s_dic: # サービス辞書に項目があるとき。 | |
s_ss = set(t_ss) # サービス名のリストを集合型に変換。 | |
self.lst_des = s_ss.intersection(s_ss ^ set([j.Name for i in self.s_dic.values() for j in i])) # オブジェクトから得たサービスのうち、サービス辞書のvalueにない(親になっていない)サービス名(=末裔)をリストで取得。 | |
else: # サービス辞書に項目がないとき | |
self.lst_des = t_ss # サポートしているサービス名を末裔とする。 | |
def i_dic_g2(self, std): # サービスからインターフェイス辞書追加関数。 | |
if std.isSingleInterfaceBased(): # new-style(single-interface–based)サービスのとき | |
lst_itd = [std.getInterface()] # サービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトでリストにして取得。 | |
else: # old-style(accumulation-based)サービスのとき | |
lst_itd = [i for i in std.getMandatoryInterfaces() + std.getOptionalInterfaces() if i.Name not in self.s_omi] # s_omiを除いてサービスがもつインターフェイスをXInterfaceTypeDescription2インターフェイスをもつオブジェクトのリストを取得。 | |
if lst_itd: self.i_dic[std.Name] = lst_itd # サービス名をkeyにしてその親インターフェイスのリストを得る。 | |
self.i_dic_g(lst_itd) # インターフェイス辞書追加関数。 | |
def i_dic_g(self, lst_itd): # インターフェイス辞書追加関数。 | |
lst_buf = lst_itd # バッファリストに親インターフェイスのタプルを代入。有無をみるだけなのでリストに変換しない。 | |
while lst_buf: # バッファリストがある間継続。 | |
lst_buf = list() # バッファリストを初期化。 | |
for itd in lst_itd: # 各親インターフェイスについて。 | |
self.im_dic_g(itd) # メソッド辞書追加関数。 | |
lst_itd = [i for i in itd.getBaseTypes()+itd.getOptionalBaseTypes() if i.Name not in self.s_omi] # さらなる親インターフェイスのリストをo_omiを除いて取得。 | |
if lst_itd: # 親インターフェイスがあるなら。 | |
self.i_dic[itd.Name] = lst_itd # インターフェイス辞書に追加。 | |
lst_buf.extend(lst_itd) # バッファリストに親インターフェイスのリストを追加。 | |
lst_itd = lst_buf # バッファリストから次の階層のインターフェイスのリストを得る。 | |
def get_dic(self): # 辞書の内容を出力する | |
print(self.lst_des) # 最初の階層を出力。 | |
self.lst_des = list(map(self.tdm.getByHierarchicalName, self.lst_des)) # XTypeDescriptionオブジェクトに変換。 | |
dic = self.s_dic # サービス辞書を取得。 | |
if dic: # 辞書があるのなら。 | |
# self.sa_dic_out(self.lst_des) # サービス属性辞書出力関数。 | |
self.i_dic_out(self.lst_des) # インターフェイス辞書出力関数。 | |
lst_buf = True # whileループの継続判定に使うリスト。 | |
lst_val = self.lst_des # whileループ内で展開するリスト。 | |
while lst_buf: | |
lst_buf = list() | |
for i in lst_val: | |
if i.Name in dic: | |
lst_val = list(dic[i.Name]) | |
lst_val.sort(key=lambda x: x.Name) # リストの要素のオブジェクトのName属性でソートする。 | |
print(i.Name, [j.Name for j in lst_val]) | |
# del dic[i.Name] # 出力したkeyを辞書から削除。 | |
# self.sa_dic_out(lst_val) | |
self.i_dic_out(lst_val) | |
lst_buf.extend(lst_val) | |
lst_val = lst_buf | |
else: | |
self.i_dic_out(self.lst_des) | |
def sa_dic_out(self, lst_val): | |
dic = self.sa_dic | |
if dic: | |
for i in lst_val: | |
if i.Name in dic: | |
lst_val = list(dic[i.Name]) | |
lst_val.sort(key=lambda x: x.Name) | |
print(i.Name, [j.Name for j in lst_val]) | |
# self.im_dic_out(lst_val) | |
# del dic[i.Name] # 出力したkeyを辞書から削除。'com.sun.star.frame.XModel'が複数でてくるため。 | |
lst_buf = lst_val | |
while lst_buf: | |
lst_buf = list() | |
for i in lst_val: | |
if i.Name in dic: | |
lst_val = list(dic[i.Name]) | |
lst_val.sort(key=lambda x: x.Name) | |
print(i.Name, [j.Name for j in lst_val]) | |
# self.im_dic_out(lst_val) | |
# del dic[i.Name] # 出力したkeyを辞書から削除。 | |
lst_buf.extend(lst_val) | |
lst_val = lst_buf | |
def i_dic_out(self, lst_val): | |
dic = self.i_dic | |
if dic: | |
lst_buf = True | |
while lst_buf: | |
lst_buf = list() | |
for i in lst_val: | |
if i.Name in dic: | |
lst_val = list(dic[i.Name]) | |
lst_val.sort(key=lambda x: x.Name) | |
print(i.Name, [j.Name for j in lst_val]) | |
# self.im_dic_out(lst_val) | |
# del dic[i.Name] # 出力したkeyを辞書から削除。 | |
lst_buf.extend(lst_val) | |
lst_val = lst_buf | |
def im_dic_out(self, lst_val): | |
dic = self.im_dic | |
if dic: | |
for i in lst_val: | |
if i.Name in dic: | |
lst_val = list(dic[i.Name]) | |
lst_val.sort(key=lambda x: x.Name) | |
print(i.Name, [j.MemberName for j in lst_val]) | |
# del dic[i.Name] # 出力したkeyを辞書から削除。 | |
lst_buf = lst_val | |
while lst_buf: | |
lst_buf = list() | |
for i in lst_val: | |
if i.Name in self.im_dic: | |
lst_val = list(dic[i.Name]) | |
lst_val.sort(key=lambda x: x.Name) | |
print(i.Name, [j.MemberName for j in lst_val]) | |
# del dic[i.Name] # 出力したkeyを辞書から削除。 | |
lst_buf.extend(lst_val) | |
lst_val = lst_buf | |
if __name__ == "__main__": | |
import unopy | |
XSCRIPTCONTEXT = unopy.connect() | |
if not XSCRIPTCONTEXT: | |
print("Failed to connect.") | |
import sys | |
sys.exit(0) | |
libreoffice52() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment