4.3. Programming the interface

Programming means we annotate the XML of the UI form files with some extra properties. They control the following things:

  • Which events in the current form replace it with a new form, e. g. clicking the Edit button loads the form called edit_item.

  • When and how requests to the Wolframe server should be sent and how the results should be interpreted when adding data to the widgets, e.g. executing a save item request with all the data in the text fields of the form added to the request XML.

4.3.1. Mapping XML data

Starting position

For mapping data structures from the user interface elements to the data description needed to fulfill an interface for a server request we need some kind of translation. An implicit mapping would only be able to describe very trivial data mappings. After drawing the user interface this translation has to be defined. On the other hand the requests answer returned by the server has to be mapped to be shown in the user interface elements view. Here applies the same: Some kind of translation is needed to map a server data structure to the user interface elements.

First example

Let's have a look at a QLineEdit element of a form and a possible XML representation of the data used for a request.

			
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE customer SYSTEM 'Customer'>
<customer>
  <name>John Smith</name>
  <address>Blue Police Box</address>
</customer>

			

For an insert or update request that transmits all data of the form to the server we have to fill the name field and the address field into the request data structure XML. The translation is defined as dynamic property "action" or "action." plus a suffix for the action identifier if needed. We will explain this naming of actions later. The value of the property is describing the request and could look as follows:

			update: Customer customer {name{{main.name}}; address{{main.address}}}

			

For the initial filling of the form with data we submit a request that just sends an id to the server. The answer that is returned by the server has then to be translated to fill the name field and the address field of the form. The translation is defined as dynamic property "answer" or "answer." plus a suffix for the action identifier. A detailed description of the language in the request and answer property value that describes requests and answers will presented in the next chapter. We provide here just an example:

			Customer customer {name{{main.name}}; address{{main.address}}}

			

Another example

Some elements are more complicated than that. They present the user a list of options or items the user to pick from, e.g. a list of cities.

When the form is saved, the currently selected element is written into the resulting XML:

			
<customer>
  <name>John Smith</name>
  <address>Blue Police Box</address>
  <city>6</city>
</customer>

			

In this case the widget with the city list can load its own domain data as a separate XML request:

			
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE city SYSTEM 'CityListRequest'>
<cities/>

			

and the corresponding domain load request answer definition in the dynamic property "answer" could look like this:

			CityList cities {city[] {id={main.city.id}; {main.city.value}}}

			

The answer contains all possible values in the domain, in our case a list of all cities and their internal id.

			
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE "cities" SYSTEM "CityList">
<cities>
<city id='1'>Tokyo</city>
<city id='2'>Lima</city>
<city id='3'>Beijing</city>
<city id='4'>Cairo</city>
<city id='5'>Tehran</city>
<city id='6'>London</city>
</cities>

			

4.3.2. Switching UI forms

A UI form contains a set of widgets, the dynamic property form contains the name of a widget (without extension .ui) to load.

For linking a push QPushButton click in the Qt designer to the switching of the form you have to attach a dynamic property named form of type string to the corresponding widget of type QPushButton:

Before loading the next form the client terminates all current requests, for instance a save request of the form data. In case of an error in an action any defined switching of the form is cancelled.

4.3.3. States and behaviour

Reserved private dynamic properties

The _w_ prefix is used for internal widget properties not of interest for the user.

Reserved public dynamic properties

The dynamic properties introduced here are edited by the user to stear application behaviour:

Stearing of widget behaviour

The following properties are reserved for states steering the behavior of the user interface:

Table 4.1. Properties

NameDescription
initialFocus

Boolean value for one widget in a form that should get the initial keyboard focus.


User interface flow

The following properties stear the user interface elements flow:

Table 4.2. Properties

NameDescription
form

Defines a form to be opened on click (push button). If the widget has an action defined, then the action is executed before and the form is opened when the action succeeds and not opened when it fails.

form:IDENTIFIER

Defines a form related to a context menu entry with identifier IDENTIFIER. If the context menu entry has also an action defined, then the action is executed before. The form is opened only if the action succeeds.


Additional interface elements

The following properties define additional interface elements:

Table 4.3. Properties

NameDescription
contextmenu

Defines a context menu with a comma separated list of identifiers of actions defined as propery value. Two following commas without menu entry identifier are used to define a separator.

contextmenu:NAME

Defines the (translatable) text of a context menu entry. NAME refers to a non empty name in the list of context menu entries.


Defining server request/answer

The following properties are used for the communication with the server:

Table 4.4. Properties

NameDescription
action

Defines a server request. This can either be a load action request for a widget that is not a push button or an action request without answer than OK/ERROR for a push button

action:IDENTIFIER

Defines an action request either related to a context menu entry (when clicked) or related to a dataslot declaration of this widget named with IDENTIFIER.

dropmove

Defines a action request that is issued on a drop request moving an object inside a widget or between widgets of the same type (same object name). The request is an action request without other answer than success or failure. Refresh after the action completed is triggered via a datasignal 'datasignal:drop' defined in the drop widget and a 'datasignal:drag' defined in the drag widget.

dropmove:OBJECTNAME

Defines a server request that is issued on a drop request moving an object from a widget with object name OBJECTNAME. The request is an action request without other answer than success or failure. Refresh after the action completed is triggered via a datasignal 'datasignal:drop' defined in the drop widget and a 'datasignal:drag' defined in the drag widget.

dropcopy

Defines a action request that is issued on a drop request copying an object inside a widget or between widgets of the same type (same object name). The kind of request and the signaling after completion is the same for a 'dropmove' action.

dropcopy:OBJECTNAME

Defines a server request that is issued on a drop request copying an object from a widget with object name OBJECTNAME. The kind of request and the signaling after completion is the same for a 'dropmove:OBJECTNAME' action.

answer

Defines the format of the action request answer linked to the widget activation (for example a click on a push button).

answer:IDENTIFIER

Defines the format of the request answer of the action defined as 'action:IDENTIFIER'


Variables and symbolic links

Table 4.5. Properties

NameDescription
global:IDENTIFIER

Defines an assignment from a global variable IDENTIFIER at initialization and writing the global variable when closing the widget.

assign:PROP

Defines an assingment of property PROP to the property defined as value "assign:PROP" on data load and refresh

link:IDENTIFIER

Defines a symbolic link to another widget. Defining the property "link:<name>" = <widgetid>: defines <name> to be a reference to the widget with the widgetid set to <widgetid>. Links are used to read data from other widgets on load and refresh.

widgetid

Unique identifier of the widget used for identifying it when resolving symbolic links or an address of a request aswer. When not explicitely defined it is implicitely defined as unique identifier on widget creation. Unique means unique during one run of one client. It's a simple counter plus the name of the widget.

synonym:NAME

Defines a renaming of the identifier NAME to the identifier in the property value. Be careful when using synonyms. They are the last construct you should consider to use in the client.


Widget states depending on data

Table 4.6. Properties

NameDescription
state:IDENFITIER

Defines a state of the widget dependent on a condition. IDENTIFIER is one of 'enabled', 'disabled', 'hidden', 'visible'. The state condition is defined the property value. The value can be a property reference in '{' '}' brackets. The condition is true when the property is defined. A condition can also be a boolean expression of the form <prop> <op> <value>, where <prop> is a property reference in '{' '}' brackets, <op> an operator and <value> a constant value Valid operators are: '==' (string),'!=' (string),'<=' (integer), '<' (integer) ,'>=' (integer), '>' (integer) For 'action' definitions the state 'state:enabled' is dependent on the properties referenced in the 'action' value.


Additional signals and slots

Table 4.7. Properties

NameDescription
datasignal:IDENTIFIER

Defines a signal of type IDENTIFIER (clicked, doubleclicked, destroyed, signaled, loaded, drag, drop) with the slot name and destination address defined as property value of "datasignal:IDENTIFIER" Datasignal destinations can be defined as follows: As widgetid, as slot identifier (declared with 'dataslot'), as widget path. A preceding identifier followed by '@' specifies what to do with the widget of the target slot. If you specify 'close' there in a form top level widget then the form is closed. Every other identifier causes a reload of the widget.

dataslot

Defines a comma separated list of slots for the signal of with the property value as slot identifer and optionally followed by a widget id in '(..)' brackets that sepcifies a sender from where the signal is accepted.


Drag and drop

Drag and Drop events are defined with the properties 'dropmove' and 'dropcopy' that define the action requests issued on a drop event. See description of the properties in "Defining Server Request/Answer". For using drag and drop the property 'acceptDrops' has to be enabled and the Widget has to be capable to do drag and drop. Drag and drop is currently only possible for the Qt standard list widgets, tree widgets and table widgets or for user defined widgets that delegate the mouse events accordingly. We do not describe here how user defined widgets can implement this mechanism of drag and drop.

What happens when an object is dragged from one object and dropped at another object is a request sent to the server. To address the elements involved in drag and drop some variables are set before issueing the request. These Variables can therefore be used in the request to specify the operation to implement the drag and drop. One of these variables is a widget link 'dragobj' that points the origin widget of the drag. With {dragobj.selected} we can address the item or set of items selected with the drag. The other variable is 'dropid' that selects the value or id of the target widget of the drop. What this value means is dependent on the widget class.

Besides the 'dropmove' and 'dropcopy' there are the datasignal properties 'datasignal:drag' and 'datasignal:drop' that can be used to specify the needed widget refresh signals that have to be performed after the drag and drop operation.

4.3.4. Widget properties as dynamic property values

Dynamic properties can reference properties of widgets like for example property = {variable expression}.

The expression can reference addressable widgets and their properties. Every Qt class has its very own set of properties it understands.