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 findButton = new QPushButton(tr("&Find"));
72 findButton->setEnabled(false);
73 submitButton = new QPushButton(tr("&Submit"));
74 submitButton->hide();
75 cancelButton = new QPushButton(tr("&Cancel"));
76 cancelButton->hide();
77
78 nextButton = new QPushButton(tr("&Next"));
79 nextButton->setEnabled(false);
80 previousButton = new QPushButton(tr("&Previous"));
81 previousButton->setEnabled(false);
82
83 loadButton = new QPushButton(tr("&Load..."));
84//! [tooltip 1]
85 loadButton->setToolTip(tr("Load contacts from a file"));
86//! [tooltip 1]
87 saveButton = new QPushButton(tr("&Save..."));
88//! [tooltip 2]
89 saveButton->setToolTip(tr("Save contacts to a file"));
90//! [tooltip 2]
91 saveButton->setEnabled(false);
92
93 dialog = new FindDialog(this);
94
95 connect(addButton, &QPushButton::clicked,
96 this, &AddressBook::addContact);
97 connect(submitButton, &QPushButton::clicked,
98 this, &AddressBook::submitContact);
99 connect(editButton, &QPushButton::clicked,
100 this, &AddressBook::editContact);
101 connect(removeButton, &QPushButton::clicked,
102 this, &AddressBook::removeContact);
103 connect(cancelButton, &QPushButton::clicked,
104 this, &AddressBook::cancel);
105 connect(findButton, &QPushButton::clicked,
106 this, &AddressBook::findContact);
107 connect(nextButton, &QPushButton::clicked,
108 this, &AddressBook::next);
109 connect(previousButton, &QPushButton::clicked,
110 this, &AddressBook::previous);
111 connect(loadButton, &QPushButton::clicked,
112 this, &AddressBook::loadFromFile);
113 connect(saveButton, &QPushButton::clicked,
114 this, &AddressBook::saveToFile);
115
116 QVBoxLayout *buttonLayout1 = new QVBoxLayout;
117 buttonLayout1->addWidget(addButton);
118 buttonLayout1->addWidget(editButton);
119 buttonLayout1->addWidget(removeButton);
120 buttonLayout1->addWidget(findButton);
121 buttonLayout1->addWidget(submitButton);
122 buttonLayout1->addWidget(cancelButton);
123 buttonLayout1->addWidget(loadButton);
124 buttonLayout1->addWidget(saveButton);
125 buttonLayout1->addStretch();
126
127 QHBoxLayout *buttonLayout2 = new QHBoxLayout;
128 buttonLayout2->addWidget(previousButton);
129 buttonLayout2->addWidget(nextButton);
130
131 QGridLayout *mainLayout = new QGridLayout;
132 mainLayout->addWidget(nameLabel, 0, 0);
133 mainLayout->addWidget(nameLine, 0, 1);
134 mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
135 mainLayout->addWidget(addressText, 1, 1);
136 mainLayout->addLayout(buttonLayout1, 1, 2);
137 mainLayout->addLayout(buttonLayout2, 2, 1);
138
139 setLayout(mainLayout);
140 setWindowTitle(tr("Simple Address Book"));
141}
142
143void AddressBook::addContact()
144{
145 oldName = nameLine->text();
146 oldAddress = addressText->toPlainText();
147
148 nameLine->clear();
149 addressText->clear();
150
151 updateInterface(AddingMode);
152}
153
154void AddressBook::editContact()
155{
156 oldName = nameLine->text();
157 oldAddress = addressText->toPlainText();
158
159 updateInterface(EditingMode);
160}
161
162void AddressBook::submitContact()
163{
164 QString name = nameLine->text();
165 QString address = addressText->toPlainText();
166
167 if (name.isEmpty() || address.isEmpty()) {
168 QMessageBox::information(this, tr("Empty Field"),
169 tr("Please enter a name and address."));
170 return;
171 }
172
173 if (currentMode == AddingMode) {
174
175 if (!contacts.contains(name)) {
176 contacts.insert(name, address);
177 QMessageBox::information(this, tr("Add Successful"),
178 tr("\"%1\" has been added to your address book.").arg(name));
179 } else {
180 QMessageBox::information(this, tr("Add Unsuccessful"),
181 tr("Sorry, \"%1\" is already in your address book.").arg(name));
182 }
183 } else if (currentMode == EditingMode) {
184
185 if (oldName != name) {
186 if (!contacts.contains(name)) {
187 QMessageBox::information(this, tr("Edit Successful"),
188 tr("\"%1\" has been edited in your address book.").arg(oldName));
189 contacts.remove(oldName);
190 contacts.insert(name, address);
191 } else {
192 QMessageBox::information(this, tr("Edit Unsuccessful"),
193 tr("Sorry, \"%1\" is already in your address book.").arg(name));
194 }
195 } else if (oldAddress != address) {
196 QMessageBox::information(this, tr("Edit Successful"),
197 tr("\"%1\" has been edited in your address book.").arg(name));
198 contacts[name] = address;
199 }
200 }
201
202 updateInterface(NavigationMode);
203}
204
205void AddressBook::cancel()
206{
207 nameLine->setText(oldName);
208 addressText->setText(oldAddress);
209 updateInterface(NavigationMode);
210}
211
212void AddressBook::removeContact()
213{
214 QString name = nameLine->text();
215 QString address = addressText->toPlainText();
216
217 if (contacts.contains(name)) {
218
219 int button = QMessageBox::question(this,
220 tr("Confirm Remove"),
221 tr("Are you sure you want to remove \"%1\"?").arg(name),
222 QMessageBox::Yes | QMessageBox::No);
223
224 if (button == QMessageBox::Yes) {
225
226 previous();
227 contacts.remove(name);
228
229 QMessageBox::information(this, tr("Remove Successful"),
230 tr("\"%1\" has been removed from your address book.").arg(name));
231 }
232 }
233
234 updateInterface(NavigationMode);
235}
236
237void AddressBook::next()
238{
239 QString name = nameLine->text();
240 QMap<QString, QString>::iterator i = contacts.find(name);
241
242 if (i != contacts.end())
243 i++;
244
245 if (i == contacts.end())
246 i = contacts.begin();
247
248 nameLine->setText(i.key());
249 addressText->setText(i.value());
250}
251
252void AddressBook::previous()
253{
254 QString name = nameLine->text();
255 QMap<QString, QString>::iterator i = contacts.find(name);
256
257 if (i == contacts.end()) {
258 nameLine->clear();
259 addressText->clear();
260 return;
261 }
262
263 if (i == contacts.begin())
264 i = contacts.end();
265
266 i--;
267 nameLine->setText(i.key());
268 addressText->setText(i.value());
269}
270
271void AddressBook::findContact()
272{
273 dialog->show();
274
275 if (dialog->exec() == 1) {
276 QString contactName = dialog->getFindText();
277
278 if (contacts.contains(contactName)) {
279 nameLine->setText(contactName);
280 addressText->setText(contacts.value(contactName));
281 } else {
282 QMessageBox::information(this, tr("Contact Not Found"),
283 tr("Sorry, \"%1\" is not in your address book.").arg(contactName));
284 return;
285 }
286 }
287
288 updateInterface(NavigationMode);
289}
290
291void AddressBook::updateInterface(Mode mode)
292{
293 currentMode = mode;
294
295 switch (currentMode) {
296
297 case AddingMode:
298 case EditingMode:
299
300 nameLine->setReadOnly(false);
301 nameLine->setFocus(Qt::OtherFocusReason);
302 addressText->setReadOnly(false);
303
304 addButton->setEnabled(false);
305 editButton->setEnabled(false);
306 removeButton->setEnabled(false);
307
308 nextButton->setEnabled(false);
309 previousButton->setEnabled(false);
310
311 submitButton->show();
312 cancelButton->show();
313
314 loadButton->setEnabled(false);
315 saveButton->setEnabled(false);
316 break;
317
318 case NavigationMode:
319
320 if (contacts.isEmpty()) {
321 nameLine->clear();
322 addressText->clear();
323 }
324
325 nameLine->setReadOnly(true);
326 addressText->setReadOnly(true);
327 addButton->setEnabled(true);
328
329 int number = contacts.size();
330 editButton->setEnabled(number >= 1);
331 removeButton->setEnabled(number >= 1);
332 findButton->setEnabled(number > 2);
333 nextButton->setEnabled(number > 1);
334 previousButton->setEnabled(number > 1);
335
336 submitButton->hide();
337 cancelButton->hide();
338
339 loadButton->setEnabled(true);
340 saveButton->setEnabled(number >= 1);
341 break;
342 }
343}
344
345//! [saveToFile() function part1]
346void AddressBook::saveToFile()
347{
348 QString fileName = QFileDialog::getSaveFileName(this,
349 tr("Save Address Book"), "",
350 tr("Address Book (*.abk);;All Files (*)"));
351
352//! [saveToFile() function part1]
353//! [saveToFile() function part2]
354 if (fileName.isEmpty())
355 return;
356 else {
357 QFile file(fileName);
358 if (!file.open(QIODevice::WriteOnly)) {
359 QMessageBox::information(this, tr("Unable to open file"),
360 file.errorString());
361 return;
362 }
363
364//! [saveToFile() function part2]
365//! [saveToFile() function part3]
366 QDataStream out(&file);
367 out.setVersion(QDataStream::Qt_4_5);
368 out << contacts;
369 }
370}
371//! [saveToFile() function part3]
372
373//! [loadFromFile() function part1]
374void AddressBook::loadFromFile()
375{
376 QString fileName = QFileDialog::getOpenFileName(this,
377 tr("Open Address Book"), "",
378 tr("Address Book (*.abk);;All Files (*)"));
379//! [loadFromFile() function part1]
380
381//! [loadFromFile() function part2]
382 if (fileName.isEmpty())
383 return;
384 else {
385
386 QFile file(fileName);
387
388 if (!file.open(QIODevice::ReadOnly)) {
389 QMessageBox::information(this, tr("Unable to open file"),
390 file.errorString());
391 return;
392 }
393
394 QDataStream in(&file);
395 in.setVersion(QDataStream::Qt_4_5);
396 contacts.clear(); // clear existing contacts
397 in >> contacts;
398//! [loadFromFile() function part2]
399
400//! [loadFromFile() function part3]
401 if (contacts.isEmpty()) {
402 QMessageBox::information(this, tr("No contacts in file"),
403 tr("The file you are attempting to open contains no contacts."));
404 } else {
405 QMap<QString, QString>::iterator i = contacts.begin();
406 nameLine->setText(i.key());
407 addressText->setText(i.value());
408 }
409 }
410
411 updateInterface(NavigationMode);
412}
413//! [loadFromFile() function part3]
414