## Adding some refinements to the ADDRESSBOOK.

..adding a flag to allow edits.
..adding a flag for the save function, along with a message-box, to save both edits and additions on exit.

At the present time, we can change any field in a database item, and add that item to the database, giving us a modified copy of the original, as well as the original. Wouldn't it be nice to have the original deleted automatically?

To do this we can simply add a flag to our NEW menu-item function, which would tell us if we have a new item. We can then check this flag in the SAVE function to determine if it is just an edit, and not actually a new item.
Adding a function to delete the old item from the list-box before adding the new one would complete this feature.

Since our database only changes if we add or delete an item, we can set a flag whenever we do this, and check this flag on exit, to ask the user if the changes should be saved.

-- address5.exw

    -- a simple addressbook example, part five. ( shows additions only )

    -- first add two new variables and initialize them.
    object line, line2, entry
    integer isnew, haschanged
    isnew=0  haschanged=0

    ----

    -- isnew will be set here to indicate this is NOT simply an edit.
    procedure onClick_btnNew( integer self, integer event, sequence params )
      setFocus(Sle1)
      clear_all()
      isnew=1  -- set since we have new item
    end procedure

    ----

    procedure onClick_btnAdd( integer self, integer event, sequence params )
      integer junk
      haschanged=1 -- our database has changed.
      junk=getIndex(List1)
      if isnew=0 then  -- is this an edit only?
         -- this deletes an old item so the newly edited item can be added.
         junk = deleteItem(List1, junk)
      end if
      isnew=0  -- reset the 'isnew' flag IF it was set.
      entry = getText(Sle1) & ", " & getText(Sle2) & ", " & getText(Sle3)

    ----

    procedure onClick_btnSave( integer self, integer event, sequence params )
      -- save our database to a file.
      haschanged=0 -- if we save a new entry, or an edited item.
      listlen = getCount(List1)           -- first, how many lines are in it ?

    ----

    procedure onClick_btnDel( integer self, integer event, sequence params )
      -- modified delete routine originally by Rev. Ferlin Scarborough
      integer junk
       haschanged=1 -- our database has changed.
       itemnum = getIndex(List1)

    ----

    procedure onMenu_Exit( integer self, integer event, sequence params )
      integer junk
      if haschanged=1 then
         junk = message_box("You have made changes.\n" &
                            "Would you like to save them?",
                             "Confirm Saving CHANGES!",
                             MB_ICONQUESTION + MB_YESNO + MB_TASKMODAL)
         if junk = IDYES then
            onClick_btnSave( self, event, params )
         end if
       end if
       closeWindow(MyWin)
    end procedure

----

..finally, adding the following four procedures will allow us to use the ENTER key to 'activate' the four buttons, as well as the default SPACE key.

    ----
    procedure onKey_btnNew( integer self, integer event, sequence params )
       integer key  key = params[1]
       if key=13 then onClick_btnNew( self, event, params ) else end if
    end procedure
    setHandler( btnNew, w32HKeyDown, routine_id("onKey_btnNew") )

    ----
    procedure onKey_btnAdd( integer self, integer event, sequence params )
       integer key  key = params[1]
       if key=13 then onClick_btnAdd( self, event, params ) else end if
    end procedure
    setHandler( btnAdd, w32HKeyDown, routine_id("onKey_btnAdd") )

    ----
    procedure onKey_btnSave( integer self, integer event, sequence params )
       integer key  key = params[1]
       if key=13 then onClick_btnSave( self, event, params ) else end if
    end procedure
    setHandler( btnSave, w32HKeyDown, routine_id("onKey_btnSave") )

    ----
    procedure onKey_btnDel(integer key, integer shift)
       integer key  key = params[1]
       if key=13 then onClick_btnDel( self, event, params ) else end if
    end procedure
    setHandler( btnDel, w32HKeyDown, routine_id("onKey_btnDel") )

    ----

I've also included a slightly different version of address5.exw, called address6.exw, which also has a few new features and a 'new' look ;-) You'll have to select this program manually in the OPEN dialog window to run it !

You'll have to search for any new code changes in the source of address6.exw yourself, but I hope you like the new 'look' .

There are however, two new features worth mentioning. By adding a whole new group of onKeyPress[] event handlers to the program, one can now enter a series of new entries using nothing but the ENTER key !

This is done by adding:

    -- 'speedy' entry section
    procedure onKey_Sle1( integer self, integer event, sequence params )
     integer key   key = params[1]
     if key=13 then setFocus(Sle2) else end if
    end procedure
    setHandler( Sle1, w32HKeyDown, routine_id("onKey_Sle1") )

    procedure onKey_Sle2( integer self, integer event, sequence params )
     integer key   key = params[1]
     if key=13 then setFocus(Sle3) else end if
    end procedure
    setHandler( Sle2, w32HKeyDown, routine_id("onKey_Sle2") )

    procedure onKey_Sle3( integer self, integer event, sequence params )
     integer key   key = params[1]
     if key=13 then setFocus(Sle4) else end if
    end procedure
    setHandler( Sle3, w32HKeyDown, routine_id("onKey_Sle3") )

    -- ** and so on to:

    procedure onKey_Sle8( integer self, integer event, sequence params )
      integer key   key = params[1]
      if key=13 then setFocus(btnAdd) else end if
    end procedure
    setHandler( Sle8, w32HKeyDown, routine_id("onKey_Sle8") )

    -- ** with a little change to:

    procedure onKey_btnAdd( integer self, integer event, sequence params )
        integer key  key = params[1]
       if key=13 then
           onClick_btnAdd( self, event params )
           setFocus(btnNew) -- added this line
        else end if
    end procedure
    setHandler( btnAdd, w32HKeyDown, routine_id("onKey_btnAdd") )

    --

I have also added an onDestroy[] event handler to the program so that if you made any changes to the database, and try to [X] out of the program, it will STILL ask you if you want to save those changes.

    procedure onDestroy_MyWin( integer self, integer event, sequence params )
      if haschanged = 1 then
         junk = message_box("You have made changes.\n" &
                                 "Would you like to save them?",
                                 "ADDRESSBOOK6 data CHANGED !",
                                  MB_ICONWARNING + MB_YESNO + MB_TASKMODAL)
         if junk = IDYES then
              onClick_btnSave( self, event, params )
         end if
      end if
    end procedure
    setHandler( MyWin, w32HDestroy, routine_id("onDestroy_MyWin") )

This, of course, required adding one line to onMenu_Exit() so we don't run this procedure if we exit the program normally.

      end if
      haschanged=0
      closeWindow(MyWin)
    end procedure

One final note:
In the actual program example, I have removed the reference to integer junk in three procedures, declaring it at the top of the program only once, and re-used it in onChange_List1(), getting rid of the integer what declaration.

    ..and thanks to Mike Fowler, here are some 'secret' codes for the last
    parameter in sle's.

    -- Mikes WIN32LIB additions

       ( ...now included in win32lib.ew as global constants )

        ES_LOWERCASE    = 16     -- convert text to lowercase
        ES_UPPERCASE    = 8      -- convert text to uppercase
        ES_NOHISESEL    = 256    -- show selection, even when not active
        ES_NUMBER       = #2000  -- only allow numbers
        ES_OEMCONVERT   = #400   -- something... ;)
        ES_PASSWORD     = 32     -- displays * instead of chars
        ES_READONLY     = #800   -- user can't type into here...
        ES_WANTRETURN   = 4096   -- adds a \n to the returned text

    So, if you wanted the ZIP code entry sle to be filled with only upper-case
    characters, for example, you would code:

      Sle7    = create(EditText, "", MyWin, 80, 240, 80, 20, 8 )
    -- or just:
      Sle7    = create(EditText, "", MyWin, 80, 240, 80, 20, ES_UPPERCASE )

..end of lesson.

CONTENTS