Calc(29)コンテクストメニューをカスタマイズする: その2

公開日: 2017年10月22日 更新日: 2019年05月11日

旧ブログ

t f B! P L
notifyContextMenuExecute()の戻り値、IGNORED、CANCELLED、EXECUTE_MODIFIED、CONTINUE_MODIFIEDの違いを試します。

前の関連記事:Calc(28)コンテクストメニューをカスタマイズする: その1


notifyContextMenuExecute()の戻り値: IGNOREDとCANCELLED


XContextMenuInterceptorインターフェイスのnotifyContextMenuExecute()メソッドはenumのContextMenuInterceptorActionを返さないといけません。

Calc(28)コンテクストメニューをカスタマイズする: その1のcontextmenuinterceptor.pyでこれらの戻り値をやってみます。

IGNORED

このContextMenuInterceptorは実行せず、次のContextMenuInterceptorは実行します。

これはこのContextMenuInterceptorだけが実行されなかったのと同じです。

つまり右クリックしてもデフォルトのコンテクストメニューが表示されるだけです。

CANCELLED

これはコンテクストメニューの表示自体をキャンセルします。

デフォルトのコンテクストメニューも表示されなくなりました。

つまり右クリックしても何も起こらなくなります。

notifyContextMenuExecute()の戻り値: EXECUTE_MODIFIEDとCONTINUE_MODIFIED


EXECUTE_MODIFIEDとCONTINUE_MODIFIEDはどちらもContextMenuInterceptorで設定したメニュー項目が表示されます。

違いがでるのは、複数のContextMenuInterceptorを同じコントローラに登録したときです。

CONTINUE_MODIFIED

コンテクストメニューを変更したあと次のContextMenuInterceptorを呼び出します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# -*- coding: utf-8 -*-
import unohelper  # オートメーションには必須(必須なのはuno)。
from com.sun.star.ui import XContextMenuInterceptor
from com.sun.star.ui import ActionTriggerSeparatorType  # 定数
from com.sun.star.ui.ContextMenuInterceptorAction import EXECUTE_MODIFIED, IGNORED, CANCELLED, CONTINUE_MODIFIED  # enum
def macro(): 
    doc = XSCRIPTCONTEXT.getDocument()  # ドキュメントのモデルを取得。
    controller = doc.getCurrentController()  # コントローラーを取得。
    contextmenuinterceptor = ContextMenuInterceptor()
    contextmenuinterceptor2 = ContextMenuInterceptor2()
    controller.registerContextMenuInterceptor(contextmenuinterceptor)
    controller.registerContextMenuInterceptor(contextmenuinterceptor2)
class ContextMenuInterceptor(unohelper.Base, XContextMenuInterceptor):
    def notifyContextMenuExecute(self, contextmenuexecuteevent):
        contextmenu = contextmenuexecuteevent.ActionTriggerContainer
        submenucontainer = contextmenu.createInstance("com.sun.star.ui.ActionTriggerContainer")
        addMenuentry(submenucontainer, "ActionTrigger", 0, {"Text": "Content", "CommandURL": ".uno:HelpIndex", "HelpURL": "5401"})
        addMenuentry(submenucontainer, "ActionTrigger", 1, {"Text": "Tips", "CommandURL": ".uno:HelpTip", "HelpURL": "5404"})
        addMenuentry(contextmenu, "ActionTrigger", 0, {"Text": "Help", "CommandURL": ".uno:HelpMenu", "HelpURL": "5410", "SubContainer": submenucontainer})
        addMenuentry(contextmenu, "ActionTriggerSeparator", 1, {"SeparatorType": ActionTriggerSeparatorType.LINE})
        return CONTINUE_MODIFIED # EXECUTE_MODIFIED, IGNORED, CANCELLED, CONTINUE_MODIFIED
class ContextMenuInterceptor2(unohelper.Base, XContextMenuInterceptor):
    def notifyContextMenuExecute(self, contextmenuexecuteevent):
        contextmenu = contextmenuexecuteevent.ActionTriggerContainer
        submenucontainer = contextmenu.createInstance("com.sun.star.ui.ActionTriggerContainer")
        addMenuentry(submenucontainer, "ActionTrigger", 0, {"Text": "Content2", "CommandURL": ".uno:HelpIndex", "HelpURL": "5401"})
        addMenuentry(submenucontainer, "ActionTrigger", 1, {"Text": "Tips2", "CommandURL": ".uno:HelpTip", "HelpURL": "5404"})
        addMenuentry(contextmenu, "ActionTrigger", 0, {"Text": "Help2", "CommandURL": ".uno:HelpMenu", "HelpURL": "5410", "SubContainer": submenucontainer})
        addMenuentry(contextmenu, "ActionTriggerSeparator", 1, {"SeparatorType": ActionTriggerSeparatorType.LINE})
        return CONTINUE_MODIFIED # EXECUTE_MODIFIED, IGNORED, CANCELLED, CONTINUE_MODIFIED
def addMenuentry(menucontainer, menutype, i, props):  # i: index, propsは辞書。menutypeはActionTriggerかActionTriggerSeparator。
    menuentry = menucontainer.createInstance("com.sun.star.ui.{}".format(menutype))  # ActionTriggerContainerからインスタンス化する。
    [menuentry.setPropertyValue(key, val) for key, val in props.items()]  #setPropertyValuesでは設定できない。エラーも出ない。
    menucontainer.insertByIndex(i, menuentry)  # submenucontainer[i]やsubmenucontainer[i:i]は不可。挿入以降のメニューコンテナの項目のインデックスは1増える。
g_exportedScripts = macro, #マクロセレクターに限定表示させる関数をタプルで指定。
contextmenuinterceptorとcontextmenuinterceptor2を、それぞれこの順でCalcのコントローラに登録しています。

registerContextMenuInterceptor()メソッドで登録したContextMenuInterceptorはinterceptorチェーンの先頭に追加されます。

contextmenuinterceptor→contextmenuinterceptor2という順に登録したので、後に登録したcontextmenuinterceptor2から呼び出されます。

デフォルトのコンテクストメニューは常に先頭で呼ばれるようようなので、デフォルトコンテクストメニュー→contextmenuinterceptor2→contextmenuinterceptor、という順で呼び出されます。

contextmenuinterceptorとcontextmenuinterceptor2は同じインデックスとコンテクストメニューに挿入しているので、contextmenuinterceptor2で挿入したインデックスはcontextmenuinterceptorの挿入でインデックスがずれることになります。


ということで右クリックすると登録した順に表示されます。

CONTINUE_MODIFIEDにしておくと、マクロを実行するたびにコンテクストメニューの項目の表示が追加されていくので、最後に呼び出されるContextMenuInterceptorのメソッドではEXECUTE_MODIFIEDを返すようにしておきます。

EXECUTE_MODIFIED

コンテクストメニューを変更したあと次のContextMenuInterceptorを呼び出さないようにします。

上のマクロではデフォルトコンテクストメニュー→contextmenuinterceptor2→contextmenuinterceptorという順に呼び出されるのでcontextmenuinterceptor2の戻り値をEXECUTE_MODIFIEDにしてみます。


Help2しか表示されなくなりました。

contextmenuinterceptorは最後に呼び出されるものなので、EXECUTE_MODIFIEDでもCONTINUE_MODIFIEDでも結果は変わりません。

次の関連記事:Calc(30)コンテクストメニューをカスタマイズする: その3

ブログ検索 by Blogger

Translate

Created by Calendar Gadget

QooQ