The field declarations, transition definitions, and graphical user interface for Tracker applications are specified by using a special process description language (PDL). This chapter describes the PDL and consists of:
PDL file
Field declarations
Transition declarations
View declarations
Help declarations
A PDL file (a file coded in the process description language) defines a complete request tracking system, including the data to be recorded, the operations allowed on that data, rules controlling those operations, automatic actions performed by the system, and the application from which users can access the request database.
After you have gathered the information necessary for defining your process, you can put together your PDL file.
Specifically, Tracker allows you to define the following for a system:
fields in the request
transitions, in terms of:
name
prior state and new state
rules
actions
views (the windows used to access request information). Some typical display areas in view windows are:
control bar
query results area
request form area, the rows of request information to be displayed, including labels and fields
help information accessible through the on-line help system
The declarations and top-level expressions in the PDL resemble those in a block-structured language such as C. The blocks are delimited by braces ({}). Declarations are separated by semicolons (;).
White space, including newlines, is ignored. Comments are allowed, using either the C form (/* comment */) or the C++ form (//comment).
You can use the #include, #define, and #ifdef C preprocessor constructs.
A PDL file has three major sections (which must be declared in this order):
Field declarations, where the fields in the request are named and where their types are declared.
Transition declarations, which define the states through which requests can pass and the rules for controlling the process.
View declarations, where the GUI applications to interact with the request database are defined.
The format for a PDL file is shown in Figure 2-1. Help declarations, that is, the information on help cards in the on-line help system, can be made for most items in a PDL file. Since they take up a lot of space, the help declarations are not shown in Figure 2-1. They are described in “Field Declarations” later in this chapter.
![]() | Note: The PDL files for supplementary applications contain view declarations only, since they use the same field and transition declarations as their main view PDL files. |
Fields are defined by type at the beginning of the PDL file. You can declare fields that display in the user interface as well as fields for internal purposes such as scratch variables. Note that you declare only fields in this section. You specify default values for fields (and other manipulations) in the view declarations section.
The field types available in Tracker are shown in Table 2-1. Those types that display predefined values through the “Values” item in the field menus are indicated. The “Values” menu is displayed when the user clicks the right mouse button on a field.
Table 2-1. Tracker Field Types
Type Name | Comments |
|---|---|
boolean | Holds boolean data (true/false). Displayed as either True or False. Accepts entries of True, False, T, or F. The “Values” menu item displays “True” and “False.” |
date | Tracker accepts a wide range of formats for dates and times. To see the full range, refer to “Using Dates” in Chapter 6, “Advanced Design Techniques.” |
file | Holds a file name. The “Values” menu item displays a pop-up file selection dialog. If a file name is entered through the GUI, the file must exist. The file type has special implications for ClearCase® users (see“Using file with ClearCase” below). |
int | |
journal | Holds multiple lines of text. Allows the system administrator to maintain a history of the changes made to any request. Instead of overwriting the current information, changes are appended to the existing history, for as long as the request is active. See “Using the journal Field” below. |
list-of | |
long-text | Holds multiple lines of text. Intended for fields containing explanations. There is no “Values” menu item but there is an “Edit...” item for using an external editor. |
one-of | Holds an enumeration value, that is, one of a set of predefined values. Values are separated by commas and can be legal identifiers or quoted, single-line text. Its use is described in detail below. The “Values” menu item displays either a sub-menu or a pop-up selection dialog, depending on the number of values. |
short-text |
When entering a file in a field of type file, Tracker responds as follows:
for a plain file: it verifies that the file exists.
for a file in a ClearCase Versioned Object Base (VOB): Tracker verifies that the file exists, determines which version is selected by the current ClearCase view, and records the version information in the file field.
The menu for file fields includes two items useful for obtaining information about ClearCase files, available if the field has a valid value and the file referred to is a VOB file. They are “Describe” and “History,” both accessible from the “Actions” sub-menu. They use ToolTalk™ to communicate with ClearCase. “Describe” executes the cleartool describe -long and “History” executes the cleartool lshistory command on the file referred to by the field. Both commands display their results in a tty window, created as needed, which is separate from the Tracker application. Subsequent command results appear there as well.
The default one-of list is a closed set from which a user must select one of the pre-defined values shown in the “Values” menu or dialog box. You can specify an open one-of set by entering an ellipsis (...) immediately (no comma) after the last value. Use open sets to specify the values used most often and to allow entry of non-predetermined values.
A one-of field may contain any single-line text value. In PDL, one-of field values may appear either as identifiers or as single-line quoted strings. A legal identifier must begin with an alpha character (upper or lower case). It may include letters, the underscore (_), and digits, in any order. You may not begin a legal identifier with $, since the $ prefix marks predefined fields or environment variables.
A single-line quoted string value may use the full character set. You can mix legal identifiers with quoted literal strings in a one-of field definition. For example;
x: one-of
a, b, c, '123', 'sarah', '4.0.1' ...
|
The short-text values let you pull in values from external programs by using the exec commands (see “Using the exec Functions” in Chapter 6, “Advanced Design Techniques”). It also lets you cross-assign values between fields. You can use the setValue method to set the one-of field value to short-text. For example, suppose that the Submitter field is a one-of field with the values being a list of engineers in a particular group. You can set the value to default to the current user of the application ($USER), which is a short-text field.
If a one-of field has 25 values or less (default), Tracker creates a cascading submenu off its “Values” menu item in the GUI. If there are more than 25 values, Tracker builds a selection dialog box that presents the user with a scrolled list from which to choose a value.
To change the default setting for the number of fields required for a scrolled list, you must set the maxAssistValues resource in the app_defaults file (see “Personal Tracker Resources” in Chapter 6, “Advanced Design Techniques.”
There are two limitations on using one-of fields:
The same value cannot appear in more than one closed enumeration in a one-of field. You can, however, share an entire enumeration between two fields by listing both field names in the same declaration or by using like (see below).
You may not use the same identifier for a one-of field value and a state identifier. If you do, Tracker produces an error message indicating that the state identifier is a duplicate name. Transition states are discussed in more detail in “Transition Declarations.”
Figure 2-2 shows the history of the actions taken on a request in a Tracker application. The actions SUBMIT_BUG, ASSIGN, and RESOLVE are recorded, along with the date and the submitter's name. Note that you cannot customize the format of the entryheader when you design your application; Tracker creates the headings automatically.
You can write anything you like to the body of the journal entry using setValue(). The RTS example PDL file stores only the transition name in the journal entry body, using:
history.setValue($TRANSITION.text); |
This is an example of a more complex journal entry:
tmpShortText.setValue(
execFilter('echo “Transition from state $STATE_old
to $STATE”'));
history.setValue(tmpShortText.value);
|
Figure 2-3 shows the field declaration for a journal field.
The key word like lets you share a field type between two fields and apply different help text.
For example;
fieldname1: fieldtype1
help {helpcardspec1};
fieldname2: like fieldname1
help {helpcardspec2};
|
In the example, fieldname2 has the same type as fieldname1, that is, fieldtype1. It uses a different help card specification, helpcardspec2.
At the beginning of the field declaration section, the following entry can appear:
entity-class entityname; |
Tracker fields in a PDL file are grouped into an entity for direct access from DML. To specify a custom name for an entity, you must declare it here; otherwise, the default name tracker_request is used.
The concept of entities in the database is covered in more detail in Chapter 3, “Using the Data Manipulation Language (DML).”
Tracker automatically assigns an entity identification number ($ENTITY_ID) to each new request as it is submitted to the database. Because the ID number is assigned prior to the execution of any actions, its value can be used in an action to set the value of other variables. For example, where report_number is of type int:
actions {
report_number.setValue($ENTITY_ID.value);
...
}
|
The following fields are predeclared and controlled solely by Tracker:
Environment variables are also available as predeclared fields. They can be changed by the PDL and used in transition rules and actions through the external methods (see “External Methods” later in this chapter).
The code segment in Figure 2-3 shows the field declarations for the PDL file used to generate the rtsquery application.
Each declaration shows the field on the left and its type on the right. Notice how the short-text type is used for short entries and how long-text is used for the multiple-line fields. Fields with the one-of designator are followed by the defined set of values.
Transitions are the operations performed on a request to change its state or data. To declare a transition, do the following:
Enter the name of the transition in the transitions section of the PDL file. This name will appear in the Modes menu and will be enabled for appropriate states.
Define the change in state (if any) as a result of this transition.
Define global actions and rules for your transition group. These are specified at the bottom of the transitions section and are applied to all transitions after the local rules or actions are applied to the individual transition.
Define on-line help as desired. You can define help for the transitions, individually and as a group, for a set of rules belonging to a transition, for a set of actions belonging to a transition, and for the global rules and transitions.
![]() | Note: Wherever you provide help text for a rule or an action you can use the key word include-pdl to include the actual rules or actions declarations in the help card; this is recommended only for sophisticated end users or for debugging transitions. |
The format for the transitions section is shown in Figure 2-4. Reserved words are shown in normal font; variables are shown in italics. On-line help declarations are also shown.
The following code segment provides an example of how transitions are declared. The code segment is the declaration for the RESOLVE transition in the rtsquery application. RESOLVE is used when a request has been executed and needs to be signed off by the approving authority.
RESOLVE(AWAITING_RESPONSE=>AWAITING_APPROVAL) {
help {
help-title 'RESOLVE Transition';
short-help-title 'RESOLVE';
fixed-width-help-text'
Use RESOLVE to close out a request. RESOLVE takes a
request from the AWAITING_RESPONSE state to the
AWAITING_APPROVAL state.';
};
rules {
resolution_description.isSet;
resolved_in.isSet;
}
actions {
recommendation.setValue(RESOLUTION);
}
}
|
The first line contains the transition name RESOLVE and the change of state, from AWAITING_RESPONSE to AWAITING_APPROVAL.
The help declaration (which is optional) comes next. Notice that this example has a full title and a short title. The fixed-width option is also used in the help text declaration. This option is described in “Creating a Help Declaration” later in this chapter.
Transition declarations can have a rules section for establishing information required for the transition and an action section for specifying what takes place as a result of the transition. Tracker also provides methods, that is, operations on fields, that are useful in creating rules and actions.
In the example, the rules section contains two rules, both of which must be true for the transition to be performed. They both use the isSet method.
The rule
resolution_description.isSet; |
requires that the Resolution field in the main view be filled in.
The line
resolved_in.isSet; |
requires that the Resolved in field in the RTS files view be entered.
The actions section has only one action in this example. It uses the setValue method to change the Recommendation field to the value RESOLUTION, signifying that the request has been resolved.
Request states are declared inside parentheses that follow transition names, separated by the transition operator, =>, as follows:
(priorstate (priorstate)n => newstate) |
These are the options for using the transition operator:
(=>statename) creates the request where none previously existed.
| (priorstate=>newstate) |
| |
| (=>) | signifies that any prior state is permitted and that there is no change in state as a result of this transition. | |
| (S1, S2, S3 ...=>S4) |
|
RTS transitions such as “NOTIFYME” and “EDIT” have no required states. Transitions for creating new requests require a new state but no prior state.
![]() | Caution: If you use the same state in more than one transition, it must match in case and spelling; otherwise, different versions of the name will be interpreted as different states. |
The rtsquery application (see Appendix B) defines these states:
After the transition's state change is declared, you declare the rules, if any, and the resulting actions, if any. Tracker supplies predefined methods for declaring rules and actions. Tracker also lets you use the following logical operators (shown in Table 2-2), borrowed from the C language.
Operator | Description |
|---|---|
&& | and |
|| | or |
! | not |
?: | ternary (if ... then ... else ...) For example, |
All the operators except the && (and) operator function in top-level rules. The use of && is restricted to embedded expressions in the PDL file; for example:
rules {
x.is(x.setValue(name.isSet ? address.isSet && company.isSet :
False));
}
|
For more information on anding top-level conditions, refer to “Rules” below.
In addition, Tracker automatically provides actions setting the $STATE field to the new state and the $TRANSITION field to the transition name.
Rules are declared after the state declaration; they are preceded by the key word rules and are enclosed by braces ({}). In the transition example, the RESOLVE transition has these rules:
rules {
resolution_description.isSet;
resolved_in.isSet;
}
|
They require that there be entries in both the Resolution field and the Resolved in field.
An individual rule is terminated by a semicolon (;) and consists of one or more conditions. You define conditions using the boolean Tracker methods. An individual condition can be ored with other conditions, using the operator ||. This means that the entire rule (terminated by the semicolon) is satisfied if any one (or more) of the individual conditions is satisfied. Rules separated by semicolons (;) are effectively anded together, that is, all of the rules must be satisfied in order to permit the transition.
If all conditions are not met, the transition will not be permitted (its Apply button will not be enabled) and incorrect fields will be highlighted accordingly. It is useful to think of a rule as having top-level and secondary-level conditions. A top-level condition is the main part of a rule; the secondary level refers to conditions inside nested expressions. When a rule is not met, only the fields in top-level rules are highlighted. The fields at the secondary level are not highlighted. For example, consider the rule:
owner.is(submitter.value); |
The rule means that the owner value must be the same as the submitter. If this condition is not met, then the owner field (which is a top-level rule) will be highlighted. The submitter field is in a nested expression and will not be highlighted. It is a good idea to explain such relationships between fields in an on-line help card, either in the transition help card or the associated rule help card if it exists.
The predefined methods are presented in Table 2-3 through Table 2-8 according to these categories:
external methods
methods for testing field data
methods for retrieving field data
methods for making field comparisons
methods for changing field values
methods for field value computations
methods for changing field characteristics
Three methods provide access to shell commands (and environment variables) external to the PDL: execCommand, execFilter, and execSelect. They take a single string parameter and are not associated with fields. These methods are described in Table 2-3. For more information, see “Using the exec Functions” in Chapter 6, “Advanced Design Techniques.”
Method | Description |
|---|---|
Returns the completion status of the command as a boolean value. It is most useful when the output of the command is not required by the PDL, but the exit status of the command may control further PDL execution or indicate the validity of field data in a rules section. | |
Returns the output of the command executed as a long-text value. It is most useful in the actions section of transitions. For example, use it to capture the output of a command and assign it to a field. | |
Given a DML (data manipulation language) select statement with semicolon (;) terminator, returns a long-text value. The select statement is executed. If the result is a single record, the value of the first field in the select statement is the return value; otherwise, the return value is the empty string. |
Here are some useful Tracker environment variables, accessible through the external methods:
$FIELD_LIST is set to name all the fields of the request (structured as a string with names separated by spaces).
$MODIFIED_FIELDS is set to name all fields that have changed.
$<fieldname> is created for each field of the request, using the name of the field as the name of the variable and generally containing the value of the field.
$<fieldname>_old holds the former value of the field if it changes. The field name also appears in $MODIFIED_FIELDS.
$<fieldname>_file contains the actual value of a field if it is too long for the $<fieldname> variable. In this case, $<fieldname> contains the single ! character and $<fieldname>_file contains the actual field value(s).
$<fieldname>_old_file holds the former value of a long field if it changes. (In such a case, $<fieldname>_old contains the single ! character.)
The methods for testing field data are called against a field, for example:
description.isSet |
They do not take parameters and do not accept the empty parentheses that C uses: for example, description.isset() is incorrect. They are predicates; they return a boolean result, so they can be used in rules. The methods are listed in Table 2-4.
Table 2-4. Methods for Testing Field Data
Method | Description |
|---|---|
Any field type. Determines whether it has been changed during the current editing session. | |
Any field type. Determines whether the field is presently set (some fields may not yet have been filled in). | |
Must be a field of type boolean. If the field is set to True, then this says false; if the field is False, this says true. |
In addition, you can test any field of type boolean with the value method (described in Table 2-11), as in this example:
boolfield.value; |
If boolfield is true, then this rule will be satisfied; if boolfield is false, or if it is unset, this rule will be unsatisfied (boolfield will be highlighted in the GUI).
The methods in Table 2-5 return other types of data in addition to booleans. They are used only inside expressions within parameter lists, typically in conjunction with a boolean method. Since there are no side effects from these methods, they are not appropriate for use as top-level methods in actions, although this is legal.
Table 2-5. Methods for Retrieving Field Data
Method | Description |
|---|---|
Any field type. Returns the name of the field. | |
Must be a field of type list. Returns the number of items in a list. | |
Any field type. Returns the value of this field in the database, even if the user has made changes (but has not yet committed them to the database). | |
For a text string, tells how long it is. | |
Returns a text string representation of any kind of field. | |
Returns the value of the field, represented as the appropriate type. |
The methods for making field comparisons are called against a field and take an expression as a parameter.
For example,
priority.isGreater(3) |
tests whether the priority field is greater than the value 3. These methods are shown in Table 2-6
.
Table 2-6. Methods for Making Field Comparisons
Method | Description |
|---|---|
Checks to see if the value of the field is expr. | |
fieldname and expr must be strings. Checks to see if they're the same value, but with case folding (ignoring case). | |
Can be performed on most types, but only where fieldname is the same type as expr. Checks whether fieldname is less than expr, according to their types. | |
Can be performed on most types, but generally only where fieldname is the same type as expr. Checks whether fieldname is less than or equal to expr, according to their types. | |
Can be performed on most types, but generally only where fieldname is the same type as expr. Checks whether fieldname is greater than or equal to expr, according to type. | |
Can be performed on most types, but generally only where fieldname is the same type as expr. Checks whether fieldname is greater than expr, according to their types. | |
Can be performed on most types, but generally only where fieldname is the same type as expr. Checks whether fieldname is not equal to expr, according to their types (opposite of “is”). |
The methods for field value computations let you perform computations using field values. They take an expression, which can contain nested methods as well. For example, the action
due_date.is(due_date.setDefault('now + 30:00:00:00'));
|
computes the value of the expression ('now + 30:00:00:00'), which is equal to the current date plus 30 days, sets that value as a default in the date field, and uses that value if another has not been entered.
These methods have two categories: methods that actually change the field values and methods that perform calculations with field values.
Table 2-7 shows the methods for changing field values.
Table 2-7. Methods for Changing Field Values
Method | Description |
|---|---|
Sets the value of the field to expr. | |
Causes the field to have no assigned value. A subsequent isSet method will return false. | |
Sets the field to the value expr if the field value has not yet been set. | |
Applies to lists only, adding expr to the end of the list. Resulting expression is the list itself. | |
Applies to lists only, removing the nth value from the list where n = expr. Return expression is a boolean: true if item is removed and false if n is greater than the number of items in the list. |
Table 2-8. Methods for Calculating with Field Values
Method | Description |
|---|---|
Applies to lists only, returning the value of the field whose subscript = expr. The result type is the base type of the list. If expr is greater than the number of items in the list, the list field will be unset, that is, it will no longer have values and isSet will return false. | |
Both must be boolean. Returns true if both are true; false otherwise. | |
Both must be boolean. Returns true if either is true; false otherwise. | |
Both must be integers. Returns the sum of the two. | |
Both must be integers. Returns the difference of the two. | |
Both must be integers. Returns the product of the two. | |
Both must be integers. Returns the result of dividing fieldname by expr. |
Currently, there is only one such method:
<fieldname>.setReadOnly
This method takes a boolean argument; it defaults to ReadOnly (true). It can be invoked in any type of field and its action is to render the field read-only in the GUI. This means the user cannot modify the data in the field, although the PDL code itself may still do so.
The action of this method lasts only for the current transition. Once the transition has been applied or cancelled, the field reverts to its original state.
The formats for Tracker windows are declared in the views section in the PDL file. You can declare any number of views to be applied to the same data in the request tracking system. You can also permit end users to customize their windows.
The views section is identified by the key word views. The declaration of the main view is first, followed by any auxiliary view declarations. Each view has a name, a title declaration enclosed in parentheses, and a body section enclosed by braces in which various labels, fields, and controls are declared. The general format for the views section is shown in Figure 2-5.
The main view name declared in the PDL file:
appears in the title bar
serves as the X11 application class name to
retrieve resources from each user's personal resource file (usually ~/.Xdefaults)
select an application's app-defaults file
select the icon used for the application by 4Dwm
is used to invoke the application (after conversion to all lower case)
The auxiliary view names appear as items in the Views menu in the main view and also in their respective title bars.
Each view can have a title declaration, within the parentheses following the view name. If the title declaration is empty, no title will be drawn above the view. In declaring a title, you can use strings inside single quotes and field names defined in the fields declaration section. The strings and field values are assembled into a one-line title at the top of the entire view.
Fields that display in a title are not editable inside the title area. You can use white space to separate items, in which case they are positioned next to each other, or you can use one or more commas to separate them. To stretch a title so that it reaches across the window, use commas; these add padding so that all the comma-separated sections are of equal width.
The body of the view is enclosed in braces and declares the features of the window, that is, labels, fields, controls, and associated on-line help. A window is defined feature by feature from top to bottom. Tracker provides a number of key words to make the process easier.
The key word display lets you define an area within the window. You can specify a title, defined in the same way as the title of the entire view. You can also select resources to control both the appearance of the display as a whole and items within the display area. See “Feature Names” in the next section.
Within the view body, you can also declare the control bar, which contains the Modes menu, button controls, and the query results area for displaying request summaries matching the query criteria.
The key word row helps you organize fields and their labels, entered as literal strings called tuples, into a row. Similar to title declarations, the items in a row are specified with or without comma separators. Padding is added at the commas, so that the groups separated by commas are evenly spaced. If the row is inside a display, the first literal string in each group is treated as a label. The width of a given column is expanded according to the longest label in the display. Rows can be given names, which are used in resource selection, but do not display any title text. Tuples are discussed in “Defining a Request Form Area” later in this chapter.
Tracker provides two mechanisms for formatting the interface:
PDL key words for defining application-specific parts of the user interface
predefined feature names attached to X11 widgets
Tracker supplies a number of key words to let you declare the standard features of Tracker applications. These are the reserved words and their meanings in PDL files.
| views {} |
| ||||
| display () {} |
Displays the control bar, including the Modes menu (see Figure 2-7). The parentheses contain the title, if any. The braces contain the transition commands in the Modes menu. If you want to include all of the defined transitions, enter the key word transitions with no other entries. If you want a subset of the transitions, enter them explicitly after transitions. If you leave the braces empty, there will be no transitions; effectively, you will have a query-only application. These conditions will cause error messages:
Displays the query results area (see Figure 2-8). The parentheses contain the title, if any. The title defaults to the field name. Insert fields to be displayed in the summary line inside the braces after the key word index. Data in this area is aligned in columns, and you can define the width of each column, and add a custom title to it. For example, the PDL file in the sample RTS system has this query results definition:
The first four field definitions are followed by a width (number of characters) and a title string. The last column defaults to the total width permissible. Any part of the field definition left blank will use the default width and/or title. These field definitions need not be set out on individual lines; they can be listed sequentially. An error message is displayed if there is no qresults declaration or if there is more than one. In order for the users to sort on a field in the GUI, the field must be placed in the declaration for the query result area. Users can only sort on one field at a time. | ||||
| row {...}; |
For more information, refer to “Defining a Request Form Area” later in this chapter. |
A feature name identifies an element in the user interface and is attached to the X11 widget that implements the display, which in turn retrieves resources. Feature names precede the PDL key words (described in the previous section) and are followed by colons. A number of useful appearance variations are provided in the standard Tracker application defaults file.
The feature names applied to views, displays, and rows are used to select resources that fine tune the appearance and behavior of the interface. Due to the hierarchical way in which X11 manages resources, a name attached to a view or display can also be used to select resources for contained display items that are nested several layers deep.
For example, if a view named viewOne contains an unnamed display, which in turn contains an unnamed row, which finally contains a certain field, you can specify resources for that field in the resource file or the application defaults file by the name viewOne, and they will be correctly applied to the field.
Resources specified by the application name itself generally take precedence over those specified by the application class name. Resources specified in individual users' resource files generally take precedence over those specified in the application defaults file.
Complete details on resource selection are located in the Xlib Programming Manual for Version 11under “Managing User Preferences.”
A number of resources are defined in the Tracker application default file (and included in the application defaults file generated for Tracker applications). To use them, you must give the indicated name to the feature you want controlled (or to a display or row that contains it). Predefined feature names are illustrated in Table 2-9.
Table 2-9. Predefined Feature Names
Names | Description |
|---|---|
Defines a list field that is one row high. | |
Draws a high-visibility rectangle around the specified display area to set it off from the rest of the interface. | |
Defines a long-text field to be the specified number of rows. | |
Defines a display area to be the specified number of columns. |
For more information on feature names, refer to “Using Dates” in Chapter 6, “Advanced Design Techniques.”
Figure 2-6 shows the declarations in the views section of a PDL file. The rtsquery application has two views: RTSQuery and RTSFiles. The main view has three customizable display areas: a control bar, a query results area, and a request form area. The auxiliary view RTSfiles is used to list files so it has a simple structure of three long-text fields and their labels.
Control bars are identified by the reserved word control-bar. They use the reserved word transitions to specify the selections in the Modes menu. In the control bar, you have the ability to define which transitions are available in the Modes menu (as shown in Figure 2-7).
Query results areas are indicated by the key word qresults(), which is preceded by the tag for the area. Following qresults() is the declaration of information to appear in each line of the list, enclosed by braces.
Figure 2-8 shows the part of the PDL file that declares the query results area for rtsquery with the corresponding display area. Notice that the declaration uses the two predefined fields $STATE and $ENTITY_ID. The numbers enclosed by colons (:) indicate the width of each column.
In the display area, numeric fields such as ID# are right-justified, and text fields are left-justified.
Tracker provides two icons in the query results area. A small rectangle next to a request in the list indicates that the request has been displayed in the form area. A check mark indicates that the request has been edited (see Bug #1 in Figure 2-8).
Two entries in the app-defaults file affect the query results area. The entry
*query_results.visibleItemCount:5 |
sets the number of lines to display at startup (request summaries) in the query results to five. If your end users prefer a different initial size, you can change this entry.
When you perform a query on the request database, Tracker retrieves the first 50 entities that it finds so that it doesn't need to perform another retrieval until the user scrolls past the fiftieth line. The entry
*QueryFetchCount: 50 |
controls the number of summaries retrieved. Retrieving more entities slows the initial query results area display but the trade-off is that you have more entities to scroll through. If performance on queries becomes a problem, you can adjust the fetch quantity.
The rtsquery request form area uses the key word display to specify the items that make up the form in the GUI. The form area in the main view body section of the PDL file is identified by this key word (see Figure 2-5). Fields are declared in the row in which they appear from left to right, separated by commas.
Fields are declared in the form of tuples. Here is a description of a typical lay-out for fields and labels. However, it is not the only way, and you can experiment as much as you wish.
Each tuple contains the field name and a label. The label for the field is entered first, enclosed in single quotes, followed by the name of the field as declared at the beginning of the PDL file. Figure 2-9 shows the code in the PDL file and the resulting view window.
You can arrange the request form area in any way you like by using tuples in the row statement. If a row consists of a single tuple, that tuple will be expanded to fill the row. For example, this format
row{'Description' 'hello there'}
|
fills the row. If you divide the row up into several tuples, the row width is evenly divided among the tuples. For example, this format
row{'Description' 'hello there', , }
|
would cause the first tuple, consisting of 'Description' and 'hello there', to use one third of the full row width. The other two tuples are empty, so the rest of the row will be empty.
You can use empty strings within a tuple to get a similar effect. For example,
row{'Found in:' ' ', ' '};
|
creates two tuples of equal width in the row. The first tuple contains the text “Found in:” plus a specified amount of space. The second tuple contains only white space. If you use this format:
row{'Found in:'};
|
the text fills up the row completely.
To calculate the amount of space required for each item in a tuple, consider these guidelines.
Literal strings default to their actual width in characters, but may expand to fill available space.
Text and text field widgets (which are used to enter field data) have a preferred width determined by the application defaults or other resources.
Tuple spacing is affected by the lay-out of corresponding tuples in the rows above and below.
The tuple is laid out from left to right, with a single space between items. The last item is then “attached” to the rightmost edge of the tuple and the tuple is stretched to fill its allotted space in the row.
When the width of the tuple is adjusted, you may have a larger space opening up between the rightmost item and its neighboring item to the left. The amount of space created will depend on how wide the tuple is, which in turn depends on the row width and number of tuples in the row. This example shows how to use tuples to left-justify a label:
display() {
row{'Resolution:' ' '};
fourRowLongText:
row{resolution_description};
}
|
The first row contains one tuple with two items, the label 'Resolution:' and the space ' '. The label will occupy a 10-character space starting from the left, and is separated from the space item by a 1-character space. The space item then expands to fill the rest of the row.
In addition to your custom settings, Tracker adjusts the width of tuples so that they form justified columns in a display. A tuple in a given column in a row is always allotted the width of the widest item in that column.
For example, in this three-column display with three rows, the width of the second column will be equivalent to the width of the 'Recommendation:' tuple in the third row:
threeColumn: display() {
row{'Report #:' $ENTITY_ID,
'Status:' $STATE,
'Priority:' priority};
row{'Type:' type,
'Submitter:' submitter,
'Owner:' owner};
row{'Date:' submit_date,
'Closed:' close_date,
'Recommendation:' recommendation};
}
|
Figure 2-10 shows how display appears on the screen.
When a user holds down the right mouse button over a field, a menu appears displaying the commands “Reuse,” “Revert,” “Clear,” and, optionally, “Values” as an aid to filling in the field.
The “Reuse” command reuses the last value displayed in the field.
The “Revert” command reverts to the prior value for the request.
The “Clear” command clears the field.
If the field type (as declared in the Fields section of the PDL file) uses the “one-of” designator, then the selection “Value” appears with a rollover menu that contains the declared set of values.
Users can select a value from the menu or type directly into the field.
You can “tear off” the rollover menu by clicking on the perforation line at the top of the menu. It then appears as a freestanding menu (see Figure 2-11).
The field declaration and view declaration for the Status field are shown in Figure 2-11, along with the resulting pop-up and rollover menus.
If you are making major modifications to the RTS applications or creating your own tracking system, you need to provide on-line help to your users. Tracker provides the same on-line help system available in all CASEVision environments. If you are unfamiliar with the operation of on-line help, please refer to the CASEVision Environment Guide.
On-line help is easily provided by making help declarations in the PDL files. You can create help cards for such topics as:
the entire application
fields as a group and individually
transitions as a group and individually
rules and actions individually within transitions and globally
all and individual views
individual display areas
control bar
query results area
rows in a display
Running tvgen (and rtsgen) automatically creates a hierarchy of on-line help based on the help declarations. Users can search for help by topic or by clicking the item on the screen while in context-sensitive help mode.
To create a help declaration, use this general format:
help {
help-title 'fulltitle';
short-help-title 'shorttitle'; //optional
help-text 'helpbody';
;
|
The entry following help-title is the complete title for the help topic. This title appears in the help index.
If you prefer a shorter version of the title in the graphic help browser, add the
short-help-title line with an abbreviated version of the title. The help information is entered after the key word help-text. All of the text must be enclosed within single quotes. By default, help text appears in proportional font; if you prefer fixed width spacing for your help text, then use the key word fixed-width-help-text in place of the key word help-text.
In addition, you can specify that the actual rules and actions declarations for a transition appear in a help card by using the key word include-pdl; this is covered in more depth in the “Transition Declarations” section.
![]() | Note: If you wish to enter a single quote (apostrophe) in help text, you must precede it with a backslash (\'). |
For the sake of conciseness, the entries inside the braces following the key word help are presented as the single term helpcardspec (short for help card specification) in this guide.
The location of the help cards in the on-line help hierarchy is a function of the declarations in the PDL file. The locations for help declarations are shown in Figure 2-12 and Figure 2-13.
In providing on-line help, you are not just documenting isolated features—you are building a system for providing information to your users. Users get information from the on-line help system in two modes: context-sensitive mode and browsing mode. This section covers
the help card hierarchy
top-level help card strategy
bottom-level help card strategy
It is important to remember that on-line help has a hierarchical structure. Figure 2-14 shows a typical Tracker hierarchy; it represents the hierarchy from a user's point of view. The stacked help cards in the diagram indicate that there can be multiple help cards and subtrees at that location. The order in which the help cards appear (top to bottom and left to right) correspond to the sequence in which they are declared in the PDL files, except for the help cards that are shown in the illustration in white. These cards are actually declared elsewhere in the hierarchy, where they appear in gray; they are in the hierarchy redundantly as a convenience for users.
In a Tracker application, you must declare the top-level system help card (at the beginning of the PDL file) and the top-level view help card (at the beginning of the view declaration section). If these are missing, you will get warning messages when tvgen (and rtsgen) is run; more importantly, your end users may get error messages if they try to use on-line help.
At the top level, it is important to make the resulting hierarchy easy for users to find what they are looking for. The top-level system help card file forms the root of the on-line help hierarchy. Below it are the top-level cards for the fields and transitions and the application help cards, which group the views.
Note that the help cards for individual fields and transitions (rules and actions included) can appear redundantly in the hierarchy, under the top-level field and transition cards and in the view subtrees that contain them. These help cards are actually declared in the fields section and transitions section of the PDL file respectively. These cards are shown in Figure 2-14 in white.
It is a good idea to include a help card for the control-bar in each application. The control-bar help card groups all relevant transition help cards as subtopics under the control-bar help card. If the user selects any item in the control-bar using context-sensitive help, help on the set of transitions provided by the application will be readily available in the subtopics window of the help viewer.
At the bottom level, you should provide detailed information for the individual transition cards on how the particular transition relates to the overall tracking process. You can describe the rules and actions in the card in the transition help card or separately in the associated rules and actions help cards.
Use help declarations for individual fields to clarify the intended use of the field and to give suggestions for using specific values for the field. The field help declarations appear at the bottom of the view help hierarchy. They are grouped under the containing row if you declare it; otherwise, they appear under the containing display area. If you declare neither the containing row nor display area, then the field help declarations are grouped directly under the view help card.
After adding or changing help declarations in the PDL, you can review the changes by running the application (after running tvgen and tvinstall) and by selecting items in the “Help” menu. Select “Browser” in the help viewer window to examine your help hierarchy.
![]() | Caution: tvgen does not remove help cards from the <databasedir>/tools/help directory before generating new on-line help. If you rename (or remove) an application in your system, you should remove the corresponding subtree in <databasedir>/tools/help. |