Time for action – enabling and disabling the menu's items

The previous section showed how to hide or show a specific keybinding depending on the open editor type. However, it doesn't stop the command being called via the menu, or from it showing up in the menu itself. Instead of just hiding the keybinding, the menu can be hidden as well by adding a visibleWhen block to the command.

The expressions framework provides a number of variables, including activeContexts, which contains a list of the active contexts at the time. Since many contexts can be active simultaneously, the active contexts is a list (for example, [dialogAndWindows,windows, textEditor,javaEditor]). So, to find an entry (in effect, a contains operation) an iterate operator with the equals expression is used.

  1. Open up the plugin.xml file, and update the the Hello command by adding a visibleWhen expression.
    <extension point="org.eclipse.ui.menus">
      <menuContribution allPopups="false"
       locationURI="menu:help?after=additions">
        <command commandId="com.packtpub.e4.clock.ui.command.hello"
         label="Hello" style="push">
          <visibleWhen>
            <with variable="activeContexts">
              <iterate operator="or">
                <equals value="org.eclipse.jdt.ui.javaEditorScope"/>
              </iterate>
            </with>
          </visibleWhen>
        </command>
      </menuContribution>
    </extension>
  2. Run the Eclipse instance, and verify that the menu is hidden until a Java editor is opened. If this behavior is not seen, run the Eclipse application with the clean argument to clear the workspace. After clearing, it will be necessary to create a new Java project with a Java class, as well as an empty text file, to verify that the menu's visibility is correct.

What just happened?

Menus have a visibleWhen guard that is evaluated when the menu is shown. If it is false, the menu is hidden.

The expressions syntax is based on nested XML elements with certain conditions. For example, an <and> block is true if all of its children are true, whereas an <or> block is true if one of its children is true. Variables can also be used with a property test using a combination of a <with> block (which binds the specified variable to the stack) and an <equals> block or other comparison.

In the case of variables that have lists, an <iterate> can be used to step through elements using either operator="or" or operator="and" to dynamically calculate enablement.

To find out if a list contains an element, a combination of <iterate> and <equals> operators is the standard pattern.

There are a number of variables that can be used in tests; these are listed in the Eclipse help documentation under the Workbench Core Expressions chapter, and include the following variables:

  • activeContexts: List of context IDs that are active at the time
  • activeShell: The active shell (dialog or window)
  • activeWorkbenchWindow: The active window
  • activeEditor: The current or last active editor
  • activePart: The active part (editor or view)
  • selection: The current selection
  • org.eclipse.core.runtime.Platform: The Platform object

The Platform object is useful for performing dynamic tests using test, such as the following:

<test value="ACTIVE"
  property="org.eclipse.core.runtime.bundleState"
  args="org.eclipse.core.expressions"/>
<test 
  property="org.eclipse.core.runtime.isBundleInstalled"
  args="org.eclipse.core.expressions"/>

Knowing if a bundle is installed is often useful; it's better to only enable functionality if a bundle is started (or in OSGi terminology, ACTIVE). As a result, use of isBundleInstalled has been replaced by the bundleState=ACTIVE tests.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset