Skip to content

Instantly share code, notes, and snippets.

@p--q
Last active August 29, 2015 14:04
Show Gist options
  • Save p--q/6c46c6b6c00ff8d5bca9 to your computer and use it in GitHub Desktop.
Save p--q/6c46c6b6c00ff8d5bca9 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
def libreoffice53():
obj = XSCRIPTCONTEXT.getDocument() # 調査対象のオブジェクトを取得。old-styleサービスの例。LibreOfficeドキュメントを開いておく必要がある。
# obj = XSCRIPTCONTEXT.getDesktop().getCurrentFrame().getContainerWindow().getToolkit() # 調査対象のオブジェクトを取得。new-styleサービスの例。
# obj = XSCRIPTCONTEXT.getComponentContext() # 調査対象のオブジェクトを取得。サービスがないオブジェクトの例。
objinsp(obj)
def objinsp(obj):
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))[::-1] # リストにして降順に並べてスタックに取得。
while stack: # スタックがある間実行。
j = stack.pop() # スタックからpop。
print(j) # 出力。
td = tdm.getByHierarchicalName(j) # jのTypeDescriptionオブジェクトを取得。
if hasattr(td, "getMandatoryServices"): # jがサービスのときtdはXServiceTypeDescriptionインターフェイスをもつ。
t_std = td.getMandatoryServices()+td.getOptionalServices() # 親サービスを取得。
if t_std: # 親サービスがあるとき。
stack.extend(sorted([i.Name for i in t_std])[::-1]) # 親サービス名を取得して降順に並べてスタックに追加。
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 hasattr(td, "getBaseType"): # インターフェイスのとき。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))[::-1]) # 集合型をリストに変換して降順にしてスタックに追加。
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)
libreoffice53()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment