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 initialize the main window (so that it has values when the application
starts), treat it as a report (as described above), and use the "show"
signal on the main window widget to trigger the running of the report.
For example:
<form report="show data">
<!-- form is cleared when window first pops up -->
<submit widget="main win" signal="show" />
</form>
<report name="show data">
<... etc ... >
</report>
Note that in order for the above to work, you must use Glade to mark
the main window as "not visible", otherwise, the main window will be
shown before DWI has initialized, and thus, DWI will never catch the
"show" signal (and thus the report won't run).
-- 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>