This chapter looks at ways to modify the contents of contacts stored in the address book application.
You now have an address book that not only holds contacts in an organized manner, but also allows navigation. It would be convenient to include edit and remove functions so that a contact's details can be changed when needed. However, this requires a little improvement, in the form of enums.
In our previous chapters, you had two modes: AddingMode and NavigationMode - but they were not defined as enums. Instead, you enabled and disabled the corresponding buttons manually, resulting in multiple lines of repeated code.
In this chapter, define the Mode enum with three different values:
To edit and remove contacts, you need two push buttons. Drag them and name them accordingly. Their objectName properties should be editButton and removeButton, respectively. The quickest way to place these two buttons into our existing layout, is to simply drag and drop them. Use the screenshot below as a guide:
Update the header file to contain the Mode enum:
Also add two new slots, editContact() and removeContact(), to your current list of public slots.
In order to switch between modes, introduce the updateInterface() function to control the enabling and disabling of all push buttons.
Lastly, declare currentMode to keep track of the enum's current mode.
Let's begin by implementing the mode-changing features of the address book application. The editButton and removeButton are disabled by default, as the address book starts up with zero contacts in memory.
These buttons are then connected to their respective slots, editContact() and removeContact.
Now look at the editContact() and removeContact() functions in detail.
This function stores the contact's old details in oldName and oldAddress, before switching the mode to EditingMode. In this mode, the submitButton and cancelButton are both enabled. Hence, the user can change the contact's details and click either button.
Since you will reuse the submitButton for both: adding a new contact and editing an existing contact, you need to modify our existing submitContact() function. So, divide it in two with an if-else statement.
First, check currentMode to see if it is in AddingMode. If it is, proceed with your adding process.
...
Otherwise, check to see if currentMode is in EditingMode. If it is, compare oldName with name. If the name has changed, remove the old contact from contacts and insert the newly updated contact.
If only the contact's address has changed, that is the oldAddress is not the same as address, update the contact's address. Lastly, set currentMode to NavigationMode. This is an important step as it re-enables all the disabled push buttons.
To remove a contact from the address book, implement the removeContact() function.
This function first checks to see if the contact exists in contacts. If it does, display a QMessageBox, to confirm the removal with the user. Once the user has confirmed, call previous() to ensure that the user interface shows another contact, and remove the contact using QMap's remove() function. As a courtesy, display a QMessageBox to inform the user. Both the message boxes used in this function are shown below:
This function is mentioned earlier as a means to enable and disable the push buttons, depending on the current mode. The function updates the current mode according to the mode argument passed to it, assigning it to currentMode, before checking its value.
Each of the push buttons is then enabled or disabled, depending on the current mode. The code for AddingMode and EditingMode is shown below:
For NavigationMode, however, include conditions within the parameters of the QPushButton::setEnabled() function. This is to ensure that editButton and removeButton are enabled when there is at least one contact in the address book; nextButton and previousButton are only enabled when there is more than one contact in the address book.
By performing the task of setting the mode and updating the user interface in the same function, you avoid the possibility of the user interface getting "out of sync" with the internal state of the application.
To maintain consistency, you need to modify our addContact() and cancel() functions respectively. Below is the code:
...