
                   HINTS, TIPS and COOKBOOK
                   ------------------------
This document explains how to accomplish 'typical' tasks, such as 
initializing windows, checking for null fields, using radio buttons, 
and the like.  Read on.

-- To initialize a form, treat it like a report.  The following will
   initialize an "widget one" with a blank and "widget two" with 
   the string "asdf":
   <report>
      <entry widget="widget one" value=""\>
      <entry widget="widget two" value="asdf"\>
   </report>

-- To run a query when the app is started (e.g. to populate the main window)
   use <submit widget="app main window" signal = "show">
   Note, however, for this to work right, you *must* have the main 
   window marked as "not visible" (glade 'common' tab) ;
   otherise the show signal will be delivered before dwi is initialized
   (and thus won't be caught).  Really.  Not kidding.  Re-read the above.

-- To have the app shut off when the app main window is closed, use
   glade to add gtk_main_quit to the "destroy" signal of the app main 
   window.  You can also use glade to hook this callback to any signal 
   on any widget.  This can also be done within DWI, if desired.
   For example, the following will hook up a menu item so that it 
	causes the gtk main loop to be exited:
   <sigaction widget="my_menu_item" signal="activate" action="main_quit"/>
	Similarly, this will cause the main loop to exit when the main
	window is closed:
   <sigaction widget="main window" signal="destroy" action="main_quit"/>

-- A <window> secion must have a <report> section in it, even if empty.
   Otherwise that window can't be the target of any actions (and will
   not be instantiated!).

-- You can append to a previously defined <window> section, merely by
   refering to it by name.  There is no technical reason that this
   would ever be needed; however, its provided as a convenience.
   For example:

   <window name="first window" provider="glade" filename="somefile.glade"  
                     root_widget="first app window">
         ....
   </window>

   <window name="second window" provider="glade" filename="somefile.glade"  
                     root_widget="some dialog">
         ....
   </window>

   <!-- append more definitions to the first window. We don't need to
        specify a provider, etc. this time.  
     -->
   <window name="first window">
         ....
   </window>

-- How to get a form to 'remember' the last values entered:
   To get a form to 'remember' the last values entered, one could,
   of course, store them in the database, and then intialize the form 
   from the database.  But there's an easier way that is more appropriate
   for most applications, and that is to store the last values entered 
   in the global key-value-pair table.  In the following example,
   the widget's value is stored when the submit button is pressed.
   Next time the form is initializzed, it will be initialized with
   the stored value.  The example:

   <form>
     <!-- store widget's value under "some key" in the global table -->
     <wtokey widget="some widget" key="some key"/>
     <submit widget="submit button" signal="clicked"/>
   </form>

   <report>
     <!-- initialize widget's value based on "some key" in the global table -->
     <entry widget="some widget" key="some key"/>
   </report>

-- How to check for blank or invalid fields:
   When preparing a form, it is often useful to make sure that the user
   entered a valid value for a field, before commiting that field to the 
   database.  This can be done with chained forms in conjunction with
   data filters.  The example below shows how to do this.

   <!-- first, prepare an error popup dialog in glade.
     -- This will use the 'whitespace' filter to make sure that
     -- the global-hash-table key 'foobar' is not whitespace. 
     -->
   <window name="demand foobar" root_widget="need foobar msg">
      <report>
        <entry widget="need foobar msg" key="foobar" filter="is_whitespace_or_null"/>
      </report> 
   </window>

   <!-- next, we have the main foobar dialog -->
   <window name="foobar dialog" a...>
              
     <!-- Copy from foobar widget into the database. But first, 
       -- chain in the "need foobar" form to make sure that the
       -- data is valid.  If the data isn't valid, the error
       -- message dialog will display, and the database insert 
       -- won't happen.
       -->
     <form type="insert" tables="BlahBlahTable">
       <chain  form="need foobar"/>
       <insert widget="foobar entry"   field="foobar"/>
       <submit widget="ok button" signal="clicked"/>
     </form>
 
 
     <!-- This form will copy from the "foobar entry" widget and insert
       -- into the global-hash-table key "foobar".  It will then cause
       -- the "demand foobar" report to run.  This report, defined above,
       -- will check to make sure the global "foobar" isn't blank.
       -->
     <form name="need foobar" report="demand foobar">
       <wtokey widget="foobar entry" key="foobar"/>
     </form>

   </window>

-- How to use radio buttons:
   First, initialize the data on *each* radio button when the form 
   is first created. For example, the following has a yes/no button:

    <report>
      <entry widget="yes button"        data="val" value="y"/>
      <entry widget="no button"         data="val" value="n"/>
      <entry widget="some other widget"            value=""/>
    </report>
                                                    
   Then copy from the widget data to the database.  The form needs to
   specify only one of the radio buttons to pick up the whole group.
   The data from the selected button will be copied to the database.

     <form type="insert" tables="MyTable">
       <insert widget="yes button"      data="val" field="choice"/>
       <insert widget="some other widget"          field="blah_blah"/>
     </form>


-- How to use the file selection dialog:
   In the example below, we have use a GtkEntry widget to allow the 
   user to type in a file name, and also use a GtkFileSelection widget
   to allow the user to browse and pick a file.  After browsing, the 
   user's selection will be copied into the GetEntry.

   <window name="file entry dialog" ...>
     <!-- launch the file picker when button is clicked -->
     <form report="file browser dialog">
        <submit widget="open the file picker button" signal="clicked"/>
     </form>

     <!-- Whenever this window is redrawn, the GtkEntry widget will 
          be initialized from the global-hash-table key "filesel result".
          The very first time, of course, this key won't exist, and 
          thus will be blank.
      -->
     <report>
       <entry widget="my filename entry widget"   key="filesel result"/>
     </report>

   </window>

   <!-- file picker dialog ============================= -->
   <window name="file browser dialog" ...>
     <!-- Whenever this window is opened, the GtkFileSelection widget will 
          be initialized from the global-hash-table key "filesel result".
          The very first time, of course, this key won't exist, and 
          thus will be blank.
      -->
     <report>
        <entry widget="file selection" key="glade filesel"/>
     </report>

     <!-- When the user clicks the "OK" button, the file that they selected
          will be copied to the global-hash-table key "filesel result".
          In addition, the window called "file entry dialog" will be redrawn.
      -->
     <form>
        <wtokey widget="file selection"  key="glade filesel"/>
        <submit widget="ok button" signal="clicked"/>
        <refresh window="file entry dialog"/>
     </form>

     <!-- Close the file picker window when either button is clicked -->
     <sigaction widget="ok button" signal="clicked" action="close_window"/>
     <sigaction widget="cancel button" signal="clicked" action="close_window"/>
   </window>
                                                                                   <!-- Add more stuff to the previously defined window -->
   <window name="file entry dialog">

     <!-- store filename into database -->
     <form type="insert" tables="file_table">
        <insert widget="my filename entry widget" field="db_file_field"/>
        <submit widget="store it" signal="clicked"/>
     </form>
   </window>

-- How to list the tables in a database:
   Use the form type "tables".  For example:

   <form type="tables" report="table list dialog">
     <submit widget="some menuitem" signal="activate" />
   </form>
                    
   <report name="table list dialog">
     <row widget="some clist">
       <entry  column="0"   field="TABLE_NAME"      />
       <entry  column="1"   field="TABLE_TYPE"      />
       <entry  column="2"   field="TABLE_QUALIFIER" />
       <entry  column="3"   field="TABLE_OWNER"     />
       <entry  column="4"   field="REMARKS"         />
     </row>
   </report>
	

-- How to list the fields in a table:
   Use the form type "fields". For example, the following picks 
	the name of a table out of a list:

   <form name="high-lite" >
     <wtokey widget="some clist" column="0"  key="table_name"  />
     <submit widget="some clist" signal="select_row" />
   </form>
										
   <form type="fields" tables_key="table_name" report="field list dialog">
     <submit widget="view button" signal="clicked" />
   </form>
							
   <report name="field list dialog">
     <row widget="some clist">
	    <entry  column="0"   field="TABLE_QUALIFIER" />
	    <entry  column="1"   field="TABLE_OWNER"  />
	    <entry  column="2"   field="TABLE_NAME"   />
	    <entry  column="3"   field="COLUMN_NAME"  />
	    <entry  column="4"   field="DATA_TYPE"    />
	    <entry  column="5"   field="TYPE_NAME"    />
	    <entry  column="6"   field="PRECISION"    />
	    <entry  column="7"   field="LENGTH"       />
	    <entry  column="8"   field="SCALE"        />
	    <entry  column="9"   field="RADIX"        />
	    <entry  column="10"  field="NULLABLE"     />
	    <entry  column="11"  field="REMARKS"      />
	    <entry  column="12"  field="DISPLAY_SIZE" />
	    <entry  column="13"  field="FIELD_TYPE"   />
     </row>
   </report>



========================== THAT'S ALL FOLKS =====================
