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(s: "Name:"));
58 nameLine = new QLineEdit;
59 nameLine->setReadOnly(true);
60
61 QLabel *addressLabel = new QLabel(tr(s: "Address:"));
62 addressText = new QTextEdit;
63 addressText->setReadOnly(true);
64
65 addButton = new QPushButton(tr(s: "&Add"));
66
67 editButton = new QPushButton(tr(s: "&Edit"));
68 editButton->setEnabled(false);
69 removeButton = new QPushButton(tr(s: "&Remove"));
70 removeButton->setEnabled(false);
71 findButton = new QPushButton(tr(s: "&Find"));
72 findButton->setEnabled(false);
73 submitButton = new QPushButton(tr(s: "&Submit"));
74 submitButton->hide();
75 cancelButton = new QPushButton(tr(s: "&Cancel"));
76 cancelButton->hide();
77
78 nextButton = new QPushButton(tr(s: "&Next"));
79 nextButton->setEnabled(false);
80 previousButton = new QPushButton(tr(s: "&Previous"));
81 previousButton->setEnabled(false);
82
83 loadButton = new QPushButton(tr(s: "&Load..."));
84//! [tooltip 1]
85 loadButton->setToolTip(tr(s: "Load contacts from a file"));
86//! [tooltip 1]
87 saveButton = new QPushButton(tr(s: "&Save..."));
88//! [tooltip 2]
89 saveButton->setToolTip(tr(s: "Save contacts to a file"));
90//! [tooltip 2]
91 saveButton->setEnabled(false);
92
93 dialog = new FindDialog(this);
94
95 connect(sender: addButton, signal: &QPushButton::clicked,
96 receiver: this, slot: &AddressBook::addContact);
97 connect(sender: submitButton, signal: &QPushButton::clicked,
98 receiver: this, slot: &AddressBook::submitContact);
99 connect(sender: editButton, signal: &QPushButton::clicked,
100 receiver: this, slot: &AddressBook::editContact);
101 connect(sender: removeButton, signal: &QPushButton::clicked,
102 receiver: this, slot: &AddressBook::removeContact);
103 connect(sender: cancelButton, signal: &QPushButton::clicked,
104 receiver: this, slot: &AddressBook::cancel);
105 connect(sender: findButton, signal: &QPushButton::clicked,
106 receiver: this, slot: &AddressBook::findContact);
107 connect(sender: nextButton, signal: &QPushButton::clicked,
108 receiver: this, slot: &AddressBook::next);
109 connect(sender: previousButton, signal: &QPushButton::clicked,
110 receiver: this, slot: &AddressBook::previous);
111 connect(sender: loadButton, signal: &QPushButton::clicked,
112 receiver: this, slot: &AddressBook::loadFromFile);
113 connect(sender: saveButton, signal: &QPushButton::clicked,
114 receiver: this, slot: &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, row: 0, column: 0);
133 mainLayout->addWidget(nameLine, row: 0, column: 1);
134 mainLayout->addWidget(addressLabel, row: 1, column: 0, Qt::AlignTop);
135 mainLayout->addWidget(addressText, row: 1, column: 1);
136 mainLayout->addLayout(buttonLayout1, row: 1, column: 2);
137 mainLayout->addLayout(buttonLayout2, row: 2, column: 1);
138
139 setLayout(mainLayout);
140 setWindowTitle(tr(s: "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(mode: AddingMode);
152}
153
154void AddressBook::editContact()
155{
156 oldName = nameLine->text();
157 oldAddress = addressText->toPlainText();
158
159 updateInterface(mode: 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(parent: this, title: tr(s: "Empty Field"),
169 text: tr(s: "Please enter a name and address."));
170 return;
171 }
172
173 if (currentMode == AddingMode) {
174
175 if (!contacts.contains(akey: name)) {
176 contacts.insert(akey: name, avalue: address);
177 QMessageBox::information(parent: this, title: tr(s: "Add Successful"),
178 text: tr(s: "\"%1\" has been added to your address book.").arg(a: name));
179 } else {
180 QMessageBox::information(parent: this, title: tr(s: "Add Unsuccessful"),
181 text: tr(s: "Sorry, \"%1\" is already in your address book.").arg(a: name));
182 }
183 } else if (currentMode == EditingMode) {
184
185 if (oldName != name) {
186 if (!contacts.contains(akey: name)) {
187 QMessageBox::information(parent: this, title: tr(s: "Edit Successful"),
188 text: tr(s: "\"%1\" has been edited in your address book.").arg(a: oldName));
189 contacts.remove(akey: oldName);
190 contacts.insert(akey: name, avalue: address);
191 } else {
192 QMessageBox::information(parent: this, title: tr(s: "Edit Unsuccessful"),
193 text: tr(s: "Sorry, \"%1\" is already in your address book.").arg(a: name));
194 }
195 } else if (oldAddress != address) {
196 QMessageBox::information(parent: this, title: tr(s: "Edit Successful"),
197 text: tr(s: "\"%1\" has been edited in your address book.").arg(a: name));
198 contacts[name] = address;
199 }
200 }
201
202 updateInterface(mode: NavigationMode);
203}
204
205void AddressBook::cancel()
206{
207 nameLine->setText(oldName);
208 addressText->setText(oldAddress);
209 updateInterface(mode: NavigationMode);
210}
211
212void AddressBook::removeContact()
213{
214 QString name = nameLine->text();
215 QString address = addressText->toPlainText();
216
217 if (contacts.contains(akey: name)) {
218
219 int button = QMessageBox::question(parent: this,
220 title: tr(s: "Confirm Remove"),
221 text: tr(s: "Are you sure you want to remove \"%1\"?").arg(a: name),
222 buttons: QMessageBox::Yes | QMessageBox::No);
223
224 if (button == QMessageBox::Yes) {
225
226 previous();
227 contacts.remove(akey: name);
228
229 QMessageBox::information(parent: this, title: tr(s: "Remove Successful"),
230 text: tr(s: "\"%1\" has been removed from your address book.").arg(a: name));
231 }
232 }
233
234 updateInterface(mode: NavigationMode);
235}
236
237void AddressBook::next()
238{
239 QString name = nameLine->text();
240 QMap<QString, QString>::iterator i = contacts.find(akey: 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(akey: 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(akey: contactName)) {
279 nameLine->setText(contactName);
280 addressText->setText(contacts.value(akey: contactName));
281 } else {
282 QMessageBox::information(parent: this, title: tr(s: "Contact Not Found"),
283 text: tr(s: "Sorry, \"%1\" is not in your address book.").arg(a: contactName));
284 return;
285 }
286 }
287
288 updateInterface(mode: 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(parent: this,
349 caption: tr(s: "Save Address Book"), dir: "",
350 filter: tr(s: "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(flags: QIODevice::WriteOnly)) {
359 QMessageBox::information(parent: this, title: tr(s: "Unable to open file"),
360 text: 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(parent: this,
377 caption: tr(s: "Open Address Book"), dir: "",
378 filter: tr(s: "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(flags: QIODevice::ReadOnly)) {
389 QMessageBox::information(parent: this, title: tr(s: "Unable to open file"),
390 text: 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(parent: this, title: tr(s: "No contacts in file"),
403 text: tr(s: "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(mode: NavigationMode);
412}
413//! [loadFromFile() function part3]
414

source code of qtbase/examples/widgets/tutorials/addressbook/part6/addressbook.cpp