Show/hide menu and toolbar entries depending on the selected perspective

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:

PropertyTester.java
plugin.xml

About Philip Wenig

Founder of OpenChrom
This entry was posted in Uncategorized. Bookmark the permalink.

13 Responses to Show/hide menu and toolbar entries depending on the selected perspective

  1. Pingback: Show/hide menu and toolbar entries depending... | Eclipse | Syngu

  2. Stu Pond says:

    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

  3. Lars Vogel says:

    It is not easier to use visibleWhen directly with activeWorkbenchWindow.activePerspectiv?

    For example:

    • Lars Vogel says:

      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

      • eselmeister says:

        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.

  4. Lars Vogel says:

    I think the ID needs to match exactly.

    • eselmeister says:

      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.

      • rcjsuen says:

        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.

  5. Lars Vogel says:

    I think you could use “or” to check for a list of names. But of course PropertyTester is more flexible.

  6. Pingback: Blog bookmarks 09/05/2011 « My Diigo bookmarks

  7. 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

  8. Sharif says:

    Thank you very much Jonathan Wright ! it saves my day 🙂

  9. Dawn Cheng says:

    awesome article! It helped me a lot!

Leave a reply to Lars Vogel Cancel reply