Enabling and disabling of toolbar/panel actions

Posted by Håvard Danielsen on 08-Feb-2007 16:28

I'm entering this as a separate thread, but it is an attempt to respond to another thread that had the question in a foreign language that might prevent others from finding this information.

Disabling and enabling of toolbar and panel actions are rule-driven. Each action has an EnableRule that decides when the action should be enabled. (It is also possible to hide and disable actions permanently for a toolbar instance in the toolbar instance property dialog. It is strongly recommended to NOT attempt to control this by calling toolbar functions like enableActions, disableActions and sensitizeActions. They work, but the setting will be overridden by the rules on the next notification from a target.)

Dynamics defines the EnableRule in the Repository while standard ADM2 defines this in the initAction procedure in toolbar.p (9.1D might have had this in action.p). Note that initAction is called only once in the session and that defineAction is NOT called in target-procedure. This is because the actions are class definitions and not instance definitions.

The EnableRule is defined as an expression of properties and/or functions with OR/AND operators between them. (expressions with parenthesis are NOT supported). The referenced properties and/or functions must exist in the object the toolbar is linked to. E.g. if you add rules to tableio-source actions, the properties and functions must be in the tableio-target (Viewer or Browser).

The linked object sends a message to the toolbar to reset the actions on any state change. This means that the rules can be based on data values, since each record change is notified to both tableio and navigation toolbars. You can also initiate the rule by publishing reset, e.g. publish "resetTableio" from target-procedure.

The syntax is probably best explained with an example. This is the tableio Add action EnableRule:

"RecordState=RecordAvailable,NoRecordAvailable and Editable and DataModified=no and CanNavigate()":U

This rule says that the Add is enabled when:

The RecordState property of the tableio-target is "RecordAvailable" or "NoRecordAvailable" The Editable property of the tableio-target is true The DataModified property of the tableio-target is false The canNavigate() function in the tablio-target is true (This is an example on how to implement more complex rules by implementing the complexity in the function) =Value (the expression is true if the property returns any of the comma separated values). Logical properties can be referenced with just their name for the TRUE value (e.g. Editable). There MUST be a corresponding get Add this rule to the action by overriding initAction in custom toolbar class (This is pseudo code that shows how to add a canAdd() function to the rule, you need to use dynamic-function and target-procedure)

Run super.

cOldrule = actionEnableRule("Add").

assignActionEnableRule("Add",cOldRule + " and canAdd()" ).

You can alternativley use defineAction, as it overrides previously defined actions. You would NOT call this in target-procedure though.

event:

on entry of xxx do:

Ensure that canAdd will return true.

Publish "resetTableio" from target-procedure.

end.

</ol>

Because actions are defined once for all toolbars, you need to implement the new function/property referenced in the rule in all tableio-targets (implement in custom datavis class).

You might need/want to have the same function or property in the rule definition of several actions. The toolbar's state change code is optimized, so each function and property is only called once for each notification even if they are referenced in many actions.

It is possible to define actions just for one particular toolbar instance by calling defineAction in the instance (target-procedure), and thus avoid the need to have the referenced functions and properties in all targets, but the action name must not conflict with the actions defined for the class.

Message was edited :

Replaced question marks with quotes (again).

Havard Danielsen

All Replies

Posted by Håvard Danielsen on 13-Feb-2007 07:44

My last comment about using the defineAction function to create actions for a toolbar instance missed an important point. I'll try again:

To define actions just for one particular toolbar instance call defineAction in target-procedure and pass "instance" as the last entry of the second (pcColumns) parameter. There is no need to have a corresponding value in the third (pcValues) parameter for this.

This thread is closed