[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-ui-dev] Changes to action enablement

Hi,

In version 1 of Eclipse the enablement and visibility of window, view,
editor and popup menu action extensions was defined using a limited set of
elements in xml.  The existing tags cannot adequately describe the
conditions when an action should be enabled or visible.  To resolve these
issues, the following approach has been prototyped:

- if a plug-in is loaded, we will instantiate every action in the plug-in.
- new features have been added to the XML to define action enablement and
visibility.  These features can be used to test system properties, plugin
installation, and object state.  In addition, they can be combined using
AND, OR, and NOT tags.  These features extend the existing markup, and do
not replace it.

A number of people rallied for eager plugin loading.  This is infeasable.
Within the workbench action enablement should be quick to calculate.  If it
is too expensive to calculate the enablement, the action should be
optimistically enabled, and a dialog should appear if the action is invoked
and cannot perform the required operation.  See the CVS actions as an
example.  This heuristic for expensive actions can also be applied to
action extension enablement.  If we load a plugin to enable an action, it
may induce a tremendous delay, especially when there may be hundreds of
plugins in Eclipse.  To avoid this delay, we must define the action
enablement criteria using XML.  If it is not possible to define the
enablement criteria accurately using xml, the action should be enabled
optimistically.

The latest drop contains the following changes:

- an IWorkbench.refreshPluginActions(String pluginId) method has been
added.  Using this method, you can trigger the creation of action delegates
for a particular plugin.  The delegates are created only if the plugin
itself has been activated.
- a new enablement element has been added to action markup.  This can be
used to define the enablement criteria for any action, and is a sub element
of the action element.
- a new visibility element has been added to popup menu extension action
markup.  This can be used to define the visibility criteria for the action,
and is a sub element of the object contribution element.

For more information on the visibility and enablement criteria, see the
attached html doc.


(See attached file: expressions.html)

If you have any comments on the enablement criteria, please respond.

Dave
Title: Eclipse Workbench Extension Point: Action Sets

Expressions

Description: Boolean expressions are used to define the visibility and enablement for many action extensions within the workbench.  For instance, an enablement element can be defined within any action extension.  This element contains a boolean _expression_ defining the enablement criteria for the action.  A visibility element can be defined for a popup menu action extension.  This element contains a boolean _expression_ defining the visibility criteria for the action.

Regardless of where the boolean _expression_ is found, the syntax of the _expression_ will follow the same form.  The root element for enablement and visibility must contain one sub element.  In the simplest case, this will consist of an objectClass, objectState, systemProperty, or pluginState element.  In the more complex case, and, or, not elements can be combined to form a boolean _expression_.  An and or or element may contain 1 or more sub elements.  A not element must contain only 1 sub element.

An objectClass element is used to evaluate the class of each object in the selection.  The name attribute of the objectClass contains a fully qualified class name.  If each object in the selection implements this class, the _expression_ is evaluated as true.

An objectState element is used to evaluate the state of each object in the selection.  In most situations, the enablement or visibility of an action can be determined by selection type.  In other situations this is not enough, and enablement or visibility must be determined using the selection state.  For instance, you may contribute an action for all objects of type IFile which are read only. This read only criteria can only be declared by specifying an objectState element.  It may have the following form ..
 

<objectState name="readOnly" value="true"/>
In the workbench, the evaluation of this _expression_ is very difficult to accomplish, because the attributes of an object are type specific, and beyond the domain of the workbench itself.  So the workbench will collaborate with the objects in the selection to evaluate the _expression_.  This is done using an IActionFilter, an evaluation strategy for objectState elements.  When an objectState element is evaluated, the workbench ask each object in the selection for an IActionFilter.  It does this by testing to see if it implements IActionFilter.  If that fails, the workbench will ask for a filter through through the IAdaptable mechanism.  If a filter is found, the workbench will pass the objectState attributes to the filter to determine if they match the state of the selected object.  If so, the term is evaluated as true.  If there is no action filter, or there is no match, the term is evaluated as false.

View and editors are encouraged to define an IActionFilter for each object in their selection.  This makes it easier for other plugin developers to extend those views or editors with new, well qualified actions.

A systemProperty element is used to evaluate the state of some system property.  Under the covers, the value of the system property is determined by invoking System.getProperty.

A pluginState element is used to evaluate the state of a plugin.  The state of the plugin may be installed or activated.

Configuration Markup:

   <!ELEMENT visibility (and | or | not | objectClass | objectState | systemProperty
        | pluginState)>

   <!ELEMENT enablement (and | or | not | objectClass | objectState | systemProperty
        | pluginState)>

   <!ELEMENT and (and | or | not | objectClass | objectState | systemProperty | pluginState)*>

   <!ELEMENT or (and | or | not | objectClass | objectState | systemProperty | pluginState)*>

   <!ELEMENT not (and | or | not | objectClass | objectState | systemProperty | pluginState)>

   <!ELEMENT objectClass EMPTY>
   <!ATTLIST objectClass
      name       CDATA #REQUIRED
   >

  • name - a fully qualified name of a class.  The _expression_ is evaluated as true only if the selection implement this class.
   <!ELEMENT objectState EMPTY>
   <!ATTLIST objectState
      name       CDATA #REQUIRED
      value      CDATA #REQUIRED
   >
  • name - the name of an object attribute.  Acceptable values for this string reflect the object type, and should be publicly declared by the plugin where the object type is declared.
  • value - the required value of the object attribute.  The acceptable values for the object attribute should be publicly declared.
   <!ELEMENT systemProperty EMPTY>
   <!ATTLIST systemProperty
      name       CDATA #REQUIRED
      value      CDATA #REQUIRED
   >
  • name - the name of the system property.
  • value - the required value of the system property.
   <!ELEMENT pluginState EMPTY>
   <!ATTLIST pluginState
      id         CDATA #REQUIRED
      value      (installed | activated)
   >
  • id - an id of a plugin which may or may not be registered in the plug-in registry.
  • value - the required state of the plugin.  Currently two states are supported: installed and activated.
  • Examples:

    The following is an example of an action set which uses the enablement element.  The action set declares a menu with the label List Element, and then populates it with actions which are enabled by a selection of ListElements with various state.  A ListElement has two attributes: name (a string) and flag (a boolean).  In this example, the All action () is enabled whenever a ListElement is selected.  The Red action () is enabled when a ListElement with name = red is selected.  And the Not Red action () is enabled when a ListElement with name != red is selected.

    <extension point = "org.eclipse.ui.actionSets">
        <actionSet id="org.eclipse.ui.tests.internal.ListElementActions"
            label="List Element">
            <menu id="org.eclipse.ui.tests.internal.ListElementMenu"
                label="List Element"
                path="additions">
                <separator name="group1"/>
            </menu>
         <action id="org.eclipse.ui.tests.internal.ac1"
                label="All"
                menubarPath="org.eclipse.ui.tests.internal.ListElementMenu/group1"
                class="org.eclipse.ui.tests.api.MockActionDelegate"
                enablesFor="1">
                <enablement>
                     <objectClass name="org.eclipse.ui.tests.api.ListElement"/>
                </enablement>
            </action>
         <action id="org.eclipse.ui.tests.internal.ac2"
                label="Red"
                menubarPath="org.eclipse.ui.tests.internal.ListElementMenu/group1"
                class="org.eclipse.ui.tests.api.MockActionDelegate"
                enablesFor="1">
                <enablement>
                 <and>
                  <objectClass name="org.eclipse.ui.tests.api.ListElement"/>
                  <objectState name="name" value="red"/>
                 </and>
                </enablement>
            </action>
         <action id="org.eclipse.ui.tests.internal.ac3"
                label="Not Red"
                menubarPath="org.eclipse.ui.tests.internal.ListElementMenu/group1"
                class="org.eclipse.ui.tests.api.MockActionDelegate"
                enablesFor="1">
                <enablement>
                 <and>
                  <objectClass name="org.eclipse.ui.tests.api.ListElement"/>
                   <not>
                   <objectState name="name" value="red"/>
                  </not>
              </and>
                </enablement>
            </action>
        </actionSet>
    </extension>
    In the next example the pluginState element is used to control the enablement of actions in an action set.  The Installed action () is enabled when the plugin with x.y.z.myPlugin is installed.  The Activated action () is enabled when the same plugin has been activated.
    <extension point = "org.eclipse.ui.actionSets">
        <actionSet id="org.eclipse.ui.tests.internal.ListElementActions"
            label="List Element">
            <menu id="org.eclipse.ui.tests.internal.ListElementMenu"
                label="List Element"
                path="additions">
                <separator name="group1"/>
            </menu>
         <action id="org.eclipse.ui.tests.internal.ac8"
                label="Installed"
                menubarPath="org.eclipse.ui.tests.internal.ListElementMenu/group1"
                class="org.eclipse.ui.tests.api.MockActionDelegate">
                <enablement>
                 <pluginState id="x.y.z.myPlugin" value="installed"/>
                </enablement>
            </action>
         <action id="org.eclipse.ui.tests.internal.ac10"
                label="Activated"
                menubarPath="org.eclipse.ui.tests.internal.ListElementMenu/group1"
                class="org.eclipse.ui.tests.api.MockActionDelegate">
                <enablement>
                 <pluginState id="x.y.z.myPlugin" value="activated"/>
                </enablement>
            </action>
        </actionSet>
    </extension>
    In the next example the systemProperty element is demonstrated.  The System Property action () is enabled when the ActionExpressionVar system property is equal to "bubba".
    <extension point = "org.eclipse.ui.actionSets">
        <actionSet id="org.eclipse.ui.tests.internal.ListElementActions"
            label="List Element">
            <menu id="org.eclipse.ui.tests.internal.ListElementMenu"
                label="List Element"
                path="additions">
                <separator name="group1"/>
            </menu>
         <action id="org.eclipse.ui.tests.internal.ac11"
                label="System Property"
                menubarPath="org.eclipse.ui.tests.internal.ListElementMenu/group1"
                class="org.eclipse.ui.tests.api.MockActionDelegate">
                <enablement>
                 <systemProperty name="ActionExpressionVar" value="bubba"/>
                </enablement>
            </action>
        </actionSet>
    </extension>
    Here is one final example, which demonstrates the declaration of visibility for a popup menu action extension.  The Red and True action is visible whenever a ListElement is selected with name = red and flag = true.
    <extension point="org.eclipse.ui.popupMenus">
        <objectContribution id="oc6"
          objectClass="org.eclipse.ui.tests.api.ListElement">
          <visibility>
             <and>
                 <objectState name="name" value="red"/>
                 <objectState name="flag" value="true"/>
             </and>
          </visibility>
          <action id="oc4" label="Red And True"
               class="org.eclipse.ui.tests.api.MockActionDelegate"/>
        </objectContribution>
    </extension>


    Supplied Implementation: For convenience, action filters have been defined for markers, resources, and projects.  The name-value pairs for each are declared on IMarkerActionFilter, IResourceActionFilter, and IProjectActionFilter.
     

    Copyright IBM Corp. 2000, 2001.  All Rights Reserved.