I’ve searched for a way to show menu and toolbar entries only in certain perspectives. In case of OpenChrom, the “Chromatogram Edit” entries should be only visible when the user has the ability to modify chromatographic data.
The “Chromatogram Edit” menu entries don’t make sense if the user tries to synchronize repositories or analyze log files.
No big thing, we could disable distinct perspectives concerning the editing of chromatgrams, but if another perspective is added by an additional plug-in, the menu/toolbar entries will be visible again. Thus, we should enable the chromatogram editing menu/toolbar entries only when perspectives with focus to edit chromatographic data are activated. To achieve this, we need a unique identifier for the chromatogram editing perspectives. The perspective id is used here for instance. All perspectives that start with the identifier “net.openchrom.chromatogram.” will be used to activate the “Chromatogram Edit” menu and toolbar entries.
package net.openchrom.chromatogram.msd.ui.perspective.propertytester; import org.eclipse.core.expressions.PropertyTester; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.PlatformUI; public class PerspecticePropertyTester extends PropertyTester { @Override public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { /* * Returns true if the actual perspective supports chromatogram editing. */ IPerspectiveDescriptor perspective = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getPerspective(); String perspectiveId = perspective.getId(); if(perspectiveId.startsWith("net.openchrom.chromatogram.")) { return true; } return false; } }
But how do we link the property tester with the menu/toolbar entries? First of all, the “PerspecticePropertyTester” class needs to be associated with the “org.eclipse.core.expressions.propertyTesters” extension point.
<extension point="org.eclipse.core.expressions.propertyTesters"> <propertyTester class="net.openchrom.chromatogram.msd.ui.perspective.propertytester.PerspecticePropertyTester" id="net.openchrom.chromatogram.msd.ui.perspective.perspectivePropertyTester" namespace="net.openchrom.chromatogram.msd.ui.perspective.perspectivePropertyTester" properties="isKnownPerspective" type="java.lang.Object"> </propertyTester> </extension>
In the next step, the property tester will referenced by the declaration of a test definition using the extension point “org.eclipse.core.expressions.definitions”. That’s very comfortable as we don’t need to reference the property tester directly in the menu and toolbar contributions. Further on, the plug-in will be activated on request.
<extension point="org.eclipse.core.expressions.definitions"> <definition id="net.openchrom.chromatogram.msd.ui.perspective.isChromatogramPerspectiveDefinition"> <with variable="activeWorkbenchWindow.activePerspective"> <test forcePluginActivation="true" property="net.openchrom.chromatogram.msd.ui.perspective.perspectivePropertyTester.isKnownPerspective"> </test> </with> </definition> </extension>
Now, we’ve prepared everything to use the test definition to enable/disable the menu/toolbar entries. It’s easy to disable a whole menu contribution.
<menuContribution locationURI="menu:org.eclipse.ui.main.menu?after=edit"> <menu id="net.openchrom.chromatogram.msd.ui.perspective.chromatogram.menu" label="Chromatogram Edit"> ... <visibleWhen checkEnabled="false"> <reference definitionId="net.openchrom.chromatogram.msd.ui.perspective.isChromatogramPerspectiveDefinition"> </reference> </visibleWhen> </menu> </menuContribution>
In contrary to the menu contribution, each toolbar entry must be enabled/disabled separately.
<menuContribution locationURI="toolbar:org.eclipse.ui.main.toolbar?after=additions"> ... <toolbar id="net.openchrom.chromatogram.msd.ui.perspective.chromatogram.toolbar.miscellaneous"> <command commandId="net.openchrom.chromatogram.msd.ui.perspective.commands.createSnapshotCommand" icon="icons/create_snapshot.png" style="push"> <visibleWhen checkEnabled="false"> <reference definitionId="net.openchrom.chromatogram.msd.ui.perspective.isChromatogramPerspectiveDefinition"> </reference> </visibleWhen> </command> </toolbar> </menuContribution>
That’s it. The source files can be viewed here:
Pingback: Show/hide menu and toolbar entries depending... | Eclipse | Syngu
Thank you very much for sharing your article about a particular difficult problem – controlling the visibility of commands. However, I general I do not favor controlling visibility of commands based on perspective id. It really limits un-necessarily the ability to re-use or mash up functionality when combining views to form new perspectives. What happens when you give your users the ability to customize their own perspectives and do a SaveAs? So what do I prefer? I would rather commands be associatated with visiblity of view parts or explicit application Context. I do commend you for sharing your thoughts
It is not easier to use visibleWhen directly with activeWorkbenchWindow.activePerspectiv?
For example:
Looks like my XML code was deleted. Trying again without markup:
visibleWhen
checkEnabled=”false”
with
variable=”activeWorkbenchWindow.activePerspective”
equals
value=”org.eclipse.jdt.ui.JavaPerspective”
equals
with
visibleWhen
Hi Lars,
thanks for your suggestions. Does the approach also work, if you’ll apply it to a name scheme? For instance, to show the menu if the perspective contains the pattern *chromatogram*? Anyhow, I’ll try it tomorrow.
I think the ID needs to match exactly.
Hi Lars,
I’ve tried it. Indeed, it only works if the perspective ID matches exactly. I think it’s a smart solution if only a certain perspective shall be used to show/hide menu and toolbar entries. On the other side, the PropertyTester class approach allows to apply individual testing patterns, for instance using regular expressions or a list of names to be tested.
It seems to me that with your code, tool items of an inactive workbench window on a defined perspective would go hidden if the active workbench window’s perspective is not one of the predefined set. So what you see when you turn your head around with multiple monitors might not actually reflect what the user expects to see.
I think you could use “or” to check for a list of names. But of course PropertyTester is more flexible.
Pingback: Blog bookmarks 09/05/2011 « My Diigo bookmarks
I recently had to solve this same problem with Luna 4.4.0 and used this blog post as a starting point. After debugging the content of the IEclipseContext I found an entry/variable under the key ‘org.eclipse.e4.ui.model.application.ui.advanced.MPerspective’. I then created a simple PropertyTester to check the elementId attribute of this object. This resulted in the following plugin.xml (https://github.com/hibouhome/rcp-spikes/blob/master/com.hibouhome.rcp.spikes.visiblewhen/plugin.xml) and PropertyTester implementation (https://github.com/hibouhome/rcp-spikes/blob/master/com.hibouhome.rcp.spikes.visiblewhen/src/com/hibouhome/rcp/spikes/visiblewhen/handlers/PerspectivePropertyTester.java). I should also note that visible when expressions only seem to work for tool bar items added as a contribution, as opposed to being added directly to the main tool bar. The following spike is a working example of tool bar item show/hide based on the currently selected perspective. I hope this helps anyone else looking to solve this same problem
Thank you very much Jonathan Wright ! it saves my day 🙂
awesome article! It helped me a lot!