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.
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.
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}}}
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>
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.
The _w_
prefix is used for internal widget properties not of interest for the user.
The dynamic properties introduced here are edited by the user to stear application behaviour:
The following properties are reserved for states steering the behavior of the user interface:
Table 4.1. Properties
Name | Description |
---|---|
initialFocus | Boolean value for one widget in a form that should get the initial keyboard focus. |
The following properties stear the user interface elements flow:
Table 4.2. Properties
Name | Description |
---|---|
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. |
The following properties define additional interface elements:
Table 4.3. Properties
Name | Description |
---|---|
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. |
The following properties are used for the communication with the server:
Table 4.4. Properties
Name | Description |
---|---|
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' |
Table 4.5. Properties
Name | Description |
---|---|
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. |
Table 4.6. Properties
Name | Description |
---|---|
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. |
Table 4.7. Properties
Name | Description |
---|---|
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 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.
Copyright © 2014 - Project Wolframe - All Rights Reserved