Retargetable action set actions
The
readmetool action set also defines retargetable actions. The action remains
visible as long as the readme action set is visible, but it is only enabled when
a view or editor that implements the action is active. When using action
sets to define retargetable actions, the actions are created in the action set
markup rather than in code. The following is from the readme tool's action
set definition:
<extension point = "org.eclipse.ui.actionSets">
<actionSet id="org_eclipse_ui_examples_readmetool_actionSet"
label="%ActionSet.name"
visible="true">
...
<action id="org_eclipse_ui_examples_readmetool_readmeRetargetAction"
menubarPath="window/org_eclipse_ui_examples_readmetool/slot1"
toolbarPath="readme"
label="%ReadmeRetargetAction.label"
tooltip="%ReadmeRetargetAction.tooltip"
helpContextId="org.eclipse.ui.examples.readmetool.open_browser_action_context"
icon="icons/ctool16/openbrwsr.png"
retarget="true">
</action>
<action id="org_eclipse_ui_examples_readmetool_readmeRelabelRetargetAction"
menubarPath="window/org_eclipse_ui_examples_readmetool/slot1"
toolbarPath="readme"
label="%ReadmeRelabelRetargetAction.label"
tooltip="%ReadmeRelabelRetargetAction.tooltip"
helpContextId="org.eclipse.ui.examples.readmetool.open_browser_action_context"
icon="icons/ctool16/openbrwsr.png"
retarget="true"
allowLabelUpdate="true">
</action>
...
Retargeted actions are specified by using the retarget="true"
attribute. This will cause a
RetargetAction
to be created in the action set. Note that the retargetable actions do not specify an implementing
class since it is up to each view or editor in the plug-in to set up a
handler that implements each action. If the allowLabelUpdate is
true, then a
LabelRetargetAction
will be created instead.
The retargeted actions will be visible in the window menu when the readme
action set is visible. However, they will not be enabled if the readme
tool's editor or outline view are not active.
What do the editor and view have to do? Again, the client side is
similar to registering a handler for the workbench or an editor's retargetable
action. The action id specified in the markup must be used when
registering a global action handler.
The ReadmeEditorActionBarContributor takes care of this for the
editor. First, it defines the handlers for the actions.
public ReadmeEditorActionBarContributor() {
...
handler4 = new EditorAction(MessageUtil.getString("Editor_Action4"));
handler5 = new EditorAction(MessageUtil.getString("Editor_Action5"));
handler5.setToolTipText(MessageUtil.getString("Readme_Editor_Action5"));
...
}
The handlers are registered at the same time that the handlers for the editor
retargetable actions were registered.
public void init(IActionBars bars, IWorkbenchPage page) {
...
bars.setGlobalActionHandler(IReadmeConstants.ACTION_SET_RETARGET4, handler4);
bars.setGlobalActionHandler(IReadmeConstants.ACTION_SET_LABELRETARGET5, handler5);
...
}
Recall that action bar contributors are shared among different instances of
the same editor. This means the handlers must be notified if the active
editor for the ReadmeEditorActionBarContributor changes.
public void setActiveEditor(IEditorPart editor) {
...
handler4.setActiveEditor(editor);
handler5.setActiveEditor(editor);
...
}
That's it for the editor. We should see these actions enable when the
editor is activated.
Note that the label for the first retargetable action ("Editor Action
4") was not used since the action set XML markup did not set allowLabelUpdate.
The ReadmeContentOutlinePage
defines its handlers in the same place it defined handlers for the editor's
retargetable actions:
public void createControl(Composite parent) {
...
action = new OutlineAction(MessageUtil.getString("Outline_Action4"));
getSite().getActionBars().setGlobalActionHandler(
IReadmeConstants.ACTION_SET_RETARGET4,
action);
action = new OutlineAction(MessageUtil.getString("Outline_Action5"));
action.setToolTipText(MessageUtil.getString("Readme_Outline_Action5"));
getSite().getActionBars().setGlobalActionHandler(
IReadmeConstants.ACTION_SET_LABELRETARGET5,
action);
}
We should see its relabeled action when the content outliner is active.