<?xml version="1.0" standalone="no"?>

<!--
* 
*
*  ProLinga-Doc
*
*  Copyright (C) 2002-2009 Xobas Software.
*  All rights reserved.
*  
*  This file is part of ProLinga-Doc.
*
*  ProLinga-Doc is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  ProLinga-Doc is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with ProLinga-Doc.  If not, see <http://www.gnu.org/licenses/>.
*
*  More information is available at the following addresses:
*
*  Website     : http://www.prolinga.org
*
*  Email       : prolinga-list@prolinga.org
*
*
-->


<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
    "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [

<!ENTITY version SYSTEM "version_local.txt" >
<!ENTITY release-date "September 02, 2009" >
<!ENTITY copyright-year "2009" >
<!ENTITY fdl  SYSTEM "../fdl.xml" >
<!ENTITY PRODUCT "prolinga-tutorial" >
<!ENTITY xobas '<emphasis><ulink url="http://www.xobas.com">Xobas Software</ulink></emphasis>'>

]>

<book id="prolinga-tutorial" lang="en">
  <bookinfo>
    <title>ProLinga Tutorial</title>
    <releaseinfo>ProLinga System Builder Tutorial: &version; - &release-date;</releaseinfo>
    <authorgroup>
      <author>
	<firstname>Bas</firstname>
	<surname>Driessen</surname>
	<affiliation>
          <orgname>&xobas;</orgname>
	    <address><email>bas.driessen@xobas.com</email></address>
	</affiliation>
	<contrib>Original author and current maintainer.</contrib>
      </author>
    </authorgroup>

    <copyright>
      <year>2002-&copyright-year;</year>
      <holder>The ProLinga Team</holder>
    </copyright>

    <legalnotice>
      <para>Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.2
      or any later version published by the Free Software Foundation;
      with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
      A copy of the license is included in the section entitled
      <ulink type="http"
      url="gfdl.html">"GNU Free Documentation License"</ulink>.</para>
    </legalnotice>

    <abstract>
      <para>This document contains the ProLinga Tutorial.
      </para>
    </abstract>
  </bookinfo>

  <chapter id="prolinga-tutorial-intro">
    <title>ProLinga Tutorial</title>

    <para>Welcome to the ProLinga Tutorial. In this tutorial you are going to 
    build a single application that allows a user to store hardware (devices)
    into a database using the ProLinga Development Environment.
    As example we take a System Administrator of a University who needs a system
    to be able to register the various hardware used on campus.</para>

    <para>This application is meant as an introduction to the ProLinga environment and for
    the sake of clarity, the end result application is very simple and basic. For more
    examples and/or training material of the more advanced features of ProLinga, go to the 
<ulink type="http"
    url="http://www.prolinga.org">ProLinga Web Site</ulink>.</para>

    <para>You need to have ProLinga installed and
    running on your system. Please see the installation instructions for your platform
    at <ulink type="http"
    url="http://www.prolinga.org/installation.html">http://www.prolinga.org/installation.html</ulink> for details.</para>

  </chapter>

  <chapter id="prolinga-tutorial-database">
    <title>Prepare the database</title>

    <para>In this tutorial you will learn how to read data from and write data
    to a database from your application.
    Check that you are using a database that 
    is supported by the
    <ulink type="http"
    url="/prolinga-data/index.html">ProLinga-Data Project</ulink>. In this tutorial a database
    called <parameter>netadm</parameter> will be used as well as a user name 
    <parameter>prolinga</parameter> to 
    connect to the database. Use the appropriate "CREATE DATABASE" and "CREATE USER" statements
    in your database environment to create the database and user. The user should have 
    read and write access to the database.</para>

    <para>An example of how to prepare a PostgreSQL and MySQL database is given here.</para>

    <sect1 id="prolinga-tutorial-postgresql">
      <title>Preparation of PostgreSQL database</title>

      <para>A correctly configured PostgreSQL database should be running on your system. For
      PostgreSQL specific installation and configuration issues, visit the Web Site of
      <ulink type="http"
      url="http://www.postgresql.org">PostgreSQL</ulink> for any help, as this falls outside
      the scope of this document.</para>

      <para>To create the database in PostgreSQL, logon to a terminal/command line environment
      as the database administrator user (by default is this user postgres) and type:</para>

<programlisting>
$ createdb netadm
</programlisting>

      <para>This should produce as response:</para>

<programlisting>
CREATE DATABASE
</programlisting>

     <para>To create the database user <parameter>prolinga</parameter>, logon to the interactive terminal of PostgreSQL
     and type:</para>

<programlisting>
$ psql -h localhost -U postgres netadm
</programlisting>

      <para>The user can then be created as follows:</para>

<programlisting>
netadm=# CREATE USER prolinga; 
</programlisting>

     <para>Exit psql (\q) and test if you now can logon to the new database <parameter>netadm</parameter> 
     with the new
     user name <parameter>prolinga</parameter>.</para>

<programlisting>
$ psql -h localhost -U prolinga netadm
</programlisting>

      <para>If all went OK, you should see the psql prompt as follows:</para>
 
<programlisting>
netadm=>
</programlisting>

    </sect1>

    <sect1 id="prolinga-tutorial-mysql">
      <title>Preparation of MySQL database</title>

      <para>A correctly configured MySQL database should be running on your system. For
      MySQL specific installation and configuration issues, visit the Web Site of
      <ulink type="http"
      url="http://www.mysql.com">MySQL</ulink> for any help, as this falls outside
      the scope of this document.</para>

      <para>To create the database in MySQL, logon to mysql client
      as the database administrator user (by default is this user root) and type:</para>

<programlisting>
$ mysql -h localhost -u root -p mysql
</programlisting>

      <para>The database can then be created as follows:</para>

<programlisting>
mysql> CREATE DATABASE netadm;
</programlisting>

      <para>If this step went OK, you will see a result as follows:</para>
 
<programlisting>
Query OK, 1 row affected (0.06 sec)
</programlisting>
      <para>The user can then be created as follows:</para>

<programlisting>
mysql> GRANT ALL ON netadm.* TO 'prolinga'@'localhost';
</programlisting>

      <para>In this example setup the user is given all privileges for the <parameter>netadm</parameter>
      database. In production environments, stricter security measures should probably apply.</para>

    </sect1>

  </chapter>

  <chapter id="prolinga-tutorial-datasource">
    <title>Create the data source</title>

    <para>ProLinga uses <ulink type="http"
    url="http://www.gnome-db.org">gnome-db (libgda)</ulink> technologies to connect to data providers as PostgreSQL and MySQL. 
    To be able to connect to a database, a Data 
    Source needs to be created that holds details as database name, user name, tcp port etc. The easiest way 
    to create this is to run the gnome-db utility <parameter>gnome-database-properties</parameter> that comes as
    part of the libgnomedb package. Make sure you run this application as the user that will run the ProLinga
    environment, or for ProLinga Networked configurations, the user that started the 
    <parameter>prolingadatd</parameter> daemon. Go to the command line and type:</para>

<programlisting>
gnome-database-properties
</programlisting>

    <para>This brings up the gnomedb database properties tool. Click on the tab 'Providers' and check that your 
    data provider is in this list. In this tuturial examples for both PostgreSQL as MySQL will be given. If there 
    is no such entry, make sure that you have installed the libgda and gda-postgres packages as outlined in
    the <ulink type="http"
    url="http://www.prolinga.org/installation_linux.html">ProLinga Installation Instructions</ulink>.</para>

    <para>Click on the tab 'Data Sources' where you will see a list of configured data sources. If this is the first 
    time you run this tool, this list is probably empty or contains just a 1 'Default' entry.</para>

    <para>Go to pulldown menu 'File' and click 'New'. This will start a druid that guides you through a series of 
    screens to collect all the data needed. Click 'Forward'. On the screen 'General Information', enter the following 
    details to create a data source to run the ProLinga demo applications netadm:</para>

    <itemizedlist>
           <listitem>
             <para>Data source name : netadm</para>
           </listitem>
           <listitem>
             <para>Provider : PostgreSQL/MySQL</para>
           </listitem>
           <listitem>
             <para>Description : ProLinga Tutorial Application</para>
           </listitem>
           <listitem>
             <para>Username : (leave blank)</para>
           </listitem>
           <listitem>
             <para>Password : (leave blank)</para>
           </listitem>
   </itemizedlist>

   <para>Click 'Forward'. Fill out the fields on screen Provider Parameters as outlined below.
   Where no data is given, leave the field blank.</para>

   <para>The values for PostgreSQL</para>

    <itemizedlist>
           <listitem>
             <para>DATABASE: netadm</para>
           </listitem>
           <listitem>
             <para>SEARCHPATH: </para>
           </listitem>
           <listitem>
             <para>HOST: localhost</para>
           </listitem>
           <listitem>
             <para>HOSTADDR: 127.0.0.1</para>
           </listitem>
           <listitem>
             <para>OPTIONS: </para>
           </listitem>
           <listitem>
             <para>PASSWORD: </para>
           </listitem>
           <listitem>
             <para>PORT: 5432</para>
           </listitem>
           <listitem>
             <para>REQUIRESSL: </para>
           </listitem>
           <listitem>
             <para>TTY: </para>
           </listitem>
           <listitem>
             <para>USER: prolinga</para>
           </listitem>
   </itemizedlist>

   <para>The values for MySQL</para>

    <itemizedlist>
           <listitem>
             <para>Database Name: netadm</para>
           </listitem>
           <listitem>
             <para>Host Name: localhost</para>
           </listitem>
           <listitem>
             <para>Port: 3306</para>
           </listitem>
           <listitem>
             <para>UNIX Socket: </para>
           </listitem>
           <listitem>
             <para>Use Secure Connection: </para>
           </listitem>
   </itemizedlist>

   <para>Click 'Forward' and then 'Apply' to confirm all changes and to create the Data Source.</para>

  </chapter>

  <chapter id="prolinga-tutorial-define-application">
    <title>Define application in the Administrator</title>

    <para>To get to the ProLinga logon screen, type the following at the command line:</para>
<programlisting>
$ prolinga4gl
</programlisting>

    <para>The ProLinga logon screen as shown below appears.</para>

    <figure><title>Screenshot ProLinga Welcome Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/welcome.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the ProLinga Welcome Screen.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>You can logon to the ProLinga environment as 3 types of users:</para>

    <orderedlist>
        <listitem>administrator user - This user can perform tasks like defining users and 
        applications as well as changing system wide settings.</listitem>
        <listitem>developer user - This user can develop applications.</listitem>
        <listitem>end-user - This user can run applications as created by the developer</listitem>
    </orderedlist>

    <para>In this tutorial, you are going to create an application <parameter>netadm</parameter>. 
    Therefore you first have to logon as the administrator user and define this application. On the
    ProLinga Welcome Screen, type <parameter>administrator</parameter> in the field "User Name" and 
    press the OK button. The Administrator screen will be displayed. Click on the tab 
    <parameter>Application</parameter> and a list of available applications will be listed.</para>

    <figure><title>List of Applications</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/adm_appn_before.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the List of Applications in the ProLinga Administrator.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Press the <parameter>Add</parameter> button and details of the new application can be added.</para>

    <itemizedlist>
      <listitem>
        <para>Application Name: The name of the application. Only use alphabetic (A-Z,a-z) and numeric (0-9) characters and
        avoid spaces and special characters.</para>
      </listitem>
      <listitem>
        <para>Password: To protect your application from being accessed, a password can be set. Leave blank for no
        password.</para>
      </listitem>
      <listitem>
        <para>Application Type: Select if the application will be an administrator, developer or standard application. Use
        standard for end-user applications. If you do do not understand this setting, choose standard.</para>
      </listitem>
      <listitem>
        <para>Initial Logic Name: If an end-user starts your application, some point must be defined as starting point. This
        is called Initial Logic. This will be the first ProLinga code executed when starting your application.</para>
      </listitem>
      <listitem>
        <para>Description: There are two types of descriptions possible. A short one that will be used in lists and a long
        one that can be used to provide more details. Any text is allowed for either description fields.</para>
      </listitem>
   </itemizedlist>

   <para>For our tutorial application <parameter>netadm</parameter>, use the following values:</para>

    <figure><title>Add New Application</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/adm_appn_add.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to add a new Application.</phrase></textobject>
      </mediaobject>
    </figure>

   <para>Press the OK button and your new application now appears in the list with the others.</para>

    <figure><title>List of Applications including netadm</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/adm_appn_after.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the List of Applications in the ProLinga Administrator including netadm.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Have a further look in the Administrator. You will notice that there is a similar interface to add/modify/delete
    users. In this tutorial we will refer to the default developer user <parameter>developer</parameter> and end-user
    <parameter>guest</parameter>, so to continue this tutorial, there is no need to create any new users. 
    However in multi-developer environments, it is recommended to assign every developer
    his/her own logon name. The same applies if there is more than one guest user on the system.</para>

    <para>Logout (Pulldown menu File and then option logout) from the Administrator.</para>
    
  </chapter>

  <chapter id="prolinga-tutorial-open-application">
    <title>Open Application in ProLinga Developer</title>

    <para>Now that the application name has been defined, it is time to start developing the application. Logon as
    user <parameter>developer</parameter> this time. On the welcome screen type <parameter>developer</parameter> in the 
    field "User Name", leave all other fields blank and press the OK button. The ProLinga Developer application will appear
    on the screen.</para>

    <figure><title>ProLinga Developer Start Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_start.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the Start Screen of the ProLinga Developer.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Press the button "Open" on the toolbar and a popup screen appears where you can generate a list of
    available applications, by applying a filter. For this example we want to see a list of all the applications,
    so leave the "*" in place and press the "Index" button.</para>

    <figure><title>Object Open Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_object_open.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the Object Open Screen.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Select the application <parameter>netadm</parameter> and press OK. This will load the application
    <parameter>netadm</parameter> into the developer. The title of the main frame shows that we have loaded
    the correct application.</para>

    <figure><title>Main Frame</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_main_frame.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the Developer's Main Frame.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Further there is an object palette available that contains links to all the various object editors
    to develop the application.</para>

    <figure><title>Object Palette</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_object_palette.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the Developer's Object Palette.</phrase></textobject>
      </mediaobject>
    </figure>

  </chapter>

  <chapter id="prolinga-tutorial-create-initial-screen">
    <title>Create Initial Screen</title>

    <para>First we are going to create a screen that we want to display as soon as an end-user starts
    the application. At first time we will not put anything on the screen, so just a blank screen to begin 
    with.</para>

    <para>ProLinga uses the <ulink type="http"
    url="http://glade.gnome.org">"Glade"</ulink> XML interface for displaying screens. Screens are
    stored in an XML format and at run time, they are parsed by libglade and the user interface
    created. Templates are provided to create screens.</para>

    <para>Press on the button <parameter>Screen</parameter> on the object palette and the Screen editor
    will appear. There are 3 types of screens possible: </para>
  
    <orderedlist>
        <listitem>Single Instance Window: Typical data view/entry window. When trying to open more than once, the 
        screen on that is on the desktop will get the focus. Examples are most editor screens in the ProLinga 
        Developer.</listitem>
        <listitem>Multiple Instance Window: Typical data view/entry window. When trying to open more than once,
        a new instance of the screen will be opened. Example is the Logic Editor in the ProLinga Developer.</listitem>
        <listitem>Dialog: This is a screen that must be closed before any other screen can get
        focus. Example is an error screen that you must respond to in order to continue.</listitem>
    </orderedlist>

    <para>For the main screen we will use the Single Instance Window. Press the button "New Window" on the toolbar
    to load the appropriate template in the editor. Click on the tab "Control" and select "False" for the field
    "Allow Multiple Instances". Now save the screen by pressing the "Save" button on the toolbar and give it the name 
    "Main".</para>

    <figure><title>Initial Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_initial_screen.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the initial screen in the editor.</phrase></textobject>
      </mediaobject>
    </figure>

  <para>We just created the first (empty) screen and we now proceed by going to create logic to call this screen.</para>

  </chapter>

  <chapter id="prolinga-tutorial-write-initial-logic">
    <title>Write Initial Logic</title>

    <para>In the Administrator, we set the initial logic to be called Main. This will be the starting
    point of the application. Therefore we now have to create this logic "Main". Logic is a collection
    of ProLinga Statements that will be processed at run-time. Other programming environments call this
    functions or procedures for instance.</para>

    <para>We will keep our initial logic very simple to begin with. What we want to happen is what we
    call the screen with the name Main which we have created in the previous chapter.</para>

    <para>Press on the button <parameter>Logic</parameter> on the object palette and the Logic editor
    will appear. To call the screen Main, use the ProLinga command SCREEN:</para>

<programlisting>
SCREEN Main
</programlisting>

    <para>It is essential that ProLinga commands, like SCREEN, are written using uppercase characters. Save this
    logic by either going to pulldown menu <parameter>File</parameter> and option <parameter>Save</parameter>
    or by pressing the save button on the toolbar. Save it with the name "Main". After the logic has been saved, it looks like this:</para>



    <figure><title>Initial Logic</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_initial_logic.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of Initial Logic.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>When saving the Logic, ProLinga also checks the syntax and
    references used. If there are any problems found, an error window will come up reporting the problems found.
    Correct the problems if that happens and try saving it again.</para>

  <para>We are now ready to run the application for the first time.</para>

  </chapter>


  <chapter id="prolinga-tutorial-run-application">
    <title>Run Application</title>

    <para>To run the application, you have to return to the ProLinga welcome screen. You can either do this by going
    to the pulldown menu "File" which is located in the main frame of the Developer and then click "logout", or 
    you can run a second ProLinga session, by typing <parameter>prolinga4gl</parameter> from (an other) command prompt.</para>

    <para>To run our application, we need to logon as an end-user. A standard end-user <parameter>guest</parameter> is
    defined by default. Use this name as user name on the logon screen and our application <parameter>netadm</parameter>
    as application name.</para>

    <figure><title>Run Application Logon</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_appn.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the login to run an application.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>After pressing the OK button, our application starts and our (empty) initial screen will be displayed on the 
    desktop.</para>

    <figure><title>Run Application First Time</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_first.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of first time running of the application.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Congratulations! Although, not very useful yet, our application is up and running. Press on the "X" in the right
    top corner to exit the application. Start the ProLinga Developer again and proceed to the next chapter.</para>

  </chapter>
  
  <chapter id="prolinga-tutorial-paint-screen">
    <title>Paint Screen</title>

    <para>It is time to put some objecs on the screen.</para>

    <para>Since the Glade XML format is used to store and render screens, it makes sense to use the Glade User Interface
    Builder to design the screens. The ProLinga Developer calls Glade to make this painter available for the
    ProLinga environment.</para>

    <para>Open the screen "Main" in the screen editor and press the button "Painter</para>

    <figure><title>Start Screen Painter</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_painter.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of start screen painter.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The Interface Builder Glade now starts up. Besides the main application frame of Glade, two other windows
    (properties window and palette) are displayed as well. To bring up our screen "Main", go to the main frame of
    the painter and double click on the line "Main" as the following example shows.</para>

    <figure><title>Make Screen Visible In Painter</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_main.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to make the screen visible in the screen painter.</phrase></textobject>
      </mediaobject>
    </figure>

   <para>Since our initial screen is empty, it make come up initially very small in the painter. Look for the small
   screen.</para>

    <figure><title>Small Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_small.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the small screen in the painter.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>To resize the screen, simply click on the edge with the mouse and make it bigger.</para>

    <figure><title>Resized Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_big.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the big screen in the painter.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>To set the title of the window, edit the field "Title" in the properties editor. To get there,
    select the screen "Main" in the main frame (same line we double clicked on earlier) and details
    of the screen become availabe in the properties window. Change the text of "Title" to 
    "Network Administration Application".</para>

    <figure><title>Screen Title</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_title.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to set the screen title.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Click on the tab "Common" and set the width of the screen to 500 and the height to 400.
    This will set the minimum size of the screen. Users will still be able to increase the size
    or maximize the screen.</para>

    <figure><title>Screen Size</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_size.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to set the screen size.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Leave all other fields default in the properties window of screen "Main".</para>

    <para>We will keep the screen simple and want to see four horizontal sections on the
    screen:</para>

    <orderedlist>
        <listitem>Pulldown menu section</listitem>
        <listitem>Toolbar</listitem>
        <listitem>Main Area</listitem>
        <listitem>Message Bar</listitem>
    </orderedlist>

    <para>Glade provides numerous ways to build up your screen. Everything can be dynamic, fixed or a mix.
    We are using a method that when a user resizes the screen, the objects on the screen will be resized too.
    </para>

    <para>To get the four sections on the screen, start by placing a "vertical box" on the screen. The way to 
    place objects on the screen is to select them from the palette window and then click on the place where
    you want this to be on your screen. Bubble help will help you identify the various objects. Click on the 
    "vertical box" button and then click on your window. When asked for the number of rows, change the default
    (3) to 4 and press the OK button.</para>

    <figure><title>Vertical Box Object</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_vert_box.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of location of vertical box object.</phrase></textobject>
      </mediaobject>
    </figure>

   <para>Your screen now should look like this:</para>

    <figure><title>Screen With Vertical Box</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_screen_vbox.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of screen with vertical box object.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Now we can get the objects in place. The first section should be our pulldown menu. Click on
    "Menu Bar" on the palette and click on the first section on the screen. This will put a default
    pulldown menu in place. We will put in the correct menu details later.</para>

    <figure><title>Screen With Pulldown Menu</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_pmenu.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of screen with pulldown menu.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>In the second section, we want a toolbar that we want to be able to move freely. Therefore we
    first have to put the object "Handle Box" in place.</para>

    <figure><title>Screen With Handle Box</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_handlebox.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of screen with handle box.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The "Handle Box" looks very big, so we have to prevent this from expanding. Click on the "Handle Box"
    on your screen (and NOT in the palette) and the properties of the "Handle Box" appear in the property window. 
    Click on the tab "Packing" and change the setting "Expand" from "Yes" to "No".</para>

    <figure><title>Prevent Handle Box Of Expanding</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_handle_expand.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to prevent handle box to expand.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The "Handle Box" now looks as follows:</para>

    <figure><title>Screen With Correct Sized Handle Box</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_handlebox_ok.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of screen with correct sized handle box.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Now place the "Toolbar" in the empty space right next to the "Handle Box". When asked for the number
    of items, change the default (3) to 2.</para>

    <figure><title>Screen With Toolbar</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_toolbar.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of screen with toolbar.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>We put the object "Frame" in the 3rd section. It is important to give it a name, so we can
    use it in later exercises to present another screen in this frame. After placing the frame on the 
    screen, go to the properties screen of this frame and set Name to "frame_main".</para>

    <figure><title>Set Name of Frame</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_frame_name.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of setting the name of a frame.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Finally, place a "Status Bar" in the last section. The screen
    now looks as follows:</para>

    <figure><title>Screen With Main Sections</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_screen_4sect.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of screen with the 4 main sections.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Save the screen. Go to the main frame of Glade and press the "Save" button. You will see a message in the 
    status bar "Project saved". Now exit the painter by clicking "Quit". You will return to the Screen Editor
    in the ProLinga Environment. You will notice that the XML in the Screen Editor has been updated automatically. Press
    "Save" to save the screen. If you do not press Save here, your changes will be lost!</para>

    <figure><title>Updated Data In Screen Editor</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_updated.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of updated screen in the Screen Editor.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Now run your application. Logon as an end-user (<parameter>guest</parameter>) and application 
    <parameter>netadm</parameter>. If all went well, you will have the following screen.</para>

    <figure><title>Run-Time View Of The Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_second.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of a Run-Time view of the screen.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>We see the pulldown menu, the frame, the status bar and since there are no buttons yet on the toolbar, we
    can't really see the toolbar yet. We have not linked any logic yet to any pulldown menu option, so nothing will
    work yet. Press the "X" in the right top corner to exit the application and logon again to the ProLinga Developer
    and open application <parameter>netadm</parameter>. Proceed to the following chapter.</para>

  </chapter>

  <chapter id="prolinga-tutorial-pulldown">
    <title>Populate Pulldown Menus</title>

    <para>When creating the screen, we added pulldown menu structure in the first section. Now we are going to put
    the right names and actions in place. As soon as a user selects an option from one of the pulldown menus, some action
    needs to happen, like display another screen, or start a calculation etc. In ProLinga, this is controlled by "Action
    Handlers". Currently, there are three types of "Action Handlers":
    </para>
  
    <orderedlist>
        <listitem>Control (C-): Built-in functions as described in the reference manual can be called. Examples are
        actions to cancel a screen or to return to the ProLinga logon screen.</listitem>
        <listitem>Logic (L-): ProLinga logic can be called. Examples are logic to read data from the database or to display
        a value on the screen.</listitem>
        <listitem>Screen (S-): A screen can be displayed. Examples are a search screen or data entry screen.</listitem>
    </orderedlist>

    <para>In the tutorial application, we will create the pulldown menus <parameter>File</parameter>,
      <parameter>Maintenance</parameter> and <parameter>Help</parameter>. The pulldown menu entries and action handlers are
      outlined below. Most actions probably do not make much sense yet, but it will become clear once we create the logic and
      screens referenced here.</para>

      <table frame="all" tocentry="1" >
        <title>Pulldown Menu File</title>
        <tgroup cols="3">
          <thead>
            <row>
              <entry>Name</entry>
              <entry>Action Handler</entry>
              <entry>Description</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>Home</entry>
              <entry>L-Home</entry>
              <entry>This will call logic called "Home" to clean up the main screen.</entry>
            </row>
            <row>
              <entry>-------</entry>
              <entry>(leave blank)</entry>
              <entry>Separator line in the pulldown menu. Cosmetics only.</entry>
            </row>
            <row>
              <entry>Logout</entry>
              <entry>C-logout</entry>
              <entry>This will exit the application and return to the ProLinga logon screen.</entry>
            </row>
            <row>
              <entry>Exit</entry>
              <entry>C-exit</entry>
              <entry>This exit the application.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <table frame="all" tocentry="1" >
        <title>Pulldown Menu Maintenance</title>
        <tgroup cols="3">
          <thead>
            <row>
              <entry>Name</entry>
              <entry>Action Handler</entry>
              <entry>Description</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>Device</entry>
              <entry>L-Device</entry>
              <entry>This will call logic called "Device" to provide a inquiry/update mechanism of available 
              devices</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <table frame="all" tocentry="1" >
        <title>Pulldown Menu Help</title>
        <tgroup cols="3">
          <thead>
            <row>
              <entry>Name</entry>
              <entry>Action Handler</entry>
              <entry>Description</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>About</entry>
              <entry>S-About</entry>
              <entry>This will display a screen with some application information.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
 
      <para>Open the screen "Main" in the painter in the ProLinga Developer. If you click on the pulldown menu,
      you will see a button called "Edit Menus...".</para>

    <figure><title>Edit Pulldown Menus Entry</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_pmenu_edit.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of where to edit pulldown menu entries.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Press the button "Edit Menus...". All pulldown menus and entries will be displayed on a separate
    screen.</para>

    <figure><title>Edit Pulldown Menus Before</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_pmenu_before.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of where to edit pulldown menu before edit.</phrase></textobject>
      </mediaobject>
    </figure>

   <para>When clicking on a line, details will be displayed in the right portion of the window. You can set
   details here like "name" and "action handler" as well as link icons to the menu entry or an accelerator.
   With the navigation buttons at the bottom of the screen you can change the order and hiearchy. When using
   an underscore sign "_" in the label name, the following character will be set as mnemonic.</para>

   <para>Edit the
   various menus, until your screen looks as follows: </para>

    <figure><title>Edit Pulldown Menus After</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_pmenu_after.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of where to edit pulldown menu after edit.</phrase></textobject>
      </mediaobject>
    </figure>
 
    <para>Save your screen in the painter, exit the painter, save your screen in the ProLinga Screen Editor
    and run your application. At the run-time your application now looks as follows:</para>

    <figure><title>Pulldown Menu 1 At Run-Time</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/run_pulldown_1.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of pulldown menu 1.</phrase></textobject>
      </mediaobject>
    </figure>
 
    <figure><title>Pulldown Menu 2 At Run-Time</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/run_pulldown_2.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of pulldown menu 2.</phrase></textobject>
      </mediaobject>
    </figure>
 
    <figure><title>Pulldown Menu 3 At Run-Time</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/run_pulldown_3.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of pulldown menu 3.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>If you click on any of the menu items linked to logic, you will get an error telling you
    that the logic does not exist. That is correct, since we have not written them yet.</para>

    <figure><title>Run-Time Error - Logic Does Not Exist</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/run_logic_error.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of an error message when logic does not exist.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The same applies to the screen. The Control "action handlers" <parameter>logout</parameter> 
    (File/Logout) and
    <parameter>exit</parameter> (File/Quit) should work OK. </para>

    <para>In the next chapter we will create the toolbar.</para>

  </chapter>

  <chapter id="prolinga-tutorial-toolbar">
    <title>Create Toolbar</title>

    <para>A toolbar normally contains a selection of often used action that are also defined as an action
    in the pulldown menu. Toolbars are created in the painter and are push buttons with an action handler
    attached.</para>

    <para>Open the screen "Main" in the painter in the ProLinga Developer. We reserved 2 places on the toolbar.
    We first have to place buttons in those empty slots. Select "Button" from the palette and click on the
    empty space on the toolbar. It now should put a button in place. Repeat that for the second button.</para>

    <figure><title>Toolbar With 2 Buttons</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_toolbar_init.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the toolbar after placing 2 buttons.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The first button we want to name "Home". The painter comes with a range of icons that can be 
    used on buttons like this. They are called "Stock Buttons". If you click on button 1 on the toolbar
    you can select the "Stock Button" called "Home" in the Properties Window.</para>

    <figure><title>Select Stock Button</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_toolbar_stock.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to set a stock button.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The action handler that we want to link to this button is the same as the one we linked to 
    the pulldown menu "Home" which is "L-Home". This will call ProLinga logic with the name "Home" when
    the user clicks on it. To set the action handler, stay in the properties window and click the 
    tab <parameter>Signals</parameter>. In the field "Signal" we can define a signal that will trigger
    the call to our logic "Home". If you press the "..." button next to the field, you will get a list
    of possible actions. We want this to take place if the user clicks the button. Therefore
    we select the action "clicked". The handler is, like in the case of the pulldown menu, L-Home.
    After you have typed then in, you have to press the button "Add" to add this new entry to the list.
    </para>

    <figure><title>Link Signal To Toolbar Button</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_toolbar_signal.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to link a signal to the button.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>The second button will be called "Quit" and the action handler is "C-exit". There is a "Stock
    Button" for this as well. If all went well, your screen now looks as follows in the painter:</para>

    <figure><title>Finished Toolbar</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_toolbar_ready.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of a finished toolbar.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Save the screen in the painter, exit the painter and save the screen in the Screen Editor. 
    Run your application and test the toolbar.</para>

    <figure><title>Finished Toolbar At Run-Time</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_toolbar.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of application at run time with finished toolbar.</phrase></textobject>
      </mediaobject>
    </figure>

  </chapter>

  <chapter id="prolinga-tutorial-about">
    <title>About Screen</title>

    <para>In our pulldown menu entry Help/About we created an action handler S-About. This means that
    if a user selects this option, a screen with the name "About" will be displayed. To practise a bit
    more with screen painting, we will now create this screen.</para>

    <para>The "About" screen will be a of type "Dialog". This means that the screen must be closed before
    the user can continue with the application. Open the Screen Editor in the ProLinga Developer and press 
    the button "New Dialog" on the toolbar. A standard template will populate the Editor. Save the screen
    and name it "About".</para>

    <figure><title>Create About Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_screen_about.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the creation of the About screen.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Bring up the screen in the painter. By default, a Dialog is displayed with an "OK" and "Cancel"
    Button. In this case, we only want a button called "Close". To change this click on the button box 
    on the screen.</para>

    <figure><title>Select ButtonBox</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_about_buttonbox.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to select the buttonbox on the screen.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Go to the properties screen and change the size from 2 to 1.</para>

    <figure><title>Change Button Size</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_about_button_size.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to change the button size.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Change the "Cancel" button to a "Close" button. Click on the button, go to the properties screen
    and change the "Stock Button" to "Close". Add the signal "clicked" and action handler "C-cancel".</para>

    <figure><title>Change Rename Button</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_about_button_close.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the Close button.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Set the screen title similar like we did on the Main screen. Call it "About".</para>

    <para>Set the screen width to 300 and the height to 200</para>

    <para>In the big empty space on the screen, place a "Vertical Box", like we did at the previous screen. Set
    the number of rows to 2 and fill row 1 and 2 with a "Label". In the properties screen of the "Label", you 
    can type any text in the field "Label" under the tab called "Widget". You can also use Pango markup like
    &lt;big&gt;label&lt;/big&gt;. Other examples are  &lt;small&gt;, &lt;b&gt; for instance. You have to change
    the setting "Use Markup" to "Yes".</para>

    <figure><title>Mark Up Label Text</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_about_markup.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to mark up label text.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Under the tab "Packing", on the properties screen of a label, you can switch
    the setting "Expand" to "Yes" to get a nice layout.</para>

    <figure><title>Expand Label</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_about_expand.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to expand a label.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Run your application, go to the pulldown menu "Help" and select "About.</para>

    <figure><title>About Screen At Run-Time</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_about.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the About screen.</phrase></textobject>
      </mediaobject>
    </figure>

  </chapter>

  <chapter id="prolinga-tutorial-object-datasource">
    <title>Data Source Object</title>

    <para>In the next couple of chapters, you will learn how to create a data entry screen and how
    to get the data from and to your database. In a previous chapter <ulink type="http"
    url="prolinga-tutorial-datasource.html">"Create the data source"</ulink> we created a data source
    (or channel if you like) to our database, which we called "netadm". In this external data source,
    we enter details as the name of our database that we want to use and the details to logon to
    that database. Now we have to link into this channel from within our application.</para> 

    <para>Bring up the "netadm" application in the ProLinga Developer and select "Data Source" on the
    object palette.</para>

    <figure><title>Data Source On Object Palette</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_object_data_source.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the data source button on the object palette.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>In the Data Source editor, press the button <parameter>New</parameter> and enter "netadm" in the field
    "External Name". This is the name of the external data source. Leave all other fields as they are. The field
    "User Name" here refers to the user name to be able to access the data source itself and not the user name
    needed to access the database. That last user name has already been defined in the external data source.</para>

    <para>Save the data source and name it "netadm".</para>

    <figure><title>Data Source In Developer</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_data_source.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the data source netadm in the ProLinga Developer.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Tables that you will create in further chapters and that use the data source "netadm", will now use your
    preferred database as data provider.</para>
  </chapter>

  <chapter id="prolinga-tutorial-logon-datasource">
    <title>Logon to Data Source</title>

    <para>Before we can access the data in our database through the data source, we first have to execute the ProLinga
    command "SQL CONNECT" to open a connection to the data source for this session. Since we will be accessing our
    data throughout the application, it is best to place this command at the very beginning of our application. 
    Remember that the starting point of our application was logic called "Main". Bring up this logic in the
    logic editor and add the following line to it:</para>

<programlisting>
SQL CONNECT netadm
</programlisting>

   <para>The name "netadm" is the name of the data source object that we created in the previous chapter. Your logic
   "Main" now should look as follows:</para>

    <figure><title>Logic With SQL CONNECT</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_logic_connect.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the logic Main with SQL CONNECT.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Similar it is good practise to close a data source upon exiting from or logging out of the application. 
    Therefore it is a good idea to
    write a logic block that is called every time the user exits or logs out from the application. 
    Write a logic block named "Quit" as
    follows:</para>

    <figure><title>Logic "Quit" With SQL DISCONNECT</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_logic_quit_disconnect.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the logic Quit with SQL DISCONNECT.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Write the same logic and save it with the name "Logout".</para>

    <figure><title>Logic "Logout" With SQL DISCONNECT</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_logic_logout_disconnect.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the logic Logout with SQL DISCONNECT.</phrase></textobject>
      </mediaobject>
    </figure>

   <para>Make sure you do not overwrite the logic called "Main" and that you press the button <parameter>New</parameter>
   in the logic editor first before writing this new logic.</para>

   <para>Now we have to make sure that this logic gets called when the user exits/logs out from the application. 
   The only way the user
   can exit the application is through the pulldown menu option "Quit" and "Logout" or through the toolbar button 
   "Quit". Currently,
   we have linked that to C-exit and C-logout, but if we change that to L-Quit and L-Logout, our new logic 
   block "Quit" or "Logout" will be 
   called upon exit/logout.
   To change this, open the screen "Main" in the Screen Editor and start the painter. To update the link from the button
   "Quit", single click on the button, go to the properties screen and press the tab "Signals". Update the handler field
   to L-Quit.</para>
 
    <figure><title>Update Toolbar Button Signal Handler</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_update_quit.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to update the toolbar button signal handler.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Update similar way the pulldown menu entry "Quit" and "Logout".</para>

    <figure><title>Update Pulldown Menu Item Signal Handler</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_update_pm.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to update the pulldown menu item signal handler.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Save the screen and test your application.</para>

  </chapter>

  <chapter id="prolinga-tutorial-table">
    <title>Create a Table</title>

    <para>Now that we have the connection from our application to the database in place, it is time that we 
    build a table. The name of the table that we want is "Device" and the fields that we want in that table
    are as follows:</para>

      <table frame="all" tocentry="1" >
        <title>Table "Device"</title>
        <tgroup cols="3">
          <thead>
            <row>
              <entry>Field Name</entry>
              <entry>Data Type</entry>
              <entry>Length</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>deviceNumber</entry>
              <entry>Unsigned Decimal</entry>
              <entry>5</entry>
            </row>
            <row>
              <entry>description</entry>
              <entry>String</entry>
              <entry>35</entry>
            </row>
            <row>
              <entry>typeId</entry>
              <entry>String</entry>
              <entry>3</entry>
            </row>
            <row>
              <entry>dateInstall</entry>
              <entry>Date (format CCYY-MM-DD)</entry>
              <entry>10</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <para>The primary key will be deviceNumber</para>

      <para>There are 4 easy steps involved in creating a table in ProLinga:</para>

      <orderedlist>
        <listitem>Check if data dictionaries are available and if not create them.</listitem>
        <listitem>Group data dictionaries together in a <parameter>Record</parameter>.</listitem>
        <listitem>Group data dictionaries together in an <parameter>Index</parameter>.</listitem>
        <listitem>Create a <parameter>Table</parameter> definition and assign the Record(s) and
        Index(es) to it.</listitem>
      </orderedlist>

      <para>From this point on we should not be using the terminology "Field Name" any more when refering
      to table definitions in ProLinga. Instead, ProLinga uses the concept of Data Dictionaries. A 
      Data Dictionary is a very powerful reusable object. Think of 2 tables for instance that both have
      a field called "description". In traditional database environments, you have to create this field 2 times.
      Besides more work, also there is a chance that 1 field has a length of 15 and the other of 35 and 
      that data can get lost when assigning one to another. In the case of ProLinga, we will use the same
      Data Dictionary for both tables, eliminating the possibility of incompatibility.</para>

      <para>To create the Data Dictionaries, open your application in the ProLinga Developer and select "Data
      Dictionary" from the Object Palette.</para>

     <figure><title>Data Dictionary On Object Palette</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_object_data_dictionary.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data dictionary button on the object palette.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Press the button "New" on toolbar of the Data Dictionary editor to make sure you start with a
     new object. We first will create the Data Dictionary "deviceNumber".
     Set the "Maximum Length" to 5, "Data Type" to UnsignedDecimal, "External Storage Type"
     to Integer and "Justification" to Right. Leave all other fields default as they are. Save the Data Dictionary
     and name it "deviceNumber".</para>

     <figure><title>Data Dictionary deviceNumber</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_dd_deviceNumber.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data dictionary "deviceNumber".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Some details of key fields. The "Data Type" is the type of the data within ProLinga, while
     "External Storage Type" is the type of the data in the database. Most of the time they will be 
     of a similar type, meaning that a String translates to the type Character and Unsigned Decimal
     to Integer, but there maybe situations that this is not the case.</para>

     <para>The same way, create the Data Dictionaries "description", "typeId" and "dateInstall".</para>

     <figure><title>Data Dictionary description</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_dd_description.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data dictionary "description".</phrase></textobject>
       </mediaobject>
     </figure>

     <figure><title>Data Dictionary typeId</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_dd_typeId.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data dictionary "typeId".</phrase></textobject>
       </mediaobject>
     </figure>

     <figure><title>Data Dictionary dateInstall</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_dd_dateInstall.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data dictionary "dateInstall".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Once we created all the Data Dictionaries that we need for our table "Device", we can group
     them together in a Record. Open the Record editor from the Object Palette.</para>

     <figure><title>Record On Object Palette</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_object_record.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the record button on the object palette.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Type in the name "deviceNumber" in the screen field "Data Dictionary Name" and press the "Add"
     button. You will see that the name now shows up in the list. Add the same the Data Dictionaries
     "description", "typeId" and "dateInstall". Instead of typing them in, you can also select them from
     the list when pressing the button "Find". The order from top to bottom will be the order of the 
     fields in the database from left to right. It is important to get this right. When finished, save
     the Record with the name "Device".</para>

     <figure><title>Record Device</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_record_device.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the record "Device".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>On a similar way, we can create an index. Open the Index editor from the Object Palette.</para>

     <figure><title>Index On Object Palette</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_object_index.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the index button on the object palette.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Click on the tab "Entries" and add the Data Dictionary Name "deviceNumber". Save the index
     with the name "deviceNumber."</para>

     <figure><title>Index deviceNumber</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_index_deviceNumber.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the index "deviceNumber".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Finally, we create the Table itself. Open the Table editor from the Object Palette.</para>

     <figure><title>Table On Object Palette</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_object_table.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the table button on the object palette.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Add the Record to the Table definition by typing the name of the Record "Device" in the field
     "Record Name" under the "Record" tab and press the "Add" button.</para>

     <figure><title>Add Record to Table</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_table_record.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of adding Record to Table definition.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Press on the tab "Index" and add the Index called "deviceNumber".</para>

     <figure><title>Add Index to Table</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_table_index.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of adding Index to Table definition.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Click on the tab "Provider". The "External Name" will be used for the physical file name in the
     database. So enter "Device" here. As "Data Interface Type" choose GDA and the Data Source is the one
     we created earlier with the name "netadm".</para>

     <figure><title>Add Provider details to Table</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_table_provider.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of adding Provider details to Table definition.</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Now save the table and give it the name "Device". Now click on the tab "Data Manager" and click
     the button "Build Database Table". If you receive no error messages, all went OK and your table is
     now created in the database. To double check this, open an interactive terminal for your database
     and check if the new table is present.</para>

     <figure><title>Check Table in Database</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/psql_device.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of Table definition in the database.</phrase></textobject>
       </mediaobject>
     </figure> 

     <para>As you can see, all the fields are available as well as the index. At this stage, we can
     not test this yet in our application, as we do not have any data entry screen. Please proceed
     to the next chapter to build one.</para>

  </chapter>

  <chapter id="prolinga-tutorial-data-entry-screen">
    <title>Paint Data Entry Screen</title>

    <para>Since we have made a screen before, not all steps are described in great detail.
    If you have problems understanding it, you may want to go back and re-visit earlier chapters.</para>

    <para>To build a Data Entry Screen, open the application in the ProLinga Developer and go to the 
    Screen Dialog Editor. 
    Click the toolbar button "New Window" and then save this screen with
    the name "Device". Now bring it up in the painter.</para>

    <para>Set the window title to "Device", set the width to 550 and the height to 350.</para>

    <para>Remember the 
    screen "Main" where we placed a "Frame" object
    in the third section. In later exercises, we will learn how we can integrate the screen "Device"
    with the screen "Main". To make this possible, we first have to place an object "Scrolled Window"
    on our screen "Device".</para>

    <figure><title>Scrolled Window Object</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_scrolled_window.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of scrolled window object.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Go to the properties screen of the scrolled window object and give it the name "device_include".</para>

    <figure><title>Name Scrolled Window</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_sw_name.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of name scrolled window.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Within the scrolled window, place a "Vertical Box" with 2 rows. In the first row place a painter
    object "Table" with 4 rows and 3 columns. In the second row place a "Horizontal Box" with 2 columns.</para>

    <figure><title>Base Screen Device</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_base.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of base screen Device.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Once we are placing objects within objects, it is easy to get lost. Therefore you can open a widget tree
    window. In the painter go to pulldown menu "View" and then click option "Show Widget Tree". Here you can simply
    select any object that you have placed on the screen.</para>

    <figure><title>Widget Tree Window</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_widget_window.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of painter widget window.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>We have 4 data dictionaries in our table definition "Device". We can now place an object "Label" on
    the screen for all 4 of them.</para>

    <figure><title>Labels on Device Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_labels.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of labels on device screen.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Do not worry about the layout. Once all objects are on the screen, we
    will get all objects to display right.</para>

    <para>In the next column we put the object "Spin Button" for the Device Number field, since that is a numeric
    one, "Text Entry" for the Description field, "Combox Box" (not be confused with Combo Box Entry) for the
    Type Id field and "Text Entry" again for the Installation Date field.</para>

    <figure><title>Entry Fields on Device Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_entries.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of entries on device screen.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>It is important to give all the editable objects a name, so we can refer to it from ProLinga logic.
    Use the names "entryDeviceNumber", "entryDescription", "entryTypeId" and "entryDateInstall". These
    values can be set in the properties screen of the objects as the example below of the Description
    Field shows.</para>

    <figure><title>Set Name Entry Field</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_entry_name.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of how to set the name of an entry field.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>In later chapters we want to create a lookup screen for the Device Number field. 
    That means we have to
    trigger an action. For now we will just place a Button on the screen called "Find".</para>

    <figure><title>Find Button on Device Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_find.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of find button on device screen.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>In the bottom 2 sections we are going to put a "Horizontal Button Box" in both of them.</para>

    <figure><title>Horizontal Button Box</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_hbutton_box.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of horizontal buttonbox object.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>When asked for the number of buttons in the box, type 1 for the left one and 3 for the right one.
    Then go to the properties screen of the left button box and set the value "Layout" in the "Widget" tab
    to "Start" and set the value to "End" in the right button box.</para>

    <figure><title>Layout Horizontal Button Boxes</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_hbutton_box_layout.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of layout setting for horizontal buttonbox objects.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Now set the left button to be a "Delete" button, and the other 3 to be "Cancel", "Apply" and "OK".
    Your screen "Device" now should look similar to this.</para>

    <figure><title>Button Boxes on Device Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_buttons.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of horizontal buttonboxes on device screen.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>All objects that we want to have are on the screen, so now we can format the screen to look a bit
    better. The buttons should always be at the bottom of the page. So we have to prevent them from expanding.
    The 2 horizontal button boxes are child objects of the horizontal box object, so we need to go to the
    properies screen of the horizontal box object. This is where you want to use the Widget Tree screen.</para>

    <figure><title>Horizontal Box in Widget Window</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_widget_hbox.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of horizontal box in widget window.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Select the horizontal box object in the Widget Window and go to the properties screen. There under the
    tab "Packing" you will find a setting called "Expand". Set this to "No". You will see the direct effect
    in the "Device" screen in the painter.</para>

    <para>The rows and columns are a bit close to eachother in the screen and we should add some spacing. The
    labels and entry fields are child objects of the table object. Select this object in the Widget Window,
    go to the properties screen and select tab "Widget" (Default). Set both Row as Col Spacing to 5. Set the field Border Width of the vertical box (vbox1) to 10. Your
    screen now should look similar like this in the painter.</para>

    <figure><title>All Objects on Device Screen</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_device_all_objects.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of all objects on device screen.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>The unused spaces around the "Find" buttons, will look OK at run-time.</para>

    <para>Before we can test this screen at run-time, we must remember how we are calling this
    screen. From the pulldown menu and toolbar, we created an action handler L-Device, meaning
    call logic "Device". We have not written that logic yet, so it is time to do it now. For the
    time being, all we want this logic to do is to call screen "Device". Therefore, open the Logic
    Editor in the Developer and write the following logic:</para>

<programlisting>
SCREEN Device
</programlisting>

    <para>Save this logic and name it "Device".</para>

    <figure><title>Logic Device</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_logic_device.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of device logic.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Start your application and see if the "Device" screen comes up. We have not written any logic
    yet to read/write data from/to your database, so that part will not work yet.</para>

    <para>You will notice that if you run your application your Device screen comes up as a separate 
    window as soon as you select the pulldown menu option "Device".</para>

    <figure><title>Device Screen Standalone</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_device_single.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot run-time Single Device Screen.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>In a previous exercise we created a frame called "frame_main" on the screen called "Main". What
    we want now is to project this new Device Screen into this frame, so it becomes one single screen. To
    cater for that we have to go into the ProLinga Developer and open logic "Device" in the Logic Editor. Now
    we change the logic from:</para>

<programlisting>
SCREEN Device
</programlisting>

     <para>to:</para>

<programlisting>
SCREEN Device CONTAINER frame_main SOURCE device_include 
</programlisting>

    <para>This tells the run-time engine to get from the screen "Device", only the object "device_include"
    and child objects. This "device_include" is the scrolled window object that we placed on the screen
    "Device". This "device_include" then should be projected in the frame (or often called containter) 
    "frame_main" on the current screen. Save this logic and if you now run your application, you should
    have a similar screen as below, once you click on the "Device" pulldown menu option.</para>

    <figure><title>Device Screen In Containter</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_run_device_container.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot run-time Device Screen in Containter.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>As you will see the screens are nicely merged into a single screen. If it is not working, please
    review previous exercises where we placed the frame "frame_main" on the screen "Main" and where we
    created the scrolled window object "device_include" on the screen "Device".</para>

    <para>As all following exercises continues to work with this merged view, do not continue until
    you have it working.</para>

  </chapter>

  <chapter id="prolinga-tutorial-create-picklist">
    <title>Create Picklist</title>

    <para>One of the screen fields used is called "Type Id". We defined it as a string with maximum
    of 3 characters. We only want to have 3 values available where the user can choose from: </para>

    <orderedlist>
      <listitem>COM - Computers</listitem>
      <listitem>MON - Monitors</listitem>
      <listitem>PRT - Printers</listitem>
    </orderedlist>

    <para>At run-time, we want to present these values to the user. That is why we chose the screen object
    "ComboBox" in the previous exercises. This ComboBox object can be used to present values that are in the
    ProLinga Pick List Object. We will now create a Pick List.</para>

    <figure><title>Pick List On Object Palette</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_object_pick_list.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the pick list button on the object palette.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Press the button "New" on the tool bar of the Pick List Editor to create a new Pick List. Now type 
    the value "COM" in the "Value" field and press the "Add" button. You will see that the value now appears
    in the list. Do the same for "MON" and "PTR". Save the Pick List with the name "DeviceType".</para>

    <figure><title>Pick List DeviceType</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_pick_list_device_type.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the pick list "DeviceType".</phrase></textobject>
      </mediaobject>
    </figure>

    <para>There is no point in testing your application at this stage, since this Pick List has no effect
    until we reference, so proceed direct to the next exercise.</para>

  </chapter>

  <chapter id="prolinga-tutorial-populate-data-entry-screen">
    <title>Populate Data Entry Screen</title>

    <para>In the previous chapter we painted a data entry screen. We now have to put the functionality in
    place. First a bit of explanation how we can get data in to and out of the screen.</para>

    <para>In ProLinga we created a table called "Device". For every table you create in ProLinga, there
    will be a table buffer available. A table buffer can hold a value for every data dictionary of 
    every record of a table. An object, like this table buffer, is called a <parameter>Data Reference
    </parameter>. Other examples of Data References are Variables and Constants for instance. Data
    Reference can be referenced from ProLinga logic and screens with a prefix.</para>

    <para>The prefix of a single
    table buffer entry is F-, referring to a single Field of the table buffer. (It will be clear
    later on why F is used and not T for instance). The syntax of a table buffer field reference
    is: <parameter>F-data_dictionary_name.table_name.record_name</parameter> 
    So to reference the field deviceNumber in the table Device, we use the reference:
    F-deviceNumber.Device.Device The last section, the record section, can be omitted and in that
    case the default record of the table will be used. Since we only have one record called Device
    which then automatically is our default record, we can shorten this to F-deviceNumber.Device </para>

    <para>In ProLinga logic we can assign a value to or from the a table buffer entry  using the 
    logic command LET. So
    LET F-deviceNumber.Device = 123 as an 'assign to' example and LET V-deviceNumber = F-deviceNumber.Device
    as an 'assign from' example. See the reference manual for more details on this.</para>

    <para>We can also link data references to screen fields. There are situations that you want to move 
    data from the screen field to the data reference, from the data reference to the screen field or 
    both. To cater for this we have to indicate which of the two data moves we want to do.</para>
    
    <orderedlist>
        <listitem>GET - This indicates that we want to move data FROM the data reference TO the
        screen field.</listitem>
        <listitem>PUT - This indicates that we want to move data TO the data reference FROM the
        screen field.</listitem>
    </orderedlist>
 
    <para>To further not confuse a data reference prefix with an action prefix, "D:" is appended
    in front. If we return to the example of F-deviceNumber.Device, the data reference calls are
    as follows:</para>

    <itemizedlist>
      <listitem>
        <para>D:GET:F-deviceNumber.Device</para>
      </listitem>
      <listitem>
        <para>D:PUT:F-deviceNumber.Device</para>
      </listitem>
    </itemizedlist>

    <para>Like any action handler, we have to link a signal to a data reference call, so the system
    knows when to make the data move. In our situation
    we want data to move FROM the data reference to the field, when the focus enters a field and we 
    want to move data (that we just typed for instance) TO the data reference when the focus leaves
    the field. There are many signals available in GTK+, but most of the time the signals
    <parameter>focus_in_event</parameter> and <parameter>focus_out_event</parameter> does the job.
    </para>

    <para>Knowing this, we can now return to our application. Open it in the ProLinga developer and
    bring up the screen "Device" in the painter. Click on the entry field (spin button) for deviceNumber
    and go to the properties screen. Under the tab "Signals" add the signals "focus_in_event" and 
    "focus_out_event" for the GET and PUT of F-deviceNumber.Device.</para>

    <figure><title>Setting Data Reference For Device Number</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_first_data_reference.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of setting signal for data reference device number.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>The same way set the following data references as well:</para>
    
    <itemizedlist>
      <listitem>
        <para>F-description.Device</para>
      </listitem>
      <listitem>
        <para>F-dateInstall.Device</para>
      </listitem>
    </itemizedlist>

    <para>The field "Type Id" needs some further explanation being a "ComboBox". As soon as this object
    is created we want the values of the Pick List "DeviceType" that we made earlier to be available
    in this object. For "ComboBox" and "ComboBoxEntry" objects, we have the Data Reference prefix P:
    available. So link P:DeviceType to signal "focus_in_event" which is emitted at screen creation time. The 
    Data Reference GET is the same as other fields and the Data Reference PUT is not linked to the
    focus_out_event, but to the "changed" signal, so every time a user selects a value, the underlying
    data reference is updated.</para>

    <figure><title>Setting Data Reference For Combo Box Type Id</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_combo_box_reference.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of setting signals for data reference type id.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>As a general rule, do not forget to save your screen in between making major changes, to prevent
    having it to do all over again, in case of any type of user/system error.</para> 

    <para>Now that we have the actual fields in place, we can finish the remainder of the action handlers.
    As soon as the user enters a device number and the focus leaves that field, we want to see all the details
    of that device number if it exists, or a message that a new device number can be added if the number
    does not exist. This means we have to link a logic to a signal from the deviceNumber field. The signal
    is again "focus_event_after" and the logic we want to call (and which we will create later) is
    "L-DeviceRead".</para>

    <figure><title>Data Reference And Action</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_glade_mix_data_reference_action.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of data reference and action.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>As you can see we can use the same signal multiple times and mix it with the use of actions and
    data references.</para>

    <para>Now we link actions to the remaining objects on the screen:</para>

    <table frame="all" tocentry="1" >
      <title>Action Handlers Remaining Screen Objects</title>
      <tgroup cols="3">
        <thead>
          <row>
            <entry>Object</entry>
            <entry>Signal</entry>
            <entry>Action Handler</entry>
          </row>
        </thead>
        <tbody>
          <row>
            <entry>Find button.</entry>
            <entry>clicked</entry>
            <entry>L-SearchDeviceNumber</entry>
          </row>
          <row>
            <entry>Delete button (left below).</entry>
            <entry>clicked</entry>
            <entry>L-DeviceDelete</entry>
          </row>
          <row>
            <entry>Cancel button.</entry>
            <entry>clicked</entry>
            <entry>L-Home</entry>
          </row>
          <row>
            <entry>Apply button.</entry>
            <entry>clicked</entry>
            <entry>L-DeviceApply</entry>
          </row>
          <row>
            <entry>OK button.</entry>
            <entry>clicked</entry>
            <entry>L-DeviceOK</entry>
          </row>
        </tbody>
      </tgroup>
     </table>

     <para>As you maybe noticed, we want to call logic L-Home rather than the expected L-Cancel for the 
     Cancel button. Remember that the
     Device screen is now integrated into the main screen. When cancelling the screen we really want to just
     clear the frame/container that holds the Device (sub) screen. To avoid confusion, we call this "Home".</para>

     <para>Now save the screen and run your application. Make sure all buttons on the Device screen now generate
     an error like "Logic [<parameter>xyz</parameter>] does not exist" when you press them.
     Notice also that this error is triggered when
     you place the cursor on the Device Number field and then leaving it by placing it somewhere else.</para> 
  
     <para>We are now finished painting the Device screen and now we have to go into ProLinga logic to get it all to work.
     </para> 

  </chapter>

  <chapter id="prolinga-tutorial-logic-data-screen">
    <title>Write Logic Data Screen</title>

    <para>In the previous chapter we made many calls to ProLinga logics. Now we will write all those logics
     as well as adding some lines to existing ones.</para>

    <sect1 id="prolinga-tutorial-logic-device">
      <title>Logic: Device</title>

      <para>In a previous exercise we already created the logic called "Device" to display the screen "Device"
      in the "frame_main" frame. We will now add some lines to it. An explanation of the added lines are 
      given as well.</para>

      <para>Change the logic "Device" to this:</para>

<programlisting>
CLEAR TABLE Device
LET F-dateInstall.Device = DATE()
SCREEN Device CONTAINER frame_main SOURCE device_include 
DISPLAY ALL
MESSAGE "Device can be updated."
FOCUS entryDeviceNumber
</programlisting>

      <para>On the screen "Device" we linked data references like <parameter>F-deviceNumber.Device</parameter>. 
      To assure that the table buffer is empty when the screen is display and does not contain some random/old
      values, we first clear the table buffer "Device" with the <parameter>CLEAR</parameter> command.</para>

      <para>We set the date field <parameter>F-dateInstall.Device</parameter> standard to today's date.</para>

      <para>The third line remains unchanged and projects the screen Device in the frame.</para>

      <para>The DISPLAY refreshes the contents of a screen field, by moving the contents of the data reference
      that is linked to it with the signal "focus_in_event" to it. By saying <parameter>DISPLAY ALL</parameter>
      we do that for all the screens. Since the data reference are table buffer entries like 
      <parameter>F-deviceNumber.Device</parameter>, which we just cleared with the CLEAR command, all entries 
      will be set to blank (or 0). So we get a nice clean data entry screen.</para>

      <para>The <parameter>MESSAGE</parameter> command places all its (data references) arguments on the status/message
      line at the botton of the current active screen.</para>

      <para>The <parameter>FOCUS</parameter> command sets the cursor to the Device Number entry field.</para>

      <para>After you applied the changes to logic "Device", save it and run the application. See if the message
      becomes visible on the status/message line and if all fields are initialized.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-home">
      <title>Logic: Home</title>

      <para>Our Screen "Device" is now displaying in the frame called "frame_main". Once the user is finished
      with the data entry screen and wants to close it, this now means that we have to clear the frame
      "frame_main". We use the ProLinga command <parameter>CLEAR</parameter> for this. 
      Write the logic "Home" as follows:</para>

<programlisting>
COMMENT --- Clear frame  ---
CLEAR CONTAINER frame_main

COMMENT --- Clear status line ---
MESSAGE ""
</programlisting>

      <para>The <parameter>CLEAR</parameter> command removes all child objects from the frame/container "frame_main".
      Further we see the logic command <parameter>COMMENT</parameter>. This command is just for documentation 
      purposes. Everything behind that command will be ignored by the ProLinga run-time engine. You may leave out
      the comment statements if you wish.</para>

      <para>The command <parameter>MESSAGE</parameter> prints text on the message/status line. Since we are giving
      it an empty string as argument, any messages on the message/status line will be deleted.</para>

      <para>Save the logic and run your application now. Click on pulldown menu "Device" and then press either the 
      button "Home" or "Cancel". Also the pulldown menu entry "Home" should be tested. You should see that the 
      frame is emptied when logic "Home" is processed."</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device-search-device-number">
      <title>Logic: SearchDeviceNumber</title>

      <para>If the user has to type in a Device Number, but does not know the number, a search
      screen can be presented where a Device Number can be looked up using search criteria. We
      will implement this feature at a later stage, so for the time being, we just want to trigger
      the message "Feature has not been implemented yet". For that we can use the <parameter>ERROR</parameter>
      command.</para>

<programlisting>
ERROR "Feature has not been implemented yet." SEVERITY Info
</programlisting>

      <para>This will trigger the information as follows:</para>

      <figure><title>Information Message</title>
        <mediaobject>
          <imageobject><imagedata fileref="images/dev_run_error_info.png" format="PNG"/></imageobject>
          <textobject><phrase>Screenshot of an information message.</phrase></textobject>
        </mediaobject>
      </figure> 

      <para>Please see the reference manual for all the various available ERROR severity options.</para>

      <para>Run your application and test if the information message comes up.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device-read">
      <title>Logic: DeviceRead</title>

      <para>This will be the logic where will test if a value exist in the database. If it exist then
      show all the details on the screen, so they can be modified and if it does not exist, provide
      a blank data entry screen for a new Device.</para>

      <para>The mechanism here is the we execute an SQL statement that returns with a DataModel (sometimes
      also referred to as 'Cursor' or 'ResultSet' in other environments). This DataModel is populated 
      automatically, so we do not have to design them first setting column names etc. The only thing
      that is required that the DataModel as an object is available in ProLinga.</para>

      <para>To create a DataModel, logon to the ProLinga Developer and select "DataModel" from the 
      Object Palette.</para>

      <figure><title>Data Model On Object Palette</title>
        <mediaobject>
          <imageobject><imagedata fileref="images/dev_object_data_model.png" format="PNG"/></imageobject>
          <textobject><phrase>Screenshot of the data model button on the object palette.</phrase></textobject>
        </mediaobject>
      </figure>

      <para>Create a new DataModel and save it as "Device". Leave the setting "AutoClear" as it is.</para>

     <figure><title>DataModel Device</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_data_model_device.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data model "Device".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Further we need a setting so we can keep track if a Device record was present or not. We
     need to know when updating if we need to trigger an "insert" or "update" action. The easiest
     way to keep track of this is by using a (global) Variable object called isPresentDevice.</para>

     <para>Before we can create this Variable "isPresentDevice", we first need to create the underlying
     data dictionary "isPresentDevice". Create a this data dictionary of type "Boolean" and length
     of 5 (so it can hold the values <parameter>True</parameter> and <parameter>False</parameter>. Since
     we have created Data Dictionaries before, only the end result is shown below:</para>

     <figure><title>Data Dictionary isPresentDevice</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_dd_ispresentdevice.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the data dictionary "isPresentDevice".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>To create the Variable "isPresentDevice" open the Variable Editor in the ProLinga Developer.</para>

      <figure><title>Variable On Object Palette</title>
        <mediaobject>
          <imageobject><imagedata fileref="images/dev_object_variable.png" format="PNG"/></imageobject>
          <textobject><phrase>Screenshot of the variable button on the object palette.</phrase></textobject>
        </mediaobject>
      </figure>

      <para>Enter the just created Data Dictionary "isPresentDevice" and set the default value to "False".
      Save the Variable with the name "isPresentDevice".</para>

     <figure><title>Variable isPresentDevice</title>
       <mediaobject>
         <imageobject><imagedata fileref="images/dev_variable_ispresentdevice.png" format="PNG"/></imageobject>
         <textobject><phrase>Screenshot of the variable "isPresentDevice".</phrase></textobject>
       </mediaobject>
     </figure>

     <para>Everything is now present to write the logic "DeviceRead".</para>

<programlisting>
LET V-isPresentDevice = FALSE()

COMMENT --- No validation on empty key
IF F-deviceNumber.Device = 0 
	RETURN
ENDIF

CLEAR DATAMODEL Device
DATAMODEL SELECT Device TABLE Device CONDITION "where \"deviceNumber\" = '" F-deviceNumber.Device "'"
IF SQLSTATUS() &lt;&gt; 0
	ERROR "Can not read Device."
	RETURN
ENDIF

IF SQLRETURN() = 0
	LET V-isPresentDevice = FALSE()
	LET L-deviceNumber = F-deviceNumber.Device
	CLEAR RECORD Device
	LET F-deviceNumber.Device = L-deviceNumber
	DISPLAY ALL
	MESSAGE "New Device can be inserted."
	FOCUS entryDescription
ELSE
	LET V-isPresentDevice = TRUE()
	FOREACH Device
		LET R-Device = O-Device
		BREAK
	ENDFOR
	DISPLAY ALL 
	MESSAGE "Device can be updated."
	FOCUS entryDescription
ENDIF
</programlisting>

      <para>At first this may look complicated to you, but if you look a bit closer, you will recognise that
      we already used most of the ProLinga logic commands in previous examples. Some commands here do need some
      additional explanation.</para>

      <para>We prevent the user from using the value 0. In that case an error message will be triggered.</para>

      <para>The DATAMODEL SELECT command executes a "Select * from" statement on a table in the database and
      will place the result in an updatable DataModel <parameter>Device</parameter>. 
      Notice in this example the " around the
      column names and the " around the column names and ' around the values. This is the only place where the 
      underlying database determines
      how to construct your SQL, mainly because most databases have their own SQL flavour. In this example
      we are using the PostgreSQL database. If you are using MySQL then you should surround the column names
      with ` and the data with ". Knowledge of the flavour of SQL you are using is required here.</para>

      <para>At the end of the command, you see "DATAMODEL Device". This means that if the query produces
      any results, load them into the DataModel "Device" that we created a little bit earlier.</para>

      <para>A little but further in the we test for SQLRETURN(). If this is set to 0 that means that a 
      Device with the requested Device Number does NOT exist. In that case we clear the table buffer and
      the user can type the details of the new Device to be added. In case SQLRETURN() is set to a value, that
      represents the number of rows the query returned.</para>

      <para>With the FOREACH ProLinga command, all entries in a datamodel can be "walked through". Since we are only 
      interested in the first entry (and only entry), we can use BREAK to break out of the loop after the first
      read. With the command <parameter>LET R-Device = O-Device</parameter>, the current DataModel entry can be 
      assigned to the table buffer, so we can use it to reference the fields.</para>

      <para>Carefully study this logic. It may look difficult at first, but after analyzing it, it is not
      that diffult</para>

      <para>Since the screen "Device" is called from the logic "Device", it is wise to initialize the
      Variable "V-isPresentDevice" in this logic as well. Open your logic "Device" and change it to this:</para>
<programlisting>
CLEAR TABLE Device
LET V-isPresentDevice = FALSE()
LET F-dateInstall.Device = DATE()
SCREEN Device CONTAINER frame_main SOURCE device_include 
DISPLAY ALL
MESSAGE "Device can be updated."
FOCUS entryDeviceNumber
</programlisting>

      <para>Notice the new second line.</para>

      <para>You can run your application now, to see if you do not get any unexpected errors. Since the table
      in the database is still empty, you will not see any data yet.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device-apply">
      <title>Logic: DeviceApply</title>

      <para>As soon as we press the "Apply" button we want to write the changes to the database. If we
      changed an existing record we want to perform an update and if created a new record we want to 
      add it. The logic to do so is as follows:</para>
<programlisting>
IF F-deviceNumber.Device = 0 
	ERROR "Please enter a Device Number."
	FOCUS entryDeviceNumber
	RETURN
ENDIF

IF V-isPresentDevice = TRUE()
	LET O-Device = R-Device
	DATAMODEL UPDATE Device
ELSE
	LET O-Device = R-Device
	DATAMODEL APPEND Device
ENDIF
IF DATAMODELSTATUS() &lt;&gt; 0 
	ERROR "Error updating Device."
	RETURN
ENDIF
MESSAGE "Device has been updated."
LET V-isPresentDevice = TRUE()
</programlisting>

      <para>After we check if a valid number was entered, we check if we either update an exising record 
      or if we add a new one. To
      update the database using the logic command DATAMODEL, we first have to make sure that the current
      record in the DataModel contains the correct values. We know that the correct values are in the table
      buffer "Device", since we have linked data references like F-deviceNumber.Parts to the screen. To get
      these values to the DataModel "Device", you can either assign them one by one (M-deviceNumber.Device =
      F-deviceNumber.Device), or by assigning a complete table buffer record to the DataModel using the 
      Group Data Reference prefixes O- (DataModel) and R- (table buffer Record).</para>

      <para>After an DATAMODEL UPDATE or APPEND, we have to check if the update went OK, by testing the
      a return status made available through the built-in function <parameter>DATAMODELSTATUS</parameter>
      </para>

      <para>Finally we inform the user by updating a message on the message bar and we have to set the
      Variable isPresentDevice to TRUE since even if we added a record, it is present now.</para>

      <para>Save the logic as "DeviceApply" and test your application. You should now be able to add new and
      modify existing records in the database.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device-ok">
      <title>Logic: DeviceOK</title>

      <para>If we press the OK button, we want exactly the same actions to be performed when pressing the
      Apply button and after that we want to close the Device screen. Closing the Device screen in our
      situation means to clear the container, so calling the logic "Home".</para>

<programlisting>
CALL DeviceApply
CALL Home
</programlisting>

      <para>With the logic command CALL we can execute another logic block. Save this logic as "DeviceOK".</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device-delete">
      <title>Logic: DeviceDelete</title>

      <para>When pressing the "Delete" button, we want to delete the record currently displayed on the
      screen. We have to perform some tests first. We have to check if a record is loaded and if so
      ask confirmation of the user if the record really can be removed. Finally the physical removal of
      the record if the user confirms.</para>

<programlisting>
IF F-deviceNumber.Device = 0 
	ERROR "Please enter a Device Number."
	FOCUS entryDeviceNumber
	RETURN
ENDIF

IF V-isPresentDevice = FALSE()
	ERROR "No Device loaded."
	RETURN
ENDIF

ERROR "Are you sure you want to remove Device: " CLIP(F-deviceNumber.Device) "?" SEVERITY Question
IF ERRORRETURN() &lt;&gt; 0
	RETURN
ENDIF

LET O-Device = R-Device
DATAMODEL REMOVE Device
IF DATAMODELSTATUS() &lt;&gt; 0 
	ERROR "Error removing Device."
	RETURN
ENDIF
LET V-isPresentDevice = FALSE()
CLEAR RECORD Device
DISPLAY ALL
MESSAGE "Device has been removed."
</programlisting>

      <para>We have seen all ProLinga statements before, so you should be able now to read this logic. Save
      the function as "DeviceDelete" and test your application.</para>

      <para>The first part of your application is now fully functional. In the next chapters we will make
      a search mechanism for a Device, in case the user does not know a Device Number.</para>

    </sect1>

  </chapter>

  <chapter id="prolinga-tutorial-variable-group-search">
    <title>Variable Group Search</title>

    <para>If the user does not know the Device Number, a search mechanism should be available. The user
    presses the "Find" button that we created earlier and a screen comes up, where the user can enter a
    filter and browse through the available Devices. One the selection is made, the screen disappears and
    the Device Number is pasted in the Device Number field on the screen Device.</para>

    <para>Before we create the Search screen, we first need a mechanism to get the value from the Search
    screen to the Device Number field on the Device screen. We can use a Variable (V-) for this like we
    seen before, but since in bigger applications, there will be more than one search screen, it is 
    probably better to group them together in a Variable Group. We create a Variable Group that can hold
    a Device Number. If the application grows, we can add more search criteria later.</para>

    <figure><title>Variable Group On Object Palette</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_object_variable_group.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the pick list button on the object palette.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Press the button "New" on the tool bar of the Variable Group Editor to create a new Variable Group. 
    Now enter the name of the Data Dictionary "deviceNumber" in the "Data Dictionary Name" field and leave
    the "Initial Value" field empty. Press the "Add" button and you will see that the value now appears
    in the list. Save the Variable Group with the name "Search".</para>

    <figure><title>Variable Group Search</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_variable_group_search.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the variable group "Search".</phrase></textobject>
      </mediaobject>
    </figure>

    <para>This change has no effect on your application yet, so there will not be any differences when
    running the application now.</para>

  </chapter>

  <chapter id="prolinga-tutorial-paint-search-screen">
    <title>Paint DeviceSearch Screen</title>

    <para>Open the Screen Dialog Editor in the ProLinga Developer. Press the "New Dialog" button and save the
    screen as "DeviceSearch". Now open this screen in the painter.</para>

    <para>Set the Title to "Search Device".</para>

    <para>Set the width of the screen to 400 and the height to 300.</para>

    <figure><title>Base Screen DeviceSearch</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_base.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of base screen DeviceSearch.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Place a "Vertical Box" in the main area of the screen.</para>

    <figure><title>Vertical Box Screen DeviceSearch</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_vbox.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of vertical box screen DeviceSearch.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Place a "Scrolled Window" object in the first section and within that a "List or Tree View"
    object.</para>

    <figure><title>List View Screen DeviceSearch</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_ltview.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of list view screen DeviceSearch.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>In the second section place a "Horizontal Box" with 3 columns.</para>

    <figure><title>Horizontal Box Screen DeviceSearch</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_hbox.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of horizontal box screen DeviceSearch.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>In the first column place a "Label" object with the text "Filter:", in the second column place a
    "Text Entry" object and the last column place a "Button" object with using the stock icon "Index".</para>

    <figure><title>Filter Screen DeviceSearch</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_filter.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of filter line screen DeviceSearch.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>Now we make some cosmetic changes. The horizontal box should not expand, Border Width set to 5 and
    Spacing set to 5. Also we set the Border Width of the Scrolled Window to 5.</para>

    <figure><title>All Objects Screen DeviceSearch</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_all_objects.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of all objects screen DeviceSearch.</phrase></textobject>
      </mediaobject>
    </figure> 

    <para>The painting of the Search Screen is now completed and we can populate it.</para>

  </chapter>

  <chapter id="prolinga-tutorial-list-store">
    <title>List Store Device</title>

    <para>We will use the  "List Tree View" on the DeviceSearch screen as a Multi Column List Box. Therefore we
    need a ProLinga List Store object that contains the data we select. Since the list will be populated
    at run-time, we only need to create an empty List Store with the columns we want to see. We will
    only display the Device Number and the Description fields.</para>
    
    <figure><title>List Store On Object Palette</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_object_list_store.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the list store button on the object palette.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Open the List Store Editor and press the "New" button on the toolbar to create a new List Store. In
    the tab "General", set the number of columns to 2 and leave the setting "Maximum Number of Rows" default
    to 1. Click on the tab "Store". Enter "Device Number" in the field "Label", select "Type" "Number" and set
    sort direction to "Ascending". Press the "Apply" button. Enter "2" in the field "Column Id" and details
    of the second column can be entered. Set "Label" to "Description", "Type" to "Text" and sorting to "None".
    Press "Apply" again. You will see both column names now in the list. Since the data will be loaded at 
    run-time, we do not have to enter any data at row level. Save the List store with the name "Device".</para>

    <figure><title>List Store Device</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_list_store_device.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the list store "Device".</phrase></textobject>
      </mediaobject>
    </figure>

    <para>In the next chapter we will link this List Store into our DeviceSearch screen, so it did not change
    the run-time behaviour of your application.</para>

  </chapter>

  <chapter id="prolinga-tutorial-populate-search-screen">
    <title>Populate DeviceSearch Screen</title>

    <para>We have created a DeviceSearch screen, but we have not linked any action handlers and data references
    to it. Open your screen "DeviceSearch" in the ProLinga Screen Editor and start the Painter.</para>

    <para>The Screen itself must be linked to "L-DeviceSearchRealize" for the "realize" signal. This
    signal is triggered as soon as the screen is created at run-time. To link signals to the screen
    itself either select the entry "DeviceSearch" in the Widget Window (first entry) or click on the
    "DeviceSearch" of the main frame of the Painter and then go to the "signal" tab of the Properties
    Window.</para>

    <para>The "Cancel" button must be linked to "C-cancel" for the "clicked" signal.</para>

    <para>The "OK" button must be linked to "L-DeviceSearchOK" for the "clicked" signal. The button should also 
    be set as the 'default' button, meaning that logic linked to the button will be executed when the 'ENTER' button 
    is pressed on the Text Entry field. Go to the 'Common' tab and set the toggle buttons 'Has Focus' and 
    'Can Focus' to 'Yes'.</para>

    <para>The "Index" button must be linked to "L-DeviceSearchList" for the "clicked" signal.</para>

    <para>The "Text Entry" field must be linked to Data Reference D:GET:G-deviceNumber.Search for
    the focus_in_event and D:PUT:G-deviceNumber.Search for the focus_out_event. With G- we can get
    a value from a Variable Group entry. It is also important that you give this object the
    name "entryFilter" so we can reference it from logic later on. Set the 'Activates Default' toggle button
    to 'Yes'. In the 'Common' tab set the toggle buttons 'Can Focus' and 'Has Focus' to 'Yes', so this field
    will get the input focus when displayed.</para>

    <para>It is important that we set the name of the "List Store", since we need to reference it later on
    from logic. Set the name to "DeviceSearchList". </para>

    <figure><title>Name The List View</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_list_name.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the name of the List View.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>Then we need to link a couple of signals to the "List View". Set a "cursor_changed" signal and 
    link that to logic "PartSearchSelect". This logic is performed every time the user selects a line in 
    the list view. Set a "button_press_event" signal and link that to "L-DeviceSearchOK". This logic will
    be triggered on a double mouse click. Set a "realize" signal and and link that to " I:"Device" ", the
    name of our List Store.</para>

    <figure><title>Signals List View</title>
      <mediaobject>
        <imageobject><imagedata fileref="images/dev_screen_search_list_signals.png" format="PNG"/></imageobject>
        <textobject><phrase>Screenshot of the signals of the List View.</phrase></textobject>
      </mediaobject>
    </figure>

    <para>This is all that needs to be done in the Painter for the "DeviceSearch" screen. Save the screen
    and continue with the next chapter where we will write all the matching logics.</para>

  </chapter>

  <chapter id="prolinga-tutorial-logic-device-search-screen">
    <title>Write Logic Device Search Screen</title>

    <para>During the painting of the "Device Search" screen, we made many calls to ProLinga logics. 
    We will now write all those logics.</para>

    <para>In the logics we need to be able to find out if the user presses OK or Cancel when
    closing the screen. For that we create a Variable (V-) called "accept". This will be of
    a boolean type that can accept a "True" and "False" value. If you are unsure how to create
    a Variable, look back a couple of chapters where we created the Variable "isPresentDevice". 
    Do exactly the same, only this time name it "accept".</para>

    <sect1 id="prolinga-tutorial-logic-search-device_number">
      <title>Logic: SearchDeviceNumber</title>

      <para>When the user presses the "Find" button from the "Device" screen, we created an
      error message that this functionality has not been implemented. Open this function
      and replace the logic with the following one:</para>

<programlisting>
LET V-accept = FALSE()
LET G-deviceNumber.Search = "*"
SCREEN DeviceSearch
IF V-accept = TRUE()
	DISPLAY entryDeviceNumber
ENDIF
</programlisting>

      <para>What we do here is to initialize the variable and variable group entry and then
      we call the screen "DeviceSearch". As soon as the user leaves this screen we check
      if the user pressed OK by testing the "V-accept" variable. In that case we want
      to display the selected value in the Device Number field.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device_search_realize">
      <title>Logic: DeviceSearchRealize</title>

      <para>As soon as the "DeviceSearch" screen is displayed, we need to clear the List Store 
      Device and display the contents of all fields.</para>

<programlisting>
CLEAR LISTSTORE Device
DISPLAY ALL
</programlisting>

      <para>This logic is performed as soon as the screen is displayed.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device_search_list">
      <title>Logic: DeviceSearchList</title>

      <para>If the user presses the "Index" button on the "DeviceSearch" screen, we want
      to get all Device entries from the database and place them in a List Store, so they
      can be presented in the List View.</para>

<programlisting>
CLEAR LISTSTORE Device

CLEAR DATAMODEL Device
DATAMODEL SELECT DeviceSearch TABLE Device
IF SQLSTATUS() &lt;&gt; 0
	RETURN
ENDIF

FOREACH DeviceSearch
	LIST APPEND Device VALUE CLIP(M-deviceNumber.DeviceSearch) CLIP(M-description.DeviceSearch)
ENDFOR

DISPLAY DeviceSearchList
</programlisting>

      <para>We first clear the List Store from any data if any, execute a DATAMODEL statement to 
      retrieve the data and append
      all values to the List Store. The built-in function CLIP, clips leading and trailing spaces
      from a data reference.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device_search_select">
      <title>Logic: DeviceSearchSelect</title>

      <para>If the user selects an entry in the multi column list box (List View), we want the selected
      value to be copied to G-deviceNumber.Search</para>

<programlisting>
LIST GET Device VALUE G-deviceNumber.Search COLNO 1
DISPLAY entryFilter
</programlisting>

      <para>Here we get the value from the first column of the List Store "Device" and store it in the
      Variable Group entry "deviceNumber". The field is visually updated on the screen with the "DISPLAY"
      command.</para>

    </sect1>

    <sect1 id="prolinga-tutorial-logic-device_search_ok">
      <title>Logic: DeviceSearchOK</title>

      <para>If the user presses OK, we want to confirm some checks if a correct selection has been made
      and if so, assign the value to the table buffer entry "F-deviceNumber.Device". We set the
      Variable "accept" to "True" so we know on the lower level that the user pressed "OK".</para>

<programlisting>
IF G-deviceNumber.Search = "*" 
	ERROR "Please enter a valid Device number."
	RETURN
ENDIF

IF CLIP(G-deviceNumber.Search) = "" 
	ERROR "Please enter a valid Device Number."
	RETURN
ENDIF

LET F-deviceNumber.Device = G-deviceNumber.Search
LET V-accept = TRUE()
CONTROL cancel
</programlisting>

      <para>The ProLinga "CONTROL" commands destroys the screen "DeviceSearch" and processing resumes in 
      the logic calling this screen (dialog).</para>

    </sect1>

    <sect1 id="prolinga-tutorial-run-device_search">
      <title>Search Screen At Run-Time</title>

      <para>If you now run your application and press the "Find" button, you will see that you have a
      working search screen.</para>

      <figure><title>Search Screen At Run-Time</title>
        <mediaobject>
          <imageobject><imagedata fileref="images/dev_run_search.png" format="PNG"/></imageobject>
          <textobject><phrase>Screenshot of the Search Screen at Run-Time.</phrase></textobject>
        </mediaobject>
      </figure>

      <para>You will see that if you select a value and click "OK" (or just double click), the
      value will be brought back to the previous screen, where you can modify the record.</para>

    </sect1>

  </chapter>

  <chapter id="prolinga-tutorial-congratulations">
    <title>Congratulations</title>

    <para>Congratulations! You just completed your first ProLinga application. We hope that 
    you enjoyed working with ProLinga and we would appreciate if you would let <ulink type="http" 
    url="http://lists.prolinga.org">us</ulink> know your comments.</para>

    <para>There are many more ProLinga commands and features in ProLinga that are not present in the
    tutorial. Please read the 
    <ulink type="http" url="/prolinga-doc/reference/index.html">Reference Manual</ulink>
    where all this is documented.</para>

  </chapter>

  <!-- The document license -->
  &fdl;

</book>
