summaryrefslogtreecommitdiffstats
path: root/doc/src/tutorials/addressbook-fr.qdoc
blob: 2847f1be0a11af847a03a6a38f6e1da5a42a87d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \page tutorials-addressbook-fr.html

    \startpage {index.html}{Qt Reference Documentation}
    \nextpage {tutorials/addressbook-fr/part1}{Chapitre 1}

    \title Tutoriel "Carnet d'adresses"
    \ingroup howto
    \ingroup tutorials
    \brief Une introduction � la programation d'interface graphique montrant comment construire une application simple avec Qt.

    Ce tutoriel est une introduction � la programmation de GUI (interface utilisateur)
    � l'aide des outils fournis par la plateforme multiplate-forme Qt.

    \image addressbook-tutorial-screenshot.png

    Ce tutoriel va nous amener � d�couvrir quelques technologies fondamentales fournies 
    par Qt, tel que:

    \list
    \o Les Widgets et leur mise en page � l'aide des layouts
    \o Les signaux et slots
    \o Les structures de donn�es de collections
    \o Les entr�es/sorties
    \endlist

    Si c'est votre premier contact avec Qt, lisez \l{How to Learn Qt}{Comment apprendre Qt}
    si ce n'est d�j� fait.

    Le code source du tutoriel est distribu� avec Qt dans le dossier \c examples/tutorials/addressbook

    Les chapitres du tutoriel:

    \list 1
    \o \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur}
    \o \l{tutorials/addressbook-fr/part2}{Ajouter des adresses}
    \o \l{tutorials/addressbook-fr/part3}{Navigation entre les �l�ments}
    \o \l{tutorials/addressbook-fr/part4}{�diter et supprimer des adresses}
    \o \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche}
    \o \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement}
    \o \l{tutorials/addressbook-fr/part7}{Fonctionnalit�s avanc�es}
    \endlist

    La petite application que nous d�velopperons ici ne poss�de pas tous les �l�ments
    des interfaces dernier cri, elle va nous permettre d'utiliser les techniques de base
    utilis�es dans les applications plus complexes.

    Lorsque vous aurez termin� ce tutoriel, nous vous recommandons de poursuivre avec l'exemple
    "\l{mainwindows/application}{Application}", qui pr�sente une interface simple utilisant
    les menus et barres d'outils, la barre d'�tat, etc.

*/

/*!
    \page tutorials-addressbook-fr-part1.html
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \nextpage {tutorials/addressbook-fr/part2}{Chapitre 2}
    \example tutorials/addressbook-fr/part1
    \title Carnet d'adresses 1 - Conception de l'interface utilisateur

    La premi�re partie de ce tutoriel traite de la conception d'une interface graphique
    (GUI) basique, que l'on utilisera pour l'application Carnet d'adresses.

    La premi�re �tape dans la cr�ation d'applications graphiques est la conception de
    l'interface utilisateur. Dans ce chapitre, nous verrons comment cr�er les labels
    et champs de saisie n�cessaires � l'implementation d'un carnet d'adresses de base.
    Le r�sultat attendu est illustr� par la capture d'�cran ci-dessous.

    \image addressbook-tutorial-part1-screenshot.png

    Nous allons avoir besoin de deux objets QLabel, \c nameLabel et \c addressLabel,
    ainsi que deux champs de saisie: un objet QLineEdit, \c nameLine, et un objet
    QTextEdit, \c addressText, afin de permettre � l'utilisateur d'entrer le nom d'un
    contact et son adresse. Les widgets utilis�s ainsi que leur placement sont visibles ci-dessous.

    \image addressbook-tutorial-part1-labeled-screenshot.png

    Trois fichiers sont n�cessaires � l'impl�mentation de ce carnet d'adresses:

    \list
        \o \c{addressbook.h} - le fichier de d�finition (header) pour la classe \c AddressBook,
        \o \c{addressbook.cpp} - le fichier source, qui comprend l'impl�mentation de la classe
            \c AddressBook
        \o \c{main.cpp} - le fichier qui contient la m�thode \c main() , et
        une instance de la classe \c AddressBook.
    \endlist

    \section1 Programmation en Qt - h�ritage


    Lorsque l'on �crit des programmes avec Qt, on a g�n�ralement recours �
    l'h�ritage depuis des objets Qt, afin d'y ajouter des fonctionnalit�s.
    C'est l'un des concepts fondamentaux de la cr�ation de widgets personnalis�s
    ou de collections de widgets. Utiliser l'h�ritage afin de compl�ter
    ou modifier le comportement d'un widget pr�sente les avantages suivants:

    \list
    \o La possibilit� d'impl�menter des m�thodes virtuelles et des m�thodes 
    virtuelles pures pour obtenir exactement ce que l'on souhaite, avec la possibilit�
    d'utiliser l'impl�mentation de la classe m�re si besoin est.
    \o Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe,
    afin que les autres parties de l'application n'aient pas � se soucier de chacun des
    widgets qui forment l'interface utilisateur.
    \o La classe fille peut �tre utilis�e pour cr�er de nombreux widgets personnalis�s
    dans une m�me application ou biblioth�que, et le code de la classe fille peut �tre
    r�utilis� dans d'autres projets
    \endlist

    Comme Qt ne fournit pas de widget standard pour un carnet d'adresses, nous 
    partirons d'une classe de widget Qt standard et y ajouterons des fonctionnalit�s.
    La classe \c AddressBook cr�e dans ce tutoriel peut �tre r�utilis�e si on a besoin d'un
    widget carnet d'adresses basique.


    \section1 La classe AddressBook

    Le fichier \l{tutorials/addressbook-fr/part1/addressbook.h}{\c addressbook.h} permet de
    d�finir la classe \c AddressBook.

    On commence par d�finir \c AddressBook comme une classe fille de QWidget et d�clarer
    un constructeur. On utilise �galement la macro Q_OBJECT pour indiquer que la classe
    exploite les fonctionnalit�s de signaux et slots offertes par Qt ainsi que
    l'internationalisation, bien que nous ne les utilisions pas � ce stade.

    \snippet tutorials/addressbook-fr/part1/addressbook.h class definition

    La classe contient les d�clarations de \c nameLine et \c addressText,
    les instances priv�es de QLineEdit et QTextEdit mentionn�es pr�c�demment.
    Vous verrez, dans les chapitres � venir que les informations contenues
    dans \c nameLine et \c addressText sont n�cessaires � de nombreuses m�thodes
    du carnet d'adresses.

    Il n'est pas n�cessaire de d�clarer les objets QLabel que nous allons utiliser 
    puisque nous n'aurons pas besoin d'y faire r�f�rence apr�s leur cr�ation.
    La fa�on dont Qt g�re la parent� des objets est trait�e dans la section suivante.

    La macro Q_OBJECT impl�mente des fonctionnalit�s parmi les plus avanc�es de Qt.
    Pour le moment, il est bon de voir la macro Q_OBJECT comme un raccourci nous 
    permettant d'utiliser les m�thodes \l{QObject::}{tr()} et \l{QObject::}{connect()}.

    Nous en avons maintenant termin� avec le fichier \c addressbook.h et allons
    passer � l'impl�mentation du fichier \c addressbook.cpp.

    \section1 Impl�mentation de la classe AddressBook

    Le constructeur de la classe \c{AddressBook} prend en param�tre un QWidget, \e parent.
    Par convention, on passe ce param�tre au constructeur de la classe m�re.
    Ce concept de parent�, o� un parent peut avoir un ou plusieurs enfants, est utile
    pour regrouper les Widgets avec Qt. Par exemple, si vous d�truisez le parent,
    tous ses enfants seront d�truits �galament.


    \snippet tutorials/addressbook/part1/addressbook.cpp constructor and input fields

    � l'int�rieur de ce constructeur, on d�clare et instancie deux objets locaux
    QLabel, \c nameLabel et \c addressLabel, de m�me on instancie \c nameLine et
    \c addressText. La m�thode \l{QObject::tr()}{tr()} renvoie une version traduite
    de la cha�ne de caract�res, si elle existe; dans le cas contraire, elle renvoie
    la cha�ne elle m�me. On peut voir cette m�thode comme un marqueur \tt{<ins�rer
    la traduction ici>}, permettant de rep�rer les objets QString � consid�rer
    pour traduire une application. Vous remarquerez, dans les chapitres � venir
    comme dans les \l{Qt Examples}{exemples Qt}, qu'elle est utilis�e chaque fois
    que l'on utilise une cha�ne susceptible d'�tre traduite.

    Lorsque l'on programme avec Qt, il est utile de savoir comment fonctionnent les
    agencements ou layouts. Qt fournit trois classes principales de layouts pour
    contr�ler le placement des widgets: QHBoxLayout, QVBoxLayout et QGridLayout.

    \image addressbook-tutorial-part1-labeled-layout.png

    On utilise un QGridLayout pour positionner nos labels et champs de saisie de mani�re
    structur�e. QGridLayout divise l'espace disponible en une grille, et place les
    widgets dans les cellules que l'on sp�cifie par les num�ros de ligne et de colonne.
    Le diagramme ci-dessus pr�sente les cellules et la position des widgets, et cette
    organisation est obtenue � l'aide du code suivant:

    \snippet tutorials/addressbook/part1/addressbook.cpp layout

    On remarque que le label \c AddressLabel est positionn� en utilisant Qt::AlignTop
    comme argument optionnel. Ceci est destin� � assurer qu'il ne sera pas centr�
    verticalement dans la cellule (1,0). Pour un aper�u rapide des layouts de Qt,
    consultez la section \l{Layout Classes}.

    Afin d'installer l'objet layout dans un widget, il faut appeler la m�thode
    \l{QWidget::setLayout()}{setLayout()} du widget en question:

    \snippet tutorials/addressbook/part1/addressbook.cpp setting the layout

    Enfin, on initialise le titre du widget � "Simple Address Book"

    \section1 Ex�cution de l'application

    Un fichier s�par�, \c main.cpp, est utilis� pour la m�thode \c main(). Dans cette
    fonction, on cr�e une instance de QApplication, \c app. QApplication se charge de
    des ressources communes � l'ensemble de l'application, tel que les polices de
    caract�res et le curseur par d�faut, ainsi que de l'ex�cution de la boucle d'�v�nements.
    De ce fait, il y a toujours un objet QApplication dans toute application graphique en Qt.

    \snippet tutorials/addressbook/part1/main.cpp main function

    On construit un nouveau widget \c AddressBook sur le tas en utilisant le mot-cl�
    \c new et en invoquant sa m�thode \l{QWidget::show()}{show()} pour l'afficher.
    Cependant, le widget ne sera pas visible tant que la boucle d'�v�nements
    n'aura pas �t� lanc�e. On d�marre la boucle d'�v�nements en appelant la
    m�thode \l{QApplication::}{exec()} de l'application; le r�sultat renvoy�
    par cette m�thode est lui m�me utilis� comme valeur de retour pour la m�thode
    \c main().
*/

/*!
    \page tutorials-addressbook-fr-part2.html
    \previouspage {tutorials/addressbook-fr/part1}{Chapitre 1}
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \nextpage {tutorials/addressbook-fr/part3}{Chapitre 3}
    \example tutorials/addressbook-fr/part2
    \title Carnet d'adresses 2 - Ajouter des adresses

    La prochaine �tape pour cr�er notre carnet d'adresses est d'ajouter un soup�on
    d'interactivit�.

    \image addressbook-tutorial-part2-add-contact.png

    Nous allons fournir un bouton que l'utilisateur peut
    cliquer pour ajouter un nouveau contact. Une structure de donn�es est aussi
    n�cessaire afin de pouvoir stocker les contacts en m�moire.

    \section1 D�finition de la classe AddressBook

    Maintenant que nous avons mis en place les labels et les champs de saisie,
    nous ajoutons les boutons pour compl�ter le processus d'ajout d'un contact.
    Cela veut dire que notre fichier \c addressbook.h a maintenant trois
    objets QPushButton et trois slots publics correspondant.

    \snippet tutorials/addressbook/part2/addressbook.h slots

    Un slot est une m�thode qui r�pond � un signal. Nous allons
    voir ce concept en d�tail lorsque nous impl�menterons la classe \c{AddressBook}.
    Pour une explication d�taill�e du concept de signal et slot, vous pouvez
    vous r�f�rer au document \l{Signals and Slots}.

    Les trois objets QPushButton \c addButton, \c submitButton et \c cancelButton
    sont maintenant inclus dans la d�claration des variables priv�es, avec
    \c nameLine et \c addressText du chapitre pr�c�dent.

    \snippet tutorials/addressbook/part2/addressbook.h pushbutton declaration

    Nous avons besoin d'un conteneur pour stocker les contacts du carnet
    d'adresses, de fa�on � pouvoir les �num�rer et les afficher.
    Un objet QMap, \c contacts, est utilis� pour �a, car il permet de stocker
    des paires cl�-valeur: le nom du contact est la \e{cl�} et l'adresse du contact
    est la \e{valeur}.

    \snippet tutorials/addressbook/part2/addressbook.h remaining private variables

    Nous d�clarons aussi deux objects QString priv�s: \c oldName et \c oldAddress.
    Ces objets sont n�cessaires pour conserver le nom et l'adresse du dernier contact
    affich� avant que l'utilisateur ne clique sur le bouton "Add". Gr�ce � ces variables
    si l'utilisateur clique sur "Cancel", il est possible de revenir
    � l'affichage du dernier contact.

    \section1 Impl�mentation de la classe AddressBook

    Dans le constructeur de \c AddressBook, \c nameLine et
    \c addressText sont mis en mode lecture seule, de fa�on � autoriser l'affichage
    mais pas la modification du contact courant.

    \dots
    \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 1
    \dots
    \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 2

    Ensuite, nous instancions les boutons \c addButton, \c submitButton, et
    \c cancelButton.

    \snippet tutorials/addressbook/part2/addressbook.cpp pushbutton declaration

    Le bouton \c addButton est affich� en invoquant la m�thode \l{QPushButton::show()}
    {show()}, tandis que \c submitButton et \c cancelButton sont cach�s en invoquant
    \l{QPushButton::hide()}{hide()}. Ces deux boutons ne seront affich�s que lorsque 
    l'utilisateur cliquera sur "Add", et ceci est g�r� par la m�thode \c addContact()
    d�crite plus loin.

    \snippet tutorials/addressbook/part2/addressbook.cpp connecting signals and slots

    Nous connectons le signal \l{QPushButton::clicked()}{clicked()} de chaque bouton 
    au slot qui g�rera l'action.
    L'image ci-dessous illustre ceci:

    \image addressbook-tutorial-part2-signals-and-slots.png

    Ensuite, nous arrangeons proprement les boutons sur la droite du widget
    AddressBook, et nous utilisons un QVBoxLayout pour les aligner verticalement.

    \snippet tutorials/addressbook/part2/addressbook.cpp vertical layout

    La methode \l{QBoxLayout::addStretch()}{addStretch()} est utilis�e pour
    assurer que les boutons ne sont pas r�partis uniform�ment, mais regroup�s
    dans la partie supperieure du widget. La figure ci-dessous montre la diff�rence
    si \l{QBoxLayout::addStretch()}{addStretch()} est utilis� ou pas.

    \image addressbook-tutorial-part2-stretch-effects.png

    Ensuite nous ajoutons \c buttonLayout1 � \c mainLayout, en utilisant
    \l{QGridLayout::addLayout()}{addLayout()}. Ceci nous permet d'imbriquer les
    mises en page puisque \c buttonLayout1 est maintenant un enfant de \c mainLayout.

    \snippet tutorials/addressbook/part2/addressbook.cpp grid layout

    Les coordonn�es du layout global ressemblent maintenant � �a:

    \image addressbook-tutorial-part2-labeled-layout.png

    Dans la m�thode \c addContact(), nous stockons les d�tails du dernier
    contact affich� dans \c oldName et \c oldAddress. Ensuite, nous
    vidons ces champs de saisie et nous d�sactivons le mode
    lecture seule. Le focus est plac� sur \c nameLine et on affiche
    \c submitButton et \c cancelButton.

    \snippet tutorials/addressbook/part2/addressbook.cpp addContact

    La m�thode \c submitContact() peut �tre divis�e en trois parties:

    \list 1
    \o Nous extrayons les d�tails du contact depuis \c nameLine et \c addressText
    et les stockons dans des objets QString. Nous les validons pour s'assurer
    que l'utilisateur n'a pas cliqu� sur "Add" avec des champs de saisie
    vides; sinon un message est affich� avec QMessageBox pour rappeller �
    l'utilisateur que les deux champs doivent �tre compl�t�s.

    \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1

    \o Ensuite, nous v�rifions si le contact existe d�j�. Si aucun contacts
    existant n'entre en conflit avec le nouveau, nous l'ajoutons �
    \c contacts et nous affichons un QMessageBox pour informer l'utilisateur
    que le contact a �t� ajout�.

    \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part2

    Si le contact existe d�j�, nous affichons un QMessageBox pour informer
    l'utilisateur du probl�me.
    Notre objet \c contacts est bas� sur des paires cl�-valeur form�s par
    le nom et l'adresse, nous voulons nous assurer que la \e cl� est unique.

    \o Une fois que les deux v�rifications pr�c�dentes ont �t� trait�es,
    nous restaurons les boutons � leur �tat normal � l'aide du code
    suivant:

    \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3

    \endlist

    La capture d'�cran ci-dessous montre l'affichage fournit par un objet
    QMessageBox, utilis� ici pour afficher un message d'information
    � l'utilisateur:

    \image addressbook-tutorial-part2-add-successful.png

    La m�thode \c cancel() restaure les d�tails du dernier contact, active
    \c addButton, et cache \c submitButton et \c cancelButton.

    \snippet tutorials/addressbook/part2/addressbook.cpp cancel

    L'id�e g�n�rale pour augmenter la flexibilit� lors de l'ajout d'un 
    contact est de donner la possiblit� de cliquer sur "Add" 
    ou "Cancel" � n'importe quel moment.
    L'organigramme ci-dessous reprend l'ensemble des interactions d�velop�es
    jusqu'ici:

    \image addressbook-tutorial-part2-add-flowchart.png
*/

/*!
    \page tutorials-addressbook-fr-part3.html
    \previouspage {tutorials/addressbook-fr/part2}{Chapitre 2}
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \nextpage {tutorials/addressbook-fr/part4}{Chapitre 4}
    \example tutorials/addressbook-fr/part3
    \title Carnet d'adresses 3 - Navigation entre les �l�ments

    L'application "Carnet d'adresses" est maintenant � moiti� termin�e. Il
    nous faut maintenant ajouter quelques fonctions pour naviguer entre
    les contacts. Avant de commencer, il faut se d�cider sur le type de structure de
    donn�es le plus appropri� pour stocker les contacts.

    Dans le chapitre 2, nous avons utilis� un QMap utilisant des paires cl�-valeur,
    avec le nom du contact comme \e cl�, et l'adresse du contact comme \e valeur.
    Cela fonctionnait bien jusqu'ici, mais pour ajouter la navigation entre les
    entr�es, quelques am�liorations sont n�cessaires.

    Nous am�liorerons le QMap en le faisant ressembler � une structure de donn�es
    similaire � une liste li�e, o� tous les �l�ments sont connect�s, y compris
    le premier et le dernier �l�ment. La figure ci-dessous illustre cette structure
    de donn�e.

    \image addressbook-tutorial-part3-linkedlist.png

    \section1 D�finition de la classe AddressBook

    Pour ajouter les fonctions de navigation au carnet d'adresses, nous avons
    besoin de deux slots suppl�mentaires dans notre classe \c AddressBook:
    \c next() et \c previous(). Ceux-ci sont ajout�s au fichier addressbook.h:

    \snippet tutorials/addressbook/part3/addressbook.h navigation functions

    Nous avons aussi besoin de deux nouveaux objets QPushButton, nous ajoutons
    donc les variables priv�es \c nextButton et \c previousButton.

    \snippet tutorials/addressbook/part3/addressbook.h navigation pushbuttons

    \section1 Impl�mentation de la classe AddressBook

    A l'int�rieur du constructeur de \c AddressBook, dans \c addressbook.cpp, nous
    instancions \c nextButton et \c previousButton et nous les d�sactivons
    par d�faut. Nous faisons ceci car la navigation ne doit �tre activ�e
    que lorsqu'il y a plus d'un contact dans le carnet d'adresses.

    \snippet tutorials/addressbook/part3/addressbook.cpp navigation pushbuttons

    Nous connectons alors ces boutons � leur slots respectifs:

    \snippet tutorials/addressbook/part3/addressbook.cpp connecting navigation signals

    L'image ci-dessous montre l'interface utilisateur que nous allons cr�er.
    Remarquez que cela ressemble de plus en plus � l'interface du programme
    complet.

    \image addressbook-tutorial-part3-screenshot.png

    Nous suivons les conventions pour les fonctions \c next() et \c previous()
    en pla�ant \c nextButton � droite et \c previousButton � gauche. Pour
    faire cette mise en page intuitive, nous utilisons un QHBoxLayout pour
    placer les widgets c�te � c�te:

    \snippet tutorials/addressbook/part3/addressbook.cpp navigation layout

    L'objet QHBoxLayout, \c buttonLayout2, est ensuite ajout� � \c mainLayout.

    \snippet tutorials/addressbook/part3/addressbook.cpp adding navigation layout

    La figure ci-dessous montre les syst�mes de coordonn�es pour les widgets du
    \c mainLayout.
    \image addressbook-tutorial-part3-labeled-layout.png

    Dans notre m�thode \c addContact(), nous avons desactiv� ces boutons 
    pour �tre s�r que l'utilisateur n'utilise pas la navigation lors de 
    l'ajout d'un contact.

    \snippet tutorials/addressbook/part3/addressbook.cpp disabling navigation

    Dans notre m�thode \c submitContact(), nous activons les boutons de
    navigation, \c nextButton et \c previousButton, en fonction de la
    taille de \c contacts. Commen mentionn� plus t�t, la navigation n'est 
    activ�e que si il y a plus d'un contact dans le carnet d'adresses.
    Les lignes suivantes montrent comment faire cela:

    \snippet tutorials/addressbook/part3/addressbook.cpp enabling navigation

    Nous incluons aussi ces lignes de code dans le bouton \c cancel().

    Souvenez vous que nous voulons �muler une liste-li�e ciruculaire �
    l'aide de l'objet QMap, \c contacts. Pour faire cela, nous obtenons un it�rateur 
    sur \c contact dans la m�thode \c next(), et ensuite:

    \list
        \o Si l'it�rateur n'est pas � la fin de \c contacts, nous l'incr�mentons
        \o Si l'it�rateur est � la fin de \c contacts, nous changeons sa position
        jusqu'au d�but de \c contacts. Cela donne l'illusion que notre QMap 
        fonctionne comme une liste circulaire.
    \endlist

    \snippet tutorials/addressbook/part3/addressbook.cpp next() function

    Une fois que nous avons it�r� jusqu'� l'objet recherch� dans \c contacts,
    nous affichons son contenu sur \c nameLine et \c addressText.

    De la m�me fa�on, pour la m�thode \c previous(), nous obtenons un 
    it�rateur sur \c contacts et ensuite:

    \list
        \o Si l'it�rateur est � la fin de \c contacts, on r�initialise
           l'affichage et on retourne.
        \o Si l'it�rateur est au d�but de \c contacts, on change sa 
           position jusqu'� la fin
        \o Ensuite, on d�cr�mente l'it�rateur
    \endlist

    \snippet tutorials/addressbook/part3/addressbook.cpp previous() function

    � nouveau, nous affichons le contenu de l'objet courant dans \c contacts.

*/

/*!

    \page tutorials-addressbook-fr-part4.html
    \previouspage {tutorials/addressbook-fr/part3}{Chapitre 3}
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \nextpage {tutorials/addressbook-fr/part5}{Chapitre 5}
    \example tutorials/addressbook-fr/part4
    \title Carnet d'Adresses 4 - �diter et supprimer des adresses


    Dans ce chapitre, nous verrons comment modifier les donn�es des contacts
    contenus dans l'application carnet d'adresses.


    \image addressbook-tutorial-screenshot.png

    Nous avons maintenant un carnet d'adresses qui ne se contente pas de
    lister des contacts de fa�on ordonn�e, mais permet �galement la 
    navigation. Il serait pratique d'inclure des fonctions telles qu'�diter et
    supprimer, afin que les d�tails associ�s � un contact puissent �tre
    modifi�s lorsque c'est n�cessaire. Cependant, cela requiert une l�g�re
    modification, sous la forme d'�num�rations. Au chapitre pr�c�dent, nous avions deux
    modes: \c {AddingMode} et \c {NavigationMode}, mais ils n'�taient pas
    d�finis en tant qu'�num�rations. Au lieu de �a, on activait et d�sactivait les
    boutons correspondants manuellement, au prix de multiples redondances dans
    le code.

    Dans ce chapitre, on d�finit l'�num�ration \c Mode avec trois valeurs possibles.

    \list
        \o \c{NavigationMode},
        \o \c{AddingMode}, et
        \o \c{EditingMode}.
    \endlist

    \section1 D�finition de la classe AddressBook

    Le fichier \c addressbook.h est mis a jour pour contenir l'�num�ration \c Mode :

    \snippet tutorials/addressbook/part4/addressbook.h Mode enum

    On ajoute �galement deux nouveaux slots, \c editContact() et
    \c removeContact(), � notre liste de slots publics.

    \snippet tutorials/addressbook/part4/addressbook.h edit and remove slots

    Afin de basculer d'un mode � l'autre, on introduit la m�thode
    \c updateInterface() pour contr�ller l'activation et la d�sactivation de
    tous les objets QPushButton. On ajoute �galement deux nouveaux boutons,
    \c editButton et \c removeButton, pour les fonctions d'�dition
    et de suppression mentionn�es plus haut.

    \snippet tutorials/addressbook/part4/addressbook.h updateInterface() declaration
    \dots
    \snippet tutorials/addressbook/part4/addressbook.h buttons declaration
    \dots
    \snippet tutorials/addressbook/part4/addressbook.h mode declaration

    Enfin, on d�clare \c currentMode pour garder une trace du mode 
    actuellement utilis�.

    \section1 Impl�mentation de la classe AddressBook

    Il nous faut maintenant impl�menter les fonctionnalit�s de changement de
    mode de l'application carnet d'adresses. Les boutons \c editButton et
    \c removeButton sont instanci�s et d�sactiv�s par d�faut, puisque le
    carnet d'adresses d�marre sans aucun contact en m�moire.

    \snippet tutorials/addressbook/part4/addressbook.cpp edit and remove buttons

    Ces boutons sont ensuite connect�s � leurs slots respectifs,
    \c editContact() et \c removeContact(), avant d'�tre ajout�s �
    \c buttonLayout1.

    \snippet tutorials/addressbook/part4/addressbook.cpp connecting edit and remove
    \dots
    \snippet tutorials/addressbook/part4/addressbook.cpp adding edit and remove to the layout

    La methode \c editContact() place les anciens d�tails du contact dans
    \c oldName et \c oldAddress, avant de basculer vers le mode
    \c EditingMode. Dans ce mode, les boutons \c submitButton et
    \c cancelButton sont tous deux activ�s, l'utilisateur peut par cons�quent
    modifier les d�tails du contact et cliquer sur l'un de ces deux boutons
    par la suite.

    \snippet tutorials/addressbook/part4/addressbook.cpp editContact() function

    La m�thode \c submitContact() a �t� divis�e en deux avec un bloc
    \c{if-else}. On teste \c currentMode pour voir si le mode courant est
    \c AddingMode. Si c'est le cas, on proc�de � l'ajout.

    \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function beginning
    \dots
    \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part1

    Sinon, on s'assure que \c currentMode est en \c EditingMode. Si c'est le
    cas, on compare \c oldName et \c name. Si le nom a chang�, on supprime
    l'ancien contact de \c contacts et on ins�re le contact mis a jour.

    \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part2

    Si seule l'adresse a chang� (i.e. \c oldAddress n'est pas identique �
    \c address), on met � jour l'adresse du contact. Enfin on r�gle
    \c currentMode � \c NavigationMode. C'est une �tape importante puisque
    c'est cela qui r�active tous les boutons d�sactiv�s.

    Afin de retirer un contact du carnet d'adresses, on impl�mente la m�thode
    \c removeContact(). Cette m�thode v�rifie que le contact est pr�sent dans
    \c contacts.

    \snippet tutorials/addressbook/part4/addressbook.cpp removeContact() function

    Si c'est le cas, on affiche une bo�te de dialogue QMessageBox, demandant
    confirmation de la suppression � l'utilisateur. Une fois la confirmation
    effectu�e, on appelle \c previous(), afin de s'assurer que l'interface
    utilisateur affiche une autre entr�e, et on supprime le contact en
    utilisant le m�thode \l{QMap::remove()}{remove()} de \l{QMap}. Dans un
    souci pratique, on informe l'utilisateur de la suppression par le biais
    d'une autre QMessageBox. Les deux bo�tes de dialogue utilis�es dans cette
    m�thode sont repr�sent�es ci-dessous.

    \image addressbook-tutorial-part4-remove.png

    \section2 Mise � jour de l'Interface utilisateur

    On a �voqu� plus haut la m�thode \c updateInterface() comme moyen
    d'activer et de d�sactiver les diff�rents boutons de l'interface en
    fonction du mode. Cette m�thode met � jour le mode courant selon
    l'argument \c mode qui lui est pass�, en l'assignant � \c currentMode,
    avant de tester sa valeur.

    Chacun des boutons est ensuite activ� ou d�sactiv�, en fonction du mode.
    Le code source pour les cas \c AddingMode et \c EditingMode est visible 
    ci-dessous:

    \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 1

    Dans le cas de \c NavigationMode, en revanche, des tests conditionnels
    sont pass�s en param�tre de QPushButton::setEnabled(). Ceci permet de
    s'assurer que les boutons \c editButton et \c removeButton ne sont activ�s
    que s'il existe au moins un contact dans le carnet d'adresses;
    \c nextButton et \c previousButton ne sont activ�s que lorsqu'il existe
    plus d'un contact dans le carnet d'adresses.

    \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 2

    En effectuant les op�rations de r�glage du mode et de mise � jour de
    l'interface utilisateur au sein de la m�me m�thode, on est � l'abri de
    l'�ventualit� o� l'interface utilisateur se "d�synchronise" de l'�tat
    interne de l'application.

*/

/*!
    \page tutorials-addressbook-fr-part5.html
    \previouspage {tutorials/addressbook-fr/part4}{Chapitre 4}
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \nextpage {tutorials/addressbook-fr/part6}{Chapitre 6}
    \example tutorials/addressbook-fr/part5
    \title Carnet d'adresse 5 - Ajout d'une fonction de recherche

    Dans ce chapitre, nous allons voir les possibilit�s pour rechercher
    des contacts dans le carnet d'adresse.

    \image addressbook-tutorial-part5-screenshot.png

    Plus nous ajoutons des contacts dans l'application, plus
    il devient difficile de naviguer avec les boutons \e Next et \e Previous.
    Dans ce cas, une fonction de recherche serait plus efficace pour rechercher
    les contacts.
    La capture d'�cran ci-dessus montre le bouton de recherche \e Find et sa position
    dans le paneau de bouton.

    Lorsque l'utilisateur clique sur le bouton \e Find, il est courant d'afficher
    une bo�te de dialogue qui demande � l'utilisateur d'entrer un nom de contact.
    Qt fournit la classe QDialog, que nous sous-classons dans ce chapitre pour
    impl�menter la class \c FindDialog.

    \section1 D�finition de la classe FindDialog

    \image addressbook-tutorial-part5-finddialog.png

    Pour sous-classer QDialog, nous commen�ons par inclure le header de
    QDialog dans le fichier \c finddialog.h. De plus, nous d�clarons les
    classes QLineEdit et QPushButton car nous utilisons ces widgets dans
    notre classe dialogue.

    Tout comme dans la classe \c AddressBook, la classe \c FindDialog utilise
    la macro Q_OBJECT et son constructeur est d�fini de fa�on � accepter
    un QWidget parent, m�me si cette bo�te de dialogue sera affich�e dans une
    fen�tre s�par�e.

    \snippet tutorials/addressbook/part5/finddialog.h FindDialog header

    Nous d�finissons la m�thode publique \c getFindText() pour �tre utilis�e
    par les classes qui instancient \c FindDialog, ce qui leur permet d'obtenir
    le texte entr� par l'utilisateur. Un slot public, \c findClicked(), est
    d�fini pour prendre en charge le texte lorsque l'utilisateur clique sur
    le bouton \gui Find.

    Finalement, nous d�finissons les variables priv�es \c findButton,
    \c lineEdit et \c findText, qui correspondent respectivement au bouton
    \gui Find, au champ de texte dans lequel l'utilisateur tape le texte
    � rechercher, et � une variable interne stockant le texte pour une
    utilisation ult�rieure.

    \section1 Impl�mentation de la classe FindDialog

    Dans le constructeur de \c FindDialog, nous instancions les objets des
    variables priv�es \c lineEdit, \c findButton et \c findText. Nous utilisons ensuite
    un QHBoxLayout pour positionner les widgets.

    \snippet tutorials/addressbook/part5/finddialog.cpp constructor

    Nous mettons en place la mise en page et le titre de la fen�tre, et
    nous connectons les signaux aux slots. Remarquez que le signal
    \l{QPushButton::clicked()}{clicked()} de \c{findButton} est connect�
    � \c findClicked() et \l{QDialog::accept()}{accept()}. Le slot
    \l{QDialog::accept()}{accept()} fourni par le QDialog ferme
    la bo�te de dialogue et lui donne le code de retour \l{QDialog::}{Accepted}.
    Nous utilisons cette fonction pour aider la m�thode \c findContact() de la classe
    \c{AddressBook} � savoir si l'objet \c FindDialog a �t� ferm�. Ceci sera
    expliqu� plus loin lorsque nous verrons la m�thode \c findContact().

    \image addressbook-tutorial-part5-signals-and-slots.png

    Dans \c findClicked(), nous validons le champ de texte pour nous
    assurer que l'utilisateur n'a pas cliqu� sur le bouton \gui Find sans
    avoir entr� un nom de contact. Ensuite, nous stockons le texte du champ
    d'entr�e \c lineEdit dans \c findText. Et finalement nous vidons le
    contenu de \c lineEdit et cachons la bo�te de dialogue.

    \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function

    La variable \c findText a un accesseur publique associ�: \c getFindText().
    �tant donn� que nous ne modifions \c findText directement que dans le
    constructeur et la m�thode \c findClicked(), nous ne cr�ons pas
    de manipulateurs associ� � \c getFindText().
    Puisque \c getFindText() est publique, les classes instanciant et
    utilisant \c FindDialog peuvent toujours acc�der � la cha�ne de
    caract�res que l'utilisateur a entr� et accept�.

    \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function

    \section1 D�finition de la classe AddressBook

    Pour utiliser \c FindDialog depuis la classe \c AddressBook, nous
    incluons \c finddialog.h dans le fichier \c addressbook.h.

    \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header

    Jusqu'ici, toutes les fonctionnalit�s du carnet d'adresses ont un
    QPushButton et un slot correspondant. De la m�me fa�on, pour la
    fonctionnalit� \gui Find, nous avons \c findButton et \c findContact().

    Le \c findButton est d�clar� comme une variable priv�e et la
    m�thode \c findContact() est d�clar�e comme un slot public.

    \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration
    \dots
    \snippet tutorials/addressbook/part5/addressbook.h findButton declaration

    Finalement, nous d�clarons la variable priv�e \c dialog que nous allons
    utiliser pour acc�der � une instance de \c FindDialog.

    \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration

    Une fois que nous avons instanci� la bo�te de dialogue, nous voulons l'utiliser
    plus qu'une fois. Utiliser une variable priv�e nous permet d'y r�f�rer
    � plus d'un endroit dans la classe.

    \section1 Impl�mentation de la classe AddressBook

    Dans le constructeur de \c AddressBook, nous instancions nos objets priv�s,
    \c findbutton et \c findDialog:

    \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton
    \dots
    \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog

    Ensuite, nous connectons le signal \l{QPushButton::clicked()}{clicked()} de
    \c{findButton} � \c findContact().

    \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find

    Maintenant, tout ce qui manque est le code de notre m�thode \c findContact():

    \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function

    Nous commen�ons par afficher l'instance de \c FindDialog, \c dialog.
    L'utilisateur peut alors entrer le nom du contact � rechercher. Lorsque
    l'utilisateur clique sur le bouton \c findButton, la bo�te de dialogue est
    masqu�e et le code de retour devient QDialog::Accepted. Ce code de retour
    vient remplir la condition du premier if.

    Ensuite, nous extrayons le texte que nous utiliserons pour la recherche,
    il s'agit ici de \c contactName obtenu � l'aide de la m�thode \c getFindText()
    de \c FindDialog. Si le contact existe dans le carnet d'adresse, nous
    l'affichons directement. Sinon, nous affichons le QMessageBox suivant pour
    indiquer que la recherche � �chou�e.

    \image addressbook-tutorial-part5-notfound.png
*/

/*!
    \page tutorials-addressbook-part6.html
    \previouspage {tutorials/addressbook-fr/part5}{Chapitre 5}
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \nextpage {tutorials/addressbook-fr/part7}{Chapitre 7}
    \example tutorials/addressbook-fr/part6
    \title Carnet d'Adresses 6 - Sauvegarde et chargement

    Ce chapitre couvre les fonctionnalit�s de gestion des fichiers de Qt que
    l'on utilise pour �crire les proc�dures de sauvegarde et chargement pour
    l'application carnet d'adresses.

    \image addressbook-tutorial-part6-screenshot.png

    Bien que la navigation et la recherche de contacts soient des
    fonctionnalit�s importantes, notre carnet d'adresses ne sera pleinement
    utilisable qu'une fois que l'on pourra sauvegarder les contacts existants
    et les charger � nouveau par la suite.
    Qt fournit de nombreuses classes pour g�rer les \l{Input/Output and
    Networking}{entr�es et sorties}, mais nous avons choisi de nous contenter d'une
    combinaison de deux classes simples � utiliser ensemble: QFile et QDataStream.

    Un objet QFile repr�sente un fichier sur le disque qui peut �tre lu, et
    dans lequel on peut �crire. QFile est une classe fille de la classe plus
    g�n�rique QIODevice, qui peut repr�senter diff�rents types de
    p�riph�riques.

    Un objet QDataStream est utilis� pour s�rialiser des donn�es binaires
    dans le but de les passer � un QIODevice pour les r�cup�rer dans le
    futur. Pour lire ou �crire dans un QIODevice, il suffit d'ouvrir le
    flux, avec le p�riph�rique appropri� en param�tre, et d'y lire ou
    �crire.

    \section1 D�finition de la classe AddressBook

    On d�clare deux slots publics, \c saveToFile() et \c loadFromFile(), 
    ainsi que deux objets QPushButton, \c loadButton et \c saveButton.

    \snippet tutorials/addressbook/part6/addressbook.h save and load functions declaration
    \dots
    \snippet tutorials/addressbook/part6/addressbook.h save and load buttons declaration

    \section1 Impl�mentation de la classe AddressBook

    Dans notre constructeur, on instancie \c loadButton et \c saveButton.
    Id�alement, l'interface serait plus conviviale avec des boutons
    affichant "Load contacts from a file" et "Save contacts to a file". Mais
    compte tenu de la dimension des autres boutons, on initialise les labels
    des boutons � \gui{Load...} et \gui{Save...}. Heureusement, Qt offre une
    fa�on simple d'ajouter des info-bulles avec
    \l{QWidget::setToolTip()}{setToolTip()}, et nous l'exploitons de la fa�on
    suivante pour nos boutons:

    \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1
    \dots
    \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2

    Bien qu'on ne cite pas le code correspondant ici, nous ajoutons ces deux boutons au
    layout de droite, \c button1Layout, comme pour les fonctionnalit�s pr�c�dentes, et 
    nous connectons leurs signaux
    \l{QPushButton::clicked()}{clicked()} � leurs slots respectifs.

    Pour la sauvegarde, on commence par r�cup�rer le nom de fichier 
    \c fileName, en utilisant QFileDialog::getSaveFileName(). C'est une
    m�thode pratique fournie par QFileDialog, qui ouvre une bo�te de
    dialogue modale et permet � l'utilisateur d'entrer un nom de fichier ou
    de choisir un fichier \c{.abk} existant. Les fichiers \c{.abk}
    correspondent � l'extension choisie pour la sauvegarde des contacts de
    notre carnet d'adresses.

    \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1

    La bo�te de dialogue affich�e est visible sur la capture d'�cran ci-
    dessous.

    \image addressbook-tutorial-part6-save.png

    Si \c fileName n'est pas vide, on cr�e un objet QFile, \c file, � partir
    de \c fileName. QFile fonctionne avec QDataStream puisqu'il d�rive de
    QIODevice.

    Ensuite, on essaie d'ouvrir le fichier en �criture, ce qui correspond au
    mode \l{QIODevice::}{WriteOnly}. Si cela �choue, on en informe
    l'utilisateur avec une QMessageBox.

    \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2

    Dans le cas contraire, on instancie un objet QDataStream, \c out, afin
    d'�crire dans le fichier ouvert. QDataStream n�cessite que la m�me
    version de flux soit utilis�e pour la lecture et l'�criture. On s'assure
    que c'est le cas en sp�cifiant explicitement d'utiliser la
    \l{QDataStream::Qt_4_5}{version introduite avec Qt 4.5} avant de
    s�rialiser les donn�es vers le fichier \c file.

    \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3

    Pour le chargement, on r�cup�re �galement \c fileName en utilisant
    QFileDialog::getOpenFileName(). Cette m�thode est l'homologue de
    QFileDialog::getSaveFileName() et affiche �galement une bo�te de
    dialogue modale permettant � l'utilisateur d'entrer un nom de fichier ou
    de selectionner un fichier \c{.abk} existant, afin de le charger dans le
    carnet d'adresses.

    \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1

    Sous Windows, par exemple, cette m�thode affiche une bo�te de dialogue
    native pour la s�lection de fichier, comme illustr� sur la capture
    d'�cran suivante:

    \image addressbook-tutorial-part6-load.png

    Si \c fileName n'est pas vide, on utilise une fois de plus un objet
    QFile, \c file, et on tente de l'ouvrir en lecture, avec le mode
    \l{QIODevice::}{ReadOnly}. De m�me que pr�c�demment dans notre
    impl�mentation de \c saveToFile(), si cette tentative s'av�re
    infructueuse, on en informe l'utilisateur par le biais d'une
    QMessageBox.

    \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2

    Dans le cas contraire, on instancie un objet QDataStream, \c in, en
    sp�cifiant la version � utiliser comme pr�c�demment, et on lit les
    informations s�rialis�es vers la structure de donn�es \c contacts. Notez
    qu'on purge \c contacts avant d'y mettre les informations lues afin de
    simplifier le processus de lecture de fichier. Une fa�on plus avanc�e de
    proc�der serait de lire les contacts dans un objet QMap temporaire, et
    de copier uniquement les contacts n'existant pas encore dans
    \c contacts.

    \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3

    Pour afficher les contacts lus depuis le fichier, on doit d'abord
    valider les donn�es obtenues afin de s'assurer que le fichier lu
    contient effectivement des entr�es de carnet d'adresses. Si c'est le
    cas, on affiche le premier contact; sinon on informe l'utilisateur du
    probl�me par une QMessageBox. Enfin, on met � jour l'interface afin
    d'activer et de d�sactiver les boutons de fa�on appropri�e.
*/

/*!
    \page tutorials-addressbook-fr-part7.html
    \previouspage {tutorials/addressbook-fr/part6}{Chapitre 6}
    \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
    \example tutorials/addressbook-fr/part7
    \title Carnet d'adresse 7 - Fonctionnalit�s avanc�es

    Ce chapitre couvre quelques fonctionnalit�s additionnelles qui
    feront de notre carnet d'adresses une application plus pratique
    pour une utilisation quotidienne.

    \image addressbook-tutorial-part7-screenshot.png

    Bien que notre application carnet d'adresses soit utile en tant que telle,
    il serait pratique de pouvoir �changer les contacts avec d'autres applications.
    Le format vCard est un un format de fichier populaire pour �changer
    ce type de donn�es.
    Dans ce chapitre, nous �tendrons notre carnet d'adresses pour permettre
    d'exporter des contacts dans des fichiers vCard \c{.vcf}.

    \section1 D�finition de la classe AddressBook

    Nous ajoutons un objet QPushButton, \c exportButton, et un slot
    public correspondant, \c exportAsVCard(), � notre classe \c AddressBook 
    dans le fichier \c addressbook.h.

    \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration
    \dots
    \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration

    \section1 Impl�mentation de la classe AddressBook

    Dans le constructeur de \c AddressBook, nous connectons le signal
    \l{QPushButton::clicked()}{clicked()} de \c{exportButton} au slot
    \c exportAsVCard().
    Nous ajoutons aussi ce bouton � \c buttonLayout1, le layout responsable
    du groupe de boutons sur la droite.

    Dans la m�thode \c exportAsVCard(), nous commen�ons par extraire le
    nom du contact dans \n name. Nous d�clarons \c firstname, \c lastName et
    \c nameList.
    Ensuite, nous cherchons la position du premier espace blanc de \c name.
    Si il y a un espace, nous s�parons le nom du contact en \c firstName et
    \c lastName. Finalement, nous rempla�ons l'espace par un underscore ("_").
    Si il n'y a pas d'espace, nous supposons que le contact ne comprend que
    le pr�nom.

    \snippet tutorials/addressbook/part7/addressbook.cpp export function part1

    Comme pour la m�thode \c saveToFile(), nous ouvrons une bo�te de dialogue
    pour donner la possibilit� � l'utilisateur de choisir un emplacement pour
    le fichier. Avec le nom de fichier choisi, nous cr�ons une instance de QFile
    pour y �crire.

    Nous essayons d'ouvrir le fichier en mode \l{QIODevice::}{WriteOnly}. Si
    cela �choue, nous affichons un QMessageBox pour informer l'utilisateur
    � propos de l'origine du probl�me et nous quittons la m�thode. Sinon, nous passons le
    fichier comme param�tre pour cr�er un objet QTextStream, \c out. De la m�me fa�on que
    QDataStream, la classe QTextStream fournit les fonctionnalit�s pour 
    lire et �crire des fichiers de texte. Gr�ce � cel�, le fichier \c{.vcf}
    g�n�r� pourra �tre ouvert et �dit� � l'aide d'un simple �diteur de texte.

    \snippet tutorials/addressbook/part7/addressbook.cpp export function part2

    Nous �crivons ensuite un fichier vCard avec la balise \c{BEGIN:VCARD},
    suivit par \c{VERSION:2.1}.
    Le nom d'un contact est �crit � l'aide de la balise \c{N:}. Pour la balise
    \c{FN:}, qui remplit le titre du contact, nous devons v�rifier si le contact
    � un nom de famille d�fini ou non. Si oui, nous utilions les d�tails de
    \c nameList pour remplir le champ, dans le cas contraire on �crit uniquement le contenu
    de \c firstName.
 
    \snippet tutorials/addressbook/part7/addressbook.cpp export function part3

    Nous continuons en �crivant l'adresse du contact. Les points-virgules
    dans l'adresse sont �chapp�s � l'aide de "\\", les retours de ligne sont
    remplac�s par des points-virgules, et les vigules sont remplac�es par des espaces.
    Finalement nous �crivons les balises  \c{ADR;HOME:;} suivies par l'adresse
    et la balise \c{END:VCARD}.

    \snippet tutorials/addressbook/part7/addressbook.cpp export function part4

    � la fin de la m�thode, un QMessageBox est affich� pour informer l'utilisateur
    que la vCard a �t� export�e avec succ�s. 

    \e{vCard est une marque d�pos�e de \l{http://www.imc.org}
    {Internet Mail Consortium}}.
*/