## Menu and toolbar paths

We've seen many action contributions that specify the path for the location of their action. Let's take a close look at what these paths mean.

### Menu paths

We'll look at menu paths first by looking at the workbench Help menu.

#### Named groups in the workbench

The locations for inserting new menus and menu items are defined using named groups. You can think of a named group as a slot or placeholder that allows you to insert your menu items at certain points in a menu bar or pulldown menu.

The workbench defines all of its group slot names in the classes IWorkbenchActionConstants and IIDEActionConstants. (Two different classes are used since resource-related menu items are factored out of the generic workbench). For each workbench menu, named groups are placed in the menu at locations where it is expected that plug-ins will insert new actions.

The following description of the help menu is adapted from the IWorkbenchActionConstants class definition.

       Standard Help menu actions
       Start group - HELP_START - "start"
       End group - HELP_END - "end"

The standard workbench help menu defines a named group called "start," followed by a named group called "end,". Defining two groups gives plug-ins a little more control over where their contributed items will be positioned within the help menu. When you define a menu, you can define as many slots as you like. Adding more slots gives other plug-ins more control over where their contributions appear relative to existing contributions.

Plug-ins that add a menu item to the help menu can use these group names to decide where their menu item will go. For example, the cheatsheet plug-in adds an action set containing the "Cheat Sheets..." menu to the workbench. Here's the markup from the org.eclipse.ui.cheatsheets plug-in's plugin.xml.

    <extension
    	point="org.eclipse.ui.actionSets">
    	<actionSet
    		label="%CHEAT_SHEETS"
    		visible="true"
    		id="org.eclipse.ui.cheatsheets.actionSet">
    		<action
    			label="%CHEAT_SHEETS_MENU"
    			class="org.eclipse.ui.internal.cheatsheets.actions.CheatSheetHelpMenuAction"
    			menubarPath="help/helpStart"
    			id="org.eclipse.ui.cheatsheets.actions.CheatSheetHelpMenuAction">
    		</action>
    	</actionSet>
    </extension>

The new help action will be placed in the help menu, inside the helpStart group.

#### Fully qualified menu paths

A complete menu path is simply "menu name/group name." Most menu names for the workbench are defined in IWorkbenchActionConstants. (Resource-related menu names are defined in IIDEActionConstants.) If we look for the name of the help menu in this class, we'll find that the fully qualified path name for our help action is "help/helpEnd."

Some menus have nested submenus. This is where longer paths come into play. If the help menu had defined a submenu called "submenu" with a named group called "submenuStart," then the fully qualified menu path for an action in the new submenu would be "help/submenu/submenuStart."

#### Externalizing UI labels

The example above demonstrates a technique for externalizing strings that appear in the UI. Externalized strings are used to make translating the plug-in's UI to other languages simpler. We can externalize the strings in our plugin.xml files by replacing the string with a key (%CHEAT_SHEETS_MENU) and creating entries in the plugin.properties file of the form:

    	CHEAT_SHEETS_MENU = Cheat Sheets...

The plugin.properties file can be translated for different languages and the plugin.xml will not need to be modified.

#### Adding new menus and groups

In many of the examples we've seen so far, the actions contributed by the sample plug-ins have been added to existing named groups within menus.

The menus extension point allows you to contribute to your menus using an alternative placement syntax, menu ids. The actionSets, viewActions, editorActions, and popupMenus extension points also allow you to define new menus and groups within your contribution. This means that you can define new submenus or new pull-down menus and contribute your actions to these new menus. In this case, the path for your new action will contain the name of your newly defined menu.

We saw this technique when the readme tool defined a new menu for its action set. Let's look at the markup one more time now that we've looked at menu paths in more detail.

       <extension point = "org.eclipse.ui.actionSets">
       <actionSet id="org_eclipse_ui_examples_readmetool_actionSet"
    	   label="%ActionSet.name"
    	   visible="true">
    	   <menu id="org_eclipse_ui_examples_readmetool"
    		   label="%ActionSet.menu"
    		   path="window/additions">
    		   <separator name="slot1"/>
    		   <separator name="slot2"/>
    		   <separator name="slot3"/>
    	   </menu>
    	   <action id="org_eclipse_ui_examples_readmetool_readmeAction"
    		   menubarPath="window/org_eclipse_ui_examples_readmetool/slot1"
    		   toolbarPath="readme"
    		   label="%ReadmeAction.label"
    		   tooltip="%ReadmeAction.tooltip"
    		   helpContextId="org.eclipse.ui.examples.readmetool.open_browser_action_context"
    		   icon="icons/ctool16/openbrwsr.png"
    		   class="org.eclipse.ui.examples.readmetool.WindowActionDelegate"
    		   enablesFor="1">
    		   <selection class="org.eclipse.core.resources.IFile"
    				name="*.readme">
    		   </selection>
    	   </action>
    	   ...

We added a new menu called "org_eclipse_ui_examples_readmetool" whose label is defined in by the key "%ActionSet.name" in the properties file. Within this menu, we define three named groups: "slot1," "slot2," and "slot3." We add this new menu to the path "window/additions."

If we go back to IWorkbenchActionConstants, we see this definition of the window menu in the javadoc:

        * <h3>Standard Window menu actions</h3>
        * <ul>
        * <li>Extra Window-like action group (<code>WINDOW_EXT</code>)</li>

If we look further at the class definition, we will see these related definitions:

       public static final String MENU_PREFIX = "";
       ...
       public static final String M_WINDOW = MENU_PREFIX+"window";
       ...
       public static final String MB_ADDITIONS = "additions";  // Group.
       ...
       public static final String WINDOW_EXT = MB_ADDITIONS;   // Group.

From this information, we can piece together the path for adding something to the workbench "Window" menu. The menu itself is called "window" and it defines one slot called "additions." We use the path "window/additions" to add our new menu.

In the action set declaration, we add an action to our newly defined menu, using the path "window/org_eclipse_ui_examples_readmetool/slot1."

Other plug-ins could add to our menu by using this same path (or perhaps one of the other slots) to add one of their own menus.

In the readme tool example, we use the separator attribute to identify the group names. This will cause a separator line to appear between these groups when they contain items. We could instead use the groupMarker attribute if we want to define a named group without showing any separators in the menu to distinguish between the groups.

### Tool bar paths

Tool bar paths work similarly to menu paths.

#### Named tool bars in the workbench

The workbench tool bar is composed of tool bars contributed by different plug-ins, including the workbench itself. Within any particular tool bar, there are named groups or slots that can be used for inserting new tool bar items.

The following description of the workbench tool bars is adapted from the IWorkbenchActionConstants class definition.

    // Workbench toolbar ids
    public static final String TOOLBAR_FILE = "org.eclipse.ui.workbench.file"
    public static final String TOOLBAR_NAVIGATE = "org.eclipse.ui.workbench.navigate";

    // Workbench toolbar group ids.  To add an item at the beginning of the group,
    // use the GROUP id.  To add an item at the end of the group, use the EXT id.
    public static final String PIN_GROUP = "pin.group";
    public static final String HISTORY_GROUP = "history.group";
    public static final String NEW_GROUP = "new.group";
    public static final String SAVE_GROUP = "save.group";
    public static final String BUILD_GROUP = "build.group";

In the simplest case, a plug-in can contribute a tool bar item in its own tool bar. For example, the readme tool actions contributed to the menu are also given a tool bar path:

    <action id="org_eclipse_ui_examples_readmetool_readmeAction"
       menubarPath="window/org_eclipse_ui_examples_readmetool/slot1"
       toolbarPath="readme"
    ...

Since there is no reference to the workbench tool bar paths or groups, the readme actions appear in their own group on the tool bar. Specifying the following path would instead place the item in the file tool bar in the save group:

    ...
    <action id="org_eclipse_ui_examples_readmetool_readmeAction"
       menubarPath="window/org_eclipse_ui_examples_readmetool/slot1"
       toolbarPath="org.eclipse.ui.workbench.file/save.group"
    ...

The paths defined in IWorkbenchActionConstants may be referenced in the tool bar paths of other plug-ins.

#### Adding to action sets of another plug-in

Suppose a plug-in wants its tool bar items better integrated with actions from a different plug-in? Let's look at how the external tools plug-in (org.eclipse.ui.externaltools) integrates its action with the debugger tool bar. The debugger (org.eclipse.debug.ui) defines its tool bar actions like this:

    <extension
          point="org.eclipse.ui.actionSets">
       <actionSet
             label="%LaunchActionSet.label"
             visible="false"
             id="org.eclipse.debug.ui.launchActionSet">
       ...
       <action
             toolbarPath="debug"
             id="org.eclipse.debug.internal.ui.actions.RunDropDownAction"
             hoverIcon="icons/full/ctool16/run_exc.png"
             class="org.eclipse.debug.internal.ui.actions.RunToolbarAction"
             disabledIcon="icons/full/dtool16/run_exc.png"
             icon="icons/full/etool16/run_exc.png"
             helpContextId="run_action_context"
             label="%RunDropDownAction.label"
             pulldown="true">
       </action>
       ...

Just like the readme tool, the debugger plug-in defines its own tool bar path, which means its tool bar items will be inside their own tool bar on the workbench. What does the external tools plug-in do?

    <extension point="org.eclipse.ui.actionSets">
    	<actionSet
    		id="org.eclipse.ui.externaltools.ExternalToolsSet"
    		label="%ActionSet.externalTools"
    		visible="true">
    		...
    		<action
    			id="org.eclipse.ui.externaltools.ExternalToolMenuDelegateToolbar"
    			definitionId= "org.eclipse.ui.externaltools.ExternalToolMenuDelegateToolbar"
    			label="%Action.externalTools"
    			toolbarPath="org.eclipse.debug.ui.launchActionSet/debug"
    			disabledIcon="icons/full/dtool16/external_tools.png"
    			icon="icons/full/etool16/external_tools.png"
    			hoverIcon="icons/full/ctool16/external_tools.png"
    			tooltip="%Action.externalToolsTip"
    			pulldown="true"
    			class="org.eclipse.ui.externaltools.internal.menu.ExternalToolMenuDelegate">
    		</action>
    	</actionSet>
    </extension>

Note the use of the action set ID of the debugger in the tool bar path. Using an action set ID in the path denotes that the tool bar item should be placed in the tool bar used by the referenced action set. Within a toolbar group, items are ordered by action set id, so for our example, the external tools action will appear after the debugger actions.

When adding to an action set's tool bar, new groups can also be defined. If the external tools plug-in defined its toolbarpath as "org.eclipse.debug.ui.launchActionSet/external" a new group would be created for the action on the tool bar. As with menus, tool bar groups are delineated by separators.

### Using paths from another plug-in

In general, it's not good practice to contribute to another plug-in's menu or tool bar by deriving the path name from the plugin.xml unless it has been marked specifically as being available for clients. It's possible that a future version of the plug-in could change the names of the paths. Two common ways to mark your plug-in's action set ids and paths as fair game are:

- annotate the XML with comments that explicitly mark the menu path or action set as usable by clients
- define a public interface (much like IWorkbenchActionConstants) which specifies exactly which menus, tool bar groups, and slots are considered fair game for use by other plug-ins