rexx-address-book/app/appui.cls

904 lines
31 KiB
OpenEdge ABL

::requires 'ooSQLite.cls'
::requires "rxunixsys" LIBRARY
::requires 'ncurses.cls'
::requires 'app/utils.rex'
::class AddressBookUI public
::method init
expose win mainMenu db
use arg db
return
::method initialize
expose win mainMenu db
win = self~DrawMainPanel(0, .false) /* default colour, no main border */
self~setupMainMenu(win)
return
::METHOD DrawMainPanel
use arg clrset, with_box
win = .window~new() /* The first invocation must be with no arguments */
win~curs_set(0) /* Hide the cursor by default */
win~keypad(1) /* Enable function keys and arrow keys */
win~raw
win~noecho
win~clear
win~cbreak
self~SetPanelColor(win, clrset)
if with_box = .true then DO
win~box(0, 0) /* Draw box with default ACS characters */
win~refresh
END
return win
::METHOD DrawSubPanel
use arg height, width, starty, startx, clrset, title, with_box
new_win = .window~new(height, width, starty, startx)
new_win~curs_set(0)
/* Set the panel color */
self~SetPanelColor(new_win, clrset)
/* Display title */
new_win~attron(new_win~A_BOLD)
new_win~mvaddstr(starty-(starty-2), (width - title~length) % 2, title)
new_win~attroff(new_win~A_BOLD)
new_win~refresh
if with_box = .true then DO
new_win~box(0,0)
new_win~refresh
END
return new_win
::METHOD SetPanelColor
use arg panel, clrset
panel~start_color()
SELECT
/* white text on blue background */
when clrset = 1 then panel~init_pair(2, panel~COLOR_WHITE, panel~COLOR_BLUE)
/* white text on grey background */
when clrset = 2 then panel~init_pair(3, panel~COLOR_WHITE, panel~COLOR_GREEN)
/* yellow text on red background */
when clrset = 3 then panel~init_pair(4, panel~COLOR_YELLOW, panel~COLOR_RED)
/* black text on white background */
when clrset = 4 then panel~init_pair(5, panel~COLOR_BLACK, panel~COLOR_WHITE)
/* black text on green background */
when clrset = 5 then panel~init_pair(6, panel~COLOR_BLACK, panel~COLOR_GREEN)
/* black text on cyan background */
when clrset = 6 then panel~init_pair(7, panel~COLOR_BLACK, panel~COLOR_CYAN)
/* Yellow text on blue background */
when clrset = 7 then panel~init_pair(8, panel~COLOR_YELLOW, panel~COLOR_BLUE)
/* Cyan text on black background */
when clrset = 8 then panel~init_pair(9, panel~COLOR_CYAN, panel~COLOR_BLACK)
/* blacken everything to give the appearance of disappearance */
when clrset = 9 then panel~init_pair(10, panel~COLOR_BLACK, panel~COLOR_BLACK)
/* red on black */
when clrset = 10 then panel~init_pair(11, panel~COLOR_RED, panel~COLOR_BLACK)
/* yellow on black */
when clrset = 11 then panel~init_pair(12, panel~COLOR_YELLOW, panel~COLOR_BLACK)
/* green on black */
when clrset = 12 then panel~init_pair(13, panel~COLOR_GREEN, panel~COLOR_BLACK)
/* Default to white text on black background */
OTHERWISE DO
clrset=0
panel~init_pair(1, panel~COLOR_WHITE, panel~COLOR_BLACK)
END
END
panel~bkgd(panel~color_pair(clrset+1))
panel~refresh
RETURN
/***********************
* SETUP MAIN MENU *
***********************/
::method setupMainMenu
expose mainMenu menuwin menu_items menu_keys selected
use arg win
max_y = win~lines
max_x = win~cols
menu_height = 16
menu_width = 30
start_y = (max_y - menu_height) % 2
start_x = (max_x - menu_width) % 2
clrset=1
title = "Rexx Address Book"
with_box = .true
menuwin = self~DrawSubPanel(menu_height, menu_width, start_y, start_x, clrset, title, with_box)
menu_items = .array~of("[V]iew Contact", "[A]dd Contact", "[D]elete Contact", "[E]dit Contact", "[S]earch", "[L]ist All", "[Q]uit")
menu_keys = .array~of("v", "a", "d", "e", "s", "l", "q")
.environment~selected = 1
self~DrawMenu(menuwin, menu_items, .environment~selected, win)
menuwin~refresh
RETURN
/***********************
* DRAW MENU *
***********************/
::method DrawMenu
expose win menu_items menu_keys selected mainwin
use arg menuwin, items, selected, mainwin
do i = 1 to items~items
if i = .environment~selected then do
menuwin~attron(menuwin~attron(menuwin~A_REVERSE))
menuwin~attron(menuwin~A_BOLD)
menuwin~mvaddstr(i+3, 2, items[i])
menuwin~attroff(menuwin~A_REVERSE)
menuwin~attroff(menuwin~A_BOLD)
end
else do
menuwin~mvaddstr(i+3, 2, items[i])
end
end
menuwin~refresh
return
/***********************
* DROP WINDOW *
***********************/
::method dropWindow
expose win menuwin
use arg window
self~SetPanelColor(window, 9)
window~erase()
window~delwin()
win~refresh
self~setupMainMenu(win)
menuwin~refresh()
RETURN
/************************************* ADD CONTACT **************************************/
/**********************
* Add new contact *
**********************/
::method addContactPanel
expose win db menuwin formwin
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 15
form_width = 60
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
formwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 12, "Add New Contact", .true)
/* Create form fields */
formwin~mvaddstr(3, 2, "First Name: ")
formwin~mvaddstr(4, 2, "Last Name: ")
formwin~mvaddstr(5, 2, "Phone: "); formwin~mvaddstr(5, 42, "Type: ");
formwin~mvaddstr(6, 2, "Email: "); formwin~mvaddstr(6, 42, "Type: ");
formwin~mvaddstr(7, 2, "Street: ")
formwin~mvaddstr(8, 2, "City: "); formwin~mvaddstr(8, 28, "State: "); formwin~mvaddstr(8, 40, "PostCode: ")
formwin~mvaddstr(9, 2, "Country: ")
formwin~mvaddstr(form_height-2, 2, "[Enter] to save, [Esc] to cancel")
formwin~refresh()
/* Input fields */
firstName = self~getInputField(formwin, 3, 14, 30, '')
if firstName = .nil then do
self~dropWindow(formwin)
RETURN
END
lastName = self~getInputField(formwin, 4, 14, 30, '')
if lastName = .nil then do
self~dropWindow(formwin)
RETURN
END
phone = self~getInputField(formwin, 5, 10, 15, '')
if phone = .nil then do
self~dropWindow(formwin)
RETURN
END
phone_type = self~getInputField(formwin, 5, 48, 15, '')
if phone_type = .nil then do
self~dropWindow(formwin)
RETURN
END
email = self~getInputField(formwin, 6, 10, 30, '')
if email = .nil then do
self~dropWindow(formwin)
RETURN
END
email_type = self~getInputField(formwin, 6, 48, 15, '')
if email_type = .nil then do
self~dropWindow(formwin)
RETURN
END
street = self~getInputField(formwin, 7, 10, 25, '')
if street = .nil then do
self~dropWindow(formwin)
RETURN
END
city = self~getInputField(formwin, 8, 10, 15, '')
if city = .nil then do
self~dropWindow(formwin)
RETURN
END
state = self~getInputField(formwin, 8, 35, 2, '')
if state = .nil then do
self~dropWindow(formwin)
RETURN
END
postCode = self~getInputField(formwin, 8, 50, 10, '')
if postCode = .nil then do
self~dropWindow(formwin)
RETURN
END
country = self~getInputField(formwin, 9, 10, 15, '')
if country = .nil then do
self~dropWindow(formwin)
RETURN
END
if firstname = "" | lastname = "" then do
formwin~mvaddstr(8, 2, "First and Last names are required.")
formwin~refresh()
call SysWait 0.5
END /* don't add contact */
else DO
/* Add to database */
contactDict = .Directory~new()
contactDict["FIRST_NAME"] = firstName
contactDict["LAST_NAME"] = lastName
contactDict["PHONE_NUMBER"] = phone
contactDict["PHONE_TYPE"] = phone_type
contactDict["EMAIL_ADDRESS"] = email
contactDict["EMAIL_TYPE"] = email_type
contactDict["STREET"] = street
contactDict["CITY"] = city
contactDict["STATE"] = state
contactDict["POSTCODE"] = postCode
contactDict["COUNTRY"] = country
result = db~addContact(contactDict)
/* Display result message */
if result > 0 then do /* should be a result id number */
formwin~mvaddstr(10, 2, "Contact ID ["result"] added successfully!")
formwin~refresh()
call SysWait 0.5
end
else do
formwin~mvaddstr(10, 2, "Failed to add contact.")
formwin~refresh()
call SysWait 0.5
end
end /* add contact */
self~dropWindow(formwin)
RETURN
/************************************* EDIT CONTACT **************************************/
/*****************************
* Edit Contact Select Panel *
*****************************/
::METHOD editContactSelectPanel
expose win db menuwin ewin
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 12
form_width = 35
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
ewin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 11, "Select A Contact To Edit", .true)
ewin~mvaddstr(4, 2, "Contact ID: ")
ewin~mvaddstr(form_height-1, 2, "[Enter] to edit, [Esc] to cancel")
ewin~refresh()
contactId = self~getInputField(ewin, 4, 14, 10, '')
if contactId = .nil then do
self~dropWindow(ewin)
RETURN
END
result = db~getContact(contactId)
if result = .nil then do /* should be a result id number */
ewin~mvaddstr(8, 2, "Contact not found.")
ewin~refresh()
call SysWait 0.5
self~dropWindow(ewin)
RETURN
end
/* launch a view panel with full contact details */
self~dropWindow(ewin)
self~editContactDetailsPanel(contactId)
RETURN
/*************************
* Edit Existing Contact *
*************************/
::METHOD editContactDetailsPanel
expose win db menuwin editwin
use arg contactId
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 15
form_width = 60
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
editwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 11, "Edit Contact Details", .true)
/* Create form fields */
editwin~mvaddstr(3, 2, "First Name: ")
editwin~mvaddstr(4, 2, "Last Name: ")
editwin~mvaddstr(5, 2, "Phone: "); editwin~mvaddstr(5, 42, "Type: ");
editwin~mvaddstr(6, 2, "Email: "); editwin~mvaddstr(6, 42, "Type: ");
editwin~mvaddstr(7, 2, "Street: ")
editwin~mvaddstr(8, 2, "City: "); editwin~mvaddstr(8, 28, "State: "); editwin~mvaddstr(8, 40, "PostCode: ")
editwin~mvaddstr(9, 2, "Country: ")
editwin~mvaddstr(form_height-1, 2, "[Enter] to save, [Esc] to cancel")
editwin~refresh()
/* Get existing details */
contactDetails = db~getContactDetails(contactId)
editwin~mvaddstr(3, 14, contactDetails~first_name);
editwin~mvaddstr(4, 14, contactDetails~last_name);
editwin~mvaddstr(5, 10, contactDetails~phone_number);
editwin~mvaddstr(5, 48, contactDetails~phone_type);
editwin~mvaddstr(6, 10, contactDetails~email_address);
editwin~mvaddstr(6, 48, contactDetails~email_type);
editwin~mvaddstr(7, 10, contactDetails~street);
editwin~mvaddstr(8, 10, contactDetails~city);
editwin~mvaddstr(8, 35, contactDetails~state);
editwin~mvaddstr(8, 50, contactDetails~postal_code);
editwin~mvaddstr(9, 10, contactDetails~country);
/* Prepopulate the input fields */
firstNameInit = contactDetails~first_name
lastNameInit = contactDetails~last_name
phoneInit = contactDetails~phone_number
phone_typeInit = contactDetails~phone_type
emailInit = contactDetails~email_address
email_typeInit = contactDetails~email_type
streetInit = contactDetails~street
cityInit = contactDetails~city
stateInit = contactDetails~state
postCodeInit = contactDetails~postal_code
countryInit = contactDetails~country
/* Input fields */
firstName = self~getInputField(editwin, 3, 14, 30, firstNameInit)
if firstName = .nil then do
self~dropWindow(editwin)
RETURN
END
lastName = self~getInputField(editwin, 4, 14, 30, lastNameInit)
if lastName = .nil then do
self~dropWindow(editwin)
RETURN
END
phone = self~getInputField(editwin, 5, 10, 15, phoneInit)
if phone = .nil then do
self~dropWindow(editwin)
RETURN
END
phone_type = self~getInputField(editwin, 5, 48, 15, phone_typeInit)
if phone_type = .nil then do
self~dropWindow(editwin)
RETURN
END
email = self~getInputField(editwin, 6, 10, 30, emailInit)
if email = .nil then do
self~dropWindow(editwin)
RETURN
END
email_type = self~getInputField(editwin, 6, 48, 15, email_typeInit)
if email_type = .nil then do
self~dropWindow(editwin)
RETURN
END
street = self~getInputField(editwin, 7, 10, 30, streetInit)
if street = .nil then do
self~dropWindow(editwin)
RETURN
END
city = self~getInputField(editwin, 8, 10, 15, cityInit)
if city = .nil then do
self~dropWindow(editwin)
RETURN
END
state = self~getInputField(editwin, 8, 35, 2, stateInit)
if state = .nil then do
self~dropWindow(editwin)
RETURN
END
postCode = self~getInputField(editwin, 8, 50, 10, postCodeInit)
if postCode = .nil then do
self~dropWindow(editwin)
RETURN
END
country = self~getInputField(editwin, 9, 10, 15, countryInit)
if country = .nil then do
self~dropWindow(editwin)
RETURN
END
/* Add to database */
contactDict = .Directory~new()
contactDict["FIRST_NAME"] = firstName
contactDict["LAST_NAME"] = lastName
contactDict["PHONE_NUMBER"] = phone
contactDict["PHONE_TYPE"] = phone_type
contactDict["EMAIL_ADDRESS"] = email
contactDict["EMAIL_TYPE"] = email_type
contactDict["STREET"] = street
contactDict["CITY"] = city
contactDict["STATE"] = state
contactDict["POSTCODE"] = postCode
contactDict["COUNTRY"] = country
result = db~updateContact(contactId, contactDict)
/* Display result message */
if result = 0 then do /* should be a result id number */
editwin~mvaddstr(11, 2, "Contact ID ["result"] edited successfully!")
editwin~refresh()
call SysWait 1.5
end
else do
editwin~mvaddstr(11, 2, "Failed to edit contact.")
editwin~refresh()
call SysWait 1.5
end
self~dropWindow(editwin)
RETURN
/************************************* DELETE CONTACT **************************************/
/****************************
* Delete Contact Panel *
****************************/
::METHOD deleteContactPanel
expose win db menuwin delwin
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 12
form_width = 35
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
delwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 10, "Delete A Contact", .true)
delwin~mvaddstr(4, 2, "Contact ID: ")
delwin~mvaddstr(form_height-1, 2, "[Enter] to del, [Esc] to cancel")
delwin~refresh()
contactId = self~getInputField(delwin, 4, 14, 10, '')
if contactId = .nil then do
self~dropWindow(delwin)
RETURN
END
result = db~deleteContact(contactId)
if result = 0 then do /* should be a result id number */
delwin~mvaddstr(8, 2, "Contact deleted successfully!")
delwin~refresh()
call SysWait 0.5
end
else do
delwin~mvaddstr(8, 2, "Failed to add contact.")
delwin~refresh()
call SysWait 0.5
end
self~dropWindow(delwin)
RETURN
/************************************* VIEW CONTACT **************************************/
/********************************
* View Contact Selection Panel *
********************************/
::METHOD viewContactSelectPanel
expose win db menuwin viewselectwin
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 12
form_width = 35
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
viewselectwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 8, "View A Contact", .true)
viewselectwin~mvaddstr(4, 2, "Contact ID: ")
viewselectwin~mvaddstr(form_height-1, 2, "[Enter] to sel., [Esc] to cancel")
viewselectwin~refresh()
contactId = self~getInputField(viewselectwin, 4, 14, 10, '')
if contactId = .nil then do
self~dropWindow(viewselectwin)
RETURN
END
result = db~getContact(contactId)
if result = .nil then do /* should be a result id number */
viewselectwin~mvaddstr(8, 2, "Contact not found.")
viewselectwin~refresh()
call SysWait 0.5
self~dropWindow(viewselectwin)
RETURN
end
/* launch a view panel with full contact details */
self~dropWindow(viewselectwin)
self~viewContactDetailPanel(contactId)
RETURN
/************************
* View Contact Details *
************************/
::METHOD viewContactDetailPanel
expose win db menuwin detailwin viewselectwin
use arg contactID
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 14
form_width = 40
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
detailwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 1, "View Contact Details", .true)
contactDetails = db~getContactDetails(contactId)
/* Detail fields */
detailwin~mvaddstr(4, 3, contactDetails~first_name);
detailwin~mvaddstr(4, LENGTH(contactDetails~first_name)+1+3, contactDetails~last_name);
detailwin~mvaddstr(5, 3, contactDetails~street)
detailwin~mvaddstr(6, 3, contactDetails~city);
detailwin~mvaddstr(6, LENGTH(contactDetails~city)+4, contactDetails~state);
detailwin~mvaddstr(6, LENGTH(contactDetails~city)+LENGTH(contactDetails~state)+5, contactDetails~postal_code);
detailwin~mvaddstr(6, LENGTH(contactDetails~city)+LENGTH(contactDetails~state)+LENGTH(contactDetails~postal_code)+6, contactDetails~country)
detailwin~mvaddstr(7, 3, contactDetails~email_address)
detailwin~mvaddstr(8, 3, contactDetails~phone_number)
detailwin~mvaddstr(form_height-1, 2, "[Esc] to cancel")
detailwin~refresh()
detailwin~getch()
self~dropWindow(detailwin)
RETURN
RETURN
/************************************* VIEW ALL CONTACTS **********************************/
/****************************
* List all contacts *
****************************/
::METHOD listAllContactsPanel
expose win db menuwin
/* Create a list panel */
max_y = win~lines
max_x = win~cols
list_height = max_y - 10
list_width = max_x - 18
start_y = (max_y - list_height) % 2
start_x = (max_x - list_width) % 2
listwin = self~DrawSubPanel(list_height, list_width, start_y, start_x, 1, "All Contacts", .true)
listwin~scrollok(.true)
listwin~Setscrreg(4,18)
/* Display column headers */
listwin~attron(listwin~A_BOLD)
listwin~mvaddstr(4, 2, "ID")
listwin~mvaddstr(4, 7, "First Name")
listwin~mvaddstr(4, 21, "Last Name")
listwin~mvaddstr(4, 36, "Phone")
listwin~mvaddstr(4, 52, "Email")
listwin~mvaddstr(5, 2, "---- ---------- ------------ --------------- -------------------------")
listwin~attroff(listwin~A_BOLD)
contacts = db~getAllContacts()
/* Display contacts */
if contacts~items > 0 then do
do i = 1 to contacts~items
contact = contacts[i]
listwin~mvaddstr(i+5, 2, contact['ID'])
listwin~mvaddstr(i+5, 7, contact['FIRST_NAME'])
listwin~mvaddstr(i+5, 21, contact['LAST_NAME'])
listwin~mvaddstr(i+5, 36, contact['PHONE_NUMBER'])
listwin~mvaddstr(i+5, 52, contact['EMAIL_ADDRESS'])
/* Break if we run out of screen space */
if i > list_height-7 then LEAVE
end
end
else do
listwin~mvaddstr(6, 5, "No contacts found.")
end
listwin~getch()
self~dropWindow(listwin)
RETURN
Return
/************************************* SEARCH ALL CONTACTS ***********************************/
/****************************
* Search for contact *
****************************/
::METHOD searchContactPanel
expose win db menuwin menu_items
/* Create a search panel */
max_y = win~lines
max_x = win~cols
search_height = 6
search_width = 50
start_y = (max_y - search_height) % 2
start_x = (max_x - search_width) % 2
searchwin = self~DrawSubPanel(search_height, search_width, start_y, start_x, 7, "Search Contacts (First, Last)", .true)
searchwin~mvaddstr(3, 2, "Search term: ")
searchwin~refresh()
/* Get search term */
term = self~getInputField(searchwin, 3, 15, 30, '')
/* If canceled, return to main menu */
if term = .nil then do
self~DropWindow(searchwin)
return
end
/* Perform search */
searchwin~erase()
searchwin~refresh()
/* Display results in a new window */
self~displaySearchResults(term)
self~dropWindow(searchwin)
return
/**************************
* DISPLAY SEARCH RESULTS *
**************************/
::METHOD displaySearchResults
expose win menuwin db
use arg term
/* Create a list panel */
max_y = win~lines
max_x = win~cols
list_height = max_y - 15
list_width = max_x - 18
start_y = (max_y - list_height) % 2
start_x = (max_x - list_width) % 2
searchoutwin = self~DrawSubPanel(list_height, list_width, start_y, start_x, 1, "Search Results", .true)
/* searchoutwin~scrollok(.true)
searchoutwin~Setscrreg(4,18) */
/* Display column headers */
searchoutwin~attron(searchoutwin~A_BOLD)
searchoutwin~mvaddstr(4, 2, "ID")
searchoutwin~mvaddstr(4, 7, "First Name")
searchoutwin~mvaddstr(4, 21, "Last Name")
searchoutwin~mvaddstr(4, 36, "Phone")
searchoutwin~mvaddstr(4, 52, "Email")
searchoutwin~mvaddstr(5, 2, "---- ---------- ------------ --------------- -------------------------")
searchoutwin~attroff(searchoutwin~A_BOLD)
contacts = db~searchContacts(term)
/* Display contacts */
if contacts~items > 0 then do
do i = 1 to contacts~items
contact = contacts[i]
searchoutwin~mvaddstr(i+5, 2, contact['ID'])
searchoutwin~mvaddstr(i+5, 7, contact['FIRST_NAME'])
searchoutwin~mvaddstr(i+5, 21, contact['LAST_NAME'])
searchoutwin~mvaddstr(i+5, 36, contact['PHONE_NUMBER'])
searchoutwin~mvaddstr(i+5, 52, contact['EMAIL_ADDRESS'])
/* Break if we run out of screen space */
if i > list_height-7 then LEAVE
end
end
else do
searchoutwin~mvaddstr(6, 5, "No contacts found.")
end
searchoutwin~getch()
self~dropWindow(searchoutwin)
RETURN
/************************************* UTILITIY METHODS **************************************/
/************************
* Get Input From Field *
************************/
::method getInputField
use arg win, y, x, maxlen, bufferContent
win~curs_set(1) /* Show cursor */
win~keypad(1) /* Enable function keys and arrow keys */
win~echo() /* Show typed characters */
win~raw
if LENGTH(bufferContent) > 0 then DO
buffer = bufferContent
win~move(y, x + buffer~length)
END
Else DO
buffer = ""
win~move(y, x)
END
blank_line = copies(" ", maxlen) /* String of spaces for clearing the line */
do forever
key = win~getch()
decimalKey = C2D(key)
select
when key = D2C(27) then do /* ESC key */
win~curs_set(0) /* Hide cursor */
win~noecho() /* Stop showing typed characters */
return .nil /* Return nil to indicate cancellation */
end
when key = D2C(10) | key = D2C(13) then do /* Enter key */
win~curs_set(0) /* Hide cursor */
win~noecho() /* Stop showing typed characters */
return buffer /* Return the entered text */
end
when decimalKey = 3290675 then do
/* when key = D2C(8) | key = D2C(26) | key = D2C(127) */
/* I don't know why the standard ASCII codes don't work! */
if buffer~length > 0 then do
buffer = buffer~left(buffer~length - 1)
win~move(y, x)
win~addstr(buffer || " ")
win~move(y, x + buffer~length)
end
end
otherwise do
if buffer~length < maxlen then do
ch = key
buffer = buffer || ch
end
end
end
end
return buffer
/***************/
/** MAIN LOOP **/
/***************/
::method mainLoop
expose win mainMenu menuwin selected menu_items menu_keys
menuwin~refresh
running = .true
do while running
key = win~getch
old_selected = .environment~selected
select
when key = menuwin~KEY_UP then do
if .environment~selected > 1 then .environment~selected = .environment~selected - 1
self~DrawMenu(menuwin, menu_items, .environment~selected, win)
menuwin~refresh
end
when key = menuwin~KEY_DOWN then do
if .environment~selected < menu_items~items then .environment~selected = .environment~selected + 1
self~DrawMenu(menuwin, menu_items, .environment~selected, win)
menuwin~refresh
end
when key = D2C(81) | key = D2C(113) then do /* Q for quit */
.environment~selected = self~findInArray(menu_keys, key)
self~ProcessSelection(menuwin, menu_keys[.environment~selected])
RETURN
END
when key = D2C(10) | key = D2C(13) then do /* Enter key - numeric codes only */
menuwin~mvaddstr(19 - 1, 18, "Letter selection ["||menu_keys[.environment~selected]||"]")
menuwin~refresh
self~ProcessSelection(menuwin, menu_keys[.environment~selected])
return
end
otherwise do
key = lower(key)
poz = self~findInArray(menu_keys, key)
if poz > 0 then do
.environment~selected = poz
self~DrawMenu(menuwin, menu_items, .environment~selected, win)
menuwin~mvaddstr(19 - 1, 18, "Letter selection ["||key||"]")
menuwin~refresh
self~ProcessSelection(menuwin, key)
end /* if pos > 0 */
end /* otherwise */
end /* select */
/* Only redraw if selection changed */
if old_selected \= .environment~selected then do
self~DrawMenu(menuwin, menu_items, .environment~selected, win)
end
end /* do while running */
return
/***********************
* PROCESS SELECTION *
***********************/
::METHOD ProcessSelection
expose menu_items menu_keys
use arg menuwin, key_char
select
when key_char = 'a' then do
self~addContactPanel()
END
when key_char = 'd' then do
self~deleteContactPanel()
END
when key_char = 'e' then do
self~editContactSelectPanel()
END
when key_char = 's' then do
self~searchContactPanel()
END
when key_char = 'l' then do
self~listAllContactsPanel()
END
when key_char = 'v' then do
self~viewContactSelectPanel()
END
when key_char = 'q' then do
menuwin~mvaddstr(19 - 3, 5, "Exiting the application... ")
menuwin~refresh
menuwin~endwin
.environment['STOPNOW'] = 1
END
otherwise nop
end
return
::METHOD findInArray
use arg array, item
do i = 1 to array~items
if array[i] = item then return i
end
return 0 /* Not found */
::METHOD cleanup
expose win menuwin
/* Clean up ncurses */
menuwin~endwin
win~endwin
exit 0
return