1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include <QtWidgets>
52#include "addressbook.h"
53
54AddressBook::AddressBook(QWidget *parent)
55 : QWidget(parent)
56{
57 QLabel *nameLabel = new QLabel(tr("Name:"));
58 nameLine = new QLineEdit;
59 nameLine->setReadOnly(true);
60
61 QLabel *addressLabel = new QLabel(tr("Address:"));
62 addressText = new QTextEdit;
63 addressText->setReadOnly(true);
64
65 addButton = new QPushButton(tr("&Add"));
66
67 editButton = new QPushButton(tr("&Edit"));
68 editButton->setEnabled(false);
69 removeButton = new QPushButton(tr("&Remove"));
70 removeButton->setEnabled(false);
71//! [instantiating findButton]
72 findButton = new QPushButton(tr("&Find"));
73 findButton->setEnabled(false);
74//! [instantiating findButton]
75 submitButton = new QPushButton(tr("&Submit"));
76 submitButton->hide();
77 cancelButton = new QPushButton(tr("&Cancel"));
78 cancelButton->hide();
79
80 nextButton = new QPushButton(tr("&Next"));
81 nextButton->setEnabled(false);
82 previousButton = new QPushButton(tr("&Previous"));
83 previousButton->setEnabled(false);
84
85//! [instantiating FindDialog]
86 dialog = new FindDialog(this);
87//! [instantiating FindDialog]
88
89 connect(addButton, &QPushButton::clicked,
90 this, &AddressBook::addContact);
91 connect(submitButton, &QPushButton::clicked,
92 this, &AddressBook::submitContact);
93 connect(editButton, &QPushButton::clicked,
94 this, &AddressBook::editContact);
95 connect(removeButton, &QPushButton::clicked,
96 this, &AddressBook::removeContact);
97 connect(cancelButton, &QPushButton::clicked,
98 this, &AddressBook::cancel);
99//! [signals and slots for find]
100 connect(findButton, &QPushButton::clicked,
101 this, &AddressBook::findContact);
102//! [signals and slots for find]
103 connect(nextButton, &QPushButton::clicked,
104 this, &AddressBook::next);
105 connect(previousButton, &QPushButton::clicked,
106 this, &AddressBook::previous);
107
108 QVBoxLayout *buttonLayout1 = new QVBoxLayout;
109 buttonLayout1->addWidget(addButton);
110 buttonLayout1->addWidget(editButton);
111 buttonLayout1->addWidget(removeButton);
112//! [adding findButton to layout]
113 buttonLayout1->addWidget(findButton);
114//! [adding findButton to layout]
115 buttonLayout1->addWidget(submitButton);
116 buttonLayout1->addWidget(cancelButton);
117 buttonLayout1->addStretch();
118
119 QHBoxLayout *buttonLayout2 = new QHBoxLayout;
120 buttonLayout2->addWidget(previousButton);
121 buttonLayout2->addWidget(nextButton);
122
123 QGridLayout *mainLayout = new QGridLayout;
124 mainLayout->addWidget(nameLabel, 0, 0);
125 mainLayout->addWidget(nameLine, 0, 1);
126 mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
127 mainLayout->addWidget(addressText, 1, 1);
128 mainLayout->addLayout(buttonLayout1, 1, 2);
129 mainLayout->addLayout(buttonLayout2, 2, 1);
130
131 setLayout(mainLayout);
132 setWindowTitle(tr("Simple Address Book"));
133}
134
135void AddressBook::addContact()
136{
137 oldName = nameLine->text();
138 oldAddress = addressText->toPlainText();
139
140 nameLine->clear();
141 addressText->clear();
142
143 updateInterface(AddingMode);
144}
145
146void AddressBook::editContact()
147{
148 oldName = nameLine->text();
149 oldAddress = addressText->toPlainText();
150
151 updateInterface(EditingMode);
152}
153
154void AddressBook::submitContact()
155{
156 QString name = nameLine->text();
157 QString address = addressText->toPlainText();
158
159 if (name.isEmpty() || address.isEmpty()) {
160 QMessageBox::information(this, tr("Empty Field"),
161 tr("Please enter a name and address."));
162 return;
163 }
164
165 if (currentMode == AddingMode) {
166
167 if (!contacts.contains(name)) {
168 contacts.insert(name, address);
169 QMessageBox::information(this, tr("Add Successful"),
170 tr("\"%1\" has been added to your address book.").arg(name));
171 } else {
172 QMessageBox::information(this, tr("Add Unsuccessful"),
173 tr("Sorry, \"%1\" is already in your address book.").arg(name));
174 }
175 } else if (currentMode == EditingMode) {
176
177 if (oldName != name) {
178 if (!contacts.contains(name)) {
179 QMessageBox::information(this, tr("Edit Successful"),
180 tr("\"%1\" has been edited in your address book.").arg(oldName));
181 contacts.remove(oldName);
182 contacts.insert(name, address);
183 } else {
184 QMessageBox::information(this, tr("Edit Unsuccessful"),
185 tr("Sorry, \"%1\" is already in your address book.").arg(name));
186 }
187 } else if (oldAddress != address) {
188 QMessageBox::information(this, tr("Edit Successful"),
189 tr("\"%1\" has been edited in your address book.").arg(name));
190 contacts[name] = address;
191 }
192 }
193
194 updateInterface(NavigationMode);
195}
196
197void AddressBook::cancel()
198{
199 nameLine->setText(oldName);
200 addressText->setText(oldAddress);
201 updateInterface(NavigationMode);
202}
203
204void AddressBook::removeContact()
205{
206 QString name = nameLine->text();
207 QString address = addressText->toPlainText();
208
209 if (contacts.contains(name)) {
210
211 int button = QMessageBox::question(this,
212 tr("Confirm Remove"),
213 tr("Are you sure you want to remove \"%1\"?").arg(name),
214 QMessageBox::Yes | QMessageBox::No);
215
216 if (button == QMessageBox::Yes) {
217
218 previous();
219 contacts.remove(name);
220
221 QMessageBox::information(this, tr("Remove Successful"),
222 tr("\"%1\" has been removed from your address book.").arg(name));
223 }
224 }
225
226 updateInterface(NavigationMode);
227}
228
229void AddressBook::next()
230{
231 QString name = nameLine->text();
232 QMap<QString, QString>::iterator i = contacts.find(name);
233
234 if (i != contacts.end())
235 i++;
236
237 if (i == contacts.end())
238 i = contacts.begin();
239
240 nameLine->setText(i.key());
241 addressText->setText(i.value());
242}
243
244void AddressBook::previous()
245{
246 QString name = nameLine->text();
247 QMap<QString, QString>::iterator i = contacts.find(name);
248
249 if (i == contacts.end()) {
250 nameLine->clear();
251 addressText->clear();
252 return;
253 }
254
255 if (i == contacts.begin())
256 i = contacts.end();
257
258 i--;
259 nameLine->setText(i.key());
260 addressText->setText(i.value());
261}
262//! [findContact() function]
263void AddressBook::findContact()
264{
265 dialog->show();
266
267 if (dialog->exec() == QDialog::Accepted) {
268 QString contactName = dialog->getFindText();
269
270 if (contacts.contains(contactName)) {
271 nameLine->setText(contactName);
272 addressText->setText(contacts.value(contactName));
273 } else {
274 QMessageBox::information(this, tr("Contact Not Found"),
275 tr("Sorry, \"%1\" is not in your address book.").arg(contactName));
276 return;
277 }
278 }
279
280 updateInterface(NavigationMode);
281}
282//! [findContact() function]
283
284void AddressBook::updateInterface(Mode mode)
285{
286 currentMode = mode;
287
288 switch (currentMode) {
289
290 case AddingMode:
291 case EditingMode:
292
293 nameLine->setReadOnly(false);
294 nameLine->setFocus(Qt::OtherFocusReason);
295 addressText->setReadOnly(false);
296
297 addButton->setEnabled(false);
298 editButton->setEnabled(false);
299 removeButton->setEnabled(false);
300
301 nextButton->setEnabled(false);
302 previousButton->setEnabled(false);
303
304 submitButton->show();
305 cancelButton->show();
306 break;
307
308 case NavigationMode:
309
310 if (contacts.isEmpty()) {
311 nameLine->clear();
312 addressText->clear();
313 }
314
315 nameLine->setReadOnly(true);
316 addressText->setReadOnly(true);
317 addButton->setEnabled(true);
318
319 int number = contacts.size();
320 editButton->setEnabled(number >= 1);
321 removeButton->setEnabled(number >= 1);
322 findButton->setEnabled(number > 2);
323 nextButton->setEnabled(number > 1);
324 previousButton->setEnabled(number > 1);
325
326 submitButton->hide();
327 cancelButton->hide();
328 break;
329 }
330}
331