~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to examples/widgets/doc/src/addressbook.qdoc

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the documentation of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:FDL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Free Documentation License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Free
 
19
** Documentation License version 1.3 as published by the Free Software
 
20
** Foundation and appearing in the file included in the packaging of
 
21
** this file.  Please review the following information to ensure
 
22
** the GNU Free Documentation License version 1.3 requirements
 
23
** will be met: http://www.gnu.org/copyleft/fdl.html.
 
24
** $QT_END_LICENSE$
 
25
**
 
26
****************************************************************************/
 
27
 
 
28
/*!
 
29
    \example itemviews/addressbook
 
30
    \title Address Book Example
 
31
    \ingroup examples-itemviews
 
32
    \brief The address book example shows how to use proxy models to display
 
33
    different views onto data from a single model.
 
34
 
 
35
    \image addressbook-example.png Screenshot of the Address Book example
 
36
 
 
37
    This example provides an address book that allows contacts to be
 
38
    grouped alphabetically into 9 groups: ABC, DEF, GHI, ... , VW,
 
39
    ..., XYZ. This is achieved by using multiple views on the same
 
40
    model, each of which is filtered using an instance of the
 
41
    QSortFilterProxyModel class.
 
42
 
 
43
 
 
44
    \section1 Overview
 
45
 
 
46
    The address book contains 5 classes: \c MainWindow,
 
47
    \c AddressWidget, \c TableModel, \c NewAddressTab and
 
48
    \c AddDialog. The \c MainWindow class uses \c AddressWidget as
 
49
    its central widget and provides \uicontrol File and \uicontrol Tools menus.
 
50
 
 
51
    \image addressbook-classes.png Diagram for Address Book Example
 
52
 
 
53
    The \c AddressWidget class is a QTabWidget subclass that is used
 
54
    to manipulate the 10 tabs displayed in the example: the 9
 
55
    alphabet group tabs and an instance of \c NewAddressTab.
 
56
    The \c NewAddressTab class is a subclass of QWidget that
 
57
    is only used whenever the address book is empty, prompting the
 
58
    user to add some contacts. \c AddressWidget also interacts with
 
59
    an instance of \c TableModel to add, edit and remove entries to
 
60
    the address book.
 
61
 
 
62
    \c TableModel is a subclass of QAbstractTableModel that provides
 
63
    the standard model/view API to access data. It also holds a
 
64
    QList of \l{QPair}s corresponding to the contacts added.
 
65
    However, this data is not all visible in a single tab. Instead,
 
66
    QTableView is used to provide 9 different views of the same
 
67
    data, according to the alphabet groups.
 
68
 
 
69
    QSortFilterProxyModel is the class responsible for filtering
 
70
    the contacts for each group of contacts. Each proxy model uses
 
71
    a QRegExp to filter out contacts that do not belong in the
 
72
    corresponding alphabetical group. The \c AddDialog class is
 
73
    used to obtain information from the user for the address book.
 
74
    This QDialog subclass is instantiated by \c NewAddressTab to
 
75
    add contacts, and by \c AddressWidget to add and edit contacts.
 
76
 
 
77
    We begin by looking at the \c TableModel implementation.
 
78
 
 
79
 
 
80
    \section1 TableModel Class Definition
 
81
 
 
82
    The \c TableModel class provides standard API to access data in
 
83
    its QList of \l{QPair}s by subclassing QAbstractTableModel. The
 
84
    basic functions that must be implemented in order to do so are:
 
85
    \c rowCount(), \c columnCount(), \c data(), \c headerData().
 
86
    For TableModel to be editable, it has to provide implementations
 
87
    \c insertRows(), \c removeRows(), \c setData() and \c flags()
 
88
    functions.
 
89
 
 
90
    \snippet itemviews/addressbook/tablemodel.h 0
 
91
 
 
92
    Two constructors are used, a default constructor which uses
 
93
    \c TableModel's own \c {QList<QPair<QString, QString>>} and one
 
94
    that takes \c {QList<QPair<QString, QString>} as an argument,
 
95
    for convenience.
 
96
 
 
97
 
 
98
    \section1 TableModel Class Implementation
 
99
 
 
100
    We implement the two constructors as defined in the header file.
 
101
    The second constructor initializes the list of pairs in the
 
102
    model, with the parameter value.
 
103
 
 
104
    \snippet itemviews/addressbook/tablemodel.cpp 0
 
105
 
 
106
    The \c rowCount() and \c columnCount() functions return the
 
107
    dimensions of the model. Whereas, \c rowCount()'s value will vary
 
108
    depending on the number of contacts added to the address book,
 
109
    \c columnCount()'s value is always 2 because we only need space
 
110
    for the \b Name and \b Address columns.
 
111
 
 
112
    \note The \c Q_UNUSED() macro prevents the compiler from
 
113
    generating warnings regarding unused parameters.
 
114
 
 
115
    \snippet itemviews/addressbook/tablemodel.cpp 1
 
116
 
 
117
    The \c data() function returns either a \b Name or
 
118
    \b {Address}, based on the contents of the model index
 
119
    supplied. The row number stored in the model index is used to
 
120
    reference an item in the list of pairs. Selection is handled
 
121
    by the QItemSelectionModel, which will be explained with
 
122
    \c AddressWidget.
 
123
 
 
124
    \snippet itemviews/addressbook/tablemodel.cpp 2
 
125
 
 
126
    The \c headerData() function displays the table's header,
 
127
    \b Name and \b Address. If you require numbered entries
 
128
    for your address book, you can use a vertical header which we
 
129
    have hidden in this example (see the \c AddressWidget
 
130
    implementation).
 
131
 
 
132
    \snippet itemviews/addressbook/tablemodel.cpp 3
 
133
 
 
134
    The \c insertRows() function is called before new data is added,
 
135
    otherwise the data will not be displayed. The
 
136
    \c beginInsertRows() and \c endInsertRows() functions are called
 
137
    to ensure all connected views are aware of the changes.
 
138
 
 
139
    \snippet itemviews/addressbook/tablemodel.cpp 4
 
140
 
 
141
    The \c removeRows() function is called to remove data. Again,
 
142
    \l{QAbstractItemModel::}{beginRemoveRows()} and
 
143
    \l{QAbstractItemModel::}{endRemoveRows()} are called to ensure
 
144
    all connected views are aware of the changes.
 
145
 
 
146
    \snippet itemviews/addressbook/tablemodel.cpp 5
 
147
 
 
148
    The \c setData() function is the function that inserts data into
 
149
    the table, item by item and not row by row. This means that to
 
150
    fill a row in the address book, \c setData() must be called
 
151
    twice, as each row has 2 columns. It is important to emit the
 
152
    \l{QAbstractItemModel::}{dataChanged()} signal as it tells all
 
153
    connected views to update their displays.
 
154
 
 
155
    \snippet itemviews/addressbook/tablemodel.cpp 6
 
156
 
 
157
    The \c flags() function returns the item flags for the given
 
158
    index.
 
159
 
 
160
    \snippet itemviews/addressbook/tablemodel.cpp 7
 
161
 
 
162
    We set the Qt::ItemIsEditable flag because we want to allow the
 
163
    \c TableModel to be edited. Although for this example we don't
 
164
    use the editing features of the QTableView object, we enable
 
165
    them here so that we can reuse the model in other programs.
 
166
 
 
167
    The last function in \c {TableModel}, \c getList() returns the
 
168
    QList<QPair<QString, QString>> object that holds all the
 
169
    contacts in the address book. We use this function later to
 
170
    obtain the list of contacts to check for existing entries, write
 
171
    the contacts to a file and read them back. Further explanation is
 
172
    given with \c AddressWidget.
 
173
 
 
174
    \snippet itemviews/addressbook/tablemodel.cpp 8
 
175
 
 
176
 
 
177
    \section1 AddressWidget Class Definition
 
178
 
 
179
    The \c AddressWidget class is technically the main class
 
180
    involved in this example as it provides functions to add, edit
 
181
    and remove contacts, to save the contacts to a file and to load
 
182
    them from a file.
 
183
 
 
184
    \snippet itemviews/addressbook/addresswidget.h 0
 
185
 
 
186
    \c AddressWidget extends QTabWidget in order to hold 10 tabs
 
187
    (\c NewAddressTab and the 9 alphabet group tabs) and also
 
188
    manipulates \c table, the \c TableModel object, \c proxyModel,
 
189
    the QSortFilterProxyModel object that we use to filter the
 
190
    entries, and \c tableView, the QTableView object.
 
191
 
 
192
 
 
193
    \section1 AddressWidget Class Implementation
 
194
 
 
195
    The \c AddressWidget constructor accepts a parent widget and
 
196
    instantiates \c NewAddressTab, \c TableModel and
 
197
    QSortFilterProxyModel. The \c NewAddressTab object, which is
 
198
    used to indicate that the address book is empty, is added
 
199
    and the rest of the 9 tabs are set up with \c setupTabs().
 
200
 
 
201
    \snippet itemviews/addressbook/addresswidget.cpp 0
 
202
 
 
203
    The \c setupTabs() function is used to set up the 9 alphabet
 
204
    group tabs, table views and proxy models in
 
205
    \c AddressWidget. Each proxy model in turn is set to filter
 
206
    contact names according to the relevant alphabet group using a
 
207
    \l{Qt::CaseInsensitive}{case-insensitive} QRegExp object. The
 
208
    table views are also sorted in ascending order using the
 
209
    corresponding proxy model's \l{QSortFilterProxyModel::}{sort()}
 
210
    function.
 
211
 
 
212
    Each table view's \l{QTableView::}{selectionMode} is set to
 
213
    QAbstractItemView::SingleSelection and
 
214
    \l{QTableView::}{selectionBehavior} is set to
 
215
    QAbstractItemView::SelectRows, allowing the user to select
 
216
    all the items in one row at the same time. Each QTableView object
 
217
    is automatically given a QItemSelectionModel that keeps track
 
218
    of the selected indexes.
 
219
 
 
220
    \snippet itemviews/addressbook/addresswidget.cpp 1
 
221
 
 
222
    The QItemSelectionModel class provides a
 
223
    \l{QItemSelectionModel::selectionChanged()}{selectionChanged}
 
224
    signal that is connected to \c{AddressWidget}'s
 
225
    \c selectionChanged() signal. This signal to signal connection
 
226
    is necessary to enable the \uicontrol{Edit Entry...} and
 
227
    \uicontrol{Remove Entry} actions in \c MainWindow's Tools menu. This
 
228
    connection is further explained in \c MainWindow's
 
229
    implementation.
 
230
 
 
231
    Each table view in the address book is added as a tab to the
 
232
    QTabWidget with the relevant label, obtained from the QStringList
 
233
    of groups.
 
234
 
 
235
    \image addressbook-signals.png Signals and Slots Connections
 
236
 
 
237
    We provide 2 \c addEntry() functions: 1 which is intended to be
 
238
    used to accept user input, and the other which performs the actual
 
239
    task of adding new entries to the address book. We divide the
 
240
    responsibility of adding entries into two parts to allow
 
241
    \c newAddressTab to  insert data without having to popup a dialog.
 
242
 
 
243
    The first \c addEntry() function is a slot connected to the
 
244
    \c MainWindow's \uicontrol{Add Entry...} action. This function creates an
 
245
    \c AddDialog object and then calls the second \c addEntry()
 
246
    function to actually add the contact to \c table.
 
247
 
 
248
    \snippet itemviews/addressbook/addresswidget.cpp 2
 
249
 
 
250
    Basic validation is done in the second \c addEntry() function to
 
251
    prevent duplicate entries in the address book. As mentioned with
 
252
    \c TableModel, this is part of the reason why we require the
 
253
    getter method \c getList().
 
254
 
 
255
    \snippet itemviews/addressbook/addresswidget.cpp 3
 
256
 
 
257
    If the model does not already contain an entry with the same name,
 
258
    we call \c setData() to insert the name and address into the
 
259
    first and second columns. Otherwise, we display a QMessageBox
 
260
    to inform the user.
 
261
 
 
262
    \note The \c newAddressTab is removed once a contact is added
 
263
    as the address book is no longer empty.
 
264
 
 
265
    Editing an entry is a way to update the contact's address only,
 
266
    as the example does not allow the user to change the name of an
 
267
    existing contact.
 
268
 
 
269
    Firstly, we obtain the active tab's QTableView object using
 
270
    QTabWidget::currentWidget(). Then we extract the
 
271
    \c selectionModel from the \c tableView to obtain the selected
 
272
    indexes.
 
273
 
 
274
    \snippet itemviews/addressbook/addresswidget.cpp 4a
 
275
 
 
276
    Next we extract data from the row the user intends to 
 
277
    edit. This data is displayed in an instance of \c AddDialog
 
278
    with a different window title. The \c table is only
 
279
    updated if changes have been made to data in \c aDialog.
 
280
 
 
281
    \snippet itemviews/addressbook/addresswidget.cpp 4b
 
282
 
 
283
    \image addressbook-editdialog.png Screenshot of Dialog to Edit a Contact
 
284
 
 
285
    Entries are removed using the \c removeEntry() function.
 
286
    The selected row is removed by accessing it through the
 
287
    QItemSelectionModel object, \c selectionModel. The
 
288
    \c newAddressTab is re-added to the \c AddressWidget only if
 
289
    the user removes all the contacts in the address book.
 
290
 
 
291
    \snippet itemviews/addressbook/addresswidget.cpp 5
 
292
 
 
293
    The \c writeToFile() function is used to save a file containing
 
294
    all the contacts in the address book. The file is saved in a
 
295
    custom \c{.dat} format. The contents of the QList of \l{QPair}s
 
296
    are written to \c file using QDataStream. If the file cannot be
 
297
    opened, a QMessageBox is displayed with the related error message.
 
298
 
 
299
    \snippet itemviews/addressbook/addresswidget.cpp 6
 
300
 
 
301
    The \c readFromFile() function loads a file containing all the
 
302
    contacts in the address book, previously saved using
 
303
    \c writeToFile(). QDataStream is used to read the contents of a
 
304
    \c{.dat} file into a list of pairs and each of these is added
 
305
    using \c addEntry().
 
306
 
 
307
    \snippet itemviews/addressbook/addresswidget.cpp 7
 
308
 
 
309
 
 
310
    \section1 NewAddressTab Class Definition
 
311
 
 
312
    The \c NewAddressTab class provides an informative tab telling
 
313
    the user that the address book is empty. It appears and
 
314
    disappears according to the contents of the address book, as
 
315
    mentioned in \c{AddressWidget}'s implementation.
 
316
 
 
317
    \image addressbook-newaddresstab.png Screenshot of NewAddressTab
 
318
 
 
319
    The \c NewAddressTab class extends QWidget and contains a QLabel
 
320
    and QPushButton.
 
321
 
 
322
    \snippet itemviews/addressbook/newaddresstab.h 0
 
323
 
 
324
 
 
325
    \section1 NewAddressTab Class Implementation
 
326
 
 
327
    The constructor instantiates the \c addButton,
 
328
    \c descriptionLabel and connects the \c{addButton}'s signal to
 
329
    the \c{addEntry()} slot.
 
330
 
 
331
    \snippet itemviews/addressbook/newaddresstab.cpp 0
 
332
 
 
333
    The \c addEntry() function is similar to \c AddressWidget's
 
334
    \c addEntry() in the sense that both functions instantiate an
 
335
    \c AddDialog object. Data from the dialog is extracted and sent
 
336
    to \c AddressWidget's \c addEntry() slot by emitting the
 
337
    \c sendDetails() signal.
 
338
 
 
339
    \snippet itemviews/addressbook/newaddresstab.cpp 1
 
340
 
 
341
    \image signals-n-slots-aw-nat.png
 
342
 
 
343
 
 
344
    \section1 AddDialog Class Definition
 
345
 
 
346
    The \c AddDialog class extends QDialog and provides the user
 
347
    with a QLineEdit and a QTextEdit to input data into the
 
348
    address book.
 
349
 
 
350
    \snippet itemviews/addressbook/adddialog.h 0
 
351
 
 
352
    \image addressbook-adddialog.png
 
353
 
 
354
 
 
355
    \section1 AddDialog Class Implementation
 
356
 
 
357
    The \c AddDialog's constructor sets up the user interface,
 
358
    creating the necessary widgets and placing them into layouts.
 
359
 
 
360
    \snippet itemviews/addressbook/adddialog.cpp 0
 
361
 
 
362
    To give the dialog the desired behavior, we connect the \uicontrol OK
 
363
    and \uicontrol Cancel buttons to the dialog's \l{QDialog::}{accept()} and
 
364
    \l{QDialog::}{reject()} slots. Since the dialog only acts as a
 
365
    container for name and address information, we do not need to
 
366
    implement any other functions for it.
 
367
 
 
368
 
 
369
    \section1 MainWindow Class Definition
 
370
 
 
371
    The \c MainWindow class extends QMainWindow and implements the
 
372
    menus and actions necessary to manipulate the address book.
 
373
 
 
374
    \table
 
375
    \row \li \inlineimage addressbook-filemenu.png
 
376
         \li \inlineimage addressbook-toolsmenu.png
 
377
    \endtable
 
378
 
 
379
    \snippet itemviews/addressbook/mainwindow.h 0
 
380
 
 
381
    The \c MainWindow class uses an \c AddressWidget as its central
 
382
    widget and provides the File menu with \uicontrol Open, \uicontrol Close and
 
383
    \uicontrol Exit actions, as well as the \uicontrol Tools menu with
 
384
    \uicontrol{Add Entry...}, \uicontrol{Edit Entry...} and \uicontrol{Remove Entry}
 
385
    actions.
 
386
 
 
387
 
 
388
    \section1 MainWindow Class Implementation
 
389
 
 
390
    The constructor for \c MainWindow instantiates AddressWidget,
 
391
    sets it as its central widget and calls the \c createMenus()
 
392
    function.
 
393
 
 
394
    \snippet itemviews/addressbook/mainwindow.cpp 0
 
395
 
 
396
    The \c createMenus() function sets up the \uicontrol File and
 
397
    \uicontrol Tools menus, connecting the actions to their respective slots.
 
398
    Both the \uicontrol{Edit Entry...} and \uicontrol{Remove Entry} actions are
 
399
    disabled by default as such actions cannot be carried out on an empty
 
400
    address book. They are only enabled when one or more contacts
 
401
    are added.
 
402
 
 
403
    \snippet itemviews/addressbook/mainwindow.cpp 1a
 
404
    \dots
 
405
    \codeline
 
406
    \snippet itemviews/addressbook/mainwindow.cpp 1b
 
407
 
 
408
    Apart from connecting all the actions' signals to their
 
409
    respective slots, we also connect \c AddressWidget's
 
410
    \c selectionChanged() signal to its \c updateActions() slot.
 
411
 
 
412
    The \c openFile() function allows the user to choose a file with
 
413
    the \l{QFileDialog::getOpenFileName()}{open file dialog}. The chosen
 
414
    file has to be a custom \c{.dat} file that contains address book
 
415
    contacts. This function is a slot connected to \c openAct in the
 
416
    \uicontrol File menu.
 
417
 
 
418
    \snippet itemviews/addressbook/mainwindow.cpp 2
 
419
 
 
420
    The \c saveFile() function allows the user to save a file with
 
421
    the \l{QFileDialog::getSaveFileName()}{save file dialog}. This function
 
422
    is a slot connected to \c saveAct in the \uicontrol File menu.
 
423
 
 
424
    \snippet itemviews/addressbook/mainwindow.cpp 3
 
425
 
 
426
    The \c updateActions() function enables and disables
 
427
    \uicontrol{Edit Entry...} and \uicontrol{Remove Entry} depending on the contents of
 
428
    the address book. If the address book is empty, these actions
 
429
    are disabled; otherwise, they are enabled. This function is a slot
 
430
    is connected to the \c AddressWidget's \c selectionChanged()
 
431
    signal.
 
432
 
 
433
    \snippet itemviews/addressbook/mainwindow.cpp 4
 
434
 
 
435
 
 
436
    \section1 main() Function
 
437
 
 
438
    The main function for the address book instantiates QApplication
 
439
    and opens a \c MainWindow before running the event loop.
 
440
 
 
441
    \snippet itemviews/addressbook/main.cpp 0
 
442
*/