Support synthesized oblique and bold in SceneGraph
[profile/ivi/qtbase.git] / doc / src / tutorials / addressbook.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the documentation of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:FDL$
10 ** GNU Free Documentation License
11 ** Alternatively, this file may be used under the terms of the GNU Free
12 ** Documentation License version 1.3 as published by the Free Software
13 ** Foundation and appearing in the file included in the packaging of
14 ** this file.
15 **
16 ** Other Usage
17 ** Alternatively, this file may be used in accordance with the terms
18 ** and conditions contained in a signed written agreement between you
19 ** and Nokia.
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \page tutorials-addressbook.html
30
31     \title Address Book Tutorial
32     \brief An introduction to GUI programming, showing how to put together a
33     simple yet fully-functioning application.
34
35     This tutorial is an introduction to GUI programming with the Qt
36     cross-platform framework.
37
38     \image addressbook-tutorial-screenshot.png
39
40     \omit
41     It doesn't cover everything; the emphasis is on teaching the programming
42     philosophy of GUI programming, and Qt's features are introduced as needed.
43     Some commonly used features are never used in this tutorial.
44     \endomit
45
46     In this tutorial, you will learn about some of the basic
47     components of Qt, including:
48
49     \list
50     \o Widgets and layout managers
51     \o Container classes
52     \o Signals and slots
53     \o Input and output devices
54     \endlist
55
56     If you are new to Qt, we recommend reading \l{How to Learn Qt} first.
57
58     Tutorial contents:
59
60     \list 1
61     \o \l{tutorials/addressbook/part1}{Designing the User Interface}
62     \o \l{tutorials/addressbook/part2}{Adding Addresses}
63     \o \l{tutorials/addressbook/part3}{Navigating between Entries}
64     \o \l{tutorials/addressbook/part4}{Editing and Removing Addresses}
65     \o \l{tutorials/addressbook/part5}{Adding a Find Function}
66     \o \l{tutorials/addressbook/part6}{Loading and Saving}
67     \o \l{tutorials/addressbook/part7}{Additional Features}
68     \endlist
69
70     The tutorial source code is located in \c{examples/tutorials/addressbook}.
71
72     Although this little application does not look much like a
73     fully-fledged modern GUI application, it uses many of the basic
74     elements that are used in more complex applications. After you
75     have worked through this tutorial, we recommend reading the
76     \l{mainwindows/application}{Application} example, which presents a
77     small GUI application, with menus, toolbars, a status bar, and so
78     on.  
79 */
80
81 /*!
82     \page tutorials-addressbook-part1.html
83
84     \example tutorials/addressbook/part1
85     \title Part 1 - Designing the User Interface
86
87     This first part covers the design of the basic graphical user
88     interface (GUI) for our address book application.
89
90     The first step in creating a GUI program is to design the user
91     interface.  Here the our goal is to set up the labels and input
92     fields to implement a basic address book. The figure below is a
93     screenshot of the expected output.
94
95     \image addressbook-tutorial-part1-screenshot.png
96
97     We require two QLabel objects, \c nameLabel and \c addressLabel, as well
98     as two input fields, a QLineEdit object, \c nameLine, and a QTextEdit
99     object, \c addressText, to enable the user to enter a contact's name and
100     address. The widgets used and their positions are shown in the figure
101     below.
102
103     \image addressbook-tutorial-part1-labeled-screenshot.png
104
105     There are three files used to implement this address book:
106
107     \list
108         \o \c{addressbook.h} - the definition file for the \c AddressBook
109             class,
110         \o \c{addressbook.cpp} - the implementation file for the
111             \c AddressBook class, and
112         \o \c{main.cpp} - the file containing a \c main() function, with
113             an instance of \c AddressBook.
114     \endlist
115
116     \section1 Qt Programming - Subclassing
117
118     When writing Qt programs, we usually subclass Qt objects to add
119     functionality. This is one of the essential concepts behind creating
120     custom widgets or collections of standard widgets. Subclassing to
121     extend or change the behavior of a widget has the following advantages:
122
123     \list
124     \o We can write implementations of virtual or pure virtual functions to
125     obtain exactly what we need, falling back on the base class's implementation
126     when necessary.
127     \o It allows us to encapsulate parts of the user interface within a class,
128     so that the other parts of the application don't need to know about the
129     individual widgets in the user interface.
130     \o The subclass can be used to create multiple custom widgets in the same
131     application or library, and the code for the subclass can be reused in other
132     projects.
133     \endlist
134
135     Since Qt does not provide a specific address book widget, we subclass a
136     standard Qt widget class and add features to it. The \c AddressBook class
137     we create in this tutorial can be reused in situations where a basic address
138     book widget is needed.
139
140     \section1 Defining the AddressBook Class
141
142     The \l{tutorials/addressbook/part1/addressbook.h}{\c addressbook.h} file is
143     used to define the \c AddressBook class.
144
145     We start by defining \c AddressBook as a QWidget subclass and declaring
146     a constructor. We also use the Q_OBJECT macro to indicate that the class
147     uses internationalization and Qt's signals and slots features, even
148     if we do not use all of these features at this stage.
149
150     \snippet tutorials/addressbook/part1/addressbook.h class definition
151
152     The class holds declarations of \c nameLine and \c addressText,
153     the private instances of QLineEdit and QTextEdit mentioned
154     earlier.  The data stored in \c nameLine and \c addressText will
155     be needed for many of the address book functions.
156
157     We don't include declarations of the QLabel objects we will use
158     because we will not need to reference them once they have been
159     created.  The way Qt tracks the ownership of objects is explained
160     in the next section.
161
162     The Q_OBJECT macro itself implements some of the more advanced features of Qt.
163     For now, it is useful to think of the Q_OBJECT macro as a shortcut which allows
164     us to use the \l{QObject::}{tr()} and \l{QObject::}{connect()} functions.
165
166     We have now completed the \c addressbook.h file and we move on to
167     implement the corresponding \c addressbook.cpp file.
168
169     \section1 Implementing the AddressBook Class
170
171     The constructor of \c AddressBook accepts a QWidget parameter, \a parent.
172     By convention, we pass this parameter to the base class's constructor.
173     This concept of ownership, where a parent can have one or more children,
174     is useful for grouping widgets in Qt. For example, if you delete a parent,
175     all of its children will be deleted as well.
176
177     \snippet tutorials/addressbook/part1/addressbook.cpp constructor and input fields
178
179     In this constructor, the QLabel objects \c nameLabel and \c
180     addressLabel are instantiated, as well as \c nameLine and \c
181     addressText. The \l{QObject::tr()}{tr()} function returns a
182     translated version of the string, if there is one
183     available. Otherwise it returns the string itself. This function
184     marks its QString parameter as one that should be translated into
185     other languages. It should be used wherever a translatable string
186     appears.
187
188     When programming with Qt, it is useful to know how layouts work.
189     Qt provides three main layout classes: QHBoxLayout, QVBoxLayout
190     and QGridLayout to handle the positioning of widgets.
191
192     \image addressbook-tutorial-part1-labeled-layout.png
193
194     We use a QGridLayout to position our labels and input fields in a
195     structured manner. QGridLayout divides the available space into a grid and
196     places widgets in the cells we specify with row and column numbers. The
197     diagram above shows the layout cells and the position of our widgets, and
198     we specify this arrangement using the following code:
199
200     \snippet tutorials/addressbook/part1/addressbook.cpp layout
201
202     Notice that \c addressLabel is positioned using Qt::AlignTop as an
203     additional argument. This is to make sure it is not vertically centered in
204     cell (1,0). For a basic overview on Qt Layouts, refer to the 
205     \l{Layout Management} documentation.
206
207     In order to install the layout object onto the widget, we have to invoke
208     the widget's \l{QWidget::setLayout()}{setLayout()} function:
209
210     \snippet tutorials/addressbook/part1/addressbook.cpp setting the layout
211
212     Lastly, we set the widget's title to "Simple Address Book".
213
214     \section1 Running the Application
215
216     A separate file, \c main.cpp, is used for the \c main() function. Within
217     this function, we instantiate a QApplication object, \c app. QApplication
218     is responsible for various application-wide resources, such as the default
219     font and cursor, and for running an event loop. Hence, there is always one
220     QApplication object in every GUI application using Qt.
221
222     \snippet tutorials/addressbook/part1/main.cpp main function
223
224     We construct a new \c AddressBook widget on the stack and invoke
225     its \l{QWidget::show()}{show()} function to display it.
226     However, the widget will not be shown until the application's event loop
227     is started. We start the event loop by calling the application's
228     \l{QApplication::}{exec()} function; the result returned by this function
229     is used as the return value from the \c main() function. At this point,
230     it becomes apparent why we instanciated \c AddressBook on the stack: It
231     will now go out of scope. Therefore, \c AddressBook and all its child widgets
232     will be deleted, thus preventing memory leaks.
233 */
234
235 /*!
236     \page tutorials-addressbook-part2.html
237
238     \example tutorials/addressbook/part2
239     \title Part 2 - Adding Addresses
240
241     The next step in creating the address book is to implement some
242     user interactions.
243
244     \image addressbook-tutorial-part2-add-contact.png
245
246     We will provide a push button that the user can click to add a new contact.
247     Also, some form of data structure is needed to store these contacts in an
248     organized way.
249
250     \section1 Defining the AddressBook Class
251
252     Now that we have the labels and input fields set up, we add push buttons to
253     complete the process of adding a contact. This means that our
254     \c addressbook.h file now has three QPushButton objects declared and three
255     corresponding public slots.
256
257     \snippet tutorials/addressbook/part2/addressbook.h slots
258
259     A slot is a function that responds to a particular signal. We will discuss
260     this concept in further detail when implementing the \c AddressBook class.
261     However, for an overview of Qt's signals and slots concept, you can refer
262     to the \l{Signals and Slots} document.
263
264     Three QPushButton objects (\c addButton, \c submitButton, and
265     \c cancelButton) are now included in our private variable declarations,
266     along with \c nameLine and \c addressText.
267
268     \snippet tutorials/addressbook/part2/addressbook.h pushbutton declaration
269
270     We need a container to store our address book contacts, so that we can
271     traverse and display them. A QMap object, \c contacts, is used for this
272     purpose as it holds a key-value pair: the contact's name as the \e key,
273     and the contact's address as the \e{value}.
274
275     \snippet tutorials/addressbook/part2/addressbook.h remaining private variables
276
277     We also declare two private QString objects, \c oldName and \c oldAddress.
278     These objects are needed to hold the name and address of the contact that
279     was last displayed, before the user clicked \gui Add. So, when the user clicks
280     \gui Cancel, we can revert to displaying the details of the last contact.
281
282     \section1 Implementing the AddressBook Class
283
284     Within the constructor of \c AddressBook, we set the \c nameLine and
285     \c addressText to read-only, so that we can only display but not edit
286     existing contact details.
287
288     \dots
289     \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 1
290     \dots
291     \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 2
292
293     Then, we instantiate our push buttons: \c addButton, \c submitButton, and
294     \c cancelButton.
295
296     \snippet tutorials/addressbook/part2/addressbook.cpp pushbutton declaration
297
298     The \c addButton is displayed by invoking the \l{QPushButton::show()}
299     {show()} function, while the \c submitButton and \c cancelButton are
300     hidden by invoking \l{QPushButton::hide()}{hide()}. These two push
301     buttons will only be displayed when the user clicks \gui Add and this is
302     handled by the \c addContact() function discussed below.
303
304     \snippet tutorials/addressbook/part2/addressbook.cpp connecting signals and slots
305
306     We connect the push buttons' \l{QPushButton::clicked()}{clicked()} signal
307     to their respective slots. The figure below illustrates this.
308
309     \image addressbook-tutorial-part2-signals-and-slots.png
310
311     Next, we arrange our push buttons neatly to the right of our address book
312     widget, using a QVBoxLayout to line them up vertically.
313
314     \snippet tutorials/addressbook/part2/addressbook.cpp vertical layout
315
316     The \l{QBoxLayout::addStretch()}{addStretch()} function is used to ensure
317     the push buttons are not evenly spaced, but arranged closer to the top of
318     the widget. The figure below shows the difference between using
319     \l{QBoxLayout::addStretch()}{addStretch()} and not using it.
320
321     \image addressbook-tutorial-part2-stretch-effects.png
322
323     We then add \c buttonLayout1 to \c mainLayout, using
324     \l{QGridLayout::addLayout()}{addLayout()}. This gives us nested layouts
325     as \c buttonLayout1 is now a child of \c mainLayout.
326
327     \snippet tutorials/addressbook/part2/addressbook.cpp grid layout
328
329     Our layout coordinates now look like this:
330
331     \image addressbook-tutorial-part2-labeled-layout.png
332
333     In the \c addContact() function, we store the last displayed contact
334     details in \c oldName and \c oldAddress. Then we clear these input
335     fields and turn off the read-only mode. The focus is set on \c nameLine
336     and we display \c submitButton and \c cancelButton.
337
338     \snippet tutorials/addressbook/part2/addressbook.cpp addContact
339
340     The \c submitContact() function can be divided into three parts:
341
342     \list 1
343     \o We extract the contact's details from \c nameLine and \c addressText
344     and store them in QString objects. We also validate to make sure that the
345     user did not click \gui Submit with empty input fields; otherwise, a
346     QMessageBox is displayed to remind the user for a name and address.
347
348     \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1
349
350     \o We then proceed to check if the contact already exists. If it does not
351     exist, we add the contact to \c contacts and we display a QMessageBox to
352     inform the user that the contact has been added.
353
354     \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part2
355
356     If the contact already exists, again, we display a QMessageBox to inform
357     the user about this, preventing the user from adding duplicate contacts.
358     Our \c contacts object is based on key-value pairs of name and address,
359     hence, we want to ensure that \e key is unique.
360
361     \o Once we have handled both cases mentioned above, we restore the push
362     buttons to their normal state with the following code:
363
364     \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3
365
366     \endlist
367
368     The screenshot below shows the QMessageBox object we use to display
369     information messages to the user.
370
371     \image addressbook-tutorial-part2-add-successful.png
372
373     The \c cancel() function restores the last displayed contact details and
374     enables \c addButton, as well as hides \c submitButton and
375     \c cancelButton.
376
377     \snippet tutorials/addressbook/part2/addressbook.cpp cancel
378
379     The general idea behind adding a contact is to give the user the
380     flexibility to click \gui Submit or \gui Cancel at any time. The flowchart below
381     further explains this concept:
382
383     \image addressbook-tutorial-part2-add-flowchart.png
384 */
385
386 /*!
387     \page tutorials-addressbook-part3.html
388
389     \example tutorials/addressbook/part3
390     \title Part 3 - Navigating between Entries
391
392     The address book is now about half complete. We should add the
393     capability to navigate among the contacts, but first we must
394     decide what sort of a data structure we need for containing these
395     contacts.
396
397     In the previous section, we used a QMap of key-value pairs with
398     the contact's name as the \e key, and the contact's address as the
399     \e value. This works well for our case. However, in order to
400     navigate and display each entry, a little bit of enhancement is
401     needed.
402
403     We enhance the QMap by making it replicate a data structure similar to a
404     circularly-linked list, where all elements are connected, including the
405     first element and the last element. The figure below illustrates this data
406     structure.
407
408     \image addressbook-tutorial-part3-linkedlist.png
409
410     \section1 Defining the AddressBook Class
411
412     To add navigation functions to the address book, we must add two
413     more slots to the \c AddressBook class: \c next() and \c
414     previous() to the \c addressbook.h file:
415
416     \snippet tutorials/addressbook/part3/addressbook.h navigation functions
417
418     We also require another two QPushButton objects, so we declare \c nextButton
419     and \c previousButton as private variables:
420
421     \snippet tutorials/addressbook/part3/addressbook.h navigation pushbuttons
422
423     \section1 Implementing the AddressBook Class
424
425     In the \c AddressBook constructor in \c addressbook.cpp, we instantiate
426     \c nextButton and \c previousButton and disable them by default. This is
427     because navigation is only enabled when there is more than one contact
428     in the address book.
429
430     \snippet tutorials/addressbook/part3/addressbook.cpp navigation pushbuttons
431
432     We then connect these push buttons to their respective slots:
433
434     \snippet tutorials/addressbook/part3/addressbook.cpp connecting navigation signals
435
436     The image below is the expected graphical user interface. 
437
438     \image addressbook-tutorial-part3-screenshot.png
439
440     We follow basic conventions for \c next() and \c previous() functions by
441     placing the \c nextButton on the right and the \c previousButton on the
442     left. In order to achieve this intuitive layout, we use QHBoxLayout to
443     place the widgets side-by-side:
444
445     \snippet tutorials/addressbook/part3/addressbook.cpp navigation layout
446
447     The QHBoxLayout object, \c buttonLayout2, is then added to \c mainLayout.
448
449     \snippet tutorials/addressbook/part3/addressbook.cpp adding navigation layout
450
451     The figure below shows the coordinates of the widgets in \c mainLayout.
452     \image addressbook-tutorial-part3-labeled-layout.png
453
454     Within our \c addContact() function, we have to disable these buttons so
455     that the user does not attempt to navigate while adding a contact.
456
457     \snippet tutorials/addressbook/part3/addressbook.cpp disabling navigation
458
459     Also, in our \c submitContact() function, we enable the navigation
460     buttons, \c nextButton and \c previousButton, depending on the size
461     of \c contacts. As mentioned earlier, navigation is only enabled when
462     there is more than one contact in the address book. The following lines
463     of code demonstrates how to do this:
464
465     \snippet tutorials/addressbook/part3/addressbook.cpp enabling navigation
466
467     We also include these lines of code in the \c cancel() function.
468
469     Recall that we intend to emulate a circularly-linked list with our QMap
470     object, \c contacts. So, in the \c next() function, we obtain an iterator
471     for \c contacts and then:
472
473     \list
474         \o If the iterator is not at the end of \c contacts, we increment it
475         by one.
476         \o If the iterator is at the end of \c contacts, we move it to the
477         beginning of \c contacts. This gives us the illusion that our QMap is
478         working like a circularly-linked list.
479     \endlist
480
481     \snippet tutorials/addressbook/part3/addressbook.cpp next() function
482
483     Once we have iterated to the correct object in \c contacts, we display
484     its contents on \c nameLine and \c addressText.
485
486     Similarly, for the \c previous() function, we obtain an iterator for
487     \c contacts and then:
488
489     \list
490         \o If the iterator is at the end of \c contacts, we clear the
491         display and return.
492         \o If the iterator is at the beginning of \c contacts, we move it to
493         the end.
494         \o We then decrement the iterator by one.
495     \endlist
496
497     \snippet tutorials/addressbook/part3/addressbook.cpp previous() function
498
499     Again, we display the contents of the current object in \c contacts.
500
501 */
502
503 /*!
504     \page tutorials-addressbook-part4.html
505
506     \example tutorials/addressbook/part4
507     \title Part 4 - Editing and Removing Addresses
508
509     Now we look at ways to modify the contents of contacts stored in
510     the address book.
511
512     \image addressbook-tutorial-screenshot.png
513
514     We now have an address book that not only holds contacts in an
515     organized manner, but also allows navigation. It would be
516     convenient to include edit and remove functions so that a
517     contact's details can be changed when needed. However, this
518     requires a little improvement, in the form of enums. We defined
519     two modes: \c{AddingMode} and \c{NavigationMode}, but they were
520     not defined as enum values. Instead, we enabled and disabled the
521     corresponding buttons manually, resulting in multiple lines of
522     repeated code.
523
524     Here we define the \c Mode enum with three different values:
525
526     \list
527         \o \c{NavigationMode},
528         \o \c{AddingMode}, and
529         \o \c{EditingMode}.
530     \endlist
531
532     \section1 Defining the AddressBook Class
533
534     The \c addressbook.h file is updated to contain the \c Mode enum:
535
536     \snippet tutorials/addressbook/part4/addressbook.h Mode enum
537
538     We also add two new slots, \c editContact() and \c removeContact(), to
539     our current list of public slots.
540
541     \snippet tutorials/addressbook/part4/addressbook.h edit and remove slots
542
543     In order to switch between modes, we introduce the \c updateInterface() function
544     to control the enabling and disabling of all QPushButton objects. We also
545     add two new push buttons, \c editButton and \c removeButton, for the edit
546     and remove functions mentioned earlier.
547
548     \snippet tutorials/addressbook/part4/addressbook.h updateInterface() declaration
549     \dots
550     \snippet tutorials/addressbook/part4/addressbook.h buttons declaration
551     \dots
552     \snippet tutorials/addressbook/part4/addressbook.h mode declaration
553
554     Lastly, we declare \c currentMode to keep track of the enum's current mode.
555
556     \section1 Implementing the AddressBook Class
557
558     We now implement the mode-changing features of the address
559     book. The \c editButton and \c removeButton are instantiated and
560     disabled by default. The address book starts with zero contacts
561     in memory.
562
563     \snippet tutorials/addressbook/part4/addressbook.cpp edit and remove buttons
564
565     These buttons are then connected to their respective slots, \c editContact()
566     and \c removeContact(), and we add them to \c buttonLayout1.
567
568     \snippet tutorials/addressbook/part4/addressbook.cpp connecting edit and remove
569     \dots
570     \snippet tutorials/addressbook/part4/addressbook.cpp adding edit and remove to the layout
571
572     The \c editContact() function stores the contact's old details in
573     \c oldName and \c oldAddress, before switching the mode to \c EditingMode.
574     In this mode, the \c submitButton and \c cancelButton are both enabled,
575     hence, the user can change the contact's details and click either button.
576
577     \snippet tutorials/addressbook/part4/addressbook.cpp editContact() function
578
579     The \c submitContact() function has been divided in two with an \c{if-else}
580     statement. We check \c currentMode to see if it's in \c AddingMode. If it is,
581     we proceed with our adding process.
582
583     \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function beginning
584     \dots
585     \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part1
586
587     Otherwise, we check to see if \c currentMode is in \c EditingMode. If it
588     is, we compare \c oldName with \c name. If the name has changed, we remove
589     the old contact from \c contacts and insert the newly updated contact.
590
591     \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part2
592
593     If only the address has changed (i.e., \c oldAddress is not the same as \c address),
594     we update the contact's address. Lastly, we set \c currentMode to
595     \c NavigationMode. This is an important step as it re-enables all the
596     disabled push buttons.
597
598     To remove a contact from the address book, we implement the
599     \c removeContact() function. This function checks to see if the contact
600     exists in \c contacts.
601
602     \snippet tutorials/addressbook/part4/addressbook.cpp removeContact() function
603
604     If it does, we display a QMessageBox, to confirm the removal with the
605     user. Once the user has confirmed, we call \c previous() to ensure that the
606     user interface shows another contact, and we remove the contact using \l{QMap}'s
607     \l{QMap::remove()}{remove()} function. As a courtesy, we display a QMessageBox
608     to inform the user. Both the message boxes used in this function are shown below:
609
610     \image addressbook-tutorial-part4-remove.png
611
612     \section2 Updating the User Interface
613
614     We mentioned the \c updateInterface() function earlier as a means to
615     enable and disable the push buttons depending on the current mode.
616     The function updates the current mode according to the \c mode argument
617     passed to it, assigning it to \c currentMode before checking its value.
618
619     Each of the push buttons is then enabled or disabled, depending on the
620     current mode. The code for \c AddingMode and \c EditingMode is shown below:
621
622     \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 1
623
624     For \c NavigationMode, however, we include conditions within the parameters
625     of the QPushButton::setEnabled() function. This is to ensure that
626     \c editButton and \c removeButton are enabled when there is at least one
627     contact in the address book; \c nextButton and \c previousButton are only
628     enabled when there is more than one contact in the address book.
629
630     \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 2
631
632     By setting the mode and updating the user interface in the same
633     function, we avoid the possibility of the user interface getting
634     out of sync with the internal state of the application.
635   */
636
637 /*!
638     \page tutorials-addressbook-part5.html
639
640     \example tutorials/addressbook/part5
641     \title Part 5 - Adding a Find Function
642
643     Here we look at ways to locate contacts and addresses in the
644     address book.
645
646     \image addressbook-tutorial-part5-screenshot.png
647
648     As we add contacts to our address book, it becomes tedious to
649     navigate the list with the \e Next and \e Previous buttons. A \e
650     Find function would be more efficient.  The screenshot above shows
651     the \e Find button and its position on the panel of buttons.
652
653     When the user clicks on the \e Find button, it is useful to
654     display a dialog that prompts for a contact's name. Qt provides
655     QDialog, which we subclass here to implement a \c FindDialog
656     class.
657
658     \section1 Defining the FindDialog Class
659
660     \image addressbook-tutorial-part5-finddialog.png
661
662     In order to subclass QDialog, we first include the header for QDialog in
663     the \c finddialog.h file. Also, we use forward declaration to declare
664     QLineEdit and QPushButton since we will be using those widgets in our
665     dialog class.
666
667     As in our \c AddressBook class, the \c FindDialog class includes
668     the Q_OBJECT macro and its constructor is defined to accept a parent
669     QWidget, even though the dialog will be opened as a separate window.
670
671     \snippet tutorials/addressbook/part5/finddialog.h FindDialog header
672
673     We define a public function, \c getFindText(), to be used by classes that
674     instantiate \c FindDialog. This function allows these classes to obtain the
675     search string entered by the user. A public slot, \c findClicked(), is also
676     defined to handle the search string when the user clicks the \gui Find
677     button.
678
679     Lastly, we define the private variables, \c findButton, \c lineEdit
680     and \c findText, corresponding to the \gui Find button, the line edit
681     into which the user types the search string, and an internal string
682     used to store the search string for later use.
683
684     \section1 Implementing the FindDialog Class
685
686     Within the constructor of \c FindDialog, we set up the private variables,
687     \c lineEdit, \c findButton and \c findText. We use a QHBoxLayout to
688     position the widgets.
689
690     \snippet tutorials/addressbook/part5/finddialog.cpp constructor
691
692     We set the layout and window title, as well as connect the signals to their
693     respective slots. Notice that \c{findButton}'s \l{QPushButton::clicked()}
694     {clicked()} signal is connected to to \c findClicked() and
695     \l{QDialog::accept()}{accept()}. The \l{QDialog::accept()}{accept()} slot
696     provided by QDialog hides the dialog and sets the result code to
697     \l{QDialog::}{Accepted}. We use this function to help \c{AddressBook}'s
698     \c findContact() function know when the \c FindDialog object has been
699     closed. We will explain this logic in further detail when discussing the
700     \c findContact() function.
701
702     \image addressbook-tutorial-part5-signals-and-slots.png
703
704     In \c findClicked(), we validate \c lineEdit to ensure that the user
705     did not click the \gui Find button without entering a contact's name. Then, we set
706     \c findText to the search string, extracted from \c lineEdit. After that,
707     we clear the contents of \c lineEdit and hide the dialog.
708
709     \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function
710
711     The \c findText variable has a public getter function, \c getFindText(),
712     associated with it. Since we only ever set \c findText directly in both the
713     constructor and in the \c findClicked() function, we do not create a
714     setter function to accompany \c getFindText().
715     Because \c getFindText() is public, classes instantiating and using
716     \c FindDialog can always access the search string that the user has
717     entered and accepted.
718
719     \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function
720
721     \section1 Defining the AddressBook Class
722
723     To ensure we can use \c FindDialog from within our \c AddressBook class, we
724     include \c finddialog.h in the \c addressbook.h file.
725
726     \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header
727
728     So far, all our address book features have a QPushButton and a
729     corresponding slot. Similarly, for the \gui Find feature we have
730     \c findButton and \c findContact().
731
732     The \c findButton is declared as a private variable and the
733     \c findContact() function is declared as a public slot.
734
735     \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration
736     \dots
737     \snippet tutorials/addressbook/part5/addressbook.h findButton declaration
738
739     Lastly, we declare the private variable, \c dialog, which we will use to
740     refer to an instance of \c FindDialog.
741
742     \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration
743
744     Once we have instantiated a dialog, we will want to use it more than once;
745     using a private variable allows us to refer to it from more than one place
746     in the class.
747
748     \section1 Implementing the AddressBook Class
749
750     Within the \c AddressBook class's constructor, we instantiate our private
751     objects, \c findButton and \c findDialog:
752
753     \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton
754     \dots
755     \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog
756
757     Next, we connect the \c{findButton}'s
758     \l{QPushButton::clicked()}{clicked()} signal to \c findContact().
759
760     \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find
761
762     Now all that is left is the code for our \c findContact() function:
763
764     \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function
765
766     We start out by displaying the \c FindDialog instance, \c dialog. This is
767     when the user enters a contact name to look up. Once the user clicks
768     the dialog's \c findButton, the dialog is hidden and the result code is
769     set to QDialog::Accepted. This ensures that
770     our \c if statement is always true.
771
772     We then proceed to extract the search string, which in this case is
773     \c contactName, using \c{FindDialog}'s \c getFindText() function. If the
774     contact exists in our address book, we display it immediately. Otherwise,
775     we display the QMessageBox shown below to indicate that their search
776     failed.
777
778     \image addressbook-tutorial-part5-notfound.png
779 */
780
781 /*!
782     \page tutorials-addressbook-part6.html
783
784     \example tutorials/addressbook/part6
785     \title Part 6 - Loading and Saving
786
787     This part covers the Qt file handling features we use to write
788     loading and saving routines for the address book.
789
790     \image addressbook-tutorial-part6-screenshot.png
791
792     Although browsing and searching the contact list are useful
793     features, our address book is not complete until we can save
794     existing contacts and load them again at a later time.
795
796     Qt provides a number of classes for \l{Input/Output and Networking}
797     {input and output}, but we have chosen to use two which are simple to use
798     in combination: QFile and QDataStream.
799
800     A QFile object represents a file on disk that can be read from and written
801     to. QFile is a subclass of the more general QIODevice class which
802     represents many different kinds of devices.
803
804     A QDataStream object is used to serialize binary data so that it can be
805     stored in a QIODevice and retrieved again later. Reading from a QIODevice
806     and writing to it is as simple as opening the stream - with the respective
807     device as a parameter - and reading from or writing to it.
808
809
810     \section1 Defining the AddressBook Class
811
812     We declare two public slots, \c saveToFile() and \c loadFromFile(), as well
813     as two QPushButton objects, \c loadButton and \c saveButton.
814
815     \snippet tutorials/addressbook/part6/addressbook.h save and load functions declaration
816     \dots
817     \snippet tutorials/addressbook/part6/addressbook.h save and load buttons declaration
818
819     \section1 Implementing the AddressBook Class
820
821     In our constructor, we instantiate \c loadButton and \c saveButton.
822     Ideally, it would be more user-friendly to set the push buttons' labels
823     to "Load contacts from a file" and "Save contacts to a file". However, due
824     to the size of our other push buttons, we set the labels to \gui{Load...}
825     and \gui{Save...}. Fortunately, Qt provides a simple way to set tooltips with
826     \l{QWidget::setToolTip()}{setToolTip()} and we use it in the following way
827     for our push buttons:
828
829     \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1
830     \dots
831     \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2
832
833     Although it is not shown here, just like the other features we implemented,
834     we add the push buttons to the layout panel on the right, \c buttonLayout1,
835     and we connect the push buttons' \l{QPushButton::clicked()}{clicked()}
836     signals to their respective slots.
837
838     For the saving feature, we first obtain \c fileName using
839     QFileDialog::getSaveFileName(). This is a convenience function provided
840     by QFileDialog, which pops up a modal file dialog and allows the user to
841     enter a file name or select any existing \c{.abk} file. The \c{.abk} file
842     is our Address Book extension that we create when we save contacts.
843
844     \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1
845
846     The file dialog that pops up is displayed in the screenshot below:
847
848     \image addressbook-tutorial-part6-save.png
849
850     If \c fileName is not empty, we create a QFile object, \c file, with
851     \c fileName. QFile works with QDataStream as QFile is a QIODevice.
852
853     Next, we attempt to open the file in \l{QIODevice::}{WriteOnly} mode.
854     If this is unsuccessful, we display a QMessageBox to inform the user.
855
856     \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2
857
858     Otherwise, we instantiate a QDataStream object, \c out, to write the open
859     file. QDataStream requires that the same version of the stream is used
860     for reading and writing. We ensure that this is the case by setting the
861     version used to the \l{QDataStream::Qt_4_5}{version introduced with Qt 4.5}
862     before serializing the data to \c file.
863
864     \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3
865
866     For the loading feature, we also obtain \c fileName using
867     QFileDialog::getOpenFileName(). This function, the counterpart to
868     QFileDialog::getSaveFileName(), also pops up the modal file dialog and
869     allows the user to enter a file name or select any existing \c{.abk} file
870     to load it into the address book.
871
872     \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1
873
874     On Windows, for example, this function pops up a native file dialog, as
875     shown in the following screenshot.
876
877     \image addressbook-tutorial-part6-load.png
878
879     If \c fileName is not empty, again, we use a QFile object, \c file, and
880     attempt to open it in \l{QIODevice::}{ReadOnly} mode. Similar to our
881     implementation of \c saveToFile(), if this attempt is unsuccessful, we
882     display a QMessageBox to inform the user.
883
884     \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2
885
886     Otherwise, we instantiate a QDataStream object, \c in, set its version as
887     above and read the serialized data into the \c contacts data structure.
888     The \c contacts object is emptied before data is read into it to simplify
889     the file reading process. A more advanced method would be to read the
890     contacts into a temporary QMap object, and copy over non-duplicate contacts
891     into \c contacts.
892
893     \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3
894
895     To display the contacts that have been read from the file, we must first
896     validate the data obtained to ensure that the file we read from actually
897     contains address book contacts. If it does, we display the first contact;
898     otherwise, we display a QMessageBox to inform the user about the problem.
899     Lastly, we update the interface to enable and disable the push buttons
900     accordingly.
901 */
902
903 /*!
904     \page tutorials-addressbook-part7.html
905
906     \example tutorials/addressbook/part7
907     \title Part 7 - Additional Features
908
909     This part covers some additional features that make the address
910     book more convenient for the frequent user.
911
912     \image addressbook-tutorial-part7-screenshot.png
913
914     Although our address book is useful in isolation, it would be
915     better if we could exchange contact data with other applications.
916     The vCard format is a popular file format that can be used for
917     this purpose.  Here we extend our address book client to allow
918     contacts to be exported to vCard \c{.vcf} files.
919
920     \section1 Defining the AddressBook Class
921
922     We add a QPushButton object, \c exportButton, and a corresponding public
923     slot, \c exportAsVCard() to our \c AddressBook class in the
924     \c addressbook.h file.
925
926     \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration
927     \dots
928     \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration
929
930     \section1 Implementing the AddressBook Class
931
932     Within the \c AddressBook constructor, we connect \c{exportButton}'s
933     \l{QPushButton::clicked()}{clicked()} signal to \c exportAsVCard().
934     We also add this button to our \c buttonLayout1, the layout responsible
935     for our panel of buttons on the right.
936
937     In our \c exportAsVCard() function, we start by extracting the contact's
938     name into \c name. We declare \c firstName, \c lastName and \c nameList.
939     Next, we look for the index of the first white space in \c name. If there
940     is a white space, we split the contact's name into \c firstName and
941     \c lastName. Then, we replace the space with an underscore ("_").
942     Alternately, if there is no white space, we assume that the contact only
943     has a first name.
944
945     \snippet tutorials/addressbook/part7/addressbook.cpp export function part1
946
947     As with the \c saveToFile() function, we open a file dialog to let the user
948     choose a location for the file. Using the file name chosen, we create an
949     instance of QFile to write to.
950
951     We attempt to open the file in \l{QIODevice::}{WriteOnly} mode. If this
952     process fails, we display a QMessageBox to inform the user about the
953     problem and return. Otherwise, we pass the file as a parameter to a
954     QTextStream object, \c out. Like QDataStream, the QTextStream class
955     provides functionality to read and write plain text to files. As a result,
956     the \c{.vcf} file generated can be opened for editing in a text editor.
957
958     \snippet tutorials/addressbook/part7/addressbook.cpp export function part2
959
960     We then write out a vCard file with the \c{BEGIN:VCARD} tag, followed by
961     the \c{VERSION:2.1} tag. The contact's name is written with the \c{N:}
962     tag. For the \c{FN:} tag, which fills in the "File as" property of a vCard,
963     we have to check whether the contact has a last name or not. If the contact
964     does, we use the details in \c nameList to fill it. Otherwise, we write
965     \c firstName only.
966
967     \snippet tutorials/addressbook/part7/addressbook.cpp export function part3
968
969     We proceed to write the contact's address. The semicolons in the address
970     are escaped with "\\", the newlines are replaced with semicolons, and the
971     commas are replaced with spaces. Lastly, we write the \c{ADR;HOME:;}
972     tag, followed by \c address and then the \c{END:VCARD} tag.
973
974     \snippet tutorials/addressbook/part7/addressbook.cpp export function part4
975
976     In the end, a QMessageBox is displayed to inform the user that the vCard
977     has been successfully exported.
978
979     \e{vCard is a trademark of the \l{http://www.imc.org}
980     {Internet Mail Consortium}}.
981 */