diff options
Diffstat (limited to 'examples/widgets')
-rw-r--r-- | examples/widgets/doc/images/itemviewspuzzle-example.png | bin | 0 -> 211091 bytes | |||
-rw-r--r-- | examples/widgets/doc/src/addressbook-fr.qdoc | 1033 | ||||
-rw-r--r-- | examples/widgets/doc/src/addressbook-tutorial.qdoc | 979 | ||||
-rw-r--r-- | examples/widgets/doc/src/addressbook.qdoc (renamed from examples/widgets/doc/addressbook.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/affine.qdoc (renamed from examples/widgets/doc/affine.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/analogclock.qdoc (renamed from examples/widgets/doc/analogclock.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/animatedtiles.qdoc (renamed from examples/widgets/doc/animatedtiles.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/appchooser.qdoc (renamed from examples/widgets/doc/appchooser.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/application.qdoc (renamed from examples/widgets/doc/application.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/applicationicon.qdoc | 67 | ||||
-rw-r--r-- | examples/widgets/doc/src/basicdrawing.qdoc (renamed from examples/widgets/doc/basicdrawing.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/basicgraphicslayouts.qdoc (renamed from examples/widgets/doc/basicgraphicslayouts.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/basiclayouts.qdoc (renamed from examples/widgets/doc/basiclayouts.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/basicsortfiltermodel.qdoc (renamed from examples/widgets/doc/basicsortfiltermodel.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/blurpicker.qdoc (renamed from examples/widgets/doc/blurpicker.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/borderlayout.qdoc (renamed from examples/widgets/doc/borderlayout.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/boxes.qdoc (renamed from examples/widgets/doc/boxes.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/calculator.qdoc (renamed from examples/widgets/doc/calculator.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/calendar.qdoc (renamed from examples/widgets/doc/calendar.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/calendarwidget.qdoc (renamed from examples/widgets/doc/calendarwidget.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/charactermap.qdoc (renamed from examples/widgets/doc/charactermap.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/chart.qdoc (renamed from examples/widgets/doc/chart.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/chip.qdoc (renamed from examples/widgets/doc/chip.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/classwizard.qdoc (renamed from examples/widgets/doc/classwizard.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/codeeditor.qdoc (renamed from examples/widgets/doc/codeeditor.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/coloreditorfactory.qdoc (renamed from examples/widgets/doc/coloreditorfactory.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/combowidgetmapper.qdoc (renamed from examples/widgets/doc/combowidgetmapper.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/composition.qdoc (renamed from examples/widgets/doc/composition.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/concentriccircles.qdoc (renamed from examples/widgets/doc/concentriccircles.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/configdialog.qdoc (renamed from examples/widgets/doc/configdialog.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/customsortfiltermodel.qdoc (renamed from examples/widgets/doc/customsortfiltermodel.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/deform.qdoc (renamed from examples/widgets/doc/deform.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/diagramscene.qdoc (renamed from examples/widgets/doc/diagramscene.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/digitalclock.qdoc (renamed from examples/widgets/doc/digitalclock.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/dirview.qdoc (renamed from examples/widgets/doc/dirview.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/dockwidgets.qdoc (renamed from examples/widgets/doc/dockwidgets.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/draganddroppuzzle.qdoc (renamed from examples/widgets/doc/draganddroppuzzle.qdoc) | 2 | ||||
-rw-r--r-- | examples/widgets/doc/src/dragdroprobot.qdoc (renamed from examples/widgets/doc/dragdroprobot.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/draggableicons.qdoc | 90 | ||||
-rw-r--r-- | examples/widgets/doc/src/draggabletext.qdoc | 36 | ||||
-rw-r--r-- | examples/widgets/doc/src/dynamiclayouts.qdoc (renamed from examples/widgets/doc/dynamiclayouts.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/easing.qdoc (renamed from examples/widgets/doc/easing.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/editabletreemodel.qdoc (renamed from examples/widgets/doc/editabletreemodel.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/elasticnodes.qdoc (renamed from examples/widgets/doc/elasticnodes.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/elidedlabel.qdoc (renamed from examples/widgets/doc/elidedlabel.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/embeddeddialogs.qdoc (renamed from examples/widgets/doc/embeddeddialogs.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/eventtransitions.qdoc (renamed from examples/widgets/doc/eventtransitions.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/extension.qdoc (renamed from examples/widgets/doc/extension.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/factorial.qdoc (renamed from examples/widgets/doc/factorial.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/fademessage.qdoc (renamed from examples/widgets/doc/fademessage.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/fetchmore.qdoc (renamed from examples/widgets/doc/fetchmore.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/findfiles.qdoc (renamed from examples/widgets/doc/findfiles.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/flowlayout.qdoc (renamed from examples/widgets/doc/flowlayout.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/fontsampler.qdoc (renamed from examples/widgets/doc/fontsampler.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/frozencolumn.qdoc (renamed from examples/widgets/doc/frozencolumn.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/gradients.qdoc (renamed from examples/widgets/doc/gradients.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/groupbox.qdoc (renamed from examples/widgets/doc/groupbox.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/icons.qdoc (renamed from examples/widgets/doc/icons.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/imagecomposition.qdoc (renamed from examples/widgets/doc/imagecomposition.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/imageviewer.qdoc (renamed from examples/widgets/doc/imageviewer.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/interview.qdoc (renamed from examples/widgets/doc/interview.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/itemviewspuzzle.qdoc (renamed from examples/widgets/doc/itemviewspuzzle.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/licensewizard.qdoc (renamed from examples/widgets/doc/licensewizard.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/lighting.qdoc (renamed from examples/widgets/doc/lighting.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/lineedits.qdoc (renamed from examples/widgets/doc/lineedits.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/mainwindow.qdoc (renamed from examples/widgets/doc/mainwindow.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/mdi.qdoc (renamed from examples/widgets/doc/mdi.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/menus.qdoc (renamed from examples/widgets/doc/menus.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/moveblocks.qdoc (renamed from examples/widgets/doc/moveblocks.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/movie.qdoc (renamed from examples/widgets/doc/movie.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/orderform.qdoc (renamed from examples/widgets/doc/orderform.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/padnavigator.qdoc (renamed from examples/widgets/doc/padnavigator.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/painterpaths.qdoc (renamed from examples/widgets/doc/painterpaths.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/pathstroke.qdoc (renamed from examples/widgets/doc/pathstroke.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/pingpong.qdoc (renamed from examples/widgets/doc/pingpong.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/pixelator.qdoc (renamed from examples/widgets/doc/pixelator.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/recentfiles.qdoc (renamed from examples/widgets/doc/recentfiles.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/rogue.qdoc (renamed from examples/widgets/doc/rogue.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/screenshot.qdoc (renamed from examples/widgets/doc/screenshot.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/scribble.qdoc (renamed from examples/widgets/doc/scribble.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/sdi.qdoc (renamed from examples/widgets/doc/sdi.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/shapedclock.qdoc (renamed from examples/widgets/doc/shapedclock.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/simpledommodel.qdoc (renamed from examples/widgets/doc/simpledommodel.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/simpletreemodel.qdoc (renamed from examples/widgets/doc/simpletreemodel.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/simplewidgetmapper.qdoc (renamed from examples/widgets/doc/simplewidgetmapper.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/sipdialog.qdoc (renamed from examples/widgets/doc/sipdialog.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/sliders.qdoc (renamed from examples/widgets/doc/sliders.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/spinboxdelegate.qdoc (renamed from examples/widgets/doc/spinboxdelegate.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/spinboxes.qdoc (renamed from examples/widgets/doc/spinboxes.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/spreadsheet.qdoc (renamed from examples/widgets/doc/spreadsheet.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/standarddialogs.qdoc (renamed from examples/widgets/doc/standarddialogs.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/stardelegate.qdoc (renamed from examples/widgets/doc/stardelegate.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/states.qdoc (renamed from examples/widgets/doc/states.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/stickman.qdoc (renamed from examples/widgets/doc/stickman.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/styles.qdoc (renamed from examples/widgets/doc/styles.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/stylesheet.qdoc (renamed from examples/widgets/doc/stylesheet.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/sub-attaq.qdoc (renamed from examples/widgets/doc/sub-attaq.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/syntaxhighlighter.qdoc (renamed from examples/widgets/doc/syntaxhighlighter.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/tabdialog.qdoc (renamed from examples/widgets/doc/tabdialog.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/tablet.qdoc (renamed from examples/widgets/doc/tablet.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/tetrix.qdoc (renamed from examples/widgets/doc/tetrix.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/textedit.qdoc (renamed from examples/widgets/doc/textedit.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/tooltips.qdoc (renamed from examples/widgets/doc/tooltips.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/trafficlight.qdoc (renamed from examples/widgets/doc/trafficlight.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/transformations.qdoc (renamed from examples/widgets/doc/transformations.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/trivialwizard.qdoc (renamed from examples/widgets/doc/trivialwizard.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/twowaybutton.qdoc (renamed from examples/widgets/doc/twowaybutton.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/wiggly.qdoc (renamed from examples/widgets/doc/wiggly.qdoc) | 0 | ||||
-rw-r--r-- | examples/widgets/doc/src/windowflags.qdoc (renamed from examples/widgets/doc/windowflags.qdoc) | 0 |
109 files changed, 2206 insertions, 1 deletions
diff --git a/examples/widgets/doc/images/itemviewspuzzle-example.png b/examples/widgets/doc/images/itemviewspuzzle-example.png Binary files differnew file mode 100644 index 0000000000..05ae28be81 --- /dev/null +++ b/examples/widgets/doc/images/itemviewspuzzle-example.png diff --git a/examples/widgets/doc/src/addressbook-fr.qdoc b/examples/widgets/doc/src/addressbook-fr.qdoc new file mode 100644 index 0000000000..53bf89f3bd --- /dev/null +++ b/examples/widgets/doc/src/addressbook-fr.qdoc @@ -0,0 +1,1033 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page tutorials-addressbook-fr.html + + \title Tutoriel "Carnet d'adresses" + \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 + \li Les Widgets et leur mise en page à l'aide des layouts + \li Les signaux et slots + \li Les structures de données de collections + \li Les entrées/sorties + \endlist + + Le code source du tutoriel est distribué avec Qt dans le dossier \c tutorials/addressbook + + Les chapitres du tutoriel: + + \list 1 + \li \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur} + \li \l{tutorials/addressbook-fr/part2}{Ajouter des adresses} + \li \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments} + \li \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses} + \li \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche} + \li \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement} + \li \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 + + \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 + \li \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook, + \li \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe + \c AddressBook + \li \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 + \li 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. + \li 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. + \li 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 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 Management}. + + 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 la pile et on invoque + 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(). + On comprend maintenant pourquoi \c AddressBook a été créé sur la pile: à la fin + du programme, l'objet sort du scope de la fonction \c main() et tous ses widgets enfants + sont supprimés, assurant ainsi qu'il n'y aura pas de fuites de mémoire. +*/ + +/*! + \page tutorials-addressbook-fr-part2.html + + \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 + \li 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 + + \li 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. + + \li 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 + + \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 + \li Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons + \li 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 + \li Si l'itérateur est à la fin de \c contacts, on réinitialise + l'affichage et on retourne. + \li Si l'itérateur est au début de \c contacts, on change sa + position jusqu'à la fin + \li 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 + + \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 + \li \c{NavigationMode}, + \li \c{AddingMode}, et + \li \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 + + \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 \uicontrol Find. + + Finalement, nous définissons les variables privées \c findButton, + \c lineEdit et \c findText, qui correspondent respectivement au bouton + \uicontrol 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 \uicontrol 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é \uicontrol 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 + + \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 à \uicontrol{Load...} et \uicontrol{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 + + \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 \c 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}}. +*/ diff --git a/examples/widgets/doc/src/addressbook-tutorial.qdoc b/examples/widgets/doc/src/addressbook-tutorial.qdoc new file mode 100644 index 0000000000..c1e39643f9 --- /dev/null +++ b/examples/widgets/doc/src/addressbook-tutorial.qdoc @@ -0,0 +1,979 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page tutorials-addressbook.html + + \title Address Book Tutorial + \brief An introduction to GUI programming, showing how to put together a + simple yet fully-functioning application. + + This tutorial is an introduction to GUI programming with the Qt + cross-platform framework. + + \image addressbook-tutorial-screenshot.png + + \omit + It doesn't cover everything; the emphasis is on teaching the programming + philosophy of GUI programming, and Qt's features are introduced as needed. + Some commonly used features are never used in this tutorial. + \endomit + + In this tutorial, you will learn about some of the basic + components of Qt, including: + + \list + \li Widgets and layout managers + \li Container classes + \li Signals and slots + \li Input and output devices + \endlist + + Tutorial contents: + + \list 1 + \li \l{tutorials/addressbook/part1}{Designing the User Interface} + \li \l{tutorials/addressbook/part2}{Adding Addresses} + \li \l{tutorials/addressbook/part3}{Navigating between Entries} + \li \l{tutorials/addressbook/part4}{Editing and Removing Addresses} + \li \l{tutorials/addressbook/part5}{Adding a Find Function} + \li \l{tutorials/addressbook/part6}{Loading and Saving} + \li \l{tutorials/addressbook/part7}{Additional Features} + \endlist + + The tutorial source code is located in \c{tutorials/addressbook}. + + Although this little application does not look much like a + fully-fledged modern GUI application, it uses many of the basic + elements that are used in more complex applications. After you + have worked through this tutorial, we recommend reading the + \l{mainwindows/application}{Application} example, which presents a + small GUI application, with menus, toolbars, a status bar, and so + on. +*/ + +/*! + \page tutorials-addressbook-part1.html + + \example tutorials/addressbook/part1 + \title Part 1 - Designing the User Interface + + This first part covers the design of the basic graphical user + interface (GUI) for our address book application. + + The first step in creating a GUI program is to design the user + interface. Here the our goal is to set up the labels and input + fields to implement a basic address book. The figure below is a + screenshot of the expected output. + + \image addressbook-tutorial-part1-screenshot.png + + We require two QLabel objects, \c nameLabel and \c addressLabel, as well + as two input fields, a QLineEdit object, \c nameLine, and a QTextEdit + object, \c addressText, to enable the user to enter a contact's name and + address. The widgets used and their positions are shown in the figure + below. + + \image addressbook-tutorial-part1-labeled-screenshot.png + + There are three files used to implement this address book: + + \list + \li \c{addressbook.h} - the definition file for the \c AddressBook + class, + \li \c{addressbook.cpp} - the implementation file for the + \c AddressBook class, and + \li \c{main.cpp} - the file containing a \c main() function, with + an instance of \c AddressBook. + \endlist + + \section1 Qt Programming - Subclassing + + When writing Qt programs, we usually subclass Qt objects to add + functionality. This is one of the essential concepts behind creating + custom widgets or collections of standard widgets. Subclassing to + extend or change the behavior of a widget has the following advantages: + + \list + \li We can write implementations of virtual or pure virtual functions to + obtain exactly what we need, falling back on the base class's implementation + when necessary. + \li It allows us to encapsulate parts of the user interface within a class, + so that the other parts of the application don't need to know about the + individual widgets in the user interface. + \li The subclass can be used to create multiple custom widgets in the same + application or library, and the code for the subclass can be reused in other + projects. + \endlist + + Since Qt does not provide a specific address book widget, we subclass a + standard Qt widget class and add features to it. The \c AddressBook class + we create in this tutorial can be reused in situations where a basic address + book widget is needed. + + \section1 Defining the AddressBook Class + + The \l{tutorials/addressbook/part1/addressbook.h}{\c addressbook.h} file is + used to define the \c AddressBook class. + + We start by defining \c AddressBook as a QWidget subclass and declaring + a constructor. We also use the Q_OBJECT macro to indicate that the class + uses internationalization and Qt's signals and slots features, even + if we do not use all of these features at this stage. + + \snippet tutorials/addressbook/part1/addressbook.h class definition + + The class holds declarations of \c nameLine and \c addressText, + the private instances of QLineEdit and QTextEdit mentioned + earlier. The data stored in \c nameLine and \c addressText will + be needed for many of the address book functions. + + We don't include declarations of the QLabel objects we will use + because we will not need to reference them once they have been + created. The way Qt tracks the ownership of objects is explained + in the next section. + + The Q_OBJECT macro itself implements some of the more advanced features of Qt. + For now, it is useful to think of the Q_OBJECT macro as a shortcut which allows + us to use the \l{QObject::}{tr()} and \l{QObject::}{connect()} functions. + + We have now completed the \c addressbook.h file and we move on to + implement the corresponding \c addressbook.cpp file. + + \section1 Implementing the AddressBook Class + + The constructor of \c AddressBook accepts a QWidget parameter, \a parent. + By convention, we pass this parameter to the base class's constructor. + This concept of ownership, where a parent can have one or more children, + is useful for grouping widgets in Qt. For example, if you delete a parent, + all of its children will be deleted as well. + + \snippet tutorials/addressbook/part1/addressbook.cpp constructor and input fields + + In this constructor, the QLabel objects \c nameLabel and \c + addressLabel are instantiated, as well as \c nameLine and \c + addressText. The \l{QObject::tr()}{tr()} function returns a + translated version of the string, if there is one + available. Otherwise it returns the string itself. This function + marks its QString parameter as one that should be translated into + other languages. It should be used wherever a translatable string + appears. + + When programming with Qt, it is useful to know how layouts work. + Qt provides three main layout classes: QHBoxLayout, QVBoxLayout + and QGridLayout to handle the positioning of widgets. + + \image addressbook-tutorial-part1-labeled-layout.png + + We use a QGridLayout to position our labels and input fields in a + structured manner. QGridLayout divides the available space into a grid and + places widgets in the cells we specify with row and column numbers. The + diagram above shows the layout cells and the position of our widgets, and + we specify this arrangement using the following code: + + \snippet tutorials/addressbook/part1/addressbook.cpp layout + + Notice that \c addressLabel is positioned using Qt::AlignTop as an + additional argument. This is to make sure it is not vertically centered in + cell (1,0). For a basic overview on Qt Layouts, refer to the + \l{Layout Management} documentation. + + In order to install the layout object onto the widget, we have to invoke + the widget's \l{QWidget::setLayout()}{setLayout()} function: + + \snippet tutorials/addressbook/part1/addressbook.cpp setting the layout + + Lastly, we set the widget's title to "Simple Address Book". + + \section1 Running the Application + + A separate file, \c main.cpp, is used for the \c main() function. Within + this function, we instantiate a QApplication object, \c app. QApplication + is responsible for various application-wide resources, such as the default + font and cursor, and for running an event loop. Hence, there is always one + QApplication object in every GUI application using Qt. + + \snippet tutorials/addressbook/part1/main.cpp main function + + We construct a new \c AddressBook widget on the stack and invoke + its \l{QWidget::show()}{show()} function to display it. + However, the widget will not be shown until the application's event loop + is started. We start the event loop by calling the application's + \l{QApplication::}{exec()} function; the result returned by this function + is used as the return value from the \c main() function. At this point, + it becomes apparent why we instanciated \c AddressBook on the stack: It + will now go out of scope. Therefore, \c AddressBook and all its child widgets + will be deleted, thus preventing memory leaks. +*/ + +/*! + \page tutorials-addressbook-part2.html + + \example tutorials/addressbook/part2 + \title Part 2 - Adding Addresses + + The next step in creating the address book is to implement some + user interactions. + + \image addressbook-tutorial-part2-add-contact.png + + We will provide a push button that the user can click to add a new contact. + Also, some form of data structure is needed to store these contacts in an + organized way. + + \section1 Defining the AddressBook Class + + Now that we have the labels and input fields set up, we add push buttons to + complete the process of adding a contact. This means that our + \c addressbook.h file now has three QPushButton objects declared and three + corresponding public slots. + + \snippet tutorials/addressbook/part2/addressbook.h slots + + A slot is a function that responds to a particular signal. We will discuss + this concept in further detail when implementing the \c AddressBook class. + However, for an overview of Qt's signals and slots concept, you can refer + to the \l{Signals and Slots} document. + + Three QPushButton objects (\c addButton, \c submitButton, and + \c cancelButton) are now included in our private variable declarations, + along with \c nameLine and \c addressText. + + \snippet tutorials/addressbook/part2/addressbook.h pushbutton declaration + + We need a container to store our address book contacts, so that we can + traverse and display them. A QMap object, \c contacts, is used for this + purpose as it holds a key-value pair: the contact's name as the \e key, + and the contact's address as the \e{value}. + + \snippet tutorials/addressbook/part2/addressbook.h remaining private variables + + We also declare two private QString objects, \c oldName and \c oldAddress. + These objects are needed to hold the name and address of the contact that + was last displayed, before the user clicked \uicontrol Add. So, when the user clicks + \uicontrol Cancel, we can revert to displaying the details of the last contact. + + \section1 Implementing the AddressBook Class + + Within the constructor of \c AddressBook, we set the \c nameLine and + \c addressText to read-only, so that we can only display but not edit + existing contact details. + + \dots + \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 1 + \dots + \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 2 + + Then, we instantiate our push buttons: \c addButton, \c submitButton, and + \c cancelButton. + + \snippet tutorials/addressbook/part2/addressbook.cpp pushbutton declaration + + The \c addButton is displayed by invoking the \l{QPushButton::show()} + {show()} function, while the \c submitButton and \c cancelButton are + hidden by invoking \l{QPushButton::hide()}{hide()}. These two push + buttons will only be displayed when the user clicks \uicontrol Add and this is + handled by the \c addContact() function discussed below. + + \snippet tutorials/addressbook/part2/addressbook.cpp connecting signals and slots + + We connect the push buttons' \l{QPushButton::clicked()}{clicked()} signal + to their respective slots. The figure below illustrates this. + + \image addressbook-tutorial-part2-signals-and-slots.png + + Next, we arrange our push buttons neatly to the right of our address book + widget, using a QVBoxLayout to line them up vertically. + + \snippet tutorials/addressbook/part2/addressbook.cpp vertical layout + + The \l{QBoxLayout::addStretch()}{addStretch()} function is used to ensure + the push buttons are not evenly spaced, but arranged closer to the top of + the widget. The figure below shows the difference between using + \l{QBoxLayout::addStretch()}{addStretch()} and not using it. + + \image addressbook-tutorial-part2-stretch-effects.png + + We then add \c buttonLayout1 to \c mainLayout, using + \l{QGridLayout::addLayout()}{addLayout()}. This gives us nested layouts + as \c buttonLayout1 is now a child of \c mainLayout. + + \snippet tutorials/addressbook/part2/addressbook.cpp grid layout + + Our layout coordinates now look like this: + + \image addressbook-tutorial-part2-labeled-layout.png + + In the \c addContact() function, we store the last displayed contact + details in \c oldName and \c oldAddress. Then we clear these input + fields and turn off the read-only mode. The focus is set on \c nameLine + and we display \c submitButton and \c cancelButton. + + \snippet tutorials/addressbook/part2/addressbook.cpp addContact + + The \c submitContact() function can be divided into three parts: + + \list 1 + \li We extract the contact's details from \c nameLine and \c addressText + and store them in QString objects. We also validate to make sure that the + user did not click \uicontrol Submit with empty input fields; otherwise, a + QMessageBox is displayed to remind the user for a name and address. + + \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1 + + \li We then proceed to check if the contact already exists. If it does not + exist, we add the contact to \c contacts and we display a QMessageBox to + inform the user that the contact has been added. + + \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part2 + + If the contact already exists, again, we display a QMessageBox to inform + the user about this, preventing the user from adding duplicate contacts. + Our \c contacts object is based on key-value pairs of name and address, + hence, we want to ensure that \e key is unique. + + \li Once we have handled both cases mentioned above, we restore the push + buttons to their normal state with the following code: + + \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3 + + \endlist + + The screenshot below shows the QMessageBox object we use to display + information messages to the user. + + \image addressbook-tutorial-part2-add-successful.png + + The \c cancel() function restores the last displayed contact details and + enables \c addButton, as well as hides \c submitButton and + \c cancelButton. + + \snippet tutorials/addressbook/part2/addressbook.cpp cancel + + The general idea behind adding a contact is to give the user the + flexibility to click \uicontrol Submit or \uicontrol Cancel at any time. The flowchart below + further explains this concept: + + \image addressbook-tutorial-part2-add-flowchart.png +*/ + +/*! + \page tutorials-addressbook-part3.html + + \example tutorials/addressbook/part3 + \title Part 3 - Navigating between Entries + + The address book is now about half complete. We should add the + capability to navigate among the contacts, but first we must + decide what sort of a data structure we need for containing these + contacts. + + In the previous section, we used a QMap of key-value pairs with + the contact's name as the \e key, and the contact's address as the + \e value. This works well for our case. However, in order to + navigate and display each entry, a little bit of enhancement is + needed. + + We enhance the QMap by making it replicate a data structure similar to a + circularly-linked list, where all elements are connected, including the + first element and the last element. The figure below illustrates this data + structure. + + \image addressbook-tutorial-part3-linkedlist.png + + \section1 Defining the AddressBook Class + + To add navigation functions to the address book, we must add two + more slots to the \c AddressBook class: \c next() and \c + previous() to the \c addressbook.h file: + + \snippet tutorials/addressbook/part3/addressbook.h navigation functions + + We also require another two QPushButton objects, so we declare \c nextButton + and \c previousButton as private variables: + + \snippet tutorials/addressbook/part3/addressbook.h navigation pushbuttons + + \section1 Implementing the AddressBook Class + + In the \c AddressBook constructor in \c addressbook.cpp, we instantiate + \c nextButton and \c previousButton and disable them by default. This is + because navigation is only enabled when there is more than one contact + in the address book. + + \snippet tutorials/addressbook/part3/addressbook.cpp navigation pushbuttons + + We then connect these push buttons to their respective slots: + + \snippet tutorials/addressbook/part3/addressbook.cpp connecting navigation signals + + The image below is the expected graphical user interface. + + \image addressbook-tutorial-part3-screenshot.png + + We follow basic conventions for \c next() and \c previous() functions by + placing the \c nextButton on the right and the \c previousButton on the + left. In order to achieve this intuitive layout, we use QHBoxLayout to + place the widgets side-by-side: + + \snippet tutorials/addressbook/part3/addressbook.cpp navigation layout + + The QHBoxLayout object, \c buttonLayout2, is then added to \c mainLayout. + + \snippet tutorials/addressbook/part3/addressbook.cpp adding navigation layout + + The figure below shows the coordinates of the widgets in \c mainLayout. + \image addressbook-tutorial-part3-labeled-layout.png + + Within our \c addContact() function, we have to disable these buttons so + that the user does not attempt to navigate while adding a contact. + + \snippet tutorials/addressbook/part3/addressbook.cpp disabling navigation + + Also, in our \c submitContact() function, we enable the navigation + buttons, \c nextButton and \c previousButton, depending on the size + of \c contacts. As mentioned earlier, navigation is only enabled when + there is more than one contact in the address book. The following lines + of code demonstrates how to do this: + + \snippet tutorials/addressbook/part3/addressbook.cpp enabling navigation + + We also include these lines of code in the \c cancel() function. + + Recall that we intend to emulate a circularly-linked list with our QMap + object, \c contacts. So, in the \c next() function, we obtain an iterator + for \c contacts and then: + + \list + \li If the iterator is not at the end of \c contacts, we increment it + by one. + \li If the iterator is at the end of \c contacts, we move it to the + beginning of \c contacts. This gives us the illusion that our QMap is + working like a circularly-linked list. + \endlist + + \snippet tutorials/addressbook/part3/addressbook.cpp next() function + + Once we have iterated to the correct object in \c contacts, we display + its contents on \c nameLine and \c addressText. + + Similarly, for the \c previous() function, we obtain an iterator for + \c contacts and then: + + \list + \li If the iterator is at the end of \c contacts, we clear the + display and return. + \li If the iterator is at the beginning of \c contacts, we move it to + the end. + \li We then decrement the iterator by one. + \endlist + + \snippet tutorials/addressbook/part3/addressbook.cpp previous() function + + Again, we display the contents of the current object in \c contacts. + +*/ + +/*! + \page tutorials-addressbook-part4.html + + \example tutorials/addressbook/part4 + \title Part 4 - Editing and Removing Addresses + + Now we look at ways to modify the contents of contacts stored in + the address book. + + \image addressbook-tutorial-screenshot.png + + We now have an address book that not only holds contacts in an + organized manner, but also allows navigation. It would be + convenient to include edit and remove functions so that a + contact's details can be changed when needed. However, this + requires a little improvement, in the form of enums. We defined + two modes: \c{AddingMode} and \c{NavigationMode}, but they were + not defined as enum values. Instead, we enabled and disabled the + corresponding buttons manually, resulting in multiple lines of + repeated code. + + Here we define the \c Mode enum with three different values: + + \list + \li \c{NavigationMode}, + \li \c{AddingMode}, and + \li \c{EditingMode}. + \endlist + + \section1 Defining the AddressBook Class + + The \c addressbook.h file is updated to contain the \c Mode enum: + + \snippet tutorials/addressbook/part4/addressbook.h Mode enum + + We also add two new slots, \c editContact() and \c removeContact(), to + our current list of public slots. + + \snippet tutorials/addressbook/part4/addressbook.h edit and remove slots + + In order to switch between modes, we introduce the \c updateInterface() function + to control the enabling and disabling of all QPushButton objects. We also + add two new push buttons, \c editButton and \c removeButton, for the edit + and remove functions mentioned earlier. + + \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 + + Lastly, we declare \c currentMode to keep track of the enum's current mode. + + \section1 Implementing the AddressBook Class + + We now implement the mode-changing features of the address + book. The \c editButton and \c removeButton are instantiated and + disabled by default. The address book starts with zero contacts + in memory. + + \snippet tutorials/addressbook/part4/addressbook.cpp edit and remove buttons + + These buttons are then connected to their respective slots, \c editContact() + and \c removeContact(), and we add them to \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 + + The \c editContact() function stores the contact's old details in + \c oldName and \c oldAddress, before switching the mode to \c EditingMode. + In this mode, the \c submitButton and \c cancelButton are both enabled, + hence, the user can change the contact's details and click either button. + + \snippet tutorials/addressbook/part4/addressbook.cpp editContact() function + + The \c submitContact() function has been divided in two with an \c{if-else} + statement. We check \c currentMode to see if it's in \c AddingMode. If it is, + we proceed with our adding process. + + \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function beginning + \dots + \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part1 + + Otherwise, we check to see if \c currentMode is in \c EditingMode. If it + is, we compare \c oldName with \c name. If the name has changed, we remove + the old contact from \c contacts and insert the newly updated contact. + + \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part2 + + If only the address has changed (i.e., \c oldAddress is not the same as \c address), + we update the contact's address. Lastly, we set \c currentMode to + \c NavigationMode. This is an important step as it re-enables all the + disabled push buttons. + + To remove a contact from the address book, we implement the + \c removeContact() function. This function checks to see if the contact + exists in \c contacts. + + \snippet tutorials/addressbook/part4/addressbook.cpp removeContact() function + + If it does, we display a QMessageBox, to confirm the removal with the + user. Once the user has confirmed, we call \c previous() to ensure that the + user interface shows another contact, and we remove the contact using \l{QMap}'s + \l{QMap::remove()}{remove()} function. As a courtesy, we display a QMessageBox + to inform the user. Both the message boxes used in this function are shown below: + + \image addressbook-tutorial-part4-remove.png + + \section2 Updating the User Interface + + We mentioned the \c updateInterface() function earlier as a means to + enable and disable the push buttons depending on the current mode. + The function updates the current mode according to the \c mode argument + passed to it, assigning it to \c currentMode before checking its value. + + Each of the push buttons is then enabled or disabled, depending on the + current mode. The code for \c AddingMode and \c EditingMode is shown below: + + \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 1 + + For \c NavigationMode, however, we include conditions within the parameters + of the QPushButton::setEnabled() function. This is to ensure that + \c editButton and \c removeButton are enabled when there is at least one + contact in the address book; \c nextButton and \c previousButton are only + enabled when there is more than one contact in the address book. + + \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 2 + + By setting the mode and updating the user interface in the same + function, we avoid the possibility of the user interface getting + out of sync with the internal state of the application. + */ + +/*! + \page tutorials-addressbook-part5.html + + \example tutorials/addressbook/part5 + \title Part 5 - Adding a Find Function + + Here we look at ways to locate contacts and addresses in the + address book. + + \image addressbook-tutorial-part5-screenshot.png + + As we add contacts to our address book, it becomes tedious to + navigate the list with the \e Next and \e Previous buttons. A \e + Find function would be more efficient. The screenshot above shows + the \e Find button and its position on the panel of buttons. + + When the user clicks on the \e Find button, it is useful to + display a dialog that prompts for a contact's name. Qt provides + QDialog, which we subclass here to implement a \c FindDialog + class. + + \section1 Defining the FindDialog Class + + \image addressbook-tutorial-part5-finddialog.png + + In order to subclass QDialog, we first include the header for QDialog in + the \c finddialog.h file. Also, we use forward declaration to declare + QLineEdit and QPushButton since we will be using those widgets in our + dialog class. + + As in our \c AddressBook class, the \c FindDialog class includes + the Q_OBJECT macro and its constructor is defined to accept a parent + QWidget, even though the dialog will be opened as a separate window. + + \snippet tutorials/addressbook/part5/finddialog.h FindDialog header + + We define a public function, \c getFindText(), to be used by classes that + instantiate \c FindDialog. This function allows these classes to obtain the + search string entered by the user. A public slot, \c findClicked(), is also + defined to handle the search string when the user clicks the \uicontrol Find + button. + + Lastly, we define the private variables, \c findButton, \c lineEdit + and \c findText, corresponding to the \uicontrol Find button, the line edit + into which the user types the search string, and an internal string + used to store the search string for later use. + + \section1 Implementing the FindDialog Class + + Within the constructor of \c FindDialog, we set up the private variables, + \c lineEdit, \c findButton and \c findText. We use a QHBoxLayout to + position the widgets. + + \snippet tutorials/addressbook/part5/finddialog.cpp constructor + + We set the layout and window title, as well as connect the signals to their + respective slots. Notice that \c{findButton}'s \l{QPushButton::clicked()} + {clicked()} signal is connected to to \c findClicked() and + \l{QDialog::accept()}{accept()}. The \l{QDialog::accept()}{accept()} slot + provided by QDialog hides the dialog and sets the result code to + \l{QDialog::}{Accepted}. We use this function to help \c{AddressBook}'s + \c findContact() function know when the \c FindDialog object has been + closed. We will explain this logic in further detail when discussing the + \c findContact() function. + + \image addressbook-tutorial-part5-signals-and-slots.png + + In \c findClicked(), we validate \c lineEdit to ensure that the user + did not click the \uicontrol Find button without entering a contact's name. Then, we set + \c findText to the search string, extracted from \c lineEdit. After that, + we clear the contents of \c lineEdit and hide the dialog. + + \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function + + The \c findText variable has a public getter function, \c getFindText(), + associated with it. Since we only ever set \c findText directly in both the + constructor and in the \c findClicked() function, we do not create a + setter function to accompany \c getFindText(). + Because \c getFindText() is public, classes instantiating and using + \c FindDialog can always access the search string that the user has + entered and accepted. + + \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function + + \section1 Defining the AddressBook Class + + To ensure we can use \c FindDialog from within our \c AddressBook class, we + include \c finddialog.h in the \c addressbook.h file. + + \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header + + So far, all our address book features have a QPushButton and a + corresponding slot. Similarly, for the \uicontrol Find feature we have + \c findButton and \c findContact(). + + The \c findButton is declared as a private variable and the + \c findContact() function is declared as a public slot. + + \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration + \dots + \snippet tutorials/addressbook/part5/addressbook.h findButton declaration + + Lastly, we declare the private variable, \c dialog, which we will use to + refer to an instance of \c FindDialog. + + \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration + + Once we have instantiated a dialog, we will want to use it more than once; + using a private variable allows us to refer to it from more than one place + in the class. + + \section1 Implementing the AddressBook Class + + Within the \c AddressBook class's constructor, we instantiate our private + objects, \c findButton and \c findDialog: + + \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton + \dots + \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog + + Next, we connect the \c{findButton}'s + \l{QPushButton::clicked()}{clicked()} signal to \c findContact(). + + \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find + + Now all that is left is the code for our \c findContact() function: + + \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function + + We start out by displaying the \c FindDialog instance, \c dialog. This is + when the user enters a contact name to look up. Once the user clicks + the dialog's \c findButton, the dialog is hidden and the result code is + set to QDialog::Accepted. This ensures that + our \c if statement is always true. + + We then proceed to extract the search string, which in this case is + \c contactName, using \c{FindDialog}'s \c getFindText() function. If the + contact exists in our address book, we display it immediately. Otherwise, + we display the QMessageBox shown below to indicate that their search + failed. + + \image addressbook-tutorial-part5-notfound.png +*/ + +/*! + \page tutorials-addressbook-part6.html + + \example tutorials/addressbook/part6 + \title Part 6 - Loading and Saving + + This part covers the Qt file handling features we use to write + loading and saving routines for the address book. + + \image addressbook-tutorial-part6-screenshot.png + + Although browsing and searching the contact list are useful + features, our address book is not complete until we can save + existing contacts and load them again at a later time. + + Qt provides a number of classes for \l{Input/Output and Networking} + {input and output}, but we have chosen to use two which are simple to use + in combination: QFile and QDataStream. + + A QFile object represents a file on disk that can be read from and written + to. QFile is a subclass of the more general QIODevice class which + represents many different kinds of devices. + + A QDataStream object is used to serialize binary data so that it can be + stored in a QIODevice and retrieved again later. Reading from a QIODevice + and writing to it is as simple as opening the stream - with the respective + device as a parameter - and reading from or writing to it. + + + \section1 Defining the AddressBook Class + + We declare two public slots, \c saveToFile() and \c loadFromFile(), as well + as two QPushButton objects, \c loadButton and \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 Implementing the AddressBook Class + + In our constructor, we instantiate \c loadButton and \c saveButton. + Ideally, it would be more user-friendly to set the push buttons' labels + to "Load contacts from a file" and "Save contacts to a file". However, due + to the size of our other push buttons, we set the labels to \uicontrol{Load...} + and \uicontrol{Save...}. Fortunately, Qt provides a simple way to set tooltips with + \l{QWidget::setToolTip()}{setToolTip()} and we use it in the following way + for our push buttons: + + \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1 + \dots + \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2 + + Although it is not shown here, just like the other features we implemented, + we add the push buttons to the layout panel on the right, \c buttonLayout1, + and we connect the push buttons' \l{QPushButton::clicked()}{clicked()} + signals to their respective slots. + + For the saving feature, we first obtain \c fileName using + QFileDialog::getSaveFileName(). This is a convenience function provided + by QFileDialog, which pops up a modal file dialog and allows the user to + enter a file name or select any existing \c{.abk} file. The \c{.abk} file + is our Address Book extension that we create when we save contacts. + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1 + + The file dialog that pops up is displayed in the screenshot below: + + \image addressbook-tutorial-part6-save.png + + If \c fileName is not empty, we create a QFile object, \c file, with + \c fileName. QFile works with QDataStream as QFile is a QIODevice. + + Next, we attempt to open the file in \l{QIODevice::}{WriteOnly} mode. + If this is unsuccessful, we display a QMessageBox to inform the user. + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2 + + Otherwise, we instantiate a QDataStream object, \c out, to write the open + file. QDataStream requires that the same version of the stream is used + for reading and writing. We ensure that this is the case by setting the + version used to the \l{QDataStream::Qt_4_5}{version introduced with Qt 4.5} + before serializing the data to \c file. + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3 + + For the loading feature, we also obtain \c fileName using + QFileDialog::getOpenFileName(). This function, the counterpart to + QFileDialog::getSaveFileName(), also pops up the modal file dialog and + allows the user to enter a file name or select any existing \c{.abk} file + to load it into the address book. + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1 + + On Windows, for example, this function pops up a native file dialog, as + shown in the following screenshot. + + \image addressbook-tutorial-part6-load.png + + If \c fileName is not empty, again, we use a QFile object, \c file, and + attempt to open it in \l{QIODevice::}{ReadOnly} mode. Similar to our + implementation of \c saveToFile(), if this attempt is unsuccessful, we + display a QMessageBox to inform the user. + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2 + + Otherwise, we instantiate a QDataStream object, \c in, set its version as + above and read the serialized data into the \c contacts data structure. + The \c contacts object is emptied before data is read into it to simplify + the file reading process. A more advanced method would be to read the + contacts into a temporary QMap object, and copy over non-duplicate contacts + into \c contacts. + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3 + + To display the contacts that have been read from the file, we must first + validate the data obtained to ensure that the file we read from actually + contains address book contacts. If it does, we display the first contact; + otherwise, we display a QMessageBox to inform the user about the problem. + Lastly, we update the interface to enable and disable the push buttons + accordingly. +*/ + +/*! + \page tutorials-addressbook-part7.html + + \example tutorials/addressbook/part7 + \title Part 7 - Additional Features + + This part covers some additional features that make the address + book more convenient for the frequent user. + + \image addressbook-tutorial-part7-screenshot.png + + Although our address book is useful in isolation, it would be + better if we could exchange contact data with other applications. + The vCard format is a popular file format that can be used for + this purpose. Here we extend our address book client to allow + contacts to be exported to vCard \c{.vcf} files. + + \section1 Defining the AddressBook Class + + We add a QPushButton object, \c exportButton, and a corresponding public + slot, \c exportAsVCard() to our \c AddressBook class in the + \c addressbook.h file. + + \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration + \dots + \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration + + \section1 Implementing the AddressBook Class + + Within the \c AddressBook constructor, we connect \c{exportButton}'s + \l{QPushButton::clicked()}{clicked()} signal to \c exportAsVCard(). + We also add this button to our \c buttonLayout1, the layout responsible + for our panel of buttons on the right. + + In our \c exportAsVCard() function, we start by extracting the contact's + name into \c name. We declare \c firstName, \c lastName and \c nameList. + Next, we look for the index of the first white space in \c name. If there + is a white space, we split the contact's name into \c firstName and + \c lastName. Then, we replace the space with an underscore ("_"). + Alternately, if there is no white space, we assume that the contact only + has a first name. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part1 + + As with the \c saveToFile() function, we open a file dialog to let the user + choose a location for the file. Using the file name chosen, we create an + instance of QFile to write to. + + We attempt to open the file in \l{QIODevice::}{WriteOnly} mode. If this + process fails, we display a QMessageBox to inform the user about the + problem and return. Otherwise, we pass the file as a parameter to a + QTextStream object, \c out. Like QDataStream, the QTextStream class + provides functionality to read and write plain text to files. As a result, + the \c{.vcf} file generated can be opened for editing in a text editor. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part2 + + We then write out a vCard file with the \c{BEGIN:VCARD} tag, followed by + the \c{VERSION:2.1} tag. The contact's name is written with the \c{N:} + tag. For the \c{FN:} tag, which fills in the "File as" property of a vCard, + we have to check whether the contact has a last name or not. If the contact + does, we use the details in \c nameList to fill it. Otherwise, we write + \c firstName only. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part3 + + We proceed to write the contact's address. The semicolons in the address + are escaped with "\\", the newlines are replaced with semicolons, and the + commas are replaced with spaces. Lastly, we write the \c{ADR;HOME:;} + tag, followed by \c address and then the \c{END:VCARD} tag. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part4 + + In the end, a QMessageBox is displayed to inform the user that the vCard + has been successfully exported. + + \e{vCard is a trademark of the \l{http://www.imc.org} + {Internet Mail Consortium}}. +*/ diff --git a/examples/widgets/doc/addressbook.qdoc b/examples/widgets/doc/src/addressbook.qdoc index 9b4ede5775..9b4ede5775 100644 --- a/examples/widgets/doc/addressbook.qdoc +++ b/examples/widgets/doc/src/addressbook.qdoc diff --git a/examples/widgets/doc/affine.qdoc b/examples/widgets/doc/src/affine.qdoc index c69794d511..c69794d511 100644 --- a/examples/widgets/doc/affine.qdoc +++ b/examples/widgets/doc/src/affine.qdoc diff --git a/examples/widgets/doc/analogclock.qdoc b/examples/widgets/doc/src/analogclock.qdoc index bb4bdb54ae..bb4bdb54ae 100644 --- a/examples/widgets/doc/analogclock.qdoc +++ b/examples/widgets/doc/src/analogclock.qdoc diff --git a/examples/widgets/doc/animatedtiles.qdoc b/examples/widgets/doc/src/animatedtiles.qdoc index 4fe25388cf..4fe25388cf 100644 --- a/examples/widgets/doc/animatedtiles.qdoc +++ b/examples/widgets/doc/src/animatedtiles.qdoc diff --git a/examples/widgets/doc/appchooser.qdoc b/examples/widgets/doc/src/appchooser.qdoc index 092db7c29e..092db7c29e 100644 --- a/examples/widgets/doc/appchooser.qdoc +++ b/examples/widgets/doc/src/appchooser.qdoc diff --git a/examples/widgets/doc/application.qdoc b/examples/widgets/doc/src/application.qdoc index 5465f99e99..5465f99e99 100644 --- a/examples/widgets/doc/application.qdoc +++ b/examples/widgets/doc/src/application.qdoc diff --git a/examples/widgets/doc/src/applicationicon.qdoc b/examples/widgets/doc/src/applicationicon.qdoc new file mode 100644 index 0000000000..8c8f762894 --- /dev/null +++ b/examples/widgets/doc/src/applicationicon.qdoc @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! \example widgets/applicationicon + \group all-examples + \title Application Icon Example + + The example shows how to add an application icon to a mobile application. + + \image appicon_screenshot.png The icon on a Nokia XPressMusic 5800 + + \section1 Creating an icon for Maemo + + Maemo expects the icon of an application to be a 64x64 PNG image file. The + file name of the icon should be the same as the executable with a \c .png + extension. You also need a \c .desktop file that gives the window manager + hints about the application, such as name, type and icon. + + \quotefile applicationicon/applicationicon.desktop + + The \c Icon field should also contain the name of the executable. On the + device, application icons are stored in the + \c /usr/share/icons/hicolor/64x64/apps directory + and desktop files in the \c /usr/share/applications/hildon directory. + + \section1 Adding the icons to the project + + For Maemo, we need to add that the \c .desktop and icon file should be + installed. + + \quotefile applicationicon/applicationicon.pro + + Currently, Qt Creator doesn't include the icon and desktop files in the + application package for Maemo, merely the executable file is included. As a + workaround for this, the files can be added manually in the Projects tab. + In the "Create Package" build step for the Maemo target, the \c .desktop + file and icon can be added to be a part of the package contents. + Unfortunately, these additions are only stored as a part of the + \c .pro.user file. This issue will be resolved in a future release of + Qt Creator. + + \image appicon_packagecontents.png Manual addition of files to the "Create Package" build step +*/ diff --git a/examples/widgets/doc/basicdrawing.qdoc b/examples/widgets/doc/src/basicdrawing.qdoc index 899aa361f8..899aa361f8 100644 --- a/examples/widgets/doc/basicdrawing.qdoc +++ b/examples/widgets/doc/src/basicdrawing.qdoc diff --git a/examples/widgets/doc/basicgraphicslayouts.qdoc b/examples/widgets/doc/src/basicgraphicslayouts.qdoc index 9f52b3eafa..9f52b3eafa 100644 --- a/examples/widgets/doc/basicgraphicslayouts.qdoc +++ b/examples/widgets/doc/src/basicgraphicslayouts.qdoc diff --git a/examples/widgets/doc/basiclayouts.qdoc b/examples/widgets/doc/src/basiclayouts.qdoc index a0f083ba58..a0f083ba58 100644 --- a/examples/widgets/doc/basiclayouts.qdoc +++ b/examples/widgets/doc/src/basiclayouts.qdoc diff --git a/examples/widgets/doc/basicsortfiltermodel.qdoc b/examples/widgets/doc/src/basicsortfiltermodel.qdoc index 0ecf4a0629..0ecf4a0629 100644 --- a/examples/widgets/doc/basicsortfiltermodel.qdoc +++ b/examples/widgets/doc/src/basicsortfiltermodel.qdoc diff --git a/examples/widgets/doc/blurpicker.qdoc b/examples/widgets/doc/src/blurpicker.qdoc index bd57acb061..bd57acb061 100644 --- a/examples/widgets/doc/blurpicker.qdoc +++ b/examples/widgets/doc/src/blurpicker.qdoc diff --git a/examples/widgets/doc/borderlayout.qdoc b/examples/widgets/doc/src/borderlayout.qdoc index aaff2dda1d..aaff2dda1d 100644 --- a/examples/widgets/doc/borderlayout.qdoc +++ b/examples/widgets/doc/src/borderlayout.qdoc diff --git a/examples/widgets/doc/boxes.qdoc b/examples/widgets/doc/src/boxes.qdoc index aa34a61bc3..aa34a61bc3 100644 --- a/examples/widgets/doc/boxes.qdoc +++ b/examples/widgets/doc/src/boxes.qdoc diff --git a/examples/widgets/doc/calculator.qdoc b/examples/widgets/doc/src/calculator.qdoc index 8480d90477..8480d90477 100644 --- a/examples/widgets/doc/calculator.qdoc +++ b/examples/widgets/doc/src/calculator.qdoc diff --git a/examples/widgets/doc/calendar.qdoc b/examples/widgets/doc/src/calendar.qdoc index b7fa7c8617..b7fa7c8617 100644 --- a/examples/widgets/doc/calendar.qdoc +++ b/examples/widgets/doc/src/calendar.qdoc diff --git a/examples/widgets/doc/calendarwidget.qdoc b/examples/widgets/doc/src/calendarwidget.qdoc index c6e86d1668..c6e86d1668 100644 --- a/examples/widgets/doc/calendarwidget.qdoc +++ b/examples/widgets/doc/src/calendarwidget.qdoc diff --git a/examples/widgets/doc/charactermap.qdoc b/examples/widgets/doc/src/charactermap.qdoc index fee2a42156..fee2a42156 100644 --- a/examples/widgets/doc/charactermap.qdoc +++ b/examples/widgets/doc/src/charactermap.qdoc diff --git a/examples/widgets/doc/chart.qdoc b/examples/widgets/doc/src/chart.qdoc index 44263d1027..44263d1027 100644 --- a/examples/widgets/doc/chart.qdoc +++ b/examples/widgets/doc/src/chart.qdoc diff --git a/examples/widgets/doc/chip.qdoc b/examples/widgets/doc/src/chip.qdoc index 966c16900a..966c16900a 100644 --- a/examples/widgets/doc/chip.qdoc +++ b/examples/widgets/doc/src/chip.qdoc diff --git a/examples/widgets/doc/classwizard.qdoc b/examples/widgets/doc/src/classwizard.qdoc index 0c357b7286..0c357b7286 100644 --- a/examples/widgets/doc/classwizard.qdoc +++ b/examples/widgets/doc/src/classwizard.qdoc diff --git a/examples/widgets/doc/codeeditor.qdoc b/examples/widgets/doc/src/codeeditor.qdoc index 695ac5c4ce..695ac5c4ce 100644 --- a/examples/widgets/doc/codeeditor.qdoc +++ b/examples/widgets/doc/src/codeeditor.qdoc diff --git a/examples/widgets/doc/coloreditorfactory.qdoc b/examples/widgets/doc/src/coloreditorfactory.qdoc index a2c02f8c1d..a2c02f8c1d 100644 --- a/examples/widgets/doc/coloreditorfactory.qdoc +++ b/examples/widgets/doc/src/coloreditorfactory.qdoc diff --git a/examples/widgets/doc/combowidgetmapper.qdoc b/examples/widgets/doc/src/combowidgetmapper.qdoc index 949014930d..949014930d 100644 --- a/examples/widgets/doc/combowidgetmapper.qdoc +++ b/examples/widgets/doc/src/combowidgetmapper.qdoc diff --git a/examples/widgets/doc/composition.qdoc b/examples/widgets/doc/src/composition.qdoc index 6aca01d255..6aca01d255 100644 --- a/examples/widgets/doc/composition.qdoc +++ b/examples/widgets/doc/src/composition.qdoc diff --git a/examples/widgets/doc/concentriccircles.qdoc b/examples/widgets/doc/src/concentriccircles.qdoc index 67bc125dbe..67bc125dbe 100644 --- a/examples/widgets/doc/concentriccircles.qdoc +++ b/examples/widgets/doc/src/concentriccircles.qdoc diff --git a/examples/widgets/doc/configdialog.qdoc b/examples/widgets/doc/src/configdialog.qdoc index 9acea72a3b..9acea72a3b 100644 --- a/examples/widgets/doc/configdialog.qdoc +++ b/examples/widgets/doc/src/configdialog.qdoc diff --git a/examples/widgets/doc/customsortfiltermodel.qdoc b/examples/widgets/doc/src/customsortfiltermodel.qdoc index 4dce820f9c..4dce820f9c 100644 --- a/examples/widgets/doc/customsortfiltermodel.qdoc +++ b/examples/widgets/doc/src/customsortfiltermodel.qdoc diff --git a/examples/widgets/doc/deform.qdoc b/examples/widgets/doc/src/deform.qdoc index 8195f90ffa..8195f90ffa 100644 --- a/examples/widgets/doc/deform.qdoc +++ b/examples/widgets/doc/src/deform.qdoc diff --git a/examples/widgets/doc/diagramscene.qdoc b/examples/widgets/doc/src/diagramscene.qdoc index b61a936d52..b61a936d52 100644 --- a/examples/widgets/doc/diagramscene.qdoc +++ b/examples/widgets/doc/src/diagramscene.qdoc diff --git a/examples/widgets/doc/digitalclock.qdoc b/examples/widgets/doc/src/digitalclock.qdoc index 92e8003205..92e8003205 100644 --- a/examples/widgets/doc/digitalclock.qdoc +++ b/examples/widgets/doc/src/digitalclock.qdoc diff --git a/examples/widgets/doc/dirview.qdoc b/examples/widgets/doc/src/dirview.qdoc index a4b799678a..a4b799678a 100644 --- a/examples/widgets/doc/dirview.qdoc +++ b/examples/widgets/doc/src/dirview.qdoc diff --git a/examples/widgets/doc/dockwidgets.qdoc b/examples/widgets/doc/src/dockwidgets.qdoc index 12f18a538f..12f18a538f 100644 --- a/examples/widgets/doc/dockwidgets.qdoc +++ b/examples/widgets/doc/src/dockwidgets.qdoc diff --git a/examples/widgets/doc/draganddroppuzzle.qdoc b/examples/widgets/doc/src/draganddroppuzzle.qdoc index d0d336f70f..2c90998dc1 100644 --- a/examples/widgets/doc/draganddroppuzzle.qdoc +++ b/examples/widgets/doc/src/draganddroppuzzle.qdoc @@ -26,7 +26,7 @@ ****************************************************************************/ /*! - \example widgets/draganddrop/puzzle + \example draganddrop/puzzle \title Drag and Drop Puzzle Example The Drag and Drop Puzzle example demonstrates a way of using the drag and drop system with diff --git a/examples/widgets/doc/dragdroprobot.qdoc b/examples/widgets/doc/src/dragdroprobot.qdoc index 60bd4eb4d8..60bd4eb4d8 100644 --- a/examples/widgets/doc/dragdroprobot.qdoc +++ b/examples/widgets/doc/src/dragdroprobot.qdoc diff --git a/examples/widgets/doc/src/draggableicons.qdoc b/examples/widgets/doc/src/draggableicons.qdoc new file mode 100644 index 0000000000..627aa673e0 --- /dev/null +++ b/examples/widgets/doc/src/draggableicons.qdoc @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/draggableicons + \title Draggable Icons Example + + The Draggable Icons example shows how to drag and drop image data between widgets + in the same application, and between different applications. + + \image draggableicons-example.png + + In many situations where drag and drop is used, the user starts dragging from + a particular widget and drops the payload onto another widget. In this example, + we subclass QLabel to create labels that we use as drag sources, and place them + inside \l{QWidget}s that serve as both containers and drop sites. + + In addition, when a drag and drop operation occurs, we want to send more than + just an image. We also want to send information about where the user clicked in + the image so that the user can place it precisely on the drop target. This level + of detail means that we must create a custom MIME type for our data. + + \section1 DragWidget Class Definition + + The icon widgets that we use to display icons are subclassed from QLabel: + + \snippet draganddrop/draggableicons/dragwidget.h 0 + + Since the QLabel class provides most of what we require for the icon, we + only need to reimplement the \l QWidget::mousePressEvent() to provide + drag and drop facilities. + + \section1 DragWidget Class Implementation + + The \c DragWidget constructor sets an attribute on the widget that ensures + that it will be deleted when it is closed: + + \snippet draganddrop/draggableicons/dragwidget.cpp 0 + + To enable dragging from the icon, we need to act on a mouse press event. + We do this by reimplementing \l QWidget::mousePressEvent() and setting up + a QDrag object. + + \snippet draganddrop/draggableicons/dragwidget.cpp 1 + + Since we will be sending pixmap data for the icon and information about the + user's click in the icon widget, we construct a QByteArray and package up the + details using a QDataStream. + + For interoperability, drag and drop operations describe the data they contain + using MIME types. In Qt, we describe this data using a QMimeData object: + + \snippet draganddrop/draggableicons/dragwidget.cpp 2 + + We choose an unofficial MIME type for this purpose, and supply the QByteArray + to the MIME data object. + + The drag and drop operation itself is handled by a QDrag object: + + \snippet draganddrop/draggableicons/dragwidget.cpp 3 + + Here, we pass the data to the drag object, set a pixmap that will be shown + alongside the cursor during the operation, and define the position of a hot + spot that places the position of this pixmap under the cursor. + +*/ diff --git a/examples/widgets/doc/src/draggabletext.qdoc b/examples/widgets/doc/src/draggabletext.qdoc new file mode 100644 index 0000000000..d497206f8b --- /dev/null +++ b/examples/widgets/doc/src/draggabletext.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example draganddrop/draggabletext + \title Draggable Text Example + + The Draggable Text example shows how to drag and drop textual data between widgets + in the same application, and between different applications. + + \image draggabletext-example.png +*/ diff --git a/examples/widgets/doc/dynamiclayouts.qdoc b/examples/widgets/doc/src/dynamiclayouts.qdoc index 318f719503..318f719503 100644 --- a/examples/widgets/doc/dynamiclayouts.qdoc +++ b/examples/widgets/doc/src/dynamiclayouts.qdoc diff --git a/examples/widgets/doc/easing.qdoc b/examples/widgets/doc/src/easing.qdoc index 7fb7f59531..7fb7f59531 100644 --- a/examples/widgets/doc/easing.qdoc +++ b/examples/widgets/doc/src/easing.qdoc diff --git a/examples/widgets/doc/editabletreemodel.qdoc b/examples/widgets/doc/src/editabletreemodel.qdoc index 24745b77b8..24745b77b8 100644 --- a/examples/widgets/doc/editabletreemodel.qdoc +++ b/examples/widgets/doc/src/editabletreemodel.qdoc diff --git a/examples/widgets/doc/elasticnodes.qdoc b/examples/widgets/doc/src/elasticnodes.qdoc index 17f14124f8..17f14124f8 100644 --- a/examples/widgets/doc/elasticnodes.qdoc +++ b/examples/widgets/doc/src/elasticnodes.qdoc diff --git a/examples/widgets/doc/elidedlabel.qdoc b/examples/widgets/doc/src/elidedlabel.qdoc index 2ce469d85f..2ce469d85f 100644 --- a/examples/widgets/doc/elidedlabel.qdoc +++ b/examples/widgets/doc/src/elidedlabel.qdoc diff --git a/examples/widgets/doc/embeddeddialogs.qdoc b/examples/widgets/doc/src/embeddeddialogs.qdoc index 24b3abdb37..24b3abdb37 100644 --- a/examples/widgets/doc/embeddeddialogs.qdoc +++ b/examples/widgets/doc/src/embeddeddialogs.qdoc diff --git a/examples/widgets/doc/eventtransitions.qdoc b/examples/widgets/doc/src/eventtransitions.qdoc index ef3f657c3d..ef3f657c3d 100644 --- a/examples/widgets/doc/eventtransitions.qdoc +++ b/examples/widgets/doc/src/eventtransitions.qdoc diff --git a/examples/widgets/doc/extension.qdoc b/examples/widgets/doc/src/extension.qdoc index 040d5d38d9..040d5d38d9 100644 --- a/examples/widgets/doc/extension.qdoc +++ b/examples/widgets/doc/src/extension.qdoc diff --git a/examples/widgets/doc/factorial.qdoc b/examples/widgets/doc/src/factorial.qdoc index 82ab5da536..82ab5da536 100644 --- a/examples/widgets/doc/factorial.qdoc +++ b/examples/widgets/doc/src/factorial.qdoc diff --git a/examples/widgets/doc/fademessage.qdoc b/examples/widgets/doc/src/fademessage.qdoc index 48f98c03ad..48f98c03ad 100644 --- a/examples/widgets/doc/fademessage.qdoc +++ b/examples/widgets/doc/src/fademessage.qdoc diff --git a/examples/widgets/doc/fetchmore.qdoc b/examples/widgets/doc/src/fetchmore.qdoc index 7ea0b30edf..7ea0b30edf 100644 --- a/examples/widgets/doc/fetchmore.qdoc +++ b/examples/widgets/doc/src/fetchmore.qdoc diff --git a/examples/widgets/doc/findfiles.qdoc b/examples/widgets/doc/src/findfiles.qdoc index 594d57472c..594d57472c 100644 --- a/examples/widgets/doc/findfiles.qdoc +++ b/examples/widgets/doc/src/findfiles.qdoc diff --git a/examples/widgets/doc/flowlayout.qdoc b/examples/widgets/doc/src/flowlayout.qdoc index b08b2283aa..b08b2283aa 100644 --- a/examples/widgets/doc/flowlayout.qdoc +++ b/examples/widgets/doc/src/flowlayout.qdoc diff --git a/examples/widgets/doc/fontsampler.qdoc b/examples/widgets/doc/src/fontsampler.qdoc index 8d7f0e0460..8d7f0e0460 100644 --- a/examples/widgets/doc/fontsampler.qdoc +++ b/examples/widgets/doc/src/fontsampler.qdoc diff --git a/examples/widgets/doc/frozencolumn.qdoc b/examples/widgets/doc/src/frozencolumn.qdoc index c65ce1d524..c65ce1d524 100644 --- a/examples/widgets/doc/frozencolumn.qdoc +++ b/examples/widgets/doc/src/frozencolumn.qdoc diff --git a/examples/widgets/doc/gradients.qdoc b/examples/widgets/doc/src/gradients.qdoc index 75f78b56ea..75f78b56ea 100644 --- a/examples/widgets/doc/gradients.qdoc +++ b/examples/widgets/doc/src/gradients.qdoc diff --git a/examples/widgets/doc/groupbox.qdoc b/examples/widgets/doc/src/groupbox.qdoc index d7384d409a..d7384d409a 100644 --- a/examples/widgets/doc/groupbox.qdoc +++ b/examples/widgets/doc/src/groupbox.qdoc diff --git a/examples/widgets/doc/icons.qdoc b/examples/widgets/doc/src/icons.qdoc index b6625db005..b6625db005 100644 --- a/examples/widgets/doc/icons.qdoc +++ b/examples/widgets/doc/src/icons.qdoc diff --git a/examples/widgets/doc/imagecomposition.qdoc b/examples/widgets/doc/src/imagecomposition.qdoc index 3f06f377b4..3f06f377b4 100644 --- a/examples/widgets/doc/imagecomposition.qdoc +++ b/examples/widgets/doc/src/imagecomposition.qdoc diff --git a/examples/widgets/doc/imageviewer.qdoc b/examples/widgets/doc/src/imageviewer.qdoc index 3556d52f7e..3556d52f7e 100644 --- a/examples/widgets/doc/imageviewer.qdoc +++ b/examples/widgets/doc/src/imageviewer.qdoc diff --git a/examples/widgets/doc/interview.qdoc b/examples/widgets/doc/src/interview.qdoc index 35721ccfae..35721ccfae 100644 --- a/examples/widgets/doc/interview.qdoc +++ b/examples/widgets/doc/src/interview.qdoc diff --git a/examples/widgets/doc/itemviewspuzzle.qdoc b/examples/widgets/doc/src/itemviewspuzzle.qdoc index ca8288cf1c..ca8288cf1c 100644 --- a/examples/widgets/doc/itemviewspuzzle.qdoc +++ b/examples/widgets/doc/src/itemviewspuzzle.qdoc diff --git a/examples/widgets/doc/licensewizard.qdoc b/examples/widgets/doc/src/licensewizard.qdoc index 125e0fec8f..125e0fec8f 100644 --- a/examples/widgets/doc/licensewizard.qdoc +++ b/examples/widgets/doc/src/licensewizard.qdoc diff --git a/examples/widgets/doc/lighting.qdoc b/examples/widgets/doc/src/lighting.qdoc index aafa70f38c..aafa70f38c 100644 --- a/examples/widgets/doc/lighting.qdoc +++ b/examples/widgets/doc/src/lighting.qdoc diff --git a/examples/widgets/doc/lineedits.qdoc b/examples/widgets/doc/src/lineedits.qdoc index c9cb7b5f43..c9cb7b5f43 100644 --- a/examples/widgets/doc/lineedits.qdoc +++ b/examples/widgets/doc/src/lineedits.qdoc diff --git a/examples/widgets/doc/mainwindow.qdoc b/examples/widgets/doc/src/mainwindow.qdoc index b4f6aebed1..b4f6aebed1 100644 --- a/examples/widgets/doc/mainwindow.qdoc +++ b/examples/widgets/doc/src/mainwindow.qdoc diff --git a/examples/widgets/doc/mdi.qdoc b/examples/widgets/doc/src/mdi.qdoc index e8b1b5c9ef..e8b1b5c9ef 100644 --- a/examples/widgets/doc/mdi.qdoc +++ b/examples/widgets/doc/src/mdi.qdoc diff --git a/examples/widgets/doc/menus.qdoc b/examples/widgets/doc/src/menus.qdoc index 3531e439c1..3531e439c1 100644 --- a/examples/widgets/doc/menus.qdoc +++ b/examples/widgets/doc/src/menus.qdoc diff --git a/examples/widgets/doc/moveblocks.qdoc b/examples/widgets/doc/src/moveblocks.qdoc index 8c12280989..8c12280989 100644 --- a/examples/widgets/doc/moveblocks.qdoc +++ b/examples/widgets/doc/src/moveblocks.qdoc diff --git a/examples/widgets/doc/movie.qdoc b/examples/widgets/doc/src/movie.qdoc index e636ce5902..e636ce5902 100644 --- a/examples/widgets/doc/movie.qdoc +++ b/examples/widgets/doc/src/movie.qdoc diff --git a/examples/widgets/doc/orderform.qdoc b/examples/widgets/doc/src/orderform.qdoc index ed40c65093..ed40c65093 100644 --- a/examples/widgets/doc/orderform.qdoc +++ b/examples/widgets/doc/src/orderform.qdoc diff --git a/examples/widgets/doc/padnavigator.qdoc b/examples/widgets/doc/src/padnavigator.qdoc index 8b1da516b5..8b1da516b5 100644 --- a/examples/widgets/doc/padnavigator.qdoc +++ b/examples/widgets/doc/src/padnavigator.qdoc diff --git a/examples/widgets/doc/painterpaths.qdoc b/examples/widgets/doc/src/painterpaths.qdoc index 45b0697cee..45b0697cee 100644 --- a/examples/widgets/doc/painterpaths.qdoc +++ b/examples/widgets/doc/src/painterpaths.qdoc diff --git a/examples/widgets/doc/pathstroke.qdoc b/examples/widgets/doc/src/pathstroke.qdoc index 89a0182934..89a0182934 100644 --- a/examples/widgets/doc/pathstroke.qdoc +++ b/examples/widgets/doc/src/pathstroke.qdoc diff --git a/examples/widgets/doc/pingpong.qdoc b/examples/widgets/doc/src/pingpong.qdoc index c56085d8cf..c56085d8cf 100644 --- a/examples/widgets/doc/pingpong.qdoc +++ b/examples/widgets/doc/src/pingpong.qdoc diff --git a/examples/widgets/doc/pixelator.qdoc b/examples/widgets/doc/src/pixelator.qdoc index 099c382c82..099c382c82 100644 --- a/examples/widgets/doc/pixelator.qdoc +++ b/examples/widgets/doc/src/pixelator.qdoc diff --git a/examples/widgets/doc/recentfiles.qdoc b/examples/widgets/doc/src/recentfiles.qdoc index e2e876b088..e2e876b088 100644 --- a/examples/widgets/doc/recentfiles.qdoc +++ b/examples/widgets/doc/src/recentfiles.qdoc diff --git a/examples/widgets/doc/rogue.qdoc b/examples/widgets/doc/src/rogue.qdoc index 4c65dd2d6e..4c65dd2d6e 100644 --- a/examples/widgets/doc/rogue.qdoc +++ b/examples/widgets/doc/src/rogue.qdoc diff --git a/examples/widgets/doc/screenshot.qdoc b/examples/widgets/doc/src/screenshot.qdoc index 2d41cf0d85..2d41cf0d85 100644 --- a/examples/widgets/doc/screenshot.qdoc +++ b/examples/widgets/doc/src/screenshot.qdoc diff --git a/examples/widgets/doc/scribble.qdoc b/examples/widgets/doc/src/scribble.qdoc index 5749b9ed07..5749b9ed07 100644 --- a/examples/widgets/doc/scribble.qdoc +++ b/examples/widgets/doc/src/scribble.qdoc diff --git a/examples/widgets/doc/sdi.qdoc b/examples/widgets/doc/src/sdi.qdoc index b686888797..b686888797 100644 --- a/examples/widgets/doc/sdi.qdoc +++ b/examples/widgets/doc/src/sdi.qdoc diff --git a/examples/widgets/doc/shapedclock.qdoc b/examples/widgets/doc/src/shapedclock.qdoc index 8d7b856fd6..8d7b856fd6 100644 --- a/examples/widgets/doc/shapedclock.qdoc +++ b/examples/widgets/doc/src/shapedclock.qdoc diff --git a/examples/widgets/doc/simpledommodel.qdoc b/examples/widgets/doc/src/simpledommodel.qdoc index 2564c654fa..2564c654fa 100644 --- a/examples/widgets/doc/simpledommodel.qdoc +++ b/examples/widgets/doc/src/simpledommodel.qdoc diff --git a/examples/widgets/doc/simpletreemodel.qdoc b/examples/widgets/doc/src/simpletreemodel.qdoc index c054352cb8..c054352cb8 100644 --- a/examples/widgets/doc/simpletreemodel.qdoc +++ b/examples/widgets/doc/src/simpletreemodel.qdoc diff --git a/examples/widgets/doc/simplewidgetmapper.qdoc b/examples/widgets/doc/src/simplewidgetmapper.qdoc index 2b7cd2d79a..2b7cd2d79a 100644 --- a/examples/widgets/doc/simplewidgetmapper.qdoc +++ b/examples/widgets/doc/src/simplewidgetmapper.qdoc diff --git a/examples/widgets/doc/sipdialog.qdoc b/examples/widgets/doc/src/sipdialog.qdoc index b5f18cb4be..b5f18cb4be 100644 --- a/examples/widgets/doc/sipdialog.qdoc +++ b/examples/widgets/doc/src/sipdialog.qdoc diff --git a/examples/widgets/doc/sliders.qdoc b/examples/widgets/doc/src/sliders.qdoc index 209d81198d..209d81198d 100644 --- a/examples/widgets/doc/sliders.qdoc +++ b/examples/widgets/doc/src/sliders.qdoc diff --git a/examples/widgets/doc/spinboxdelegate.qdoc b/examples/widgets/doc/src/spinboxdelegate.qdoc index 258811cc4c..258811cc4c 100644 --- a/examples/widgets/doc/spinboxdelegate.qdoc +++ b/examples/widgets/doc/src/spinboxdelegate.qdoc diff --git a/examples/widgets/doc/spinboxes.qdoc b/examples/widgets/doc/src/spinboxes.qdoc index ed4eea6a60..ed4eea6a60 100644 --- a/examples/widgets/doc/spinboxes.qdoc +++ b/examples/widgets/doc/src/spinboxes.qdoc diff --git a/examples/widgets/doc/spreadsheet.qdoc b/examples/widgets/doc/src/spreadsheet.qdoc index 7364f022cb..7364f022cb 100644 --- a/examples/widgets/doc/spreadsheet.qdoc +++ b/examples/widgets/doc/src/spreadsheet.qdoc diff --git a/examples/widgets/doc/standarddialogs.qdoc b/examples/widgets/doc/src/standarddialogs.qdoc index b56642b6ec..b56642b6ec 100644 --- a/examples/widgets/doc/standarddialogs.qdoc +++ b/examples/widgets/doc/src/standarddialogs.qdoc diff --git a/examples/widgets/doc/stardelegate.qdoc b/examples/widgets/doc/src/stardelegate.qdoc index aba8864c2b..aba8864c2b 100644 --- a/examples/widgets/doc/stardelegate.qdoc +++ b/examples/widgets/doc/src/stardelegate.qdoc diff --git a/examples/widgets/doc/states.qdoc b/examples/widgets/doc/src/states.qdoc index 52eda087f1..52eda087f1 100644 --- a/examples/widgets/doc/states.qdoc +++ b/examples/widgets/doc/src/states.qdoc diff --git a/examples/widgets/doc/stickman.qdoc b/examples/widgets/doc/src/stickman.qdoc index cffdb64822..cffdb64822 100644 --- a/examples/widgets/doc/stickman.qdoc +++ b/examples/widgets/doc/src/stickman.qdoc diff --git a/examples/widgets/doc/styles.qdoc b/examples/widgets/doc/src/styles.qdoc index f8be98d2da..f8be98d2da 100644 --- a/examples/widgets/doc/styles.qdoc +++ b/examples/widgets/doc/src/styles.qdoc diff --git a/examples/widgets/doc/stylesheet.qdoc b/examples/widgets/doc/src/stylesheet.qdoc index af45411f8c..af45411f8c 100644 --- a/examples/widgets/doc/stylesheet.qdoc +++ b/examples/widgets/doc/src/stylesheet.qdoc diff --git a/examples/widgets/doc/sub-attaq.qdoc b/examples/widgets/doc/src/sub-attaq.qdoc index ae00eb0926..ae00eb0926 100644 --- a/examples/widgets/doc/sub-attaq.qdoc +++ b/examples/widgets/doc/src/sub-attaq.qdoc diff --git a/examples/widgets/doc/syntaxhighlighter.qdoc b/examples/widgets/doc/src/syntaxhighlighter.qdoc index 66727c0030..66727c0030 100644 --- a/examples/widgets/doc/syntaxhighlighter.qdoc +++ b/examples/widgets/doc/src/syntaxhighlighter.qdoc diff --git a/examples/widgets/doc/tabdialog.qdoc b/examples/widgets/doc/src/tabdialog.qdoc index 98983d124b..98983d124b 100644 --- a/examples/widgets/doc/tabdialog.qdoc +++ b/examples/widgets/doc/src/tabdialog.qdoc diff --git a/examples/widgets/doc/tablet.qdoc b/examples/widgets/doc/src/tablet.qdoc index 846a9a357b..846a9a357b 100644 --- a/examples/widgets/doc/tablet.qdoc +++ b/examples/widgets/doc/src/tablet.qdoc diff --git a/examples/widgets/doc/tetrix.qdoc b/examples/widgets/doc/src/tetrix.qdoc index 1a30845024..1a30845024 100644 --- a/examples/widgets/doc/tetrix.qdoc +++ b/examples/widgets/doc/src/tetrix.qdoc diff --git a/examples/widgets/doc/textedit.qdoc b/examples/widgets/doc/src/textedit.qdoc index 1bb596eb6e..1bb596eb6e 100644 --- a/examples/widgets/doc/textedit.qdoc +++ b/examples/widgets/doc/src/textedit.qdoc diff --git a/examples/widgets/doc/tooltips.qdoc b/examples/widgets/doc/src/tooltips.qdoc index e06f080a93..e06f080a93 100644 --- a/examples/widgets/doc/tooltips.qdoc +++ b/examples/widgets/doc/src/tooltips.qdoc diff --git a/examples/widgets/doc/trafficlight.qdoc b/examples/widgets/doc/src/trafficlight.qdoc index ec3578abaa..ec3578abaa 100644 --- a/examples/widgets/doc/trafficlight.qdoc +++ b/examples/widgets/doc/src/trafficlight.qdoc diff --git a/examples/widgets/doc/transformations.qdoc b/examples/widgets/doc/src/transformations.qdoc index 79681a2799..79681a2799 100644 --- a/examples/widgets/doc/transformations.qdoc +++ b/examples/widgets/doc/src/transformations.qdoc diff --git a/examples/widgets/doc/trivialwizard.qdoc b/examples/widgets/doc/src/trivialwizard.qdoc index e27f9cadc2..e27f9cadc2 100644 --- a/examples/widgets/doc/trivialwizard.qdoc +++ b/examples/widgets/doc/src/trivialwizard.qdoc diff --git a/examples/widgets/doc/twowaybutton.qdoc b/examples/widgets/doc/src/twowaybutton.qdoc index 40f8c6f1f3..40f8c6f1f3 100644 --- a/examples/widgets/doc/twowaybutton.qdoc +++ b/examples/widgets/doc/src/twowaybutton.qdoc diff --git a/examples/widgets/doc/wiggly.qdoc b/examples/widgets/doc/src/wiggly.qdoc index e84ab00e61..e84ab00e61 100644 --- a/examples/widgets/doc/wiggly.qdoc +++ b/examples/widgets/doc/src/wiggly.qdoc diff --git a/examples/widgets/doc/windowflags.qdoc b/examples/widgets/doc/src/windowflags.qdoc index e85842b30a..e85842b30a 100644 --- a/examples/widgets/doc/windowflags.qdoc +++ b/examples/widgets/doc/src/windowflags.qdoc |