From 47799adc0d1bfb9e0e592dbc9af3eb4680e0c81b Mon Sep 17 00:00:00 2001 From: Casper van Donderen Date: Wed, 9 May 2012 12:35:30 +0200 Subject: Doc: Move some remaining files over for modularization. The files in this change were still in qtbase/doc/src or required for it. qtbase/doc/src should now only contain example documentation and images for the example documentation. Change-Id: Ia7ca8e7fd2b316e77c706a08df71303bc8294213 Reviewed-by: Marius Storm-Olsen --- src/corelib/doc/images/resources.png | Bin 0 -> 49998 bytes .../doc/snippets/code/doc_src_resources.cpp | 54 + .../doc/snippets/code/doc_src_resources.qdoc | 65 + src/corelib/doc/src/io.qdoc | 39 + src/corelib/doc/src/resource-system.qdoc | 202 ++ src/corelib/global/qlogging.cpp | 6 +- src/corelib/io/qfiledevice.cpp | 4 +- src/corelib/io/qurlquery.cpp | 2 +- src/corelib/tools/qhash.cpp | 2 +- src/corelib/tools/qstringlist.cpp | 8 +- src/gui/doc/images/qrect-diagram-zero.png | Bin 0 -> 5198 bytes src/gui/doc/images/qrectf-diagram-one.png | Bin 0 -> 9594 bytes src/gui/doc/images/qrectf-diagram-three.png | Bin 0 -> 9392 bytes src/gui/doc/images/qrectf-diagram-two.png | Bin 0 -> 9387 bytes src/gui/doc/snippets/code/doc_src_coordsys.cpp | 87 + src/gui/doc/src/coordsys.qdoc | 20 +- src/gui/kernel/qkeysequence.cpp | 38 +- src/gui/text/qabstracttextdocumentlayout.cpp | 2 +- src/network/doc/images/tcpstream.png | Bin 0 -> 11470 bytes src/network/doc/images/udppackets.png | Bin 0 -> 24707 bytes src/network/doc/src/bearermanagement.qdoc | 268 +++ src/network/doc/src/network-programming.qdoc | 291 +++ src/network/doc/src/ssl.qdoc | 79 + .../addressbook-tutorial-part1-labeled-layout.png | Bin 0 -> 19114 bytes ...dressbook-tutorial-part1-labeled-screenshot.png | Bin 0 -> 23223 bytes .../addressbook-tutorial-part1-screenshot.png | Bin 0 -> 9872 bytes .../addressbook-tutorial-part2-add-contact.png | Bin 0 -> 12936 bytes .../addressbook-tutorial-part2-add-flowchart.png | Bin 0 -> 23533 bytes .../addressbook-tutorial-part2-add-successful.png | Bin 0 -> 10825 bytes .../addressbook-tutorial-part2-labeled-layout.png | Bin 0 -> 27103 bytes ...ddressbook-tutorial-part2-signals-and-slots.png | Bin 0 -> 9968 bytes .../addressbook-tutorial-part2-stretch-effects.png | Bin 0 -> 12268 bytes .../addressbook-tutorial-part3-labeled-layout.png | Bin 0 -> 27467 bytes .../addressbook-tutorial-part3-linkedlist.png | Bin 0 -> 10209 bytes .../addressbook-tutorial-part3-screenshot.png | Bin 0 -> 14041 bytes .../images/addressbook-tutorial-part4-remove.png | Bin 0 -> 22248 bytes .../addressbook-tutorial-part5-finddialog.png | Bin 0 -> 10046 bytes .../images/addressbook-tutorial-part5-notfound.png | Bin 0 -> 10789 bytes .../addressbook-tutorial-part5-screenshot.png | Bin 0 -> 15849 bytes ...ddressbook-tutorial-part5-signals-and-slots.png | Bin 0 -> 5542 bytes .../doc/images/addressbook-tutorial-part6-load.png | Bin 0 -> 24797 bytes .../doc/images/addressbook-tutorial-part6-save.png | Bin 0 -> 24747 bytes .../addressbook-tutorial-part6-screenshot.png | Bin 0 -> 16819 bytes .../addressbook-tutorial-part7-screenshot.png | Bin 0 -> 18369 bytes .../doc/images/addressbook-tutorial-screenshot.png | Bin 0 -> 15275 bytes src/widgets/doc/images/clock.png | Bin 0 -> 16514 bytes src/widgets/doc/images/columnview.png | Bin 0 -> 3480 bytes src/widgets/doc/images/dummy_tree.png | Bin 0 -> 20189 bytes src/widgets/doc/images/example_model.png | Bin 0 -> 16577 bytes src/widgets/doc/images/list_table_tree.png | Bin 0 -> 85530 bytes src/widgets/doc/images/listview.png | Bin 0 -> 9695 bytes .../doc/images/mainwindow-docks-example.png | Bin 0 -> 14427 bytes src/widgets/doc/images/modelview-combobox.png | Bin 0 -> 5022 bytes src/widgets/doc/images/modelview-header.png | Bin 0 -> 30302 bytes src/widgets/doc/images/modelview-models.png | Bin 0 -> 20540 bytes src/widgets/doc/images/modelview-overview.png | Bin 0 -> 15042 bytes src/widgets/doc/images/modelview-roles.png | Bin 0 -> 24954 bytes src/widgets/doc/images/modelview-tablemodel.png | Bin 0 -> 12256 bytes src/widgets/doc/images/modelview-treemodel.png | Bin 0 -> 9193 bytes src/widgets/doc/images/modelview.png | Bin 0 -> 2887 bytes src/widgets/doc/images/qcompleter.png | Bin 0 -> 17017 bytes src/widgets/doc/images/readonlytable_role.png | Bin 0 -> 27467 bytes src/widgets/doc/images/selected-items1.png | Bin 0 -> 31870 bytes src/widgets/doc/images/selected-items2.png | Bin 0 -> 32025 bytes src/widgets/doc/images/selected-items3.png | Bin 0 -> 32100 bytes src/widgets/doc/images/selection-extended.png | Bin 0 -> 11401 bytes src/widgets/doc/images/selection-multi.png | Bin 0 -> 13058 bytes src/widgets/doc/images/selection-single.png | Bin 0 -> 7849 bytes src/widgets/doc/images/selection2.png | Bin 0 -> 23784 bytes src/widgets/doc/images/shareddirmodel.png | Bin 0 -> 45891 bytes src/widgets/doc/images/sharedmodel-tableviews.png | Bin 0 -> 16811 bytes .../doc/images/sharedselection-tableviews.png | Bin 0 -> 14212 bytes src/widgets/doc/images/spinboxdelegate-example.png | Bin 0 -> 4762 bytes src/widgets/doc/images/standard-views.png | Bin 0 -> 44495 bytes src/widgets/doc/images/standardwidget.png | Bin 0 -> 1466 bytes src/widgets/doc/images/stardelegate.png | Bin 0 -> 12230 bytes src/widgets/doc/images/stringlistmodel.png | Bin 0 -> 4849 bytes src/widgets/doc/images/tableview.png | Bin 0 -> 10102 bytes src/widgets/doc/images/tree_2_with_algorithm.png | Bin 0 -> 16921 bytes src/widgets/doc/images/treeview.png | Bin 0 -> 17173 bytes src/widgets/doc/images/widgetmapper.png | Bin 0 -> 20145 bytes .../doc/images/widgets-tutorial-childwidget.png | Bin 0 -> 8547 bytes .../doc/images/widgets-tutorial-nestedlayouts.png | Bin 0 -> 23287 bytes .../doc/images/widgets-tutorial-toplevel.png | Bin 0 -> 6087 bytes .../doc/images/widgets-tutorial-windowlayout.png | Bin 0 -> 5849 bytes .../code/doc_src_model-view-programming.cpp | 76 + .../doc/snippets/code/doc_src_qt4-mainwindow.cpp | 110 + .../doc/snippets/dockwidgets/mainwindow.cpp | 122 + .../doc/snippets/itemselection/itemselection.pro | 3 + src/widgets/doc/snippets/itemselection/main.cpp | 115 + src/widgets/doc/snippets/itemselection/model.cpp | 238 ++ src/widgets/doc/snippets/itemselection/model.h | 74 + src/widgets/doc/snippets/qlistview-dnd/main.cpp | 51 + .../doc/snippets/qlistview-dnd/mainwindow.cpp | 83 + .../doc/snippets/qlistview-dnd/mainwindow.h | 61 + src/widgets/doc/snippets/qlistview-dnd/model.cpp | 167 ++ src/widgets/doc/snippets/qlistview-dnd/model.h | 73 + .../doc/snippets/qlistview-dnd/qlistview-dnd.pro | 5 + src/widgets/doc/snippets/qlistwidget-dnd/main.cpp | 51 + .../doc/snippets/qlistwidget-dnd/mainwindow.cpp | 87 + .../doc/snippets/qlistwidget-dnd/mainwindow.h | 62 + .../snippets/qlistwidget-dnd/qlistwidget-dnd.pro | 3 + .../doc/snippets/qsortfilterproxymodel/main.cpp | 77 + .../qsortfilterproxymodel.pro | 1 + .../snippets/qtablewidget-using/Images/cubed.png | Bin 0 -> 437 bytes .../snippets/qtablewidget-using/Images/squared.png | Bin 0 -> 440 bytes .../doc/snippets/qtablewidget-using/images.qrc | 6 + .../doc/snippets/qtablewidget-using/main.cpp | 51 + .../doc/snippets/qtablewidget-using/mainwindow.h | 70 + .../qtablewidget-using/qtablewidget-using.pro | 4 + .../doc/snippets/reading-selections/main.cpp | 59 + .../doc/snippets/reading-selections/model.cpp | 238 ++ .../doc/snippets/reading-selections/model.h | 74 + .../reading-selections/reading-selections.pro | 2 + .../doc/snippets/reading-selections/window.cpp | 120 + .../doc/snippets/reading-selections/window.h | 67 + src/widgets/doc/snippets/sharedtablemodel/main.cpp | 89 + .../doc/snippets/sharedtablemodel/model.cpp | 236 ++ src/widgets/doc/snippets/sharedtablemodel/model.h | 74 + .../snippets/sharedtablemodel/sharedtablemodel.pro | 2 + src/widgets/doc/snippets/simplemodel-use/main.cpp | 95 + .../snippets/simplemodel-use/simplemodel-use.pro | 1 + src/widgets/doc/snippets/stringlistmodel/main.cpp | 83 + src/widgets/doc/snippets/stringlistmodel/model.cpp | 211 ++ src/widgets/doc/snippets/stringlistmodel/model.h | 82 + .../snippets/stringlistmodel/stringlistmodel.pro | 3 + .../doc/snippets/updating-selections/main.cpp | 59 + .../doc/snippets/updating-selections/model.cpp | 236 ++ .../doc/snippets/updating-selections/model.h | 74 + .../updating-selections/updating-selections.pro | 2 + .../doc/snippets/updating-selections/window.cpp | 109 + .../doc/snippets/updating-selections/window.h | 67 + .../doc/snippets/widgets-tutorial/template.cpp | 56 + src/widgets/doc/src/addressbook-fr.qdoc | 1036 +++++++++ src/widgets/doc/src/addressbook.qdoc | 981 ++++++++ src/widgets/doc/src/model-view-programming.qdoc | 2339 ++++++++++++++++++++ src/widgets/doc/src/modelview.qdoc | 897 ++++++++ src/widgets/doc/src/widgets-tutorial.qdoc | 249 +++ .../doc/src/windows-and-dialogs/dialogs.qdoc | 60 + .../doc/src/windows-and-dialogs/mainwindow.qdoc | 261 +++ 140 files changed, 10578 insertions(+), 41 deletions(-) create mode 100644 src/corelib/doc/images/resources.png create mode 100644 src/corelib/doc/snippets/code/doc_src_resources.cpp create mode 100644 src/corelib/doc/snippets/code/doc_src_resources.qdoc create mode 100644 src/corelib/doc/src/io.qdoc create mode 100644 src/corelib/doc/src/resource-system.qdoc create mode 100644 src/gui/doc/images/qrect-diagram-zero.png create mode 100644 src/gui/doc/images/qrectf-diagram-one.png create mode 100644 src/gui/doc/images/qrectf-diagram-three.png create mode 100644 src/gui/doc/images/qrectf-diagram-two.png create mode 100644 src/gui/doc/snippets/code/doc_src_coordsys.cpp create mode 100644 src/network/doc/images/tcpstream.png create mode 100644 src/network/doc/images/udppackets.png create mode 100644 src/network/doc/src/bearermanagement.qdoc create mode 100644 src/network/doc/src/network-programming.qdoc create mode 100644 src/network/doc/src/ssl.qdoc create mode 100644 src/widgets/doc/images/addressbook-tutorial-part1-labeled-layout.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part1-labeled-screenshot.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part1-screenshot.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part2-add-contact.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part2-add-flowchart.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part2-add-successful.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part2-labeled-layout.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part2-signals-and-slots.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part2-stretch-effects.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part3-labeled-layout.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part3-linkedlist.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part3-screenshot.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part4-remove.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part5-finddialog.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part5-notfound.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part5-screenshot.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part5-signals-and-slots.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part6-load.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part6-save.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part6-screenshot.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-part7-screenshot.png create mode 100644 src/widgets/doc/images/addressbook-tutorial-screenshot.png create mode 100644 src/widgets/doc/images/clock.png create mode 100644 src/widgets/doc/images/columnview.png create mode 100644 src/widgets/doc/images/dummy_tree.png create mode 100644 src/widgets/doc/images/example_model.png create mode 100644 src/widgets/doc/images/list_table_tree.png create mode 100755 src/widgets/doc/images/listview.png create mode 100644 src/widgets/doc/images/mainwindow-docks-example.png create mode 100755 src/widgets/doc/images/modelview-combobox.png create mode 100644 src/widgets/doc/images/modelview-header.png create mode 100644 src/widgets/doc/images/modelview-models.png create mode 100644 src/widgets/doc/images/modelview-overview.png create mode 100644 src/widgets/doc/images/modelview-roles.png create mode 100644 src/widgets/doc/images/modelview-tablemodel.png create mode 100644 src/widgets/doc/images/modelview-treemodel.png create mode 100644 src/widgets/doc/images/modelview.png create mode 100644 src/widgets/doc/images/qcompleter.png create mode 100644 src/widgets/doc/images/readonlytable_role.png create mode 100644 src/widgets/doc/images/selected-items1.png create mode 100644 src/widgets/doc/images/selected-items2.png create mode 100644 src/widgets/doc/images/selected-items3.png create mode 100644 src/widgets/doc/images/selection-extended.png create mode 100644 src/widgets/doc/images/selection-multi.png create mode 100644 src/widgets/doc/images/selection-single.png create mode 100644 src/widgets/doc/images/selection2.png create mode 100644 src/widgets/doc/images/shareddirmodel.png create mode 100644 src/widgets/doc/images/sharedmodel-tableviews.png create mode 100644 src/widgets/doc/images/sharedselection-tableviews.png create mode 100644 src/widgets/doc/images/spinboxdelegate-example.png create mode 100644 src/widgets/doc/images/standard-views.png create mode 100644 src/widgets/doc/images/standardwidget.png create mode 100644 src/widgets/doc/images/stardelegate.png create mode 100644 src/widgets/doc/images/stringlistmodel.png create mode 100755 src/widgets/doc/images/tableview.png create mode 100644 src/widgets/doc/images/tree_2_with_algorithm.png create mode 100644 src/widgets/doc/images/treeview.png create mode 100644 src/widgets/doc/images/widgetmapper.png create mode 100644 src/widgets/doc/images/widgets-tutorial-childwidget.png create mode 100644 src/widgets/doc/images/widgets-tutorial-nestedlayouts.png create mode 100644 src/widgets/doc/images/widgets-tutorial-toplevel.png create mode 100644 src/widgets/doc/images/widgets-tutorial-windowlayout.png create mode 100644 src/widgets/doc/snippets/code/doc_src_model-view-programming.cpp create mode 100644 src/widgets/doc/snippets/code/doc_src_qt4-mainwindow.cpp create mode 100644 src/widgets/doc/snippets/dockwidgets/mainwindow.cpp create mode 100644 src/widgets/doc/snippets/itemselection/itemselection.pro create mode 100644 src/widgets/doc/snippets/itemselection/main.cpp create mode 100644 src/widgets/doc/snippets/itemselection/model.cpp create mode 100644 src/widgets/doc/snippets/itemselection/model.h create mode 100644 src/widgets/doc/snippets/qlistview-dnd/main.cpp create mode 100644 src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp create mode 100644 src/widgets/doc/snippets/qlistview-dnd/mainwindow.h create mode 100644 src/widgets/doc/snippets/qlistview-dnd/model.cpp create mode 100644 src/widgets/doc/snippets/qlistview-dnd/model.h create mode 100644 src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro create mode 100644 src/widgets/doc/snippets/qlistwidget-dnd/main.cpp create mode 100644 src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp create mode 100644 src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.h create mode 100644 src/widgets/doc/snippets/qlistwidget-dnd/qlistwidget-dnd.pro create mode 100644 src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp create mode 100644 src/widgets/doc/snippets/qsortfilterproxymodel/qsortfilterproxymodel.pro create mode 100644 src/widgets/doc/snippets/qtablewidget-using/Images/cubed.png create mode 100644 src/widgets/doc/snippets/qtablewidget-using/Images/squared.png create mode 100644 src/widgets/doc/snippets/qtablewidget-using/images.qrc create mode 100644 src/widgets/doc/snippets/qtablewidget-using/main.cpp create mode 100644 src/widgets/doc/snippets/qtablewidget-using/mainwindow.h create mode 100644 src/widgets/doc/snippets/qtablewidget-using/qtablewidget-using.pro create mode 100644 src/widgets/doc/snippets/reading-selections/main.cpp create mode 100644 src/widgets/doc/snippets/reading-selections/model.cpp create mode 100644 src/widgets/doc/snippets/reading-selections/model.h create mode 100644 src/widgets/doc/snippets/reading-selections/reading-selections.pro create mode 100644 src/widgets/doc/snippets/reading-selections/window.cpp create mode 100644 src/widgets/doc/snippets/reading-selections/window.h create mode 100644 src/widgets/doc/snippets/sharedtablemodel/main.cpp create mode 100644 src/widgets/doc/snippets/sharedtablemodel/model.cpp create mode 100644 src/widgets/doc/snippets/sharedtablemodel/model.h create mode 100644 src/widgets/doc/snippets/sharedtablemodel/sharedtablemodel.pro create mode 100644 src/widgets/doc/snippets/simplemodel-use/main.cpp create mode 100644 src/widgets/doc/snippets/simplemodel-use/simplemodel-use.pro create mode 100644 src/widgets/doc/snippets/stringlistmodel/main.cpp create mode 100644 src/widgets/doc/snippets/stringlistmodel/model.cpp create mode 100644 src/widgets/doc/snippets/stringlistmodel/model.h create mode 100644 src/widgets/doc/snippets/stringlistmodel/stringlistmodel.pro create mode 100644 src/widgets/doc/snippets/updating-selections/main.cpp create mode 100644 src/widgets/doc/snippets/updating-selections/model.cpp create mode 100644 src/widgets/doc/snippets/updating-selections/model.h create mode 100644 src/widgets/doc/snippets/updating-selections/updating-selections.pro create mode 100644 src/widgets/doc/snippets/updating-selections/window.cpp create mode 100644 src/widgets/doc/snippets/updating-selections/window.h create mode 100644 src/widgets/doc/snippets/widgets-tutorial/template.cpp create mode 100644 src/widgets/doc/src/addressbook-fr.qdoc create mode 100644 src/widgets/doc/src/addressbook.qdoc create mode 100644 src/widgets/doc/src/model-view-programming.qdoc create mode 100644 src/widgets/doc/src/modelview.qdoc create mode 100644 src/widgets/doc/src/widgets-tutorial.qdoc create mode 100644 src/widgets/doc/src/windows-and-dialogs/dialogs.qdoc create mode 100644 src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc (limited to 'src') diff --git a/src/corelib/doc/images/resources.png b/src/corelib/doc/images/resources.png new file mode 100644 index 0000000000..eb7af96d77 Binary files /dev/null and b/src/corelib/doc/images/resources.png differ diff --git a/src/corelib/doc/snippets/code/doc_src_resources.cpp b/src/corelib/doc/snippets/code/doc_src_resources.cpp new file mode 100644 index 0000000000..f401add728 --- /dev/null +++ b/src/corelib/doc/snippets/code/doc_src_resources.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [4] +QResource::registerResource("/path/to/myresource.rcc"); +//! [4] + + +//! [5] +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Q_INIT_RESOURCE(graphlib); + ... + return app.exec(); +} +//! [5] diff --git a/src/corelib/doc/snippets/code/doc_src_resources.qdoc b/src/corelib/doc/snippets/code/doc_src_resources.qdoc new file mode 100644 index 0000000000..c51dbbcbf3 --- /dev/null +++ b/src/corelib/doc/snippets/code/doc_src_resources.qdoc @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +images/cut.png +//! [0] + + +//! [1] + + images/cut.png + +//! [1] + + +//! [2] + + cut.jpg + + + cut_fr.jpg + +//! [2] + + +//! [3] +rcc -binary myresource.qrc -o myresource.rcc +//! [3] diff --git a/src/corelib/doc/src/io.qdoc b/src/corelib/doc/src/io.qdoc new file mode 100644 index 0000000000..dfe9be2b3c --- /dev/null +++ b/src/corelib/doc/src/io.qdoc @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \group io + \title Input/Output and Networking + \ingroup groups + + \brief Classes providing file input and output along with directory and + network handling. + + These classes are used to handle input and output to and from external + devices, processes, files etc. as well as manipulating files and directories. +*/ + diff --git a/src/corelib/doc/src/resource-system.qdoc b/src/corelib/doc/src/resource-system.qdoc new file mode 100644 index 0000000000..89a099a1c1 --- /dev/null +++ b/src/corelib/doc/src/resource-system.qdoc @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** 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 resources.html + \title The Qt Resource System + \ingroup qt-network + \brief A platform-independent mechanism for storing binary files in an application. + + \keyword resource system + + The Qt resource system is a platform-independent mechanism for + storing binary files in the application's executable. This is + useful if your application always needs a certain set of files + (icons, translation files, etc.) and you don't want to run the + risk of losing the files. + + The resource system is based on tight cooperation between \l qmake, + \l rcc (Qt's resource compiler), and QFile. It obsoletes Qt 3's + \c qembed tool and the + \l{http://qt.nokia.com/doc/qq/qq05-iconography.html#imagestorage}{image + collection} mechanism. + + \section1 Resource Collection Files (\c{.qrc}) + + The resources associated with an application are specified in a + \c .qrc file, an XML-based file format that lists files on the + disk and optionally assigns them a resource name that the + application must use to access the resource. + + Here's an example \c .qrc file: + + \quotefile mainwindows/application/application.qrc + + The resource files listed in the \c .qrc file are files that are + part of the application's source tree. The specified paths are + relative to the directory containing the \c .qrc file. Note that + the listed resource files must be located in the same directory as + the \c .qrc file, or one of its subdirectories. + + Resource data can either be compiled into the binary and thus accessed + immediately in application code, or a binary resource can be created + and at a later point in application code registered with the resource + system. + + By default, resources are accessible in the application under the + same file name as they have in the source tree, with a \c :/ prefix, + or by a \link QUrl URL\endlink with a \c qrc scheme. + + For example, the file path \c :/images/cut.png or the URL + \c qrc:///images/cut.png would give access to the + \c cut.png file, whose location in the application's source tree + is \c images/cut.png. This can be changed using the \c file tag's + \c alias attribute: + + \snippet code/doc_src_resources.qdoc 0 + + The file is then accessible as \c :/cut-img.png from the + application. It is also possible to specify a path prefix for all + files in the \c .qrc file using the \c qresource tag's \c prefix + attribute: + + \snippet code/doc_src_resources.qdoc 1 + + In this case, the file is accessible as \c + :/myresources/cut-img.png. + + Some resources need to change based on the user's locale, + such as translation files or icons. This is done by adding a \c lang + attribute to the \c qresource tag, specifying a suitable locale + string. For example: + + \snippet code/doc_src_resources.qdoc 2 + + If the user's locale is French (i.e., QLocale::system().name() returns + "fr_FR"), \c :/cut.jpg becomes a reference to the \c cut_fr.jpg + image. For other locales, \c cut.jpg is used. + + See the QLocale documentation for a description of the format to use + for locale strings. + + + \section2 External Binary Resources + + For an external binary resource to be created you must create the resource + data (commonly given the \c .rcc extension) by passing the -binary switch to + \l rcc. Once the binary resource is created you can register the resource + with the QResource API. + + For example, a set of resource data specified in a \c .qrc file can be + compiled in the following way: + + \snippet code/doc_src_resources.qdoc 3 + + In the application, this resource would be registered with code like this: + + \snippet code/doc_src_resources.cpp 4 + + \section2 Compiled-In Resources + + For a resource to be compiled into the binary the \c .qrc file must be + mentioned in the application's \c .pro file so that \c qmake knows + about it. For example: + + \snippet mainwindows/application/application.pro 0 + + \c qmake will produce make rules to generate a file called \c + qrc_application.cpp that is linked into the application. This + file contains all the data for the images and other resources as + static C++ arrays of compressed binary data. The \c + qrc_application.cpp file is automatically regenerated whenever + the \c .qrc file changes or one of the files that it refers to + changes. If you don't use \c .pro files, you can either invoke + \c rcc manually or add build rules to your build system. + + \image resources.png Building resources into an application + + Currently, Qt always stores the data directly in the executable, + even on Windows and Mac OS X, where the operating system provides + native support for resources. This might change in a future Qt + release. + + \section1 Compression + + Resources are compressed by default (in the \c ZIP format). It is + possible to turn off compression. This can be useful if your + resources already contain a compressed format, such as \c .png + files. You do this by giving the \c {-no-compress} command line + argument. + + \code + rcc -no-compress myresources.qrc + \endcode + + \c rcc also gives you some control over the compression. You can + specify the compression level and the threshold level to consider + while compressing files, for example: + + \code + rcc -compress 2 -threshold 3 myresources.qrc + \endcode + + \section1 Using Resources in the Application + + In the application, resource paths can be used in most places + instead of ordinary file system paths. In particular, you can + pass a resource path instead of a file name to the QIcon, QImage, + or QPixmap constructor: + + \snippet mainwindows/application/mainwindow.cpp 21 + + See the \l{mainwindows/application}{Application} example for an + actual application that uses Qt's resource system to store its + icons. + + In memory, resources are represented by a tree of resource + objects. The tree is automatically built at startup and used by + QFile for resolving paths to resources. You can use a QDir initialized + with ":/" to navigate through the resource tree from the root. + + Qt's resources support the concept of a search path list. If you then + refer to a resource with \c : instead of \c :/ as the prefix, the + resource will be looked up using the search path list. The search + path list is empty at startup; call QDir::addSearchPath() to + add paths to it. + + If you have resources in a static library, you might need to + force initialization of your resources by calling \l + Q_INIT_RESOURCE() with the base name of the \c .qrc file. For + example: + + \snippet code/doc_src_resources.cpp 5 + + Similarly, if you must unload a set of resources explicitly + (because a plugin is being unloaded or the resources are not valid + any longer), you can force removal of your resources by calling + Q_CLEANUP_RESOURCE() with the same base name as above. +*/ diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 52ffae5f98..ed845745be 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -737,7 +737,7 @@ void qWinMessageHandler2(QtMsgType t, const QMessageLogContext &context, This is a typedef for a pointer to a function with the following signature: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 7 + \snippet code/src_corelib_global_qglobal.cpp 7 This typedef is deprecated, you should use QtMessageHandler instead. \sa QtMsgType, QtMessageHandler, qInstallMsgHandler(), qInstallMessageHandler() @@ -751,7 +751,7 @@ void qWinMessageHandler2(QtMsgType t, const QMessageLogContext &context, This is a typedef for a pointer to a function with the following signature: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 49 + \snippet code/src_corelib_global_qglobal.cpp 49 \sa QtMsgType, qInstallMessageHandler() */ @@ -785,7 +785,7 @@ void qWinMessageHandler2(QtMsgType t, const QMessageLogContext &context, Example: - \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 23 + \snippet code/src_corelib_global_qglobal.cpp 23 \sa QtMessageHandler, QtMsgType, qDebug(), qWarning(), qCritical(), qFatal(), {Debugging Techniques} diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 17eedb0bdd..e1f1db9ead 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -146,12 +146,12 @@ void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum) handling considerably. It is possible to force permission checking on NTFS by including the following code in your source: - \snippet doc/src/snippets/ntfsp.cpp 0 + \snippet ntfsp.cpp 0 Permission checking is then turned on and off by incrementing and decrementing \c qt_ntfs_permission_lookup by 1. - \snippet doc/src/snippets/ntfsp.cpp 1 + \snippet ntfsp.cpp 1 */ //************* QFileDevice diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 2e2db11558..5625aebd3c 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -511,7 +511,7 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const If \a valueDelimiter is set to '(' and \a pairDelimiter is ')', the above query string would instead be represented like this: - \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 4 + \snippet code/src_corelib_io_qurl.cpp 4 \note Non-standard delimiters should be chosen from among what RFC 3986 calls "sub-delimiters". They are: diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 10dcff92c7..3172014363 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -838,7 +838,7 @@ void QHashData::checkSanity() operator==() and a qHash() implementation. Example: - \snippet doc/src/snippets/code/src_corelib_tools_qhash.cpp 13 + \snippet code/src_corelib_tools_qhash.cpp 13 In the example above, we've relied on Qt's global qHash(const QString &, uint) to give us a hash value for the employee's name, and diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index c25d326b9d..0b0aeb50c0 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -404,8 +404,8 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegExp &r For example: - \snippet doc/src/snippets/qstringlist/main.cpp 5 - \snippet doc/src/snippets/qstringlist/main.cpp 16 + \snippet qstringlist/main.cpp 5 + \snippet qstringlist/main.cpp 16 For regular expressions that contain capturing groups, occurrences of \b{\\1}, \b{\\2}, ..., in \a after are @@ -413,8 +413,8 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegExp &r For example: - \snippet doc/src/snippets/qstringlist/main.cpp 5 - \snippet doc/src/snippets/qstringlist/main.cpp 17 + \snippet qstringlist/main.cpp 5 + \snippet qstringlist/main.cpp 17 */ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularExpression &re, const QString &after) { diff --git a/src/gui/doc/images/qrect-diagram-zero.png b/src/gui/doc/images/qrect-diagram-zero.png new file mode 100644 index 0000000000..90e3db0c41 Binary files /dev/null and b/src/gui/doc/images/qrect-diagram-zero.png differ diff --git a/src/gui/doc/images/qrectf-diagram-one.png b/src/gui/doc/images/qrectf-diagram-one.png new file mode 100644 index 0000000000..842289ce07 Binary files /dev/null and b/src/gui/doc/images/qrectf-diagram-one.png differ diff --git a/src/gui/doc/images/qrectf-diagram-three.png b/src/gui/doc/images/qrectf-diagram-three.png new file mode 100644 index 0000000000..e05106a7e1 Binary files /dev/null and b/src/gui/doc/images/qrectf-diagram-three.png differ diff --git a/src/gui/doc/images/qrectf-diagram-two.png b/src/gui/doc/images/qrectf-diagram-two.png new file mode 100644 index 0000000000..192d00df79 Binary files /dev/null and b/src/gui/doc/images/qrectf-diagram-two.png differ diff --git a/src/gui/doc/snippets/code/doc_src_coordsys.cpp b/src/gui/doc/snippets/code/doc_src_coordsys.cpp new file mode 100644 index 0000000000..b677d28a50 --- /dev/null +++ b/src/gui/doc/snippets/code/doc_src_coordsys.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QPainter painter(this); + +painter.setPen(Qt::darkGreen); +painter.drawRect(1, 2, 6, 4); +//! [0] + + +//! [1] +QPainter painter(this); + +painter.setPen(Qt::darkGreen); +painter.drawLine(2, 7, 6, 1); +//! [1] + + +//! [2] +QPainter painter(this); +painter.setRenderHint( + QPainter::Antialiasing); +painter.setPen(Qt::darkGreen); +painter.drawRect(1, 2, 6, 4); +//! [2] + + +//! [3] +QPainter painter(this); +painter.setRenderHint( + QPainter::Antialiasing); +painter.setPen(Qt::darkGreen); +painter.drawLine(2, 7, 6, 1); +//! [3] + + +//! [4] +QPainter painter(this); +painter.setWindow(QRect(-50, -50, 100, 100)); +//! [4] + + +//! [5] +int side = qMin(width(), height()) +int x = (width() - side / 2); +int y = (height() - side / 2); + +painter.setViewport(x, y, side, side); +//! [5] diff --git a/src/gui/doc/src/coordsys.qdoc b/src/gui/doc/src/coordsys.qdoc index 655dbf7cf3..bfa046f7fb 100644 --- a/src/gui/doc/src/coordsys.qdoc +++ b/src/gui/doc/src/coordsys.qdoc @@ -97,10 +97,10 @@ \row \li - \snippet doc/src/snippets/code/doc_src_coordsys.cpp 0 + \snippet code/doc_src_coordsys.cpp 0 \li - \snippet doc/src/snippets/code/doc_src_coordsys.cpp 1 + \snippet code/doc_src_coordsys.cpp 1 \endtable When rendering with a pen with an even number of pixels, the @@ -163,10 +163,10 @@ \row \li - \snippet doc/src/snippets/code/doc_src_coordsys.cpp 2 + \snippet code/doc_src_coordsys.cpp 2 \li - \snippet doc/src/snippets/code/doc_src_coordsys.cpp 3 + \snippet code/doc_src_coordsys.cpp 3 \endtable \section1 Transformations @@ -238,7 +238,7 @@ \row \li {2,1} - \snippet examples/widgets/analogclock/analogclock.cpp 9 + \snippet widgets/analogclock/analogclock.cpp 9 First, we set up the painter. We translate the coordinate system so that point (0, 0) is in the widget's center, instead of being @@ -253,7 +253,7 @@ See also the \l {Window-Viewport Conversion} section. - \snippet examples/widgets/analogclock/analogclock.cpp 18 + \snippet widgets/analogclock/analogclock.cpp 18 We draw the clock's hour hand by rotating the coordinate system and calling QPainter::drawConvexPolygon(). Thank's to the @@ -268,14 +268,14 @@ the code guarantees that the code that follows won't be disturbed by the transformations we've used. - \snippet examples/widgets/analogclock/analogclock.cpp 24 + \snippet widgets/analogclock/analogclock.cpp 24 We do the same for the clock's minute hand, which is defined by the four points (1, 0), (0, 1), (-1, 0), and (0, -40). These coordinates specify a hand that is thinner and longer than the minute hand. - \snippet examples/widgets/analogclock/analogclock.cpp 27 + \snippet widgets/analogclock/analogclock.cpp 27 Finally, we draw the clock face, which consists of twelve short lines at 30-degree intervals. At the end of that, the painter is @@ -319,7 +319,7 @@ -50) to (50, 50) with (0, 0) in the center by calling the QPainter::setWindow() function: - \snippet doc/src/snippets/code/doc_src_coordsys.cpp 4 + \snippet code/doc_src_coordsys.cpp 4 Now, the logical coordinates (-50,-50) correspond to the paint device's physical coordinates (0, 0). Independent of the paint @@ -333,7 +333,7 @@ viewport and "window" maintain the same aspect ratio to prevent deformation: - \snippet doc/src/snippets/code/doc_src_coordsys.cpp 5 + \snippet code/doc_src_coordsys.cpp 5 If we make the logical coordinate system a square, we should also make the viewport a square using the QPainter::setViewport() diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 635e3dadca..d03294f246 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -177,7 +177,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni more modifiers, such as Qt::SHIFT, Qt::CTRL, Qt::ALT and Qt::META. \endlist - For example, \gui{Ctrl P} might be a sequence used as a shortcut for + For example, \uicontrol{Ctrl P} might be a sequence used as a shortcut for printing a document, and can be specified in any of the following ways: @@ -185,8 +185,8 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni Note that, for letters, the case used in the specification string does not matter. In the above examples, the user does not need to - hold down the \key{Shift} key to activate a shortcut specified - with "Ctrl+P". However, for other keys, the use of \key{Shift} as + hold down the \uicontrol{Shift} key to activate a shortcut specified + with "Ctrl+P". However, for other keys, the use of \uicontrol{Shift} as an unspecified extra modifier key can lead to confusion for users of an application whose keyboards have different layouts to those used by the developers. See the \l{Keyboard Layout Issues} section @@ -207,9 +207,9 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni as Qt::Key_A. \b{Note:} On Mac OS X, references to "Ctrl", Qt::CTRL, Qt::Control - and Qt::ControlModifier correspond to the \key Command keys on the + and Qt::ControlModifier correspond to the \uicontrol Command keys on the Macintosh keyboard, and references to "Meta", Qt::META, Qt::Meta and - Qt::MetaModifier correspond to the \key Control keys. Developers on + Qt::MetaModifier correspond to the \uicontrol Control keys. Developers on Mac OS X can use the same shortcut descriptions across all platforms, and their applications will automatically work as expected on Mac OS X. @@ -220,9 +220,9 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni setting up actions in a typical application. The table below shows some common key sequences that are often used for these standard shortcuts by applications on four widely-used platforms. Note - that on Mac OS X, the \key Ctrl value corresponds to the \key - Command keys on the Macintosh keyboard, and the \key Meta value - corresponds to the \key Control keys. + that on Mac OS X, the \uicontrol Ctrl value corresponds to the \uicontrol + Command keys on the Macintosh keyboard, and the \uicontrol Meta value + corresponds to the \uicontrol Control keys. \table \header \li StandardKey \li Windows \li Mac OS X \li KDE \li GNOME @@ -302,23 +302,23 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni Many key sequence specifications are chosen by developers based on the layout of certain types of keyboard, rather than choosing keys that - represent the first letter of an action's name, such as \key{Ctrl S} - ("Ctrl+S") or \key{Ctrl C} ("Ctrl+C"). + represent the first letter of an action's name, such as \uicontrol{Ctrl S} + ("Ctrl+S") or \uicontrol{Ctrl C} ("Ctrl+C"). Additionally, because certain symbols can only be entered with the help of modifier keys on certain keyboard layouts, key sequences intended for use with one keyboard layout may map to a different key, map to no keys at all, or require an additional modifier key to be used on different keyboard layouts. - For example, the shortcuts, \key{Ctrl plus} and \key{Ctrl minus}, are often + For example, the shortcuts, \uicontrol{Ctrl plus} and \uicontrol{Ctrl minus}, are often used as shortcuts for zoom operations in graphics applications, and these may be specified as "Ctrl++" and "Ctrl+-" respectively. However, the way these shortcuts are specified and interpreted depends on the keyboard layout. - Users of Norwegian keyboards will note that the \key{+} and \key{-} keys + Users of Norwegian keyboards will note that the \uicontrol{+} and \uicontrol{-} keys are not adjacent on the keyboard, but will still be able to activate both - shortcuts without needing to press the \key{Shift} key. However, users - with British keyboards will need to hold down the \key{Shift} key - to enter the \key{+} symbol, making the shortcut effectively the same as + shortcuts without needing to press the \uicontrol{Shift} key. However, users + with British keyboards will need to hold down the \uicontrol{Shift} key + to enter the \uicontrol{+} symbol, making the shortcut effectively the same as "Ctrl+Shift+=". Although some developers might resort to fully specifying all the modifiers @@ -327,9 +327,9 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni For example, a developer using a British keyboard may decide to specify "Ctrl+Shift+=" as the key sequence in order to create a shortcut that - coincidentally behaves in the same way as \key{Ctrl plus}. However, the - \key{=} key needs to be accessed using the \key{Shift} key on Norwegian - keyboard, making the required shortcut effectively \key{Ctrl Shift Shift =} + coincidentally behaves in the same way as \uicontrol{Ctrl plus}. However, the + \uicontrol{=} key needs to be accessed using the \uicontrol{Shift} key on Norwegian + keyboard, making the required shortcut effectively \uicontrol{Ctrl Shift Shift =} (an impossible key combination). As a result, both human-readable strings and hard-coded key codes @@ -351,7 +351,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni key codes, can be created by using the multiple argument constructor, or by passing a human-readable string of comma-separated key sequences. - For example, the key sequence, \key{Ctrl X} followed by \key{Ctrl C}, can + For example, the key sequence, \uicontrol{Ctrl X} followed by \uicontrol{Ctrl C}, can be specified using either of the following ways: \snippet code/src_gui_kernel_qkeysequence.cpp 1 diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index e14cfe0f82..45903f678c 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -120,7 +120,7 @@ QT_BEGIN_NAMESPACE and QTextObjectInterface. QObject must be the first class inherited. For instance: - \snippet examples/richtext/textobject/svgtextobject.h 1 + \snippet richtext/textobject/svgtextobject.h 1 The data of a text object is usually stored in the QTextCharFormat using QTextCharFormat::setProperty(), and then retrieved with diff --git a/src/network/doc/images/tcpstream.png b/src/network/doc/images/tcpstream.png new file mode 100644 index 0000000000..7975376c8c Binary files /dev/null and b/src/network/doc/images/tcpstream.png differ diff --git a/src/network/doc/images/udppackets.png b/src/network/doc/images/udppackets.png new file mode 100644 index 0000000000..bd66c3f65e Binary files /dev/null and b/src/network/doc/images/udppackets.png differ diff --git a/src/network/doc/src/bearermanagement.qdoc b/src/network/doc/src/bearermanagement.qdoc new file mode 100644 index 0000000000..91dc32c5a5 --- /dev/null +++ b/src/network/doc/src/bearermanagement.qdoc @@ -0,0 +1,268 @@ +/**************************************************************************** +** +** 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 bearer-management.html + +\title Bearer Management +\ingroup qt-network +\brief An API to control the system's connectivity state. + +Bearer Management controls the connectivity state of the system so that +the user can start or stop interfaces or roam transparently between +access points. + +\tableofcontents + + +\section1 Overview + +The Bearer Management API controls the system's connectivity state. This +incorporates simple information such as whether the device is online and +how many interfaces there are as well as enables the application developer +to start, stop network interfaces and influences other connection specific +details. Depending on the platform's capabilities it may even provide +session management so that a network interface remains up for as long as +clients have a registered interest in them while at the same time +optimizes the interface's uptime. + +This API does not provide support for management of network configurations +themselves. It is up to the platform to provide infrastructure which +enables to user to create, edit or delete network configurations. + +\section2 The API in Detail + +Computer systems manage their network interfaces via a set of configurations. +Each configuration describes a set of parameters which instruct the system +how a particular network interface is started. One of the most simplistic +examples might be an Ethernet configuration that links a network card to a +DHCP server. A more complex example might be a Wireless LAN configuration +which may comprise of hardware details such as the WLAN card address, +WLAN access point details (e.g ESSID, encryption details) and user specific +information (for example username and password). Once the network interface +was configured and started according to the configuration blue print, +multiple applications are free to use this link layer connection/session +for their own socket operations. Note that the QNetworkConfiguration object +only provides limited information about the configuration details themselves. +It's main purpose is to act as a configuration identifier through which link +layer connections can be created, destroyed and monitored. + +QNetworkSession provides two types of use cases. It enables the monitoring of +physical network interfaces and management of network sessions. Network sessions +are a common feature on mobile devices where multiple applications +can request network sessions as they see fit. The system consolidates and tracks +active network sessions for the same network interface by maintaining the link +layer connections until the last session has been closed. The subsequent table +lists the major QNetworkSession functions and how they fit into the session and +hardware management categories: + +\table 60% +\header \li Interface management \li Session management +\row \li QNetworkSession::stop() \li QNetworkSession::open() +\row \li QNetworkSession::interface() \li QNetworkSession::close() +\row \li QNetworkSession::state() \li QNetworkSession::isOpen() +\row \li QNetworkSession::bytesWritten() \li QNetworkSession::migrate() +\row \li QNetworkSession::bytesReceived() \li QNetworkSession::ignore() +\row \li QNetworkSession::activeTime() \li QNetworkSession::accept() +\row \li QNetworkSession::stateChanged() \li QNetworkSession::reject() +\row \li \li QNetworkSession::opened() +\row \li \li QNetworkSession::closed() +\endtable + +The state of the session represents the state of the underlying access point +whereas the session's openness implies the networking/connectivity state available +to the current process. + +Possible use cases for interface management are network management related +applications which intend to monitor the connectivity state but do not engage +in network communication themselves. Any application wanting to open a socket +to a remote address will typically use session management related functionality. + +\section3 Service networks + +Some mobile platforms use the concept of grouped access points (also +called SNAP or Service Network Access Point). In principle multiple +configurations are grouped together and possibly even prioritized when +compared to each other. This is useful for use cases where all +configurations serve a similar purpose or context. A common context could +be that they provide access to the public Internet or possibly only to the +office Intranet. By providing a pool of configurations the system can make +a decision based on given priorities which usually map to factors such as +speed, availability and cost. Furthermore the system can automatically +roam from one access point to the next one while ensuring minimal impact on +the user experience. + +The \l{QNetworkConfiguration::Type} flag specifies to what category a +configuration belongs. The \l{QNetworkConfiguration::InternetAccessPoint} +type is the most common example. It represents a configuration that can be +used to create a session. The above mentioned grouping behavior is provided +by \l {QNetworkConfiguration::ServiceNetwork} configurations. Service +networks are place holders until such time when the user attempts to +\l {QNetworkSession::open()}{open()} a new session. At that point in time +the system determines which of the configurations \l{QNetworkConfiguration::children()} +is best to use. The selection algorithm is provided by the platform and is usually managed +by network settings applications. A service network can only have one level of indirection +which implies children can only be of type \l {QNetworkConfiguration::InternetAccessPoint}. + +Most systems allow the user to define the systems default configuration. +Usually the default behavior is either a service network, a particular +Internet access point or the user instructs the platform to ask the user +once an application requests the network. User interaction is generally +implemented by some sort of system dialog which shows up at the appropriate +point in time. The application does not have to handle the user input. This +API provides the \l QNetworkConfigurationManager::defaultConfiguration() +call which serves a similar purpose. The subsequent code snippet provides +a quick way how an application can quickly create a new network session +without (or only minimal) user interaction: + +\code + // Set Internet Access Point + QNetworkConfigurationManager manager; + const bool canStartIAP = (manager.capabilities() + & QNetworkConfigurationManager::CanStartAndStopInterfaces); + // Is there default access point, use it + QNetworkConfiguration cfg = manager.defaultConfiguration(); + if (!cfg.isValid() || (!canStartIAP && cfg.state() != QNetworkConfiguration::Active)) { + QMessageBox::information(this, tr("Network"), tr( + "No Access Point found.")); + return; + } + + session = new QNetworkSession(cfg, this); + session->open(); + session->waitForOpened(-1); +\endcode + +To accommodate the "Ask user" use case the default configuration can be of +type QNetworkConfiguration::UserChoice. A user choice configuration is +resolved as part of the \l {QNetworkSession::open()} call. Note that a +\l{QNetworkConfiguration::UserChoice}{UserChoice} configuration is only +ever returned via \l {QNetworkConfigurationManager::defaultConfiguration()} +and not \l QNetworkConfigurationManager::allConfigurations(). + +On systems which do not maintain a list of +\l {QNetworkConfigurationManager::defaultConfiguration()}{defaultConfiguration()} +an invalid configuration is returned. A possible workaround could be to +implement a custom dialog which is populated based on what +\l QNetworkConfigurationManager::allConfigurations() returns. + +\section3 Managing network sessions + +A QNetworkSession object separates a \l {QNetworkSession::state()}{state()} +and an \l{QNetworkSession::isOpen()}{isOpen()} condition. + +The state() attribute enables developers to detect whether the system +currently maintains a global network session for the given +QNetworkConfiguration. If \l {QNetworkSession::isOpen()}{isOpen()} +returns true the QNetworkSession instance at hand was at least one of the +entities requesting the global network session. This distinction is +required to support the notion of session registrations. For as long as +there are one or more open QNetworkSession instances the underlying +network interface is not shut down. Therefore the session +\l{QNetworkSession::state()}{state()} can be used to monitor the state of +network interfaces. + +An open session is created by calling \l {QNetworkSession::open()} and +closed via \l{QNetworkSession::close()}, respectively. If the session +is \l{QNetworkSession::Disconnected}{disconnected} at the time of the +\l{QNetworkSession::open()}{open()} call the underlying interface is started; +otherwise only the reference counter against the global session is +incremented. The opposite behavior can be observed when using +\l{QNetworkSession::close()}{close()}. + +In some use cases it may be necessary to turn the interface off despite of +open sessions. This can be achieved by calling +\l{QNetworkSession::stop()}{stop()}. An example use case could be a +network manager type of application allowing the user to control the +overall state of the devices connectivity. + +Global (inter-process) session support is platform dependent and can be +detected via \l {QNetworkConfigurationManager::SystemSessionSupport}. +If the system does not support global session calling +\l{QNetworkSession::close()}{close()} never stops the interface. + +\section3 Roaming + +Roaming is the process of reconnecting a device from one network to another +while minimizing the impact on the application. The system notifies the application +about link layer changes so that the required preparation can be taken. +The most common reaction would be to reinitialize sockets and to renegotiate +stateful connections with other parties. In the most extreme cases applications +may even prevent the roaming altogether. + +Roaming is initiated when the system determines that a more appropriate access point +becomes available to the user. In general such a decision is based on cost, network speed +or network type (access to certain private networks may only be provided via certain access points). +Almost all devices providing roaming support have some form of global configuration application +enabling the user to define such groups of access points (service networks) and priorities. + +This API supports two types of roaming. Application level roaming (ALR) +provides the most control over the process. Applications will be notified about upcoming +link layer changes and get the opportunity to test the new access point. Eventually they can +reject or accept the link layer change. The second form of roaming is referred to as Forced Roaming. +The system simply changes the link layer without consulting the application. It is up to +the application to detect that some of its internal socket may have become invalid. As a consequence +it has to reinitialize those sockets and reestablish the previous user session without +any interruption. Forced roaming has the advantage that applications don't have to +manage the entire roaming process by themselves. + +QNetworkSession is the central class for managing roaming related issues. + +\section3 Platform capabilities + +Some API features are not available on all platforms. The +\l QNetworkConfigurationManager::Capability should be used to detect +platform features at runtime. The following table lists the various +platform APIs being used by this API. This may assist in the process of +determining the feature support: + +\table + \header + \li Platform + \li Backend capabilities + \row + \li Linux\unicode{0xAE} + \li Linux uses the \l {http://projects.gnome.org/NetworkManager}{NetworkManager} + and \l {http://connman.net/}{ConnMan} / \l {http://ofono.org/}{oFono} APIs + which support interface notifications and starting and stopping of network + interfaces. + \row + \li Windows\unicode{0xAE} XP + \li This platform supports interface notifications without active polling. + \row + \li Windows XP SP2+Hotfixes, Windows XP SP3, Windows Vista, Windows 7 + \li In addition to standard Windows XP wifi access point monitoring has been improved which includes the ability to start and stop wifi interfaces. This requires Windows to manage the wifi interfaces. + \row + \li Mac OS\unicode{0xAE} + \li This platform has full support by way of CoreWLAN offered in Mac OS 10.6. Previous + versions of Mac OS - 10.5 and 10.4 have limited support. + \row + \li All other platforms (*nix, Windows Mobile) + \li This backend is the fallback for all platforms supports network interface notifications via active polling only. +\endtable + +*/ diff --git a/src/network/doc/src/network-programming.qdoc b/src/network/doc/src/network-programming.qdoc new file mode 100644 index 0000000000..0701b04f6f --- /dev/null +++ b/src/network/doc/src/network-programming.qdoc @@ -0,0 +1,291 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \group network + \title Network Programming API + \brief Classes for Network Programming + + \ingroup groups +*/ + +/*! + \page network-programming.html + \title Network Programming + \ingroup qt-network + \brief An Introduction to Network Programming with Qt + + The QtNetwork module offers classes that allow you to write TCP/IP clients + and servers. It offers lower-level classes such as QTcpSocket, + QTcpServer and QUdpSocket that represent low level network concepts, + and high level classes such as QNetworkRequest, QNetworkReply and + QNetworkAccessManager to perform network operations using common protocols. + It also offers classes such as QNetworkConfiguration, + QNetworkConfigurationManager and QNetworkSession that implement bearer + management. + + \tableofcontents + + \section1 Qt's Classes for Network Programming + + The following classes provide support for network programming in Qt. + + \annotatedlist network + + \section1 High Level Network Operations for HTTP and FTP + + The Network Access API is a collection of classes for performing + common network operations. The API provides an abstraction layer + over the specific operations and protocols used (for example, + getting and posting data over HTTP), and only exposes classes, + functions, and signals for general or high level concepts. + + Network requests are represented by the QNetworkRequest class, + which also acts as a general container for information associated + with a request, such as any header information and the encryption + used. The URL specified when a request object is constructed + determines the protocol used for a request. + Currently HTTP, FTP and local file URLs are supported for uploading + and downloading. + + The coordination of network operations is performed by the + QNetworkAccessManager class. Once a request has been created, + this class is used to dispatch it and emit signals to report on + its progress. The manager also coordinates the use of + \l{QNetworkCookieJar}{cookies} to store data on the client, + authentication requests, and the use of proxies. + + Replies to network requests are represented by the QNetworkReply + class; these are created by QNetworkAccessManager when a request + is dispatched. The signals provided by QNetworkReply can be used + to monitor each reply individually, or developers may choose to + use the manager's signals for this purpose instead and discard + references to replies. Since QNetworkReply is a subclass of + QIODevice, replies can be handled synchronously or asynchronously; + i.e., as blocking or non-blocking operations. + + Each application or library can create one or more instances of + QNetworkAccessManager to handle network communication. + + \section1 Using TCP with QTcpSocket and QTcpServer + + TCP (Transmission Control Protocol) is a low-level network + protocol used by most Internet protocols, including HTTP and FTP, + for data transfer. It is a reliable, stream-oriented, + connection-oriented transport protocol. It is particularly well + suited to the continuous transmission of data. + + \image tcpstream.png A TCP Stream + + The QTcpSocket class provides an interface for TCP. You can use + QTcpSocket to implement standard network protocols such as POP3, + SMTP, and NNTP, as well as custom protocols. + + A TCP connection must be established to a remote host and port + before any data transfer can begin. Once the connection has been + established, the IP address and port of the peer are available + through QTcpSocket::peerAddress() and QTcpSocket::peerPort(). At + any time, the peer can close the connection, and data transfer + will then stop immediately. + + QTcpSocket works asynchronously and emits signals to report status + changes and errors, just like QNetworkAccessManager. It + relies on the event loop to detect incoming data and to + automatically flush outgoing data. You can write data to the + socket using QTcpSocket::write(), and read data using + QTcpSocket::read(). QTcpSocket represents two independent streams + of data: one for reading and one for writing. + + Since QTcpSocket inherits QIODevice, you can use it with + QTextStream and QDataStream. When reading from a QTcpSocket, you + must make sure that enough data is available by calling + QTcpSocket::bytesAvailable() beforehand. + + If you need to handle incoming TCP connections (e.g., in a server + application), use the QTcpServer class. Call QTcpServer::listen() + to set up the server, and connect to the + QTcpServer::newConnection() signal, which is emitted once for + every client that connects. In your slot, call + QTcpServer::nextPendingConnection() to accept the connection and + use the returned QTcpSocket to communicate with the client. + + Although most of its functions work asynchronously, it's possible + to use QTcpSocket synchronously (i.e., blocking). To get blocking + behavior, call QTcpSocket's waitFor...() functions; these suspend + the calling thread until a signal has been emitted. For example, + after calling the non-blocking QTcpSocket::connectToHost() + function, call QTcpSocket::waitForConnected() to block the thread + until the \l{QTcpSocket::connected()}{connected()} signal has + been emitted. + + Synchronous sockets often lead to code with a simpler flow of + control. The main disadvantage of the waitFor...() approach is + that events won't be processed while a waitFor...() function is + blocking. If used in the GUI thread, this might freeze the + application's user interface. For this reason, we recommend that + you use synchronous sockets only in non-GUI threads. When used + synchronously, QTcpSocket doesn't require an event loop. + + The \l{network/fortuneclient}{Fortune Client} and + \l{network/fortuneserver}{Fortune Server} examples show how to use + QTcpSocket and QTcpServer to write TCP client-server + applications. See also \l{network/blockingfortuneclient}{Blocking + Fortune Client} for an example on how to use a synchronous + QTcpSocket in a separate thread (without using an event loop), + and \l{network/threadedfortuneserver}{Threaded Fortune Server} + for an example of a multithreaded TCP server with one thread per + active client. + + \section1 Using UDP with QUdpSocket + + UDP (User Datagram Protocol) is a lightweight, unreliable, + datagram-oriented, connectionless protocol. It can be used when + reliability isn't important. For example, a server that reports + the time of day could choose UDP. If a datagram with the time of + day is lost, the client can simply make another request. + + \image udppackets.png UDP Packets + + The QUdpSocket class allows you to send and receive UDP + datagrams. It inherits QAbstractSocket, and it therefore shares + most of QTcpSocket's interface. The main difference is that + QUdpSocket transfers data as datagrams instead of as a continuous + stream of data. In short, a datagram is a data packet of limited + size (normally smaller than 512 bytes), containing the IP address + and port of the datagram's sender and receiver in addition to the + data being transferred. + + QUdpSocket supports IPv4 broadcasting. Broadcasting is often used + to implement network discovery protocols, such as finding which + host on the network has the most free hard disk space. One host + broadcasts a datagram to the network that all other hosts + receive. Each host that receives a request then sends a reply + back to the sender with its current amount of free disk space. + The originator waits until it has received replies from all + hosts, and can then choose the server with most free space to + store data. To broadcast a datagram, simply send it to the + special address QHostAddress::Broadcast (255.255.255.255), or + to your local network's broadcast address. + + QUdpSocket::bind() prepares the socket for accepting incoming + datagrams, much like QTcpServer::listen() for TCP servers. + Whenever one or more datagrams arrive, QUdpSocket emits the + \l{QUdpSocket::readyRead()}{readyRead()} signal. Call + QUdpSocket::readDatagram() to read the datagram. + + The \l{network/broadcastsender}{Broadcast Sender} and + \l{network/broadcastreceiver}{Broadcast Receiver} examples show how to + write a UDP sender and a UDP receiver using Qt. + + QUdpSocket also supports multicasting. The + \l{network/multicastsender}{Multicast Sender} and + \l{network/multicastreceiver}{Multicast Receiver} examples show how to use + write UDP multicast clients. + + \section1 Resolving Host Names using QHostInfo + + Before establishing a network connection, QTcpSocket and + QUdpSocket perform a name lookup, translating the host name + you're connecting to into an IP address. This operation is + usually performed using the DNS (Domain Name Service) protocol. + + QHostInfo provides a static function that lets you perform such a + lookup yourself. By calling QHostInfo::lookupHost() with a host + name, a QObject pointer, and a slot signature, QHostInfo will + perform the name lookup and invoke the given slot when the + results are ready. The actual lookup is done in a separate + thread, making use of the operating system's own methods for + performing name lookups. + + QHostInfo also provides a static function called + QHostInfo::fromName() that takes the host name as argument and + returns the results. In this case, the name lookup is performed + in the same thread as the caller. This overload is useful for + non-GUI applications or for doing name lookups in a separate, + non-GUI thread. (Calling this function in a GUI thread may cause + your user interface to freeze while the function blocks as + it performs the lookup.) + + \section1 Support for Network Proxies + + Network communication with Qt can be performed through proxies, + which direct or filter network traffic between local and remote + connections. + + Individual proxies are represented by the QNetworkProxy class, + which is used to describe and configure the connection to a proxy. + Proxy types which operate on different levels of network communication + are supported, with SOCKS 5 support allowing proxying of network + traffic at a low level, and HTTP and FTP proxying working at the + protocol level. See QNetworkProxy::ProxyType for more information. + + Proxying can be enabled on a per-socket basis or for all network + communication in an application. A newly opened socket can be + made to use a proxy by calling its QAbstractSocket::setProxy() + function before it is connected. Application-wide proxying can + be enabled for all subsequent socket connections through the use + of the QNetworkProxy::setApplicationProxy() function. + + Proxy factories are used to create policies for proxy use. + QNetworkProxyFactory supplies proxies based on queries for specific + proxy types. The queries themselves are encoded in QNetworkProxyQuery + objects which enable proxies to be selected based on key criteria, + such as the purpose of the proxy (TCP, UDP, TCP server, URL request), + local port, remote host and port, and the protocol in use (HTTP, FTP, + etc.). + + QNetworkProxyFactory::proxyForQuery() is used to query the factory + directly. An application-wide policy for proxying can be implemented + by passing a factory to QNetworkProxyFactory::setApplicationProxyFactory() + and a custom proxying policy can be created by subclassing + QNetworkProxyFactory; see the class documentation for details. + + \section1 Bearer Management Support + + Bearer Management controls the connectivity state of the device such that + the application can start or stop network interfaces and roam + transparently between access points. + + The QNetworkConfigurationManager class manages the list of network + configurations known to the device. A network configuration describes the + set of parameters used to start a network interface and is represented by + the QNetworkConfiguration class. + + A network interface is started by openning a QNetworkSession based on a + given network configuration. In most situations creating a network session + based on the platform specified default network configuration is + appropriate. The default network configuration is returned by the + QNetworkConfigurationManager::defaultConfiguration() function. + + On some platforms it is a platform requirement that the application open a + network session before any network operations can be performed. This can be + tested by the presents of the + QNetworkConfigurationManager::NetworkSessionRequired flag in the value + returned by the QNetworkConfigurationManager::capabilities() function. + + \sa {Bearer Management} +*/ diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc new file mode 100644 index 0000000000..21828d7af9 --- /dev/null +++ b/src/network/doc/src/ssl.qdoc @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 ssl.html + \title Secure Sockets Layer (SSL) Classes + \brief Classes for secure communication over network sockets. + \ingroup qt-network + + \keyword SSL + + The classes below provide support for secure network communication using + the Secure Sockets Layer (SSL) protocol, using the \l{OpenSSL Toolkit} to + perform encryption and protocol handling. + + See the \l{General Qt Requirements} page for information about the + versions of OpenSSL that are known to work with Qt. + + \section1 Enabling and Disabling SSL Support + + When building Qt from source, the configuration system checks for the presence + of the \c{openssl/opensslv.h} header provided by source or developer packages + of OpenSSL. + + By default, an SSL-enabled Qt library dynamically loads any installed OpenSSL + library at run-time. However, it is possible to link against the library at + compile-time by configuring Qt with the \c{-openssl-linked} option. + + When building a version of Qt linked against OpenSSL, the build system will + attempt to link with libssl and libcrypt libraries located in the default + location on the developer's system. This location is configurable: + set the \c OPENSSL_LIBS environment variable to contain the linker options + required to link Qt against the installed library. For example, on a Unix/Linux + system: + + \code + ./configure -openssl-linked OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' + \endcode + + To disable SSL support in a Qt build, configure Qt with the \c{-no-openssl} + option. + + \section1 Licensing Information + + \note Due to import and export restrictions in some parts of the world, we + are unable to supply the OpenSSL Toolkit with Qt packages. Developers wishing + to use SSL communication in their deployed applications should either ensure + that their users have the appropriate libraries installed, or they should + consult a suitably qualified legal professional to ensure that applications + using code from the OpenSSL project are correctly certified for import + and export in relevant regions of the world. + + When the QtNetwork module is built with SSL support, the library is linked + against OpenSSL in a way that requires OpenSSL license compliance. +*/ diff --git a/src/widgets/doc/images/addressbook-tutorial-part1-labeled-layout.png b/src/widgets/doc/images/addressbook-tutorial-part1-labeled-layout.png new file mode 100644 index 0000000000..b19cb360a1 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part1-labeled-layout.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part1-labeled-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-part1-labeled-screenshot.png new file mode 100644 index 0000000000..f9b91eebe6 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part1-labeled-screenshot.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part1-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-part1-screenshot.png new file mode 100644 index 0000000000..454b0959e6 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part1-screenshot.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part2-add-contact.png b/src/widgets/doc/images/addressbook-tutorial-part2-add-contact.png new file mode 100644 index 0000000000..6f2b947b21 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part2-add-contact.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part2-add-flowchart.png b/src/widgets/doc/images/addressbook-tutorial-part2-add-flowchart.png new file mode 100644 index 0000000000..ca9af3720d Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part2-add-flowchart.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part2-add-successful.png b/src/widgets/doc/images/addressbook-tutorial-part2-add-successful.png new file mode 100644 index 0000000000..99a2154007 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part2-add-successful.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part2-labeled-layout.png b/src/widgets/doc/images/addressbook-tutorial-part2-labeled-layout.png new file mode 100644 index 0000000000..1e000c8f31 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part2-labeled-layout.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part2-signals-and-slots.png b/src/widgets/doc/images/addressbook-tutorial-part2-signals-and-slots.png new file mode 100644 index 0000000000..e49f8dc262 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part2-signals-and-slots.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part2-stretch-effects.png b/src/widgets/doc/images/addressbook-tutorial-part2-stretch-effects.png new file mode 100644 index 0000000000..d9f7f31227 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part2-stretch-effects.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part3-labeled-layout.png b/src/widgets/doc/images/addressbook-tutorial-part3-labeled-layout.png new file mode 100644 index 0000000000..1981ba8cb6 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part3-labeled-layout.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part3-linkedlist.png b/src/widgets/doc/images/addressbook-tutorial-part3-linkedlist.png new file mode 100644 index 0000000000..e7f4725dce Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part3-linkedlist.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part3-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-part3-screenshot.png new file mode 100644 index 0000000000..75159b4045 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part3-screenshot.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part4-remove.png b/src/widgets/doc/images/addressbook-tutorial-part4-remove.png new file mode 100644 index 0000000000..8eb259ef02 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part4-remove.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part5-finddialog.png b/src/widgets/doc/images/addressbook-tutorial-part5-finddialog.png new file mode 100644 index 0000000000..743d92ef6f Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part5-finddialog.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part5-notfound.png b/src/widgets/doc/images/addressbook-tutorial-part5-notfound.png new file mode 100644 index 0000000000..2d35766ab5 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part5-notfound.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part5-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-part5-screenshot.png new file mode 100644 index 0000000000..3abe2775c2 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part5-screenshot.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part5-signals-and-slots.png b/src/widgets/doc/images/addressbook-tutorial-part5-signals-and-slots.png new file mode 100644 index 0000000000..1771e7bbbf Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part5-signals-and-slots.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part6-load.png b/src/widgets/doc/images/addressbook-tutorial-part6-load.png new file mode 100644 index 0000000000..a027a1decb Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part6-load.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part6-save.png b/src/widgets/doc/images/addressbook-tutorial-part6-save.png new file mode 100644 index 0000000000..757feeb9ac Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part6-save.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part6-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-part6-screenshot.png new file mode 100644 index 0000000000..7bb2f749bf Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part6-screenshot.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-part7-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-part7-screenshot.png new file mode 100644 index 0000000000..3e7b3ca522 Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-part7-screenshot.png differ diff --git a/src/widgets/doc/images/addressbook-tutorial-screenshot.png b/src/widgets/doc/images/addressbook-tutorial-screenshot.png new file mode 100644 index 0000000000..3fba6e849e Binary files /dev/null and b/src/widgets/doc/images/addressbook-tutorial-screenshot.png differ diff --git a/src/widgets/doc/images/clock.png b/src/widgets/doc/images/clock.png new file mode 100644 index 0000000000..c7f6a1b296 Binary files /dev/null and b/src/widgets/doc/images/clock.png differ diff --git a/src/widgets/doc/images/columnview.png b/src/widgets/doc/images/columnview.png new file mode 100644 index 0000000000..127b79531f Binary files /dev/null and b/src/widgets/doc/images/columnview.png differ diff --git a/src/widgets/doc/images/dummy_tree.png b/src/widgets/doc/images/dummy_tree.png new file mode 100644 index 0000000000..7373ea60f6 Binary files /dev/null and b/src/widgets/doc/images/dummy_tree.png differ diff --git a/src/widgets/doc/images/example_model.png b/src/widgets/doc/images/example_model.png new file mode 100644 index 0000000000..4261261c7e Binary files /dev/null and b/src/widgets/doc/images/example_model.png differ diff --git a/src/widgets/doc/images/list_table_tree.png b/src/widgets/doc/images/list_table_tree.png new file mode 100644 index 0000000000..b2daf1f3a5 Binary files /dev/null and b/src/widgets/doc/images/list_table_tree.png differ diff --git a/src/widgets/doc/images/listview.png b/src/widgets/doc/images/listview.png new file mode 100755 index 0000000000..fa49c52c62 Binary files /dev/null and b/src/widgets/doc/images/listview.png differ diff --git a/src/widgets/doc/images/mainwindow-docks-example.png b/src/widgets/doc/images/mainwindow-docks-example.png new file mode 100644 index 0000000000..a5641fd9cd Binary files /dev/null and b/src/widgets/doc/images/mainwindow-docks-example.png differ diff --git a/src/widgets/doc/images/modelview-combobox.png b/src/widgets/doc/images/modelview-combobox.png new file mode 100755 index 0000000000..d172b413eb Binary files /dev/null and b/src/widgets/doc/images/modelview-combobox.png differ diff --git a/src/widgets/doc/images/modelview-header.png b/src/widgets/doc/images/modelview-header.png new file mode 100644 index 0000000000..2597635b9f Binary files /dev/null and b/src/widgets/doc/images/modelview-header.png differ diff --git a/src/widgets/doc/images/modelview-models.png b/src/widgets/doc/images/modelview-models.png new file mode 100644 index 0000000000..183a7cffd5 Binary files /dev/null and b/src/widgets/doc/images/modelview-models.png differ diff --git a/src/widgets/doc/images/modelview-overview.png b/src/widgets/doc/images/modelview-overview.png new file mode 100644 index 0000000000..41e3a6827f Binary files /dev/null and b/src/widgets/doc/images/modelview-overview.png differ diff --git a/src/widgets/doc/images/modelview-roles.png b/src/widgets/doc/images/modelview-roles.png new file mode 100644 index 0000000000..2a60ce7190 Binary files /dev/null and b/src/widgets/doc/images/modelview-roles.png differ diff --git a/src/widgets/doc/images/modelview-tablemodel.png b/src/widgets/doc/images/modelview-tablemodel.png new file mode 100644 index 0000000000..9a9ea2f1b0 Binary files /dev/null and b/src/widgets/doc/images/modelview-tablemodel.png differ diff --git a/src/widgets/doc/images/modelview-treemodel.png b/src/widgets/doc/images/modelview-treemodel.png new file mode 100644 index 0000000000..f7b02eb150 Binary files /dev/null and b/src/widgets/doc/images/modelview-treemodel.png differ diff --git a/src/widgets/doc/images/modelview.png b/src/widgets/doc/images/modelview.png new file mode 100644 index 0000000000..7b042af8a4 Binary files /dev/null and b/src/widgets/doc/images/modelview.png differ diff --git a/src/widgets/doc/images/qcompleter.png b/src/widgets/doc/images/qcompleter.png new file mode 100644 index 0000000000..d25caacc72 Binary files /dev/null and b/src/widgets/doc/images/qcompleter.png differ diff --git a/src/widgets/doc/images/readonlytable_role.png b/src/widgets/doc/images/readonlytable_role.png new file mode 100644 index 0000000000..7d2d416a53 Binary files /dev/null and b/src/widgets/doc/images/readonlytable_role.png differ diff --git a/src/widgets/doc/images/selected-items1.png b/src/widgets/doc/images/selected-items1.png new file mode 100644 index 0000000000..12b572d4d8 Binary files /dev/null and b/src/widgets/doc/images/selected-items1.png differ diff --git a/src/widgets/doc/images/selected-items2.png b/src/widgets/doc/images/selected-items2.png new file mode 100644 index 0000000000..ad247d90a9 Binary files /dev/null and b/src/widgets/doc/images/selected-items2.png differ diff --git a/src/widgets/doc/images/selected-items3.png b/src/widgets/doc/images/selected-items3.png new file mode 100644 index 0000000000..d7aa7be46b Binary files /dev/null and b/src/widgets/doc/images/selected-items3.png differ diff --git a/src/widgets/doc/images/selection-extended.png b/src/widgets/doc/images/selection-extended.png new file mode 100644 index 0000000000..8ca488d812 Binary files /dev/null and b/src/widgets/doc/images/selection-extended.png differ diff --git a/src/widgets/doc/images/selection-multi.png b/src/widgets/doc/images/selection-multi.png new file mode 100644 index 0000000000..766e4a18bc Binary files /dev/null and b/src/widgets/doc/images/selection-multi.png differ diff --git a/src/widgets/doc/images/selection-single.png b/src/widgets/doc/images/selection-single.png new file mode 100644 index 0000000000..d9d0655864 Binary files /dev/null and b/src/widgets/doc/images/selection-single.png differ diff --git a/src/widgets/doc/images/selection2.png b/src/widgets/doc/images/selection2.png new file mode 100644 index 0000000000..66c757f88e Binary files /dev/null and b/src/widgets/doc/images/selection2.png differ diff --git a/src/widgets/doc/images/shareddirmodel.png b/src/widgets/doc/images/shareddirmodel.png new file mode 100644 index 0000000000..7b9fdeda04 Binary files /dev/null and b/src/widgets/doc/images/shareddirmodel.png differ diff --git a/src/widgets/doc/images/sharedmodel-tableviews.png b/src/widgets/doc/images/sharedmodel-tableviews.png new file mode 100644 index 0000000000..d241e4ca1a Binary files /dev/null and b/src/widgets/doc/images/sharedmodel-tableviews.png differ diff --git a/src/widgets/doc/images/sharedselection-tableviews.png b/src/widgets/doc/images/sharedselection-tableviews.png new file mode 100644 index 0000000000..ccbda2578f Binary files /dev/null and b/src/widgets/doc/images/sharedselection-tableviews.png differ diff --git a/src/widgets/doc/images/spinboxdelegate-example.png b/src/widgets/doc/images/spinboxdelegate-example.png new file mode 100644 index 0000000000..5e57a9c12b Binary files /dev/null and b/src/widgets/doc/images/spinboxdelegate-example.png differ diff --git a/src/widgets/doc/images/standard-views.png b/src/widgets/doc/images/standard-views.png new file mode 100644 index 0000000000..c804551622 Binary files /dev/null and b/src/widgets/doc/images/standard-views.png differ diff --git a/src/widgets/doc/images/standardwidget.png b/src/widgets/doc/images/standardwidget.png new file mode 100644 index 0000000000..3ccccf14a3 Binary files /dev/null and b/src/widgets/doc/images/standardwidget.png differ diff --git a/src/widgets/doc/images/stardelegate.png b/src/widgets/doc/images/stardelegate.png new file mode 100644 index 0000000000..24fa9fb0d7 Binary files /dev/null and b/src/widgets/doc/images/stardelegate.png differ diff --git a/src/widgets/doc/images/stringlistmodel.png b/src/widgets/doc/images/stringlistmodel.png new file mode 100644 index 0000000000..eedbff3585 Binary files /dev/null and b/src/widgets/doc/images/stringlistmodel.png differ diff --git a/src/widgets/doc/images/tableview.png b/src/widgets/doc/images/tableview.png new file mode 100755 index 0000000000..8be1b6ce62 Binary files /dev/null and b/src/widgets/doc/images/tableview.png differ diff --git a/src/widgets/doc/images/tree_2_with_algorithm.png b/src/widgets/doc/images/tree_2_with_algorithm.png new file mode 100644 index 0000000000..ecf91012bf Binary files /dev/null and b/src/widgets/doc/images/tree_2_with_algorithm.png differ diff --git a/src/widgets/doc/images/treeview.png b/src/widgets/doc/images/treeview.png new file mode 100644 index 0000000000..af31fe9bf1 Binary files /dev/null and b/src/widgets/doc/images/treeview.png differ diff --git a/src/widgets/doc/images/widgetmapper.png b/src/widgets/doc/images/widgetmapper.png new file mode 100644 index 0000000000..9627088077 Binary files /dev/null and b/src/widgets/doc/images/widgetmapper.png differ diff --git a/src/widgets/doc/images/widgets-tutorial-childwidget.png b/src/widgets/doc/images/widgets-tutorial-childwidget.png new file mode 100644 index 0000000000..0d42d701fc Binary files /dev/null and b/src/widgets/doc/images/widgets-tutorial-childwidget.png differ diff --git a/src/widgets/doc/images/widgets-tutorial-nestedlayouts.png b/src/widgets/doc/images/widgets-tutorial-nestedlayouts.png new file mode 100644 index 0000000000..1e2a9f4a1d Binary files /dev/null and b/src/widgets/doc/images/widgets-tutorial-nestedlayouts.png differ diff --git a/src/widgets/doc/images/widgets-tutorial-toplevel.png b/src/widgets/doc/images/widgets-tutorial-toplevel.png new file mode 100644 index 0000000000..a80d13c50d Binary files /dev/null and b/src/widgets/doc/images/widgets-tutorial-toplevel.png differ diff --git a/src/widgets/doc/images/widgets-tutorial-windowlayout.png b/src/widgets/doc/images/widgets-tutorial-windowlayout.png new file mode 100644 index 0000000000..fce52cdcd9 Binary files /dev/null and b/src/widgets/doc/images/widgets-tutorial-windowlayout.png differ diff --git a/src/widgets/doc/snippets/code/doc_src_model-view-programming.cpp b/src/widgets/doc/snippets/code/doc_src_model-view-programming.cpp new file mode 100644 index 0000000000..ca9aa606f7 --- /dev/null +++ b/src/widgets/doc/snippets/code/doc_src_model-view-programming.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QAbstractItemModel *model = index.model(); +//! [0] + + +//! [1] +QModelIndex index = model->index(row, column, ...); +//! [1] + + +//! [2] +QModelIndex indexA = model->index(0, 0, QModelIndex()); +QModelIndex indexB = model->index(1, 1, QModelIndex()); +QModelIndex indexC = model->index(2, 1, QModelIndex()); +//! [2] + + +//! [3] +QModelIndex index = model->index(row, column, parent); +//! [3] + + +//! [4] +QModelIndex indexA = model->index(0, 0, QModelIndex()); +QModelIndex indexC = model->index(2, 1, QModelIndex()); +//! [4] + + +//! [5] +QModelIndex indexB = model->index(1, 0, indexA); +//! [5] + + +//! [6] +QVariant value = model->data(index, role); +//! [6] diff --git a/src/widgets/doc/snippets/code/doc_src_qt4-mainwindow.cpp b/src/widgets/doc/snippets/code/doc_src_qt4-mainwindow.cpp new file mode 100644 index 0000000000..ecbb5f5220 --- /dev/null +++ b/src/widgets/doc/snippets/code/doc_src_qt4-mainwindow.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ +//! [0] + + +//! [1] +fileToolbar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); +addToolBar(Qt::TopToolBarArea, fileToolbar); +//! [1] + + +//! [2] +setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); +setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); +setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); +setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); +//! [2] + + +//! [3] +QWidget *centralWidget = new QWidget(this); +setCentralWidget(centralWidget); +//! [3] + + +//! [4] +QPopupMenu *fileMenu = new QPopupMenu(this); +openAction->addTo(fileMenu); +saveAction->addTo(fileMenu); +... +menuBar()->insertItem(tr("&File"), fileMenu); +//! [4] + + +//! [5] +QMenu *fileMenu = menuBar()->addMenu(tr("&File")); +fileMenu->addAction(openAction); +fileMenu->addAction(saveAction); +... +//! [5] + + +//! [6] +QToolBar *fileTools = new QToolBar(this, "file toolbar"); +openAction->addTo(fileTools); +saveAction->addTo(fileTools); +... +//! [6] + + +//! [7] +QToolBar *fileTools = addToolBar(tr("File Tool Bar")); +fileTools->addAction(openAction); +fileTools->addAction(saveAction); +... +//! [7] + + +//! [8] +QDockWidget *dockWidget = new QDockWidget(this); +mainWin->moveDockWidget(dockWidget, Qt::DockLeft); +//! [8] + + +//! [9] +QDockWidget *dockWidget = new QDockWidget(mainWindow); +mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dockWidget); +//! [9] diff --git a/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp b/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp new file mode 100644 index 0000000000..882af70b64 --- /dev/null +++ b/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ + setWindowTitle("Dock Widgets"); + + setupDockWindow(); + setupContents(); + setupMenus(); + + textBrowser = new QTextBrowser(this); + + connect(headingList, SIGNAL(itemClicked(QListWidgetItem *)), + this, SLOT(updateText(QListWidgetItem *))); + + updateText(headingList->item(0)); + headingList->setCurrentRow(0); + setCentralWidget(textBrowser); +} + +void MainWindow::setupContents() +{ + QFile titlesFile(":/Resources/titles.txt"); + titlesFile.open(QFile::ReadOnly); + int chapter = 0; + + do { + QString line = titlesFile.readLine().trimmed(); + QStringList parts = line.split("\t", QString::SkipEmptyParts); + if (parts.size() != 2) + break; + + QString chapterTitle = parts[0]; + QString fileName = parts[1]; + + QFile chapterFile(fileName); + + chapterFile.open(QFile::ReadOnly); + QListWidgetItem *item = new QListWidgetItem(chapterTitle, headingList); + item->setData(Qt::DisplayRole, chapterTitle); + item->setData(Qt::UserRole, chapterFile.readAll()); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + chapterFile.close(); + + chapter++; + } while (titlesFile.isOpen()); + + titlesFile.close(); +} + +void MainWindow::setupDockWindow() +{ +//! [0] + contentsWindow = new QDockWidget(tr("Table of Contents"), this); + contentsWindow->setAllowedAreas(Qt::LeftDockWidgetArea + | Qt::RightDockWidgetArea); + addDockWidget(Qt::LeftDockWidgetArea, contentsWindow); + + headingList = new QListWidget(contentsWindow); + contentsWindow->setWidget(headingList); +//! [0] +} + +void MainWindow::setupMenus() +{ + QAction *exitAct = new QAction(tr("E&xit"), this); + exitAct->setShortcut(tr("Ctrl+Q")); + exitAct->setStatusTip(tr("Exit the application")); + connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(exitAct); +} + +void MainWindow::updateText(QListWidgetItem *item) +{ + QString text = item->data(Qt::UserRole).toString(); + textBrowser->setHtml(text); +} diff --git a/src/widgets/doc/snippets/itemselection/itemselection.pro b/src/widgets/doc/snippets/itemselection/itemselection.pro new file mode 100644 index 0000000000..b1126bfe73 --- /dev/null +++ b/src/widgets/doc/snippets/itemselection/itemselection.pro @@ -0,0 +1,3 @@ +HEADERS = model.h +SOURCES = main.cpp \ + model.cpp diff --git a/src/widgets/doc/snippets/itemselection/main.cpp b/src/widgets/doc/snippets/itemselection/main.cpp new file mode 100644 index 0000000000..f39fb68b32 --- /dev/null +++ b/src/widgets/doc/snippets/itemselection/main.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + main.cpp + + A simple example that shows how selections can be used directly on a model. + It shows the result of some selections made using a table view. +*/ + +#include +#include +#include +#include + +#include "model.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + +//! [0] + TableModel *model = new TableModel(8, 4, &app); + + QTableView *table = new QTableView(0); + table->setModel(model); + + QItemSelectionModel *selectionModel = table->selectionModel(); +//! [0] //! [1] + QModelIndex topLeft; + QModelIndex bottomRight; + + topLeft = model->index(0, 0, QModelIndex()); + bottomRight = model->index(5, 2, QModelIndex()); +//! [1] + +//! [2] + QItemSelection selection(topLeft, bottomRight); + selectionModel->select(selection, QItemSelectionModel::Select); +//! [2] + +//! [3] + QItemSelection toggleSelection; + + topLeft = model->index(2, 1, QModelIndex()); + bottomRight = model->index(7, 3, QModelIndex()); + toggleSelection.select(topLeft, bottomRight); + + selectionModel->select(toggleSelection, QItemSelectionModel::Toggle); +//! [3] + +//! [4] + QItemSelection columnSelection; + + topLeft = model->index(0, 1, QModelIndex()); + bottomRight = model->index(0, 2, QModelIndex()); + + columnSelection.select(topLeft, bottomRight); + + selectionModel->select(columnSelection, + QItemSelectionModel::Select | QItemSelectionModel::Columns); + + QItemSelection rowSelection; + + topLeft = model->index(0, 0, QModelIndex()); + bottomRight = model->index(1, 0, QModelIndex()); + + rowSelection.select(topLeft, bottomRight); + + selectionModel->select(rowSelection, + QItemSelectionModel::Select | QItemSelectionModel::Rows); +//! [4] + + table->setWindowTitle("Selected items in a table model"); + table->show(); + table->resize(460, 280); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/itemselection/model.cpp b/src/widgets/doc/snippets/itemselection/model.cpp new file mode 100644 index 0000000000..6c9c5bad82 --- /dev/null +++ b/src/widgets/doc/snippets/itemselection/model.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + model.cpp + + Provides a table model for use in various examples. +*/ + +#include + +#include "model.h" + +/*! + Constructs a table model with at least one row and one column. +*/ + +TableModel::TableModel(int rows, int columns, QObject *parent) + : QAbstractTableModel(parent) +{ + QStringList newList; + + for (int column = 0; column < qMax(1, columns); ++column) { + newList.append(""); + } + + for (int row = 0; row < qMax(1, rows); ++row) { + rowList.append(newList); + } +} + + +/*! + Returns the number of items in the row list as the number of rows + in the model. +*/ + +int TableModel::rowCount(const QModelIndex &/*parent*/) const +{ + return rowList.size(); +} + +/*! + Returns the number of items in the first list item as the number of + columns in the model. All rows should have the same number of columns. +*/ + +int TableModel::columnCount(const QModelIndex &/*parent*/) const +{ + return rowList[0].size(); +} + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned for the display role; otherwise an invalid variant + is returned. +*/ + +QVariant TableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return rowList[index.row()][index.column()]; + else + return QVariant(); +} + +/*! + Returns the appropriate header string depending on the orientation of + the header and the section. If anything other than the display role is + requested, we return an invalid variant. +*/ + +QVariant TableModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("Column %1").arg(section); + else + return QString("Row %1").arg(section); +} + +/*! + Returns an appropriate value for the item's flags. Valid items are + enabled, selectable, and editable. +*/ + +Qt::ItemFlags TableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; +} + +/*! + Changes an item in the model, but only if the following conditions + are met: + + * The index supplied is valid. + * The role associated with editing text is specified. + + The dataChanged() signal is emitted if the item is changed. +*/ + +bool TableModel::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + if (!index.isValid() || role != Qt::EditRole) + return false; + + rowList[index.row()][index.column()] = value.toString(); + emit dataChanged(index, index); + return true; +} + +/*! + Inserts a number of rows into the model at the specified position. +*/ + +bool TableModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + int columns = columnCount(); + beginInsertRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + QStringList items; + for (int column = 0; column < columns; ++column) + items.append(""); + rowList.insert(position, items); + } + + endInsertRows(); + return true; +} + +/*! + Inserts a number of columns into the model at the specified position. + Each entry in the list is extended in turn with the required number of + empty strings. +*/ + +bool TableModel::insertColumns(int position, int columns, + const QModelIndex &parent) +{ + int rows = rowCount(); + beginInsertColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = position; column < columns; ++column) { + rowList[row].insert(position, ""); + } + } + + endInsertColumns(); + return true; +} + +/*! + Removes a number of rows from the model at the specified position. +*/ + +bool TableModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + beginRemoveRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + rowList.removeAt(position); + } + + endRemoveRows(); + return true; +} + +/*! + Removes a number of columns from the model at the specified position. + Each row is shortened by the number of columns specified. +*/ + +bool TableModel::removeColumns(int position, int columns, + const QModelIndex &parent) +{ + int rows = rowCount(); + beginRemoveColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + rowList[row].removeAt(position); + } + } + + endRemoveColumns(); + return true; +} diff --git a/src/widgets/doc/snippets/itemselection/model.h b/src/widgets/doc/snippets/itemselection/model.h new file mode 100644 index 0000000000..ef63e45ce0 --- /dev/null +++ b/src/widgets/doc/snippets/itemselection/model.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/src/widgets/doc/snippets/qlistview-dnd/main.cpp b/src/widgets/doc/snippets/qlistview-dnd/main.cpp new file mode 100644 index 0000000000..56bff2a612 --- /dev/null +++ b/src/widgets/doc/snippets/qlistview-dnd/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow *window = new MainWindow; + window->show(); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp new file mode 100644 index 0000000000..ff35c5e25d --- /dev/null +++ b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" +#include "model.h" + +MainWindow::MainWindow() +{ + QMenu *fileMenu = new QMenu(tr("&File")); + + QAction *quitAction = fileMenu->addAction(tr("E&xit")); + quitAction->setShortcut(tr("Ctrl+Q")); + + menuBar()->addMenu(fileMenu); + +// For convenient quoting: +//! [0] +QListView *listView = new QListView(this); +listView->setSelectionMode(QAbstractItemView::ExtendedSelection); +listView->setDragEnabled(true); +listView->setAcceptDrops(true); +listView->setDropIndicatorShown(true); +//! [0] + + this->listView = listView; + + connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + + setupListItems(); + + setCentralWidget(listView); + setWindowTitle(tr("List View")); +} + +void MainWindow::setupListItems() +{ + QStringList items; + items << tr("Oak") << tr("Fir") << tr("Pine") << tr("Birch") << tr("Hazel") + << tr("Redwood") << tr("Sycamore") << tr("Chestnut") + << tr("Mahogany"); + + DragDropListModel *model = new DragDropListModel(items, this); + listView->setModel(model); +} diff --git a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.h b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.h new file mode 100644 index 0000000000..daac61260e --- /dev/null +++ b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QListView; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private: + void setupListItems(); + + QListView *listView; +}; + +#endif diff --git a/src/widgets/doc/snippets/qlistview-dnd/model.cpp b/src/widgets/doc/snippets/qlistview-dnd/model.cpp new file mode 100644 index 0000000000..190ac968c0 --- /dev/null +++ b/src/widgets/doc/snippets/qlistview-dnd/model.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of an example program for Qt. +** EDITIONS: NOLIMITS +** +****************************************************************************/ + +/* + model.cpp + + A simple model that uses a QStringList as its data source. +*/ + +#include + +#include "model.h" + +DragDropListModel::DragDropListModel(const QStringList &strings, + QObject *parent) + : QStringListModel(strings, parent) +{ +} + +//! [0] +bool DragDropListModel::dropMimeData(const QMimeData *data, + Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if (action == Qt::IgnoreAction) + return true; + + if (!data->hasFormat("application/vnd.text.list")) + return false; + + if (column > 0) +//! [0] //! [1] + return false; +//! [1] + +//! [2] + int beginRow; + + if (row != -1) + beginRow = row; +//! [2] //! [3] + else if (parent.isValid()) + beginRow = parent.row(); +//! [3] //! [4] + else + beginRow = rowCount(QModelIndex()); +//! [4] + +//! [5] + QByteArray encodedData = data->data("application/vnd.text.list"); + QDataStream stream(&encodedData, QIODevice::ReadOnly); + QStringList newItems; + int rows = 0; + + while (!stream.atEnd()) { + QString text; + stream >> text; + newItems << text; + ++rows; + } +//! [5] + +//! [6] + insertRows(beginRow, rows, QModelIndex()); + foreach (const QString &text, newItems) { + QModelIndex idx = index(beginRow, 0, QModelIndex()); + setData(idx, text); + beginRow++; + } + + return true; +} +//! [6] + +//! [7] +Qt::ItemFlags DragDropListModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags defaultFlags = QStringListModel::flags(index); + + if (index.isValid()) + return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; + else + return Qt::ItemIsDropEnabled | defaultFlags; +} +//! [7] + +//! [8] +QMimeData *DragDropListModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData(); + QByteArray encodedData; + + QDataStream stream(&encodedData, QIODevice::WriteOnly); + + foreach (const QModelIndex &index, indexes) { + if (index.isValid()) { + QString text = data(index, Qt::DisplayRole).toString(); + stream << text; + } + } + + mimeData->setData("application/vnd.text.list", encodedData); + return mimeData; +} +//! [8] + +//! [9] +QStringList DragDropListModel::mimeTypes() const +{ + QStringList types; + types << "application/vnd.text.list"; + return types; +} +//! [9] + +//! [10] +Qt::DropActions DragDropListModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} +//! [10] diff --git a/src/widgets/doc/snippets/qlistview-dnd/model.h b/src/widgets/doc/snippets/qlistview-dnd/model.h new file mode 100644 index 0000000000..9d1ff904e1 --- /dev/null +++ b/src/widgets/doc/snippets/qlistview-dnd/model.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of an example program for Qt. +** EDITIONS: NOLIMITS +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include + +class DragDropListModel : public QStringListModel +{ + Q_OBJECT + +public: + DragDropListModel(const QStringList &strings, QObject *parent = 0); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + QMimeData *mimeData(const QModelIndexList &indexes) const; + QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const; +}; + +#endif diff --git a/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro b/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro new file mode 100644 index 0000000000..71fa273a69 --- /dev/null +++ b/src/widgets/doc/snippets/qlistview-dnd/qlistview-dnd.pro @@ -0,0 +1,5 @@ +SOURCES = main.cpp \ + mainwindow.cpp \ + model.cpp +HEADERS = mainwindow.h \ + model.h diff --git a/src/widgets/doc/snippets/qlistwidget-dnd/main.cpp b/src/widgets/doc/snippets/qlistwidget-dnd/main.cpp new file mode 100644 index 0000000000..56bff2a612 --- /dev/null +++ b/src/widgets/doc/snippets/qlistwidget-dnd/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow *window = new MainWindow; + window->show(); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp new file mode 100644 index 0000000000..8d93f823f4 --- /dev/null +++ b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" + +MainWindow::MainWindow() +{ + QMenu *fileMenu = new QMenu(tr("&File")); + + QAction *quitAction = fileMenu->addAction(tr("E&xit")); + quitAction->setShortcut(tr("Ctrl+Q")); + + menuBar()->addMenu(fileMenu); + +// For convenient quoting: +//! [0] +QListWidget *listWidget = new QListWidget(this); +listWidget->setSelectionMode(QAbstractItemView::SingleSelection); +listWidget->setDragEnabled(true); +listWidget->viewport()->setAcceptDrops(true); +listWidget->setDropIndicatorShown(true); +//! [0] //! [1] +listWidget->setDragDropMode(QAbstractItemView::InternalMove); +//! [1] + + this->listWidget = listWidget; + + connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + + setupListItems(); + + setCentralWidget(listWidget); + setWindowTitle(tr("List Widget")); +} + +void MainWindow::setupListItems() +{ + QListWidgetItem *item; + item = new QListWidgetItem(tr("Oak"), listWidget); + item = new QListWidgetItem(tr("Fir"), listWidget); + item = new QListWidgetItem(tr("Pine"), listWidget); + item = new QListWidgetItem(tr("Birch"), listWidget); + item = new QListWidgetItem(tr("Hazel"), listWidget); + item = new QListWidgetItem(tr("Redwood"), listWidget); + item = new QListWidgetItem(tr("Sycamore"), listWidget); + item = new QListWidgetItem(tr("Chestnut"), listWidget); + item = new QListWidgetItem(tr("Mahogany"), listWidget); +} diff --git a/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.h b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.h new file mode 100644 index 0000000000..50cac647d1 --- /dev/null +++ b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QListWidget; +class QListWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private: + void setupListItems(); + + QListWidget *listWidget; +}; + +#endif diff --git a/src/widgets/doc/snippets/qlistwidget-dnd/qlistwidget-dnd.pro b/src/widgets/doc/snippets/qlistwidget-dnd/qlistwidget-dnd.pro new file mode 100644 index 0000000000..12a900a7c6 --- /dev/null +++ b/src/widgets/doc/snippets/qlistwidget-dnd/qlistwidget-dnd.pro @@ -0,0 +1,3 @@ +SOURCES = main.cpp \ + mainwindow.cpp +HEADERS = mainwindow.h diff --git a/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp b/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp new file mode 100644 index 0000000000..0d78ae3f10 --- /dev/null +++ b/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QObject *parent = &app; + + QStringList numbers; + numbers << "One" << "Two" << "Three" << "Four" << "Five"; + + QAbstractItemModel *stringListModel = new QStringListModel(numbers, parent); + +//! [0] + QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(parent); + filterModel->setSourceModel(stringListModel); +//! [0] + + QWidget *window = new QWidget; + +//! [1] + QListView *filteredView = new QListView; + filteredView->setModel(filterModel); +//! [1] + filteredView->setWindowTitle("Filtered view onto a string list model"); + + QLineEdit *patternEditor = new QLineEdit; + QObject:: + connect(patternEditor, SIGNAL(textChanged(const QString &)), + filterModel, SLOT(setFilterRegExp(const QString &))); + + QVBoxLayout *layout = new QVBoxLayout(window); + layout->addWidget(filteredView); + layout->addWidget(patternEditor); + + window->show(); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/qsortfilterproxymodel/qsortfilterproxymodel.pro b/src/widgets/doc/snippets/qsortfilterproxymodel/qsortfilterproxymodel.pro new file mode 100644 index 0000000000..16181f21cf --- /dev/null +++ b/src/widgets/doc/snippets/qsortfilterproxymodel/qsortfilterproxymodel.pro @@ -0,0 +1 @@ +SOURCES = main.cpp diff --git a/src/widgets/doc/snippets/qtablewidget-using/Images/cubed.png b/src/widgets/doc/snippets/qtablewidget-using/Images/cubed.png new file mode 100644 index 0000000000..2cd9048ca6 Binary files /dev/null and b/src/widgets/doc/snippets/qtablewidget-using/Images/cubed.png differ diff --git a/src/widgets/doc/snippets/qtablewidget-using/Images/squared.png b/src/widgets/doc/snippets/qtablewidget-using/Images/squared.png new file mode 100644 index 0000000000..bfdf993289 Binary files /dev/null and b/src/widgets/doc/snippets/qtablewidget-using/Images/squared.png differ diff --git a/src/widgets/doc/snippets/qtablewidget-using/images.qrc b/src/widgets/doc/snippets/qtablewidget-using/images.qrc new file mode 100644 index 0000000000..1d49b52866 --- /dev/null +++ b/src/widgets/doc/snippets/qtablewidget-using/images.qrc @@ -0,0 +1,6 @@ + + + Images/squared.png + Images/cubed.png + + diff --git a/src/widgets/doc/snippets/qtablewidget-using/main.cpp b/src/widgets/doc/snippets/qtablewidget-using/main.cpp new file mode 100644 index 0000000000..56bff2a612 --- /dev/null +++ b/src/widgets/doc/snippets/qtablewidget-using/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow *window = new MainWindow; + window->show(); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/qtablewidget-using/mainwindow.h b/src/widgets/doc/snippets/qtablewidget-using/mainwindow.h new file mode 100644 index 0000000000..5c8c997762 --- /dev/null +++ b/src/widgets/doc/snippets/qtablewidget-using/mainwindow.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QTableWidget; +class QTableWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void averageItems(); + void sumItems(); + +private: + void setupTableItems(); + + QAction *removeAction; +//! [0] + QTableWidget *tableWidget; +//! [0] +}; + +#endif diff --git a/src/widgets/doc/snippets/qtablewidget-using/qtablewidget-using.pro b/src/widgets/doc/snippets/qtablewidget-using/qtablewidget-using.pro new file mode 100644 index 0000000000..ffe134cbb6 --- /dev/null +++ b/src/widgets/doc/snippets/qtablewidget-using/qtablewidget-using.pro @@ -0,0 +1,4 @@ +SOURCES = main.cpp \ + mainwindow.cpp +HEADERS = mainwindow.h +RESOURCES += images.qrc diff --git a/src/widgets/doc/snippets/reading-selections/main.cpp b/src/widgets/doc/snippets/reading-selections/main.cpp new file mode 100644 index 0000000000..3356ffc8ab --- /dev/null +++ b/src/widgets/doc/snippets/reading-selections/main.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + main.cpp + + A simple example that shows how selections can be used directly on a model. + It shows the result of some selections made using a table view. +*/ + +#include + +#include "window.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QMainWindow *window = new MainWindow; + window->show(); + window->resize(640, 480); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/reading-selections/model.cpp b/src/widgets/doc/snippets/reading-selections/model.cpp new file mode 100644 index 0000000000..ca4b9f84dd --- /dev/null +++ b/src/widgets/doc/snippets/reading-selections/model.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + model.cpp + + Provides a table model for use in various examples. +*/ + +#include + +#include "model.h" + +/*! + Constructs a table model with at least one row and one column. +*/ + +TableModel::TableModel(int rows, int columns, QObject *parent) + : QAbstractTableModel(parent) +{ + QStringList newList; + + for (int column = 0; column < qMax(1, columns); ++column) { + newList.append(""); + } + + for (int row = 0; row < qMax(1, rows); ++row) { + rowList.append(newList); + } +} + + +/*! + Returns the number of items in the row list as the number of rows + in the model. +*/ + +int TableModel::rowCount(const QModelIndex &/*parent*/) const +{ + return rowList.size(); +} + +/*! + Returns the number of items in the first list item as the number of + columns in the model. All rows should have the same number of columns. +*/ + +int TableModel::columnCount(const QModelIndex &/*parent*/) const +{ + return rowList[0].size(); +} + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned for the display role; otherwise an invalid variant + is returned. +*/ + +QVariant TableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return rowList[index.row()][index.column()]; + else + return QVariant(); +} + +/*! + Returns the appropriate header string depending on the orientation of + the header and the section. If anything other than the display role is + requested, we return an invalid variant. +*/ + +QVariant TableModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("Column %1").arg(section); + else + return QString("Row %1").arg(section); +} + +/*! + Returns an appropriate value for the item's flags. Valid items are + enabled, selectable, and editable. +*/ + +Qt::ItemFlags TableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +/*! + Changes an item in the model, but only if the following conditions + are met: + + * The index supplied is valid. + * The role associated with editing text is specified. + + The dataChanged() signal is emitted if the item is changed. +*/ + +bool TableModel::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + if (!index.isValid() || role != Qt::EditRole) + return false; + + rowList[index.row()][index.column()] = value.toString(); + emit dataChanged(index, index); + return true; +} + +/*! + Inserts a number of rows into the model at the specified position. +*/ + +bool TableModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + int columns = columnCount(); + beginInsertRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + QStringList items; + for (int column = 0; column < columns; ++column) + items.append(""); + rowList.insert(position, items); + } + + endInsertRows(); + return true; +} + +/*! + Inserts a number of columns into the model at the specified position. + Each entry in the list is extended in turn with the required number of + empty strings. +*/ + +bool TableModel::insertColumns(int position, int columns, + const QModelIndex &parent) +{ + int rows = rowCount(); + beginInsertColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = position; column < columns; ++column) { + rowList[row].insert(position, ""); + } + } + + endInsertColumns(); + return true; +} + +/*! + Removes a number of rows from the model at the specified position. +*/ + +bool TableModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + beginRemoveRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + rowList.removeAt(position); + } + + endRemoveRows(); + return true; +} + +/*! + Removes a number of columns from the model at the specified position. + Each row is shortened by the number of columns specified. +*/ + +bool TableModel::removeColumns(int position, int columns, + const QModelIndex &parent) +{ + int rows = rowCount(); + beginRemoveColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + rowList[row].removeAt(position); + } + } + + endRemoveColumns(); + return true; +} diff --git a/src/widgets/doc/snippets/reading-selections/model.h b/src/widgets/doc/snippets/reading-selections/model.h new file mode 100644 index 0000000000..ef63e45ce0 --- /dev/null +++ b/src/widgets/doc/snippets/reading-selections/model.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/src/widgets/doc/snippets/reading-selections/reading-selections.pro b/src/widgets/doc/snippets/reading-selections/reading-selections.pro new file mode 100644 index 0000000000..91ebd3e84f --- /dev/null +++ b/src/widgets/doc/snippets/reading-selections/reading-selections.pro @@ -0,0 +1,2 @@ +HEADERS += model.h window.h +SOURCES += main.cpp model.cpp window.cpp diff --git a/src/widgets/doc/snippets/reading-selections/window.cpp b/src/widgets/doc/snippets/reading-selections/window.cpp new file mode 100644 index 0000000000..dd9970374f --- /dev/null +++ b/src/widgets/doc/snippets/reading-selections/window.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + window.cpp + + A minimal subclass of QTableView with slots to allow the selection model + to be monitored. +*/ + +#include +#include +#include +#include +#include +#include + +#include "model.h" +#include "window.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ + setWindowTitle("Selected Items in a Table Model"); + + model = new TableModel(8, 4, this); + + table = new QTableView(this); + table->setModel(model); + + QMenu *actionMenu = new QMenu(tr("&Actions"), this); + QAction *fillAction = actionMenu->addAction(tr("&Fill Selection")); + QAction *clearAction = actionMenu->addAction(tr("&Clear Selection")); + QAction *selectAllAction = actionMenu->addAction(tr("&Select All")); + menuBar()->addMenu(actionMenu); + + connect(fillAction, SIGNAL(triggered()), this, SLOT(fillSelection())); + connect(clearAction, SIGNAL(triggered()), this, SLOT(clearSelection())); + connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll())); + + selectionModel = table->selectionModel(); + + statusBar(); + setCentralWidget(table); +} + +void MainWindow::fillSelection() +{ +//! [0] + QModelIndexList indexes = selectionModel->selectedIndexes(); + QModelIndex index; + + foreach(index, indexes) { + QString text = QString("(%1,%2)").arg(index.row()).arg(index.column()); + model->setData(index, text); + } +//! [0] +} + +void MainWindow::clearSelection() +{ + QModelIndexList indexes = selectionModel->selectedIndexes(); + QModelIndex index; + + foreach(index, indexes) + model->setData(index, ""); +} + +void MainWindow::selectAll() +{ +//! [1] + QModelIndex parent = QModelIndex(); +//! [1] //! [2] + QModelIndex topLeft = model->index(0, 0, parent); + QModelIndex bottomRight = model->index(model->rowCount(parent)-1, + model->columnCount(parent)-1, parent); +//! [2] + +//! [3] + QItemSelection selection(topLeft, bottomRight); + selectionModel->select(selection, QItemSelectionModel::Select); +//! [3] +} diff --git a/src/widgets/doc/snippets/reading-selections/window.h b/src/widgets/doc/snippets/reading-selections/window.h new file mode 100644 index 0000000000..6d2537c22d --- /dev/null +++ b/src/widgets/doc/snippets/reading-selections/window.h @@ -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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include +#include +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + +private slots: + void fillSelection(); + void clearSelection(); + void selectAll(); + +private: + QAbstractItemModel *model; + QItemSelectionModel *selectionModel; + QTableView *table; +}; + +#endif diff --git a/src/widgets/doc/snippets/sharedtablemodel/main.cpp b/src/widgets/doc/snippets/sharedtablemodel/main.cpp new file mode 100644 index 0000000000..f031a02aca --- /dev/null +++ b/src/widgets/doc/snippets/sharedtablemodel/main.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + main.cpp + + A simple example that shows how a single model can be shared between + multiple views. +*/ + +#include +#include +#include +#include + +#include "model.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + TableModel *model = new TableModel(4, 2, &app); + +//! [0] + QTableView *firstTableView = new QTableView; + QTableView *secondTableView = new QTableView; +//! [0] + +//! [1] + firstTableView->setModel(model); + secondTableView->setModel(model); +//! [1] + + firstTableView->horizontalHeader()->setModel(model); + + for (int row = 0; row < 4; ++row) { + for (int column = 0; column < 2; ++column) { + QModelIndex index = model->index(row, column, QModelIndex()); + model->setData(index, QVariant(QString("(%1, %2)").arg(row).arg(column))); + } + } + +//! [2] + secondTableView->setSelectionModel(firstTableView->selectionModel()); +//! [2] + + firstTableView->setWindowTitle("First table view"); + secondTableView->setWindowTitle("Second table view"); + firstTableView->show(); + secondTableView->show(); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/sharedtablemodel/model.cpp b/src/widgets/doc/snippets/sharedtablemodel/model.cpp new file mode 100644 index 0000000000..ec56f84adb --- /dev/null +++ b/src/widgets/doc/snippets/sharedtablemodel/model.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + model.cpp + + Provides a table model for use in various examples. +*/ + +#include + +#include "model.h" + +/*! + Constructs a table model with at least one row and one column. +*/ + +TableModel::TableModel(int rows, int columns, QObject *parent) + : QAbstractTableModel(parent) +{ + QStringList newList; + + for (int column = 0; column < qMax(1, columns); ++column) { + newList.append(""); + } + + for (int row = 0; row < qMax(1, rows); ++row) { + rowList.append(newList); + } +} + + +/*! + Returns the number of items in the row list as the number of rows + in the model. +*/ + +int TableModel::rowCount(const QModelIndex &/*parent*/) const +{ + return rowList.size(); +} + +/*! + Returns the number of items in the first list item as the number of + columns in the model. All rows should have the same number of columns. +*/ + +int TableModel::columnCount(const QModelIndex &/*parent*/) const +{ + return rowList[0].size(); +} + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned for the display role; otherwise an invalid variant + is returned. +*/ + +QVariant TableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return rowList[index.row()][index.column()]; + else + return QVariant(); +} + +/*! + Returns the appropriate header string depending on the orientation of + the header and the section. If anything other than the display role is + requested, we return an invalid variant. +*/ + +QVariant TableModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("Column %1").arg(section); + else + return QString("Row %1").arg(section); +} + +/*! + Returns an appropriate value for the item's flags. Valid items are + enabled, selectable, and editable. +*/ + +Qt::ItemFlags TableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; +} + +/*! + Changes an item in the model, but only if the following conditions + are met: + + * The index supplied is valid. + * The role associated with editing text is specified. + + The dataChanged() signal is emitted if the item is changed. +*/ + +bool TableModel::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + if (!index.isValid() || role != Qt::EditRole) + return false; + + rowList[index.row()][index.column()] = value.toString(); + emit dataChanged(index, index); + return true; +} + +/*! + Inserts a number of rows into the model at the specified position. +*/ + +bool TableModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + int columns = columnCount(); + beginInsertRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + QStringList items; + for (int column = 0; column < columns; ++column) + items.append(""); + rowList.insert(position, items); + } + + endInsertRows(); + return true; +} + +/*! + Inserts a number of columns into the model at the specified position. + Each entry in the list is extended in turn with the required number of + empty strings. +*/ + +bool TableModel::insertColumns(int position, int columns, const QModelIndex &parent) +{ + int rows = rowCount(); + beginInsertColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = position; column < columns; ++column) { + rowList[row].insert(position, ""); + } + } + + endInsertColumns(); + return true; +} + +/*! + Removes a number of rows from the model at the specified position. +*/ + +bool TableModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + beginRemoveRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + rowList.removeAt(position); + } + + endRemoveRows(); + return true; +} + +/*! + Removes a number of columns from the model at the specified position. + Each row is shortened by the number of columns specified. +*/ + +bool TableModel::removeColumns(int position, int columns, const QModelIndex &parent) +{ + int rows = rowCount(); + beginRemoveColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + rowList[row].removeAt(position); + } + } + + endRemoveColumns(); + return true; +} diff --git a/src/widgets/doc/snippets/sharedtablemodel/model.h b/src/widgets/doc/snippets/sharedtablemodel/model.h new file mode 100644 index 0000000000..ef63e45ce0 --- /dev/null +++ b/src/widgets/doc/snippets/sharedtablemodel/model.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/src/widgets/doc/snippets/sharedtablemodel/sharedtablemodel.pro b/src/widgets/doc/snippets/sharedtablemodel/sharedtablemodel.pro new file mode 100644 index 0000000000..10671e6e25 --- /dev/null +++ b/src/widgets/doc/snippets/sharedtablemodel/sharedtablemodel.pro @@ -0,0 +1,2 @@ +HEADERS += model.h +SOURCES += main.cpp model.cpp diff --git a/src/widgets/doc/snippets/simplemodel-use/main.cpp b/src/widgets/doc/snippets/simplemodel-use/main.cpp new file mode 100644 index 0000000000..d8188b14e6 --- /dev/null +++ b/src/widgets/doc/snippets/simplemodel-use/main.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + main.cpp + + A simple example of how to access items from an existing model. +*/ + +#include + +/*! + Create a default directory model and, using the index-based interface to + the model and some QLabel widgets, populate the window's layout with the + names of objects in the directory. + + Note that we only want to read the filenames in the highest level of the + directory, so we supply a default (invalid) QModelIndex to the model in + order to indicate that we want top-level items. +*/ + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QWidget *window = new QWidget; + QVBoxLayout *layout = new QVBoxLayout(window); + QLabel *title = new QLabel("Some items from the directory model", window); + title->setBackgroundRole(QPalette::Base); + title->setMargin(8); + layout->addWidget(title); + +//! [0] + QFileSystemModel *model = new QFileSystemModel; + QModelIndex parentIndex = model->index(QDir::currentPath()); + int numRows = model->rowCount(parentIndex); +//! [0] + +//! [1] + for (int row = 0; row < numRows; ++row) { + QModelIndex index = model->index(row, 0, parentIndex); +//! [1] + +//! [2] + QString text = model->data(index, Qt::DisplayRole).toString(); + // Display the text in a widget. +//! [2] + + QLabel *label = new QLabel(text, window); + layout->addWidget(label); +//! [3] + } +//! [3] + + window->setWindowTitle("A simple model example"); + window->show(); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/simplemodel-use/simplemodel-use.pro b/src/widgets/doc/snippets/simplemodel-use/simplemodel-use.pro new file mode 100644 index 0000000000..28dcadcbfa --- /dev/null +++ b/src/widgets/doc/snippets/simplemodel-use/simplemodel-use.pro @@ -0,0 +1 @@ +SOURCES += main.cpp diff --git a/src/widgets/doc/snippets/stringlistmodel/main.cpp b/src/widgets/doc/snippets/stringlistmodel/main.cpp new file mode 100644 index 0000000000..d4f0efdc22 --- /dev/null +++ b/src/widgets/doc/snippets/stringlistmodel/main.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + The main function for the string list model example. This creates and + populates a model with values from a string list then displays the + contents of the model using a QListView widget. +*/ + +#include +#include +#include + +#include "model.h" + +//! [0] +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + +// Unindented for quoting purposes: +//! [1] +QStringList numbers; +numbers << "One" << "Two" << "Three" << "Four" << "Five"; + +QAbstractItemModel *model = new StringListModel(numbers); +//! [0] //! [1] //! [2] //! [3] +QListView *view = new QListView; +//! [2] +view->setWindowTitle("View onto a string list model"); +//! [4] +view->setModel(model); +//! [3] //! [4] + + model->insertRows(5, 7, QModelIndex()); + + for (int row = 5; row < 12; ++row) { + QModelIndex index = model->index(row, 0, QModelIndex()); + model->setData(index, QString::number(row+1)); + } + +//! [5] + view->show(); + return app.exec(); +} +//! [5] diff --git a/src/widgets/doc/snippets/stringlistmodel/model.cpp b/src/widgets/doc/snippets/stringlistmodel/model.cpp new file mode 100644 index 0000000000..6795345d36 --- /dev/null +++ b/src/widgets/doc/snippets/stringlistmodel/model.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + model.cpp + + A simple model that uses a QStringList as its data source. +*/ + +#include "model.h" + +/*! + Returns the number of items in the string list as the number of rows + in the model. +*/ + +//! [0] +int StringListModel::rowCount(const QModelIndex &parent) const +{ + return stringList.count(); +} +//! [0] + + +#ifdef 0 +// This represents a read-only version of data(), an early stage in the +// development of the example leading to an editable StringListModel. + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned. +*/ + +//! [1-data-read-only] +QVariant StringListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= stringList.size()) + return QVariant(); + + if (role == Qt::DisplayRole) + return stringList.at(index.row()); + else + return QVariant(); +} +//! [1-data-read-only] +#endif + + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned. +*/ + +//! [1] +QVariant StringListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= stringList.size()) + return QVariant(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) + return stringList.at(index.row()); + else + return QVariant(); +} +//! [1] + +/*! + Returns the appropriate header string depending on the orientation of + the header and the section. If anything other than the display role is + requested, we return an invalid variant. +*/ + +//! [2] +QVariant StringListModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("Column %1").arg(section); + else + return QString("Row %1").arg(section); +} +//! [2] + +/*! + Returns an appropriate value for the item's flags. Valid items are + enabled, selectable, and editable. +*/ + +//! [3] +Qt::ItemFlags StringListModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + return QAbstractItemModel::flags(index) | Qt::ItemIsEditable; +} +//! [3] + +/*! + Changes an item in the string list, but only if the following conditions + are met: + + * The index supplied is valid. + * The index corresponds to an item to be shown in a view. + * The role associated with editing text is specified. + + The dataChanged() signal is emitted if the item is changed. +*/ + +//! [4] +bool StringListModel::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + if (index.isValid() && role == Qt::EditRole) { + + stringList.replace(index.row(), value.toString()); + emit dataChanged(index, index); + return true; + } +//! [4] //! [5] + return false; +} +//! [5] + +/*! + Inserts a number of rows into the model at the specified position. +*/ + +//! [6] +bool StringListModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + beginInsertRows(QModelIndex(), position, position+rows-1); + + for (int row = 0; row < rows; ++row) { + stringList.insert(position, ""); + } + + endInsertRows(); + return true; +//! [6] //! [7] +} +//! [7] + +/*! + Removes a number of rows from the model at the specified position. +*/ + +//! [8] +bool StringListModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + beginRemoveRows(QModelIndex(), position, position+rows-1); + + for (int row = 0; row < rows; ++row) { + stringList.removeAt(position); + } + + endRemoveRows(); + return true; +//! [8] //! [9] +} +//! [9] diff --git a/src/widgets/doc/snippets/stringlistmodel/model.h b/src/widgets/doc/snippets/stringlistmodel/model.h new file mode 100644 index 0000000000..1dceccb8a8 --- /dev/null +++ b/src/widgets/doc/snippets/stringlistmodel/model.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +//! [0] +class StringListModel : public QAbstractListModel +{ + Q_OBJECT + +public: + StringListModel(const QStringList &strings, QObject *parent = 0) + : QAbstractListModel(parent), stringList(strings) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, +//! [0] //! [1] + int role = Qt::DisplayRole) const; +//! [1] + +//! [2] + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, +//! [2] //! [3] + int role = Qt::EditRole); +//! [3] + +//! [4] + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); +//! [4] + +//! [5] +private: + QStringList stringList; +}; +//! [5] + +#endif diff --git a/src/widgets/doc/snippets/stringlistmodel/stringlistmodel.pro b/src/widgets/doc/snippets/stringlistmodel/stringlistmodel.pro new file mode 100644 index 0000000000..b1126bfe73 --- /dev/null +++ b/src/widgets/doc/snippets/stringlistmodel/stringlistmodel.pro @@ -0,0 +1,3 @@ +HEADERS = model.h +SOURCES = main.cpp \ + model.cpp diff --git a/src/widgets/doc/snippets/updating-selections/main.cpp b/src/widgets/doc/snippets/updating-selections/main.cpp new file mode 100644 index 0000000000..3356ffc8ab --- /dev/null +++ b/src/widgets/doc/snippets/updating-selections/main.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + main.cpp + + A simple example that shows how selections can be used directly on a model. + It shows the result of some selections made using a table view. +*/ + +#include + +#include "window.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QMainWindow *window = new MainWindow; + window->show(); + window->resize(640, 480); + return app.exec(); +} diff --git a/src/widgets/doc/snippets/updating-selections/model.cpp b/src/widgets/doc/snippets/updating-selections/model.cpp new file mode 100644 index 0000000000..ec56f84adb --- /dev/null +++ b/src/widgets/doc/snippets/updating-selections/model.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + model.cpp + + Provides a table model for use in various examples. +*/ + +#include + +#include "model.h" + +/*! + Constructs a table model with at least one row and one column. +*/ + +TableModel::TableModel(int rows, int columns, QObject *parent) + : QAbstractTableModel(parent) +{ + QStringList newList; + + for (int column = 0; column < qMax(1, columns); ++column) { + newList.append(""); + } + + for (int row = 0; row < qMax(1, rows); ++row) { + rowList.append(newList); + } +} + + +/*! + Returns the number of items in the row list as the number of rows + in the model. +*/ + +int TableModel::rowCount(const QModelIndex &/*parent*/) const +{ + return rowList.size(); +} + +/*! + Returns the number of items in the first list item as the number of + columns in the model. All rows should have the same number of columns. +*/ + +int TableModel::columnCount(const QModelIndex &/*parent*/) const +{ + return rowList[0].size(); +} + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned for the display role; otherwise an invalid variant + is returned. +*/ + +QVariant TableModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return rowList[index.row()][index.column()]; + else + return QVariant(); +} + +/*! + Returns the appropriate header string depending on the orientation of + the header and the section. If anything other than the display role is + requested, we return an invalid variant. +*/ + +QVariant TableModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) + return QString("Column %1").arg(section); + else + return QString("Row %1").arg(section); +} + +/*! + Returns an appropriate value for the item's flags. Valid items are + enabled, selectable, and editable. +*/ + +Qt::ItemFlags TableModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::ItemIsEnabled; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; +} + +/*! + Changes an item in the model, but only if the following conditions + are met: + + * The index supplied is valid. + * The role associated with editing text is specified. + + The dataChanged() signal is emitted if the item is changed. +*/ + +bool TableModel::setData(const QModelIndex &index, + const QVariant &value, int role) +{ + if (!index.isValid() || role != Qt::EditRole) + return false; + + rowList[index.row()][index.column()] = value.toString(); + emit dataChanged(index, index); + return true; +} + +/*! + Inserts a number of rows into the model at the specified position. +*/ + +bool TableModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + int columns = columnCount(); + beginInsertRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + QStringList items; + for (int column = 0; column < columns; ++column) + items.append(""); + rowList.insert(position, items); + } + + endInsertRows(); + return true; +} + +/*! + Inserts a number of columns into the model at the specified position. + Each entry in the list is extended in turn with the required number of + empty strings. +*/ + +bool TableModel::insertColumns(int position, int columns, const QModelIndex &parent) +{ + int rows = rowCount(); + beginInsertColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = position; column < columns; ++column) { + rowList[row].insert(position, ""); + } + } + + endInsertColumns(); + return true; +} + +/*! + Removes a number of rows from the model at the specified position. +*/ + +bool TableModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + beginRemoveRows(parent, position, position + rows - 1); + + for (int row = 0; row < rows; ++row) { + rowList.removeAt(position); + } + + endRemoveRows(); + return true; +} + +/*! + Removes a number of columns from the model at the specified position. + Each row is shortened by the number of columns specified. +*/ + +bool TableModel::removeColumns(int position, int columns, const QModelIndex &parent) +{ + int rows = rowCount(); + beginRemoveColumns(parent, position, position + columns - 1); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + rowList[row].removeAt(position); + } + } + + endRemoveColumns(); + return true; +} diff --git a/src/widgets/doc/snippets/updating-selections/model.h b/src/widgets/doc/snippets/updating-selections/model.h new file mode 100644 index 0000000000..ef63e45ce0 --- /dev/null +++ b/src/widgets/doc/snippets/updating-selections/model.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/src/widgets/doc/snippets/updating-selections/updating-selections.pro b/src/widgets/doc/snippets/updating-selections/updating-selections.pro new file mode 100644 index 0000000000..91ebd3e84f --- /dev/null +++ b/src/widgets/doc/snippets/updating-selections/updating-selections.pro @@ -0,0 +1,2 @@ +HEADERS += model.h window.h +SOURCES += main.cpp model.cpp window.cpp diff --git a/src/widgets/doc/snippets/updating-selections/window.cpp b/src/widgets/doc/snippets/updating-selections/window.cpp new file mode 100644 index 0000000000..eaa37b8c87 --- /dev/null +++ b/src/widgets/doc/snippets/updating-selections/window.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + window.cpp + + A minimal subclass of QTableView with slots to allow the selection model + to be monitored. +*/ + +#include +#include +#include +#include + +#include "model.h" +#include "window.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) +{ + setWindowTitle("Selected items in a table model"); + + model = new TableModel(8, 4, this); + + table = new QTableView(this); + table->setModel(model); + + selectionModel = table->selectionModel(); + connect(selectionModel, + SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), + this, SLOT(updateSelection(const QItemSelection &, const QItemSelection &))); + connect(selectionModel, + SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(changeCurrent(const QModelIndex &, const QModelIndex &))); + + statusBar(); + setCentralWidget(table); +} + +//! [0] +void MainWindow::updateSelection(const QItemSelection &selected, + const QItemSelection &deselected) +{ + QModelIndex index; + QModelIndexList items = selected.indexes(); + + foreach (index, items) { + QString text = QString("(%1,%2)").arg(index.row()).arg(index.column()); + model->setData(index, text); +//! [0] //! [1] + } +//! [1] + +//! [2] + items = deselected.indexes(); + + foreach (index, items) + model->setData(index, ""); +} +//! [2] + +//! [3] +void MainWindow::changeCurrent(const QModelIndex ¤t, + const QModelIndex &previous) +{ + statusBar()->showMessage( + tr("Moved from (%1,%2) to (%3,%4)") + .arg(previous.row()).arg(previous.column()) + .arg(current.row()).arg(current.column())); +} +//! [3] diff --git a/src/widgets/doc/snippets/updating-selections/window.h b/src/widgets/doc/snippets/updating-selections/window.h new file mode 100644 index 0000000000..0d87ced010 --- /dev/null +++ b/src/widgets/doc/snippets/updating-selections/window.h @@ -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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include +#include +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + +public slots: + void updateSelection(const QItemSelection &selected, + const QItemSelection &deselected); + void changeCurrent(const QModelIndex ¤t, const QModelIndex &previous); + +private: + QAbstractItemModel *model; + QItemSelectionModel *selectionModel; + QTableView *table; +}; + +#endif diff --git a/src/widgets/doc/snippets/widgets-tutorial/template.cpp b/src/widgets/doc/snippets/widgets-tutorial/template.cpp new file mode 100644 index 0000000000..187952d44d --- /dev/null +++ b/src/widgets/doc/snippets/widgets-tutorial/template.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** 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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [main.cpp body] +#include + +// Include header files for application components. +// ... + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + // Set up and show widgets. + // ... + + return app.exec(); +} +//! [main.cpp body] diff --git a/src/widgets/doc/src/addressbook-fr.qdoc b/src/widgets/doc/src/addressbook-fr.qdoc new file mode 100644 index 0000000000..edd53239d0 --- /dev/null +++ b/src/widgets/doc/src/addressbook-fr.qdoc @@ -0,0 +1,1036 @@ +/**************************************************************************** +** +** 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 + + Si c'est votre premier contact avec Qt, lisez \l{How to Learn Qt}{Comment apprendre Qt} + si ce n'est déjà fait. + + Le code source du tutoriel est distribué avec Qt dans le dossier \c examples/tutorials/addressbook + + Les chapitres du tutoriel: + + \list 1 + \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{}, permettant de repérer les objets QString à considérer + pour traduire une application. Vous remarquerez, dans les chapitres à venir + comme dans les \l{Qt Examples}{exemples Qt}, qu'elle est utilisée chaque fois + que l'on utilise une chaîne susceptible d'être traduite. + + Lorsque l'on programme avec Qt, il est utile de savoir comment fonctionnent les + agencements ou layouts. Qt fournit trois classes principales de layouts pour + contrôler le placement des widgets: QHBoxLayout, QVBoxLayout et QGridLayout. + + \image addressbook-tutorial-part1-labeled-layout.png + + On utilise un QGridLayout pour positionner nos labels et champs de saisie de manière + structurée. QGridLayout divise l'espace disponible en une grille, et place les + widgets dans les cellules que l'on spécifie par les numéros de ligne et de colonne. + Le diagramme ci-dessus présente les cellules et la position des widgets, et cette + organisation est obtenue à l'aide du code suivant: + + \snippet tutorials/addressbook/part1/addressbook.cpp layout + + On remarque que le label \c AddressLabel est positionné en utilisant Qt::AlignTop + comme argument optionnel. Ceci est destiné à assurer qu'il ne sera pas centré + verticalement dans la cellule (1,0). Pour un aperçu rapide des layouts de Qt, + consultez la section \l{Layout 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 \gui Find. + + Finalement, nous définissons les variables privées \c findButton, + \c lineEdit et \c findText, qui correspondent respectivement au bouton + \gui Find, au champ de texte dans lequel l'utilisateur tape le texte + à rechercher, et à une variable interne stockant le texte pour une + utilisation ultérieure. + + \section1 Implémentation de la classe FindDialog + + Dans le constructeur de \c FindDialog, nous instancions les objets des + variables privées \c lineEdit, \c findButton et \c findText. Nous utilisons ensuite + un QHBoxLayout pour positionner les widgets. + + \snippet tutorials/addressbook/part5/finddialog.cpp constructor + + Nous mettons en place la mise en page et le titre de la fenêtre, et + nous connectons les signaux aux slots. Remarquez que le signal + \l{QPushButton::clicked()}{clicked()} de \c{findButton} est connecté + à \c findClicked() et \l{QDialog::accept()}{accept()}. Le slot + \l{QDialog::accept()}{accept()} fourni par le QDialog ferme + la boîte de dialogue et lui donne le code de retour \l{QDialog::}{Accepted}. + Nous utilisons cette fonction pour aider la méthode \c findContact() de la classe + \c{AddressBook} à savoir si l'objet \c FindDialog a été fermé. Ceci sera + expliqué plus loin lorsque nous verrons la méthode \c findContact(). + + \image addressbook-tutorial-part5-signals-and-slots.png + + Dans \c findClicked(), nous validons le champ de texte pour nous + assurer que l'utilisateur n'a pas cliqué sur le bouton \gui Find sans + avoir entré un nom de contact. Ensuite, nous stockons le texte du champ + d'entrée \c lineEdit dans \c findText. Et finalement nous vidons le + contenu de \c lineEdit et cachons la boîte de dialogue. + + \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function + + La variable \c findText a un accesseur publique associé: \c getFindText(). + Étant donné que nous ne modifions \c findText directement que dans le + constructeur et la méthode \c findClicked(), nous ne créons pas + de manipulateurs associé à \c getFindText(). + Puisque \c getFindText() est publique, les classes instanciant et + utilisant \c FindDialog peuvent toujours accéder à la chaîne de + caractères que l'utilisateur a entré et accepté. + + \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function + + \section1 Définition de la classe AddressBook + + Pour utiliser \c FindDialog depuis la classe \c AddressBook, nous + incluons \c finddialog.h dans le fichier \c addressbook.h. + + \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header + + Jusqu'ici, toutes les fonctionnalités du carnet d'adresses ont un + QPushButton et un slot correspondant. De la même façon, pour la + fonctionnalité \gui Find, nous avons \c findButton et \c findContact(). + + Le \c findButton est déclaré comme une variable privée et la + méthode \c findContact() est déclarée comme un slot public. + + \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration + \dots + \snippet tutorials/addressbook/part5/addressbook.h findButton declaration + + Finalement, nous déclarons la variable privée \c dialog que nous allons + utiliser pour accéder à une instance de \c FindDialog. + + \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration + + Une fois que nous avons instancié la boîte de dialogue, nous voulons l'utiliser + plus qu'une fois. Utiliser une variable privée nous permet d'y référer + à plus d'un endroit dans la classe. + + \section1 Implémentation de la classe AddressBook + + Dans le constructeur de \c AddressBook, nous instancions nos objets privés, + \c findbutton et \c findDialog: + + \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton + \dots + \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog + + Ensuite, nous connectons le signal \l{QPushButton::clicked()}{clicked()} de + \c{findButton} à \c findContact(). + + \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find + + Maintenant, tout ce qui manque est le code de notre méthode \c findContact(): + + \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function + + Nous commençons par afficher l'instance de \c FindDialog, \c dialog. + L'utilisateur peut alors entrer le nom du contact à rechercher. Lorsque + l'utilisateur clique sur le bouton \c findButton, la boîte de dialogue est + masquée et le code de retour devient QDialog::Accepted. Ce code de retour + vient remplir la condition du premier if. + + Ensuite, nous extrayons le texte que nous utiliserons pour la recherche, + il s'agit ici de \c contactName obtenu à l'aide de la méthode \c getFindText() + de \c FindDialog. Si le contact existe dans le carnet d'adresse, nous + l'affichons directement. Sinon, nous affichons le QMessageBox suivant pour + indiquer que la recherche à échouée. + + \image addressbook-tutorial-part5-notfound.png +*/ + +/*! + \page tutorials-addressbook-part6.html + + \example tutorials/addressbook-fr/part6 + \title Carnet d'Adresses 6 - Sauvegarde et chargement + + Ce chapitre couvre les fonctionnalités de gestion des fichiers de Qt que + l'on utilise pour écrire les procédures de sauvegarde et chargement pour + l'application carnet d'adresses. + + \image addressbook-tutorial-part6-screenshot.png + + Bien que la navigation et la recherche de contacts soient des + fonctionnalités importantes, notre carnet d'adresses ne sera pleinement + utilisable qu'une fois que l'on pourra sauvegarder les contacts existants + et les charger à nouveau par la suite. + Qt fournit de nombreuses classes pour gérer les \l{Input/Output and + Networking}{entrées et sorties}, mais nous avons choisi de nous contenter d'une + combinaison de deux classes simples à utiliser ensemble: QFile et QDataStream. + + Un objet QFile représente un fichier sur le disque qui peut être lu, et + dans lequel on peut écrire. QFile est une classe fille de la classe plus + générique QIODevice, qui peut représenter différents types de + périphériques. + + Un objet QDataStream est utilisé pour sérialiser des données binaires + dans le but de les passer à un QIODevice pour les récupérer dans le + futur. Pour lire ou écrire dans un QIODevice, il suffit d'ouvrir le + flux, avec le périphérique approprié en paramètre, et d'y lire ou + écrire. + + \section1 Définition de la classe AddressBook + + On déclare deux slots publics, \c saveToFile() et \c loadFromFile(), + ainsi que deux objets QPushButton, \c loadButton et \c saveButton. + + \snippet tutorials/addressbook/part6/addressbook.h save and load functions declaration + \dots + \snippet tutorials/addressbook/part6/addressbook.h save and load buttons declaration + + \section1 Implémentation de la classe AddressBook + + Dans notre constructeur, on instancie \c loadButton et \c saveButton. + Idéalement, l'interface serait plus conviviale avec des boutons + affichant "Load contacts from a file" et "Save contacts to a file". Mais + compte tenu de la dimension des autres boutons, on initialise les labels + des boutons à \gui{Load...} et \gui{Save...}. Heureusement, Qt offre une + façon simple d'ajouter des info-bulles avec + \l{QWidget::setToolTip()}{setToolTip()}, et nous l'exploitons de la façon + suivante pour nos boutons: + + \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1 + \dots + \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2 + + Bien qu'on ne cite pas le code correspondant ici, nous ajoutons ces deux boutons au + layout de droite, \c button1Layout, comme pour les fonctionnalités précédentes, et + nous connectons leurs signaux + \l{QPushButton::clicked()}{clicked()} à leurs slots respectifs. + + Pour la sauvegarde, on commence par récupérer le nom de fichier + \c fileName, en utilisant QFileDialog::getSaveFileName(). C'est une + méthode pratique fournie par QFileDialog, qui ouvre une boîte de + dialogue modale et permet à l'utilisateur d'entrer un nom de fichier ou + de choisir un fichier \c{.abk} existant. Les fichiers \c{.abk} + correspondent à l'extension choisie pour la sauvegarde des contacts de + notre carnet d'adresses. + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1 + + La boîte de dialogue affichée est visible sur la capture d'écran ci- + dessous. + + \image addressbook-tutorial-part6-save.png + + Si \c fileName n'est pas vide, on crée un objet QFile, \c file, à partir + de \c fileName. QFile fonctionne avec QDataStream puisqu'il dérive de + QIODevice. + + Ensuite, on essaie d'ouvrir le fichier en écriture, ce qui correspond au + mode \l{QIODevice::}{WriteOnly}. Si cela échoue, on en informe + l'utilisateur avec une QMessageBox. + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2 + + Dans le cas contraire, on instancie un objet QDataStream, \c out, afin + d'écrire dans le fichier ouvert. QDataStream nécessite que la même + version de flux soit utilisée pour la lecture et l'écriture. On s'assure + que c'est le cas en spécifiant explicitement d'utiliser la + \l{QDataStream::Qt_4_5}{version introduite avec Qt 4.5} avant de + sérialiser les données vers le fichier \c file. + + \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3 + + Pour le chargement, on récupère également \c fileName en utilisant + QFileDialog::getOpenFileName(). Cette méthode est l'homologue de + QFileDialog::getSaveFileName() et affiche également une boîte de + dialogue modale permettant à l'utilisateur d'entrer un nom de fichier ou + de selectionner un fichier \c{.abk} existant, afin de le charger dans le + carnet d'adresses. + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1 + + Sous Windows, par exemple, cette méthode affiche une boîte de dialogue + native pour la sélection de fichier, comme illustré sur la capture + d'écran suivante: + + \image addressbook-tutorial-part6-load.png + + Si \c fileName n'est pas vide, on utilise une fois de plus un objet + QFile, \c file, et on tente de l'ouvrir en lecture, avec le mode + \l{QIODevice::}{ReadOnly}. De même que précédemment dans notre + implémentation de \c saveToFile(), si cette tentative s'avère + infructueuse, on en informe l'utilisateur par le biais d'une + QMessageBox. + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2 + + Dans le cas contraire, on instancie un objet QDataStream, \c in, en + spécifiant la version à utiliser comme précédemment, et on lit les + informations sérialisées vers la structure de données \c contacts. Notez + qu'on purge \c contacts avant d'y mettre les informations lues afin de + simplifier le processus de lecture de fichier. Une façon plus avancée de + procéder serait de lire les contacts dans un objet QMap temporaire, et + de copier uniquement les contacts n'existant pas encore dans + \c contacts. + + \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3 + + Pour afficher les contacts lus depuis le fichier, on doit d'abord + valider les données obtenues afin de s'assurer que le fichier lu + contient effectivement des entrées de carnet d'adresses. Si c'est le + cas, on affiche le premier contact; sinon on informe l'utilisateur du + problème par une QMessageBox. Enfin, on met à jour l'interface afin + d'activer et de désactiver les boutons de façon appropriée. +*/ + +/*! + \page tutorials-addressbook-fr-part7.html + + \example tutorials/addressbook-fr/part7 + \title Carnet d'adresse 7 - Fonctionnalités avancées + + Ce chapitre couvre quelques fonctionnalités additionnelles qui + feront de notre carnet d'adresses une application plus pratique + pour une utilisation quotidienne. + + \image addressbook-tutorial-part7-screenshot.png + + Bien que notre application carnet d'adresses soit utile en tant que telle, + il serait pratique de pouvoir échanger les contacts avec d'autres applications. + Le format vCard est un un format de fichier populaire pour échanger + ce type de données. + Dans ce chapitre, nous étendrons notre carnet d'adresses pour permettre + d'exporter des contacts dans des fichiers vCard \c{.vcf}. + + \section1 Définition de la classe AddressBook + + Nous ajoutons un objet QPushButton, \c exportButton, et un slot + public correspondant, \c exportAsVCard(), à notre classe \c AddressBook + dans le fichier \c addressbook.h. + + \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration + \dots + \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration + + \section1 Implémentation de la classe AddressBook + + Dans le constructeur de \c AddressBook, nous connectons le signal + \l{QPushButton::clicked()}{clicked()} de \c{exportButton} au slot + \c exportAsVCard(). + Nous ajoutons aussi ce bouton à \c buttonLayout1, le layout responsable + du groupe de boutons sur la droite. + + Dans la méthode \c exportAsVCard(), nous commençons par extraire le + nom du contact dans \n name. Nous déclarons \c firstname, \c lastName et + \c nameList. + Ensuite, nous cherchons la position du premier espace blanc de \c name. + Si il y a un espace, nous séparons le nom du contact en \c firstName et + \c lastName. Finalement, nous remplaçons l'espace par un underscore ("_"). + Si il n'y a pas d'espace, nous supposons que le contact ne comprend que + le prénom. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part1 + + Comme pour la méthode \c saveToFile(), nous ouvrons une boîte de dialogue + pour donner la possibilité à l'utilisateur de choisir un emplacement pour + le fichier. Avec le nom de fichier choisi, nous créons une instance de QFile + pour y écrire. + + Nous essayons d'ouvrir le fichier en mode \l{QIODevice::}{WriteOnly}. Si + cela échoue, nous affichons un QMessageBox pour informer l'utilisateur + à propos de l'origine du problème et nous quittons la méthode. Sinon, nous passons le + fichier comme paramètre pour créer un objet QTextStream, \c out. De la même façon que + QDataStream, la classe QTextStream fournit les fonctionnalités pour + lire et écrire des fichiers de texte. Grâce à celà, le fichier \c{.vcf} + généré pourra être ouvert et édité à l'aide d'un simple éditeur de texte. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part2 + + Nous écrivons ensuite un fichier vCard avec la balise \c{BEGIN:VCARD}, + suivit par \c{VERSION:2.1}. + Le nom d'un contact est écrit à l'aide de la balise \c{N:}. Pour la balise + \c{FN:}, qui remplit le titre du contact, nous devons vérifier si le contact + à un nom de famille défini ou non. Si oui, nous utilions les détails de + \c nameList pour remplir le champ, dans le cas contraire on écrit uniquement le contenu + de \c firstName. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part3 + + Nous continuons en écrivant l'adresse du contact. Les points-virgules + dans l'adresse sont échappés à l'aide de "\\", les retours de ligne sont + remplacés par des points-virgules, et les vigules sont remplacées par des espaces. + Finalement nous écrivons les balises \c{ADR;HOME:;} suivies par l'adresse + et la balise \c{END:VCARD}. + + \snippet tutorials/addressbook/part7/addressbook.cpp export function part4 + + À la fin de la méthode, un QMessageBox est affiché pour informer l'utilisateur + que la vCard a été exportée avec succès. + + \e{vCard est une marque déposée de \l{http://www.imc.org} + {Internet Mail Consortium}}. +*/ diff --git a/src/widgets/doc/src/addressbook.qdoc b/src/widgets/doc/src/addressbook.qdoc new file mode 100644 index 0000000000..27bdb0fac4 --- /dev/null +++ b/src/widgets/doc/src/addressbook.qdoc @@ -0,0 +1,981 @@ +/**************************************************************************** +** +** 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 + + If you are new to Qt, we recommend reading \l{How to Learn Qt} first. + + 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{examples/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 \gui Add. So, when the user clicks + \gui 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 \gui 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 \gui 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 \gui Submit or \gui 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 \gui Find + button. + + Lastly, we define the private variables, \c findButton, \c lineEdit + and \c findText, corresponding to the \gui 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 \gui 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 \gui 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 \gui{Load...} + and \gui{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/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc new file mode 100644 index 0000000000..0e48efbff8 --- /dev/null +++ b/src/widgets/doc/src/model-view-programming.qdoc @@ -0,0 +1,2339 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \group model-view + \title Model/View Classes +*/ + +/*! + \page model-view-programming.html + \ingroup qt-basic-concepts + + \title Model/View Programming + \brief A guide to Qt's extensible model/view architecture. + + \section1 Introduction to Model/View Programming + + Qt 4 introduced a new set of item view classes that use a model/view + architecture to manage the relationship between data and the way it + is presented to the user. The separation of functionality introduced by + this architecture gives developers greater flexibility to customize the + presentation of items, and provides a standard model interface to allow + a wide range of data sources to be used with existing item views. + In this document, we give a brief introduction to the model/view paradigm, + outline the concepts involved, and describe the architecture of the item + view system. Each of the components in the architecture is explained, + and examples are given that show how to use the classes provided. + + \section2 The model/view architecture + + Model-View-Controller (MVC) is a design pattern originating from + Smalltalk that is often used when building user interfaces. + In \l{Design Patterns}, Gamma et al. write: + + \quotation + MVC consists of three kinds of objects. The Model is the application + object, the View is its screen presentation, and the Controller defines + the way the user interface reacts to user input. Before MVC, user + interface designs tended to lump these objects together. MVC decouples + them to increase flexibility and reuse. + \endquotation + + If the view and the controller objects are combined, the result is + the model/view architecture. This still separates the way that data + is stored from the way that it is presented to the user, but provides + a simpler framework based on the same principles. This separation + makes it possible to display the same data in several different views, + and to implement new types of views, without changing the underlying + data structures. + To allow flexible handling of user input, we introduce the concept of + the \e delegate. The advantage of having a delegate in this framework + is that it allows the way items of data are rendered and edited to be + customized. + + \table + \row \li \inlineimage modelview-overview.png + \li \b{The model/view architecture} + + The model communicates with a source of data, providing an \e interface + for the other components in the architecture. The nature of the + communication depends on the type of data source, and the way the model + is implemented. + + The view obtains \e{model indexes} from the model; these are references + to items of data. By supplying model indexes to the model, the view can + retrieve items of data from the data source. + + In standard views, a \e delegate renders the items of data. When an item + is edited, the delegate communicates with the model directly using + model indexes. + \endtable + + Generally, the model/view classes can be separated into the three groups + described above: models, views, and delegates. Each of these components + is defined by \e abstract classes that provide common interfaces and, + in some cases, default implementations of features. + Abstract classes are meant to be subclassed in order to provide the full + set of functionality expected by other components; this also allows + specialized components to be written. + + Models, views, and delegates communicate with each other using \e{signals + and slots}: + + \list + \li Signals from the model inform the view about changes to the data + held by the data source. + \li Signals from the view provide information about the user's interaction + with the items being displayed. + \li Signals from the delegate are used during editing to tell the + model and view about the state of the editor. + \endlist + + \section3 Models + + All item models are based on the QAbstractItemModel class. This class + defines an interface that is used by views and delegates to access data. + The data itself does not have to be stored in the model; it can be held + in a data structure or repository provided by a separate class, a file, + a database, or some other application component. + + The basic concepts surrounding models are presented in the section + on \l{Model Classes}. + + QAbstractItemModel + provides an interface to data that is flexible enough to handle views + that represent data in the form of tables, lists, and trees. However, + when implementing new models for list and table-like data structures, + the QAbstractListModel and QAbstractTableModel classes are better + starting points because they provide appropriate default implementations + of common functions. Each of these classes can be subclassed to provide + models that support specialized kinds of lists and tables. + + The process of subclassing models is discussed in the section on + \l{Creating New Models}. + + Qt provides some ready-made models that can be used to handle items of + data: + + \list + \li QStringListModel is used to store a simple list of QString items. + \li QStandardItemModel manages more complex tree structures of items, each + of which can contain arbitrary data. + \li QFileSystemModel provides information about files and directories in the + local filing system. + \li QSqlQueryModel, QSqlTableModel, and QSqlRelationalTableModel are used + to access databases using model/view conventions. + \endlist + + If these standard models do not meet your requirements, you can subclass + QAbstractItemModel, QAbstractListModel, or QAbstractTableModel to create + your own custom models. + + \section3 Views + + Complete implementations are provided for different kinds of + views: QListView displays a list of items, QTableView displays data + from a model in a table, and QTreeView shows model items of data in a + hierarchical list. Each of these classes is based on the + QAbstractItemView abstract base class. Although these classes are + ready-to-use implementations, they can also be subclassed to provide + customized views. + + The available views are examined in the section on \l{View Classes}. + + \section3 Delegates + + QAbstractItemDelegate is the abstract base class for delegates in the + model/view framework. Since Qt 4.4, the default delegate implementation is + provided by QStyledItemDelegate, and this is used as the default delegate + by Qt's standard views. However, QStyledItemDelegate and QItemDelegate are + independent alternatives to painting and providing editors for items in + views. The difference between them is that QStyledItemDelegate uses the + current style to paint its items. We therefore recommend using + QStyledItemDelegate as the base class when implementing custom delegates or + when working with Qt style sheets. + + Delegates are described in the section on \l{Delegate Classes}. + + \section3 Sorting + + There are two ways of approaching sorting in the model/view + architecture; which approach to choose depends on your underlying + model. + + If your model is sortable, i.e, if it reimplements the + QAbstractItemModel::sort() function, both QTableView and QTreeView + provide an API that allows you to sort your model data + programmatically. In addition, you can enable interactive sorting + (i.e. allowing the users to sort the data by clicking the view's + headers), by connecting the QHeaderView::sortIndicatorChanged() signal + to the QTableView::sortByColumn() slot or the + QTreeView::sortByColumn() slot, respectively. + + The alternative approach, if your model do not have the required + interface or if you want to use a list view to present your data, + is to use a proxy model to transform the structure of your model + before presenting the data in the view. This is covered in detail + in the section on \l {Proxy Models}. + + \section3 Convenience classes + + A number of \e convenience classes are derived from the standard view + classes for the benefit of applications that rely on Qt's item-based + item view and table classes. They are not intended to be subclassed, + but simply exist to provide a familiar interface to the equivalent classes + in Qt 3. + Examples of such classes include \l QListWidget, \l QTreeWidget, and + \l QTableWidget; these provide similar behavior to the \c QListBox, + \c QListView, and \c QTable classes in Qt 3. + + These classes are less flexible than the view classes, and cannot be + used with arbitrary models. We recommend that you use a model/view + approach to handling data in item views unless you strongly need an + item-based set of classes. + + If you wish to take advantage of the features provided by the model/view + approach while still using an item-based interface, consider using view + classes, such as QListView, QTableView, and QTreeView with + QStandardItemModel. + + \section1 Using models and views + + The following sections explain how to use the model/view pattern + in Qt. Each section includes an an example and is followed by a + section showing how to create new components. + + \section2 Two models included in Qt + + Two of the standard models provided by Qt are QStandardItemModel and + QFileSystemModel. QStandardItemModel is a multi-purpose model that can be + used to represent various different data structures needed by list, table, + and tree views. This model also holds the items of data. + QFileSystemModel is a model that maintains information about the contents + of a directory. As a result, it does not hold any items of data itself, but + simply represents files and directories on the local filing system. + + QFileSystemModel provides a ready-to-use model to experiment with, and can be + easily configured to use existing data. Using this model, we can show how + to set up a model for use with ready-made views, and explore how to + manipulate data using model indexes. + + \section2 Using views with an existing model + + The QListView and QTreeView classes are the most suitable views + to use with QFileSystemModel. The example presented below displays the + contents of a directory in a tree view next to the same information in + a list view. The views share the user's selection so that the selected + items are highlighted in both views. + + \image shareddirmodel.png + + We set up a QFileSystemModel so that it is ready for use, and create some + views to display the contents of a directory. This shows the simplest + way to use a model. The construction and use of the model is + performed from within a single \c main() function: + + \snippet shareddirmodel/main.cpp 0 + + The model is set up to use data from a certain file system. The call to + \l{QFileSystemModel::}{setRootPath()} tell the model which drive on the + file system to expose to the views. + + We create two views so that we can examine the items held in the model in two + different ways: + + \snippet shareddirmodel/main.cpp 5 + + The views are constructed in the same way as other widgets. Setting up + a view to display the items in the model is simply a matter of calling its + \l{QAbstractItemView::setModel()}{setModel()} function with the directory + model as the argument. We filter the data supplied by the model by calling + the \l{QAbstractItemView::}{setRootIndex()} function on each view, passing + a suitable \e{model index} from the file system model for the current + directory. + + The \c index() function used in this case is unique to QFileSystemModel; we + supply it with a directory and it returns a model index. Model indexes are + discussed in \l{Model Classes}. + + The rest of the function just displays the views within a splitter + widget, and runs the application's event loop: + + \snippet shareddirmodel/main.cpp 8 + + In the above example, we neglected to mention how to handle selections + of items. This subject is covered in more detail in the section about + \l{Handling Selections in Item Views}. + + \section1 Model classes + + Before examining how selections are handled, you may find it + useful to examine the concepts used in the model/view framework. + + \section2 Basic concepts + + In the model/view architecture, the model provides a standard interface + that views and delegates use to access data. In Qt, the standard + interface is defined by the QAbstractItemModel class. No matter how the + items of data are stored in any underlying data structure, all subclasses + of QAbstractItemModel represent the data as a hierarchical structure + containing tables of items. Views use this \e convention to access items + of data in the model, but they are not restricted in the way that they + present this information to the user. + + \image modelview-models.png + + Models also notify any attached views about changes to data through the + signals and slots mechanism. + + This section describes some basic concepts that are central to the way + item of data are accessed by other components via a model class. More + advanced concepts are discussed in later sections. + + \section3 Model indexes + + To ensure that the representation of the data is kept separate from the + way it is accessed, the concept of a \e{model index} is introduced. Each + piece of information that can be obtained via a model is represented by + a model index. Views and delegates use these indexes to request items of + data to display. + + As a result, only the model needs to know how to obtain data, and the type + of data managed by the model can be defined fairly generally. Model indexes + contain a pointer to the model that created them, and this prevents + confusion when working with more than one model. + + \snippet code/doc_src_model-view-programming.cpp 0 + + Model indexes provide \e temporary references to pieces of information, and + can be used to retrieve or modify data via the model. Since models may + reorganize their internal structures from time to time, model indexes may + become invalid, and \e{should not be stored}. If a long-term reference to a + piece of information is required, a \e{persistent model index} must be + created. This provides a reference to the information that the model keeps + up-to-date. Temporary model indexes are provided by the QModelIndex class, + and persistent model indexes are provided by the QPersistentModelIndex + class. + + To obtain a model index that corresponds to an item of data, three + properties must be specified to the model: a row number, a column number, + and the model index of a parent item. The following sections describe + and explain these properties in detail. + + \section3 Rows and columns + + In its most basic form, a model can be accessed as a simple table in which + items are located by their row and column numbers. \e{This does not mean + that the underlying pieces of data are stored in an array structure}; the + use of row and column numbers is only a convention to allow components to + communicate with each other. We can retrieve information about any given + item by specifying its row and column numbers to the model, and we receive + an index that represents the item: + + \snippet code/doc_src_model-view-programming.cpp 1 + + Models that provide interfaces to simple, single level data structures like + lists and tables do not need any other information to be provided but, as + the above code indicates, we need to supply more information when obtaining + a model index. + + \table + \row \li \inlineimage modelview-tablemodel.png + \li \b{Rows and columns} + + The diagram shows a representation of a basic table model in which each + item is located by a pair of row and column numbers. We obtain a model + index that refers to an item of data by passing the relevant row and + column numbers to the model. + + \snippet code/doc_src_model-view-programming.cpp 2 + + Top level items in a model are always referenced by specifying + \c QModelIndex() as their parent item. This is discussed in the next + section. + \endtable + + \section3 Parents of items + + The table-like interface to item data provided by models is ideal when + using data in a table or list view; the row and column number system maps + exactly to the way the views display items. However, structures such as + tree views require the model to expose a more flexible interface to the + items within. As a result, each item can also be the parent of another + table of items, in much the same way that a top-level item in a tree view + can contain another list of items. + + When requesting an index for a model item, we must provide some information + about the item's parent. Outside the model, the only way to refer to an + item is through a model index, so a parent model index must also be given: + + \snippet code/doc_src_model-view-programming.cpp 3 + + \table + \row \li \inlineimage modelview-treemodel.png + \li \b{Parents, rows, and columns} + + The diagram shows a representation of a tree model in which each item is + referred to by a parent, a row number, and a column number. + + Items "A" and "C" are represented as top-level siblings in the model: + + \snippet code/doc_src_model-view-programming.cpp 4 + + Item "A" has a number of children. A model index for item "B" is + obtained with the following code: + + \snippet code/doc_src_model-view-programming.cpp 5 + \endtable + + \section3 Item roles + + Items in a model can perform various \e roles for other components, + allowing different kinds of data to be supplied for different situations. + For example, Qt::DisplayRole is used to access a string that can be + displayed as text in a view. Typically, items contain data for a number of + different roles, and the standard roles are defined by Qt::ItemDataRole. + + We can ask the model for the item's data by passing it the model index + corresponding to the item, and by specifying a role to obtain the type + of data we want: + + \snippet code/doc_src_model-view-programming.cpp 6 + + \table + \row \li \inlineimage modelview-roles.png + \li \b{Item roles} + + The role indicates to the model which type of data is being referred to. + Views can display the roles in different ways, so it is important to + supply appropriate information for each role. + + The \l{Creating New Models} section covers some specific uses of roles in + more detail. + \endtable + + Most common uses for item data are covered by the standard roles defined in + Qt::ItemDataRole. By supplying appropriate item data for each role, models + can provide hints to views and delegates about how items should be + presented to the user. Different kinds of views have the freedom to + interpret or ignore this information as required. It is also possible to + define additional roles for application-specific purposes. + + \section3 Summary + + \list + \li Model indexes give views and delegates information about the location + of items provided by models in a way that is independent of any + underlying data structures. + \li Items are referred to by their row and column numbers, and by the model + index of their parent items. + \li Model indexes are constructed by models at the request of other + components, such as views and delegates. + \li If a valid model index is specified for the parent item when an index is + requested using \l{QAbstractItemModel::index()}{index()}, the index + returned refers to an item beneath that parent item in the model. + The index obtained refers to a child of that item. + \li If an invalid model index is specified for the parent item when an index + is requested using \l{QAbstractItemModel::index()}{index()}, the index + returned refers to a top-level item in the model. + \li The \l{Qt::ItemDataRole}{role} distinguishes between the + different kinds of data associated with an item. + \endlist + + \section2 Using model indexes + + To demonstrate how data can be retrieved from a model, using model + indexes, we set up a QFileSystemModel without a view and display the + names of files and directories in a widget. + Although this does not show a normal way of using a model, it demonstrates + the conventions used by models when dealing with model indexes. + + We construct a file system model in the following way: + + \snippet simplemodel-use/main.cpp 0 + + In this case, we set up a default QFileSystemModel, obtain a parent index + using a specific implementation of \l{QFileSystemModel::}{index()} + provided by that model, and we count the number of rows in the model using + the \l{QFileSystemModel::}{rowCount()} function. + + For simplicity, we are only interested in the items in the first column + of the model. We examine each row in turn, obtaining a model index for + the first item in each row, and read the data stored for that item + in the model. + + \snippet simplemodel-use/main.cpp 1 + + To obtain a model index, we specify the row number, column number (zero + for the first column), and the appropriate model index for the parent + of all the items that we want. + The text stored in each item is retrieved using the model's + \l{QFileSystemModel::}{data()} function. We specify the model index and + the \l{Qt::ItemDataRole}{DisplayRole} to obtain data for the + item in the form of a string. + + \snippet simplemodel-use/main.cpp 2 + \codeline + \snippet simplemodel-use/main.cpp 3 + + The above example demonstrates the basic principles used to retrieve + data from a model: + + \list + \li The dimensions of a model can be found using + \l{QAbstractItemModel::rowCount()}{rowCount()} and + \l{QAbstractItemModel::columnCount()}{columnCount()}. + These functions generally require a parent model index to be + specified. + \li Model indexes are used to access items in the model. The row, column, + and parent model index are needed to specify the item. + \li To access top-level items in a model, specify a null model index + as the parent index with \c QModelIndex(). + \li Items contain data for different roles. To obtain the data for a + particular role, both the model index and the role must be supplied + to the model. + \endlist + + \section2 Further reading + + New models can be created by implementing the standard interface + provided by QAbstractItemModel. In the \l{Creating New Models} + section, we demonstrate this by creating a convenient ready-to-use + model for holding lists of strings. + + \section1 View classes + + \section2 Concepts + + In the model/view architecture, the view obtains items of data from the + model and presents them to the user. The way that the data is + presented need not resemble the representation of the data provided by + the model, and may be \e{completely different} from the underlying data + structure used to store items of data. + + The separation of content and presentation is achieved by the use of a + standard model interface provided by QAbstractItemModel, a standard view + interface provided by QAbstractItemView, and the use of model indexes + that represent items of data in a general way. + Views typically manage the overall layout of the data obtained from + models. They may render individual items of data themselves, or use + \l{Delegate Classes}{delegates} to handle both rendering and editing + features. + + As well as presenting data, views handle navigation between items, + and some aspects of item selection. The views also implement basic + user interface features, such as context menus and drag and drop. + A view can provide default editing facilities for items, or it may + work with a \l{Delegate Classes}{delegate} to provide a custom + editor. + + A view can be constructed without a model, but a model must be + provided before it can display useful information. Views keep track of + the items that the user has selected through the use of + \l{Handling Selections in Item Views}{selections} which can be maintained + separately for each view, or shared between multiple views. + + Some views, such as QTableView and QTreeView, display headers as well + as items. These are also implemented by a view class, QHeaderView. + Headers usually access the same model as the view that contains them. + They retrieve data from the model using the + \l{QAbstractItemModel::headerData()} function, and usually display + header information in the form of a label. New headers can be + subclassed from the QHeaderView class to provide more specialized + labels for views. + + \section2 Using an existing view + + Qt provides three ready-to-use view classes that present data from + models in ways that are familiar to most users. + QListView can display items from a model as a simple list, or in the + form of a classic icon view. QTreeView displays items from a + model as a hierarchy of lists, allowing deeply nested structures to be + represented in a compact way. QTableView presents items from a model + in the form of a table, much like the layout of a spreadsheet + application. + + \image standard-views.png + + The default behavior of the standard views shown above should be + sufficient for most applications. They provide basic editing + facilities, and can be customized to suit the needs of more specialized + user interfaces. + + \section3 Using a model + + We take the string list model that \l{Creating New Models}{we created as + an example model}, set it up with some data, and construct a view to + display the contents of the model. This can all be performed within a + single function: + + \snippet stringlistmodel/main.cpp 0 + + Note that the \c StringListModel is declared as a \l QAbstractItemModel. + This allows us to use the abstract interface to the model, and + ensures that the code still works, even if we replace the string list + model with a different model. + + The list view provided by \l QListView is sufficient for presenting + the items in the string list model. We construct the view, and set up + the model using the following lines of code: + + \snippet stringlistmodel/main.cpp 2 + \snippet stringlistmodel/main.cpp 4 + + The view is shown in the normal way: + + \snippet stringlistmodel/main.cpp 5 + + The view renders the contents of a model, accessing data via the model's + interface. When the user tries to edit an item, the view uses a default + delegate to provide an editor widget. + + \image stringlistmodel.png + + The above image shows how a QListView represents the data in the string + list model. Since the model is editable, the view automatically allows + each item in the list to be edited using the default delegate. + + \section3 Using multiple views of a model + + Providing multiple views onto the same model is simply a matter of + setting the same model for each view. In the following code we create + two table views, each using the same simple table model which we have + created for this example: + + \snippet sharedtablemodel/main.cpp 0 + \codeline + \snippet sharedtablemodel/main.cpp 1 + + The use of signals and slots in the model/view architecture means that + changes to the model can be propagated to all the attached views, + ensuring that we can always access the same data regardless of the + view being used. + + \image sharedmodel-tableviews.png + + The above image shows two different views onto the same model, each + containing a number of selected items. Although the data from the model + is shown consistently across view, each view maintains its own internal + selection model. This can be useful in certain situations but, for + many applications, a shared selection model is desirable. + + \section2 Handling selections of items + + The mechanism for handling selections of items within views is provided + by the \l QItemSelectionModel class. All of the standard views construct + their own selection models by default, and interact with them in the + normal way. The selection model being used by a view can be obtained + through the \l{QAbstractItemView::selectionModel()}{selectionModel()} + function, and a replacement selection model can be specified with + \l{QAbstractItemView::setSelectionModel()}{setSelectionModel()}. + The ability to control the selection model used by a view is useful + when we want to provide multiple consistent views onto the same model + data. + + Generally, unless you are subclassing a model or view, you don't + need to manipulate the contents of selections directly. However, + the interface to the selection model can be accessed, if required, + and this is explored in \l{Handling Selections in Item Views}. + + \section3 Sharing selections among views + + Although it is convenient that the view classes provide their own + selection models by default, when we use more than one view onto the + same model it is often desirable that both the model's data and the + user's selection are shown consistently in all views. + Since the view classes allow their internal selection models to be + replaced, we can achieve a unified selection between views with the + following line: + + \snippet sharedtablemodel/main.cpp 2 + + The second view is given the selection model for the first view. + Both views now operate on the same selection model, keeping both + the data and the selected items synchronized. + + \image sharedselection-tableviews.png + + In the example shown above, two views of the same type were used to + display the same model's data. However, if two different types of view + were used, the selected items may be represented very differently in + each view; for example, a contiguous selection in a table view can be + represented as a fragmented set of highlighted items in a tree view. + + \section1 Delegate classes + + \section2 Concepts + + Unlike the Model-View-Controller pattern, the model/view design does not + include a completely separate component for managing interaction with + the user. Generally, the view is responsible for the presentation of + model data to the user, and for processing user input. To allow some + flexibility in the way this input is obtained, the interaction is + performed by delegates. These components provide input capabilities + and are also responsible for rendering individual items in some views. + The standard interface for controlling delegates is defined in the + \l QAbstractItemDelegate class. + + Delegates are expected to be able to render their contents themselves + by implementing the \l{QItemDelegate::paint()}{paint()} + and \l{QItemDelegate::sizeHint()}{sizeHint()} functions. + However, simple widget-based delegates can subclass \l QItemDelegate + instead of \l QAbstractItemDelegate, and take advantage of the default + implementations of these functions. + + Editors for delegates can be implemented either by using widgets to manage + the editing process or by handling events directly. + The first approach is covered later in this section, and it is also + shown in the \l{Spin Box Delegate Example}{Spin Box Delegate} example. + + The \l{Pixelator Example}{Pixelator} example shows how to create a + custom delegate that performs specialized rendering for a table view. + + \section2 Using an existing delegate + + The standard views provided with Qt use instances of \l QItemDelegate + to provide editing facilities. This default implementation of the + delegate interface renders items in the usual style for each of the + standard views: \l QListView, \l QTableView, and \l QTreeView. + + All the standard roles are handled by the default delegate used by + the standard views. The way these are interpreted is described in the + QItemDelegate documentation. + + The delegate used by a view is returned by the + \l{QAbstractItemView::itemDelegate()}{itemDelegate()} function. + The \l{QAbstractItemView::setItemDelegate()}{setItemDelegate()} function + allows you to install a custom delegate for a standard view, and it is + necessary to use this function when setting the delegate for a custom + view. + + \section2 A simple delegate + + The delegate implemented here uses a \l QSpinBox to provide + editing facilities, and is mainly intended for use with models + that display integers. Although we set up a custom integer-based + table model for this purpose, we could easily have used \l + QStandardItemModel instead, since the custom delegate controls + data entry. We construct a table view to display the contents of + the model, and this will use the custom delegate for editing. + + \image spinboxdelegate-example.png + + We subclass the delegate from \l QItemDelegate because we do not want + to write custom display functions. However, we must still provide + functions to manage the editor widget: + + \snippet itemviews/spinboxdelegate/delegate.h 0 + + Note that no editor widgets are set up when the delegate is + constructed. We only construct an editor widget when it is needed. + + \section3 Providing an editor + + In this example, when the table view needs to provide an editor, it + asks the delegate to provide an editor widget that is appropriate + for the item being modified. The + \l{QAbstractItemDelegate::createEditor()}{createEditor()} function is + supplied with everything that the delegate needs to be able to set up + a suitable widget: + + \snippet itemviews/spinboxdelegate/delegate.cpp 1 + + Note that we do not need to keep a pointer to the editor widget because + the view takes responsibility for destroying it when it is no longer + needed. + + We install the delegate's default event filter on the editor to ensure + that it provides the standard editing shortcuts that users expect. + Additional shortcuts can be added to the editor to allow more + sophisticated behavior; these are discussed in the section on + \l{#EditingHints}{Editing Hints}. + + The view ensures that the editor's data and geometry are set + correctly by calling functions that we define later for these purposes. + We can create different editors depending on the model index supplied + by the view. For example, if we have a column of integers and a column + of strings we could return either a \c QSpinBox or a \c QLineEdit, + depending on which column is being edited. + + The delegate must provide a function to copy model data into the + editor. In this example, we read the data stored in the + \l{Qt::ItemDataRole}{display role}, and set the value in the + spin box accordingly. + + \snippet itemviews/spinboxdelegate/delegate.cpp 2 + + In this example, we know that the editor widget is a spin box, but we + could have provided different editors for different types of data in + the model, in which case we would need to cast the widget to the + appropriate type before accessing its member functions. + + \section3 Submitting data to the model + + When the user has finished editing the value in the spin box, the view + asks the delegate to store the edited value in the model by calling the + \l{QAbstractItemDelegate::setModelData()}{setModelData()} function. + + \snippet itemviews/spinboxdelegate/delegate.cpp 3 + + Since the view manages the editor widgets for the delegate, we only + need to update the model with the contents of the editor supplied. + In this case, we ensure that the spin box is up-to-date, and update + the model with the value it contains using the index specified. + + The standard \l QItemDelegate class informs the view when it has + finished editing by emitting the + \l{QAbstractItemDelegate::closeEditor()}{closeEditor()} signal. + The view ensures that the editor widget is closed and destroyed. In + this example, we only provide simple editing facilities, so we need + never emit this signal. + + All the operations on data are performed through the interface + provided by \l QAbstractItemModel. This makes the delegate mostly + independent from the type of data it manipulates, but some + assumptions must be made in order to use certain types of + editor widgets. In this example, we have assumed that the model + always contains integer values, but we can still use this + delegate with different kinds of models because \l{QVariant} + provides sensible default values for unexpected data. + + \section3 Updating the editor's geometry + + It is the responsibility of the delegate to manage the editor's + geometry. The geometry must be set when the editor is created, and + when the item's size or position in the view is changed. Fortunately, + the view provides all the necessary geometry information inside a + \l{QStyleOptionViewItem}{view option} object. + + \snippet itemviews/spinboxdelegate/delegate.cpp 4 + + In this case, we just use the geometry information provided by the + view option in the item rectangle. A delegate that renders items with + several elements would not use the item rectangle directly. It would + position the editor in relation to the other elements in the item. + + \target EditingHints + \section3 Editing hints + + After editing, delegates should provide hints to the other components + about the result of the editing process, and provide hints that will + assist any subsequent editing operations. This is achieved by + emitting the \l{QAbstractItemDelegate::closeEditor()}{closeEditor()} + signal with a suitable hint. This is taken care of by the default + QItemDelegate event filter which we installed on the spin box when + it was constructed. + + The behavior of the spin box could be adjusted to make it more user + friendly. In the default event filter supplied by QItemDelegate, if + the user hits \key Return to confirm their choice in the spin box, + the delegate commits the value to the model and closes the spin box. + We can change this behavior by installing our own event filter on the + spin box, and provide editing hints that suit our needs; for example, + we might emit \l{QAbstractItemDelegate::closeEditor()}{closeEditor()} + with the \l{QAbstractItemDelegate::EndEditHint}{EditNextItem} hint to + automatically start editing the next item in the view. + + Another approach that does not require the use of an event + filter is to provide our own editor widget, perhaps subclassing + QSpinBox for convenience. This alternative approach would give us + more control over how the editor widget behaves at the cost of + writing additional code. It is usually easier to install an event + filter in the delegate if you need to customize the behavior of + a standard Qt editor widget. + + Delegates do not have to emit these hints, but those that do not will + be less integrated into applications, and will be less usable than + those that emit hints to support common editing actions. + + \section1 Handling selections in item views + + \section2 Concepts + + The selection model used in the item view classes offers many improvements + over the selection model used in Qt 3. It provides a more general + description of selections based on the facilities of the model/view + architecture. Although the standard classes for manipulating selections are + sufficient for the item views provided, the selection model allows you to + create specialized selection models to suit the requirements for your own + item models and views. + + Information about the items selected in a view is stored in an instance of + the \l QItemSelectionModel class. This maintains model indexes for items in + a single model, and is independent of any views. Since there can be many + views onto a model, it is possible to share selections between views, + allowing applications to show multiple views in a consistent way. + + Selections are made up of \e{selection ranges}. These efficiently maintain + information about large selections of items by recording only the starting + and ending model indexes for each range of selected items. Non-contiguous + selections of items are constructed by using more than one selection range + to describe the selection. + + Selections are applied to a collection of model indexes held by a selection + model. The most recent selection of items applied is known as the + \e{current selection}. The effects of this selection can be modified even + after its application through the use of certain types of selection + commands. These are discussed later in this section. + + \section3 Current item and selected items + + In a view, there is always a current item and a selected item - two + independent states. An item can be the current item and selected at the + same time. The view is responsible for ensuring that there is always a + current item as keyboard navigation, for example, requires a current item. + + The table below highlights the differences between current item and + selected items. + + \table + \header + \li Current Item + \li Selected Items + + \row + \li There can only be one current item. + \li There can be multiple selected items. + \row + \li The current item will be changed with key navigation or mouse + button clicks. + \li The selected state of items is set or unset, depending on several + pre-defined modes - e.g., single selection, multiple selection, + etc. - when the user interacts with the items. + \row + \li The current item will be edited if the edit key, \uicontrol F2, is + pressed or the item is double-clicked (provided that editing is + enabled). + \li The current item can be used together with an anchor to specify a + range that should be selected or deselected (or a combination of + the two). + \row + \li The current item is indicated by the focus rectangle. + \li The selected items are indicated with the selection rectangle. + \endtable + + When manipulating selections, it is often helpful to think of + \l QItemSelectionModel as a record of the selection state of all the items + in an item model. Once a selection model is set up, collections of items + can be selected, deselected, or their selection states can be toggled + without the need to know which items are already selected. The indexes of + all selected items can be retrieved at any time, and other components can + be informed of changes to the selection model via the signals and slots + mechanism. + + \section2 Using a selection model + + The standard view classes provide default selection models that can + be used in most applications. A selection model belonging to one view + can be obtained using the view's + \l{QAbstractItemView::selectionModel()}{selectionModel()} function, + and shared between many views with + \l{QAbstractItemView::setSelectionModel()}{setSelectionModel()}, + so the construction of new selection models is generally not required. + + A selection is created by specifying a model, and a pair of model + indexes to a \l QItemSelection. This uses the indexes to refer to items + in the given model, and interprets them as the top-left and bottom-right + items in a block of selected items. + To apply the selection to items in a model requires the selection to be + submitted to a selection model; this can be achieved in a number of ways, + each having a different effect on the selections already present in the + selection model. + + \section3 Selecting items + + To demonstrate some of the principal features of selections, we construct + an instance of a custom table model with 32 items in total, and open a + table view onto its data: + + \snippet itemselection/main.cpp 0 + + The table view's default selection model is retrieved for later use. + We do not modify any items in the model, but instead select a few + items that the view will display at the top-left of the table. To do + this, we need to retrieve the model indexes corresponding to the + top-left and bottom-right items in the region to be selected: + + \snippet itemselection/main.cpp 1 + + To select these items in the model, and see the corresponding change + in the table view, we need to construct a selection object then apply + it to the selection model: + + \snippet itemselection/main.cpp 2 + + The selection is applied to the selection model using a command + defined by a combination of + \l{QItemSelectionModel::SelectionFlag}{selection flags}. + In this case, the flags used cause the items recorded in the + selection object to be included in the selection model, regardless + of their previous state. The resulting selection is shown by the view. + + \image selected-items1.png + + The selection of items can be modified using various operations that + are defined by the selection flags. The selection that results from + these operations may have a complex structure, but it is represented + efficiently by the selection model. The use of different selection + flags to manipulate the selected items is described when we examine + how to update a selection. + + \section3 Reading the selection state + + The model indexes stored in the selection model can be read using + the \l{QItemSelectionModel::selectedIndexes()}{selectedIndexes()} + function. This returns an unsorted list of model indexes that we can + iterate over as long as we know which model they are for: + + \snippet reading-selections/window.cpp 0 + + The above code uses Qt's convenient \l{Container Classes}{foreach + keyword} to iterate over, and modify, the items corresponding to the + indexes returned by the selection model. + + The selection model emits signals to indicate changes in the + selection. These notify other components about changes to both the + selection as a whole and the currently focused item in the item + model. We can connect the + \l{QItemSelectionModel::selectionChanged()}{selectionChanged()} + signal to a slot, and examine the items in the model that are selected or + deselected when the selection changes. The slot is called with two + \l{QItemSelection} objects: one contains a list of indexes that + correspond to newly selected items; the other contains indexes that + correspond to newly deselected items. + + In the following code, we provide a slot that receives the + \l{QItemSelectionModel::selectionChanged()}{selectionChanged()} + signal, fills in the selected items with + a string, and clears the contents of the deselected items. + + \snippet updating-selections/window.cpp 0 + \snippet updating-selections/window.cpp 1 + \codeline + \snippet updating-selections/window.cpp 2 + + We can keep track of the currently focused item by connecting the + \l{QItemSelectionModel::currentChanged()}{currentChanged()} signal + to a slot that is called with two model indexes. These correspond to + the previously focused item, and the currently focused item. + + In the following code, we provide a slot that receives the + \l{QItemSelectionModel::currentChanged()}{currentChanged()} signal, + and uses the information provided to update the status bar of a + \l QMainWindow: + + \snippet updating-selections/window.cpp 3 + + Monitoring selections made by the user is straightforward with these + signals, but we can also update the selection model directly. + + \section3 Updating a selection + + Selection commands are provided by a combination of selection flags, + defined by \l{QItemSelectionModel::SelectionFlag}. + Each selection flag tells the selection model how to update its + internal record of selected items when either of the + \l{QItemSelection::select()}{select()} functions are called. + The most commonly used flag is the + \l{QItemSelectionModel::SelectionFlag}{Select} flag + which instructs the selection model to record the specified items as + being selected. The + \l{QItemSelectionModel::SelectionFlag}{Toggle} flag causes the + selection model to invert the state of the specified items, + selecting any deselected items given, and deselecting any currently + selected items. The \l{QItemSelectionModel::SelectionFlag}{Deselect} + flag deselects all the specified items. + + Individual items in the selection model are updated by creating a + selection of items, and applying them to the selection model. In the + following code, we apply a second selection of items to the table + model shown above, using the + \l{QItemSelectionModel::SelectionFlag}{Toggle} command to invert the + selection state of the items given. + + \snippet itemselection/main.cpp 3 + + The results of this operation are displayed in the table view, + providing a convenient way of visualizing what we have achieved: + + \image selected-items2.png + + By default, the selection commands only operate on the individual + items specified by the model indexes. However, the flag used to + describe the selection command can be combined with additional flags + to change entire rows and columns. For example if you call + \l{QItemSelectionModel::select()}{select()} with only one index, but + with a command that is a combination of + \l{QItemSelectionModel::SelectionFlag}{Select} and + \l{QItemSelectionModel::SelectionFlag}{Rows}, the + entire row containing the item referred to is selected. + The following code demonstrates the use of the + \l{QItemSelectionModel::SelectionFlag}{Rows} and + \l{QItemSelectionModel::SelectionFlag}{Columns} flags: + + \snippet itemselection/main.cpp 4 + + Although only four indexes are supplied to the selection model, the + use of the + \l{QItemSelectionModel::SelectionFlag}{Columns} and + \l{QItemSelectionModel::SelectionFlag}{Rows} selection flags means + that two columns and two rows are selected. The following image shows + the result of these two selections: + + \image selected-items3.png + + The commands performed on the example model have all involved + accumulating a selection of items in the model. It is also possible + to clear the selection, or to replace the current selection with + a new one. + + To replace the current selection with a new selection, combine + the other selection flags with the + \l{QItemSelectionModel::SelectionFlag}{Current} flag. A command using + this flag instructs the selection model to replace its current collection + of model indexes with those specified in a call to + \l{QItemSelectionModel::select()}{select()}. + To clear all selections before you start adding new ones, + combine the other selection flags with the + \l{QItemSelectionModel::SelectionFlag}{Clear} flag. This + has the effect of resetting the selection model's collection of model + indexes. + + \section3 Selecting all items in a model + + To select all items in a model, it is necessary to create a + selection for each level of the model that covers all items in that + level. We do this by retrieving the indexes corresponding to the + top-left and bottom-right items with a given parent index: + + \snippet reading-selections/window.cpp 2 + + A selection is constructed with these indexes and the model. The + corresponding items are then selected in the selection model: + + \snippet reading-selections/window.cpp 3 + + This needs to be performed for all levels in the model. + For top-level items, we would define the parent index in the usual way: + + \snippet reading-selections/window.cpp 1 + + For hierarchical models, the + \l{QAbstractItemModel::hasChildren()}{hasChildren()} function is used to + determine whether any given item is the parent of another level of + items. + + \section1 Creating new models + + The separation of functionality between the model/view components allows + models to be created that can take advantage of existing views. This + approach lets us present data from a variety of sources using standard + graphical user interface components, such as QListView, QTableView, and + QTreeView. + + The QAbstractItemModel class provides an interface that is flexible + enough to support data sources that arrange information in hierarchical + structures, allowing for the possibility that data will be inserted, + removed, modified, or sorted in some way. It also provides support for + drag and drop operations. + + The QAbstractListModel and QAbstractTableModel classes provide support + for interfaces to simpler non-hierarchical data structures, and are + easier to use as a starting point for simple list and table models. + + In this section, we create a simple read-only model to explore + the basic principles of the model/view architecture. Later in this + section, we adapt this simple model so that items can be modified + by the user. + + For an example of a more complex model, see the + \l{itemviews/simpletreemodel}{Simple Tree Model} example. + + The requirements of QAbstractItemModel subclasses is described in more + detail in the \l{Model Subclassing Reference} document. + + \section2 Designing a model + + When creating a new model for an existing data structure, it is + important to consider which type of model should be used to + provide an interface onto the data. If the data structure can be + represented as a list or table of items, you can subclass + QAbstractListModel or QAbstractTableModel since these classes + provide suitable default implementations for many functions. + + However, if the underlying data structure can only be represented + by a hierarchical tree structure, it is necessary to subclass + QAbstractItemModel. This approach is taken in the + \l{itemviews/simpletreemodel}{Simple Tree Model} example. + + In this section, we implement a simple model based on a list of + strings, so the QAbstractListModel provides an ideal base class on + which to build. + + Whatever form the underlying data structure takes, it is + usually a good idea to supplement the standard QAbstractItemModel API + in specialized models with one that allows more natural access to the + underlying data structure. This makes it easier to populate the model + with data, yet still enables other general model/view components to + interact with it using the standard API. The model described below + provides a custom constructor for just this purpose. + + \section2 A read-only example model + + The model implemented here is a simple, non-hierarchical, read-only data + model based on the standard QStringListModel class. It has a \l QStringList + as its internal data source, and implements only what is needed to make a + functioning model. To make the implementation easier, we subclass + \l QAbstractListModel because it defines sensible default behavior for list + models, and it exposes a simpler interface than the \l QAbstractItemModel + class. + + When implementing a model it is important to remember that + \l QAbstractItemModel does not store any data itself, it merely + presents an interface that the views use to access the data. + For a minimal read-only model it is only necessary to implement a few + functions as there are default implementations for most of the + interface. The class declaration is as follows: + + \snippet stringlistmodel/model.h 0 + \snippet stringlistmodel/model.h 1 + \codeline + \snippet stringlistmodel/model.h 5 + + Apart from the model's constructor, we only need to implement two + functions: \l{QAbstractItemModel::rowCount()}{rowCount()} returns the + number of rows in the model and \l{QAbstractItemModel::data()}{data()} + returns an item of data corresponding to a specified model index. + + Well behaved models also implement + \l{QAbstractItemModel::headerData()}{headerData()} to give tree and + table views something to display in their headers. + + Note that this is a non-hierarchical model, so we don't have to worry + about the parent-child relationships. If our model was hierarchical, we + would also have to implement the + \l{QAbstractItemModel::index()}{index()} and + \l{QAbstractItemModel::parent()}{parent()} functions. + + The list of strings is stored internally in the \c stringList private + member variable. + + \section3 Dimensions of the model + + We want the number of rows in the model to be the same as the number of + strings in the string list. We implement the + \l{QAbstractItemModel::rowCount()}{rowCount()} function with this in + mind: + + \snippet stringlistmodel/model.cpp 0 + + Since the model is non-hierarchical, we can safely ignore the model index + corresponding to the parent item. By default, models derived from + QAbstractListModel only contain one column, so we do not need to + reimplement the \l{QAbstractItemModel::columnCount()}{columnCount()} + function. + + \section3 Model headers and data + + For items in the view, we want to return the strings in the string list. + The \l{QAbstractItemModel::data()}{data()} function is responsible for + returning the item of data that corresponds to the index argument: + + \snippet stringlistmodel/model.cpp 1-data-read-only + + We only return a valid QVariant if the model index supplied is valid, + the row number is within the range of items in the string list, and the + requested role is one that we support. + + Some views, such as QTreeView and QTableView, are able to display headers + along with the item data. If our model is displayed in a view with headers, + we want the headers to show the row and column numbers. We can provide + information about the headers by subclassing the + \l{QAbstractItemModel::headerData()}{headerData()} function: + + \snippet stringlistmodel/model.cpp 2 + + Again, we return a valid QVariant only if the role is one that we support. + The orientation of the header is also taken into account when deciding the + exact data to return. + + Not all views display headers with the item data, and those that do may + be configured to hide them. Nonetheless, it is recommended that you + implement the \l{QAbstractItemModel::headerData()}{headerData()} function + to provide relevant information about the data provided by the model. + + An item can have several roles, giving out different data depending on the + role specified. The items in our model only have one role, + \l{Qt::ItemDataRole}{DisplayRole}, so we return the data + for items irrespective of the role specified. + However, we could reuse the data we provide for the + \l{Qt::ItemDataRole}{DisplayRole} in + other roles, such as the + \l{Qt::ItemDataRole}{ToolTipRole} that views can use to + display information about items in a tooltip. + + \section2 An editable model + + The read-only model shows how simple choices could be presented to the + user but, for many applications, an editable list model is much more + useful. We can modify the read-only model to make the items editable + by changing the data() function we implemented for read-only, and + by implementing two extra functions: + \l{QAbstractItemModel::flags()}{flags()} and + \l{QAbstractItemModel::setData()}{setData()}. + The following function declarations are added to the class definition: + + \snippet stringlistmodel/model.h 2 + \snippet stringlistmodel/model.h 3 + + \section3 Making the model editable + + A delegate checks whether an item is editable before creating an + editor. The model must let the delegate know that its items are + editable. We do this by returning the correct flags for each item in + the model; in this case, we enable all items and make them both + selectable and editable: + + \snippet stringlistmodel/model.cpp 3 + + Note that we do not have to know how the delegate performs the actual + editing process. We only have to provide a way for the delegate to set the + data in the model. This is achieved through the + \l{QAbstractItemModel::setData()}{setData()} function: + + \snippet stringlistmodel/model.cpp 4 + \snippet stringlistmodel/model.cpp 5 + + In this model, the item in the string list that corresponds to the + model index is replaced by the value provided. However, before we + can modify the string list, we must make sure that the index is + valid, the item is of the correct type, and that the role is + supported. By convention, we insist that the role is the + \l{Qt::ItemDataRole}{EditRole} since this is the role used by the + standard item delegate. For boolean values, however, you can use + Qt::CheckStateRole and set the Qt::ItemIsUserCheckable flag; a + checkbox is then used for editing the value. The underlying + data in this model is the same for all roles, so this detail just + makes it easier to integrate the model with standard components. + + When the data has been set, the model must let the views know that some + data has changed. This is done by emitting the + \l{QAbstractItemModel::dataChanged()}{dataChanged()} signal. Since only + one item of data has changed, the range of items specified in the signal + is limited to just one model index. + + Also the data() function needs to be changed to add the Qt::EditRole test: + + \snippet stringlistmodel/model.cpp 1 + + \section3 Inserting and removing rows + + It is possible to change the number of rows and columns in a model. In the + string list model it only makes sense to change the number of rows, so we + only reimplement the functions for inserting and removing rows. These are + declared in the class definition: + + \snippet stringlistmodel/model.h 4 + + Since rows in this model correspond to strings in a list, the + \c insertRows() function inserts a number of empty strings into the string + list before the specified position. The number of strings inserted is + equivalent to the number of rows specified. + + The parent index is normally used to determine where in the model the + rows should be added. In this case, we only have a single top-level list + of strings, so we just insert empty strings into that list. + + \snippet stringlistmodel/model.cpp 6 + \snippet stringlistmodel/model.cpp 7 + + The model first calls the + \l{QAbstractItemModel::beginInsertRows()}{beginInsertRows()} function to + inform other components that the number of rows is about to change. The + function specifies the row numbers of the first and last new rows to be + inserted, and the model index for their parent item. After changing the + string list, it calls + \l{QAbstractItemModel::endInsertRows()}{endInsertRows()} to complete the + operation and inform other components that the dimensions of the model + have changed, returning true to indicate success. + + The function to remove rows from the model is also simple to write. + The rows to be removed from the model are specified by the position and + the number of rows given. + We ignore the parent index to simplify our implementation, and just + remove the corresponding items from the string list. + + \snippet stringlistmodel/model.cpp 8 + \snippet stringlistmodel/model.cpp 9 + + The \l{QAbstractItemModel::beginRemoveRows()}{beginRemoveRows()} function + is always called before any underlying data is removed, and specifies the + first and last rows to be removed. This allows other components to access + the data before it becomes unavailable. + After the rows have been removed, the model emits + \l{QAbstractItemModel::endRemoveRows()}{endRemoveRows()} to finish the + operation and let other components know that the dimensions of the model + have changed. + + \section2 Next steps + + We can display the data provided by this model, or any other model, using + the \l QListView class to present the model's items in the form of a vertical + list. + For the string list model, this view also provides a default editor so that + the items can be manipulated. We examine the possibilities made available by + the standard view classes in \l{View Classes}. + + The \l{Model Subclassing Reference} document discusses the requirements of + QAbstractItemModel subclasses in more detail, and provides a guide to the + virtual functions that must be implemented to enable various features in + different types of models. + + \section1 Item view convenience classes + + Qt 4 also introduced some standard widgets to provide classic + item-based container widgets. These behave in a similar way to the + item view classes in Qt 3, but have been rewritten to use the + underlying model/view framework for performance and + maintainability. The old item view classes are still available in + the compatibility library (see the \l{porting4.html}{Porting + Guide} for more information). + + The item-based widgets have been given names which reflect their uses: + \c QListWidget provides a list of items, \c QTreeWidget displays a + multi-level tree structure, and \c QTableWidget provides a table of cell + items. Each class inherits the behavior of the \c QAbstractItemView + class which implements common behavior for item selection and header + management. + + \section2 List widgets + + Single level lists of items are typically displayed using a \c QListWidget + and a number of \c{QListWidgetItem}s. A list widget is constructed in the + same way as any other widget: + + \snippet qlistwidget-using/mainwindow.cpp 0 + + List items can be added directly to the list widget when they are + constructed: + + \snippet qlistwidget-using/mainwindow.cpp 3 + + They can also be constructed without a parent list widget and added to + a list at some later time: + + \snippet qlistwidget-using/mainwindow.cpp 6 + \snippet qlistwidget-using/mainwindow.cpp 7 + + Each item in a list can display a text label and an icon. The colors + and font used to render the text can be changed to provide a customized + appearance for items. Tooltips, status tips, and "What's + This?" help are all easily configured to ensure that the list is properly + integrated into the application. + + \snippet qlistwidget-using/mainwindow.cpp 8 + + By default, items in a list are presented in the order of their creation. + Lists of items can be sorted according to the criteria given in + \l{Qt::SortOrder} to produce a list of items that is sorted in forward or + reverse alphabetical order: + + \snippet qlistwidget-using/mainwindow.cpp 4 + \snippet qlistwidget-using/mainwindow.cpp 5 + + \section2 Tree widgets + + Trees or hierarchical lists of items are provided by the \c QTreeWidget + and \c QTreeWidgetItem classes. Each item in the tree widget can have + child items of its own, and can display a number of columns of + information. Tree widgets are created just like any other widget: + + \snippet qtreewidget-using/mainwindow.cpp 0 + + Before items can be added to the tree widget, the number of columns must + be set. For example, we could define two columns, and create a header + to provide labels at the top of each column: + + \snippet qtreewidget-using/mainwindow.cpp 1 + \snippet qtreewidget-using/mainwindow.cpp 2 + + The easiest way to set up the labels for each section is to supply a string + list. For more sophisticated headers, you can construct a tree item, + decorate it as you wish, and use that as the tree widget's header. + + Top-level items in the tree widget are constructed with the tree widget as + their parent widget. They can be inserted in an arbitrary order, or you + can ensure that they are listed in a particular order by specifying the + previous item when constructing each item: + + \snippet qtreewidget-using/mainwindow.cpp 3 + \codeline + \snippet qtreewidget-using/mainwindow.cpp 4 + + Tree widgets deal with top-level items slightly differently to other + items from deeper within the tree. Items can be removed from the top + level of the tree by calling the tree widget's + \l{QTreeWidget::takeTopLevelItem()}{takeTopLevelItem()} function, but + items from lower levels are removed by calling their parent item's + \l{QTreeWidgetItem::takeChild()}{takeChild()} function. + Items are inserted in the top level of the tree with the + \l{QTreeWidget::insertTopLevelItem()}{insertTopLevelItem()} function. + At lower levels in the tree, the parent item's + \l{QTreeWidgetItem::insertChild()}{insertChild()} function is used. + + It is easy to move items around between the top level and lower levels + in the tree. We just need to check whether the items are top-level items + or not, and this information is supplied by each item's \c parent() + function. For example, we can remove the current item in the tree widget + regardless of its location: + + \snippet qtreewidget-using/mainwindow.cpp 10 + \snippet qtreewidget-using/mainwindow.cpp 11 + + Inserting the item somewhere else in the tree widget follows the same + pattern: + + \snippet qtreewidget-using/mainwindow.cpp 8 + \snippet qtreewidget-using/mainwindow.cpp 9 + + \section2 Table widgets + + Tables of items similar to those found in spreadsheet applications + are constructed with the \c QTableWidget and \c QTableWidgetItem. These + provide a scrolling table widget with headers and items to use within it. + + Tables can be created with a set number of rows and columns, or these + can be added to an unsized table as they are needed. + + \snippet qtablewidget-using/mainwindow.h 0 + \snippet qtablewidget-using/mainwindow.cpp 0 + + Items are constructed outside the table before being added to the table + at the required location: + + \snippet qtablewidget-using/mainwindow.cpp 3 + + Horizontal and vertical headers can be added to the table by constructing + items outside the table and using them as headers: + + \snippet qtablewidget-using/mainwindow.cpp 1 + + Note that the rows and columns in the table begin at zero. + + \section2 Common features + + There are a number of item-based features common to each of the + convenience classes that are available through the same interfaces + in each class. We present these in the following sections with some + examples for different widgets. + Look at the list of \l{Model/View Classes} for each of the widgets + for more details about the use of each function used. + + \section3 Hidden items + + It is sometimes useful to be able to hide items in an item view widget + rather than remove them. Items for all of the above widgets can be + hidden and later shown again. You can determine whether an item is hidden + by calling the isItemHidden() function, and items can be hidden with + \c setItemHidden(). + + Since this operation is item-based, the same function is available for + all three convenience classes. + + \section3 Selections + + The way items are selected is controlled by the widget's selection mode + (\l{QAbstractItemView::SelectionMode}). + This property controls whether the user can select one or many items and, + in many-item selections, whether the selection must be a continuous range + of items. The selection mode works in the same way for all of the + above widgets. + + \table + \row + \li \image selection-single.png + \li \b{Single item selections:} + Where the user needs to choose a single item from a widget, the + default \c SingleSelection mode is most suitable. In this mode, the + current item and the selected item are the same. + + \row + \li \image selection-multi.png + \li \b{Multi-item selections:} + In this mode, the user can toggle the selection state of any item in the + widget without changing the existing selection, much like the way + non-exclusive checkboxes can be toggled independently. + + \row + \li \image selection-extended.png + \li \b{Extended selections:} + Widgets that often require many adjacent items to be selected, such + as those found in spreadsheets, require the \c ExtendedSelection mode. + In this mode, continuous ranges of items in the widget can be selected + with both the mouse and the keyboard. + Complex selections, involving many items that are not adjacent to other + selected items in the widget, can also be created if modifier keys are + used. + + If the user selects an item without using a modifier key, the existing + selection is cleared. + \endtable + + The selected items in a widget are read using the \c selectedItems() + function, providing a list of relevant items that can be iterated over. + For example, we can find the sum of all the numeric values within a + list of selected items with the following code: + + \snippet qtablewidget-using/mainwindow.cpp 4 + + Note that for the single selection mode, the current item will be in + the selection. In the multi-selection and extended selection modes, the + current item may not lie within the selection, depending on the way the + user formed the selection. + + \section3 Searching + + It is often useful to be able to find items within an item view widget, + either as a developer or as a service to present to users. All three + item view convenience classes provide a common \c findItems() function + to make this as consistent and simple as possible. + + Items are searched for by the text that they contain according to + criteria specified by a selection of values from Qt::MatchFlags. + We can obtain a list of matching items with the \c findItems() + function: + + \snippet qtreewidget-using/mainwindow.cpp 6 + \snippet qtreewidget-using/mainwindow.cpp 7 + + The above code causes items in a tree widget to be selected if they + contain the text given in the search string. This pattern can also be + used in the list and table widgets. + + \section1 Using Drag and Drop with Item Views + + Qt's drag and drop infrastructure is fully supported by the model/view framework. + Items in lists, tables, and trees can be dragged within the views, and data can be + imported and exported as MIME-encoded data. + + The standard views automatically support internal drag and drop, where items are + moved around to change the order in which they are displayed. By default, drag and + drop is not enabled for these views because they are configured for the simplest, + most common uses. To allow items to be dragged around, certain properties of the + view need to be enabled, and the items themselves must also allow dragging to occur. + + The requirements for a model that only allows items to be exported from a + view, and which does not allow data to be dropped into it, are fewer than + those for a fully-enabled drag and drop model. + + See also the \l{Model Subclassing Reference} for more information about + enabling drag and drop support in new models. + + \section2 Using convenience views + + Each of the types of item used with QListWidget, QTableWidget, and QTreeWidget + is configured to use a different set of flags by default. For example, each + QListWidgetItem or QTreeWidgetItem is initially enabled, checkable, selectable, + and can be used as the source of a drag and drop operation; each QTableWidgetItem + can also be edited and used as the target of a drag and drop operation. + + Although all of the standard items have one or both flags set for drag and drop, + you generally need to set various properties in the view itself to take advantage + of the built-in support for drag and drop: + + \list + \li To enable item dragging, set the view's + \l{QAbstractItemView::dragEnabled}{dragEnabled} property to \c true. + \li To allow the user to drop either internal or external items within the view, + set the view's \l{QAbstractScrollArea::}{viewport()}'s + \l{QWidget::acceptDrops}{acceptDrops} property to \c true. + \li To show the user where the item currently being dragged will be placed if + dropped, set the view's \l{QAbstractItemView::showDropIndicator}{showDropIndicator} + property. This provides the user with continuously updating information about + item placement within the view. + \endlist + + For example, we can enable drag and drop in a list widget with the following lines + of code: + + \snippet qlistwidget-dnd/mainwindow.cpp 0 + + The result is a list widget which allows the items to be copied + around within the view, and even lets the user drag items between + views containing the same type of data. In both situations, the + items are copied rather than moved. + + To enable the user to move the items around within the view, we + must set the list widget's \l {QAbstractItemView::}{dragDropMode}: + + \snippet qlistwidget-dnd/mainwindow.cpp 1 + + \section2 Using model/view classes + + Setting up a view for drag and drop follows the same pattern used with the + convenience views. For example, a QListView can be set up in the same way as a + QListWidget: + + \snippet qlistview-dnd/mainwindow.cpp 0 + + Since access to the data displayed by the view is controlled by a model, the + model used also has to provide support for drag and drop operations. The + actions supported by a model can be specified by reimplementing the + QAbstractItemModel::supportedDropActions() function. For example, copy and + move operations are enabled with the following code: + + \snippet qlistview-dnd/model.cpp 10 + + Although any combination of values from Qt::DropActions can be given, the + model needs to be written to support them. For example, to allow Qt::MoveAction + to be used properly with a list model, the model must provide an implementation + of QAbstractItemModel::removeRows(), either directly or by inheriting the + implementation from its base class. + + \section3 Enabling drag and drop for items + + Models indicate to views which items can be dragged, and which will accept drops, + by reimplementing the QAbstractItemModel::flags() function to provide suitable + flags. + + For example, a model which provides a simple list based on QAbstractListModel + can enable drag and drop for each of the items by ensuring that the flags + returned contain the \l Qt::ItemIsDragEnabled and \l Qt::ItemIsDropEnabled + values: + + \snippet qlistview-dnd/model.cpp 7 + + Note that items can be dropped into the top level of the model, but dragging is + only enabled for valid items. + + In the above code, since the model is derived from QStringListModel, we + obtain a default set of flags by calling its implementation of the flags() + function. + + \section3 Encoding exported data + + When items of data are exported from a model in a drag and drop operation, they + are encoded into an appropriate format corresponding to one or more MIME types. + Models declare the MIME types that they can use to supply items by reimplementing + the QAbstractItemModel::mimeTypes() function, returning a list of standard MIME + types. + + For example, a model that only provides plain text would provide the following + implementation: + + \snippet qlistview-dnd/model.cpp 9 + + The model must also provide code to encode data in the advertised format. This + is achieved by reimplementing the QAbstractItemModel::mimeData() function to + provide a QMimeData object, just as in any other drag and drop operation. + + The following code shows how each item of data, corresponding to a given list of + indexes, is encoded as plain text and stored in a QMimeData object. + + \snippet qlistview-dnd/model.cpp 8 + + Since a list of model indexes is supplied to the function, this approach is general + enough to be used in both hierarchical and non-heirarchical models. + + Note that custom datatypes must be declared as \l{QMetaObject}{meta objects} + and that stream operators must be implemented for them. See the QMetaObject + class description for details. + + \section3 Inserting dropped data into a model + + The way that any given model handles dropped data depends on both its type + (list, table, or tree) and the way its contents is likely to be presented to + the user. Generally, the approach taken to accommodate dropped data should + be the one that most suits the model's underlying data store. + + Different types of model tend to handle dropped data in different ways. List + and table models only provide a flat structure in which items of data are + stored. As a result, they may insert new rows (and columns) when data is + dropped on an existing item in a view, or they may overwrite the item's + contents in the model using some of the data supplied. Tree models are + often able to add child items containing new data to their underlying data + stores, and will therefore behave more predictably as far as the user + is concerned. + + Dropped data is handled by a model's reimplementation of + QAbstractItemModel::dropMimeData(). For example, a model that handles a + simple list of strings can provide an implementation that handles data + dropped onto existing items separately to data dropped into the top level + of the model (i.e., onto an invalid item). + + The model first has to make sure that the operation should be acted on, + the data supplied is in a format that can be used, and that its destination + within the model is valid: + + \snippet qlistview-dnd/model.cpp 0 + \snippet qlistview-dnd/model.cpp 1 + + A simple one column string list model can indicate failure if the data + supplied is not plain text, or if the column number given for the drop + is invalid. + + The data to be inserted into the model is treated differently depending on + whether it is dropped onto an existing item or not. In this simple example, + we want to allow drops between existing items, before the first item in the + list, and after the last item. + + When a drop occurs, the model index corresponding to the parent item will + either be valid, indicating that the drop occurred on an item, or it will + be invalid, indicating that the drop occurred somewhere in the view that + corresponds to top level of the model. + + \snippet qlistview-dnd/model.cpp 2 + + We initially examine the row number supplied to see if we can use it + to insert items into the model, regardless of whether the parent index is + valid or not. + + \snippet qlistview-dnd/model.cpp 3 + + If the parent model index is valid, the drop occurred on an item. In this + simple list model, we find out the row number of the item and use that + value to insert dropped items into the top level of the model. + + \snippet qlistview-dnd/model.cpp 4 + + When a drop occurs elsewhere in the view, and the row number is unusable, + we append items to the top level of the model. + + In hierarchical models, when a drop occurs on an item, it would be better to + insert new items into the model as children of that item. In the simple + example shown here, the model only has one level, so this approach is not + appropriate. + + \section3 Decoding imported data + + Each implementation of \l{QAbstractItemModel::dropMimeData()}{dropMimeData()} must + also decode the data and insert it into the model's underlying data structure. + + For a simple string list model, the encoded items can be decoded and streamed + into a QStringList: + + \snippet qlistview-dnd/model.cpp 5 + + The strings can then be inserted into the underlying data store. For consistency, + this can be done through the model's own interface: + + \snippet qlistview-dnd/model.cpp 6 + + Note that the model will typically need to provide implementations of the + QAbstractItemModel::insertRows() and QAbstractItemModel::setData() functions. + + \sa {Item Views Puzzle Example} + + \section1 Proxy models + + In the model/view framework, items of data supplied by a single model can be shared + by any number of views, and each of these can possibly represent the same information + in completely different ways. + Custom views and delegates are effective ways to provide radically different + representations of the same data. However, applications often need to provide + conventional views onto processed versions of the same data, such as differently-sorted + views onto a list of items. + + Although it seems appropriate to perform sorting and filtering operations as internal + functions of views, this approach does not allow multiple views to share the results + of such potentially costly operations. The alternative approach, involving sorting + within the model itself, leads to the similar problem where each view has to display + items of data that are organized according to the most recent processing operation. + + To solve this problem, the model/view framework uses proxy models to manage the + information supplied between individual models and views. Proxy models are components + that behave like ordinary models from the perspective of a view, and access data from + source models on behalf of that view. The signals and slots used by the model/view + framework ensure that each view is updated appropriately no matter how many proxy models + are placed between itself and the source model. + + \section2 Using proxy models + + Proxy models can be inserted between an existing model and any number of views. + Qt is supplied with a standard proxy model, QSortFilterProxyModel, that is usually + instantiated and used directly, but can also be subclassed to provide custom filtering + and sorting behavior. The QSortFilterProxyModel class can be used in the following way: + + \snippet qsortfilterproxymodel/main.cpp 0 + \codeline + \snippet qsortfilterproxymodel/main.cpp 1 + + Since proxy models are inherit from QAbstractItemModel, they can be connected to + any kind of view, and can be shared between views. They can also be used to + process the information obtained from other proxy models in a pipeline arrangement. + + The QSortFilterProxyModel class is designed to be instantiated and used directly + in applications. More specialized proxy models can be created by subclassing this + classes and implementing the required comparison operations. + + \section2 Customizing proxy models + + Generally, the type of processing used in a proxy model involves mapping each item of + data from its original location in the source model to either a different location in + the proxy model. In some models, some items may have no corresponding location in the + proxy model; these models are \e filtering proxy models. Views access items using + model indexes provided by the proxy model, and these contain no information about the + source model or the locations of the original items in that model. + + QSortFilterProxyModel enables data from a source model to be filtered before + being supplied to views, and also allows the contents of a source model to + be supplied to views as pre-sorted data. + + \section3 Custom filtering models + + The QSortFilterProxyModel class provides a filtering model that is fairly versatile, + and which can be used in a variety of common situations. For advanced users, + QSortFilterProxyModel can be subclassed, providing a mechanism that enables custom + filters to be implemented. + + Subclasses of QSortFilterProxyModel can reimplement two virtual functions that are + called whenever a model index from the proxy model is requested or used: + + \list + \li \l{QSortFilterProxyModel::filterAcceptsColumn()}{filterAcceptsColumn()} is used to + filter specific columns from part of the source model. + \li \l{QSortFilterProxyModel::filterAcceptsRow()}{filterAcceptsRow()} is used to filter + specific rows from part of the source model. + \endlist + + The default implementations of the above functions in QSortFilterProxyModel + return true to ensure that all items are passed through to views; reimplementations + of these functions should return false to filter out individual rows and columns. + + \section3 Custom sorting models + + QSortFilterProxyModel instances use Qt's built-in qStableSort() function to set up + mappings between items in the source model and those in the proxy model, allowing a + sorted hierarchy of items to be exposed to views without modifying the structure of the + source model. To provide custom sorting behavior, reimplement the + \l{QSortFilterProxyModel::lessThan()}{lessThan()} function to perform custom + comparisons. + + \section1 Model subclassing reference + + Model subclasses need to provide implementations of many of the virtual functions + defined in the QAbstractItemModel base class. The number of these functions that need + to be implemented depends on the type of model - whether it supplies views with + a simple list, a table, or a complex hierarchy of items. Models that inherit from + QAbstractListModel and QAbstractTableModel can take advantage of the default + implementations of functions provided by those classes. Models that expose items + of data in tree-like structures must provide implementations for many of the + virtual functions in QAbstractItemModel. + + The functions that need to be implemented in a model subclass can be divided into three + groups: + + \list + \li \b{Item data handling:} All models need to implement functions to enable views and + delegates to query the dimensions of the model, examine items, and retrieve data. + \li \b{Navigation and index creation:} Hierarchical models need to provide functions + that views can call to navigate the tree-like structures they expose, and obtain + model indexes for items. + \li \b{Drag and drop support and MIME type handling:} Models inherit functions that + control the way that internal and external drag and drop operations are performed. + These functions allow items of data to be described in terms of MIME types that + other components and applications can understand. + \endlist + + For more information, see the \l + {"Item View Classes" Chapter of C++ GUI Programming with Qt 4}. + + \section2 Item data handling + + Models can provide varying levels of access to the data they provide: They can be + simple read-only components, some models may support resizing operations, and + others may allow items to be edited. + + \section2 Read-Only access + + To provide read-only access to data provided by a model, the following functions + \e{must} be implemented in the model's subclass: + + \table 90% + \row \li \l{QAbstractItemModel::flags()}{flags()} + \li Used by other components to obtain information about each item provided by + the model. In many models, the combination of flags should include + Qt::ItemIsEnabled and Qt::ItemIsSelectable. + \row \li \l{QAbstractItemModel::data()}{data()} + \li Used to supply item data to views and delegates. Generally, models only + need to supply data for Qt::DisplayRole and any application-specific user + roles, but it is also good practice to provide data for Qt::ToolTipRole, + Qt::AccessibleTextRole, and Qt::AccessibleDescriptionRole. + See the Qt::ItemDataRole enum documentation for information about the types + associated with each role. + \row \li \l{QAbstractItemModel::headerData()}{headerData()} + \li Provides views with information to show in their headers. The information is + only retrieved by views that can display header information. + \row \li \l{QAbstractItemModel::rowCount()}{rowCount()} + \li Provides the number of rows of data exposed by the model. + \endtable + + These four functions must be implemented in all types of model, including list models + (QAbstractListModel subclasses) and table models (QAbstractTableModel subclasses). + + Additionally, the following functions \e{must} be implemented in direct subclasses + of QAbstractTableModel and QAbstractItemModel: + + \table 90% + \row \li \l{QAbstractItemModel::columnCount()}{columnCount()} + \li Provides the number of columns of data exposed by the model. List models do not + provide this function because it is already implemented in QAbstractListModel. + \endtable + + \section3 Editable items + + Editable models allow items of data to be modified, and may also provide + functions to allow rows and columns to be inserted and removed. To enable + editing, the following functions must be implemented correctly: + + \table 90% + \row \li \l{QAbstractItemModel::flags()}{flags()} + \li Must return an appropriate combination of flags for each item. In particular, + the value returned by this function must include \l{Qt::ItemIsEditable} in + addition to the values applied to items in a read-only model. + \row \li \l{QAbstractItemModel::setData()}{setData()} + \li Used to modify the item of data associated with a specified model index. + To be able to accept user input, provided by user interface elements, this + function must handle data associated with Qt::EditRole. + The implementation may also accept data associated with many different kinds + of roles specified by Qt::ItemDataRole. After changing the item of data, + models must emit the \l{QAbstractItemModel::dataChanged()}{dataChanged()} + signal to inform other components of the change. + \row \li \l{QAbstractItemModel::setHeaderData()}{setHeaderData()} + \li Used to modify horizontal and vertical header information. After changing + the item of data, models must emit the + \l{QAbstractItemModel::headerDataChanged()}{headerDataChanged()} + signal to inform other components of the change. + \endtable + + \section3 Resizable models + + All types of model can support the insertion and removal of rows. Table models + and hierarchical models can also support the insertion and removal of columns. + It is important to notify other components about changes to the model's dimensions + both \e before and \e after they occur. As a result, the following functions + can be implemented to allow the model to be resized, but implementations must + ensure that the appropriate functions are called to notify attached views and + delegates: + + \table 90% + \row \li \l{QAbstractItemModel::insertRows()}{insertRows()} + \li Used to add new rows and items of data to all types of model. + Implementations must call + \l{QAbstractItemModel::beginInsertRows()}{beginInsertRows()} \e before + inserting new rows into any underlying data structures, and call + \l{QAbstractItemModel::endInsertRows()}{endInsertRows()} + \e{immediately afterwards}. + \row \li \l{QAbstractItemModel::removeRows()}{removeRows()} + \li Used to remove rows and the items of data they contain from all types of model. + Implementations must call + \l{QAbstractItemModel::beginRemoveRows()}{beginRemoveRows()} + \e before inserting new columns into any underlying data structures, and call + \l{QAbstractItemModel::endRemoveRows()}{endRemoveRows()} + \e{immediately afterwards}. + \row \li \l{QAbstractItemModel::insertColumns()}{insertColumns()} + \li Used to add new columns and items of data to table models and hierarchical models. + Implementations must call + \l{QAbstractItemModel::beginInsertColumns()}{beginInsertColumns()} \e before + rows are removed from any underlying data structures, and call + \l{QAbstractItemModel::endInsertColumns()}{endInsertColumns()} + \e{immediately afterwards}. + \row \li \l{QAbstractItemModel::removeColumns()}{removeColumns()} + \li Used to remove columns and the items of data they contain from table models and + hierarchical models. + Implementations must call + \l{QAbstractItemModel::beginRemoveColumns()}{beginRemoveColumns()} + \e before columns are removed from any underlying data structures, and call + \l{QAbstractItemModel::endRemoveColumns()}{endRemoveColumns()} + \e{immediately afterwards}. + \endtable + + Generally, these functions should return true if the operation was successful. + However, there may be cases where the operation only partly succeeded; for example, + if less than the specified number of rows could be inserted. In such cases, the + model should return false to indicate failure to enable any attached components to + handle the situation. + + The signals emitted by the functions called in implementations of the resizing + API give attached components the chance to take action before any data becomes + unavailable. The encapsulation of insert and remove operations with begin and end + functions also enable the model to manage + \l{QPersistentModelIndex}{persistent model indexes} correctly. + + Normally, the begin and end functions are capable of informing other components + about changes to the model's underlying structure. For more complex changes to the + model's structure, perhaps involving internal reorganization or sorting of data, + it is necessary to emit the \l{QAbstractItemModel::layoutChanged()}{layoutChanged()} + signal to cause any attached views to be updated. + + \section3 Lazy population of model data + + Lazy population of model data effectively allows requests for information + about the model to be deferred until it is actually needed by views. + + Some models need to obtain data from remote sources, or must perform + time-consuming operations to obtain information about the way the + data is organized. Since views generally request as much information + as possible in order to accurately display model data, it can be useful + to restrict the amount of information returned to them to reduce + unnecessary follow-up requests for data. + + In hierarchical models where finding the number of children of a given + item is an expensive operation, it is useful to ensure that the model's + \l{QAbstractItemModel::}{rowCount()} implementation is only called when + necessary. In such cases, the \l{QAbstractItemModel::}{hasChildren()} + function can be reimplemented to provide an inexpensive way for views to + check for the presence of children and, in the case of QTreeView, draw + the appropriate decoration for their parent item. + + Whether the reimplementation of \l{QAbstractItemModel::}{hasChildren()} + returns \c true or \c false, it may not be necessary for the view to call + \l{QAbstractItemModel::}{rowCount()} to find out how many children are + present. For example, QTreeView does not need to know how many children + there are if the parent item has not been expanded to show them. + + If it is known that many items will have children, reimplementing + \l{QAbstractItemModel::}{hasChildren()} to unconditionally return \c true + is sometimes a useful approach to take. This ensures that each item can + be later examined for children while making initial population of model + data as fast as possible. The only disadvantage is that items without + children may be displayed incorrectly in some views until the user + attempts to view the non-existent child items. + + \section2 Navigation and model index creation + + Hierarchical models need to provide functions that views can call to navigate the + tree-like structures they expose, and obtain model indexes for items. + + \section3 Parents and children + + Since the structure exposed to views is determined by the underlying data + structure, it is up to each model subclass to create its own model indexes + by providing implementations of the following functions: + + \table 90% + \row \li \l{QAbstractItemModel::index()}{index()} + \li Given a model index for a parent item, this function allows views and delegates + to access children of that item. If no valid child item - corresponding to the + specified row, column, and parent model index, can be found, the function + must return QModelIndex(), which is an invalid model index. + \row \li \l{QAbstractItemModel::parent()}{parent()} + \li Provides a model index corresponding to the parent of any given child item. + If the model index specified corresponds to a top-level item in the model, or if + there is no valid parent item in the model, the function must return + an invalid model index, created with the empty QModelIndex() constructor. + \endtable + + Both functions above use the \l{QAbstractItemModel::createIndex()}{createIndex()} + factory function to generate indexes for other components to use. It is normal for + models to supply some unique identifier to this function to ensure that + the model index can be re-associated with its corresponding item later on. + + \section2 Drag and drop support and MIME type handling + + The model/view classes support drag and drop operations, providing default behavior + that is sufficient for many applications. However, it is also possible to customize + the way items are encoded during drag and drop operations, whether they are copied + or moved by default, and how they are inserted into existing models. + + Additionally, the convenience view classes implement specialized behavior that + should closely follow that expected by existing developers. + The \l{#Convenience Views}{Convenience Views} section provides an overview of this + behavior. + + \section3 MIME data + + By default, the built-in models and views use an internal MIME type + (\c{application/x-qabstractitemmodeldatalist}) to pass around information about + model indexes. This specifies data for a list of items, containing the row and + column numbers of each item, and information about the roles that each item + supports. + + Data encoded using this MIME type can be obtained by calling + QAbstractItemModel::mimeData() with a QModelIndexList containing the items to + be serialized. + \omit + The following types are used to store information about + each item as it is streamed into a QByteArray and stored in a QMimeData object: + + \table 90% + \header \li Description \li Type + \row \li Row \li int + \row \li Column \li int + \row \li Data for each role \li QMap + \endtable + + This information can be retrieved for use in non-model classes by calling + QMimeData::data() with the \c{application/x-qabstractitemmodeldatalist} MIME + type and streaming out the items one by one. + \endomit + + When implementing drag and drop support in a custom model, it is possible to + export items of data in specialized formats by reimplementing the following + function: + + \table 90% + \row \li \l{QAbstractItemModel::mimeData()}{mimeData()} + \li This function can be reimplemented to return data in formats other + than the default \c{application/x-qabstractitemmodeldatalist} internal + MIME type. + + Subclasses can obtain the default QMimeData object from the base class + and add data to it in additional formats. + \endtable + + For many models, it is useful to provide the contents of items in common format + represented by MIME types such as \c{text/plain} and \c{image/png}. Note that + images, colors and HTML documents can easily be added to a QMimeData object with + the QMimeData::setImageData(), QMimeData::setColorData(), and + QMimeData::setHtml() functions. + + \section3 Accepting dropped data + + When a drag and drop operation is performed over a view, the underlying model is + queried to determine which types of operation it supports and the MIME types + it can accept. This information is provided by the + QAbstractItemModel::supportedDropActions() and QAbstractItemModel::mimeTypes() + functions. Models that do not override the implementations provided by + QAbstractItemModel support copy operations and the default internal MIME type + for items. + + When serialized item data is dropped onto a view, the data is inserted into + the current model using its implementation of QAbstractItemModel::dropMimeData(). + The default implementation of this function will never overwrite any data in the + model; instead, it tries to insert the items of data either as siblings of an + item, or as children of that item. + + To take advantage of QAbstractItemModel's default implementation for the built-in + MIME type, new models must provide reimplementations of the following functions: + + \table 90% + \row \li \l{QAbstractItemModel::insertRows()}{insertRows()} + \li {1, 2} These functions enable the model to automatically insert new data using + the existing implementation provided by QAbstractItemModel::dropMimeData(). + \row \li \l{QAbstractItemModel::insertColumns()}{insertColumns()} + \row \li \l{QAbstractItemModel::setData()}{setData()} + \li Allows the new rows and columns to be populated with items. + \row \li \l{QAbstractItemModel::setItemData()}{setItemData()} + \li This function provides more efficient support for populating new items. + \endtable + + To accept other forms of data, these functions must be reimplemented: + + \table 90% + \row \li \l{QAbstractItemModel::supportedDropActions()}{supportedDropActions()} + \li Used to return a combination of \l{Qt::DropActions}{drop actions}, + indicating the types of drag and drop operations that the model accepts. + \row \li \l{QAbstractItemModel::mimeTypes()}{mimeTypes()} + \li Used to return a list of MIME types that can be decoded and handled by + the model. Generally, the MIME types that are supported for input into + the model are the same as those that it can use when encoding data for + use by external components. + \row \li \l{QAbstractItemModel::dropMimeData()}{dropMimeData()} + \li Performs the actual decoding of the data transferred by drag and drop + operations, determines where in the model it will be set, and inserts + new rows and columns where necessary. How this function is implemented + in subclasses depends on the requirements of the data exposed by each + model. + \endtable + + If the implementation of the \l{QAbstractItemModel::dropMimeData()}{dropMimeData()} + function changes the dimensions of a model by inserting or removing rows or + columns, or if items of data are modified, care must be taken to ensure that + all relevant signals are emitted. It can be useful to simply call + reimplementations of other functions in the subclass, such as + \l{QAbstractItemModel::setData()}{setData()}, + \l{QAbstractItemModel::insertRows()}{insertRows()}, and + \l{QAbstractItemModel::insertColumns()}{insertColumns()}, to ensure that the + model behaves consistently. + + In order to ensure drag operations work properly, it is important to + reimplement the following functions that remove data from the model: + + \list + \li \l{QAbstractItemModel::}{removeRows()} + \li \l{QAbstractItemModel::}{removeRow()} + \li \l{QAbstractItemModel::}{removeColumns()} + \li \l{QAbstractItemModel::}{removeColumn()} + \endlist + + For more information about drag and drop with item views, refer to + \l{Using drag and drop with item views}. + + \section3 Convenience views + + The convenience views (QListWidget, QTableWidget, and QTreeWidget) override + the default drag and drop functionality to provide less flexible, but more + natural behavior that is appropriate for many applications. For example, + since it is more common to drop data into cells in a QTableWidget, replacing + the existing contents with the data being transferred, the underlying model + will set the data of the target items rather than insert new rows and columns + into the model. For more information on drag and drop in convenience views, + you can see \l{Using drag and drop with item views}. + + \section2 Performance optimization for large amounts of data + + The \l{QAbstractItemModel::}{canFetchMore()} function checks if the parent + has more data available and returns true or false accordingly. The + \l{QAbstractItemModel::}{fetchMore()} function fetches data based on the + parent specified. Both these functions can be combined, for example, in a + database query involving incremental data to populate a QAbstractItemModel. + We reimplement \l{QAbstractItemModel::}{canFetchMore()} to indicate if there + is more data to be fetched and \l{QAbstractItemModel::}{fetchMore()} to + populate the model as required. + + Another example would be dynamically populated tree models, where we + reimplement \l{QAbstractItemModel::}{fetchMore()} when a branch in the tree + model is expanded. + + If your reimplementation of \l{QAbstractItemModel::}{fetchMore()} adds rows + to the model, you need to call \l{QAbstractItemModel::}{beginInsertRows()} + and \l{QAbstractItemModel::}{endInsertRows()}. Also, both + \l{QAbstractItemModel::}{canFetchMore()} and \l{QAbstractItemModel::} + {fetchMore()} must be reimplemented as their default implementation returns + false and does nothing. + + \keyword Model/View Classes + \section1 The model/view classes + + These classes use the model/view design pattern in which the + underlying data (in the model) is kept separate from the way the + data is presented and manipulated by the user (in the view). + + \annotatedlist model-view + + \section1 Related examples + + \list + \li \l{itemviews/dirview}{Dir View} + \li \l{itemviews/spinboxdelegate}{Spin Box Delegate} + \li \l{itemviews/pixelator}{Pixelator} + \li \l{itemviews/simpletreemodel}{Simple Tree Model} + \li \l{itemviews/chart}{Chart} + \endlist +*/ diff --git a/src/widgets/doc/src/modelview.qdoc b/src/widgets/doc/src/modelview.qdoc new file mode 100644 index 0000000000..97432b4df4 --- /dev/null +++ b/src/widgets/doc/src/modelview.qdoc @@ -0,0 +1,897 @@ +/**************************************************************************** +** +** 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 modelview.html + \ingroup tutorials + \startpage {index.html}{Qt Reference Documentation} + + \title Model/View Tutorial + \brief An introduction to ModelView programming + + Every UI developer should know about ModelView programming and the goal of + this tutorial is to provide you with an easily understandable introduction + to this topic. + + Table, list and tree widgets are components frequently used in GUIs. There + are 2 different ways how these widgets can access their data. The + traditional way involves widgets which include internal containers for + storing data. This approach is very intuitive, however, in many non-trivial + applications, it leads to data synchronization issues. + The second approach is model/view programming, in + which widgets do not maintain internal data containers. They access external + data through a standardized interface and therefore avoid data duplication. + This may seem complicated at first, but once you take a closer look, it is + not only easy to grasp, but the many benefits of model/view programming also + become clearer. + + \image treeview.png + + In the process, we will learn about some basic technologies provided by Qt, + such as: + + \list + \li The difference between standard and model/view widgets + \li Adapters between forms and models + \li Developing a simple model/view application + \li Predefined models + \li Intermediate topics such as: + \list + \li Tree views + \li Selection + \li Delegates + \li Debugging with model test + \endlist + \endlist + + You will also learn whether your new application can be written easier with + model/view programming or if classic widgets will work just as well. + + This tutorial includes example code for you to edit and integrate into your + project. The tutorial's source code is located in Qt's + \c examples/tutorials/modelview directory. + + For more detailed information you may also want to look at the + \l{model-view-programming.html}{reference documentation} + + If you are completely new to Qt, please read \l{How to Learn Qt} if you + have not already done so. + + + \section1 1. Introduction + + Model/View is a technology used to separate data from views in widgets that + handle data sets. Standard widgets are not designed for separating data + from views and this is why Qt 4 has two different types of widgets. Both + types of widgets look the same, but they interact with data differently. + + \table + \row + \li Standard widgets use data that is part of the widget. + \li \image standardwidget.png + \row + \li View classes operate on external data (the model) + \li \image modelview.png + \endtable + + \section2 1.1 Standard Widgets + + Let's have a closer look at a standard table widget. A table widget is a 2D + array of the data elements that the user can change. The table widget can be + integrated into a program flow by reading and writing the data elements that + the table widget provides. + This method is very intuitive and useful in many applications, but displaying + and editing a database table with a standard table widget can be problematic. + Two copies of the data have to be coordinated: one outside the + widget; one inside the widget. The developer is responsible for + synchronizing both versions. Besides this, the tight coupling of presentation and data + makes it harder to write unit tests. + + \section2 1.2 Model/View to the Rescue + + Model/view stepped up to provide a solution that uses a more versatile + architecture. Model/view eliminates the data consistency problems that may + occur with standard widgets. Model/view also makes it easier to use more + than one view of the same data because one model can be passed on to many + views. The most important difference is that model/view widgets do not store + data behind the table cells. In fact, they operate directly from your data. + Since view classes do not know your data's structure, you need to provide a + wrapper to make your data conform to the QAbstractItemModel interface. A + view uses this interface to read from and write to your data. Any instance + of a class that implements QAbstractItemModel is said to be a model. Once + the view receives a pointer to a model, it will read and display its content + and be its editor. + + \section2 1.3 Overview of the Model/View Widgets + + Here is an overview of the model/view widgets and their corresponding + standard widgets. + + \table + \header + \li Widget + \li Standard Widget\br + (an item based convenience class) + \li Model/View View Class\br + (for use with external data) + \row + \li \inlineimage listview.png + \li \l QListWidget + \li \l QListView + \row + \li \inlineimage tableview.png + \li \l QTableWidget + \li \l QTableView + \row + \li \inlineimage treeview.png + \li \l QTreeWidget + \li \l QTreeView + \row + \li \inlineimage columnview.png + \li + \li \l QColumnView shows a tree as a hierarchy of lists + \row + \li \inlineimage modelview-combobox.png + \li {2, 1} \l QComboBox can work as both a view class and also + as a traditional widget + \endtable + + \section2 1.4 Using Adapters between Forms and Models + + Having adapters between forms and models can come in handy. + + We can edit data stored in tables directly from within the table itself, but + it's much more comfortable to edit data in text fields. There is no direct + model/view counterpart that separates data and views for widgets that + operate on one value (QLineEdit, QCheckBox ...) instead of a dataset, so we + need an adapter in order to connect the form to the source of data. + + \l QDataWidgetMapper is a great solution because it maps form widgets to a + table row and makes it very easy to build forms for database tables. + + \image widgetmapper.png + + Another example of an adapter is \l QCompleter. Qt has \l QCompleter for + providing auto-completions in Qt widgets such as \l QComboBox and, as shown + below, \l QLineEdit. \l QCompleter uses a model as its data source. + + \image qcompleter.png + + + \section1 2. A Simple Model/View Application + If you want to develop a model/view application, where should you start? + We recommend starting with a simple example and extending it step-by-step. + This makes understanding the architecture a lot easier. Trying to understand + the model/view architecture in detail before invoking the IDE has proven + to be less convenient for many developers. It is substantially easier to + start with a simple model/view application that has demo data. Give it a + try! Simply replace the data in the examples below with your own. + + Below are 7 very simple and independent applications that show different + sides of model/view programming. The source code can be found inside the + \c{examples/tutorials/modelview} directory. + + \section2 2.1 A Read Only Table + + We start with an application that uses a QTableView to show data. We will + add editing capabilities later. + + (file source: examples/tutorials/modelview/1_readonly/main.cpp) + \snippet tutorials/modelview/1_readonly/main.cpp Quoting ModelView Tutorial + + We have the usual \l {modelview-part2-main-cpp.html}{main()} function: + + Here is the interesting part: We create an instance of MyModel and use + \l{QTableView::setModel()}{tableView.setModel(&myModel);} to pass a + pointer of it to to \l{QTableView}{tableView}. \l{QTableView}{tableView} + will invoke the methods of the pointer it has received to find out two + things: + + \list + \li How many rows and columns should be displayed. + \li What content should be printed into each cell. + \endlist + + The model needs some code to respond to this. + + We have a table data set, so let's start with QAbstractTableModel since it + is easier to use than the more general QAbstractItemModel. + + (file source: examples/tutorials/modelview/1_readonly/mymodel.h) + \snippet tutorials/modelview/1_readonly/mymodel.h Quoting ModelView Tutorial + + QAbstractTableModel requires the implementation of three abstract methods. + + (file source: examples/tutorials/modelview/1_readonly/mymodel.cpp) + \snippet tutorials/modelview/1_readonly/mymodel.cpp Quoting ModelView Tutorial + + The number of rows and columns is provided by + \l{QAbstractItemModel::rowCount()}{MyModel::rowCount()} and + \l{QAbstractItemModel::columnCount()}{MyModel::columnCount()}. When the view + has to know what the cell's text is, it calls the method + \l{QAbstractItemModel::data()}{MyModel::data()}. Row and column information + is specified with parameter \c index and the role is set to + \l{Qt::ItemDataRole}{Qt::DisplayRole}. Other roles are covered in the next + section. In our example, the data that should be displayed is generated. In + a real application, \c MyModel would have a member called \c MyData, which + serves as the target for all reading and writing operations. + + This small example demonstrates the passive nature of a model. The model + does not know when it will be used or which data is needed. It simply + provides data each time the view requests it. + + What happens when the model's data needs to be changed? How does the view + realize that data has changed and needs to be read again? The model has to + emit a signal that indicates what range of cells has changed. This will be + demonstrated in section 2.3. + + \section2 2.2 Extending the Read Only Example with Roles + + In addition to controlling what text the view displays, the model also + controls the text's appearance. When we slightly change the model, we get + the following result: \image readonlytable_role.png + + In fact, nothing except for the \l{QAbstractItemModel::}{data()} method + needs to be changed to set fonts, background colour, alignment and a + checkbox. + Below is the \l{QAbstractItemModel::data()}{data()} method that produces the + result shown above. The difference is that this time we use parameter int + role to return different pieces of information depending on its value. + + (file source: examples/tutorials/modelview/2_formatting/mymodel.cpp) + \snippet tutorials/modelview/2_formatting/mymodel.cpp Quoting ModelView Tutorial + + Each formatting property will be requested from the model with a separate + call to the \l{QAbstractItemModel::data()}{data()} method. The \c role + parameter is used to let the model know which property is being requested: + + \table + \header + \li \l{Qt::ItemDataRole}{enum Qt::ItemDataRole} + \li Meaning + \li Type + \row + \li \l{Qt::ItemDataRole}{}Qt::DisplayRole + \li text + \li QString + \row + \li \l{Qt::ItemDataRole}{Qt::FontRole} + \li font + \li QFont + \row + \li \l{Qt::ItemDataRole}{BackgroundRole} + \li brush for the background of the cell + \li QBrush + \row + \li \l{Qt::ItemDataRole}{Qt::TextAlignmentRole} + \li text alignment + \li \l{Qt::AlignmentFlag}{enum Qt::AlignmentFlag} + \row + \li {1, 3} \l{Qt::ItemDataRole}{Qt::CheckStateRole} + \li {1, 3} suppresses checkboxes with \l{QVariant}{QVariant()}, + + sets checkboxes with \l{Qt::CheckState}{Qt::Checked} + + or \l{Qt::CheckState}{Qt::Unchecked} + \li {1, 3} \l{Qt::ItemDataRole}{enum Qt::ItemDataRole} + \endtable + + Refer to the Qt namespace documentation to learn more about the + \l{Qt::ItemDataRole}{Qt::ItemDataRole} enum's capabilities. + + Now we need to determine how using a separated model impacts the + application's performance, so let's trace how often the view calls the + \l{QAbstractItemModel::}{data()} method. In order to track how often the + view calls the model, we have put a debug statement in the + \l{QAbstractItemModel::}{data()} method, which logs onto the error output + stream. In our small example, \l{QAbstractItemModel::}{data()} will be + called 42 times. + Each time you hover the cursor over the field, + \l{QAbstractItemModel::}{data()} will be called again -- 7 times for + each cell. That's why it is important to make sure that your data is + available when \l{QAbstractItemModel::}{data()} is invoked and expensive + lookup operations are cached. + + \section2 2.3 A Clock inside a Table Cell + + \image clock.png + + We still have a read only table, but this time the content changes every + second because we are showing the current time. + + (file source: examples/tutorials/modelview/3_changingmodel/mymodel.cpp) + \snippet tutorials/modelview/3_changingmodel/mymodel.cpp quoting mymodel_QVariant + + Something is missing to make the clock tick. We need to tell the view every + second that the time has changed and that it needs to be read again. We do + this with a timer. In the constructor, we set its interval to 1 second and + connect its timeout signal. + + (file source: examples/tutorials/modelview/3_changingmodel/mymodel.cpp) + \snippet tutorials/modelview/3_changingmodel/mymodel.cpp quoting mymodel_a + + Here is the corresponding slot: + + (file source: examples/tutorials/modelview/3_changingmodel/mymodel.cpp) + \snippet tutorials/modelview/3_changingmodel/mymodel.cpp quoting mymodel_b + + We ask the view to read the data in the top left cell again by emitting the + \l{QAbstractItemModel::}{dataChanged()} signal. Note that we did not + explicitly connect the \l{QAbstractItemModel::}{dataChanged()} signal to the + view. This happened automatically when we called \l{QTableView::}{setModel()}. + + \section2 2.4 Setting up Headers for Columns and Rows + + Headers can be hidden via a view method: \c{tableView->verticalHeader()->hide();} + \image modelview-header.png + + The header content, however, is set via the model, so we reimplement the + \l{QAbstractItemModel::headerData()}{headerData()} method: + + (file source: examples/tutorials/modelview/4_headers/mymodel.cpp) + \snippet tutorials/modelview/4_headers/mymodel.cpp quoting mymodel_c + + Note that method \l{QAbstractItemModel::headerData()}{headerData()} also has + a parameter role which has the same meaning as in + \l{QAbstractItemModel::data()}{MyModel::data()}. + + \section2 2.5 The Minimal Editing Example + + In this example, we are going to build an application that automatically + populates a window title with content by repeating values entered into table + cells. To be able to access the window title easily we put the QTableView in + a QMainWindow. + + The model decides whether editing capabilities are available. We only have + to modify the model in order for the available editing capabilities to be + enabled. This is done by reimplementing the following virtual methods: + \l{QAbstractItemModel::}{setData()} and \l{QAbstractItemModel::}{flags()}. + + (file source: examples/tutorials/modelview/5_edit/mymodel.h) + \snippet tutorials/modelview/5_edit/mymodel.h Quoting ModelView Tutorial + + We use \c the two-dimensional array QString \c m_gridData to store our data. + This makes \c m_gridData the core of \c MyModel. The rest of \c MyModel acts + like a wrapper and adapts \c m_gridData to the QAbstractItemModel + interface. We have also introduced the \c editCompleted() signal, which + makes it possible to transfer the modified text to the window title. + + (file source: examples/tutorials/modelview/5_edit/mymodel.cpp) + \snippet tutorials/modelview/5_edit/mymodel.cpp quoting mymodel_e + + \l{QAbstractItemModel::setData()}{setData()} will be called each time the + user edits a cell. The \c index parameter tells us which field has been + edited and \c value provides the result of the editing process. The role + will always be set to \l Qt::EditRole because our cells only contain text. + If a checkbox were present and user permissions are set to allow the + checkbox to be selected, calls would also be made with the role set to + \l Qt::CheckStateRole. + + (file source: examples/tutorials/modelview/5_edit/mymodel.cpp) + \snippet tutorials/modelview/5_edit/mymodel.cpp quoting mymodel_f + + Various properties of a cell can be adjusted with + \l{QAbstractItemModel::flags()}{flags()}. + + Returning \l{Qt::ItemFlag}{Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled} + is enough to show an editor that a cell can be selected. + + If editing one cell modifies more data than the data in that particular + cell, the model must emit a \l{QAbstractItemModel::}{dataChanged()} signal + in order for the data that has been changed to be read. + + + \section1 3. Intermediate Topics + + \section2 3.1 TreeView + + You can convert the example above into an application with a tree view. + Simply replace QTableView with QTreeView, which results in a read/write + tree. No changes have to be made to the model. The tree won't have any + hierarchies because there aren't any hierarchies in the model itself. + + \image dummy_tree.png + + QListView, QTableView and QTreeView all use a model abstraction, which is a + merged list, table and tree. This makes it possible to use several different + types of view classes from the same model. + + \image list_table_tree.png + + This is how our example model looks so far: + + \image example_model.png + + We want to present a real tree. We have wrapped our data in the examples + above in order to make a model. This time we use QStandardItemModel, which + is a container for hierarchical data that also implements + QAbstractItemModel. To show a tree, QStandardItemModel must be populated + with \l{QStandardItem}s, which are able to hold all the standard properties + of items like text, fonts, checkboxes or brushes. + + \image tree_2_with_algorithm.png + + (file source: examples/tutorials/modelview/6_treeview/mainwindow.cpp) + \snippet tutorials/modelview/6_treeview/mainwindow.cpp Quoting ModelView Tutorial + + We simply instantiate a QStandardItemModel and add a couple of + \l{QStandardItem}{QStandardItems} to the constructor. We can then make a + hierarchical data structure because a QStandardItem can hold other + \l{QStandardItem}{QStandardItems}. Nodes are collapsed and expanded within + the view. + + \section2 3.2 Working with Selections + + We want to access a selected item's content in order to output it into the + window title together with the hierarchy level. + + \image selection2.png + + So let's create a couple of items: + + (file source: examples/tutorials/modelview/7_selections/mainwindow.cpp) + \snippet tutorials/modelview/7_selections/mainwindow.cpp quoting modelview_a + + Views manage selections within a separate selection model, which can be + retrieved with the \l{QAbstractItemView::}{selectionModel()} method. We + retrieve the selection Model in order to connect a slot to its + \l{QAbstractItemView::}{selectionChanged()} signal. + + (file source: examples/tutorials/modelview/7_selections/mainwindow.cpp) + \snippet tutorials/modelview/7_selections/mainwindow.cpp quoting modelview_b + + We get the model index that corresponds to the selection by calling + \l{QItemSelectionModel::currentIndex()}{treeView->selectionModel()->currentIndex()} + and we get the the field's string by using the model index. Then we just + calculate the item's \c hierarchyLevel. Top level items do not have parents + and the \l{QAbstractItemModel::}{parent()} method will return a default + constructed \l{QModelIndex}{QModelIndex()}. This is why we use the + \l{QAbstractItemModel::}{parent()} method to iterate to the top level while + counting the steps performed during iteration. + + The selection model (as shown above) can be retrieved, but it can also be + set with \l{QAbstractItemView}{QAbstractItemView::setSelectionModel}. This + is how it's possible to have 3 view classes with synchronized selections + because only one instance of a selection model is used. To share a selection + model between 3 views use \l{QAbstractItemView::}{selectionModel()} and + assign the result to the second and third view class with + \l{QAbstractItemView::}{setSelectionModel()}. + + \section2 3.3 Predefined Models + + The typical way to use model/view is to wrap specific data to make it usable + with view classes. Qt, however, also provides predefined models for common + underlying data structures. If one of the available data structures is + suitable for your application, a predefined model can be a good choice. + + \table + \row + \li QStringListModel + \li Stores a list of strings + \row + \li QStandardItemModel + \li Stores arbitrary hierarchical items + \row + \li QFileSystemModel\br + QDirModel + \li Encapsulate the local file system + \row + \li QSqlQueryModel + \li Encapsulate an SQL result set + \row + \li QSqlTableModel + \li Encapsulates an SQL table + \row + \li QSqlRelationalTableModel + \li Encapsulates an SQL table with foreign keys + \row + \li QSortFilterProxyModel + \li Sorts and/or filters another model + + \endtable + + \section2 3.4 Delegates + + In all examples so far, data is presented as text or a checkbox in a cell + and is edited as text or a checkbox. The component that provides these + presentation and editing services is called a \e delegate. We are only just + beginning to work with the delegate because the view uses a default + delegate. But imagine that we want to have a different editor (e.g., a + slider or a drop down list) Or imagine that we want to present data as + graphics. + Let's take a look at an example called \l{Star Delegate Example}{Star + Delegate}, in which stars are used to show a rating: + + \image stardelegate.png + + The view has a \l{QAbstractItemView::}{setItemDelegate()} method that + replaces the default delegate and installs a custom delegate. + A new delegate can be written by creating a class that inherits from + QStyledItemDelegate. In order to write a delegate that displays stars and + has no input capabilities, we only need to override 2 methods. + + \code + class StarDelegate : public QStyledItemDelegate + { + Q_OBJECT + public: + StarDelegate(QWidget *parent = 0); + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + }; + \endcode + + \l{QStyledItemDelegate::}{paint()} draws stars depending on the content of + the underlying data. The data can be looked up by calling + \l{QModelIndex::data()}{index.data()}. The delegate's + \l{QAbstractItemDelegate::}{sizeHint()} method is used to obtain each + star's dimensions, so the the cell will provide enough height and width to + accommodate the stars. + + Writing custom delegates is the right choice if you want to show your data + with a custom graphical representation inside the grid of the view class. If + you want to leave the grid, you would not use a custom delegate but a custom + view class. + + Other references to delegates in Qt Documentation: + + \list + \li \l{Spin Box Delegate Example} + \li \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference} + \li \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference} + \li \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference} + \li \l{QItemDelegate}{QItemDelegate Class Reference} + \endlist + + + \section2 3.5 Debugging with ModelTest + + The passive nature of models provides new challenges for programmers. + Inconsistencies in the model can cause the application to crash. Since the + model is hit by numerous calls from the view, it is hard to find out which + call has crashed the application and which operation has introduced the + problem. + + Qt Labs provides software called + \l{http://labs.qt.nokia.com/page/Projects/Itemview/Modeltest}{ModelTest}, + which checks models while your programming is running. Every time the model + is changed, ModelTest scans the model and reports errors with an assert. + This is especially important for tree models, since their hierarchical + nature leaves many possibilities for subtle inconsistencies. + + Unlike view classes, ModelTest uses out of range indexes to test the model. + This means your application may crash with ModelTest even if it runs + perfectly without it. So you also need to handle all of the indexes that are + out of range when using ModelTest. + + + \section1 4. Good Sources of Additional Information + + \section2 4.1 Books + + Model/View programming is covered quite extensively in the documentation of + Qt but also in several good books. + + \list 1 + \li \b{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield, + \e{Prentice Hall, 2nd edition}, ISBN 0-13-235416-0. Also available in + German: \b{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung}, + \e{Addison-Wesley}, ISBN 3-827327-29-6 + \li \b{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin, + \e{Open Source Press}, ISBN 1-59327-147-6. + Translated from \b{Qt 4, Einführung in die Applikationsentwicklung}, + \e{Open Source Press}, ISBN 3-937514-12-0. + \li \b{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8. + \li \b{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6. + This book covers Model/View programming on more than 150 pages. + \endlist + + More information about these books is available on the + \l{Books about Qt Programming}{Qt Web site}. + + The following list provides an overview of example programs contained in the first three + books listed above. Some of them make very good templates for developing similar + applications. + + \table + \header + \li Example name + \li View class used + \li Model used + \li Aspects covered + \li + \row + \li Team Leaders + \li QListview + \li QStringListModel + \li + \li Book 1, Chapter 10, Figure 10.6 + \row + \li Directory Viewer + \li QTreeView + \li QDirModel + \li + \li Book 1, Chapter 10, Figure 10.7 + \row + \li Color Names + \li QListView + \li QSortFilterProxyModel + applied to QStringListModel + \li + \li Book 1, Chapter 10, Figure 10.8 + \row + \li Currencies + \li QTableView + \li custom model based on + QAbstractTableModel + \li Read only + \li Book 1, Chapter 10, Figure 10.10 + \row + \li Cities + \li QTableView + \li Custom model based on + QAbstractTableModel + \li Read / write + \li Book 1, Chapter 10, Figure 10.12 + \row + \li Boolean Parser + \li QTreeView + \li Custom model based on + QAbstractItemModel + \li Read only + \li Book 1, Chapter 10, Figure 10.14 + \row + \li Track Editor + \li {2, 1} QTableWidget + \li Custom delegate providing a custom editor + \li Book 1, Chapter 10, Figure 10.15 + + \row + \li Four directory views + \li QListView + QTableView + QTreeView + \li QDirModel + \li Demonstrates the use of multiple views + \li Book2, Chapter 8.2 + \row + \li Address Book + \li QListView + QTableView + QTreeView + \li Custom model based on + QAbstractTableModel + \li Read / write + \li Book2, Chapter 8.4 + \row + \li Address Book with sorting + \li + \li QProxyModel + \li Introducing sort and filter capabilities + \li Book2, Chapter 8.5 + \row + \li Address Book + with checkboxes + \li + \li + \li Introducing checkboxes in model/view + \li Book2, Chapter 8.6 + \row + \li Address Book with transposed grid + \li + \li Custom proxy Model based on QAbstractProxyModel + \li Introducing a custom model + \li Book2, Chapter 8.7 + \row + \li Address Book with drag and drop + \li + \li + \li Introducing drag and drop support + \li Book2, Chapter 8.8 + \row + \li Address Book with custom editor + \li + \li + \li Introducing custom delegates + \li Book2, Chapter 8.9 + \row + \li Views + \li QListView + QTableView + QTreeView + \li QStandardItemModel + \li Read only + \li Book 3, Chapter 5, figure 5-3 + \row + \li Bardelegate + \li QTableView + \li + \li Custom delegate for presentation based on QAbstractItemDelegate + \li Book 3, Chapter 5, figure 5-5 + \row + \li Editdelegate + \li QTableView + \li + \li Custom delegate for editing based on QAbstractItemDelegate + \li Book 3, Chapter 5, figure 5-6 + \row + \li Singleitemview + \li Custom view based on QAbstractItemView + \li + \li Custom view + \li Book 3, + Chapter 5, + figure 5-7 + \row + \li listmodel + \li QTableView + \li Custom Model based on QAbstractTableModel + \li Read only + \li Book 3, Chapter 5, Figure 5-8 + \row + \li treemodel + \li QTreeView + \li Custom Model based on QAbstractItemModel + \li Read only + \li Book 3, Chapter 5, Figure 5-10 + \row + \li edit integers + \li QListView + \li Custom Model based on QAbstractListModel + \li Read / write + \li Book 3, Chapter 5, Listing 5-37, Figure 5-11 + \row + \li sorting + \li QTableView + \li QSortFilterProxyModel applied to QStringListModel + \li Demonstrates sorting + \li Book 3, Chapter 5, Figure 5-12 + \endtable + + + \section2 4.2 Qt Documentation + + Qt 5.0 comes with 19 examples for model/view. + The examples can be found on the \l{Item Views Examples} page. + + \table + \header + \li Example name + \li View class used + \li Model used + \li Aspects covered + \row + \li Address Book + \li QTableView + \li QAbstractTableModel + QSortFilterProxyModel + \li Usage of QSortFilterProxyModel to generate different + subsets from one data pool + \row + \li Basic Sort/Filter Model + \li QTreeView + \li QStandardItemModel + QSortFilterProxyModel + \li + \row + \li Chart + \li Custom view + \li QStandardItemModel + \li Designing custom views that cooperate with selection models + \row + \li Color Editor Factory + \li {2, 1} QTableWidget + \li Enhancing the standard delegate with a new custom editor to choose colours + \row + \li Combo Widget Mapper + \li QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox + \li QStandardItemModel + \li Shows how a QComboBox can serve as a view class + \row + \li Custom Sort/Filter Model + \li QTreeView + \li QStandardItemModel + QSortFilterProxyModel + \li Subclass QSortFilterProxyModel for advanced sorting and filtering + \row + \li Dir View + \li QTreeView + \li QDirModel + \li Very small example to demonstrate how to assign a model to a view + \row + \li Editable Tree Model + \li QTreeView + \li Custom tree model + \li Comprehensive example for working with trees, demonstrates + editing cells and tree structure with an underlying custom + model + \row + \li Fetch More + \li QListView + \li Custom list model + \li Dynamically changing model + \row + \li Frozen Column + \li QTableView + \li QStandardItemModel + \li + \row + \li Interview + \li Multiple + \li Custom item model + \li Multiple views + \row + \li Pixelator + \li QTableView + \li Custom table model + \li Implementation of a custom delegate + \row + \li Puzzle + \li QListView + \li Custom list model + \li Model/view with drag and drop + \row + \li Simple DOM Model + \li QTreeView + \li Custom tree model + \li Read only example for a custom tree model + \row + \li Simple Tree Model + \li QTreeView + \li Custom tree model + \li Read only example for a custom tree model + \row + \li Simple Widget Mapper + \li QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox + \li QStandardItemModel + \li Basic QDataWidgetMapper usage + \row + \li Spin Box Delegate + \li QTableView + \li QStandardItemModel + \li Custom delegate that uses a spin box as a cell editor + \row + \li Spreadsheet + \li {2, 1} QTableView + \li Custom delegates + \row + \li Star Delegate + \li {2, 1} QTableWidget + \li Comprehensive custom delegate example. + \endtable + + A \l{Model/View Programming}{reference document} for model/view technology + is also available. +*/ + +/*! + \page modelview-part2-main-cpp.html + \title main.cpp + \quotefile tutorials/modelview/1_readonly/main.cpp +*/ diff --git a/src/widgets/doc/src/widgets-tutorial.qdoc b/src/widgets/doc/src/widgets-tutorial.qdoc new file mode 100644 index 0000000000..37f095d500 --- /dev/null +++ b/src/widgets/doc/src/widgets-tutorial.qdoc @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** 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 widgets-tutorial.html + \ingroup tutorials + \title Widgets Tutorial + \brief This tutorial covers basic usage of widgets and layouts, showing how + they are used to build GUI applications. + + \section1 Introduction + + Widgets are the basic building blocks for graphical user interface + (GUI) applications built with Qt. Each GUI component (e.g. + buttons, labels, text editor) is a \l{QWidget}{widget} that is + placed somewhere within a user interface window, or is displayed + as an independent window. Each type of widge is provided by a + subclass of QWidget, which is itself a subclass of QObject. + + QWidget is not an abstract class. It can be used as a container + for other widgets, and it can be subclassed with minimal effort to + create new, custom widgets. QWidget is often used to create a + window inside which other \l{QWidget}s are placed. + + As with \l{QObject}s, \l{QWidget}s can be created with parent + objects to indicate ownership, ensuring that objects are deleted + when they are no longer used. With widgets, these parent-child + relationships have an additional meaning: Each child widget is + displayed within the screen area occupied by its parent widget. + This means that when you delete a window widget, all the child + widgets it contains are also deleted. + + \section1 Writing a main Function + + Many of the GUI examples provided with Qt follow the pattern of + having a \c{main.cpp} file, which contains the standard code to + initialize the application, plus any number of other source/header + files that contain the application logic and custom GUI components. + + A typical \c main() function in \c{main.cpp} looks like this: + + \snippet widgets-tutorial/template.cpp main.cpp body + + First, a QApplication object is constructed, which can be + configured with arguments passed in from the command line. After + the widgets have been created and shown, QApplication::exec() is + called to start Qt's event loop. Control passes to Qt until this + function returns. Finally, \c{main()} returns the value returned + by QApplication::exec(). + + \section1 Simple widget examples + + Each of theses simple widget examples is written entirely within + the \c main() function. + + \list + \li \l {tutorials/widgets/toplevel} {Creating a window} + + \li \l {tutorials/widgets/childwidget} {Creating child widgets} + + \li \l {tutorials/widgets/windowlayout} {Using layouts} + + \li \l {tutorials/widgets/nestedlayouts} {Nested layouts} + \endlist + + \section1 Real world widget examples + + In these \l{Widget examples} {more advanced examples}, the code + that creates the widgets and layouts is stored in other files. For + example, the GUI for a main window may be created in the + constructor of a QMainWindow subclass. + + \section1 Building The Examples + + If you installed a binary package to get Qt, or if you compiled Qt + yourself, the examples described in this tutorial should already + be built and ready to run. If you wish to modify and recompile + them, follow these steps: + + \list 1 + + \li From a command prompt, enter the directory containing the + example you have modified. + + \li Type \c qmake and press \key{Return}. If this doesn't work, + make sure that the executable is on your path, or enter its + full location. + + \li On Linux/Unix and Mac OS X, type \c make and press + \key{Return}; on Windows with Visual Studio, type \c nmake and + press \key{Return}. + + \endlist + + An executable file is created in the current directory. On + Windows, this file may be located in a \c debug or \c release + subdirectory. You can run this executable to see the example code + at work. +*/ + +/*! + \example tutorials/widgets/toplevel + \title Widgets Tutorial - Creating a Window + + If a widget is created without a parent, it is treated as a window, or + \e{top-level widget}, when it is shown. Since it has no parent object to + ensure that it is deleted when no longer needed, it is up to the + developer to keep track of the top-level widgets in an application. + + In the following example, we use QWidget to create and show a window with + a default size: + + \div {class="qt-code"} + \table + \row + \li \snippet tutorials/widgets/toplevel/main.cpp main program + \li \inlineimage widgets-tutorial-toplevel.png + \endtable + \enddiv + + To create a real GUI, we need to place widgets inside the window. To do + this, we pass a QWidget instance to a widget's constructor, as we will + demonstrate in the next part of this tutorial. + +*/ + +/*! + \example tutorials/widgets/childwidget + \title Widgets Tutorial - Child Widgets + + We can add a child widget to the window created in the previous example by + passing \c window as the parent to its constructor. In this case, we add a + button to the window and place it in a specific location: + + \div {class="qt-code"} + \table + \row + \li \snippet tutorials/widgets/childwidget/main.cpp main program + \li \inlineimage widgets-tutorial-childwidget.png + \endtable + \enddiv + + The button is now a child of the window and will be deleted when the + window is destroyed. Note that hiding or closing the window does not + automatically destroy it. It will be destroyed when the example exits. +*/ + +/*! + \example tutorials/widgets/windowlayout + \title Widgets Tutorial - Using Layouts + + Usually, child widgets are arranged inside a window using layout objects + rather than by specifying positions and sizes explicitly. Here, we + construct a label and line edit widget that we would like to arrange + side-by-side. + + \div {class="qt-code"} + \table + \row + \li \snippet tutorials/widgets/windowlayout/main.cpp main program + \li \inlineimage widgets-tutorial-windowlayout.png + \endtable + \enddiv + + The \c layout object we construct manages the positions and sizes of + widgets supplied to it with the \l{QHBoxLayout::}{addWidget()} function. + The layout itself is supplied to the window itself in the call to + \l{QWidget::}{setLayout()}. Layouts are only visible through the effects + they have on the widgets (and other layouts) they are responsible for + managing. + + In the example above, the ownership of each widget is not immediately + clear. Since we construct the widgets and the layout without parent + objects, we would expect to see an empty window and two separate windows + containing a label and a line edit. However, when we tell the layout to + manage the label and line edit and set the layout on the window, both the + widgets and the layout itself are ''reparented'' to become children of + the window. +*/ + +/*! + \example tutorials/widgets/nestedlayouts + \title Widgets Tutorial - Nested Layouts + + Just as widgets can contain other widgets, layouts can be used to provide + different levels of grouping for widgets. Here, we want to display a + label alongside a line edit at the top of a window, above a table view + showing the results of a query. + + We achieve this by creating two layouts: \c{queryLayout} is a QHBoxLayout + that contains QLabel and QLineEdit widgets placed side-by-side; + \c{mainLayout} is a QVBoxLayout that contains \c{queryLayout} and a + QTableView arranged vertically. + + \div {class="qt-code"} + \table + \row + \li \snippet tutorials/widgets/nestedlayouts/main.cpp first part + \snippet tutorials/widgets/nestedlayouts/main.cpp last part + \li \inlineimage widgets-tutorial-nestedlayouts.png + \endtable + \enddiv + + Note that we call the \c{mainLayout}'s \l{QBoxLayout::}{addLayout()} + function to insert the \c{queryLayout} above the \c{resultView} table. + + We have omitted the code that sets up the model containing the data shown + by the QTableView widget, \c resultView. For completeness, we show this below. + + As well as QHBoxLayout and QVBoxLayout, Qt also provides QGridLayout + and QFormLayout classes to help with more complex user interfaces. + These can be seen if you run \l{Qt Designer}. + + \section1 Setting up the Model + + In the code above, we did not show where the table's data came from + because we wanted to concentrate on the use of layouts. Here, we see + that the model holds a number of items corresponding to rows, each of + which is set up to contain data for two columns. + + \snippet tutorials/widgets/nestedlayouts/main.cpp set up the model + + The use of models and views is covered in the + \l{Item Views Examples} and in the \l{Model/View Programming} overview. +*/ diff --git a/src/widgets/doc/src/windows-and-dialogs/dialogs.qdoc b/src/widgets/doc/src/windows-and-dialogs/dialogs.qdoc new file mode 100644 index 0000000000..e1c6de42b8 --- /dev/null +++ b/src/widgets/doc/src/windows-and-dialogs/dialogs.qdoc @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \group standard-dialogs + \ingroup qt-gui-concepts + \title Standard Dialogs + \brief A list of Qt classes for implementing standard dialogs. +*/ + +/*! + \page dialogs.html + \title Dialog Windows + \ingroup qt-gui-concepts + \brief An overview over dialog windows. + + \previouspage Application Main Window + \contentspage Application Windows and Dialogs + \nextpage Desktop Integration + + Dialogs can be \e{modal}, in which case the user is required to provide + necessary information before work in the main window + can continue, or \e{modeless}. Modeless dialogs do not prevent the user from + interacting with any of the other windows in the application. + + Qt provides a set of ready-made dialogs for file, font, color-selection + and more. + + \annotatedlist standard-dialogs + + Custom dialogs can be easily created by composing regular widgets into + a QDialog. These classes are specifically designed for building custom + dialogs: + + \annotatedlist dialog-classes +*/ diff --git a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc new file mode 100644 index 0000000000..3c175669fb --- /dev/null +++ b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +/*! + \group mainwindow-classes + \title Main Window and Related Classes +*/ + +/*! + \page application-windows.html + \title Window and Dialog Widgets + \brief Windows and Dialogs in Qt. + \ingroup qt-gui-concepts + + A \l{Widgets Tutorial}{widget} that is not embedded in a parent widget is called a window. + (Usually, windows have a frame and a title bar, although it is also possible to create + windows without such decoration using suitable window flags). In Qt, QMainWindow + and the various subclasses of QDialog are the most common window types. + + In applications, windows provide the screen space upon which the user + interface is built. Windows separate applications visually from each other + and usually provide a window decoration that allows the user to resize and + position the applications according to his preferences. Windows are typically + integrated into the desktop environment and to some degree managed by the + window management system that the desktop environment provides. For instance, + selected windows of an application are represented in the task bar. + + \section1 Primary and Secondary Windows + + Any QWidget that has no parent will become a window, and will on most platforms + be listed in the desktop's task bar. This is usually only wanted for one + window in the application, the \e{primary window}. + + In addition, a QWidget that has a parent can become a window by setting the + \l{Qt::WindowType}{Qt::WA_Window} flag. Depending on the window management system + such \e{secondary windows} are usually stacked on top of their respective parent + window, and not have a task bar entry of their own. + + The QMainWindow and the QDialog classes set the Qt::WA_Window flag in their + constructor, as they are designed to be used as windows and provide facilities + that are not wanted for child widgets. + + \section1 Main Windows and Dialogs + + The \l{Application Main Window} provides the framework for building the + application's main user interface, and are created by subclassing QMainWindow. + QMainWindow has its own layout to which you can add a \l{QMenuBar}{menu bar}, + \l{QToolBar}{tool bars}, \l{QDockWidget}{dockable widgets} and a + \l{QStatusBar}{status bar}. The center area can be occupied by any kind of + QWidget. + + \l{Dialog Windows} are used as secondary windows that present the user with + options and choices. Dialogs are created by subclassing QDialog and using + \l{Widgets and Layouts}{widgets and layouts} to implement the user interface. + In addition, Qt provides a number of ready-made standard dialogs that can be + used for standard tasks like file or font selection. + + Both main windows and dialogs can be created with \QD, Qt's visual design tool. + Using \QD is a lot faster than hand-coding, and makes it easy to test different + design ideas. Creating designs visually and reading the code generated by + \l{uic} is a great way to learn Qt! + + \keyword window geometry + \section1 Window Geometry + + QWidget provides several functions that deal with a widget's + geometry. Some of these functions operate on the pure client area + (i.e. the window excluding the window frame), others include the + window frame. The differentiation is done in a way that covers the + most common usage transparently. + + \list + \li \b{Including the window frame:} + \l{QWidget::x()}{x()}, + \l{QWidget::y()}{y()}, + \l{QWidget::frameGeometry()}{frameGeometry()}, + \l{QWidget::pos()}{pos()}, and + \l{QWidget::move()}{move()}. + \li \b{Excluding the window frame:} + \l{QWidget::geometry()}{geometry()}, + \l{QWidget::width()}{width()}, + \l{QWidget::height()}{height()}, + \l{QWidget::rect()}{rect()}, and + \l{QWidget::size()}{size()}. + \endlist + + Note that the distinction only matters for decorated top-level + widgets. For all child widgets, the frame geometry is equal to the + widget's client geometry. + + This diagram shows most of the functions in use: + \img geometry.png Geometry diagram + + \section2 X11 Peculiarities + + On X11, a window does not have a frame until the window manager + decorates it. This happens asynchronously at some point in time + after calling QWidget::show() and the first paint event the + window receives, or it does not happen at all. Bear in mind that + X11 is policy-free (others call it flexible). Thus you cannot + make any safe assumption about the decoration frame your window + will get. Basic rule: There's always one user who uses a window + manager that breaks your assumption, and who will complain to + you. + + Furthermore, a toolkit cannot simply place windows on the screen. All + Qt can do is to send certain hints to the window manager. The window + manager, a separate process, may either obey, ignore or misunderstand + them. Due to the partially unclear Inter-Client Communication + Conventions Manual (ICCCM), window placement is handled quite + differently in existing window managers. + + X11 provides no standard or easy way to get the frame geometry + once the window is decorated. Qt solves this problem with nifty + heuristics and clever code that works on a wide range of window + managers that exist today. Don't be surprised if you find one + where QWidget::frameGeometry() returns wrong results though. + + Nor does X11 provide a way to maximize a window. + QWidget::showMaximized() has to emulate the feature. Its result + depends on the result of QWidget::frameGeometry() and the + capability of the window manager to do proper window placement, + neither of which can be guaranteed. +*/ + +/*! + \page mainwindow.html + \title Application Main Window + \ingroup qt-gui-concepts + \brief Creating the application window. + + \tableofcontents + + \section1 Overview of the Main Window Classes + + These classes provide everything you need for a typical modern main + application window, like the main window itself, menu and tool bars, + a status bar, etc. + + \annotatedlist mainwindow-classes + + \section1 The Main Window Classes + + Qt 4 provides the following classes for managing main windows and + associated user interface components: + + \list + \li QMainWindow remains the central class around which applications + can be built. The interface to this class has been simplified, and + much of the functionality previously included in this class is now + present in the companion QDockWidget and QToolBar classes. + + \li QDockWidget provides a widget that can be used to create + detachable tool palettes or helper windows. Dock widgets keep track + of their own properties, and they can be moved, closed, and floated + as external windows. + + \li QToolBar provides a generic toolbar widget that can hold a + number of different action-related widgets, such as buttons, + drop-down menus, comboboxes, and spin boxes. The emphasis on a + unified action model in Qt 4 means that toolbars cooperate well + with menus and keyboard shortcuts. + \endlist + + \section1 Example Code + + Using QMainWindow is straightforward. Generally, we subclass + QMainWindow and set up menus, toolbars, and dock widgets inside + the QMainWindow constructor. + + To add a menu bar to the main window, we simply create the menus, and + add them to the main window's menu bar. Note that the + QMainWindow::menuBar() function will automatically create the menu bar + the first time it is called. You can also call + QMainWindow::setMenuBar() to use a custom menu bar in the main window. + + \snippet code/doc_src_qt4-mainwindow.cpp 0 + \dots + \snippet mainwindows/menus/mainwindow.cpp 5 + \dots + + Once actions have been created, we can add them to the main window + components. To begin with, we add them to the pop-up menus: + + \snippet mainwindows/menus/mainwindow.cpp 10 + \dots + \snippet mainwindows/menus/mainwindow.cpp 11 + \dots + + The QToolBar and QMenu classes use Qt's action system to provide a + consistent API. In the above code, some existing actions were added to + the file menu with the QMenu::addAction() function. QToolBar also + provides this function, making it easy to reuse actions in different + parts of the main window. This avoids unnecessary duplication of work. + + We create a toolbar as a child of the main window, and add the desired + actions to it: + + \snippet mainwindows/sdi/mainwindow.cpp 0 + \dots + \snippet code/doc_src_qt4-mainwindow.cpp 1 + + In this example, the toolbar is restricted to the top and bottom + toolbar areas of the main window, and is initially placed in the + top tool bar area. We can see that the actions specified by \c + newAct and \c openAct will be displayed both on the toolbar and in + the file menu. + + QDockWidget is used in a similar way to QToolBar. We create a + dock widget as a child of the main window, and add widgets as children + of the dock widget: + + \snippet dockwidgets/mainwindow.cpp 0 + + In this example, the dock widget can only be placed in the left and + right dock areas, and it is initially placed in the left dock area. + + The QMainWindow API allows the programmer to customize which dock + widget areas occupy the four corners of the dock widget area. If + required, the default can be changed with the + QMainWindow::setCorner() function: + + \snippet code/doc_src_qt4-mainwindow.cpp 2 + + The following diagram shows the configuration produced by the above code. + Note that the left and right dock widgets will occupy the top and bottom + corners of the main window in this layout. + + \image mainwindow-docks-example.png + + Once all of the main window components have been set up, the central widget + is created and installed by using code similar to the following: + + \snippet code/doc_src_qt4-mainwindow.cpp 3 + + The central widget can be any subclass of QWidget. +*/ -- cgit v1.2.3