aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/folderlistmodel/fileinfothread.cpp280
-rw-r--r--src/imports/folderlistmodel/fileinfothread_p.h107
-rw-r--r--src/imports/folderlistmodel/fileproperty_p.h94
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.json1
-rw-r--r--src/imports/folderlistmodel/folderlistmodel.pro9
-rw-r--r--src/imports/folderlistmodel/plugin.cpp7
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp494
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h60
-rw-r--r--src/imports/gestures/gestures.json1
-rw-r--r--src/imports/localstorage/localstorage.json1
-rw-r--r--src/imports/localstorage/localstorage.pro4
-rw-r--r--src/imports/localstorage/plugin.cpp4
-rw-r--r--src/imports/shaders/shaders.json1
-rw-r--r--src/imports/testlib/main.cpp4
-rw-r--r--src/imports/testlib/testlib.json1
-rw-r--r--src/imports/testlib/testlib.pro3
-rw-r--r--src/imports/xmllistmodel/plugin.cpp4
-rw-r--r--src/imports/xmllistmodel/xmllistmodel.json1
-rw-r--r--src/plugins/accessible/quick/accessible.json3
-rw-r--r--src/plugins/accessible/quick/main.cpp8
-rw-r--r--src/plugins/accessible/quick/quick.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.h1
-rw-r--r--src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.json2
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro2
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.json1
-rw-r--r--src/qml/debugger/qdebugmessageservice.cpp2
-rw-r--r--src/qml/debugger/qqmldebugserverconnection_p.h6
-rw-r--r--src/qml/debugger/qqmlinspectorinterface_p.h5
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp62
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h158
-rw-r--r--src/qml/debugger/qv8profilerservice.cpp14
-rw-r--r--src/qml/debugger/qv8profilerservice_p.h1
-rw-r--r--src/qml/qml/ftw/qfastmetabuilder.cpp64
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp15
-rw-r--r--src/qml/qml/qqmlcompiler.cpp30
-rw-r--r--src/qml/qml/qqmlcompiler_p.h1
-rw-r--r--src/qml/qml/qqmlcomponent.cpp22
-rw-r--r--src/qml/qml/qqmlcomponent_p.h4
-rw-r--r--src/qml/qml/qqmlengine.cpp16
-rw-r--r--src/qml/qml/qqmlexpression.cpp4
-rw-r--r--src/qml/qml/qqmlextensioninterface.h7
-rw-r--r--src/qml/qml/qqmlimageprovider.h2
-rw-r--r--src/qml/qml/qqmlincubator.cpp7
-rw-r--r--src/qml/qml/qqmlincubator.h3
-rw-r--r--src/qml/qml/qqmlinstruction.cpp4
-rw-r--r--src/qml/qml/qqmllocale.cpp5
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp2
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h1
-rw-r--r--src/qml/qml/qqmlpropertyvalueinterceptor_p.h5
-rw-r--r--src/qml/qml/qqmlpropertyvaluesource.h5
-rw-r--r--src/qml/qml/qqmlrewrite.cpp123
-rw-r--r--src/qml/qml/qqmlrewrite_p.h5
-rw-r--r--src/qml/qml/qqmltypeloader.cpp6
-rw-r--r--src/qml/qml/qqmlvme_p.h24
-rw-r--r--src/qml/qml/qquickworkerscript.cpp2
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp79
-rw-r--r--src/qml/qml/v4/qv4bindings_p.h2
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp25
-rw-r--r--src/qml/qml/v4/qv4compiler_p_p.h1
-rw-r--r--src/qml/qml/v4/qv4instruction.cpp9
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h3
-rw-r--r--src/qml/qml/v4/qv4ir.cpp3
-rw-r--r--src/qml/qml/v4/qv4ir_p.h1
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp9
-rw-r--r--src/qml/qml/v4/qv4program_p.h1
-rw-r--r--src/qml/qml/v8/qjsconverter_p.h38
-rw-r--r--src/qml/qml/v8/qjsengine.h38
-rw-r--r--src/qml/qml/v8/qjsengine_p.h40
-rw-r--r--src/qml/qml/v8/qjsvalue.h41
-rw-r--r--src/qml/qml/v8/qjsvalue_impl_p.h38
-rw-r--r--src/qml/qml/v8/qjsvalue_p.h38
-rw-r--r--src/qml/qml/v8/qjsvalueiterator.h39
-rw-r--r--src/qml/qml/v8/qjsvalueiterator_impl_p.h36
-rw-r--r--src/qml/qml/v8/qjsvalueiterator_p.h36
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp19
-rw-r--r--src/qml/qml/v8/qscript_impl_p.h40
-rw-r--r--src/qml/qml/v8/qscriptisolate_p.h38
-rw-r--r--src/qml/qml/v8/qscriptoriginalglobalobject_p.h38
-rw-r--r--src/qml/qml/v8/qscriptshareddata_p.h38
-rw-r--r--src/qml/qml/v8/qscripttools_p.h38
-rw-r--r--src/qml/qml/v8/qv8engine.cpp10
-rw-r--r--src/qml/qml/v8/qv8engine_impl_p.h36
-rw-r--r--src/qml/qml/v8/qv8engine_p.h2
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp4
-rw-r--r--src/quick/items/items.pri8
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp613
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h373
-rw-r--r--src/quick/items/qquickcanvas.cpp30
-rw-r--r--src/quick/items/qquickevents_p_p.h14
-rw-r--r--src/quick/items/qquickflickable.cpp17
-rw-r--r--src/quick/items/qquickgridview.cpp163
-rw-r--r--src/quick/items/qquickitem.cpp6
-rw-r--r--src/quick/items/qquickitem_p.h4
-rw-r--r--src/quick/items/qquickitemanimation.cpp2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp8
-rw-r--r--src/quick/items/qquickitemview.cpp921
-rw-r--r--src/quick/items/qquickitemview_p.h51
-rw-r--r--src/quick/items/qquickitemview_p_p.h92
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp876
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h209
-rw-r--r--src/quick/items/qquicklistview.cpp273
-rw-r--r--src/quick/items/qquicklistview_p.h3
-rw-r--r--src/quick/items/qquickpositioners.cpp375
-rw-r--r--src/quick/items/qquickpositioners_p.h16
-rw-r--r--src/quick/items/qquickpositioners_p_p.h11
-rw-r--r--src/quick/items/qquicksprite.cpp4
-rw-r--r--src/quick/items/qquicksprite_p.h24
-rw-r--r--src/quick/items/qquickspriteengine.cpp2
-rw-r--r--src/quick/items/qquickspriteengine_p.h2
-rw-r--r--src/quick/items/qquickspritesequence.cpp482
-rw-r--r--src/quick/items/qquickspritesequence_p.h148
-rw-r--r--src/quick/items/qquickstateoperations.cpp3
-rw-r--r--src/quick/items/qquicktext.cpp331
-rw-r--r--src/quick/items/qquicktext_p_p.h46
-rw-r--r--src/quick/items/qquicktextcontrol.cpp94
-rw-r--r--src/quick/items/qquicktextcontrol_p.h12
-rw-r--r--src/quick/items/qquicktextcontrol_p_p.h55
-rw-r--r--src/quick/items/qquicktextedit.cpp65
-rw-r--r--src/quick/items/qquicktextedit_p.h6
-rw-r--r--src/quick/items/qquicktextedit_p_p.h79
-rw-r--r--src/quick/items/qquicktextinput.cpp42
-rw-r--r--src/quick/items/qquicktextinput_p.h4
-rw-r--r--src/quick/items/qquicktextinput_p_p.h13
-rw-r--r--src/quick/items/qquickvisualadaptormodel_p.h4
-rw-r--r--src/quick/items/qquickvisualdatamodel.cpp41
-rw-r--r--src/quick/items/qquickvisualdatamodel_p.h1
-rw-r--r--src/quick/items/qquickvisualitemmodel_p.h1
-rw-r--r--src/quick/items/qquickwindowmanager.cpp176
-rw-r--r--src/quick/items/qquickwindowmanager_p.h5
-rw-r--r--src/quick/items/qquickwindowmodule.cpp2
-rw-r--r--src/quick/items/qquickwindowmodule_p.h2
-rw-r--r--src/quick/particles/qquickage.cpp2
-rw-r--r--src/quick/particles/qquickage_p.h2
-rw-r--r--src/quick/particles/qquickangledirection.cpp3
-rw-r--r--src/quick/particles/qquickangledirection_p.h2
-rw-r--r--src/quick/particles/qquickcumulativedirection.cpp2
-rw-r--r--src/quick/particles/qquickcumulativedirection_p.h2
-rw-r--r--src/quick/particles/qquickcustomaffector.cpp2
-rw-r--r--src/quick/particles/qquickcustomaffector_p.h2
-rw-r--r--src/quick/particles/qquickdirection.cpp2
-rw-r--r--src/quick/particles/qquickdirection_p.h2
-rw-r--r--src/quick/particles/qquickellipseextruder.cpp3
-rw-r--r--src/quick/particles/qquickellipseextruder_p.h2
-rw-r--r--src/quick/particles/qquickfriction.cpp2
-rw-r--r--src/quick/particles/qquickfriction_p.h2
-rw-r--r--src/quick/particles/qquickgravity.cpp2
-rw-r--r--src/quick/particles/qquickgravity_p.h2
-rw-r--r--src/quick/particles/qquickgroupgoal.cpp2
-rw-r--r--src/quick/particles/qquickgroupgoal_p.h2
-rw-r--r--src/quick/particles/qquickimageparticle.cpp9
-rw-r--r--src/quick/particles/qquickimageparticle_p.h2
-rw-r--r--src/quick/particles/qquickitemparticle.cpp2
-rw-r--r--src/quick/particles/qquickitemparticle_p.h2
-rw-r--r--src/quick/particles/qquicklineextruder.cpp3
-rw-r--r--src/quick/particles/qquicklineextruder_p.h2
-rw-r--r--src/quick/particles/qquickmaskextruder.cpp2
-rw-r--r--src/quick/particles/qquickmaskextruder_p.h2
-rw-r--r--src/quick/particles/qquickparticleaffector.cpp2
-rw-r--r--src/quick/particles/qquickparticleaffector_p.h2
-rw-r--r--src/quick/particles/qquickparticleemitter.cpp2
-rw-r--r--src/quick/particles/qquickparticleemitter_p.h2
-rw-r--r--src/quick/particles/qquickparticleextruder.cpp3
-rw-r--r--src/quick/particles/qquickparticleextruder_p.h2
-rw-r--r--src/quick/particles/qquickparticlegroup.cpp2
-rw-r--r--src/quick/particles/qquickparticlegroup_p.h2
-rw-r--r--src/quick/particles/qquickparticlepainter.cpp2
-rw-r--r--src/quick/particles/qquickparticlepainter_p.h2
-rw-r--r--src/quick/particles/qquickparticlesmodule.cpp2
-rw-r--r--src/quick/particles/qquickparticlesmodule_p.h2
-rw-r--r--src/quick/particles/qquickparticlesystem.cpp2
-rw-r--r--src/quick/particles/qquickparticlesystem_p.h2
-rw-r--r--src/quick/particles/qquickpointattractor.cpp2
-rw-r--r--src/quick/particles/qquickpointattractor_p.h2
-rw-r--r--src/quick/particles/qquickpointdirection.cpp3
-rw-r--r--src/quick/particles/qquickpointdirection_p.h2
-rw-r--r--src/quick/particles/qquickrectangleextruder.cpp3
-rw-r--r--src/quick/particles/qquickrectangleextruder_p.h2
-rw-r--r--src/quick/particles/qquickspritegoal.cpp2
-rw-r--r--src/quick/particles/qquickspritegoal_p.h2
-rw-r--r--src/quick/particles/qquicktargetdirection.cpp2
-rw-r--r--src/quick/particles/qquicktargetdirection_p.h2
-rw-r--r--src/quick/particles/qquicktrailemitter.cpp2
-rw-r--r--src/quick/particles/qquicktrailemitter_p.h2
-rw-r--r--src/quick/particles/qquickturbulence.cpp2
-rw-r--r--src/quick/particles/qquickturbulence_p.h2
-rw-r--r--src/quick/particles/qquickv8particledata.cpp2
-rw-r--r--src/quick/particles/qquickv8particledata_p.h2
-rw-r--r--src/quick/particles/qquickwander.cpp2
-rw-r--r--src/quick/particles/qquickwander_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode_p.h2
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp1
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp15
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp1
-rw-r--r--src/quick/scenegraph/qsgdefaultrectanglenode.cpp3
-rw-r--r--src/quick/scenegraph/qsgdefaultrectanglenode_p.h4
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp6
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp39
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h2
-rw-r--r--src/quick/scenegraph/scenegraph.pri2
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil.cpp714
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil_p.h24
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp3
-rw-r--r--src/quick/util/qquickanimationcontroller_p.h2
-rw-r--r--src/quick/util/qquickpixmapcache.cpp10
-rw-r--r--src/quick/util/qquickstyledtext.cpp43
-rw-r--r--src/quick/util/qquickstyledtext_p.h6
214 files changed, 5901 insertions, 3274 deletions
diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp
new file mode 100644
index 0000000000..3c4d60bb89
--- /dev/null
+++ b/src/imports/folderlistmodel/fileinfothread.cpp
@@ -0,0 +1,280 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fileinfothread_p.h"
+#include <qdiriterator.h>
+
+#include <QDebug>
+
+
+FileInfoThread::FileInfoThread(QObject *parent)
+ : QThread(parent),
+ abort(false),
+ watcher(0),
+ sortFlags(QDir::Name),
+ needUpdate(true),
+ folderUpdate(false),
+ sortUpdate(false),
+ showDirs(true),
+ showDirsFirst(false),
+ showDotDot(false),
+ showOnlyReadable(false)
+{
+ watcher = new QFileSystemWatcher(this);
+ connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString)));
+ connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(updateFile(QString)));
+ start(LowPriority);
+}
+
+FileInfoThread::~FileInfoThread()
+{
+ QMutexLocker locker(&mutex);
+ abort = true;
+ condition.wakeOne();
+ locker.unlock();
+ wait();
+}
+
+void FileInfoThread::clear()
+{
+ QMutexLocker locker(&mutex);
+ watcher->removePaths(watcher->files());
+ watcher->removePaths(watcher->directories());
+}
+
+void FileInfoThread::removePath(const QString &path)
+{
+ QMutexLocker locker(&mutex);
+ watcher->removePath(path);
+ currentPath.clear();
+}
+
+void FileInfoThread::setPath(const QString &path)
+{
+ Q_ASSERT(!path.isEmpty());
+
+ QMutexLocker locker(&mutex);
+ watcher->addPath(path);
+ currentPath = path;
+ needUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setRootPath(const QString &path)
+{
+ Q_ASSERT(!path.isEmpty());
+
+ QMutexLocker locker(&mutex);
+ rootPath = path;
+}
+
+void FileInfoThread::dirChanged(const QString &directoryPath)
+{
+ Q_UNUSED(directoryPath);
+ QMutexLocker locker(&mutex);
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setSortFlags(QDir::SortFlags flags)
+{
+ QMutexLocker locker(&mutex);
+ sortFlags = flags;
+ sortUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setNameFilters(const QStringList & filters)
+{
+ QMutexLocker locker(&mutex);
+ nameFilters = filters;
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setShowDirs(bool showFolders)
+{
+ QMutexLocker locker(&mutex);
+ showDirs = showFolders;
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setShowDirsFirst(bool showDirsFirst)
+{
+ QMutexLocker locker(&mutex);
+ showDirsFirst = showDirsFirst;
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setShowDotDot(bool on)
+{
+ QMutexLocker locker(&mutex);
+ showDotDot = on;
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::setShowOnlyReadable(bool on)
+{
+ QMutexLocker locker(&mutex);
+ showOnlyReadable = on;
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::updateFile(const QString &path)
+{
+ Q_UNUSED(path);
+ QMutexLocker locker(&mutex);
+ folderUpdate = true;
+ condition.wakeAll();
+}
+
+void FileInfoThread::run()
+{
+ forever {
+ bool updateFiles = false;
+ QMutexLocker locker(&mutex);
+ if (abort) {
+ return;
+ }
+ if (currentPath.isEmpty() || !needUpdate)
+ condition.wait(&mutex);
+
+ if (abort) {
+ return;
+ }
+
+ if (!currentPath.isEmpty()) {
+ updateFiles = true;
+ }
+ if (updateFiles)
+ getFileInfos(currentPath);
+ locker.unlock();
+ }
+}
+
+
+void FileInfoThread::getFileInfos(const QString &path)
+{
+ QDir::Filters filter;
+ filter = QDir::Files | QDir::NoDot | QDir::CaseSensitive;
+ if (showDirs)
+ filter = filter | QDir::AllDirs | QDir::Drives;
+ if ((path == rootPath) || !showDotDot)
+ filter = filter | QDir::NoDotDot;
+ if (showOnlyReadable)
+ filter = filter | QDir::Readable;
+ if (showDirsFirst)
+ sortFlags = sortFlags | QDir::DirsFirst;
+
+ QDir currentDir(path, QString(), sortFlags);
+ QFileInfoList fileInfoList;
+ QList<FileProperty> filePropertyList;
+
+ fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags);
+
+ if (!fileInfoList.isEmpty()) {
+ foreach (QFileInfo info, fileInfoList) {
+ //qDebug() << "Adding file : " << info.fileName() << "to list ";
+ filePropertyList << FileProperty(info);
+ }
+ if (folderUpdate) {
+ int fromIndex = 0;
+ int toIndex = currentFileList.size()-1;
+ findChangeRange(filePropertyList, fromIndex, toIndex);
+ folderUpdate = false;
+ currentFileList = filePropertyList;
+ //qDebug() << "emit directoryUpdated : " << fromIndex << " " << toIndex;
+ emit directoryUpdated(path, filePropertyList, fromIndex, toIndex);
+ } else {
+ currentFileList = filePropertyList;
+ if (sortUpdate) {
+ emit sortFinished(filePropertyList);
+ sortUpdate = false;
+ } else
+ emit directoryChanged(path, filePropertyList);
+ }
+ } else {
+ // The directory is empty
+ if (folderUpdate) {
+ int fromIndex = 0;
+ int toIndex = currentFileList.size()-1;
+ folderUpdate = false;
+ currentFileList.clear();
+ emit directoryUpdated(path, filePropertyList, fromIndex, toIndex);
+ } else {
+ currentFileList.clear();
+ emit directoryChanged(path, filePropertyList);
+ }
+ }
+ needUpdate = false;
+}
+
+void FileInfoThread::findChangeRange(const QList<FileProperty> &list, int &fromIndex, int &toIndex)
+{
+ if (currentFileList.size() == 0) {
+ fromIndex = 0;
+ toIndex = list.size();
+ return;
+ }
+
+ int i;
+ int listSize = list.size() < currentFileList.size() ? list.size() : currentFileList.size();
+ bool changeFound = false;
+
+ for (i=0; i < listSize; i++) {
+ if (list.at(i) != currentFileList.at(i)) {
+ changeFound = true;
+ break;
+ }
+ }
+
+ if (changeFound)
+ fromIndex = i;
+ else
+ fromIndex = i-1;
+
+ // For now I let the rest of the list be updated..
+ toIndex = list.size() > currentFileList.size() ? list.size() - 1 : currentFileList.size() - 1;
+}
diff --git a/src/imports/folderlistmodel/fileinfothread_p.h b/src/imports/folderlistmodel/fileinfothread_p.h
new file mode 100644
index 0000000000..a5be6e6fcc
--- /dev/null
+++ b/src/imports/folderlistmodel/fileinfothread_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILEINFOTHREAD_P_H
+#define FILEINFOTHREAD_P_H
+
+#include <QThread>
+#include <QMutex>
+#include <QWaitCondition>
+#include <QFileSystemWatcher>
+#include <QFileInfo>
+#include <QDir>
+
+#include "fileproperty_p.h"
+
+class FileInfoThread : public QThread
+{
+ Q_OBJECT
+
+Q_SIGNALS:
+ void directoryChanged(const QString &directory, const QList<FileProperty> &list) const;
+ void directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex) const;
+ void sortFinished(const QList<FileProperty> &list) const;
+
+public:
+ FileInfoThread(QObject *parent = 0);
+ ~FileInfoThread();
+
+ void clear();
+ void removePath(const QString &path);
+ void setPath(const QString &path);
+ void setRootPath(const QString &path);
+ void setSortFlags(QDir::SortFlags flags);
+ void setNameFilters(const QStringList & nameFilters);
+ void setShowDirs(bool showFolders);
+ void setShowDirsFirst(bool showDirsFirst);
+ void setShowDotDot(bool on);
+ void setShowOnlyReadable(bool on);
+
+public Q_SLOTS:
+ void dirChanged(const QString &directoryPath);
+ void updateFile(const QString &path);
+
+protected:
+ void run();
+ void getFileInfos(const QString &path);
+ void findChangeRange(const QList<FileProperty> &list, int &fromIndex, int &toIndex);
+
+private:
+ QMutex mutex;
+ QWaitCondition condition;
+ volatile bool abort;
+
+ QFileSystemWatcher *watcher;
+ QList<FileProperty> currentFileList;
+ QDir::SortFlags sortFlags;
+ QString currentPath;
+ QString rootPath;
+ QStringList nameFilters;
+ bool needUpdate;
+ bool folderUpdate;
+ bool sortUpdate;
+ bool showDirs;
+ bool showDirsFirst;
+ bool showDotDot;
+ bool showOnlyReadable;
+};
+
+#endif // FILEINFOTHREAD_P_H
diff --git a/src/imports/folderlistmodel/fileproperty_p.h b/src/imports/folderlistmodel/fileproperty_p.h
new file mode 100644
index 0000000000..690581a9a3
--- /dev/null
+++ b/src/imports/folderlistmodel/fileproperty_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FILEPROPERTY_P_H
+#define FILEPROPERTY_P_H
+
+#include <QFileInfo>
+#include <QDateTime>
+
+class FileProperty
+{
+public:
+ FileProperty(const QFileInfo &info)
+ {
+ mFileName = info.fileName();
+ mFilePath = info.filePath();
+ mBaseName = info.baseName();
+ mSize = info.size();
+ mSuffix = info.completeSuffix();
+ mIsDir = info.isDir();
+ mIsFile = info.isFile();
+ mLastModified = info.lastModified();
+ mLastRead = info.lastRead();
+ }
+ ~FileProperty()
+ {}
+
+ inline QString fileName() const { return mFileName; }
+ inline QString filePath() const { return mFilePath; }
+ inline QString baseName() const { return mBaseName; }
+ inline qint64 size() const { return mSize; }
+ inline QString suffix() const { return mSuffix; }
+ inline bool isDir() const { return mIsDir; }
+ inline bool isFile() const { return mIsFile; }
+ inline QDateTime lastModified() const { return mLastModified; }
+ inline QDateTime lastRead() const { return mLastRead; }
+
+ inline bool operator !=(const FileProperty &fileInfo) const {
+ return !operator==(fileInfo);
+ }
+ bool operator ==(const FileProperty &property) const {
+ return ((mFileName == property.mFileName) && (isDir() == property.isDir()));
+ }
+
+private:
+ QString mFileName;
+ QString mFilePath;
+ QString mBaseName;
+ QString mSuffix;
+ qint64 mSize;
+ bool mIsDir;
+ bool mIsFile;
+ QDateTime mLastModified;
+ QDateTime mLastRead;
+};
+#endif // FILEPROPERTY_P_H
diff --git a/src/imports/folderlistmodel/folderlistmodel.json b/src/imports/folderlistmodel/folderlistmodel.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/imports/folderlistmodel/folderlistmodel.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/folderlistmodel/folderlistmodel.pro b/src/imports/folderlistmodel/folderlistmodel.pro
index b4cfcea495..592d8375c8 100644
--- a/src/imports/folderlistmodel/folderlistmodel.pro
+++ b/src/imports/folderlistmodel/folderlistmodel.pro
@@ -2,10 +2,13 @@ TARGET = qmlfolderlistmodelplugin
TARGETPATH = Qt/labs/folderlistmodel
include(../qimportbase.pri)
-QT += widgets qml
+QT += qml
-SOURCES += qquickfolderlistmodel.cpp plugin.cpp
-HEADERS += qquickfolderlistmodel.h
+SOURCES += qquickfolderlistmodel.cpp plugin.cpp \
+ fileinfothread.cpp
+HEADERS += qquickfolderlistmodel.h \
+ fileproperty_p.h \
+ fileinfothread_p.h
DESTDIR = $$QT.qml.imports/$$TARGETPATH
target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index 78fc230fdc..bc904512a8 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE
class QmlFolderListModelPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "folderlistmodel.json")
+
public:
virtual void registerTypes(const char *uri)
{
@@ -64,8 +66,3 @@ public:
QT_END_NAMESPACE
#include "plugin.moc"
-
-//![plugin export decl]
-Q_EXPORT_PLUGIN2(qmlfolderlistmodelplugin, QT_PREPEND_NAMESPACE(QmlFolderListModelPlugin));
-//![plugin export decl]
-
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index 5621622cca..d68d7af6d4 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -41,25 +41,71 @@
//![code]
#include "qquickfolderlistmodel.h"
-#include <QDirModel>
+#include "fileinfothread_p.h"
+#include "fileproperty_p.h"
#include <QDebug>
#include <qqmlcontext.h>
-#ifndef QT_NO_DIRMODEL
-
QT_BEGIN_NAMESPACE
class QQuickFolderListModelPrivate
{
+ Q_DECLARE_PUBLIC(QQuickFolderListModel)
+
public:
- QQuickFolderListModelPrivate()
- : sortField(QQuickFolderListModel::Name), sortReversed(false), count(0), showDirs(true), showDots(false), showOnlyReadable(false), insideRefresh(false) {
+ QQuickFolderListModelPrivate(QQuickFolderListModel *q)
+ : q_ptr(q),
+ sortField(QQuickFolderListModel::Name), sortReversed(false), showDirs(true), showDirsFirst(false), showDots(false), showOnlyReadable(false)
+ {
nameFilters << QLatin1String("*");
}
- void updateSorting() {
- QDir::SortFlags flags = 0;
- switch(sortField) {
+
+ QQuickFolderListModel *q_ptr;
+ QUrl currentDir;
+ QUrl rootDir;
+ FileInfoThread fileInfoThread;
+ QList<FileProperty> data;
+ QHash<int, QByteArray> roleNames;
+ QQuickFolderListModel::SortField sortField;
+ QStringList nameFilters;
+ bool sortReversed;
+ bool showDirs;
+ bool showDirsFirst;
+ bool showDots;
+ bool showOnlyReadable;
+
+ ~QQuickFolderListModelPrivate() {}
+ void init();
+ void updateSorting();
+
+ // private slots
+ void _q_directoryChanged(const QString &directory, const QList<FileProperty> &list);
+ void _q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex);
+ void _q_sortFinished(const QList<FileProperty> &list);
+};
+
+
+void QQuickFolderListModelPrivate::init()
+{
+ Q_Q(QQuickFolderListModel);
+ qRegisterMetaType<QList<FileProperty> >("QList<FileProperty>");
+ q->connect(&fileInfoThread, SIGNAL(directoryChanged(QString, QList<FileProperty>)),
+ q, SLOT(_q_directoryChanged(QString, QList<FileProperty>)));
+ q->connect(&fileInfoThread, SIGNAL(directoryUpdated(QString, QList<FileProperty>, int, int)),
+ q, SLOT(_q_directoryUpdated(QString, QList<FileProperty>, int, int)));
+ q->connect(&fileInfoThread, SIGNAL(sortFinished(QList<FileProperty>)),
+ q, SLOT(_q_sortFinished(QList<FileProperty>)));
+}
+
+
+void QQuickFolderListModelPrivate::updateSorting()
+{
+ Q_Q(QQuickFolderListModel);
+
+ QDir::SortFlags flags = 0;
+
+ switch (sortField) {
case QQuickFolderListModel::Unsorted:
flags |= QDir::Unsorted;
break;
@@ -75,26 +121,80 @@ public:
case QQuickFolderListModel::Type:
flags |= QDir::Type;
break;
- }
+ default:
+ break;
+ }
+
+ emit q->layoutAboutToBeChanged();
+
+ if (sortReversed)
+ flags |= QDir::Reversed;
+
+ fileInfoThread.setSortFlags(flags);
+}
+
+void QQuickFolderListModelPrivate::_q_directoryChanged(const QString &directory, const QList<FileProperty> &list)
+{
+ Q_Q(QQuickFolderListModel);
+ Q_UNUSED(directory);
+
+ data = list;
+ q->endResetModel();
+ emit q->rowCountChanged();
+ emit q->folderChanged();
+}
- if (sortReversed)
- flags |= QDir::Reversed;
- model.setSorting(flags);
+void QQuickFolderListModelPrivate::_q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex)
+{
+ Q_Q(QQuickFolderListModel);
+ Q_UNUSED(directory);
+
+ QModelIndex parent;
+ if (data.size() > list.size()) {
+ //File(s) removed. Since I do not know how many
+ //or where I need to update the whole list from the first item.
+ data = list;
+ q->beginRemoveRows(parent, fromIndex, toIndex);
+ q->endRemoveRows();
+ q->beginInsertRows(parent, fromIndex, list.size()-1);
+ q->endInsertRows();
+ emit q->rowCountChanged();
+ } else if (data.size() < list.size()) {
+ //qDebug() << "File added. FromIndex: " << fromIndex << " toIndex: " << toIndex << " list size: " << list.size();
+ //File(s) added. Calculate how many and insert
+ //from the first changed one.
+ toIndex = fromIndex + (list.size() - data.size()-1);
+ q->beginInsertRows(parent, fromIndex, toIndex);
+ q->endInsertRows();
+ data = list;
+ emit q->rowCountChanged();
+ QModelIndex modelIndexFrom = q->createIndex(fromIndex, 0);
+ QModelIndex modelIndexTo = q->createIndex(toIndex, 0);
+ emit q->dataChanged(modelIndexFrom, modelIndexTo);
+ } else {
+ //qDebug() << "File has been updated";
+ QModelIndex modelIndexFrom = q->createIndex(fromIndex, 0);
+ QModelIndex modelIndexTo = q->createIndex(toIndex, 0);
+ data = list;
+ emit q->dataChanged(modelIndexFrom, modelIndexTo);
}
+}
+
+void QQuickFolderListModelPrivate::_q_sortFinished(const QList<FileProperty> &list)
+{
+ Q_Q(QQuickFolderListModel);
+
+ QModelIndex parent;
+ q->beginRemoveRows(parent, 0, data.size()-1);
+ data.clear();
+ q->endRemoveRows();
+
+ q->beginInsertRows(parent, 0, list.size()-1);
+ data = list;
+ q->endInsertRows();
+}
- QDirModel model;
- QUrl folder;
- QStringList nameFilters;
- QModelIndex folderIndex;
- QQuickFolderListModel::SortField sortField;
- bool sortReversed;
- int count;
- bool showDirs;
- bool showDots;
- bool showOnlyReadable;
- bool insideRefresh;
-};
/*!
\qmlclass FolderListModel QQuickFolderListModel
@@ -115,8 +215,14 @@ public:
Components access names and paths via the following roles:
\list
- \o fileName
- \o filePath
+ \o \c fileName
+ \o \c filePath
+ \o \c fileBaseName
+ \o \c fileSuffix
+ \o \c fileSize
+ \o \c fileModified
+ \o \c fileAccessed
+ \o \c fileIsDir
\endlist
Additionally a file entry can be differentiated from a folder entry via the
@@ -157,39 +263,62 @@ public:
*/
QQuickFolderListModel::QQuickFolderListModel(QObject *parent)
- : QAbstractListModel(parent)
+ : QAbstractListModel(parent), d_ptr(new QQuickFolderListModelPrivate(this))
{
- QHash<int, QByteArray> roles;
- roles[FileNameRole] = "fileName";
- roles[FilePathRole] = "filePath";
- setRoleNames(roles);
-
- d = new QQuickFolderListModelPrivate;
- d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot);
- connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int))
- , this, SLOT(inserted(const QModelIndex&,int,int)));
- connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int))
- , this, SLOT(removed(const QModelIndex&,int,int)));
- connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&))
- , this, SLOT(handleDataChanged(const QModelIndex&,const QModelIndex&)));
- connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh()));
- connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh()));
+ Q_D(QQuickFolderListModel);
+ d->roleNames[FileNameRole] = "fileName";
+ d->roleNames[FilePathRole] = "filePath";
+ d->roleNames[FileBaseNameRole] = "fileBaseName";
+ d->roleNames[FileSuffixRole] = "fileSuffix";
+ d->roleNames[FileSizeRole] = "fileSize";
+ d->roleNames[FileLastModifiedRole] = "fileModified";
+ d->roleNames[FileLastReadRole] = "fileAccessed";
+ d->roleNames[FileIsDirRole] = "fileIsDir";
+ setRoleNames(d->roleNames);
+
+ d->init();
}
QQuickFolderListModel::~QQuickFolderListModel()
{
- delete d;
}
QVariant QQuickFolderListModel::data(const QModelIndex &index, int role) const
{
+ Q_D(const QQuickFolderListModel);
QVariant rv;
- QModelIndex modelIndex = d->model.index(index.row(), 0, d->folderIndex);
- if (modelIndex.isValid()) {
- if (role == FileNameRole)
- rv = d->model.data(modelIndex, QDirModel::FileNameRole).toString();
- else if (role == FilePathRole)
- rv = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString());
+
+ if (index.row() >= d->data.size())
+ return rv;
+
+ switch (role)
+ {
+ case FileNameRole:
+ rv = d->data.at(index.row()).fileName();
+ break;
+ case FilePathRole:
+ rv = d->data.at(index.row()).filePath();
+ break;
+ case FileBaseNameRole:
+ rv = d->data.at(index.row()).baseName();
+ break;
+ case FileSuffixRole:
+ rv = d->data.at(index.row()).suffix();
+ break;
+ case FileSizeRole:
+ rv = d->data.at(index.row()).size();
+ break;
+ case FileLastModifiedRole:
+ rv = d->data.at(index.row()).lastModified().date().toString(Qt::ISODate) + " " + d->data.at(index.row()).lastModified().time().toString();
+ break;
+ case FileLastReadRole:
+ rv = d->data.at(index.row()).lastRead().date().toString(Qt::ISODate) + " " + d->data.at(index.row()).lastRead().time().toString();
+ break;
+ case FileIsDirRole:
+ rv = d->data.at(index.row()).isDir();
+ break;
+ default:
+ break;
}
return rv;
}
@@ -202,8 +331,14 @@ QVariant QQuickFolderListModel::data(const QModelIndex &index, int role) const
*/
int QQuickFolderListModel::rowCount(const QModelIndex &parent) const
{
+ Q_D(const QQuickFolderListModel);
Q_UNUSED(parent);
- return d->count;
+ return d->data.size();
+}
+
+QModelIndex QQuickFolderListModel::index(int row, int , const QModelIndex &) const
+{
+ return createIndex(row, 0);
}
/*!
@@ -219,46 +354,70 @@ int QQuickFolderListModel::rowCount(const QModelIndex &parent) const
*/
QUrl QQuickFolderListModel::folder() const
{
- return d->folder;
+ Q_D(const QQuickFolderListModel);
+ return d->currentDir;
}
void QQuickFolderListModel::setFolder(const QUrl &folder)
{
- if (folder == d->folder)
+ Q_D(QQuickFolderListModel);
+
+ if (folder == d->currentDir)
return;
- QModelIndex index = d->model.index(folder.toLocalFile()); // This can modify the filtering rules.
- if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) {
- d->folder = folder;
- QMetaObject::invokeMethod(this, "resetFiltering", Qt::QueuedConnection); // resetFiltering will invoke refresh().
- emit folderChanged();
+ QString resolvedPath = QDir::cleanPath(folder.path());
+
+ beginResetModel();
+
+ //Remove the old path for the file system watcher
+ if (!d->currentDir.isEmpty())
+ d->fileInfoThread.removePath(d->currentDir.path());
+
+ d->currentDir = folder;
+
+ QFileInfo info(resolvedPath);
+ if (!info.exists() || !info.isDir()) {
+ d->data.clear();
+ endResetModel();
+ emit rowCountChanged();
+ return;
}
+
+ d->fileInfoThread.setPath(resolvedPath);
+}
+
+
+/*!
+ \qmlproperty string QQuickFolderListModel::rootFolder
+
+ When the rootFolder is set, then this folder will
+ be threated as the root in the file system, so that
+ you can only travers sub folders from this rootFolder.
+*/
+QUrl QQuickFolderListModel::rootFolder() const
+{
+ Q_D(const QQuickFolderListModel);
+ return d->rootDir;
}
-void QQuickFolderListModel::resetFiltering()
+void QQuickFolderListModel::setRootFolder(const QUrl &path)
{
- // ensure that we reset the filtering rules, because the QDirModel::index()
- // function isn't quite as const as it claims to be.
- QDir::Filters filt = d->model.filter();
+ Q_D(QQuickFolderListModel);
- if (d->showDirs)
- filt |= (QDir::AllDirs | QDir::Drives);
- else
- filt &= ~(QDir::AllDirs | QDir::Drives);
+ if (path.isEmpty())
+ return;
- if (d->showDots)
- filt &= ~QDir::NoDotAndDotDot;
- else
- filt |= QDir::NoDotAndDotDot;
+ QString resolvedPath = QDir::cleanPath(path.path());
- if (d->showOnlyReadable)
- filt |= QDir::Readable;
- else
- filt &= ~QDir::Readable;
+ QFileInfo info(resolvedPath);
+ if (!info.exists() || !info.isDir())
+ return;
- d->model.setFilter(filt); // this causes a refresh().
+ d->fileInfoThread.setRootPath(resolvedPath);
+ d->rootDir = path;
}
+
/*!
\qmlproperty url FolderListModel::parentFolder
@@ -266,7 +425,9 @@ void QQuickFolderListModel::resetFiltering()
*/
QUrl QQuickFolderListModel::parentFolder() const
{
- QString localFile = d->folder.toLocalFile();
+ Q_D(const QQuickFolderListModel);
+
+ QString localFile = d->currentDir.toLocalFile();
if (!localFile.isEmpty()) {
QDir dir(localFile);
#if defined(Q_OS_WIN)
@@ -277,10 +438,10 @@ QUrl QQuickFolderListModel::parentFolder() const
dir.cdUp();
localFile = dir.path();
} else {
- int pos = d->folder.path().lastIndexOf(QLatin1Char('/'));
+ int pos = d->currentDir.path().lastIndexOf(QLatin1Char('/'));
if (pos == -1)
return QUrl();
- localFile = d->folder.path().left(pos);
+ localFile = d->currentDir.path().left(pos);
}
return QUrl::fromLocalFile(localFile);
}
@@ -303,13 +464,15 @@ QUrl QQuickFolderListModel::parentFolder() const
*/
QStringList QQuickFolderListModel::nameFilters() const
{
+ Q_D(const QQuickFolderListModel);
return d->nameFilters;
}
void QQuickFolderListModel::setNameFilters(const QStringList &filters)
{
+ Q_D(QQuickFolderListModel);
+ d->fileInfoThread.setNameFilters(filters);
d->nameFilters = filters;
- d->model.setNameFilters(d->nameFilters);
}
void QQuickFolderListModel::classBegin()
@@ -318,11 +481,10 @@ void QQuickFolderListModel::classBegin()
void QQuickFolderListModel::componentComplete()
{
- if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile()))
- setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
+ Q_D(QQuickFolderListModel);
- if (!d->folderIndex.isValid())
- QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
+ if (!d->currentDir.isValid() || d->currentDir.toLocalFile().isEmpty() || !QDir().exists(d->currentDir.toLocalFile()))
+ setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
}
/*!
@@ -331,9 +493,9 @@ void QQuickFolderListModel::componentComplete()
The \a sortField property contains field to use for sorting. sortField
may be one of:
\list
- \o Unsorted - no sorting is applied. The order is system default.
+ \o Unsorted - no sorting is applied.
\o Name - sort by filename
- \o Time - sort by time modified
+ \o LastModified - sort by time modified
\o Size - sort by file size
\o Type - sort by file type (extension)
\endlist
@@ -342,17 +504,25 @@ void QQuickFolderListModel::componentComplete()
*/
QQuickFolderListModel::SortField QQuickFolderListModel::sortField() const
{
+ Q_D(const QQuickFolderListModel);
return d->sortField;
}
void QQuickFolderListModel::setSortField(SortField field)
{
+ Q_D(QQuickFolderListModel);
if (field != d->sortField) {
d->sortField = field;
d->updateSorting();
}
}
+int QQuickFolderListModel::roleFromString(const QString &roleName) const
+{
+ Q_D(const QQuickFolderListModel);
+ return d->roleNames.key(roleName.toLatin1(), -1);
+}
+
/*!
\qmlproperty bool FolderListModel::sortReversed
@@ -362,11 +532,14 @@ void QQuickFolderListModel::setSortField(SortField field)
*/
bool QQuickFolderListModel::sortReversed() const
{
+ Q_D(const QQuickFolderListModel);
return d->sortReversed;
}
void QQuickFolderListModel::setSortReversed(bool rev)
{
+ Q_D(QQuickFolderListModel);
+
if (rev != d->sortReversed) {
d->sortReversed = rev;
d->updateSorting();
@@ -382,91 +555,66 @@ void QQuickFolderListModel::setSortReversed(bool rev)
bool QQuickFolderListModel::isFolder(int index) const
{
if (index != -1) {
- QModelIndex idx = d->model.index(index, 0, d->folderIndex);
- if (idx.isValid())
- return d->model.isDir(idx);
+ QModelIndex idx = createIndex(index, 0);
+ if (idx.isValid()) {
+ QVariant var = data(idx, FileIsDirRole);
+ if (var.isValid())
+ return var.toBool();
+ }
}
return false;
}
-void QQuickFolderListModel::refresh()
-{
- if (d->insideRefresh)
- return;
- d->insideRefresh = true;
+/*!
+ \qmlproperty bool FolderListModel::showDirs
- d->folderIndex = QModelIndex();
- if (d->count) {
- emit beginRemoveRows(QModelIndex(), 0, d->count-1);
- d->count = 0;
- emit endRemoveRows();
- }
+ If true, directories are included in the model; otherwise only files
+ are included.
- d->folderIndex = d->model.index(d->folder.toLocalFile());
- int newcount = d->model.rowCount(d->folderIndex);
- if (newcount) {
- emit beginInsertRows(QModelIndex(), 0, newcount-1);
- d->count = newcount;
- emit endInsertRows();
- }
+ By default, this property is true.
- d->insideRefresh = false; // finished refreshing.
-}
+ Note that the nameFilters are not applied to directories.
-void QQuickFolderListModel::inserted(const QModelIndex &index, int start, int end)
+ \sa showDotAndDotDot
+*/
+bool QQuickFolderListModel::showDirs() const
{
- if (index == d->folderIndex) {
- emit beginInsertRows(QModelIndex(), start, end);
- d->count = d->model.rowCount(d->folderIndex);
- emit endInsertRows();
- }
+ Q_D(const QQuickFolderListModel);
+ return d->showDirs;
}
-void QQuickFolderListModel::removed(const QModelIndex &index, int start, int end)
+void QQuickFolderListModel::setShowDirs(bool on)
{
- if (index == d->folderIndex) {
- emit beginRemoveRows(QModelIndex(), start, end);
- d->count = d->model.rowCount(d->folderIndex);
- emit endRemoveRows();
- }
-}
+ Q_D(QQuickFolderListModel);
-void QQuickFolderListModel::handleDataChanged(const QModelIndex &start, const QModelIndex &end)
-{
- if (start.parent() == d->folderIndex)
- emit dataChanged(index(start.row(),0), index(end.row(),0));
+ d->fileInfoThread.setShowDirs(on);
+ d->showDirs = on;
}
/*!
- \qmlproperty bool FolderListModel::showDirs
+ \qmlproperty bool FolderListModel::showDirsFirst
- If true, directories are included in the model; otherwise only files
- are included.
+ If true, if directories are included in the model they will
+ always be shown first, then the files.
- By default, this property is true.
-
- Note that the nameFilters are not applied to directories.
+ By default, this property is false.
- \sa showDotAndDotDot
*/
-bool QQuickFolderListModel::showDirs() const
+bool QQuickFolderListModel::showDirsFirst() const
{
- return d->model.filter() & QDir::AllDirs;
+ Q_D(const QQuickFolderListModel);
+ return d->showDirsFirst;
}
-void QQuickFolderListModel::setShowDirs(bool on)
+void QQuickFolderListModel::setShowDirsFirst(bool on)
{
- if (!(d->model.filter() & QDir::AllDirs) == !on)
- return;
- if (on) {
- d->showDirs = true;
- d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives);
- } else {
- d->showDirs = false;
- d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives));
- }
+ Q_D(QQuickFolderListModel);
+
+ d->fileInfoThread.setShowDirsFirst(on);
+ d->showDirsFirst = on;
}
+
/*!
\qmlproperty bool FolderListModel::showDotAndDotDot
@@ -479,19 +627,16 @@ void QQuickFolderListModel::setShowDirs(bool on)
*/
bool QQuickFolderListModel::showDotAndDotDot() const
{
- return !(d->model.filter() & QDir::NoDotAndDotDot);
+ Q_D(const QQuickFolderListModel);
+ return d->showDots;
}
void QQuickFolderListModel::setShowDotAndDotDot(bool on)
{
- if (!(d->model.filter() & QDir::NoDotAndDotDot) == on)
- return;
- if (on) {
- d->showDots = true;
- d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot);
- } else {
- d->showDots = false;
- d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot);
+ Q_D(QQuickFolderListModel);
+
+ if (on != d->showDots) {
+ d->fileInfoThread.setShowDotDot(on);
}
}
@@ -507,23 +652,46 @@ void QQuickFolderListModel::setShowDotAndDotDot(bool on)
*/
bool QQuickFolderListModel::showOnlyReadable() const
{
- return d->model.filter() & QDir::Readable;
+ Q_D(const QQuickFolderListModel);
+ return d->showOnlyReadable;
}
void QQuickFolderListModel::setShowOnlyReadable(bool on)
{
- if (!(d->model.filter() & QDir::Readable) == !on)
- return;
- if (on) {
- d->showOnlyReadable = true;
- d->model.setFilter(d->model.filter() | QDir::Readable);
- } else {
- d->showOnlyReadable = false;
- d->model.setFilter(d->model.filter() & ~QDir::Readable);
+ Q_D(QQuickFolderListModel);
+
+ if (on != d->showOnlyReadable) {
+ d->fileInfoThread.setShowOnlyReadable(on);
}
}
+/*!
+ \qmlmethod QVariant QQuickFolderListModel::get(int idx, const QString &property) const
+
+ Get the folder property for the given index. The following properties
+ are available.
+
+ \list
+ \o \c fileName
+ \o \c filePath
+ \o \c fileBaseName
+ \o \c fileSuffix
+ \o \c fileSize
+ \o \c fileModified
+ \o \c fileAccessed
+ \o \c fileIsDir
+ \endlist
+*/
+QVariant QQuickFolderListModel::get(int idx, const QString &property) const
+{
+ int role = roleFromString(property);
+ if (role >= 0 && idx >= 0)
+ return data(index(idx, 0), role);
+ else
+ return QVariant();
+}
+
+#include "moc_qquickfolderlistmodel.cpp"
+
//![code]
QT_END_NAMESPACE
-
-#endif // QT_NO_DIRMODEL
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index 10af7c8075..830a30b146 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -47,8 +47,6 @@
#include <QUrl>
#include <QAbstractListModel>
-#ifndef QT_NO_DIRMODEL
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -68,14 +66,16 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus
//![class props]
Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
+ Q_PROPERTY(QUrl rootFolder READ rootFolder WRITE setRootFolder)
Q_PROPERTY(QUrl parentFolder READ parentFolder NOTIFY folderChanged)
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed)
Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs)
+ Q_PROPERTY(bool showDirsFirst READ showDirsFirst WRITE setShowDirsFirst)
Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
- Q_PROPERTY(int count READ count)
+ Q_PROPERTY(int count READ count NOTIFY rowCountChanged)
//![class props]
//![abslistmodel]
@@ -83,10 +83,20 @@ public:
QQuickFolderListModel(QObject *parent = 0);
~QQuickFolderListModel();
- enum Roles { FileNameRole = Qt::UserRole+1, FilePathRole = Qt::UserRole+2 };
-
- int rowCount(const QModelIndex &parent) const;
- QVariant data(const QModelIndex &index, int role) const;
+ enum Roles {
+ FileNameRole = Qt::UserRole + 1,
+ FilePathRole = Qt::UserRole + 2,
+ FileBaseNameRole = Qt::UserRole + 3,
+ FileSuffixRole = Qt::UserRole + 4,
+ FileSizeRole = Qt::UserRole + 5,
+ FileLastModifiedRole = Qt::UserRole + 6,
+ FileLastReadRole = Qt::UserRole +7,
+ FileIsDirRole = Qt::UserRole + 8
+ };
+
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
//![abslistmodel]
//![count]
@@ -96,6 +106,8 @@ public:
//![prop funcs]
QUrl folder() const;
void setFolder(const QUrl &folder);
+ QUrl rootFolder() const;
+ void setRootFolder(const QUrl &path);
QUrl parentFolder() const;
@@ -111,49 +123,47 @@ public:
void setSortReversed(bool rev);
bool showDirs() const;
- void setShowDirs(bool);
+ void setShowDirs(bool showDirs);
+ bool showDirsFirst() const;
+ void setShowDirsFirst(bool showDirsFirst);
bool showDotAndDotDot() const;
- void setShowDotAndDotDot(bool);
+ void setShowDotAndDotDot(bool on);
bool showOnlyReadable() const;
- void setShowOnlyReadable(bool);
+ void setShowOnlyReadable(bool on);
//![prop funcs]
-//![isfolder]
Q_INVOKABLE bool isFolder(int index) const;
-//![isfolder]
+ Q_INVOKABLE QVariant get(int idx, const QString &property) const;
//![parserstatus]
virtual void classBegin();
virtual void componentComplete();
//![parserstatus]
+ int roleFromString(const QString &roleName) const;
+
//![notifier]
Q_SIGNALS:
void folderChanged();
+ void rowCountChanged() const;
//![notifier]
//![class end]
-private Q_SLOTS:
- void refresh();
- void resetFiltering();
- void inserted(const QModelIndex &index, int start, int end);
- void removed(const QModelIndex &index, int start, int end);
- void handleDataChanged(const QModelIndex &start, const QModelIndex &end);
+
private:
Q_DISABLE_COPY(QQuickFolderListModel)
- QQuickFolderListModelPrivate *d;
+ Q_DECLARE_PRIVATE(QQuickFolderListModel)
+ QScopedPointer<QQuickFolderListModelPrivate> d_ptr;
+
+ Q_PRIVATE_SLOT(d_func(), void _q_directoryChanged(const QString &directory, const QList<FileProperty> &list))
+ Q_PRIVATE_SLOT(d_func(), void _q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex))
+ Q_PRIVATE_SLOT(d_func(), void _q_sortFinished(const QList<FileProperty> &list))
};
//![class end]
QT_END_NAMESPACE
-//![qml decl]
-QML_DECLARE_TYPE(QQuickFolderListModel)
-//![qml decl]
-
QT_END_HEADER
-#endif // QT_NO_DIRMODEL
-
#endif // QQUICKFOLDERLISTMODEL_H
diff --git a/src/imports/gestures/gestures.json b/src/imports/gestures/gestures.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/imports/gestures/gestures.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/localstorage/localstorage.json b/src/imports/localstorage/localstorage.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/imports/localstorage/localstorage.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/localstorage/localstorage.pro b/src/imports/localstorage/localstorage.pro
index c54bc564d9..fa1718dd68 100644
--- a/src/imports/localstorage/localstorage.pro
+++ b/src/imports/localstorage/localstorage.pro
@@ -6,10 +6,12 @@ QT += sql qml qml-private v8-private core-private
SOURCES += plugin.cpp
+OTHER_FILES += localstorage.json
+
DESTDIR = $$QT.qml.imports/$$TARGETPATH
target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
qmldir.files += $$PWD/qmldir
qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
-INSTALLS += target qmldir \ No newline at end of file
+INSTALLS += target qmldir
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 77e68877d4..7c55225ed1 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -651,6 +651,8 @@ static QObject *module_api_factory(QQmlEngine *engine, QJSEngine *scriptEngine)
class QQmlLocalStoragePlugin : public QQmlExtensionPlugin
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "localstorage.json")
+
public:
QQmlLocalStoragePlugin()
{
@@ -664,5 +666,3 @@ public:
};
#include "plugin.moc"
-
-Q_EXPORT_PLUGIN2(plugin, QQmlLocalStoragePlugin);
diff --git a/src/imports/shaders/shaders.json b/src/imports/shaders/shaders.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/imports/shaders/shaders.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index 8ab745a7d2..6473d216c7 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -135,6 +135,8 @@ QT_BEGIN_NAMESPACE
class QTestQmlModule : public QQmlExtensionPlugin
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "testlib.json")
+
public:
virtual void registerTypes(const char *uri)
{
@@ -152,5 +154,3 @@ public:
QT_END_NAMESPACE
#include "main.moc"
-
-Q_EXPORT_PLUGIN2(qmltestplugin, QT_PREPEND_NAMESPACE(QTestQmlModule))
diff --git a/src/imports/testlib/testlib.json b/src/imports/testlib/testlib.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/imports/testlib/testlib.json
@@ -0,0 +1 @@
+{}
diff --git a/src/imports/testlib/testlib.pro b/src/imports/testlib/testlib.pro
index a4cb03466e..dfb23cea0c 100644
--- a/src/imports/testlib/testlib.pro
+++ b/src/imports/testlib/testlib.pro
@@ -7,7 +7,8 @@ CONFIG += qt plugin
QT += qml quick qmltest qmltest-private v8-private qml-private core-private testlib
SOURCES += main.cpp
-HEADERS +=
+
+OTHER_FILES += testlib.json
DESTDIR = $$QT.qml.imports/$$TARGETPATH
diff --git a/src/imports/xmllistmodel/plugin.cpp b/src/imports/xmllistmodel/plugin.cpp
index 54a6d5e212..58253492e1 100644
--- a/src/imports/xmllistmodel/plugin.cpp
+++ b/src/imports/xmllistmodel/plugin.cpp
@@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE
class QmlXmlListModelPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface" FILE "xmllistmodel.json")
+
public:
virtual void registerTypes(const char *uri)
{
@@ -61,5 +63,3 @@ public:
QT_END_NAMESPACE
#include "plugin.moc"
-
-Q_EXPORT_PLUGIN2(qmlxmllistmodelplugin, QT_PREPEND_NAMESPACE(QmlXmlListModelPlugin));
diff --git a/src/imports/xmllistmodel/xmllistmodel.json b/src/imports/xmllistmodel/xmllistmodel.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/imports/xmllistmodel/xmllistmodel.json
@@ -0,0 +1 @@
+{}
diff --git a/src/plugins/accessible/quick/accessible.json b/src/plugins/accessible/quick/accessible.json
new file mode 100644
index 0000000000..845a45aa78
--- /dev/null
+++ b/src/plugins/accessible/quick/accessible.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "QQuickView", "QQuickItem" ]
+}
diff --git a/src/plugins/accessible/quick/main.cpp b/src/plugins/accessible/quick/main.cpp
index 783d4674da..6ff3d5db9e 100644
--- a/src/plugins/accessible/quick/main.cpp
+++ b/src/plugins/accessible/quick/main.cpp
@@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE
class AccessibleQuickFactory : public QAccessiblePlugin
{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QAccessibleFactoryInterface" FILE "accessible.json")
+
public:
AccessibleQuickFactory();
@@ -105,9 +108,8 @@ QAccessibleInterface *AccessibleQuickFactory::create(const QString &classname, Q
return 0;
}
-Q_EXPORT_STATIC_PLUGIN(AccessibleQuickFactory)
-Q_EXPORT_PLUGIN2(qtaccessiblequick, AccessibleQuickFactory)
-
QT_END_NAMESPACE
+#include "main.moc"
+
#endif // QT_NO_ACCESSIBILITY
diff --git a/src/plugins/accessible/quick/quick.pro b/src/plugins/accessible/quick/quick.pro
index ae6ec032da..213d2e889b 100644
--- a/src/plugins/accessible/quick/quick.pro
+++ b/src/plugins/accessible/quick/quick.pro
@@ -19,5 +19,7 @@ SOURCES += \
HEADERS += \
qaccessiblequickview.h \
qaccessiblequickitem.h
+
+OTHERFILES += accessible.json
}
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro b/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro
index 014f964652..f0514134d1 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qmldbg_qtquick2.pro
@@ -27,5 +27,7 @@ HEADERS += \
../shared/qqmlinspectorprotocol.h \
../shared/qmlinspectorconstants.h
+OTHER_FILES += qtquick2plugin.json
+
target.path += $$[QT_INSTALL_PLUGINS]/qmltooling
INSTALLS += target
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.cpp b/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.cpp
index ea52788896..16dfaed597 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.cpp
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.cpp
@@ -84,5 +84,3 @@ void QtQuick2Plugin::clientMessage(const QByteArray &message)
} // namespace QtQuick2
} // namespace QmlJSDebugger
-
-Q_EXPORT_PLUGIN2(qmldbg_qtquick2, QmlJSDebugger::QtQuick2::QtQuick2Plugin)
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.h b/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.h
index d78aac6ead..6c3f3d6943 100644
--- a/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.h
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.h
@@ -55,6 +55,7 @@ class QtQuick2Plugin : public QObject, public QQmlInspectorInterface
{
Q_OBJECT
Q_DISABLE_COPY(QtQuick2Plugin)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlInspectorInterface" FILE "qtquick2plugin.json")
Q_INTERFACES(QQmlInspectorInterface)
public:
diff --git a/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.json b/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.json
new file mode 100644
index 0000000000..311847daa5
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_qtquick2/qtquick2plugin.json
@@ -0,0 +1,2 @@
+{}
+
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro b/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro
index cb663dbc0c..0c5e196b18 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro
+++ b/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro
@@ -14,5 +14,7 @@ SOURCES += \
HEADERS += \
qtcpserverconnection.h
+OTHER_FILES += qtcpserverconnection.json
+
target.path += $$[QT_INSTALL_PLUGINS]/qmltooling
INSTALLS += target
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
index 63a3297f37..1c5ec37512 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
@@ -193,7 +193,5 @@ void QTcpServerConnection::invalidPacket()
qWarning("QQmlDebugServer: Received a corrupted packet! Giving up ...");
}
-Q_EXPORT_PLUGIN2(tcpserver, QTcpServerConnection)
-
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
index 74c6b95e56..e81c9f7f0f 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h
@@ -54,9 +54,9 @@ class QTcpServerConnection : public QObject, public QQmlDebugServerConnection
Q_OBJECT
Q_DECLARE_PRIVATE(QTcpServerConnection)
Q_DISABLE_COPY(QTcpServerConnection)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlDebugServerConnection" FILE "qtcpserverconnection.json")
Q_INTERFACES(QQmlDebugServerConnection)
-
public:
QTcpServerConnection();
~QTcpServerConnection();
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.json b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.json
@@ -0,0 +1 @@
+{}
diff --git a/src/qml/debugger/qdebugmessageservice.cpp b/src/qml/debugger/qdebugmessageservice.cpp
index 2c52809e56..dcaa514cd7 100644
--- a/src/qml/debugger/qdebugmessageservice.cpp
+++ b/src/qml/debugger/qdebugmessageservice.cpp
@@ -42,6 +42,8 @@
#include "qdebugmessageservice_p.h"
#include "qqmldebugservice_p_p.h"
+#include <QDataStream>
+
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QDebugMessageService, qmlDebugMessageService)
diff --git a/src/qml/debugger/qqmldebugserverconnection_p.h b/src/qml/debugger/qqmldebugserverconnection_p.h
index c9092f1911..ab9e7bd73f 100644
--- a/src/qml/debugger/qqmldebugserverconnection_p.h
+++ b/src/qml/debugger/qqmldebugserverconnection_p.h
@@ -43,7 +43,7 @@
#define QQMLDEBUGSERVERCONNECTION_H
#include <QtQml/qtqmlglobal.h>
-#include <QtCore/QtPlugin>
+#include <private/qqmlglobal_p.h>
//
// W A R N I N G
@@ -76,7 +76,9 @@ public:
virtual bool waitForMessage() = 0;
};
-Q_DECLARE_INTERFACE(QQmlDebugServerConnection, "com.trolltech.Qt.QQmlDebugServerConnection/1.0")
+#define QQmlDebugServerConnection_iid "org.qt-project.Qt.QQmlDebugServerConnection"
+
+Q_DECLARE_INTERFACE(QQmlDebugServerConnection, QQmlDebugServerConnection_iid)
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlinspectorinterface_p.h b/src/qml/debugger/qqmlinspectorinterface_p.h
index 7f52dffa2e..5b015d36df 100644
--- a/src/qml/debugger/qqmlinspectorinterface_p.h
+++ b/src/qml/debugger/qqmlinspectorinterface_p.h
@@ -54,6 +54,7 @@
//
#include <QtQml/qtqmlglobal.h>
+#include <private/qqmlglobal_p.h>
QT_BEGIN_HEADER
@@ -74,7 +75,9 @@ public:
virtual void clientMessage(const QByteArray &message) = 0;
};
-Q_DECLARE_INTERFACE(QQmlInspectorInterface, "com.trolltech.Qt.QQmlInspectorInterface/1.0")
+#define QQmlInspectorInterface_iid "org.qt-project.Qt.QQmlInspectorInterface"
+
+Q_DECLARE_INTERFACE(QQmlInspectorInterface, QQmlInspectorInterface_iid)
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp
index d6a0307836..2731d2046b 100644
--- a/src/qml/debugger/qqmlprofilerservice.cpp
+++ b/src/qml/debugger/qqmlprofilerservice.cpp
@@ -52,23 +52,10 @@
QT_BEGIN_NAMESPACE
+// instance will be set, unset in constructor. Allows static methods to be inlined.
+QQmlProfilerService *QQmlProfilerService::instance = 0;
Q_GLOBAL_STATIC(QQmlProfilerService, profilerInstance)
-QQmlBindingProfiler::QQmlBindingProfiler(const QString &url, int line, int column)
-{
- QQmlProfilerService::startRange(QQmlProfilerService::Binding);
- QQmlProfilerService::rangeLocation(QQmlProfilerService::Binding, url, line, column);
-}
-
-QQmlBindingProfiler::~QQmlBindingProfiler()
-{
- QQmlProfilerService::endRange(QQmlProfilerService::Binding);
-}
-
-void QQmlBindingProfiler::addDetail(const QString &details)
-{
- QQmlProfilerService::rangeData(QQmlProfilerService::Binding, details);
-}
// convert to a QByteArray that can be sent to the debug client
// use of QDataStream can skew results
@@ -106,12 +93,13 @@ QQmlProfilerService::QQmlProfilerService()
QQmlProfilerService::~QQmlProfilerService()
{
+ instance = 0;
}
void QQmlProfilerService::initialize()
{
// just make sure that the service is properly registered
- profilerInstance();
+ instance = profilerInstance();
}
bool QQmlProfilerService::startProfiling()
@@ -134,36 +122,6 @@ void QQmlProfilerService::addEvent(EventType t)
profilerInstance()->addEventImpl(t);
}
-void QQmlProfilerService::startRange(RangeType t)
-{
- profilerInstance()->startRangeImpl(t);
-}
-
-void QQmlProfilerService::rangeData(RangeType t, const QString &data)
-{
- profilerInstance()->rangeDataImpl(t, data);
-}
-
-void QQmlProfilerService::rangeData(RangeType t, const QUrl &data)
-{
- profilerInstance()->rangeDataImpl(t, data);
-}
-
-void QQmlProfilerService::rangeLocation(RangeType t, const QString &fileName, int line, int column)
-{
- profilerInstance()->rangeLocationImpl(t, fileName, line, column);
-}
-
-void QQmlProfilerService::rangeLocation(RangeType t, const QUrl &fileName, int line, int column)
-{
- profilerInstance()->rangeLocationImpl(t, fileName, line, column);
-}
-
-void QQmlProfilerService::endRange(RangeType t)
-{
- profilerInstance()->endRangeImpl(t);
-}
-
void QQmlProfilerService::animationFrame(qint64 delta)
{
profilerInstance()->animationFrameImpl(delta);
@@ -214,7 +172,7 @@ void QQmlProfilerService::addEventImpl(EventType event)
processMessage(ed);
}
-void QQmlProfilerService::startRangeImpl(RangeType range)
+void QQmlProfilerService::startRange(RangeType range)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
@@ -223,7 +181,7 @@ void QQmlProfilerService::startRangeImpl(RangeType range)
processMessage(rd);
}
-void QQmlProfilerService::rangeDataImpl(RangeType range, const QString &rData)
+void QQmlProfilerService::rangeData(RangeType range, const QString &rData)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
@@ -232,7 +190,7 @@ void QQmlProfilerService::rangeDataImpl(RangeType range, const QString &rData)
processMessage(rd);
}
-void QQmlProfilerService::rangeDataImpl(RangeType range, const QUrl &rData)
+void QQmlProfilerService::rangeData(RangeType range, const QUrl &rData)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
@@ -241,7 +199,7 @@ void QQmlProfilerService::rangeDataImpl(RangeType range, const QUrl &rData)
processMessage(rd);
}
-void QQmlProfilerService::rangeLocationImpl(RangeType range, const QString &fileName, int line, int column)
+void QQmlProfilerService::rangeLocation(RangeType range, const QString &fileName, int line, int column)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
@@ -250,7 +208,7 @@ void QQmlProfilerService::rangeLocationImpl(RangeType range, const QString &file
processMessage(rd);
}
-void QQmlProfilerService::rangeLocationImpl(RangeType range, const QUrl &fileName, int line, int column)
+void QQmlProfilerService::rangeLocation(RangeType range, const QUrl &fileName, int line, int column)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
@@ -259,7 +217,7 @@ void QQmlProfilerService::rangeLocationImpl(RangeType range, const QUrl &fileNam
processMessage(rd);
}
-void QQmlProfilerService::endRangeImpl(RangeType range)
+void QQmlProfilerService::endRange(RangeType range)
{
if (!QQmlDebugService::isDebuggingEnabled() || !m_enabled)
return;
diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h
index a74ce10c74..7a708456ba 100644
--- a/src/qml/debugger/qqmlprofilerservice_p.h
+++ b/src/qml/debugger/qqmlprofilerservice_p.h
@@ -54,9 +54,11 @@
//
#include <private/qqmldebugservice_p.h>
+#include <QtQml/qtqmlglobal.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmutex.h>
#include <QtCore/qvector.h>
+#include <QtCore/qstringbuilder.h>
QT_BEGIN_HEADER
@@ -83,13 +85,6 @@ Q_DECLARE_TYPEINFO(QQmlProfilerData, Q_MOVABLE_TYPE);
class QUrl;
class QQmlEngine;
-// RAII
-class Q_AUTOTEST_EXPORT QQmlBindingProfiler {
-public:
- QQmlBindingProfiler(const QString &url, int line, int column);
- ~QQmlBindingProfiler();
- void addDetail(const QString &details);
-};
class Q_QML_EXPORT QQmlProfilerService : public QQmlDebugService
{
@@ -132,12 +127,6 @@ public:
static bool stopProfiling();
static void sendStartedProfilingMessage();
static void addEvent(EventType);
- static void startRange(RangeType);
- static void rangeData(RangeType, const QString &);
- static void rangeData(RangeType, const QUrl &);
- static void rangeLocation(RangeType, const QString &, int, int);
- static void rangeLocation(RangeType, const QUrl &, int, int);
- static void endRange(RangeType);
static void animationFrame(qint64);
static void sendProfilingData();
@@ -154,14 +143,16 @@ private:
bool stopProfilingImpl();
void sendStartedProfilingMessageImpl();
void addEventImpl(EventType);
- void startRangeImpl(RangeType);
- void rangeDataImpl(RangeType, const QString &);
- void rangeDataImpl(RangeType, const QUrl &);
- void rangeLocationImpl(RangeType, const QString &, int, int);
- void rangeLocationImpl(RangeType, const QUrl &, int, int);
- void endRangeImpl(RangeType);
void animationFrameImpl(qint64);
+ void startRange(RangeType);
+ void rangeData(RangeType, const QString &);
+ void rangeData(RangeType, const QUrl &);
+ void rangeLocation(RangeType, const QString &, int, int);
+ void rangeLocation(RangeType, const QUrl &, int, int);
+ void endRange(RangeType);
+
+
bool profilingEnabled();
void setProfilingEnabled(bool enable);
void sendMessages();
@@ -173,6 +164,135 @@ private:
bool m_messageReceived;
QVector<QQmlProfilerData> m_data;
QMutex m_mutex;
+
+ static QQmlProfilerService *instance;
+
+ friend struct QQmlBindingProfiler;
+ friend struct QQmlHandlingSignalProfiler;
+ friend struct QQmlObjectCreatingProfiler;
+ friend struct QQmlCompilingProfiler;
+};
+
+//
+// RAII helper structs
+//
+
+struct QQmlBindingProfiler {
+ QQmlBindingProfiler(const QString &url, int line, int column)
+ {
+ QQmlProfilerService *instance = QQmlProfilerService::instance;
+ enabled = instance ? instance->profilingEnabled() : false;
+ if (enabled) {
+ instance->startRange(QQmlProfilerService::Binding);
+ instance->rangeLocation(QQmlProfilerService::Binding, url, line, column);
+ }
+ }
+
+ ~QQmlBindingProfiler()
+ {
+ if (enabled)
+ QQmlProfilerService::instance->endRange(QQmlProfilerService::Binding);
+ }
+
+ void addDetail(const QString &details)
+ {
+ if (enabled)
+ QQmlProfilerService::instance->rangeData(QQmlProfilerService::Binding,
+ details);
+ }
+\
+ bool enabled;
+};
+
+struct QQmlHandlingSignalProfiler {
+ QQmlHandlingSignalProfiler()
+ {
+ enabled = QQmlProfilerService::instance
+ ? QQmlProfilerService::instance->profilingEnabled() : false;
+ if (enabled) {
+ QQmlProfilerService::instance->startRange(
+ QQmlProfilerService::HandlingSignal);
+ }
+ }
+
+ void setSignalInfo(const QString &name, const QString &expression)
+ {
+ if (enabled)
+ QQmlProfilerService::instance->rangeData(
+ QQmlProfilerService::HandlingSignal,
+ name % QLatin1String(": ") % expression);
+ }
+
+ void setLocation(const QString &file, int line, int column)
+ {
+ if (enabled)
+ QQmlProfilerService::instance->rangeLocation(
+ QQmlProfilerService::HandlingSignal, file, line, column);
+ }
+
+ ~QQmlHandlingSignalProfiler()
+ {
+ if (enabled)
+ QQmlProfilerService::instance->endRange(
+ QQmlProfilerService::HandlingSignal);
+ }
+
+ bool enabled;
+};
+
+struct QQmlObjectCreatingProfiler {
+ QQmlObjectCreatingProfiler()
+ {
+ QQmlProfilerService *instance = QQmlProfilerService::instance;
+ enabled = instance ?
+ instance->profilingEnabled() : false;
+ if (enabled)
+ instance->startRange(QQmlProfilerService::Creating);
+ }
+
+ void setTypeName(const QString &typeName)
+ {
+ if (enabled)
+ QQmlProfilerService::instance->rangeData(
+ QQmlProfilerService::Creating, typeName);
+ }
+
+ void setLocation(const QUrl &url, int line, int column)
+ {
+ if (enabled)
+ QQmlProfilerService::instance->rangeLocation(
+ QQmlProfilerService::Creating, url, line, column);
+ }
+
+ ~QQmlObjectCreatingProfiler()
+ {
+ if (enabled)
+ QQmlProfilerService::instance->endRange(QQmlProfilerService::Creating);
+ }
+
+ bool enabled;
+};
+
+struct QQmlCompilingProfiler {
+ QQmlCompilingProfiler(const QString &name)
+ {
+ QQmlProfilerService *instance = QQmlProfilerService::instance;
+ enabled = instance ?
+ instance->profilingEnabled() : false;
+ if (enabled) {
+ instance->startRange(QQmlProfilerService::Compiling);
+ instance->rangeLocation(QQmlProfilerService::Compiling, name, 1, 1);
+ instance->rangeData(QQmlProfilerService::Compiling, name);
+ }
+ }
+
+ ~QQmlCompilingProfiler()
+ {
+ if (enabled)
+ QQmlProfilerService::instance->endRange(QQmlProfilerService::Compiling);
+ }
+
+ bool enabled;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv8profilerservice.cpp b/src/qml/debugger/qv8profilerservice.cpp
index eba8b0feef..6473a2f4fb 100644
--- a/src/qml/debugger/qv8profilerservice.cpp
+++ b/src/qml/debugger/qv8profilerservice.cpp
@@ -187,6 +187,13 @@ void QV8ProfilerService::startProfiling(const QString &title)
v8::CpuProfiler::StartProfiling(v8title);
d->m_ongoing.append(title);
+
+ // indicate profiling started
+ QByteArray data;
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << (int)QV8ProfilerService::V8Started;
+
+ sendMessage(data);
}
void QV8ProfilerService::stopProfiling(const QString &title)
@@ -205,6 +212,13 @@ void QV8ProfilerService::stopProfiling(const QString &title)
// can happen at start
const v8::CpuProfileNode *rootNode = cpuProfile->GetTopDownRoot();
d->printProfileTree(rootNode);
+ } else {
+ // indicate completion, even without data
+ QByteArray data;
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << (int)QV8ProfilerService::V8Complete;
+
+ sendMessage(data);
}
}
diff --git a/src/qml/debugger/qv8profilerservice_p.h b/src/qml/debugger/qv8profilerservice_p.h
index d408d9ed0e..b706d1762a 100644
--- a/src/qml/debugger/qv8profilerservice_p.h
+++ b/src/qml/debugger/qv8profilerservice_p.h
@@ -85,6 +85,7 @@ public:
V8Complete,
V8SnapshotChunk,
V8SnapshotComplete,
+ V8Started,
V8MaximumMessage
};
diff --git a/src/qml/qml/ftw/qfastmetabuilder.cpp b/src/qml/qml/ftw/qfastmetabuilder.cpp
index 9663c1e944..02f50911ea 100644
--- a/src/qml/qml/ftw/qfastmetabuilder.cpp
+++ b/src/qml/qml/ftw/qfastmetabuilder.cpp
@@ -42,6 +42,8 @@
#include "qfastmetabuilder_p.h"
#include <QtCore/qmetaobject.h>
+#include <private/qobject_p.h>
+#include <private/qmetaobject_p.h>
QT_BEGIN_NAMESPACE
@@ -50,65 +52,6 @@ struct QFastMetaBuilderHeader
int fieldCount;
};
-struct QMetaObjectPrivate
-{
- int revision;
- int className;
- int classInfoCount, classInfoData;
- int methodCount, methodData;
- int propertyCount, propertyData;
- int enumeratorCount, enumeratorData;
- int constructorCount, constructorData; //since revision 2
- int flags; //since revision 3
- int signalCount; //since revision 4
-};
-
-enum MetaObjectFlag {
- DynamicMetaObject = 0x01
-};
-
-enum PropertyFlags {
- Invalid = 0x00000000,
- Readable = 0x00000001,
- Writable = 0x00000002,
- Resettable = 0x00000004,
- EnumOrFlag = 0x00000008,
- StdCppSet = 0x00000100,
-// Override = 0x00000200,
- Constant = 0x00000400,
- Final = 0x00000800,
- Designable = 0x00001000,
- ResolveDesignable = 0x00002000,
- Scriptable = 0x00004000,
- ResolveScriptable = 0x00008000,
- Stored = 0x00010000,
- ResolveStored = 0x00020000,
- Editable = 0x00040000,
- ResolveEditable = 0x00080000,
- User = 0x00100000,
- ResolveUser = 0x00200000,
- Notify = 0x00400000,
- Revisioned = 0x00800000
-};
-
-enum MethodFlags {
- AccessPrivate = 0x00,
- AccessProtected = 0x01,
- AccessPublic = 0x02,
- AccessMask = 0x03, //mask
-
- MethodMethod = 0x00,
- MethodSignal = 0x04,
- MethodSlot = 0x08,
- MethodConstructor = 0x0c,
- MethodTypeMask = 0x0c,
-
- MethodCompatibility = 0x10,
- MethodCloned = 0x20,
- MethodScriptable = 0x40,
- MethodRevisioned = 0x80
-};
-
#define FMBHEADER_FIELD_COUNT 1
#define HEADER_FIELD_COUNT 14
@@ -175,7 +118,7 @@ QFastMetaBuilder::StringRef QFastMetaBuilder::init(int classNameLength,
int dataIndex = HEADER_FIELD_COUNT;
- p->revision = 4;
+ p->revision = 6;
p->className = 0;
// Class infos
@@ -364,6 +307,7 @@ void QFastMetaBuilder::fromData(QMetaObject *output, const QMetaObject *parent,
output->d.superdata = parent;
output->d.stringdata = data.constData() + header(data)->fieldCount * sizeof(uint);
output->d.data = fieldPointer(data);
+ output->d.extradata = 0;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 6f552450ef..ca6b13e7f8 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -170,12 +170,18 @@ int QQmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
if (c == QMetaObject::InvokeMetaMethod && id == evaluateIdx) {
if (!m_expression)
return -1;
- if (QQmlDebugService::isDebuggingEnabled()) {
- QQmlProfilerService::startRange(QQmlProfilerService::HandlingSignal);
- QQmlProfilerService::rangeData(QQmlProfilerService::HandlingSignal, QLatin1String(m_signal.signature()) % QLatin1String(": ") % m_expression->expression());
- QQmlProfilerService::rangeLocation(QQmlProfilerService::HandlingSignal, m_expression->sourceFile(), m_expression->lineNumber(), m_expression->columnNumber());
+
+ if (QQmlDebugService::isDebuggingEnabled())
QV8DebugService::instance()->signalEmitted(QString::fromAscii(m_signal.signature()));
+
+ QQmlHandlingSignalProfiler prof;
+ if (prof.enabled) {
+ prof.setSignalInfo(QString::fromLatin1(m_signal.signature()),
+ m_expression->expression());
+ prof.setLocation(m_expression->sourceFile(), m_expression->lineNumber(),
+ m_expression->columnNumber());
}
+
m_isEvaluating = true;
if (!m_paramsValid) {
if (!m_signal.parameterTypes().isEmpty())
@@ -191,7 +197,6 @@ int QQmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
}
if (m_params) m_params->clearValues();
m_isEvaluating = false;
- QQmlProfilerService::endRange(QQmlProfilerService::HandlingSignal);
return -1;
} else {
return QObject::qt_metacall(c, id, a);
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 65247e1e80..23c4adc7b4 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -3609,16 +3609,19 @@ bool QQmlCompiler::completeComponentBuild()
bool isSharable = false;
binding.rewrittenExpression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
- if (isSharable && !binding.property->isValueTypeSubProperty && !binding.property->isAlias /* See above re alias */ &&
+ if (isSharable && !binding.property->isAlias /* See above re alias */ &&
binding.property->type != qMetaTypeId<QQmlBinding*>()) {
binding.dataType = BindingReference::V8;
sharedBindings.append(b);
+
+ if (componentStats)
+ componentStats->componentStat.sharedBindings.append(b->value->location);
} else {
binding.dataType = BindingReference::QtScript;
- }
- if (componentStats)
- componentStats->componentStat.scriptBindings.append(b->value->location);
+ if (componentStats)
+ componentStats->componentStat.scriptBindings.append(b->value->location);
+ }
}
if (!sharedBindings.isEmpty()) {
@@ -3699,6 +3702,25 @@ void QQmlCompiler::dumpStats()
qWarning().nospace() << output.constData();
}
+ qWarning().nospace() << " Shared Bindings: " << stat.sharedBindings.count();
+ {
+ QByteArray output;
+ for (int ii = 0; ii < stat.sharedBindings.count(); ++ii) {
+ if (0 == (ii % 10)) {
+ if (ii) output.append("\n");
+ output.append(" ");
+ }
+
+ output.append("(");
+ output.append(QByteArray::number(stat.sharedBindings.at(ii).start.line));
+ output.append(":");
+ output.append(QByteArray::number(stat.sharedBindings.at(ii).start.column));
+ output.append(") ");
+ }
+ if (!output.isEmpty())
+ qWarning().nospace() << output.constData();
+ }
+
qWarning().nospace() << " QScript Bindings: " << stat.scriptBindings.count();
{
QByteArray output;
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index 9b13b7e63b..3b6fdf1473 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -450,6 +450,7 @@ private:
int ids;
QList<QQmlScript::LocationSpan> scriptBindings;
+ QList<QQmlScript::LocationSpan> sharedBindings;
QList<QQmlScript::LocationSpan> optimizedBindings;
int objects;
};
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index e168f063c0..5dd8fc8ae9 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -51,6 +51,7 @@
#include "qqmlengine.h"
#include "qqmlbinding_p.h"
#include "qqmlbinding_p_p.h"
+#include "qqmlglobal_p.h"
#include "qqmlscript_p.h"
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlenginedebugservice_p.h>
@@ -738,14 +739,15 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine);
- bool isRoot = enginePriv->inProgressCreations == 0;
+ if (enginePriv->inProgressCreations == 0) {
+ // only track root, since further ones might not be properly nested
+ profiler = new QQmlObjectCreatingProfiler();
+ }
+
enginePriv->inProgressCreations++;
state.errors.clear();
state.completePending = true;
- if (isRoot)
- QQmlProfilerService::startRange(QQmlProfilerService::Creating);
-
enginePriv->referenceScarceResources();
state.vme.init(context, cc, start, creationContext);
QObject *rv = state.vme.execute(&state.errors);
@@ -761,13 +763,12 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
if (!context->isInternal)
context->asQQmlContextPrivate()->instances.append(rv);
QQmlEngineDebugService::instance()->objectCreated(engine, rv);
- if (isRoot) {
- QQmlProfilerService::rangeData(QQmlProfilerService::Creating,
- buildTypeNameForDebug(rv->metaObject()));
+
+ if (profiler && profiler->enabled) {
+ profiler->setTypeName(buildTypeNameForDebug(rv->metaObject()));
QQmlData *data = QQmlData::get(rv);
Q_ASSERT(data);
- QQmlProfilerService::rangeLocation(QQmlProfilerService::Creating,
- cc->url, data->lineNumber, data->columnNumber);
+ profiler->setLocation(cc->url, data->lineNumber, data->columnNumber);
}
}
@@ -823,7 +824,8 @@ void QQmlComponentPrivate::completeCreate()
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
complete(ep, &state);
- QQmlProfilerService::endRange(QQmlProfilerService::Creating);
+ delete profiler;
+ profiler = 0;
}
}
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 731fb6a8a7..b03dd68936 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -62,6 +62,7 @@
#include "qqmlvme_p.h"
#include "qqmlerror.h"
#include "qqml.h"
+#include "../debugger/qqmlprofilerservice_p.h"
#include <QtCore/QString>
#include <QtCore/QStringList>
@@ -83,7 +84,7 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public
Q_DECLARE_PUBLIC(QQmlComponent)
public:
- QQmlComponentPrivate() : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0) {}
+ QQmlComponentPrivate() : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0), profiler(0) {}
QObject *beginCreate(QQmlContextData *);
void completeCreate();
@@ -116,6 +117,7 @@ public:
QQmlEngine *engine;
QQmlGuardedContextData creationContext;
+ QQmlObjectCreatingProfiler *profiler;
void clear();
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 8cfe635543..ee5a0c954e 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -355,7 +355,8 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
QQmlEnginePrivate::~QQmlEnginePrivate()
{
- Q_ASSERT(inProgressCreations == 0);
+ if (inProgressCreations)
+ qWarning() << QQmlEngine::tr("There are still \"%1\" items in the process of being created at engine destruction.").arg(inProgressCreations);
while (cleanup) {
QQmlCleanup *c = cleanup;
@@ -965,13 +966,13 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
QQmlData *data = QQmlData::get(object);
if (data && data->deferredComponent) {
- if (QQmlDebugService::isDebuggingEnabled()) {
- QQmlProfilerService::startRange(QQmlProfilerService::Creating);
+ QQmlObjectCreatingProfiler prof;
+ if (prof.enabled) {
QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
- QString typeName = type ? type->qmlTypeName() : QString::fromUtf8(object->metaObject()->className());
- QQmlProfilerService::rangeData(QQmlProfilerService::Creating, typeName);
+ prof.setTypeName(type ? type->qmlTypeName()
+ : QString::fromUtf8(object->metaObject()->className()));
if (data->outerContext)
- QQmlProfilerService::rangeLocation(QQmlProfilerService::Creating, data->outerContext->url, data->lineNumber, data->columnNumber);
+ prof.setLocation(data->outerContext->url, data->lineNumber, data->columnNumber);
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(data->context->engine);
@@ -982,7 +983,6 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
data->deferredComponent = 0;
QQmlComponentPrivate::complete(ep, &state);
- QQmlProfilerService::endRange(QQmlProfilerService::Creating);
}
}
@@ -1411,7 +1411,7 @@ void QQmlEngine::addImportPath(const QString& path)
imports \c com.mycompany.Feature will cause the QQmlEngine to look
in \c /opt/MyApp/lib/imports/com/mycompany/Feature/ for the components
provided by that module. A \c qmldir file is required for defining the
- type version mapping and possibly declarative extensions plugins.
+ type version mapping and possibly QML extensions plugins.
By default, the list contains the directory of the application executable,
paths specified in the \c QML_IMPORT_PATH environment variable,
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 3fbb80c280..ecdbf21d4b 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -78,13 +78,13 @@ QQmlJavaScriptExpression::~QQmlJavaScriptExpression()
clearGuards();
}
-static QQmlJavaScriptExpression::VTable QDeclarativeExpressionPrivate_jsvtable = {
+static QQmlJavaScriptExpression::VTable QQmlExpressionPrivate_jsvtable = {
QQmlExpressionPrivate::expressionIdentifier,
QQmlExpressionPrivate::expressionChanged
};
QQmlExpressionPrivate::QQmlExpressionPrivate()
-: QQmlJavaScriptExpression(&QDeclarativeExpressionPrivate_jsvtable),
+: QQmlJavaScriptExpression(&QQmlExpressionPrivate_jsvtable),
expressionFunctionValid(true), expressionFunctionRewritten(false),
extractExpressionFromFunction(false), line(-1), dataRef(0)
{
diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h
index 63ef1adc08..194319431d 100644
--- a/src/qml/qml/qqmlextensioninterface.h
+++ b/src/qml/qml/qqmlextensioninterface.h
@@ -66,8 +66,13 @@ public:
virtual void initializeEngine(QQmlEngine *engine, const char *uri) = 0;
};
+#define QQmlTypesExtensionInterface_iid "org.qt-project.Qt.QQmlTypesExtensionInterface"
+
Q_DECLARE_INTERFACE(QQmlTypesExtensionInterface, "org.qt-project.Qt.QQmlTypesExtensionInterface/1.0")
-Q_DECLARE_INTERFACE(QQmlExtensionInterface, "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+
+#define QQmlExtensionInterface_iid "org.qt-project.Qt.QQmlExtensionInterface"
+
+Q_DECLARE_INTERFACE(QQmlExtensionInterface, QQmlExtensionInterface_iid)
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlimageprovider.h b/src/qml/qml/qqmlimageprovider.h
index d59cfc42ca..fe06925123 100644
--- a/src/qml/qml/qqmlimageprovider.h
+++ b/src/qml/qml/qqmlimageprovider.h
@@ -59,7 +59,7 @@ class Q_QML_EXPORT QQuickTextureFactory : public QObject
{
public:
QQuickTextureFactory();
- ~QQuickTextureFactory();
+ virtual ~QQuickTextureFactory();
virtual QSGTexture *createTexture(QQuickCanvas *canvas) const = 0;
virtual QSize textureSize() const = 0;
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index ee622ba048..834d4bbb97 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -376,17 +376,18 @@ void QQmlIncubationController::incubateFor(int msecs)
/*!
Incubate objects while the bool pointed to by \a flag is true, or until there are no
-more objects to incubate.
+more objects to incubate, or up to msecs if msecs is not zero.
Generally this method is used in conjunction with a thread or a UNIX signal that sets
the bool pointed to by \a flag to false when it wants incubation to be interrupted.
*/
-void QQmlIncubationController::incubateWhile(bool *flag)
+void QQmlIncubationController::incubateWhile(volatile bool *flag, int msecs)
{
if (!d || d->incubatorCount == 0)
return;
- QQmlVME::Interrupt i(flag);
+ QQmlVME::Interrupt i(flag, msecs * 1000000);
+ i.reset();
do {
QQmlIncubatorPrivate *p = (QQmlIncubatorPrivate*)d->incubatorList.first();
p->incubate(i);
diff --git a/src/qml/qml/qqmlincubator.h b/src/qml/qml/qqmlincubator.h
index 5d8ae7d6c3..2fb2aaf2f1 100644
--- a/src/qml/qml/qqmlincubator.h
+++ b/src/qml/qml/qqmlincubator.h
@@ -42,6 +42,7 @@
#ifndef QQMLINCUBATOR_H
#define QQMLINCUBATOR_H
+#include <QtQml/qtqmlglobal.h>
#include <QtQml/qqmlerror.h>
QT_BEGIN_HEADER
@@ -110,7 +111,7 @@ public:
int incubatingObjectCount() const;
void incubateFor(int msecs);
- void incubateWhile(bool *flag);
+ void incubateWhile(volatile bool *flag, int msecs=0);
protected:
virtual void incubatingObjectCountChanged(int);
diff --git a/src/qml/qml/qqmlinstruction.cpp b/src/qml/qml/qqmlinstruction.cpp
index 72f04c9d61..b37117e69b 100644
--- a/src/qml/qml/qqmlinstruction.cpp
+++ b/src/qml/qml/qqmlinstruction.cpp
@@ -190,7 +190,7 @@ void QQmlCompiledData::dump(QQmlInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << "STORE_INTERFACE\t\t" << instr->storeObject.propertyIndex;
break;
case QQmlInstruction::StoreSignal:
- qWarning().nospace() << idx << "\t\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value << "\t\t" << primitives.at(instr->storeSignal.value);
+ qWarning().nospace() << idx << "\t\t" << "STORE_SIGNAL\t\t" << instr->storeSignal.signalIndex << "\t" << instr->storeSignal.value;
break;
case QQmlInstruction::StoreImportedScript:
qWarning().nospace() << idx << "\t\t" << "STORE_IMPORTED_SCRIPT\t" << instr->storeScript.value;
@@ -199,7 +199,7 @@ void QQmlCompiledData::dump(QQmlInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << "STORE_SCRIPT_STRING\t" << instr->storeScriptString.propertyIndex << "\t" << instr->storeScriptString.value << "\t" << instr->storeScriptString.scope << "\t" << instr->storeScriptString.bindingId;
break;
case QQmlInstruction::AssignSignalObject:
- qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal << "\t\t\t" << primitives.at(instr->assignSignalObject.signal);
+ qWarning().nospace() << idx << "\t\t" << "ASSIGN_SIGNAL_OBJECT\t" << instr->assignSignalObject.signal;
break;
case QQmlInstruction::AssignCustomType:
qWarning().nospace() << idx << "\t\t" << "ASSIGN_CUSTOMTYPE\t" << instr->assignCustomType.propertyIndex << "\t" << instr->assignCustomType.primitive << "\t" << instr->assignCustomType.type;
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 4dc30f27ea..d684378832 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -524,7 +524,10 @@ v8::Handle<v8::Value> QQmlNumberExtension::fromLocaleString(const v8::Arguments&
static v8::Handle<v8::Value> locale_get_firstDayOfWeek(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
GET_LOCALE_DATA_RESOURCE(info.This());
- return v8::Integer::New(r->locale.firstDayOfWeek());
+ int fdow = int(r->locale.firstDayOfWeek());
+ if (fdow == 7)
+ fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date
+ return v8::Integer::New(fdow);
}
static v8::Handle<v8::Value> locale_get_measurementSystem(v8::Local<v8::String>, const v8::AccessorInfo &info)
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 9b132a4647..93c6aa1f00 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -50,6 +50,8 @@
#include <QtCore/qdebug.h>
+#include <ctype.h> // for toupper
+
Q_DECLARE_METATYPE(QJSValue)
Q_DECLARE_METATYPE(QQmlV8Handle);
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 095ee79867..a128cd9055 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -149,6 +149,7 @@ public:
bool hasOverride() const { return !(flags & IsValueTypeVirtual) &&
!(flags & HasAccessors) &&
overrideIndex >= 0; }
+ bool hasRevision() const { return !(flags & HasAccessors) && revision != 0; }
// Returns -1 if not a value type virtual property
inline int getValueTypeCoreIndex() const;
diff --git a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h
index f8b8643a00..cf449c9eff 100644
--- a/src/qml/qml/qqmlpropertyvalueinterceptor_p.h
+++ b/src/qml/qml/qqmlpropertyvalueinterceptor_p.h
@@ -67,7 +67,10 @@ public:
virtual void setTarget(const QQmlProperty &property) = 0;
virtual void write(const QVariant &value) = 0;
};
-Q_DECLARE_INTERFACE(QQmlPropertyValueInterceptor, "com.trolltech.qml.QQmlPropertyValueInterceptor")
+
+#define QQmlPropertyValueInterceptor_iid "org.qt-project.Qt.QQmlPropertyValueInterceptor"
+
+Q_DECLARE_INTERFACE(QQmlPropertyValueInterceptor, QQmlPropertyValueInterceptor_iid)
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlpropertyvaluesource.h b/src/qml/qml/qqmlpropertyvaluesource.h
index 910b23877e..bbd3c2f594 100644
--- a/src/qml/qml/qqmlpropertyvaluesource.h
+++ b/src/qml/qml/qqmlpropertyvaluesource.h
@@ -58,7 +58,10 @@ public:
virtual ~QQmlPropertyValueSource();
virtual void setTarget(const QQmlProperty &) = 0;
};
-Q_DECLARE_INTERFACE(QQmlPropertyValueSource, "com.trolltech.qml.QQmlPropertyValueSource")
+
+#define QQmlPropertyValueSource_iid "org.qt-project.Qt.QQmlPropertyValueSource"
+
+Q_DECLARE_INTERFACE(QQmlPropertyValueSource, QQmlPropertyValueSource_iid)
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlrewrite.cpp b/src/qml/qml/qqmlrewrite.cpp
index 828f7bf641..72bd23955b 100644
--- a/src/qml/qml/qqmlrewrite.cpp
+++ b/src/qml/qml/qqmlrewrite.cpp
@@ -51,6 +51,45 @@ DEFINE_BOOL_CONFIG_OPTION(rewriteDump, QML_REWRITE_DUMP);
namespace QQmlRewrite {
+static void rewriteStringLiteral(AST::StringLiteral *ast, const QString *code, int startPosition, TextWriter *writer)
+{
+ const unsigned position = ast->firstSourceLocation().begin() - startPosition + 1;
+ const unsigned length = ast->literalToken.length - 2;
+ const QStringRef spell = code->midRef(position, length);
+ const int end = spell.size();
+ int index = 0;
+
+ while (index < end) {
+ const QChar ch = spell.at(index++);
+
+ if (index < end && ch == QLatin1Char('\\')) {
+ int pos = index;
+
+ // skip a possibly empty sequence of \r characters
+ while (pos < end && spell.at(pos) == QLatin1Char('\r'))
+ ++pos;
+
+ if (pos < end && spell.at(pos) == QLatin1Char('\n')) {
+ // This is a `\' followed by a newline terminator.
+ // In this case there's nothing to replace. We keep the code
+ // as it is and we resume the searching.
+ index = pos + 1; // refresh the index
+ }
+ } else if (ch == QLatin1Char('\r') || ch == QLatin1Char('\n')) {
+ const QString sep = ch == QLatin1Char('\r') ? QLatin1String("\\r") : QLatin1String("\\n");
+ const int pos = index - 1;
+ QString s = sep;
+
+ while (index < end && spell.at(index) == ch) {
+ s += sep;
+ ++index;
+ }
+
+ writer->replace(position + pos, index - pos, s);
+ }
+ }
+}
+
bool SharedBindingTester::isSharable(const QString &code)
{
Engine engine;
@@ -204,40 +243,7 @@ bool RewriteBinding::visit(AST::ExpressionStatement *ast)
bool RewriteBinding::visit(AST::StringLiteral *ast)
{
- /* When rewriting the code for bindings, we have to remove ILLEGAL JS tokens like newlines.
- They're still in multi-line strings, because the QML parser allows them, but we have to
- rewrite them to be JS compliant.
-
- For performance reasons, we don't go for total correctness. \r is only replaced if a
- \n was found (since most line endings are \n or \r\n) and QChar::LineSeparator is not
- even considered. QTBUG-24064.
-
- Note that rewriteSignalHandler has a function just like this one, for the same reason.
- */
-
- unsigned startOfString = ast->firstSourceLocation().begin() + 1 - _position;
- unsigned stringLength = ast->firstSourceLocation().length - 2;
-
- int lastIndex = -1;
- bool foundNewLine = false;
- QStringRef subStr(_code, startOfString, stringLength);
- while (true) {
- lastIndex = subStr.indexOf(QLatin1Char('\n'), lastIndex + 1);
- if (lastIndex == -1)
- break;
- foundNewLine = true;
- _writer->replace(startOfString+lastIndex, 1, QLatin1String("\\n"));
- }
-
- if (foundNewLine) {
- while (true) {
- lastIndex = subStr.indexOf(QLatin1Char('\r'), lastIndex + 1);
- if (lastIndex == -1)
- break;
- _writer->replace(startOfString+lastIndex, 1, QLatin1String("\\r"));
- }
- }
-
+ rewriteStringLiteral(ast, _code, _position, _writer);
return false;
}
@@ -361,6 +367,13 @@ void RewriteBinding::rewriteCaseStatements(AST::StatementList *statements, bool
}
}
+RewriteSignalHandler::RewriteSignalHandler()
+ : _writer(0)
+ , _code(0)
+ , _position(0)
+{
+}
+
void RewriteSignalHandler::accept(AST::Node *node)
{
AST::Node::acceptChild(node, this);
@@ -368,42 +381,10 @@ void RewriteSignalHandler::accept(AST::Node *node)
bool RewriteSignalHandler::visit(AST::StringLiteral *ast)
{
- unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position;
- _strStarts << startOfExpressionStatement + 1;
- _strLens << ast->firstSourceLocation().length - 2;
-
+ rewriteStringLiteral(ast, _code, _position, _writer);
return false;
}
-void RewriteSignalHandler::rewriteMultilineStrings(QString &code)
-{
- QList<int> replaceR, replaceN;
- for (int i=0; i < _strStarts.count(); i++) {
- QStringRef curSubstr = QStringRef(&code, _strStarts[i], _strLens[i]);
- int lastIndex = -1;
- while (true) {
- lastIndex = curSubstr.indexOf(QLatin1Char('\n'), lastIndex + 1);
- if (lastIndex == -1)
- break;
- replaceN << _strStarts[i]+lastIndex;
- }
-
- if (replaceN.count()) {
- while (true) {
- lastIndex = curSubstr.indexOf(QLatin1Char('\r'), lastIndex + 1);
- if (lastIndex == -1)
- break;
- replaceR << _strStarts[i]+lastIndex;
- }
- }
- }
- for (int ii = replaceN.count() - 1; ii >= 0; ii--)
- code.replace(replaceN[ii], 1, QLatin1String("\\n"));
- if (replaceR.count())
- for (int ii = replaceR.count() - 1; ii >= 0; ii--)
- code.replace(replaceR[ii], 1, QLatin1String("\\r"));
-}
-
QString RewriteSignalHandler::operator()(QQmlJS::AST::Node *node, const QString &code, const QString &name)
{
if (rewriteDump()) {
@@ -417,13 +398,15 @@ QString RewriteSignalHandler::operator()(QQmlJS::AST::Node *node, const QString
if (!expression && !statement)
return code;
- _strStarts.clear();
- _strLens.clear();
+ TextWriter w;
+ _writer = &w;
+ _code = &code;
+
_position = expression ? expression->firstSourceLocation().begin() : statement->firstSourceLocation().begin();
accept(node);
QString rewritten = code;
- rewriteMultilineStrings(rewritten);
+ w.write(&rewritten);
rewritten = QStringLiteral("(function ") + name + QStringLiteral("() { ") + rewritten + QStringLiteral(" })");
diff --git a/src/qml/qml/qqmlrewrite_p.h b/src/qml/qml/qqmlrewrite_p.h
index e915d797df..1d69839878 100644
--- a/src/qml/qml/qqmlrewrite_p.h
+++ b/src/qml/qml/qqmlrewrite_p.h
@@ -126,11 +126,12 @@ private:
class RewriteSignalHandler: protected AST::Visitor
{
- QList<int> _strStarts;
- QList<int> _strLens;
+ TextWriter *_writer;
+ const QString *_code;
int _position;
public:
+ RewriteSignalHandler();
QString operator()(QQmlJS::AST::Node *node, const QString &code, const QString &name);
protected:
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index cde2885f0c..5cbb2f6943 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1578,13 +1578,12 @@ void QQmlTypeData::downloadProgressChanged(qreal p)
void QQmlTypeData::compile()
{
Q_ASSERT(m_compiledData == 0);
- QQmlProfilerService::startRange(QQmlProfilerService::Compiling);
m_compiledData = new QQmlCompiledData(typeLoader()->engine());
m_compiledData->url = finalUrl();
m_compiledData->name = finalUrlString();
- QQmlProfilerService::rangeLocation(QQmlProfilerService::Compiling, QUrl(m_compiledData->name),1,1);
- QQmlProfilerService::rangeData(QQmlProfilerService::Compiling, m_compiledData->name);
+
+ QQmlCompilingProfiler prof(m_compiledData->name);
QQmlCompiler compiler(&scriptParser._pool);
if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
@@ -1592,7 +1591,6 @@ void QQmlTypeData::compile()
m_compiledData->release();
m_compiledData = 0;
}
- QQmlProfilerService::endRange(QQmlProfilerService::Compiling);
}
void QQmlTypeData::resolveTypes()
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 8c8d4d079e..844f2cc98b 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -97,7 +97,7 @@ public:
class Interrupt {
public:
inline Interrupt();
- inline Interrupt(bool *runWhile);
+ inline Interrupt(volatile bool *runWhile, int nsecs=0);
inline Interrupt(int nsecs);
inline void reset();
@@ -105,13 +105,11 @@ public:
private:
enum Mode { None, Time, Flag };
Mode mode;
- union {
- struct {
- QElapsedTimer timer;
- int nsecs;
- };
- bool *runWhile;
+ struct {
+ QElapsedTimer timer;
+ int nsecs;
};
+ volatile bool *runWhile;
};
QQmlVME() : data(0), componentAttached(0) {}
@@ -202,23 +200,23 @@ private:
};
QQmlVME::Interrupt::Interrupt()
-: mode(None)
+ : mode(None), nsecs(0), runWhile(0)
{
}
-QQmlVME::Interrupt::Interrupt(bool *runWhile)
-: mode(Flag), runWhile(runWhile)
+QQmlVME::Interrupt::Interrupt(volatile bool *runWhile, int nsecs)
+ : mode(Flag), nsecs(nsecs), runWhile(runWhile)
{
}
QQmlVME::Interrupt::Interrupt(int nsecs)
-: mode(Time), nsecs(nsecs)
+ : mode(Time), nsecs(nsecs), runWhile(0)
{
}
void QQmlVME::Interrupt::reset()
{
- if (mode == Time)
+ if (mode == Time || nsecs)
timer.start();
}
@@ -229,7 +227,7 @@ bool QQmlVME::Interrupt::shouldInterrupt() const
} else if (mode == Time) {
return timer.nsecsElapsed() > nsecs;
} else if (mode == Flag) {
- return !*runWhile;
+ return !*runWhile || (nsecs && timer.nsecsElapsed() > nsecs);
} else {
return false;
}
diff --git a/src/qml/qml/qquickworkerscript.cpp b/src/qml/qml/qquickworkerscript.cpp
index f91aa28509..529f181e7a 100644
--- a/src/qml/qml/qquickworkerscript.cpp
+++ b/src/qml/qml/qquickworkerscript.cpp
@@ -202,7 +202,7 @@ QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
{
- initDeclarativeGlobalObject();
+ initQmlGlobalObject();
#define CALL_ONMESSAGE_SCRIPT \
"(function(object, message) { "\
"var isfunction = false; "\
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index c03292d74d..4fd84945fc 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -50,6 +50,7 @@
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlmetatype_p.h>
#include <private/qqmltrace_p.h>
+#include <private/qqmlstringconverters_p.h>
#include <QtQml/qqmlinfo.h>
#include <QtCore/qnumeric.h>
@@ -86,9 +87,11 @@ struct Register {
QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
QString *getstringptr() { return (QString *)typeDataPtr(); }
QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
+ QColor *getcolorptr() { return (QColor *)typeDataPtr(); }
const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
const QString *getstringptr() const { return (QString *)typeDataPtr(); }
const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
+ const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); }
void *typeDataPtr() { return (void *)&data; }
void *typeMemory() { return (void *)data; }
@@ -112,6 +115,7 @@ struct Register {
inline void cleanup();
inline void cleanupString();
inline void cleanupUrl();
+ inline void cleanupColor();
inline void cleanupVariant();
inline void copy(const Register &other);
@@ -135,6 +139,8 @@ void Register::cleanup()
getstringptr()->~QString();
} else if (dataType == QUrlType) {
geturlptr()->~QUrl();
+ } else if (dataType == QColorType) {
+ getcolorptr()->~QColor();
} else if (dataType == QVariantType) {
getvariantptr()->~QVariant();
}
@@ -154,6 +160,12 @@ void Register::cleanupUrl()
setUndefined();
}
+void Register::cleanupColor()
+{
+ getcolorptr()->~QColor();
+ setUndefined();
+}
+
void Register::cleanupVariant()
{
getvariantptr()->~QVariant();
@@ -168,6 +180,8 @@ void Register::copy(const Register &other)
new (getstringptr()) QString(*other.getstringptr());
else if (other.dataType == QUrlType)
new (geturlptr()) QUrl(*other.geturlptr());
+ else if (other.dataType == QColorType)
+ new (getcolorptr()) QColor(*other.getcolorptr());
else if (other.dataType == QVariantType)
new (getvariantptr()) QVariant(*other.getvariantptr());
}
@@ -181,6 +195,8 @@ void Register::init(Type type)
new (getstringptr()) QString();
else if (dataType == QUrlType)
new (geturlptr()) QUrl();
+ else if (dataType == QColorType)
+ new (getcolorptr()) QColor();
else if (dataType == QVariantType)
new (getvariantptr()) QVariant();
}
@@ -256,7 +272,8 @@ void QV4Bindings::Binding::destroy()
int QV4Bindings::Binding::propertyIndex() const
{
- return property;
+ //mask out the type information set for value types
+ return property & 0xFF00FFFF;
}
QObject *QV4Bindings::Binding::object() const
@@ -662,6 +679,11 @@ inline quint32 QV4Bindings::toUint32(qreal n)
MARK_REGISTER(reg); \
}
+#define COLOR_REGISTER(reg) { \
+ registers[(reg)].settype(QColorType); \
+ MARK_REGISTER(reg); \
+}
+
#define VARIANT_REGISTER(reg) { \
registers[(reg)].settype(QVariantType); \
MARK_REGISTER(reg); \
@@ -1022,6 +1044,27 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertStringToColor, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QString tmp(*src.getstringptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupString();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ QColor *colorPtr = output.getcolorptr();
+ new (colorPtr) QColor(QQmlStringConverters::colorFromString(tmp));
+
+ COLOR_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1059,6 +1102,40 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertUrlToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ // for compatibility with color behavior in v8, always true
+ output.setbool(true);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToBool, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertColorToString, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QColor tmp(*src.getcolorptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupColor();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ // to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
+ new (output.getstringptr()) QString(QVariant(tmp).toString());
+ STRING_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToString, unaryop)
+
QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
{
const Register &src = registers[instr->unaryop.src];
diff --git a/src/qml/qml/v4/qv4bindings_p.h b/src/qml/qml/v4/qv4bindings_p.h
index 61d29a6f57..1824fa4ee9 100644
--- a/src/qml/qml/v4/qv4bindings_p.h
+++ b/src/qml/qml/v4/qv4bindings_p.h
@@ -96,6 +96,8 @@ private:
int index:30;
bool enabled:1;
bool updating:1;
+ // Encoding of property is coreIndex | (propType << 16) | (valueTypeIndex << 24)
+ // propType and valueTypeIndex are only set if the property is a value type property
int property;
QObject *scope;
int line;
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index d61fd580c7..f8fe3b4b57 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -63,7 +63,7 @@ static bool qmlEnableV4 = true;
using namespace QQmlJS;
QV4CompilerPrivate::QV4CompilerPrivate()
-: _function(0) , _block(0) , _discarded(false)
+ : _function(0) , _block(0) , _discarded(false), registerCount(0)
{
}
@@ -75,6 +75,7 @@ void QV4CompilerPrivate::trace(int line, int column)
bytecode.clear();
this->currentReg = _function->tempCount;
+ this->registerCount = qMax(this->registerCount, this->currentReg);
foreach (IR::BasicBlock *bb, _function->basicBlocks) {
if (! bb->isTerminated() && (bb->index + 1) < _function->basicBlocks.size())
@@ -344,6 +345,9 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
case QMetaType::QUrl:
regType = QUrlType;
break;
+ case QMetaType::QColor:
+ regType = QColorType;
+ break;
default:
if (propTy == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
@@ -581,6 +585,12 @@ void QV4CompilerPrivate::convertToBool(IR::Expr *expr, int reg)
gen(i);
} return;
+ case IR::ColorType: {
+ Instr::ConvertColorToBool i;
+ i.output = i.src = reg;
+ gen(i);
+ } return;
+
default:
discard();
break;
@@ -880,6 +890,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::RealType: opcode = V4Instr::ConvertRealToBool; break;
case IR::StringType: opcode = V4Instr::ConvertStringToBool; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToBool; break;
default: break;
} // switch
} else if (targetTy == IR::IntType) {
@@ -908,6 +919,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::IntType: opcode = V4Instr::ConvertIntToString; break;
case IR::RealType: opcode = V4Instr::ConvertRealToString; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToString; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToString; break;
default: break;
} // switch
} else if (targetTy == IR::UrlType) {
@@ -920,11 +932,17 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::BoolType: gen(V4Instr::ConvertBoolToString, convToString); sourceTy = IR::StringType; break;
case IR::IntType: gen(V4Instr::ConvertIntToString, convToString); sourceTy = IR::StringType; break;
case IR::RealType: gen(V4Instr::ConvertRealToString, convToString); sourceTy = IR::StringType; break;
+ case IR::ColorType: gen(V4Instr::ConvertColorToString, convToString); sourceTy = IR::StringType; break;
default: break;
} // switch
if (sourceTy == IR::StringType)
opcode = V4Instr::ConvertStringToUrl;
+ } else if (targetTy == IR::ColorType) {
+ switch (sourceTy) {
+ case IR::StringType: opcode = V4Instr::ConvertStringToColor; break;
+ default: break;
+ } // switch
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
@@ -989,6 +1007,9 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
case IR::UrlType:
test.regType = QMetaType::QUrl;
break;
+ case IR::ColorType:
+ test.regType = QMetaType::QColor;
+ break;
case IR::SGAnchorLineType:
test.regType = QQmlMetaType::QQuickAnchorLineMetaTypeId();
break;
@@ -1119,7 +1140,7 @@ bool QV4CompilerPrivate::compile(QQmlJS::AST::Node *node)
qerr << endl;
}
- if (discarded || subscriptionIds.count() > 0xFFFF || registeredStrings.count() > 0xFFFF)
+ if (discarded || subscriptionIds.count() > 0xFFFF || registeredStrings.count() > 0xFFFF || registerCount > 31)
return false;
return true;
diff --git a/src/qml/qml/v4/qv4compiler_p_p.h b/src/qml/qml/v4/qv4compiler_p_p.h
index 4b74a1d1c5..a9209d978f 100644
--- a/src/qml/qml/v4/qv4compiler_p_p.h
+++ b/src/qml/qml/v4/qv4compiler_p_p.h
@@ -231,6 +231,7 @@ private:
void discard() { _discarded = true; }
bool _discarded;
quint8 currentReg;
+ quint8 registerCount;
bool usedSubscriptionIdsChanged;
quint32 currentBlockMask;
diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp
index 08b2570747..efbd2b2c1c 100644
--- a/src/qml/qml/v4/qv4instruction.cpp
+++ b/src/qml/qml/v4/qv4instruction.cpp
@@ -171,12 +171,21 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertStringToUrl:
INSTR_DUMP << "\t" << "ConvertStringToUrl" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertStringToColor:
+ INSTR_DUMP << "\t" << "ConvertStringToColor" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertUrlToBool:
INSTR_DUMP << "\t" << "ConvertUrlToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertUrlToString:
INSTR_DUMP << "\t" << "ConvertUrlToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertColorToBool:
+ INSTR_DUMP << "\t" << "ConvertColorToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertColorToString:
+ INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index 8150eedf54..964c95513f 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -92,8 +92,11 @@ QT_BEGIN_NAMESPACE
F(ConvertStringToInt, unaryop) \
F(ConvertStringToReal, unaryop) \
F(ConvertStringToUrl, unaryop) \
+ F(ConvertStringToColor, unaryop) \
F(ConvertUrlToBool, unaryop) \
F(ConvertUrlToString, unaryop) \
+ F(ConvertColorToBool, unaryop) \
+ F(ConvertColorToString, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinReal, unaryop) \
F(MathCosReal, unaryop) \
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index be822145a4..3b33898cd1 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -59,6 +59,7 @@ inline const char *typeName(Type t)
case VoidType: return "void";
case StringType: return "string";
case UrlType: return "url";
+ case ColorType: return "color";
case SGAnchorLineType: return "SGAnchorLine";
case AttachType: return "AttachType";
case ObjectType: return "object";
@@ -77,7 +78,7 @@ inline bool isNumberType(IR::Type ty)
inline bool isStringType(IR::Type ty)
{
- return ty == IR::StringType || ty == IR::UrlType;
+ return ty == IR::StringType || ty == IR::UrlType || ty == IR::ColorType;
}
IR::Type maxType(IR::Type left, IR::Type right)
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 48a08adf9f..e80c7e2869 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -142,6 +142,7 @@ enum Type {
VoidType,
StringType,
UrlType,
+ ColorType,
SGAnchorLineType,
AttachType,
ObjectType,
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 1956be8e72..0efb2686df 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -70,6 +70,9 @@ static IR::Type irTypeFromVariantType(int t, QQmlEnginePrivate *engine, const QM
case QMetaType::QUrl:
return IR::UrlType;
+ case QMetaType::QColor:
+ return IR::ColorType;
+
default:
if (t == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
return IR::SGAnchorLineType;
@@ -438,7 +441,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
QQmlPropertyData *data = cache->property(name);
- if (data && data->revision != 0) {
+ if (data && data->hasRevision()) {
if (qmlVerboseCompiler())
qWarning() << "*** versioned symbol:" << name;
discard();
@@ -459,7 +462,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
QQmlPropertyData *data = cache->property(name);
- if (data && data->revision != 0) {
+ if (data && data->hasRevision()) {
if (qmlVerboseCompiler())
qWarning() << "*** versioned symbol:" << name;
discard();
@@ -610,7 +613,7 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
if (!data || data->isFunction())
return false; // Don't support methods (or non-existing properties ;)
- if (data->revision != 0) {
+ if (data->hasRevision()) {
if (qmlVerboseCompiler())
qWarning() << "*** versioned symbol:" << name;
discard();
diff --git a/src/qml/qml/v4/qv4program_p.h b/src/qml/qml/v4/qv4program_p.h
index b6b03e438b..d23cc6192f 100644
--- a/src/qml/qml/v4/qv4program_p.h
+++ b/src/qml/qml/v4/qv4program_p.h
@@ -96,6 +96,7 @@ enum QQmlRegisterType {
QStringType = FirstCleanupType,
QUrlType,
QVariantType,
+ QColorType
};
const char *QV4Program::data() const
diff --git a/src/qml/qml/v8/qjsconverter_p.h b/src/qml/qml/v8/qjsconverter_p.h
index 29fef3c700..d85f9aa0cf 100644
--- a/src/qml/qml/v8/qjsconverter_p.h
+++ b/src/qml/qml/v8/qjsconverter_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qjsengine.h b/src/qml/qml/v8/qjsengine.h
index 1521c752d4..fa2584bf81 100644
--- a/src/qml/qml/v8/qjsengine.h
+++ b/src/qml/qml/v8/qjsengine.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qjsengine_p.h b/src/qml/qml/v8/qjsengine_p.h
index ecd5f7cc86..9866aa84b9 100644
--- a/src/qml/qml/v8/qjsengine_p.h
+++ b/src/qml/qml/v8/qjsengine_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
-**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qjsvalue.h b/src/qml/qml/v8/qjsvalue.h
index 30ea2e7345..209090ed47 100644
--- a/src/qml/qml/v8/qjsvalue.h
+++ b/src/qml/qml/v8/qjsvalue.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
@@ -25,7 +43,6 @@
#define QJSVALUE_H
#include <QtQml/qtqmlglobal.h>
-
#include <QtCore/qstring.h>
#include <QtCore/qlist.h>
#include <QtCore/qsharedpointer.h>
@@ -69,7 +86,7 @@ public:
QJSValue(const QString &value);
QJSValue(const QLatin1String &value);
#ifndef QT_NO_CAST_FROM_ASCII
- QT_ASCII_CAST_WARN_CONSTRUCTOR QJSValue(const char *str);
+ QT_ASCII_CAST_WARN QJSValue(const char *str);
#endif
QJSValue &operator=(const QJSValue &other);
diff --git a/src/qml/qml/v8/qjsvalue_impl_p.h b/src/qml/qml/v8/qjsvalue_impl_p.h
index cd33859c50..fbddcfa5ba 100644
--- a/src/qml/qml/v8/qjsvalue_impl_p.h
+++ b/src/qml/qml/v8/qjsvalue_impl_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qjsvalue_p.h b/src/qml/qml/v8/qjsvalue_p.h
index 3eccba64bd..acfe958cb6 100644
--- a/src/qml/qml/v8/qjsvalue_p.h
+++ b/src/qml/qml/v8/qjsvalue_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qjsvalueiterator.h b/src/qml/qml/v8/qjsvalueiterator.h
index c47f07d43b..3c1b450dd8 100644
--- a/src/qml/qml/v8/qjsvalueiterator.h
+++ b/src/qml/qml/v8/qjsvalueiterator.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
@@ -24,6 +42,7 @@
#ifndef QSCRIPTVALUEITERATOR_H
#define QSCRIPTVALUEITERATOR_H
+#include <QtQml/qtqmlglobal.h>
#include <QtQml/qjsvalue.h>
#include <QtCore/qscopedpointer.h>
diff --git a/src/qml/qml/v8/qjsvalueiterator_impl_p.h b/src/qml/qml/v8/qjsvalueiterator_impl_p.h
index 131296ecac..2c060b21a7 100644
--- a/src/qml/qml/v8/qjsvalueiterator_impl_p.h
+++ b/src/qml/qml/v8/qjsvalueiterator_impl_p.h
@@ -5,17 +5,35 @@
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qjsvalueiterator_p.h b/src/qml/qml/v8/qjsvalueiterator_p.h
index 2a5bcdec22..f5f4c44441 100644
--- a/src/qml/qml/v8/qjsvalueiterator_p.h
+++ b/src/qml/qml/v8/qjsvalueiterator_p.h
@@ -5,17 +5,35 @@
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 5284832ae1..7d7aaa2148 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1096,8 +1096,17 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
V8THROW_ERROR("Qt.createQmlObject(): Component is not ready");
QObject *obj = component.beginCreate(effectiveContext);
- if (obj)
+ if (obj) {
QQmlData::get(obj, true)->setImplicitDestructible();
+
+ obj->setParent(parentArg);
+
+ QList<QQmlPrivate::AutoParentFunction> functions = QQmlMetaType::parentFunctions();
+ for (int ii = 0; ii < functions.count(); ++ii) {
+ if (QQmlPrivate::Parented == functions.at(ii)(obj, parentArg))
+ break;
+ }
+ }
component.completeCreate();
if (component.isError()) {
@@ -1107,14 +1116,6 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
Q_ASSERT(obj);
- obj->setParent(parentArg);
-
- QList<QQmlPrivate::AutoParentFunction> functions = QQmlMetaType::parentFunctions();
- for (int ii = 0; ii < functions.count(); ++ii) {
- if (QQmlPrivate::Parented == functions.at(ii)(obj, parentArg))
- break;
- }
-
return v8engine->newQObject(obj);
}
diff --git a/src/qml/qml/v8/qscript_impl_p.h b/src/qml/qml/v8/qscript_impl_p.h
index fdbf2f0097..d4acc4502a 100644
--- a/src/qml/qml/v8/qscript_impl_p.h
+++ b/src/qml/qml/v8/qscript_impl_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
-**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qscriptisolate_p.h b/src/qml/qml/v8/qscriptisolate_p.h
index 4afa74756f..77848557a4 100644
--- a/src/qml/qml/v8/qscriptisolate_p.h
+++ b/src/qml/qml/v8/qscriptisolate_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qscriptoriginalglobalobject_p.h b/src/qml/qml/v8/qscriptoriginalglobalobject_p.h
index 12321cc71a..e4661c1bf2 100644
--- a/src/qml/qml/v8/qscriptoriginalglobalobject_p.h
+++ b/src/qml/qml/v8/qscriptoriginalglobalobject_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qscriptshareddata_p.h b/src/qml/qml/v8/qscriptshareddata_p.h
index df95b26206..d3491c70ee 100644
--- a/src/qml/qml/v8/qscriptshareddata_p.h
+++ b/src/qml/qml/v8/qscriptshareddata_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qscripttools_p.h b/src/qml/qml/v8/qscripttools_p.h
index fcea205f61..d69e9c83ad 100644
--- a/src/qml/qml/v8/qscripttools_p.h
+++ b/src/qml/qml/v8/qscripttools_p.h
@@ -3,19 +3,37 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtScript module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 4c2cce1525..8e8223fea1 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -75,12 +75,14 @@ static bool ObjectComparisonCallback(v8::Local<v8::Object> lhs, v8::Local<v8::Ob
if (lhs == rhs)
return true;
+ if (lhs.IsEmpty() || rhs.IsEmpty())
+ return false;
+
QV8ObjectResource *lhsr = static_cast<QV8ObjectResource*>(lhs->GetExternalResource());
QV8ObjectResource *rhsr = static_cast<QV8ObjectResource*>(rhs->GetExternalResource());
- Q_ASSERT(lhsr->engine == rhsr->engine);
-
if (lhsr && rhsr) {
+ Q_ASSERT(lhsr->engine == rhsr->engine);
QV8ObjectResource::ResourceType lhst = lhsr->resourceType();
QV8ObjectResource::ResourceType rhst = rhsr->resourceType();
@@ -874,7 +876,7 @@ void QV8Engine::ensurePerThreadIsolate()
perThreadEngineData.setLocalData(new ThreadData);
}
-void QV8Engine::initDeclarativeGlobalObject()
+void QV8Engine::initQmlGlobalObject()
{
v8::HandleScope handels;
v8::Context::Scope contextScope(m_context);
@@ -885,7 +887,7 @@ void QV8Engine::initDeclarativeGlobalObject()
void QV8Engine::setEngine(QQmlEngine *engine)
{
m_engine = engine;
- initDeclarativeGlobalObject();
+ initQmlGlobalObject();
}
void QV8Engine::setException(v8::Handle<v8::Value> value, v8::Handle<v8::Message> msg)
diff --git a/src/qml/qml/v8/qv8engine_impl_p.h b/src/qml/qml/v8/qv8engine_impl_p.h
index ebb21f851c..7173ae4c01 100644
--- a/src/qml/qml/v8/qv8engine_impl_p.h
+++ b/src/qml/qml/v8/qv8engine_impl_p.h
@@ -5,17 +5,35 @@
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL-ONLY$
+** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
-** 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.
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
**
-** If you have questions regarding the use of this file, please contact
-** us via http://www.qt-project.org/.
**
** $QT_END_LICENSE$
**
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 22a8d7599f..bc57b27085 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -283,7 +283,7 @@ public:
inline void pop();
};
- void initDeclarativeGlobalObject();
+ void initQmlGlobalObject();
void setEngine(QQmlEngine *engine);
QQmlEngine *engine() { return m_engine; }
v8::Local<v8::Object> global() { return m_context->Global(); }
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp
index b84ae339be..78b2cb719c 100644
--- a/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp
@@ -513,7 +513,7 @@ v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject
if (!result)
return v8::Handle<v8::Value>();
- if (revisionMode == QV8QObjectWrapper::CheckRevision && result->revision != 0) {
+ if (revisionMode == QV8QObjectWrapper::CheckRevision && result->hasRevision()) {
QQmlData *ddata = QQmlData::get(object);
if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result))
return v8::Handle<v8::Value>();
@@ -673,7 +673,7 @@ bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, const QH
if (!result)
return false;
- if (revisionMode == QV8QObjectWrapper::CheckRevision && result->revision != 0) {
+ if (revisionMode == QV8QObjectWrapper::CheckRevision && result->hasRevision()) {
QQmlData *ddata = QQmlData::get(object);
if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result))
return false;
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index 9a3b24c328..b8b4e1104c 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -65,12 +65,14 @@ HEADERS += \
$$PWD/qquickimplicitsizeitem_p_p.h \
$$PWD/qquickspriteengine_p.h \
$$PWD/qquicksprite_p.h \
- $$PWD/qquickspriteimage_p.h \
+ $$PWD/qquickspritesequence_p.h \
+ $$PWD/qquickanimatedsprite_p.h \
$$PWD/qquickdrag_p.h \
$$PWD/qquickdroparea_p.h \
$$PWD/qquickmultipointtoucharea_p.h \
$$PWD/qquickitemview_p.h \
$$PWD/qquickitemview_p_p.h \
+ $$PWD/qquickitemviewtransition_p.h \
$$PWD/qquickscreen_p.h \
$$PWD/qquickwindowmodule_p.h \
$$PWD/qquickwindowmanager_p.h
@@ -116,12 +118,14 @@ SOURCES += \
$$PWD/qquickimplicitsizeitem.cpp \
$$PWD/qquickspriteengine.cpp \
$$PWD/qquicksprite.cpp \
- $$PWD/qquickspriteimage.cpp \
+ $$PWD/qquickspritesequence.cpp \
+ $$PWD/qquickanimatedsprite.cpp \
$$PWD/qquickaccessibleattached.cpp \
$$PWD/qquickdrag.cpp \
$$PWD/qquickdroparea.cpp \
$$PWD/qquickmultipointtoucharea.cpp \
$$PWD/qquickitemview.cpp \
+ $$PWD/qquickitemviewtransition.cpp \
$$PWD/qquickwindowmodule.cpp \
$$PWD/qquickscreen.cpp \
$$PWD/qquickwindowmanager.cpp
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
new file mode 100644
index 0000000000..618178fd1c
--- /dev/null
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -0,0 +1,613 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickanimatedsprite_p.h"
+#include "qquicksprite_p.h"
+#include "qquickspriteengine_p.h"
+#include <QtQuick/private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+#include <QtQuick/qsgnode.h>
+#include <QtQuick/qsgengine.h>
+#include <QtQuick/qsgtexturematerial.h>
+#include <QtQuick/qsgtexture.h>
+#include <QtQuick/qquickcanvas.h>
+#include <QtQml/qqmlinfo.h>
+#include <QFile>
+#include <cmath>
+#include <qmath.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static const char vertexShaderCode[] =
+ "attribute highp vec2 vTex;\n"
+ "uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress\n"
+ "uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)\n"
+ "uniform highp vec2 size;//w,h of element\n"
+ "\n"
+ "uniform highp mat4 qt_Matrix;\n"
+ "\n"
+ "varying highp vec4 fTexS;\n"
+ "varying lowp float progress;\n"
+ "\n"
+ "\n"
+ "void main() {\n"
+ " progress = animData.z;\n"
+ " //Calculate frame location in texture\n"
+ " fTexS.xy = animPos.xy + vTex.xy * animData.xy;\n"
+ " //Next frame is also passed, for interpolation\n"
+ " fTexS.zw = animPos.zw + vTex.xy * animData.xy;\n"
+ "\n"
+ " gl_Position = qt_Matrix * vec4(size.x * vTex.x, size.y * vTex.y, 0, 1);\n"
+ "}\n";
+
+static const char fragmentShaderCode[] =
+ "uniform sampler2D texture;\n"
+ "uniform lowp float qt_Opacity;\n"
+ "\n"
+ "varying highp vec4 fTexS;\n"
+ "varying lowp float progress;\n"
+ "\n"
+ "void main() {\n"
+ " gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), progress) * qt_Opacity;\n"
+ "}\n";
+
+class QQuickAnimatedSpriteMaterial : public QSGMaterial
+{
+public:
+ QQuickAnimatedSpriteMaterial();
+ ~QQuickAnimatedSpriteMaterial();
+ virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
+ virtual QSGMaterialShader *createShader() const;
+ virtual int compare(const QSGMaterial *other) const
+ {
+ return this - static_cast<const QQuickAnimatedSpriteMaterial *>(other);
+ }
+
+ QSGTexture *texture;
+
+ float animT;
+ float animX1;
+ float animY1;
+ float animX2;
+ float animY2;
+ float animW;
+ float animH;
+ float elementWidth;
+ float elementHeight;
+};
+
+QQuickAnimatedSpriteMaterial::QQuickAnimatedSpriteMaterial()
+ : texture(0)
+ , animT(0.0f)
+ , animX1(0.0f)
+ , animY1(0.0f)
+ , animX2(0.0f)
+ , animY2(0.0f)
+ , animW(1.0f)
+ , animH(1.0f)
+ , elementWidth(1.0f)
+ , elementHeight(1.0f)
+{
+ setFlag(Blending, true);
+}
+
+QQuickAnimatedSpriteMaterial::~QQuickAnimatedSpriteMaterial()
+{
+ delete texture;
+}
+
+class AnimatedSpriteMaterialData : public QSGMaterialShader
+{
+public:
+ AnimatedSpriteMaterialData(const char * /* vertexFile */ = 0, const char * /* fragmentFile */ = 0)
+ {
+ }
+
+ void deactivate() {
+ QSGMaterialShader::deactivate();
+
+ for (int i=0; i<8; ++i) {
+ program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+ }
+ }
+
+ virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
+ {
+ QQuickAnimatedSpriteMaterial *m = static_cast<QQuickAnimatedSpriteMaterial *>(newEffect);
+ m->texture->bind();
+
+ program()->setUniformValue(m_opacity_id, state.opacity());
+ program()->setUniformValue(m_animData_id, m->animW, m->animH, m->animT);
+ program()->setUniformValue(m_animPos_id, m->animX1, m->animY1, m->animX2, m->animY2);
+ program()->setUniformValue(m_size_id, m->elementWidth, m->elementHeight);
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, state.combinedMatrix());
+ }
+
+ virtual void initialize() {
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
+ m_animData_id = program()->uniformLocation("animData");
+ m_animPos_id = program()->uniformLocation("animPos");
+ m_size_id = program()->uniformLocation("size");
+ }
+
+ virtual const char *vertexShader() const { return vertexShaderCode; }
+ virtual const char *fragmentShader() const { return fragmentShaderCode; }
+
+ virtual char const *const *attributeNames() const {
+ static const char *attr[] = {
+ "vTex",
+ 0
+ };
+ return attr;
+ }
+
+ int m_matrix_id;
+ int m_opacity_id;
+ int m_animData_id;
+ int m_animPos_id;
+ int m_size_id;
+
+ static float chunkOfBytes[1024];
+};
+
+float AnimatedSpriteMaterialData::chunkOfBytes[1024];
+
+QSGMaterialShader *QQuickAnimatedSpriteMaterial::createShader() const
+{
+ return new AnimatedSpriteMaterialData;
+}
+
+struct AnimatedSpriteVertex {
+ float tx;
+ float ty;
+};
+
+struct AnimatedSpriteVertices {
+ AnimatedSpriteVertex v1;
+ AnimatedSpriteVertex v2;
+ AnimatedSpriteVertex v3;
+ AnimatedSpriteVertex v4;
+};
+
+/*!
+ \qmlclass AnimatedSprite QQuickAnimatedSprite
+ \inqmlmodule QtQuick 2
+ \inherits Item
+ \brief The AnimatedSprite element draws a sprite animation
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::AnimatedSprite::running
+
+ Whether the sprite is animating or not.
+
+ Default is true
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::AnimatedSprite::interpolate
+
+ If true, interpolation will occur between sprite frames to make the
+ animation appear smoother.
+
+ Default is true.
+*/
+
+/*!
+ \qmlproperty qreal QtQuick2::AnimatedSprite::frameRate
+
+ Frames per second to show in the animation. Values below 0 are invalid.
+
+ If frameRate is valid then it will be used to calculate the duration of the frames.
+ If not, and frameDuration is valid , then frameDuration will be used.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::frameDuration
+
+ Duration of each frame of the animation. Values below 0 are invalid.
+
+ If frameRate is valid then it will be used to calculate the duration of the frames.
+ If not, and frameDuration is valid, then frameDuration will be used.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::frameCount
+
+ Number of frames in this AnimatedSprite.
+*/
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::frameHeight
+
+ Height of a single frame in this AnimatedSprite.
+
+ May be omitted if it is the only sprite in the file.
+*/
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::frameWidth
+
+ Width of a single frame in this AnimatedSprite.
+
+ May be omitted if it is the only sprite in the file.
+*/
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::frameX
+
+ The X coordinate in the image file of the first frame of the AnimatedSprite.
+
+ May be omitted if the first frame starts in the upper left corner of the file.
+*/
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::frameY
+
+ The Y coordinate in the image file of the first frame of the AnimatedSprite.
+
+ May be omitted if the first frame starts in the upper left corner of the file.
+*/
+/*!
+ \qmlproperty url QtQuick2::AnimatedSprite::source
+
+ The image source for the animation.
+
+ If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
+ Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
+
+ If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::AnimatedSprite::reverse
+
+ If true, then the animation will be played in reverse.
+
+ Default is false.
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::AnimatedSprite::frameSync
+
+ If true, then the animation will have no duration. Instead, the animation will advance
+ one frame each time a frame is rendered to the screen. This syncronizes it with the painting
+ rate as opposed to elapsed time.
+
+ If frameSync is set to true, it overrides both frameRate and frameDuration.
+
+ Default is false.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::loops
+
+ After playing the animation this many times, the animation will automatically stop. Negative values are invalid.
+
+ If this is set to AnimatedSprite.Infinite the animation will not stop playing on its own.
+
+ Default is AnimatedSprite.Infinite
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::AnimatedSprite::paused
+
+ When paused, the current frame can be advanced manually.
+
+ Default is false.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::AnimatedSprite::currentFrame
+
+ When paused, the current frame can be advanced manually by setting this property or calling advance().
+
+*/
+
+//TODO: Implicitly size element to size of sprite
+QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) :
+ QQuickItem(parent)
+ , m_node(0)
+ , m_material(0)
+ , m_sprite(new QQuickSprite)
+ , m_spriteEngine(0)
+ , m_curFrame(0)
+ , m_pleaseReset(false)
+ , m_running(true)
+ , m_paused(false)
+ , m_interpolate(true)
+ , m_loops(-1)
+ , m_curLoop(0)
+ , m_pauseOffset(0)
+{
+ setFlag(ItemHasContents);
+ connect(this, SIGNAL(runningChanged(bool)),
+ this, SLOT(update()));
+}
+
+void QQuickAnimatedSprite::reloadImage()
+{
+ if (!isComponentComplete())
+ return;
+ createEngine();//### It's not as inefficient as it sounds, but it still sucks having to recreate the engine
+}
+
+void QQuickAnimatedSprite::componentComplete()
+{
+ createEngine();
+ QQuickItem::componentComplete();
+ if (m_running)
+ start();
+}
+
+void QQuickAnimatedSprite::start()
+{
+ if (m_running)
+ return;
+ m_curLoop = 0;
+ m_timestamp.start();
+ m_running = true;
+ emit runningChanged(true);
+ update();
+}
+
+void QQuickAnimatedSprite::stop()
+{
+ if (!m_running)
+ return;
+ m_running = false;
+ emit runningChanged(false);
+}
+
+void QQuickAnimatedSprite::advance(int frames)
+{
+ if (!frames)
+ return;
+ //TODO-C: May not work when running - only when paused
+ m_curFrame += frames;
+ while (m_curFrame < 0)
+ m_curFrame += m_sprite->frames();
+ m_curFrame = m_curFrame % m_sprite->frames();
+ emit currentFrameChanged(m_curFrame);
+}
+
+void QQuickAnimatedSprite::pause()
+{
+ if (m_paused)
+ return;
+ m_pauseOffset = m_timestamp.elapsed();
+ m_paused = true;
+ emit pausedChanged(true);
+}
+
+void QQuickAnimatedSprite::resume()
+{
+ if (!m_paused)
+ return;
+ m_pauseOffset = m_pauseOffset - m_timestamp.elapsed();
+ m_paused = false;
+ emit pausedChanged(false);
+}
+
+void QQuickAnimatedSprite::createEngine()
+{
+ if (m_spriteEngine)
+ delete m_spriteEngine;
+ QList<QQuickSprite*> spriteList;
+ spriteList << m_sprite;
+ m_spriteEngine = new QQuickSpriteEngine(QList<QQuickSprite*>(spriteList), this);
+ m_spriteEngine->startAssemblingImage();
+ reset();
+}
+
+static QSGGeometry::Attribute AnimatedSprite_Attributes[] = {
+ QSGGeometry::Attribute::create(0, 2, GL_FLOAT), // tex
+};
+
+static QSGGeometry::AttributeSet AnimatedSprite_AttributeSet =
+{
+ 1, // Attribute Count
+ 2 * sizeof(float),
+ AnimatedSprite_Attributes
+};
+
+QSGGeometryNode* QQuickAnimatedSprite::buildNode()
+{
+ if (!m_spriteEngine) {
+ qmlInfo(this) << "No sprite engine...";
+ return 0;
+ } else if (m_spriteEngine->status() == QQuickPixmap::Null) {
+ m_spriteEngine->startAssemblingImage();
+ update();//Schedule another update, where we will check again
+ return 0;
+ } else if (m_spriteEngine->status() == QQuickPixmap::Loading) {
+ update();//Schedule another update, where we will check again
+ return 0;
+ }
+
+ m_material = new QQuickAnimatedSpriteMaterial();
+
+ QImage image = m_spriteEngine->assembledImage();
+ if (image.isNull())
+ return 0;
+ m_sheetSize = QSizeF(image.size());
+ m_material->texture = canvas()->createTextureFromImage(image);
+ m_material->texture->setFiltering(QSGTexture::Linear);
+ m_spriteEngine->start(0);
+ m_material->animT = 0;
+ m_material->animX1 = m_spriteEngine->spriteX() / m_sheetSize.width();
+ m_material->animY1 = m_spriteEngine->spriteY() / m_sheetSize.height();
+ m_material->animX2 = m_material->animX1;
+ m_material->animY2 = m_material->animY1;
+ m_material->animW = m_spriteEngine->spriteWidth() / m_sheetSize.width();
+ m_material->animH = m_spriteEngine->spriteHeight() / m_sheetSize.height();
+ m_material->elementWidth = width();
+ m_material->elementHeight = height();
+
+ int vCount = 4;
+ int iCount = 6;
+ QSGGeometry *g = new QSGGeometry(AnimatedSprite_AttributeSet, vCount, iCount);
+ g->setDrawingMode(GL_TRIANGLES);
+
+ AnimatedSpriteVertices *p = (AnimatedSpriteVertices *) g->vertexData();
+
+ p->v1.tx = 0;
+ p->v1.ty = 0;
+
+ p->v2.tx = 1.0;
+ p->v2.ty = 0;
+
+ p->v3.tx = 0;
+ p->v3.ty = 1.0;
+
+ p->v4.tx = 1.0;
+ p->v4.ty = 1.0;
+
+ quint16 *indices = g->indexDataAsUShort();
+ indices[0] = 0;
+ indices[1] = 1;
+ indices[2] = 2;
+ indices[3] = 1;
+ indices[4] = 3;
+ indices[5] = 2;
+
+
+ m_timestamp.start();
+ m_node = new QSGGeometryNode();
+ m_node->setGeometry(g);
+ m_node->setMaterial(m_material);
+ m_node->setFlag(QSGGeometryNode::OwnsMaterial);
+ return m_node;
+}
+
+void QQuickAnimatedSprite::reset()
+{
+ m_pleaseReset = true;
+}
+
+QSGNode *QQuickAnimatedSprite::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
+{
+ if (m_pleaseReset) {
+ delete m_node;
+
+ m_node = 0;
+ m_material = 0;
+ m_pleaseReset = false;
+ }
+
+ prepareNextFrame();
+
+ if (m_running) {
+ update();
+ if (m_node)
+ m_node->markDirty(QSGNode::DirtyMaterial);
+ }
+
+ return m_node;
+}
+
+void QQuickAnimatedSprite::prepareNextFrame()
+{
+ if (m_node == 0)
+ m_node = buildNode();
+ if (m_node == 0) //error creating node
+ return;
+
+ uint timeInt = m_timestamp.elapsed() + m_pauseOffset;
+ qreal time = timeInt / 1000.;
+ m_material->elementHeight = height();
+ m_material->elementWidth = width();
+
+ double frameAt; //double just for modf
+ qreal progress;
+ if (!m_paused) {
+ //Advance State (keeps time for psuedostates)
+ m_spriteEngine->updateSprites(timeInt);
+
+ //Advance AnimatedSprite
+ qreal animT = m_spriteEngine->spriteStart()/1000.0;
+ qreal frameCount = m_spriteEngine->spriteFrames();
+ qreal frameDuration = m_spriteEngine->spriteDuration()/frameCount;
+ if (frameDuration > 0) {
+ qreal frame = (time - animT)/(frameDuration / 1000.0);
+ frame = qBound(qreal(0.0), frame, frameCount - qreal(1.0));//Stop at count-1 frames until we have between anim interpolation
+ progress = modf(frame,&frameAt);
+ if (m_curFrame > frameAt) //went around
+ m_curLoop++;
+ m_curFrame = frameAt;
+ } else {
+ m_curFrame++;
+ if (m_curFrame >= frameCount){
+ m_curFrame = 0;
+ m_curLoop++;
+ m_spriteEngine->advance();
+ }
+ frameAt = m_curFrame;
+ progress = 0;
+ }
+ if (m_loops > 0 && m_curLoop >= m_loops) {
+ frameAt = 0;
+ m_running = false;
+ }
+ } else {
+ frameAt = m_curFrame;
+ }
+ if (m_spriteEngine->sprite()->reverse())
+ frameAt = (m_spriteEngine->spriteFrames() - 1) - frameAt;
+ qreal y = m_spriteEngine->spriteY() / m_sheetSize.height();
+ qreal w = m_spriteEngine->spriteWidth() / m_sheetSize.width();
+ qreal h = m_spriteEngine->spriteHeight() / m_sheetSize.height();
+ qreal x1 = m_spriteEngine->spriteX() / m_sheetSize.width();
+ x1 += frameAt * w;
+ qreal x2 = x1;
+ if (frameAt < (m_spriteEngine->spriteFrames()-1))
+ x2 += w;
+
+ m_material->animX1 = x1;
+ m_material->animY1 = y;
+ m_material->animX2 = x2;
+ m_material->animY2 = y;
+ m_material->animW = w;
+ m_material->animH = h;
+ m_material->animT = m_interpolate ? progress : 0.0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
new file mode 100644
index 0000000000..708f94b7ec
--- /dev/null
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKANIMATEDSPRITE_P_H
+#define QQUICKANIMATEDSPRITE_P_H
+
+#include <QtQuick/QQuickItem>
+#include <private/qquicksprite_p.h>
+#include <QTime>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QSGContext;
+class QQuickSprite;
+class QQuickSpriteEngine;
+class QSGGeometryNode;
+class QQuickAnimatedSpriteMaterial;
+class Q_AUTOTEST_EXPORT QQuickAnimatedSprite : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
+ Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate NOTIFY interpolateChanged)
+ //###try to share similar spriteEngines for less overhead?
+ //These properties come out of QQuickSprite, since a SimpleSpriteImage is a renderer for a single sprite
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(bool reverse READ reverse WRITE setReverse NOTIFY reverseChanged)
+ Q_PROPERTY(bool frameSync READ frameSync WRITE setFrameSync NOTIFY frameSyncChanged)
+ Q_PROPERTY(int frameCount READ frameCount WRITE setFrameCount NOTIFY frameCountChanged)
+ //If frame height or width is not specified, it is assumed to be a single long row of square frames.
+ //Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used.
+ Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged)
+ Q_PROPERTY(int frameWidth READ frameWidth WRITE setFrameWidth NOTIFY frameWidthChanged)
+ Q_PROPERTY(int frameX READ frameX WRITE setFrameX NOTIFY frameXChanged)
+ Q_PROPERTY(int frameY READ frameY WRITE setFrameY NOTIFY frameYChanged)
+ //Precedence order: frameRate, frameDuration
+ Q_PROPERTY(qreal frameRate READ frameRate WRITE setFrameRate NOTIFY frameRateChanged RESET resetFrameRate)
+ Q_PROPERTY(int frameDuration READ frameDuration WRITE setFrameDuration NOTIFY frameDurationChanged RESET resetFrameDuration)
+ //Extra Simple Sprite Stuff
+ Q_PROPERTY(int loops READ loops WRITE setLoops NOTIFY loopsChanged)
+ Q_PROPERTY(bool paused READ paused WRITE setPaused NOTIFY pausedChanged)
+ Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY currentFrameChanged)
+
+ Q_ENUMS(LoopParameters)
+public:
+ explicit QQuickAnimatedSprite(QQuickItem *parent = 0);
+ enum LoopParameters {
+ Infinite = -1
+ };
+
+ bool running() const
+ {
+ return m_running;
+ }
+
+ bool interpolate() const
+ {
+ return m_interpolate;
+ }
+
+ QUrl source() const
+ {
+ return m_sprite->source();
+ }
+
+ bool reverse() const
+ {
+ return m_sprite->reverse();
+ }
+
+ bool frameSync() const
+ {
+ return m_sprite->frameSync();
+ }
+
+ int frameCount() const
+ {
+ return m_sprite->frames();
+ }
+
+ int frameHeight() const
+ {
+ return m_sprite->frameHeight();
+ }
+
+ int frameWidth() const
+ {
+ return m_sprite->frameWidth();
+ }
+
+ int frameX() const
+ {
+ return m_sprite->frameX();
+ }
+
+ int frameY() const
+ {
+ return m_sprite->frameY();
+ }
+
+ qreal frameRate() const
+ {
+ return m_sprite->frameRate();
+ }
+
+ int frameDuration() const
+ {
+ return m_sprite->frameDuration();
+ }
+
+ int loops() const
+ {
+ return m_loops;
+ }
+
+ bool paused() const
+ {
+ return m_paused;
+ }
+
+ int currentFrame() const
+ {
+ return m_curFrame;
+ }
+
+signals:
+
+ void pausedChanged(bool arg);
+ void runningChanged(bool arg);
+ void interpolateChanged(bool arg);
+
+ void sourceChanged(QUrl arg);
+
+ void reverseChanged(bool arg);
+
+ void frameSyncChanged(bool arg);
+
+ void frameCountChanged(int arg);
+
+ void frameHeightChanged(int arg);
+
+ void frameWidthChanged(int arg);
+
+ void frameXChanged(int arg);
+
+ void frameYChanged(int arg);
+
+ void frameRateChanged(qreal arg);
+
+ void frameDurationChanged(int arg);
+
+ void loopsChanged(int arg);
+
+ void currentFrameChanged(int arg);
+
+public slots:
+ void start();
+ void stop();
+ void restart() {stop(); start();}
+ void advance(int frames=1);
+ void pause();
+ void resume();
+
+ void setRunning(bool arg)
+ {
+ if (m_running != arg) {
+ if (m_running)
+ stop();
+ else
+ start();
+ }
+ }
+
+ void setPaused(bool arg)
+ {
+ if (m_paused != arg) {
+ if (m_paused)
+ resume();
+ else
+ pause();
+ }
+ }
+
+ void setInterpolate(bool arg)
+ {
+ if (m_interpolate != arg) {
+ m_interpolate = arg;
+ emit interpolateChanged(arg);
+ }
+ }
+
+ void setSource(QUrl arg)
+ {
+ if (m_sprite->m_source != arg) {
+ m_sprite->setSource(arg);
+ emit sourceChanged(arg);
+ }
+ }
+
+ void setReverse(bool arg)
+ {
+ if (m_sprite->m_reverse != arg) {
+ m_sprite->setReverse(arg);
+ emit reverseChanged(arg);
+ }
+ }
+
+ void setFrameSync(bool arg)
+ {
+ if (m_sprite->m_frameSync != arg) {
+ m_sprite->setFrameSync(arg);
+ emit frameSyncChanged(arg);
+ }
+ }
+
+ void setFrameCount(int arg)
+ {
+ if (m_sprite->m_frames != arg) {
+ m_sprite->setFrameCount(arg);
+ emit frameCountChanged(arg);
+ reloadImage();
+ }
+ }
+
+ void setFrameHeight(int arg)
+ {
+ if (m_sprite->m_frameHeight != arg) {
+ m_sprite->setFrameHeight(arg);
+ emit frameHeightChanged(arg);
+ reloadImage();
+ }
+ }
+
+ void setFrameWidth(int arg)
+ {
+ if (m_sprite->m_frameWidth != arg) {
+ m_sprite->setFrameWidth(arg);
+ emit frameWidthChanged(arg);
+ reloadImage();
+ }
+ }
+
+ void setFrameX(int arg)
+ {
+ if (m_sprite->m_frameX != arg) {
+ m_sprite->setFrameX(arg);
+ emit frameXChanged(arg);
+ reloadImage();
+ }
+ }
+
+ void setFrameY(int arg)
+ {
+ if (m_sprite->m_frameY != arg) {
+ m_sprite->setFrameY(arg);
+ emit frameYChanged(arg);
+ reloadImage();
+ }
+ }
+
+ void setFrameRate(qreal arg)
+ {
+ if (m_sprite->m_frameRate != arg) {
+ m_sprite->setFrameRate(arg);
+ emit frameRateChanged(arg);
+ }
+ }
+
+ void setFrameDuration(int arg)
+ {
+ if (m_sprite->m_frameDuration != arg) {
+ m_sprite->setFrameDuration(arg);
+ emit frameDurationChanged(arg);
+ }
+ }
+
+ void resetFrameRate()
+ {
+ setFrameRate(-1.0);
+ }
+
+ void resetFrameDuration()
+ {
+ setFrameDuration(-1);
+ }
+
+ void setLoops(int arg)
+ {
+ if (m_loops != arg) {
+ m_loops = arg;
+ emit loopsChanged(arg);
+ }
+ }
+
+ void setCurrentFrame(int arg) //TODO-C: Probably only works when paused
+ {
+ if (m_curFrame != arg) {
+ m_curFrame = arg;
+ emit currentFrameChanged(arg); //TODO-C Only emitted on manual advance!
+ }
+ }
+
+
+private slots:
+ void createEngine();
+protected:
+ void reset();
+ void componentComplete();
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+private:
+ void prepareNextFrame();
+ void reloadImage();
+ QSGGeometryNode* buildNode();
+ QSGGeometryNode *m_node;
+ QQuickAnimatedSpriteMaterial *m_material;
+ QQuickSprite* m_sprite;
+ QQuickSpriteEngine* m_spriteEngine;
+ QTime m_timestamp;
+ int m_curFrame;
+ bool m_pleaseReset;
+ bool m_running;
+ bool m_paused;
+ bool m_interpolate;
+ QSizeF m_sheetSize;
+ int m_loops;
+ int m_curLoop;
+ int m_pauseOffset;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKANIMATEDSPRITE_P_H
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index 1e1db18723..92a422a56d 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -94,11 +94,10 @@ protected:
{
if (e->type() == QEvent::User) {
Q_ASSERT(m_eventSent);
-
- bool *amtp = m_canvas->windowManager->allowMainThreadProcessing();
+ volatile bool *amtp = m_canvas->windowManager->allowMainThreadProcessing();
while (incubatingObjectCount()) {
if (amtp)
- incubateWhile(amtp);
+ incubateWhile(amtp, 2);
else
incubateFor(5);
QCoreApplication::processEvents();
@@ -115,6 +114,8 @@ protected:
m_eventSent = true;
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
+ // If no animations are running, the renderer may be waiting
+ m_canvas->windowManager->wakeup();
}
private:
@@ -377,25 +378,36 @@ void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event)
QQuickMouseEventEx me = touchToMouseEvent(QEvent::MouseButtonDblClick, p);
me.setTimestamp(event->timestamp());
me.setAccepted(false);
- deliverMouseEvent(&me);
- if (me.isAccepted()) {
- touchMouseId = p.id();
- event->setAccepted(true);
+ me.setCapabilities(event->device()->capabilities());
+ if (!mouseGrabberItem) {
+ if (deliverInitialMousePressEvent(rootItem, &me)) {
+ touchMouseId = p.id();
+ event->setAccepted(true);
+ }
+ } else {
+ deliverMouseEvent(&me);
+ if (me.isAccepted()) {
+ touchMouseId = p.id();
+ event->setAccepted(true);
+ }
}
}
QQuickMouseEventEx me = touchToMouseEvent(QEvent::MouseButtonPress, p);
me.setTimestamp(event->timestamp());
me.setAccepted(false);
+ me.setCapabilities(event->device()->capabilities());
deliverMouseEvent(&me);
if (me.isAccepted()) {
touchMouseId = p.id();
event->setAccepted(true);
- break;
}
+ if (touchMouseId != -1)
+ break;
} else if (p.id() == touchMouseId) {
if (p.state() & Qt::TouchPointMoved) {
QQuickMouseEventEx me = touchToMouseEvent(QEvent::MouseMove, p);
me.setTimestamp(event->timestamp());
+ me.setCapabilities(event->device()->capabilities());
if (!mouseGrabberItem) {
if (lastMousePosition.isNull())
lastMousePosition = me.windowPos();
@@ -419,6 +431,7 @@ void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event)
return;
QQuickMouseEventEx me = touchToMouseEvent(QEvent::MouseButtonRelease, p);
me.setTimestamp(event->timestamp());
+ me.setCapabilities(event->device()->capabilities());
deliverMouseEvent(&me);
mouseGrabberItem = 0;
}
@@ -746,6 +759,7 @@ QQuickCanvas::~QQuickCanvas()
QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(d->rootItem);
rootItemPrivate->removeFromDirtyList();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
delete d->incubationController; d->incubationController = 0;
delete d->rootItem; d->rootItem = 0;
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index e69d44303b..6300b0f2a7 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -163,8 +163,11 @@ public:
QQuickMouseEventEx(const QMouseEvent &event)
: QMouseEvent(event)
{
- if (extended(&event))
- setVelocity(extended(&event)->velocity());
+ const QQuickMouseEventEx *eventEx = extended(&event);
+ if (eventEx) {
+ setVelocity(eventEx->velocity());
+ setCapabilities(eventEx->capabilities());
+ }
}
static const QQuickMouseEventEx *extended(const QMouseEvent *e) {
@@ -186,8 +189,15 @@ public:
}
QVector2D velocity() const { return _velocity; }
+ void setCapabilities(QTouchDevice::Capabilities caps) {
+ setExtended();
+ _capabilities = caps;
+ }
+ QTouchDevice::Capabilities capabilities() const { return _capabilities; }
+
private:
QVector2D _velocity;
+ QTouchDevice::Capabilities _capabilities;
};
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index ef67549780..f75ca14989 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -977,7 +977,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
lastPosTime = currentTimestamp;
QQuickMouseEventEx *extended = QQuickMouseEventEx::extended(event);
if (q->yflick() && !rejectY) {
- if (extended) {
+ if (extended && extended->capabilities().testFlag(QTouchDevice::Velocity)) {
vData.addVelocitySample(extended->velocity().y(), maxVelocity);
} else {
qreal dy = event->localPos().y()-lastPos.y();
@@ -985,7 +985,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
}
}
if (q->xflick() && !rejectX) {
- if (extended) {
+ if (extended && extended->capabilities().testFlag(QTouchDevice::Velocity)) {
hData.addVelocitySample(extended->velocity().x(), maxVelocity);
} else {
qreal dx = event->localPos().x()-lastPos.x();
@@ -1022,7 +1022,8 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
qreal vVelocity = 0;
if (elapsed < 100 && vData.velocity != 0.) {
QQuickMouseEventEx *extended = QQuickMouseEventEx::extended(event);
- vVelocity = extended ? extended->velocity().y() : vData.velocity;
+ vVelocity = (extended && extended->capabilities().testFlag(QTouchDevice::Velocity))
+ ? extended->velocity().y() : vData.velocity;
}
if (vData.atBeginning || vData.atEnd) {
vVelocity /= 2;
@@ -1037,7 +1038,8 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
qreal hVelocity = 0;
if (elapsed < 100 && hData.velocity != 0.) {
QQuickMouseEventEx *extended = QQuickMouseEventEx::extended(event);
- hVelocity = extended ? extended->velocity().x() : hData.velocity;
+ hVelocity = (extended && extended->capabilities().testFlag(QTouchDevice::Velocity))
+ ? extended->velocity().x() : hData.velocity;
}
if (hData.atBeginning || hData.atEnd) {
hVelocity /= 2;
@@ -1771,8 +1773,11 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
QQuickMouseEventEx mouseEvent(event->type(), mapFromScene(event->windowPos()),
event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
- if (QQuickMouseEventEx::extended(event))
- mouseEvent.setVelocity(QQuickMouseEventEx::extended(event)->velocity());
+ QQuickMouseEventEx *eventEx = QQuickMouseEventEx::extended(event);
+ if (eventEx) {
+ mouseEvent.setVelocity(eventEx->velocity());
+ mouseEvent.setCapabilities(eventEx->capabilities());
+ }
mouseEvent.setTimestamp(event->timestamp());
mouseEvent.setAccepted(false);
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index a57d0ee778..45fbc9f93e 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -127,9 +127,6 @@ public:
return (x >= itemX() && x < itemX() + view->cellWidth() &&
y >= itemY() && y < itemY() + view->cellHeight());
}
- QQuickItemView *itemView() const {
- return view;
- }
QQuickGridView *view;
@@ -485,7 +482,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
#endif
if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer))))
break;
- if (!canTransition(FxViewItemTransitionManager::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
+ if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(colPos, rowPos);
item->item->setVisible(!doBuffer);
visibleItems.append(item);
@@ -523,7 +520,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, doBuffer))))
break;
--visibleIndex;
- if (!canTransition(FxViewItemTransitionManager::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
+ if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(colPos, rowPos);
item->item->setVisible(!doBuffer);
visibleItems.prepend(item);
@@ -1586,10 +1583,11 @@ void QQuickGridView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::GridView::populate
- This property holds the transition to apply to items that are initially created for a
- view.
- This transition is applied to all the items that are created when:
+ This property holds the transition to apply to the items that are initially created
+ for a view.
+
+ It is applied to all items that are created when:
\list
\o The view is first created
@@ -1619,10 +1617,10 @@ void QQuickGridView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::GridView::add
- This property holds the transition to apply to items that are added within the view.
- The transition is applied to items that have been added to the visible area of the view. For
- example, here is a view that specifies such a transition:
+ This property holds the transition to apply to items that are added to the view.
+
+ For example, here is a view that specifies such a transition:
\code
GridView {
@@ -1636,8 +1634,8 @@ void QQuickGridView::setSnapMode(SnapMode mode)
Whenever an item is added to the above view, the item will be animated from the position (100,100)
to its final x,y position within the view, over one second. The transition only applies to
the new items that are added to the view; it does not apply to the items below that are
- displaced by the addition of the new items. To animate the displaced items, set the \l
- addDisplaced property.
+ displaced by the addition of the new items. To animate the displaced items, set the \l displaced
+ or \l addDisplaced properties.
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
@@ -1651,11 +1649,11 @@ void QQuickGridView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::GridView::addDisplaced
- This property holds the transition to apply to items in the view that are displaced by other
- items that have been added to the view.
- The transition is applied to items that are currently visible and have been displaced by newly
- added items. For example, here is a view that specifies such a transition:
+ This property holds the transition to apply to items within the view that are displaced by
+ the addition of other items to the view.
+
+ For example, here is a view that specifies such a transition:
\code
GridView {
@@ -1673,6 +1671,11 @@ void QQuickGridView::setSnapMode(SnapMode mode)
the new item that has been added to the view; to animate the added items, set the \l add
property.
+ If an item is displaced by multiple types of operations at the same time, it is not defined as to
+ whether the addDisplaced, moveDisplaced or removeDisplaced transition will be applied. Additionally,
+ if it is not necessary to specify different transitions depending on whether an item is displaced
+ by an add, move or remove operation, consider setting the \l displaced property instead.
+
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
@@ -1680,15 +1683,15 @@ void QQuickGridView::setSnapMode(SnapMode mode)
populated, or when the view's \l model changes. In those cases, the \l populate transition is
applied instead.
- \sa add, populate, ViewTransition
+ \sa displaced, add, populate, ViewTransition
*/
/*!
\qmlproperty Transition QtQuick2::GridView::move
- This property holds the transition to apply to items in the view that are moved by a move
- operation.
- The transition is applied to items that are moving within the view or are moving
- into the view as a result of a move operation in the view's model. For example:
+ This property holds the transition to apply to items in the view that are being moved due
+ to a move operation in the view's \l model.
+
+ For example, here is a view that specifies such a transition:
\code
GridView {
@@ -1699,10 +1702,11 @@ void QQuickGridView::setSnapMode(SnapMode mode)
}
\endcode
- Whenever an item is moved within the above view, the item will be animated to its new position in
- the view over one second. The transition only applies to the items that are the subject of the
- move operation in the model; it does not apply to the items below them that are displaced by
- the move operation. To animate the displaced items, set the \l moveDisplaced property.
+ Whenever the \l model performs a move operation to move a particular set of indexes, the
+ respective items in the view will be animated to their new positions in the view over one
+ second. The transition only applies to the items that are the subject of the move operation
+ in the model; it does not apply to items below them that are displaced by the move operation.
+ To animate the displaced items, set the \l displaced or \l moveDisplaced properties.
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
@@ -1712,11 +1716,11 @@ void QQuickGridView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::GridView::moveDisplaced
- This property holds the transition to apply to items in the view that are displaced by a
- move operation in the view.
- The transition is applied to items that are currently visible and have been displaced following
- a move operation in the view's model. For example, here is a view that specifies such a transition:
+ This property holds the transition to apply to items that are displaced by a move operation in
+ the view's \l model.
+
+ For example, here is a view that specifies such a transition:
\code
GridView {
@@ -1727,25 +1731,31 @@ void QQuickGridView::setSnapMode(SnapMode mode)
}
\endcode
- Whenever an item moves within (or moves into) the above view, all items beneath it are
- displaced, causing them to move upwards (or sideways, if horizontally orientated) within the
- view. As this displacement occurs, the items' movement to their new x,y positions within the
- view will be animated by a NumberAnimation over one second, as specified. This transition is
- not applied to the item that are actually the subject of the move operation; to animate the
- moved items, set the \l move property.
+ Whenever the \l model performs a move operation to move a particular set of indexes, the items
+ between the source and destination indexes of the move operation are displaced, causing them
+ to move upwards or downwards (or sideways, if horizontally orientated) within the view. As this
+ displacement occurs, the items' movement to their new x,y positions within the view will be
+ animated by a NumberAnimation over one second, as specified. This transition is not applied to
+ the items that are the actual subjects of the move operation; to animate the moved items, set
+ the \l move property.
+
+ If an item is displaced by multiple types of operations at the same time, it is not defined as to
+ whether the addDisplaced, moveDisplaced or removeDisplaced transition will be applied. Additionally,
+ if it is not necessary to specify different transitions depending on whether an item is displaced
+ by an add, move or remove operation, consider setting the \l displaced property instead.
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
- \sa move, ViewTransition
+ \sa displaced, move, ViewTransition
*/
/*!
\qmlproperty Transition QtQuick2::GridView::remove
+
This property holds the transition to apply to items that are removed from the view.
- The transition is applied to items that have been removed from the visible area of the view. For
- example:
+ For example, here is a view that specifies such a transition:
\code
GridView {
@@ -1762,8 +1772,8 @@ void QQuickGridView::setSnapMode(SnapMode mode)
Whenever an item is removed from the above view, the item will be animated to the position (100,100)
over one second, and in parallel will also change its opacity to 0. The transition
only applies to the items that are removed from the view; it does not apply to the items below
- them that are displaced by the removal of the items. To animate the displaced items, set the \l
- removeDisplaced property.
+ them that are displaced by the removal of the items. To animate the displaced items, set the
+ \l displaced or \l removeDisplaced properties.
Note that by the time the transition is applied, the item has already been removed from the
model; any references to the model data for the removed index will not be valid.
@@ -1779,11 +1789,11 @@ void QQuickGridView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::GridView::removeDisplaced
+
This property holds the transition to apply to items in the view that are displaced by the
removal of other items in the view.
- The transition is applied to items that are currently visible and have been displaced by
- the removal of items. For example, here is a view that specifies such a transition:
+ For example, here is a view that specifies such a transition:
\code
GridView {
@@ -1801,11 +1811,53 @@ void QQuickGridView::setSnapMode(SnapMode mode)
the item that has actually been removed from the view; to animate the removed items, set the
\l remove property.
+ If an item is displaced by multiple types of operations at the same time, it is not defined as to
+ whether the addDisplaced, moveDisplaced or removeDisplaced transition will be applied. Additionally,
+ if it is not necessary to specify different transitions depending on whether an item is displaced
+ by an add, move or remove operation, consider setting the \l displaced property instead.
+
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
- \sa remove, ViewTransition
+ \sa displaced, remove, ViewTransition
*/
+
+/*!
+ \qmlproperty Transition QtQuick2::GridView::displaced
+ This property holds the generic transition to apply to items that have been displaced by
+ any model operation that affects the view.
+
+ This is a convenience for specifying a generic transition for items that are displaced
+ by add, move or remove operations, without having to specify the individual addDisplaced,
+ moveDisplaced and removeDisplaced properties. For example, here is a view that specifies
+ a displaced transition:
+
+ \code
+ GridView {
+ ...
+ displaced: Transition {
+ NumberAnimation { properties: "x,y"; duration: 1000 }
+ }
+ }
+ \endcode
+
+ When any item is added, moved or removed within the above view, the items below it are
+ displaced, causing them to move down (or sideways, if horizontally orientated) within the
+ view. As this displacement occurs, the items' movement to their new x,y positions within
+ the view will be animated by a NumberAnimation over one second, as specified.
+
+ If a view specifies this generic displaced transition as well as a specific addDisplaced,
+ moveDisplaced or removeDisplaced transition, the more specific transition will be used
+ instead of the generic displaced transition when the relevant operation occurs, providing that
+ the more specific transition has not been disabled (by setting \l {Transition::enabled}{enabled}
+ to false). If it has indeed been disabled, the generic displaced transition is applied instead.
+
+ For more details and examples on how to use view transitions, see the ViewTransition
+ documentation.
+
+ \sa addDisplaced, moveDisplaced, removeDisplaced, ViewTransition
+*/
+
void QQuickGridView::viewportMoved()
{
Q_D(QQuickGridView);
@@ -2109,10 +2161,12 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
FxViewItem *item = visibleItems.at(i);
if (item->index != -1 && item->index >= modelIndex) {
item->index += count;
- if (change.isMove())
- transitionNextReposition(item, FxViewItemTransitionManager::MoveTransition, false);
- else
- transitionNextReposition(item, FxViewItemTransitionManager::AddTransition, false);
+ if (transitioner) {
+ if (change.isMove())
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false);
+ else
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, false);
+ }
}
}
@@ -2143,7 +2197,8 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
insertResult->changedFirstItem = true;
if (!change.isMove()) {
addedItems->append(item);
- transitionNextReposition(item, FxViewItemTransitionManager::AddTransition, true);
+ if (transitioner)
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true);
}
insertResult->sizeChangesBeforeVisiblePos += rowSize();
}
@@ -2176,11 +2231,12 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
if (change.isMove()) {
// we know this is a move target, since move displaced items that are
// shuffled into view due to a move would be added in refill()
- if (canTransition(FxViewItemTransitionManager::MoveTransition, true) && newItem)
+ if (newItem && transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, true))
movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
} else {
addedItems->append(item);
- transitionNextReposition(item, FxViewItemTransitionManager::AddTransition, true);
+ if (transitioner)
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true);
}
insertResult->sizeChangesAfterVisiblePos += rowSize();
@@ -2201,6 +2257,9 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult)
{
+ if (!transitioner)
+ return;
+
int markerItemIndex = -1;
for (int i=0; i<visibleItems.count(); i++) {
if (visibleItems[i]->index == afterModelIndex) {
@@ -2228,7 +2287,7 @@ void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
qreal origColPos = gridItem->rowPos();
int indexDiff = gridItem->index - countItemsRemoved;
gridItem->setPosition((indexDiff % columns) * colSize(), (indexDiff / columns) * rowSize());
- transitionNextReposition(gridItem, FxViewItemTransitionManager::RemoveTransition, false);
+ transitioner->transitionNextReposition(gridItem, QQuickItemViewTransitioner::RemoveTransition, false);
gridItem->setPosition(origRowPos, origColPos);
}
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 357c72cc71..77808a61d9 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1627,7 +1627,7 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
\inmodule QtQuick
- All visual items in Qt Declarative inherit from QQuickItem. Although QQuickItem
+ All visual items in Qt Quick inherit from QQuickItem. Although QQuickItem
has no visual appearance, it defines all the properties that are
common across visual items - such as the x and y position, the
width and height, \l {anchor-layout}{anchoring} and key handling.
@@ -1646,7 +1646,7 @@ void QQuickItemPrivate::setAccessibleFlagAndListener()
\ingroup qml-basic-visual-elements
\brief The Item is the most basic of all visual items in QML.
- All visual items in Qt Declarative inherit from Item. Although Item
+ All visual items in Qt Quick inherit from Item. Although Item
has no visual appearance, it defines all the properties that are
common across visual items - such as the x and y position, the
width and height, \l {anchor-layout}{anchoring} and key handling.
@@ -2122,7 +2122,7 @@ QQuickItem *QQuickItemPrivate::InitializationState::getFocusScope(QQuickItem *it
{
if (!focusScope) {
QQuickItem *fs = item->parentItem();
- while (!fs->isFocusScope())
+ while (fs->parentItem() && !fs->isFocusScope())
fs = fs->parentItem();
focusScope = fs;
}
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 8adb80e88b..03fc66eadb 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -830,8 +830,8 @@ private:
Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
{
- return extra.flag()?Qt::LeftButton:Qt::MouseButton(0) |
- (extra.isAllocated()?extra->acceptedMouseButtons:Qt::MouseButtons(0));
+ return ((extra.flag() ? Qt::LeftButton : Qt::MouseButton(0)) |
+ (extra.isAllocated() ? extra->acceptedMouseButtons : Qt::MouseButtons(0)));
}
QSGContext *QQuickItemPrivate::sceneGraphContext() const
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 1316a3d84a..32f1047e51 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -551,6 +551,8 @@ QAbstractAnimationJob* QQuickAnchorAnimation::transition(QQuickStateActions &act
delete data;
}
+ animator->setDuration(d->duration);
+ animator->setEasingCurve(d->easing);
return initInstance(animator);
}
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 64b84d35dd..3d23f7b03a 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -61,6 +61,7 @@
#include "qquickvisualdatamodel_p.h"
#include "qquickgridview_p.h"
#include "qquickpathview_p.h"
+#include "qquickitemviewtransition_p.h"
#include <private/qquickpath_p.h>
#include <private/qquickpathinterpolator_p.h>
#include "qquickpositioners_p.h"
@@ -77,7 +78,8 @@
#include <QtQuick/private/qquickcanvasitem_p.h>
#include <QtQuick/private/qquickcontext2d_p.h>
#include "qquicksprite_p.h"
-#include "qquickspriteimage_p.h"
+#include "qquickspritesequence_p.h"
+#include "qquickanimatedsprite_p.h"
#include "qquickdrag_p.h"
#include "qquickdroparea_p.h"
#include "qquickmultipointtoucharea_p.h"
@@ -200,7 +202,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickCanvasItem>("QtQuick", 2, 0, "Canvas");
qmlRegisterType<QQuickSprite>("QtQuick", 2, 0, "Sprite");
- qmlRegisterType<QQuickSpriteImage>("QtQuick", 2, 0, "SpriteImage");
+ qmlRegisterType<QQuickAnimatedSprite>("QtQuick", 2, 0, "AnimatedSprite");
+ qmlRegisterType<QQuickSpriteSequence>("QtQuick", 2, 0, "SpriteSequence");
+ qmlRegisterType<QQuickSpriteSequence>("QtQuick", 2, 0, "SpriteImage");//Deprecation in progress
qmlRegisterType<QQuickParentChange>(uri, major, minor,"ParentChange");
qmlRegisterType<QQuickAnchorChanges>(uri, major, minor,"AnchorChanges");
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 418b3196ed..516cf0c1bb 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -46,20 +46,12 @@ QT_BEGIN_NAMESPACE
FxViewItem::FxViewItem(QQuickItem *i, bool own)
- : item(i), ownItem(own), index(-1), releaseAfterTransition(false)
- , transition(0)
- , nextTransitionType(FxViewItemTransitionManager::NoTransition)
- , isTransitionTarget(false)
- , nextTransitionToSet(false)
+ : QQuickViewItem(i), ownItem(own), releaseAfterTransition(false)
{
}
FxViewItem::~FxViewItem()
{
- if (transition)
- transition->m_item = 0;
- delete transition;
-
if (ownItem && item) {
item->setParentItem(0);
item->deleteLater();
@@ -67,273 +59,6 @@ FxViewItem::~FxViewItem()
}
}
-qreal FxViewItem::itemX() const
-{
- if (nextTransitionType != FxViewItemTransitionManager::NoTransition)
- return nextTransitionToSet ? nextTransitionTo.x() : item->x();
- else if (transition && transition->isActive())
- return transition->m_toPos.x();
- else
- return item->x();
-}
-
-qreal FxViewItem::itemY() const
-{
- // If item is transitioning to some pos, return that dest pos.
- // If item was redirected to some new pos before the current transition finished,
- // return that new pos.
- if (nextTransitionType != FxViewItemTransitionManager::NoTransition)
- return nextTransitionToSet ? nextTransitionTo.y() : item->y();
- else if (transition && transition->isActive())
- return transition->m_toPos.y();
- else
- return item->y();
-}
-
-void FxViewItem::setVisible(bool visible)
-{
- if (!visible && transitionScheduledOrRunning())
- return;
- item->setVisible(visible);
-}
-
-void FxViewItem::setNextTransition(FxViewItemTransitionManager::TransitionType type, bool isTargetItem)
-{
- // Don't reset nextTransitionToSet - once it is set, it cannot be changed
- // until the animation finishes since the itemX() and itemY() may be used
- // to calculate positions for transitions for other items in the view.
- nextTransitionType = type;
- isTransitionTarget = isTargetItem;
-}
-
-bool FxViewItem::transitionScheduledOrRunning() const
-{
- return (transition && transition->isActive())
- || nextTransitionType != FxViewItemTransitionManager::NoTransition;
-}
-
-bool FxViewItem::prepareTransition(const QRectF &viewBounds)
-{
- bool doTransition = false;
-
- switch (nextTransitionType) {
- case FxViewItemTransitionManager::NoTransition:
- {
- return false;
- }
- case FxViewItemTransitionManager::PopulateTransition:
- {
- return true;
- }
- case FxViewItemTransitionManager::AddTransition:
- case FxViewItemTransitionManager::RemoveTransition:
- // For Add targets, do transition if item is moving into visible area
- // For Remove targets, do transition if item is currently in visible area
- if (isTransitionTarget) {
- doTransition = (nextTransitionType == FxViewItemTransitionManager::AddTransition)
- ? viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()))
- : viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height()));
- if (!doTransition)
- item->setPos(nextTransitionTo);
- } else {
- if (viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height()))
- || viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()))) {
- doTransition = (nextTransitionTo != item->pos());
- } else {
- item->setPos(nextTransitionTo);
- }
- }
- break;
- case FxViewItemTransitionManager::MoveTransition:
- // do transition if moving from or into visible area
- if (nextTransitionTo != item->pos()) {
- doTransition = viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height()))
- || viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()));
- if (!doTransition)
- item->setPos(nextTransitionTo);
- }
- break;
- }
-
- if (!doTransition)
- resetTransitionData();
- return doTransition;
-}
-
-void FxViewItem::startTransition()
-{
- if (nextTransitionType == FxViewItemTransitionManager::NoTransition)
- return;
-
- if (!transition || transition->m_type != nextTransitionType || transition->m_isTarget != isTransitionTarget) {
- delete transition;
- transition = new FxViewItemTransitionManager;
- }
-
- // if item is not already moving somewhere, set it to not move anywhere
- // so that removed items do not move to the default (0,0)
- if (!nextTransitionToSet)
- moveTo(item->pos());
-
- transition->startTransition(this, nextTransitionType, nextTransitionTo, isTransitionTarget);
- nextTransitionType = FxViewItemTransitionManager::NoTransition;
-}
-
-void FxViewItem::stopTransition()
-{
- if (transition) {
- transition->cancel();
- delete transition;
- transition = 0;
- }
- resetTransitionData();
- finishedTransition();
-}
-
-void FxViewItem::finishedTransition()
-{
- nextTransitionToSet = false;
- nextTransitionTo = QPointF();
-
- if (releaseAfterTransition) {
- QQuickItemViewPrivate *vp = static_cast<QQuickItemViewPrivate*>(QObjectPrivate::get(itemView()));
- vp->releasePendingTransition.removeOne(this);
- vp->releaseItem(this);
- }
-}
-
-void FxViewItem::resetTransitionData()
-{
- nextTransitionType = FxViewItemTransitionManager::NoTransition;
- isTransitionTarget = false;
- nextTransitionTo = QPointF();
- nextTransitionToSet = false;
-}
-
-bool FxViewItem::isPendingRemoval() const
-{
- if (nextTransitionType == FxViewItemTransitionManager::RemoveTransition)
- return isTransitionTarget;
- if (transition && transition->isActive() && transition->m_type == FxViewItemTransitionManager::RemoveTransition)
- return transition->m_isTarget;
- return false;
-}
-
-void FxViewItem::moveTo(const QPointF &pos)
-{
- if (transitionScheduledOrRunning()) {
- nextTransitionTo = pos;
- nextTransitionToSet = true;
- } else {
- item->setPos(pos);
- }
-}
-
-
-FxViewItemTransitionManager::FxViewItemTransitionManager()
- : m_active(false), m_item(0), m_type(FxViewItemTransitionManager::NoTransition), m_isTarget(false)
-{
-}
-
-FxViewItemTransitionManager::~FxViewItemTransitionManager()
-{
-}
-
-bool FxViewItemTransitionManager::isActive() const
-{
- return m_active;
-}
-
-void FxViewItemTransitionManager::startTransition(FxViewItem *item, FxViewItemTransitionManager::TransitionType type, const QPointF &to, bool isTargetItem)
-{
- if (!item) {
- qWarning("startTransition(): invalid item");
- return;
- }
-
- QQuickItemViewPrivate *vp = static_cast<QQuickItemViewPrivate*>(QObjectPrivate::get(item->itemView()));
-
- QQuickTransition *trans = 0;
- switch (type) {
- case NoTransition:
- break;
- case PopulateTransition:
- trans = vp->populateTransition;
- break;
- case AddTransition:
- trans = isTargetItem ? vp->addTransition : vp->addDisplacedTransition;
- break;
- case MoveTransition:
- trans = isTargetItem ? vp->moveTransition : vp->moveDisplacedTransition;
- break;
- case RemoveTransition:
- trans = isTargetItem ? vp->removeTransition : vp->removeDisplacedTransition;
- break;
- }
-
- if (!trans) {
- qWarning("QQuickItemView: invalid view transition!");
- return;
- }
-
- m_active = true;
- m_item = item;
- m_toPos = to;
- m_type = type;
- m_isTarget = isTargetItem;
-
- QQuickViewTransitionAttached *attached =
- static_cast<QQuickViewTransitionAttached*>(qmlAttachedPropertiesObject<QQuickViewTransitionAttached>(trans));
- if (attached) {
- attached->m_index = item->index;
- attached->m_item = item->item;
- attached->m_destination = to;
- switch (type) {
- case NoTransition:
- break;
- case PopulateTransition:
- case AddTransition:
- attached->m_targetIndexes = vp->addTransitionIndexes;
- attached->m_targetItems = vp->addTransitionTargets;
- break;
- case MoveTransition:
- attached->m_targetIndexes = vp->moveTransitionIndexes;
- attached->m_targetItems = vp->moveTransitionTargets;
- break;
- case RemoveTransition:
- attached->m_targetIndexes = vp->removeTransitionIndexes;
- attached->m_targetItems = vp->removeTransitionTargets;
- break;
- }
- emit attached->indexChanged();
- emit attached->itemChanged();
- emit attached->destinationChanged();
- emit attached->targetIndexesChanged();
- emit attached->targetItemsChanged();
- }
-
- QQuickStateOperation::ActionList actions;
- actions << QQuickAction(item->item, QLatin1String("x"), QVariant(to.x()));
- actions << QQuickAction(item->item, QLatin1String("y"), QVariant(to.y()));
-
- QQuickTransitionManager::transition(actions, trans, item->item);
-}
-
-void FxViewItemTransitionManager::finished()
-{
- QQuickTransitionManager::finished();
-
- m_active = false;
-
- if (m_item)
- m_item->finishedTransition();
- m_item = 0;
- m_toPos.setX(0);
- m_toPos.setY(0);
- m_type = NoTransition;
- m_isTarget = false;
-}
-
QQuickItemViewChangeSet::QQuickItemViewChangeSet()
: active(false)
@@ -412,363 +137,6 @@ void QQuickItemViewChangeSet::reset()
currentRemoved = false;
}
-
-QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent)
- : QObject(parent), m_index(-1), m_item(0)
-{
-}
-/*!
- \qmlclass ViewTransition QQuickViewTransitionAttached
- \inqmlmodule QtQuick 2
- \ingroup qml-view-elements
- \brief The ViewTransition attached property provides details on items under transition in a view.
-
- With ListView and GridView, it is possible to specify transitions that should be applied whenever
- the items in the view change as a result of modifications to the view's model. They both have the
- following properties that can be set to the appropriate transitions to be run for various
- operations:
-
- \list
- \o \c add and \c addDisplaced - the transitions to run when items are added to the view
- \o \c remove and \c removeDisplaced - the transitions to run when items are removed from the view
- \o \c move and \c moveDisplaced - the transitions to run when items are moved within the view
- (i.e. as a result of a move operation in the model)
- \o \c populate - the transition to run when a view is created, or when the model changes
- \endlist
-
- Such view transitions additionally have access to a ViewTransition attached property that
- provides details of the items that are under transition and the operation that triggered the
- transition. Since view transitions are run once per item, these details can be used to customise
- each transition for each individual item.
-
- The ViewTransition attached property provides the following properties specific to the item to
- which the transition is applied:
-
- \list
- \o ViewTransition.item - the item that is under transition
- \o ViewTransition.index - the index of this item
- \o ViewTransition.destination - the (x,y) point to which this item is moving for the relevant view operation
- \endlist
-
- In addition, ViewTransition provides properties specific to the items which are the target
- of the operation that triggered the transition:
-
- \list
- \o ViewTransition.targetIndexes - the indexes of the target items
- \o ViewTransition.targetItems - the target items themselves
- \endlist
-
- View transitions can be written without referring to any of the attributes listed
- above. These attributes merely provide extra details that are useful for customising view
- transitions.
-
- Following is an introduction to view transitions and the ways in which the ViewTransition
- attached property can be used to augment view transitions.
-
-
- \section2 View transitions: a simple example
-
- Here is a basic example of the use of view transitions. The view below specifies transitions for
- the \c add and \c addDisplaced properties, which will be run when items are added to the view:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-basic.qml 0
-
- When the space key is pressed, adding an item to the model, the new item will fade in and
- increase in scale over 400 milliseconds as it is added to the view. Also, any item that is
- displaced by the addition of a new item will animate to its new position in the view over
- 400 milliseconds, as specified by the \c addDisplaced transition.
-
- If five items were inserted in succession at index 0, the effect would be this:
-
- \image viewtransitions-basic.gif
-
- Notice that the NumberAnimation objects above do not need to specify a \c target to animate
- the appropriate item. Also, the NumberAnimation in the \c addTransition does not need to specify
- the \c to value to move the item to its correct position in the view. This is because the view
- implicitly sets the \c target and \c to values with the correct item and final item position
- values if these properties are not explicitly defined.
-
- At its simplest, a view transition may just animate an item to its new position following a
- view operation, just as the \c addDisplaced transition does above, or animate some item properties,
- as in the \c add transition above. Additionally, a view transition may make use of the
- ViewTransition attached property to customise animation behavior for different items. Following
- are some examples of how this can be achieved.
-
-
- \section2 Using the ViewTransition attached property
-
- As stated, the various ViewTransition properties provide details specific to the individual item
- being transitioned as well as the operation that triggered the transition. In the animation above,
- five items are inserted in succession at index 0. When the fifth and final insertion takes place,
- adding "Item 4" to the view, the \c add transition is run once (for the inserted item) and the
- \c addDisplaced transition is run four times (once for each of the four existing items in the view).
-
- At this point, if we examined the \c addDisplaced transition that was run for the bottom displaced
- item ("Item 0"), the ViewTransition property values provided to this transition would be as follows:
-
- \table
- \header
- \o Property
- \o Value
- \o Explanation
- \row
- \o ViewTransition.item
- \o "Item 0" delegate instance
- \o The "Item 0" \l Rectangle object itself
- \row
- \o ViewTransition.index
- \o \c int value of 4
- \o The index of "Item 0" within the model following the add operation
- \row
- \o ViewTransition.destination
- \o \l point value of (0, 120)
- \o The position that "Item 0" is moving to
- \row
- \o ViewTransition.targetIndexes
- \o \c int array, just contains the integer "0" (zero)
- \o The index of "Item 4", the new item added to the view
- \row
- \o ViewTransition.targetItems
- \o object array, just contains the "Item 4" delegate instance
- \o The "Item 4" \l Rectangle object - the new item added to the view
- \endtable
-
- The ViewTransition.targetIndexes and ViewTransition.targetItems lists provide the items and
- indexes of all delegate instances that are the targets of the relevant operation. For an add
- operation, these are all the items that are added into the view; for a remove, these are all
- the items removed from the view, and so on. (Note these lists will only contain references to
- items that have been created within the view or its cached items; targets that are not within
- the visible area of the view or within the item cache will not be accessible.)
-
- So, while the ViewTransition.item, ViewTransition.index and ViewTransition.destination values
- vary for each individual transition that is run, the ViewTransition.targetIndexes and
- ViewTransition.targetItems values are the same for every \c add and \c addDisplaced transition
- that is triggered by a particular add operation.
-
-
- \section3 Delaying animations based on index
-
- Since each view transition is run once for each item affected by the transition, the ViewTransition
- properties can be used within a transition to define custom behavior for each item's transition.
- For example, the ListView in the previous example could use this information to create a ripple-type
- effect on the movement of the displaced items.
-
- This can be achieved by modifying the \c addDisplaced transition so that it delays the animation of
- each displaced item based on the difference between its index (provided by ViewTransition.index)
- and the first removed index (provided by ViewTransition.targetIndexes):
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-delayedbyindex.qml 0
-
- Each displaced item delays its animation by an additional 100 milliseconds, producing a subtle
- ripple-type effect when items are displaced by the add, like this:
-
- \image viewtransitions-delayedbyindex.gif
-
-
- \section3 Animating items to intermediate positions
-
- The ViewTransition.item property gives a reference to the item to which the transition is being
- applied. This can be used to access any of the item's attributes, custom \c property values,
- and so on.
-
- Below is a modification of the \c addDisplaced transition from the previous example. It adds a
- ParallelAnimation with nested NumberAnimation objects that reference ViewTransition.item to access
- each item's \c x and \c y values at the start of their transitions. This allows each item to
- animate to an intermediate position relative to its starting point for the transition, before
- animating to its final position in the view:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-intermediatemove.qml 0
-
- Now, a displaced item will first move to a position of (20, 50) relative to its starting
- position, and then to its final, correct position in the view:
-
- \image viewtransitions-intermediatemove.gif
-
- Since the final NumberAnimation does not specify a \c to value, the view implicitly sets this
- value to the item's final position in the view, and so this last animation will move this item
- to the correct place. If the transition requires the final position of the item for some calculation,
- this is accessible through ViewTransition.destination.
-
- Instead of using multiple NumberAnimations, you could use a PathAnimation to animate an item over
- a curved path. For example, the \c add transition in the previous example could be augmented with
- a PathAnimation as follows: to animate newly added items along a path:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-pathanim.qml 0
-
- This animates newly added items along a path. Notice that each path is specified relative to
- each item's final destination point, so that items inserted at different indexes start their
- paths from different positions:
-
- \image viewtransitions-pathanim.gif
-
-
- \section2 Handling interrupted animations
-
- A view transition may be interrupted at any time if a different view transition needs to be
- applied while the original transition is in progress. For example, say Item A is inserted at index 0
- and undergoes an "add" transition; then, Item B is inserted at index 0 in quick succession before
- Item A's transition has finished. Since Item B is inserted before Item A, it will displace Item
- A, causing the view to interrupt Item A's "add" transition mid-way and start an "addDisplaced"
- transition on Item A instead.
-
- For simple animations that simply animate an item's movement to its final destination, this
- interruption is unlikely to require additional consideration. However, if a transition changes other
- properties, this interruption may cause unwanted side effects. Consider the first example on this
- page, repeated below for convenience:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-basic.qml 0
-
- If multiple items are added in rapid succession, without waiting for a previous transition
- to finish, this is the result:
-
- \image viewtransitions-interruptedbad.gif
-
- Each newly added item undergoes an \c add transition, but before the transition can finish,
- another item is added, displacing the previously added item. Because of this, the \c add
- transition on the previously added item is interrupted and an \c addDisplaced transition is
- started on the item instead. Due to the interruption, the \c opacity and \c scale animations
- have not completed, thus producing items with opacity and scale that are below 1.0.
-
- To fix this, the \c addDisplaced transition should additionally ensure the item properties are
- set to the end values specified in the \c add transition, effectively resetting these values
- whenever an item is displaced. In this case, it means setting the item opacity and scale to 1.0:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-interruptedgood.qml 0
-
- Now, when an item's \c add transition is interrupted, its opacity and scale are animated to 1.0
- upon displacement, avoiding the erroneous visual effects from before:
-
- \image viewtransitions-interruptedgood.gif
-
- The same principle applies to any combination of view transitions. An added item may be moved
- before its add transition finishes, or a moved item may be removed before its moved transition
- finishes, and so on; so, the rule of thumb is that every transition should handle the same set of
- properties.
-
-
- \section2 Restrictions regarding ScriptAction
-
- When a view transition is initialized, any property bindings that refer to the ViewTransition
- attached property are evaluated in preparation for the transition. Due to the nature of the
- internal construction of a view transition, the attributes of the ViewTransition attached
- property are only valid for the relevant item when the transition is initialized, and may not be
- valid when the transition is actually run.
-
- Therefore, a ScriptAction within a view transition should not refer to the ViewTransition
- attached property, as it may not refer to the expected values at the time that the ScriptAction
- is actually invoked. Consider the following example:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-scriptactionbad.qml 0
-
- When the space key is pressed, three items are moved from index 5 to index 1. For each moved
- item, the \c moveTransition sequence presumably animates the item's color to "yellow", then
- animates it to its final position, then changes the item color back to "lightsteelblue" using a
- ScriptAction. However, when run, the transition does not produce the intended result:
-
- \image viewtransitions-scriptactionbad.gif
-
- Only the last moved item is returned to the "lightsteelblue" color; the others remain yellow. This
- is because the ScriptAction is not run until after the transition has already been initialized, by
- which time the ViewTransition.item value has changed to refer to a different item; the item that
- the script had intended to refer to is not the one held by ViewTransition.item at the time the
- ScriptAction is actually invoked.
-
- In this instance, to avoid this issue, the view could set the property using a PropertyAction
- instead:
-
- \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-scriptactiongood.qml 0
-
- When the transition is initialized, the PropertyAction \c target will be set to the respective
- ViewTransition.item for the transition and will later run with the correct item target as
- expected.
- */
-
-/*!
- \qmlattachedproperty list QtQuick2::ViewTransition::index
-
- This attached property holds the index of the item that is being
- transitioned.
-
- Note that if the item is being moved, this property holds the index that
- the item is moving to, not from.
-*/
-
-/*!
- \qmlattachedproperty list QtQuick2::ViewTransition::item
-
- This attached property holds the the item that is being transitioned.
-
- \warning This item should not be kept and referred to outside of the transition
- as it may become invalid as the view changes.
-*/
-
-/*!
- \qmlattachedproperty list QtQuick2::ViewTransition::destination
-
- This attached property holds the final destination position for the transitioned
- item within the view.
-
- This property value is a \l point with \c x and \c y properties.
-*/
-
-/*!
- \qmlattachedproperty list QtQuick2::ViewTransition::targetIndexes
-
- This attached property holds a list of the indexes of the items in view
- that are the target of the relevant operation.
-
- The targets are the items that are the subject of the operation. For
- an add operation, these are the items being added; for a remove, these
- are the items being removed; for a move, these are the items being
- moved.
-
- For example, if the transition was triggered by an insert operation
- that added two items at index 1 and 2, this targetIndexes list would
- have the value [1,2].
-
- \note The targetIndexes list only contains the indexes of items that are actually
- in view, or will be in the view once the relevant operation completes.
-
- \sa QtQuick2::ViewTransition::targetIndexes
-*/
-
-/*!
- \qmlattachedproperty list QtQuick2::ViewTransition::targetItems
-
- This attached property holds the list of items in view that are the
- target of the relevant operation.
-
- The targets are the items that are the subject of the operation. For
- an add operation, these are the items being added; for a remove, these
- are the items being removed; for a move, these are the items being
- moved.
-
- For example, if the transition was triggered by an insert operation
- that added two items at index 1 and 2, this targetItems list would
- contain these two items.
-
- \note The targetItems list only contains items that are actually
- in view, or will be in the view once the relevant operation completes.
-
- \warning The objects in this list should not be kept and referred to
- outside of the transition as the items may become invalid. The targetItems
- are only valid when the Transition is initially created; this also means
- they should not be used by ScriptAction objects in the Transition, which are
- not evaluated until the transition is run.
-
- \sa QtQuick2::ViewTransition::targetIndexes
-*/
-QQmlListProperty<QObject> QQuickViewTransitionAttached::targetItems()
-{
- return QQmlListProperty<QObject>(this, m_targetItems);
-}
-
-QQuickViewTransitionAttached *QQuickViewTransitionAttached::qmlAttachedProperties(QObject *obj)
-{
- return new QQuickViewTransitionAttached(obj);
-}
-
-
//-----------------------------------
QQuickItemView::QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent)
@@ -867,9 +235,9 @@ void QQuickItemView::setModel(const QVariant &model)
}
d->updateViewport();
- if (d->populateTransition) {
+ if (d->transitioner && d->transitioner->populateTransition) {
d->forceLayout = true;
- d->usePopulateTransition = true;
+ d->transitioner->setPopulateTransitionEnabled(true);
polish();
}
}
@@ -1228,14 +596,15 @@ void QQuickItemView::setHighlightMoveDuration(int duration)
QQuickTransition *QQuickItemView::populateTransition() const
{
Q_D(const QQuickItemView);
- return d->populateTransition;
+ return d->transitioner ? d->transitioner->populateTransition : 0;
}
void QQuickItemView::setPopulateTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->populateTransition != transition) {
- d->populateTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->populateTransition != transition) {
+ d->transitioner->populateTransition = transition;
emit populateTransitionChanged();
}
}
@@ -1243,14 +612,15 @@ void QQuickItemView::setPopulateTransition(QQuickTransition *transition)
QQuickTransition *QQuickItemView::addTransition() const
{
Q_D(const QQuickItemView);
- return d->addTransition;
+ return d->transitioner ? d->transitioner->addTransition : 0;
}
void QQuickItemView::setAddTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->addTransition != transition) {
- d->addTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->addTransition != transition) {
+ d->transitioner->addTransition = transition;
emit addTransitionChanged();
}
}
@@ -1258,14 +628,15 @@ void QQuickItemView::setAddTransition(QQuickTransition *transition)
QQuickTransition *QQuickItemView::addDisplacedTransition() const
{
Q_D(const QQuickItemView);
- return d->addDisplacedTransition;
+ return d->transitioner ? d->transitioner->addDisplacedTransition : 0;
}
void QQuickItemView::setAddDisplacedTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->addDisplacedTransition != transition) {
- d->addDisplacedTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->addDisplacedTransition != transition) {
+ d->transitioner->addDisplacedTransition = transition;
emit addDisplacedTransitionChanged();
}
}
@@ -1273,14 +644,15 @@ void QQuickItemView::setAddDisplacedTransition(QQuickTransition *transition)
QQuickTransition *QQuickItemView::moveTransition() const
{
Q_D(const QQuickItemView);
- return d->moveTransition;
+ return d->transitioner ? d->transitioner->moveTransition : 0;
}
void QQuickItemView::setMoveTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->moveTransition != transition) {
- d->moveTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->moveTransition != transition) {
+ d->transitioner->moveTransition = transition;
emit moveTransitionChanged();
}
}
@@ -1288,14 +660,15 @@ void QQuickItemView::setMoveTransition(QQuickTransition *transition)
QQuickTransition *QQuickItemView::moveDisplacedTransition() const
{
Q_D(const QQuickItemView);
- return d->moveDisplacedTransition;
+ return d->transitioner ? d->transitioner->moveDisplacedTransition : 0;
}
void QQuickItemView::setMoveDisplacedTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->moveDisplacedTransition != transition) {
- d->moveDisplacedTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->moveDisplacedTransition != transition) {
+ d->transitioner->moveDisplacedTransition = transition;
emit moveDisplacedTransitionChanged();
}
}
@@ -1303,14 +676,15 @@ void QQuickItemView::setMoveDisplacedTransition(QQuickTransition *transition)
QQuickTransition *QQuickItemView::removeTransition() const
{
Q_D(const QQuickItemView);
- return d->removeTransition;
+ return d->transitioner ? d->transitioner->removeTransition : 0;
}
void QQuickItemView::setRemoveTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->removeTransition != transition) {
- d->removeTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->removeTransition != transition) {
+ d->transitioner->removeTransition = transition;
emit removeTransitionChanged();
}
}
@@ -1318,18 +692,35 @@ void QQuickItemView::setRemoveTransition(QQuickTransition *transition)
QQuickTransition *QQuickItemView::removeDisplacedTransition() const
{
Q_D(const QQuickItemView);
- return d->removeDisplacedTransition;
+ return d->transitioner ? d->transitioner->removeDisplacedTransition : 0;
}
void QQuickItemView::setRemoveDisplacedTransition(QQuickTransition *transition)
{
Q_D(QQuickItemView);
- if (d->removeDisplacedTransition != transition) {
- d->removeDisplacedTransition = transition;
+ d->createTransitioner();
+ if (d->transitioner->removeDisplacedTransition != transition) {
+ d->transitioner->removeDisplacedTransition = transition;
emit removeDisplacedTransitionChanged();
}
}
+QQuickTransition *QQuickItemView::displacedTransition() const
+{
+ Q_D(const QQuickItemView);
+ return d->transitioner ? d->transitioner->displacedTransition : 0;
+}
+
+void QQuickItemView::setDisplacedTransition(QQuickTransition *transition)
+{
+ Q_D(QQuickItemView);
+ d->createTransitioner();
+ if (d->transitioner->displacedTransition != transition) {
+ d->transitioner->displacedTransition = transition;
+ emit displacedTransitionChanged();
+ }
+}
+
void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
{
Q_Q(QQuickItemView);
@@ -1464,64 +855,6 @@ void QQuickItemViewPrivate::applyPendingChanges()
layout();
}
-bool QQuickItemViewPrivate::canTransition(FxViewItemTransitionManager::TransitionType type, bool asTarget) const
-{
- switch (type) {
- case FxViewItemTransitionManager::NoTransition:
- break;
- case FxViewItemTransitionManager::PopulateTransition:
- return usePopulateTransition
- && populateTransition && populateTransition->enabled();
- case FxViewItemTransitionManager::AddTransition:
- if (asTarget)
- return addTransition && addTransition->enabled();
- else
- return addDisplacedTransition && addDisplacedTransition->enabled();
- case FxViewItemTransitionManager::MoveTransition:
- if (asTarget)
- return moveTransition && moveTransition->enabled();
- else
- return moveDisplacedTransition && moveDisplacedTransition->enabled();
- case FxViewItemTransitionManager::RemoveTransition:
- if (asTarget)
- return removeTransition && removeTransition->enabled();
- else
- return removeDisplacedTransition && removeDisplacedTransition->enabled();
- }
- return false;
-}
-
-bool QQuickItemViewPrivate::hasItemTransitions() const
-{
- return canTransition(FxViewItemTransitionManager::PopulateTransition, true)
- || canTransition(FxViewItemTransitionManager::AddTransition, true)
- || canTransition(FxViewItemTransitionManager::AddTransition, false)
- || canTransition(FxViewItemTransitionManager::MoveTransition, true)
- || canTransition(FxViewItemTransitionManager::MoveTransition, false)
- || canTransition(FxViewItemTransitionManager::RemoveTransition, true)
- || canTransition(FxViewItemTransitionManager::RemoveTransition, false);
-}
-
-void QQuickItemViewPrivate::transitionNextReposition(FxViewItem *item, FxViewItemTransitionManager::TransitionType type, bool isTarget)
-{
- bool matchedTransition = false;
- if (type == FxViewItemTransitionManager::AddTransition) {
- // don't run add transitions for added items while populating
- matchedTransition = !usePopulateTransition && canTransition(type, isTarget);
- } else {
- matchedTransition = canTransition(type, isTarget);
- }
-
- if (matchedTransition) {
- item->setNextTransition(type, isTarget);
- } else {
- // the requested transition type is not valid, but the item is scheduled/in another
- // transition, so cancel it to allow the item to move directly to the correct pos
- if (item->transitionScheduledOrRunning())
- item->stopTransition();
- }
-}
-
int QQuickItemViewPrivate::findMoveKeyIndex(QQuickChangeSet::MoveKey key, const QVector<QQuickChangeSet::Remove> &changes) const
{
for (int i=0; i<changes.count(); i++) {
@@ -1582,8 +915,8 @@ void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &
// start new transitions
bool prevDisableLayout = disableLayout;
if (!disableLayout) {
- FxViewItem *actualItem = hasItemTransitions() ? visibleItem(currentIndex) : 0;
- if (actualItem && actualItem->transition && actualItem->transition->isRunning())
+ FxViewItem *actualItem = transitioner ? visibleItem(currentIndex) : 0;
+ if (actualItem && actualItem->transitionRunning())
disableLayout = true;
}
updateHighlight();
@@ -1601,7 +934,7 @@ void QQuickItemView::destroyRemoved()
it != d->visibleItems.end();) {
FxViewItem *item = *it;
if (item->index == -1 && item->attached->delayRemove() == false) {
- if (d->canTransition(FxViewItemTransitionManager::RemoveTransition, true)) {
+ if (d->transitioner && d->transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) {
// don't remove from visibleItems until next layout()
d->runDelayedRemoveTransition = true;
QObject::disconnect(item->attached, SIGNAL(delayRemoveChanged()), this, SLOT(destroyRemoved()));
@@ -1625,7 +958,8 @@ void QQuickItemView::modelUpdated(const QQuickChangeSet &changeSet, bool reset)
{
Q_D(QQuickItemView);
if (reset) {
- d->usePopulateTransition = true;
+ if (d->transitioner)
+ d->transitioner->setPopulateTransitionEnabled(true);
d->moveReason = QQuickItemViewPrivate::SetIndex;
d->regenerate();
if (d->highlight && d->currentItem) {
@@ -1635,7 +969,7 @@ void QQuickItemView::modelUpdated(const QQuickChangeSet &changeSet, bool reset)
}
d->moveReason = QQuickItemViewPrivate::Other;
emit countChanged();
- if (d->populateTransition) {
+ if (d->transitioner && d->transitioner->populateTransition) {
d->forceLayout = true;
polish();
}
@@ -1935,7 +1269,8 @@ void QQuickItemView::componentComplete()
d->updateFooter();
d->updateViewport();
d->setPosition(d->contentStartOffset());
- d->usePopulateTransition = true;
+ if (d->transitioner)
+ d->transitioner->setPopulateTransitionEnabled(true);
if (d->isValid()) {
d->refill();
@@ -1971,19 +1306,23 @@ QQuickItemViewPrivate::QQuickItemViewPrivate()
, highlightRangeStart(0), highlightRangeEnd(0)
, highlightMoveDuration(150)
, headerComponent(0), header(0), footerComponent(0), footer(0)
- , populateTransition(0)
- , addTransition(0), addDisplacedTransition(0)
- , moveTransition(0), moveDisplacedTransition(0)
- , removeTransition(0), removeDisplacedTransition(0)
+ , transitioner(0)
, minExtent(0), maxExtent(0)
, ownModel(false), wrap(false)
, disableLayout(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
, haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
, fillCacheBuffer(false), inRequest(false), requestedAsync(false)
- , usePopulateTransition(false), runDelayedRemoveTransition(false)
+ , runDelayedRemoveTransition(false)
{
}
+QQuickItemViewPrivate::~QQuickItemViewPrivate()
+{
+ if (transitioner)
+ transitioner->setChangeListener(0);
+ delete transitioner;
+}
+
bool QQuickItemViewPrivate::isValid() const
{
return model && model->count() && model->isValid();
@@ -2161,6 +1500,12 @@ void QQuickItemViewPrivate::clear()
createHighlight();
trackedItem = 0;
+ if (requestedIndex >= 0 && requestedAsync) {
+ if (model)
+ model->cancel(requestedIndex);
+ requestedIndex = -1;
+ }
+
markExtentsDirty();
itemCount = 0;
}
@@ -2260,15 +1605,17 @@ void QQuickItemViewPrivate::layout()
if (!isValid() && !visibleItems.count()) {
clear();
setPosition(contentStartOffset());
- usePopulateTransition = false;
+ if (transitioner)
+ transitioner->setPopulateTransitionEnabled(false);
return;
}
- if (runDelayedRemoveTransition && canTransition(FxViewItemTransitionManager::RemoveTransition, false)) {
+ if (runDelayedRemoveTransition && transitioner
+ && transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
// assume that any items moving now are moving due to the remove - if they schedule
// a different transition, that will override this one anyway
for (int i=0; i<visibleItems.count(); i++)
- transitionNextReposition(visibleItems[i], FxViewItemTransitionManager::RemoveTransition, false);
+ transitioner->transitionNextReposition(visibleItems[i], QQuickItemViewTransitioner::RemoveTransition, false);
}
ChangeResult insertionPosChanges;
@@ -2282,9 +1629,9 @@ void QQuickItemViewPrivate::layout()
}
forceLayout = false;
- if (canTransition(FxViewItemTransitionManager::PopulateTransition, true)) {
+ if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) {
for (int i=0; i<visibleItems.count(); i++)
- transitionNextReposition(visibleItems.at(i), FxViewItemTransitionManager::PopulateTransition, true);
+ transitioner->transitionNextReposition(visibleItems.at(i), QQuickItemViewTransitioner::PopulateTransition, true);
}
layoutVisibleItems();
@@ -2303,11 +1650,11 @@ void QQuickItemViewPrivate::layout()
updateViewport();
updateUnrequestedPositions();
- if (hasItemTransitions()) {
+ if (transitioner) {
// items added in the last refill() may need to be transitioned in - e.g. a remove
// causes items to slide up into view
- if (canTransition(FxViewItemTransitionManager::MoveTransition, false)
- || canTransition(FxViewItemTransitionManager::RemoveTransition, false)) {
+ if (transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, false)
+ || transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) {
translateAndTransitionItemsAfter(lastIndexInView, insertionPosChanges, removalPosChanges);
}
@@ -2317,8 +1664,7 @@ void QQuickItemViewPrivate::layout()
for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin();
it != releasePendingTransition.end(); ) {
FxViewItem *item = *it;
- if ( (item->transition && item->transition->isActive())
- || prepareNonVisibleItemTransition(item, viewBounds)) {
+ if (item->transitionRunning() || prepareNonVisibleItemTransition(item, viewBounds)) {
++it;
} else {
releaseItem(item);
@@ -2327,11 +1673,12 @@ void QQuickItemViewPrivate::layout()
}
for (int i=0; i<visibleItems.count(); i++)
- visibleItems[i]->startTransition();
+ visibleItems[i]->startTransition(transitioner);
for (int i=0; i<releasePendingTransition.count(); i++)
- releasePendingTransition[i]->startTransition();
+ releasePendingTransition[i]->startTransition(transitioner);
+ transitioner->setPopulateTransitionEnabled(false);
}
- usePopulateTransition = false;
+
runDelayedRemoveTransition = false;
}
@@ -2434,7 +1781,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
// for each item that was moved directly into the view as a result of a move(),
// find the index it was moved from in order to set its initial position, so that we
// can transition it from this "original" position to its new position in the view
- if (canTransition(FxViewItemTransitionManager::MoveTransition, true)) {
+ if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, true)) {
for (int i=0; i<movingIntoView.count(); i++) {
int fromIndex = findMoveKeyIndex(movingIntoView[i].moveKey, removals);
if (fromIndex >= 0) {
@@ -2442,7 +1789,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
repositionItemAt(movingIntoView[i].item, fromIndex, -totalInsertionResult->sizeChangesAfterVisiblePos);
else
repositionItemAt(movingIntoView[i].item, fromIndex, totalInsertionResult->sizeChangesAfterVisiblePos);
- transitionNextReposition(movingIntoView[i].item, FxViewItemTransitionManager::MoveTransition, true);
+ transitioner->transitionNextReposition(movingIntoView[i].item, QQuickItemViewTransitioner::MoveTransition, true);
}
}
}
@@ -2506,10 +1853,12 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQuickChangeSet::Remove &re
} else if (item->index >= removal.index + removal.count) {
// after removed items
item->index -= removal.count;
- if (removal.isMove())
- transitionNextReposition(item, FxViewItemTransitionManager::MoveTransition, false);
- else
- transitionNextReposition(item, FxViewItemTransitionManager::RemoveTransition, false);
+ if (transitioner) {
+ if (removal.isMove())
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false);
+ else
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::RemoveTransition, false);
+ }
++it;
} else {
// removed item
@@ -2543,7 +1892,8 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQuickChangeSet::
}
if (removal.isMove()) {
currentChanges.removedItems.insert(removal.moveKey(item->index), item);
- transitionNextReposition(item, FxViewItemTransitionManager::MoveTransition, true);
+ if (transitioner)
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, true);
} else {
// track item so it is released later
currentChanges.removedItems.insertMulti(QQuickChangeSet::MoveKey(), item);
@@ -2591,16 +1941,24 @@ void QQuickItemViewPrivate::repositionFirstItem(FxViewItem *prevVisibleItemsFirs
}
}
+void QQuickItemViewPrivate::createTransitioner()
+{
+ if (!transitioner) {
+ transitioner = new QQuickItemViewTransitioner;
+ transitioner->setChangeListener(this);
+ }
+}
+
void QQuickItemViewPrivate::prepareVisibleItemTransitions()
{
Q_Q(QQuickItemView);
- if (!hasItemTransitions())
+ if (!transitioner)
return;
- addTransitionIndexes.clear();
- addTransitionTargets.clear();
- moveTransitionIndexes.clear();
- moveTransitionTargets.clear();
+ transitioner->addTransitionIndexes.clear();
+ transitioner->addTransitionTargets.clear();
+ transitioner->moveTransitionIndexes.clear();
+ transitioner->moveTransitionTargets.clear();
QRectF viewBounds(0, position(), q->width(), q->height());
for (int i=0; i<visibleItems.count(); i++) {
@@ -2609,18 +1967,18 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions()
continue;
if (visibleItems[i]->isTransitionTarget) {
switch (visibleItems[i]->nextTransitionType) {
- case FxViewItemTransitionManager::NoTransition:
+ case QQuickItemViewTransitioner::NoTransition:
break;
- case FxViewItemTransitionManager::PopulateTransition:
- case FxViewItemTransitionManager::AddTransition:
- addTransitionIndexes.append(visibleItems[i]->index);
- addTransitionTargets.append(visibleItems[i]->item);
+ case QQuickItemViewTransitioner::PopulateTransition:
+ case QQuickItemViewTransitioner::AddTransition:
+ transitioner->addTransitionIndexes.append(visibleItems[i]->index);
+ transitioner->addTransitionTargets.append(visibleItems[i]->item);
break;
- case FxViewItemTransitionManager::MoveTransition:
- moveTransitionIndexes.append(visibleItems[i]->index);
- moveTransitionTargets.append(visibleItems[i]->item);
+ case QQuickItemViewTransitioner::MoveTransition:
+ transitioner->moveTransitionIndexes.append(visibleItems[i]->index);
+ transitioner->moveTransitionTargets.append(visibleItems[i]->item);
break;
- case FxViewItemTransitionManager::RemoveTransition:
+ case QQuickItemViewTransitioner::RemoveTransition:
// removed targets won't be in visibleItems, handle these
// in prepareNonVisibleItemTransition()
break;
@@ -2631,10 +1989,13 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions()
void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems)
{
- removeTransitionIndexes.clear();
- removeTransitionTargets.clear();
+ if (!transitioner)
+ return;
- if (canTransition(FxViewItemTransitionManager::RemoveTransition, true)) {
+ transitioner->removeTransitionIndexes.clear();
+ transitioner->removeTransitionTargets.clear();
+
+ if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) {
for (QHash<QQuickChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin();
it != removedItems->end(); ) {
bool isRemove = it.key().moveId < 0;
@@ -2642,7 +2003,7 @@ void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::Move
FxViewItem *item = *it;
item->releaseAfterTransition = true;
releasePendingTransition.append(item);
- transitionNextReposition(item, FxViewItemTransitionManager::RemoveTransition, true);
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::RemoveTransition, true);
it = removedItems->erase(it);
} else {
++it;
@@ -2658,18 +2019,21 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co
// removed, or moved to outside of the view, as well as those that are
// displaced to a position outside of the view due to an insert or move.
- if (item->nextTransitionType == FxViewItemTransitionManager::MoveTransition)
+ if (!transitioner)
+ return false;
+
+ if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition)
repositionItemAt(item, item->index, 0);
if (!item->prepareTransition(viewBounds))
return false;
if (item->isTransitionTarget) {
- if (item->nextTransitionType == FxViewItemTransitionManager::MoveTransition) {
- moveTransitionIndexes.append(item->index);
- moveTransitionTargets.append(item->item);
- } else if (item->nextTransitionType == FxViewItemTransitionManager::RemoveTransition) {
- removeTransitionIndexes.append(item->index);
- removeTransitionTargets.append(item->item);
+ if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition) {
+ transitioner->moveTransitionIndexes.append(item->index);
+ transitioner->moveTransitionTargets.append(item->item);
+ } else if (item->nextTransitionType == QQuickItemViewTransitioner::RemoveTransition) {
+ transitioner->removeTransitionIndexes.append(item->index);
+ transitioner->removeTransitionTargets.append(item->item);
}
}
@@ -2677,6 +2041,15 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co
return true;
}
+void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickViewItem *i)
+{
+ FxViewItem *item = static_cast<FxViewItem *>(i);
+ if (item->releaseAfterTransition) {
+ releasePendingTransition.removeOne(item);
+ releaseItem(item);
+ }
+}
+
/*
This may return 0 if the item is being created asynchronously.
When the item becomes available, refill() will be called and the item
@@ -2768,21 +2141,23 @@ void QQuickItemView::destroyingItem(QQuickItem *item)
d->unrequestedItems.remove(item);
}
-void QQuickItemViewPrivate::releaseItem(FxViewItem *item)
+bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
{
Q_Q(QQuickItemView);
if (!item || !model)
- return;
+ return true;
if (trackedItem == item)
trackedItem = 0;
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
- if (model->release(item->item) == 0) {
+ QQuickVisualModel::ReleaseFlags flags = model->release(item->item);
+ if (flags == 0) {
// item was not destroyed, and we no longer reference it.
item->item->setVisible(false);
unrequestedItems.insert(item->item, model->indexOf(item->item, q));
}
delete item;
+ return flags != QQuickVisualModel::Referenced;
}
QQuickItem *QQuickItemViewPrivate::createHighlightItem()
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 01a6ee28ec..f252fb58f1 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -48,7 +48,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Qml)
+QT_MODULE(Quick)
class QQuickChangeSet;
@@ -83,6 +83,7 @@ class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(QQuickTransition *moveDisplaced READ moveDisplacedTransition WRITE setMoveDisplacedTransition NOTIFY moveDisplacedTransitionChanged)
Q_PROPERTY(QQuickTransition *remove READ removeTransition WRITE setRemoveTransition NOTIFY removeTransitionChanged)
Q_PROPERTY(QQuickTransition *removeDisplaced READ removeDisplacedTransition WRITE setRemoveDisplacedTransition NOTIFY removeDisplacedTransitionChanged)
+ Q_PROPERTY(QQuickTransition *displaced READ displacedTransition WRITE setDisplacedTransition NOTIFY displacedTransitionChanged)
Q_PROPERTY(QQmlComponent *highlight READ highlight WRITE setHighlight NOTIFY highlightChanged)
Q_PROPERTY(QQuickItem *highlightItem READ highlightItem NOTIFY highlightItemChanged)
@@ -151,6 +152,9 @@ public:
QQuickTransition *removeDisplacedTransition() const;
void setRemoveDisplacedTransition(QQuickTransition *transition);
+ QQuickTransition *displacedTransition() const;
+ void setDisplacedTransition(QQuickTransition *transition);
+
QQmlComponent *highlight() const;
void setHighlight(QQmlComponent *);
@@ -211,6 +215,7 @@ signals:
void moveDisplacedTransitionChanged();
void removeTransitionChanged();
void removeDisplacedTransitionChanged();
+ void displacedTransitionChanged();
void highlightChanged();
void highlightItemChanged();
@@ -324,53 +329,9 @@ public:
QString m_nextSection;
};
-class QQuickViewTransitionAttached : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(int index READ index NOTIFY indexChanged)
- Q_PROPERTY(QQuickItem* item READ item NOTIFY itemChanged)
- Q_PROPERTY(QPointF destination READ destination NOTIFY destinationChanged)
-
- Q_PROPERTY(QList<int> targetIndexes READ targetIndexes NOTIFY targetIndexesChanged)
- Q_PROPERTY(QQmlListProperty<QObject> targetItems READ targetItems NOTIFY targetItemsChanged)
-
-public:
- QQuickViewTransitionAttached(QObject *parent);
-
- int index() const { return m_index; }
- QQuickItem *item() const { return m_item; }
- QPointF destination() const { return m_destination; }
-
- QList<int> targetIndexes() const { return m_targetIndexes; }
- QQmlListProperty<QObject> targetItems();
-
- static QQuickViewTransitionAttached *qmlAttachedProperties(QObject *);
-
-signals:
- void indexChanged();
- void itemChanged();
- void destinationChanged();
-
- void targetIndexesChanged();
- void targetItemsChanged();
-
-private:
- friend class FxViewItemTransitionManager;
- int m_index;
- QQuickItem *m_item;
- QPointF m_destination;
-
- QList<int> m_targetIndexes;
- QList<QObject *> m_targetItems;
-};
-
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QQuickViewTransitionAttached)
-QML_DECLARE_TYPEINFO(QQuickViewTransitionAttached, QML_HAS_ATTACHED_PROPERTIES)
-
QT_END_HEADER
#endif // QQUICKITEMVIEW_P_H
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index a4892e8972..80dacc0cb4 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -43,10 +43,10 @@
#define QQUICKITEMVIEW_P_P_H
#include "qquickitemview_p.h"
+#include "qquickitemviewtransition_p.h"
#include "qquickflickable_p_p.h"
#include "qquickvisualdatamodel_p.h"
#include "qquickvisualitemmodel_p.h"
-#include <private/qquicktransitionmanager_p_p.h>
#include <private/qquickchangeset_p.h>
@@ -54,58 +54,15 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Declarative)
+QT_MODULE(Quick)
-class FxViewItem;
-class FxViewItemTransitionManager : public QQuickTransitionManager
-{
-public:
- enum TransitionType {
- NoTransition,
- PopulateTransition,
- AddTransition,
- MoveTransition,
- RemoveTransition
- };
-
- FxViewItemTransitionManager();
- ~FxViewItemTransitionManager();
-
- bool isActive() const;
- void startTransition(FxViewItem *item, FxViewItemTransitionManager::TransitionType type, const QPointF &to, bool isTargetItem);
-
- bool m_active;
- FxViewItem *m_item;
- QPointF m_toPos;
- FxViewItemTransitionManager::TransitionType m_type;
- bool m_isTarget;
-
-protected:
- virtual void finished();
-};
-
-
-class FxViewItem
+class FxViewItem : public QQuickViewItem
{
public:
FxViewItem(QQuickItem *, bool own);
virtual ~FxViewItem();
- qreal itemX() const;
- qreal itemY() const;
-
- void setVisible(bool visible);
-
- void setNextTransition(FxViewItemTransitionManager::TransitionType, bool isTargetItem);
- bool transitionScheduledOrRunning() const;
- bool isPendingRemoval() const;
-
- bool prepareTransition(const QRectF &viewBounds);
- void startTransition();
- void stopTransition();
- void finishedTransition();
-
// these are positions and sizes along the current direction of scrolling/flicking
virtual qreal position() const = 0;
virtual qreal endPosition() const = 0;
@@ -113,23 +70,10 @@ public:
virtual qreal sectionSize() const = 0;
virtual bool contains(qreal x, qreal y) const = 0;
- virtual QQuickItemView *itemView() const = 0;
- QQuickItem *item;
+ QQuickItemViewAttached *attached;
bool ownItem;
- int index;
bool releaseAfterTransition;
- QQuickItemViewAttached *attached;
-
- FxViewItemTransitionManager *transition;
- QPointF nextTransitionTo;
- FxViewItemTransitionManager::TransitionType nextTransitionType;
- bool isTransitionTarget;
- bool nextTransitionToSet;
-
-protected:
- void moveTo(const QPointF &pos);
- void resetTransitionData();
};
@@ -155,11 +99,12 @@ public:
};
-class QQuickItemViewPrivate : public QQuickFlickablePrivate
+class QQuickItemViewPrivate : public QQuickFlickablePrivate, public QQuickItemViewTransitionChangeListener
{
Q_DECLARE_PUBLIC(QQuickItemView)
public:
QQuickItemViewPrivate();
+ ~QQuickItemViewPrivate();
struct ChangeResult {
QQmlNullableValue<qreal> visiblePos;
@@ -225,7 +170,7 @@ public:
void mirrorChange();
FxViewItem *createItem(int modelIndex, bool asynchronous = false);
- virtual void releaseItem(FxViewItem *item);
+ virtual bool releaseItem(FxViewItem *item);
QQuickItem *createHighlightItem();
QQuickItem *createComponentItem(QQmlComponent *component, bool receiveItemGeometryChanges, bool createDefault = false);
@@ -243,13 +188,12 @@ public:
void repositionFirstItem(FxViewItem *prevVisibleItemsFirst, qreal prevVisibleItemsFirstPos,
FxViewItem *prevFirstVisible, ChangeResult *insertionResult, ChangeResult *removalResult);
+ void createTransitioner();
void prepareVisibleItemTransitions();
void prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems);
bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds);
+ virtual void viewItemTransitionFinished(QQuickViewItem *item);
- bool canTransition(FxViewItemTransitionManager::TransitionType type, bool asTarget) const;
- bool hasItemTransitions() const;
- void transitionNextReposition(FxViewItem *item, FxViewItemTransitionManager::TransitionType type, bool isTarget);
int findMoveKeyIndex(QQuickChangeSet::MoveKey key, const QVector<QQuickChangeSet::Remove> &changes) const;
void checkVisible() const;
@@ -281,7 +225,6 @@ public:
FxViewItem *requestedItem;
QQuickItemViewChangeSet currentChanges;
- // XXX split into struct
QQmlComponent *highlightComponent;
FxViewItem *highlight;
int highlightRange; // enum value
@@ -294,27 +237,13 @@ public:
QQmlComponent *footerComponent;
FxViewItem *footer;
- QQuickTransition *populateTransition;
- QQuickTransition *addTransition;
- QQuickTransition *addDisplacedTransition;
- QQuickTransition *moveTransition;
- QQuickTransition *moveDisplacedTransition;
- QQuickTransition *removeTransition;
- QQuickTransition *removeDisplacedTransition;
-
- QList<int> addTransitionIndexes;
- QList<int> moveTransitionIndexes;
- QList<int> removeTransitionIndexes;
- QList<QObject *> addTransitionTargets;
- QList<QObject *> moveTransitionTargets;
- QList<QObject *> removeTransitionTargets;
-
struct MovedItem {
FxViewItem *item;
QQuickChangeSet::MoveKey moveKey;
MovedItem(FxViewItem *i, QQuickChangeSet::MoveKey k)
: item(i), moveKey(k) {}
};
+ QQuickItemViewTransitioner *transitioner;
QList<FxViewItem *> releasePendingTransition;
mutable qreal minExtent;
@@ -333,7 +262,6 @@ public:
bool fillCacheBuffer : 1;
bool inRequest : 1;
bool requestedAsync : 1;
- bool usePopulateTransition : 1;
bool runDelayedRemoveTransition : 1;
protected:
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
new file mode 100644
index 0000000000..54375bf4ff
--- /dev/null
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -0,0 +1,876 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickitemviewtransition_p.h"
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquicktransition_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QList<int> qquickitemviewtransition_emptyIndexes = QList<int>();
+static QList<QObject *> qquickitemviewtransition_emptyTargets = QList<QObject *>();
+
+
+class QQuickItemViewTransitionJob : public QQuickTransitionManager
+{
+public:
+ QQuickItemViewTransitionJob();
+ ~QQuickItemViewTransitionJob();
+
+ void startTransition(QQuickViewItem *item, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem);
+
+ QQuickItemViewTransitioner *m_transitioner;
+ QQuickViewItem *m_item;
+ QPointF m_toPos;
+ QQuickItemViewTransitioner::TransitionType m_type;
+ bool m_isTarget;
+
+protected:
+ virtual void finished();
+};
+
+
+QQuickItemViewTransitionJob::QQuickItemViewTransitionJob()
+ : m_transitioner(0)
+ , m_item(0)
+ , m_type(QQuickItemViewTransitioner::NoTransition)
+ , m_isTarget(false)
+{
+}
+
+QQuickItemViewTransitionJob::~QQuickItemViewTransitionJob()
+{
+ if (m_transitioner)
+ m_transitioner->runningJobs.remove(this);
+}
+
+void QQuickItemViewTransitionJob::startTransition(QQuickViewItem *item, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem)
+{
+ if (type == QQuickItemViewTransitioner::NoTransition)
+ return;
+ if (!item) {
+ qWarning("startTransition(): invalid item");
+ return;
+ }
+ if (!transitioner) {
+ qWarning("startTransition(): invalid transitioner");
+ return;
+ }
+
+ QQuickTransition *trans = transitioner->transitionObject(type, isTargetItem);
+ if (!trans) {
+ qWarning("QQuickItemView: invalid view transition!");
+ return;
+ }
+
+ m_item = item;
+ m_transitioner = transitioner;
+ m_toPos = to;
+ m_type = type;
+ m_isTarget = isTargetItem;
+
+ QQuickViewTransitionAttached *attached =
+ static_cast<QQuickViewTransitionAttached*>(qmlAttachedPropertiesObject<QQuickViewTransitionAttached>(trans));
+ if (attached) {
+ attached->m_index = item->index;
+ attached->m_item = item->item;
+ attached->m_destination = to;
+ attached->m_targetIndexes = m_transitioner->targetIndexes(type);
+ attached->m_targetItems = m_transitioner->targetItems(type);
+ emit attached->indexChanged();
+ emit attached->itemChanged();
+ emit attached->destinationChanged();
+ emit attached->targetIndexesChanged();
+ emit attached->targetItemsChanged();
+ }
+
+ QQuickStateOperation::ActionList actions;
+ actions << QQuickAction(item->item, QLatin1String("x"), QVariant(to.x()));
+ actions << QQuickAction(item->item, QLatin1String("y"), QVariant(to.y()));
+
+ m_transitioner->runningJobs << this;
+ QQuickTransitionManager::transition(actions, trans, item->item);
+}
+
+void QQuickItemViewTransitionJob::finished()
+{
+ QQuickTransitionManager::finished();
+
+ if (m_transitioner)
+ m_transitioner->finishedTransition(this, m_item);
+
+ m_item = 0;
+ m_toPos.setX(0);
+ m_toPos.setY(0);
+ m_type = QQuickItemViewTransitioner::NoTransition;
+ m_isTarget = false;
+}
+
+
+QQuickItemViewTransitioner::QQuickItemViewTransitioner()
+ : populateTransition(0)
+ , addTransition(0), addDisplacedTransition(0)
+ , moveTransition(0), moveDisplacedTransition(0)
+ , removeTransition(0), removeDisplacedTransition(0)
+ , displacedTransition(0)
+ , changeListener(0)
+ , usePopulateTransition(false)
+{
+}
+
+QQuickItemViewTransitioner::~QQuickItemViewTransitioner()
+{
+ for (QSet<QQuickItemViewTransitionJob *>::iterator it = runningJobs.begin(); it != runningJobs.end(); ++it)
+ (*it)->m_transitioner = 0;
+}
+
+bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const
+{
+ if (!asTarget
+ && type != QQuickItemViewTransitioner::NoTransition && type != QQuickItemViewTransitioner::PopulateTransition
+ && displacedTransition && displacedTransition->enabled()) {
+ return true;
+ }
+
+ switch (type) {
+ case QQuickItemViewTransitioner::NoTransition:
+ break;
+ case QQuickItemViewTransitioner::PopulateTransition:
+ return usePopulateTransition
+ && populateTransition && populateTransition->enabled();
+ case QQuickItemViewTransitioner::AddTransition:
+ if (asTarget)
+ return addTransition && addTransition->enabled();
+ else
+ return addDisplacedTransition && addDisplacedTransition->enabled();
+ case QQuickItemViewTransitioner::MoveTransition:
+ if (asTarget)
+ return moveTransition && moveTransition->enabled();
+ else
+ return moveDisplacedTransition && moveDisplacedTransition->enabled();
+ case QQuickItemViewTransitioner::RemoveTransition:
+ if (asTarget)
+ return removeTransition && removeTransition->enabled();
+ else
+ return removeDisplacedTransition && removeDisplacedTransition->enabled();
+ }
+ return false;
+}
+
+void QQuickItemViewTransitioner::transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget)
+{
+ bool matchedTransition = false;
+ if (type == QQuickItemViewTransitioner::AddTransition) {
+ // don't run add transitions for added items while populating
+ if (usePopulateTransition)
+ matchedTransition = false;
+ else
+ matchedTransition = canTransition(type, isTarget);
+ } else {
+ matchedTransition = canTransition(type, isTarget);
+ }
+
+ if (matchedTransition) {
+ item->setNextTransition(type, isTarget);
+ } else {
+ // the requested transition type is not valid, but the item is scheduled/in another
+ // transition, so cancel it to allow the item to move directly to the correct pos
+ if (item->transitionScheduledOrRunning())
+ item->stopTransition();
+ }
+}
+
+QQuickTransition *QQuickItemViewTransitioner::transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget)
+{
+ if (type == QQuickItemViewTransitioner::NoTransition)
+ return 0;
+
+ if (type == PopulateTransition)
+ asTarget = true; // no separate displaced transition
+
+ QQuickTransition *trans = 0;
+ switch (type) {
+ case NoTransition:
+ break;
+ case PopulateTransition:
+ trans = populateTransition;
+ break;
+ case AddTransition:
+ trans = asTarget ? addTransition : addDisplacedTransition;
+ break;
+ case MoveTransition:
+ trans = asTarget ? moveTransition : moveDisplacedTransition;
+ break;
+ case RemoveTransition:
+ trans = asTarget ? removeTransition : removeDisplacedTransition;
+ break;
+ }
+
+ if (!asTarget && (!trans || !trans->enabled()))
+ trans = displacedTransition;
+ if (trans && trans->enabled())
+ return trans;
+ return 0;
+}
+
+const QList<int> &QQuickItemViewTransitioner::targetIndexes(QQuickItemViewTransitioner::TransitionType type) const
+{
+ switch (type) {
+ case QQuickItemViewTransitioner::NoTransition:
+ break;
+ case QQuickItemViewTransitioner::PopulateTransition:
+ case QQuickItemViewTransitioner::AddTransition:
+ return addTransitionIndexes;
+ case QQuickItemViewTransitioner::MoveTransition:
+ return moveTransitionIndexes;
+ case QQuickItemViewTransitioner::RemoveTransition:
+ return removeTransitionIndexes;
+ }
+
+ return qquickitemviewtransition_emptyIndexes;
+}
+
+const QList<QObject *> &QQuickItemViewTransitioner::targetItems(QQuickItemViewTransitioner::TransitionType type) const
+{
+ switch (type) {
+ case QQuickItemViewTransitioner::NoTransition:
+ break;
+ case QQuickItemViewTransitioner::PopulateTransition:
+ case QQuickItemViewTransitioner::AddTransition:
+ return addTransitionTargets;
+ case QQuickItemViewTransitioner::MoveTransition:
+ return moveTransitionTargets;
+ case QQuickItemViewTransitioner::RemoveTransition:
+ return removeTransitionTargets;
+ }
+
+ return qquickitemviewtransition_emptyTargets;
+}
+
+void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob *job, QQuickViewItem *item)
+{
+ if (!runningJobs.contains(job))
+ return;
+ runningJobs.remove(job);
+ if (item) {
+ item->finishedTransition();
+ if (changeListener)
+ changeListener->viewItemTransitionFinished(item);
+ }
+}
+
+
+QQuickViewItem::QQuickViewItem(QQuickItem *i)
+ : item(i)
+ , transition(0)
+ , nextTransitionType(QQuickItemViewTransitioner::NoTransition)
+ , index(-1)
+ , isTransitionTarget(false)
+ , nextTransitionToSet(false)
+{
+}
+
+QQuickViewItem::~QQuickViewItem()
+{
+ delete transition;
+}
+
+qreal QQuickViewItem::itemX() const
+{
+ if (nextTransitionType != QQuickItemViewTransitioner::NoTransition)
+ return nextTransitionToSet ? nextTransitionTo.x() : item->x();
+ else if (transition && transition->isRunning())
+ return transition->m_toPos.x();
+ else
+ return item->x();
+}
+
+qreal QQuickViewItem::itemY() const
+{
+ // If item is transitioning to some pos, return that dest pos.
+ // If item was redirected to some new pos before the current transition finished,
+ // return that new pos.
+ if (nextTransitionType != QQuickItemViewTransitioner::NoTransition)
+ return nextTransitionToSet ? nextTransitionTo.y() : item->y();
+ else if (transition && transition->isRunning())
+ return transition->m_toPos.y();
+ else
+ return item->y();
+}
+
+void QQuickViewItem::moveTo(const QPointF &pos)
+{
+ if (transitionScheduledOrRunning()) {
+ nextTransitionTo = pos;
+ nextTransitionToSet = true;
+ } else {
+ item->setPos(pos);
+ }
+}
+
+void QQuickViewItem::setVisible(bool visible)
+{
+ if (!visible && transitionScheduledOrRunning())
+ return;
+ item->setVisible(visible);
+}
+
+bool QQuickViewItem::transitionScheduledOrRunning() const
+{
+ return (transition && transition->isRunning())
+ || nextTransitionType != QQuickItemViewTransitioner::NoTransition;
+}
+
+bool QQuickViewItem::transitionRunning() const
+{
+ return (transition && transition->isRunning());
+}
+
+bool QQuickViewItem::isPendingRemoval() const
+{
+ if (nextTransitionType == QQuickItemViewTransitioner::RemoveTransition)
+ return isTransitionTarget;
+ if (transition && transition->isRunning() && transition->m_type == QQuickItemViewTransitioner::RemoveTransition)
+ return transition->m_isTarget;
+ return false;
+}
+
+bool QQuickViewItem::prepareTransition(const QRectF &viewBounds)
+{
+ bool doTransition = false;
+
+ // If item is not already moving somewhere, set it to not move anywhere.
+ // This ensures that removed targets don't transition to the default (0,0) and that
+ // items set for other transition types only transition if they actually move somewhere.
+ if (nextTransitionType != QQuickItemViewTransitioner::NoTransition && !nextTransitionToSet)
+ moveTo(item->pos());
+
+ // For move transitions (both target and displaced) and displaced transitions of other
+ // types, only run the transition if the item is actually moving to another position.
+
+ switch (nextTransitionType) {
+ case QQuickItemViewTransitioner::NoTransition:
+ {
+ return false;
+ }
+ case QQuickItemViewTransitioner::PopulateTransition:
+ {
+ return true;
+ }
+ case QQuickItemViewTransitioner::AddTransition:
+ case QQuickItemViewTransitioner::RemoveTransition:
+ if (viewBounds.isNull()) {
+ if (isTransitionTarget)
+ doTransition = true;
+ else
+ doTransition = transitionWillChangePosition();
+ } else if (isTransitionTarget) {
+ // For Add targets, do transition if item is moving into visible area
+ // For Remove targets, do transition if item is currently in visible area
+ doTransition = (nextTransitionType == QQuickItemViewTransitioner::AddTransition)
+ ? viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()))
+ : viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height()));
+ if (!doTransition)
+ item->setPos(nextTransitionTo);
+ } else {
+ if (viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height()))
+ || viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()))) {
+ doTransition = transitionWillChangePosition();
+ } else {
+ item->setPos(nextTransitionTo);
+ }
+ }
+ break;
+ case QQuickItemViewTransitioner::MoveTransition:
+ // do transition if moving from or into visible area
+ if (transitionWillChangePosition()) {
+ doTransition = viewBounds.isNull()
+ || viewBounds.intersects(QRectF(item->x(), item->y(), item->width(), item->height()))
+ || viewBounds.intersects(QRectF(nextTransitionTo.x(), nextTransitionTo.y(), item->width(), item->height()));
+ if (!doTransition)
+ item->setPos(nextTransitionTo);
+ }
+ break;
+ }
+
+ if (!doTransition)
+ resetTransitionData();
+ return doTransition;
+}
+
+void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner)
+{
+ if (nextTransitionType == QQuickItemViewTransitioner::NoTransition)
+ return;
+
+ if (!transition || transition->m_type != nextTransitionType || transition->m_isTarget != isTransitionTarget) {
+ delete transition;
+ transition = new QQuickItemViewTransitionJob;
+ }
+
+ // if item is not already moving somewhere, set it to not move anywhere
+ // so that removed items do not move to the default (0,0)
+ if (!nextTransitionToSet)
+ moveTo(item->pos());
+
+ transition->startTransition(this, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget);
+ nextTransitionType = QQuickItemViewTransitioner::NoTransition;
+}
+
+void QQuickViewItem::stopTransition()
+{
+ if (transition) {
+ transition->cancel();
+ delete transition;
+ transition = 0;
+ }
+ resetTransitionData();
+ finishedTransition();
+}
+
+void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem)
+{
+ // Don't reset nextTransitionToSet - once it is set, it cannot be changed
+ // until the animation finishes since the itemX() and itemY() may be used
+ // to calculate positions for transitions for other items in the view.
+ nextTransitionType = type;
+ isTransitionTarget = isTargetItem;
+}
+
+bool QQuickViewItem::transitionWillChangePosition() const
+{
+ if (transitionRunning() && transition->m_toPos != nextTransitionTo)
+ return true;
+ return nextTransitionTo != item->pos();
+}
+
+void QQuickViewItem::finishedTransition()
+{
+ nextTransitionToSet = false;
+ nextTransitionTo = QPointF();
+}
+
+void QQuickViewItem::resetTransitionData()
+{
+ nextTransitionType = QQuickItemViewTransitioner::NoTransition;
+ isTransitionTarget = false;
+ nextTransitionTo = QPointF();
+ nextTransitionToSet = false;
+}
+
+
+QQuickViewTransitionAttached::QQuickViewTransitionAttached(QObject *parent)
+ : QObject(parent), m_item(0), m_index(-1)
+{
+}
+/*!
+ \qmlclass ViewTransition QQuickViewTransitionAttached
+ \inqmlmodule QtQuick 2
+ \ingroup qml-view-elements
+ \brief The ViewTransition attached property provides details on items under transition in a view.
+
+ With ListView and GridView, it is possible to specify transitions that should be applied whenever
+ the items in the view change as a result of modifications to the view's model. They both have the
+ following properties that can be set to the appropriate transitions to be run for various
+ operations:
+
+ \list
+ \o \c populate - the transition to run when a view is created, or when the model changes
+ \o \c add - the transition to apply to items that are added to the view
+ \o \c remove - the transition to apply to items that are removed from the view
+ \o \c move - the transition to apply to items that are moved within the view (i.e. as a result
+ of a move operation in the model)
+ \o \c displaced - the generic transition to be applied to any items that are displaced by an
+ add, move or remove operation
+ \o \c addDisplaced, \c removeDisplaced and \c moveDisplaced - the transitions to be applied when
+ items are displaced by add, move, or remove operations, respectively (these override the
+ generic displaced transition if specified)
+ \endlist
+
+ For the \l Row, \l Column, \l Grid and \l Flow positioner elements, which operate with collections of child
+ items rather than data models, the following properties are used instead:
+
+ \list
+ \o \c add - the transition to apply to items that are created for the positioner, added to
+ or reparented to the positioner, or items that have become \l {Item::}{visible}
+ \o \c move - the transition to apply to items that have moved within the positioner, including
+ when they are displaced due to the addition or removal of other items, or when items are otherwise
+ rearranged within the positioner, or when items are repositioned due to the resizing of other
+ items in the positioner
+ \endlist
+
+ View transitions have access to a ViewTransition attached property that
+ provides details of the items that are under transition and the operation that triggered the
+ transition. Since view transitions are run once per item, these details can be used to customise
+ each transition for each individual item.
+
+ The ViewTransition attached property provides the following properties specific to the item to
+ which the transition is applied:
+
+ \list
+ \o ViewTransition.item - the item that is under transition
+ \o ViewTransition.index - the index of this item
+ \o ViewTransition.destination - the (x,y) point to which this item is moving for the relevant view operation
+ \endlist
+
+ In addition, ViewTransition provides properties specific to the items which are the target
+ of the operation that triggered the transition:
+
+ \list
+ \o ViewTransition.targetIndexes - the indexes of the target items
+ \o ViewTransition.targetItems - the target items themselves
+ \endlist
+
+ (Note that for the \l Row, \l Column, \l Grid and \l Flow positioner elements, the \c move transition only
+ provides these two additional details when the transition is triggered by the addition of items
+ to a positioner.)
+
+ View transitions can be written without referring to any of the attributes listed
+ above. These attributes merely provide extra details that are useful for customising view
+ transitions.
+
+ Following is an introduction to view transitions and the ways in which the ViewTransition
+ attached property can be used to augment view transitions.
+
+
+ \section2 View transitions: a simple example
+
+ Here is a basic example of the use of view transitions. The view below specifies transitions for
+ the \c add and \c displaced properties, which will be run when items are added to the view:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-basic.qml 0
+
+ When the space key is pressed, adding an item to the model, the new item will fade in and
+ increase in scale over 400 milliseconds as it is added to the view. Also, any item that is
+ displaced by the addition of a new item will animate to its new position in the view over
+ 400 milliseconds, as specified by the \c displaced transition.
+
+ If five items were inserted in succession at index 0, the effect would be this:
+
+ \image viewtransitions-basic.gif
+
+ Notice that the NumberAnimation objects above do not need to specify a \c target to animate
+ the appropriate item. Also, the NumberAnimation in the \c addTransition does not need to specify
+ the \c to value to move the item to its correct position in the view. This is because the view
+ implicitly sets the \c target and \c to values with the correct item and final item position
+ values if these properties are not explicitly defined.
+
+ At its simplest, a view transition may just animate an item to its new position following a
+ view operation, just as the \c displaced transition does above, or animate some item properties,
+ as in the \c add transition above. Additionally, a view transition may make use of the
+ ViewTransition attached property to customise animation behavior for different items. Following
+ are some examples of how this can be achieved.
+
+
+ \section2 Using the ViewTransition attached property
+
+ As stated, the various ViewTransition properties provide details specific to the individual item
+ being transitioned as well as the operation that triggered the transition. In the animation above,
+ five items are inserted in succession at index 0. When the fifth and final insertion takes place,
+ adding "Item 4" to the view, the \c add transition is run once (for the inserted item) and the
+ \c displaced transition is run four times (once for each of the four existing items in the view).
+
+ At this point, if we examined the \c displaced transition that was run for the bottom displaced
+ item ("Item 0"), the ViewTransition property values provided to this transition would be as follows:
+
+ \table
+ \header
+ \o Property
+ \o Value
+ \o Explanation
+ \row
+ \o ViewTransition.item
+ \o "Item 0" delegate instance
+ \o The "Item 0" \l Rectangle object itself
+ \row
+ \o ViewTransition.index
+ \o \c int value of 4
+ \o The index of "Item 0" within the model following the add operation
+ \row
+ \o ViewTransition.destination
+ \o \l point value of (0, 120)
+ \o The position that "Item 0" is moving to
+ \row
+ \o ViewTransition.targetIndexes
+ \o \c int array, just contains the integer "0" (zero)
+ \o The index of "Item 4", the new item added to the view
+ \row
+ \o ViewTransition.targetItems
+ \o object array, just contains the "Item 4" delegate instance
+ \o The "Item 4" \l Rectangle object - the new item added to the view
+ \endtable
+
+ The ViewTransition.targetIndexes and ViewTransition.targetItems lists provide the items and
+ indexes of all delegate instances that are the targets of the relevant operation. For an add
+ operation, these are all the items that are added into the view; for a remove, these are all
+ the items removed from the view, and so on. (Note these lists will only contain references to
+ items that have been created within the view or its cached items; targets that are not within
+ the visible area of the view or within the item cache will not be accessible.)
+
+ So, while the ViewTransition.item, ViewTransition.index and ViewTransition.destination values
+ vary for each individual transition that is run, the ViewTransition.targetIndexes and
+ ViewTransition.targetItems values are the same for every \c add and \c displaced transition
+ that is triggered by a particular add operation.
+
+
+ \section3 Delaying animations based on index
+
+ Since each view transition is run once for each item affected by the transition, the ViewTransition
+ properties can be used within a transition to define custom behavior for each item's transition.
+ For example, the ListView in the previous example could use this information to create a ripple-type
+ effect on the movement of the displaced items.
+
+ This can be achieved by modifying the \c displaced transition so that it delays the animation of
+ each displaced item based on the difference between its index (provided by ViewTransition.index)
+ and the first removed index (provided by ViewTransition.targetIndexes):
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-delayedbyindex.qml 0
+
+ Each displaced item delays its animation by an additional 100 milliseconds, producing a subtle
+ ripple-type effect when items are displaced by the add, like this:
+
+ \image viewtransitions-delayedbyindex.gif
+
+
+ \section3 Animating items to intermediate positions
+
+ The ViewTransition.item property gives a reference to the item to which the transition is being
+ applied. This can be used to access any of the item's attributes, custom \c property values,
+ and so on.
+
+ Below is a modification of the \c displaced transition from the previous example. It adds a
+ ParallelAnimation with nested NumberAnimation objects that reference ViewTransition.item to access
+ each item's \c x and \c y values at the start of their transitions. This allows each item to
+ animate to an intermediate position relative to its starting point for the transition, before
+ animating to its final position in the view:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-intermediatemove.qml 0
+
+ Now, a displaced item will first move to a position of (20, 50) relative to its starting
+ position, and then to its final, correct position in the view:
+
+ \image viewtransitions-intermediatemove.gif
+
+ Since the final NumberAnimation does not specify a \c to value, the view implicitly sets this
+ value to the item's final position in the view, and so this last animation will move this item
+ to the correct place. If the transition requires the final position of the item for some calculation,
+ this is accessible through ViewTransition.destination.
+
+ Instead of using multiple NumberAnimations, you could use a PathAnimation to animate an item over
+ a curved path. For example, the \c add transition in the previous example could be augmented with
+ a PathAnimation as follows: to animate newly added items along a path:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-pathanim.qml 0
+
+ This animates newly added items along a path. Notice that each path is specified relative to
+ each item's final destination point, so that items inserted at different indexes start their
+ paths from different positions:
+
+ \image viewtransitions-pathanim.gif
+
+
+ \section2 Handling interrupted animations
+
+ A view transition may be interrupted at any time if a different view transition needs to be
+ applied while the original transition is in progress. For example, say Item A is inserted at index 0
+ and undergoes an "add" transition; then, Item B is inserted at index 0 in quick succession before
+ Item A's transition has finished. Since Item B is inserted before Item A, it will displace Item
+ A, causing the view to interrupt Item A's "add" transition mid-way and start a "displaced"
+ transition on Item A instead.
+
+ For simple animations that simply animate an item's movement to its final destination, this
+ interruption is unlikely to require additional consideration. However, if a transition changes other
+ properties, this interruption may cause unwanted side effects. Consider the first example on this
+ page, repeated below for convenience:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-basic.qml 0
+
+ If multiple items are added in rapid succession, without waiting for a previous transition
+ to finish, this is the result:
+
+ \image viewtransitions-interruptedbad.gif
+
+ Each newly added item undergoes an \c add transition, but before the transition can finish,
+ another item is added, displacing the previously added item. Because of this, the \c add
+ transition on the previously added item is interrupted and a \c displaced transition is
+ started on the item instead. Due to the interruption, the \c opacity and \c scale animations
+ have not completed, thus producing items with opacity and scale that are below 1.0.
+
+ To fix this, the \c displaced transition should additionally ensure the item properties are
+ set to the end values specified in the \c add transition, effectively resetting these values
+ whenever an item is displaced. In this case, it means setting the item opacity and scale to 1.0:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-interruptedgood.qml 0
+
+ Now, when an item's \c add transition is interrupted, its opacity and scale are animated to 1.0
+ upon displacement, avoiding the erroneous visual effects from before:
+
+ \image viewtransitions-interruptedgood.gif
+
+ The same principle applies to any combination of view transitions. An added item may be moved
+ before its add transition finishes, or a moved item may be removed before its moved transition
+ finishes, and so on; so, the rule of thumb is that every transition should handle the same set of
+ properties.
+
+
+ \section2 Restrictions regarding ScriptAction
+
+ When a view transition is initialized, any property bindings that refer to the ViewTransition
+ attached property are evaluated in preparation for the transition. Due to the nature of the
+ internal construction of a view transition, the attributes of the ViewTransition attached
+ property are only valid for the relevant item when the transition is initialized, and may not be
+ valid when the transition is actually run.
+
+ Therefore, a ScriptAction within a view transition should not refer to the ViewTransition
+ attached property, as it may not refer to the expected values at the time that the ScriptAction
+ is actually invoked. Consider the following example:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-scriptactionbad.qml 0
+
+ When the space key is pressed, three items are moved from index 5 to index 1. For each moved
+ item, the \c moveTransition sequence presumably animates the item's color to "yellow", then
+ animates it to its final position, then changes the item color back to "lightsteelblue" using a
+ ScriptAction. However, when run, the transition does not produce the intended result:
+
+ \image viewtransitions-scriptactionbad.gif
+
+ Only the last moved item is returned to the "lightsteelblue" color; the others remain yellow. This
+ is because the ScriptAction is not run until after the transition has already been initialized, by
+ which time the ViewTransition.item value has changed to refer to a different item; the item that
+ the script had intended to refer to is not the one held by ViewTransition.item at the time the
+ ScriptAction is actually invoked.
+
+ In this instance, to avoid this issue, the view could set the property using a PropertyAction
+ instead:
+
+ \snippet doc/src/snippets/declarative/viewtransitions/viewtransitions-scriptactiongood.qml 0
+
+ When the transition is initialized, the PropertyAction \c target will be set to the respective
+ ViewTransition.item for the transition and will later run with the correct item target as
+ expected.
+ */
+
+/*!
+ \qmlattachedproperty list QtQuick2::ViewTransition::index
+
+ This attached property holds the index of the item that is being
+ transitioned.
+
+ Note that if the item is being moved, this property holds the index that
+ the item is moving to, not from.
+*/
+
+/*!
+ \qmlattachedproperty list QtQuick2::ViewTransition::item
+
+ This attached property holds the the item that is being transitioned.
+
+ \warning This item should not be kept and referred to outside of the transition
+ as it may become invalid as the view changes.
+*/
+
+/*!
+ \qmlattachedproperty list QtQuick2::ViewTransition::destination
+
+ This attached property holds the final destination position for the transitioned
+ item within the view.
+
+ This property value is a \l point with \c x and \c y properties.
+*/
+
+/*!
+ \qmlattachedproperty list QtQuick2::ViewTransition::targetIndexes
+
+ This attached property holds a list of the indexes of the items in view
+ that are the target of the relevant operation.
+
+ The targets are the items that are the subject of the operation. For
+ an add operation, these are the items being added; for a remove, these
+ are the items being removed; for a move, these are the items being
+ moved.
+
+ For example, if the transition was triggered by an insert operation
+ that added two items at index 1 and 2, this targetIndexes list would
+ have the value [1,2].
+
+ \note The targetIndexes list only contains the indexes of items that are actually
+ in view, or will be in the view once the relevant operation completes.
+
+ \sa QtQuick2::ViewTransition::targetIndexes
+*/
+
+/*!
+ \qmlattachedproperty list QtQuick2::ViewTransition::targetItems
+
+ This attached property holds the list of items in view that are the
+ target of the relevant operation.
+
+ The targets are the items that are the subject of the operation. For
+ an add operation, these are the items being added; for a remove, these
+ are the items being removed; for a move, these are the items being
+ moved.
+
+ For example, if the transition was triggered by an insert operation
+ that added two items at index 1 and 2, this targetItems list would
+ contain these two items.
+
+ \note The targetItems list only contains items that are actually
+ in view, or will be in the view once the relevant operation completes.
+
+ \warning The objects in this list should not be kept and referred to
+ outside of the transition as the items may become invalid. The targetItems
+ are only valid when the Transition is initially created; this also means
+ they should not be used by ScriptAction objects in the Transition, which are
+ not evaluated until the transition is run.
+
+ \sa QtQuick2::ViewTransition::targetIndexes
+*/
+QQmlListProperty<QObject> QQuickViewTransitionAttached::targetItems()
+{
+ return QQmlListProperty<QObject>(this, m_targetItems);
+}
+
+QQuickViewTransitionAttached *QQuickViewTransitionAttached::qmlAttachedProperties(QObject *obj)
+{
+ return new QQuickViewTransitionAttached(obj);
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
new file mode 100644
index 0000000000..3fb43d6b96
--- /dev/null
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKITEMVIEWTRANSITION_P_P_H
+#define QQUICKITEMVIEWTRANSITION_P_P_H
+
+#include <private/qquicktransitionmanager_p_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Quick)
+
+class QQuickItem;
+class QQuickViewItem;
+class QQuickItemViewTransitionJob;
+
+
+class QQuickItemViewTransitionChangeListener
+{
+public:
+ QQuickItemViewTransitionChangeListener() {}
+ virtual ~QQuickItemViewTransitionChangeListener() {}
+
+ virtual void viewItemTransitionFinished(QQuickViewItem *item) = 0;
+};
+
+
+class QQuickItemViewTransitioner
+{
+public:
+ enum TransitionType {
+ NoTransition,
+ PopulateTransition,
+ AddTransition,
+ MoveTransition,
+ RemoveTransition
+ };
+
+ QQuickItemViewTransitioner();
+ virtual ~QQuickItemViewTransitioner();
+
+ bool canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const;
+ void transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget);
+
+ QQuickTransition *transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget);
+ const QList<int> &targetIndexes(QQuickItemViewTransitioner::TransitionType type) const;
+ const QList<QObject *> &targetItems(QQuickItemViewTransitioner::TransitionType type) const;
+
+ inline void setPopulateTransitionEnabled(bool b) { usePopulateTransition = b; }
+ inline void setChangeListener(QQuickItemViewTransitionChangeListener *obj) { changeListener = obj; }
+
+ QSet<QQuickItemViewTransitionJob *> runningJobs;
+
+ QList<int> addTransitionIndexes;
+ QList<int> moveTransitionIndexes;
+ QList<int> removeTransitionIndexes;
+ QList<QObject *> addTransitionTargets;
+ QList<QObject *> moveTransitionTargets;
+ QList<QObject *> removeTransitionTargets;
+
+ QQuickTransition *populateTransition;
+ QQuickTransition *addTransition;
+ QQuickTransition *addDisplacedTransition;
+ QQuickTransition *moveTransition;
+ QQuickTransition *moveDisplacedTransition;
+ QQuickTransition *removeTransition;
+ QQuickTransition *removeDisplacedTransition;
+ QQuickTransition *displacedTransition;
+
+private:
+ friend class QQuickItemViewTransitionJob;
+
+ QQuickItemViewTransitionChangeListener *changeListener;
+ bool usePopulateTransition;
+
+ void finishedTransition(QQuickItemViewTransitionJob *job, QQuickViewItem *item);
+};
+
+
+/*
+ An item in a view, that can be transitioned using QQuickViewTransitionJob.
+ */
+class QQuickViewItem
+{
+public:
+ QQuickViewItem(QQuickItem *i);
+ virtual ~QQuickViewItem();
+
+ qreal itemX() const;
+ qreal itemY() const;
+
+ void moveTo(const QPointF &pos);
+ void setVisible(bool visible);
+
+ bool transitionScheduledOrRunning() const;
+ bool transitionRunning() const;
+ bool isPendingRemoval() const;
+
+ bool prepareTransition(const QRectF &viewBounds);
+ void startTransition(QQuickItemViewTransitioner *transitioner);
+ void stopTransition();
+
+ QPointF nextTransitionTo;
+ QQuickItem *item;
+ QQuickItemViewTransitionJob *transition;
+ QQuickItemViewTransitioner::TransitionType nextTransitionType;
+ int index;
+ bool isTransitionTarget;
+ bool nextTransitionToSet;
+
+private:
+ friend class QQuickItemViewTransitioner;
+ friend class QQuickItemViewTransitionJob;
+ void setNextTransition(QQuickItemViewTransitioner::TransitionType, bool isTargetItem);
+ bool transitionWillChangePosition() const;
+ void finishedTransition();
+ void resetTransitionData();
+};
+
+
+class QQuickViewTransitionAttached : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int index READ index NOTIFY indexChanged)
+ Q_PROPERTY(QQuickItem* item READ item NOTIFY itemChanged)
+ Q_PROPERTY(QPointF destination READ destination NOTIFY destinationChanged)
+
+ Q_PROPERTY(QList<int> targetIndexes READ targetIndexes NOTIFY targetIndexesChanged)
+ Q_PROPERTY(QQmlListProperty<QObject> targetItems READ targetItems NOTIFY targetItemsChanged)
+
+public:
+ QQuickViewTransitionAttached(QObject *parent);
+
+ int index() const { return m_index; }
+ QQuickItem *item() const { return m_item; }
+ QPointF destination() const { return m_destination; }
+
+ QList<int> targetIndexes() const { return m_targetIndexes; }
+ QQmlListProperty<QObject> targetItems();
+
+ static QQuickViewTransitionAttached *qmlAttachedProperties(QObject *);
+
+signals:
+ void indexChanged();
+ void itemChanged();
+ void destinationChanged();
+
+ void targetIndexesChanged();
+ void targetItemsChanged();
+
+private:
+ friend class QQuickItemViewTransitionJob;
+ QPointF m_destination;
+ QList<int> m_targetIndexes;
+ QList<QObject *> m_targetItems;
+
+ QQuickItem *m_item;
+ int m_index;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickViewTransitionAttached)
+QML_DECLARE_TYPEINFO(QQuickViewTransitionAttached, QML_HAS_ATTACHED_PROPERTIES)
+
+QT_END_HEADER
+
+#endif // QQUICKITEMVIEWTRANSITION_P_P_H
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index beb607dde5..5e9a685cf5 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -93,7 +93,7 @@ public:
virtual FxViewItem *newViewItem(int index, QQuickItem *item);
virtual void initializeViewItem(FxViewItem *item);
- virtual void releaseItem(FxViewItem *item);
+ virtual bool releaseItem(FxViewItem *item);
virtual void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer);
virtual void repositionPackageItemAt(QQuickItem *item, int index);
virtual void resetFirstItemPosition(qreal pos = 0.0);
@@ -236,7 +236,7 @@ void QQuickViewSection::setLabelPositioning(int l)
class FxListItemSG : public FxViewItem
{
public:
- FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, own), section(0), view(v) {
+ FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, own), view(v) {
attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
if (attached)
static_cast<QQuickListViewAttached*>(attached)->setView(view);
@@ -244,12 +244,21 @@ public:
~FxListItemSG() {}
+ inline QQuickItem *section() const {
+ return attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : 0;
+ }
+ void setSection(QQuickItem *s) {
+ if (!attached)
+ attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
+ static_cast<QQuickListViewAttached*>(attached)->m_sectionItem = s;
+ }
+
qreal position() const {
- if (section) {
+ if (section()) {
if (view->orientation() == QQuickListView::Vertical)
- return section->y();
+ return section()->y();
else
- return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section->width()-section->x() : section->x());
+ return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -section()->width()-section()->x() : section()->x());
} else {
return itemPosition();
}
@@ -261,8 +270,8 @@ public:
return (view->effectiveLayoutDirection() == Qt::RightToLeft ? -item->width()-itemX() : itemX());
}
qreal size() const {
- if (section)
- return (view->orientation() == QQuickListView::Vertical ? item->height()+section->height() : item->width()+section->width());
+ if (section())
+ return (view->orientation() == QQuickListView::Vertical ? item->height()+section()->height() : item->width()+section()->width());
else
return (view->orientation() == QQuickListView::Vertical ? item->height() : item->width());
}
@@ -270,8 +279,8 @@ public:
return (view->orientation() == QQuickListView::Vertical ? item->height() : item->width());
}
qreal sectionSize() const {
- if (section)
- return (view->orientation() == QQuickListView::Vertical ? section->height() : section->width());
+ if (section())
+ return (view->orientation() == QQuickListView::Vertical ? section()->height() : section()->width());
return 0.0;
}
qreal endPosition() const {
@@ -285,14 +294,14 @@ public:
}
void setPosition(qreal pos) {
// position the section immediately even if there is a transition
- if (section) {
+ if (section()) {
if (view->orientation() == QQuickListView::Vertical) {
- section->setY(pos);
+ section()->setY(pos);
} else {
if (view->effectiveLayoutDirection() == Qt::RightToLeft)
- section->setX(-section->width()-pos);
+ section()->setX(-section()->width()-pos);
else
- section->setX(pos);
+ section()->setX(pos);
}
}
moveTo(pointForPosition(pos));
@@ -307,27 +316,23 @@ public:
return (x >= itemX() && x < itemX() + item->width() &&
y >= itemY() && y < itemY() + item->height());
}
- QQuickItemView *itemView() const {
- return view;
- }
- QQuickItem *section;
QQuickListView *view;
private:
QPointF pointForPosition(qreal pos) const {
if (view->orientation() == QQuickListView::Vertical) {
- if (section)
- pos += section->height();
+ if (section())
+ pos += section()->height();
return QPointF(itemX(), pos);
} else {
if (view->effectiveLayoutDirection() == Qt::RightToLeft) {
- if (section)
- pos += section->width();
+ if (section())
+ pos += section()->width();
return QPointF(-item->width() - pos, itemY());
} else {
- if (section)
- pos += section->width();
+ if (section())
+ pos += section()->width();
return QPointF(pos, itemY());
}
}
@@ -566,25 +571,31 @@ void QQuickListViewPrivate::initializeViewItem(FxViewItem *item)
}
}
-void QQuickListViewPrivate::releaseItem(FxViewItem *item)
+bool QQuickListViewPrivate::releaseItem(FxViewItem *item)
{
- if (item) {
- FxListItemSG* listItem = static_cast<FxListItemSG*>(item);
- if (listItem->section) {
- int i = 0;
- do {
- if (!sectionCache[i]) {
- sectionCache[i] = listItem->section;
- sectionCache[i]->setVisible(false);
- listItem->section = 0;
- break;
- }
- ++i;
- } while (i < sectionCacheSize);
- delete listItem->section;
- }
+ if (!item || !model)
+ return true;
+
+ QQuickListViewAttached *att = static_cast<QQuickListViewAttached*>(item->attached);
+
+ bool released = QQuickItemViewPrivate::releaseItem(item);
+ if (released && att && att->m_sectionItem) {
+ // We hold no more references to this item
+ int i = 0;
+ do {
+ if (!sectionCache[i]) {
+ sectionCache[i] = att->m_sectionItem;
+ sectionCache[i]->setVisible(false);
+ att->m_sectionItem = 0;
+ break;
+ }
+ ++i;
+ } while (i < sectionCacheSize);
+ delete att->m_sectionItem;
+ att->m_sectionItem = 0;
}
- QQuickItemViewPrivate::releaseItem(item);
+
+ return released;
}
bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool doBuffer)
@@ -629,7 +640,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
#endif
if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer))))
break;
- if (!canTransition(FxViewItemTransitionManager::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
+ if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(pos);
item->item->setVisible(!doBuffer);
pos += item->size() + spacing;
@@ -649,7 +660,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d
break;
--visibleIndex;
visiblePos -= item->size() + spacing;
- if (!canTransition(FxViewItemTransitionManager::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
+ if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(visiblePos);
item->item->setVisible(!doBuffer);
visibleItems.prepend(item);
@@ -944,18 +955,18 @@ void QQuickListViewPrivate::updateInlineSection(FxListItemSG *listItem)
if (listItem->attached->m_prevSection != listItem->attached->m_section
&& (sectionCriteria->labelPositioning() & QQuickViewSection::InlineLabels
|| (listItem->index == 0 && sectionCriteria->labelPositioning() & QQuickViewSection::CurrentLabelAtStart))) {
- if (!listItem->section) {
+ if (!listItem->section()) {
qreal pos = listItem->position();
- listItem->section = getSectionItem(listItem->attached->m_section);
+ listItem->setSection(getSectionItem(listItem->attached->m_section));
listItem->setPosition(pos);
} else {
- QQmlContext *context = QQmlEngine::contextForObject(listItem->section)->parentContext();
+ QQmlContext *context = QQmlEngine::contextForObject(listItem->section())->parentContext();
context->setContextProperty(QLatin1String("section"), listItem->attached->m_section);
}
- } else if (listItem->section) {
+ } else if (listItem->section()) {
qreal pos = listItem->position();
- releaseSectionItem(listItem->section);
- listItem->section = 0;
+ releaseSectionItem(listItem->section());
+ listItem->setSection(0);
listItem->setPosition(pos);
}
}
@@ -972,7 +983,7 @@ void QQuickListViewPrivate::updateStickySections()
QQuickItem *lastSectionItem = 0;
int index = 0;
while (index < visibleItems.count()) {
- if (QQuickItem *section = static_cast<FxListItemSG *>(visibleItems.at(index))->section) {
+ if (QQuickItem *section = static_cast<FxListItemSG *>(visibleItems.at(index))->section()) {
// Find the current section header and last visible section header
// and hide them if they will overlap a static section header.
qreal sectionPos = orient == QQuickListView::Vertical ? section->y() : section->x();
@@ -1173,9 +1184,9 @@ void QQuickListViewPrivate::initializeCurrentItem()
if (currentItem) {
FxListItemSG *listItem = static_cast<FxListItemSG *>(currentItem);
- // don't reposition the item if it's about to be transitioned to another position
+ // don't reposition the item if it is already in the visibleItems list
FxViewItem *actualItem = visibleItem(currentIndex);
- if ((!actualItem || !actualItem->transitionScheduledOrRunning())) {
+ if (!actualItem) {
if (currentIndex == visibleIndex - 1 && visibleItems.count()) {
// We can calculate exact postion in this case
listItem->setPosition(visibleItems.first()->position() - currentItem->size() - spacing);
@@ -1186,12 +1197,6 @@ void QQuickListViewPrivate::initializeCurrentItem()
}
}
- // Avoid showing section delegate twice. We still need the section heading so that
- // currentItem positioning works correctly.
- // This is slightly sub-optimal, but section heading caching minimizes the impact.
- if (listItem->section)
- listItem->section->setVisible(false);
-
if (visibleItems.isEmpty())
averageSize = listItem->size();
}
@@ -2245,10 +2250,11 @@ void QQuickListView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::ListView::populate
- This property holds the transition to apply to items that are initially created for a
- view.
- This transition is applied to all the items that are created when:
+ This property holds the transition to apply to the items that are initially created
+ for a view.
+
+ It is applied to all items that are created when:
\list
\o The view is first created
@@ -2278,10 +2284,10 @@ void QQuickListView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::ListView::add
- This property holds the transition to apply to items that are added within the view.
- The transition is applied to items that have been added to the visible area of the view. For
- example, here is a view that specifies such a transition:
+ This property holds the transition to apply to items that are added to the view.
+
+ For example, here is a view that specifies such a transition:
\code
ListView {
@@ -2295,8 +2301,8 @@ void QQuickListView::setSnapMode(SnapMode mode)
Whenever an item is added to the above view, the item will be animated from the position (100,100)
to its final x,y position within the view, over one second. The transition only applies to
the new items that are added to the view; it does not apply to the items below that are
- displaced by the addition of the new items. To animate the displaced items, set the \l
- addDisplaced property.
+ displaced by the addition of the new items. To animate the displaced items, set the \l displaced
+ or \l addDisplaced properties.
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
@@ -2310,11 +2316,11 @@ void QQuickListView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::ListView::addDisplaced
- This property holds the transition to apply to items in the view that are displaced by other
- items that have been added to the view.
- The transition is applied to items that are currently visible and have been displaced by newly
- added items. For example, here is a view that specifies such a transition:
+ This property holds the transition to apply to items within the view that are displaced by
+ the addition of other items to the view.
+
+ For example, here is a view that specifies such a transition:
\code
ListView {
@@ -2332,6 +2338,11 @@ void QQuickListView::setSnapMode(SnapMode mode)
the new item that has been added to the view; to animate the added items, set the \l add
property.
+ If an item is displaced by multiple types of operations at the same time, it is not defined as to
+ whether the addDisplaced, moveDisplaced or removeDisplaced transition will be applied. Additionally,
+ if it is not necessary to specify different transitions depending on whether an item is displaced
+ by an add, move or remove operation, consider setting the \l displaced property instead.
+
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
@@ -2339,16 +2350,16 @@ void QQuickListView::setSnapMode(SnapMode mode)
populated, or when the view's \l model changes. In those cases, the \l populate transition is
applied instead.
- \sa add, populate, ViewTransition
+ \sa displaced, add, populate, ViewTransition
*/
/*!
\qmlproperty Transition QtQuick2::ListView::move
- This property holds the transition to apply to items in the view that are moved by a move
- operation.
- The transition is applied to items that are moving within the view or are moving
- into the view as a result of a move operation in the view's model. For example:
+ This property holds the transition to apply to items in the view that are being moved due
+ to a move operation in the view's \l model.
+
+ For example, here is a view that specifies such a transition:
\code
ListView {
@@ -2359,10 +2370,11 @@ void QQuickListView::setSnapMode(SnapMode mode)
}
\endcode
- Whenever an item is moved within the above view, the item will be animated to its new position in
- the view over one second. The transition only applies to the items that are the subject of the
- move operation in the model; it does not apply to the items below them that are displaced by
- the move operation. To animate the displaced items, set the \l moveDisplaced property.
+ Whenever the \l model performs a move operation to move a particular set of indexes, the
+ respective items in the view will be animated to their new positions in the view over one
+ second. The transition only applies to the items that are the subject of the move operation
+ in the model; it does not apply to items below them that are displaced by the move operation.
+ To animate the displaced items, set the \l displaced or \l moveDisplaced properties.
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
@@ -2372,11 +2384,11 @@ void QQuickListView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::ListView::moveDisplaced
- This property holds the transition to apply to items in the view that are displaced by a
- move operation in the view.
- The transition is applied to items that are currently visible and have been displaced following
- a move operation in the view's model. For example, here is a view that specifies such a transition:
+ This property holds the transition to apply to items that are displaced by a move operation in
+ the view's \l model.
+
+ For example, here is a view that specifies such a transition:
\code
ListView {
@@ -2387,25 +2399,31 @@ void QQuickListView::setSnapMode(SnapMode mode)
}
\endcode
- Whenever an item moves within (or moves into) the above view, all items beneath it are
- displaced, causing them to move upwards (or sideways, if horizontally orientated) within the
- view. As this displacement occurs, the items' movement to their new x,y positions within the
- view will be animated by a NumberAnimation over one second, as specified. This transition is
- not applied to the item that are actually the subject of the move operation; to animate the
- moved items, set the \l move property.
+ Whenever the \l model performs a move operation to move a particular set of indexes, the items
+ between the source and destination indexes of the move operation are displaced, causing them
+ to move upwards or downwards (or sideways, if horizontally orientated) within the view. As this
+ displacement occurs, the items' movement to their new x,y positions within the view will be
+ animated by a NumberAnimation over one second, as specified. This transition is not applied to
+ the items that are the actual subjects of the move operation; to animate the moved items, set
+ the \l move property.
+
+ If an item is displaced by multiple types of operations at the same time, it is not defined as to
+ whether the addDisplaced, moveDisplaced or removeDisplaced transition will be applied. Additionally,
+ if it is not necessary to specify different transitions depending on whether an item is displaced
+ by an add, move or remove operation, consider setting the \l displaced property instead.
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
- \sa move, ViewTransition
+ \sa displaced, move, ViewTransition
*/
/*!
\qmlproperty Transition QtQuick2::ListView::remove
+
This property holds the transition to apply to items that are removed from the view.
- The transition is applied to items that have been removed from the visible area of the view. For
- example:
+ For example, here is a view that specifies such a transition:
\code
ListView {
@@ -2422,8 +2440,8 @@ void QQuickListView::setSnapMode(SnapMode mode)
Whenever an item is removed from the above view, the item will be animated to the position (100,100)
over one second, and in parallel will also change its opacity to 0. The transition
only applies to the items that are removed from the view; it does not apply to the items below
- them that are displaced by the removal of the items. To animate the displaced items, set the \l
- removeDisplaced property.
+ them that are displaced by the removal of the items. To animate the displaced items, set the
+ \l displaced or \l removeDisplaced properties.
Note that by the time the transition is applied, the item has already been removed from the
model; any references to the model data for the removed index will not be valid.
@@ -2439,11 +2457,11 @@ void QQuickListView::setSnapMode(SnapMode mode)
/*!
\qmlproperty Transition QtQuick2::ListView::removeDisplaced
+
This property holds the transition to apply to items in the view that are displaced by the
removal of other items in the view.
- The transition is applied to items that are currently visible and have been displaced by
- the removal of items. For example, here is a view that specifies such a transition:
+ For example, here is a view that specifies such a transition:
\code
ListView {
@@ -2461,12 +2479,52 @@ void QQuickListView::setSnapMode(SnapMode mode)
the item that has actually been removed from the view; to animate the removed items, set the
\l remove property.
+ If an item is displaced by multiple types of operations at the same time, it is not defined as to
+ whether the addDisplaced, moveDisplaced or removeDisplaced transition will be applied. Additionally,
+ if it is not necessary to specify different transitions depending on whether an item is displaced
+ by an add, move or remove operation, consider setting the \l displaced property instead.
+
For more details and examples on how to use view transitions, see the ViewTransition
documentation.
- \sa remove, ViewTransition
+ \sa displaced, remove, ViewTransition
*/
+/*!
+ \qmlproperty Transition QtQuick2::ListView::displaced
+ This property holds the generic transition to apply to items that have been displaced by
+ any model operation that affects the view.
+
+ This is a convenience for specifying the generic transition to be applied to any items
+ that are displaced by an add, move or remove operation, without having to specify the
+ individual addDisplaced, moveDisplaced and removeDisplaced properties. For example, here
+ is a view that specifies a displaced transition:
+
+ \code
+ ListView {
+ ...
+ displaced: Transition {
+ NumberAnimation { properties: "x,y"; duration: 1000 }
+ }
+ }
+ \endcode
+
+ When any item is added, moved or removed within the above view, the items below it are
+ displaced, causing them to move down (or sideways, if horizontally orientated) within the
+ view. As this displacement occurs, the items' movement to their new x,y positions within
+ the view will be animated by a NumberAnimation over one second, as specified.
+
+ If a view specifies this generic displaced transition as well as a specific addDisplaced,
+ moveDisplaced or removeDisplaced transition, the more specific transition will be used
+ instead of the generic displaced transition when the relevant operation occurs, providing that
+ the more specific transition has not been disabled (by setting \l {Transition::enabled}{enabled}
+ to false). If it has indeed been disabled, the generic displaced transition is applied instead.
+
+ For more details and examples on how to use view transitions, see the ViewTransition
+ documentation.
+
+ \sa addDisplaced, moveDisplaced, removeDisplaced, ViewTransition
+*/
void QQuickListView::viewportMoved()
{
@@ -2729,7 +2787,8 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
insertResult->changedFirstItem = true;
if (!change.isMove()) {
addedItems->append(item);
- transitionNextReposition(item, FxViewItemTransitionManager::AddTransition, true);
+ if (transitioner)
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true);
}
insertResult->sizeChangesBeforeVisiblePos += item->size() + spacing;
pos -= item->size() + spacing;
@@ -2755,11 +2814,12 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
if (change.isMove()) {
// we know this is a move target, since move displaced items that are
// shuffled into view due to a move would be added in refill()
- if (canTransition(FxViewItemTransitionManager::MoveTransition, true) && newItem)
+ if (newItem && transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition, true))
movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
} else {
addedItems->append(item);
- transitionNextReposition(item, FxViewItemTransitionManager::AddTransition, true);
+ if (transitioner)
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true);
}
insertResult->sizeChangesAfterVisiblePos += item->size() + spacing;
pos += item->size() + spacing;
@@ -2771,10 +2831,12 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &
FxViewItem *item = visibleItems.at(index);
if (item->index != -1)
item->index += count;
- if (change.isMove())
- transitionNextReposition(item, FxViewItemTransitionManager::MoveTransition, false);
- else
- transitionNextReposition(item, FxViewItemTransitionManager::AddTransition, false);
+ if (transitioner) {
+ if (change.isMove())
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false);
+ else
+ transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, false);
+ }
}
updateVisibleIndex();
@@ -2786,6 +2848,9 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
{
Q_UNUSED(insertionResult);
+ if (!transitioner)
+ return;
+
int markerItemIndex = -1;
for (int i=0; i<visibleItems.count(); i++) {
if (visibleItems[i]->index == afterModelIndex) {
@@ -2805,7 +2870,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex
if (!listItem->transitionScheduledOrRunning()) {
qreal pos = listItem->position();
listItem->setPosition(pos - sizeRemoved);
- transitionNextReposition(listItem, FxViewItemTransitionManager::RemoveTransition, false);
+ transitioner->transitionNextReposition(listItem, QQuickItemViewTransitioner::RemoveTransition, false);
listItem->setPosition(pos);
}
}
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index 239647a954..ef989ba839 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -181,7 +181,7 @@ class QQuickListViewAttached : public QQuickItemViewAttached
public:
QQuickListViewAttached(QObject *parent)
- : QQuickItemViewAttached(parent), m_view(0) {}
+ : QQuickItemViewAttached(parent), m_view(0), m_sectionItem(0) {}
~QQuickListViewAttached() {}
Q_PROPERTY(QQuickListView *view READ view NOTIFY viewChanged)
@@ -198,6 +198,7 @@ Q_SIGNALS:
public:
QQmlGuard<QQuickListView> m_view;
+ QQuickItem *m_sectionItem;
};
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 739f74d69a..e1d0457916 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -109,8 +109,11 @@ QQuickBasePositioner::QQuickBasePositioner(QQuickBasePositionerPrivate &dd, Posi
QQuickBasePositioner::~QQuickBasePositioner()
{
Q_D(QQuickBasePositioner);
+ delete d->transitioner;
for (int i = 0; i < positionedItems.count(); ++i)
d->unwatchChanges(positionedItems.at(i).item);
+ for (int i = 0; i < unpositionedItems.count(); ++i)
+ d->unwatchChanges(unpositionedItems.at(i).item);
positionedItems.clear();
}
@@ -140,31 +143,36 @@ void QQuickBasePositioner::setSpacing(qreal s)
QQuickTransition *QQuickBasePositioner::move() const
{
Q_D(const QQuickBasePositioner);
- return d->moveTransition;
+ return d->transitioner ? d->transitioner->displacedTransition : 0;
}
void QQuickBasePositioner::setMove(QQuickTransition *mt)
{
Q_D(QQuickBasePositioner);
- if (mt == d->moveTransition)
+ if (!d->transitioner)
+ d->transitioner = new QQuickItemViewTransitioner;
+ if (mt == d->transitioner->displacedTransition)
return;
- d->moveTransition = mt;
+
+ d->transitioner->displacedTransition = mt;
emit moveChanged();
}
QQuickTransition *QQuickBasePositioner::add() const
{
Q_D(const QQuickBasePositioner);
- return d->addTransition;
+ return d->transitioner ? d->transitioner->addTransition : 0;
}
void QQuickBasePositioner::setAdd(QQuickTransition *add)
{
Q_D(QQuickBasePositioner);
- if (add == d->addTransition)
+ if (!d->transitioner)
+ d->transitioner = new QQuickItemViewTransitioner;
+ if (add == d->transitioner->addTransition)
return;
- d->addTransition = add;
+ d->transitioner->addTransition = add;
emit addChanged();
}
@@ -187,6 +195,9 @@ void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &v
if (idx >= 0) {
d->unwatchChanges(child);
positionedItems.remove(idx);
+ } else if ((idx = unpositionedItems.find(posItem)) >= 0) {
+ d->unwatchChanges(child);
+ unpositionedItems.remove(idx);
}
d->setPositioningDirty();
}
@@ -213,6 +224,7 @@ void QQuickBasePositioner::prePositioning()
for (int ii = 0; ii < unpositionedItems.count(); ii++)
oldItems.append(unpositionedItems[ii]);
unpositionedItems.clear();
+ int addedIndex = -1;
for (int ii = 0; ii < children.count(); ++ii) {
QQuickItem *child = children.at(ii);
@@ -224,9 +236,22 @@ void QQuickBasePositioner::prePositioning()
posItem.isNew = true;
if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
posItem.isVisible = false;
+ posItem.index = -1;
unpositionedItems.append(posItem);
} else {
+ posItem.index = positionedItems.count();
positionedItems.append(posItem);
+
+ if (d->transitioner) {
+ if (addedIndex < 0)
+ addedIndex = posItem.index;
+ PositionedItem *theItem = &positionedItems[positionedItems.count()-1];
+
+ d->transitioner->transitionNextReposition(theItem,
+ QQuickItemViewTransitioner::AddTransition, true);
+ d->transitioner->addTransitionIndexes << posItem.index;
+ d->transitioner->addTransitionTargets << posItem.item;
+ }
}
} else {
PositionedItem *item = &oldItems[wIdx];
@@ -234,75 +259,93 @@ void QQuickBasePositioner::prePositioning()
// i.e. their positioning is not affected if an ancestor is hidden.
if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
item->isVisible = false;
+ item->index = -1;
unpositionedItems.append(*item);
} else if (!item->isVisible) {
+ // item changed from non-visible to visible, treat it as a "new" item
item->isVisible = true;
item->isNew = true;
+ item->index = positionedItems.count();
positionedItems.append(*item);
+
+ if (d->transitioner) {
+ if (addedIndex < 0)
+ addedIndex = item->index;
+ d->transitioner->transitionNextReposition(&positionedItems[positionedItems.count()-1],
+ QQuickItemViewTransitioner::AddTransition, true);
+ d->transitioner->addTransitionIndexes << item->index;
+ d->transitioner->addTransitionTargets << item->item;
+ }
} else {
item->isNew = false;
+ item->index = positionedItems.count();
positionedItems.append(*item);
}
}
}
+
+ if (d->transitioner) {
+ for (int i=0; i<positionedItems.count(); i++) {
+ if (!positionedItems[i].isNew) {
+ if (addedIndex >= 0) {
+ d->transitioner->transitionNextReposition(&positionedItems[i], QQuickItemViewTransitioner::AddTransition, false);
+ } else {
+ // just queue the item for a move-type displace - if the item hasn't
+ // moved anywhere, it won't be transitioned anyway
+ d->transitioner->transitionNextReposition(&positionedItems[i], QQuickItemViewTransitioner::MoveTransition, false);
+ }
+ }
+ }
+ }
+
QSizeF contentSize(0,0);
reportConflictingAnchors();
if (!d->anchorConflict) {
doPositioning(&contentSize);
updateAttachedProperties();
}
- if (!d->addActions.isEmpty() || !d->moveActions.isEmpty())
- finishApplyTransitions();
+
+ if (d->transitioner) {
+ QRectF viewBounds;
+ for (int i=0; i<positionedItems.count(); i++) {
+ if (positionedItems[i].prepareTransition(viewBounds))
+ positionedItems[i].startTransition(d->transitioner);
+ }
+ d->transitioner->addTransitionIndexes.clear();
+ d->transitioner->addTransitionTargets.clear();
+ }
+
d->doingPositioning = false;
+
//Set implicit size to the size of its children
setImplicitSize(contentSize.width(), contentSize.height());
}
-void QQuickBasePositioner::positionX(qreal x, const PositionedItem &target)
+void QQuickBasePositioner::positionItem(qreal x, qreal y, PositionedItem *target)
{
Q_D(QQuickBasePositioner);
- if (d->type == Horizontal || d->type == Both) {
- if (target.isNew) {
- if (!d->addTransition || !d->addTransition->enabled())
- target.item->setX(x);
- else
- d->addActions << QQuickAction(target.item, QLatin1String("x"), QVariant(x));
- } else if (x != target.item->x()) {
- if (!d->moveTransition || !d->moveTransition->enabled())
- target.item->setX(x);
- else
- d->moveActions << QQuickAction(target.item, QLatin1String("x"), QVariant(x));
- }
+ if ( (target->itemX() != x || target->itemY() != y)
+ && d->type == Both) {
+ target->moveTo(QPointF(x, y));
}
}
-void QQuickBasePositioner::positionY(qreal y, const PositionedItem &target)
+void QQuickBasePositioner::positionItemX(qreal x, PositionedItem *target)
{
Q_D(QQuickBasePositioner);
- if (d->type == Vertical || d->type == Both) {
- if (target.isNew) {
- if (!d->addTransition || !d->addTransition->enabled())
- target.item->setY(y);
- else
- d->addActions << QQuickAction(target.item, QLatin1String("y"), QVariant(y));
- } else if (y != target.item->y()) {
- if (!d->moveTransition || !d->moveTransition->enabled())
- target.item->setY(y);
- else
- d->moveActions << QQuickAction(target.item, QLatin1String("y"), QVariant(y));
- }
+ if (target->itemX() != x
+ && (d->type == Horizontal || d->type == Both)) {
+ target->moveTo(QPointF(x, target->itemY()));
}
}
-void QQuickBasePositioner::finishApplyTransitions()
+void QQuickBasePositioner::positionItemY(qreal y, PositionedItem *target)
{
Q_D(QQuickBasePositioner);
- // Note that if a transition is not set the transition manager will
- // apply the changes directly, in the case add/move aren't set
- d->addTransitionManager.transition(d->addActions, d->addTransition);
- d->moveTransitionManager.transition(d->moveActions, d->moveTransition);
- d->addActions.clear();
- d->moveActions.clear();
+ if (target->itemY() != y
+ && (d->type == Vertical || d->type == Both)) {
+ target->moveTo(QPointF(target->itemX(), y));
+ }
}
QQuickPositionerAttached *QQuickBasePositioner::qmlAttachedProperties(QObject *obj)
@@ -496,30 +539,42 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem)
/*!
\qmlproperty Transition QtQuick2::Column::add
- This property holds the transition to be applied when adding an
- item to the positioner. The transition will only be applied to the
- added item(s). Positioner transitions will only affect the
- position (x, y) of items.
+ This property holds the transition to be run for items that are added to this
+ positioner. For a positioner, this applies to:
- For a positioner, adding an item can mean that either the object
- has been created or reparented, and thus is now a child or the
- positioner, or that the object has changed its \l visible property
- from false to true, and thus is now visible.
+ \list
+ \o Items that are created or reparented as a child of the positioner
+ \o Child items that change their \l visible property from false to true, and thus
+ are now visible
+ \endlist
- \sa move
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being added. See the \l ViewTransition documentation for more details
+ and examples on using these transitions.
+
+ \sa move, ViewTransition, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Column::move
- This property holds the transition to apply to any item that has moved
- within the positioner. Positioner transitions will only affect
- the position (x, y) of items.
+ This property holds the transition to run for items that have moved within the
+ positioner. For a positioner, this applies to:
+
+ \list
+ \o Child items that move when they are displaced due to the addition, removal or
+ rearrangement of other items in the positioner
+ \o Child items that are repositioned due to the resizing of other items in the positioner
+ \endlist
+
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being moved. Note, however, that for this move transition, the
+ ViewTransition.targetIndexes and ViewTransition.targetItems lists are only set when
+ this transition is triggered by the addition of other items in the positioner; in other
+ cases, these lists will be empty.
- This transition is applied to items that are displaced as a result of the
- addition or removal of other items in the positioner, or when items move due to
- a move operation in a related model, or when items resize themselves.
+ See the \l ViewTransition documentation for more details and examples on using these transitions.
- \sa add, {qml/positioners}{Positioners example}
+ \sa add, ViewTransition, {qml/positioners}{Positioners example}
*/
/*!
\qmlproperty real QtQuick2::Column::spacing
@@ -540,11 +595,8 @@ void QQuickColumn::doPositioning(QSizeF *contentSize)
qreal voffset = 0;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
- const PositionedItem &child = positionedItems.at(ii);
-
- if (child.item->y() != voffset)
- positionY(voffset, child);
-
+ PositionedItem &child = positionedItems[ii];
+ positionItemY(voffset, &child);
contentSize->setWidth(qMax(contentSize->width(), child.item->width()));
voffset += child.item->height();
@@ -620,42 +672,42 @@ void QQuickColumn::reportConflictingAnchors()
/*!
\qmlproperty Transition QtQuick2::Row::add
- This property holds the transition to be applied when adding an
- item to the positioner. The transition will only be applied to the
- added item(s). Positioner transitions will only affect the
- position (x, y) of items.
+ This property holds the transition to be run for items that are added to this
+ positioner. For a positioner, this applies to:
- For a positioner, adding an item can mean that either the object
- has been created or reparented, and thus is now a child or the
- positioner, or that the object has changed its \l visible property
- from false to true, and thus is now visible.
+ \list
+ \o Items that are created or reparented as a child of the positioner
+ \o Child items that change their \l visible property from false to true, and thus
+ are now visible
+ \endlist
+
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being added. See the \l ViewTransition documentation for more details
+ and examples on using these transitions.
- \sa move
+ \sa move, ViewTransition, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Row::move
- This property holds the transition to apply to any item that has moved
- within the positioner. Positioner transitions will only affect
- the position (x, y) of items.
-
- This transition is applied to items that are displaced as a result of the
- addition or removal of other items in the positioner, or when items move due to
- a move operation in a related model, or when items resize themselves.
-
- \qml
- Row {
- id: positioner
- move: Transition {
- NumberAnimation {
- properties: "x"
- duration: 1000
- }
- }
- }
- \endqml
+ This property holds the transition to run for items that have moved within the
+ positioner. For a positioner, this applies to:
+
+ \list
+ \o Child items that move when they are displaced due to the addition, removal or
+ rearrangement of other items in the positioner
+ \o Child items that are repositioned due to the resizing of other items in the positioner
+ \endlist
- \sa add, {qml/positioners}{Positioners example}
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being moved. Note, however, that for this move transition, the
+ ViewTransition.targetIndexes and ViewTransition.targetItems lists are only set when
+ this transition is triggered by the addition of other items in the positioner; in other
+ cases, these lists will be empty.
+
+ See the \l ViewTransition documentation for more details and examples on using these transitions.
+
+ \sa add, ViewTransition, {qml/positioners}{Positioners example}
*/
/*!
\qmlproperty real QtQuick2::Row::spacing
@@ -731,11 +783,10 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
QList<qreal> hoffsets;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
- const PositionedItem &child = positionedItems.at(ii);
+ PositionedItem &child = positionedItems[ii];
if (d->isLeftToRight()) {
- if (child.item->x() != hoffset)
- positionX(hoffset, child);
+ positionItemX(hoffset, &child);
} else {
hoffsets << hoffset;
}
@@ -762,10 +813,9 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
int acc = 0;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
- const PositionedItem &child = positionedItems.at(ii);
+ PositionedItem &child = positionedItems[ii];
hoffset = end - hoffsets[acc++] - child.item->width();
- if (child.item->x() != hoffset)
- positionX(hoffset, child);
+ positionItemX(hoffset, &child);
}
}
@@ -834,41 +884,42 @@ void QQuickRow::reportConflictingAnchors()
/*!
\qmlproperty Transition QtQuick2::Grid::add
- This property holds the transition to be applied when adding an
- item to the positioner. The transition will only be applied to the
- added item(s). Positioner transitions will only affect the
- position (x, y) of items.
+ This property holds the transition to be run for items that are added to this
+ positioner. For a positioner, this applies to:
- For a positioner, adding an item can mean that either the object
- has been created or reparented, and thus is now a child or the
- positioner, or that the object has changed its \l visible property
- from false to true, and thus is now visible.
+ \list
+ \o Items that are created or reparented as a child of the positioner
+ \o Child items that change their \l visible property from false to true, and thus
+ are now visible
+ \endlist
+
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being added. See the \l ViewTransition documentation for more details
+ and examples on using these transitions.
- \sa move
+ \sa move, ViewTransition, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Grid::move
- This property holds the transition to apply to any item that has moved
- within the positioner. Positioner transitions will only affect
- the position (x, y) of items.
+ This property holds the transition to run for items that have moved within the
+ positioner. For a positioner, this applies to:
- This transition is applied to items that are displaced as a result of the
- addition or removal of other items in the positioner, or when items move due to
- a move operation in a related model, or when items resize themselves.
+ \list
+ \o Child items that move when they are displaced due to the addition, removal or
+ rearrangement of other items in the positioner
+ \o Child items that are repositioned due to the resizing of other items in the positioner
+ \endlist
- \qml
- Grid {
- move: Transition {
- NumberAnimation {
- properties: "x,y"
- duration: 1000
- }
- }
- }
- \endqml
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being moved. Note, however, that for this move transition, the
+ ViewTransition.targetIndexes and ViewTransition.targetItems lists are only set when
+ this transition is triggered by the addition of other items in the positioner; in other
+ cases, these lists will be empty.
+
+ See the \l ViewTransition documentation for more details and examples on using these transitions.
- \sa add, {qml/positioners}{Positioners example}
+ \sa add, ViewTransition, {qml/positioners}{Positioners example}
*/
/*!
\qmlproperty qreal QtQuick2::Grid::spacing
@@ -1155,14 +1206,11 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
int curRow =0;
int curCol =0;
for (int i = 0; i < positionedItems.count(); ++i) {
- const PositionedItem &child = positionedItems.at(i);
+ PositionedItem &child = positionedItems[i];
qreal childXOffset = xoffset;
if (!d->isLeftToRight())
childXOffset -= child.item->width();
- if ((child.item->x() != childXOffset) || (child.item->y() != yoffset)) {
- positionX(childXOffset, child);
- positionY(yoffset, child);
- }
+ positionItem(childXOffset, yoffset, &child);
if (m_flow == LeftToRight) {
if (d->isLeftToRight())
@@ -1249,42 +1297,42 @@ void QQuickGrid::reportConflictingAnchors()
/*!
\qmlproperty Transition QtQuick2::Flow::add
- This property holds the transition to be applied when adding an
- item to the positioner. The transition will only be applied to the
- added item(s). Positioner transitions will only affect the
- position (x, y) of items.
+ This property holds the transition to be run for items that are added to this
+ positioner. For a positioner, this applies to:
+
+ \list
+ \o Items that are created or reparented as a child of the positioner
+ \o Child items that change their \l visible property from false to true, and thus
+ are now visible
+ \endlist
- For a positioner, adding an item can mean that either the object
- has been created or reparented, and thus is now a child or the
- positioner, or that the object has changed its \l visible property
- from false to true, and thus is now visible.
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being added. See the \l ViewTransition documentation for more details
+ and examples on using these transitions.
- \sa move
+ \sa move, ViewTransition, {declarative/positioners}{Positioners example}
*/
/*!
\qmlproperty Transition QtQuick2::Flow::move
- This property holds the transition to apply to any item that has moved
- within the positioner. Positioner transitions will only affect
- the position (x, y) of items.
-
- This transition is applied to items that are displaced as a result of the
- addition or removal of other items in the positioner, or when items move due to
- a move operation in a related model, or when items resize themselves.
-
- \qml
- Flow {
- id: positioner
- move: Transition {
- NumberAnimation {
- properties: "x,y"
- ease: "easeOutBounce"
- }
- }
- }
- \endqml
+ This property holds the transition to run for items that have moved within the
+ positioner. For a positioner, this applies to:
+
+ \list
+ \o Child items that move when they are displaced due to the addition, removal or
+ rearrangement of other items in the positioner
+ \o Child items that are repositioned due to the resizing of other items in the positioner
+ \endlist
+
+ The transition can use the \l ViewTransition property to access more details about
+ the item that is being moved. Note, however, that for this move transition, the
+ ViewTransition.targetIndexes and ViewTransition.targetItems lists are only set when
+ this transition is triggered by the addition of other items in the positioner; in other
+ cases, these lists will be empty.
+
+ See the \l ViewTransition documentation for more details and examples on using these transitions.
- \sa add, {qml/positioners}{Positioners example}
+ \sa add, ViewTransition, {qml/positioners}{Positioners example}
*/
/*!
\qmlproperty real QtQuick2::Flow::spacing
@@ -1409,7 +1457,7 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
QList<qreal> hoffsets;
for (int i = 0; i < positionedItems.count(); ++i) {
- const PositionedItem &child = positionedItems.at(i);
+ PositionedItem &child = positionedItems[i];
if (d->flow == LeftToRight) {
if (widthValid() && hoffset && hoffset + child.item->width() > width()) {
@@ -1426,13 +1474,11 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
}
if (d->isLeftToRight()) {
- if (child.item->x() != hoffset)
- positionX(hoffset, child);
+ positionItem(hoffset, voffset, &child);
} else {
hoffsets << hoffset;
+ positionItemY(voffset, &child);
}
- if (child.item->y() != voffset)
- positionY(voffset, child);
contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width()));
contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height()));
@@ -1457,10 +1503,9 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
end = contentSize->width();
int acc = 0;
for (int i = 0; i < positionedItems.count(); ++i) {
- const PositionedItem &child = positionedItems.at(i);
+ PositionedItem &child = positionedItems[i];
hoffset = end - hoffsets[acc++] - child.item->width();
- if (child.item->x() != hoffset)
- positionX(hoffset, child);
+ positionItemX(hoffset, &child);
}
}
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index a2ad572c0e..8921bfa39b 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -43,6 +43,7 @@
#define QQUICKPOSITIONERS_P_H
#include "qquickimplicitsizeitem_p.h"
+#include "qquickitemviewtransition_p.h"
#include <QtQuick/private/qquickstate_p.h>
#include <private/qpodvector_p.h>
@@ -96,6 +97,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickBasePositioner : public QQuickImplicitSizeIte
Q_PROPERTY(QQuickTransition *add READ add WRITE setAdd NOTIFY addChanged)
public:
enum PositionerType { None = 0x0, Horizontal = 0x1, Vertical = 0x2, Both = 0x3 };
+
QQuickBasePositioner(PositionerType, QQuickItem *parent);
~QQuickBasePositioner();
@@ -116,7 +118,6 @@ protected:
QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
virtual void componentComplete();
virtual void itemChange(ItemChange, const ItemChangeData &);
- void finishApplyTransitions();
virtual void updatePolish();
@@ -131,19 +132,22 @@ protected Q_SLOTS:
protected:
virtual void doPositioning(QSizeF *contentSize)=0;
virtual void reportConflictingAnchors()=0;
- class PositionedItem {
+
+ class PositionedItem : public QQuickViewItem
+ {
public :
- PositionedItem(QQuickItem *i) : item(i), isNew(false), isVisible(true) {}
+ PositionedItem(QQuickItem *i) : QQuickViewItem(i), isNew(false), isVisible(true) {}
bool operator==(const PositionedItem &other) const { return other.item == item; }
- QQuickItem *item;
+
bool isNew;
bool isVisible;
};
QPODVector<PositionedItem,8> positionedItems;
QPODVector<PositionedItem,8> unpositionedItems;//Still 'in' the positioner, just not positioned
- void positionX(qreal,const PositionedItem &target);
- void positionY(qreal,const PositionedItem &target);
+ void positionItem(qreal x, qreal y, PositionedItem *target);
+ void positionItemX(qreal, PositionedItem *target);
+ void positionItemY(qreal, PositionedItem *target);
private:
Q_DISABLE_COPY(QQuickBasePositioner)
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 39ca806b5e..21fa67574b 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -66,6 +66,8 @@
QT_BEGIN_NAMESPACE
+class QQuickItemViewTransitioner;
+
class QQuickBasePositionerPrivate : public QQuickImplicitSizeItemPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickBasePositioner)
@@ -73,7 +75,7 @@ class QQuickBasePositionerPrivate : public QQuickImplicitSizeItemPrivate, public
public:
QQuickBasePositionerPrivate()
: spacing(0), type(QQuickBasePositioner::None)
- , moveTransition(0), addTransition(0), positioningDirty(false)
+ , transitioner(0), positioningDirty(false)
, doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
{
}
@@ -87,12 +89,7 @@ public:
qreal spacing;
QQuickBasePositioner::PositionerType type;
- QQuickTransition *moveTransition;
- QQuickTransition *addTransition;
- QQuickStateOperation::ActionList addActions;
- QQuickStateOperation::ActionList moveActions;
- QQuickTransitionManager addTransitionManager;
- QQuickTransitionManager moveTransitionManager;
+ QQuickItemViewTransitioner *transitioner;
void watchChanges(QQuickItem *other);
void unwatchChanges(QQuickItem* other);
diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp
index 817a6b411a..e0535ed77e 100644
--- a/src/quick/items/qquicksprite.cpp
+++ b/src/quick/items/qquicksprite.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -145,7 +145,7 @@ QT_BEGIN_NAMESPACE
will repeat itself after completing.
*/
/*!
- \qmlproperty int QtQuick2::Sprite::frames
+ \qmlproperty int QtQuick2::Sprite::frameCount
Number of frames in this sprite.
*/
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index 7c5c20bb50..85e3ed8b16 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -48,6 +48,7 @@
#include <QQmlListProperty>
#include <QtQuick/private/qquickpixmapcache_p.h>
#include "qquickspriteengine_p.h"
+#include <QDebug>
QT_BEGIN_HEADER
@@ -60,7 +61,8 @@ class QQuickSprite : public QQuickStochasticState
//Renderers have to query this hint when advancing frames
Q_PROPERTY(bool reverse READ reverse WRITE setReverse NOTIFY reverseChanged)
Q_PROPERTY(bool frameSync READ frameSync WRITE setFrameSync NOTIFY frameSyncChanged)
- Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged)
+ Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY frameCountChanged)
+ Q_PROPERTY(int frameCount READ frameCount WRITE setFrameCount NOTIFY frameCountChanged)
//If frame height or width is not specified, it is assumed to be a single long row of square frames.
//Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used.
Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged)
@@ -101,6 +103,11 @@ public:
return m_frames;
}
+ int frameCount() const
+ {
+ return m_frames;
+ }
+
int frameX() const
{
return m_frameX;
@@ -158,7 +165,7 @@ signals:
void reverseChanged(bool arg);
- void framesChanged(int arg);
+ void frameCountChanged(int arg);
void frameXChanged(int arg);
@@ -211,9 +218,15 @@ public slots:
void setFrames(int arg)
{
+ qWarning() << "Sprite::frames has been renamed Sprite::frameCount";
+ setFrameCount(arg);
+ }
+
+ void setFrameCount(int arg)
+ {
if (m_frames != arg) {
m_frames = arg;
- emit framesChanged(arg);
+ emit frameCountChanged(arg);
}
}
@@ -278,7 +291,8 @@ private slots:
private:
friend class QQuickImageParticle;
- friend class QQuickSpriteImage;
+ friend class QQuickSpriteSequence;
+ friend class QQuickAnimatedSprite;
friend class QQuickSpriteEngine;
friend class QQuickStochasticEngine;
int m_generatedCount;
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 5a78472b45..1c35688c29 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 751b75f231..3763509462 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
new file mode 100644
index 0000000000..ce0a246748
--- /dev/null
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -0,0 +1,482 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickspritesequence_p.h"
+#include "qquicksprite_p.h"
+#include "qquickspriteengine_p.h"
+#include <QtQuick/private/qsgcontext_p.h>
+#include <private/qsgadaptationlayer_p.h>
+#include <QtQuick/qsgnode.h>
+#include <QtQuick/qsgengine.h>
+#include <QtQuick/qsgtexturematerial.h>
+#include <QtQuick/qsgtexture.h>
+#include <QtQuick/qquickcanvas.h>
+#include <QtQml/qqmlinfo.h>
+#include <QFile>
+#include <cmath>
+#include <qmath.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static const char vertexShaderCode[] =
+ "attribute highp vec2 vTex;\n"
+ "uniform highp vec3 animData;// w,h(premultiplied of anim), interpolation progress\n"
+ "uniform highp vec4 animPos;//x,y, x,y (two frames for interpolation)\n"
+ "uniform highp vec2 size;//w,h of element\n"
+ "\n"
+ "uniform highp mat4 qt_Matrix;\n"
+ "\n"
+ "varying highp vec4 fTexS;\n"
+ "varying lowp float progress;\n"
+ "\n"
+ "\n"
+ "void main() {\n"
+ " progress = animData.z;\n"
+ " //Calculate frame location in texture\n"
+ " fTexS.xy = animPos.xy + vTex.xy * animData.xy;\n"
+ " //Next frame is also passed, for interpolation\n"
+ " fTexS.zw = animPos.zw + vTex.xy * animData.xy;\n"
+ "\n"
+ " gl_Position = qt_Matrix * vec4(size.x * vTex.x, size.y * vTex.y, 0, 1);\n"
+ "}\n";
+
+static const char fragmentShaderCode[] =
+ "uniform sampler2D texture;\n"
+ "uniform lowp float qt_Opacity;\n"
+ "\n"
+ "varying highp vec4 fTexS;\n"
+ "varying lowp float progress;\n"
+ "\n"
+ "void main() {\n"
+ " gl_FragColor = mix(texture2D(texture, fTexS.xy), texture2D(texture, fTexS.zw), progress) * qt_Opacity;\n"
+ "}\n";
+
+class QQuickSpriteSequenceMaterial : public QSGMaterial
+{
+public:
+ QQuickSpriteSequenceMaterial();
+ ~QQuickSpriteSequenceMaterial();
+ virtual QSGMaterialType *type() const { static QSGMaterialType type; return &type; }
+ virtual QSGMaterialShader *createShader() const;
+ virtual int compare(const QSGMaterial *other) const
+ {
+ return this - static_cast<const QQuickSpriteSequenceMaterial *>(other);
+ }
+
+ QSGTexture *texture;
+
+ float animT;
+ float animX1;
+ float animY1;
+ float animX2;
+ float animY2;
+ float animW;
+ float animH;
+ float elementWidth;
+ float elementHeight;
+};
+
+QQuickSpriteSequenceMaterial::QQuickSpriteSequenceMaterial()
+ : animT(0.0f)
+ , animX1(0.0f)
+ , animY1(0.0f)
+ , animX2(0.0f)
+ , animY2(0.0f)
+ , animW(1.0f)
+ , animH(1.0f)
+ , elementWidth(1.0f)
+ , elementHeight(1.0f)
+{
+ setFlag(Blending, true);
+}
+
+QQuickSpriteSequenceMaterial::~QQuickSpriteSequenceMaterial()
+{
+ delete texture;
+}
+
+class SpriteSequenceMaterialData : public QSGMaterialShader
+{
+public:
+ SpriteSequenceMaterialData(const char * /* vertexFile */ = 0, const char * /* fragmentFile */ = 0)
+ {
+ }
+
+ void deactivate() {
+ QSGMaterialShader::deactivate();
+
+ for (int i=0; i<8; ++i) {
+ program()->setAttributeArray(i, GL_FLOAT, chunkOfBytes, 1, 0);
+ }
+ }
+
+ virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *)
+ {
+ QQuickSpriteSequenceMaterial *m = static_cast<QQuickSpriteSequenceMaterial *>(newEffect);
+ m->texture->bind();
+
+ program()->setUniformValue(m_opacity_id, state.opacity());
+ program()->setUniformValue(m_animData_id, m->animW, m->animH, m->animT);
+ program()->setUniformValue(m_animPos_id, m->animX1, m->animY1, m->animX2, m->animY2);
+ program()->setUniformValue(m_size_id, m->elementWidth, m->elementHeight);
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_matrix_id, state.combinedMatrix());
+ }
+
+ virtual void initialize() {
+ m_matrix_id = program()->uniformLocation("qt_Matrix");
+ m_opacity_id = program()->uniformLocation("qt_Opacity");
+ m_animData_id = program()->uniformLocation("animData");
+ m_animPos_id = program()->uniformLocation("animPos");
+ m_size_id = program()->uniformLocation("size");
+ }
+
+ virtual const char *vertexShader() const { return vertexShaderCode; }
+ virtual const char *fragmentShader() const { return fragmentShaderCode; }
+
+ virtual char const *const *attributeNames() const {
+ static const char *attr[] = {
+ "vTex",
+ 0
+ };
+ return attr;
+ }
+
+ int m_matrix_id;
+ int m_opacity_id;
+ int m_animData_id;
+ int m_animPos_id;
+ int m_size_id;
+
+ static float chunkOfBytes[1024];
+};
+
+float SpriteSequenceMaterialData::chunkOfBytes[1024];
+
+QSGMaterialShader *QQuickSpriteSequenceMaterial::createShader() const
+{
+ return new SpriteSequenceMaterialData;
+}
+
+struct SpriteVertex {
+ float tx;
+ float ty;
+};
+
+struct SpriteVertices {
+ SpriteVertex v1;
+ SpriteVertex v2;
+ SpriteVertex v3;
+ SpriteVertex v4;
+};
+
+/*!
+ \qmlclass SpriteSequence QQuickSpriteSequence
+ \inqmlmodule QtQuick 2
+ \inherits Item
+ \brief The SpriteSequence element draws a sprite animation
+
+*/
+/*!
+ \qmlproperty bool QtQuick2::SpriteSequence::running
+
+ Whether the sprite is animating or not.
+
+ Default is true
+*/
+/*!
+ \qmlproperty bool QtQuick2::SpriteSequence::interpolate
+
+ If true, interpolation will occur between sprite frames to make the
+ animation appear smoother.
+
+ Default is true.
+*/
+/*!
+ \qmlproperty string QtQuick2::SpriteSequence::goalSprite
+
+ The name of the Sprite which is currently animating.
+*/
+/*!
+ \qmlproperty string QtQuick2::SpriteSequence::goalSprite
+
+ The name of the Sprite which the animation should move to.
+
+ Sprite states have defined durations and transitions between them, setting goalState
+ will cause it to disregard any path weightings (including 0) and head down the path
+ which will reach the goalState quickest (fewest animations). It will pass through
+ intermediate states on that path, and animate them for their duration.
+
+ If it is possible to return to the goalState from the starting point of the goalState
+ it will continue to do so until goalState is set to "" or an unreachable state.
+*/
+/*! \qmlmethod void QtQuick2::SpriteSequence::jumpTo(string sprite)
+
+ This function causes the sprite to jump to the specified state immediately, intermediate
+ states are not played.
+*/
+/*!
+ \qmlproperty list<Sprite> QtQuick2::SpriteSequence::sprites
+
+ The sprite or sprites to draw. Sprites will be scaled to the size of this element.
+*/
+
+//TODO: Implicitly size element to size of first sprite?
+QQuickSpriteSequence::QQuickSpriteSequence(QQuickItem *parent) :
+ QQuickItem(parent)
+ , m_node(0)
+ , m_material(0)
+ , m_spriteEngine(0)
+ , m_curFrame(0)
+ , m_pleaseReset(false)
+ , m_running(true)
+ , m_interpolate(true)
+ , m_curStateIdx(0)
+{
+ setFlag(ItemHasContents);
+ connect(this, SIGNAL(runningChanged(bool)),
+ this, SLOT(update()));
+}
+
+void QQuickSpriteSequence::jumpTo(const QString &sprite)
+{
+ if (!m_spriteEngine)
+ return;
+ m_spriteEngine->setGoal(m_spriteEngine->stateIndex(sprite), 0, true);
+}
+
+void QQuickSpriteSequence::setGoalSprite(const QString &sprite)
+{
+ if (m_goalState != sprite){
+ m_goalState = sprite;
+ emit goalSpriteChanged(sprite);
+ m_spriteEngine->setGoal(m_spriteEngine->stateIndex(sprite));
+ }
+}
+
+QQmlListProperty<QQuickSprite> QQuickSpriteSequence::sprites()
+{
+ return QQmlListProperty<QQuickSprite>(this, &m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+}
+
+void QQuickSpriteSequence::createEngine()
+{
+ //TODO: delay until component complete
+ if (m_spriteEngine)
+ delete m_spriteEngine;
+ if (m_sprites.count())
+ m_spriteEngine = new QQuickSpriteEngine(m_sprites, this);
+ else
+ m_spriteEngine = 0;
+ reset();
+}
+
+static QSGGeometry::Attribute SpriteSequence_Attributes[] = {
+ QSGGeometry::Attribute::create(0, 2, GL_FLOAT), // tex
+};
+
+static QSGGeometry::AttributeSet SpriteSequence_AttributeSet =
+{
+ 1, // Attribute Count
+ 2 * sizeof(float),
+ SpriteSequence_Attributes
+};
+
+QSGGeometryNode* QQuickSpriteSequence::buildNode()
+{
+ if (!m_spriteEngine) {
+ qmlInfo(this) << "No sprite engine...";
+ return 0;
+ } else if (m_spriteEngine->status() == QQuickPixmap::Null) {
+ m_spriteEngine->startAssemblingImage();
+ update();//Schedule another update, where we will check again
+ return 0;
+ } else if (m_spriteEngine->status() == QQuickPixmap::Loading) {
+ update();//Schedule another update, where we will check again
+ return 0;
+ }
+
+ m_material = new QQuickSpriteSequenceMaterial();
+
+ QImage image = m_spriteEngine->assembledImage();
+ if (image.isNull())
+ return 0;
+ m_sheetSize = QSizeF(image.size());
+ m_material->texture = canvas()->createTextureFromImage(image);
+ m_material->texture->setFiltering(QSGTexture::Linear);
+ m_spriteEngine->start(0);
+ m_material->animT = 0;
+ m_material->animX1 = m_spriteEngine->spriteX() / m_sheetSize.width();
+ m_material->animY1 = m_spriteEngine->spriteY() / m_sheetSize.height();
+ m_material->animX2 = m_material->animX1;
+ m_material->animY2 = m_material->animY1;
+ m_material->animW = m_spriteEngine->spriteWidth() / m_sheetSize.width();
+ m_material->animH = m_spriteEngine->spriteHeight() / m_sheetSize.height();
+ m_material->elementWidth = width();
+ m_material->elementHeight = height();
+ m_curState = m_spriteEngine->state(m_spriteEngine->curState())->name();
+ emit currentSpriteChanged(m_curState);
+
+ int vCount = 4;
+ int iCount = 6;
+ QSGGeometry *g = new QSGGeometry(SpriteSequence_AttributeSet, vCount, iCount);
+ g->setDrawingMode(GL_TRIANGLES);
+
+ SpriteVertices *p = (SpriteVertices *) g->vertexData();
+
+ p->v1.tx = 0;
+ p->v1.ty = 0;
+
+ p->v2.tx = 1.0;
+ p->v2.ty = 0;
+
+ p->v3.tx = 0;
+ p->v3.ty = 1.0;
+
+ p->v4.tx = 1.0;
+ p->v4.ty = 1.0;
+
+ quint16 *indices = g->indexDataAsUShort();
+ indices[0] = 0;
+ indices[1] = 1;
+ indices[2] = 2;
+ indices[3] = 1;
+ indices[4] = 3;
+ indices[5] = 2;
+
+
+ m_timestamp.start();
+ m_node = new QSGGeometryNode();
+ m_node->setGeometry(g);
+ m_node->setMaterial(m_material);
+ m_node->setFlag(QSGGeometryNode::OwnsMaterial);
+ return m_node;
+}
+
+void QQuickSpriteSequence::reset()
+{
+ m_pleaseReset = true;
+}
+
+QSGNode *QQuickSpriteSequence::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
+{
+ if (m_pleaseReset) {
+ delete m_node;
+
+ m_node = 0;
+ m_material = 0;
+ m_pleaseReset = false;
+ }
+
+ prepareNextFrame();
+
+ if (m_running) {
+ update();
+ if (m_node)
+ m_node->markDirty(QSGNode::DirtyMaterial);
+ }
+
+ return m_node;
+}
+
+void QQuickSpriteSequence::prepareNextFrame()
+{
+ if (m_node == 0)
+ m_node = buildNode();
+ if (m_node == 0) //error creating node
+ return;
+
+ uint timeInt = m_timestamp.elapsed();
+ qreal time = timeInt / 1000.;
+ m_material->elementHeight = height();
+ m_material->elementWidth = width();
+
+ //Advance State
+ m_spriteEngine->updateSprites(timeInt);
+ if (m_curStateIdx != m_spriteEngine->curState()) {
+ m_curStateIdx = m_spriteEngine->curState();
+ m_curState = m_spriteEngine->state(m_spriteEngine->curState())->name();
+ emit currentSpriteChanged(m_curState);
+ m_curFrame= -1;
+ }
+
+ //Advance Sprite
+ qreal animT = m_spriteEngine->spriteStart()/1000.0;
+ qreal frameCount = m_spriteEngine->spriteFrames();
+ qreal frameDuration = m_spriteEngine->spriteDuration()/frameCount;
+ double frameAt;
+ qreal progress;
+ if (frameDuration > 0) {
+ qreal frame = (time - animT)/(frameDuration / 1000.0);
+ frame = qBound(qreal(0.0), frame, frameCount - qreal(1.0));//Stop at count-1 frames until we have between anim interpolation
+ progress = modf(frame,&frameAt);
+ } else {
+ m_curFrame++;
+ if (m_curFrame >= frameCount){
+ m_curFrame = 0;
+ m_spriteEngine->advance();
+ }
+ frameAt = m_curFrame;
+ progress = 0;
+ }
+ if (m_spriteEngine->sprite()->reverse())
+ frameAt = (m_spriteEngine->spriteFrames() - 1) - frameAt;
+ qreal y = m_spriteEngine->spriteY() / m_sheetSize.height();
+ qreal w = m_spriteEngine->spriteWidth() / m_sheetSize.width();
+ qreal h = m_spriteEngine->spriteHeight() / m_sheetSize.height();
+ qreal x1 = m_spriteEngine->spriteX() / m_sheetSize.width();
+ x1 += frameAt * w;
+ qreal x2 = x1;
+ if (frameAt < (frameCount-1))
+ x2 += w;
+
+ m_material->animX1 = x1;
+ m_material->animY1 = y;
+ m_material->animX2 = x2;
+ m_material->animY2 = y;
+ m_material->animW = w;
+ m_material->animH = h;
+ m_material->animT = m_interpolate ? progress : 0.0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
new file mode 100644
index 0000000000..a2f9e4139a
--- /dev/null
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSPRITESEQUENCE_P_H
+#define QQUICKSPRITESEQUENCE_P_H
+
+#include <QtQuick/QQuickItem>
+#include <QTime>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QSGContext;
+class QQuickSprite;
+class QQuickSpriteEngine;
+class QSGGeometryNode;
+class QQuickSpriteSequenceMaterial;
+class Q_AUTOTEST_EXPORT QQuickSpriteSequence : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(bool running READ running WRITE setRunning NOTIFY runningChanged)
+ Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate NOTIFY interpolateChanged)
+ Q_PROPERTY(QString goalSprite READ goalSprite WRITE setGoalSprite NOTIFY goalSpriteChanged)
+ Q_PROPERTY(QString currentSprite READ currentSprite NOTIFY currentSpriteChanged)
+ //###try to share similar spriteEngines for less overhead?
+ Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites)
+ Q_CLASSINFO("DefaultProperty", "sprites")
+
+public:
+ explicit QQuickSpriteSequence(QQuickItem *parent = 0);
+
+ QQmlListProperty<QQuickSprite> sprites();
+
+ bool running() const
+ {
+ return m_running;
+ }
+
+ bool interpolate() const
+ {
+ return m_interpolate;
+ }
+
+ QString goalSprite() const
+ {
+ return m_goalState;
+ }
+
+ QString currentSprite() const
+ {
+ return m_curState;
+ }
+
+signals:
+
+ void runningChanged(bool arg);
+ void interpolateChanged(bool arg);
+ void goalSpriteChanged(QString arg);
+ void currentSpriteChanged(QString arg);
+
+public slots:
+
+ void jumpTo(const QString &sprite);
+ void setGoalSprite(const QString &sprite);
+
+ void setRunning(bool arg)
+ {
+ if (m_running != arg) {
+ m_running = arg;
+ emit runningChanged(arg);
+ }
+ }
+
+ void setInterpolate(bool arg)
+ {
+ if (m_interpolate != arg) {
+ m_interpolate = arg;
+ emit interpolateChanged(arg);
+ }
+ }
+
+private slots:
+ void createEngine();
+protected:
+ void reset();
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+private:
+ void prepareNextFrame();
+ QSGGeometryNode* buildNode();
+ QSGGeometryNode *m_node;
+ QQuickSpriteSequenceMaterial *m_material;
+ QList<QQuickSprite*> m_sprites;
+ QQuickSpriteEngine* m_spriteEngine;
+ QTime m_timestamp;
+ int m_curFrame;
+ bool m_pleaseReset;
+ bool m_running;
+ bool m_interpolate;
+ QString m_goalState;
+ QString m_curState;
+ int m_curStateIdx;
+ QSizeF m_sheetSize;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QQUICKSPRITESEQUENCE_P_H
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index 037a48ceed..668c7c07d7 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -132,8 +132,7 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
if (ok) {
//qDebug() << x << y << rotation << scale;
- target->setX(x);
- target->setY(y);
+ target->setPos(QPointF(x, y));
target->setRotation(target->rotation() + rotation);
target->setScale(target->scale() * scale);
}
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 7aa4276f8d..36b902ff8c 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -72,21 +72,32 @@ QT_BEGIN_NAMESPACE
const QChar QQuickTextPrivate::elideChar = QChar(0x2026);
QQuickTextPrivate::QQuickTextPrivate()
- : lineHeight(1)
- , elideLayout(0), textLine(0), doc(0)
+ : elideLayout(0), textLine(0)
#if defined(Q_OS_MAC)
, layoutThread(0), paintingThread(0)
#endif
, color(0xFF000000), linkColor(0xFF0000FF), styleColor(0xFF000000)
- , lineCount(1), maximumLineCount(INT_MAX), multilengthEos(-1), minimumPixelSize(12), minimumPointSize(12), nbActiveDownloads(0)
- , hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop), elideMode(QQuickText::ElideNone)
+ , lineCount(1), multilengthEos(-1)
+ , elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
, format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap)
- , lineHeightMode(QQuickText::ProportionalHeight), style(QQuickText::Normal)
- , fontSizeMode(QQuickText::FixedSize), updateType(UpdatePaintNode)
+ , style(QQuickText::Normal)
+ , updateType(UpdatePaintNode)
, maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
, styledText(false), singleline(false), internalWidthUpdate(false), requireImplicitWidth(false)
, truncated(false), hAlignImplicit(true), rightToLeftText(false)
- , layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false)
+ , layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
+{
+}
+
+QQuickTextPrivate::ExtraData::ExtraData()
+ : lineHeight(1.0)
+ , doc(0)
+ , minimumPixelSize(12)
+ , minimumPointSize(12)
+ , nbActiveDownloads(0)
+ , maximumLineCount(INT_MAX)
+ , lineHeightMode(QQuickText::ProportionalHeight)
+ , fontSizeMode(QQuickText::FixedSize)
{
}
@@ -299,12 +310,24 @@ void QQuickTextPrivate::updateLayout()
if (!richText) {
if (textHasChanged) {
if (styledText && !text.isEmpty()) {
- QQuickStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid);
+ layout.setFont(font);
+ // needs temporary bool because formatModifiesFontSize is in a bit-field
+ bool fontSizeModified = false;
+ QQuickStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified);
+ formatModifiesFontSize = fontSizeModified;
} else {
layout.clearAdditionalFormats();
- multilengthEos = text.indexOf(QLatin1Char('\x9c'));
- QString tmp = multilengthEos != -1 ? text.mid(0, multilengthEos) : text;
- tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ QString tmp = text;
+ multilengthEos = tmp.indexOf(QLatin1Char('\x9c'));
+ if (multilengthEos != -1) {
+ tmp = tmp.mid(0, multilengthEos);
+ tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ } else if (tmp.contains(QLatin1Char('\n'))) {
+ // Replace always does a detach. Checking for the new line character first
+ // means iterating over those items again if found but prevents a realloc
+ // otherwise.
+ tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ }
layout.setText(tmp);
}
textHasChanged = false;
@@ -312,10 +335,10 @@ void QQuickTextPrivate::updateLayout()
} else {
ensureDoc();
QTextBlockFormat::LineHeightTypes type;
- type = lineHeightMode == QQuickText::FixedHeight ? QTextBlockFormat::FixedHeight : QTextBlockFormat::ProportionalHeight;
+ type = lineHeightMode() == QQuickText::FixedHeight ? QTextBlockFormat::FixedHeight : QTextBlockFormat::ProportionalHeight;
QTextBlockFormat blockFormat;
- blockFormat.setLineHeight((lineHeightMode == QQuickText::FixedHeight ? lineHeight : lineHeight * 100), type);
- for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next()) {
+ blockFormat.setLineHeight((lineHeightMode() == QQuickText::FixedHeight ? lineHeight() : lineHeight() * 100), type);
+ for (QTextBlock it = extra->doc->begin(); it != extra->doc->end(); it = it.next()) {
QTextCursor cursor(it);
cursor.mergeBlockFormat(blockFormat);
}
@@ -334,13 +357,13 @@ void QQuickText::imageDownloadFinished()
{
Q_D(QQuickText);
- (d->nbActiveDownloads)--;
+ (d->extra->nbActiveDownloads)--;
// when all the remote images have been downloaded,
// if one of the sizes was not specified at parsing time
// we use the implicit size from pixmapcache and re-layout.
- if (d->nbActiveDownloads == 0) {
+ if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) {
bool needToUpdateLayout = false;
foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) {
if (!img->size.isValid()) {
@@ -375,7 +398,7 @@ void QQuickTextPrivate::updateSize()
return;
}
- QFontMetrics fm(font);
+ QFontMetricsF fm(font);
if (text.isEmpty()) {
qreal fontHeight = fm.height();
q->setImplicitSize(0, fontHeight);
@@ -388,23 +411,23 @@ void QQuickTextPrivate::updateSize()
qreal naturalWidth = 0;
- int dy = q->height();
- QSize size(0, 0);
- QSize previousSize = layedOutTextRect.size();
+ qreal dy = q->height();
+ QSizeF size(0, 0);
+ QSizeF previousSize = layedOutTextRect.size();
#if defined(Q_OS_MAC)
layoutThread = QThread::currentThread();
#endif
//setup instance of QTextLayout for all cases other than richtext
if (!richText) {
- QRect textRect = setupTextLayout(&naturalWidth);
+ QRectF textRect = setupTextLayout(&naturalWidth);
layedOutTextRect = textRect;
size = textRect.size();
dy -= size.height();
} else {
singleline = false; // richtext can't elide or be optimized for single-line case
ensureDoc();
- doc->setDefaultFont(font);
+ extra->doc->setDefaultFont(font);
QQuickText::HAlignment horizontalAlignment = q->effectiveHAlign();
if (rightToLeftText) {
if (horizontalAlignment == QQuickText::AlignLeft)
@@ -416,21 +439,21 @@ void QQuickTextPrivate::updateSize()
option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
option.setWrapMode(QTextOption::WrapMode(wrapMode));
option.setUseDesignMetrics(true);
- doc->setDefaultTextOption(option);
+ extra->doc->setDefaultTextOption(option);
if (requireImplicitWidth && q->widthValid()) {
- doc->setTextWidth(-1);
- naturalWidth = doc->idealWidth();
+ extra->doc->setTextWidth(-1);
+ naturalWidth = extra->doc->idealWidth();
}
if (wrapMode != QQuickText::NoWrap && q->widthValid())
- doc->setTextWidth(q->width());
+ extra->doc->setTextWidth(q->width());
else
- doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
- dy -= (int)doc->size().height();
- QSize dsize = doc->size().toSize();
- layedOutTextRect = QRect(QPoint(0,0), dsize);
- size = QSize(int(doc->idealWidth()),dsize.height());
+ extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
+ dy -= extra->doc->size().height();
+ QSizeF dsize = extra->doc->size();
+ layedOutTextRect = QRectF(QPointF(0,0), dsize);
+ size = QSizeF(extra->doc->idealWidth(),dsize.height());
}
- int yoff = 0;
+ qreal yoff = 0;
if (q->heightValid()) {
if (vAlign == QQuickText::AlignBottom)
@@ -570,8 +593,8 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
textLine->setWidth(q->width());
else
textLine->setWidth(INT_MAX);
- if (lineHeight != 1.0)
- textLine->setHeight((lineHeightMode == QQuickText::FixedHeight) ? lineHeight : line.height() * lineHeight);
+ if (lineHeight() != 1.0)
+ textLine->setHeight((lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : line.height() * lineHeight());
emit q->lineLaidOut(textLine);
@@ -590,24 +613,43 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
#endif
}
-QString QQuickTextPrivate::elidedText(int lineWidth, const QTextLine &line, QTextLine *nextLine) const
+void QQuickTextPrivate::elideFormats(
+ const int start, const int length, int offset, QList<QTextLayout::FormatRange> *elidedFormats)
+{
+ const int end = start + length;
+ QList<QTextLayout::FormatRange> formats = layout.additionalFormats();
+ for (int i = 0; i < formats.count(); ++i) {
+ QTextLayout::FormatRange format = formats.at(i);
+ const int formatLength = qMin(format.start + format.length, end) - qMax(format.start, start);
+ if (formatLength > 0) {
+ format.start = qMax(offset, format.start - start + offset);
+ format.length = formatLength;
+ elidedFormats->append(format);
+ }
+ }
+}
+
+QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine) const
{
if (nextLine) {
nextLine->setLineWidth(INT_MAX);
return layout.engine()->elidedText(
Qt::TextElideMode(elideMode),
- lineWidth,
+ QFixed::fromReal(lineWidth),
0,
line.textStart(),
line.textLength() + nextLine->textLength());
} else {
QString elideText = layout.text().mid(line.textStart(), line.textLength());
- elideText[elideText.length() - 1] = elideChar;
- // Appending the elide character may push the line over the maximum width
- // in which case the elided text will need to be elided.
- QFontMetricsF metrics(layout.font());
- if (metrics.width(elideChar) + line.naturalTextWidth() >= lineWidth)
- elideText = metrics.elidedText(elideText, Qt::TextElideMode(elideMode), lineWidth);
+ if (!styledText) {
+ // QFontMetrics won't help eliding styled text.
+ elideText[elideText.length() - 1] = elideChar;
+ // Appending the elide character may push the line over the maximum width
+ // in which case the elided text will need to be elided.
+ QFontMetricsF metrics(layout.font());
+ if (metrics.width(elideChar) + line.naturalTextWidth() >= lineWidth)
+ elideText = metrics.elidedText(elideText, Qt::TextElideMode(elideMode), lineWidth);
+ }
return elideText;
}
}
@@ -619,7 +661,7 @@ QString QQuickTextPrivate::elidedText(int lineWidth, const QTextLine &line, QTex
already absolutely positioned horizontally).
*/
-QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
+QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
{
Q_Q(QQuickText);
layout.setCacheEnabled(true);
@@ -647,7 +689,7 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
// Layout to determine the implicit width.
layout.beginLayout();
- for (int i = 0; i < maximumLineCount; ++i) {
+ for (int i = 0; i < maximumLineCount(); ++i) {
QTextLine line = layout.createLine();
if (!line.isValid())
break;
@@ -658,30 +700,31 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
}
QFontMetrics fm(font);
- qreal height = (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : fm.height() * lineHeight;
+ qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight();
return QRect(0, 0, 0, height);
}
- const int lineWidth = q->widthValid() ? q->width() : INT_MAX;
+ const qreal lineWidth = q->widthValid() ? q->width() : FLT_MAX;
+ const qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+
const bool customLayout = isLineLaidOutConnected();
const bool wasTruncated = truncated;
- const bool singlelineElide = !styledText && elideMode != QQuickText::ElideNone && q->widthValid();
- const bool multilineElide = !styledText
- && elideMode == QQuickText::ElideRight
+ const bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
+ const bool multilineElide = elideMode == QQuickText::ElideRight
&& q->widthValid()
&& (q->heightValid() || maximumLineCountValid);
const bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();
- const bool horizontalFit = fontSizeMode & QQuickText::HorizontalFit && q->widthValid();
- const bool verticalFit = fontSizeMode & QQuickText::VerticalFit
+ const bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
+ const bool verticalFit = fontSizeMode() & QQuickText::VerticalFit
&& (q->heightValid() || (maximumLineCountValid && canWrap));
const bool pixelSize = font.pixelSize() != -1;
QString layoutText = layout.text();
int largeFont = pixelSize ? font.pixelSize() : font.pointSize();
- int smallFont = fontSizeMode != QQuickText::FixedSize
- ? qMin(pixelSize ? minimumPixelSize : minimumPointSize, largeFont)
+ int smallFont = fontSizeMode() != QQuickText::FixedSize
+ ? qMin(pixelSize ? minimumPixelSize() : minimumPointSize(), largeFont)
: largeFont;
int scaledFontSize = largeFont;
@@ -695,6 +738,8 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
qreal height = 0;
QString elideText;
bool once = true;
+ int elideStart = 0;
+ int elideEnd = 0;
*naturalWidth = 0;
@@ -712,12 +757,14 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
}
layout.beginLayout();
+
bool wrapped = false;
bool truncateHeight = false;
truncated = false;
elide = false;
int characterCount = 0;
int unwrappedLineCount = 1;
+ int maxLineCount = maximumLineCount();
height = 0;
br = QRectF();
line = layout.createLine();
@@ -732,7 +779,7 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
// Elide the previous line if the accumulated height of the text exceeds the height
// of the element.
- if (multilineElide && height > q->height() && visibleCount > 1) {
+ if (multilineElide && height > maxHeight && visibleCount > 1) {
elide = true;
if (eos != -1) // There's an abbreviated string available, skip the rest as it's
break; // all going to be discarded.
@@ -747,13 +794,16 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
elideText = layoutText.at(line.textStart() - 1) != QChar::LineSeparator
? elidedText(lineWidth, previousLine, &line)
: elidedText(lineWidth, previousLine);
+ elideStart = previousLine.textStart();
+ // elideEnd isn't required for right eliding.
+
// The previous line is the last one visible so move the current one off somewhere
// out of the way and back everything up one line.
line.setLineWidth(0);
line.setPosition(QPointF(FLT_MAX, FLT_MAX));
line = previousLine;
--visibleCount;
- height -= (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : previousLine.height() * lineHeight;
+ height -= (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : previousLine.height() * lineHeight();
break;
}
@@ -770,10 +820,12 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
height = preLayoutHeight;
elideText = layout.engine()->elidedText(
Qt::TextElideMode(elideMode),
- lineWidth,
+ QFixed::fromReal(lineWidth),
0,
line.textStart(),
line.textLength());
+ elideStart = line.textStart();
+ elideEnd = elideStart + line.textLength();
} else {
br = br.united(line.naturalTextRect());
}
@@ -787,7 +839,7 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
// Stop if the maximum number of lines has been reached and elide the last line
// if enabled.
- if (visibleCount == maximumLineCount) {
+ if (visibleCount == maxLineCount) {
truncated = true;
characterCount = nextLine.textStart() + nextLine.textLength();
@@ -799,6 +851,8 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
elideText = wrappedLine
? elidedText(lineWidth, line, &nextLine)
: elidedText(lineWidth, line);
+ elideStart = line.textStart();
+ // elideEnd isn't required for right eliding.
} else {
br = br.united(line.naturalTextRect());
}
@@ -821,13 +875,13 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
if (requireImplicitWidth
&& characterCount < layoutText.length()
- && unwrappedLineCount < maximumLineCount) {
+ && unwrappedLineCount < maxLineCount) {
// Use a new layout to get the maximum width for the remaining text. Using a
// different layout excludes the truncated text from rendering.
QTextLayout widthLayout(layoutText.mid(characterCount), scaledFont);
widthLayout.setTextOption(layout.textOption());
- for (; unwrappedLineCount <= maximumLineCount; ++unwrappedLineCount) {
+ for (; unwrappedLineCount <= maxLineCount; ++unwrappedLineCount) {
QTextLine line = widthLayout.createLine();
if (!line.isValid())
break;
@@ -870,7 +924,7 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
}
if (verticalFit) {
- if (truncateHeight || (q->heightValid() && unelidedRect.height() > q->height())) {
+ if (truncateHeight || unelidedRect.height() > maxHeight) {
largeFont = scaledFontSize - 1;
scaledFontSize = (smallFont + largeFont + 1) / 2;
if (smallFont > largeFont)
@@ -891,6 +945,33 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
if (elide) {
if (!elideLayout)
elideLayout = new QTextLayout;
+ if (styledText) {
+ QList<QTextLayout::FormatRange> formats;
+ switch (elideMode) {
+ case QQuickText::ElideRight:
+ elideFormats(elideStart, elideText.length() - 1, 0, &formats);
+ break;
+ case QQuickText::ElideLeft:
+ elideFormats(elideEnd - elideText.length() + 1, elideText.length() - 1, 1, &formats);
+ break;
+ case QQuickText::ElideMiddle: {
+ const int index = elideText.indexOf(elideChar);
+ if (index != -1) {
+ elideFormats(elideStart, index, 0, &formats);
+ elideFormats(
+ elideEnd - elideText.length() + index + 1,
+ elideText.length() - index - 1,
+ index + 1,
+ &formats);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ elideLayout->setAdditionalFormats(formats);
+ }
+
elideLayout->setFont(layout.font());
elideLayout->setTextOption(layout.textOption());
elideLayout->setText(elideText);
@@ -928,7 +1009,7 @@ QRect QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
if (truncated != wasTruncated)
emit q->truncatedChanged();
- return QRect(qRound(br.x()), qRound(br.y()), qCeil(br.width()), qCeil(br.height()));
+ return br;
}
void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height)
@@ -938,7 +1019,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
if (imgTags.isEmpty()) {
line.setPosition(QPointF(line.position().x(), height));
- height += (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : line.height() * lineHeight;
+ height += (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : line.height() * lineHeight();
return;
}
@@ -957,7 +1038,9 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
image->pix = new QQuickPixmap(qmlEngine(q), url, image->size);
if (image->pix->isLoading()) {
image->pix->connectFinished(q, SLOT(imageDownloadFinished()));
- nbActiveDownloads++;
+ if (!extra.isAllocated() || !extra->nbActiveDownloads)
+ extra.value().nbActiveDownloads = 0;
+ extra->nbActiveDownloads++;
} else if (image->pix->isReady()) {
if (!image->size.isValid()) {
image->size = image->pix->implicitSize();
@@ -990,7 +1073,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
}
line.setPosition(QPointF(line.position().x(), height + textTop));
- height += (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : totalLineHeight * lineHeight;
+ height += (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : totalLineHeight * lineHeight();
}
/*!
@@ -998,12 +1081,12 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal
*/
void QQuickTextPrivate::ensureDoc()
{
- if (!doc) {
+ if (!extra.isAllocated() || !extra->doc) {
Q_Q(QQuickText);
- doc = new QQuickTextDocumentWithImageResources(q);
- doc->setDocumentMargin(0);
- doc->setBaseUrl(q->baseUrl());
- FAST_CONNECT(doc, SIGNAL(imagesLoaded()), q, SLOT(q_imagesLoaded()));
+ extra.value().doc = new QQuickTextDocumentWithImageResources(q);
+ extra->doc->setDocumentMargin(0);
+ extra->doc->setBaseUrl(q->baseUrl());
+ FAST_CONNECT(extra->doc, SIGNAL(imagesLoaded()), q, SLOT(q_imagesLoaded()));
}
}
@@ -1253,8 +1336,13 @@ void QQuickText::setFont(const QFont &font)
d->font.setPointSizeF(size/2.0);
}
- if (oldFont != d->font)
+ if (oldFont != d->font) {
+ // if the format changes the size of the text
+ // with headings or <font> tag, we need to re-parse
+ if (d->formatModifiesFontSize)
+ d->textHasChanged = true;
d->updateLayout();
+ }
emit fontChanged(d->sourceFont);
}
@@ -1285,8 +1373,8 @@ void QQuickText::setText(const QString &n)
if (isComponentComplete()) {
if (d->richText) {
d->ensureDoc();
- d->doc->setText(n);
- d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
+ d->extra->doc->setText(n);
+ d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
} else {
d->rightToLeftText = d->text.isRightToLeft();
}
@@ -1550,11 +1638,6 @@ void QQuickTextPrivate::mirrorChange()
}
}
-QTextDocument *QQuickTextPrivate::textDocument()
-{
- return doc;
-}
-
QQuickText::VAlignment QQuickText::vAlign() const
{
Q_D(const QQuickText);
@@ -1647,7 +1730,7 @@ bool QQuickText::truncated() const
int QQuickText::maximumLineCount() const
{
Q_D(const QQuickText);
- return d->maximumLineCount;
+ return d->maximumLineCount();
}
void QQuickText::setMaximumLineCount(int lines)
@@ -1655,8 +1738,8 @@ void QQuickText::setMaximumLineCount(int lines)
Q_D(QQuickText);
d->maximumLineCountValid = lines==INT_MAX ? false : true;
- if (d->maximumLineCount != lines) {
- d->maximumLineCount = lines;
+ if (d->maximumLineCount() != lines) {
+ d->extra.value().maximumLineCount = lines;
d->updateLayout();
emit maximumLineCountChanged();
}
@@ -1758,8 +1841,8 @@ void QQuickText::setTextFormat(TextFormat format)
if (isComponentComplete()) {
if (!wasRich && d->richText) {
d->ensureDoc();
- d->doc->setText(d->text);
- d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
+ d->extra->doc->setText(d->text);
+ d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
} else {
d->rightToLeftText = d->text.isRightToLeft();
}
@@ -1812,7 +1895,7 @@ void QQuickText::setElideMode(QQuickText::TextElideMode mode)
d->elideMode = mode;
d->updateLayout();
- emit elideModeChanged(d->elideMode);
+ emit elideModeChanged(mode);
}
/*!
@@ -1854,8 +1937,10 @@ void QQuickText::setBaseUrl(const QUrl &url)
if (baseUrl() != url) {
d->baseUrl = url;
- if (d->doc)
- d->doc->setBaseUrl(url);
+ if (d->richText) {
+ d->ensureDoc();
+ d->extra->doc->setBaseUrl(url);
+ }
if (d->styledText) {
d->textHasChanged = true;
qDeleteAll(d->imgTags);
@@ -1879,7 +1964,7 @@ QRectF QQuickText::boundingRect() const
{
Q_D(const QQuickText);
- QRect rect = d->layedOutTextRect;
+ QRectF rect = d->layedOutTextRect;
if (d->style != Normal)
rect.adjust(-1, 0, 1, 2);
@@ -1897,7 +1982,7 @@ QRectF QQuickText::boundingRect() const
break;
}
- return QRectF(rect);
+ return rect;
}
/*! \internal */
@@ -1914,7 +1999,7 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
bool leftAligned = effectiveHAlign() == QQuickText::AlignLeft;
bool wrapped = d->wrapMode != QQuickText::NoWrap;
bool elide = d->elideMode != QQuickText::ElideNone;
- bool scaleFont = d->fontSizeMode != QQuickText::FixedSize && (widthValid() || heightValid());
+ bool scaleFont = d->fontSizeMode() != QQuickText::FixedSize && (widthValid() || heightValid());
if ((!widthChanged && !heightChanged) || d->internalWidthUpdate)
goto geomChangeDone;
@@ -1935,7 +2020,7 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
if (d->elideMode == QQuickText::ElideRight && wrapped && newGeometry.height() > oldGeometry.height() && !scaleFont) {
if (!d->truncated)
goto geomChangeDone; // Multiline eliding not affected if we're not currently truncated and we get higher.
- if (d->maximumLineCountValid && d->lineCount == d->maximumLineCount)
+ if (d->maximumLineCountValid && d->lineCount == d->maximumLineCount())
goto geomChangeDone; // Multiline eliding not affected if we're already at max line count and we get higher.
}
@@ -2002,7 +2087,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
if (d->richText) {
d->ensureDoc();
- node->addTextDocument(bounds.topLeft(), d->doc, color, d->style, styleColor, linkColor);
+ node->addTextDocument(bounds.topLeft(), d->extra->doc, color, d->style, styleColor, linkColor);
} else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) {
node->addTextLayout(QPoint(0, bounds.y()), &d->layout, color, d->style, styleColor, linkColor);
if (d->elideLayout)
@@ -2062,17 +2147,17 @@ qreal QQuickText::contentHeight() const
qreal QQuickText::lineHeight() const
{
Q_D(const QQuickText);
- return d->lineHeight;
+ return d->lineHeight();
}
void QQuickText::setLineHeight(qreal lineHeight)
{
Q_D(QQuickText);
- if ((d->lineHeight == lineHeight) || (lineHeight < 0.0))
+ if ((d->lineHeight() == lineHeight) || (lineHeight < 0.0))
return;
- d->lineHeight = lineHeight;
+ d->extra.value().lineHeight = lineHeight;
d->updateLayout();
emit lineHeightChanged(lineHeight);
}
@@ -2092,16 +2177,16 @@ void QQuickText::setLineHeight(qreal lineHeight)
QQuickText::LineHeightMode QQuickText::lineHeightMode() const
{
Q_D(const QQuickText);
- return d->lineHeightMode;
+ return d->lineHeightMode();
}
void QQuickText::setLineHeightMode(LineHeightMode mode)
{
Q_D(QQuickText);
- if (mode == d->lineHeightMode)
+ if (mode == d->lineHeightMode())
return;
- d->lineHeightMode = mode;
+ d->extra.value().lineHeightMode = mode;
d->updateLayout();
emit lineHeightModeChanged(mode);
@@ -2135,18 +2220,18 @@ void QQuickText::setLineHeightMode(LineHeightMode mode)
QQuickText::FontSizeMode QQuickText::fontSizeMode() const
{
Q_D(const QQuickText);
- return d->fontSizeMode;
+ return d->fontSizeMode();
}
void QQuickText::setFontSizeMode(FontSizeMode mode)
{
Q_D(QQuickText);
- if (d->fontSizeMode == mode)
+ if (d->fontSizeMode() == mode)
return;
polish();
- d->fontSizeMode = mode;
+ d->extra.value().fontSizeMode = mode;
emit fontSizeModeChanged();
}
@@ -2163,18 +2248,18 @@ void QQuickText::setFontSizeMode(FontSizeMode mode)
int QQuickText::minimumPixelSize() const
{
Q_D(const QQuickText);
- return d->minimumPixelSize;
+ return d->minimumPixelSize();
}
void QQuickText::setMinimumPixelSize(int size)
{
Q_D(QQuickText);
- if (d->minimumPixelSize == size)
+ if (d->minimumPixelSize() == size)
return;
- if (d->fontSizeMode != FixedSize && (widthValid() || heightValid()))
+ if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid()))
polish();
- d->minimumPixelSize = size;
+ d->extra.value().minimumPixelSize = size;
emit minimumPixelSizeChanged();
}
@@ -2191,18 +2276,18 @@ void QQuickText::setMinimumPixelSize(int size)
int QQuickText::minimumPointSize() const
{
Q_D(const QQuickText);
- return d->minimumPointSize;
+ return d->minimumPointSize();
}
void QQuickText::setMinimumPointSize(int size)
{
Q_D(QQuickText);
- if (d->minimumPointSize == size)
+ if (d->minimumPointSize() == size)
return;
- if (d->fontSizeMode != FixedSize && (widthValid() || heightValid()))
+ if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid()))
polish();
- d->minimumPointSize = size;
+ d->extra.value().minimumPointSize = size;
emit minimumPointSizeChanged();
}
@@ -2212,7 +2297,9 @@ void QQuickText::setMinimumPointSize(int size)
int QQuickText::resourcesLoading() const
{
Q_D(const QQuickText);
- return d->doc ? d->doc->resourcesLoading() : 0;
+ if (d->richText && d->extra.isAllocated() && d->extra->doc)
+ return d->extra->doc->resourcesLoading();
+ return 0;
}
/*! \internal */
@@ -2222,8 +2309,8 @@ void QQuickText::componentComplete()
if (d->updateOnComponentComplete) {
if (d->richText) {
d->ensureDoc();
- d->doc->setText(d->text);
- d->rightToLeftText = d->doc->toPlainText().isRightToLeft();
+ d->extra->doc->setText(d->text);
+ d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
} else {
d->rightToLeftText = d->text.isRightToLeft();
}
@@ -2270,15 +2357,21 @@ void QQuickText::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickText);
+ QString link;
if (d->isLinkActivatedConnected()) {
if (d->styledText)
- d->activeLink = d->anchorAt(event->localPos());
- else if (d->richText && d->doc)
- d->activeLink = d->doc->documentLayout()->anchorAt(event->localPos());
+ link = d->anchorAt(event->localPos());
+ else if (d->richText) {
+ d->ensureDoc();
+ link = d->extra->doc->documentLayout()->anchorAt(event->localPos());
+ }
}
- if (d->activeLink.isEmpty())
+ if (link.isEmpty()) {
event->setAccepted(false);
+ } else {
+ d->extra.value().activeLink = link;
+ }
// ### may malfunction if two of the same links are clicked & dragged onto each other)
@@ -2298,12 +2391,14 @@ void QQuickText::mouseReleaseEvent(QMouseEvent *event)
if (d->isLinkActivatedConnected()) {
if (d->styledText)
link = d->anchorAt(event->localPos());
- else if (d->richText && d->doc)
- link = d->doc->documentLayout()->anchorAt(event->localPos());
+ else if (d->richText) {
+ d->ensureDoc();
+ link = d->extra->doc->documentLayout()->anchorAt(event->localPos());
+ }
}
- if (!link.isEmpty() && d->activeLink == link)
- emit linkActivated(d->activeLink);
+ if (!link.isEmpty() && d->extra.isAllocated() && d->extra->activeLink == link)
+ emit linkActivated(d->extra->activeLink);
else
event->setAccepted(false);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 0f8c93a9e3..0425c37406 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -60,6 +60,7 @@
#include <QtGui/qabstracttextdocumentlayout.h>
#include <QtGui/qtextlayout.h>
#include <private/qquickstyledtext_p.h>
+#include <private/qlazilyallocated_p.h>
QT_BEGIN_NAMESPACE
@@ -79,17 +80,30 @@ public:
bool determineHorizontalAlignment();
bool setHAlign(QQuickText::HAlignment, bool forceAlign = false);
void mirrorChange();
- QTextDocument *textDocument();
bool isLineLaidOutConnected();
void setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height);
- QString elidedText(int lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const;
- QRect layedOutTextRect;
+ QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const;
+ void elideFormats(int start, int length, int offset, QList<QTextLayout::FormatRange> *elidedFormats);
- qreal lineHeight;
+ QRectF layedOutTextRect;
+
+ struct ExtraData {
+ ExtraData();
+
+ qreal lineHeight;
+ QQuickTextDocumentWithImageResources *doc;
+ QString activeLink;
+ int minimumPixelSize;
+ int minimumPointSize;
+ int nbActiveDownloads;
+ int maximumLineCount;
+ QQuickText::LineHeightMode lineHeightMode;
+ QQuickText::FontSizeMode fontSizeMode;
+ };
+ QLazilyAllocated<ExtraData> extra;
QString text;
- QString activeLink;
QUrl baseUrl;
QFont font;
QFont sourceFont;
@@ -99,7 +113,6 @@ public:
QTextLayout layout;
QTextLayout *elideLayout;
QQuickTextLine *textLine;
- QQuickTextDocumentWithImageResources *doc;
#if defined(Q_OS_MAC)
QList<QRectF> linesRects;
@@ -112,11 +125,7 @@ public:
QRgb styleColor;
int lineCount;
- int maximumLineCount;
int multilengthEos;
- int minimumPixelSize;
- int minimumPointSize;
- int nbActiveDownloads;
enum UpdateType {
UpdateNone,
@@ -124,14 +133,12 @@ public:
UpdatePaintNode
};
+ QQuickText::TextElideMode elideMode;
QQuickText::HAlignment hAlign;
QQuickText::VAlignment vAlign;
- QQuickText::TextElideMode elideMode;
QQuickText::TextFormat format;
QQuickText::WrapMode wrapMode;
- QQuickText::LineHeightMode lineHeightMode;
QQuickText::TextStyle style;
- QQuickText::FontSizeMode fontSizeMode;
UpdateType updateType;
bool maximumLineCountValid:1;
@@ -148,6 +155,7 @@ public:
bool layoutTextElided:1;
bool textHasChanged:1;
bool needToUpdateLayout:1;
+ bool formatModifiesFontSize:1;
static const QChar elideChar;
@@ -155,14 +163,18 @@ public:
void ensureDoc();
- QRect setupTextLayout(qreal *const naturalWidth);
+ QRectF setupTextLayout(qreal *const naturalWidth);
void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
bool isLinkActivatedConnected();
QString anchorAt(const QPointF &pos);
- static inline QQuickTextPrivate *get(QQuickText *t) {
- return t->d_func();
- }
+ inline qreal lineHeight() const { return extra.isAllocated() ? extra->lineHeight : 1.0; }
+ inline int maximumLineCount() const { return extra.isAllocated() ? extra->maximumLineCount : INT_MAX; }
+ inline QQuickText::LineHeightMode lineHeightMode() const { return extra.isAllocated() ? extra->lineHeightMode : QQuickText::ProportionalHeight; }
+ inline QQuickText::FontSizeMode fontSizeMode() const { return extra.isAllocated() ? extra->fontSizeMode : QQuickText::FixedSize; }
+ inline int minimumPixelSize() const { return extra.isAllocated() ? extra->minimumPixelSize : 12; }
+ inline int minimumPointSize() const { return extra.isAllocated() ? extra->minimumPointSize : 12; }
+ static inline QQuickTextPrivate *get(QQuickText *t) { return t->d_func(); }
};
class QQuickPixmap;
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index a763626410..9a61312910 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -97,13 +97,17 @@ static QTextLine currentTextLine(const QTextCursor &cursor)
}
QQuickTextControlPrivate::QQuickTextControlPrivate()
- : doc(0), cursorOn(false), cursorIsFocusIndicator(false),
+ : doc(0),
+ preeditCursor(0),
interactionFlags(Qt::TextEditorInteraction),
+ cursorOn(false),
+ cursorIsFocusIndicator(false),
mousePressed(false),
- lastSelectionState(false), ignoreAutomaticScrollbarAdjustement(false),
+ lastSelectionState(false),
+ ignoreAutomaticScrollbarAdjustement(false),
overwriteMode(false),
acceptRichText(true),
- preeditCursor(0), hideCursor(false),
+ hideCursor(false),
hasFocus(false),
isEnabled(true),
hadSelectionOnMousePress(false),
@@ -298,7 +302,6 @@ void QQuickTextControlPrivate::setContent(Qt::TextFormat format, const QString &
doc = document;
clearDocument = false;
} else {
- palette = QGuiApplication::palette();
doc = new QTextDocument(q);
}
_q_documentLayoutChanged();
@@ -631,18 +634,6 @@ QQuickTextControl::~QQuickTextControl()
{
}
-void QQuickTextControl::setView(QObject *view)
-{
- Q_D(QQuickTextControl);
- d->contextObject = view;
-}
-
-QObject *QQuickTextControl::view() const
-{
- Q_D(const QQuickTextControl);
- return d->contextObject;
-}
-
QTextDocument *QQuickTextControl::document() const
{
Q_D(const QQuickTextControl);
@@ -1418,7 +1409,7 @@ bool QQuickTextControlPrivate::sendMouseEventToInputContext(QMouseEvent *e, cons
Q_UNUSED(e);
- if (contextObject && isPreediting()) {
+ if (isPreediting()) {
QTextLayout *layout = cursor.block().layout();
int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position();
@@ -1908,81 +1899,12 @@ QString QQuickTextControl::toHtml() const
}
#endif
-QPalette QQuickTextControl::palette() const
-{
- Q_D(const QQuickTextControl);
- return d->palette;
-}
-
-void QQuickTextControl::setPalette(const QPalette &pal)
-{
- Q_D(QQuickTextControl);
- d->palette = pal;
-}
-
bool QQuickTextControl::cursorOn() const
{
Q_D(const QQuickTextControl);
return d->cursorOn;
}
-QAbstractTextDocumentLayout::PaintContext QQuickTextControl::getPaintContext() const
-{
- Q_D(const QQuickTextControl);
-
- QAbstractTextDocumentLayout::PaintContext ctx;
-
- ctx.palette = d->palette;
- if (d->cursorOn && d->isEnabled) {
- if (d->hideCursor)
- ctx.cursorPosition = -1;
- else if (d->preeditCursor != 0)
- ctx.cursorPosition = - (d->preeditCursor + 2);
- else
- ctx.cursorPosition = d->cursor.position();
- }
-
- if (d->cursor.hasSelection()) {
- QAbstractTextDocumentLayout::Selection selection;
- selection.cursor = d->cursor;
- if (0 && d->cursorIsFocusIndicator) {
-#if 0
- // ###
- QStyleOption opt;
- opt.palette = ctx.palette;
- QStyleHintReturnVariant ret;
- QStyle *style = QGuiApplication::style();
- if (widget)
- style = widget->style();
- style->styleHint(QStyle::SH_TextControl_FocusIndicatorTextCharFormat, &opt, widget, &ret);
- selection.format = qvariant_cast<QTextFormat>(ret.variant).toCharFormat();
-#endif
- } else {
- QPalette::ColorGroup cg = d->hasFocus ? QPalette::Active : QPalette::Inactive;
- selection.format.setBackground(ctx.palette.brush(cg, QPalette::Highlight));
- selection.format.setForeground(ctx.palette.brush(cg, QPalette::HighlightedText));
- if (fullWidthSelection)
- selection.format.setProperty(QTextFormat::FullWidthSelection, true);
- }
- ctx.selections.append(selection);
- }
-
- return ctx;
-}
-
-void QQuickTextControl::drawContents(QPainter *p, const QRectF &rect)
-{
- Q_D(QQuickTextControl);
- p->save();
- QAbstractTextDocumentLayout::PaintContext ctx = getPaintContext();
- if (rect.isValid())
- p->setClipRect(rect, Qt::IntersectClip);
- ctx.clip = rect;
-
- d->doc->documentLayout()->draw(p, ctx);
- p->restore();
-}
-
int QQuickTextControl::hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const
{
Q_D(const QQuickTextControl);
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index e7beefdaa3..97ecdc4c6e 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -90,9 +90,6 @@ public:
explicit QQuickTextControl(QTextDocument *doc, QObject *parent = 0);
virtual ~QQuickTextControl();
- void setView(QObject *view);
- QObject *view() const;
-
QTextDocument *document() const;
void setTextCursor(const QTextCursor &cursor);
@@ -127,9 +124,6 @@ public:
qreal textWidth() const;
QSizeF size() const;
- void setIgnoreUnusedNavigationEvents(bool ignore);
- bool ignoreUnusedNavigationEvents() const;
-
void moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
bool canPaste() const;
@@ -178,16 +172,10 @@ Q_SIGNALS:
void linkHovered(const QString &);
public:
- // control properties
- QPalette palette() const;
- void setPalette(const QPalette &pal);
-
virtual void processEvent(QEvent *e, const QMatrix &matrix);
void processEvent(QEvent *e, const QPointF &coordinateOffset = QPointF());
// control methods
- void drawContents(QPainter *painter, const QRectF &rect = QRectF());
-
void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason);
virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
diff --git a/src/quick/items/qquicktextcontrol_p_p.h b/src/quick/items/qquicktextcontrol_p_p.h
index daf2f8ca82..44bc00221b 100644
--- a/src/quick/items/qquicktextcontrol_p_p.h
+++ b/src/quick/items/qquicktextcontrol_p_p.h
@@ -132,49 +132,40 @@ public:
bool isPreediting() const;
void commitPreedit();
- QTextDocument *doc;
- bool cursorOn;
- QTextCursor cursor;
- bool cursorIsFocusIndicator;
- QTextCharFormat lastCharFormat;
-
- Qt::TextInteractionFlags interactionFlags;
-
- QBasicTimer cursorBlinkTimer;
- QBasicTimer trippleClickTimer;
QPointF trippleClickPoint;
+ QPointF mousePressPos;
- bool mousePressed;
-
- QPoint mousePressPos;
-
- QPointer<QObject> contextObject;
-
- bool lastSelectionState;
-
- bool ignoreAutomaticScrollbarAdjustement;
+ QTextCharFormat lastCharFormat;
+ QTextDocument *doc;
+ QTextCursor cursor;
QTextCursor selectedWordOnDoubleClick;
QTextCursor selectedBlockOnTrippleClick;
+ QString tentativeCommit;
+ QString highlightedAnchor; // Anchor below cursor
+ QString anchorOnMousePress;
+ QString linkToCopy;
- bool overwriteMode;
- bool acceptRichText;
+ QBasicTimer cursorBlinkTimer;
+ QBasicTimer trippleClickTimer;
int preeditCursor;
- bool hideCursor; // used to hide the cursor in the preedit area
- QString tentativeCommit;
-
- QPalette palette;
- bool hasFocus;
- bool isEnabled;
- QString highlightedAnchor; // Anchor below cursor
- QString anchorOnMousePress;
- bool hadSelectionOnMousePress;
+ Qt::TextInteractionFlags interactionFlags;
- bool wordSelectionEnabled;
+ bool cursorOn : 1;
+ bool cursorIsFocusIndicator : 1;
+ bool mousePressed : 1;
+ bool lastSelectionState : 1;
+ bool ignoreAutomaticScrollbarAdjustement : 1;
+ bool overwriteMode : 1;
+ bool acceptRichText : 1;
+ bool hideCursor : 1; // used to hide the cursor in the preedit area
+ bool hasFocus : 1;
+ bool isEnabled : 1;
+ bool hadSelectionOnMousePress : 1;
+ bool wordSelectionEnabled : 1;
- QString linkToCopy;
void _q_copyLink();
void _q_updateBlock(const QTextBlock &);
void _q_documentLayoutChanged();
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 6eed95767b..a9bff73bd9 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -399,9 +399,6 @@ void QQuickTextEdit::setColor(const QColor &color)
return;
d->color = color;
- QPalette pal = d->control->palette();
- pal.setColor(QPalette::Text, color);
- d->control->setPalette(pal);
updateDocument();
emit colorChanged(d->color);
}
@@ -424,9 +421,6 @@ void QQuickTextEdit::setSelectionColor(const QColor &color)
return;
d->selectionColor = color;
- QPalette pal = d->control->palette();
- pal.setColor(QPalette::Highlight, color);
- d->control->setPalette(pal);
updateDocument();
emit selectionColorChanged(d->selectionColor);
}
@@ -449,9 +443,6 @@ void QQuickTextEdit::setSelectedTextColor(const QColor &color)
return;
d->selectedTextColor = color;
- QPalette pal = d->control->palette();
- pal.setColor(QPalette::HighlightedText, color);
- d->control->setPalette(pal);
updateDocument();
emit selectedTextColorChanged(d->selectedTextColor);
}
@@ -741,10 +732,10 @@ QRectF QQuickTextEdit::positionToRectangle(int pos) const
Position 0 is before the first character, position 1 is after the first character
but before the second, and so on until position \l {text}.length, which is after all characters.
*/
-int QQuickTextEdit::positionAt(int x, int y) const
+int QQuickTextEdit::positionAt(qreal x, qreal y) const
{
Q_D(const QQuickTextEdit);
- int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
+ int r = d->document->documentLayout()->hitTest(QPointF(x,y-d->yoff), Qt::FuzzyHit);
QTextCursor cursor = d->control->textCursor();
if (r > cursor.position()) {
// The cursor position includes positions within the preedit text, but only positions in the
@@ -1299,10 +1290,10 @@ Qt::TextInteractionFlags QQuickTextEdit::textInteractionFlags() const
automatically when it changes. The width of the delegate is unaffected by changes in the
cursor rectangle.
*/
-QRect QQuickTextEdit::cursorRectangle() const
+QRectF QQuickTextEdit::cursorRectangle() const
{
Q_D(const QQuickTextEdit);
- return d->control->cursorRect().toRect().translated(0,d->yoff);
+ return d->control->cursorRect().translated(0, d->yoff);
}
bool QQuickTextEdit::event(QEvent *event)
@@ -1634,10 +1625,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
QRectF bounds = boundingRect();
- QColor selectionColor = d->control->palette().color(QPalette::Highlight);
- QColor selectedTextColor = d->control->palette().color(QPalette::HighlightedText);
node->addTextDocument(bounds.topLeft(), d->document, d->color, QQuickText::Normal, QColor(),
- selectionColor, selectedTextColor, selectionStart(),
+ d->selectionColor, d->selectedTextColor, selectionStart(),
selectionEnd() - 1); // selectionEnd() returns first char after
// selection
@@ -1756,31 +1745,21 @@ void QQuickTextEditPrivate::init()
document = new QQuickTextDocumentWithImageResources(q);
control = new QQuickTextControl(document, q);
- control->setView(q);
control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
control->setAcceptRichText(false);
control->setCursorIsFocusIndicator(true);
- // QQuickTextControl follows the default text color
- // defined by the platform, declarative text
- // should be black by default
- QPalette pal = control->palette();
- if (pal.color(QPalette::Text) != color) {
- pal.setColor(QPalette::Text, color);
- control->setPalette(pal);
- }
-
- QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateDocument()));
- QObject::connect(control, SIGNAL(updateCursorRequest()), q, SLOT(updateCursor()));
- QObject::connect(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
- QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
- QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
- QObject::connect(control, SIGNAL(cursorRectangleChanged()), q, SLOT(moveCursorDelegate()));
- QObject::connect(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
+ FAST_CONNECT(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateDocument()));
+ FAST_CONNECT(control, SIGNAL(updateCursorRequest()), q, SLOT(updateCursor()));
+ FAST_CONNECT(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
+ FAST_CONNECT(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
+ FAST_CONNECT(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
+ FAST_CONNECT(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
+ FAST_CONNECT(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
+ FAST_CONNECT(control, SIGNAL(cursorRectangleChanged()), q, SLOT(moveCursorDelegate()));
+ FAST_CONNECT(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
#ifndef QT_NO_CLIPBOARD
- QObject::connect(QGuiApplication::clipboard(), SIGNAL(dataChanged()), q, SLOT(q_canPasteChanged()));
+ FAST_CONNECT(QGuiApplication::clipboard(), SIGNAL(dataChanged()), q, SLOT(q_canPasteChanged()));
#endif
FAST_CONNECT(document, SIGNAL(undoAvailable(bool)), q, SIGNAL(canUndoChanged()));
FAST_CONNECT(document, SIGNAL(redoAvailable(bool)), q, SIGNAL(canRedoChanged()));
@@ -1884,11 +1863,11 @@ void QQuickTextEdit::updateSize()
} else {
d->document->setTextWidth(-1);
}
- QFontMetrics fm = QFontMetrics(d->font);
- int dy = height();
- dy -= (int)d->document->size().height();
+ QFontMetricsF fm(d->font);
+ qreal dy = height();
+ dy -= d->document->size().height();
- int nyoff;
+ qreal nyoff;
if (heightValid()) {
if (d->vAlign == AlignBottom)
nyoff = dy;
@@ -1904,7 +1883,7 @@ void QQuickTextEdit::updateSize()
setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
//### need to comfirm cost of always setting these
- int newWidth = qCeil(d->document->idealWidth());
+ qreal newWidth = d->document->idealWidth();
if (!widthValid() && d->document->textWidth() != newWidth)
d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
// ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
@@ -1913,13 +1892,13 @@ void QQuickTextEdit::updateSize()
iWidth = newWidth;
else if (d->requireImplicitWidth)
iWidth = naturalWidth;
- qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
+ qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height();
if (iWidth > -1)
setImplicitSize(iWidth, newHeight);
else
setImplicitHeight(newHeight);
- QSize size(newWidth, newHeight);
+ QSizeF size(newWidth, newHeight);
if (d->contentSize != size) {
d->contentSize = size;
emit contentSizeChanged();
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 4dcb7f48d6..b28ec9d7d7 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -79,7 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
- Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+ Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
Q_PROPERTY(QQmlComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
@@ -212,7 +212,7 @@ public:
void setTextInteractionFlags(Qt::TextInteractionFlags flags);
Qt::TextInteractionFlags textInteractionFlags() const;
- QRect cursorRectangle() const;
+ QRectF cursorRectangle() const;
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
@@ -224,7 +224,7 @@ public:
void resetBaseUrl();
Q_INVOKABLE QRectF positionToRectangle(int) const;
- Q_INVOKABLE int positionAt(int x, int y) const;
+ Q_INVOKABLE int positionAt(qreal x, qreal y) const;
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 3004d5b833..055b5c7929 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -68,15 +68,17 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate
public:
QQuickTextEditPrivate()
- : color("black"), hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop),
- documentDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true),
- persistentSelection(false), requireImplicitWidth(false), selectByMouse(false), canPaste(false),
- canPasteValid(false), hAlignImplicit(true), rightToLeftText(false),
- textCached(false),
- textMargin(0.0), lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0),
- format(QQuickTextEdit::PlainText), document(0), wrapMode(QQuickTextEdit::NoWrap),
- mouseSelectionMode(QQuickTextEdit::SelectCharacters),
- lineCount(0), yoff(0), inputMethodHints(Qt::ImhNone), updateType(UpdatePaintNode)
+ : color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF))
+ , textMargin(0.0), yoff(0), font(sourceFont), cursorComponent(0), cursor(0), document(0), control(0)
+ , lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
+ , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
+ , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
+ , mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone)
+ , updateType(UpdatePaintNode)
+ , documentDirty(true), dirty(false), richText(false), cursorVisible(false)
+ , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false)
+ , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true)
+ , rightToLeftText(false), textCached(false)
{
}
@@ -92,17 +94,42 @@ public:
void mirrorChange();
qreal getImplicitWidth() const;
+ QColor color;
+ QColor selectionColor;
+ QColor selectedTextColor;
+
+ QSizeF contentSize;
+
+ qreal textMargin;
+ qreal yoff;
+
QString text;
QUrl baseUrl;
- QFont font;
QFont sourceFont;
- QColor color;
- QColor selectionColor;
- QColor selectedTextColor;
- QString style;
- QColor styleColor;
+ QFont font;
+
+ QQmlComponent* cursorComponent;
+ QQuickItem* cursor;
+ QQuickTextDocumentWithImageResources *document;
+ QQuickTextControl *control;
+
+ int lastSelectionStart;
+ int lastSelectionEnd;
+ int lineCount;
+
+ enum UpdateType {
+ UpdateNone,
+ UpdateOnlyPreprocess,
+ UpdatePaintNode
+ };
+
QQuickTextEdit::HAlignment hAlign;
QQuickTextEdit::VAlignment vAlign;
+ QQuickTextEdit::TextFormat format;
+ QQuickTextEdit::WrapMode wrapMode;
+ QQuickTextEdit::SelectionMode mouseSelectionMode;
+ Qt::InputMethodHints inputMethodHints;
+ UpdateType updateType;
bool documentDirty : 1;
bool dirty : 1;
@@ -117,28 +144,6 @@ public:
bool hAlignImplicit:1;
bool rightToLeftText:1;
bool textCached:1;
-
- qreal textMargin;
- int lastSelectionStart;
- int lastSelectionEnd;
- QQmlComponent* cursorComponent;
- QQuickItem* cursor;
- QQuickTextEdit::TextFormat format;
- QQuickTextDocumentWithImageResources *document;
- QQuickTextControl *control;
- QQuickTextEdit::WrapMode wrapMode;
- QQuickTextEdit::SelectionMode mouseSelectionMode;
- int lineCount;
- int yoff;
- QSize contentSize;
- Qt::InputMethodHints inputMethodHints;
-
- enum UpdateType {
- UpdateNone,
- UpdateOnlyPreprocess,
- UpdatePaintNode
- };
- UpdateType updateType;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index ab5afa334d..1a93345aa2 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -677,7 +677,7 @@ void QQuickTextInput::setCursorPosition(int cp)
cursor rectangle.
*/
-QRect QQuickTextInput::cursorRectangle() const
+QRectF QQuickTextInput::cursorRectangle() const
{
Q_D(const QQuickTextInput);
@@ -688,12 +688,8 @@ QRect QQuickTextInput::cursorRectangle() const
c = 0;
QTextLine l = d->m_textLayout.lineForTextPosition(c);
if (!l.isValid())
- return QRect();
- return QRect(
- qRound(l.cursorToX(c) - d->hscroll),
- qRound(l.y() - d->vscroll),
- 1,
- qCeil(l.height()));
+ return QRectF();
+ return QRectF(l.cursorToX(c) - d->hscroll, l.y() - d->vscroll, 1, l.height());
}
/*!
@@ -1368,7 +1364,7 @@ void QQuickTextInput::positionAt(QQmlV8Function *args) const
args->returnValue(v8::Int32::New(pos));
}
-int QQuickTextInputPrivate::positionAt(int x, int y, QTextLine::CursorPosition position) const
+int QQuickTextInputPrivate::positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const
{
x += hscroll;
y += vscroll;
@@ -1432,7 +1428,7 @@ void QQuickTextInput::mouseDoubleClickEvent(QMouseEvent *event)
d->selectWordAtPos(cursor);
event->setAccepted(true);
if (!d->hasPendingTripleClick()) {
- d->tripleClickStartPoint = event->localPos().toPoint();
+ d->tripleClickStartPoint = event->localPos();
d->tripleClickTimer.start();
}
} else {
@@ -1617,15 +1613,15 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
Q_Q(QQuickTextInput);
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + m_preeditCursor);
const int preeditLength = m_textLayout.preeditAreaText().length();
- const int width = qMax(0, qFloor(q->width()));
- int widthUsed = currentLine.isValid() ? qRound(currentLine.naturalTextWidth()) : 0;
+ const qreal width = qMax<qreal>(0, q->width());
+ qreal widthUsed = currentLine.isValid() ? currentLine.naturalTextWidth() : 0;
int previousScroll = hscroll;
if (!autoScroll || widthUsed <= width || m_echoMode == QQuickTextInput::NoEcho) {
hscroll = 0;
} else {
Q_ASSERT(currentLine.isValid());
- int cix = qRound(currentLine.cursorToX(m_cursor + preeditLength));
+ qreal cix = currentLine.cursorToX(m_cursor + preeditLength);
if (cix - hscroll >= width) {
// text doesn't fit, cursor is to the right of br (scroll right)
hscroll = cix - width;
@@ -1640,7 +1636,7 @@ void QQuickTextInputPrivate::updateHorizontalScroll()
if (preeditLength > 0) {
// check to ensure long pre-edit text doesn't push the cursor
// off to the left
- cix = qRound(currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1)));
+ cix = currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1));
if (cix < hscroll)
hscroll = cix;
}
@@ -1653,9 +1649,9 @@ void QQuickTextInputPrivate::updateVerticalScroll()
{
Q_Q(QQuickTextInput);
const int preeditLength = m_textLayout.preeditAreaText().length();
- const int height = qMax(0, qFloor(q->height()));
- int heightUsed = boundingRect.height();
- int previousScroll = vscroll;
+ const qreal height = qMax<qreal>(0, q->height());
+ qreal heightUsed = boundingRect.height();
+ qreal previousScroll = vscroll;
if (!autoScroll || heightUsed <= height) {
// text fits in br; use vscroll for alignment
@@ -1674,8 +1670,8 @@ void QQuickTextInputPrivate::updateVerticalScroll()
} else {
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + preeditLength);
QRectF r = currentLine.isValid() ? currentLine.rect() : QRectF();
- int top = qFloor(r.top());
- int bottom = qCeil(r.bottom());
+ qreal top = r.top();
+ int bottom = r.bottom();
if (bottom - vscroll >= height) {
// text doesn't fit, cursor is to the below the br (scroll down)
@@ -1692,7 +1688,7 @@ void QQuickTextInputPrivate::updateVerticalScroll()
// check to ensure long pre-edit text doesn't push the cursor
// off the top
currentLine = m_textLayout.lineForTextPosition(m_cursor + qMax(0, m_preeditCursor - 1));
- top = currentLine.isValid() ? qRound(currentLine.rect().top()) : 0;
+ top = currentLine.isValid() ? currentLine.rect().top() : 0;
if (top < vscroll)
vscroll = top;
}
@@ -1742,11 +1738,11 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
node->deleteContent();
node->setMatrix(QMatrix4x4());
- QPoint offset = QPoint(0,0);
+ QPointF offset(0, 0);
if (d->autoScroll && d->m_textLayout.lineCount() > 0) {
- QFontMetrics fm = QFontMetrics(d->font);
+ QFontMetricsF fm(d->font);
// the y offset is there to keep the baseline constant in case we have script changes in the text.
- offset = -QPoint(d->hscroll, d->vscroll + qRound(d->m_textLayout.lineAt(0).ascent()) - fm.ascent());
+ offset = -QPoint(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent());
} else {
offset = -QPoint(d->hscroll, d->vscroll);
}
@@ -2732,7 +2728,7 @@ void QQuickTextInputPrivate::updateLayout()
updateType = UpdatePaintNode;
q->update();
- q->setImplicitSize(qCeil(boundingRect.width()), qCeil(boundingRect.height()));
+ q->setImplicitSize(boundingRect.width(), boundingRect.height());
if (previousRect != boundingRect)
emit q->contentSizeChanged();
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index 8961dbc3e1..011af65bff 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -76,7 +76,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged)
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
- Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
+ Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged)
Q_PROPERTY(QQmlComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged)
Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged)
Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged)
@@ -195,7 +195,7 @@ public:
int cursorPosition() const;
void setCursorPosition(int cp);
- QRect cursorRectangle() const;
+ QRectF cursorRectangle() const;
int selectionStart() const;
int selectionEnd() const;
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 2575694888..9a59b44549 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -77,14 +77,14 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr
Q_DECLARE_PUBLIC(QQuickTextInput)
public:
QQuickTextInputPrivate()
- : cursorItem(0)
+ : hscroll(0)
+ , vscroll(0)
+ , cursorItem(0)
, textNode(0)
, m_maskData(0)
, color(QRgb(0xFF000000))
, selectionColor(QRgb(0xFF000080))
, selectedTextColor(QRgb(0xFFFFFFFF))
- , hscroll(0)
- , vscroll(0)
, m_cursor(0)
, m_preeditCursor(0)
, m_blinkPeriod(0)
@@ -179,6 +179,9 @@ public:
QQmlGuard<QValidator> m_validator;
#endif
+ qreal hscroll;
+ qreal vscroll;
+
QTextLayout m_textLayout;
QString m_text;
QString m_inputMask;
@@ -203,8 +206,6 @@ public:
#endif
int lastSelectionStart;
int lastSelectionEnd;
- int hscroll;
- int vscroll;
int m_cursor;
int m_preeditCursor;
int m_blinkPeriod; // 0 for non-blinking cursor
@@ -295,7 +296,7 @@ public:
int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
- int positionAt(int x, int y, QTextLine::CursorPosition position) const;
+ int positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const;
int positionAt(const QPointF &point, QTextLine::CursorPosition position = QTextLine::CursorBetweenCharacters) const {
return positionAt(point.x(), point.y(), position);
}
diff --git a/src/quick/items/qquickvisualadaptormodel_p.h b/src/quick/items/qquickvisualadaptormodel_p.h
index 93de4b1126..cf6dabe237 100644
--- a/src/quick/items/qquickvisualadaptormodel_p.h
+++ b/src/quick/items/qquickvisualadaptormodel_p.h
@@ -121,7 +121,9 @@ public:
virtual QObject *proxiedObject() = 0;
};
-Q_DECLARE_INTERFACE(QQuickVisualAdaptorModelProxyInterface, "com.trolltech.qml.QQuickVisualAdaptorModelProxyInterface")
+#define QQuickVisualAdaptorModelProxyInterface_iid "org.qt-project.Qt.QQuickVisualAdaptorModelProxyInterface"
+
+Q_DECLARE_INTERFACE(QQuickVisualAdaptorModelProxyInterface, QQuickVisualAdaptorModelProxyInterface_iid)
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp
index 07ad3660be..70f8897b2d 100644
--- a/src/quick/items/qquickvisualdatamodel.cpp
+++ b/src/quick/items/qquickvisualdatamodel.cpp
@@ -450,6 +450,41 @@ QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModel::release(QQuickItem *i
return stat;
}
+// Cancel a requested async item
+void QQuickVisualDataModel::cancel(int index)
+{
+ Q_D(QQuickVisualDataModel);
+ if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) {
+ qWarning() << "VisualDataModel::cancel: index out range" << index << d->m_compositor.count(d->m_compositorGroup);
+ return;
+ }
+
+ Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index);
+ QQuickVisualDataModelItem *cacheItem = it->inCache() ? d->m_cache.at(it.cacheIndex) : 0;
+ if (cacheItem) {
+ if (cacheItem->incubationTask) {
+ delete cacheItem->incubationTask->incubatingContext;
+ cacheItem->incubationTask->incubatingContext = 0;
+ d->releaseIncubator(cacheItem->incubationTask);
+ cacheItem->incubationTask = 0;
+ }
+ if (cacheItem->object && !cacheItem->isObjectReferenced()) {
+ d->destroy(cacheItem->object);
+ if (QQuickPackage *package = qobject_cast<QQuickPackage *>(cacheItem->object))
+ d->emitDestroyingPackage(package);
+ else if (QQuickItem *item = qobject_cast<QQuickItem *>(cacheItem->object))
+ d->emitDestroyingItem(item);
+ cacheItem->object = 0;
+ }
+ if (!cacheItem->isReferenced()) {
+ d->m_compositor.clearFlags(Compositor::Cache, it.cacheIndex, 1, Compositor::CacheFlag);
+ d->m_cache.removeAt(it.cacheIndex);
+ delete cacheItem;
+ Q_ASSERT(d->m_cache.count() == d->m_compositor.count(Compositor::Cache));
+ }
+ }
+}
+
void QQuickVisualDataModelPrivate::group_append(
QQmlListProperty<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group)
{
@@ -708,8 +743,10 @@ void QQuickVisualDataModelPrivate::incubatorStatusChanged(QVDMIncubationTask *in
incubationTask->incubatingContext = 0;
if (!cacheItem->isReferenced()) {
int cidx = m_cache.indexOf(cacheItem);
- m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag);
- m_cache.removeAt(cidx);
+ if (cidx >= 0) {
+ m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag);
+ m_cache.removeAt(cidx);
+ }
delete cacheItem;
Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache));
}
diff --git a/src/quick/items/qquickvisualdatamodel_p.h b/src/quick/items/qquickvisualdatamodel_p.h
index ee90d528f4..535374be09 100644
--- a/src/quick/items/qquickvisualdatamodel_p.h
+++ b/src/quick/items/qquickvisualdatamodel_p.h
@@ -106,6 +106,7 @@ public:
bool isValid() const { return delegate() != 0; }
QQuickItem *item(int index, bool asynchronous=false);
ReleaseFlags release(QQuickItem *item);
+ void cancel(int index);
virtual QString stringValue(int index, const QString &role);
virtual void setWatchedRoles(QList<QByteArray> roles);
diff --git a/src/quick/items/qquickvisualitemmodel_p.h b/src/quick/items/qquickvisualitemmodel_p.h
index 9f90a29125..bf56195c66 100644
--- a/src/quick/items/qquickvisualitemmodel_p.h
+++ b/src/quick/items/qquickvisualitemmodel_p.h
@@ -69,6 +69,7 @@ public:
virtual bool isValid() const = 0;
virtual QQuickItem *item(int index, bool asynchronous=false) = 0;
virtual ReleaseFlags release(QQuickItem *item) = 0;
+ virtual void cancel(int) {}
virtual QString stringValue(int, const QString &) = 0;
virtual void setWatchedRoles(QList<QByteArray> roles) = 0;
diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp
index 55f11bf4c0..5de8ad1279 100644
--- a/src/quick/items/qquickwindowmanager.cpp
+++ b/src/quick/items/qquickwindowmanager.cpp
@@ -48,8 +48,8 @@
#include <QtCore/private/qabstractanimation_p.h>
#include <QtGui/QOpenGLContext>
-#include <QtGui/QPlatformIntegration>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qplatformintegration_qpa.h>
#include <QtQml/private/qqmlglobal_p.h>
@@ -145,6 +145,10 @@ DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP);
//#define THREAD_DEBUG
+QQuickWindowManager::~QQuickWindowManager()
+{
+}
+
class QQuickRenderThreadSingleContextWindowManager : public QThread, public QQuickWindowManager
{
Q_OBJECT
@@ -165,7 +169,6 @@ public:
, shouldExit(false)
, hasExited(false)
, isDeferredUpdatePosted(false)
- , runToReleaseResources(false)
, canvasToGrab(0)
{
sg->moveToThread(this);
@@ -176,13 +179,10 @@ public:
connect(animationDriver, SIGNAL(stopped()), this, SLOT(animationStopped()));
}
- ~QQuickRenderThreadSingleContextWindowManager()
- {
- releaseResources();
- }
-
QSGContext *sceneGraphContext() const { return sg; }
+ void releaseResources() { }
+
void show(QQuickCanvas *canvas);
void hide(QQuickCanvas *canvas);
@@ -193,6 +193,7 @@ public:
void resize(QQuickCanvas *canvas, const QSize &size);
void handleDeferredUpdate();
void maybeUpdate(QQuickCanvas *canvas);
+ void wakeup();
void startRendering();
void stopRendering();
@@ -201,10 +202,8 @@ public:
void sync(bool guiAlreadyLocked);
void initialize();
- void releaseResources();
- void releaseResourcesInThread();
- bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
+ volatile bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
bool event(QEvent *);
@@ -245,7 +244,7 @@ private:
QMutex mutex;
QWaitCondition condition;
- bool allowMainThreadProcessingFlag;
+ volatile bool allowMainThreadProcessingFlag;
int isGuiLocked;
uint animationRunning: 1;
@@ -258,7 +257,6 @@ private:
uint shouldExit : 1;
uint hasExited : 1;
uint isDeferredUpdatePosted : 1;
- uint runToReleaseResources : 1;
QQuickCanvas *canvasToGrab;
QImage grabContent;
@@ -291,29 +289,26 @@ class QQuickTrivialWindowManager : public QObject, public QQuickWindowManager
{
public:
QQuickTrivialWindowManager();
- ~QQuickTrivialWindowManager()
- {
- releaseResources();
- }
void show(QQuickCanvas *canvas);
void hide(QQuickCanvas *canvas);
void canvasDestroyed(QQuickCanvas *canvas);
- void releaseResources();
void initializeGL();
void renderCanvas(QQuickCanvas *canvas);
void paint(QQuickCanvas *canvas);
QImage grab(QQuickCanvas *canvas);
void resize(QQuickCanvas *canvas, const QSize &size);
+ void wakeup();
void maybeUpdate(QQuickCanvas *canvas);
- bool *allowMainThreadProcessing();
+ void releaseResources() { }
+
+ volatile bool *allowMainThreadProcessing();
QSGContext *sceneGraphContext() const;
- QQuickCanvas *masterCanvas() const;
bool event(QEvent *);
@@ -564,18 +559,10 @@ void QQuickRenderThreadSingleContextWindowManager::run()
#ifdef THREAD_DEBUG
printf("QML Rendering Thread Started\n");
#endif
- lock();
-
- if (runToReleaseResources) {
- releaseResourcesInThread();
- runToReleaseResources = false;
- unlock();
- return;
- }
-
- if (!gl)
- initialize();
+ lock();
+ Q_ASSERT(!gl);
+ initialize();
// Wake GUI as it is waiting for the GL context to have appeared, as
// an indication that the render thread is now running.
wake();
@@ -772,6 +759,12 @@ void QQuickRenderThreadSingleContextWindowManager::run()
m_removed_windows << m_rendered_windows.keys();
handleRemovedWindows();
+ sg->invalidate();
+
+ gl->doneCurrent();
+ delete gl;
+ gl = 0;
+
#ifdef THREAD_DEBUG
printf(" RenderThread: render loop exited... Good Night!\n");
#endif
@@ -790,59 +783,6 @@ void QQuickRenderThreadSingleContextWindowManager::run()
#endif
}
-void QQuickRenderThreadSingleContextWindowManager::releaseResourcesInThread()
-{
-#ifdef THREAD_DEBUG
- printf(" RenderThread: releasing resources...\n");
-#endif
- QQuickCanvas *canvas = masterCanvas();
- QWindow *tmpSurface = 0;
-
- if (canvas) {
- gl->makeCurrent(canvas);
- } else {
- tmpSurface = new QWindow();
- tmpSurface->setSurfaceType(QSurface::OpenGLSurface);
- tmpSurface->resize(4, 4);
- tmpSurface->create();
- gl->makeCurrent(tmpSurface);
- }
-
- sg->invalidate();
- gl->doneCurrent();
- delete gl;
- gl = 0;
-
- if (tmpSurface)
- delete tmpSurface;
-
- wake();
-}
-
-void QQuickRenderThreadSingleContextWindowManager::releaseResources()
-{
-#ifdef THREAD_DEBUG
- printf("GUI: releasing resources\n");
-#endif
-
- lockInGui();
- if (!isRunning() && gl) {
- runToReleaseResources = true;
- start();
-
- while (isRunning()) {
- wait();
- }
- }
-#ifdef THREAD_DEBUG
- else {
- printf("GUI: render thread running not releasing resources...\n");
- }
-#endif
- unlockInGui();
-
-}
-
bool QQuickRenderThreadSingleContextWindowManager::event(QEvent *e)
{
Q_ASSERT(QThread::currentThread() == qApp->thread());
@@ -1074,6 +1014,7 @@ void QQuickRenderThreadSingleContextWindowManager::startRendering()
animationTimer = -1;
}
+
}
@@ -1190,6 +1131,14 @@ void QQuickRenderThreadSingleContextWindowManager::maybeUpdate(QQuickCanvas *)
}
+void QQuickRenderThreadSingleContextWindowManager::wakeup()
+{
+ lockInGui();
+ if (isRenderBlocked)
+ wake();
+ unlockInGui();
+}
+
QQuickTrivialWindowManager::QQuickTrivialWindowManager()
: gl(0)
, eventPending(false)
@@ -1216,46 +1165,17 @@ void QQuickTrivialWindowManager::hide(QQuickCanvas *canvas)
m_windows.remove(canvas);
QQuickCanvasPrivate *cd = QQuickCanvasPrivate::get(canvas);
cd->cleanupNodesOnShutdown();
-}
-
-void QQuickTrivialWindowManager::canvasDestroyed(QQuickCanvas *canvas)
-{
- hide(canvas);
-}
-
-void QQuickTrivialWindowManager::releaseResources()
-{
- if (m_windows.size() == 0 && gl) {
- QQuickCanvas *canvas = masterCanvas();
- QWindow *tmpSurface = 0;
-
- if (canvas) {
- gl->makeCurrent(canvas);
- } else {
- tmpSurface = new QWindow();
- tmpSurface->setSurfaceType(QSurface::OpenGLSurface);
- tmpSurface->resize(4, 4);
- tmpSurface->create();
- gl->makeCurrent(tmpSurface);
- }
+ if (m_windows.size() == 0) {
sg->invalidate();
delete gl;
gl = 0;
-
- delete tmpSurface;
}
}
-QQuickCanvas *QQuickTrivialWindowManager::masterCanvas() const
+void QQuickTrivialWindowManager::canvasDestroyed(QQuickCanvas *canvas)
{
- // Find a "proper surface" to bind...
- for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin();
- it != m_windows.constEnd(); ++it) {
- if (it.key()->visible())
- return it.key();
- }
- return 0;
+ hide(canvas);
}
void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas)
@@ -1265,20 +1185,30 @@ void QQuickTrivialWindowManager::renderCanvas(QQuickCanvas *canvas)
CanvasData &data = const_cast<CanvasData &>(m_windows[canvas]);
- QQuickCanvas *window = canvas->visible() ? canvas : masterCanvas();
+ QQuickCanvas *masterCanvas = 0;
+ if (!canvas->visible()) {
+ // Find a "proper surface" to bind...
+ for (QHash<QQuickCanvas *, CanvasData>::const_iterator it = m_windows.constBegin();
+ it != m_windows.constEnd() && !masterCanvas; ++it) {
+ if (it.key()->visible())
+ masterCanvas = it.key();
+ }
+ } else {
+ masterCanvas = canvas;
+ }
- if (!window)
+ if (!masterCanvas)
return;
if (!gl) {
gl = new QOpenGLContext();
- gl->setFormat(window->requestedFormat());
+ gl->setFormat(masterCanvas->requestedFormat());
gl->create();
- if (!gl->makeCurrent(window))
+ if (!gl->makeCurrent(masterCanvas))
qWarning("QQuickCanvas: makeCurrent() failed...");
sg->initialize(gl);
} else {
- gl->makeCurrent(window);
+ gl->makeCurrent(masterCanvas);
}
bool alsoSwap = data.updatePending;
@@ -1348,9 +1278,11 @@ void QQuickTrivialWindowManager::maybeUpdate(QQuickCanvas *canvas)
}
}
+void QQuickTrivialWindowManager::wakeup()
+{
+}
-
-bool *QQuickTrivialWindowManager::allowMainThreadProcessing()
+volatile bool *QQuickTrivialWindowManager::allowMainThreadProcessing()
{
return 0;
}
diff --git a/src/quick/items/qquickwindowmanager_p.h b/src/quick/items/qquickwindowmanager_p.h
index ed972b5c76..9372e90f5e 100644
--- a/src/quick/items/qquickwindowmanager_p.h
+++ b/src/quick/items/qquickwindowmanager_p.h
@@ -52,6 +52,8 @@ class QSGContext;
class QQuickWindowManager
{
public:
+ virtual ~QQuickWindowManager();
+
virtual void show(QQuickCanvas *canvas) = 0;
virtual void hide(QQuickCanvas *canvas) = 0;
@@ -62,8 +64,9 @@ public:
virtual void resize(QQuickCanvas *canvas, const QSize &size) = 0;
virtual void maybeUpdate(QQuickCanvas *canvas) = 0;
+ virtual void wakeup() = 0;
- virtual bool *allowMainThreadProcessing() = 0;
+ virtual volatile bool *allowMainThreadProcessing() = 0;
virtual QSGContext *sceneGraphContext() const = 0;
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 6faeb96da0..4c9620748a 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index e0da37d22c..72fd2b32bd 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickage.cpp b/src/quick/particles/qquickage.cpp
index 307fb58577..9f24cba3cc 100644
--- a/src/quick/particles/qquickage.cpp
+++ b/src/quick/particles/qquickage.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickage_p.h b/src/quick/particles/qquickage_p.h
index 60fc0bd98d..2ec8faae4b 100644
--- a/src/quick/particles/qquickage_p.h
+++ b/src/quick/particles/qquickage_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickangledirection.cpp b/src/quick/particles/qquickangledirection.cpp
index 48fc5a8273..a3bd45e0bf 100644
--- a/src/quick/particles/qquickangledirection.cpp
+++ b/src/quick/particles/qquickangledirection.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qquickangledirection_p.h"
+#include <stdlib.h>
#include <cmath>
QT_BEGIN_NAMESPACE
const qreal CONV = 0.017453292519943295;
diff --git a/src/quick/particles/qquickangledirection_p.h b/src/quick/particles/qquickangledirection_p.h
index 4f86fec5f4..84633cd40e 100644
--- a/src/quick/particles/qquickangledirection_p.h
+++ b/src/quick/particles/qquickangledirection_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickcumulativedirection.cpp b/src/quick/particles/qquickcumulativedirection.cpp
index 4f4a2cc46e..d7c4094297 100644
--- a/src/quick/particles/qquickcumulativedirection.cpp
+++ b/src/quick/particles/qquickcumulativedirection.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickcumulativedirection_p.h b/src/quick/particles/qquickcumulativedirection_p.h
index 38663572fb..e1675a18d8 100644
--- a/src/quick/particles/qquickcumulativedirection_p.h
+++ b/src/quick/particles/qquickcumulativedirection_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickcustomaffector.cpp b/src/quick/particles/qquickcustomaffector.cpp
index 7c991c7352..acec98192d 100644
--- a/src/quick/particles/qquickcustomaffector.cpp
+++ b/src/quick/particles/qquickcustomaffector.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickcustomaffector_p.h b/src/quick/particles/qquickcustomaffector_p.h
index e831dbce1d..1266830f94 100644
--- a/src/quick/particles/qquickcustomaffector_p.h
+++ b/src/quick/particles/qquickcustomaffector_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickdirection.cpp b/src/quick/particles/qquickdirection.cpp
index da022fe4f5..4127d06be0 100644
--- a/src/quick/particles/qquickdirection.cpp
+++ b/src/quick/particles/qquickdirection.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickdirection_p.h b/src/quick/particles/qquickdirection_p.h
index 22e2278b46..651865a1f5 100644
--- a/src/quick/particles/qquickdirection_p.h
+++ b/src/quick/particles/qquickdirection_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickellipseextruder.cpp b/src/quick/particles/qquickellipseextruder.cpp
index 3b80810773..3eb547fd2f 100644
--- a/src/quick/particles/qquickellipseextruder.cpp
+++ b/src/quick/particles/qquickellipseextruder.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qquickellipseextruder_p.h"
+#include <stdlib.h>
#include <cmath>
QT_BEGIN_NAMESPACE
/*!
diff --git a/src/quick/particles/qquickellipseextruder_p.h b/src/quick/particles/qquickellipseextruder_p.h
index 00b151eae2..c2d0c634ab 100644
--- a/src/quick/particles/qquickellipseextruder_p.h
+++ b/src/quick/particles/qquickellipseextruder_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickfriction.cpp b/src/quick/particles/qquickfriction.cpp
index 57de3d9eac..d37d109f48 100644
--- a/src/quick/particles/qquickfriction.cpp
+++ b/src/quick/particles/qquickfriction.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickfriction_p.h b/src/quick/particles/qquickfriction_p.h
index b79e57a047..3b06710529 100644
--- a/src/quick/particles/qquickfriction_p.h
+++ b/src/quick/particles/qquickfriction_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickgravity.cpp b/src/quick/particles/qquickgravity.cpp
index 2ab3a299f1..cf4f35eb72 100644
--- a/src/quick/particles/qquickgravity.cpp
+++ b/src/quick/particles/qquickgravity.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickgravity_p.h b/src/quick/particles/qquickgravity_p.h
index 807b315255..a738fd3ef3 100644
--- a/src/quick/particles/qquickgravity_p.h
+++ b/src/quick/particles/qquickgravity_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickgroupgoal.cpp b/src/quick/particles/qquickgroupgoal.cpp
index 926768d27a..0d7f15a9e1 100644
--- a/src/quick/particles/qquickgroupgoal.cpp
+++ b/src/quick/particles/qquickgroupgoal.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickgroupgoal_p.h b/src/quick/particles/qquickgroupgoal_p.h
index 483d45fc50..f553badbd6 100644
--- a/src/quick/particles/qquickgroupgoal_p.h
+++ b/src/quick/particles/qquickgroupgoal_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickimageparticle.cpp b/src/quick/particles/qquickimageparticle.cpp
index bf576b0a54..7f87dabe7d 100644
--- a/src/quick/particles/qquickimageparticle.cpp
+++ b/src/quick/particles/qquickimageparticle.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -1237,6 +1237,9 @@ void QQuickImageParticle::clearShadows()
//Only call if you need to, may initialize the whole array first time
QQuickParticleData* QQuickImageParticle::getShadowDatum(QQuickParticleData* datum)
{
+ //Will return datum if the datum is a sentinel or uninitialized, to centralize that one check
+ if (datum->systemIndex == -1)
+ return datum;
QQuickParticleGroupData* gd = m_system->groupData[datum->group];
if (!m_shadowData.contains(datum->group)) {
QVector<QQuickParticleData*> data;
@@ -1339,6 +1342,10 @@ void QQuickImageParticle::finishBuildParticleNodes()
}
}
}
+#ifdef Q_OS_WIN
+ if (perfLevel < Deformable) //QTBUG-24540 , point sprite 'extension' isn't working on windows.
+ perfLevel = Deformable;
+#endif
if (perfLevel >= Colored && !m_color.isValid())
m_color = QColor(Qt::white);//Hidden default, but different from unset
diff --git a/src/quick/particles/qquickimageparticle_p.h b/src/quick/particles/qquickimageparticle_p.h
index 401f4609b0..dca524bcab 100644
--- a/src/quick/particles/qquickimageparticle_p.h
+++ b/src/quick/particles/qquickimageparticle_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickitemparticle.cpp b/src/quick/particles/qquickitemparticle.cpp
index 571ca7f8a5..91ef06fcb2 100644
--- a/src/quick/particles/qquickitemparticle.cpp
+++ b/src/quick/particles/qquickitemparticle.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickitemparticle_p.h b/src/quick/particles/qquickitemparticle_p.h
index d02659889e..c7b8a2661e 100644
--- a/src/quick/particles/qquickitemparticle_p.h
+++ b/src/quick/particles/qquickitemparticle_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquicklineextruder.cpp b/src/quick/particles/qquicklineextruder.cpp
index c98ce8d76b..f555de3f72 100644
--- a/src/quick/particles/qquicklineextruder.cpp
+++ b/src/quick/particles/qquicklineextruder.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,6 +39,7 @@
**
****************************************************************************/
#include "qquicklineextruder_p.h"
+#include <stdlib.h>
#include <cmath>
/*!
diff --git a/src/quick/particles/qquicklineextruder_p.h b/src/quick/particles/qquicklineextruder_p.h
index 1f65f8d808..6f2b2493a6 100644
--- a/src/quick/particles/qquicklineextruder_p.h
+++ b/src/quick/particles/qquicklineextruder_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickmaskextruder.cpp b/src/quick/particles/qquickmaskextruder.cpp
index 5c27cc7678..50b71749c0 100644
--- a/src/quick/particles/qquickmaskextruder.cpp
+++ b/src/quick/particles/qquickmaskextruder.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickmaskextruder_p.h b/src/quick/particles/qquickmaskextruder_p.h
index 94b30720c1..8b6c3f0b2d 100644
--- a/src/quick/particles/qquickmaskextruder_p.h
+++ b/src/quick/particles/qquickmaskextruder_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticleaffector.cpp b/src/quick/particles/qquickparticleaffector.cpp
index 6a5a4f3304..0005af86af 100644
--- a/src/quick/particles/qquickparticleaffector.cpp
+++ b/src/quick/particles/qquickparticleaffector.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticleaffector_p.h b/src/quick/particles/qquickparticleaffector_p.h
index b5126fb0db..4147488f87 100644
--- a/src/quick/particles/qquickparticleaffector_p.h
+++ b/src/quick/particles/qquickparticleaffector_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticleemitter.cpp b/src/quick/particles/qquickparticleemitter.cpp
index 1625f1498a..0f7f3817f2 100644
--- a/src/quick/particles/qquickparticleemitter.cpp
+++ b/src/quick/particles/qquickparticleemitter.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticleemitter_p.h b/src/quick/particles/qquickparticleemitter_p.h
index bb010a13e9..70adcff34c 100644
--- a/src/quick/particles/qquickparticleemitter_p.h
+++ b/src/quick/particles/qquickparticleemitter_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticleextruder.cpp b/src/quick/particles/qquickparticleextruder.cpp
index f5605ef4d4..279f7c05f3 100644
--- a/src/quick/particles/qquickparticleextruder.cpp
+++ b/src/quick/particles/qquickparticleextruder.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qquickparticleextruder_p.h"
+#include <stdlib.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/particles/qquickparticleextruder_p.h b/src/quick/particles/qquickparticleextruder_p.h
index da59bca044..e24950e4e8 100644
--- a/src/quick/particles/qquickparticleextruder_p.h
+++ b/src/quick/particles/qquickparticleextruder_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlegroup.cpp b/src/quick/particles/qquickparticlegroup.cpp
index c4b230f5e9..9a165074a1 100644
--- a/src/quick/particles/qquickparticlegroup.cpp
+++ b/src/quick/particles/qquickparticlegroup.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlegroup_p.h b/src/quick/particles/qquickparticlegroup_p.h
index 774eb8df86..8889187558 100644
--- a/src/quick/particles/qquickparticlegroup_p.h
+++ b/src/quick/particles/qquickparticlegroup_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlepainter.cpp b/src/quick/particles/qquickparticlepainter.cpp
index b9f745edd8..f46f2f2235 100644
--- a/src/quick/particles/qquickparticlepainter.cpp
+++ b/src/quick/particles/qquickparticlepainter.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlepainter_p.h b/src/quick/particles/qquickparticlepainter_p.h
index ffa80d73dd..ebe76d98ea 100644
--- a/src/quick/particles/qquickparticlepainter_p.h
+++ b/src/quick/particles/qquickparticlepainter_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlesmodule.cpp b/src/quick/particles/qquickparticlesmodule.cpp
index f9b45f960e..e83cde3cd1 100644
--- a/src/quick/particles/qquickparticlesmodule.cpp
+++ b/src/quick/particles/qquickparticlesmodule.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlesmodule_p.h b/src/quick/particles/qquickparticlesmodule_p.h
index 6d16f00c15..b7cf09919e 100644
--- a/src/quick/particles/qquickparticlesmodule_p.h
+++ b/src/quick/particles/qquickparticlesmodule_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlesystem.cpp b/src/quick/particles/qquickparticlesystem.cpp
index 6dc6d21812..4fd6108f2f 100644
--- a/src/quick/particles/qquickparticlesystem.cpp
+++ b/src/quick/particles/qquickparticlesystem.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickparticlesystem_p.h b/src/quick/particles/qquickparticlesystem_p.h
index 387219f720..f70cc5af94 100644
--- a/src/quick/particles/qquickparticlesystem_p.h
+++ b/src/quick/particles/qquickparticlesystem_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickpointattractor.cpp b/src/quick/particles/qquickpointattractor.cpp
index 3772e2d050..7cb8c32671 100644
--- a/src/quick/particles/qquickpointattractor.cpp
+++ b/src/quick/particles/qquickpointattractor.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickpointattractor_p.h b/src/quick/particles/qquickpointattractor_p.h
index 30a666d196..85b7a9aa30 100644
--- a/src/quick/particles/qquickpointattractor_p.h
+++ b/src/quick/particles/qquickpointattractor_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickpointdirection.cpp b/src/quick/particles/qquickpointdirection.cpp
index 79c3365f86..e35eb4854c 100644
--- a/src/quick/particles/qquickpointdirection.cpp
+++ b/src/quick/particles/qquickpointdirection.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qquickpointdirection_p.h"
+#include <stdlib.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/particles/qquickpointdirection_p.h b/src/quick/particles/qquickpointdirection_p.h
index e66014653f..7b18e6d8d7 100644
--- a/src/quick/particles/qquickpointdirection_p.h
+++ b/src/quick/particles/qquickpointdirection_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickrectangleextruder.cpp b/src/quick/particles/qquickrectangleextruder.cpp
index 777d0f66f0..ad2207ca9a 100644
--- a/src/quick/particles/qquickrectangleextruder.cpp
+++ b/src/quick/particles/qquickrectangleextruder.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qquickrectangleextruder_p.h"
+#include <stdlib.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/particles/qquickrectangleextruder_p.h b/src/quick/particles/qquickrectangleextruder_p.h
index 055058c1be..1d4f8cc439 100644
--- a/src/quick/particles/qquickrectangleextruder_p.h
+++ b/src/quick/particles/qquickrectangleextruder_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickspritegoal.cpp b/src/quick/particles/qquickspritegoal.cpp
index 4f9518d97e..95d913cafa 100644
--- a/src/quick/particles/qquickspritegoal.cpp
+++ b/src/quick/particles/qquickspritegoal.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickspritegoal_p.h b/src/quick/particles/qquickspritegoal_p.h
index 44b022ffee..2b6b4f28fc 100644
--- a/src/quick/particles/qquickspritegoal_p.h
+++ b/src/quick/particles/qquickspritegoal_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquicktargetdirection.cpp b/src/quick/particles/qquicktargetdirection.cpp
index 3f24a252d9..695684dfde 100644
--- a/src/quick/particles/qquicktargetdirection.cpp
+++ b/src/quick/particles/qquicktargetdirection.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquicktargetdirection_p.h b/src/quick/particles/qquicktargetdirection_p.h
index cc5b65e66f..0e0e942ca8 100644
--- a/src/quick/particles/qquicktargetdirection_p.h
+++ b/src/quick/particles/qquicktargetdirection_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquicktrailemitter.cpp b/src/quick/particles/qquicktrailemitter.cpp
index e5317567fe..32f8763599 100644
--- a/src/quick/particles/qquicktrailemitter.cpp
+++ b/src/quick/particles/qquicktrailemitter.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquicktrailemitter_p.h b/src/quick/particles/qquicktrailemitter_p.h
index f68dd05441..0b63a444ec 100644
--- a/src/quick/particles/qquicktrailemitter_p.h
+++ b/src/quick/particles/qquicktrailemitter_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickturbulence.cpp b/src/quick/particles/qquickturbulence.cpp
index db77e8d328..18ecc6a4cd 100644
--- a/src/quick/particles/qquickturbulence.cpp
+++ b/src/quick/particles/qquickturbulence.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickturbulence_p.h b/src/quick/particles/qquickturbulence_p.h
index f453140cd2..cd5535c387 100644
--- a/src/quick/particles/qquickturbulence_p.h
+++ b/src/quick/particles/qquickturbulence_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickv8particledata.cpp b/src/quick/particles/qquickv8particledata.cpp
index 3a387d8f01..8e50e41091 100644
--- a/src/quick/particles/qquickv8particledata.cpp
+++ b/src/quick/particles/qquickv8particledata.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickv8particledata_p.h b/src/quick/particles/qquickv8particledata_p.h
index 9b4a4435cc..21ec6458c1 100644
--- a/src/quick/particles/qquickv8particledata_p.h
+++ b/src/quick/particles/qquickv8particledata_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickwander.cpp b/src/quick/particles/qquickwander.cpp
index ec86323e53..3e7cf33a64 100644
--- a/src/quick/particles/qquickwander.cpp
+++ b/src/quick/particles/qquickwander.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/particles/qquickwander_p.h b/src/quick/particles/qquickwander_p.h
index d71e55dd5f..bb418f7912 100644
--- a/src/quick/particles/qquickwander_p.h
+++ b/src/quick/particles/qquickwander_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the Declarative module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index b9eec27e82..5c14bd5bc7 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -777,9 +777,9 @@ QSGClipNode::~QSGClipNode()
Sets whether this clip node has a rectangular clip to \a rectHint.
This is an optimization hint which means that the renderer can
- use scissoring instead of stencil, which is significnatly faster.
+ use scissoring instead of stencil, which is significantly faster.
- When this hint is and it is applicable, the clip region will be
+ When this hint is set and it is applicable, the clip region will be
generated from clipRect() rather than geometry().
*/
@@ -791,7 +791,7 @@ void QSGClipNode::setIsRectangular(bool rectHint)
/*!
- \fn void QSGClipNode::clipRect() const
+ \fn QRectF QSGClipNode::clipRect() const
Returns the clip rect of this node.
*/
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 0697fbe630..ee9fd9fbbb 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode_p.h b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
index a2f2be828e..45636cc796 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrendernode_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index dcb1e5b8be..92045c55f4 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -45,6 +45,7 @@
#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
#include <private/qrawfont_p.h>
+#include <private/qdistancefield_p.h>
#include <QtGui/qguiapplication.h>
#include <qdir.h>
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index e38a4eef6a..10276c17f8 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -238,7 +238,7 @@ void QSGContext::renderNextFrame(QSGRenderer *renderer, GLuint fboId)
*/
QSGRectangleNode *QSGContext::createRectangleNode()
{
- return new QSGDefaultRectangleNode(this);
+ return new QSGDefaultRectangleNode;
}
/*!
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index d5f84553ba..b8a66fd0c0 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -71,7 +71,6 @@ struct QSGAdaptionPluginData
~QSGAdaptionPluginData()
{
- delete factory;
}
bool tried;
@@ -102,15 +101,15 @@ QSGAdaptionPluginData *contextFactory()
if (!device.isEmpty()) {
plugin->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(device));
plugin->deviceName = device;
- }
#ifndef QT_NO_DEBUG
- if (!device.isEmpty()) {
- qWarning("Could not create scene graph context for device '%s'"
- " - check that plugins are installed correctly in %s",
- qPrintable(device),
- qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath)));
- }
+ if (!plugin->factory) {
+ qWarning("Could not create scene graph context for device '%s'"
+ " - check that plugins are installed correctly in %s",
+ qPrintable(device),
+ qPrintable(QLibraryInfo::location(QLibraryInfo::PluginsPath)));
+ }
#endif
+ }
#endif // QT_NO_LIBRARY || QT_NO_SETTINGS
}
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index fa90873dc6..d0d8ea143b 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -62,7 +62,7 @@ struct Q_QUICK_EXPORT QSGContextFactoryInterface : public QFactoryInterface
};
#define QSGContextFactoryInterface_iid \
- "com.trolltech.Qt.QSGContextFactoryInterface"
+ "org.qt-project.Qt.QSGContextFactoryInterface"
Q_DECLARE_INTERFACE(QSGContextFactoryInterface, QSGContextFactoryInterface_iid)
class Q_QUICK_EXPORT QSGContextPlugin : public QObject, public QSGContextFactoryInterface
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index 73dcad6a47..05d076ec1e 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -41,6 +41,7 @@
#include "qsgdefaultdistancefieldglyphcache_p.h"
+#include <QtGui/private/qdistancefield_p.h>
#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <qopenglfunctions.h>
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
index 334bd4346f..18cac36550 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp
@@ -54,7 +54,7 @@
QT_BEGIN_NAMESPACE
-QSGDefaultRectangleNode::QSGDefaultRectangleNode(QSGContext *context)
+QSGDefaultRectangleNode::QSGDefaultRectangleNode()
: m_border(0)
, m_radius(0)
, m_pen_width(0)
@@ -62,7 +62,6 @@ QSGDefaultRectangleNode::QSGDefaultRectangleNode(QSGContext *context)
, m_gradient_is_opaque(true)
, m_dirty_geometry(false)
, m_default_geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
- , m_context(context)
{
setGeometry(&m_default_geometry);
setMaterial(&m_fill_material);
diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode_p.h b/src/quick/scenegraph/qsgdefaultrectanglenode_p.h
index 2a0aa05b90..faa2b6a43c 100644
--- a/src/quick/scenegraph/qsgdefaultrectanglenode_p.h
+++ b/src/quick/scenegraph/qsgdefaultrectanglenode_p.h
@@ -57,7 +57,7 @@ class QSGContext;
class QSGDefaultRectangleNode : public QSGRectangleNode
{
public:
- QSGDefaultRectangleNode(QSGContext *context);
+ QSGDefaultRectangleNode();
~QSGDefaultRectangleNode();
virtual void setRect(const QRectF &rect);
@@ -95,8 +95,6 @@ private:
uint m_material_type : 2; // Only goes up to 3
QSGGeometry m_default_geometry;
-
- QSGContext *m_context;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index 30b4a2f9b8..c66b82c16e 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -233,7 +233,11 @@ int QSGDistanceFieldTextMaterial::compare(const QSGMaterial *o) const
}
QRgb c1 = m_color.rgba();
QRgb c2 = other->m_color.rgba();
- return int(c2 < c1) - int(c1 < c2);
+ if (c1 != c2)
+ return int(c2 < c1) - int(c1 < c2);
+ int t0 = m_texture ? m_texture->textureId : -1;
+ int t1 = other->m_texture ? other->m_texture->textureId : -1;
+ return t0 - t1;
}
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
index 799d354400..46bd141909 100644
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
@@ -90,7 +90,7 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr
this, SLOT(reportItemsAvailable(QByteArray,void*,QSize,QVector<quint32>,QVector<QPoint>)),
Qt::DirectConnection);
connect(sharedGraphicsCache, SIGNAL(itemsUpdated(QByteArray,void*,QSize,QVector<quint32>,QVector<QPoint>)),
- this, SLOT(reportItemsAvailable(QByteArray,void*,QSize,QVector<quint32>,QVector<QPoint>)),
+ this, SLOT(reportItemsUpdated(QByteArray,void*,QSize,QVector<quint32>,QVector<QPoint>)),
Qt::DirectConnection);
connect(sharedGraphicsCache, SIGNAL(itemsInvalidated(QByteArray,QVector<quint32>)),
this, SLOT(reportItemsInvalidated(QByteArray,QVector<quint32>)),
@@ -542,9 +542,38 @@ void QSGSharedDistanceFieldGlyphCache::processPendingGlyphs()
}
void QSGSharedDistanceFieldGlyphCache::reportItemsAvailable(const QByteArray &cacheId,
- void *bufferId, const QSize &bufferSize,
- const QVector<quint32> &itemIds,
- const QVector<QPoint> &positions)
+ void *bufferId,
+ const QSize &bufferSize,
+ const QVector<quint32> &itemIds,
+ const QVector<QPoint> &positions)
+{
+ bool requestedItemsInList = false;
+ {
+ QMutexLocker locker(&m_pendingGlyphsMutex);
+ if (m_cacheId != cacheId)
+ return;
+
+#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
+ qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsAvailable() called for %s (%d glyphs, bufferSize: %dx%d)",
+ cacheId.constData(), itemIds.size(), bufferSize.width(), bufferSize.height());
+#endif
+
+ for (int i=0; i<itemIds.size(); ++i) {
+ if (m_requestedGlyphsThatHaveNotBeenReturned.contains(itemIds.at(i))) {
+ requestedItemsInList = true;
+ break;
+ }
+ }
+ }
+
+ if (requestedItemsInList)
+ reportItemsUpdated(cacheId, bufferId, bufferSize, itemIds, positions);
+}
+
+void QSGSharedDistanceFieldGlyphCache::reportItemsUpdated(const QByteArray &cacheId,
+ void *bufferId, const QSize &bufferSize,
+ const QVector<quint32> &itemIds,
+ const QVector<QPoint> &positions)
{
{
QMutexLocker locker(&m_pendingGlyphsMutex);
@@ -554,7 +583,7 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsAvailable(const QByteArray &ca
Q_ASSERT(itemIds.size() == positions.size());
#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG)
- qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsAvailable() called for %s (%d glyphs, bufferSize: %dx%d)",
+ qDebug("QSGSharedDistanceFieldGlyphCache::reportItemsUpdated() called for %s (%d glyphs, bufferSize: %dx%d)",
cacheId.constData(), itemIds.size(), bufferSize.width(), bufferSize.height());
#endif
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
index 851f72d6a7..3052f20813 100644
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
@@ -78,6 +78,8 @@ private Q_SLOTS:
void reportItemsAvailable(const QByteArray &cacheId,
void *bufferId, const QSize &bufferSize,
const QVector<quint32> &itemIds, const QVector<QPoint> &positions);
+ void reportItemsUpdated(const QByteArray &cacheId, void *bufferId, const QSize &bufferSize,
+ const QVector<quint32> &itemIds, const QVector<QPoint> &positions);
void reportItemsInvalidated(const QByteArray &cacheId, const QVector<quint32> &itemIds);
private:
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index dae4a3b8a8..f5fa18f87a 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -64,7 +64,6 @@ HEADERS += \
$$PWD/qsgdefaultimagenode_p.h \
$$PWD/qsgdefaultrectanglenode_p.h \
$$PWD/qsgflashnode_p.h \
- $$PWD/qsgpathsimplifier_p.h \
$$PWD/qsgshareddistancefieldglyphcache_p.h
SOURCES += \
@@ -79,7 +78,6 @@ SOURCES += \
$$PWD/qsgdefaultimagenode.cpp \
$$PWD/qsgdefaultrectanglenode.cpp \
$$PWD/qsgflashnode.cpp \
- $$PWD/qsgpathsimplifier.cpp \
$$PWD/qsgshareddistancefieldglyphcache.cpp
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
index caca610fe2..76fdf97d80 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
+++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
@@ -41,8 +41,6 @@
#include "qsgdistancefieldutil_p.h"
-#include <qmath.h>
-#include <private/qsgpathsimplifier_p.h>
#include <private/qsgadaptationlayer_p.h>
#include <QtGui/private/qopenglengineshadersource_p.h>
#include <QtQuick/private/qsgcontext_p.h>
@@ -64,718 +62,6 @@ static float defaultAntialiasingSpreadFunc(float glyphScale)
return range / glyphScale;
}
-namespace
-{
- enum FillHDir
- {
- LeftToRight,
- RightToLeft
- };
-
- enum FillVDir
- {
- TopDown,
- BottomUp
- };
-
- enum FillClip
- {
- NoClip,
- Clip
- };
-}
-
-template <FillClip clip, FillHDir dir>
-inline void fillLine(qint32 *, int, int, int, qint32, qint32)
-{
-}
-
-template <>
-inline void fillLine<Clip, LeftToRight>(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd)
-{
- int fromX = qMax(0, lx >> 8);
- int toX = qMin(width, rx >> 8);
- int x = toX - fromX;
- if (x <= 0)
- return;
- qint32 val = d + (((fromX << 8) + 0xff - lx) * dd >> 8);
- line += fromX;
- do {
- *line = abs(val) < abs(*line) ? val : *line;
- val += dd;
- ++line;
- } while (--x);
-}
-
-template <>
-inline void fillLine<Clip, RightToLeft>(qint32 *line, int width, int lx, int rx, qint32 d, qint32 dd)
-{
- int fromX = qMax(0, lx >> 8);
- int toX = qMin(width, rx >> 8);
- int x = toX - fromX;
- if (x <= 0)
- return;
- qint32 val = d + (((toX << 8) + 0xff - rx) * dd >> 8);
- line += toX;
- do {
- val -= dd;
- --line;
- *line = abs(val) < abs(*line) ? val : *line;
- } while (--x);
-}
-
-template <>
-inline void fillLine<NoClip, LeftToRight>(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd)
-{
- int fromX = lx >> 8;
- int toX = rx >> 8;
- int x = toX - fromX;
- if (x <= 0)
- return;
- qint32 val = d + ((~lx & 0xff) * dd >> 8);
- line += fromX;
- do {
- *line = abs(val) < abs(*line) ? val : *line;
- val += dd;
- ++line;
- } while (--x);
-}
-
-template <>
-inline void fillLine<NoClip, RightToLeft>(qint32 *line, int, int lx, int rx, qint32 d, qint32 dd)
-{
- int fromX = lx >> 8;
- int toX = rx >> 8;
- int x = toX - fromX;
- if (x <= 0)
- return;
- qint32 val = d + ((~rx & 0xff) * dd >> 8);
- line += toX;
- do {
- val -= dd;
- --line;
- *line = abs(val) < abs(*line) ? val : *line;
- } while (--x);
-}
-
-template <FillClip clip, FillVDir vDir, FillHDir hDir>
-inline void fillLines(qint32 *bits, int width, int height, int upperY, int lowerY,
- int &lx, int ldx, int &rx, int rdx, qint32 &d, qint32 ddy, qint32 ddx)
-{
- Q_UNUSED(height);
- Q_ASSERT(upperY < lowerY);
- int y = lowerY - upperY;
- if (vDir == TopDown) {
- qint32 *line = bits + upperY * width;
- do {
- fillLine<clip, hDir>(line, width, lx, rx, d, ddx);
- lx += ldx;
- d += ddy;
- rx += rdx;
- line += width;
- } while (--y);
- } else {
- qint32 *line = bits + lowerY * width;
- do {
- lx -= ldx;
- d -= ddy;
- rx -= rdx;
- line -= width;
- fillLine<clip, hDir>(line, width, lx, rx, d, ddx);
- } while (--y);
- }
-}
-
-template <FillClip clip>
-void drawTriangle(qint32 *bits, int width, int height, const QPoint *center,
- const QPoint *v1, const QPoint *v2, qint32 value)
-{
- const int y1 = clip == Clip ? qBound(0, v1->y() >> 8, height) : v1->y() >> 8;
- const int y2 = clip == Clip ? qBound(0, v2->y() >> 8, height) : v2->y() >> 8;
- const int yC = clip == Clip ? qBound(0, center->y() >> 8, height) : center->y() >> 8;
-
- const int v1Frac = clip == Clip ? (y1 << 8) + 0xff - v1->y() : ~v2->y() & 0xff;
- const int v2Frac = clip == Clip ? (y2 << 8) + 0xff - v2->y() : ~v1->y() & 0xff;
- const int centerFrac = clip == Clip ? (yC << 8) + 0xff - center->y() : ~center->y() & 0xff;
-
- int dx1 = 0, x1 = 0, dx2 = 0, x2 = 0;
- qint32 dd1, d1, dd2, d2;
- if (v1->y() != center->y()) {
- dx1 = ((v1->x() - center->x()) << 8) / (v1->y() - center->y());
- x1 = center->x() + centerFrac * (v1->x() - center->x()) / (v1->y() - center->y());
- }
- if (v2->y() != center->y()) {
- dx2 = ((v2->x() - center->x()) << 8) / (v2->y() - center->y());
- x2 = center->x() + centerFrac * (v2->x() - center->x()) / (v2->y() - center->y());
- }
-
- const qint32 div = (v2->x() - center->x()) * (v1->y() - center->y())
- - (v2->y() - center->y()) * (v1->x() - center->x());
- const qint32 dd = div ? qint32((qint64(value * (v1->y() - v2->y())) << 8) / div) : 0;
-
- if (y2 < yC) {
- if (y1 < yC) {
- // Center at the bottom.
- if (y2 < y1) {
- // y2 < y1 < yC
- // Long right edge.
- d1 = centerFrac * value / (v1->y() - center->y());
- dd1 = ((value << 8) / (v1->y() - center->y()));
- fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y1, yC, x1, dx1,
- x2, dx2, d1, dd1, dd);
- dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());
- x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());
- fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y2, y1, x1, dx1,
- x2, dx2, value, 0, dd);
- } else {
- // y1 <= y2 < yC
- // Long left edge.
- d2 = centerFrac * value / (v2->y() - center->y());
- dd2 = ((value << 8) / (v2->y() - center->y()));
- fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y2, yC, x1, dx1,
- x2, dx2, d2, dd2, dd);
- if (y1 != y2) {
- dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());
- x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());
- fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y1, y2, x1, dx1,
- x2, dx2, value, 0, dd);
- }
- }
- } else {
- // y2 < yC <= y1
- // Center to the right.
- int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());
- int xUp, xDn;
- xUp = xDn = v2->x() + (clip == Clip ? (yC << 8) + 0xff - v2->y()
- : (center->y() | 0xff) - v2->y())
- * (v1->x() - v2->x()) / (v1->y() - v2->y());
- fillLines<clip, BottomUp, LeftToRight>(bits, width, height, y2, yC, xUp, dx,
- x2, dx2, value, 0, dd);
- if (yC != y1)
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, yC, y1, xDn, dx,
- x1, dx1, value, 0, dd);
- }
- } else {
- if (y1 < yC) {
- // y1 < yC <= y2
- // Center to the left.
- int dx = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());
- int xUp, xDn;
- xUp = xDn = v1->x() + (clip == Clip ? (yC << 8) + 0xff - v1->y()
- : (center->y() | 0xff) - v1->y())
- * (v1->x() - v2->x()) / (v1->y() - v2->y());
- fillLines<clip, BottomUp, RightToLeft>(bits, width, height, y1, yC, x1, dx1,
- xUp, dx, value, 0, dd);
- if (yC != y2)
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, yC, y2, x2, dx2,
- xDn, dx, value, 0, dd);
- } else {
- // Center at the top.
- if (y2 < y1) {
- // yC <= y2 < y1
- // Long right edge.
- if (yC != y2) {
- d2 = centerFrac * value / (v2->y() - center->y());
- dd2 = ((value << 8) / (v2->y() - center->y()));
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, yC, y2, x2, dx2,
- x1, dx1, d2, dd2, dd);
- }
- dx2 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());
- x2 = v2->x() + v2Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, y2, y1, x2, dx2,
- x1, dx1, value, 0, dd);
- } else {
- // Long left edge.
- // yC <= y1 <= y2
- if (yC != y1) {
- d1 = centerFrac * value / (v1->y() - center->y());
- dd1 = ((value << 8) / (v1->y() - center->y()));
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, yC, y1, x2, dx2,
- x1, dx1, d1, dd1, dd);
- }
- if (y1 != y2) {
- dx1 = ((v1->x() - v2->x()) << 8) / (v1->y() - v2->y());
- x1 = v1->x() + v1Frac * (v1->x() - v2->x()) / (v1->y() - v2->y());
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, y1, y2, x2, dx2,
- x1, dx1, value, 0, dd);
- }
- }
- }
- }
-}
-
-template <FillClip clip>
-void drawRectangle(qint32 *bits, int width, int height,
- const QPoint *int1, const QPoint *center1, const QPoint *ext1,
- const QPoint *int2, const QPoint *center2, const QPoint *ext2,
- qint32 extValue)
-{
- if (center1->y() > center2->y()) {
- qSwap(center1, center2);
- qSwap(int1, ext2);
- qSwap(ext1, int2);
- extValue = -extValue;
- }
-
- Q_ASSERT(ext1->x() - center1->x() == center1->x() - int1->x());
- Q_ASSERT(ext1->y() - center1->y() == center1->y() - int1->y());
- Q_ASSERT(ext2->x() - center2->x() == center2->x() - int2->x());
- Q_ASSERT(ext2->y() - center2->y() == center2->y() - int2->y());
-
- const int yc1 = clip == Clip ? qBound(0, center1->y() >> 8, height) : center1->y() >> 8;
- const int yc2 = clip == Clip ? qBound(0, center2->y() >> 8, height) : center2->y() >> 8;
- const int yi1 = clip == Clip ? qBound(0, int1->y() >> 8, height) : int1->y() >> 8;
- const int yi2 = clip == Clip ? qBound(0, int2->y() >> 8, height) : int2->y() >> 8;
- const int ye1 = clip == Clip ? qBound(0, ext1->y() >> 8, height) : ext1->y() >> 8;
- const int ye2 = clip == Clip ? qBound(0, ext2->y() >> 8, height) : ext2->y() >> 8;
-
- const int center1Frac = clip == Clip ? (yc1 << 8) + 0xff - center1->y() : ~center1->y() & 0xff;
- const int center2Frac = clip == Clip ? (yc2 << 8) + 0xff - center2->y() : ~center2->y() & 0xff;
- const int int1Frac = clip == Clip ? (yi1 << 8) + 0xff - int1->y() : ~int1->y() & 0xff;
- const int ext1Frac = clip == Clip ? (ye1 << 8) + 0xff - ext1->y() : ~ext1->y() & 0xff;
-
- int dxC = 0, dxE = 0; // cap slope, edge slope
- qint32 ddC = 0;
- if (ext1->y() != int1->y()) {
- dxC = ((ext1->x() - int1->x()) << 8) / (ext1->y() - int1->y());
- ddC = (extValue << 9) / (ext1->y() - int1->y());
- }
- if (ext1->y() != ext2->y())
- dxE = ((ext1->x() - ext2->x()) << 8) / (ext1->y() - ext2->y());
-
- const qint32 div = (ext1->x() - int1->x()) * (ext2->y() - int1->y())
- - (ext1->y() - int1->y()) * (ext2->x() - int1->x());
- const qint32 dd = div ? qint32((qint64(extValue * (ext2->y() - ext1->y())) << 9) / div) : 0;
-
- int xe1, xe2, xc1, xc2;
- qint32 d;
-
- qint32 intValue = -extValue;
-
- if (center2->x() < center1->x()) {
- // Leaning to the right. '/'
- if (int1->y() < ext2->y()) {
- // Mostly vertical.
- Q_ASSERT(ext1->y() != ext2->y());
- xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- if (ye1 != yi1) {
- xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc2 += (ye1 - yc1) * dxC;
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, yi1, xe1, dxE,
- xc2, dxC, extValue, 0, dd);
- }
- if (yi1 != ye2)
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, yi1, ye2, xe1, dxE,
- xe2, dxE, extValue, 0, dd);
- if (ye2 != yi2) {
- xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc1 += (ye2 - yc2) * dxC;
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, ye2, yi2, xc1, dxC,
- xe2, dxE, intValue, 0, dd);
- }
- } else {
- // Mostly horizontal.
- Q_ASSERT(ext1->y() != int1->y());
- xc1 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc2 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc1 += (ye2 - yc2) * dxC;
- xc2 += (ye1 - yc1) * dxC;
- if (ye1 != ye2) {
- xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, ye2, xe1, dxE,
- xc2, dxC, extValue, 0, dd);
- }
- if (ye2 != yi1) {
- d = (clip == Clip ? (ye2 << 8) + 0xff - center2->y()
- : (ext2->y() | 0xff) - center2->y())
- * 2 * extValue / (ext1->y() - int1->y());
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye2, yi1, xc1, dxC,
- xc2, dxC, d, ddC, dd);
- }
- if (yi1 != yi2) {
- xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, yi2, xc1, dxC,
- xe2, dxE, intValue, 0, dd);
- }
- }
- } else {
- // Leaning to the left. '\'
- if (ext1->y() < int2->y()) {
- // Mostly vertical.
- Q_ASSERT(ext1->y() != ext2->y());
- xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- if (yi1 != ye1) {
- xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc1 += (yi1 - yc1) * dxC;
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, ye1, xc1, dxC,
- xe2, dxE, intValue, 0, dd);
- }
- if (ye1 != yi2)
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, ye1, yi2, xe1, dxE,
- xe2, dxE, intValue, 0, dd);
- if (yi2 != ye2) {
- xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc2 += (yi2 - yc2) * dxC;
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, yi2, ye2, xe1, dxE,
- xc2, dxC, extValue, 0, dd);
- }
- } else {
- // Mostly horizontal.
- Q_ASSERT(ext1->y() != int1->y());
- xc1 = center1->x() + center1Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc2 = center2->x() + center2Frac * (ext1->x() - int1->x()) / (ext1->y() - int1->y());
- xc1 += (yi1 - yc1) * dxC;
- xc2 += (yi2 - yc2) * dxC;
- if (yi1 != yi2) {
- xe2 = int1->x() + int1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi1, yi2, xc1, dxC,
- xe2, dxE, intValue, 0, dd);
- }
- if (yi2 != ye1) {
- d = (clip == Clip ? (yi2 << 8) + 0xff - center2->y()
- : (int2->y() | 0xff) - center2->y())
- * 2 * extValue / (ext1->y() - int1->y());
- fillLines<clip, TopDown, RightToLeft>(bits, width, height, yi2, ye1, xc1, dxC,
- xc2, dxC, d, ddC, dd);
- }
- if (ye1 != ye2) {
- xe1 = ext1->x() + ext1Frac * (ext1->x() - ext2->x()) / (ext1->y() - ext2->y());
- fillLines<clip, TopDown, LeftToRight>(bits, width, height, ye1, ye2, xe1, dxE,
- xc2, dxC, extValue, 0, dd);
- }
- }
- }
-}
-
-static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vertices,
- const quint32 *indices, int indexCount, qint32 value)
-{
- Q_ASSERT(indexCount != 0);
- Q_ASSERT(height <= 128);
- QVarLengthArray<quint8, 16> scans[128];
- int first = 0;
- for (int i = 1; i < indexCount; ++i) {
- quint32 idx1 = indices[i - 1];
- quint32 idx2 = indices[i];
- Q_ASSERT(idx1 != quint32(-1));
- if (idx2 == quint32(-1)) {
- idx2 = indices[first];
- Q_ASSERT(idx2 != quint32(-1));
- first = ++i;
- }
- const QPoint *v1 = &vertices[idx1];
- const QPoint *v2 = &vertices[idx2];
- if (v2->y() < v1->y())
- qSwap(v1, v2);
- int fromY = qMax(0, v1->y() >> 8);
- int toY = qMin(height, v2->y() >> 8);
- if (fromY >= toY)
- continue;
- int dx = ((v2->x() - v1->x()) << 8) / (v2->y() - v1->y());
- int x = v1->x() + ((fromY << 8) + 0xff - v1->y()) * (v2->x() - v1->x()) / (v2->y() - v1->y());
- for (int y = fromY; y < toY; ++y) {
- quint32 c = quint32(x >> 8);
- if (c < quint32(width))
- scans[y].append(quint8(c));
- x += dx;
- }
- }
- for (int i = 0; i < height; ++i) {
- quint8 *scanline = scans[i].data();
- int size = scans[i].size();
- for (int j = 1; j < size; ++j) {
- int k = j;
- quint8 value = scanline[k];
- for (; k != 0 && value < scanline[k - 1]; --k)
- scanline[k] = scanline[k - 1];
- scanline[k] = value;
- }
- qint32 *line = bits + i * width;
- int j = 0;
- for (; j + 1 < size; j += 2) {
- for (quint8 x = scanline[j]; x < scanline[j + 1]; ++x)
- line[x] = value;
- }
- if (j < size) {
- for (int x = scanline[j]; x < width; ++x)
- line[x] = value;
- }
- }
-}
-
-static QImage makeDistanceField(int imgSize, const QPainterPath &path, int dfScale, int offs)
-{
- QImage image(imgSize, imgSize, QImage::Format_Indexed8);
-
- if (path.isEmpty()) {
- image.fill(0);
- return image;
- }
-
- QTransform transform;
- transform.translate(offs, offs);
- transform.scale(qreal(1) / dfScale, qreal(1) / dfScale);
-
- QDataBuffer<quint32> pathIndices(0);
- QDataBuffer<QPoint> pathVertices(0);
- qSimplifyPath(path, pathVertices, pathIndices, transform);
-
- const qint32 interiorColor = -0x7f80; // 8:8 signed format, -127.5
- const qint32 exteriorColor = 0x7f80; // 8:8 signed format, 127.5
-
- QScopedArrayPointer<qint32> bits(new qint32[imgSize * imgSize]);
- for (int i = 0; i < imgSize * imgSize; ++i)
- bits[i] = exteriorColor;
-
- const qreal angleStep = qreal(15 * 3.141592653589793238 / 180);
- const QPoint rotation(qRound(cos(angleStep) * 0x4000),
- qRound(sin(angleStep) * 0x4000)); // 2:14 signed
-
- const quint32 *indices = pathIndices.data();
- QVarLengthArray<QPoint> normals;
- QVarLengthArray<QPoint> vertices;
- QVarLengthArray<bool> isConvex;
- QVarLengthArray<bool> needsClipping;
-
- drawPolygons(bits.data(), imgSize, imgSize, pathVertices.data(), indices, pathIndices.size(),
- interiorColor);
-
- int index = 0;
-
- while (index < pathIndices.size()) {
- normals.clear();
- vertices.clear();
- needsClipping.clear();
-
- // Find end of polygon.
- int end = index;
- while (indices[end] != quint32(-1))
- ++end;
-
- // Calculate vertex normals.
- for (int next = index, prev = end - 1; next < end; prev = next++) {
- quint32 fromVertexIndex = indices[prev];
- quint32 toVertexIndex = indices[next];
-
- const QPoint &from = pathVertices.at(fromVertexIndex);
- const QPoint &to = pathVertices.at(toVertexIndex);
-
- QPoint n(to.y() - from.y(), from.x() - to.x());
- if (n.x() == 0 && n.y() == 0)
- continue;
- int scale = qRound((offs << 16) / sqrt(qreal(n.x() * n.x() + n.y() * n.y()))); // 8:16
- n.rx() = n.x() * scale >> 8;
- n.ry() = n.y() * scale >> 8;
- normals.append(n);
- QPoint v(to.x() + 0x7f, to.y() + 0x7f);
- vertices.append(v);
- needsClipping.append((to.x() < offs << 8) || (to.x() >= (imgSize - offs) << 8)
- || (to.y() < offs << 8) || (to.y() >= (imgSize - offs) << 8));
- }
-
- isConvex.resize(normals.count());
- for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) {
- isConvex[prev] = normals.at(prev).x() * normals.at(next).y()
- - normals.at(prev).y() * normals.at(next).x() < 0;
- }
-
- // Draw quads.
- for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++) {
- QPoint n = normals.at(next);
- QPoint intPrev = vertices.at(prev);
- QPoint extPrev = vertices.at(prev);
- QPoint intNext = vertices.at(next);
- QPoint extNext = vertices.at(next);
-
- extPrev.rx() -= n.x();
- extPrev.ry() -= n.y();
- intPrev.rx() += n.x();
- intPrev.ry() += n.y();
- extNext.rx() -= n.x();
- extNext.ry() -= n.y();
- intNext.rx() += n.x();
- intNext.ry() += n.y();
-
- if (needsClipping[prev] || needsClipping[next]) {
- drawRectangle<Clip>(bits.data(), imgSize, imgSize,
- &intPrev, &vertices.at(prev), &extPrev,
- &intNext, &vertices.at(next), &extNext,
- exteriorColor);
- } else {
- drawRectangle<NoClip>(bits.data(), imgSize, imgSize,
- &intPrev, &vertices.at(prev), &extPrev,
- &intNext, &vertices.at(next), &extNext,
- exteriorColor);
- }
-
- if (isConvex.at(prev)) {
- QPoint p = extPrev;
- if (needsClipping[prev]) {
- for (;;) {
- QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14,
- (n.y() * rotation.x() + n.x() * rotation.y()) >> 14);
- n = rn;
- if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) {
- p.rx() = vertices.at(prev).x() - normals.at(prev).x();
- p.ry() = vertices.at(prev).y() - normals.at(prev).y();
- drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &extPrev, &p, exteriorColor);
- break;
- }
-
- p.rx() = vertices.at(prev).x() - n.x();
- p.ry() = vertices.at(prev).y() - n.y();
- drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &extPrev, &p, exteriorColor);
- extPrev = p;
- }
- } else {
- for (;;) {
- QPoint rn((n.x() * rotation.x() - n.y() * rotation.y()) >> 14,
- (n.y() * rotation.x() + n.x() * rotation.y()) >> 14);
- n = rn;
- if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() <= 0) {
- p.rx() = vertices.at(prev).x() - normals.at(prev).x();
- p.ry() = vertices.at(prev).y() - normals.at(prev).y();
- drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &extPrev, &p, exteriorColor);
- break;
- }
-
- p.rx() = vertices.at(prev).x() - n.x();
- p.ry() = vertices.at(prev).y() - n.y();
- drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &extPrev, &p, exteriorColor);
- extPrev = p;
- }
- }
- } else {
- QPoint p = intPrev;
- if (needsClipping[prev]) {
- for (;;) {
- QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14,
- (n.y() * rotation.x() - n.x() * rotation.y()) >> 14);
- n = rn;
- if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) {
- p.rx() = vertices.at(prev).x() + normals.at(prev).x();
- p.ry() = vertices.at(prev).y() + normals.at(prev).y();
- drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &p, &intPrev, interiorColor);
- break;
- }
-
- p.rx() = vertices.at(prev).x() + n.x();
- p.ry() = vertices.at(prev).y() + n.y();
- drawTriangle<Clip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &p, &intPrev, interiorColor);
- intPrev = p;
- }
- } else {
- for (;;) {
- QPoint rn((n.x() * rotation.x() + n.y() * rotation.y()) >> 14,
- (n.y() * rotation.x() - n.x() * rotation.y()) >> 14);
- n = rn;
- if (n.x() * normals.at(prev).y() - n.y() * normals.at(prev).x() >= 0) {
- p.rx() = vertices.at(prev).x() + normals.at(prev).x();
- p.ry() = vertices.at(prev).y() + normals.at(prev).y();
- drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &p, &intPrev, interiorColor);
- break;
- }
-
- p.rx() = vertices.at(prev).x() + n.x();
- p.ry() = vertices.at(prev).y() + n.y();
- drawTriangle<NoClip>(bits.data(), imgSize, imgSize, &vertices.at(prev),
- &p, &intPrev, interiorColor);
- intPrev = p;
- }
- }
- }
- }
-
- index = end + 1;
- }
-
- const qint32 *inLine = bits.data();
- uchar *outLine = image.bits();
- int padding = image.bytesPerLine() - image.width();
- for (int y = 0; y < imgSize; ++y) {
- for (int x = 0; x < imgSize; ++x, ++inLine, ++outLine)
- *outLine = uchar((0x7f80 - *inLine) >> 8);
- outLine += padding;
- }
-
- return image;
-}
-
-bool qt_fontHasNarrowOutlines(const QRawFont &f)
-{
- QRawFont font = f;
- font.setPixelSize(QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE);
- Q_ASSERT(font.isValid());
-
- QVector<quint32> glyphIndices = font.glyphIndexesForString(QLatin1String("O"));
- if (glyphIndices.size() < 1)
- return false;
-
- QImage im = font.alphaMapForGlyph(glyphIndices.at(0), QRawFont::PixelAntialiasing);
- if (im.isNull())
- return false;
-
- int minHThick = 999;
- int minVThick = 999;
-
- int thick = 0;
- bool in = false;
- int y = (im.height() + 1) / 2;
- for (int x = 0; x < im.width(); ++x) {
- int a = qAlpha(im.pixel(x, y));
- if (a > 127) {
- in = true;
- ++thick;
- } else if (in) {
- in = false;
- minHThick = qMin(minHThick, thick);
- thick = 0;
- }
- }
-
- thick = 0;
- in = false;
- int x = (im.width() + 1) / 2;
- for (int y = 0; y < im.height(); ++y) {
- int a = qAlpha(im.pixel(x, y));
- if (a > 127) {
- in = true;
- ++thick;
- } else if (in) {
- in = false;
- minVThick = qMin(minVThick, thick);
- thick = 0;
- }
- }
-
- return minHThick == 1 || minVThick == 1;
-}
-
-QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution)
-{
- QRawFont renderFont = font;
- renderFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(doubleResolution) * QT_DISTANCEFIELD_SCALE(doubleResolution));
-
- QPainterPath path = renderFont.pathForGlyph(glyph);
- path.translate(-path.boundingRect().topLeft());
- path.setFillRule(Qt::WindingFill);
-
- QImage im = makeDistanceField(QT_DISTANCEFIELD_TILESIZE(doubleResolution),
- path,
- QT_DISTANCEFIELD_SCALE(doubleResolution),
- QT_DISTANCEFIELD_RADIUS(doubleResolution) / QT_DISTANCEFIELD_SCALE(doubleResolution));
- return im;
-}
-
QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager(QSGContext *c)
: sgCtx(c)
, m_threshold_func(defaultThresholdFunc)
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
index cf805e7ff6..49391a737c 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
+++ b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
@@ -48,33 +48,9 @@
QT_BEGIN_NAMESPACE
-#define QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE 54
-#define QT_DISTANCEFIELD_DEFAULT_TILESIZE 64
-#define QT_DISTANCEFIELD_DEFAULT_SCALE 16
-#define QT_DISTANCEFIELD_DEFAULT_RADIUS 80
-#define QT_DISTANCEFIELD_HIGHGLYPHCOUNT 2000
-
-#define QT_DISTANCEFIELD_BASEFONTSIZE(NarrowOutlineFont) \
- (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE * 2 : \
- QT_DISTANCEFIELD_DEFAULT_BASEFONTSIZE)
-#define QT_DISTANCEFIELD_TILESIZE(NarrowOutlineFont) \
- (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_TILESIZE * 2 : \
- QT_DISTANCEFIELD_DEFAULT_TILESIZE)
-#define QT_DISTANCEFIELD_SCALE(NarrowOutlineFont) \
- (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_SCALE / 2 : \
- QT_DISTANCEFIELD_DEFAULT_SCALE)
-#define QT_DISTANCEFIELD_RADIUS(NarrowOutlineFont) \
- (NarrowOutlineFont ? QT_DISTANCEFIELD_DEFAULT_RADIUS / 2 : \
- QT_DISTANCEFIELD_DEFAULT_RADIUS)
-
-
typedef float (*ThresholdFunc)(float glyphScale);
typedef float (*AntialiasingSpreadFunc)(float glyphScale);
-bool qt_fontHasNarrowOutlines(const QRawFont &f);
-QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution);
-
-
class QOpenGLShaderProgram;
class QSGDistanceFieldGlyphCache;
class QSGContext;
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 5dd4dad6e4..24b92fa98f 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -497,6 +497,8 @@ void QSGPlainTexture::bind()
? m_image
: m_image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ updateBindOptions(m_dirty_bind_options);
+
#ifdef QT_OPENGL_ES
swizzleBGRAToRGBA(&tmp);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp.constBits());
@@ -513,7 +515,6 @@ void QSGPlainTexture::bind()
m_texture_size = QSize(w, h);
m_texture_rect = QRectF(0, 0, 1, 1);
- updateBindOptions(m_dirty_bind_options);
m_dirty_bind_options = false;
}
diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h
index 24b0b4e2f8..2b2b2a84ec 100644
--- a/src/quick/util/qquickanimationcontroller_p.h
+++ b/src/quick/util/qquickanimationcontroller_p.h
@@ -49,7 +49,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Declarative)
+QT_MODULE(Quick)
class QQuickAnimationControllerPrivate;
class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlParserStatus
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 85e155f081..aae5306aa7 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -762,6 +762,8 @@ void QQuickPixmapStore::unreferencePixmap(QQuickPixmapData *data)
data->nextUnreferenced = m_unreferencedPixmaps;
data->prevUnreferencedPtr = &m_unreferencedPixmaps;
+ if (!m_destroying) // the texture factories may have been cleaned up already.
+ m_unreferencedCost += data->cost();
m_unreferencedPixmaps = data;
if (m_unreferencedPixmaps->nextUnreferenced) {
@@ -772,8 +774,6 @@ void QQuickPixmapStore::unreferencePixmap(QQuickPixmapData *data)
if (!m_lastUnreferencedPixmap)
m_lastUnreferencedPixmap = data;
- m_unreferencedCost += data->cost();
-
shrinkCache(-1); // Shrink the cache incase it has become larger than cache_limit
if (m_timerId == -1 && m_unreferencedPixmaps && !m_destroying)
@@ -810,8 +810,10 @@ void QQuickPixmapStore::shrinkCache(int remove)
data->prevUnreferencedPtr = 0;
data->prevUnreferenced = 0;
- remove -= data->cost();
- m_unreferencedCost -= data->cost();
+ if (!m_destroying) {
+ remove -= data->cost();
+ m_unreferencedCost -= data->cost();
+ }
data->removeFromCache();
delete data;
}
diff --git a/src/quick/util/qquickstyledtext.cpp b/src/quick/util/qquickstyledtext.cpp
index 87d447169c..8462166dec 100644
--- a/src/quick/util/qquickstyledtext.cpp
+++ b/src/quick/util/qquickstyledtext.cpp
@@ -69,6 +69,8 @@
QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT int qt_defaultDpi();
+
class QQuickStyledTextPrivate
{
public:
@@ -85,9 +87,10 @@ public:
QList<QQuickStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QQmlContext *context,
- bool preloadImages)
+ bool preloadImages,
+ bool *fontSizeModified)
: text(t), layout(l), imgTags(&imgTags), baseFont(layout.font()), baseUrl(baseUrl), hasNewLine(false), nbImages(0), updateImagePositions(false)
- , preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), context(context)
+ , preFormat(false), prependSpace(false), hasSpace(true), preloadImages(preloadImages), fontSizeModified(fontSizeModified), context(context)
{
}
@@ -103,7 +106,7 @@ public:
void parseImageAttributes(const QChar *&ch, const QString &textIn, QString &textOut);
QPair<QStringRef,QStringRef> parseAttribute(const QChar *&ch, const QString &textIn);
QStringRef parseValue(const QChar *&ch, const QString &textIn);
-
+ void setFontSize(int size, QTextCharFormat &format);
inline void skipSpace(const QChar *&ch) {
while (ch->isSpace() && !ch->isNull())
@@ -126,6 +129,7 @@ public:
bool prependSpace;
bool hasSpace;
bool preloadImages;
+ bool *fontSizeModified;
QQmlContext *context;
static const QChar lessThan;
@@ -160,8 +164,9 @@ QQuickStyledText::QQuickStyledText(const QString &string, QTextLayout &layout,
QList<QQuickStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QQmlContext *context,
- bool preloadImages)
- : d(new QQuickStyledTextPrivate(string, layout, imgTags, baseUrl, context, preloadImages))
+ bool preloadImages,
+ bool *fontSizeModified)
+ : d(new QQuickStyledTextPrivate(string, layout, imgTags, baseUrl, context, preloadImages, fontSizeModified))
{
}
@@ -174,11 +179,12 @@ void QQuickStyledText::parse(const QString &string, QTextLayout &layout,
QList<QQuickStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QQmlContext *context,
- bool preloadImages)
+ bool preloadImages,
+ bool *fontSizeModified)
{
if (string.isEmpty())
return;
- QQuickStyledText styledText(string, layout, imgTags, baseUrl, context, preloadImages);
+ QQuickStyledText styledText(string, layout, imgTags, baseUrl, context, preloadImages, fontSizeModified);
styledText.d->parse();
}
@@ -298,6 +304,20 @@ void QQuickStyledTextPrivate::appendText(const QString &textIn, int start, int l
hasNewLine = false;
}
+//
+// Calculates and sets the correct font size in points
+// depending on the size multiplier and base font.
+//
+void QQuickStyledTextPrivate::setFontSize(int size, QTextCharFormat &format)
+{
+ static const qreal scaling[] = { 0.7, 0.8, 1.0, 1.2, 1.5, 2.0, 2.4 };
+ if (baseFont.pointSizeF() != -1)
+ format.setFontPointSize(baseFont.pointSize() * scaling[size - 1]);
+ else
+ format.setFontPointSize(baseFont.pixelSize() * qreal(72.) / qreal(qt_defaultDpi()) * scaling[size - 1]);
+ *fontSizeModified = true;
+}
+
bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn, QString &textOut, QTextCharFormat &format)
{
skipSpace(ch);
@@ -353,12 +373,11 @@ bool QQuickStyledTextPrivate::parseTag(const QChar *&ch, const QString &textIn,
} else if (char0 == QLatin1Char('h') && tagLength == 2) {
int level = tag.at(1).digitValue();
if (level >= 1 && level <= 6) {
- static const qreal scaling[] = { 2.0, 1.5, 1.2, 1.0, 0.8, 0.7 };
if (!hasNewLine)
textOut.append(QChar::LineSeparator);
hasSpace = true;
prependSpace = false;
- format.setFontPointSize(baseFont.pointSize() * scaling[level - 1]);
+ setFontSize(7 - level, format);
format.setFontWeight(QFont::Bold);
return true;
}
@@ -550,10 +569,8 @@ bool QQuickStyledTextPrivate::parseFontAttributes(const QChar *&ch, const QStrin
int size = attr.second.toString().toInt();
if (attr.second.at(0) == QLatin1Char('-') || attr.second.at(0) == QLatin1Char('+'))
size += 3;
- if (size >= 1 && size <= 7) {
- static const qreal scaling[] = { 0.7, 0.8, 1.0, 1.2, 1.5, 2.0, 2.4 };
- format.setFontPointSize(baseFont.pointSize() * scaling[size-1]);
- }
+ if (size >= 1 && size <= 7)
+ setFontSize(size, format);
}
} while (!ch->isNull() && !attr.first.isEmpty());
diff --git a/src/quick/util/qquickstyledtext_p.h b/src/quick/util/qquickstyledtext_p.h
index bfc7ffe7ed..4e0f9eaaaf 100644
--- a/src/quick/util/qquickstyledtext_p.h
+++ b/src/quick/util/qquickstyledtext_p.h
@@ -85,14 +85,16 @@ public:
QList<QQuickStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QQmlContext *context,
- bool preloadImages);
+ bool preloadImages,
+ bool *fontSizeModified);
private:
QQuickStyledText(const QString &string, QTextLayout &layout,
QList<QQuickStyledTextImgTag*> &imgTags,
const QUrl &baseUrl,
QQmlContext *context,
- bool preloadImages);
+ bool preloadImages,
+ bool *fontSizeModified);
~QQuickStyledText();
QQuickStyledTextPrivate *d;