|[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. DaveTitle: Eclipse Workbench Extension Point: Action Sets
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.
<!ELEMENT visibility (and | or | not | objectClass
| objectState | systemProperty
<!ELEMENT enablement (and | or | not | objectClass
| objectState | systemProperty
<!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>
name CDATA #REQUIRED
value CDATA #REQUIRED
name CDATA #REQUIRED
value CDATA #REQUIRED
id CDATA #REQUIRED
value (installed | activated)
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">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">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">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.