eclipse: Defining your own toolbar menu in plugin.xml but using it in your view or editor's controls

The next challenge I have is how to define a toolbar menu in the plugin.xml folder, for example, to define toolbars for Sections or other widgets capable of having a toolbar (not just the main workbench page) but still pull that definition and instantiate it for my specific view or editor part such as the section. The issue where I don't see how it works is if I define it in the plugin.xml how to do I ensure that when the toolbar needs to be created from that XML specification, that it has the right parent is used such as my Section object in an editor.

The standard menu examples (eclipse 3.3) all seem to assume that it is the main workbench window page that has the toolbars and menus, except perhaps those view specific popup menus and such. Like the popup menus, I need to ensure that the right parent is used to create the toolbar.

The key to the story is the IMenuService which is accessible off the workbench (not the window). The menu service off the workbench


IMenuService service = (IMenuService) PlatformUI.getWorkbench().getService(IMenuService.class);


allows you to 2 things. Add a contribution manager factory (this type of factory populates contribution managers--one type of contribution manager is a toolbar contribution manager) and populate a contribution manager. A contribution manager sits on top of a raw SWT toolbar or menu widget and manages the order and other attributes of toolbar or menu buttons. It is like a viewer for a table or combo widget that makes SWT easier to use at the jface level.

The contribution manager factories are managed by the menu service based on URI--string paths that point to specific menu ids, etc. Hence, if you define some app-specific toolbar in your plugin.xml, then access the service, you will be able to populate a contribution manager (that fronts a toolbar) once you access the proper menu service. In your editor or view, merely define a contribution manager (such as a toolbar contribution manager) then "populate" this contribution manager by accessing the menu service from the workbench. The contribution manager can create the actual toolbar you want with the proper parent using the createControl() method. In this scenario, you do not nede to define your contribution manager factory since the default one that is used, the one that reads your plugin.xml, works fine here.

Once you have created your toolbar, you can define your handlers to be active when than editor element (like the Section) is selected and other criteria you define. I recommend that the handlers be defined in the controller class for your view or editor and handle enablement based on your presentation model or domain model in some way. If the toolbar has commands that operate at the workspace level, you can define your handlers as you normally do in the plugin.xml directly, but for smaller viewers that are highly specific, the locally defined and enabled handler gives you more control over its state more easily.

Here's the definition you can use in your plugin.xml, notice that I define a few additions points so you can add more icons:


<menucontribution locationURI="toolbar:yourapp.toolbarX">
<command commandid="yourapp.newObject" >
<separator name="additions1" visible="true" >
<command commandid="org.eclipse.ui.edit.cut" >
<command commandid="org.eclipse.ui.edit.copy" >
<command commandid="org.eclipse.ui.edit.paste" >
<separator name="additions2" visible="true" >
<command commandid="org.eclipse.ui.edit.delete" >
<separator name="additions3" visible="true" >
</menucontribution>



Then you just need the following code to access it somewhere in the class that creates your view:


protected void createToolBarManager(Composite p) {
toolbar = new ToolBarManager(SWT.FLAT);
getMenuService().populateContributionManager(toolbar, "toolbar:yourapp.toolbarX");
toolbar.createControl(p);



PW on the eclipse team pointed out that you have to release the contributions after in the dispose() call for your view.


protected IMenuService getMenuService() {
final IMenuService service = (IMenuService) PlatformUI.getWorkbench()
.getService(IMenuService.class);
return service;
}


public void dispose() {
getMenuService().releaseContributions(toolbar);
}

Popular posts from this blog

React, Redux, Recompose and some simple steps to remove "some" boilerplate and improve reuse

graphql (facebook), falcor (netflix) and odata and ...

cats/cats-effect and webservices function composition