aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--dist/changes-5.3.131
-rw-r--r--examples/qml/networkaccessmanagerfactory/doc/src/networkaccessmanagerfactory.qdoc38
-rw-r--r--examples/quick/customitems/dialcontrol/dialcontrol.qmlproject17
-rw-r--r--examples/quick/customitems/dialcontrol/doc/images/qml-dialcontrol-example.pngbin0 -> 33569 bytes
-rw-r--r--examples/quick/customitems/dialcontrol/doc/src/dialcontrol.qdoc53
-rw-r--r--examples/quick/customitems/flipable/doc/images/qml-flipable-example.pngbin0 -> 13301 bytes
-rw-r--r--examples/quick/customitems/flipable/doc/src/flipable.qdoc49
-rw-r--r--examples/quick/customitems/flipable/flipable.qmlproject16
-rw-r--r--examples/quick/customitems/scrollbar/doc/images/qml-scrollbar-example.pngbin0 -> 159568 bytes
-rw-r--r--examples/quick/customitems/scrollbar/doc/src/scrollbar.qdoc37
-rw-r--r--examples/quick/customitems/tabwidget/doc/images/qml-tabwidget-example.pngbin0 -> 5298 bytes
-rw-r--r--examples/quick/customitems/tabwidget/doc/images/tab.png (renamed from examples/quick/customitems/tabwidget/tab.png)bin507 -> 507 bytes
-rw-r--r--examples/quick/customitems/tabwidget/doc/src/tabwidget.qdoc40
-rw-r--r--examples/quick/demos/calqlatr/calqlatr.pro12
-rw-r--r--examples/quick/demos/calqlatr/calqlatr.qrc10
-rw-r--r--examples/quick/demos/calqlatr/content/audio/touch.wavbin950 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/icon-back.pngbin328 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/icon-close.pngbin488 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/icon-settings.pngbin503 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/logo.pngbin5950 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/settings-selected-a.pngbin2326 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/settings-selected-b.pngbin2334 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/touch-green.pngbin4808 -> 0 bytes
-rw-r--r--examples/quick/demos/calqlatr/content/images/touch-white.pngbin4601 -> 0 bytes
-rw-r--r--examples/quick/demos/demos.pro5
-rw-r--r--examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-3.jpgbin0 -> 25541 bytes
-rw-r--r--examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-4.jpgbin0 -> 79678 bytes
-rw-r--r--examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-5.jpgbin0 -> 27911 bytes
-rw-r--r--examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-6.jpgbin0 -> 59198 bytes
-rw-r--r--examples/quick/demos/maroon/doc/src/maroon.qdoc855
-rw-r--r--examples/quick/demos/rssnews/content/BusyIndicator.qml73
-rw-r--r--examples/quick/demos/rssnews/content/CategoryDelegate.qml107
-rw-r--r--examples/quick/demos/rssnews/content/NewsDelegate.qml147
-rw-r--r--examples/quick/demos/rssnews/content/RssFeeds.qml91
-rw-r--r--examples/quick/demos/rssnews/content/ScrollBar.qml79
-rw-r--r--examples/quick/demos/rssnews/content/images/Asia.jpgbin0 -> 10578 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Business.jpgbin0 -> 17276 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Entertainment.jpgbin0 -> 15433 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Europe.jpgbin0 -> 15872 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Health.jpgbin0 -> 16015 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Politics.jpgbin0 -> 16401 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Science.jpgbin0 -> 9496 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Sports.jpgbin0 -> 9281 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/Technology.jpgbin0 -> 22290 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/TopStories.jpgbin0 -> 8067 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/USNational.jpgbin0 -> 9635 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/World.jpgbin0 -> 15128 bytes
-rw-r--r--examples/quick/demos/rssnews/content/images/btn_close.pngbin0 -> 1267 bytes
-rw-r--r--examples/quick/demos/rssnews/doc/images/qtquick-demo-rssnews-small.pngbin43372 -> 56864 bytes
-rw-r--r--examples/quick/demos/rssnews/doc/src/rssnews.qdoc337
-rw-r--r--examples/quick/demos/rssnews/main.cpp (renamed from examples/quick/demos/calqlatr/content/StyleLabel.qml)15
-rw-r--r--examples/quick/demos/rssnews/rssnews.pro13
-rw-r--r--examples/quick/demos/rssnews/rssnews.qml197
-rw-r--r--examples/quick/demos/rssnews/rssnews.qrc25
-rw-r--r--examples/quick/imageprovider/doc/images/qml-imageprovider-example.pngbin0 -> 2259 bytes
-rw-r--r--examples/quick/imageprovider/doc/src/imageprovider.qdoc37
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp273
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/fbitem.h136
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/logo.cpp141
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/logo.h65
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/main.cpp56
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp216
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h80
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro17
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc5
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/test.qml210
-rw-r--r--examples/quick/quickwidgets/quickwidgets.pro3
-rw-r--r--examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc113
-rw-r--r--examples/quick/scenegraph/openglunderqml/squircle.cpp74
-rw-r--r--examples/quick/scenegraph/openglunderqml/squircle.h32
-rw-r--r--examples/quick/threading/threadedlistmodel/doc/src/threadedlistmodel.qdoc35
-rw-r--r--examples/quick/threading/workerscript/workerscript.js40
-rw-r--r--examples/quick/threading/workerscript/workerscript.qmlproject40
-rw-r--r--examples/quick/views/doc/src/views.qdoc2
-rw-r--r--src/imports/localstorage/plugin.cpp2
-rw-r--r--src/plugins/accessible/quick/qaccessiblequickitem.cpp2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp4
-rw-r--r--src/qml/compiler/qv4ssa.cpp31
-rw-r--r--src/qml/doc/images/visualitemmodel.png (renamed from src/quick/doc/images/visualitemmodel.png)bin347 -> 347 bytes
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc85
-rw-r--r--src/qml/doc/src/javascript/hostenvironment.qdoc4
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc4
-rw-r--r--src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc8
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc8
-rw-r--r--src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc5
-rw-r--r--src/qml/doc/src/whatsnew.qdoc5
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4engine.cpp6
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/qml/qqmlcomponent.cpp11
-rw-r--r--src/qml/qml/qqmlcomponent_p.h6
-rw-r--r--src/qml/qml/qqmldata_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp11
-rw-r--r--src/qml/qml/qqmlengine_p.h3
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp4
-rw-r--r--src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp53
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h19
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp7
-rw-r--r--src/qml/types/qqmllistmodel.cpp4
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp4
-rw-r--r--src/qml/types/qquickworkerscript.cpp6
-rw-r--r--src/qmltest/quicktestresult.cpp2
-rw-r--r--src/quick/doc/qtquick.qdocconf2
-rw-r--r--src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc6
-rw-r--r--src/quick/doc/src/concepts/statesanimations/animations.qdoc4
-rw-r--r--src/quick/doc/src/concepts/statesanimations/states.qdoc2
-rw-r--r--src/quick/doc/src/examples.qdoc2
-rw-r--r--src/quick/doc/src/tutorial.qdoc2
-rw-r--r--src/quick/items/qquickborderimage.cpp2
-rw-r--r--src/quick/items/qquickflickable.cpp65
-rw-r--r--src/quick/items/qquickflickable_p_p.h4
-rw-r--r--src/quick/items/qquickflipable.cpp2
-rw-r--r--src/quick/items/qquickgridview.cpp2
-rw-r--r--src/quick/items/qquickimage.cpp4
-rw-r--r--src/quick/items/qquickimagebase.cpp5
-rw-r--r--src/quick/items/qquickitem.cpp2
-rw-r--r--src/quick/items/qquickitemview.cpp14
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp6
-rw-r--r--src/quick/items/qquickmousearea.cpp2
-rw-r--r--src/quick/items/qquickmousearea_p.h34
-rw-r--r--src/quick/items/qquickpathview.cpp10
-rw-r--r--src/quick/items/qquickpathview_p_p.h1
-rw-r--r--src/quick/items/qquickscreen_p.h18
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp2
-rw-r--r--src/quick/items/qquicktext.cpp10
-rw-r--r--src/quick/items/qquicktextedit.cpp8
-rw-r--r--src/quick/items/qquicktextedit_p_p.h5
-rw-r--r--src/quick/items/qquicktextinput.cpp2
-rw-r--r--src/quick/items/qquicktextnode.cpp2
-rw-r--r--src/quick/items/qquicktranslate.cpp2
-rw-r--r--src/quick/items/qquickwindow.cpp12
-rw-r--r--src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp4
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp3
-rw-r--r--src/quick/scenegraph/util/qsgpainternode.cpp5
-rw-r--r--src/quick/util/qquickanimation.cpp3
-rw-r--r--src/quick/util/qquickbehavior.cpp2
-rw-r--r--src/quick/util/qquickfontloader.cpp2
-rw-r--r--src/quick/util/qquickimageprovider.cpp7
-rw-r--r--src/quick/util/qquickpropertychanges.cpp2
-rw-r--r--src/quick/util/qquickstate.cpp2
-rw-r--r--src/quick/util/qquicktransition.cpp2
-rw-r--r--src/quickwidgets/qquickwidget.cpp3
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp9
-rw-r--r--tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml37
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp60
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h45
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp28
-rw-r--r--tests/auto/qmltest/listview/tst_listview.qml41
-rw-r--r--tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp2
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp9
-rw-r--r--tests/auto/quick/qquickitem2/data/keysforward.qml6
-rw-r--r--tests/auto/quick/qquicklistview/data/layoutChangeSort.qml58
-rw-r--r--tests/auto/quick/qquicklistview/data/simplelistview.qml11
-rw-r--r--tests/auto/quick/qquicklistview/qquicklistview.pro7
-rw-r--r--tests/auto/quick/qquicklistview/randomsortmodel.cpp107
-rw-r--r--tests/auto/quick/qquicklistview/randomsortmodel.h64
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp102
-rw-r--r--tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml45
-rw-r--r--tests/auto/quick/qquickpathview/data/incorrectSteal.qml85
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp98
-rw-r--r--tests/auto/quick/qquickwindow/data/unloadSubWindow.qml22
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp23
166 files changed, 4580 insertions, 684 deletions
diff --git a/.qmake.conf b/.qmake.conf
index d170e6d272..effef04600 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,4 +2,4 @@ load(qt_build_config)
CONFIG += qt_example_installs
CONFIG += warning_clean
-MODULE_VERSION = 5.3.1
+MODULE_VERSION = 5.3.2
diff --git a/dist/changes-5.3.1 b/dist/changes-5.3.1
new file mode 100644
index 0000000000..f015cb804c
--- /dev/null
+++ b/dist/changes-5.3.1
@@ -0,0 +1,31 @@
+Qt 5.3.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.3.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ http://qt-project.org/doc/qt-5.3
+
+The Qt version 5.3 series is binary compatible with the 5.2.x series.
+Applications compiled for 5.2 will continue to run with 5.3.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ http://bugreports.qt-project.org/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+
+QtQuick
+-------
+
+ - Platform Specific Changes:
+ * Added canPaste property to TextInput element also on platforms that
+ don't support a clipboard (QT_NO_CLIPBOARD is defined).
+
diff --git a/examples/qml/networkaccessmanagerfactory/doc/src/networkaccessmanagerfactory.qdoc b/examples/qml/networkaccessmanagerfactory/doc/src/networkaccessmanagerfactory.qdoc
new file mode 100644
index 0000000000..a4d4acd715
--- /dev/null
+++ b/examples/qml/networkaccessmanagerfactory/doc/src/networkaccessmanagerfactory.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \title C++ Extensions: Network Access Manager Factory Example
+ \example networkaccessmanagerfactory
+
+ This example shows how to use QQmlNetworkAccessManagerFactory to create a QNetworkAccessManager
+ with a proxy.
+
+ Usage:
+ networkaccessmanagerfactory [-host <proxy> -port <port>] [file]
+*/
+
diff --git a/examples/quick/customitems/dialcontrol/dialcontrol.qmlproject b/examples/quick/customitems/dialcontrol/dialcontrol.qmlproject
new file mode 100644
index 0000000000..4056ad87ef
--- /dev/null
+++ b/examples/quick/customitems/dialcontrol/dialcontrol.qmlproject
@@ -0,0 +1,17 @@
+import QmlProject 1.1
+
+Project {
+ mainFile: "dialcontrol.qml"
+
+ /* Include .qml, .js, and image files from current directory and subdirectories */
+ QmlFiles {
+ directory: "."
+ }
+ JavaScriptFiles {
+ directory: "."
+ }
+ ImageFiles {
+ directory: "."
+ }
+}
+
diff --git a/examples/quick/customitems/dialcontrol/doc/images/qml-dialcontrol-example.png b/examples/quick/customitems/dialcontrol/doc/images/qml-dialcontrol-example.png
new file mode 100644
index 0000000000..74cd645d3a
--- /dev/null
+++ b/examples/quick/customitems/dialcontrol/doc/images/qml-dialcontrol-example.png
Binary files differ
diff --git a/examples/quick/customitems/dialcontrol/doc/src/dialcontrol.qdoc b/examples/quick/customitems/dialcontrol/doc/src/dialcontrol.qdoc
new file mode 100644
index 0000000000..f0c5863526
--- /dev/null
+++ b/examples/quick/customitems/dialcontrol/doc/src/dialcontrol.qdoc
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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$
+**
+****************************************************************************/
+
+
+/*!
+ \title UI Components: Dial Control Example
+ \example customitems/dialcontrol
+
+ This example shows how to create a dial-type control. It combines
+ \l Image elements with \l Rotation transforms and \l SpringAnimation behaviors
+ to produce an interactive speedometer-type dial.
+
+ \image qml-dialcontrol-example.png
+*/
+
+
diff --git a/examples/quick/customitems/flipable/doc/images/qml-flipable-example.png b/examples/quick/customitems/flipable/doc/images/qml-flipable-example.png
new file mode 100644
index 0000000000..dd68a66cef
--- /dev/null
+++ b/examples/quick/customitems/flipable/doc/images/qml-flipable-example.png
Binary files differ
diff --git a/examples/quick/customitems/flipable/doc/src/flipable.qdoc b/examples/quick/customitems/flipable/doc/src/flipable.qdoc
new file mode 100644
index 0000000000..7ee5fba73a
--- /dev/null
+++ b/examples/quick/customitems/flipable/doc/src/flipable.qdoc
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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$
+**
+****************************************************************************/
+
+/*!
+ \title UI Components: Flipable Example
+ \example customitems/flipable
+
+ This example shows how to use the \l Flipable element.
+
+ \image qml-flipable-example.png
+*/
+
diff --git a/examples/quick/customitems/flipable/flipable.qmlproject b/examples/quick/customitems/flipable/flipable.qmlproject
new file mode 100644
index 0000000000..68718b2e69
--- /dev/null
+++ b/examples/quick/customitems/flipable/flipable.qmlproject
@@ -0,0 +1,16 @@
+import QmlProject 1.1
+
+Project {
+ mainFile: "flipable.qml"
+
+ /* Include .qml, .js, and image files from current directory and subdirectories */
+ QmlFiles {
+ directory: "."
+ }
+ JavaScriptFiles {
+ directory: "."
+ }
+ ImageFiles {
+ directory: "."
+ }
+}
diff --git a/examples/quick/customitems/scrollbar/doc/images/qml-scrollbar-example.png b/examples/quick/customitems/scrollbar/doc/images/qml-scrollbar-example.png
new file mode 100644
index 0000000000..54adf33daa
--- /dev/null
+++ b/examples/quick/customitems/scrollbar/doc/images/qml-scrollbar-example.png
Binary files differ
diff --git a/examples/quick/customitems/scrollbar/doc/src/scrollbar.qdoc b/examples/quick/customitems/scrollbar/doc/src/scrollbar.qdoc
new file mode 100644
index 0000000000..7847692e73
--- /dev/null
+++ b/examples/quick/customitems/scrollbar/doc/src/scrollbar.qdoc
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*!
+ \title UI Components: Scroll Bar Example
+ \example customitems/scrollbar
+
+ This example shows how to create scroll bars for a \l Flickable element
+ using the \l {Flickable::visibleArea.xPosition}{Flickable::visibleArea}
+ properties.
+
+ \image qml-scrollbar-example.png
+*/
+
diff --git a/examples/quick/customitems/tabwidget/doc/images/qml-tabwidget-example.png b/examples/quick/customitems/tabwidget/doc/images/qml-tabwidget-example.png
new file mode 100644
index 0000000000..847052d301
--- /dev/null
+++ b/examples/quick/customitems/tabwidget/doc/images/qml-tabwidget-example.png
Binary files differ
diff --git a/examples/quick/customitems/tabwidget/tab.png b/examples/quick/customitems/tabwidget/doc/images/tab.png
index ad8021605f..ad8021605f 100644
--- a/examples/quick/customitems/tabwidget/tab.png
+++ b/examples/quick/customitems/tabwidget/doc/images/tab.png
Binary files differ
diff --git a/examples/quick/customitems/tabwidget/doc/src/tabwidget.qdoc b/examples/quick/customitems/tabwidget/doc/src/tabwidget.qdoc
new file mode 100644
index 0000000000..9aefd96e92
--- /dev/null
+++ b/examples/quick/customitems/tabwidget/doc/src/tabwidget.qdoc
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \title TabWidget Example
+ \example customitems/tabwidget
+
+ This example shows how to create a tab widget. It also demonstrates how
+ \l {Property aliases}{property aliases} and
+ \l {QML Object Attributes#Default Properties}{default properties} can be used to collect and
+ assemble the child items declared within an \l Item.
+
+ \image qml-tabwidget-example.png
+*/
+
+
diff --git a/examples/quick/demos/calqlatr/calqlatr.pro b/examples/quick/demos/calqlatr/calqlatr.pro
index 91d52a293e..20543c08da 100644
--- a/examples/quick/demos/calqlatr/calqlatr.pro
+++ b/examples/quick/demos/calqlatr/calqlatr.pro
@@ -10,20 +10,10 @@ OTHER_FILES = calqlatr.qml \
content/Button.qml \
content/Display.qml \
content/NumberPad.qml \
- content/StyleLabel.qml \
- content/audio/touch.wav \
content/calculator.js \
- content/images/icon-back.png \
- content/images/icon-close.png \
- content/images/icon-settings.png \
- content/images/logo.png \
content/images/paper-edge-left.png \
content/images/paper-edge-right.png \
- content/images/paper-grip.png \
- content/images/settings-selected-a.png \
- content/images/settings-selected-b.png \
- content/images/touch-green.png \
- content/images/touch-white.png
+ content/images/paper-grip.png
target.path = $$[QT_INSTALL_EXAMPLES]/quick/demos/calqlatr
INSTALLS += target
diff --git a/examples/quick/demos/calqlatr/calqlatr.qrc b/examples/quick/demos/calqlatr/calqlatr.qrc
index fda7d35d7e..7483304e02 100644
--- a/examples/quick/demos/calqlatr/calqlatr.qrc
+++ b/examples/quick/demos/calqlatr/calqlatr.qrc
@@ -5,18 +5,8 @@
<file>content/calculator.js</file>
<file>content/Display.qml</file>
<file>content/NumberPad.qml</file>
- <file>content/StyleLabel.qml</file>
- <file>content/audio/touch.wav</file>
- <file>content/images/icon-back.png</file>
- <file>content/images/icon-close.png</file>
- <file>content/images/icon-settings.png</file>
- <file>content/images/logo.png</file>
<file>content/images/paper-edge-left.png</file>
<file>content/images/paper-edge-right.png</file>
<file>content/images/paper-grip.png</file>
- <file>content/images/settings-selected-a.png</file>
- <file>content/images/settings-selected-b.png</file>
- <file>content/images/touch-green.png</file>
- <file>content/images/touch-white.png</file>
</qresource>
</RCC>
diff --git a/examples/quick/demos/calqlatr/content/audio/touch.wav b/examples/quick/demos/calqlatr/content/audio/touch.wav
deleted file mode 100644
index 94cccb7546..0000000000
--- a/examples/quick/demos/calqlatr/content/audio/touch.wav
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/icon-back.png b/examples/quick/demos/calqlatr/content/images/icon-back.png
deleted file mode 100644
index 2989ee2e35..0000000000
--- a/examples/quick/demos/calqlatr/content/images/icon-back.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/icon-close.png b/examples/quick/demos/calqlatr/content/images/icon-close.png
deleted file mode 100644
index 3e21248232..0000000000
--- a/examples/quick/demos/calqlatr/content/images/icon-close.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/icon-settings.png b/examples/quick/demos/calqlatr/content/images/icon-settings.png
deleted file mode 100644
index 98e662f53f..0000000000
--- a/examples/quick/demos/calqlatr/content/images/icon-settings.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/logo.png b/examples/quick/demos/calqlatr/content/images/logo.png
deleted file mode 100644
index 6bc65610bc..0000000000
--- a/examples/quick/demos/calqlatr/content/images/logo.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/settings-selected-a.png b/examples/quick/demos/calqlatr/content/images/settings-selected-a.png
deleted file mode 100644
index e08ddface8..0000000000
--- a/examples/quick/demos/calqlatr/content/images/settings-selected-a.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/settings-selected-b.png b/examples/quick/demos/calqlatr/content/images/settings-selected-b.png
deleted file mode 100644
index d9aa7e3431..0000000000
--- a/examples/quick/demos/calqlatr/content/images/settings-selected-b.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/touch-green.png b/examples/quick/demos/calqlatr/content/images/touch-green.png
deleted file mode 100644
index 64dbde66b1..0000000000
--- a/examples/quick/demos/calqlatr/content/images/touch-green.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/calqlatr/content/images/touch-white.png b/examples/quick/demos/calqlatr/content/images/touch-white.png
deleted file mode 100644
index bb02b000cf..0000000000
--- a/examples/quick/demos/calqlatr/content/images/touch-white.png
+++ /dev/null
Binary files differ
diff --git a/examples/quick/demos/demos.pro b/examples/quick/demos/demos.pro
index ac15cc3c1f..9aac7bf6f7 100644
--- a/examples/quick/demos/demos.pro
+++ b/examples/quick/demos/demos.pro
@@ -7,6 +7,7 @@ SUBDIRS = samegame \
photosurface \
stocqt
+qtHaveModule(xmlpatterns): SUBDIRS += rssnews
+
EXAMPLE_FILES = \
- photoviewer \
- rssnews
+ photoviewer
diff --git a/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-3.jpg b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-3.jpg
new file mode 100644
index 0000000000..a83e282d5f
--- /dev/null
+++ b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-3.jpg
Binary files differ
diff --git a/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-4.jpg b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-4.jpg
new file mode 100644
index 0000000000..8a6063b7c7
--- /dev/null
+++ b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-4.jpg
Binary files differ
diff --git a/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-5.jpg b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-5.jpg
new file mode 100644
index 0000000000..e3e4a2ec89
--- /dev/null
+++ b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-5.jpg
Binary files differ
diff --git a/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-6.jpg b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-6.jpg
new file mode 100644
index 0000000000..ad6b4bf156
--- /dev/null
+++ b/examples/quick/demos/maroon/doc/images/qtquick-demo-maroon-med-6.jpg
Binary files differ
diff --git a/examples/quick/demos/maroon/doc/src/maroon.qdoc b/examples/quick/demos/maroon/doc/src/maroon.qdoc
index 59f6397dcf..4b364397c1 100644
--- a/examples/quick/demos/maroon/doc/src/maroon.qdoc
+++ b/examples/quick/demos/maroon/doc/src/maroon.qdoc
@@ -29,14 +29,861 @@
\title Qt Quick Demo - Maroon in Trouble
\ingroup qtquickdemos
\example demos/maroon
- \brief A cute game designed for touchscreens.
- \image qtquick-demo-maroon-med-1.png
+ \brief A Qt Quick game for touch devices that uses SpriteSequence,
+ ParticleSystem, Emitter, and Wander types to animate objects and the SoundEffect type to
+ play sound effects.
+
\image qtquick-demo-maroon-med-2.png
- \e{Maroon in Trouble} demonstrates various QML and \l{Qt Quick} features
- such as displaying custom components and playing sound effects.
+ \e{Maroon in Trouble} demonstrates QML features that are useful when
+ developing games:
+
+ \list
+ \li Using custom QML types to create different screens for
+ different stages of the game.
+ \li Using the \l Item and \l Image types to construct a game background.
+ \li Using the SequentialAnimation, NumberAnimation, ParticleSystem,
+ \l Emitter, and \l Wander types to animate background objects.
+ \li Using the \l Timer and \l Repeater types to display a countdown
+ sequence before starting the game.
+ \li Using a custom QML type with custom properties to construct a game
+ board.
+ \li Using the SpriteSequence and \l Sprite types to add animated objects
+ to the game board.
+ \li Using a custom QML type that uses the \l Image type with some custom
+ properties to add a menu where the players can buy objects.
+ \li Using custom properties with private functions to keep track of game
+ statistics and a custom QML type to display them to the players.
+ \li Using the \l State type with JavaScript functions to manage game
+ states.
+ \li Using the \l SoundEffect type to play individual sound effects
+ depending on the object type and the action applied to the object.
+ \li Using signal handlers to specify keyboard shortcuts for some game
+ actions.
+ \li Using resource files to package game resources for deployment and
+ delivery.
+ \endlist
\include examples-run.qdocinc
+ \section1 Adding Screens
+
+ In the Maroon in Trouble app, we use the following custom types that
+ are each defined in a separate .qml file to create the game screens:
+
+ \list
+ \li NewGameScreen.qml
+ \li GameCanvas.qml
+ \li GameOverScreen.qml
+ \endlist
+
+ To use the custom types, we add an import statement to the main QML file,
+ maroon.qml that imports the folder called \c content where the types are
+ located:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto content
+ \printuntil "
+
+ We use the screen types at different stages of the game. The NewGameScreen
+ type is used to create the screen that appears when the players start the
+ app. In NewGameScreen.qml, we use an \l{Image} type to create a New Game
+ button that the players can press to start a new game.
+
+ \image qtquick-demo-maroon-med-1.png
+
+ Tapping the button initiates a countdown timer that triggers the creation
+ of the game canvas by using the GameCanvas type. Another \l{Timer} type
+ spawns mobs of fish inside bubbles that the players must free before they
+ reach the surface. The players can tap on the screen to open a menu where
+ they can buy different types of weapons (melee, ranged, and bombs) to burst
+ the bubbles.
+
+ \image qtquick-demo-maroon-med-2.png
+
+ When the game finishes, a screen created by using the GameOverScreen type
+ appears. On this screen, the players can see their score and start a new
+ game.
+
+ \image qtquick-demo-maroon-med-3.jpg
+
+ The screens are all created on the same background and use some of the same
+ images and animations.
+
+ \section1 Constructing the Background
+
+ In the maroon.qml file, we use an \l{Item} type with the id \c root and a
+ fixed width and height to create a main window for the game:
+
+ \skipto Item
+ \printuntil passedSplash
+
+ We declare two custom properties for the root item, \c gameState and
+ \c passedSplash that we will use later to manage game states.
+
+ We use an \l{Image} item to display the game background image:
+
+ \printuntil anchors.bottom
+
+ We want to be able to load the background image only once at app startup
+ and still use different scenes for the game screens. Therefore,
+ background.png is three times the length of the root item and displays a
+ scene that stretches from the bottom of sea to the sky above the horizon.
+
+ We use the \c anchors.bottom property to anchor the background image to the
+ bottom of the \l{Column} layout that we use to position the screens:
+
+ \skipto Column
+ \printuntil GameOverScreen
+
+ We set a negative value for the \c y property to set the first scene at the
+ bottom of the sea. We calculate the position by subtracting the height of
+ a screen from the \c height property.
+
+ Within the column layout, we use an \l{Item} type to add objects to the
+ background. Within the item, we use \l{Row} layout objects to position
+ \l{Image} objects that display waves on the game canvas and the game over
+ screen:
+
+ \printuntil }
+ \printuntil }
+ \dots
+ \skipto Row
+ \printuntil }
+ \printuntil }
+
+ The second row of waves is positioned on the y axis with a slight offset to
+ the first row. We also use the \c opacity property to make the waves appear
+ lighter in color than the first two waves, which gives the background some
+ depth.
+
+ We use \l{Image} objects to also display sunlight on the new game screen and
+ on the game canvas:
+
+ \skipto Image
+ \printuntil anchors
+ \dots
+ \skipto Image
+ \printuntil anchors
+
+ We set the \c opacity property of the images to \c 0.02 and \c 0.04 to give
+ some depth to the rays of sunshine. We use the \c y property to position the
+ images at fixed locations on the y axis and the
+ \c {anchors.horizontalCenter} property to center them horizontally in
+ relation to their parent.
+
+ We use an \l {Image} type to display an image that adds a deepening shadow
+ to the background:
+
+ \skipto Image
+ \printuntil }
+
+ We set the \c opacity property of the image to \c 0.5 to make the background
+ visible behind the shadow.
+
+ To make the background more interesting, we animate some of the objects we
+ added to it.
+
+ \section1 Animating Background Objects
+
+ We use NumberAnimation to move the waves horizontally across the screen in
+ opposite directions and SequentialAnimation with NumberAnimation to move
+ them up and down.
+
+ We apply the number animation to the \c x property of \c wave as a property
+ value source to animate the x value from its current value to the
+ \c -(wave.width), over 16 seconds. We set the \c loops property to
+ \c {Animation.Infinite} to repeat the animation indefinitely:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto wave.width
+ \printuntil }
+
+ We apply the sequential animation to the \c y property of the image as a
+ property value source to animate the y value. We use one number animation
+ to animate the image from the y position of two below the value of y to two
+ above it, over 1600 milliseconds. We use another number animation to
+ subsequently animate the image in the opposite direction, again over 1600
+ milliseconds. The animation is repeated indefinitely:
+
+ \skipto SequentialAnimation
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We use the easing curve of the type \c {Easing.InOutQuad} for a quintic
+ (t^5) function to accelerate the motion until halfway and then decelerate
+ it.
+
+ We use sequential animation and number animation to animate \c wave2
+ similarly to \c wave, but in the opposite direction:
+
+ \skipto SequentialAnimation
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We use sequential animation to rotate the rays of sunlight in degrees
+ clockwise around an origin point that we set to \c {Item.Top} in the
+ \c transformOrigin property. The animation is repeated indefinitely:
+
+ \skipto transformOrigin
+ \printuntil to: -10
+ \printuntil }
+
+ We use one number animation to rotate the image from \c -10 degrees to
+ \c 10 degrees over 8 seconds and another to subsequently rotate it from
+ \c 10 degrees to \c -10 degrees over the same duration.
+
+ We use the easing curve of the type \c {Easing.InOutSine} for a sinusoidal
+ (sin(t)) function to accelerate the motion until halfway and then decelerate
+ it.
+
+ We use sequential animation and number animation to animate another
+ sunlight.png image similarly, but in the opposite direction:
+
+ \skipto transformOrigin
+ \printuntil to: 10
+ \printuntil }
+
+ For examples of using SequentialAnimation and NumberAnimation on the \c x
+ and \c y properties and the \c width and \c height properties, see
+ NewGameScreen.qml.
+
+ \section1 Emitting Particles
+
+ In addition to animation, we use particles to generate motion on the game
+ screens. We use the ParticleSystem QML type in maroon.qml to make bubbles
+ appear at the bottom of the new game screen and game canvas and slowly float
+ towards the top on varying trajectories.
+
+ To use the ParticleSystem type, we must import \l{Qt Quick Particles}:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto Particles
+ \printuntil 0
+
+ To have the particles appear on the game background, we place the
+ ParticleSystem type within the \l{Image} type that displays the game
+ background:
+
+ \skipto Image
+ \printuntil anchors.fill
+
+ In the ParticleSystem, we use an \l{Emitter} type to emit particles from the
+ location of the emitter at the rate of two per second with the life span of
+ 15 seconds:
+
+ \skipto Emitter
+ \printuntil sizeVariation
+ \printuntil }
+
+ The \c acceleration property uses the PointDirection type to
+ specify random variation of the x and y coordinates, so that the bubbles
+ appear inside a rectangular area around the emitter that is anchored to the
+ bottom of the image.
+
+ The \c size property sets the base size of the particles at the beginning of
+ their life to 24 pixels and the \c sizeVariation property randomly increases
+ or decreases the particle size by up to 16 pixels, so that we get bubbles in
+ different sizes.
+
+ As emitters have no visualization, we use the ImageParticle type to render
+ the catch.png image at the particle location:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto ImageParticle
+ \printuntil }
+
+ A \l{Wander} type applies a random trajectory to the particles, so that the
+ bubbles follow random routes from the bottom to the top.
+
+ \printuntil }
+
+ For another example of using the ParticleSystem type, see the
+ GameOverScreen.qml file, where an ImageParticle type is used to make clouds
+ move across the sky.
+
+ \section1 Using Timers
+
+ \image qtquick-demo-maroon-med-4.jpg
+
+ In maroon.qml, we use the \l{Timer} type with a \l{Repeater} type to display
+ a countdown sequence before using another timer to start a new game. Both
+ timers are started simultaneously in the \c "gameOn" state, that is when the
+ players tap the New Game button and \c passedSplash is \c true. This is
+ explained in more detail in \l{Managing Game States}.
+
+ We use the \c countdownTimer to display the countdown sequence:
+
+ \skipto Timer
+ \printuntil }
+
+ The \c onTriggered signal handler is called when the timer is triggered to
+ increment the value of the the \c countdown custom property.
+
+ We set the \c repeat property to \c true to specify that the timer is
+ triggered at the interval of 1 second as long as the value of \c countdown
+ is less than 5.
+
+ The \c countdown property is defined in the root item with an initial value
+ of \c 10, so that \c countdownTimer is not running by default:
+
+ \skipto countdown:
+ \printuntil 10
+
+ Each time the timer is triggered, an image from the countdown sequence is
+ displayed. We use a \l{Repeater} type to instantiate the \l{Image} delegate
+ in the context of the repeater's parent, \c canvasArea item, seeded with
+ data from the \c model:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto Repeater
+ \printuntil scale
+ \printuntil }
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We scale the images from \c 0.0 to \c 1.0 and use the \c visible property to
+ hide the images for the previous steps as the countdown progresses. We also
+ raise the opacity of the image that matches the current countdown step,
+ keeping the others nearly transparent.
+
+ By animating the changes in the \c opacity and \c scale properties using a
+ \l Behavior type, we achieve a countdown sequence where numbers zoom in
+ towards the players.
+
+ \section1 Constructing the Game Board
+
+ To construct the game board, we use the GameCanvas custom type that is
+ defined in GameCanvas.qml.
+
+ In maroon.qml, we use the GameCanvas type to display the game canvas
+ at the position of 32 on the x axis and 20 pixels from the bottom of
+ its parent item, \c canvasArea:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto GameCanvas
+ \printuntil }
+
+ We set the \c focus property to \c true to give \c canvas active focus on
+ startup.
+
+ In GameCanvas.qml, we use an \l Item type and define custom properties for
+ it to create a grid of equally sized squares divided to 4 columns on 6 rows:
+
+ \quotefromfile demos/maroon/content/GameCanvas.qml
+ \skipto Item
+ \printuntil canvas
+
+ We use the custom properties to set the \c width and \c height of the
+ \c grid item as the amount of columns and rows multiplied by square size:
+
+ \skipto width
+ \printuntil height
+
+ We use an \l{Image} type with a MouseArea type to display a help button
+ that the players can tap to view an image that contains instructions for
+ playing the game:
+
+ \skipuntil endGame
+ \skipto Image
+ \printuntil bottomMargin
+ \printuntil }
+
+ We declare the \c goAway() private function to disable the mouse area and
+ make the image fully transparent and a \c comeBack() function to enable the
+ mouse area and make the button fully opaque. We use a \l {Behavior} type on
+ the \c opacity property to apply the default number animation when the value
+ of \c opacity changes.
+
+ When the players tap the help button, the \c onClicked signal handler is
+ called to hide the help button by setting the \c {helpButton.visible}
+ property to \c false and to show the help image by setting the
+ \c {helpImage.visible} property to \c false.
+
+ \image qtquick-demo-maroon-med-6.jpg
+
+ We use anchoring to position the help button at the bottom center of the
+ game canvas.
+
+ We use another \l{Image} type to to display the help image:
+
+ \printuntil }
+ \printuntil }
+
+ To hide the help image when the players tap it, the \c onClicked signal
+ handler within the MouseArea type is called to set the \c{helpImage.visible}
+ property to \c true.
+
+ To ensure that the images are placed on top when they are visible, we set
+ a high value for their \c z property.
+
+ The following sections describe how to use timers to add animated objects to
+ the game board and how to create a menu dialog from which the players can
+ add more objects to it.
+
+ \section1 Animating Objects on the Game Board
+
+ We use sprite animation to animate objects on the game board. The Qt Quick
+ \l{Sprite Animations}{sprite engine} is a stochastic state machine combined
+ with the ability to chop up images containing multiple frames of an
+ animation.
+
+ \section2 Spawning Fish
+
+ We use a \l{Timer} element with the \c tick() function in GameCanvas.qml to
+ spawn mobs of fish in waves at an increasing rate, starting at 16
+ milliseconds:
+
+ \quotefromfile demos/maroon/content/GameCanvas.qml
+ \skipto Timer
+ \printuntil }
+
+ We use the MobBase custom type that is defined in MobBase.qml to
+ animate mobs of fish that swim inside bubbles. We use an \l{Item} type with
+ custom properties and private functions to create the fish and the bubbles
+ and to define the actions that can be applied to them:
+
+ \quotefromfile demos/maroon/content/mobs/MobBase.qml
+ \skipto Item
+ \printuntil }
+ \dots
+
+ We use a SpriteSequence type to animate the fish:
+
+ \skipto SpriteSequence
+ \printuntil goalSprite
+
+ The SpriteSequence type renders and controls a list of animations
+ defined by \l{Sprite} types:
+
+ \skipto Sprite {
+ \printuntil name: "right"
+ \printuntil }
+ \printuntil }
+
+ In the \c fishSprite sprite sequence, each sprite defines one frame within
+ the mob-idle.png file, which shows a fish facing right, front, and left:
+
+ \image ../../content/gfx/mob-idle.png
+
+ We use the \c frameWidth, \c frameHeight, and \c frameX properties to
+ determine that the first 64x64-pixel square of the image is framed in the
+ \c "left" sprite, the second in the \c "front" sprite, and the third in the
+ \c "right" sprite. For each sprite, the \c frameCount property is set to
+ \c 1 to specify that the sprite contains one frame.
+
+ We use the \c frameDuration and \c frameDurationVariation properties to
+ specify that the duration of an animation can vary from \c 400 to \c 1200
+ milliseconds.
+
+ The \c to property specifies that the sprites have weighted transitions to
+ other sprites. The \c "left" and \c "right" sprites always transfer to the
+ \c "front" sprite. When the \c "front" animation finishes, the sprite engine
+ chooses \c "left" or \c "right" randomly, but at roughly equal proportions,
+ because they both have the weight \c 1.
+
+ When the fish are set free, we want them to swim away in the direction they
+ are facing until they get off the screen. If they were facing front, we use
+ the \c jumpTo method with the JavaScript \c {Math.random()} method in the
+ \c die() private function to randomly jump to the \c "left" or \c "right"
+ sprite:
+
+ \quotefromfile demos/maroon/content/mobs/MobBase.qml
+ \skipto die()
+ \printuntil }
+
+ We then use the \c start() function to run a NumberAnimation that applies a
+ number animation to the x value from its current value to \c -360 or \c 360,
+ depending on whether the \c goingLeft custom property is \c true, in 300
+ milliseconds:
+
+ \skipto NumberAnimation
+ \printuntil }
+
+ \section2 Bursting Bubbles
+
+ We use another SpriteSequence to animate the bubbles so that they
+ become smaller and finally burst when they are attacked by a shooter or
+ a melee. For this effect, we set the value of the \c scale property to
+ decrease by \c 0.2 each time the custom \c hp property changes:
+
+ \skipto SpriteSequence
+ \printuntil goalSprite
+
+ We use a \l{Behavior} type to apply a NumberAnimation when the value of
+ \c scale changes. We use the \c{Easing.OutBack} easing type for a back
+ (overshooting cubic function: (s+1)*t^3 - s*t^2) easing out curve that
+ decelerates the motion to zero velocity in 150 milliseconds:
+
+ \skipto Behavior
+ \printuntil }
+ \printuntil }
+
+ The SpriteSequence consist of two sprites that display different images. The
+ first sprite, \c "big", uses the catch.png image to display an empty bubble:
+
+ \skipto Sprite
+ \printuntil }
+ \printuntil }
+
+ We set the \c to property to \c "burst" with the weight \c 0 to make the
+ second sprite, \c "burst", a valid goal for the \c jumpTo method that we use
+ in the \c die() private function to jump directly to the \c "burst" sprite
+ without playing the first sprite.
+
+ In the \c "burst" sprite, we set the \c frameCount property to \c 3 and the
+ \c frameX property to \c 64 to specify that the animation starts at pixel
+ location 64 and loads each frame for the duration of 200 milliseconds.
+
+ \skipto Sprite
+ \printuntil }
+
+ Within the SpriteSequence, we use SequentialAnimation with NumberAnimation
+ to animate the transitions between the frames. To create a pulsating effect
+ on the bubbles, we apply a sequential animation on the \c width property
+ with two number animations to first increase the bubble width from
+ \c{* 1} to \c{* 1.1} over 800 milliseconds and then bring it back over 1
+ second:
+
+ \skipto SequentialAnimation
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ Similarly, we increase the bubble height from \c{* 1} to \c{* 1.15} over
+ 1200 milliseconds and then bring it back over 1 second:
+
+ \skipto SequentialAnimation
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We use yet another SpriteSequence to display the effect of squid ink on the
+ bubbles. For more examples of using sprite sequences, see the QML files in
+ the \c towers directory.
+
+ \section1 Adding Dialogs
+
+ \image qtquick-demo-maroon-med-5.jpg
+
+ In GameCanvas.qml, we use an \l{Image} type with some custom properties to
+ create a menu where the players can buy tower objects:
+
+ \quotefromfile demos/maroon/content/GameCanvas.qml
+ \skipto Image
+ \printuntil towerExists
+
+ We set the \c visible property to \c false to hide the menu by default. The
+ \c z property is set to 1500 to ensure that the menu is displayed in front
+ of all other items when it is visible.
+
+ We use a MouseArea type to open or close the menu when players tap on the
+ canvas:
+
+ \quotefromfile demos/maroon/content/GameCanvas.qml
+ \skipto MouseArea
+ \printuntil }
+ \printuntil }
+
+ We set the \c anchors.fill property to \c parent to allow the players to tap
+ anywhere on the game canvas. We use a condition in the \c onClicked
+ signal handler to call the \c {finish()} function if the menu is visible
+ and the \c {open()} function otherwise.
+
+ The \c {finish()} function hides the menu by setting the \c shown custom
+ property to \c false:
+
+ \skipto finish
+ \printuntil }
+
+ The \c {open()} function displays the menu at the x and y position of the
+ mouse pointer:
+
+ \printuntil }
+
+ If \c gameRunning is \c true, we call the JavaScript \c row() function to
+ calculate the value of the \c targetRow custom property and the \c col()
+ function to calculate the value of the \c targetCol custom property. If
+ the value of \c targetRow equals \c 0, the y position is set to one square
+ above the mouse pointer. Otherwise, it is set to one square below the mouse
+ pointer.
+
+ We use the \c towerIdx() function to set the value of the \c towerExists
+ custom property.
+
+ We set the \c shown custom property to \c true to show the menu and call the
+ \c {helpButton.goAway()} function to hide the help button when the menu
+ opens.
+
+ We use states and transitions to display the menu when the \c shown
+ property is \c true and the \c gameOver property is \c false:
+
+ \printuntil OutElastic
+ \printuntil }
+
+ To set the visibility of the menu to \c "visible" without animating the
+ property change, we use a PropertyAction type. We do want to animate the
+ changes in opacity and scale, though, so we use number animation to
+ animate the value of the \c scale property from \c 0.9 to \c 1 and the
+ value of \c opacity property from \c 0.7 to \c 1, over 500 milliseconds.
+ We use the \c {Easing.outElastic} easing type for an elastic (exponentially
+ decaying sine wave) function easing curve that decelerates from zero
+ velocity.
+
+ To construct the menu, we use a BuildButton custom type that is defined in
+ BuildButton.qml. In GameCanvas.qml, we create one build button for each
+ tower object that the players can buy and position them in a \l{Row} layout
+ in front of the menu background image, dialog.png:
+
+ \printuntil dialog-factory.png
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ For each build button, we set the values of \c towerType and \c index custom
+ properties that we define in BuildButton.qml.
+
+ We use the \c canBuild custom property to prevent players from adding tower
+ objects in locations where tower objects already exist.
+
+ We use the \c source property to display the image for the tower type.
+
+ The \c onClicked signal handler is called to execute the \c finish()
+ function that closes the menu when the players tap an enabled build button.
+
+ Build buttons are enabled when the players have enough coins to buy the
+ tower objects. We use an \l {Image} type in BuildButton.qml to display
+ images on the buttons:
+
+ \quotefromfile demos/maroon/content/BuildButton.qml
+ \skipto Image
+ \printuntil }
+
+ We use the \c opacity property to make the buttons appear enabled. If
+ \c canBuild is \c true and the value of the \c gameCanvas.coins property
+ is larger than or equal to the cost of a tower object, the images are fully
+ opaque, otherwise their opacity is set to \c 0.4.
+
+ We use a \l{Text} type to display the cost of each tower item, as specified
+ by the the \c towerData variable, depending on \c towerType:
+
+ \skipto Text
+ \printuntil }
+
+ To display a pointer on the screen at the position where the tower object
+ will be added, we use the \l {Image} type. We use the \c visible property
+ to determine whether the dialog-pointer.png image should be positioned below
+ or above the menu. When the value of the \c col property equals the \c index
+ and the value or the \c row property is not \c 0, we anchor the image to the
+ bottom of its parent, BuildButton.
+
+ When the value or the \c row property is \c 0, we anchor the image to the
+ top of BuildButton to position the pointer above the menu and use the
+ \c rotation property to rotate it by 180 degrees, so that it points upwards:
+
+ \skipto Image
+ \printuntil }
+ \printuntil }
+
+ \section1 Keeping Track of Game Statistics
+
+ To keep track of the game statistics, we use the InfoBar custom type (that
+ is defined in InfoBar.qml) in maroon.qml:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto InfoBar
+ \printuntil }
+
+ We use the \c {anchors.bottom} and \c {anchors.bottomMargin} properties to
+ position the info bar at 6 points from the top of the game canvas. We bind
+ the \c width property of the info bar to that of its parent.
+
+ In InfoBar.qml, we use an \l{Item} type to create the info bar. Within it,
+ we use a \l{Row} layout type to display the number of lives the players have
+ left, the number of fish that have been saved, and the amount of coins that
+ are available for use.
+
+ We use the \c anchors property to position the rows in relationship to their
+ parent and to each other. In the first \l{Row} object, we use the
+ \c {anchors.left} and \c {anchors.leftMargin} properties to position the
+ heart icons at 10 points from the left border of the parent item:
+
+ \quotefromfile demos/maroon/content/InfoBar.qml
+ \skipto Item
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We use a \l{Repeater} type with a \c model and a \c delegate to display as
+ many hearts as the players have lives left. We use the \c spacing property
+ to leave 5 pixels between the displayed icons.
+
+ In the second \l{Row} object, we use the \c {anchors.right} and
+ \c {anchors.rightMargin} properties to position the number of fish saved at
+ 20 points left of the third \l{Row} object that displays the number of coins
+ available (and has the id \c points):
+
+ \skipto Row
+ \printuntil /^\}/
+
+ In these objects, we set spacing to 5 pixels to separate the icons from the
+ numbers that we display by using a \l{Text} type.
+
+ In GameCanvas.qml, we define custom properties to hold the game statistics:
+
+ \quotefromfile demos/maroon/content/GameCanvas.qml
+ \skipto score
+ \printuntil lives
+
+ We declare the \c freshState() function to set the initial game statistics
+ when a new game starts:
+
+ \skipto freshState()
+ \printuntil }
+
+ We use the \c {Logic.gameState.score} variable in the \c die() function
+ that we declare in MobBase.qml to increase the score by one when the players
+ set a fish free:
+
+ \quotefromfile demos/maroon/content/mobs/MobBase.qml
+ \skipto score
+ \printuntil ;
+
+ \section1 Managing Game States
+
+ In maroon.qml, we use a \l{State} type and JavaScript to switch between
+ screens according to the game state. The logic.js file contains definitions
+ for the functions. To use the functions in a QML file, we import logic.js as
+ the \c Logic namespace in that file:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto logic.js
+ \printuntil Logic
+
+ The base state displays the new game screen when the application starts.
+ In addition, we call the Component.onCompleted signal handler to initialize
+ a new game:
+
+ \skipto newGameState
+ \printuntil ;
+
+ In NewGameScreen.qml we use the \c onClicked signal handler to emit the
+ \c startButtonClicked() signal when the players tap the New Game button:
+
+ \quotefromfile demos/maroon/content/NewGameScreen.qml
+ \skipto to: 150
+ \skipto Image
+ \printuntil }
+
+ In maroon.qml, we use the \c onStartButtonClicked signal handler to set the
+ \c passedSplash property of the \c root item to \c true:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto NewGameScreen
+ \printuntil }
+
+ We then use the \c passedSplash property in the \c when property of the
+ \c gameOn state to trigger the \c gameStarter timer:
+
+ \skipto State {
+ \printuntil gameStarter
+ \printuntil }
+
+ We also switch to the \c "gameOn" state and move to the y position
+ \c {-(height - 960)} to display the game canvas.
+
+ In the \c gameStarter \l{Timer} object we use the \c onTriggered signal
+ handler to call the \c startGame() function that starts a new game:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto property int
+ \skipto Timer
+ \printuntil }
+
+ The game continues until \c gameState.gameOver is set to \c true and
+ \c gameState.gameRunning is set to \c false by calling the \c endGame()
+ function when the value of the \c gameState.lives property becomes less
+ than or equal to \c 0.
+
+ In GameOverScreen.qml, we use a MouseArea type and an \c onClicked signal
+ handler within an \l{Image} type to return to the game canvas when the
+ players tap the New Game button:
+
+ \quotefromfile demos/maroon/content/GameOverScreen.qml
+ \skipto opacity: 0.5
+ \skipto Image
+ \printuntil }
+ \printuntil }
+
+ The \c onClicked signal handler triggers a state change in maroon.qml to
+ display the game canvas:
+
+ \quotefromfile demos/maroon/maroon.qml
+ \skipto target: gameStarter
+ \skipto State
+ \printuntil }
+ \printuntil }
+
+ \section1 Playing Sound Effects
+
+ The app can play sound effects if the \l{Qt Multimedia} module is installed.
+ In the SoundEffect.qml file, we proxy a SoundEffect type:
+
+ \quotefromfile demos/maroon/content/SoundEffect.qml
+ \skipto Item
+ \printuntil }
+ \printuntil }
+
+ We add the \c qtHaveModule() qmake command to the app .pro file, maroon.pro,
+ to check whether the \l{Qt Multimedia} module is present:
+
+ \quotefromfile demos/maroon/maroon.pro
+ \skipto QT
+ \printuntil multimedia
+
+ In each QML file that defines a custom type used on the game canvas, we
+ use a SoundEffect type to specify the audio file to play for that type
+ of objects. For example, in Bomb.qml, we specify the sound that a bomb
+ makes when it explodes:
+
+ \quotefromfile demos/maroon/content/towers/Bomb.qml
+ \skipto SoundEffect
+ \printuntil }
+
+ To play the sound effect when a bomb explodes, we call the \c sound.play()
+ function that we declare as a member of the private \c fire() function
+ within the TowerBase custom type:
+
+ \quotefromfile demos/maroon/content/towers/Bomb.qml
+ \skipto fire()
+ \printuntil }
+
+ For more examples of playing sound effects, see the QML files in the
+ \c towers directory and MobBase.qml.
+
+ \section1 Adding Keyboard Shortcuts
+
+ This is a touch example, so you should not really need to handle key
+ presses. However, we do not want you to have to spend more time playing the
+ game than you want to while testing it, so we use the \c {Keys.onPressed}
+ signal handler to specify keyboard shortcuts. You can press Shift+Up to
+ increment the values of the \c coins property to add coins, Shift+Left to
+ increment the value of \c lives, Shift+Down to increment the value of the
+ \c waveProgress property to spawn mobs of fish faster, and Shift+Right to
+ call the \c endGame() function to quit the game:
+
+ \quotefromfile demos/maroon/content/GameCanvas.qml
+ \skipto Keys
+ \printuntil }
+
+ \section1 Packaging Resources for Deployment
+
+ To be able to run the app on mobile devices, we package all QML, JavaScript,
+ image, and sound files into a Qt resource file (.qrc). For more information,
+ see \l{The Qt Resource System}.
+
\sa {QML Applications}
*/
diff --git a/examples/quick/demos/rssnews/content/BusyIndicator.qml b/examples/quick/demos/rssnews/content/BusyIndicator.qml
index c16f582c40..e6cd15847a 100644
--- a/examples/quick/demos/rssnews/content/BusyIndicator.qml
+++ b/examples/quick/demos/rssnews/content/BusyIndicator.qml
@@ -1,53 +1,54 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
+** This file is part of the examples 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 Digia Plc 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$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
Image {
id: container
- property bool on: false
- source: "images/busy.png"; visible: container.on
+ source: "images/busy.png";
NumberAnimation on rotation {
- running: container.on; from: 0; to: 360; loops: Animation.Infinite; duration: 1200
+ running: container.visible
+ from: 0; to: 360;
+ loops: Animation.Infinite;
+ duration: 1200
}
}
diff --git a/examples/quick/demos/rssnews/content/CategoryDelegate.qml b/examples/quick/demos/rssnews/content/CategoryDelegate.qml
index 31dd9c0d3b..93d688a29c 100644
--- a/examples/quick/demos/rssnews/content/CategoryDelegate.qml
+++ b/examples/quick/demos/rssnews/content/CategoryDelegate.qml
@@ -1,82 +1,89 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtQml module of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** "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 Digia Plc 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.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
**
+** 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$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
-Item {
+Rectangle {
id: delegate
- width: delegate.ListView.view.width; height: 60
+ property bool selected: ListView.isCurrentItem
+ property real itemSize
+ width: itemSize
+ height: itemSize
+
+ Image {
+ anchors.centerIn: parent
+ source: image
+ }
Text {
- text: name
- color: delegate.ListView.isCurrentItem ? "white" : "black"
- font { family: "Helvetica"; pixelSize: 16; bold: true }
+ id: titleText
+
anchors {
- left: parent.left; leftMargin: 15
- verticalCenter: parent.verticalCenter
+ left: parent.left; leftMargin: 20
+ right: parent.right; rightMargin: 20
+ top: parent.top; topMargin: 20
}
- }
- BusyIndicator {
- scale: 0.6
- on: delegate.ListView.isCurrentItem && window.loading
- anchors { right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter }
+ font { pixelSize: 18; bold: true }
+ text: name
+ color: selected ? "#ffffff" : "#ebebdd"
+ scale: selected ? 1.15 : 1.0
+ Behavior on color { ColorAnimation { duration: 150 } }
+ Behavior on scale { PropertyAnimation { duration: 300 } }
}
- Rectangle {
- width: delegate.width; height: 1; color: "#cccccc"
- anchors.bottom: delegate.bottom
- visible: delegate.ListView.isCurrentItem ? false : true
- }
- Rectangle {
- width: delegate.width; height: 1; color: "white"
- visible: delegate.ListView.isCurrentItem ? false : true
+ BusyIndicator {
+ scale: 0.8
+ visible: delegate.ListView.isCurrentItem && window.loading
+ anchors.centerIn: parent
}
MouseArea {
anchors.fill: delegate
onClicked: {
delegate.ListView.view.currentIndex = index
- window.currentFeed = feed
+ if (window.currentFeed == feed)
+ feedModel.reload()
+ else
+ window.currentFeed = feed
}
}
}
diff --git a/examples/quick/demos/rssnews/content/NewsDelegate.qml b/examples/quick/demos/rssnews/content/NewsDelegate.qml
index ec39510eba..280e4d1631 100644
--- a/examples/quick/demos/rssnews/content/NewsDelegate.qml
+++ b/examples/quick/demos/rssnews/content/NewsDelegate.qml
@@ -1,71 +1,130 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtQml module of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** "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 Digia Plc 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.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
**
+** 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$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
-Item {
+Column {
id: delegate
- height: column.height + 40
width: delegate.ListView.view.width
+ spacing: 8
+
+ // Returns a string representing how long ago an event occurred
+ function timeSinceEvent(pubDate) {
+ var result = pubDate;
+
+ // We need to modify the pubDate read from the RSS feed
+ // so the JavaScript Date object can interpret it
+ var d = pubDate.replace(',','').split(' ');
+ if (d.length != 6)
+ return result;
+
+ var date = new Date([d[0], d[2], d[1], d[3], d[4], 'GMT' + d[5]].join(' '));
+
+ if (!isNaN(date.getDate())) {
+ var age = new Date() - date;
+ var minutes = Math.floor(Number(age) / 60000);
+ if (minutes < 1440) {
+ if (minutes < 2)
+ result = qsTr("Just now");
+ else if (minutes < 60)
+ result = '' + minutes + ' ' + qsTr("minutes ago")
+ else if (minutes < 120)
+ result = qsTr("1 hour ago");
+ else
+ result = '' + Math.floor(minutes/60) + ' ' + qsTr("hours ago");
+ }
+ else {
+ result = date.toDateString();
+ }
+ }
+ return result;
+ }
+
+ Item { height: 8; width: delegate.width }
- Column {
- id: column
- x: 20; y: 20
- width: parent.width - 40
+ Row {
+ width: parent.width
+ spacing: 8
+
+ Column {
+ Item {
+ width: 4
+ height: titleText.font.pixelSize / 4
+ }
+
+ Image {
+ id: titleImage
+ source: image
+ }
+ }
Text {
id: titleText
- text: title; width: parent.width; wrapMode: Text.WordWrap
- font { bold: true; family: "Helvetica"; pointSize: 16 }
+
+ text: title
+ width: delegate.width - titleImage.width
+ wrapMode: Text.WordWrap
+ font.pixelSize: 26
+ font.bold: true
}
+ }
- Text {
- id: descriptionText
- width: parent.width; text: description
- wrapMode: Text.WordWrap; font.family: "Helvetica"
+ Text {
+ width: delegate.width
+ font.pixelSize: 12
+ textFormat: Text.RichText
+ font.italic: true
+ text: timeSinceEvent(pubDate) + " (<a href=\"" + link + "\">Link</a>)"
+ onLinkActivated: {
+ Qt.openUrlExternally(link)
}
}
- Rectangle {
- width: parent.width; height: 1; color: "#cccccc"
- anchors.bottom: parent.bottom
+ Text {
+ id: descriptionText
+
+ text: description
+ width: parent.width
+ wrapMode: Text.WordWrap
+ font.pixelSize: 14
+ textFormat: Text.StyledText
+ horizontalAlignment: Qt.AlignLeft
}
}
diff --git a/examples/quick/demos/rssnews/content/RssFeeds.qml b/examples/quick/demos/rssnews/content/RssFeeds.qml
index 50bc771192..3ae3b23921 100644
--- a/examples/quick/demos/rssnews/content/RssFeeds.qml
+++ b/examples/quick/demos/rssnews/content/RssFeeds.qml
@@ -1,59 +1,56 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
+** This file is part of the examples 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 Digia Plc 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$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
ListModel {
- id: rssFeeds
-
- ListElement { name: "Top Stories"; feed: "rss.news.yahoo.com/rss/topstories" }
- ListElement { name: "World"; feed: "rss.news.yahoo.com/rss/world" }
- ListElement { name: "Europe"; feed: "rss.news.yahoo.com/rss/europe" }
- ListElement { name: "Oceania"; feed: "rss.news.yahoo.com/rss/oceania" }
- ListElement { name: "U.S. National"; feed: "rss.news.yahoo.com/rss/us" }
- ListElement { name: "Politics"; feed: "rss.news.yahoo.com/rss/politics" }
- ListElement { name: "Business"; feed: "rss.news.yahoo.com/rss/business" }
- ListElement { name: "Technology"; feed: "rss.news.yahoo.com/rss/tech" }
- ListElement { name: "Entertainment"; feed: "rss.news.yahoo.com/rss/entertainment" }
- ListElement { name: "Health"; feed: "rss.news.yahoo.com/rss/health" }
- ListElement { name: "Science"; feed: "rss.news.yahoo.com/rss/science" }
- ListElement { name: "Sports"; feed: "rss.news.yahoo.com/rss/sports" }
+ ListElement { name: "Top Stories"; feed: "news.yahoo.com/rss/topstories"; image: "images/TopStories.jpg" }
+ ListElement { name: "World"; feed: "news.yahoo.com/rss/world"; image: "images/World.jpg" }
+ ListElement { name: "Europe"; feed: "news.yahoo.com/rss/europe"; image: "images/Europe.jpg" }
+ ListElement { name: "Asia"; feed: "news.yahoo.com/rss/asia"; image: "images/Asia.jpg" }
+ ListElement { name: "U.S. National"; feed: "news.yahoo.com/rss/us"; image: "images/USNational.jpg" }
+ ListElement { name: "Politics"; feed: "news.yahoo.com/rss/politics"; image: "images/Politics.jpg" }
+ ListElement { name: "Business"; feed: "news.yahoo.com/rss/business"; image: "images/Business.jpg" }
+ ListElement { name: "Technology"; feed: "news.yahoo.com/rss/tech"; image: "images/Technology.jpg" }
+ ListElement { name: "Entertainment"; feed: "news.yahoo.com/rss/entertainment"; image: "images/Entertainment.jpg" }
+ ListElement { name: "Health"; feed: "news.yahoo.com/rss/health"; image: "images/Health.jpg" }
+ ListElement { name: "Science"; feed: "news.yahoo.com/rss/science"; image: "images/Science.jpg" }
+ ListElement { name: "Sports"; feed: "news.yahoo.com/rss/sports"; image: "images/Sports.jpg" }
}
diff --git a/examples/quick/demos/rssnews/content/ScrollBar.qml b/examples/quick/demos/rssnews/content/ScrollBar.qml
index d3cf4a6851..606f2e4259 100644
--- a/examples/quick/demos/rssnews/content/ScrollBar.qml
+++ b/examples/quick/demos/rssnews/content/ScrollBar.qml
@@ -1,51 +1,50 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtQml module of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** "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 Digia Plc 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.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
**
+** 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$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
Item {
id: container
property variant scrollArea
- property variant orientation: Qt.Vertical
+ property int orientation: Qt.Vertical
opacity: 0
@@ -56,7 +55,11 @@ Item {
ny = scrollArea.visibleArea.yPosition * container.height;
else
ny = scrollArea.visibleArea.xPosition * container.width;
- if (ny > 2) return ny; else return 2;
+
+ if (ny > 2)
+ return ny;
+ else
+ return 2;
}
function size()
@@ -79,8 +82,12 @@ Item {
t = Math.ceil(container.height - 3 - ny);
else
t = Math.ceil(container.width - 3 - ny);
- if (nh > t) return t; else return nh;
- } else return nh + ny;
+ if (nh > t)
+ return t;
+ else
+ return nh;
+ } else
+ return nh + ny;
}
Rectangle { anchors.fill: parent; color: "Black"; opacity: 0.3 }
@@ -89,14 +96,16 @@ Item {
source: "images/scrollbar.png"
border { left: 1; right: 1; top: 1; bottom: 1 }
x: container.orientation == Qt.Vertical ? 2 : position()
- width: container.orientation == Qt.Vertical ? container.width - 4 : size()
y: container.orientation == Qt.Vertical ? position() : 2
+ width: container.orientation == Qt.Vertical ? container.width - 4 : size()
height: container.orientation == Qt.Vertical ? size() : container.height - 4
}
states: State {
name: "visible"
- when: container.orientation == Qt.Vertical ? scrollArea.movingVertically : scrollArea.movingHorizontally
+ when: container.orientation == Qt.Vertical ?
+ scrollArea.movingVertically :
+ scrollArea.movingHorizontally
PropertyChanges { target: container; opacity: 1.0 }
}
diff --git a/examples/quick/demos/rssnews/content/images/Asia.jpg b/examples/quick/demos/rssnews/content/images/Asia.jpg
new file mode 100644
index 0000000000..a609557a08
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Asia.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Business.jpg b/examples/quick/demos/rssnews/content/images/Business.jpg
new file mode 100644
index 0000000000..b2c1d92138
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Business.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Entertainment.jpg b/examples/quick/demos/rssnews/content/images/Entertainment.jpg
new file mode 100644
index 0000000000..2c69fc04d7
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Entertainment.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Europe.jpg b/examples/quick/demos/rssnews/content/images/Europe.jpg
new file mode 100644
index 0000000000..bf524e13d0
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Europe.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Health.jpg b/examples/quick/demos/rssnews/content/images/Health.jpg
new file mode 100644
index 0000000000..0e8c71f0c9
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Health.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Politics.jpg b/examples/quick/demos/rssnews/content/images/Politics.jpg
new file mode 100644
index 0000000000..0b1800c97e
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Politics.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Science.jpg b/examples/quick/demos/rssnews/content/images/Science.jpg
new file mode 100644
index 0000000000..7faccbbb97
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Science.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Sports.jpg b/examples/quick/demos/rssnews/content/images/Sports.jpg
new file mode 100644
index 0000000000..0ab3bd3ce7
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Sports.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/Technology.jpg b/examples/quick/demos/rssnews/content/images/Technology.jpg
new file mode 100644
index 0000000000..db553028fb
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/Technology.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/TopStories.jpg b/examples/quick/demos/rssnews/content/images/TopStories.jpg
new file mode 100644
index 0000000000..e35bd67f20
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/TopStories.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/USNational.jpg b/examples/quick/demos/rssnews/content/images/USNational.jpg
new file mode 100644
index 0000000000..82c78228c1
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/USNational.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/World.jpg b/examples/quick/demos/rssnews/content/images/World.jpg
new file mode 100644
index 0000000000..7a0a806fd4
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/World.jpg
Binary files differ
diff --git a/examples/quick/demos/rssnews/content/images/btn_close.png b/examples/quick/demos/rssnews/content/images/btn_close.png
new file mode 100644
index 0000000000..6d635375eb
--- /dev/null
+++ b/examples/quick/demos/rssnews/content/images/btn_close.png
Binary files differ
diff --git a/examples/quick/demos/rssnews/doc/images/qtquick-demo-rssnews-small.png b/examples/quick/demos/rssnews/doc/images/qtquick-demo-rssnews-small.png
index 0ad6c02251..ffef99ee5c 100644
--- a/examples/quick/demos/rssnews/doc/images/qtquick-demo-rssnews-small.png
+++ b/examples/quick/demos/rssnews/doc/images/qtquick-demo-rssnews-small.png
Binary files differ
diff --git a/examples/quick/demos/rssnews/doc/src/rssnews.qdoc b/examples/quick/demos/rssnews/doc/src/rssnews.qdoc
index 12c7c0d19b..b1a2d03cc7 100644
--- a/examples/quick/demos/rssnews/doc/src/rssnews.qdoc
+++ b/examples/quick/demos/rssnews/doc/src/rssnews.qdoc
@@ -29,13 +29,344 @@
\title Qt Quick Demo - RSS News
\ingroup qtquickdemos
\example demos/rssnews
- \brief A QML RSS news reader.
+ \brief A QML RSS news reader that uses XmlListModel and XmlRole to download
+ XML data, ListModel and ListElement to create a category list, and ListView
+ to display the data.
+
\image qtquick-demo-rssnews-small.png
- \e{RSS News} demonstrates various QML and \l{Qt Quick} features such as
- loading XML data and displaying custom components.
+ \e{RSS News} demonstrates the following \l{Qt Quick} features:
+
+ \list
+ \li Using custom types to create screens and screen controls.
+ \li Using list models and list elements to represent data.
+ \li Using XML list models to download XML data.
+ \li Using list views to display data.
+ \li Using the \l Component type to create a footer for the news item
+ list view.
+ \li Using the \l Image type to create a button for closing the app.
+ \endlist
\include examples-run.qdocinc
+ \section1 Using Custom Types
+
+ In the RSS News app, we use the following custom types that are each defined
+ in a separate .qml file:
+
+ \list
+ \li \c BusyIndicator.qml
+ \li \c CategoryDelegate.qml
+ \li \c NewsDelegate.qml
+ \li \c RssFeeds.qml
+ \li \c ScrollBar.qml
+ \endlist
+
+ To use the custom types, we add an import statement to the main QML file,
+ rssnews.qml that imports the folder called \c content where the types are
+ located:
+
+ \quotefromfile demos/rssnews/rssnews.qml
+ \skipto content
+ \printuntil "
+
+ \section1 Creating the Main Window
+
+ In rssnews.qml, we use a \l{Rectangle} type with custom properties to create
+ the app main window:
+
+ \printuntil isPortrait
+
+ We will use the custom properties later for loading XML data and for
+ adjusting the screen layout depending on its orientation.
+
+ \section1 Creating a Category List
+
+ In rssnews.qml, we use the RssFeeds custom type that we specify in
+ RssFeeds.qml to create a list of feed categories:
+
+ \skipto RssFeeds
+ \printuntil }
+
+ In RssFeeds.qml, we use a ListModel type with a ListElement type to
+ create a category list where list elements represent feed categories:
+
+ \quotefromfile demos/rssnews/content/RssFeeds.qml
+ \skipto ListModel
+ \printuntil /^\}/
+
+ List elements are defined like other QML types except that they contain a
+ collection of \e role definitions instead of properties. Roles both define
+ how the data is accessed and include the data itself.
+
+ For each list element, we use the \c name role to specify the category name,
+ the \c feed role to specify the URL to load the data from, and the \c image
+ role to display an image for the category.
+
+ In rssnews.qml, we use a ListView type to display the category list:
+
+ \quotefromfile demos/rssnews/rssnews.qml
+ \skipto ListView
+ \printuntil }
+ \printuntil }
+
+ To lay out the category list horizontally at the top of the window in
+ portrait orientation and vertically on the left side in landscape
+ orientation, we use the \c orientation property. Based on the orientation,
+ we bind either the width or the height of the list to a fixed value
+ (\c itemWidth).
+
+ We use the \c anchors.top property to position the list view at the top of
+ the screen in both orientations.
+
+ We use the \c model property to load XML data from the \c rssFeeds model,
+ and \c CategoryDelegate as the delegate to instantiate each item in the
+ list.
+
+ \section1 Creating List Elements
+
+ In CategoryDelegate.qml, we use the \l Rectangle type with custom properties
+ to create list elements:
+
+ \quotefromfile demos/rssnews/content/CategoryDelegate.qml
+ \skipto Rectangle
+ \printuntil selected
+
+ We set the \c selected property to the \c ListView.isCurrentItem attached
+ property to specify that \c selected is \c true if \c delegate is the
+ current item.
+
+ We use the \l Image type \c source property to display the image, centered
+ in the delegate, specified for the list element by the \c image role in the
+ \c rssFeeds list model:
+
+ \skipto Image
+ \printuntil }
+
+ We use a \l Text type to add titles to list elements:
+
+ \printuntil Behavior
+ \printuntil }
+
+ We use the \c anchors property to position the title at the top of the list
+ element, with a 20-pixel margin. We use \c font properties to adjust font
+ size and text formatting.
+
+ We use the \c color property to brighten the text and to scale it slightly
+ larger when the list item is the current item. By applying a \l Behavior to
+ the property, we animate the actions of selecting and deselecting list
+ items.
+
+ We use a MouseArea type to download XML data when users tap a category list
+ element:
+
+ \skipto MouseArea
+ \printuntil }
+ \printuntil }
+
+ The \c anchors.fill property is set to \c delegate to enable users to tap
+ anywhere within the list element.
+
+ We use the \c onClicked signal handler to load the XML data for the category
+ list. If the tapped category is already current, the \c reload() function
+ is called to reload the data.
+
+ \section1 Downloading XML Data
+
+ In rssnews.qml, we use an XmlListModel type as a data source for ListView
+ elements to display news items in the selected category:
+
+ \quotefromfile demos/rssnews/rssnews.qml
+ \skipto XmlListModel {
+ \printuntil namespaceDeclarations
+
+ We use the \c source property and the \c window.currentFeed custom property
+ to fetch news items for the selected category.
+
+ The \c query property specifies that the XmlListModel generates a model item
+ for each \c <item> in the XML document.
+
+ We use the XmlRole type to specify the model item attributes. Each model
+ item has the \c title, \c description, \c image, \c link, and \c pubDate
+ attributes that match the values of the corresponding \c <item> in the XML
+ document:
+
+ \printuntil pubDate
+ \printuntil }
+
+ We use the \c feedModel model in a ListView type to display the data:
+
+ \skipuntil ScrollBar
+ \skipto ListView
+ \printuntil }
+ \printuntil }
+
+ To list the news items below the category list in portrait orientation and
+ to its right in landscape orientation, we use the \c isPortrait custom
+ property to anchor the top of the news items list to the left of \c window
+ and bottom of \c categories in portrait orientation and to the right of
+ \c categories and bottom of \c window in landscape orientation.
+
+ We use the \c anchors.bottom property to anchor the bottom of the list view
+ to the bottom of the window in both orientations.
+
+ In portrait orientation, we clip the painting of the news items to the
+ bounding rectangle of the list view to avoid graphical artifacts when news
+ items are scrolled over other items. In landscape, this is not required,
+ because the list spans the entire screen vertically.
+
+ We use the \c model property to load XML data from the \c feedModel model,
+ and use \c NewsDelegate as the delegate to instantiate each item in the
+ list.
+
+ In NewsDelegate.qml, we use a \l Column type to lay out the XML data:
+
+ \quotefromfile demos/rssnews/content/NewsDelegate.qml
+ \skipto Column
+ \printuntil spacing
+
+ Within the column, we use a \l Row and another column to position images and
+ title text:
+
+ \skipto Row
+ \printuntil font.bold
+ \printuntil }
+ \printuntil }
+
+ We generate a textual representation of how long ago the item was posted
+ using the \c timeSinceEvent() JavaScript function:
+
+ \printuntil }
+ \printuntil }
+
+ We use the \c onLinkActivated signal handler to open the URL in an external
+ browser when users select the link.
+
+ \section1 Providing Feedback to Users
+
+ In CategoryDelegate.qml, we use the \c BusyIndicator custom type to indicate
+ activity while the XML data is being loaded:
+
+ \quotefromfile demos/rssnews/content/CategoryDelegate.qml
+ \skipto BusyIndicator
+ \printuntil }
+
+ We use the \c scale property to reduce the indicator size to \c 0.8. We bind
+ the \c visible property to the \c isCurrentItem attached property of the
+ \c delegate list view and \c loading property of the main window to display
+ the indicator image when a category list item is the current item and XML
+ data is being loaded.
+
+ We define the \c BusyIndicator type in \c BusyIndicator.qml. We use an
+ \l Image type to display an image and apply a NumberAnimation to its
+ \c rotation property to rotate the image in an infinite loop:
+
+ \quotefromfile demos/rssnews/content/BusyIndicator.qml
+ \skipto Image
+ \printuntil }
+ \printuntil }
+
+ In your apps, you can also use the BusyIndicator type from the
+ \l {Qt Quick Controls} module.
+
+ \section1 Creating Scroll Bars
+
+ In rssnews.qml, we use our own custom \c ScrollBar type to create scroll
+ bars in the category and news item list views. In your apps, you can also
+ use the ScrollView type from the \l {Qt Quick Controls} module.
+
+ First, we create a scroll bar in the category list view. We bind the
+ \c orientation property to the \c isPortrait property and to the
+ \c Horizontal value of the \c Qt::Orientation enum type to display a
+ horizontal scroll bar in portrait orientation and to the \c Vertical value
+ to display a vertical scroll bar in landscape orientation:
+
+ \quotefromfile demos/rssnews/rssnews.qml
+ \skipto ScrollBar
+ \printuntil }
+
+ Same as with the \c categories list view, we adjust the width and height of
+ the scroll bar based on the \c isPortrait property.
+
+ We use the \c scrollArea property to display the scroll bar in the
+ \c categories list view.
+
+ We use the \c anchors.right property to anchor the scroll bar to the right
+ side of the category list.
+
+ \skipto ScrollBar
+ \printuntil }
+
+ Second, we create another scroll bar in the news item list view. We want a
+ vertical scroll bar to appear on the right side of the view regardless of
+ screen orientation, so we can set the \c width property to \c 8 and bind the
+ \c anchors.right property to the \c window.right property. We use the
+ \c anchors.top property to anchor the scroll bar top to the bottom of the
+ category list in portrait orientation and to the top of the news item list
+ in landscape orientation. We use the \c anchors.bottom property to anchor
+ the scroll bar bottom to the list view bottom in both orientations.
+
+ We define the \c ScrollBar type in \c ScrollBar.qml. We use an \l Item type
+ with custom properties to create a container for the scroll bar:
+
+ \quotefromfile demos/rssnews/content/ScrollBar.qml
+ \skipto Item
+ \printuntil opacity
+
+ We use a BorderImage type to display the scroll bar thumb at the x and y
+ position that we calculate by using the \c position() function:
+
+ \skipto BorderImage
+ \printuntil height
+ \printuntil }
+
+ We use the \c size function to calculate the thumb width and height
+ depending on the screen orientation.
+
+ We use \c states to make the scroll bar visible when the users move the
+ scroll area:
+
+ \printuntil }
+ \printuntil }
+
+ We use \c transitions to apply a NumberAnimation to the \c "opacity"
+ property when the state changes from "visible" to the default state:
+
+ \printuntil /^\}/
+
+ \section1 Creating Footers
+
+ In rssnews.qml, we use a \l Component type with a \l Rectangle type to
+ create a footer for the news list view:
+
+ \quotefromfile demos/rssnews/rssnews.qml
+ \skipto Component
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We bind the \c width of the footer to the width of the component and the
+ \c height to the of close button to align them when no news items are
+ displayed.
+
+ \section1 Creating Buttons
+
+ In rssnews.qml, we use an \l Image type to create a simple push button that
+ users can tap to close the app:
+
+ \printuntil Qt.quit()
+ \printuntil }
+ \printuntil }
+ \printuntil }
+
+ We use \c anchors to position the close button in the top right corner of
+ the news list view, with 4-pixel margins. Because the close button overlaps
+ the category list in portrait orientation, we animate the \c opacity
+ property to make the button almost fully transparent when users are
+ scrolling the category list.
+
+ We use the \c onClicked signal handler within a MouseArea to call the
+ \c quit() function when users select the close button.
+
\sa {QML Applications}
*/
diff --git a/examples/quick/demos/calqlatr/content/StyleLabel.qml b/examples/quick/demos/rssnews/main.cpp
index ff4e10a932..0064412f39 100644
--- a/examples/quick/demos/calqlatr/content/StyleLabel.qml
+++ b/examples/quick/demos/rssnews/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
@@ -37,14 +37,5 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-import QtQuick 2.0
-
-Text {
- width: 64
- font.pixelSize: 14
- font.bold: false
- wrapMode: Text.WordWrap
- lineHeight: 0.75
- color: "#676764"
-}
+#include "../../shared/shared.h"
+DECLARATIVE_EXAMPLE_MAIN(demos/rssnews/rssnews)
diff --git a/examples/quick/demos/rssnews/rssnews.pro b/examples/quick/demos/rssnews/rssnews.pro
new file mode 100644
index 0000000000..c67c5a6558
--- /dev/null
+++ b/examples/quick/demos/rssnews/rssnews.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+QT += quick qml xml xmlpatterns
+SOURCES += main.cpp
+RESOURCES += rssnews.qrc
+
+OTHER_FILES = rssnews.qml \
+ content/*.qml \
+ content/*.js \
+ content/images/*
+
+target.path = $$[QT_INSTALL_EXAMPLES]/quick/demos/rssnews
+INSTALLS += target
diff --git a/examples/quick/demos/rssnews/rssnews.qml b/examples/quick/demos/rssnews/rssnews.qml
index a367490ef7..cb9734208d 100644
--- a/examples/quick/demos/rssnews/rssnews.qml
+++ b/examples/quick/demos/rssnews/rssnews.qml
@@ -1,112 +1,159 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtQml module of the Qt Toolkit.
+** This file is part of the examples of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** "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 Digia Plc 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.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
**
+** 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$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.2
import QtQuick.XmlListModel 2.0
-import "content"
+import QtQuick.Window 2.1
+import "./content"
Rectangle {
id: window
- width: 800; height: 480
- property string currentFeed: "rss.news.yahoo.com/rss/topstories"
- property bool loading: feedModel.status == XmlListModel.Loading
+ width: 800
+ height: 480
+
+ property string currentFeed: rssFeeds.get(0).feed
+ property bool loading: feedModel.status === XmlListModel.Loading
+ property bool isPortrait: Screen.primaryOrientation === Qt.PortraitOrientation
+
+ onLoadingChanged: {
+ if (feedModel.status == XmlListModel.Ready)
+ list.positionViewAtBeginning()
+ }
RssFeeds { id: rssFeeds }
XmlListModel {
id: feedModel
+
source: "http://" + window.currentFeed
- query: "/rss/channel/item"
+ query: "/rss/channel/item[child::media:content]"
+ namespaceDeclarations: "declare namespace media = 'http://search.yahoo.com/mrss/';"
XmlRole { name: "title"; query: "title/string()" }
+ // Remove any links from the description
+ XmlRole { name: "description"; query: "fn:replace(description/string(), '\&lt;a href=.*\/a\&gt;', '')" }
+ XmlRole { name: "image"; query: "media:content/@url/string()" }
XmlRole { name: "link"; query: "link/string()" }
- XmlRole { name: "description"; query: "description/string()" }
+ XmlRole { name: "pubDate"; query: "pubDate/string()" }
}
- Row {
- Rectangle {
- width: 220; height: window.height
- color: "#efefef"
-
- ListView {
- focus: true
- id: categories
- anchors.fill: parent
- model: rssFeeds
- footer: quitButtonDelegate
- delegate: CategoryDelegate {}
- highlight: Rectangle { color: "steelblue" }
- highlightMoveVelocity: 9999999
- }
- ScrollBar {
- scrollArea: categories; height: categories.height; width: 8
- anchors.right: categories.right
- }
- }
- ListView {
- id: list
- width: window.width - 220; height: window.height
- model: feedModel
- delegate: NewsDelegate {}
- }
+ ListView {
+ id: categories
+ property int itemWidth: 190
+
+ width: isPortrait ? parent.width : itemWidth
+ height: isPortrait ? itemWidth : parent.height
+ orientation: isPortrait ? ListView.Horizontal : ListView.Vertical
+ anchors.top: parent.top
+ model: rssFeeds
+ delegate: CategoryDelegate { itemSize: categories.itemWidth }
+ spacing: 3
+ }
+
+ ScrollBar {
+ id: listScrollBar
+
+ orientation: isPortrait ? Qt.Horizontal : Qt.Vertical
+ height: isPortrait ? 8 : categories.height;
+ width: isPortrait ? categories.width : 8
+ scrollArea: categories;
+ anchors.right: categories.right
}
+
+ ListView {
+ id: list
+
+ anchors.left: isPortrait ? window.left : categories.right
+ anchors.right: closeButton.left
+ anchors.top: isPortrait ? categories.bottom : window.top
+ anchors.bottom: window.bottom
+ anchors.leftMargin: 30
+ anchors.rightMargin: 4
+ clip: isPortrait
+ model: feedModel
+ footer: footerText
+ delegate: NewsDelegate {}
+ }
+
+ ScrollBar {
+ scrollArea: list
+ width: 8
+ anchors.right: window.right
+ anchors.top: isPortrait ? categories.bottom : window.top
+ anchors.bottom: window.bottom
+ }
+
Component {
- id: quitButtonDelegate
- Item {
- width: categories.width; height: 60
+ id: footerText
+
+ Rectangle {
+ width: parent.width
+ height: closeButton.height
+ color: "lightgray"
+
Text {
- text: "Quit"
- font { family: "Helvetica"; pixelSize: 16; bold: true }
- anchors {
- left: parent.left; leftMargin: 15
- verticalCenter: parent.verticalCenter
- }
+ text: "RSS Feed from Yahoo News"
+ anchors.centerIn: parent
+ font.pixelSize: 14
}
- MouseArea {
- anchors.fill: parent
- onClicked: Qt.quit()
+ }
+ }
+
+ Image {
+ id: closeButton
+ source: "content/images/btn_close.png"
+ scale: 0.8
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.margins: 4
+ opacity: (isPortrait && categories.moving) ? 0.2 : 1.0
+ Behavior on opacity {
+ NumberAnimation { duration: 300; easing.type: Easing.OutSine }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ Qt.quit()
}
}
}
- ScrollBar { scrollArea: list; height: list.height; width: 8; anchors.right: window.right }
- Rectangle { x: 220; height: window.height; width: 1; color: "#cccccc" }
}
diff --git a/examples/quick/demos/rssnews/rssnews.qrc b/examples/quick/demos/rssnews/rssnews.qrc
new file mode 100644
index 0000000000..1208d44fd7
--- /dev/null
+++ b/examples/quick/demos/rssnews/rssnews.qrc
@@ -0,0 +1,25 @@
+<RCC>
+ <qresource prefix="/demos/rssnews">
+ <file>rssnews.qml</file>
+ <file>content/BusyIndicator.qml</file>
+ <file>content/CategoryDelegate.qml</file>
+ <file>content/NewsDelegate.qml</file>
+ <file>content/RssFeeds.qml</file>
+ <file>content/ScrollBar.qml</file>
+ <file>content/images/btn_close.png</file>
+ <file>content/images/Business.jpg</file>
+ <file>content/images/busy.png</file>
+ <file>content/images/Entertainment.jpg</file>
+ <file>content/images/Europe.jpg</file>
+ <file>content/images/Health.jpg</file>
+ <file>content/images/Asia.jpg</file>
+ <file>content/images/Politics.jpg</file>
+ <file>content/images/Science.jpg</file>
+ <file>content/images/scrollbar.png</file>
+ <file>content/images/Sports.jpg</file>
+ <file>content/images/Technology.jpg</file>
+ <file>content/images/TopStories.jpg</file>
+ <file>content/images/USNational.jpg</file>
+ <file>content/images/World.jpg</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/imageprovider/doc/images/qml-imageprovider-example.png b/examples/quick/imageprovider/doc/images/qml-imageprovider-example.png
new file mode 100644
index 0000000000..e82548ae81
--- /dev/null
+++ b/examples/quick/imageprovider/doc/images/qml-imageprovider-example.png
Binary files differ
diff --git a/examples/quick/imageprovider/doc/src/imageprovider.qdoc b/examples/quick/imageprovider/doc/src/imageprovider.qdoc
new file mode 100644
index 0000000000..d25eeae672
--- /dev/null
+++ b/examples/quick/imageprovider/doc/src/imageprovider.qdoc
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \title C++ Extensions: Image Provider Example
+ \example imageprovider
+
+ This examples shows how to use QQuickImageProvider to serve images
+ to QML image elements.
+
+ \image qml-imageprovider-example.png
+*/
+
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
new file mode 100644
index 0000000000..3b9f2e97f3
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 "fbitem.h"
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLFunctions>
+#include <QMatrix4x4>
+
+FbItem::FbItem(QQuickItem *parent)
+ : QQuickFramebufferObject(parent),
+ m_target(0, 0, -1),
+ m_syncState(AllNeedsSync),
+ m_multisample(false)
+{
+}
+
+QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
+{
+ return new FbItemRenderer(m_multisample);
+}
+
+void FbItem::setEye(const QVector3D &v)
+{
+ if (m_eye != v) {
+ m_eye = v;
+ m_syncState |= CameraNeedsSync;
+ update();
+ }
+}
+
+void FbItem::setTarget(const QVector3D &v)
+{
+ if (m_target != v) {
+ m_target = v;
+ m_syncState |= CameraNeedsSync;
+ update();
+ }
+}
+
+void FbItem::setRotation(const QVector3D &v)
+{
+ if (m_rotation != v) {
+ m_rotation = v;
+ m_syncState |= RotationNeedsSync;
+ update();
+ }
+}
+
+int FbItem::swapSyncState()
+{
+ int s = m_syncState;
+ m_syncState = 0;
+ return s;
+}
+
+FbItemRenderer::FbItemRenderer(bool multisample)
+ : m_inited(false),
+ m_multisample(multisample),
+ m_dirty(DirtyAll)
+{
+ m_camera.setToIdentity();
+ m_baseWorld.setToIdentity();
+ m_baseWorld.translate(0, 0, -1);
+ m_world = m_baseWorld;
+}
+
+void FbItemRenderer::synchronize(QQuickFramebufferObject *qfbitem)
+{
+ FbItem *item = static_cast<FbItem *>(qfbitem);
+ int syncState = item->swapSyncState();
+ if (syncState & FbItem::CameraNeedsSync) {
+ m_camera.setToIdentity();
+ m_camera.lookAt(item->eye(), item->eye() + item->target(), QVector3D(0, 1, 0));
+ m_dirty |= DirtyCamera;
+ }
+ if (syncState & FbItem::RotationNeedsSync) {
+ m_rotation = item->rotation();
+ m_dirty |= DirtyWorld;
+ }
+}
+
+struct StateBinder
+{
+ StateBinder(FbItemRenderer *r)
+ : m_r(r) {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glEnable(GL_DEPTH_TEST);
+ f->glEnable(GL_CULL_FACE);
+ f->glDepthMask(GL_TRUE);
+ f->glDepthFunc(GL_LESS);
+ f->glFrontFace(GL_CCW);
+ f->glCullFace(GL_BACK);
+ m_r->m_program->bind();
+ }
+ ~StateBinder() {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ m_r->m_program->release();
+ f->glDisable(GL_CULL_FACE);
+ f->glDisable(GL_DEPTH_TEST);
+ }
+ FbItemRenderer *m_r;
+};
+
+void FbItemRenderer::updateDirtyUniforms()
+{
+ if (m_dirty & DirtyProjection)
+ m_program->setUniformValue(m_projMatrixLoc, m_proj);
+
+ if (m_dirty & DirtyCamera)
+ m_program->setUniformValue(m_camMatrixLoc, m_camera);
+
+ if (m_dirty & DirtyWorld) {
+ m_program->setUniformValue(m_worldMatrixLoc, m_world);
+ QMatrix3x3 normalMatrix = m_world.normalMatrix();
+ m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
+ }
+
+ if (m_dirty & DirtyLight)
+ m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
+
+ m_dirty = 0;
+}
+
+void FbItemRenderer::render()
+{
+ ensureInit();
+
+ QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
+ if (!m_vao.isCreated())
+ setupVertexAttribs();
+
+ StateBinder state(this);
+
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glClearColor(0, 0, 0, 0);
+ f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (m_dirty & DirtyWorld) {
+ m_world = m_baseWorld;
+ m_world.rotate(m_rotation.x(), 1, 0, 0);
+ m_world.rotate(m_rotation.y(), 0, 1, 0);
+ m_world.rotate(m_rotation.z(), 0, 0, 1);
+ }
+
+ updateDirtyUniforms();
+
+ f->glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
+}
+
+QOpenGLFramebufferObject *FbItemRenderer::createFramebufferObject(const QSize &size)
+{
+ m_dirty |= DirtyProjection;
+ m_proj.setToIdentity();
+ m_proj.perspective(45.0f, GLfloat(size.width()) / size.height(), 0.01f, 100.0f);
+
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ format.setSamples(m_multisample ? 4 : 0);
+ return new QOpenGLFramebufferObject(size, format);
+}
+
+void FbItemRenderer::ensureInit()
+{
+ if (m_inited)
+ return;
+
+ m_inited = true;
+
+ initBuf();
+ initProgram();
+}
+
+void FbItemRenderer::initBuf()
+{
+ m_vao.create();
+ QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
+
+ m_logoVbo.create();
+ m_logoVbo.bind();
+ m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
+
+ setupVertexAttribs();
+}
+
+void FbItemRenderer::setupVertexAttribs()
+{
+ m_logoVbo.bind();
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glEnableVertexAttribArray(0);
+ f->glEnableVertexAttribArray(1);
+ f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
+ f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
+ m_logoVbo.release();
+}
+
+static const char *vertexShaderSource =
+ "attribute vec4 vertex;\n"
+ "attribute vec3 normal;\n"
+ "varying vec3 vert;\n"
+ "varying vec3 vertNormal;\n"
+ "uniform mat4 projMatrix;\n"
+ "uniform mat4 camMatrix;\n"
+ "uniform mat4 worldMatrix;\n"
+ "uniform mat3 normalMatrix;\n"
+ "void main() {\n"
+ " vert = vertex.xyz;\n"
+ " vertNormal = normalMatrix * normal;\n"
+ " gl_Position = projMatrix * camMatrix * worldMatrix * vertex;\n"
+ "}\n";
+
+static const char *fragmentShaderSource =
+ "varying highp vec3 vert;\n"
+ "varying highp vec3 vertNormal;\n"
+ "uniform highp vec3 lightPos;\n"
+ "void main() {\n"
+ " highp vec3 L = normalize(lightPos - vert);\n"
+ " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
+ " highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
+ " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
+ " gl_FragColor = vec4(col, 1.0);\n"
+ "}\n";
+
+void FbItemRenderer::initProgram()
+{
+ m_program.reset(new QOpenGLShaderProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->bindAttributeLocation("vertex", 0);
+ m_program->bindAttributeLocation("normal", 1);
+ m_program->link();
+ m_projMatrixLoc = m_program->uniformLocation("projMatrix");
+ m_camMatrixLoc = m_program->uniformLocation("camMatrix");
+ m_worldMatrixLoc = m_program->uniformLocation("worldMatrix");
+ m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
+ m_lightPosLoc = m_program->uniformLocation("lightPos");
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
new file mode 100644
index 0000000000..b29998c253
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 FBITEM_H
+#define FBITEM_H
+
+#include <QQuickFramebufferObject>
+#include <QOpenGLVertexArrayObject>
+#include <QOpenGLBuffer>
+#include <QOpenGLShaderProgram>
+#include <QVector3D>
+#include "logo.h"
+
+struct StateBinder;
+
+class FbItemRenderer : public QQuickFramebufferObject::Renderer
+{
+public:
+ FbItemRenderer(bool multisample);
+ void synchronize(QQuickFramebufferObject *item) Q_DECL_OVERRIDE;
+ void render() Q_DECL_OVERRIDE;
+ QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) Q_DECL_OVERRIDE;
+
+private:
+ void ensureInit();
+ void initBuf();
+ void setupVertexAttribs();
+ void initProgram();
+ void updateDirtyUniforms();
+
+ bool m_inited;
+ bool m_multisample;
+ QMatrix4x4 m_proj;
+ QMatrix4x4 m_camera;
+ QMatrix4x4 m_baseWorld;
+ QMatrix4x4 m_world;
+ QOpenGLVertexArrayObject m_vao;
+ QOpenGLBuffer m_logoVbo;
+ Logo m_logo;
+ QScopedPointer<QOpenGLShaderProgram> m_program;
+ int m_projMatrixLoc;
+ int m_camMatrixLoc;
+ int m_worldMatrixLoc;
+ int m_normalMatrixLoc;
+ int m_lightPosLoc;
+ QVector3D m_rotation;
+
+ enum Dirty {
+ DirtyProjection = 0x01,
+ DirtyCamera = 0x02,
+ DirtyWorld = 0x04,
+ DirtyLight = 0x08,
+ DirtyAll = 0xFF
+ };
+ int m_dirty;
+
+ friend struct StateBinder;
+};
+
+class FbItem : public QQuickFramebufferObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector3D eye READ eye WRITE setEye)
+ Q_PROPERTY(QVector3D target READ target WRITE setTarget)
+ Q_PROPERTY(QVector3D rotation READ rotation WRITE setRotation)
+ Q_PROPERTY(bool multisample READ multisample WRITE setMultisample)
+
+public:
+ explicit FbItem(QQuickItem *parent = 0);
+
+ QQuickFramebufferObject::Renderer *createRenderer() const Q_DECL_OVERRIDE;
+
+ QVector3D eye() const { return m_eye; }
+ void setEye(const QVector3D &v);
+ QVector3D target() const { return m_target; }
+ void setTarget(const QVector3D &v);
+
+ QVector3D rotation() const { return m_rotation; }
+ void setRotation(const QVector3D &v);
+
+ enum SyncState {
+ CameraNeedsSync = 0x01,
+ RotationNeedsSync = 0x02,
+ AllNeedsSync = 0xFF
+ };
+ int swapSyncState();
+
+ bool multisample() const { return m_multisample; }
+ void setMultisample(bool m) { m_multisample = m; }
+
+private:
+ QVector3D m_eye;
+ QVector3D m_target;
+ QVector3D m_rotation;
+ int m_syncState;
+ bool m_multisample;
+};
+
+#endif // FBITEM_H
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/logo.cpp b/examples/quick/quickwidgets/qquickviewcomparison/logo.cpp
new file mode 100644
index 0000000000..1ba47ddfb5
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/logo.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 "logo.h"
+#include <qmath.h>
+
+Logo::Logo()
+ : m_count(0)
+{
+ m_data.resize(2500 * 6);
+
+ const GLfloat x1 = +0.06f;
+ const GLfloat y1 = -0.14f;
+ const GLfloat x2 = +0.14f;
+ const GLfloat y2 = -0.06f;
+ const GLfloat x3 = +0.08f;
+ const GLfloat y3 = +0.00f;
+ const GLfloat x4 = +0.30f;
+ const GLfloat y4 = +0.22f;
+
+ quad(x1, y1, x2, y2, y2, x2, y1, x1);
+ quad(x3, y3, x4, y4, y4, x4, y3, x3);
+
+ extrude(x1, y1, x2, y2);
+ extrude(x2, y2, y2, x2);
+ extrude(y2, x2, y1, x1);
+ extrude(y1, x1, x1, y1);
+ extrude(x3, y3, x4, y4);
+ extrude(x4, y4, y4, x4);
+ extrude(y4, x4, y3, x3);
+
+ const int NumSectors = 100;
+
+ for (int i = 0; i < NumSectors; ++i) {
+ GLfloat angle = (i * 2 * M_PI) / NumSectors;
+ GLfloat angleSin = qSin(angle);
+ GLfloat angleCos = qCos(angle);
+ const GLfloat x5 = 0.30f * angleSin;
+ const GLfloat y5 = 0.30f * angleCos;
+ const GLfloat x6 = 0.20f * angleSin;
+ const GLfloat y6 = 0.20f * angleCos;
+
+ angle = ((i + 1) * 2 * M_PI) / NumSectors;
+ angleSin = qSin(angle);
+ angleCos = qCos(angle);
+ const GLfloat x7 = 0.20f * angleSin;
+ const GLfloat y7 = 0.20f * angleCos;
+ const GLfloat x8 = 0.30f * angleSin;
+ const GLfloat y8 = 0.30f * angleCos;
+
+ quad(x5, y5, x6, y6, x7, y7, x8, y8);
+
+ extrude(x6, y6, x7, y7);
+ extrude(x8, y8, x5, y5);
+ }
+}
+
+void Logo::add(const QVector3D &v, const QVector3D &n)
+{
+ GLfloat *p = m_data.data() + m_count;
+ *p++ = v.x();
+ *p++ = v.y();
+ *p++ = v.z();
+ *p++ = n.x();
+ *p++ = n.y();
+ *p++ = n.z();
+ m_count += 6;
+}
+
+void Logo::quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4)
+{
+ QVector3D n = QVector3D::normal(QVector3D(x4 - x1, y4 - y1, 0.0f), QVector3D(x2 - x1, y2 - y1, 0.0f));
+
+ add(QVector3D(x1, y1, -0.05f), n);
+ add(QVector3D(x4, y4, -0.05f), n);
+ add(QVector3D(x2, y2, -0.05f), n);
+
+ add(QVector3D(x3, y3, -0.05f), n);
+ add(QVector3D(x2, y2, -0.05f), n);
+ add(QVector3D(x4, y4, -0.05f), n);
+
+ n = QVector3D::normal(QVector3D(x1 - x4, y1 - y4, 0.0f), QVector3D(x2 - x4, y2 - y4, 0.0f));
+
+ add(QVector3D(x4, y4, 0.05f), n);
+ add(QVector3D(x1, y1, 0.05f), n);
+ add(QVector3D(x2, y2, 0.05f), n);
+
+ add(QVector3D(x2, y2, 0.05f), n);
+ add(QVector3D(x3, y3, 0.05f), n);
+ add(QVector3D(x4, y4, 0.05f), n);
+}
+
+void Logo::extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ QVector3D n = QVector3D::normal(QVector3D(0.0f, 0.0f, -0.1f), QVector3D(x2 - x1, y2 - y1, 0.0f));
+
+ add(QVector3D(x1, y1, +0.05f), n);
+ add(QVector3D(x1, y1, -0.05f), n);
+ add(QVector3D(x2, y2, +0.05f), n);
+
+ add(QVector3D(x2, y2, -0.05f), n);
+ add(QVector3D(x2, y2, +0.05f), n);
+ add(QVector3D(x1, y1, -0.05f), n);
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/logo.h b/examples/quick/quickwidgets/qquickviewcomparison/logo.h
new file mode 100644
index 0000000000..29bb7fa241
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/logo.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 LOGO_H
+#define LOGO_H
+
+#include <qopengl.h>
+#include <QVector>
+#include <QVector3D>
+
+class Logo
+{
+public:
+ Logo();
+ const GLfloat *constData() const { return m_data.constData(); }
+ int count() const { return m_count; }
+ int vertexCount() const { return m_count / 6; }
+
+private:
+ void quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4);
+ void extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+ void add(const QVector3D &v, const QVector3D &n);
+
+ QVector<GLfloat> m_data;
+ int m_count;
+};
+
+#endif // LOGO_H
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/main.cpp b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
new file mode 100644
index 0000000000..5f006c3fb6
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char **argv)
+{
+ qputenv("QML_BAD_GUI_RENDER_LOOP", "1"); // QTBUG-39507
+
+ QApplication app(argc, argv);
+
+ MainWindow widgetWindow;
+ widgetWindow.resize(1024, 768);
+ widgetWindow.show();
+
+ return app.exec();
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
new file mode 100644
index 0000000000..dbf4121518
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 "mainwindow.h"
+#include "fbitem.h"
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QLabel>
+#include <QQuickItem>
+
+MainWindow::MainWindow()
+ : m_currentView(0),
+ m_currentRootObject(0)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+
+ QGroupBox *groupBox = new QGroupBox(tr("Type"));
+ QVBoxLayout *vbox = new QVBoxLayout;
+ m_radioView = new QRadioButton(tr("QQuickView in a window container (direct)"));
+ m_radioWidget = new QRadioButton(tr("QQuickWidget (indirect through framebuffer objects)"));
+ vbox->addWidget(m_radioView);
+ vbox->addWidget(m_radioWidget);
+ m_radioView->setChecked(true);
+ connect(m_radioView, &QRadioButton::toggled, this, &MainWindow::updateView);
+ connect(m_radioWidget, &QRadioButton::toggled, this, &MainWindow::updateView);
+ groupBox->setLayout(vbox);
+
+ layout->addWidget(groupBox);
+
+ m_checkboxMultiSample = new QCheckBox(tr("Multisample (4x)"));
+ connect(m_checkboxMultiSample, &QCheckBox::toggled, this, &MainWindow::updateView);
+ layout->addWidget(m_checkboxMultiSample);
+
+ m_labelStatus = new QLabel;
+ layout->addWidget(m_labelStatus);
+
+ qmlRegisterType<FbItem>("fbitem", 1, 0, "FbItem");
+
+ QWidget *quickContainer = new QWidget;
+ layout->addWidget(quickContainer);
+ layout->setStretchFactor(quickContainer, 8);
+ m_containerLayout = new QVBoxLayout;
+ quickContainer->setLayout(m_containerLayout);
+
+ // Add an overlay widget to demonstrate that it will _not_ work with
+ // QQuickView, whereas it is perfectly fine with QQuickWidget.
+ QPalette semiTransparent(QColor(255,0,0,128));
+ semiTransparent.setBrush(QPalette::Text, Qt::white);
+ semiTransparent.setBrush(QPalette::WindowText, Qt::white);
+
+ m_overlayLabel = new QLabel("This is a\nsemi-transparent\n overlay widget\nwhich is placed\non top\n of the Quick\ncontent.", this);
+ m_overlayLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
+ m_overlayLabel->setAutoFillBackground(true);
+ m_overlayLabel->setPalette(semiTransparent);
+ QFont f = font();
+ f.setPixelSize(QFontInfo(f).pixelSize()*2);
+ f.setWeight(QFont::Bold);
+ m_overlayLabel->setFont(f);
+ m_overlayLabel->hide();
+
+ m_checkboxOverlayVisible = new QCheckBox(tr("Show widget overlay"));
+ connect(m_checkboxOverlayVisible, &QCheckBox::toggled, m_overlayLabel, &QWidget::setVisible);
+ layout->addWidget(m_checkboxOverlayVisible);
+
+ setLayout(layout);
+
+ updateView();
+}
+
+void MainWindow::resizeEvent(QResizeEvent*)
+{
+ int margin = width() / 10;
+ int top = m_checkboxMultiSample->y();
+ int bottom = m_checkboxOverlayVisible->geometry().bottom();
+ m_overlayLabel->setGeometry(margin, top, width() - 2 * margin, bottom - top);
+}
+
+void MainWindow::switchTo(QWidget *view)
+{
+ if (m_containerLayout->count())
+ m_containerLayout->takeAt(0);
+
+ delete m_currentView;
+ m_currentView = view;
+ m_containerLayout->addWidget(m_currentView);
+ m_currentView->setFocus();
+}
+
+void MainWindow::updateView()
+{
+ QString text = m_currentRootObject
+ ? m_currentRootObject->property("currentText").toString()
+ : QStringLiteral("Hello Qt");
+
+ QUrl source("qrc:qquickviewcomparison/test.qml");
+ QSurfaceFormat format;
+ format.setDepthBufferSize(16);
+ format.setStencilBufferSize(8);
+ if (m_checkboxMultiSample->isChecked())
+ format.setSamples(4);
+
+ if (m_radioView->isChecked()) {
+ QQuickView *quickView = new QQuickView;
+ quickView->setFormat(format);
+ quickView->setResizeMode(QQuickView::SizeRootObjectToView);
+ connect(quickView, &QQuickView::statusChanged, this, &MainWindow::onStatusChangedView);
+ connect(quickView, &QQuickView::sceneGraphError, this, &MainWindow::onSceneGraphError);
+ quickView->setSource(source);
+ m_currentRootObject = quickView->rootObject();
+ switchTo(QWidget::createWindowContainer(quickView));
+ } else {
+ QQuickWidget *quickWidget = new QQuickWidget;
+ quickWidget->setFormat(format);
+ quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ connect(quickWidget, &QQuickWidget::statusChanged, this, &MainWindow::onStatusChangedWidget);
+ connect(quickWidget, &QQuickWidget::sceneGraphError, this, &MainWindow::onSceneGraphError);
+ quickWidget->setSource(source);
+ m_currentRootObject = quickWidget->rootObject();
+ switchTo(quickWidget);
+ }
+
+ m_currentRootObject->setProperty("currentText", text);
+ m_currentRootObject->setProperty("multisample", m_checkboxMultiSample->isChecked());
+
+ m_overlayLabel->raise();
+}
+
+void MainWindow::onStatusChangedView(QQuickView::Status status)
+{
+ QString s;
+ switch (status) {
+ case QQuickView::Null:
+ s = tr("Null");
+ break;
+ case QQuickView::Ready:
+ s = tr("Ready");
+ break;
+ case QQuickView::Loading:
+ s = tr("Loading");
+ break;
+ case QQuickView::Error:
+ s = tr("Error");
+ break;
+ default:
+ s = tr("Unknown");
+ break;
+ }
+ m_labelStatus->setText(tr("QQuickView status: %1").arg(s));
+}
+
+void MainWindow::onStatusChangedWidget(QQuickWidget::Status status)
+{
+ QString s;
+ switch (status) {
+ case QQuickWidget::Null:
+ s = tr("Null");
+ break;
+ case QQuickWidget::Ready:
+ s = tr("Ready");
+ break;
+ case QQuickWidget::Loading:
+ s = tr("Loading");
+ break;
+ case QQuickWidget::Error:
+ s = tr("Error");
+ break;
+ default:
+ s = tr("Unknown");
+ break;
+ }
+ m_labelStatus->setText(tr("QQuickWidget status: %1").arg(s));
+}
+
+void MainWindow::onSceneGraphError(QQuickWindow::SceneGraphError error, const QString &message)
+{
+ m_labelStatus->setText(tr("Scenegraph error %1: %2").arg(error).arg(message));
+}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
new file mode 100644
index 0000000000..c7bd514d81
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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 MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QWidget>
+#include <QQuickWidget>
+#include <QQuickView>
+
+QT_FORWARD_DECLARE_CLASS(QRadioButton)
+QT_FORWARD_DECLARE_CLASS(QCheckBox)
+QT_FORWARD_DECLARE_CLASS(QLabel)
+QT_FORWARD_DECLARE_CLASS(QLayout)
+
+class MainWindow : public QWidget
+{
+public:
+ MainWindow();
+
+protected:
+ void resizeEvent(QResizeEvent*);
+private slots:
+ void updateView();
+ void onStatusChangedView(QQuickView::Status status);
+ void onStatusChangedWidget(QQuickWidget::Status status);
+ void onSceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
+
+private:
+ void switchTo(QWidget *view);
+
+ QRadioButton *m_radioView;
+ QRadioButton *m_radioWidget;
+ QCheckBox *m_checkboxMultiSample;
+ QLabel *m_labelStatus;
+ QLayout *m_containerLayout;
+ QWidget *m_currentView;
+ QObject *m_currentRootObject;
+ QLabel *m_overlayLabel;
+ QCheckBox *m_checkboxOverlayVisible;
+};
+
+#endif
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro
new file mode 100644
index 0000000000..9d70f7aa5a
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+TARGET = qquickviewcomparison
+
+QT += quick widgets quickwidgets
+
+SOURCES += main.cpp \
+ mainwindow.cpp \
+ logo.cpp \
+ fbitem.cpp
+
+HEADERS += mainwindow.h \
+ logo.h \
+ fbitem.h
+
+RESOURCES += qquickviewcomparison.qrc
+
+OTHER_FILES += test.qml
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc
new file mode 100644
index 0000000000..2b259fdeec
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qquickviewcomparison">
+ <file>test.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/test.qml b/examples/quick/quickwidgets/qquickviewcomparison/test.qml
new file mode 100644
index 0000000000..2e8c83024a
--- /dev/null
+++ b/examples/quick/quickwidgets/qquickviewcomparison/test.qml
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+import QtQuick.Particles 2.0
+import fbitem 1.0
+
+Rectangle {
+ id: root
+ color: "lightBlue"
+ property alias currentText: edit.text
+ property alias multisample: fbitem.multisample
+
+ ParticleSystem {
+ anchors.fill: parent
+ running: true
+
+ ImageParticle {
+ source: "qrc:///particleresources/glowdot.png"
+ alpha: 0
+ colorVariation: 1
+ }
+
+ Emitter {
+ anchors.fill: parent
+ lifeSpan: 3000
+ emitRate: 30
+ size: 50
+ sizeVariation: 10
+ velocity: PointDirection { xVariation: 10; yVariation: 10; }
+ acceleration: PointDirection {
+ y: -10
+ xVariation: 5
+ yVariation: 5
+ }
+ }
+ }
+
+ Rectangle {
+ y: 10
+ width: parent.width / 2
+ height: edit.contentHeight + 4
+ anchors.horizontalCenter: parent.horizontalCenter
+ border.color: "gray"
+ border.width: 2
+ radius: 8
+ color: "lightGray"
+ clip: true
+ TextInput {
+ id: edit
+ anchors.horizontalCenter: parent.horizontalCenter
+ maximumLength: 30
+ focus: true
+ font.pointSize: 20
+ }
+ }
+
+ Rectangle {
+ width: 300
+ height: 300
+ anchors.centerIn: parent
+ color: "red"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 20000; loops: Animation.Infinite; }
+ }
+
+ FbItem {
+ id: fbitem
+ anchors.fill: parent
+ SequentialAnimation on eye.y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: 0.15
+ duration: 1000
+ }
+ NumberAnimation {
+ from: 0.15
+ to: 0
+ duration: 2000
+ }
+ }
+ SequentialAnimation on eye.x {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: -0.5
+ duration: 3000
+ }
+ NumberAnimation {
+ from: -0.5
+ to: 0.5
+ duration: 3000
+ easing.type: Easing.OutQuad
+ }
+ NumberAnimation {
+ from: 0.5
+ to: 0
+ duration: 1000
+ }
+ }
+ SequentialAnimation on rotation.y {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: 360
+ duration: 5000
+ }
+ NumberAnimation {
+ from: 360
+ to: 0
+ duration: 2500
+ }
+ }
+ SequentialAnimation on rotation.x {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: 360
+ duration: 6000
+ }
+ NumberAnimation {
+ from: 360
+ to: 0
+ duration: 3000
+ }
+ }
+ }
+
+ Text {
+ id: effText
+ text: edit.text
+ anchors.centerIn: parent
+ font.pointSize: 60
+ style: Text.Outline
+ styleColor: "green"
+ }
+
+ ShaderEffectSource {
+ id: effSource
+ sourceItem: effText
+ hideSource: true
+ }
+
+ ShaderEffect {
+ SequentialAnimation on scale {
+ loops: Animation.Infinite
+ NumberAnimation { from: 1.0; to: 2.0; duration: 1000; easing.type: Easing.InCirc }
+ PauseAnimation { duration: 1000 }
+ NumberAnimation { from: 2.0; to: 0.5; duration: 1000; easing.type: Easing.OutExpo }
+ NumberAnimation { from: 0.5; to: 1.0; duration: 500 }
+ PauseAnimation { duration: 1000 }
+ }
+ width: effText.width
+ height: effText.height
+ anchors.centerIn: parent
+ property variant source: effSource
+ property real amplitude: 0.002
+ property real frequency: 10
+ property real time: 0
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 1000 }
+ fragmentShader:
+ "uniform lowp float qt_Opacity;" +
+ "uniform highp float amplitude;" +
+ "uniform highp float frequency;" +
+ "uniform highp float time;" +
+ "uniform sampler2D source;" +
+ "varying highp vec2 qt_TexCoord0;" +
+ "void main() {" +
+ " highp vec2 p = sin(time + frequency * qt_TexCoord0);" +
+ " gl_FragColor = texture2D(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;" +
+ "}"
+ }
+}
diff --git a/examples/quick/quickwidgets/quickwidgets.pro b/examples/quick/quickwidgets/quickwidgets.pro
index 07192b6696..be932f33d0 100644
--- a/examples/quick/quickwidgets/quickwidgets.pro
+++ b/examples/quick/quickwidgets/quickwidgets.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = quickwidget
+SUBDIRS = quickwidget \
+ qquickviewcomparison
diff --git a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
index 1f87412aa4..de023ff95c 100644
--- a/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
+++ b/examples/quick/scenegraph/openglunderqml/doc/src/openglunderqml.qdoc
@@ -50,54 +50,40 @@
in the QML file and this value is used by the OpenGL shader
program that draws the squircles.
+ \snippet scenegraph/openglunderqml/squircle.h 2
+
+ First of all, we need an object we can expose to QML. This is a
+ subclass of QQuickItem so we can easily access \l QQuickItem::window().
+
\snippet scenegraph/openglunderqml/squircle.h 1
- First of all, we need a QObject with a slot to connect the signals
- to. We subclass QQuickItem in order to use the \l
- QQuickItem::window() which holds the window instance we want to
- connect to.
-
- We use two values of \c t. The variable \c m_t is the property
- value as it exists in the GUI thread. The \c m_thread_t value is a
- copy of \c m_t for use in the rendering thread. We need an
- explicit copy because the scene graph can render in one thread
- while updating properties on the GUI thread in preparation for the
- next frame. If we had used only one value, the animation could
- have updated the value to that of the next frame before we got a
- chance to render it.
-
- \note In this example, a wrong value for \c t will have minimal
- consequences, but we emphasize that rendering and GUI thread
- objects and values must stay separate to avoid race conditions,
- undesired behavior and in the worst case, crashes.
+ Then we need an object to take care of the rendering. This
+ instance needs to be separated from the QQuickItem because the
+ item lives in the GUI thread and the rendering potentially happens
+ on the render thread. Since we want to connect to \l
+ QQuickWindow::beforeRendering(), we make the renderer a QObject.
+ The renderer contains a copy of all the state it needs,
+ independent of the GUI thread.
+
+ \note Don't be tempted to merge the two objects into
+ one. QQuickItems may be deleted on the GUI thread while the render
+ thread is rendering.
Lets move on to the implementation.
\snippet scenegraph/openglunderqml/squircle.cpp 7
The constructor of the \c Squircle class simply initializes the
- values. The shader program will be initialized during rendering
- later.
-
- \snippet scenegraph/openglunderqml/squircle.cpp 8
-
- The property setter checks that the value has indeed changed
- before updating its internal variable. It then calls \l
- QQuickWindow::update() which will trigger another frame to be
- rendered. Note that the setter might be called during
- initialization, before the object has been entered into the scene
- and before it has a window.
+ values and connects to the window changed signal which we will use
+ to prepare our renderer.
\snippet scenegraph/openglunderqml/squircle.cpp 1
- \snippet scenegraph/openglunderqml/squircle.cpp 2
- For our paint function to be called, we need to connect to the
- window's signals. When Squircle object is populated into the
- scene, the windowChanged signal is emitted. In our handler,
- we connect \l QQuickWindow::beforeRendering() to
- \c paint() to do the rendering, and \l
- QQuickWindow::beforeSynchronizing() to \c sync() to copy the state
- of the \c t property for the upcoming frame.
+ Once we have a window, we attach to the \l
+ QQuickWindow::beforeSynchronizing() signal which we will use to
+ create the renderer and to copy state into it safely. We also
+ connect to the \l QQuickWindow::sceneGraphInvalidated() signal to
+ handle the cleanup of the renderer.
\note Since the Squircle object has affinity to the GUI thread and
the signals are emitted from the rendering thread, it is crucial
@@ -113,18 +99,35 @@
graph, we need to turn this clearing off. This means that we need
to clear ourselves in the \c paint() function.
- \snippet scenegraph/openglunderqml/squircle.cpp 4
+ \snippet scenegraph/openglunderqml/squircle.cpp 9
+
+ We use the \c sync() function to initialize the renderer and to
+ copy the state in our item into the renderer. When the renderer is
+ created, we also connect the \l QQuickWindow::beforeRendering() to
+ the renderer's \c paint() slot.
- The first thing we do in the \c paint() function is to
- initialize the shader program. By initializing the shader program
- here, we make sure that the OpenGL context is bound and that we
- are on the correct thread.
+ \note The \l QQuickWindow::beforeSynchronizing() signal is emitted
+ on the rendering thread while the GUI thread is blocked, so it is
+ safe to simply copy the value without any additional protection.
- We also connect to the QOpenGLContext::aboutToBeDestroyed()
- signal, so that we can clean up the shader program when the
- context is destroyed. Again, this is a \l Qt::DirectConnection as
- all rendering related operations must happen on the rendering
- thread.
+ \snippet scenegraph/openglunderqml/squircle.cpp 6
+
+ In the \c cleanup() function we delete the renderer which in turn
+ cleans up its own resources.
+
+ \snippet scenegraph/openglunderqml/squircle.cpp 8
+
+ When the value of \c t changes, we call \l QQuickWindow::update()
+ rather than \l QQuickItem::update() because the former will force
+ the entire window to be redrawn, even when the scene graph has not
+ changed since the last frame.
+
+ \snippet scenegraph/openglunderqml/squircle.cpp 4
+
+ In the SquircleRenderer's \c paint() function we start by
+ initializing the shader program. By initializing the shader
+ program here, we make sure that the OpenGL context is bound and
+ that we are on the correct thread.
\snippet scenegraph/openglunderqml/squircle.cpp 5
@@ -133,18 +136,10 @@
attributes we used so that the OpenGL context is in a "clean"
state for the scene graph to pick it up.
- \snippet scenegraph/openglunderqml/squircle.cpp 6
-
- In the \c cleanup() function we delete the program.
-
- \snippet scenegraph/openglunderqml/squircle.cpp 9
-
- We use the \c sync() function to copy the state of the
- object in the GUI thread into the rendering thread.
-
- The signal is emitted on the rendering thread while the GUI
- thread is blocked, so it is safe to simply copy the value without
- any additional protection.
+ \note If tracking the changes in the OpenGL context's state is not
+ feasible, one can use the function \l
+ QQuickWindow::resetOpenGLState() which will reset all state that
+ the scene graph relies on.
\snippet scenegraph/openglunderqml/main.cpp 1
diff --git a/examples/quick/scenegraph/openglunderqml/squircle.cpp b/examples/quick/scenegraph/openglunderqml/squircle.cpp
index 91d69c90a4..4b892e3761 100644
--- a/examples/quick/scenegraph/openglunderqml/squircle.cpp
+++ b/examples/quick/scenegraph/openglunderqml/squircle.cpp
@@ -47,9 +47,8 @@
//! [7]
Squircle::Squircle()
- : m_program(0)
- , m_t(0)
- , m_thread_t(0)
+ : m_t(0)
+ , m_renderer(0)
{
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
}
@@ -71,24 +70,46 @@ void Squircle::setT(qreal t)
void Squircle::handleWindowChanged(QQuickWindow *win)
{
if (win) {
-//! [1]
- // Connect the beforeRendering signal to our paint function.
- // Since this call is executed on the rendering thread it must be
- // a Qt::DirectConnection
-//! [2]
- connect(win, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection);
connect(win, SIGNAL(beforeSynchronizing()), this, SLOT(sync()), Qt::DirectConnection);
-//! [2]
-
+ connect(win, SIGNAL(sceneGraphInvalidated()), this, SLOT(cleanup()), Qt::DirectConnection);
+//! [1]
// If we allow QML to do the clearing, they would clear what we paint
// and nothing would show.
//! [3]
win->setClearBeforeRendering(false);
}
}
+//! [3]
+
+//! [6]
+void Squircle::cleanup()
+{
+ if (m_renderer) {
+ delete m_renderer;
+ m_renderer = 0;
+ }
+}
-//! [3] //! [4]
-void Squircle::paint()
+SquircleRenderer::~SquircleRenderer()
+{
+ delete m_program;
+}
+//! [6]
+
+//! [9]
+void Squircle::sync()
+{
+ if (!m_renderer) {
+ m_renderer = new SquircleRenderer();
+ connect(window(), SIGNAL(beforeRendering()), m_renderer, SLOT(paint()), Qt::DirectConnection);
+ }
+ m_renderer->setViewportSize(window()->size() * window()->devicePixelRatio());
+ m_renderer->setT(m_t);
+}
+//! [9]
+
+//! [4]
+void SquircleRenderer::paint()
{
if (!m_program) {
m_program = new QOpenGLShaderProgram();
@@ -112,8 +133,6 @@ void Squircle::paint()
m_program->bindAttributeLocation("vertices", 0);
m_program->link();
- connect(window()->openglContext(), SIGNAL(aboutToBeDestroyed()),
- this, SLOT(cleanup()), Qt::DirectConnection);
}
//! [4] //! [5]
m_program->bind();
@@ -127,12 +146,9 @@ void Squircle::paint()
1, 1
};
m_program->setAttributeArray(0, GL_FLOAT, values, 2);
- m_program->setUniformValue("t", (float) m_thread_t);
+ m_program->setUniformValue("t", (float) m_t);
- qreal ratio = window()->devicePixelRatio();
- int w = int(ratio * window()->width());
- int h = int(ratio * window()->height());
- glViewport(0, 0, w, h);
+ glViewport(0, 0, m_viewportSize.width(), m_viewportSize.height());
glDisable(GL_DEPTH_TEST);
@@ -148,21 +164,3 @@ void Squircle::paint()
m_program->release();
}
//! [5]
-
-//! [6]
-void Squircle::cleanup()
-{
- if (m_program) {
- delete m_program;
- m_program = 0;
- }
-}
-//! [6]
-
-//! [9]
-void Squircle::sync()
-{
- m_thread_t = m_t;
-}
-//! [9]
-
diff --git a/examples/quick/scenegraph/openglunderqml/squircle.h b/examples/quick/scenegraph/openglunderqml/squircle.h
index 449e02bbf1..aa50908242 100644
--- a/examples/quick/scenegraph/openglunderqml/squircle.h
+++ b/examples/quick/scenegraph/openglunderqml/squircle.h
@@ -45,11 +45,32 @@
#include <QtQuick/QQuickItem>
#include <QtGui/QOpenGLShaderProgram>
+
+
+//! [1]
+class SquircleRenderer : public QObject {
+ Q_OBJECT
+public:
+ SquircleRenderer() : m_t(0), m_program(0) { }
+ ~SquircleRenderer();
+
+ void setT(qreal t) { m_t = t; }
+ void setViewportSize(const QSize &size) { m_viewportSize = size; }
+
+public slots:
+ void paint();
+
+private:
+ QSize m_viewportSize;
+ qreal m_t;
+ QOpenGLShaderProgram *m_program;
+};
//! [1]
+
+//! [2]
class Squircle : public QQuickItem
{
Q_OBJECT
-
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
public:
@@ -62,19 +83,16 @@ signals:
void tChanged();
public slots:
- void paint();
- void cleanup();
void sync();
+ void cleanup();
private slots:
void handleWindowChanged(QQuickWindow *win);
private:
- QOpenGLShaderProgram *m_program;
-
qreal m_t;
- qreal m_thread_t;
+ SquircleRenderer *m_renderer;
};
-//! [1]
+//! [2]
#endif // SQUIRCLE_H
diff --git a/examples/quick/threading/threadedlistmodel/doc/src/threadedlistmodel.qdoc b/examples/quick/threading/threadedlistmodel/doc/src/threadedlistmodel.qdoc
new file mode 100644
index 0000000000..de7b2a49a2
--- /dev/null
+++ b/examples/quick/threading/threadedlistmodel/doc/src/threadedlistmodel.qdoc
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \title Threaded ListModel Example
+ \example threading/threadedlistmodel
+
+ This example shows how to use a ListModel from multiple threads using
+ WorkerScript.
+*/
+
diff --git a/examples/quick/threading/workerscript/workerscript.js b/examples/quick/threading/workerscript/workerscript.js
index 67fbd8af9a..0a6a37ef29 100644
--- a/examples/quick/threading/workerscript/workerscript.js
+++ b/examples/quick/threading/workerscript/workerscript.js
@@ -1,3 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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$
+**
+****************************************************************************/
+
//Will be initialized when WorkerScript{} is instantiated
var cache = new Array(64);
for (var i = 0; i < 64; i++)
diff --git a/examples/quick/threading/workerscript/workerscript.qmlproject b/examples/quick/threading/workerscript/workerscript.qmlproject
index 6d7a91feeb..05c5cf4756 100644
--- a/examples/quick/threading/workerscript/workerscript.qmlproject
+++ b/examples/quick/threading/workerscript/workerscript.qmlproject
@@ -1,3 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples 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 Digia Plc 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$
+**
+****************************************************************************/
+
import QmlProject 1.1
Project {
diff --git a/examples/quick/views/doc/src/views.qdoc b/examples/quick/views/doc/src/views.qdoc
index d25d9f40c9..0e91bfe78c 100644
--- a/examples/quick/views/doc/src/views.qdoc
+++ b/examples/quick/views/doc/src/views.qdoc
@@ -68,7 +68,7 @@
\section1 Highlight
- \e Highlight demonstrates adding a custom highlight to a \l ListView.
+ \e Highlight demonstrates adding a custom highlight to a ListView.
\snippet views/listview/highlight.qml 0
\section1 Highlight Ranges
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index d5dbeeb4c2..5fe445758b 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -554,7 +554,7 @@ The API can be used from JavaScript functions in your QML:
The API conforms to the Synchronous API of the HTML5 Web Database API,
\link http://www.w3.org/TR/2009/WD-webdatabase-20091029/ W3C Working Draft 29 October 2009\endlink.
-The \l{localstorage/localstorage}{SQL Local Storage example} demonstrates the basics of
+The \l{Qt Quick Examples - Local Storage}{SQL Local Storage example} demonstrates the basics of
using the Offline Storage API.
\section3 Open or create a databaseData
diff --git a/src/plugins/accessible/quick/qaccessiblequickitem.cpp b/src/plugins/accessible/quick/qaccessiblequickitem.cpp
index 164144c052..be7ada442a 100644
--- a/src/plugins/accessible/quick/qaccessiblequickitem.cpp
+++ b/src/plugins/accessible/quick/qaccessiblequickitem.cpp
@@ -184,7 +184,7 @@ QAccessible::Role QAccessibleQuickItem::role() const
bool ok;
QAccessible::Role role = (QAccessible::Role)v.toInt(&ok);
if (!ok) // Not sure if this check is needed.
- role = QAccessible::Pane;
+ role = QAccessible::Client;
return role;
}
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 60a0829b9b..dacaa14a3d 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -277,12 +277,12 @@ bool QQmlTypeCompiler::compile()
if (qmlType->parserStatusCast() != -1)
++parserStatusCount;
}
+ ++objectCount;
if (typeRef->component) {
bindingCount += typeRef->component->totalBindingsCount;
parserStatusCount += typeRef->component->totalParserStatusCount;
objectCount += typeRef->component->totalObjectCount;
- } else
- ++objectCount;
+ }
}
}
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 97114b9507..d7dbfac50b 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -246,13 +246,31 @@ public:
if (set.blockNumbers)
numberIt = set.blockNumbers->begin();
else
- flagIt = std::distance(set.blockFlags->begin(),
- std::find(set.blockFlags->begin(),
- set.blockFlags->end(),
- true));
+ findNextWithFlags(0);
}
}
+ void findNextWithFlags(size_t start)
+ {
+ flagIt = std::distance(set.blockFlags->begin(),
+ std::find(set.blockFlags->begin() + start,
+ set.blockFlags->end(),
+ true));
+
+ // The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an
+ // iterator pointing to the last element. It will not be set to ::end(), but beyond
+ // that. (It will be set to the first multiple of the native word size that is bigger
+ // than size().)
+ //
+ // See http://llvm.org/bugs/show_bug.cgi?id=19663
+ //
+ // As we use the size to for our end() iterator, take the minimum of the size and the
+ // distance for the flagIt:
+ flagIt = qMin(flagIt, set.blockFlags->size());
+
+ Q_ASSERT(flagIt <= set.blockFlags->size());
+ }
+
public:
BasicBlock *operator*() const
{
@@ -282,10 +300,7 @@ public:
if (set.blockNumbers)
++numberIt;
else
- flagIt = std::distance(set.blockFlags->begin(),
- std::find(set.blockFlags->begin() + flagIt + 1,
- set.blockFlags->end(),
- true));
+ findNextWithFlags(flagIt + 1);
return *this;
}
diff --git a/src/quick/doc/images/visualitemmodel.png b/src/qml/doc/images/visualitemmodel.png
index 5e6d1325b2..5e6d1325b2 100644
--- a/src/quick/doc/images/visualitemmodel.png
+++ b/src/qml/doc/images/visualitemmodel.png
Binary files differ
diff --git a/src/qml/doc/src/javascript/expressions.qdoc b/src/qml/doc/src/javascript/expressions.qdoc
index 79c11b3ac5..37baa49c52 100644
--- a/src/qml/doc/src/javascript/expressions.qdoc
+++ b/src/qml/doc/src/javascript/expressions.qdoc
@@ -37,44 +37,36 @@ Object} includes a number of helper methods that simplify building UIs and
interacting with the QML environment.
The JavaScript environment provided by QML is stricter than that in a web
-browser. For example, in QML you cannot add, or modify, members of the
+browser. For example, in QML you cannot add to, or modify, members of the
JavaScript global object. In regular JavaScript, it is possible to do this
accidentally by using a variable without declaring it. In QML this will throw
-an exception, so all local variables should be explicitly declared. See
+an exception, so all local variables must be explicitly declared. See
\l{JavaScript Environment Restrictions} for a complete description of the
restrictions on JavaScript code executed from QML.
-There are various ways in which JavaScript expressions may be defined and used
-in QML, including property bindings, signal handlers, custom methods and
-JavaScript imports.
-
-
-
-
-\section1 JavaScript Expressions in QML Objects
-
-QML \l{QML Object Types}{object types} defined in \l{QML Documents}
-{QML documents} can make use of JavaScript expressions which implement program
-logic. There are four ways that JavaScript can be used in a QML document:
+Various parts of \l{QML Documents}{QML documents} can contain JavaScript code:
\list 1
- \li Relationships between \l{Property Attributes}{properties} are described
- using JavaScript expressions in \l{Property Binding}{property bindings}.
- When any of a property's \e dependencies change, the property is
- automatically updated too, according to the specified relationship.
- \li \l{Signal Attributes}{Signal handlers} can be defined
- which are automatically evaluated when the object emits the associated
- signal.
- \li \l{Method Attributes}{Custom methods} can be defined
- in QML files as JavaScript functions.
- \li JavaScript files providing functions and variables can be
- \l{Importing JavaScript Resources in QML}{imported} in a QML
- document.
+ \li The body of \l{Property Binding}{property bindings}. These JavaScript
+ expressions describe relationships between QML object \l{Property Attributes}
+ {properties}. When any of a property's \e dependencies change, the property
+ is automatically updated too, according to the specified relationship.
+ \li The body of \l{Signal Attributes}{Signal handlers}. These JavaScript
+ statements are automatically evaluated whenever a QML object emits the
+ associated signal.
+ \li The definition of \l{Method Attributes}{custom methods}. JavaScript functions
+ that are defined within the body of a QML object become methods of that
+ object.
+ \li Standalone \l{Importing JavaScript Resources in QML}{JavaScript resource
+ (.js) files}. These files are actually separate from QML documents, but
+ they can be imported into QML documents. Functions and variables that are
+ defined within the imported files can be used in property bindings, signal
+ handlers, and custom methods.
\endlist
-\section2 Property Bindings
+\section1 JavaScript in Property Bindings
In the following example, the \l Rectangle's \c color depends on the
\l MouseArea's \c pressed property. This relationship is described using a
@@ -136,7 +128,7 @@ bindings differ from value assignments.
-\section2 Signal Handlers
+\section1 JavaScript in Signal Handlers
QML object types can emit signals in reaction to certain events occurring.
Those signals can be handled by signal handler functions, which can be defined
@@ -188,7 +180,7 @@ to define the implementation of signal handlers in QML with JavaScript.
-\section2 JavaScript Expressions in Functions
+\section1 JavaScript in Standalone Functions
Program logic can also be defined in JavaScript functions. These functions can
be defined inline in QML documents (as custom methods) or externally in
@@ -196,12 +188,12 @@ imported JavaScript files.
-\section3 Custom Methods
+\section2 JavaScript in Custom Object Methods
Custom methods can be defined in QML documents and may be called from signal
handlers, property bindings, or functions in other QML objects. Methods
-defined in this way are often referred to as "inline JavaScript functions" as
-their implementation is included in the QML object type definition
+defined in this way are often referred to as \e{inline JavaScript functions}
+because their implementation is included in the QML object type definition
(QML document), as opposed to an external JavaScript file.
An example of an inline custom method is as follows:
@@ -225,7 +217,7 @@ Item {
}
\endqml
-The factorial function will run whenever the MouseArea detects a clicked signal.
+The factorial function will run whenever the MouseArea detects a \c clicked signal.
Importantly, custom methods defined inline in a QML document are exposed to
other objects, and therefore inline functions on the root object in a QML
@@ -238,7 +230,7 @@ to define custom methods in QML with JavaScript code implementations.
-\section3 Functions in Imported JavaScript Files
+\section2 Functions in Imported JavaScript Files
Non-trivial program logic is best separated into external JavaScript files.
These files can be imported into QML files using an \c import statement, in
@@ -263,7 +255,7 @@ the section about \l{Importing JavaScript Resources in QML}.
-\section3 Connecting Signals to JavaScript Functions
+\section2 Connecting Signals to JavaScript Functions
QML object types which emit signals also provide default signal handlers for
their signals, as described in a previous section. Sometimes, however, a
@@ -292,23 +284,26 @@ See \l{qtqml-syntax-signals.html}
-\section1 Running JavaScript at Startup
+\section1 JavaScript in Application Startup Code
It is occasionally necessary to run some imperative code at application (or
component instance) startup. While it is tempting to just include the startup
script as \e {global code} in an external script file, this can have severe
limitations as the QML environment may not have been fully established. For
example, some objects might not have been created or some
-\l {Property Binding}{property bindings} may not have been run.
-\l {JavaScript Environment Restrictions} covers the exact limitations of global
+\l {Property Binding}{property bindings} may not have been established. See
+\l {JavaScript Environment Restrictions} for the exact limitations of global
script code.
-Every QML object has an \e attached \l Component property that references the
-component within which the object was instantiated. Every \l Component
-will emit a \c completed signal, and thus every object can define an
-implementation for the \c onCompleted() handler which can be used to trigger the
-execution of script code at startup after the QML environment has been
-completely established. For example:
+A QML object will emit the \c{Component.completed} \l{Signal and Handler Event
+System#Attached Signal Handlers}{attached signal} when its instantiation is
+complete. JavaScript code in the corresponding \c{Component.onCompleted} handler
+runs after the object is instantiated. Thus, the best place to write application
+startup code is in the \c{Component.onCompleted} handler of the top-level level
+object, because this object emits \c{Component.completed} when the QML environment
+is fully established.
+
+For example:
\qml
import QtQuick 2.0
@@ -346,7 +341,7 @@ signal just before being destroyed.
\section1 Scarce Resources in JavaScript
As described in the documentation for \l{QML Basic Types}, a \c var type
-property may hold a "scarce resource" (image or pixmap). There are several
+property may hold a \e{scarce resource} (image or pixmap). There are several
important semantics of scarce resources which should be noted:
\list
diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc
index a63ef617c0..bd3ff63bf8 100644
--- a/src/qml/doc/src/javascript/hostenvironment.qdoc
+++ b/src/qml/doc/src/javascript/hostenvironment.qdoc
@@ -135,8 +135,8 @@ var initialPosition = { rootObject.x, rootObject.y }
\endcode
This restriction exists as the QML environment is not yet fully established.
-To run code after the environment setup has completed, refer to
-\l {Running JavaScript at Startup}.
+To run code after the environment setup has completed, see
+\l {JavaScript in Application Startup Code}.
\li The value of \c this is currently undefined in QML in the majority of contexts.
diff --git a/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc
index 8bfe309144..a481847136 100644
--- a/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/cppplugins.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -120,7 +120,7 @@
\snippet qmlextensionplugins/plugins.qml 0
- The full source code is available in the \l {qml/qmlextensionplugins}{plugins example}.
+ The full source code is available in the \l {qmlextensionplugins}{plugins example}.
\section1 Reference
diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
index 78b16a0a0d..ef6c8b1b67 100644
--- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
+++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -181,7 +181,7 @@ plugin MyPluginLibrary
\li C++ Plugin Class
\li
\code
- classname <C++ plugin class>
+classname <C++ plugin class>
\endcode
\li Provides the class name of the C++ plugin used by the module.
@@ -265,10 +265,6 @@ version of installed software, since a versioned import \e only imports types
for that version, leaving other identifiers available, even if the actual
installed version might otherwise provide those identifiers.
-See \l{examples/qml/plugins} for an example that uses C++
-plugins.
-
-
\section1 Example of a qmldir File
One example of a \c qmldir file follows:
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 3e48ec2308..dd42e251c2 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -562,9 +562,9 @@ any items added to this list for an \l Item are automatically added to its
list of \l {Item::children}{children}.
Default properties can be useful for reassigning the children of an item. See
-the \l{declarative/customitems/tabwidget}{TabWidget example}, which uses a
-default property to automatically reassign children of the TabWidget as
-children of an inner ListView.
+the \l{TabWidget Example}, which uses a default property to
+automatically reassign children of the TabWidget as children of an inner
+ListView.
\section3 Read-Only Properties
diff --git a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc
index c1c2c0f5db..16e36f6f6d 100644
--- a/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/typesystem/basictypes.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -498,6 +498,7 @@ property is only invoked when the property is reassigned to a different object v
"destroy" method on the \c var property from within JavaScript. They
may also explicitly preserve the scarce resource by calling the
"preserve" method on the \c var property from within JavaScript.
+
For more information regarding the usage of a scarce resource, please
see \l{Scarce Resources in JavaScript}.
@@ -542,7 +543,7 @@ property is only invoked when the property is reassigned to a different object v
"destroy" method on the \c variant property from within JavaScript. They
may also explicitly preserve the scarce resource by calling the
"preserve" method on the \c variant property from within JavaScript.
- For more information regarding the usage of a scarce resource, please
+ For more information on the usage of a scarce resource, please
see \l{Scarce Resources in JavaScript}.
\section1 Storing Arrays and Objects
diff --git a/src/qml/doc/src/whatsnew.qdoc b/src/qml/doc/src/whatsnew.qdoc
index f13a4dac1d..10e7108207 100644
--- a/src/qml/doc/src/whatsnew.qdoc
+++ b/src/qml/doc/src/whatsnew.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -94,7 +94,8 @@ has now been replaced by the new \l {Qt QML} and \l {Qt Quick} modules. See the
\list
\li New \l var property type. This is a general-purpose property type which obsoletes the \l variant type.
Properties of the \l var type may hold JavaScript references.
-\li QML properties of type \l var and \l variant can now hold pixmaps. See \l {Scarce Resources in JavaScript} for more information.
+\li QML properties of type \l var and \l variant can now hold pixmaps.
+ See \l {Scarce Resources in JavaScript} for more information.
\li Value type improvements:
\list
\li QML now supports defining properties of value type basic types within QML documents. Supported types include
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index d5b3b8a651..fbd757a829 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -371,7 +371,7 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
ScopedValue result(scope);
- if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len) {
+ if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len && instance->arrayData->type != ArrayData::Custom) {
result = instance->arrayData->vtable()->pop_front(instance.getPointer());
} else {
result = instance->getIndexed(0);
@@ -550,7 +550,7 @@ ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
uint len = instance->getLength();
- if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len) {
+ if (!instance->protoHasArray() && !instance->arrayData->hasAttributes() && instance->arrayData->length() <= len && instance->arrayData->type != ArrayData::Custom) {
instance->arrayData->vtable()->push_front(instance.getPointer(), ctx->callData->args, ctx->callData->argc);
} else {
ScopedValue v(scope);
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 8916cc597e..72be889e72 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -839,7 +839,11 @@ void ExecutionEngine::markObjects()
ExecutionContext *c = currentContext();
while (c) {
- c->mark(this);
+ Q_ASSERT(c->inUse);
+ if (!c->markBit) {
+ c->markBit = 1;
+ c->markObjects(c, this);
+ }
c = c->parent;
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index a02424a3dc..d64f821a38 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -962,6 +962,8 @@ static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine *
const QObjectList &children = parent->children();
for (int i = 0; i < children.count(); ++i) {
QObject *child = children.at(i);
+ if (!child)
+ continue;
QQmlData *ddata = QQmlData::get(child, /*create*/false);
if (ddata)
ddata->jsWrapper.markOnce(e);
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 39a7d8905d..68f950d840 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -150,7 +150,7 @@ V8_DEFINE_EXTENSION(QQmlComponentExtension, componentExtension);
// QQmlEngine *engine = qmlContext(this)->engine();
QQmlComponent component(engine, QUrl::fromLocalFile("MyItem.qml"));
QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create());
- childItem->setParent(this);
+ childItem->setParentItem(this);
}
\endcode
@@ -780,6 +780,11 @@ QQmlComponent::QQmlComponent(QQmlComponentPrivate &dd, QObject *parent)
The ownership of the returned object instance is transferred to the caller.
+ If the object being created from this component is a visual item, it must
+ have a visual parent, which can be set by calling
+ QQuickItem::setParentItem(). See \l {Concepts - Visual Parent in Qt Quick}
+ for more details.
+
\sa QQmlEngine::ObjectOwnership
*/
QObject *QQmlComponent::create(QQmlContext *context)
@@ -880,7 +885,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
enginePriv->referenceScarceResources();
QObject *rv = 0;
- state.creator = new QQmlObjectCreator(context, cc, creationContext);
+ state.creator.reset(new QQmlObjectCreator(context, cc, creationContext));
rv = state.creator->create(start);
if (!rv)
state.errors = state.creator->errors;
@@ -920,7 +925,7 @@ void QQmlComponentPrivate::beginDeferred(QQmlEnginePrivate *enginePriv,
Q_ASSERT(ddata->deferredData);
QQmlData::DeferredData *deferredData = ddata->deferredData;
QQmlContextData *creationContext = 0;
- state->creator = new QQmlObjectCreator(deferredData->context->parent, deferredData->compiledData, creationContext);
+ state->creator.reset(new QQmlObjectCreator(deferredData->context->parent, deferredData->compiledData, creationContext));
if (!state->creator->populateDeferredProperties(object))
state->errors << state->creator->errors;
}
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index e8ae540148..2c70d7b100 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -106,15 +106,13 @@ public:
struct ConstructionState {
ConstructionState()
- : creator(0)
- , completePending(false)
+ : completePending(false)
{}
~ConstructionState()
{
- delete creator;
}
- QQmlObjectCreator *creator;
+ QScopedPointer<QQmlObjectCreator> creator;
QList<QQmlError> errors;
bool completePending;
};
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 93060e97fb..e3e1434746 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -239,7 +239,7 @@ bool QQmlData::wasDeleted(QObject *object)
return true;
QObjectPrivate *priv = QObjectPrivate::get(object);
- if (priv->wasDeleted)
+ if (!priv || priv->wasDeleted)
return true;
return priv->declarativeData &&
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 0424c57f97..9bf983ab85 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -560,7 +560,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
workerScriptEngine(0),
activeObjectCreator(0),
networkAccessManager(0), networkAccessManagerFactory(0), urlInterceptor(0),
- scarceResourcesRefCount(0), importDatabase(e), typeLoader(e), uniqueId(1),
+ scarceResourcesRefCount(0), typeLoader(e), importDatabase(e), uniqueId(1),
incubatorCount(0), incubationController(0), mutex(QMutex::Recursive)
{
useNewCompiler = true;
@@ -2306,20 +2306,17 @@ static inline QString shellNormalizeFileName(const QString &name)
// The correct declaration of the SHGetPathFromIDList symbol is
// being used in mingw-w64 as of r6215, which is a v3 snapshot.
#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
- ITEMIDLIST file;
- if (FAILED(SHParseDisplayName(nameC, NULL, &file, 0, NULL)))
- return name;
- TCHAR buffer[MAX_PATH];
- if (!SHGetPathFromIDList(&file, buffer))
+ ITEMIDLIST *file;
+ if (FAILED(SHParseDisplayName(nameC, NULL, reinterpret_cast<LPITEMIDLIST>(&file), 0, NULL)))
return name;
#else
PIDLIST_ABSOLUTE file;
if (FAILED(SHParseDisplayName(nameC, NULL, &file, 0, NULL)))
return name;
+#endif
TCHAR buffer[MAX_PATH];
if (!SHGetPathFromIDList(file, buffer))
return name;
-#endif
QString canonicalName = QString::fromWCharArray(buffer);
// Upper case drive letter
if (canonicalName.size() > 2 && canonicalName.at(1) == QLatin1Char(':'))
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 5767ca90f0..1fe3442817 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -185,8 +185,9 @@ public:
void referenceScarceResources();
void dereferenceScarceResources();
- QQmlImportDatabase importDatabase;
QQmlTypeLoader typeLoader;
+ QQmlImportDatabase importDatabase;
+
QString offlineStoragePath;
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index f3d1ba9d41..1c321d131d 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE
\snippet qmlextensionplugins/plugins.qml 0
- The full source code is available in the \l {qml/qmlextensionplugins}{plugins example}.
+ The full source code is available in the \l {qmlextensionplugins}{plugins example}.
The \l {Writing QML Extensions with C++} tutorial also contains a chapter
on creating QML plugins.
diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
index b0271b11f2..9d808f56d9 100644
--- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
+++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE
The \l {Qt Quick 1} version of this class is named QDeclarativeNetworkAccessManagerFactory.
- \sa {qml/networkaccessmanagerfactory}{NetworkAccessManagerFactory example}
+ \sa {C++ Extensions: Network Access Manager Factory Example}{Network Access Manager Factory Example}
*/
/*!
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index a8eeeeeddd..1de467b0fa 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -91,11 +91,12 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
init(parentContext);
sharedState = new QQmlObjectCreatorSharedState;
- sharedState.setFlag(); // We own it, so we must delete it
+ topLevelCreator = true;
sharedState->componentAttached = 0;
sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount);
sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount);
sharedState->allCreatedObjects.allocate(compiledData->totalObjectCount);
+ sharedState->allJavaScriptObjects = 0;
sharedState->creationContext = creationContext;
sharedState->rootContext = 0;
@@ -115,6 +116,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
init(parentContext);
sharedState = inheritedSharedState;
+ topLevelCreator = false;
}
void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
@@ -139,9 +141,9 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
QQmlObjectCreator::~QQmlObjectCreator()
{
- if (sharedState.flag()) {
+ if (topLevelCreator) {
{
- QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher(sharedState.data());
+ QQmlObjectCreatorRecursionWatcher watcher(this);
}
for (int i = 0; i < sharedState->allCreatedBindings.count(); ++i) {
QQmlAbstractBinding *b = sharedState->allCreatedBindings.at(i);
@@ -153,7 +155,10 @@ QQmlObjectCreator::~QQmlObjectCreator()
if (ps)
ps->d = 0;
}
- delete sharedState.data();
+ while (sharedState->componentAttached) {
+ QQmlComponentAttached *a = sharedState->componentAttached;
+ a->rem();
+ }
}
}
@@ -191,6 +196,13 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
sharedState->rootContext->isRootObjectInCreation = true;
}
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
+
+ Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator);
+ if (topLevelCreator)
+ sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount);
+
QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count());
for (QHash<int, int>::ConstIterator it = objectIndexToId.constBegin(), end = objectIndexToId.constEnd();
it != end; ++it) {
@@ -204,8 +216,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context->setIdPropertyData(mapping);
if (subComponentIndex == -1) {
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QV4::Scope scope(v4);
QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
context->importedScripts = scripts;
for (int i = 0; i < compiledData->scripts.count(); ++i) {
@@ -226,6 +236,9 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
ddata->compiledData->addref();
}
+ if (topLevelCreator)
+ sharedState->allJavaScriptObjects = 0;
+
phase = CreatingObjectsPhase2;
if (interrupt && interrupt->shouldInterrupt())
@@ -254,8 +267,11 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope valueScope(v4);
- QV4::ScopedValue scopeObjectProtector(valueScope, declarativeData->jsWrapper.value());
- Q_UNUSED(scopeObjectProtector);
+
+ Q_ASSERT(topLevelCreator);
+ Q_ASSERT(!sharedState->allJavaScriptObjects);
+ sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount);
+
QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
@@ -1146,9 +1162,12 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
qSwap(_scopeObject, scopeObject);
QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+
+ Q_ASSERT(sharedState->allJavaScriptObjects);
+ QV4::ValueRef ref = QV4::ValueRef::fromRawValue(sharedState->allJavaScriptObjects++);
+ ref = QV4::QObjectWrapper::wrap(v4, instance);
+
QV4::Scope valueScope(v4);
- QV4::ScopedValue scopeObjectProtector(valueScope, ddata ? ddata->jsWrapper.value() : 0);
- Q_UNUSED(scopeObjectProtector);
QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
@@ -1168,7 +1187,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
phase = Finalizing;
- QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher(sharedState.data());
+ QQmlObjectCreatorRecursionWatcher watcher(this);
ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
{
@@ -1253,6 +1272,11 @@ void QQmlObjectCreator::clear()
while (!sharedState->allCreatedObjects.isEmpty())
delete sharedState->allCreatedObjects.pop();
+ while (sharedState->componentAttached) {
+ QQmlComponentAttached *a = sharedState->componentAttached;
+ a->rem();
+ }
+
phase = Done;
}
@@ -1325,3 +1349,10 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
}
+
+
+QQmlObjectCreatorRecursionWatcher::QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator)
+ : sharedState(creator->sharedState)
+ , watcher(creator->sharedState.data())
+{
+}
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 379a3b2970..fb4d71d054 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -57,13 +57,14 @@ struct QQmlTypeCompiler;
class QQmlInstantiationInterrupt;
struct QQmlVmeProfiler;
-struct QQmlObjectCreatorSharedState
+struct QQmlObjectCreatorSharedState : public QSharedData
{
QQmlContextData *rootContext;
QQmlContextData *creationContext;
QFiniteStack<QQmlAbstractBinding*> allCreatedBindings;
QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
QFiniteStack<QObject*> allCreatedObjects;
+ QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase.
QQmlComponentAttached *componentAttached;
QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
QQmlVmeProfiler profiler;
@@ -128,7 +129,8 @@ private:
const QVector<QQmlPropertyCache *> &propertyCaches;
const QVector<QByteArray> &vmeMetaObjectData;
QHash<int, int> objectIndexToId;
- QFlagPointer<QQmlObjectCreatorSharedState> sharedState;
+ QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
+ bool topLevelCreator;
void *activeVMEDataForRootContext;
QObject *_qobject;
@@ -142,6 +144,19 @@ private:
QQmlVMEMetaObject *_vmeMetaObject;
QQmlListProperty<void> _currentList;
QV4::ExecutionContext *_qmlContext;
+
+ friend struct QQmlObjectCreatorRecursionWatcher;
+};
+
+struct QQmlObjectCreatorRecursionWatcher
+{
+ QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator);
+
+ bool hasRecursed() const { return watcher.hasRecursed(); }
+
+private:
+ QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
+ QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher;
};
QT_END_NAMESPACE
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 6029e277dd..aab385ceb5 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -1572,12 +1572,7 @@ void QQmlDelegateModel::_q_layoutChanged(const QList<QPersistentModelIndex> &par
if (i == index.row())
continue;
- QVector<Compositor::Insert> inserts;
- QVector<Compositor::Remove> removes;
- d->m_compositor.listItemsMoved(&d->m_adaptorModel, i, index.row(), 1, &removes, &inserts);
- if (!removes.isEmpty() || !inserts.isEmpty()) {
- d->itemsMoved(removes, inserts);
- }
+ _q_itemsMoved(i, index.row(), 1);
}
d->m_storedPersistentIndexes.clear();
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index f57d4a6a58..be49b6e5a0 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -1526,7 +1526,7 @@ QQmlListModelParser::ListInstruction *QQmlListModelParser::ListModelData::instru
You must call sync() or else the changes made to the list from that
thread will not be reflected in the list model in the main thread.
- \sa {qml-data-models}{Data Models}, {declarative/threading/threadedlistmodel}{Threaded ListModel example}, {Qt QML}
+ \sa {qml-data-models}{Data Models}, {Qt Quick Examples - Threading}, {Qt QML}
*/
QQmlListModel::QQmlListModel(QObject *parent)
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
index d4dbae383d..ca9f25ff59 100644
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -164,7 +164,7 @@ public:
\image visualitemmodel.png
- \sa {quick/views/objectmodel}{ObjectModel example}
+ \sa {Qt Quick Examples - Views}
*/
/*!
\qmltype VisualItemModel
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 80c4112930..4e842c5133 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -623,8 +623,8 @@ void QQuickWorkerScriptEngine::run()
Worker script can not use \l {qtqml-javascript-imports.html}{.import} syntax.
- \sa {declarative/threading/workerscript}{WorkerScript example},
- {declarative/threading/threadedlistmodel}{Threaded ListModel example}
+ \sa {Qt Quick Examples - Threading},
+ {Threaded ListModel Example}
*/
QQuickWorkerScript::QQuickWorkerScript(QObject *parent)
: QObject(parent), m_engine(0), m_scriptId(-1), m_componentComplete(true)
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index a1686459a5..44256f3f8c 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -685,7 +685,7 @@ void QuickTestResult::stopBenchmark()
QObject *QuickTestResult::grabImage(QQuickItem *item)
{
- if (item) {
+ if (item && item->window()) {
QQuickWindow *window = item->window();
QImage grabbed = window->grabWindow();
QRectF rf(item->x(), item->y(), item->width(), item->height());
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index edad14cfd4..959a54b7d8 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -67,6 +67,8 @@ excludedirs += ../../imports/dialogs \
../../imports/models \
../../../examples/quick/dialogs
+manifestmeta.thumbnail.names += "QtQuick/Threaded ListModel Example"
+
navigation.landingpage = "Qt Quick"
navigation.cppclassespage = "Qt Quick C++ Classes"
navigation.qmltypespage = "Qt Quick QML Types"
diff --git a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc
index f1e13e127c..49e4998ee1 100644
--- a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc
+++ b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc
@@ -57,7 +57,7 @@ to a QStringList:
\snippet models/stringlistmodel/main.cpp 0
The complete source code for this example is available in
-\l {quick/modelviews/stringlistmodel}{examples/quick/modelviews/stringlistmodel}
+\l {models/stringlistmodel}{examples/quick/models/stringlistmodel}
within the Qt install directory.
\b{Note:} There is no way for the view to know that the contents of a QStringList
@@ -94,7 +94,7 @@ object, as they are easily available via the \c modelData
object.
The complete source code for this example is available in
-\l {quick/modelviews/objectlistmodel}{examples/quick/modelviews/objectlistmodel}
+\l {models/objectlistmodel}{examples/quick/models/objectlistmodel}
within the Qt install directory.
Note: There is no way for the view to know that the contents of a QList
@@ -140,7 +140,7 @@ QAbstractItemModel::beginInsertRows(), and so on. See the \l {Model subclassing
more information.
The complete source code for this example is available in
-\l {quick/modelviews/abstractitemmodel}{examples/quick/modelviews/abstractitemmodel}
+\l {models/abstractitemmodel}{examples/quick/models/abstractitemmodel}
within the Qt install directory.
QAbstractItemModel presents a hierarchy of tables, but the views currently provided by QML
diff --git a/src/quick/doc/src/concepts/statesanimations/animations.qdoc b/src/quick/doc/src/concepts/statesanimations/animations.qdoc
index e4e208863b..080b786f9b 100644
--- a/src/quick/doc/src/concepts/statesanimations/animations.qdoc
+++ b/src/quick/doc/src/concepts/statesanimations/animations.qdoc
@@ -183,7 +183,7 @@ There are several methods of assigning behavior animations to properties. The
\c{Behavior on <property>} declaration is a convenient way of assigning a
behavior animation onto a property.
-See the \l {declarative/animation/behaviors}{Behaviors example} for a
+See the \l {Qt Quick Examples - Animation} for a
demonstration of behavioral animations.
\section1 Playing Animations in Parallel or in Sequence
@@ -235,7 +235,7 @@ are also different parameters to control the curve, some of which are exclusive
to a particular curve. For more information about the easing curves, visit the
\l {PropertyAnimation::easing.type}{easing} documentation.
-The \l{declarative/animation/easing}{easing example} visually demonstrates each
+The \l{animation/easing}{easing example} visually demonstrates each
of the different easing types.
\section2 Other Animation Types
diff --git a/src/quick/doc/src/concepts/statesanimations/states.qdoc b/src/quick/doc/src/concepts/statesanimations/states.qdoc
index d9978d454e..b0d7765c66 100644
--- a/src/quick/doc/src/concepts/statesanimations/states.qdoc
+++ b/src/quick/doc/src/concepts/statesanimations/states.qdoc
@@ -121,7 +121,7 @@ interpolation behaviors are definable. The
{Animation and Transitions} article has more information about creating state
animations.
-The \l {declarative/animation/states}{States and Transitions example}
+The \l {animation/states}{States and Transitions example}
demonstrates how to declare a basic set of states and apply animated
transitions between them.
diff --git a/src/quick/doc/src/examples.qdoc b/src/quick/doc/src/examples.qdoc
index 3669a31de0..51525b8f57 100644
--- a/src/quick/doc/src/examples.qdoc
+++ b/src/quick/doc/src/examples.qdoc
@@ -126,7 +126,7 @@ Creator.
\list
\li \l{Qt Quick Controls - Gallery}{Controls Gallery}
\li \l{Qt Quick System Dialog Examples}{Dialog Examples}
- \li \l{Qt Quick Controls - Calendar Example}{Calendar Example}
+ \li \l{Calendar Example}
\li \l{Qt Quick Controls - Table View Example}{TableView}
\li \l{Qt Quick Examples - Text}{Text and Fonts}
\li \l{Qt Quick Examples - Toggle Switch}{Custom Toggle Switch}
diff --git a/src/quick/doc/src/tutorial.qdoc b/src/quick/doc/src/tutorial.qdoc
index 75ca1b8d55..91032f1d92 100644
--- a/src/quick/doc/src/tutorial.qdoc
+++ b/src/quick/doc/src/tutorial.qdoc
@@ -223,5 +223,5 @@ This is equivalent to writing the two transitions separately.
The \l ParallelAnimation type makes sure that the two types of animations (number and color) start at the same time.
We could also run them one after the other by using \l SequentialAnimation instead.
-For more details on states and transitions, see \l {Qt Quick States} and the \l{quick/animation/states}{states and transitions example}.
+For more details on states and transitions, see \l {Qt Quick States} and the \l{animation/states}{states and transitions example}.
*/
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index b4a89b3107..16c8d94e8d 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -138,7 +138,7 @@ QT_BEGIN_NAMESPACE
to use \l{BorderImage::horizontalTileMode}{BorderImage.Round} instead of
\l{BorderImage::horizontalTileMode}{BorderImage.Repeat} in cases like these.
- The \l{declarative/imageelements/borderimage}{BorderImage example} shows how a BorderImage
+ The Border Image example in \l{Qt Quick Examples - Image Elements} shows how a BorderImage
can be used to simulate a shadow effect on a rectangular item.
\section1 Image Loading
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index d1bad78d41..63dde661d9 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -327,7 +327,7 @@ bool QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExt
maxDistance = qAbs(maxExtent - data.move.value());
data.flickTarget = maxExtent;
}
- if (maxDistance > 0) {
+ if (maxDistance > 0 || boundsBehavior == QQuickFlickable::DragAndOvershootBounds) {
qreal v = velocity;
if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
if (v < 0)
@@ -677,7 +677,7 @@ is finished.
\dots 8
\snippet qml/flickableScrollbar.qml 1
- \sa {declarative/customitems/scrollbar}{scrollbar example}
+ \sa {customitems/scrollbar}{UI Components: Scrollbar Example}
*/
QQuickFlickable::QQuickFlickable(QQuickItem *parent)
: QQuickItem(*(new QQuickFlickablePrivate), parent)
@@ -763,15 +763,8 @@ void QQuickFlickable::setInteractive(bool interactive)
Q_D(QQuickFlickable);
if (interactive != d->interactive) {
d->interactive = interactive;
- if (!interactive && (d->hData.flicking || d->vData.flicking)) {
- d->clearTimeline();
- d->hData.vTime = d->vData.vTime = d->timeline.time();
- d->hData.flicking = false;
- d->vData.flicking = false;
- emit flickingChanged();
- emit flickingHorizontallyChanged();
- emit flickingVerticallyChanged();
- emit flickEnded();
+ if (!interactive) {
+ d->cancelInteraction();
}
emit interactiveChanged();
}
@@ -1374,15 +1367,15 @@ void QQuickFlickablePrivate::replayDelayedPress()
delayedPressTimer.stop();
// If we have the grab, release before delivering the event
- QQuickWindow *w = q->window();
- if (w && (w->mouseGrabberItem() == q)) {
- q->ungrabMouse();
+ if (QQuickWindow *w = q->window()) {
+ if (w->mouseGrabberItem() == q)
+ q->ungrabMouse();
+
+ // Use the event handler that will take care of finding the proper item to propagate the event
+ replayingPressEvent = true;
+ QQuickWindowPrivate::get(w)->deliverMouseEvent(mouseEvent.data());
+ replayingPressEvent = false;
}
-
- // Use the event handler that will take care of finding the proper item to propagate the event
- replayingPressEvent = true;
- QQuickWindowPrivate::get(w)->deliverMouseEvent(mouseEvent.data());
- replayingPressEvent = false;
}
}
@@ -1541,6 +1534,10 @@ void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
void QQuickFlickable::flick(qreal xVelocity, qreal yVelocity)
{
Q_D(QQuickFlickable);
+ d->hData.reset();
+ d->vData.reset();
+ d->hData.velocity = xVelocity;
+ d->vData.velocity = yVelocity;
bool flickedX = d->flickX(xVelocity);
bool flickedY = d->flickY(yVelocity);
d->flickingStarted(flickedX, flickedY);
@@ -2011,18 +2008,24 @@ bool QQuickFlickable::yflick() const
void QQuickFlickable::mouseUngrabEvent()
{
Q_D(QQuickFlickable);
- if (d->pressed) {
- // if our mouse grab has been removed (probably by another Flickable),
- // fix our state
- d->clearDelayedPress();
- d->pressed = false;
- d->draggingEnding();
- d->stealMouse = false;
- setKeepMouseGrab(false);
- d->fixupX();
- d->fixupY();
- if (!d->isViewMoving())
- movementEnding();
+ // if our mouse grab has been removed (probably by another Flickable),
+ // fix our state
+ d->cancelInteraction();
+}
+
+void QQuickFlickablePrivate::cancelInteraction()
+{
+ Q_Q(QQuickFlickable);
+ if (pressed) {
+ clearDelayedPress();
+ pressed = false;
+ draggingEnding();
+ stealMouse = false;
+ q->setKeepMouseGrab(false);
+ fixupX();
+ fixupY();
+ if (!isViewMoving())
+ q->movementEnding();
}
}
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 07c434f452..13af2e055c 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -101,7 +101,7 @@ public:
AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal))
: move(fp, func)
, transitionToBounds(0)
- , viewSize(-1), lastPos(0), startMargin(0), endMargin(0)
+ , viewSize(-1), lastPos(0), velocity(0), startMargin(0), endMargin(0)
, origin(0)
, transitionTo(0)
, continuousFlickVelocity(0), velocityTime(), vTime(0)
@@ -200,6 +200,8 @@ public:
bool isViewMoving() const;
+ void cancelInteraction();
+
public:
QQuickItem *contentItem;
diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp
index 1ea5e57656..63466cf52d 100644
--- a/src/quick/items/qquickflipable.cpp
+++ b/src/quick/items/qquickflipable.cpp
@@ -127,7 +127,7 @@ public:
state, and \l {Animation and Transitions in Qt Quick} for more information on how
animations work within transitions.
- \sa {declarative/customitems/flipable}{Flipable example}
+ \sa {customitems/flipable}{UI Components: Flipable Example}
*/
QQuickFlipable::QQuickFlipable(QQuickItem *parent)
: QQuickItem(*(new QQuickFlipablePrivate), parent)
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index d5ca3a128e..c9a051c9bb 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -1616,7 +1616,7 @@ void QQuickGridView::setFlow(Flow flow)
}
setContentX(0);
setContentY(0);
- d->regenerate();
+ d->regenerate(true);
emit flowChanged();
}
}
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index d7527742dc..781fcccd9f 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -153,7 +153,7 @@ QQuickImagePrivate::QQuickImagePrivate()
size bounded via the \l sourceSize property. This is especially important for content
that is loaded from external sources or provided by the user.
- \sa {declarative/imageelements/image}{Image example}, QQuickImageProvider
+ \sa {Qt Quick Examples - Image Elements}, QQuickImageProvider
*/
QQuickImage::QQuickImage(QQuickItem *parent)
@@ -277,7 +277,7 @@ void QQuickImagePrivate::setImage(const QImage &image)
Note that \c clip is \c false by default which means that the item might
paint outside its bounding rectangle even if the fillMode is set to \c PreserveAspectCrop.
- \sa {declarative/imageelements/image}{Image example}
+ \sa {Qt Quick Examples - Image Elements}
*/
QQuickImage::FillMode QQuickImage::fillMode() const
{
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 66a56cc8bf..bf67cbef26 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -332,6 +332,11 @@ void QQuickImageBase::resolve2xLocalFile(const QUrl &url, qreal targetDevicePixe
Q_ASSERT(sourceUrl);
Q_ASSERT(sourceDevicePixelRatio);
+ // Bail out if "@2x" image loading is disabled, don't change the source url or devicePixelRatio.
+ static bool disable2xImageLoading = !qgetenv("QT_HIGHDPI_DISABLE_2X_IMAGE_LOADING").isEmpty();
+ if (disable2xImageLoading)
+ return;
+
QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
// Non-local file path: @2x loading is not supported.
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index ef2eac4b61..442080a335 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1333,6 +1333,7 @@ void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
+ event->accept();
QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inPress = false;
@@ -1375,6 +1376,7 @@ void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
+ event->accept();
QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inRelease = false;
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 94abbd0954..ff8c69a9c0 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1783,18 +1783,20 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
emit q->countChanged();
}
-void QQuickItemViewPrivate::regenerate()
+void QQuickItemViewPrivate::regenerate(bool orientationChanged)
{
Q_Q(QQuickItemView);
if (q->isComponentComplete()) {
currentChanges.reset();
- delete header;
- header = 0;
- delete footer;
- footer = 0;
+ if (orientationChanged) {
+ delete header;
+ header = 0;
+ delete footer;
+ footer = 0;
+ }
+ clear();
updateHeader();
updateFooter();
- clear();
updateViewport();
setPosition(contentStartOffset());
refill();
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a0d17b3bf9..297b9a1471 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -184,7 +184,7 @@ public:
virtual void clear();
virtual void updateViewport();
- void regenerate();
+ void regenerate(bool orientationChanged=false);
void layout();
virtual void animationFinished(QAbstractAnimationJob *);
void refill();
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index ba4f1c53ba..e5b9f9cf59 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -1937,7 +1937,7 @@ QQuickListView::~QQuickListView()
highlight item is \c 0.
\sa highlightItem, highlightFollowsCurrentItem,
- {Qt Quick Examples - Views#Highlight demonstrates adding a custom highlight to a ListView.}{ListView highlight example}
+ {Qt Quick Examples - Views#Highlight}{ListView highlight example}
*/
/*!
@@ -2070,7 +2070,7 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
setFlickableDirection(HorizontalFlick);
setContentY(0);
}
- d->regenerate();
+ d->regenerate(true);
emit orientationChanged();
}
}
@@ -2252,7 +2252,7 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
differing sections will result in a section header being created
even if that section exists elsewhere.
- \sa {quick/views/listview}{ListView examples}
+ \sa {Qt Quick Examples - Views}{ListView examples}
*/
QQuickViewSection *QQuickListView::sectionCriteria()
{
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index d4b64ea75a..bac52f04f8 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -253,7 +253,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
\snippet qml/mousearea/mousearea.qml intro-extended
- \sa MouseEvent, {declarative/touchinteraction/mousearea}{MouseArea example},
+ \sa MouseEvent, {mousearea}{MouseArea example},
{Important Concepts In Qt Quick - User Input}
*/
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index c564a78c3c..1ffa95771b 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -141,25 +141,25 @@ protected:
bool setPressed(Qt::MouseButton button, bool);
bool sendMouseEvent(QMouseEvent *event);
- virtual void mousePressEvent(QMouseEvent *event);
- virtual void mouseReleaseEvent(QMouseEvent *event);
- virtual void mouseDoubleClickEvent(QMouseEvent *event);
- virtual void mouseMoveEvent(QMouseEvent *event);
- virtual void mouseUngrabEvent();
- virtual void hoverEnterEvent(QHoverEvent *event);
- virtual void hoverMoveEvent(QHoverEvent *event);
- virtual void hoverLeaveEvent(QHoverEvent *event);
+ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mouseUngrabEvent() Q_DECL_OVERRIDE;
+ void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
+ void hoverMoveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
+ void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
#ifndef QT_NO_WHEELEVENT
- virtual void wheelEvent(QWheelEvent *event);
+ void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
#endif
- virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e);
- virtual void timerEvent(QTimerEvent *event);
- virtual void windowDeactivateEvent();
-
- virtual void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry);
- virtual void itemChange(ItemChange change, const ItemChangeData& value);
- virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ bool childMouseEventFilter(QQuickItem *i, QEvent *e) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
+ void windowDeactivateEvent() Q_DECL_OVERRIDE;
+
+ void geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ void itemChange(ItemChange change, const ItemChangeData& value) Q_DECL_OVERRIDE;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
private:
void handlePress();
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 45cd8e184c..335e7611f1 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -104,6 +104,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate()
, stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
, autoHighlight(true), highlightUp(false), layoutScheduled(false)
, moving(false), flicking(false), dragging(false), inRequest(false), delegateValidated(false)
+ , inRefill(false)
, dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY)
, moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
, firstIndex(-1), pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
@@ -1873,11 +1874,18 @@ void QQuickPathView::refill()
{
Q_D(QQuickPathView);
+ if (d->inRefill) {
+ d->scheduleLayout();
+ return;
+ }
+
d->layoutScheduled = false;
if (!d->isValid() || !isComponentComplete())
return;
+ d->inRefill = true;
+
bool currentVisible = false;
int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
@@ -2010,6 +2018,8 @@ void QQuickPathView::refill()
}
while (d->itemCache.count())
d->releaseItem(d->itemCache.takeLast());
+
+ d->inRefill = false;
}
void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index 813f472072..e21f3757e6 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -152,6 +152,7 @@ public:
bool requestedOnPath : 1;
bool inRequest : 1;
bool delegateValidated : 1;
+ bool inRefill : 1;
QElapsedTimer timer;
qint64 lastPosTime;
QPointF lastPos;
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index a155ff1843..25a1805a44 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -58,13 +58,13 @@ class Q_AUTOTEST_EXPORT QQuickScreenAttached : public QObject
{
Q_OBJECT
- Q_PROPERTY(QString name READ name NOTIFY nameChanged REVISION 1);
+ Q_PROPERTY(QString name READ name NOTIFY nameChanged);
Q_PROPERTY(int width READ width NOTIFY widthChanged)
Q_PROPERTY(int height READ height NOTIFY heightChanged)
- Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged REVISION 1)
- Q_PROPERTY(int desktopAvailableHeight READ desktopAvailableHeight NOTIFY desktopGeometryChanged REVISION 1)
- Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged REVISION 1)
- Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged REVISION 2)
+ Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged)
+ Q_PROPERTY(int desktopAvailableHeight READ desktopAvailableHeight NOTIFY desktopGeometryChanged)
+ Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged)
+ Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged)
Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged)
Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged)
@@ -87,12 +87,12 @@ public:
void windowChanged(QQuickWindow*);
Q_SIGNALS:
- Q_REVISION(1) void nameChanged();
+ void nameChanged();
void widthChanged();
void heightChanged();
- Q_REVISION(1) void desktopGeometryChanged();
- Q_REVISION(1) void logicalPixelDensityChanged();
- Q_REVISION(2) void pixelDensityChanged();
+ void desktopGeometryChanged();
+ void logicalPixelDensityChanged();
+ void pixelDensityChanged();
void primaryOrientationChanged();
void orientationChanged();
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index ebeff599f4..99d4979073 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -1031,7 +1031,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
}
// Don't create the paint node if we're not spanning any area
- if (width() == 0 || height() == 0) {
+ if (width() <= 0 || height() <= 0) {
delete oldNode;
return 0;
}
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index cbdea3917a..71265689e9 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -711,7 +711,8 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
}
bool shouldUseDesignMetrics = renderType != QQuickText::NativeRendering;
-
+ if (!visibleImgTags.isEmpty())
+ visibleImgTags.clear();
layout.setCacheEnabled(true);
QTextOption textOption = layout.textOption();
if (textOption.alignment() != q->effectiveHAlign()
@@ -940,9 +941,10 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
maxHeight = q->heightValid() ? q->height() : FLT_MAX;
// If the width of the item has changed and it's possible the result of wrapping,
- // eliding, or scaling has changed do another layout.
+ // eliding, scaling has changed, or the text is not left aligned do another layout.
if ((lineWidth < qMin(oldWidth, naturalWidth) || (widthExceeded && lineWidth > oldWidth))
- && (singlelineElide || multilineElide || canWrap || horizontalFit)) {
+ && (singlelineElide || multilineElide || canWrap || horizontalFit
+ || q->effectiveHAlign() != QQuickText::AlignLeft)) {
widthExceeded = false;
heightExceeded = false;
continue;
@@ -1227,7 +1229,7 @@ void QQuickTextPrivate::ensureDoc()
Text provides read-only text. For editable text, see \l TextEdit.
- \sa {declarative/text/fonts}{Fonts example}
+ \sa {Qt Quick Examples - Text#Fonts}{Fonts example}
*/
QQuickText::QQuickText(QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickTextPrivate), parent)
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 5280301675..fdaef6df8e 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -112,7 +112,7 @@ TextEdit {
You can translate between cursor positions (characters from the start of the document) and pixel
points using positionAt() and positionToRectangle().
- \sa Text, TextInput, {examples/quick/text/textselection}{Text Selection example}
+ \sa Text, TextInput
*/
/*!
@@ -1777,8 +1777,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
d->updateType = QQuickTextEditPrivate::UpdateNone;
- if (!oldNode) // If we had any text node references, they were deleted along with the root node
+ if (!oldNode) {
+ // If we had any QQuickTextNode node references, they were deleted along with the root node
+ // But here we must delete the Node structures in textNodeMap
+ qDeleteAll(d->textNodeMap);
d->textNodeMap.clear();
+ }
RootNode *rootNode = static_cast<RootNode *>(oldNode);
TextNodeIterator nodeIterator = d->textNodeMap.begin();
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 25681c89f6..0cf7ee2850 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -111,6 +111,11 @@ public:
{
}
+ ~QQuickTextEditPrivate()
+ {
+ qDeleteAll(textNodeMap);
+ }
+
static QQuickTextEditPrivate *get(QQuickTextEdit *item) {
return static_cast<QQuickTextEditPrivate *>(QObjectPrivate::get(item)); }
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 597025b796..b70e292026 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -87,7 +87,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
On Mac OS X, the Up/Down key bindings for Home/End are explicitly disabled.
If you want such bindings (on any platform), you will need to construct them in QML.
- \sa TextEdit, Text, {declarative/text/textselection}{Text Selection example}
+ \sa TextEdit, Text
*/
QQuickTextInput::QQuickTextInput(QQuickItem* parent)
: QQuickImplicitSizeItem(*(new QQuickTextInputPrivate), parent)
diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp
index da0d9cd714..02e321dfba 100644
--- a/src/quick/items/qquicktextnode.cpp
+++ b/src/quick/items/qquicktextnode.cpp
@@ -303,6 +303,8 @@ void QQuickTextNode::deleteContent()
while (firstChild() != 0)
delete firstChild();
m_cursorNode = 0;
+ qDeleteAll(m_textures);
+ m_textures.clear();
}
#if 0
diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp
index 14f8c204f3..ebf9f616a2 100644
--- a/src/quick/items/qquicktranslate.cpp
+++ b/src/quick/items/qquicktranslate.cpp
@@ -336,7 +336,7 @@ public:
\image axisrotation.png
- \sa {declarative/customitems/dialcontrol}{Dial Control example}, {Qt Quick Demo - Clocks}
+ \sa {customitems/dialcontrol}{Dial Control example}, {Qt Quick Demo - Clocks}
*/
QQuickRotation::QQuickRotation(QObject *parent)
: QQuickTransform(*new QQuickRotationPrivate, parent)
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index e78f9141a8..3c2718dcaf 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1093,6 +1093,7 @@ QQuickWindow::~QQuickWindow()
d->windowManager->windowDestroyed(this);
}
+ QCoreApplication::removePostedEvents(this, QEvent::DeferredDelete);
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
delete d->incubationController; d->incubationController = 0;
#ifndef QT_NO_DRAGANDDROP
@@ -3081,6 +3082,8 @@ QQmlIncubationController *QQuickWindow::incubationController() const
\warning Make very sure that a signal handler for beforeSynchronizing leaves the GL
context in the same state as it was when the signal handler was entered. Failing to
do so can result in the scene not rendering properly.
+
+ \sa resetOpenGLState()
*/
/*!
@@ -3102,6 +3105,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
do so can result in the scene not rendering properly.
\since 5.3
+ \sa resetOpenGLState()
*/
/*!
@@ -3122,6 +3126,8 @@ QQmlIncubationController *QQuickWindow::incubationController() const
\warning Make very sure that a signal handler for beforeRendering leaves the GL
context in the same state as it was when the signal handler was entered. Failing to
do so can result in the scene not rendering properly.
+
+ \sa resetOpenGLState()
*/
/*!
@@ -3141,6 +3147,8 @@ QQmlIncubationController *QQuickWindow::incubationController() const
\warning Make very sure that a signal handler for afterRendering() leaves the GL
context in the same state as it was when the signal handler was entered. Failing to
do so can result in the scene not rendering properly.
+
+ \sa resetOpenGLState()
*/
/*!
@@ -3193,7 +3201,7 @@ QQmlIncubationController *QQuickWindow::incubationController() const
context in the same state as it was when the signal handler was entered. Failing to
do so can result in the scene not rendering properly.
- \sa sceneGraphInvalidated()
+ \sa sceneGraphInvalidated(), resetOpenGLState()
\since 5.3
*/
@@ -3260,7 +3268,7 @@ QSGTexture *QQuickWindow::createTextureFromImage(const QImage &image) const
\warning The returned texture is not memory managed by the scene graph and
must be explicitly deleted by the caller on the rendering thread.
- This is acheived by deleting the texture from a QSGNode destructor
+ This is achieved by deleting the texture from a QSGNode destructor
or by using deleteLater() in the case where the texture already has affinity
to the rendering thread.
diff --git a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
index 9ff0971774..bffdf40bc1 100644
--- a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
+++ b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
@@ -52,7 +52,6 @@ namespace QSGShaderRewriter {
struct Tokenizer {
enum Token {
- Token_Invalid,
Token_Void,
Token_OpenBrace,
Token_CloseBrace,
@@ -75,7 +74,6 @@ struct Tokenizer {
};
const char *Tokenizer::NAMES[] = {
- "Invalid",
"Void",
"OpenBrace",
"CloseBrace",
@@ -167,7 +165,7 @@ Tokenizer::Token Tokenizer::next()
}
}
- return Token_Invalid;
+ return Token_EOF;
}
}
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index e76aa1bbb5..05302cfe33 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -94,8 +94,12 @@ void QSGRenderLoop::cleanup()
foreach (QQuickWindow *w, s_instance->windows()) {
QQuickWindowPrivate *wd = QQuickWindowPrivate::get(w);
if (wd->windowManager == s_instance) {
+ // windowDestroyed() triggers a sendPostedEvent(DeferredDelete),
+ // so wd will be null if the window was deleteLater()'ed
+ bool wasDeleted = wd->wasDeleted;
s_instance->windowDestroyed(w);
- wd->windowManager = 0;
+ if (!wasDeleted)
+ wd->windowManager = 0;
}
}
delete s_instance;
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index e37344b21c..782beca1de 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -274,6 +274,9 @@ void Atlas::uploadBgra(Texture *texture)
const QRect &r = texture->atlasSubRect();
QImage image = texture->image();
+ if (image.isNull())
+ return;
+
if (image.format() != QImage::Format_ARGB32_Premultiplied
&& image.format() != QImage::Format_RGB32) {
image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
diff --git a/src/quick/scenegraph/util/qsgpainternode.cpp b/src/quick/scenegraph/util/qsgpainternode.cpp
index b454f666ac..8ccb9d2ffb 100644
--- a/src/quick/scenegraph/util/qsgpainternode.cpp
+++ b/src/quick/scenegraph/util/qsgpainternode.cpp
@@ -96,7 +96,6 @@ QSGPainterNode::QSGPainterNode(QQuickPaintedItem *item)
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
, m_texture(0)
, m_gl_device(0)
- , m_size(1, 1)
, m_dirtyContents(false)
, m_opaquePainting(false)
, m_linear_filtering(false)
@@ -116,6 +115,10 @@ QSGPainterNode::QSGPainterNode(QQuickPaintedItem *item)
setMaterial(&m_materialO);
setOpaqueMaterial(&m_material);
setGeometry(&m_geometry);
+
+#ifdef QSG_RUNTIME_DESCRIPTION
+ qsgnode_set_description(this, QString::fromLatin1("QQuickPaintedItem(%1):%2").arg(QString::fromLatin1(item->metaObject()->className())).arg(item->objectName()));
+#endif
}
QSGPainterNode::~QSGPainterNode()
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index 10d2176d0a..544e2d4daa 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -2344,8 +2344,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
groups of three points defining a curve from 0,0 to 1,1 - control1, control2,
end point: [cx1, cy1, cx2, cy2, endx, endy, ...]. The last point must be 1,1.
- See the \l {qml/animation/easing}{easing} example for a demonstration of
- the different easing settings.
+ See the \l {Qt Quick Examples - Animation#Easing Curves}{Easing Curves} for a demonstration of the different easing settings.
//! propertyanimation.easing
*/
QEasingCurve QQuickPropertyAnimation::easing() const
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index 74e5b40ab1..2e37682811 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -99,7 +99,7 @@ public:
state change. For general advice on using Behaviors to animate state changes, see
\l{Using Qt Quick Behaviors with States}.
- \sa {Animation and Transitions in Qt Quick}, {declarative/animation/behaviors}{Behavior example}, {Qt QML}
+ \sa {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation#Behaviors}{Behavior example}, {Qt QML}
*/
diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp
index c0672359ef..26f34b46c6 100644
--- a/src/quick/util/qquickfontloader.cpp
+++ b/src/quick/util/qquickfontloader.cpp
@@ -170,7 +170,7 @@ QHash<QUrl, QQuickFontObject*> QQuickFontLoaderPrivate::fonts;
}
\endqml
- \sa {declarative/text/fonts}{Fonts example}
+ \sa {Qt Quick Examples - Text#Fonts}{Qt Quick Examples - Text Fonts}
*/
QQuickFontLoader::QQuickFontLoader(QObject *parent)
: QObject(*(new QQuickFontLoaderPrivate), parent)
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 16c18d2594..24d6ad7a1f 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -203,9 +203,8 @@ QImage QQuickTextureFactory::image() const
\image imageprovider.png
- A complete example is available in Qt's
- \l {qml/imageprovider}{examples/quick/imageprovider}
- directory. Note the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
+ See the \l {imageprovider}{Image Provider Example} for the complete implementation.
+ Note that the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
instead of registering it in the application \c main() function as shown above.
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index 882ad66891..0289f46429 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -132,7 +132,7 @@ QT_BEGIN_NAMESPACE
changed implicitly through their parent's state, they should be set explicitly in all PropertyChanges.
An item will still not be enabled/visible if one of its parents is not enabled or visible.
- \sa {declarative/animation/states}{states example}, {Qt Quick States}{Qt Quick States}, {Qt QML}
+ \sa {Qt Quick Examples - Animation#States}{States example}, {Qt Quick States}, {Qt QML}
*/
/*!
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index 2cc8a4e50d..641dea3dc7 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -150,7 +150,7 @@ QQuickStateOperation::QQuickStateOperation(QObjectPrivate &dd, QObject *parent)
\note Setting the state of an object from within another state of the same object is
not allowed.
- \sa {declarative/animation/states}{states example}, {Qt Quick States}{Qt Quick States},
+ \sa {Qt Quick Examples - Animation#States}{States example}, {Qt Quick States},
{Animation and Transitions in Qt Quick}{Transitions}, {Qt QML}
*/
QQuickState::QQuickState(QObject *parent)
diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp
index dcfc4549c2..6d1f646f95 100644
--- a/src/quick/util/qquicktransition.cpp
+++ b/src/quick/util/qquicktransition.cpp
@@ -96,7 +96,7 @@ QT_BEGIN_NAMESPACE
\l Behavior, the Transition animation overrides the \l Behavior for that
state change.
- \sa {Animation and Transitions in Qt Quick}, {declarative/animation/states}{states example}, {Qt Quick States}{Qt Quick States}, {Qt QML}
+ \sa {Animation and Transitions in Qt Quick}, {Qt Quick Examples - Animation#States}{States example}, {Qt Quick States}, {Qt QML}
*/
//ParallelAnimationWrapper allows us to do a "callback" when the animation finishes, rather than connecting
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index 3743a8cf1e..5e1502b633 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -310,6 +310,7 @@ QQuickWidget::QQuickWidget(QWidget *parent)
: QWidget(*(new QQuickWidgetPrivate), parent, 0)
{
setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
d_func()->init();
}
@@ -322,6 +323,7 @@ QQuickWidget::QQuickWidget(const QUrl &source, QWidget *parent)
: QWidget(*(new QQuickWidgetPrivate), parent, 0)
{
setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
d_func()->init();
setSource(source);
}
@@ -339,6 +341,7 @@ QQuickWidget::QQuickWidget(QQmlEngine* engine, QWidget *parent)
: QWidget(*(new QQuickWidgetPrivate), parent, 0)
{
setMouseTracking(true);
+ setFocusPolicy(Qt::StrongFocus);
Q_ASSERT(engine);
d_func()->init(engine);
}
diff --git a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
index 26919af1b6..f91d0135a9 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
+++ b/tests/auto/qml/debugger/qpacketprotocol/tst_qpacketprotocol.cpp
@@ -84,10 +84,15 @@ void tst_QPacketProtocol::init()
QVERIFY(m_server->listen(QHostAddress("127.0.0.1")));
m_client = new QTcpSocket(this);
+
+ QSignalSpy serverSpy(m_server, SIGNAL(newConnection()));
+ QSignalSpy clientSpy(m_client, SIGNAL(connected()));
+
m_client->connectToHost(m_server->serverAddress(), m_server->serverPort());
- QVERIFY(m_client->waitForConnected());
- QVERIFY(m_server->waitForNewConnection(10000));
+ QVERIFY(clientSpy.count() > 0 || clientSpy.wait());
+ QVERIFY(serverSpy.count() > 0 || serverSpy.wait());
+
m_serverConn = m_server->nextPendingConnection();
}
diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml
index 8847055a70..5103168fd3 100644
--- a/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml
+++ b/tests/auto/qml/qqmlecmascript/data/sequenceConversion.array.qml
@@ -165,6 +165,43 @@ Item {
}
}
}
+
+ // unshift
+ msco.stringListProperty = [ "one", "two" ]
+ var unshiftedVal = msco.stringListProperty.unshift("zero")
+ expected = [ "zero", "one", "two" ]
+ if (msco.stringListProperty.toString() != expected.toString()) success = false;
+ expected = 3
+ if (msco.stringListProperty.length != expected) success = false
+ msco.stringListProperty = [ ]
+ msco.stringListProperty.unshift("zero", "one")
+ expected = [ "zero", "one" ]
+ if (msco.stringListProperty.toString() != expected.toString()) success = false;
+ expected = 2
+ if (msco.stringListProperty.length != expected) success = false
+
+ // shift
+ msco.stringListProperty = [ "one", "two", "three" ]
+ var shiftVal = msco.stringListProperty.shift()
+ expected = [ "two", "three" ]
+ if (msco.stringListProperty.toString() != expected.toString()) success = false;
+ expected = "one"
+ if (shiftVal != expected) success = false
+ shiftVal = msco.stringListProperty.shift()
+ expected = [ "three" ]
+ if (msco.stringListProperty.toString() != expected.toString()) success = false;
+ expected = "two"
+ if (shiftVal != expected) success = false
+ shiftVal = msco.stringListProperty.shift()
+ expected = 0
+ if (msco.stringListProperty.length != expected) success = false;
+ expected = "three"
+ if (shiftVal != expected) success = false
+ shiftVal = msco.stringListProperty.shift()
+ expected = 0
+ if (msco.stringListProperty.length != expected) success = false;
+ expected = undefined
+ if (shiftVal != expected) success = false
}
property variant variantList: [ 1, 2, 3, 4, 5 ];
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index eb06b9e57d..560d86005c 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -300,6 +300,62 @@ static QObject *create_singletonWithEnum(QQmlEngine *, QJSEngine *)
return new SingletonWithEnum;
}
+QObjectContainer::QObjectContainer()
+ : widgetParent(0)
+ , gcOnAppend(false)
+{}
+
+QQmlListProperty<QObject> QObjectContainer::data()
+{
+ return QQmlListProperty<QObject>(this, 0, children_append, children_count, children_at, children_clear);
+}
+
+void QObjectContainer::children_append(QQmlListProperty<QObject> *prop, QObject *o)
+{
+ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
+ that->dataChildren.append(o);
+ QObject::connect(o, SIGNAL(destroyed(QObject*)), prop->object, SLOT(childDestroyed(QObject*)));
+
+ if (that->gcOnAppend) {
+ QQmlEngine *engine = qmlEngine(that);
+ engine->collectGarbage();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+ }
+}
+
+int QObjectContainer::children_count(QQmlListProperty<QObject> *prop)
+{
+ return static_cast<QObjectContainer*>(prop->object)->dataChildren.count();
+}
+
+QObject *QObjectContainer::children_at(QQmlListProperty<QObject> *prop, int index)
+{
+ return static_cast<QObjectContainer*>(prop->object)->dataChildren.at(index);
+}
+
+void QObjectContainer::children_clear(QQmlListProperty<QObject> *prop)
+{
+ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
+ foreach (QObject *c, that->dataChildren)
+ QObject::disconnect(c, SIGNAL(destroyed(QObject*)), that, SLOT(childDestroyed(QObject*)));
+ that->dataChildren.clear();
+}
+
+void QObjectContainer::childDestroyed(QObject *child) {
+ dataChildren.removeAll(child);
+}
+
+void FloatingQObject::classBegin()
+{
+ setParent(0);
+}
+
+void FloatingQObject::componentComplete()
+{
+ Q_ASSERT(!parent());
+}
+
void registerTypes()
{
qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias");
@@ -381,6 +437,10 @@ void registerTypes()
qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi2",1,0,"Data",testImportOrder_api2);
qmlRegisterSingletonType<SingletonWithEnum>("Qt.test.singletonWithEnum", 1, 0, "SingletonWithEnum", create_singletonWithEnum);
+
+ qmlRegisterType<QObjectContainer>("Qt.test", 1, 0, "QObjectContainer");
+ qmlRegisterType<QObjectContainerWithGCOnAppend>("Qt.test", 1, 0, "QObjectContainerWithGCOnAppend");
+ qmlRegisterType<FloatingQObject>("Qt.test", 1, 0, "FloatingQObject");
}
#include "testtypes.moc"
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 928d594f62..d5a1220f23 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1661,6 +1661,51 @@ public:
};
};
+// Like QtObject, but with default property
+class QObjectContainer : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("DefaultProperty", "data")
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
+public:
+ QObjectContainer();
+
+ QQmlListProperty<QObject> data();
+
+ static void children_append(QQmlListProperty<QObject> *prop, QObject *o);
+ static int children_count(QQmlListProperty<QObject> *prop);
+ static QObject *children_at(QQmlListProperty<QObject> *prop, int index);
+ static void children_clear(QQmlListProperty<QObject> *prop);
+
+ QList<QObject*> dataChildren;
+ QWidget *widgetParent;
+ bool gcOnAppend;
+
+protected slots:
+ void childDestroyed(QObject *child);
+};
+
+class QObjectContainerWithGCOnAppend : public QObjectContainer
+{
+ Q_OBJECT
+public:
+ QObjectContainerWithGCOnAppend()
+ {
+ gcOnAppend = true;
+ }
+};
+
+class FloatingQObject : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+public:
+ FloatingQObject() {}
+
+ virtual void classBegin();
+ virtual void componentComplete();
+};
+
void registerTypes();
#endif // TESTTYPES_H
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index a1e36b42e6..a9486a8e63 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -322,6 +322,7 @@ private slots:
void varPropertyAccessOnObjectWithInvalidContext();
void importedScriptsAccessOnObjectWithInvalidContext();
void contextObjectOnLazyBindings();
+ void garbageCollectionDuringCreation();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -7603,6 +7604,33 @@ void tst_qqmlecmascript::contextObjectOnLazyBindings()
QCOMPARE(subObject->property("testValue").toInt(), int(42));
}
+void tst_qqmlecmascript::garbageCollectionDuringCreation()
+{
+ QQmlComponent component(&engine);
+ component.setData("import Qt.test 1.0\n"
+ "QObjectContainerWithGCOnAppend {\n"
+ " objectName: \"root\"\n"
+ " FloatingQObject {\n"
+ " objectName: \"parentLessChild\"\n"
+ " property var blah;\n" // Ensure we have JS wrapper
+ " }\n"
+ "}\n",
+ QUrl());
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ QObject *child = container->dataChildren.first();
+ QQmlData *ddata = QQmlData::get(child);
+ QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
+
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 0);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml
index 03be57909f..069b62a726 100644
--- a/tests/auto/qmltest/listview/tst_listview.qml
+++ b/tests/auto/qmltest/listview/tst_listview.qml
@@ -108,6 +108,33 @@ Item {
property int createdDelegates: 0
}
+ ListView
+ {
+ id: listInteractiveCurrentIndexEnforce
+ width: 600
+ height: 600
+
+ snapMode: ListView.SnapOneItem
+ orientation: ListView.Horizontal
+ interactive: !currentItem.moving
+ highlightRangeMode: ListView.StrictlyEnforceRange
+
+ model: 4
+
+ focus: true
+ Keys.onPressed: if (event.key == Qt.Key_K) currentIndex = currentIndex + 1;
+
+ delegate: Flickable {
+ width: 600
+ height: 600
+ contentWidth: 600
+ contentHeight: 1200
+
+ MouseArea { anchors.fill: parent }
+ Rectangle { anchors.fill: parent; color: index == 0 ? "red" : index == 1 ? "green" : index == 2 ? "blue" : "white" }
+ }
+ }
+
Component {
id: delegateModelAfterCreateComponent
Rectangle {
@@ -272,5 +299,19 @@ Item {
listViewDelegateModelAfterCreate.model = 40;
verify(listViewDelegateModelAfterCreate.createdDelegates > 0);
}
+
+ function test_listInteractiveCurrentIndexEnforce() {
+ mousePress(listInteractiveCurrentIndexEnforce, 10, 50);
+ mouseMove(listInteractiveCurrentIndexEnforce, 10, 40);
+ mouseMove(listInteractiveCurrentIndexEnforce, 10, 30);
+ mouseMove(listInteractiveCurrentIndexEnforce, 10, 20);
+ mouseMove(listInteractiveCurrentIndexEnforce, 10, 10);
+ compare(listInteractiveCurrentIndexEnforce.interactive, false);
+ mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10);
+ tryCompare(listInteractiveCurrentIndexEnforce, "interactive", true);
+ keyClick("k");
+ compare(listInteractiveCurrentIndexEnforce.currentIndex, 1);
+ tryCompare(listInteractiveCurrentIndexEnforce, "contentX", listInteractiveCurrentIndexEnforce.width);
+ }
}
}
diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
index 7d50e130f2..760cdd7b49 100644
--- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
+++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
@@ -281,7 +281,7 @@ void tst_QQuickAccessible::basicPropertiesTest()
QVERIFY(item);
QCOMPARE(item->childCount(), 2);
QCOMPARE(item->rect().size(), QSize(400, 400));
- QCOMPARE(item->role(), QAccessible::Pane);
+ QCOMPARE(item->role(), QAccessible::Client);
QCOMPARE(iface->indexOfChild(item), 0);
QAccessibleInterface *text = item->child(0);
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 863fb69b84..a350074b42 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -3613,12 +3613,13 @@ void tst_QQuickGridView::resetModel_headerFooter()
model.reset();
- header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
+ // A reset should not force a new header or footer to be created.
+ QQuickItem *newHeader = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(newHeader == header);
QCOMPARE(header->y(), -header->height());
- footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
+ QQuickItem *newFooter = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(newFooter == footer);
QCOMPARE(footer->y(), 60.*2);
delete window;
diff --git a/tests/auto/quick/qquickitem2/data/keysforward.qml b/tests/auto/quick/qquickitem2/data/keysforward.qml
index f0cb4d9508..5677aa62f1 100644
--- a/tests/auto/quick/qquickitem2/data/keysforward.qml
+++ b/tests/auto/quick/qquickitem2/data/keysforward.qml
@@ -58,7 +58,7 @@ Item {
objectName: "primary"
property var pressedKeys: []
property var releasedKeys: []
- Keys.forwardTo: secondaryTarget
+ Keys.forwardTo: [ secondaryTarget, extraTarget ]
Keys.onPressed: { event.accepted = event.key === Qt.Key_P; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
Keys.onReleased: { event.accepted = event.key === Qt.Key_P; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
@@ -81,4 +81,8 @@ Item {
Keys.onPressed: { event.accepted = event.key === Qt.Key_S; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
Keys.onReleased: { event.accepted = event.key === Qt.Key_S; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
}
+
+ Item {
+ id: extraTarget
+ }
}
diff --git a/tests/auto/quick/qquicklistview/data/layoutChangeSort.qml b/tests/auto/quick/qquicklistview/data/layoutChangeSort.qml
new file mode 100644
index 0000000000..e54f164e45
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/layoutChangeSort.qml
@@ -0,0 +1,58 @@
+import QtQuick 2.0
+import QtQml.Models 2.1
+
+Rectangle {
+ id: root
+ width: 240
+ height: 320
+ color: "#ffffff"
+
+
+ Component {
+ id: myDelegate
+ Rectangle {
+ id: wrapper
+ objectName: "wrapper"
+ height: 20
+ width: 240
+ Text {
+ objectName: "delegateText"
+ text: display
+ }
+ color: ListView.isCurrentItem ? "lightsteelblue" : "white"
+ }
+ }
+
+ DelegateModel {
+ id: delegateModel
+ objectName: "delegateModel"
+ model: testModel
+ delegate: myDelegate
+ }
+
+ ListView {
+ id: list
+ objectName: "listView"
+ model: delegateModel;
+ focus: true
+ anchors.fill: parent
+
+
+ section {
+ property: "SortRole";
+ delegate: Rectangle {
+ width: parent.width;
+ height: 20;
+ color: "steelblue";
+
+ Text {
+ anchors {
+ fill: parent;
+ margins: 5;
+ }
+ text: section;
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/simplelistview.qml b/tests/auto/quick/qquicklistview/data/simplelistview.qml
new file mode 100644
index 0000000000..56a96150c5
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/simplelistview.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.0
+
+ListView {
+ width: 400
+ height: 400
+ model: 100
+ delegate: Rectangle {
+ height: 40; width: 400
+ color: index % 2 ? "lightsteelblue" : "lightgray"
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro
index 2ae04d32fe..c9b634b9e8 100644
--- a/tests/auto/quick/qquicklistview/qquicklistview.pro
+++ b/tests/auto/quick/qquicklistview/qquicklistview.pro
@@ -4,10 +4,13 @@ TARGET = tst_qquicklistview
macx:CONFIG -= app_bundle
HEADERS += incrementalmodel.h \
- proxytestinnermodel.h
+ proxytestinnermodel.h \
+ randomsortmodel.h
SOURCES += tst_qquicklistview.cpp \
incrementalmodel.cpp \
- proxytestinnermodel.cpp
+ proxytestinnermodel.cpp \
+ randomsortmodel.cpp
+
include (../../shared/util.pri)
include (../shared/util.pri)
diff --git a/tests/auto/quick/qquicklistview/randomsortmodel.cpp b/tests/auto/quick/qquicklistview/randomsortmodel.cpp
new file mode 100644
index 0000000000..e9082e39c9
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/randomsortmodel.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "randomsortmodel.h"
+
+RandomSortModel::RandomSortModel(QObject* parent):
+ QAbstractListModel(parent)
+{
+ for (int i = 0; i < 10; ++i) {
+ mData.append(qMakePair(QString::fromLatin1("Item %1").arg(i), i * 10));
+ }
+}
+
+QHash<int, QByteArray> RandomSortModel::roleNames() const
+{
+ QHash<int,QByteArray> roles = QAbstractItemModel::roleNames();
+ roles[Qt::UserRole] = "SortRole";
+ return roles;
+}
+
+
+int RandomSortModel::rowCount(const QModelIndex& parent) const
+{
+ if (!parent.isValid())
+ return mData.count();
+
+ return 0;
+}
+
+QVariant RandomSortModel::data(const QModelIndex& index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (index.row() >= mData.count()) {
+ return QVariant();
+ }
+
+ if (role == Qt::DisplayRole) {
+ return QString::fromLatin1("%1 (weight %2)").arg(mData[index.row()].first).arg(mData[index.row()].second);
+ } else if (role == Qt::UserRole) {
+ return mData[index.row()].second;
+ }
+
+ return QVariant();
+}
+
+void RandomSortModel::randomize()
+{
+ const int row = qrand() % mData.count();
+ int random;
+ bool exists = false;
+ // Make sure we won't end up with two items with the same weight, as that
+ // would make unit-testing much harder
+ do {
+ exists = false;
+ random = qrand() % (mData.count() * 10);
+ QList<QPair<QString, int> >::ConstIterator iter, end;
+ for (iter = mData.constBegin(), end = mData.constEnd(); iter != end; ++iter) {
+ if ((*iter).second == random) {
+ exists = true;
+ break;
+ }
+ }
+ } while (exists);
+ mData[row].second = random;
+ Q_EMIT dataChanged(index(row, 0), index(row, 0));
+}
diff --git a/tests/auto/quick/qquicklistview/randomsortmodel.h b/tests/auto/quick/qquicklistview/randomsortmodel.h
new file mode 100644
index 0000000000..8d28698d9b
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/randomsortmodel.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RANDOMSORTMODEL_H
+#define RANDOMSORTMODEL_H
+
+#include <QAbstractListModel>
+
+class RandomSortModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ explicit RandomSortModel(QObject* parent = 0);
+ QHash<int, QByteArray> roleNames() const;
+
+ QVariant data(const QModelIndex& index, int role) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+
+ void randomize();
+
+ private:
+ QList<QPair<QString, int> > mData;
+};
+
+#endif // RANDOMSORTMODEL_H
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index f267b93b26..d22f3487da 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -58,6 +58,7 @@
#include "../shared/visualtestutil.h"
#include "incrementalmodel.h"
#include "proxytestinnermodel.h"
+#include "randomsortmodel.h"
#include <math.h>
Q_DECLARE_METATYPE(Qt::LayoutDirection)
@@ -232,6 +233,11 @@ private slots:
void roundingErrors();
void roundingErrors_data();
+ void QTBUG_38209();
+ void programmaticFlickAtBounds();
+
+ void layoutChange();
+
void QTBUG_39492_data();
void QTBUG_39492();
@@ -4085,12 +4091,13 @@ void tst_QQuickListView::resetModel_headerFooter()
model.reset();
- header = findItem<QQuickItem>(contentItem, "header");
- QVERIFY(header);
+ // A reset should not force a new header or footer to be created.
+ QQuickItem *newHeader = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(newHeader == header);
QCOMPARE(header->y(), -header->height());
- footer = findItem<QQuickItem>(contentItem, "footer");
- QVERIFY(footer);
+ QQuickItem *newFooter = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(newFooter == footer);
QCOMPARE(footer->y(), 30.*4);
delete window;
@@ -7316,6 +7323,93 @@ void tst_QQuickListView::roundingErrors_data()
QTest::newRow("pixelAligned=false") << false;
}
+void tst_QQuickListView::QTBUG_38209()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("simplelistview.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject());
+ QVERIFY(listview);
+
+ // simulate mouse flick
+ flick(window.data(), QPoint(200, 200), QPoint(200, 50), 100);
+ QTRY_VERIFY(listview->isMoving() == false);
+ qreal contentY = listview->contentY();
+
+ // flick down
+ listview->flick(0, 1000);
+
+ // ensure we move more than just a couple pixels
+ QTRY_VERIFY(contentY - listview->contentY() > qreal(100.0));
+}
+
+void tst_QQuickListView::programmaticFlickAtBounds()
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("simplelistview.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject());
+ QVERIFY(listview);
+ QSignalSpy spy(listview, SIGNAL(contentYChanged()));
+
+ // flick down
+ listview->flick(0, 1000);
+
+ // verify that there is movement beyond bounds
+ QVERIFY(spy.wait(100));
+
+ // reset, and test with StopAtBounds
+ listview->cancelFlick();
+ listview->returnToBounds();
+ QTRY_COMPARE(listview->contentY(), qreal(0.0));
+ listview->setBoundsBehavior(QQuickFlickable::StopAtBounds);
+
+ // flick down
+ listview->flick(0, 1000);
+
+ // verify that there is no movement beyond bounds
+ QVERIFY(!spy.wait(100));
+}
+
+void tst_QQuickListView::layoutChange()
+{
+ RandomSortModel *model = new RandomSortModel;
+ QSortFilterProxyModel *sortModel = new QSortFilterProxyModel;
+ sortModel->setSourceModel(model);
+ sortModel->setSortRole(Qt::UserRole);
+ sortModel->setDynamicSortFilter(true);
+ sortModel->sort(0);
+
+ QScopedPointer<QQuickView> window(createView());
+ window->rootContext()->setContextProperty("testModel", QVariant::fromValue(sortModel));
+ window->setSource(testFileUrl("layoutChangeSort.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = window->rootObject()->findChild<QQuickListView *>("listView");
+ QVERIFY(listview);
+
+ for (int iter = 0; iter < 100; iter++) {
+ for (int i = 0; i < sortModel->rowCount(); ++i) {
+ QQuickItem *delegateItem = listview->itemAt(10, 10 + 2 * i * 20 + 20); // item + group
+ QVERIFY(delegateItem);
+ QQuickItem *delegateText = delegateItem->findChild<QQuickItem *>("delegateText");
+ QVERIFY(delegateText);
+
+ QCOMPARE(delegateText->property("text").toString(),
+ sortModel->index(i, 0, QModelIndex()).data().toString());
+ }
+
+ model->randomize();
+ listview->forceLayout();
+ QTest::qWait(5); // give view a chance to update
+ }
+}
+
void tst_QQuickListView::QTBUG_39492_data()
{
QStandardItemModel *sourceModel = new QStandardItemModel(this);
diff --git a/tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml b/tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml
new file mode 100644
index 0000000000..f02ab35faf
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/changePathDuringRefill.qml
@@ -0,0 +1,45 @@
+import QtQuick 2.3
+
+PathView {
+ id: view
+ objectName: "pathView"
+ width: 100
+ height: delegateHeight * pathItemCount
+ model: ["A", "B", "C"]
+ pathItemCount: 3
+ anchors.centerIn: parent
+
+ property int delegateHeight: 0
+
+ activeFocusOnTab: true
+ Keys.onDownPressed: view.incrementCurrentIndex()
+ Keys.onUpPressed: view.decrementCurrentIndex()
+ preferredHighlightBegin: 0.5
+ preferredHighlightEnd: 0.5
+
+ delegate: Rectangle {
+ objectName: "delegate" + modelData
+ width: view.width
+ height: textItem.height
+ border.color: "red"
+
+ onHeightChanged: {
+ if (index == 0)
+ view.delegateHeight = textItem.height
+ }
+
+ Text {
+ id: textItem
+ text: modelData
+ }
+ }
+
+ path: Path {
+ startX: view.width / 2
+ startY: 0
+ PathLine {
+ x: view.width / 2
+ y: view.pathItemCount * view.delegateHeight
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickpathview/data/incorrectSteal.qml b/tests/auto/quick/qquickpathview/data/incorrectSteal.qml
new file mode 100644
index 0000000000..bcd6923b73
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/incorrectSteal.qml
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite 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 Digia Plc 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Flickable {
+ objectName: "flickable"
+ width: 400; height: 400
+
+ contentHeight: height
+ contentWidth: width * 3
+ contentX: 400
+
+ Row {
+ Rectangle { width: 400; height: 400; color: "green" }
+ Rectangle {
+ width: 400; height: 400; color: "blue"
+ clip: true
+
+ PathView {
+ id: pathView
+ objectName: "pathView"
+ width: parent.width
+ height: 200
+ anchors.verticalCenter: parent.verticalCenter
+
+ dragMargin: 400
+ pathItemCount: 6
+
+ model: 10
+ path: Path {
+ startX: -pathView.width / 2
+ startY: pathView.height / 2
+ PathLine { x: pathView.width + pathView.width / 2; y: pathView.height / 2 }
+ }
+
+ delegate: Rectangle {
+ width: 100; height: 200
+ color: "purple"
+ MouseArea {
+ anchors.fill: parent
+ }
+ }
+ }
+ }
+ Rectangle { width: 400; height: 400; color: "yellow" }
+ }
+}
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index 579cb954aa..1960775ad3 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -47,6 +47,7 @@
#include <QtQml/qqmlexpression.h>
#include <QtQml/qqmlincubator.h>
#include <QtQuick/private/qquickpathview_p.h>
+#include <QtQuick/private/qquickflickable_p.h>
#include <QtQuick/private/qquickpath_p.h>
#include <QtQuick/private/qquicktext_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
@@ -142,6 +143,8 @@ private slots:
void indexAt_itemAt();
void indexAt_itemAt_data();
void cacheItemCount();
+ void incorrectSteal();
+ void changePathDuringRefill();
};
class TestObject : public QObject
@@ -2120,7 +2123,102 @@ void tst_QQuickPathView::cacheItemCount()
bool b = true;
controller.incubateWhile(&b);
}
+}
+
+static void testCurrentIndexChange(QQuickPathView *pathView, const QStringList &objectNamesInOrder)
+{
+ for (int visualIndex = 0; visualIndex < objectNamesInOrder.size() - 1; ++visualIndex) {
+ QQuickRectangle *delegate = findItem<QQuickRectangle>(pathView, objectNamesInOrder.at(visualIndex));
+ QVERIFY(delegate);
+
+ QQuickRectangle *nextDelegate = findItem<QQuickRectangle>(pathView, objectNamesInOrder.at(visualIndex + 1));
+ QVERIFY(nextDelegate);
+
+ QVERIFY(delegate->y() < nextDelegate->y());
+ }
+}
+
+void tst_QQuickPathView::changePathDuringRefill()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("changePathDuringRefill.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QCOMPARE(window.data(), qGuiApp->focusWindow());
+
+ QQuickPathView *pathView = qobject_cast<QQuickPathView*>(window->rootObject());
+ QVERIFY(pathView != 0);
+
+ testCurrentIndexChange(pathView, QStringList() << "delegateC" << "delegateA" << "delegateB");
+
+ pathView->incrementCurrentIndex();
+ /*
+ Decrementing moves delegateA down, resulting in an offset of 1,
+ so incrementing will move it up, resulting in an offset of 2:
+
+ delegateC delegateA
+ delegateA => delegateB
+ delegateB delegateC
+ */
+ QTRY_COMPARE(pathView->offset(), 2.0);
+ testCurrentIndexChange(pathView, QStringList() << "delegateA" << "delegateB" << "delegateC");
+}
+
+void tst_QQuickPathView::incorrectSteal()
+{
+ QScopedPointer<QQuickView> window(createView());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+ window->setSource(testFileUrl("incorrectSteal.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QCOMPARE(window.data(), qGuiApp->focusWindow());
+
+ QQuickPathView *pathview = findItem<QQuickPathView>(window->rootObject(), "pathView");
+ QVERIFY(pathview != 0);
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
+ QVERIFY(flickable != 0);
+
+ QSignalSpy movingSpy(pathview, SIGNAL(movingChanged()));
+ QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted()));
+ QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded()));
+
+ QSignalSpy fflickingSpy(flickable, SIGNAL(flickingChanged()));
+ QSignalSpy fflickStartedSpy(flickable, SIGNAL(flickStarted()));
+ QSignalSpy fflickEndedSpy(flickable, SIGNAL(flickEnded()));
+
+ int waitInterval = 5;
+ QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(23,218));
+
+ QTest::mouseMove(window.data(), QPoint(25,218), waitInterval);
+ QTest::mouseMove(window.data(), QPoint(26,218), waitInterval);
+ QTest::mouseMove(window.data(), QPoint(28,219), waitInterval);
+ QTest::mouseMove(window.data(), QPoint(31,219), waitInterval);
+ QTest::mouseMove(window.data(), QPoint(39,219), waitInterval);
+
+ // first move beyond threshold does not trigger drag
+ QVERIFY(!pathview->isMoving());
+ QVERIFY(!pathview->isDragging());
+ QCOMPARE(movingSpy.count(), 0);
+ QCOMPARE(moveStartedSpy.count(), 0);
+ QCOMPARE(moveEndedSpy.count(), 0);
+ QCOMPARE(fflickingSpy.count(), 0);
+ QCOMPARE(fflickStartedSpy.count(), 0);
+ QCOMPARE(fflickEndedSpy.count(), 0);
+
+ // no further moves after the initial move beyond threshold
+ QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(53,219));
+ QTRY_COMPARE(movingSpy.count(), 2);
+ QTRY_COMPARE(moveEndedSpy.count(), 1);
+ QCOMPARE(moveStartedSpy.count(), 1);
+ // Flickable should not handle this
+ QEXPECT_FAIL("", "QTBUG-37859", Abort);
+ QCOMPARE(fflickingSpy.count(), 0);
+ QCOMPARE(fflickStartedSpy.count(), 0);
+ QCOMPARE(fflickEndedSpy.count(), 0);
}
QTEST_MAIN(tst_QQuickPathView)
diff --git a/tests/auto/quick/qquickwindow/data/unloadSubWindow.qml b/tests/auto/quick/qquickwindow/data/unloadSubWindow.qml
new file mode 100644
index 0000000000..bf9df4867d
--- /dev/null
+++ b/tests/auto/quick/qquickwindow/data/unloadSubWindow.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.3
+import QtQuick.Window 2.2
+
+Window {
+ id: root
+ property var transientWindow
+ property Loader loader1: Loader {
+ sourceComponent: Item {
+ Loader {
+ id: loader2
+ sourceComponent : Window {
+ id: inner
+ visible: true
+ Component.onCompleted: root.transientWindow = inner
+ }
+ }
+ Component.onDestruction: {
+ loader2.active = false;
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index b05146fa3a..b8f9102775 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -47,6 +47,7 @@
#include <QtQml/QQmlEngine>
#include <QtQml/QQmlComponent>
#include <QtQuick/private/qquickrectangle_p.h>
+#include <QtQuick/private/qquickloader_p.h>
#include "../../shared/util.h"
#include "../shared/visualtestutil.h"
#include <QSignalSpy>
@@ -347,6 +348,8 @@ private slots:
void crashWhenHoverItemDeleted();
+ void unloadSubWindow();
+
void qobjectEventFilter_touch();
void qobjectEventFilter_key();
void qobjectEventFilter_mouse();
@@ -1705,6 +1708,26 @@ void tst_qquickwindow::crashWhenHoverItemDeleted()
}
}
+// QTBUG-33436
+void tst_qquickwindow::unloadSubWindow()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("unloadSubWindow.qml"));
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(component.create());
+ QVERIFY(window);
+ window->show();
+ QTest::qWaitForWindowExposed(window);
+ QQuickWindow *transient = Q_NULLPTR;
+ QTRY_VERIFY(transient = window->property("transientWindow").value<QQuickWindow*>());
+ QTest::qWaitForWindowExposed(transient);
+
+ // Unload the inner window (in nested Loaders) and make sure it doesn't crash
+ QQuickLoader *loader = window->property("loader1").value<QQuickLoader*>();
+ loader->setActive(false);
+ QTRY_VERIFY(!transient->isVisible());
+}
+
// QTBUG-32004
void tst_qquickwindow::qobjectEventFilter_touch()
{