diff --git a/addbook.rex b/addbook.rex index d8acd1d..db73b66 100755 --- a/addbook.rex +++ b/addbook.rex @@ -31,7 +31,7 @@ Exit ::METHOD Init expose ui db db = .AddressBookDB~new() - ui = .AddressBookUI~new() + ui = .AddressBookUI~new(db) return ::method run diff --git a/app/appui.cls b/app/appui.cls index 4e8ac0e..c665328 100644 --- a/app/appui.cls +++ b/app/appui.cls @@ -6,11 +6,12 @@ ::class AddressBookUI public ::method init - expose win mainMenu + expose win mainMenu db + use arg db return ::method initialize - expose win mainMenu + expose win mainMenu db win = self~DrawMainPanel(0, .true) /* default colour, draw border box */ self~setupMainMenu(win) @@ -124,6 +125,200 @@ menuwin~refresh return + ::method addContactPanel + expose win db menuwin menu_items + + /* Create a form panel */ + max_y = win~lines + max_x = win~cols + form_height = 14 + form_width = 50 + 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, 0, "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(6, 2, "Email: ") + 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 return /* User canceled */ + + lastName = self~getInputField(formwin, 4, 14, 30) + if lastName = .nil then return + + phone = self~getInputField(formwin, 5, 14, 15) + if phone = .nil then return + + email = self~getInputField(formwin, 6, 14, 30) + if email = .nil then return + + /* Add to database */ + contactDict = .Directory~new() + contactDict["FIRST_NAME"] = firstName + contactDict["LAST_NAME"] = lastName + contactDict["PHONE"] = phone + contactDict["EMAIL"] = email + result = db~addContact(contactDict) + + /* Display result message */ + if result > 0 then do + formwin~mvaddstr(8, 2, "Contact ID ["result"] added successfully!") + end + else do + formwin~mvaddstr(8, 2, "Failed to add contact.") + end + + formwin~refresh() + call SysWait 1.5 + formwin~erase() + formwin~refresh() + + /* Redraw the main menu */ + + self~setupMainMenu(win) + + return + + ::method listAllContactsPanel + expose win db menuwin + + /* Create a list panel */ + max_y = win~lines + max_x = win~cols + list_height = 20 + list_width = 70 + 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, 0, "All Contacts", .true) + + /* Display column headers */ + listwin~attron(listwin~A_BOLD) + listwin~mvaddstr(3, 2, "ID") + listwin~mvaddstr(3, 6, "First Name") + listwin~mvaddstr(3, 22, "Last Name") + listwin~mvaddstr(4, 2, "-- ---------- ---------") + /* listwin~mvaddstr(2, 38, "Phone") + listwin~mvaddstr(2, 54, "Email") */ + listwin~attroff(listwin~A_BOLD) + + /* Get all contacts */ + contacts = db~getAllContacts() + + /* Display contacts */ + if contacts~items > 0 then do + do i = 1 to contacts~items + contact = contacts[i] + listwin~mvaddstr(i+4, 2, contact['ID']) + listwin~mvaddstr(i+4, 6, contact['FIRST_NAME']) + listwin~mvaddstr(i+4, 22, contact['LAST_NAME']) + /* listwin~mvaddstr(i+3, 38, contact['phone']) + listwin~mvaddstr(i+3, 54, contact['email']) */ + + /* Break if we run out of screen space */ + if i > list_height-6 then leave + end + end + else do + listwin~mvaddstr(5, 5, "No contacts found.") + end + + listwin~mvaddstr(list_height-2, 2, "Press any key to return to main menu") + listwin~refresh() + + /* Wait for any key */ + listwin~getch() + + listwin~erase() + listwin~refresh() + + /* Redraw the main menu */ + win~refresh + self~setupMainMenu(win) + return + + ::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, 3, "Search Contacts", .true) + + searchwin~mvaddstr(3, 2, "Search term: ") + searchwin~refresh() + + /* Get search term */ + term = self~getInputField(searchwin, 3, 14, 30) + + /* If canceled, return to main menu */ + if term = .nil then do + searchwin~erase() + searchwin~refresh() + self~DrawMenu(menuwin, menu_items, .environment~selected, win) + menuwin~refresh() + return + end + + /* Perform search */ + searchwin~erase() + searchwin~refresh() + + /* Display results in a new window */ + self~displaySearchResults(term) + return + + ::method getInputField + use arg win, y, x, maxlen + + win~move(y, x) + win~curs_set(1) /* Show cursor */ + win~keypad(1) /* Enable function keys and arrow keys */ + win~echo() /* Show typed characters */ + win~raw + + buffer = "" + + do forever + key = win~getch() + 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 key = D2C(8) | key = 127 then do /* Backspace */ + if buffer~length > 0 then do + buffer = buffer~left(buffer~length - 1) + win~move(y, x) + win~addstr(buffer || " ") /* Erase the last character */ + 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 @@ -187,6 +382,7 @@ menuwin~mvaddstr(19 - 3, 5, "I would launch the ADD panel "); menuwin~refresh call SysWait 0.25 + self~addContactPanel() END when key_char = 'r' then do menuwin~mvaddstr(19 - 3, 5, "I would launch the REMOVE panel "); @@ -202,11 +398,13 @@ menuwin~mvaddstr(19 - 3, 5, "I would launch the SEARCH panel "); menuwin~refresh call SysWait 0.25 + self~searchContactPanel() END when key_char = 'l' then do menuwin~mvaddstr(19 - 3, 5, "I would launch the LIST panel ") menuwin~refresh call SysWait 0.25 + self~listAllContactsPanel() END when key_char = 'q' then do menuwin~mvaddstr(19 - 3, 5, "Exiting the application... ") diff --git a/db/contacts.sqlite b/db/contacts.sqlite index 5fad5a9..f4c03bd 100644 Binary files a/db/contacts.sqlite and b/db/contacts.sqlite differ