-
Notifications
You must be signed in to change notification settings - Fork 7
Macros_ja
MRI には MRI 自身をコントロールするマクロ機能があります。このマクロは Python で書くことができます。
マクロではすべての MRI の機能にアクセスできますが、オフィースがクラッシュするかもしれません。しかし、MRI は一般的なユーザーのためのものではないので、深刻な問題ではありません。
MRI のマクロは MRI の実装に深く関係しています。そのため、MRI の内部構造を知らなければマクロを書くことは難しいでしょう。このドキュメントでは、重要な部分のみ説明しています。詳細については MRI のコードを参照してください。
MRI ウィンドウを開いてください。ウィドウのメインメニューに Macros メニュー項目があります。このメニューの項目は動的に作成されます。
マクロは以下のディレクトリに保存されている必要があります。
- 拡張機能のレポジトリ、これは MRI に付属するものです。
- ユーザーのレポジトリ、これはメインメニューの Tools - Configuration... から設定できます。
MRI マクロが含まれているファイルを持っているなら、それをマクロディレクトリに配置する簡単な方法が用意されています。Macros - bundle.py - Import Macros を選択してください。選択したファイルがユーザーのマクロ用ディレクトリへコピーされます。
マクロファイルが ZIP、tar.gz, tar.bz2 アーカイブに圧縮されている場合、解凍されて内容がインポートされます。また、README ファイルがアーカイブに含まれている場合、インポートされる前にその内容がライセンスダイアログに表示されます。
マクロメニューは動的に作成されますが、一旦読み込まれると静的なものになります。マクロレポジトリに変更があった場合、再度読み込んでください。Macros - bundle.py - Reload Macros を選択してください。この項目は既に読み込まれた項目を削除して再度読み込みます。
マクロは Python で書き、ファイルの拡張子として ".py" をつけ、ユーザーのレポジトリに保存してください。レポジトリについては前出の項目を参照してください。
MRI で実行できるマクロには二種類あります。一つは、MRI 自身を拡張する簡単なコードです。もうひとつは、記録可能なマクロで、項目に対して行われた操作がコードとして生成されます。このドキュメントでは、前者を「普通のマクロ」と呼び、後者を「アクションマクロ」と呼ぶことにします。
普通のマクロの例を示します。
# # hello.py example
# __all__ の項目がマクロメニューに表示されます。
# リスト中の順番は保持され、
# 空の項目は区切り線になります。
__all__ = ["hello_world", "", "another_function"]
def hello_world(mri):
""" Greeting
Description of this method """
# The document string of the function is used to specify
# its title and description. First line is used for title of it
# and second line is used for description of the function.
mri.message("Hello World!")
def another_function(mri):
pass
def private_function(mri):
""" This function is not shown in the list of function. """
関数のドキュメント文字列は、メニュー項目または他の場所でタイトルおよびツールチップテキストとして使用されます。
変数はファイルからエクスポートされている関数のリストを取得するために使用されます。前出の例では、hello_world と another_function のみが hello.py 項目のサブ項目として表示され、空の文字列によって指定された区切り線で区切られます。
現在のターゲットを使用する例を示します。ここで呼び出したメソッドはコードジェネレータが記録しません。
def another_example(mri):
target = mri.current.target # 現在のターゲットの実際の値
sheets = target.getSheets()
sheet = sheets.getSheets()
# To do something
アクションマクロは API 呼び出しをコードとして記録できます。Entry のインスタンスを利用して作業する点が普通のマクロとは異なります。履歴に項目がないエントリーを利用する場合、ジェネレータステートメントで履歴に登録してください。
簡単な例を示します。
def action_macro(mri):
current = mri.current # current is a Writer document object
text = current.getText()
cursor = text.createTextCursor()
サービスのインスタンスなど、新しいインスタンスで作業する場合、履歴に登録してください。
def macro_test(mri):
current = mri.current
transformer = mri.create_service(
"com.sun.star.util.URLTransformer")
yield current, transformer
アクションマクロとそれを利用するコードジェネレータには様々な制限があります。例えば、リスナーのような独自の UNO コンポーネントはアクションマクロで利用できません。
すべてのマクロは現在の MRI インスタンスを最初の引数として受け取ります。その値は、MRI のコアプログラムです。MRI インスタンスはユーザーインターフェースをサポートしていません。MRI のウィンドウは ui インスタンス変数を通じてアクセスできます。
MRI インスタンスはインスタンス変数に様々な値を保持しています。
変数 | 型 | 説明 |
ctx | pyuno | コンポーネントコンテキスト。 |
config | mytools_Mri.config.Config | 設定 |
web | mytools_Mri.web.IDL | ウェブページを開くウェブブラウザクラス。 |
engine | mytools_Mri.engine.Engine | イントロスペクションとリフレクション。 |
history | mytools_Mri.node.Root | 履歴階層。 |
current | mytools_Mri.engine.Entry | 現在のエントリー。 |
cg | mytools_Mri.cg.CodeGenerator | コードジェネレータの管理。 |
mode | bool | ノーマルモードで True、False でマクロモード。 |
open_new | bool | True の場合、次のターゲットは新しい MRI で開きます。 |
macros | mytools_Mri.macros.Macros | マクロの管理。 |
ui | mytools_Mri.ui.MRIUi | UI インスタンス。 |
以下のメソッドは Entry のインスタンスを返し、メソッドの呼び出しに応じてコードのエントリーを生成します。
get_component_context() -> Entry
コンポーネントコンテキストを返します。
assign_element(k, value, append=False) -> None
現在のシークエンスに要素を設定します。この関数は Entry のインスタンスの [] メソッドによって呼び出されます。
create_service(name, *args, **kwds) -> Enry | pyuno
名前で指定されたサービスのインスタンスを返します。nocode=True が指定された場合、サービスのインスタンスの pyuno オブジェクトが返されます。
create_struct(name, *args, **kwds) -> Entry | pyuno
名前で指定された構造体の新しいインスタンスを返します。nocode=True が指定された場合、構造体のオブジェクトが返されます。
create_sequence(type_name, length, var=None) -> Entry
型名と長さを指定して作成された新しいシークエンスを返します。
declare_variable(type_name, value) -> Entry
指定した名前で変数を生成してコードにエントリーを追加します。
MRI は ctx インスタンス変数に css.uno.XComponentContext インターフェースを保持しています。新しい UNO サービスのインスタンスを作成するために使用できます。
MRI keeps current target in current instance variable, which is instance of mytools_Mri.engine.Entry class.
エンジンは UNO オブジェクトの情報を取得するためのコアオブジェクトです。css.beans.Introspection, css.reflection.CoreReflection および css.reflection.TypeDescription サービスを使用しており、mytools_Mri.engine.Engine クラスで実装されています。エンジンのインスタンスは MRI のエンジンインスタンス変数からアクセスできます。
def use_engine(mri):
""" Shows type name of the current target. """
engine = mri.engine
current = mri.current
mri.ui.message(engine.get_type_name(current))
ウェブオブジェクトは設定でユーザーの指定したウェブブラウザで上生ページを開く手助けをしてくれます。mytools_Mri.web.IDL クラスで実装されています。
def open_url(mri):
""" Allows to open any URL in your web browser. """
url = "http://example.com/"
mri.web.open_url(url)
def open_ref(mri):
""" Open IDL reference with its name,
second argument is optional. """
idl = "com.sun.star.awt.Rectangle"
name = "X"
mri.web.open_idl_reference(idl, name)
mytools_Mri.ui.MRIUi クラスは MRI のウィンドウを管理しています。
変数 | 型 | 説明 |
ctx | pyuno | コンポーネントコンテキスト。 |
main | mytools_Mri.MRI | MRI インスタンス。 |
desktop | pyuno | デスクトップインスタンス。 |
listeners | dict | リスナーインスタンス。 |
property_mode | bool | True の場合プロパティ値を設定、それ以外で取得。 |
tree | mytools_Mri.ui.pages.HistoryTreeUi | ツリー状に履歴を表示するサブウィンドウ。 |
dlgs | mytools_Mri.ui.dialogs.Dialogs | ダイアログを提供します。 |
status_eraser | threading.Timer | ステータス表示を消去するタイマー。 |
frame | pyuno | MRI ウィンドウのフレーム。 |
cont | pyuno | MRI ウィンドウのコンテナウィンドウ。 |
pages | mytools_Mri.ui.pages.InfoUi/GridUi | コントロールの内容へのアクセスを提供。 |
mytools_Mri.ui.dialogs.Dialogs クラスにいくつかダイアログが定義されています。それらのダイアログは MRIUi クラスのインスタンスの dlgs インスタンス変数から利用できます。
def dialog_select(mri):
items = ("Item 1", "Item 2", "Item 3", "Item 1")
item = mri.ui.dlgs.dialog_select(items, "Title")
mri.ui.dlgs.dialog_info("%s is selected. " % item)
dialog_select メソッドの二番目の引数はダイアログのタイトルを指定します。上記の場合、二つの Item 1 項目があり、そのどちらが選択されたかどうかを知るには、三番目の引数に True を指定してください。その場合、返り値が選択された値のインデックスになります。キャンセルされた場合、None が返ります。
ユーザーによるテキストの入力を取得したい場合、入力ダイアログを表示する dialog_input メソッドを使用してください。
def dialog_input(mri):
text = mri.ui.dlgs.dialog_input(
"Service Name", "Input a service name.",
"com.sun.star.awt.")
mri.ui.message(text)
履歴からエントリーを選択させるダイアログもあります。
def history_selector(mri):
entry = mri.ui.dlgs.history_selector("Select Entry")
if entry:
mri.ui.message(entry.name)
ダイアログになにかを表示したい場合や、ユーザーに選択を求める場合、message メソッドが用意されています。このメソッドは css.awt.XMessageBoxFactory へのショートカットを提供します。詳細はリファレンスを参照してください。このメソッドの定義は次のようになっています。
def message(self, message, title="", type="messbox", buttons=1):
Entry クラスは MRI がインスペクトする現在または他のターゲットを保持するためのクラスです。例えば、現在のターゲットは MRI インスタンスの current インスタンス変数からアクセスできます。Entry クラスは mytools_Mri.engine モジュールで定義されており、継承構造は以下のようになっています。
mytools_Mri.engine.Entry <
(mytools_Mri.engine.EntryBase, mytools_Mri.node.Node)
次の表に Entry クラスのインスタンス変数についてまとめます。
変数 | 型 | 説明 |
target | object | このインスタンスでラップされている実際の値。 |
inspected | pyuno | css.beans.XIntrospectionAccess インターフェース。 |
type | pyuno | css.reflection.CoreReflection による IDL 型。 |
mri | mytools_Mri.MRI | 生きている MRI インスタンスへの参照。 |
code_entry | mytools_Mri.cg.CodeEntry | コード生成のための情報を保持。 |
次の表にある機能をもつ関数を提供しています。
メソッド | 説明 |
get_target() | 実際の値を取得するためにターゲットのインスタンス変数を使用してください。 |
has_interface(name) | 指定したインターフェースをエクスポートしているかどうかを確認します。 |
supports_service(name) | ターゲットが指定したサービスをサポートしているかどうかを確認します。 |
append(obj) | obj をリストに追加します。エントリーが MRI インスタンスの create_sequence メソッドで作成されたリストの場合のみ動作します。 |
MRIUi の pages インスタンス変数は mytools_Mri.pages.InfoUi または GridUi インスタンスを保持しています。どちらを保持しているかどうかは、MRI ウィンドウが表示しているコントロールに依存します。これらのクラスの継承構造は少し複雑です。それらの継承構造を以下に示します。すべてのクラスは mytools_Mri.ui.pages モジュールで定義されています。
InfoUi < (Ui, PageStatus,
Pages < PagesBase)
GridUi < (Ui, PageStatus,
GridPages < GridPagesBase < PagesBase)
メソッド | 説明 |
get_type_name() | 型名を返します。 |
set_type_name(name) | 型名を設定します。 |
get_imple_name() | 実装名を返します。 |
set_imple_name(name) | 実装名を設定します。 |
get_code() | 現在のコードテキストを取得します。 |
set_code(txt) | 現在のコードテキストを設定します。 |
PageStatus クラスは情報ページの更新状態を管理しています。
PagesBase クラスは子クラスによって提供されるべき複数のメソッドを提供しています。それらのメソッドは情報コントロールへのアクセスを提供しています。Properties: 0, Methods: 1, Interfaces: 2, Services 3 となっています。
メソッド | 説明 |
get_selected(index=None) | 選択されているテキストを返します。 |
get_current_line(index=None) | 現在の行を返します。 |
get_first_word(index=None) | 現在の行の最初の単語を返します。 |
activate(index) | アクティブページのインデックスを指定します。 |
get_active() | アクティブページのインデックスを取得します。 |
search(search_text, index=None) | 検索します。 |
MRI は独自のコントローラを使用しており、ウィンドウのフレームに結び付けられています。そのコントローラは Python で書かれており、他の MRI のインスタンスへのアクセスを提供しています。すべての MRI ウィンドウはデスクトップに登録されており、それらは css.frame.XFrame インターフェースからアクセスできます。
def do_something_with(mri):
# find MRI window from the desktop
found = None
frames = mri.ui.desktop.getFrames()
for i in range(frames.getCount()):
frame = frames.getByIndex(i)
if frame.getTitle() == "MRI":
found = frame
break
if found:
controller = found.getController()
# MRIUi instance of another MRI
ui = controller.ui
mri2 = ui.main # instance of mytools_Mri.MRI
MRI ウィンドウの階層構造を示します。
frame: css.frame.Frame
- Controller: mytools_Mri.ui.controller.Controller
- Model: いつも None
- Container Window: 普通のウィンドウ
- Component Window: css.awt.UnoControlContainer
- splitter: コントロールのコンテナに追加されていません。
- label_status: ステータスを表示する FixedText。
- edit_type: 型情報を表示するフィールド。
- edit_in: 実装名を表示するフィールド。
- list_hist: 履歴リスト。
- btn_back: 戻るボタン。
- btn_forward: 進むボタン。
- edit_search: 検索フィールド。
- btn_search: 検索ボタン。
- btn_tree: ツリーを開くボタン。
- btn_index_acc: Index ボタン。
- btn_name_acc: Name ボタン。
- subcont: css.awt.UnoControlContainer (タブなしモード)
- info_0:
- info_1:
- info_2:
- info_3:
- subcont: css.awt.UnoControlContainer (タブモード)
- page_0
- info_0
- page_1
- info_1
- page_2
- info_2
- page_3
- info_3
拡張機能パッケージの Macros ディレクトリに配置されている bundle.py ファイルに多くの例があります。
現在のシェープコレクションにあるすべての子シェープをインスペクトするコードを示します。
def inspect_shapes(mri):
""" Inspect Shapes
Inspect all shapes in this container. """
shape = mri.current # current target
# check current shape is correct type
if shape.supports_service("com.sun.star.drawing.ShapeCollection"):
# getCount call is not collected to code
for i in range(shape.target.getCount()):
child = shape.getByIndex(i)
Entry インスタンスは target インスタンス変数に実際の値を保持しています。ターゲットの実際の値が必要なら、その値を参照してください。
def show_property_value(mri):
current = mri.current
ui = mri.ui
ui.message(current.target)