The most common use of entity events is to control cursor movement for character-based host applications. These examples illustrate several different ways to do this.
In each case the problem is the same: there is no way to directly control the movement of the cursor on a character-based terminal. The host application will move the cursor to any one of a number of pre-defined locations in response to keystrokes entered by the user. The issue is: how can Verastream best tell the host application how to move between positions on the terminal screen?
Each example is based upon the Pine e-mail program model which is supplied with the Verastream development kit. Each example uses a different method to move the cursor while using tabbing and tab stops to write attribute values to the AddressEdit entity.
All of these examples can be tested in a similar way. You will need to have a machine running the Pine e-mail program. (Pine is freely available from the University of Washington.) You will need an account on the machine running Pine which you don't mind playing with. Pine does not actually need to be attached to a real mail server for these tests.
Use the Design Tool's Session Setup dialog to point to the machine running Pine. You will probably also want to modify the login and logout command lists to login and logoff from the test machine, and to start and quit Pine. The command lists supplied with the example work with an unmodified Bash shell running under Linux.
Once you can successfully connect to the machine running Pine, make sure that there is at least one e-mail address in Pine's address book. (The Address_add entity can be used to do this.) Then navigate to the Address_edit entity and use the Write Attributes Test dialog to:
The test data you enter in the Write Attributes Test dialog can be reused if (after writing the attributes) you type CTRL-C (in the Design Tool's terminal window) to tell Pine to discard the changes, and then re-display the Address_edit entity.
The Move Cursor example uses an entity event handler which handles the Move Cursor event. The event handler is given two pieces of information: where the cursor is and where it needs to go. It is up to the event handler to figure out the best to get from here to there.
Using a Move Cursor event handler bypasses the normal Verastream tabstop logic.
The event handler itself is simple. If the target location is in a row above the current row, move the cursor up; otherwise move it down.
The Pine model has an entity event handler attached to the Address_edit entity. The Address_edit.LineDown and Address_edit.LineUp operations have an event handler attached which simply logs the name of the operation executed.
The Scripted Tabbing example uses the standard Verastream tabstop logic, but overrides the operations used to move the cursor.
Using this kind of implementation is useful when the standard tabstop logic works well enough to decide where to move the cursor. In this case, trying to move the cursor beyond the last entity will cause a timeout error. The operation event handler suppresses this timeout so that Verastream's tabstop logic can work normally.
The Scripted Tabbing example attaches an event handler to the Address_edit.LineUp and Address_edit.LineDown operations. The event handler first executes the default operation (to move in one direction or the other). If moving the cursor results in a timeout, the timeout error is suppressed, Verastream notices that the cursor hasn't moved, and reverses the tab direction.
The Pine model uses the same operation event handler for both the Address_edit.LineDown and Address_edit.LineUp.
If tabstops are defined, the event handler executes the default operation (line up or line down), and then waits until the cursor reaches any of the defined tabstops.
If no tabstops are defined, the event handler waits for the cursor to move and returns, figuring that wherever the cursor ended up must be okay.
If the cursor does not move after issuing a cursor movement command, a timeout will be reported. In this case, the event handler assumes that the cursor can't move any more in that direction, so the timeout error is not reported. The Verastream tabstop logic will notice that the cursor hasn't moved, so the cursor movement is reversed.
To force a timeout to reverse the cursor movement:
Executing the test will move the cursor forward (down), causing a timeout at the Addresses entity. The cursor movement then reverses to reach the Nickname.
The Write Attributes example is significantly more complex than the others. In this case, the event handler is handed a set of attributes (names and new values) which needs to be written. The event handler is responsible for figuring out the order in which to update all of the attributes.
Moving the cursor on the Address_edit entity is simple: send a cursor-up command to move up; send a cursor-down command to move down. The optimal strategy to handle attribute writes is write the attribute values while moving the cursor in only one direction, starting with either the first (topmost) or last (bottommost) attribute, whichever is closer to the starting cursor position.
The implementation strategy is to first gather information about the attributes to be written, to decide where to begin and which way to move the cursor, and then to move and write to each attribute value in turn. This is done as follows:
The event handler contains several subsidiary classes which simplify the actual
event handler code (that is, the
writeAttributes() method itself).
A priority queue manages sorting the attributes, an attribute-region object
keeps the attribute name and location together, and an iterator for the
queue returns the queue contents (the attributes and locations) in the
The model is the standard Pine model with an entity event handler attached to the Address_edit entity.
The Entity Arrival example demonstrates how to use an entity arrival event to automatically bypass an entity. This prevents the need to add the entity as an intermediate entity to each operation that might encounter it.
The implementation of the event handler is fairly straight forward. The
entityArrival() method is called when VHI recognizes the
entity. In the method an operation is executed to bypass the entity.
The pine model is used to demonstrate this ability. The CancelChanges entity is configured to be automatically bypassed. The event handler is attached to this entity and the "Immediate arrival processing" option is checked in the Advanced Entity Properties. This is important, otherwise the entity will not be recognized during execution of operation commands.