GRIDPLUS - Example 5
Home Reference Manpage Examples Download License Contact

Example Of a Complete Simple Application

This is an example of a complete "Phonebook" application based on a MetaKit database. This example is mainly intended to demonstrate how a complete GRIDPLUS application may be structured.

This example assumes familiarity with the previous/earlier examples, as the more basic GRIDPLUS usage is not described in full.

User Guide

Main Window:

The toolbar contains six buttons, each has appropriate pop-up/balloon help:-

Add new record.
Delete selected record.
Edit selected record.
Find matching records.
Display help text.
Exit application.


Add Record:

Pressing the "Add Record" button will display the following modal (toplevel) window:-

The "Add Record" window toolbar contains two buttons, each has appropriate pop-up/balloon help:-

Save new record.
Close "Add Record" window without saving record.

The "Last Name" and "Phone" entry fields must contain data. If there is an attempt to either leave one of these fields -or- to save the record when the field is empty, a screen similar to the following will be displayed:-


Delete Record:

In order to delete a record it is necessary to select a record, by single-clicking a line in the main window list, before pressing the "Delete Record" button.

When this is done the following dialog is displayed:-

Pressing the "OK" button will delete the record. Pressing the "Cancel" button will abort the delete operation.

If no record is selected when the "Delete Record" button is pressed, the following dialog is displayed:-

Pressing the "OK" button closes the dialog.


Edit Record:

Pressing the "Edit Record" button will display the following modal (toplevel) window:-

The "Edit Record" window toolbar contains two buttons, each has appropriate pop-up/balloon help:-

Save amended record.
Close "Edit Record" window without saving changes.

If no record is selected when the "Edit Record" button is pressed, the following dialog is displayed:-

Pressing the "OK" button closes the dialog.


Find Matching Records:

To display records that contain a particular text/number string, type the required find string in the field to the right of the "Find" toolbar button then either; Press the Enter/Return key or the "Find" toolbar button.

Using the sample database and "service" find string, the following is displayed:-

Pressing the either the Enter/Return key or the "Find" toolbar button with an empty find field will display all records in the database.

Note: The find string is matched anywhere in a record and is not case sensitive.


Display Help Text:

Pressing the "Display Phonebook Help" button will display the following (toplevel) window:-

The "Phonebook Help" window toolbar contains five buttons, each has appropriate pop-up/balloon help:-

Display "Top" (begining) of help text.
Display previous topic.
Display next topic.
Display "Bottom" (end) of help text.
Close "Phonebook Help".

The blue/underlined text are links to the various topics in the help text. When the mouse pointer is over a link its colour changes to red. When a link is "clicked" the display moves to show the selected topic.

Clicking on the "Adding New Records" link (or pressing the "Next Topic" button) will display the following screen:-

The previous/next topic buttons can also be used to step through the help text topics. The display will move to show the previous/next topic relative to the last topic selected either by clicking on a link -or- by pressing one of the top/previous/next/bottom topic buttons.

Source Code

#----------------------------------------------#
# Procedure To Display Main Application Screen #
#----------------------------------------------#

proc mainDisplay {} {

   gridplus window . -deletewindow toolbar,exit

   gridplus entry .find -style toolbar -size 30 {
      {.string + ~toolbar,find}
   }

   gridplus button .toolbar -style toolbar -pad 0 {
      {.add :actitemadd16 "?Add Record"} {.delete :actitemdelete16 "?Delete Record"} \
      {.edit :edit16 "?Edit Record"} | {.find :viewmag16 "Find" 50} {@find} |        \
      {.help :acthelp16 "?Display Phonebook Help"} {.exit :actexit16 "?Exit Phonebook"}
   }

   gridplus layout .toolbar_border -relief raised {
      .toolbar
   } 

   gridplus tablelist .phonelist -action double -options stripe -width 80 -scroll y {
      0 id           hide
      0 "First Name"
      0 "Last Name"
      0 "Phone"
      0 "Department"
   }

   gridplus layout .main -title "Phonebook" {
      .toolbar_border:ew
      .phonelist
   }

   pack .main
}

#-------------------------#
# Procedure To Add Record #
#-------------------------#

proc toolbar,add {} {

   gridplus window .add -modal 1 -deletewindow add:toolbar,close

   gridplus set -errormessage "This field must not be blank"
   label .add.errormessage -foreground red

   gridplus button .add.toolbar -style toolbar {
      {.save :filesave16 "?Save Record" !} {.close :fileclose16 "?Close"}
   }

   gridplus layout .add.toolbar_border -relief raised {
      .add.toolbar
   } 

   gridplus entry .add.phone -size 30 {
      {"First Name"  .firstname +}
      {"Last Name"   .lastname !notnull}
      {"Phone"       .phone !notnull}
      {"Department " .department}
   }

   gridplus layout .add.main -title "Add Record" {
      .add.toolbar_border:ew
      .add.phone
      .add.errormessage
   }

   pack .add.main
}

#----------------------------#
# Procedure To Delete Record #
#----------------------------#

proc toolbar,delete {} {
   global {}

   if {! [info exists (.phonelist)]} {
      tk_messageBox -icon error -title "Phonebook: Delete" -message "No record selected for delete" -type ok
      return
   } else {
      set action [tk_messageBox -icon warning -title "Phonebook: Delete" -message "Delete Record: [lrange $(.phonelist) 1 2]" -type okcancel]
      if {$action eq "ok"} {
         mk::row delete db.data![lindex $(.phonelist) 0]
         refreshList
      }
   }
}

#--------------------------#
# Procedure To Edit Record #
#--------------------------#

proc toolbar,edit {} {
   global {}

   if {! [info exists (.phonelist)]} {
      tk_messageBox -icon error -title "Phonebook: Edit" -message "No record selected for edit" -type ok
      return
   }

   gridplus window .edit -modal 1 -deletewindow edit:toolbar,close

   gridplus set -errormessage "This field must not be blank"
   label .edit.errormessage -foreground red

   gridplus button .edit.toolbar -style toolbar {
      {.save :filesave16 "?Save Record" !} {.close :fileclose16 "?Close"}
   }

   gridplus layout .edit.toolbar_border -relief raised {
      .edit.toolbar
   } 

   gridplus entry .edit.phone -size 30 {
      {"First Name"  .firstname +}
      {"Last Name"   .lastname !notnull}
      {"Phone"       .phone !notnull}
      {"Department " .department}
   }

   gridplus layout .edit.main -title "Edit Record" {
      .edit.toolbar_border:ew
      .edit.phone
      .edit.errormessage
   }

   gpmap {
      .edit.phone,firstname
      .edit.phone,lastname
      .edit.phone,phone
      .edit.phone,department
   } [lrange $(.phonelist) 1 end]

   pack .edit.main
}

# **Link this proc to the "phonelist" double-click action**

proc phonelist {} {toolbar,edit}

#------------------------------------#
# Procedure To Find Matching Records #
#------------------------------------#

proc toolbar,find {} {
   global {}

   set list {}

   foreach row [mk::select db.data -keyword {firstname lastname phone department} $(.find,string)] {
      lappend list "$row [mk::get db.data!$row firstname lastname phone department]"
   }

   gpset .phonelist   $list
   gpset .find,string {}
}

#--------------------------------#
# Procedure To Display Help Text #
#--------------------------------#

proc toolbar,help {} {

   if {! [gridplus window .help -deletewindow help:toolbar,close]} {
      return
   }

   gridplus button .help.toolbar -style toolbar {
      {.top :playstart16 "?Top"} {.previous :nav1leftarrow16 "?Previous Topic"} \
      {.next :nav1rightarrow16 "?Next Topic"} {.bottom :playend16 "?Bottom"} |  \
      {.close :fileclose16 "?Close Phonebook Help"}
   }

   gridplus layout .help.toolbar_border -relief raised {
      .help.toolbar
   } 

   gridplus text .help.text -scroll y -tags 1 -linkcolor blue/red -linkstyle underline -height 15 -width 50

   gridplus layout .help.main -title "Phonebook Help" {
      .help.toolbar_border:ew
      .help.text
   }

   pack .help.main

   gpset .help.text {<label top:default><font arial:default><size 8:default><bgcolor dodgerblue><color white>\
<size +10>Phonebook Help
<size +2></color><bgcolor lightgray>Topics
</bgcolor>
<link add>Adding New Records</link>
<link delete>Deleting Records</link>
<link edit>Editing Records</link>
<link find>Finding Records</link>
<link exit>Exiting Phonebook Application</link>

<label add><bgcolor lightgray>Adding New Records
</bgcolor>
Press the <image :actitemadd16> button to display the <b>Add Record</b> window.\
This window has two options:-

  <image :filesave16> Save record.

  <image :fileclose16> Close window without saving record.

The <b>Last Name</b> and <b>Phone</b> fields must contain data. An attempt to\
save the record -or- move to another field when one of these fields are empty\
will highlight the field with a red background and display: <color red>This\
field must not be blank</color>

<label delete><bgcolor lightgray>Deleting Records
</bgcolor>
Press the <image :actitemdelete16> button to delete the currently selected record.

A delete confirmation dialog is displayed: Press <b>OK</b> to delete the record\
-or- <b>Cancel</b> to abort the deletion.

<label edit><bgcolor lightgray>Editing Records
</bgcolor>
Press the <image :edit16> button to display the <b>Edit Record</b> window for the\
currently selected record. This window has two options:-

  <image :filesave16> Save record.

  <image :fileclose16> Close window without saving record.

The <b>Last Name</b> and <b>Phone</b> fields must contain data. An attempt to\
save the record -or- move to another field when one of these fields are empty\
will highlight the field with a red background and display: <color red>This\
field must not be blank</color>

<label find><bgcolor lightgray>Finding Records
</bgcolor>
Enter a search string into the <b>Find</b> field then press the <image :viewmag16>\
button to display the matching records.

The search string is matched anywhere in the record and is not case sensitive.

<label exit><bgcolor lightgray>Exiting Phonebook Application
</bgcolor>
Press the <image :actexit16> button to exit the <b>Phonebook</b> application.

<label bottom><bgcolor lightgray><b>Phonebook</b> - (c) Adrian Davis 2004
</bgcolor>}

}

#-------------------------------#
# Procedure To Exit Application #
#-------------------------------#

proc toolbar,exit {} {

   mk::file commit db
   mk::file close  db

   exit
}

#--------------------------------#
# Procedure To Save "add" Record #
#--------------------------------#

proc add:toolbar,save {} {
   global {}

   mk::row append db.data                \
      firstname  $(.add.phone,firstname) \
      lastname   $(.add.phone,lastname)  \
      phone      $(.add.phone,phone)     \
      department $(.add.phone,department)

   refreshList

   add:toolbar,close
}

#---------------------------------#
# Procedure To Close "add" Window #
#---------------------------------#

proc add:toolbar,close {} {

   gridplus clear .add

   destroy .add
}

#---------------------------------#
# Procedure To Save "edit" Record #
#---------------------------------#

proc edit:toolbar,save {} {
   global {}

   mk::set db.data![lindex $(.phonelist) 0] \
      firstname  $(.edit.phone,firstname)   \
      lastname   $(.edit.phone,lastname)    \
      phone      $(.edit.phone,phone)       \
      department $(.edit.phone,department)

   refreshList

   edit:toolbar,close
}

#----------------------------------#
# Procedure To Close "edit" Window #
#----------------------------------#

proc edit:toolbar,close {} {

   gridplus clear .edit

   destroy .edit
}

#---------------------------------------#
# Procedure To Display Top Of Help Text #
#---------------------------------------#

proc help:toolbar,top {} {
   gridplus goto .help.text top
}

#------------------------------------------#
# Procedure To Display Bottom Of Help Text #
#------------------------------------------#

proc help:toolbar,bottom {} {
   gridplus goto .help.text bottom
}

#-------------------------------------------#
# Procedure To Display Next Help Text Topic #
#-------------------------------------------#

proc help:toolbar,next {} {
   global {}

   set topics  [list top add delete edit find exit bottom]
   set current [lsearch $topics $(.help.text)]

   if {[set next [lindex $topics [expr {$current + 1}]]] ne ""} {
      gridplus goto .help.text $next
   }
}

#-----------------------------------------------#
# Procedure To Display Previous Help Text Topic #
#-----------------------------------------------#

proc help:toolbar,previous {} {
   global {}

   set topics  [list top add delete edit find exit bottom]
   set current [lsearch $topics $(.help.text)]

   if {[set previous [lindex $topics [expr {$current - 1}]]] ne ""} {
      gridplus goto .help.text $previous
   }
}

#----------------------------------#
# Procedure To Close "help" Window #
#----------------------------------#

proc help:toolbar,close {} {

   gridplus clear .help

   destroy .help

}

#-----------------------------------#
# Procedure To Refresh Display List #
#-----------------------------------#

proc refreshList {} {

   set list {}

   foreach row [mk::select db.data] {
      lappend list "$row [mk::get db.data!$row firstname lastname phone department]"
   }

   gpset .phonelist $list
}

#=======================#
# Start The Application #
#=======================#

package require gridplus 1.1
namespace import -force gridplus::*

# Require metakit package
package require Mk4tcl

# Open database
mk::file open db phonebook.mk

# Create a "toolbar" style
gridplus style toolbar {-buttonrelief flat -borderwidth 0 -space 0 -pad 0 -takefocus 0}

# Start
mainDisplay

refreshList

Comments

proc mainDisplay {} {

gridplus window . -deletewindow toolbar,exit

Create a procedure called "mainDisplay" to display the main/root window. Set the "-deletewindow" procedure to "toolbar,exit"; this will invoke the same exit procedure as will be invoked by the toolbar "Exit Application" button, if the window is closed using window manager facilities, to allow the database to be closed properly.
gridplus entry .find -style toolbar -size 30 {
   {.string + ~toolbar,find}
}

Creates a GRIDPLUS entry grid called ".find", using the "toolbar" style, which is "30" characters wide.

The grid contains one entry called ".string". This content of this entry can be accessed as "$(.find,string)". The "+" widget option gives keyboard focus to the entry. The "~toolbar,find" option causes the "toolbar,find" procedure to be invoked if the Enter/Return key is pressed while the entry has keyboard focus. This is the same procedure as will be invoked by the "Find" toolbar button.

gridplus button .toolbar -style toolbar -pad 0 {
   {.add :actitemadd16 "?Add Record"} {.delete :actitemdelete16 "?Delete Record"} \
   {.edit :edit16 "?Edit Record"} | {.find :viewmag16 "Find" 50} {@find} |        \
   {.help :acthelp16 "?Display Phonebook Help"} {.exit :actexit16 "?Exit Phonebook"}
} 

gridplus layout .toolbar_border -relief raised {
   .toolbar
}

Creates a GRIDPLUS button grid called ".toolbar". Each button has an explicitly defined name, an icon and associated pop-up/balloon help.

For Example: "{.add :actitemadd16 "?Add Record"}".

This button will invoke a procedure called "toolbar,add", will have the ICONS image called "actitemadd16", and has "Add Record" as the pop-up/balloon help.

The ".find" button is compound; It displays both the "viewmag16" image and "Find" text. The ".find" entry grid is embedded in the toolbar next to the find button ("@find").

A GRIDPLUS Layout is used to add a "raised" border to the toolbar.

gridplus tablelist .phonelist -action double -options stripe -width 80 -scroll y {
   0 id           hide
   0 "First Name"
   0 "Last Name"
   0 "Phone"
   0 "Department"
}
Creates a tablelist called ".phonelist", which is "80" characters wide and has a "y" direction (vertical) scrollbar. The "-options stripe" option causes alternate lines in the list to have a lightblue background. The "-action double" option will invoke a procedure called "phonelist" when a line in the list is selected using a double-click.

The table list has five columns. Each has a size of "0" (zero), which auto-sizes the columns to fit the column header/data (See the website of Dr Csaba Nemithi, author of the Tablelist package).

The "hide" option is a GRIDPLUS addition. This causes a hidden column to be created. In this application, the hidden column is used to store the MetaKit database row ID of the record.

gridplus layout .main -title "Phonebook" {
   .toolbar_border:ew
   .phonelist
}

pack .main
Lays out the GRIDPLUS elements for the root/main window and displays the window contents.


proc toolbar,add {} {

gridplus window .add -modal 1 -deletewindow add:toolbar,close
Creates a procedure called "toolbar,add" to display the "Add Record" window. Creates a toplevel modal window called ".add. Sets the "-deletewindow" procedure to "add:toolbar,close"; this will invoke the same exit procedure as will be invoked by the toolbar "Close" button, if the window is closed using window manager facilities, to allow all references to the window contents to be cleared.
gridplus set -errormessage "This field must not be blank"
label .add.errormessage -foreground red
Sets the entry validation failure error message to "This field must not be blank". Also, creates an error message label called ".add.errormessage" with "red" text (See Validations).
gridplus button .add.toolbar -style toolbar {
   {.save :filesave16 "?Save Record" !} {.close :fileclose16 "?Close"}
}

gridplus layout .add.toolbar_border -relief raised {
   .add.toolbar
} 
Creates a GRIDPLUS button grid called ".add.toolbar". Each button has an explicitly defined name, an icon and associated pop-up/balloon help.

A GRIDPLUS Layout is used to add a "raised" border to the toolbar.

gridplus entry .add.phone -size 30 {
   {"First Name"  .firstname +}
   {"Last Name"   .lastname !notnull}
   {"Phone"       .phone !notnull}
   {"Department " .department}
}
Creates a grid of GRIDPLUS entry widgets named ".add.phone". The default for entry size is set to "30" characters.

Four entry widgets are created: The "+" widget option for the "First Name" entry causes this option to be given keyboard focus when the window is created. The "Last Name" and "Phone" entries have the "!notnull" validation option (See Validations). In this case the user must complete both of these fields if the record is to be saved.

gridplus layout .add.main -title "Add Record" {
   .add.toolbar_border:ew
   .add.phone
   .add.errormessage
}

pack .add.main
Lays out the GRIDPLUS elements for the "Add Record" window and displays the window contents.


proc toolbar,delete {} {
   global {}
Creates a procedure called "toolbar,delete" to delete the selected record in the tablelist. Makes available the null named array ("global {}").
if {! [info exists (.phonelist)]} {
   tk_messageBox -icon error -title "Phonebook: Delete" -message "No record selected for delete" -type ok
   return
} else {
   set action [tk_messageBox -icon warning -title "Phonebook: Delete" -message "Delete Record: [lrange $(.phonelist) 1 2]" -type okcancel]
   if {$action eq "ok"} {
      mk::row delete db.data![lindex $(.phonelist) 0]
      refreshList
   }
}
If no record has been selected, the "(.phonelist)" element will not exist. If this is the case an appropriate message is displayed using "tk_messageBox".

If a record has been selected the user is asked to confirm the action using "tk_messageBox". If the user clicks the "OK" button the record is deleted from the database and the tablelist refreshed to update its contents.


proc toolbar,edit {} {
global {}
Creates a procedure called "toolbar,edit" to display the "Edit Record" window. Makes available the null named array ("global {}").

if {! [info exists (.phonelist)]} {
   tk_messageBox -icon error -title "Phonebook: Edit" -message "No record selected for edit" -type ok
   return
}
If no record has been selected, the "(.phonelist)" element will not exist. If this is the case an appropriate message is displayed using "tk_messageBox".

gridplus window .edit -modal 1 -deletewindow edit:toolbar,close
Creates a toplevel modal window called ".edit. Sets the "-deletewindow" procedure to "edit:toolbar,close"; this will invoke the same exit procedure as will be invoked by the toolbar "Close" button, if the window is closed using window manager facilities, to allow all references to the window contents to be cleared.

gridplus set -errormessage "This field must not be blank"
label .edit.errormessage -foreground red
ets the entry validation failure error message to "This field must not be blank". Also, creates an error message label called ".edit.errormessage" with "red" text (See Validations).

gridplus button .edit.toolbar -style toolbar {
   {.save :filesave16 "?Save Record" !} {.close :fileclose16 "?Close"}
}

gridplus layout .edit.toolbar_border -relief raised {
   .edit.toolbar
} 
Creates a GRIDPLUS button grid called ".edit.toolbar". Each button has an explicitly defined name, an icon and associated pop-up/balloon help.

A GRIDPLUS Layout is used to add a "raised" border to the toolbar.

gridplus entry .edit.phone -size 30 {
   {"First Name"  .firstname +}
   {"Last Name"   .lastname !notnull}
   {"Phone"       .phone !notnull}
   {"Department " .department}
}
Creates a grid of GRIDPLUS entry widgets named ".edit.phone". The default for entry size is set to "30" characters.

Four entry widgets are created: The "+" widget option for the "First Name" entry causes this option to be given keyboard focus when the window is created. The "Last Name" and "Phone" entries have the "!notnull" validation option (See Validations). In this case the user must complete both of these fields if the record is to be saved.

gridplus layout .edit.main -title "Edit Record" {
      .edit.toolbar_border:ew
      .edit.phone
      .edit.errormessage
   }
Lays out the GRIDPLUS elements for the "Edit Record" window.

gpmap {
   .edit.phone,firstname
   .edit.phone,lastname
   .edit.phone,phone
   .edit.phone,department
} [lrange $(.phonelist) 1 end]
Sets the ".edit.phone" entry widgets to the values of the selected Tablelist record. The first column of the Tableist contains the MetaKit database row ID; This is not used in the edit window, so "[lrange $(.phonelist) 1 end]" will return the required part of theTablelist record.

pack .edit.main
Displays the window contents.


proc phonelist {} {toolbar,edit}
Creates a procedure called "phonelist" which invokes the "toolbar,edit" procedure. This allows either the toolbar edit button -or- a double click on a line in the Tablelist to invoke the same procedure.


proc toolbar,find {} {

global {}

set list {}

Creates a procedure called "toolbar,find" to display all records which contain the find string. Makes available the null named array ("global {}"), and initialises the "list" variable.

foreach row [mk::select db.data -keyword {firstname lastname phone department} $(.find,string)] {
      lappend list "$row [mk::get db.data!$row firstname lastname phone department]"
   }
Find all records in the MetaKit database which contain "$(.find,string)". Appends "firstname lastname phone department" data to the "list" variable.

gpset .phonelist   $list
gpset .find,string {}
Sets the contents of the ".phonelist" Tablelist to the value of the "list" variable, and sets the contents of the ".find,string" entry to null.


proc toolbar,help {} {

if {! [gridplus window .help -deletewindow help:toolbar,close]} {
   return
}
Creates a procedure called "toolbar,help" to display the "Phonebook Help" window. Creates a toplevel modal window called ".help. Sets the "-deletewindow" procedure to "help:toolbar,close"; this will invoke the same exit procedure as will be invoked by the toolbar "Close" button, if the window is closed using window manager facilities, to allow all references to the window contents to be cleared. The "gridplus window" command/mode returns "0" if the window already exists, so the "if" can be used to "skip" this procedure if the help window is currently displayed.
gridplus button .help.toolbar -style toolbar {
   {.top :playstart16 "?Top"} {.previous :nav1leftarrow16 "?Previous Topic"} \
   {.next :nav1rightarrow16 "?Next Topic"} {.bottom :playend16 "?Bottom"} |  \
   {.close :fileclose16 "?Close Phonebook Help"}
}

gridplus layout .help.toolbar_border -relief raised {
   .help.toolbar
} 
Creates a GRIDPLUS button grid called ".help.toolbar". Each button has an explicitly defined name, an icon and associated pop-up/balloon help.

A GRIDPLUS Layout is used to add a "raised" border to the toolbar.

gridplus text .help.text -scroll y -tags 1 -linkcolor blue/red -linkstyle underline -height 15 -width 50
Creates a GRIDPLUS text widget named ".help.text". The "-tags 1" option enables tag processing. In this mode tags, similar in style to HTML, are interpreted, allowing various text attributes (bold, underline, italic etc.) to be set and links to text/commands to be created. The "-linkcolor blue/red" option sets the normal color of links in the text widget to "blue", which will change to "red" when the mouse pointer is over the link. The "-linkstyle underline" causes links to be underlined. This is the only style currently support for "-linkstyle" when used with the GRIDPLUS text widget.

gridplus layout .help.main -title "Phonebook Help" {
   .help.toolbar_border:ew
   .help.text
}

pack .help.main
Lays out the GRIDPLUS elements for the "Phonebook Help" window and displays the window contents.

gpset .help.text {<label top:default><font arial:default><size 8:default><bgcolor dodgerblue><color white>\
<size +10>Phonebook Help
<size +2></color><bgcolor lightgray>Topics
</bgcolor>
<link add>Adding New Records</link>
<link delete>Deleting Records</link>
<link edit>Editing Records</link>
<link find>Finding Records</link>
<link exit>Exiting Phonebook Application</link>

<label add><bgcolor lightgray>Adding New Records
</bgcolor>
Press the <image :actitemadd16> button to display the <b>Add Record</b> window.\
This window has two options:-

  <image :filesave16> Save record.

  <image :fileclose16> Close window without saving record.

The <b>Last Name</b> and <b>Phone</b> fields must contain data. An attempt to\
save the record -or- move to another field when one of these fields are empty\
will highlight the field with a red background and display: <color red>This\
field must not be blank</color>

<label delete><bgcolor lightgray>Deleting Records
</bgcolor>
Press the <image :actitemdelete16> button to delete the currently selected record.

A delete confirmation dialog is displayed: Press <b>OK</b> to delete the record\
-or- <b>Cancel</b> to abort the deletion.

<label edit><bgcolor lightgray>Editing Records
</bgcolor>
Press the <image :edit16> button to display the <b>Edit Record</b> window for the\
currently selected record. This window has two options:-

  <image :filesave16> Save record.

  <image :fileclose16> Close window without saving record.

The <b>Last Name</b> and <b>Phone</b> fields must contain data. An attempt to\
save the record -or- move to another field when one of these fields are empty\
will highlight the field with a red background and display: <color red>This\
field must not be blank</color>

<label find><bgcolor lightgray>Finding Records
</bgcolor>
Enter a search string into the <b>Find</b> field then press the <image :viewmag16>\
button to display the matching records.

The search string is matched anywhere in the record and is not case sensitive.

<label exit><bgcolor lightgray>Exiting Phonebook Application
</bgcolor>
Press the <image :actexit16> button to exit the <b>Phonebook</b> application.

<label bottom><bgcolor lightgray><b>Phonebook</b> - (c) Adrian Davis 2004
</bgcolor>}
Sets the contents of ".help.text" to the required help text. See the text and tags pages for details of how the tags work and what they mean.


proc toolbar,exit {} {

mk::file commit db
mk::file close  db

exit

}
Creates a procedure called "toolbar,exit" to commit changes, close the database and exit the application.


proc add:toolbar,save {} {
global {}
Creates a procedure called "add:toolbar,save" to save a new record from the details entred in the "Add Record" window. Makes available the null named array ("global {}").

mk::row append db.data                \
   firstname  $(.add.phone,firstname) \
   lastname   $(.add.phone,lastname)  \
   phone      $(.add.phone,phone)     \
   department $(.add.phone,department)
Appends a new record to the MetaKit database.

refreshList

add:toolbar,close
Invokes the "refreshList" procedure to update the Tablelist to show the new record. Invokes the "add:toolbar,close" to close the "Add Record" window.


proc add:toolbar,close {} {

gridplus clear .add

destroy .add

}
Creates a procedure called "add:toolbar,close" to clear all references to the contents of, and to destroy, the "Add Record" window (".add").


proc edit:toolbar,save {} {
global {}
Creates a procedure called "edit:toolbar,save" to save an edited record from the details entred in the "Edit Record" window. Makes available the null named array ("global {}").

mk::set db.data![lindex $(.phonelist) 0] \
   firstname  $(.edit.phone,firstname)   \
   lastname   $(.edit.phone,lastname)    \
   phone      $(.edit.phone,phone)       \
   department $(.edit.phone,department)
Writes the edited record to the MetaKit database.

refreshList

edit:toolbar,close
Invokes the "refreshList" procedure to update the Tablelist to show the edited record. Invokes the "edit:toolbar,close" to close the "Edit Record" window.


proc edit:toolbar,close {} {

gridplus clear .edit

destroy .edit

}
Creates a procedure called "edit:toolbar,close" to clear all references to the contents of, and to destroy, the "Edit Record" window (".edit").


proc help:toolbar,top {} {

gridplus goto .help.text top

}
Creates a procedure called "help:toolbar,top" to move the ".help.text" display to show the begining ("top" label) of the help text.


proc help:toolbar,bottom {} {

gridplus goto .help.text bottom

}
Creates a procedure called "help:toolbar,bottom" to move the ".help.text" display to show the end ("bottom" label) of the help text.


proc help:toolbar,next {} {

global {}
Creates a procedure called "help:toolbar,next" to move the ".help.text" display to show the next help text topic.
set topics  [list top add delete edit find exit bottom]
set current [lsearch $topics $(.help.text)]
Sets the value of the "current" variable to a number representing the position of the current topic in the "topics" list. The name of the last visited label is available as the value of "(.help.text)".
if {[set next [lindex $topics [expr {$current + 1}]]] ne ""} {
   gridplus goto .help.text $next
}
If not already at the last label move the ".help.text" display to show the next help text topic as defined in the topics" list.


proc help:toolbar,previous {} {

global {}
Creates a procedure called "help:toolbar,previous" to move the ".help.text" display to show the prvious help text topic.
set topics  [list top add delete edit find exit bottom]
set current [lsearch $topics $(.help.text)]
Sets the value of the "current" variable to a number representing the position of the current topic in the "topics" list. The name of the last visited label is available as the value of "(.help.text)".
if {[set previous [lindex $topics [expr {$current - 1}]]] ne ""} {
   gridplus goto .help.text $previous
}
If not already at the first label move the ".help.text" display to show the previous help text topic as defined in the topics" list.


proc help:toolbar,close {} {

gridplus clear .help

destroy .help

}
Creates a procedure called "help:toolbar,close" to clear all references to the contents of, and to destroy, the "Phonebook Help" window (".help").


proc refreshList {} {

set list {}
Creates a procedure called "refreshList" to update the contents of the ".phonelist" Tablelist, and sets the value of the "list" variable to null.

foreach row [mk::select db.data] {
   lappend list "$row [mk::get db.data!$row firstname lastname phone department]"
}
Reads all of the rows in the MetaKit database an dappned the data for each row to the "list" variable.

gpset .phonelist $list
Sets the contents of the ".phonelist" Tablelist to the value of the "list" variable.


# Require metakit package
package require Mk4tcl

# Open database
mk::file open   db phonebook.mk

# Create a "toolbar" style
gridplus style toolbar {-buttonrelief flat -borderwidth 0 -space 0 -pad 0 -takefocus 0}

# Start
mainDisplay

refreshList
Start the application. The comments in the source code for this part os the application provide a suitable description of its function.


Copyright © 2004 Adrian Davis.