-
-
Save p--q/a1abde78b9da7d100104 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
# -*- coding: utf-8 -*- | |
def libreoffice54(): | |
obj = XSCRIPTCONTEXT.getDocument() # 調査対象のオブジェクトを取得。old-styleサービスの例。LibreOfficeドキュメントを開いておく必要がある。 | |
# obj = XSCRIPTCONTEXT.getDesktop().getCurrentFrame().getContainerWindow().getToolkit() # 調査対象のオブジェクトを取得。new-styleサービスの例。 | |
# obj = XSCRIPTCONTEXT.getComponentContext() # 調査対象のオブジェクトを取得。サービスがないオブジェクトの例。 | |
objinsp(obj) | |
def objinsp(obj): | |
from com.sun.star.uno.TypeClass import SERVICE, INTERFACE | |
tdm = XSCRIPTCONTEXT.getComponentContext().getByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager') # TypeDescriptionManagerをシングルトンでインスタンス化。 | |
st_omi = {'com.sun.star.uno.XInterface', 'com.sun.star.uno.XWeak', 'com.sun.star.lang.XTypeProvider'} # 結果を出力しないインターフェイス名の集合。'com.sun.star.uno.XInterface'は必ず指定が必要。 | |
st_s = set() # 起点となるサービスやインターフェイスを入れる集合型。 | |
if hasattr(obj, "getSupportedServiceNames"): # オブジェクトがサービスを持っているとき。 | |
st_ss = set(obj.getSupportedServiceNames()) # オブジェクトのサポートサービス名一覧の集合を得る。 | |
st_sups = set() # 親サービスを入れる集合。 | |
if len(st_ss) > 1: # サポートしているサービス名が複数ある場合。 | |
stack = st_ss.copy() # サポートサービス名をスタックに取得。(このスタックは集合型。) | |
while stack: # スタックがある間実行。 | |
std = tdm.getByHierarchicalName(stack.pop()) # スタックから要素を1つpopしてサービスのTypeDescriptionオブジェクトを取得。 | |
t_std = std.getMandatoryServices()+std.getOptionalServices() # 親サービスのタプルを取得。 | |
if t_std: # 親サービスがあるとき。 | |
st_s = set([i.Name for i in t_std]).difference(st_sups) # 親サービスのTypeDescriptionオブジェクトからサービス名を得て集合型で既に取得した親サービスにないものだけを取得。 | |
if st_s: | |
stack.update(st_s) # スタックに新たなサービスのみ追加。 | |
st_sups.update(st_s) # 既に取得した親サービスに追加。 | |
st_s = st_ss.difference(st_sups) # オブジェクトのサポートサービスのうち親サービスにないものだけにする=これがサービスの末裔。 | |
else: # サポートしているサービスがないときはインターフェイス名一覧を得る。 | |
if hasattr(obj, "getTypes"): # サポートしているインターフェイスがある場合。 | |
t_sid = obj.getTypes() # サポートインターフェイスのTypeDescriptionオブジェクトを取得。 | |
if t_sid: # サポートインターフェイスがあるとき。 | |
st_s = set([i.typeName for i in t_sid]).difference(st_omi) # 除外するインターフェイス名を除いてサポートインターフェイス名一覧を集合型で取得。 | |
if st_s: # 起点となるサービスかインターフェイスがあるとき。 | |
stack = sorted(list(st_s), reverse=True) # リストにして降順に並べてスタックに取得。 | |
lst_level = [0 for i in stack] # stackの要素すべてについて階層を取得。 | |
indent = " " # インデントを設定。 | |
while stack: # スタックがある間実行。 | |
j = stack.pop() # スタックからpop。 | |
level = lst_level.pop() # jの階層に1を加えて取得。 | |
branch = ["", ""] # 枝をリセット。 | |
if level > 1: # 階層が2以上のとき。 | |
for i in range(1, level): # 階層iから出た枝が次行の階層i-1の枝になる。 | |
if i in lst_level: # iは枝の階層ではなく、枝のより上の行にあるその枝がでた階層になる。 | |
branch[0] += "│ " # 縦枝を加える。 | |
else: | |
branch[0] += indent | |
if level > 0: # 階層が1以上のとき | |
if level in lst_level: # スタックに同じ階層にノードがあるとき。 | |
branch[1] = "├─" | |
else: | |
branch[1] = "└─" | |
print("".join(branch) + j) # 枝をつけて出力。 | |
td = tdm.getByHierarchicalName(j) # jのTypeDescriptionオブジェクトを取得。 | |
if td.getTypeClass() == SERVICE: # jがサービスのときtdはXServiceTypeDescriptionインターフェイスをもつ。 | |
t_std = td.getMandatoryServices()+td.getOptionalServices() # 親サービスを取得。 | |
if t_std: # 親サービスがあるとき。 | |
stack.extend(sorted([i.Name for i in t_std], reverse=True)) # 親サービス名を取得して降順に並べてスタックに追加。 | |
lst_level.extend([level + 1 for i in t_std]) # 階層を取得。 | |
itd = td.getInterface() # new-styleサービスのインターフェイスを取得。TypeDescriptionオブジェクト。 | |
if itd: # new-styleサービスのインターフェイスがあるとき。 | |
t_i = itd, # XInterfaceTypeDescription2インターフェイスをもつTypeDescriptionオブジェクト。 | |
else: # new-styleサービスのインターフェイスがないときはold-styleサービスのインターフェイスを取得。 | |
t_i = td.getMandatoryInterfaces() + td.getOptionalInterfaces() # XInterfaceTypeDescriptionインターフェイスをもつTypeDescriptionオブジェクト。 | |
elif td.getTypeClass() == INTERFACE: # インターフェイスのとき。XInterfaceTypeDescription2インターフェイスをもつTypeDescriptionオブジェクト。 | |
t_i = td.getBaseTypes()+td.getOptionalBaseTypes() # さらなる親インターフェイスのリストをo_omiを除いて取得。 | |
if t_i: # 親インターフェイスがあるとき。(TypeDescriptionオブジェクト) | |
st_i = set([i.Name for i in t_i]).difference(st_omi) # st_omiを除いてインターフェイス名を取得。 | |
t_i = tuple() # 次のループのためにインターフェイスのTypeDescriptionオブジェクトの入れ物を初期化。 | |
if st_i: # インターフェイス名の集合型があるとき。 | |
stack.extend(sorted(list(st_i), reverse=True)) # 集合型をリストに変換して降順にしてスタックに追加。 | |
lst_level.extend([level + 1 for i in list(st_i)]) # 階層を取得。 | |
st_omi.update(st_i) # すでにでてきたインターフェイス名をst_omiに追加して次は使わないようにする。 | |
if __name__ == "__main__": | |
import unopy | |
XSCRIPTCONTEXT = unopy.connect() | |
if not XSCRIPTCONTEXT: | |
print("Failed to connect.") | |
import sys | |
sys.exit(0) | |
libreoffice54() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment