The Eclipse plugin mechanism is very powerful because it can be easily used to assemble a lot of software components into a sophisticated working application but that same mechanism can also make it harder to discover for yourself how things work together. Popup menu items involve the interaction of several systems so they are harder than normal to understand.
Popup menus are those menus that appear when the popup menu 'trigger' is invoked
(usually a right mouse click). Popup menus display menu items that are context sensitive.
That is, popup menus usually display menu items that are particularly relevent to the
UI component associated with the trigger and with the current state of the workbench.
The items to display on a popup menu can come from two places, the current selection and the current view. Both types of popup menu items are defined using the org.jlense.uiworks.popupMenus extension point using <objectContribution> and <viewerContribution> elements. objectContributions are items that are associated with the current selection and viewerContributions are items that are associated with the current view. ;viewerContributions will always be displayed on popup menus when thier associated view is the currently active view. objectContributions are displayed on a popup menu when the current selection satisfies the objectContribution's selection criteria as specified in the <objectContribution> element.
The org.jlense.uiworks.popupMenus extension point allows a plug-in to contribute to a view's popup menus.
You can contribute an action to a specific view by its id (viewerContribution), or by associating it with a particular object type (objectContribution).
So, if you want an item to always be displayed on a popup menu for a
particular view then you would use a <viewerContribution> element.
For example, the org.jlense.uiworks plugin defines two object contributions that can contribute items to the popup menus (a.k.a. "context" menus) of all other contributed views. Let's take a look at those object contributions.
<extension point="org.jlense.uiworks.popupMenus"> <objectContribution objectClass="org.jlense.uiworks.action.IOpenable" > <action id="org.jlense.uiworks.open.selection" menubarPath="new.ext" definitionID="org.jlense.uiworks.open.selection" label="&Open@Ctrl+O" tooltip="Open the selected item(s)" helpContextId="org.jlense.uiworks.open.selection" icon="icons/full/ctool16/open.gif" class="org.jlense.uiworks.action.OpenSelectedActionDelegate" enablesFor="+"> </action> </objectContribution> <objectContribution objectClass="org.jlense.uiworks.action.IDeleteable" > <action id="org.jlense.uiworks.delete" menubarPath="cut.ext" definitionID="org.jlense.uiworks.delete.selection" label="&Delete@Ctrl+D" tooltip="Delete the selected item(s)" helpContextId="org.jlense.uiworks.delete" icon="icons/full/ctool16/deleteable.gif" class="org.jlense.uiworks.action.DeleteActionDelegate" enablesFor="+"> </action> </objectContribution> </extension>
What these definitions say is that if the currently selected item implements the IOpenable interface (or has an IOpenable adapter) then display an 'Open' menu item for opening the item. Or if the currently selected item implements the IDeleteable interface (or has an IDeleteable adapter) then display a 'Delete' menu item for deleting the item.
Let's take a look at how the workbench uses these extension definitions to actually crate a popup menu.
Obviously, if the workbench is going to create an appropraite popupo menu for an object then the workbench has know what the 'current selection' is. The details of selection providers and selection listeners are provided elsewhere. For right now it is sufficient to know that any view that wishes to take advantage of the workbench's ability to generate popup menu items for selected objects must supply the workbench with a 'Selection Provider'. In this way the workbench can get the current selection from the current view.
That takes care of actually telling the workbench what the current selection is. When a user selects a item in a view then the view's selection provider tells the workbench exactly what has been selected. From this information the workbench can create items for the popup menu based on registered popupMenu extenstion points.
After determining what object's are selected the workbench must then determine
if the selected items satisfy the criteria of any <objectContribution>
extension. If so then the workbench will create a popup menu item for the
selected items that represents the <objectContribution>.
Clearly a better method than inheritence is needed to determine if an object is of a certain type or has certain capabilities. The solutuion is adapters. The workbench popup menu implementation works with the Eclipse Adapter Manager. If the workbench can find and adapter for the currently selected object that implements IOpenable then it will display the IOpenable meni item.
The adapter mechanism may seem like an unneccessary level of indirection but it is important because it makes it possible for plugins to extend objects created by other plugins in a loosely coupled, independent manner.
So, to sum up, to display popup menu items...