summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-03-17 02:29:31 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-03-17 02:29:31 (GMT)
commit349df5c1ec50fde17a2dbf94af64ed76c55d7aaf (patch)
treea5fe4490baad4a02dff6b91208ea5a0b7a53d98d /src
parent53fd1e2fd9c75d7d55606d4ac5df75eda96b9cc9 (diff)
parentd8aaf0f1823e1bcbfb687ac964187332b5c90259 (diff)
downloadQt-349df5c1ec50fde17a2dbf94af64ed76c55d7aaf.zip
Qt-349df5c1ec50fde17a2dbf94af64ed76c55d7aaf.tar.gz
Qt-349df5c1ec50fde17a2dbf94af64ed76c55d7aaf.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml: (112 commits) Verbose unexpected errors. One url for an *unqualilfied* import is not special. Fix test failures Optimization: Don't unnecessarily run VMEStack element constructors Optimization: Reduce unnecessary QObject allocations Reset QDeclarativeDeclarativeData::outerContext when the context is removed Simplify QDeclarativeComponent::creationContext() logic Optimization: Use id notifier for QtScript bindings Optimization: Combine QDeclarativeDeclarativeData and QObject allocations Fixes for the module import Fix documentation add alan's tic-tac-toe AI Remove test in .pro file also Remove unneeded #include and add needed header to .pri Add easing changes to QmlChanges.txt Update more animation on property value source docs. Doc fixes. QmlChanges.txt cleanup. Remove WorkerListModel and integrate its functionality into ListModel. Split post alpha API changes into a separate section. ...
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qresource.cpp8
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qobject_p.h1
-rw-r--r--src/declarative/QmlChanges.txt97
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp16
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp16
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp3
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocuspanel.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocuspanel_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocusscope.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativefocusscope_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp8
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp183
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview_p.h9
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp58
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.h27
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h10
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp130
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp176
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h6
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp13
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativepainteditem.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp96
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview_p_p.h5
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners.cpp7
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp56
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp14
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp10
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp6
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp6
-rw-r--r--src/declarative/qml/qdeclarative.h22
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp161
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h33
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp233
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings_p.h2
-rw-r--r--src/declarative/qml/qdeclarativecompileddata.cpp14
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp29
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h3
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp82
-rw-r--r--src/declarative/qml/qdeclarativecomponent.h1
-rw-r--r--src/declarative/qml/qdeclarativecomponent_p.h10
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager.cpp57
-rw-r--r--src/declarative/qml/qdeclarativecompositetypemanager_p.h3
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp509
-rw-r--r--src/declarative/qml/qdeclarativecontext.h11
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h187
-rw-r--r--src/declarative/qml/qdeclarativecontextscriptclass.cpp83
-rw-r--r--src/declarative/qml/qdeclarativecontextscriptclass_p.h10
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h3
-rw-r--r--src/declarative/qml/qdeclarativedeclarativedata_p.h27
-rw-r--r--src/declarative/qml/qdeclarativedirparser.cpp5
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp335
-rw-r--r--src/declarative/qml/qdeclarativeengine.h4
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h14
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp45
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp241
-rw-r--r--src/declarative/qml/qdeclarativeexpression.h12
-rw-r--r--src/declarative/qml/qdeclarativeexpression_p.h34
-rw-r--r--src/declarative/qml/qdeclarativeinfo.cpp5
-rw-r--r--src/declarative/qml/qdeclarativeinstruction.cpp2
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp26
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h1
-rw-r--r--src/declarative/qml/qdeclarativenotifier.cpp110
-rw-r--r--src/declarative/qml/qdeclarativenotifier_p.h272
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp174
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass_p.h9
-rw-r--r--src/declarative/qml/qdeclarativeparser.cpp5
-rw-r--r--src/declarative/qml/qdeclarativeparser_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h6
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp84
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h9
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h17
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp2
-rw-r--r--src/declarative/qml/qdeclarativevaluetypescriptclass.cpp7
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp99
-rw-r--r--src/declarative/qml/qdeclarativevme_p.h18
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp25
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject_p.h3
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript.cpp647
-rw-r--r--src/declarative/qml/qdeclarativeworkerscript_p.h41
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp2
-rw-r--r--src/declarative/qml/qml.pri2
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp112
-rw-r--r--src/declarative/util/qdeclarativeanimation_p.h21
-rw-r--r--src/declarative/util/qdeclarativeanimation_p_p.h13
-rw-r--r--src/declarative/util/qdeclarativefontloader.cpp19
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp956
-rw-r--r--src/declarative/util/qdeclarativelistmodel_p.h21
-rw-r--r--src/declarative/util/qdeclarativelistmodel_p_p.h199
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent.cpp245
-rw-r--r--src/declarative/util/qdeclarativelistmodelworkeragent_p.h155
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp41
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp3
-rw-r--r--src/declarative/util/qdeclarativestate.cpp62
-rw-r--r--src/declarative/util/qdeclarativestate_p.h8
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp251
-rw-r--r--src/declarative/util/qdeclarativestateoperations_p.h9
-rw-r--r--src/declarative/util/qdeclarativetransitionmanager.cpp26
-rw-r--r--src/declarative/util/qdeclarativeutilmodule.cpp76
-rw-r--r--src/declarative/util/qdeclarativeview.cpp5
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp55
-rw-r--r--src/declarative/util/util.pri8
-rw-r--r--src/gui/painting/qregion.cpp36
-rw-r--r--src/imports/imports.pro2
-rw-r--r--src/imports/multimedia/multimedia.pro6
-rw-r--r--src/imports/particles/particles.cpp (renamed from src/imports/webkit/webkitqmlplugin_export.h)38
-rw-r--r--src/imports/particles/particles.pro20
-rw-r--r--src/imports/particles/qdeclarativeparticles.cpp (renamed from src/declarative/graphicsitems/qdeclarativeparticles.cpp)25
-rw-r--r--src/imports/particles/qdeclarativeparticles_p.h (renamed from src/declarative/graphicsitems/qdeclarativeparticles_p.h)14
-rw-r--r--src/imports/particles/qmldir1
-rw-r--r--src/imports/qimportbase.pri2
-rw-r--r--src/imports/webkit/plugin.cpp2
-rw-r--r--src/imports/webkit/qdeclarativewebview.cpp8
-rw-r--r--src/imports/webkit/qdeclarativewebview_p.h7
-rw-r--r--src/imports/webkit/qdeclarativewebview_p_p.h4
-rw-r--r--src/imports/webkit/webkit.pro10
-rw-r--r--src/imports/widgets/widgets.cpp6
-rw-r--r--src/imports/widgets/widgets.pro9
-rw-r--r--src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp24
-rw-r--r--src/script/bridge/qscriptdeclarativeclass.cpp5
-rw-r--r--src/script/bridge/qscriptdeclarativeclass_p.h1
-rw-r--r--src/script/bridge/qscriptdeclarativeobject.cpp17
-rw-r--r--src/script/bridge/qscriptdeclarativeobject_p.h2
133 files changed, 4575 insertions, 2690 deletions
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index 6d33c8b..8e76e9e 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1411,8 +1411,12 @@ QString QResourceFileEngine::fileName(FileName file) const
} else if(file == PathName || file == AbsolutePathName) {
const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName();
const int slash = path.lastIndexOf(QLatin1Char('/'));
- if (slash != -1)
- return path.left(slash);
+ if (slash == -1)
+ return QLatin1String(":");
+ else if (slash <= 1)
+ return QLatin1String(":/");
+ return path.left(slash);
+
} else if(file == CanonicalName || file == CanonicalPathName) {
const QString absoluteFilePath = d->resource.absoluteFilePath();
if(file == CanonicalPathName) {
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 389e6e7..68f34ca 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2033,6 +2033,8 @@ void QObjectPrivate::setParent_helper(QObject *o)
}
}
}
+ if (!wasDeleted && declarativeData)
+ declarativeData->parentChanged(q, o);
}
/*!
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index cc5bf97..20e3da1 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -90,6 +90,7 @@ class Q_CORE_EXPORT QDeclarativeData
public:
virtual ~QDeclarativeData();
virtual void destroyed(QObject *) = 0;
+ virtual void parentChanged(QObject *, QObject *) = 0;
};
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt
index 591fb3d..7c584b4d 100644
--- a/src/declarative/QmlChanges.txt
+++ b/src/declarative/QmlChanges.txt
@@ -1,4 +1,32 @@
=============================================================================
+The changes below are pre Qt 4.7.0 beta
+
+PathView: offset property now uses range 0-1.0 rather than 0-100
+ListView, GridView::positionViewAtIndex() gained a 'mode' parameter
+Removed Qt.playSound (replaced by SoundEffect element)
+Removed Qt.closestAngle (use RotationAnimation instead)
+Removed NumberFormatter
+Removed DateTimeFormatter (use Qt.formatDateTime() instead)
+Using WebView now requires "import org.webkit 1.0"
+Using Particles now requires "import Qt.labs.particles 1.0"
+AnchorAnimation must now be used to animate anchor changes (and not NumberAnimation)
+
+C++ API
+-------
+QDeclarativeContext::addDefaultObject() has been replaced with
+QDeclarativeContext::setContextObject()
+
+Behavior and Animation syntax
+-----------------------------
+Previously animations and behaviors could be "assigned" to properties like this:
+ Item { x: Behavior {}; y: NumberAnimation {} }
+To make it more obvious that these are not regular value assignments a new "on"
+syntax has been introduced:
+ Item { Behavior on x {}; NumberAnimation on y {} }
+Only the syntax has changed, the behavior is identical.
+
+
+=============================================================================
The changes below are pre Qt 4.7.0 alpha
Flickable: renamed viewportWidth -> contentWidth
@@ -6,33 +34,14 @@ Flickable: renamed viewportHeight -> contentHeight
Flickable: renamed viewportX -> contentX
Flickable: renamed viewportY -> contentY
Removed Flickable.reportedVelocitySmoothing
-Removed Qt.playSound (replaced by SoundEffect element)
-Removed NumberFormatter
-Removed DateTimeFormatter (use Qt.formatDateTime() instead)
Renamed MouseRegion -> MouseArea
Connection: syntax and rename:
Connection { sender: a; signal: foo(); script: xxx }
Connection { sender: a; signal: bar(); script: yyy }
becomes:
Connections { target: a; onFoo: xxx; onBar: yyy }
-Using WebView now requires "import org.webkit 1.0"
-
-QmlView
--------
-The API of QmlView has been narrowed and its role as a convenience class
-reinforced.
-- remove addItem()
-- remove clearItems() - use 'delete root()'
-- remove reset()
-- resizeContent -> enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView }
-- remove setQml(), qml()
-- rename setUrl(), ur() to setSource(), source()
-- root() -> rootObject(), returns QGraphicsObject rather than QmlGraphicsItem
-- remove quit() signal -> use quit() signal of engine()
-- initialSize() signal removed
-- Added status() to determine status of the internal QmlComponent
-sectionExpression has been replaced by section.property, section.criteria
+ListView::sectionExpression has been replaced by section.property, section.criteria
ListModel
---------
@@ -42,29 +51,45 @@ ListModel
- foo: true is now a bool (not string "true")
- foo: false is now a bool (not string "false" == true!)
-C++ API
--------
-QML_DEFINE_... definition macros, previously global macros, are replaced by
-QML_REGISTER_... registration macros, which must be called explicitly. C++ API users
-should also consider using the QmlExtensionPlugin (previously named QmlModulePlugin)
-as a cleaner mechanism for publishing libraries of QML types, or the upcoming
-application plugin features of the qmlviewer / qmlruntime / qml.
-
PropertyAnimation
------------------
matchProperties and matchTargets have been renamed back to properties and targets.
The semantics are explained in the PropertyAnimation::properties documentation
and the animation overview documentation.
-Behavior and Animation syntax
------------------------------
+Easing curves and their parameters are now specified via dot properties:
+* easing.type : enum
+* easing.amplitude : real
+* easing.overshoot : real
+* easing.period : real
+For example:
+PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 }
+
+C++ API
+-------
+QML_DEFINE_... definition macros, previously global macros, are replaced by
+qmlRegisterType registration functions, which must be called explicitly.
+C++ API users should also consider using the QmlExtensionPlugin (previously
+named QmlModulePlugin) as a cleaner mechanism for publishing libraries of QML
+types, or the upcoming application plugin features of the qmlviewer /
+qmlruntime / qml.
+
+QmlView
+-------
+The API of QmlView has been narrowed and its role as a convenience class
+reinforced.
+- remove addItem()
+- remove clearItems() - use 'delete root()'
+- remove reset()
+- resizeContent -> enum ResizeMode { SizeViewToRootObject, SizeRootObjectToView }
+- remove setQml(), qml()
+- rename setUrl(), ur() to setSource(), source()
+- root() -> rootObject(), returns QGraphicsObject rather than QmlGraphicsItem
+- remove quit() signal -> use quit() signal of engine()
+- initialSize() signal removed
+- Added status() to determine status of the internal QmlComponent
+- removed execute() - setSource() will also execute the QML.
-Previously animations and behaviors could be "assigned" to properties like this:
- Item { x: Behavior {}; y: NumberAnimation {} }
-To make it more obvious that these are not regular value assignments a new "on"
-syntax has been introduced:
- Item { Behavior on x {}; NumberAnimation on y {} }
-Only the syntax has changed, the behavior is identical.
=============================================================================
The changes below are pre-4.6.0 release.
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index 3ff92b1..d30651b 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -48,7 +48,6 @@ HEADERS += \
$$PWD/qdeclarativevisualitemmodel_p.h \
$$PWD/qdeclarativelistview_p.h \
$$PWD/qdeclarativegraphicsobjectcontainer_p.h \
- $$PWD/qdeclarativeparticles_p.h \
$$PWD/qdeclarativelayoutitem_p.h \
$$PWD/qdeclarativeitemchangelistener_p.h \
$$PWD/qdeclarativeeffects.cpp
@@ -82,5 +81,4 @@ SOURCES += \
$$PWD/qdeclarativevisualitemmodel.cpp \
$$PWD/qdeclarativelistview.cpp \
$$PWD/qdeclarativegraphicsobjectcontainer.cpp \
- $$PWD/qdeclarativeparticles.cpp \
- $$PWD/qdeclarativelayoutitem.cpp \
+ $$PWD/qdeclarativelayoutitem.cpp
diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
index 20b1de3..2c2e034 100644
--- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
@@ -247,9 +247,25 @@ void QDeclarativeAnimatedImage::setSource(const QUrl &url)
emit statusChanged(d->status);
}
+#define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16
+
void QDeclarativeAnimatedImage::movieRequestFinished()
{
Q_D(QDeclarativeAnimatedImage);
+
+ d->redirectCount++;
+ if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = d->reply->url().resolved(redirect.toUrl());
+ d->reply->deleteLater();
+ d->reply = 0;
+ setSource(url);
+ return;
+ }
+ }
+ d->redirectCount=0;
+
d->_movie = new QMovie(d->reply);
if (!d->_movie->isValid()){
qWarning() << "Error Reading Animated Image File " << d->url;
diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h
index 39bb3e5..273c1d6 100644
--- a/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage_p_p.h
@@ -66,7 +66,7 @@ class QDeclarativeAnimatedImagePrivate : public QDeclarativeImagePrivate
public:
QDeclarativeAnimatedImagePrivate()
- : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0)
+ : playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0)
{
}
@@ -75,6 +75,7 @@ public:
int preset_currentframe;
QMovie *_movie;
QNetworkReply *reply;
+ int redirectCount;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index de16668..a7534b8 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -191,7 +191,7 @@ void QDeclarativeBorderImage::load()
update();
} else {
d->status = Loading;
- if (d->url.path().endsWith(QLatin1String(".sci"))) {
+ if (d->url.path().endsWith(QLatin1String("sci"))) {
#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
QString lf = toLocalFileOrQrc(d->url);
if (!lf.isEmpty()) {
@@ -400,9 +400,23 @@ void QDeclarativeBorderImage::requestFinished()
update();
}
+#define BORDERIMAGE_MAX_REDIRECT 16
+
void QDeclarativeBorderImage::sciRequestFinished()
{
Q_D(QDeclarativeBorderImage);
+
+ d->redirectCount++;
+ if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) {
+ QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = d->sciReply->url().resolved(redirect.toUrl());
+ setSource(url);
+ return;
+ }
+ }
+ d->redirectCount=0;
+
if (d->sciReply->error() != QNetworkReply::NoError) {
d->status = Error;
d->sciReply->deleteLater();
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
index b9cf73a..82b9ebf 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
@@ -68,7 +68,8 @@ public:
: border(0), sciReply(0),
sciPendingPixmapCache(false),
horizontalTileMode(QDeclarativeBorderImage::Stretch),
- verticalTileMode(QDeclarativeBorderImage::Stretch)
+ verticalTileMode(QDeclarativeBorderImage::Stretch),
+ redirectCount(0)
{
}
@@ -90,6 +91,7 @@ public:
bool sciPendingPixmapCache;
QDeclarativeBorderImage::TileMode horizontalTileMode;
QDeclarativeBorderImage::TileMode verticalTileMode;
+ int redirectCount;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 67068a0..9ccb3b6 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -264,6 +264,7 @@ void QDeclarativeFlickablePrivate::fixupY()
void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
+ Q_Q(QDeclarativeFlickable);
if (data.move.value() > minExtent || maxExtent > minExtent) {
timeline.reset(data.move);
if (data.move.value() != minExtent) {
@@ -273,6 +274,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
} else {
data.move.setValue(minExtent);
+ q->viewportMoved();
}
}
//emit flickingChanged();
@@ -284,6 +286,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
} else {
data.move.setValue(maxExtent);
+ q->viewportMoved();
}
//emit flickingChanged();
} else {
diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
index 0323a59..20524b6 100644
--- a/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativefocuspanel.cpp
@@ -41,6 +41,8 @@
#include "qdeclarativefocuspanel_p.h"
+#include "qdeclarativeitem_p.h"
+
#include <QtGui/qgraphicsscene.h>
#include <QEvent>
@@ -65,7 +67,8 @@ QT_BEGIN_NAMESPACE
QDeclarativeFocusPanel::QDeclarativeFocusPanel(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
- setFlag(ItemIsPanel);
+ Q_D(QDeclarativeItem);
+ d->flags |= QGraphicsItem::ItemIsPanel;
}
QDeclarativeFocusPanel::~QDeclarativeFocusPanel()
diff --git a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h
index 1ad8b6e..d9ca0b0 100644
--- a/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h
+++ b/src/declarative/graphicsitems/qdeclarativefocuspanel_p.h
@@ -66,6 +66,7 @@ protected:
private:
Q_DISABLE_COPY(QDeclarativeFocusPanel)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem)
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
index 384a47b..484df13 100644
--- a/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
+++ b/src/declarative/graphicsitems/qdeclarativefocusscope.cpp
@@ -41,6 +41,8 @@
#include "qdeclarativefocusscope_p.h"
+#include "qdeclarativeitem_p.h"
+
QT_BEGIN_NAMESPACE
/*!
@@ -62,7 +64,8 @@ QT_BEGIN_NAMESPACE
QDeclarativeFocusScope::QDeclarativeFocusScope(QDeclarativeItem *parent) :
QDeclarativeItem(parent)
{
- setFlag(QGraphicsItem::ItemIsFocusScope);
+ Q_D(QDeclarativeItem);
+ d->flags |= QGraphicsItem::ItemIsFocusScope;
}
QDeclarativeFocusScope::~QDeclarativeFocusScope()
diff --git a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h
index cd480b4..c65a07c 100644
--- a/src/declarative/graphicsitems/qdeclarativefocusscope_p.h
+++ b/src/declarative/graphicsitems/qdeclarativefocusscope_p.h
@@ -54,6 +54,7 @@ QT_MODULE(Declarative)
class Q_DECLARATIVE_EXPORT QDeclarativeFocusScope : public QDeclarativeItem
{
Q_OBJECT
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem)
public:
QDeclarativeFocusScope(QDeclarativeItem *parent=0);
virtual ~QDeclarativeFocusScope();
diff --git a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp
index 1977817..eb5b6ce 100644
--- a/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegraphicsobjectcontainer.cpp
@@ -65,12 +65,12 @@ public:
if (graphicsObject && graphicsObject->isWidget()) {
if (!on) {
graphicsObject->removeEventFilter(q);
- QObject::disconnect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize()));
- QObject::disconnect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize()));
+ QObject::disconnect(q, SIGNAL(widthChanged(qreal)), q, SLOT(_q_updateSize()));
+ QObject::disconnect(q, SIGNAL(heightChanged(qreal)), q, SLOT(_q_updateSize()));
} else {
graphicsObject->installEventFilter(q);
- QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(_q_updateSize()));
- QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(_q_updateSize()));
+ QObject::connect(q, SIGNAL(widthChanged(qreal)), q, SLOT(_q_updateSize()));
+ QObject::connect(q, SIGNAL(heightChanged(qreal)), q, SLOT(_q_updateSize()));
}
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 60ffbe2..b1391f9 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -97,7 +97,7 @@ class QDeclarativeGridViewPrivate : public QDeclarativeFlickablePrivate
public:
QDeclarativeGridViewPrivate()
: currentItem(0), flow(QDeclarativeGridView::LeftToRight)
- , visiblePos(0), visibleIndex(0) , currentIndex(-1)
+ , visibleIndex(0) , currentIndex(-1)
, cellWidth(100), cellHeight(100), columns(1), requestedIndex(-1)
, highlightRangeStart(0), highlightRangeEnd(0), highlightRange(QDeclarativeGridView::NoHighlightRange)
, highlightComponent(0), highlight(0), trackedItem(0)
@@ -305,7 +305,6 @@ public:
QHash<QDeclarativeItem*,int> unrequestedItems;
FxGridItem *currentItem;
QDeclarativeGridView::Flow flow;
- int visiblePos;
int visibleIndex;
int currentIndex;
int cellWidth;
@@ -350,7 +349,6 @@ void QDeclarativeGridViewPrivate::clear()
for (int i = 0; i < visibleItems.count(); ++i)
releaseItem(visibleItems.at(i));
visibleItems.clear();
- visiblePos = 0;
visibleIndex = 0;
releaseItem(currentItem);
currentItem = 0;
@@ -536,7 +534,7 @@ void QDeclarativeGridViewPrivate::scheduleLayout()
Q_Q(QDeclarativeGridView);
if (!layoutScheduled) {
layoutScheduled = true;
- QMetaObject::invokeMethod(q, "layout", Qt::QueuedConnection);
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority);
}
}
@@ -748,21 +746,26 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
if (currentItem && currentItem->rowPos() - position() != highlightRangeStart) {
qreal pos = currentItem->rowPos() - highlightRangeStart;
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(-pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
} else if (snapMode != QDeclarativeGridView::NoSnap) {
- qreal pos = qMax(qMin(snapPosAt(position()) - highlightRangeStart, -maxExtent), -minExtent);
- qreal dist = qAbs(data.move + pos);
+ qreal pos = -snapPosAt(-(data.move.value() - highlightRangeStart)) + highlightRangeStart;
+ pos = qMin(qMax(pos, maxExtent), minExtent);
+ qreal dist = qAbs(data.move.value() - pos);
if (dist > 0) {
timeline.reset(data.move);
- if (fixupDuration)
- timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
- data.move.setValue(-pos);
+ if (fixupDuration) {
+ timeline.move(data.move, pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
+ } else {
+ data.move.setValue(pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
} else {
@@ -788,7 +791,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
if (FxGridItem *item = firstVisibleItem())
maxDistance = qAbs(item->rowPos() + data.move.value());
} else if (data.move.value() < minExtent) {
- maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0));
+ maxDistance = qAbs(minExtent - data.move.value());
}
if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange)
data.flickTarget = minExtent;
@@ -797,7 +800,7 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
qreal pos = snapPosAt(-data.move.value()) + rowSize();
maxDistance = qAbs(pos + data.move.value());
} else if (data.move.value() > maxExtent) {
- maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0);
+ maxDistance = qAbs(maxExtent - data.move.value());
}
if (snapMode != QDeclarativeGridView::SnapToRow && highlightRange != QDeclarativeGridView::StrictlyEnforceRange)
data.flickTarget = maxExtent;
@@ -816,7 +819,8 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
qreal maxAccel = v2 / (2.0f * maxDistance);
qreal overshootDist = 0.0;
if (maxAccel < accel) {
- qreal dist = v2 / (accel * 2.0);
+ // + rowSize()/4 to encourage moving at least one item in the flick direction
+ qreal dist = v2 / (accel * 2.0) + rowSize()/4;
if (v > 0)
dist = -dist;
data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart;
@@ -1421,6 +1425,17 @@ void QDeclarativeGridView::setSnapMode(SnapMode mode)
}
}
+bool QDeclarativeGridView::event(QEvent *event)
+{
+ Q_D(QDeclarativeGridView);
+ if (event->type() == QEvent::User) {
+ d->layout();
+ return true;
+ }
+
+ return QDeclarativeFlickable::event(event);
+}
+
void QDeclarativeGridView::viewportMoved()
{
Q_D(QDeclarativeGridView);
@@ -1651,47 +1666,84 @@ void QDeclarativeGridView::moveCurrentIndexRight()
}
/*!
- \qmlmethod GridView::positionViewAtIndex(int index)
+ \qmlmethod GridView::positionViewAtIndex(int index, PositionMode mode)
+
+ Positions the view such that the \a index is at the position specified by
+ \a mode:
+
+ \list
+ \o Beginning - position item at the top (or left for TopToBottom flow) of the view.
+ \o Center- position item in the center of the view.
+ \o End - position item at bottom (or right for horizontal orientation) of the view.
+ \o Visible - if any part of the item is visible then take no action, otherwise
+ bring the item into view.
+ \o Contain - ensure the entire item is visible. If the item is larger than
+ the view the item is positioned at the top (or left for TopToBottom flow) of the view.
+ \endlist
- Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view.
If positioning the view at the index would cause empty space to be displayed at
- the end of the view, the view will be positioned at the end.
+ the beginning or end of the view, the view will be positioned at the boundary.
It is not recommended to use contentX or contentY to position the view
at a particular index. This is unreliable since removing items from the start
- of the list does not cause all other items to be repositioned.
+ of the view does not cause all other items to be repositioned.
The correct way to bring an item into view is with positionViewAtIndex.
*/
-void QDeclarativeGridView::positionViewAtIndex(int index)
+void QDeclarativeGridView::positionViewAtIndex(int index, int mode)
{
Q_D(QDeclarativeGridView);
if (!d->isValid() || index < 0 || index >= d->model->count())
return;
+ if (mode < Beginning || mode > Contain)
+ return;
- qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent();
+ qreal pos = d->position();
FxGridItem *item = d->visibleItem(index);
- if (item) {
- // Already created - just move to top of view
- int pos = qMin(item->rowPos(), maxExtent);
- d->setPosition(pos);
- } else {
- int pos = d->rowPosAt(index);
+ if (!item) {
+ int itemPos = d->rowPosAt(index);
// save the currently visible items in case any of them end up visible again
QList<FxGridItem*> oldVisible = d->visibleItems;
d->visibleItems.clear();
d->visibleIndex = index - index % d->columns;
- d->setPosition(pos);
- // setPosition() will cause refill. Adjust if we have moved beyond range
- if (d->position() > maxExtent)
- d->setPosition(maxExtent);
+ d->setPosition(itemPos);
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
d->releaseItem(oldVisible.at(i));
+ item = d->visibleItem(index);
+ }
+ if (item) {
+ qreal itemPos = item->rowPos();
+ switch (mode) {
+ case Beginning:
+ pos = itemPos;
+ break;
+ case Center:
+ pos = itemPos - (d->size() - d->rowSize())/2;
+ break;
+ case End:
+ pos = itemPos - d->size() + d->rowSize();
+ break;
+ case Visible:
+ if (itemPos > pos + d->size())
+ pos = itemPos - d->size() + d->rowSize();
+ else if (item->endRowPos() < pos)
+ pos = itemPos;
+ break;
+ case Contain:
+ if (item->endRowPos() > pos + d->size())
+ pos = itemPos - d->size() + d->rowSize();
+ if (itemPos < pos)
+ pos = itemPos;
+ }
+ qreal maxExtent = d->flow == QDeclarativeGridView::LeftToRight ? -maxYExtent() : -maxXExtent();
+ pos = qMin(pos, maxExtent);
+ qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent();
+ pos = qMax(pos, minExtent);
+ d->setPosition(pos);
}
d->fixupPosition();
}
-
void QDeclarativeGridView::componentComplete()
{
Q_D(QDeclarativeGridView);
@@ -1763,7 +1815,7 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
{
Q_D(QDeclarativeGridView);
if (!d->visibleItems.count() || d->model->count() <= 1) {
- refill();
+ d->scheduleLayout();
d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1)));
emit countChanged();
return;
@@ -1792,8 +1844,9 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
d->currentIndex += count;
if (d->currentItem)
d->currentItem->index = d->currentIndex;
+ emit currentIndexChanged();
}
- d->layout();
+ d->scheduleLayout();
emit countChanged();
return;
}
@@ -1823,9 +1876,21 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
}
}
+ // Update the indexes of the following visible items.
+ for (int i = 0; i < d->visibleItems.count(); ++i) {
+ FxGridItem *listItem = d->visibleItems.at(i);
+ if (listItem->index != -1 && listItem->index >= modelIndex)
+ listItem->index += count;
+ }
+
+ bool addedVisible = false;
QList<FxGridItem*> added;
int i = 0;
while (i < insertCount && rowPos <= to + d->rowSize()*(d->columns - (colPos/d->colSize()))/qreal(d->columns)) {
+ if (!addedVisible) {
+ d->scheduleLayout();
+ addedVisible = true;
+ }
FxGridItem *item = d->createItem(modelIndex + i);
d->visibleItems.insert(index, item);
item->setPosition(colPos, rowPos);
@@ -1846,6 +1911,15 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
}
}
+ // update visibleIndex
+ d->visibleIndex = 0;
+ for (QList<FxGridItem*>::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
+ if ((*it)->index != -1) {
+ d->visibleIndex = (*it)->index;
+ break;
+ }
+ }
+
if (d->currentIndex >= modelIndex) {
// adjust current item index
d->currentIndex += count;
@@ -1853,18 +1927,13 @@ void QDeclarativeGridView::itemsInserted(int modelIndex, int count)
d->currentItem->index = d->currentIndex;
d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex));
}
- }
- // Update the indexes of the following visible items.
- for (; index < d->visibleItems.count(); ++index) {
- FxGridItem *listItem = d->visibleItems.at(index);
- if (listItem->index != -1)
- listItem->index += count;
+ emit currentIndexChanged();
}
// everything is in order now - emit add() signal
for (int j = 0; j < added.count(); ++j)
added.at(j)->attached->emitAdd();
- d->layout();
+
emit countChanged();
}
@@ -1880,8 +1949,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
FxGridItem *item = *it;
if (item->index == -1 || item->index < modelIndex) {
// already removed, or before removed items
- if (item->index < modelIndex)
+ if (item->index < modelIndex && !removedVisible) {
+ d->scheduleLayout();
removedVisible = true;
+ }
++it;
} else if (item->index >= modelIndex + count) {
// after removed items
@@ -1889,7 +1960,10 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
++it;
} else {
// removed item
- removedVisible = true;
+ if (!removedVisible) {
+ d->scheduleLayout();
+ removedVisible = true;
+ }
item->attached->emitRemove();
if (item->attached->delayRemove()) {
item->index = -1;
@@ -1907,6 +1981,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
+ emit currentIndexChanged();
} else if (currentRemoved) {
// current item has been removed.
d->releaseItem(d->currentItem);
@@ -1916,6 +1991,7 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
}
// update visibleIndex
+ d->visibleIndex = 0;
for (it = d->visibleItems.begin(); it != d->visibleItems.end(); ++it) {
if ((*it)->index != -1) {
d->visibleIndex = (*it)->index;
@@ -1923,27 +1999,16 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
}
}
- if (removedVisible) {
- if (d->visibleItems.isEmpty()) {
- d->visibleIndex = 0;
- d->setPosition(0);
- refill();
- } else {
- // Correct the positioning of the items
- d->scheduleLayout();
- }
+ if (removedVisible && d->visibleItems.isEmpty()) {
+ d->timeline.clear();
+ d->setPosition(0);
+ if (d->model->count() == 0)
+ update();
}
emit countChanged();
}
-void QDeclarativeGridView::layout()
-{
- Q_D(QDeclarativeGridView);
- if (d->layoutScheduled)
- d->layout();
-}
-
void QDeclarativeGridView::destroyRemoved()
{
Q_D(QDeclarativeGridView);
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index 787c04c..f14ec14 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -137,6 +137,9 @@ public:
SnapMode snapMode() const;
void setSnapMode(SnapMode mode);
+ enum PositionMode { Beginning, Center, End, Visible, Contain };
+ Q_ENUMS(PositionMode)
+
static QDeclarativeGridViewAttached *qmlAttachedProperties(QObject *);
public Q_SLOTS:
@@ -144,7 +147,7 @@ public Q_SLOTS:
void moveCurrentIndexDown();
void moveCurrentIndexLeft();
void moveCurrentIndexRight();
- void positionViewAtIndex(int index);
+ void positionViewAtIndex(int index, int mode);
Q_SIGNALS:
void countChanged();
@@ -164,6 +167,7 @@ Q_SIGNALS:
void snapModeChanged();
protected:
+ virtual bool event(QEvent *event);
virtual void viewportMoved();
virtual qreal minYExtent() const;
virtual qreal maxYExtent() const;
@@ -181,7 +185,6 @@ private Q_SLOTS:
void destroyRemoved();
void createdItem(int index, QDeclarativeItem *item);
void destroyingItem(QDeclarativeItem *item);
- void layout();
private:
void refill();
@@ -192,7 +195,7 @@ class QDeclarativeGridViewAttached : public QObject
Q_OBJECT
public:
QDeclarativeGridViewAttached(QObject *parent)
- : QObject(parent), m_isCurrent(false), m_delayRemove(false) {}
+ : QObject(parent), m_view(0), m_isCurrent(false), m_delayRemove(false) {}
~QDeclarativeGridViewAttached() {}
Q_PROPERTY(QDeclarativeGridView *view READ view CONSTANT)
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index c7d7a4c..4ba80ad 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -273,7 +273,7 @@ void QDeclarativeContents::calcHeight()
m_height = qMax(bottom - top, qreal(0.0));
if (m_height != oldheight || m_y != oldy)
- emit rectChanged();
+ emit rectChanged(rectF());
}
//TODO: optimization: only check sender(), if there is one
@@ -301,7 +301,7 @@ void QDeclarativeContents::calcWidth()
m_width = qMax(right - left, qreal(0.0));
if (m_width != oldwidth || m_x != oldx)
- emit rectChanged();
+ emit rectChanged(rectF());
}
void QDeclarativeContents::setItem(QDeclarativeItem *item)
@@ -313,11 +313,11 @@ void QDeclarativeContents::setItem(QDeclarativeItem *item)
QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i));
if(!child)//### Should this be ignoring non-QDeclarativeItem graphicsobjects?
continue;
- connect(child, SIGNAL(heightChanged()), this, SLOT(calcHeight()));
+ connect(child, SIGNAL(heightChanged(qreal)), this, SLOT(calcHeight()));
connect(child, SIGNAL(yChanged()), this, SLOT(calcHeight()));
- connect(child, SIGNAL(widthChanged()), this, SLOT(calcWidth()));
+ connect(child, SIGNAL(widthChanged(qreal)), this, SLOT(calcWidth()));
connect(child, SIGNAL(xChanged()), this, SLOT(calcWidth()));
- connect(this, SIGNAL(rectChanged()), m_item, SIGNAL(childrenRectChanged()));
+ connect(this, SIGNAL(rectChanged(QRectF)), m_item, SIGNAL(childrenRectChanged(QRectF)));
}
calcHeight();
@@ -1662,7 +1662,7 @@ void QDeclarativeItem::setClip(bool c)
if (clip() == c)
return;
setFlag(ItemClipsChildrenToShape, c);
- emit clipChanged();
+ emit clipChanged(c);
}
/*!
@@ -1802,11 +1802,11 @@ void QDeclarativeItem::geometryChanged(const QRectF &newGeometry,
if (newGeometry.x() != oldGeometry.x())
emit xChanged();
if (newGeometry.width() != oldGeometry.width())
- emit widthChanged();
+ emit widthChanged(newGeometry.width());
if (newGeometry.y() != oldGeometry.y())
emit yChanged();
if (newGeometry.height() != oldGeometry.height())
- emit heightChanged();
+ emit heightChanged(newGeometry.height());
for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
@@ -2068,7 +2068,6 @@ void QDeclarativeItem::setBaselineOffset(qreal offset)
return;
d->_baselineOffset = offset;
- emit baselineOffsetChanged();
for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
@@ -2078,6 +2077,7 @@ void QDeclarativeItem::setBaselineOffset(qreal offset)
anchor->updateVerticalAnchors();
}
}
+ emit baselineOffsetChanged(offset);
}
/*!
@@ -2224,7 +2224,7 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep)
}
/*!
- \qmlmethod object Item::mapFromItem(Item item, int x, int y)
+ \qmlmethod object Item::mapFromItem(Item item, real x, real y)
Maps the point (\a x, \a y), which is in \a item's coordinate system, to
this item's coordinate system, and returns an object with \c x and \c y
@@ -2233,7 +2233,7 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep)
If \a item is a \c null value, this maps the point from the coordinate
system of the root QML view.
*/
-QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int y) const
+QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const
{
QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
@@ -2244,13 +2244,13 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int
// If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene()
QPointF p = qobject_cast<QGraphicsItem*>(this)->mapFromItem(itemObj, x, y);
- sv.setProperty("x", p.x());
- sv.setProperty("y", p.y());
+ sv.setProperty(QLatin1String("x"), p.x());
+ sv.setProperty(QLatin1String("y"), p.y());
return sv;
}
/*!
- \qmlmethod object Item::mapToItem(Item item, int x, int y)
+ \qmlmethod object Item::mapToItem(Item item, real x, real y)
Maps the point (\a x, \a y), which is in this item's coordinate system, to
\a item's coordinate system, and returns an object with \c x and \c y
@@ -2259,7 +2259,7 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, int x, int
If \a item is a \c null value, this maps \a x and \a y to the coordinate
system of the root QML view.
*/
-QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, int x, int y) const
+QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const
{
QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject();
QDeclarativeItem *itemObj = qobject_cast<QDeclarativeItem*>(item.toQObject());
@@ -2270,23 +2270,15 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, int x, int y)
// If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene()
QPointF p = qobject_cast<QGraphicsItem*>(this)->mapToItem(itemObj, x, y);
- sv.setProperty("x", p.x());
- sv.setProperty("y", p.y());
+ sv.setProperty(QLatin1String("x"), p.x());
+ sv.setProperty(QLatin1String("y"), p.y());
return sv;
}
-/*!
- \internal
-
- This function emits the \e focusChanged signal.
-
- Subclasses overriding this function should call up
- to their base class.
-*/
-void QDeclarativeItem::focusChanged(bool flag)
+void QDeclarativeItemPrivate::focusChanged(bool flag)
{
- Q_UNUSED(flag);
- emit focusChanged();
+ Q_Q(QDeclarativeItem);
+ emit q->focusChanged(flag);
}
/*! \internal */
@@ -2579,14 +2571,16 @@ QPointF QDeclarativeItemPrivate::computeTransformOrigin() const
/*! \internal */
bool QDeclarativeItem::sceneEvent(QEvent *event)
{
+ Q_D(QDeclarativeItem);
if (event->type() == QEvent::KeyPress) {
QKeyEvent *k = static_cast<QKeyEvent *>(event);
-
if ((k->key() == Qt::Key_Tab || k->key() == Qt::Key_Backtab) &&
!(k->modifiers() & (Qt::ControlModifier | Qt::AltModifier))) {
keyPressEvent(static_cast<QKeyEvent *>(event));
if (!event->isAccepted())
return QGraphicsItem::sceneEvent(event);
+ else
+ return true;
} else {
return QGraphicsItem::sceneEvent(event);
}
@@ -2595,7 +2589,7 @@ bool QDeclarativeItem::sceneEvent(QEvent *event)
if (event->type() == QEvent::FocusIn ||
event->type() == QEvent::FocusOut) {
- focusChanged(hasFocus());
+ d->focusChanged(hasFocus());
}
return rv;
}
@@ -2608,7 +2602,7 @@ QVariant QDeclarativeItem::itemChange(GraphicsItemChange change,
Q_D(const QDeclarativeItem);
switch (change) {
case ItemParentHasChanged:
- emit parentChanged();
+ emit parentChanged(parentItem());
break;
case ItemChildAddedChange:
case ItemChildRemovedChange:
@@ -2721,7 +2715,7 @@ void QDeclarativeItem::setSmooth(bool smooth)
if (d->smooth == smooth)
return;
d->smooth = smooth;
- emit smoothChanged();
+ emit smoothChanged(smooth);
update();
}
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h
index 2053eba..9b85ba3 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem.h
@@ -42,8 +42,8 @@
#ifndef QDECLARATIVEITEM_H
#define QDECLARATIVEITEM_H
-#include <qdeclarative.h>
-#include <qdeclarativecomponent.h>
+#include <QtDeclarative/qdeclarative.h>
+#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/QObject>
#include <QtCore/QList>
@@ -161,8 +161,8 @@ public:
bool keepMouseGrab() const;
void setKeepMouseGrab(bool);
- Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, int x, int y) const;
- Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, int x, int y) const;
+ Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, qreal x, qreal y) const;
+ Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const;
QDeclarativeAnchorLine left() const;
QDeclarativeAnchorLine right() const;
@@ -173,18 +173,18 @@ public:
QDeclarativeAnchorLine baseline() const;
Q_SIGNALS:
- void widthChanged();
- void heightChanged();
+ void widthChanged(qreal);
+ void heightChanged(qreal);
void childrenChanged();
- void childrenRectChanged();
- void baselineOffsetChanged();
+ void childrenRectChanged(const QRectF &);
+ void baselineOffsetChanged(qreal);
void stateChanged(const QString &);
- void focusChanged();
- void wantsFocusChanged();
- void parentChanged();
+ void focusChanged(bool);
+ void wantsFocusChanged(bool);
+ void parentChanged(QDeclarativeItem *);
void transformOriginChanged(TransformOrigin);
- void smoothChanged();
- void clipChanged();
+ void smoothChanged(bool);
+ void clipChanged(bool);
protected:
bool isComponentComplete() const;
@@ -199,7 +199,6 @@ protected:
virtual void classBegin();
virtual void componentComplete();
- virtual void focusChanged(bool);
virtual void keyPressEvent(QKeyEvent *event);
virtual void keyReleaseEvent(QKeyEvent *event);
virtual void inputMethodEvent(QInputMethodEvent *);
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index e424970..55df063 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -91,7 +91,7 @@ public Q_SLOTS:
void calcWidth();
Q_SIGNALS:
- void rectChanged();
+ void rectChanged(QRectF);
private:
QDeclarativeItem *m_item;
@@ -101,7 +101,7 @@ private:
qreal m_height;
};
-class QDeclarativeItemPrivate : public QGraphicsItemPrivate
+class Q_DECLARATIVE_EXPORT QDeclarativeItemPrivate : public QGraphicsItemPrivate
{
Q_DECLARE_PUBLIC(QDeclarativeItem)
@@ -240,7 +240,7 @@ public:
// Reimplemented from QGraphicsItemPrivate
virtual void subFocusItemChange()
{
- emit q_func()->wantsFocusChanged();
+ emit q_func()->wantsFocusChanged(subFocusItem != 0);
}
// Reimplemented from QGraphicsItemPrivate
@@ -255,9 +255,11 @@ public:
}
}
+ virtual void focusChanged(bool);
+
static int consistentTime;
static QTime currentTime();
- static void Q_DECLARATIVE_EXPORT setConsistentTime(int t);
+ static void setConsistentTime(int t);
static void start(QTime &);
static int elapsed(QTime &);
static int restart(QTime &);
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 25660f8..2ac55a4 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -65,7 +65,6 @@
#include "qdeclarativelistview_p.h"
#include "qdeclarativeloader_p.h"
#include "qdeclarativemousearea_p.h"
-#include "qdeclarativeparticles_p.h"
#include "qdeclarativepath_p.h"
#include "qdeclarativepathview_p.h"
#include "qdeclarativerectangle_p.h"
@@ -82,76 +81,71 @@
void QDeclarativeItemModule::defineModule()
{
- QML_REGISTER_TYPE(Qt,4,6,AnimatedImage,QDeclarativeAnimatedImage);
- QML_REGISTER_TYPE(Qt,4,6,Blur,QGraphicsBlurEffect);
- QML_REGISTER_TYPE(Qt,4,6,BorderImage,QDeclarativeBorderImage);
- QML_REGISTER_TYPE(Qt,4,6,Colorize,QGraphicsColorizeEffect);
- QML_REGISTER_TYPE(Qt,4,6,Column,QDeclarativeColumn);
- QML_REGISTER_TYPE(Qt,4,6,Drag,QDeclarativeDrag);
- QML_REGISTER_TYPE(Qt,4,6,DropShadow,QGraphicsDropShadowEffect);
- QML_REGISTER_TYPE(Qt,4,6,Flickable,QDeclarativeFlickable);
- QML_REGISTER_TYPE(Qt,4,6,Flipable,QDeclarativeFlipable);
- QML_REGISTER_TYPE(Qt,4,6,Flow,QDeclarativeFlow);
- QML_REGISTER_TYPE(Qt,4,6,FocusPanel,QDeclarativeFocusPanel);
- QML_REGISTER_TYPE(Qt,4,6,FocusScope,QDeclarativeFocusScope);
- QML_REGISTER_TYPE(Qt,4,6,Gradient,QDeclarativeGradient);
- QML_REGISTER_TYPE(Qt,4,6,GradientStop,QDeclarativeGradientStop);
- QML_REGISTER_TYPE(Qt,4,6,GraphicsObjectContainer,QDeclarativeGraphicsObjectContainer);
- QML_REGISTER_TYPE(Qt,4,6,Grid,QDeclarativeGrid);
- QML_REGISTER_TYPE(Qt,4,6,GridView,QDeclarativeGridView);
- QML_REGISTER_TYPE(Qt,4,6,Image,QDeclarativeImage);
- QML_REGISTER_TYPE(Qt,4,6,Item,QDeclarativeItem);
- QML_REGISTER_TYPE(Qt,4,6,KeyNavigation,QDeclarativeKeyNavigationAttached);
- QML_REGISTER_TYPE(Qt,4,6,Keys,QDeclarativeKeysAttached);
- QML_REGISTER_TYPE(Qt,4,6,LayoutItem,QDeclarativeLayoutItem);
- QML_REGISTER_TYPE(Qt,4,6,ListView,QDeclarativeListView);
- QML_REGISTER_TYPE(Qt,4,6,Loader,QDeclarativeLoader);
- QML_REGISTER_TYPE(Qt,4,6,MouseArea,QDeclarativeMouseArea);
- QML_REGISTER_TYPE(Qt,4,6,Opacity,QGraphicsOpacityEffect);
- QML_REGISTER_TYPE(Qt,4,6,ParticleMotion,QDeclarativeParticleMotion);
- QML_REGISTER_TYPE(Qt,4,6,ParticleMotionGravity,QDeclarativeParticleMotionGravity);
- QML_REGISTER_TYPE(Qt,4,6,ParticleMotionLinear,QDeclarativeParticleMotionLinear);
- QML_REGISTER_TYPE(Qt,4,6,ParticleMotionWander,QDeclarativeParticleMotionWander);
- QML_REGISTER_TYPE(Qt,4,6,Particles,QDeclarativeParticles);
- QML_REGISTER_TYPE(Qt,4,6,Path,QDeclarativePath);
- QML_REGISTER_TYPE(Qt,4,6,PathAttribute,QDeclarativePathAttribute);
- QML_REGISTER_TYPE(Qt,4,6,PathCubic,QDeclarativePathCubic);
- QML_REGISTER_TYPE(Qt,4,6,PathLine,QDeclarativePathLine);
- QML_REGISTER_TYPE(Qt,4,6,PathPercent,QDeclarativePathPercent);
- QML_REGISTER_TYPE(Qt,4,6,PathQuad,QDeclarativePathQuad);
- QML_REGISTER_TYPE(Qt,4,6,PathView,QDeclarativePathView);
- QML_REGISTER_TYPE(Qt,4,6,Pen,QDeclarativePen);
- QML_REGISTER_TYPE(Qt,4,6,QIntValidator,QIntValidator);
+ qmlRegisterType<QDeclarativeAnimatedImage>("Qt",4,6,"AnimatedImage");
+ qmlRegisterType<QGraphicsBlurEffect>("Qt",4,6,"Blur");
+ qmlRegisterType<QDeclarativeBorderImage>("Qt",4,6,"BorderImage");
+ qmlRegisterType<QGraphicsColorizeEffect>("Qt",4,6,"Colorize");
+ qmlRegisterType<QDeclarativeColumn>("Qt",4,6,"Column");
+ qmlRegisterType<QDeclarativeDrag>("Qt",4,6,"Drag");
+ qmlRegisterType<QGraphicsDropShadowEffect>("Qt",4,6,"DropShadow");
+ qmlRegisterType<QDeclarativeFlickable>("Qt",4,6,"Flickable");
+ qmlRegisterType<QDeclarativeFlipable>("Qt",4,6,"Flipable");
+ qmlRegisterType<QDeclarativeFlow>("Qt",4,6,"Flow");
+ qmlRegisterType<QDeclarativeFocusPanel>("Qt",4,6,"FocusPanel");
+ qmlRegisterType<QDeclarativeFocusScope>("Qt",4,6,"FocusScope");
+ qmlRegisterType<QDeclarativeGradient>("Qt",4,6,"Gradient");
+ qmlRegisterType<QDeclarativeGradientStop>("Qt",4,6,"GradientStop");
+ qmlRegisterType<QDeclarativeGraphicsObjectContainer>("Qt",4,6,"GraphicsObjectContainer");
+ qmlRegisterType<QDeclarativeGrid>("Qt",4,6,"Grid");
+ qmlRegisterType<QDeclarativeGridView>("Qt",4,6,"GridView");
+ qmlRegisterType<QDeclarativeImage>("Qt",4,6,"Image");
+ qmlRegisterType<QDeclarativeItem>("Qt",4,6,"Item");
+ qmlRegisterType<QDeclarativeKeyNavigationAttached>("Qt",4,6,"KeyNavigation");
+ qmlRegisterType<QDeclarativeKeysAttached>("Qt",4,6,"Keys");
+ qmlRegisterType<QDeclarativeLayoutItem>("Qt",4,6,"LayoutItem");
+ qmlRegisterType<QDeclarativeListView>("Qt",4,6,"ListView");
+ qmlRegisterType<QDeclarativeLoader>("Qt",4,6,"Loader");
+ qmlRegisterType<QDeclarativeMouseArea>("Qt",4,6,"MouseArea");
+ qmlRegisterType<QGraphicsOpacityEffect>("Qt",4,6,"Opacity");
+ qmlRegisterType<QDeclarativePath>("Qt",4,6,"Path");
+ qmlRegisterType<QDeclarativePathAttribute>("Qt",4,6,"PathAttribute");
+ qmlRegisterType<QDeclarativePathCubic>("Qt",4,6,"PathCubic");
+ qmlRegisterType<QDeclarativePathLine>("Qt",4,6,"PathLine");
+ qmlRegisterType<QDeclarativePathPercent>("Qt",4,6,"PathPercent");
+ qmlRegisterType<QDeclarativePathQuad>("Qt",4,6,"PathQuad");
+ qmlRegisterType<QDeclarativePathView>("Qt",4,6,"PathView");
+ qmlRegisterType<QDeclarativePen>("Qt",4,6,"Pen");
+ qmlRegisterType<QIntValidator>("Qt",4,6,"QIntValidator");
#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
- QML_REGISTER_TYPE(Qt,4,7,QDoubleValidator,QDoubleValidator);
- QML_REGISTER_TYPE(Qt,4,7,QRegExpValidator,QRegExpValidator);
+ qmlRegisterType<QDoubleValidator>("Qt",4,7,"QDoubleValidator");
+ qmlRegisterType<QRegExpValidator>("Qt",4,7,"QRegExpValidator");
#endif
- QML_REGISTER_TYPE(Qt,4,6,Rectangle,QDeclarativeRectangle);
- QML_REGISTER_TYPE(Qt,4,6,Repeater,QDeclarativeRepeater);
- QML_REGISTER_TYPE(Qt,4,6,Rotation,QGraphicsRotation);
- QML_REGISTER_TYPE(Qt,4,6,Row,QDeclarativeRow);
- QML_REGISTER_TYPE(Qt,4,6,Scale,QGraphicsScale);
- QML_REGISTER_TYPE(Qt,4,6,Text,QDeclarativeText);
- QML_REGISTER_TYPE(Qt,4,6,TextEdit,QDeclarativeTextEdit);
- QML_REGISTER_TYPE(Qt,4,6,TextInput,QDeclarativeTextInput);
- QML_REGISTER_TYPE(Qt,4,6,ViewSection,QDeclarativeViewSection);
- QML_REGISTER_TYPE(Qt,4,6,VisibleArea,QDeclarativeFlickableVisibleArea);
- QML_REGISTER_TYPE(Qt,4,6,VisualDataModel,QDeclarativeVisualDataModel);
- QML_REGISTER_TYPE(Qt,4,6,VisualItemModel,QDeclarativeVisualItemModel);
+ qmlRegisterType<QDeclarativeRectangle>("Qt",4,6,"Rectangle");
+ qmlRegisterType<QDeclarativeRepeater>("Qt",4,6,"Repeater");
+ qmlRegisterType<QGraphicsRotation>("Qt",4,6,"Rotation");
+ qmlRegisterType<QDeclarativeRow>("Qt",4,6,"Row");
+ qmlRegisterType<QGraphicsScale>("Qt",4,6,"Scale");
+ qmlRegisterType<QDeclarativeText>("Qt",4,6,"Text");
+ qmlRegisterType<QDeclarativeTextEdit>("Qt",4,6,"TextEdit");
+ qmlRegisterType<QDeclarativeTextInput>("Qt",4,6,"TextInput");
+ qmlRegisterType<QDeclarativeViewSection>("Qt",4,6,"ViewSection");
+ qmlRegisterType<QDeclarativeFlickableVisibleArea>("Qt",4,6,"VisibleArea");
+ qmlRegisterType<QDeclarativeVisualDataModel>("Qt",4,6,"VisualDataModel");
+ qmlRegisterType<QDeclarativeVisualItemModel>("Qt",4,6,"VisualItemModel");
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeAnchors);
- QML_REGISTER_NOCREATE_TYPE(QGraphicsEffect);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeKeyEvent);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeMouseEvent);
- QML_REGISTER_NOCREATE_TYPE(QGraphicsObject);
- QML_REGISTER_NOCREATE_TYPE(QGraphicsTransform);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativePathElement);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeCurve);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeScaleGrid);
- QML_REGISTER_NOCREATE_TYPE(QValidator);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeVisualModel);
- QML_REGISTER_NOCREATE_TYPE(QAction);
+ qmlRegisterType<QDeclarativeAnchors>();
+ qmlRegisterType<QGraphicsEffect>();
+ qmlRegisterType<QDeclarativeKeyEvent>();
+ qmlRegisterType<QDeclarativeMouseEvent>();
+ qmlRegisterType<QGraphicsObject>();
+ qmlRegisterType<QGraphicsTransform>();
+ qmlRegisterType<QDeclarativePathElement>();
+ qmlRegisterType<QDeclarativeCurve>();
+ qmlRegisterType<QDeclarativeScaleGrid>();
+ qmlRegisterType<QValidator>();
+ qmlRegisterType<QDeclarativeVisualModel>();
+ qmlRegisterType<QAction>();
#ifdef QT_WEBKIT_LIB
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeWebSettings);
+ qmlRegisterType<QDeclarativeWebSettings>();
#endif
}
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index d54bb70..e5013a9 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -158,7 +158,7 @@ public:
, bufferMode(NoBuffer)
, ownModel(false), wrap(false), autoHighlight(true), haveHighlightRange(false)
, correctFlick(true), inFlickCorrection(false), lazyRelease(false)
- , deferredRelease(false), minExtentDirty(true), maxExtentDirty(true)
+ , deferredRelease(false), layoutScheduled(false), minExtentDirty(true), maxExtentDirty(true)
{}
void init();
@@ -414,6 +414,7 @@ public:
}
void refill(qreal from, qreal to, bool doBuffer = false);
+ void scheduleLayout();
void layout();
void updateUnrequestedIndexes();
void updateUnrequestedPositions();
@@ -480,6 +481,7 @@ public:
bool inFlickCorrection : 1;
bool lazyRelease : 1;
bool deferredRelease : 1;
+ bool layoutScheduled : 1;
mutable bool minExtentDirty : 1;
mutable bool maxExtentDirty : 1;
};
@@ -557,7 +559,7 @@ void QDeclarativeListViewPrivate::releaseItem(FxListItem *item)
return;
if (trackedItem == item) {
const char *notifier1 = orient == QDeclarativeListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged());
- const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged());
+ const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged(qreal)) : SIGNAL(widthChanged(qreal));
QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged()));
QObject::disconnect(trackedItem->item, notifier2, q, SLOT(trackedPositionChanged()));
trackedItem = 0;
@@ -680,9 +682,19 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer)
lazyRelease = false;
}
+void QDeclarativeListViewPrivate::scheduleLayout()
+{
+ Q_Q(QDeclarativeListView);
+ if (!layoutScheduled) {
+ layoutScheduled = true;
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority);
+ }
+}
+
void QDeclarativeListViewPrivate::layout()
{
Q_Q(QDeclarativeListView);
+ layoutScheduled = false;
updateSections();
if (!visibleItems.isEmpty()) {
int oldEnd = visibleItems.last()->endPosition();
@@ -748,7 +760,7 @@ void QDeclarativeListViewPrivate::updateTrackedItem()
FxListItem *oldTracked = trackedItem;
const char *notifier1 = orient == QDeclarativeListView::Vertical ? SIGNAL(yChanged()) : SIGNAL(xChanged());
- const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged()) : SIGNAL(widthChanged());
+ const char *notifier2 = orient == QDeclarativeListView::Vertical ? SIGNAL(heightChanged(qreal)) : SIGNAL(widthChanged(qreal));
if (trackedItem && item != trackedItem) {
QObject::disconnect(trackedItem->item, notifier1, q, SLOT(trackedPositionChanged()));
@@ -1082,10 +1094,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
if (currentItem && currentItem->position() - position() != highlightRangeStart) {
qreal pos = currentItem->position() - highlightRangeStart;
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(-pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
} else if (snapMode != QDeclarativeListView::NoSnap) {
@@ -1094,10 +1108,12 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
timeline.reset(data.move);
- if (fixupDuration)
+ if (fixupDuration) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
+ } else {
data.move.setValue(-pos);
+ q->viewportMoved();
+ }
vTime = timeline.time();
}
}
@@ -1124,7 +1140,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
if (FxListItem *item = firstVisibleItem())
maxDistance = qAbs(item->position() + data.move.value());
} else if (data.move.value() < minExtent) {
- maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0));
+ maxDistance = qAbs(minExtent - data.move.value());
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
data.flickTarget = minExtent;
@@ -1133,7 +1149,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
if (FxListItem *item = nextVisibleItem())
maxDistance = qAbs(item->position() + data.move.value());
} else if (data.move.value() > maxExtent) {
- maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0);
+ maxDistance = qAbs(maxExtent - data.move.value());
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
data.flickTarget = maxExtent;
@@ -1156,7 +1172,8 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
qreal v2 = v * v;
qreal maxAccel = v2 / (2.0f * maxDistance);
if (maxAccel < accel) {
- qreal dist = v2 / (accel * 2.0);
+ // + averageSize/4 to encourage moving at least one item in the flick direction
+ qreal dist = v2 / (accel * 2.0) + averageSize/4;
if (v > 0)
dist = -dist;
data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart;
@@ -1944,6 +1961,17 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header)
}
}
+bool QDeclarativeListView::event(QEvent *event)
+{
+ Q_D(QDeclarativeListView);
+ if (event->type() == QEvent::User) {
+ d->layout();
+ return true;
+ }
+
+ return QDeclarativeFlickable::event(event);
+}
+
void QDeclarativeListView::viewportMoved()
{
Q_D(QDeclarativeListView);
@@ -1956,10 +1984,11 @@ void QDeclarativeListView::viewportMoved()
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
// reposition highlight
qreal pos = d->highlight->position();
- if (pos > d->position() + d->highlightRangeEnd - 1 - d->highlight->size())
- pos = d->position() + d->highlightRangeEnd - 1 - d->highlight->size();
- if (pos < d->position() + d->highlightRangeStart)
- pos = d->position() + d->highlightRangeStart;
+ qreal viewPos = qRound(d->position());
+ if (pos > viewPos + d->highlightRangeEnd - 1 - d->highlight->size())
+ pos = viewPos + d->highlightRangeEnd - 1 - d->highlight->size();
+ if (pos < viewPos + d->highlightRangeStart)
+ pos = viewPos + d->highlightRangeStart;
d->highlight->setPosition(pos);
// update current index
@@ -2032,7 +2061,7 @@ qreal QDeclarativeListView::maxYExtent() const
return height();
if (d->maxExtentDirty) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange)
- d->maxExtent = -(d->positionAt(count()-1) - d->highlightRangeEnd);
+ d->maxExtent = -(d->endPosition() - d->highlightRangeEnd);
else
d->maxExtent = -(d->endPosition() - height() + 1);
if (d->footer)
@@ -2069,7 +2098,7 @@ qreal QDeclarativeListView::maxXExtent() const
return width();
if (d->maxExtentDirty) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange)
- d->maxExtent = -(d->positionAt(count()-1) - d->highlightRangeEnd);
+ d->maxExtent = -(d->endPosition() - d->highlightRangeEnd);
else
d->maxExtent = -(d->endPosition() - width() + 1);
if (d->footer)
@@ -2151,11 +2180,23 @@ void QDeclarativeListView::decrementCurrentIndex()
}
/*!
- \qmlmethod ListView::positionViewAtIndex(int index)
+ \qmlmethod ListView::positionViewAtIndex(int index, PositionMode mode)
+
+ Positions the view such that the \a index is at the position specified by
+ \a mode:
+
+ \list
+ \o Beginning - position item at the top (or left for horizontal orientation) of the view.
+ \o Center- position item in the center of the view.
+ \o End - position item at bottom (or right for horizontal orientation) of the view.
+ \o Visible - if any part of the item is visible then take no action, otherwise
+ bring the item into view.
+ \o Contain - ensure the entire item is visible. If the item is larger than
+ the view the item is positioned at the top (or left for horizontal orientation) of the view.
+ \endlist
- Positions the view such that the \a index is at the top (or left for horizontal orientation) of the view.
If positioning the view at the index would cause empty space to be displayed at
- the end of the view, the view will be positioned at the end.
+ the beginning or end of the view, the view will be positioned at the boundary.
It is not recommended to use contentX or contentY to position the view
at a particular index. This is unreliable since removing items from the start
@@ -2163,32 +2204,58 @@ void QDeclarativeListView::decrementCurrentIndex()
the actual start of the view can vary based on the size of the delegates.
The correct way to bring an item into view is with positionViewAtIndex.
*/
-void QDeclarativeListView::positionViewAtIndex(int index)
+void QDeclarativeListView::positionViewAtIndex(int index, int mode)
{
Q_D(QDeclarativeListView);
if (!d->isValid() || index < 0 || index >= d->model->count())
return;
+ if (mode < Beginning || mode > Contain)
+ return;
- qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent();
+ qreal pos = d->position();
FxListItem *item = d->visibleItem(index);
- if (item) {
- // Already created - just move to top of view
- int pos = qMin(item->position(), maxExtent);
- d->setPosition(pos);
- } else {
- int pos = d->positionAt(index);
+ if (!item) {
+ int itemPos = d->positionAt(index);
// save the currently visible items in case any of them end up visible again
QList<FxListItem*> oldVisible = d->visibleItems;
d->visibleItems.clear();
- d->visiblePos = pos;
+ d->visiblePos = itemPos;
d->visibleIndex = index;
- d->setPosition(pos);
- // setPosition() will cause refill. Adjust if we have moved beyond range.
- if (d->position() > maxExtent)
- d->setPosition(maxExtent);
+ d->setPosition(itemPos);
// now release the reference to all the old visible items.
for (int i = 0; i < oldVisible.count(); ++i)
d->releaseItem(oldVisible.at(i));
+ item = d->visibleItem(index);
+ }
+ if (item) {
+ const qreal itemPos = item->position();
+ switch (mode) {
+ case Beginning:
+ pos = itemPos;
+ break;
+ case Center:
+ pos = itemPos - (d->size() - item->size())/2;
+ break;
+ case End:
+ pos = itemPos - d->size() + item->size();
+ break;
+ case Visible:
+ if (itemPos > pos + d->size())
+ pos = itemPos - d->size() + item->size();
+ else if (item->endPosition() < pos)
+ pos = itemPos;
+ break;
+ case Contain:
+ if (item->endPosition() > pos + d->size())
+ pos = itemPos - d->size() + item->size();
+ if (itemPos < pos)
+ pos = itemPos;
+ }
+ qreal maxExtent = d->orient == QDeclarativeListView::Vertical ? -maxYExtent() : -maxXExtent();
+ pos = qMin(pos, maxExtent);
+ qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent();
+ pos = qMax(pos, minExtent);
+ d->setPosition(pos);
}
d->fixupPosition();
}
@@ -2273,7 +2340,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
d->updateUnrequestedIndexes();
d->moveReason = QDeclarativeListViewPrivate::Other;
if (!d->visibleItems.count() || d->model->count() <= 1) {
- d->layout();
+ d->scheduleLayout();
d->updateCurrent(qMax(0, qMin(d->currentIndex, d->model->count()-1)));
emit countChanged();
return;
@@ -2303,8 +2370,9 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
d->currentIndex += count;
if (d->currentItem)
d->currentItem->index = d->currentIndex;
+ emit currentIndexChanged();
}
- d->layout();
+ d->scheduleLayout();
emit countChanged();
return;
}
@@ -2327,7 +2395,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
int i = 0;
int from = d->position() - d->buffer;
for (i = count-1; i >= 0 && pos > from; --i) {
- addedVisible = true;
+ if (!addedVisible) {
+ d->scheduleLayout();
+ addedVisible = true;
+ }
FxListItem *item = d->createItem(modelIndex + i);
d->visibleItems.insert(insertionIdx, item);
pos -= item->size() + d->spacing;
@@ -2354,7 +2425,10 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
int i = 0;
int to = d->buffer+d->position()+d->size()-1;
for (i = 0; i < count && pos <= to; ++i) {
- addedVisible = true;
+ if (!addedVisible) {
+ d->scheduleLayout();
+ addedVisible = true;
+ }
FxListItem *item = d->createItem(modelIndex + i);
d->visibleItems.insert(index, item);
item->setPosition(pos);
@@ -2377,6 +2451,7 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
d->currentItem->index = d->currentIndex;
d->currentItem->setPosition(d->currentItem->position() + diff);
}
+ emit currentIndexChanged();
}
// Update the indexes of the following visible items.
for (; index < d->visibleItems.count(); ++index) {
@@ -2390,8 +2465,6 @@ void QDeclarativeListView::itemsInserted(int modelIndex, int count)
for (int j = 0; j < added.count(); ++j)
added.at(j)->attached->emitAdd();
- if (addedVisible)
- d->layout();
emit countChanged();
}
@@ -2417,7 +2490,10 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
++it;
} else {
// removed item
- removedVisible = true;
+ if (!removedVisible) {
+ d->scheduleLayout();
+ removedVisible = true;
+ }
item->attached->emitRemove();
if (item->attached->delayRemove()) {
item->index = -1;
@@ -2442,6 +2518,7 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
+ emit currentIndexChanged();
} else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
// current item has been removed.
d->currentItem->attached->setIsCurrentItem(false);
@@ -2459,20 +2536,13 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
}
}
- if (removedVisible) {
- if (d->visibleItems.isEmpty()) {
- d->visibleIndex = 0;
- d->visiblePos = d->header ? d->header->size() : 0;
- d->timeline.clear();
- d->setPosition(0);
- if (d->model->count() == 0)
- update();
- else
- refill();
- } else {
- // Correct the positioning of the items
- d->layout();
- }
+ if (removedVisible && d->visibleItems.isEmpty()) {
+ d->visibleIndex = 0;
+ d->visiblePos = d->header ? d->header->size() : 0;
+ d->timeline.clear();
+ d->setPosition(0);
+ if (d->model->count() == 0)
+ update();
}
emit countChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index d66ac2b..0c2677c 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -191,10 +191,13 @@ public:
static QDeclarativeListViewAttached *qmlAttachedProperties(QObject *);
+ enum PositionMode { Beginning, Center, End, Visible, Contain };
+ Q_ENUMS(PositionMode)
+
public Q_SLOTS:
void incrementCurrentIndex();
void decrementCurrentIndex();
- void positionViewAtIndex(int index);
+ void positionViewAtIndex(int index, int mode);
Q_SIGNALS:
void countChanged();
@@ -219,6 +222,7 @@ Q_SIGNALS:
void footerChanged();
protected:
+ virtual bool event(QEvent *event);
virtual void viewportMoved();
virtual qreal minYExtent() const;
virtual qreal maxYExtent() const;
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index b0499d7..6dbcd16 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -155,6 +155,8 @@ void QDeclarativeLoaderPrivate::initResize()
QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeLoaderPrivate), parent)
{
+ Q_D(QDeclarativeItem);
+ d->flags |= QGraphicsItem::ItemIsFocusScope;
}
/*!
@@ -273,7 +275,7 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded()
if (component) {
QDeclarativeContext *ctxt = new QDeclarativeContext(qmlContext(q));
- ctxt->addDefaultObject(q);
+ ctxt->setContextObject(q);
if (!component->errors().isEmpty()) {
qWarning() << component->errors();
@@ -346,12 +348,13 @@ QDeclarativeLoader::Status QDeclarativeLoader::status() const
}
/*!
- \qmlproperty real Loader::progress
+\qmlproperty real Loader::progress
- This property holds the progress of QML data loading, from 0.0 (nothing loaded)
- to 1.0 (finished).
+This property holds the progress of loading QML data from the network, from
+0.0 (nothing loaded) to 1.0 (finished). Most QML files are quite small, so
+this value will rapidly change from 0 to 1.
- \sa status
+\sa status
*/
qreal QDeclarativeLoader::progress() const
{
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index ec7aa62..13195af 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -383,7 +383,6 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
d->dragged = false;
setHovered(true);
- d->start = event->pos();
d->startScene = event->scenePos();
// we should only start timer if pressAndHold is connected to.
if (d->isConnected("pressAndHold(QDeclarativeMouseEvent*)"))
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
index d4871f2..88206cd 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h
@@ -101,7 +101,6 @@ public:
bool dragY : 1;
bool dragged : 1;
QDeclarativeDrag *drag;
- QPointF start;
QPointF startScene;
qreal startX;
qreal startY;
diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
index ab6007a..28a93d2 100644
--- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
@@ -211,8 +211,8 @@ QDeclarativePaintedItem::~QDeclarativePaintedItem()
*/
void QDeclarativePaintedItem::init()
{
- connect(this,SIGNAL(widthChanged()),this,SLOT(clearCache()));
- connect(this,SIGNAL(heightChanged()),this,SLOT(clearCache()));
+ connect(this,SIGNAL(widthChanged(qreal)),this,SLOT(clearCache()));
+ connect(this,SIGNAL(heightChanged(qreal)),this,SLOT(clearCache()));
connect(this,SIGNAL(visibleChanged()),this,SLOT(clearCache()));
}
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index cc17157..b9c8971 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -354,7 +354,7 @@ void QDeclarativePathView::setCurrentIndex(int idx)
/*!
\qmlproperty real PathView::offset
- The offset specifies how far along the path the items are from their initial positions.
+ The offset specifies how far along the path (0.0-1.0) the items are from their initial positions.
*/
qreal QDeclarativePathView::offset() const
{
@@ -373,9 +373,9 @@ void QDeclarativePathViewPrivate::setOffset(qreal o)
{
Q_Q(QDeclarativePathView);
if (_offset != o) {
- _offset = qmlMod(o, qreal(100.0));
+ _offset = qmlMod(o, qreal(1.0));
if (_offset < 0)
- _offset = 100.0 + _offset;
+ _offset = 1.0 + _offset;
q->refill();
}
}
@@ -503,7 +503,7 @@ QPointF QDeclarativePathViewPrivate::pointNear(const QPointF &point, qreal *near
}
if (nearPercent)
- *nearPercent = nearPc / 10.0;
+ *nearPercent = nearPc / 1000.0;
return nearPoint;
}
@@ -559,10 +559,10 @@ void QDeclarativePathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (diff) {
setOffset(d->_offset + diff);
- if (diff > 50)
- diff -= 100;
- else if (diff < -50)
- diff += 100;
+ if (diff > 0.5)
+ diff -= 1.0;
+ else if (diff < -0.5)
+ diff += 1.0;
d->lastElapsed = QDeclarativeItemPrivate::restart(d->lastPosTime);
d->lastDist = diff;
@@ -579,15 +579,15 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
qreal elapsed = qreal(d->lastElapsed + QDeclarativeItemPrivate::elapsed(d->lastPosTime)) / 1000.;
qreal velocity = elapsed > 0. ? d->lastDist / elapsed : 0;
- if (d->model && d->model->count() && qAbs(velocity) > 5) {
- if (velocity > 100)
- velocity = 100;
- else if (velocity < -100)
- velocity = -100;
- qreal inc = qmlMod(d->_offset - d->snapPos, qreal(100.0 / d->model->count()));
- qreal dist = qAbs(velocity/2 - qmlMod(velocity/2, qreal(100.0 / d->model->count()) - inc));
+ if (d->model && d->model->count() && qAbs(velocity) > 0.05) {
+ if (velocity > 1.5)
+ velocity = 1.5;
+ else if (velocity < -1.5)
+ velocity = -1.5;
+ qreal inc = qmlMod(d->_offset - d->snapPos, qreal(1.0 / d->model->count()));
+ qreal dist = qAbs(velocity/2 - qmlMod(velocity/2, qreal(1.0 / d->model->count()) - inc));
d->moveOffset.setValue(d->_offset);
- d->tl.accel(d->moveOffset, velocity, 10, dist);
+ d->tl.accel(d->moveOffset, velocity, 0.1, dist);
d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d));
} else {
d->fixOffset();
@@ -676,10 +676,10 @@ void QDeclarativePathView::componentComplete()
itemIndex += d->pathOffset;
itemIndex %= d->items.count();
- qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0));
+ qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0));
if (targetOffset < 0)
- targetOffset = 100.0 + targetOffset;
+ targetOffset = 1.0 + targetOffset;
if (targetOffset != d->_offset) {
d->moveOffset.setValue(targetOffset);
}
@@ -712,8 +712,8 @@ void QDeclarativePathViewPrivate::regenerate()
}
items.append(item);
item->setZValue(i);
- qreal percent = i * (100. / numItems) + _offset;
- percent = qAbs(qmlMod(percent, qreal(100.0))/100.0);
+ qreal percent = qreal(i) / numItems + _offset;
+ percent = qAbs(qmlMod(percent, qreal(1.0)));
updateItem(item, percent);
model->completeItem();
if (currentIndex == index) {
@@ -745,10 +745,10 @@ void QDeclarativePathView::refill()
QList<qreal> positions;
for (int i=0; i<d->items.count(); i++){
- qreal percent = i * (100. / d->items.count());
+ qreal percent = qreal(i) / d->items.count();
percent = percent + d->_offset;
- percent = qmlMod(percent, qreal(100.0));
- positions << qAbs(percent/100.0);
+ percent = qmlMod(percent, qreal(1.0));
+ positions << qAbs(percent);
}
if (d->pathItems==-1) {
@@ -843,10 +843,10 @@ void QDeclarativePathView::itemsInserted(int modelIndex, int count)
int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count();
itemIndex += d->pathOffset;
itemIndex %= d->items.count();
- qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0));
+ qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0));
if (targetOffset < 0)
- targetOffset = 100.0 + targetOffset;
+ targetOffset = 1.0 + targetOffset;
if (targetOffset != d->_offset)
d->moveOffset.setValue(targetOffset);
}
@@ -880,10 +880,10 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count)
int itemIndex = (d->currentIndex - d->firstIndex + d->model->count())%d->model->count();
itemIndex += d->pathOffset;
itemIndex %= d->items.count();
- qreal targetOffset = qmlMod(100 + (d->snapPos*100) - 100.0 * itemIndex / d->items.count(), qreal(100.0));
+ qreal targetOffset = qmlMod(1.0 + d->snapPos - qreal(itemIndex) / d->items.count(), qreal(1.0));
if (targetOffset < 0)
- targetOffset = 100.0 + targetOffset;
+ targetOffset = 1.0 + targetOffset;
if (targetOffset != d->_offset)
d->moveOffset.setValue(targetOffset);
}
@@ -919,15 +919,15 @@ int QDeclarativePathViewPrivate::calcCurrentIndex()
{
int current = -1;
if (model && items.count()) {
- _offset = qmlMod(_offset, qreal(100.0));
+ _offset = qmlMod(_offset, qreal(1.0));
if (_offset < 0)
- _offset += 100.0;
+ _offset += 1.0;
if (pathItems == -1) {
- qreal delta = qmlMod(_offset - snapPos, qreal(100.0));
+ qreal delta = qmlMod(_offset - snapPos, qreal(1.0));
if (delta < 0)
- delta = 100.0 + delta;
- int ii = model->count() - qRound(delta * model->count() / 100);
+ delta = 1.0 + delta;
+ int ii = model->count() - qRound(delta * model->count());
if (ii < 0)
ii = 0;
current = ii;
@@ -935,10 +935,10 @@ int QDeclarativePathViewPrivate::calcCurrentIndex()
qreal bestDiff=1e9;
int bestI=-1;
for (int i=0; i<items.count(); i++){
- qreal percent = i * (100. / items.count());
+ qreal percent = qreal(i) / items.count();
percent = percent + _offset;
- percent = qmlMod(percent, qreal(100.0));
- qreal diff = qAbs(snapPos - (percent/100.0));
+ percent = qmlMod(percent, qreal(1.0));
+ qreal diff = qAbs(snapPos - percent);
if (diff < bestDiff){
bestDiff = diff;
bestI = i;
@@ -1017,10 +1017,10 @@ void QDeclarativePathViewPrivate::snapToCurrent()
itemIndex = itemIndex - model->count() + items.count();
}
itemIndex %= items.count();
- qreal targetOffset = qmlMod(100 + (snapPos*100) - 100.0 * itemIndex / items.count(), qreal(100.0));
+ qreal targetOffset = qmlMod(1.0 + snapPos - qreal(itemIndex) / items.count(), qreal(1.0));
if (targetOffset < 0)
- targetOffset = 100.0 + targetOffset;
+ targetOffset = 1.0 + targetOffset;
if (targetOffset == _offset && rounds == 0)
return;
@@ -1031,24 +1031,24 @@ void QDeclarativePathViewPrivate::snapToCurrent()
if (rounds!=0){
//Compensate if the targetOffset would bring the target in from off the screen
qreal distance = targetOffset - _offset;
- if (distance <= -50)
+ if (distance <= -0.5)
rounds--;
- if (distance > 50)
+ if (distance > 0.5)
rounds++;
- tl.move(moveOffset, targetOffset + 100.0*(-rounds), QEasingCurve(QEasingCurve::InOutQuad),
- int(100*items.count()*qMax((qreal)(2.0/items.count()),(qreal)qAbs(rounds))));
+ tl.move(moveOffset, targetOffset -rounds, QEasingCurve(QEasingCurve::InOutQuad),
+ int(items.count()*qMax((qreal)(2.0/items.count()),(qreal)qAbs(rounds))));
tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this));
return;
}
- if (targetOffset - _offset > 50.0) {
- qreal distance = 100 - targetOffset + _offset;
+ if (targetOffset - _offset > 0.5) {
+ qreal distance = 1 - targetOffset + _offset;
tl.move(moveOffset, 0.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * _offset / distance));
- tl.set(moveOffset, 100.0);
- tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * (100-targetOffset) / distance));
- } else if (targetOffset - _offset <= -50.0) {
- qreal distance = 100 - _offset + targetOffset;
- tl.move(moveOffset, 100.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * (100-_offset) / distance));
+ tl.set(moveOffset, 1.0);
+ tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * (1.0-targetOffset) / distance));
+ } else if (targetOffset - _offset <= -0.5) {
+ qreal distance = 1 - _offset + targetOffset;
+ tl.move(moveOffset, 1.0, QEasingCurve(QEasingCurve::OutQuad), int(200 * (1.0-_offset) / distance));
tl.set(moveOffset, 0.0);
tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InQuad), int(200 * targetOffset / distance));
} else {
diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
index 4083ab5..62f7d95 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
@@ -66,11 +66,6 @@
QT_BEGIN_NAMESPACE
-typedef struct PathViewItem{
- int index;
- QDeclarativeItem* item;
-}PathViewItem;
-
class QDeclarativeOpenMetaObjectType;
class QDeclarativePathViewAttached;
class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
index 1212e89..0f59a70 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
@@ -212,19 +212,22 @@ void QDeclarativeBasePositioner::prePositioning()
QList<QGraphicsItem *> children = d->QGraphicsItemPrivate::children;
qSort(children.begin(), children.end(), d->insertionOrder);
+ QPODVector<PositionedItem,8> oldItems;
+ positionedItems.copyAndClear(oldItems);
for (int ii = 0; ii < children.count(); ++ii) {
QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii));
if (!child)
continue;
PositionedItem *item = 0;
PositionedItem posItem(child);
- int wIdx = positionedItems.find(posItem);
+ int wIdx = oldItems.find(posItem);
if (wIdx < 0) {
d->watchChanges(child);
positionedItems.append(posItem);
item = &positionedItems[positionedItems.count()-1];
} else {
- item = &positionedItems[wIdx];
+ item = &oldItems[wIdx];
+ positionedItems.append(*item);
}
if (child->opacity() <= 0.0 || !child->isVisible()) {
item->isVisible = false;
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
index e4cd499..b9696c8 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
@@ -296,6 +296,8 @@ void QDeclarativeRepeater::clear()
void QDeclarativeRepeater::regenerate()
{
Q_D(QDeclarativeRepeater);
+ if (!isComponentComplete())
+ return;
clear();
@@ -312,23 +314,65 @@ void QDeclarativeRepeater::regenerate()
}
}
-void QDeclarativeRepeater::itemsInserted(int, int)
+void QDeclarativeRepeater::itemsInserted(int index, int count)
{
- regenerate();
+ Q_D(QDeclarativeRepeater);
+ if (!isComponentComplete())
+ return;
+ for (int i = 0; i < count; ++i) {
+ int modelIndex = index + i;
+ QDeclarativeItem *item = d->model->item(modelIndex);
+ if (item) {
+ item->setParent(parentItem());
+ if (modelIndex < d->deletables.count())
+ item->stackBefore(d->deletables.at(modelIndex));
+ else
+ item->stackBefore(this);
+ d->deletables.insert(modelIndex, item);
+ }
+ }
}
-void QDeclarativeRepeater::itemsRemoved(int, int)
+void QDeclarativeRepeater::itemsRemoved(int index, int count)
{
- regenerate();
+ Q_D(QDeclarativeRepeater);
+ if (!isComponentComplete())
+ return;
+ while (count--) {
+ QDeclarativeItem *item = d->deletables.takeAt(index);
+ if (item) {
+ item->setParentItem(this);
+ d->model->release(item);
+ }
+ }
}
-void QDeclarativeRepeater::itemsMoved(int,int,int)
+void QDeclarativeRepeater::itemsMoved(int from, int to, int count)
{
- regenerate();
+ Q_D(QDeclarativeRepeater);
+ if (!isComponentComplete())
+ return;
+ QList<QDeclarativeItem*> removed;
+ int removedCount = count;
+ while (removedCount--)
+ removed << d->deletables.takeAt(from);
+ for (int i = 0; i < count; ++i)
+ d->deletables.insert(to + i, removed.at(i));
+ for (int i = 0; i < d->model->count(); ++i) {
+ if (i < from && i < to)
+ continue;
+ QDeclarativeItem *item = d->deletables.at(i);
+ if (i < d->deletables.count()-1)
+ item->stackBefore(d->deletables.at(i+1));
+ else
+ item->stackBefore(this);
+ }
}
void QDeclarativeRepeater::modelReset()
{
+ if (!isComponentComplete())
+ return;
regenerate();
}
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index be73b39..dbae47d 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -760,17 +760,11 @@ void QDeclarativeTextEdit::keyReleaseEvent(QKeyEvent *event)
QDeclarativePaintedItem::keyReleaseEvent(event);
}
-/*!
- \overload
- Handles changing of the focus property. Focus is applied to the control
- even if the edit does not have active focus. This is because things
- like KeyProxy can give the behavior of focus even when hasFocus() isn't
- true.
-*/
-void QDeclarativeTextEdit::focusChanged(bool hasFocus)
+void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus)
{
- setCursorVisible(hasFocus);
- QDeclarativeItem::focusChanged(hasFocus);
+ Q_Q(QDeclarativeTextEdit);
+ q->setCursorVisible(hasFocus);
+ QDeclarativeItemPrivate::focusChanged(hasFocus);
}
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index 6183b1d..b1682c4 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -215,8 +215,6 @@ protected:
void keyPressEvent(QKeyEvent *);
void keyReleaseEvent(QKeyEvent *);
- void focusChanged(bool);
-
// mouse filter?
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
index 002fac4..dd2a29d 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h
@@ -80,6 +80,7 @@ public:
void updateDefaultTextOption();
void relayoutDocument();
void updateSelection();
+ void focusChanged(bool);
QString text;
QFont font;
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 3382628..6df3533 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -636,12 +636,12 @@ int QDeclarativeTextInput::xToPos(int x)
return d->control->xToPos(x - d->hscroll);
}
-void QDeclarativeTextInput::focusChanged(bool hasFocus)
+void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus)
{
- Q_D(QDeclarativeTextInput);
- d->focused = hasFocus;
- setCursorVisible(hasFocus);
- QDeclarativeItem::focusChanged(hasFocus);
+ Q_Q(QDeclarativeTextInput);
+ focused = hasFocus;
+ q->setCursorVisible(hasFocus);
+ QDeclarativeItemPrivate::focusChanged(hasFocus);
}
void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev)
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index f690ae2..6a61c2d 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -199,8 +199,6 @@ protected:
void keyPressEvent(QKeyEvent* ev);
bool event(QEvent *e);
- void focusChanged(bool hasFocus);
-
public Q_SLOTS:
void selectAll();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index 3d28f40..5d17a55 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -83,6 +83,7 @@ public:
void init();
void startCreatingCursor();
+ void focusChanged(bool hasFocus);
QLineControl* control;
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index 6bad4da..6341764 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -196,7 +196,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express
return QVariant();
QDeclarativeContext *ccontext = qmlContext(this);
QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext);
- ctxt->addDefaultObject(d->children.at(index));
+ ctxt->setContextObject(d->children.at(index));
QDeclarativeExpression e(ctxt, expression, objectContext);
QVariant value = e.value();
delete ctxt;
@@ -991,7 +991,7 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray
QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext);
QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this);
ctxt->setContextProperty(QLatin1String("model"), data);
- ctxt->addDefaultObject(data);
+ ctxt->setContextObject(data);
nobj = d->m_delegate->beginCreate(ctxt);
if (complete)
d->m_delegate->completeCreate();
@@ -1104,7 +1104,7 @@ QVariant QDeclarativeVisualDataModel::evaluate(int index, const QString &express
if (!ccontext) ccontext = qmlContext(this);
QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext);
QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this);
- ctxt->addDefaultObject(data);
+ ctxt->setContextObject(data);
QDeclarativeExpression e(ctxt, expression, objectContext);
value = e.value();
delete data;
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index 34163a4..6404be3 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -56,9 +56,11 @@
#include <stdio.h>
#include <string.h>
-QT_QML_BEGIN_NAMESPACE
-
+QT_BEGIN_NAMESPACE
extern double qstrtod(const char *s00, char const **se, bool *ok);
+QT_END_NAMESPACE
+
+QT_QML_BEGIN_NAMESPACE
#define shiftWindowsLineBreak() \
do { \
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index 77b7484..dfdef11 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -99,7 +99,7 @@ int qmlRegisterType()
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
- 0,
+ 0, 0,
0, 0, 0, 0, &T::staticMetaObject,
@@ -131,7 +131,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
- QDeclarativePrivate::create<T>,
+ sizeof(T), QDeclarativePrivate::createInto<T>,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -163,7 +163,7 @@ int qmlRegisterExtendedType()
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
- 0,
+ 0, 0,
0, 0, 0, 0, &T::staticMetaObject,
@@ -203,7 +203,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
- QDeclarativePrivate::create<T>,
+ sizeof(T), QDeclarativePrivate::createInto<T>,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -256,7 +256,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
qRegisterMetaType<T *>(pointerName.constData()),
qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
- QDeclarativePrivate::create<T>,
+ sizeof(T), QDeclarativePrivate::createInto<T>,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -275,18 +275,6 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
return QDeclarativePrivate::registerType(type);
}
-#define QML_REGISTER_INTERFACE(INTERFACE) \
- qmlRegisterInterface<INTERFACE>(#INTERFACE)
-
-#define QML_REGISTER_EXTENDED_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, CLASS, EXTENSION) \
- qmlRegisterExtendedType<CLASS,EXTENSION>(#URI, VERSION_MAJ, VERSION_MIN, #NAME)
-
-#define QML_REGISTER_TYPE(URI,VMAJ,VMIN,NAME,CLASS) \
- qmlRegisterType<CLASS>(#URI, VMAJ, VMIN, #NAME)
-
-#define QML_REGISTER_NOCREATE_TYPE(CLASS) \
- qmlRegisterType<CLASS>()
-
class QDeclarativeContext;
class QDeclarativeEngine;
Q_DECLARATIVE_EXPORT void qmlExecuteDeferred(QObject *);
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 88ca5cd..090bd5b 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -79,14 +79,25 @@ QDeclarativeBindingPrivate::QDeclarativeBindingPrivate()
{
}
-QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj, QDeclarativeContext *ctxt, const QString &url, int lineNumber, QObject *parent)
+QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj,
+ QDeclarativeContextData *ctxt, const QString &url, int lineNumber,
+ QObject *parent)
: QDeclarativeExpression(ctxt, data, rc, obj, url, lineNumber, *new QDeclarativeBindingPrivate)
{
setParent(parent);
setNotifyOnValueChanged(true);
}
-QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt, QObject *parent)
+QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt,
+ QObject *parent)
+: QDeclarativeExpression(QDeclarativeContextData::get(ctxt), str, obj, *new QDeclarativeBindingPrivate)
+{
+ setParent(parent);
+ setNotifyOnValueChanged(true);
+}
+
+QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContextData *ctxt,
+ QObject *parent)
: QDeclarativeExpression(ctxt, str, obj, *new QDeclarativeBindingPrivate)
{
setParent(parent);
@@ -181,8 +192,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
}
if (data->error.isValid()) {
- QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine())?
- QDeclarativeEnginePrivate::get(data->context()->engine()):0;
+ QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)?
+ QDeclarativeEnginePrivate::get(data->context()->engine):0;
if (!data->addError(p))
qWarning().nospace() << qPrintable(this->error().toString());
} else {
@@ -223,7 +234,7 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF
int QDeclarativeBinding::propertyIndex()
{
Q_D(QDeclarativeBinding);
- return d->bindingData()->property.index();
+ return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property);
}
bool QDeclarativeBinding::enabled() const
@@ -259,23 +270,57 @@ void QDeclarativeAbstractBinding::addToObject(QObject *object)
{
Q_ASSERT(object);
+ if (m_object == object)
+ return;
+
+ int index = propertyIndex();
+
removeFromObject();
Q_ASSERT(!m_prevBinding);
- QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true);
- m_nextBinding = data->bindings;
- if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
- m_prevBinding = &data->bindings;
- data->bindings = this;
m_object = object;
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, true);
+
+ if (index & 0xFF000000) {
+ // Value type
+
+ int coreIndex = index & 0xFFFFFF;
+
+ // Find the value type proxy (if there is one)
+ QDeclarativeValueTypeProxyBinding *proxy = 0;
+ if (data->hasBindingBit(coreIndex)) {
+ QDeclarativeAbstractBinding *b = data->bindings;
+ while (b && b->propertyIndex() != coreIndex)
+ b = b->m_nextBinding;
+ Q_ASSERT(b && b->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy);
+ proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(b);
+ }
+
+ if (!proxy)
+ proxy = new QDeclarativeValueTypeProxyBinding(object, coreIndex);
+ proxy->addToObject(object);
+
+ m_nextBinding = proxy->m_bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &proxy->m_bindings;
+ proxy->m_bindings = this;
- data->setBindingBit(m_object, propertyIndex());
+ } else {
+ m_nextBinding = data->bindings;
+ if (m_nextBinding) m_nextBinding->m_prevBinding = &m_nextBinding;
+ m_prevBinding = &data->bindings;
+ data->bindings = this;
+
+ data->setBindingBit(m_object, index);
+ }
}
void QDeclarativeAbstractBinding::removeFromObject()
{
if (m_prevBinding) {
+ int index = propertyIndex();
+
Q_ASSERT(m_object);
*m_prevBinding = m_nextBinding;
@@ -283,8 +328,14 @@ void QDeclarativeAbstractBinding::removeFromObject()
m_prevBinding = 0;
m_nextBinding = 0;
- QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false);
- if (data) data->clearBindingBit(propertyIndex());
+ if (index & 0xFF000000) {
+ // Value type - we don't remove the proxy from the object. It will sit their happily
+ // doing nothing for ever more.
+ } else {
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(m_object, false);
+ if (data) data->clearBindingBit(index);
+ }
+
m_object = 0;
}
}
@@ -305,4 +356,88 @@ void QDeclarativeAbstractBinding::setEnabled(bool e, QDeclarativePropertyPrivate
if (e) m_mePtr = 0;
}
+QDeclarativeValueTypeProxyBinding::QDeclarativeValueTypeProxyBinding(QObject *o, int index)
+: m_object(o), m_index(index), m_bindings(0)
+{
+}
+
+QDeclarativeValueTypeProxyBinding::~QDeclarativeValueTypeProxyBinding()
+{
+ while (m_bindings) {
+ QDeclarativeAbstractBinding *binding = m_bindings;
+ binding->setEnabled(false, 0);
+ binding->destroy();
+ }
+}
+
+void QDeclarativeValueTypeProxyBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (e) {
+ addToObject(m_object);
+
+ QDeclarativeAbstractBinding *bindings = m_bindings;
+ m_bindings = 0;
+ recursiveEnable(bindings, flags);
+ } else {
+ removeFromObject();
+
+ QDeclarativeAbstractBinding *bindings = m_bindings;
+ m_bindings = 0;
+ recursiveDisable(bindings);
+ }
+}
+
+void QDeclarativeValueTypeProxyBinding::recursiveEnable(QDeclarativeAbstractBinding *b, QDeclarativePropertyPrivate::WriteFlags flags)
+{
+ if (!b)
+ return;
+
+ QDeclarativeAbstractBinding *next = b->m_nextBinding;
+ b->m_prevBinding = 0;
+ b->m_nextBinding = 0;
+ Q_ASSERT(b->m_mePtr == 0);
+ b->m_mePtr = &b;
+
+ recursiveEnable(next, flags);
+
+ if (b)
+ b->setEnabled(true, flags);
+}
+
+void QDeclarativeValueTypeProxyBinding::recursiveDisable(QDeclarativeAbstractBinding *b)
+{
+ if (!b)
+ return;
+
+ recursiveDisable(b->m_nextBinding);
+
+ b->setEnabled(false, 0);
+
+ Q_ASSERT(b->m_prevBinding == 0);
+ Q_ASSERT(b->m_nextBinding == 0);
+ b->m_nextBinding = m_bindings;
+ if (b->m_nextBinding) b->m_nextBinding->m_prevBinding = &b->m_nextBinding;
+ b->m_prevBinding = &m_bindings;
+ m_bindings = b;
+}
+
+int QDeclarativeValueTypeProxyBinding::propertyIndex()
+{
+ return m_index;
+}
+
+void QDeclarativeValueTypeProxyBinding::update(QDeclarativePropertyPrivate::WriteFlags)
+{
+}
+
+QDeclarativeAbstractBinding *QDeclarativeValueTypeProxyBinding::binding(int propertyIndex)
+{
+ QDeclarativeAbstractBinding *binding = m_bindings;
+
+ while (binding && binding->propertyIndex() != propertyIndex)
+ binding = binding->m_nextBinding;
+
+ return binding;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 1a714f0..533b6d4 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -74,6 +74,9 @@ public:
virtual QString expression() const;
+ enum Type { PropertyBinding, ValueTypeProxy };
+ virtual Type bindingType() const { return PropertyBinding; }
+
void setEnabled(bool e) { setEnabled(e, QDeclarativePropertyPrivate::DontRemoveBinding); }
virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags) = 0;
virtual int propertyIndex() = 0;
@@ -92,6 +95,7 @@ private:
friend class QDeclarativeProperty;
friend class QDeclarativePropertyPrivate;
friend class QDeclarativeVME;
+ friend class QDeclarativeValueTypeProxyBinding;
QObject *m_object;
QDeclarativeAbstractBinding **m_mePtr;
@@ -99,6 +103,30 @@ private:
QDeclarativeAbstractBinding *m_nextBinding;
};
+class QDeclarativeValueTypeProxyBinding : public QDeclarativeAbstractBinding
+{
+public:
+ QDeclarativeValueTypeProxyBinding(QObject *o, int coreIndex);
+ virtual ~QDeclarativeValueTypeProxyBinding();
+
+ virtual Type bindingType() const { return ValueTypeProxy; }
+
+ virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags);
+ virtual int propertyIndex();
+ virtual void update(QDeclarativePropertyPrivate::WriteFlags);
+
+ QDeclarativeAbstractBinding *binding(int propertyIndex);
+
+private:
+ void recursiveEnable(QDeclarativeAbstractBinding *, QDeclarativePropertyPrivate::WriteFlags);
+ void recursiveDisable(QDeclarativeAbstractBinding *);
+
+ friend class QDeclarativeAbstractBinding;
+ QObject *m_object;
+ int m_index;
+ QDeclarativeAbstractBinding *m_bindings;
+};
+
class QDeclarativeContext;
class QDeclarativeBindingPrivate;
class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression, public QDeclarativeAbstractBinding
@@ -106,8 +134,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeBinding : public QDeclarativeExpression,
Q_OBJECT
public:
QDeclarativeBinding(const QString &, QObject *, QDeclarativeContext *, QObject *parent=0);
- QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContext *, const QString &, int,
- QObject *parent);
+ QDeclarativeBinding(const QString &, QObject *, QDeclarativeContextData *, QObject *parent=0);
+ QDeclarativeBinding(void *, QDeclarativeRefCount *, QObject *, QDeclarativeContextData *,
+ const QString &, int, QObject *parent);
~QDeclarativeBinding();
void setTarget(const QDeclarativeProperty &);
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 17937fd..c8bff17 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -48,12 +48,17 @@
#include <private/qdeclarativejsast_p.h>
#include <private/qdeclarativejsengine_p.h>
#include <private/qdeclarativeexpression_p.h>
+#include <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
#include <QtCore/qnumeric.h>
#include <private/qdeclarativeanchors_p_p.h>
+#include <private/qdeclarativeglobal_p.h>
QT_BEGIN_NAMESPACE
+DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL);
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER);
+
using namespace QDeclarativeJS;
namespace {
@@ -124,24 +129,7 @@ public:
QDeclarativeCompiledBindingsPrivate *parent;
};
- struct Subscription {
- struct Signal {
- QDeclarativeGuard<QObject> source;
- int notifyIndex;
- };
-
- enum { InvalidType, SignalType, IdType } type;
- inline Subscription();
- inline ~Subscription();
- bool isSignal() const { return type == SignalType; }
- bool isId() const { return type == IdType; }
- inline Signal *signal();
- inline QDeclarativeContextPrivate::IdNotifier *id();
- union {
- char signalData[sizeof(Signal)];
- char idData[sizeof(QDeclarativeContextPrivate::IdNotifier)];
- };
- };
+ typedef QDeclarativeNotifierEndpoint Subscription;
Subscription *subscriptions;
QScriptDeclarativeClass::PersistentIdentifier *identifiers;
@@ -154,18 +142,18 @@ public:
static int methodCount;
void init();
- void run(int instr, QDeclarativeContextPrivate *context,
+ void run(int instr, QDeclarativeContextData *context,
QDeclarativeDelayedError *error, QObject *scope, QObject *output);
inline void unsubscribe(int subIndex);
- inline void subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex);
+ inline void subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex);
inline void subscribe(QObject *o, int notifyIndex, int subIndex);
QDeclarativePropertyCache::Data *findproperty(QObject *obj,
- const QScriptDeclarativeClass::Identifier &name,
- QDeclarativeEnginePrivate *enginePriv,
- QDeclarativePropertyCache::Data &local);
+ const QScriptDeclarativeClass::Identifier &name,
+ QDeclarativeEnginePrivate *enginePriv,
+ QDeclarativePropertyCache::Data &local);
bool findproperty(QObject *obj,
Register *output,
QDeclarativeEnginePrivate *enginePriv,
@@ -174,7 +162,7 @@ public:
bool isTerminal);
void findgeneric(Register *output, // value output
int subIdx, // Subscription index in config
- QDeclarativeContextPrivate *context, // Context to search in
+ QDeclarativeContextData *context, // Context to search in
const QScriptDeclarativeClass::Identifier &name,
bool isTerminal);
};
@@ -190,21 +178,9 @@ QDeclarativeCompiledBindingsPrivate::~QDeclarativeCompiledBindingsPrivate()
delete [] identifiers; identifiers = 0;
}
-QDeclarativeCompiledBindingsPrivate::Subscription::Subscription()
-: type(InvalidType)
-{
-}
-
-QDeclarativeCompiledBindingsPrivate::Subscription::~Subscription()
-{
- if (type == SignalType) ((Signal *)signalData)->~Signal();
- else if (type == IdType) ((QDeclarativeContextPrivate::IdNotifier *)idData)->~IdNotifier();
-}
-
-
int QDeclarativeCompiledBindingsPrivate::methodCount = -1;
-QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context)
+QDeclarativeCompiledBindings::QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context)
: QObject(*(new QDeclarativeCompiledBindingsPrivate))
{
Q_D(QDeclarativeCompiledBindings);
@@ -248,7 +224,6 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati
{
if (e) {
addToObject(target);
- update(flags);
} else {
removeFromObject();
}
@@ -303,47 +278,51 @@ void QDeclarativeCompiledBindingsPrivate::run(Binding *binding)
if (!binding->enabled)
return;
- if (binding->updating)
- qWarning("ERROR: Circular binding");
- QDeclarativeContext *context = q->QDeclarativeAbstractExpression::context();
+ QDeclarativeContextData *context = q->QDeclarativeAbstractExpression::context();
if (!context) {
qWarning("QDeclarativeCompiledBindings: Attempted to evaluate an expression in an invalid context");
return;
}
- QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(context);
+ if (!context->engine)
+ return;
+
+ if (binding->updating) {
+ QString name;
+ if (binding->property & 0xFFFF0000) {
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
+
+ QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
+ Q_ASSERT(vt);
+
+ name = QLatin1String(binding->target->metaObject()->property(binding->property & 0xFFFF).name());
+ name.append(QLatin1String("."));
+ name.append(QLatin1String(vt->metaObject()->property(binding->property >> 24).name()));
+ } else {
+ name = QLatin1String(binding->target->metaObject()->property(binding->property).name());
+ }
+ qmlInfo(binding->target) << QCoreApplication::translate("QDeclarativeCompiledBindings", "Binding loop detected for property \"%1\"").arg(name);
+ return;
+ }
+
+ binding->updating = true;
if (binding->property & 0xFFFF0000) {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(cp->engine);
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
QDeclarativeValueType *vt = ep->valueTypes[(binding->property >> 16) & 0xFF];
Q_ASSERT(vt);
vt->read(binding->target, binding->property & 0xFFFF);
QObject *target = vt;
- run(binding->index, cp, binding, binding->scope, target);
+ run(binding->index, context, binding, binding->scope, target);
vt->write(binding->target, binding->property & 0xFFFF,
QDeclarativePropertyPrivate::DontRemoveBinding);
} else {
- run(binding->index, cp, binding, binding->scope, binding->target);
+ run(binding->index, context, binding, binding->scope, binding->target);
}
-}
-
-QDeclarativeCompiledBindingsPrivate::Subscription::Signal *QDeclarativeCompiledBindingsPrivate::Subscription::signal()
-{
- if (type == IdType) ((QDeclarativeContextPrivate::IdNotifier *)idData)->~IdNotifier();
- if (type != SignalType) new (signalData) Signal;
- type = SignalType;
- return (Signal *)signalData;
-}
-
-QDeclarativeContextPrivate::IdNotifier *QDeclarativeCompiledBindingsPrivate::Subscription::id()
-{
- if (type == SignalType) ((Signal *)signalData)->~Signal();
- if (type != IdType) new (idData) QDeclarativeContextPrivate::IdNotifier;
- type = IdType;
- return (QDeclarativeContextPrivate::IdNotifier *)idData;
+ binding->updating = false;
}
namespace {
@@ -653,26 +632,11 @@ struct QDeclarativeBindingCompilerPrivate
void QDeclarativeCompiledBindingsPrivate::unsubscribe(int subIndex)
{
- Q_Q(QDeclarativeCompiledBindings);
-
QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- if (sub->isSignal()) {
- QDeclarativeCompiledBindingsPrivate::Subscription::Signal *s = sub->signal();
- if (s->source)
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
- QMetaObject::disconnectOne(s->source, s->notifyIndex,
- q, methodCount + subIndex);
-#else
- // QTBUG-6781
- QMetaObject::disconnect(s->source, s->notifyIndex,
- q, methodCount + subIndex);
-#endif
- } else if (sub->isId()) {
- sub->id()->clear();
- }
+ sub->disconnect();
}
-void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate *p, int idIndex, int subIndex)
+void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextData *p, int idIndex, int subIndex)
{
Q_Q(QDeclarativeCompiledBindings);
@@ -680,15 +644,9 @@ void QDeclarativeCompiledBindingsPrivate::subscribeId(QDeclarativeContextPrivate
if (p->idValues[idIndex]) {
QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
- QDeclarativeContextPrivate::IdNotifier *i = sub->id();
-
- i->next = p->idValues[idIndex].bindings;
- i->prev = &p->idValues[idIndex].bindings;
- p->idValues[idIndex].bindings = i;
- if (i->next) i->next->prev = &i->next;
-
- i->target = q;
- i->methodIndex = methodCount + subIndex;
+ sub->target = q;
+ sub->targetMethod = methodCount + subIndex;
+ sub->connect(&p->idValues[idIndex].bindings);
}
}
@@ -697,27 +655,12 @@ void QDeclarativeCompiledBindingsPrivate::subscribe(QObject *o, int notifyIndex,
Q_Q(QDeclarativeCompiledBindings);
QDeclarativeCompiledBindingsPrivate::Subscription *sub = (subscriptions + subIndex);
-
- if (sub->isId())
- unsubscribe(subIndex);
-
- QDeclarativeCompiledBindingsPrivate::Subscription::Signal *s = sub->signal();
- if (o != s->source || notifyIndex != s->notifyIndex) {
- if (s->source)
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
- QMetaObject::disconnectOne(s->source, s->notifyIndex,
- q, methodCount + subIndex);
-#else
- // QTBUG-6781
- QMetaObject::disconnect(s->source, s->notifyIndex,
- q, methodCount + subIndex);
-#endif
- s->source = o;
- s->notifyIndex = notifyIndex;
- if (s->source && s->notifyIndex != -1)
- QMetaObject::connect(s->source, s->notifyIndex, q,
- methodCount + subIndex, Qt::DirectConnection);
- }
+ sub->target = q;
+ sub->targetMethod = methodCount + subIndex;
+ if (o)
+ sub->connect(o, notifyIndex);
+ else
+ sub->disconnect();
}
// Conversion functions - these MUST match the QtScript expression path
@@ -767,7 +710,7 @@ inline static bool toBool(Register *reg, int type, bool *ok = 0)
}
}
-inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextPrivate *context, bool *ok = 0)
+inline static QUrl toUrl(Register *reg, int type, QDeclarativeContextData *context, bool *ok = 0)
{
if (ok) *ok = true;
@@ -811,9 +754,9 @@ static QObject *variantToQObject(const QVariant &value, bool *ok)
}
bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *output,
- QDeclarativeEnginePrivate *enginePriv,
- int subIdx, const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal)
+ QDeclarativeEnginePrivate *enginePriv,
+ int subIdx, const QScriptDeclarativeClass::Identifier &name,
+ bool isTerminal)
{
if (!obj) {
output->setUndefined();
@@ -884,10 +827,10 @@ bool QDeclarativeCompiledBindingsPrivate::findproperty(QObject *obj, Register *o
}
void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output,
- int subIdx,
- QDeclarativeContextPrivate *context,
- const QScriptDeclarativeClass::Identifier &name,
- bool isTerminal)
+ int subIdx,
+ QDeclarativeContextData *context,
+ const QScriptDeclarativeClass::Identifier &name,
+ bool isTerminal)
{
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(context->engine);
@@ -898,14 +841,17 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output,
if (contextPropertyIndex != -1) {
- if (subIdx != -1)
- subscribe(QDeclarativeContextPrivate::get(context), contextPropertyIndex + context->notifyIndex, subIdx);
-
if (contextPropertyIndex < context->idValueCount) {
output->setQObject(context->idValues[contextPropertyIndex]);
output->settype(QMetaType::QObjectStar);
+
+ if (subIdx != -1)
+ subscribeId(context, contextPropertyIndex, subIdx);
+
} else {
- const QVariant &value = context->propertyValues.at(contextPropertyIndex);
+ QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate();
+ const QVariant &value = cp->propertyValues.at(contextPropertyIndex);
+
if (isTerminal) {
new (output->typeDataPtr()) QVariant(value);
output->settype(qMetaTypeId<QVariant>());
@@ -916,6 +862,11 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output,
else { output->settype(QMetaType::QObjectStar); }
return;
}
+
+ if (subIdx != -1)
+ subscribe(context->asQDeclarativeContext(), contextPropertyIndex + cp->notifyIndex, subIdx);
+
+
}
return;
@@ -928,18 +879,14 @@ void QDeclarativeCompiledBindingsPrivate::findgeneric(Register *output,
}
}
- if (QObject *root = context->defaultObjects.isEmpty()?0:context->defaultObjects.first()) {
+ if (QObject *root = context->contextObject) {
if (findproperty(root, output, enginePriv, subIdx, name, isTerminal))
return;
}
- if (context->parent) {
- context = QDeclarativeContextPrivate::get(context->parent);
- } else {
- context = 0;
- }
+ context = context->parent;
}
output->setUndefined();
@@ -958,7 +905,7 @@ void QDeclarativeCompiledBindingsPrivate::init()
}
static void throwException(int id, QDeclarativeDelayedError *error,
- Program *program, QDeclarativeContextPrivate *context,
+ Program *program, QDeclarativeContextData *context,
const QString &description = QString())
{
error->error.setUrl(context->url);
@@ -1120,8 +1067,8 @@ static void dumpInstruction(const Instr *instr)
}
void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
- QDeclarativeContextPrivate *context, QDeclarativeDelayedError *error,
- QObject *scope, QObject *output)
+ QDeclarativeContextData *context, QDeclarativeDelayedError *error,
+ QObject *scope, QObject *output)
{
error->removeError();
@@ -1169,7 +1116,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
break;
case Instr::LoadRoot:
- registers[instr->load.reg].setQObject(context->defaultObjects.at(0));
+ registers[instr->load.reg].setQObject(context->contextObject);
break;
case Instr::LoadAttached:
@@ -1455,7 +1402,7 @@ void QDeclarativeCompiledBindingsPrivate::run(int instrIndex,
// name is not present in the current context or it would have been
// found during the static compile
findgeneric(registers + instr->find.reg, instr->find.subscribeIndex,
- QDeclarativeContextPrivate::get(context->parent),
+ context->parent,
identifiers[instr->find.name].identifier,
instr->common.type == Instr::FindGenericTerminal);
break;
@@ -1612,6 +1559,9 @@ bool QDeclarativeBindingCompilerPrivate::compile(QDeclarativeJS::AST::Node *node
return false;
if (type.unknownType) {
+ if (!qmlExperimental())
+ return false;
+
if (destination->type != QMetaType::QReal &&
destination->type != QVariant::String &&
destination->type != QMetaType::Bool &&
@@ -1895,7 +1845,7 @@ bool QDeclarativeBindingCompilerPrivate::parseName(AST::Node *node, Result &type
if (!fetch(type, component->metaObject(), reg, d1Idx, subscribeName, nameNodes.at(ii)))
return false;
- } else {
+ } else if (qmlExperimental()) {
Instr find;
if (nameParts.count() == 1)
find.common.type = Instr::FindGenericTerminal;
@@ -2051,7 +2001,11 @@ bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result
int lhsTmp = -1;
int rhsTmp = -1;
+
if (lhs.unknownType) {
+ if (!qmlExperimental())
+ return false;
+
lhsTmp = acquireReg();
Instr conv;
@@ -2062,6 +2016,9 @@ bool QDeclarativeBindingCompilerPrivate::numberArith(Result &type, const Result
}
if (rhs.unknownType) {
+ if (!qmlExperimental())
+ return false;
+
rhsTmp = acquireReg();
Instr conv;
@@ -2107,6 +2064,9 @@ bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result
int rhsTmp = -1;
if (lhs.unknownType) {
+ if (!qmlExperimental())
+ return false;
+
lhsTmp = acquireReg(Instr::CleanupString);
Instr convert;
@@ -2117,6 +2077,9 @@ bool QDeclarativeBindingCompilerPrivate::stringArith(Result &type, const Result
}
if (rhs.unknownType) {
+ if (!qmlExperimental())
+ return false;
+
rhsTmp = acquireReg(Instr::CleanupString);
Instr convert;
@@ -2637,6 +2600,12 @@ int QDeclarativeBindingCompiler::compile(const Expression &expression, QDeclarat
{
if (!expression.expression.asAST()) return false;
+ if (!qmlExperimental() && expression.property->isValueTypeSubProperty)
+ return -1;
+
+ if (qmlDisableOptimizer())
+ return -1;
+
d->context = expression.context;
d->component = expression.component;
d->destination = expression.property;
diff --git a/src/declarative/qml/qdeclarativecompiledbindings_p.h b/src/declarative/qml/qdeclarativecompiledbindings_p.h
index 2e24371..84a5df9 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings_p.h
+++ b/src/declarative/qml/qdeclarativecompiledbindings_p.h
@@ -95,7 +95,7 @@ class QDeclarativeCompiledBindingsPrivate;
class QDeclarativeCompiledBindings : public QObject, public QDeclarativeAbstractExpression, public QDeclarativeRefCount
{
public:
- QDeclarativeCompiledBindings(const char *program, QDeclarativeContext *context);
+ QDeclarativeCompiledBindings(const char *program, QDeclarativeContextData *context);
virtual ~QDeclarativeCompiledBindings();
QDeclarativeAbstractBinding *configBinding(int index, QObject *target, QObject *scope, int property);
diff --git a/src/declarative/qml/qdeclarativecompileddata.cpp b/src/declarative/qml/qdeclarativecompileddata.cpp
index bdf16a3..dfbf453 100644
--- a/src/declarative/qml/qdeclarativecompileddata.cpp
+++ b/src/declarative/qml/qdeclarativecompileddata.cpp
@@ -199,20 +199,6 @@ void QDeclarativeCompiledData::clear()
cachedPrograms[ii] = 0;
}
-
-QObject *QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContext *ctxt, const QBitField &bindings) const
-{
- if (type) {
- QObject *rv = type->create();
- if (rv)
- QDeclarativeEngine::setContextForObject(rv, ctxt);
- return rv;
- } else {
- Q_ASSERT(component);
- return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings);
- }
-}
-
const QMetaObject *QDeclarativeCompiledData::TypeReference::metaObject() const
{
if (type) {
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index ef1032b..06ff47c 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATISTICS_DUMP);
-DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL);
+DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
using namespace QDeclarativeParser;
@@ -1850,6 +1850,7 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
QMetaProperty p = type->metaObject()->property(idx);
prop->index = idx;
prop->type = p.userType();
+ prop->isValueTypeSubProperty = true;
if (prop->value)
COMPILE_EXCEPTION(prop, QCoreApplication::translate("QDeclarativeCompiler","Property assignment expected"));
@@ -2712,7 +2713,9 @@ bool QDeclarativeCompiler::completeComponentBuild()
QDeclarativeBindingCompiler bindingCompiler;
- for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin(); iter != compileState.bindings.end(); ++iter) {
+ for (QHash<QDeclarativeParser::Value*,BindingReference>::Iterator iter = compileState.bindings.begin();
+ iter != compileState.bindings.end(); ++iter) {
+
BindingReference &binding = *iter;
expr.context = binding.bindingContext.object;
@@ -2720,18 +2723,13 @@ bool QDeclarativeCompiler::completeComponentBuild()
expr.expression = binding.expression;
expr.imports = unit->imports;
- if (qmlExperimental()) {
- int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine));
- if (index != -1) {
- qWarning() << "Accepted for optimization:" << qPrintable(expr.expression.asScript());
- binding.dataType = BindingReference::Experimental;
- binding.compiledIndex = index;
- componentStat.optimizedBindings++;
- continue;
- } else {
- qWarning() << "Rejected for optimization:" << qPrintable(expr.expression.asScript());
- }
- }
+ int index = bindingCompiler.compile(expr, QDeclarativeEnginePrivate::get(engine));
+ if (index != -1) {
+ binding.dataType = BindingReference::Experimental;
+ binding.compiledIndex = index;
+ componentStat.optimizedBindings++;
+ continue;
+ }
binding.dataType = BindingReference::QtScript;
@@ -2768,7 +2766,8 @@ bool QDeclarativeCompiler::completeComponentBuild()
if (bindingCompiler.isValid()) {
compileState.compiledBindingData = bindingCompiler.program();
- QDeclarativeBindingCompiler::dump(compileState.compiledBindingData);
+ if (bindingsDump())
+ QDeclarativeBindingCompiler::dump(compileState.compiledBindingData);
}
saveComponentState();
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index cca42e2..05b556e 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QDeclarativeComponent;
class QDeclarativeContext;
+class QDeclarativeContextData;
class QScriptProgram;
class Q_AUTOTEST_EXPORT QDeclarativeCompiledData : public QDeclarativeRefCount, public QDeclarativeCleanup
@@ -95,7 +96,7 @@ public:
QDeclarativeComponent *component;
QDeclarativeRefCount *ref;
- QObject *createInstance(QDeclarativeContext *, const QBitField &) const;
+ QObject *createInstance(QDeclarativeContextData *, const QBitField &) const;
const QMetaObject *metaObject() const;
};
QList<TypeReference> types;
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index d6bb216..a280d7e 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -404,23 +404,9 @@ QDeclarativeContext *QDeclarativeComponent::creationContext() const
{
Q_D(const QDeclarativeComponent);
if(d->creationContext)
- return d->creationContext;
- QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(this);
- if (ddata)
- return ddata->context;
- else
- return 0;
-}
+ return d->creationContext->asQDeclarativeContext();
-/*!
- \internal
- Sets the QDeclarativeContext the component was created in. This is only
- desirable for components created in QML script.
-*/
-void QDeclarativeComponent::setCreationContext(QDeclarativeContext* c)
-{
- Q_D(QDeclarativeComponent);
- d->creationContext = c;
+ return qmlContext(this);
}
/*!
@@ -512,7 +498,6 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q
{
}
-
/*!
\internal
A version of create which returns a scriptObject, for use in script
@@ -526,7 +511,9 @@ QScriptValue QDeclarativeComponent::createObject()
return QScriptValue();
}
QObject* ret = create(ctxt);
- return QDeclarativeEnginePrivate::qmlScriptObject(ret, d->engine);
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine);
+ QDeclarativeDeclarativeData::get(ret, true)->setImplicitDestructible();
+ return priv->objectClass->newQObject(ret, QMetaType::QObjectStar);
}
/*!
@@ -541,19 +528,19 @@ QObject *QDeclarativeComponent::create(QDeclarativeContext *context)
{
Q_D(QDeclarativeComponent);
- return d->create(context, QBitField());
+ if (!context)
+ context = d->engine->rootContext();
+
+ QObject *rv = beginCreate(context);
+ completeCreate();
+ return rv;
}
-QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context,
- const QBitField &bindings)
+QObject *QDeclarativeComponentPrivate::create(QDeclarativeContextData *context,
+ const QBitField &bindings)
{
if (!context)
- context = engine->rootContext();
-
- if (context->engine() != engine) {
- qWarning("QDeclarativeComponent::create(): Must create component in context from the same QDeclarativeEngine");
- return 0;
- }
+ context = QDeclarativeContextData::get(engine->rootContext());
QObject *rv = beginCreate(context, bindings);
completeCreate();
@@ -586,11 +573,17 @@ QObject *QDeclarativeComponentPrivate::create(QDeclarativeContext *context,
QObject *QDeclarativeComponent::beginCreate(QDeclarativeContext *context)
{
Q_D(QDeclarativeComponent);
- return d->beginCreate(context, QBitField());
+ QObject *rv = d->beginCreate(context?QDeclarativeContextData::get(context):0, QBitField());
+ if (rv) {
+ QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(rv);
+ Q_ASSERT(ddata);
+ ddata->indestructible = true;
+ }
+ return rv;
}
QObject *
-QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QBitField &bindings)
+QDeclarativeComponentPrivate::beginCreate(QDeclarativeContextData *context, const QBitField &bindings)
{
Q_Q(QDeclarativeComponent);
if (!context) {
@@ -598,7 +591,7 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB
return 0;
}
- if (context->engine() != engine) {
+ if (context->engine != engine) {
qWarning("QDeclarativeComponent::beginCreate(): Must create component in context from the same QDeclarativeEngine");
return 0;
}
@@ -615,29 +608,24 @@ QDeclarativeComponentPrivate::beginCreate(QDeclarativeContext *context, const QB
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeContextPrivate *contextPriv =
- static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context));
- QDeclarativeContext *ctxt = new QDeclarativeContext(context, 0, true);
- static_cast<QDeclarativeContextPrivate*>(ctxt->d_func())->url = cc->url;
- static_cast<QDeclarativeContextPrivate*>(ctxt->d_func())->imports = cc->importCache;
+ QDeclarativeContextData *ctxt = new QDeclarativeContextData;
+ ctxt->isInternal = true;
+ ctxt->url = cc->url;
+ ctxt->imports = cc->importCache;
cc->importCache->addref();
+ ctxt->setParent(context);
QObject *rv = begin(ctxt, ep, cc, start, count, &state, bindings);
- if (rv) {
- QDeclarative_setParent_noEvent(ctxt, rv);
- } else {
- delete ctxt;
- }
+ if (rv && !context->isInternal && ep->isDebugging)
+ context->asQDeclarativeContextPrivate()->instances.append(rv);
- if (rv && !contextPriv->isInternal && ep->isDebugging)
- contextPriv->instances.append(rv);
return rv;
}
-QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv,
- QDeclarativeCompiledData *component, int start, int count,
- ConstructionState *state, const QBitField &bindings)
+QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv,
+ QDeclarativeCompiledData *component, int start, int count,
+ ConstructionState *state, const QBitField &bindings)
{
bool isRoot = !enginePriv->inBeginCreate;
enginePriv->inBeginCreate = true;
@@ -667,8 +655,8 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContext *ctxt, QDeclar
return rv;
}
-void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContext *, QDeclarativeEnginePrivate *enginePriv,
- QObject *object, ConstructionState *state)
+void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeContextData *, QDeclarativeEnginePrivate *enginePriv,
+ QObject *object, ConstructionState *state)
{
bool isRoot = !enginePriv->inBeginCreate;
enginePriv->inBeginCreate = true;
diff --git a/src/declarative/qml/qdeclarativecomponent.h b/src/declarative/qml/qdeclarativecomponent.h
index aec0480..13a243e 100644
--- a/src/declarative/qml/qdeclarativecomponent.h
+++ b/src/declarative/qml/qdeclarativecomponent.h
@@ -104,7 +104,6 @@ public:
void loadUrl(const QUrl &url);
void setData(const QByteArray &, const QUrl &baseUrl);
- void setCreationContext(QDeclarativeContext*);
QDeclarativeContext *creationContext() const;
static QDeclarativeComponentAttached *qmlAttachedProperties(QObject *);
diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h
index 3155813..649fce5 100644
--- a/src/declarative/qml/qdeclarativecomponent_p.h
+++ b/src/declarative/qml/qdeclarativecomponent_p.h
@@ -81,8 +81,8 @@ class QDeclarativeComponentPrivate : public QObjectPrivate
public:
QDeclarativeComponentPrivate() : typeData(0), progress(0.), start(-1), count(-1), cc(0), engine(0), creationContext(0) {}
- QObject *create(QDeclarativeContext *context, const QBitField &);
- QObject *beginCreate(QDeclarativeContext *, const QBitField &);
+ QObject *create(QDeclarativeContextData *, const QBitField &);
+ QObject *beginCreate(QDeclarativeContextData *, const QBitField &);
void completeCreate();
QDeclarativeCompositeTypeData *typeData;
@@ -108,15 +108,15 @@ public:
};
ConstructionState state;
- static QObject *begin(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv,
+ static QObject *begin(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv,
QDeclarativeCompiledData *component, int start, int count,
ConstructionState *state, const QBitField &bindings = QBitField());
- static void beginDeferred(QDeclarativeContext *ctxt, QDeclarativeEnginePrivate *enginePriv,
+ static void beginDeferred(QDeclarativeContextData *ctxt, QDeclarativeEnginePrivate *enginePriv,
QObject *object, ConstructionState *state);
static void complete(QDeclarativeEnginePrivate *enginePriv, ConstructionState *state);
QDeclarativeEngine *engine;
- QDeclarativeContext *creationContext;
+ QDeclarativeContextData *creationContext;
void clear();
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager.cpp b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
index b90a598..e2a6e0c 100644
--- a/src/declarative/qml/qdeclarativecompositetypemanager.cpp
+++ b/src/declarative/qml/qdeclarativecompositetypemanager.cpp
@@ -154,7 +154,7 @@ QDeclarativeCompositeTypeData::TypeReference::TypeReference()
}
QDeclarativeCompositeTypeManager::QDeclarativeCompositeTypeManager(QDeclarativeEngine *e)
-: engine(e)
+: engine(e), redirectCount(0)
{
}
@@ -172,6 +172,10 @@ QDeclarativeCompositeTypeManager::~QDeclarativeCompositeTypeManager()
QDeclarativeCompositeTypeData *QDeclarativeCompositeTypeManager::get(const QUrl &url)
{
+ Redirects::Iterator redir = redirects.find(url);
+ if (redir != redirects.end())
+ return get(*redir);
+
QDeclarativeCompositeTypeData *unit = components.value(url);
if (!unit) {
@@ -219,6 +223,8 @@ void QDeclarativeCompositeTypeManager::clearCache()
}
}
+#define TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION 16
+
void QDeclarativeCompositeTypeManager::replyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
@@ -226,6 +232,26 @@ void QDeclarativeCompositeTypeManager::replyFinished()
QDeclarativeCompositeTypeData *unit = components.value(reply->url());
Q_ASSERT(unit);
+ redirectCount++;
+ if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = reply->url().resolved(redirect.toUrl());
+ redirects.insert(reply->url(),url);
+ unit->imports.setBaseUrl(url);
+ components.remove(reply->url());
+ components.insert(url, unit);
+ reply->deleteLater();
+ reply = engine->networkAccessManager()->get(QNetworkRequest(url));
+ QObject::connect(reply, SIGNAL(finished()),
+ this, SLOT(replyFinished()));
+ QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(requestProgress(qint64,qint64)));
+ return;
+ }
+ }
+ redirectCount = 0;
+
if (reply->error() != QNetworkReply::NoError) {
QString errorDescription;
// ### - Fill in error
@@ -256,6 +282,24 @@ void QDeclarativeCompositeTypeManager::resourceReplyFinished()
QDeclarativeCompositeTypeResource *resource = resources.value(reply->url());
Q_ASSERT(resource);
+ redirectCount++;
+ if (redirectCount < TYPEMANAGER_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = reply->url().resolved(redirect.toUrl());
+ redirects.insert(reply->url(),url);
+ resource->url = url.toString();
+ resources.remove(reply->url());
+ resources.insert(url, resource);
+ reply->deleteLater();
+ reply = engine->networkAccessManager()->get(QNetworkRequest(url));
+ QObject::connect(reply, SIGNAL(finished()),
+ this, SLOT(resourceReplyFinished()));
+ return;
+ }
+ }
+ redirectCount = 0;
+
if (reply->error() != QNetworkReply::NoError) {
resource->status = QDeclarativeCompositeTypeResource::Error;
@@ -462,17 +506,18 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData
int waiting = 0;
foreach (QDeclarativeScriptParser::Import imp, unit->data.imports()) {
- QString qmldir;
+ QString qmldircontentnetwork;
if (imp.type == QDeclarativeScriptParser::Import::File && imp.qualifier.isEmpty()) {
QString importUrl = unit->imports.baseUrl().resolved(QUrl(imp.uri + QLatin1String("/qmldir"))).toString();
for (int ii = 0; ii < unit->resources.count(); ++ii) {
if (unit->resources.at(ii)->url == importUrl) {
- qmldir = QString::fromUtf8(unit->resources.at(ii)->data);
+ qmldircontentnetwork = QString::fromUtf8(unit->resources.at(ii)->data);
break;
}
}
}
+
int vmaj = -1;
int vmin = -1;
if (!imp.version.isEmpty()) {
@@ -487,7 +532,7 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData
}
if (!QDeclarativeEnginePrivate::get(engine)->
- addToImport(&unit->imports, qmldir, imp.uri, imp.qualifier, vmaj, vmin, imp.type))
+ addToImport(&unit->imports, qmldircontentnetwork, imp.uri, imp.qualifier, vmaj, vmin, imp.type))
{
QDeclarativeError error;
error.setUrl(unit->imports.baseUrl());
@@ -546,6 +591,10 @@ int QDeclarativeCompositeTypeManager::resolveTypes(QDeclarativeCompositeTypeData
continue;
}
+ Redirects::Iterator redir = redirects.find(url);
+ if (redir != redirects.end())
+ url = *redir;
+
QDeclarativeCompositeTypeData *urlUnit = components.value(url);
if (!urlUnit) {
diff --git a/src/declarative/qml/qdeclarativecompositetypemanager_p.h b/src/declarative/qml/qdeclarativecompositetypemanager_p.h
index 03d16b8..a572e0c 100644
--- a/src/declarative/qml/qdeclarativecompositetypemanager_p.h
+++ b/src/declarative/qml/qdeclarativecompositetypemanager_p.h
@@ -109,6 +109,9 @@ private:
Components components;
typedef QHash<QUrl, QDeclarativeCompositeTypeResource *> Resources;
Resources resources;
+ typedef QHash<QUrl, QUrl> Redirects;
+ Redirects redirects;
+ int redirectCount;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index f70e143..60fc1d1 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -58,83 +58,13 @@
QT_BEGIN_NAMESPACE
QDeclarativeContextPrivate::QDeclarativeContextPrivate()
-: parent(0), engine(0), isInternal(false), propertyNames(0),
- notifyIndex(-1), highPriorityCount(0), imports(0), expressions(0), contextObjects(0),
- idValues(0), idValueCount(0), optimizedBindings(0)
+: data(0), notifyIndex(-1)
{
}
-void QDeclarativeContextPrivate::addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject)
-{
- Q_Q(QDeclarativeContext);
-
- if (!engine)
- return;
-
- QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
- QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
-
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
-
- scriptContext->pushScope(enginePriv->contextClass->newContext(q, scopeObject));
- scriptContext->pushScope(enginePriv->globalClass->globalObject());
-
- QScriptValue scope = scriptEngine->newObject();
- scriptContext->setActivationObject(scope);
- scriptContext->pushScope(scope);
-
- for (int ii = 0; ii < script.codes.count(); ++ii) {
- scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii));
-
- if (scriptEngine->hasUncaughtException()) {
- QDeclarativeError error;
- QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
- qWarning().nospace() << qPrintable(error.toString());
- }
- }
-
- scriptEngine->popContext();
-
- scripts.append(scope);
-}
-
-void QDeclarativeContextPrivate::destroyed(ContextGuard *guard)
-{
- Q_Q(QDeclarativeContext);
-
- // process of being deleted (which is *probably* why obj has been destroyed
- // anyway), as we're about to get deleted which will invalidate all the
- // expressions that could depend on us
- QObject *parent = q->parent();
- if (parent && QObjectPrivate::get(parent)->wasDeleted)
- return;
-
- while(guard->bindings) {
- QObject *o = guard->bindings->target;
- int mi = guard->bindings->methodIndex;
- guard->bindings->clear();
- if (o) o->qt_metacall(QMetaObject::InvokeMetaMethod, mi, 0);
- }
-
- for (int ii = 0; ii < idValueCount; ++ii) {
- if (&idValues[ii] == guard) {
- QMetaObject::activate(q, ii + notifyIndex, 0);
- return;
- }
- }
-}
-
-void QDeclarativeContextPrivate::init()
-{
- Q_Q(QDeclarativeContext);
-
- if (parent)
- parent->d_func()->childContexts.insert(q);
-}
-
/*!
\class QDeclarativeContext
- \since 4.7
+ \since 4.7
\brief The QDeclarativeContext class defines a context within a QML engine.
\mainclass
@@ -177,7 +107,7 @@ void QDeclarativeContextPrivate::init()
MyDataSet myDataSet;
QDeclarativeEngine engine;
QDeclarativeContext context(engine.rootContext());
- context.addDefaultObject(&myDataSet);
+ context.setContextObject(&myDataSet);
QDeclarativeComponent component(&engine, "ListView { model=myModel }");
component.create(&context);
@@ -221,8 +151,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *e, bool)
: QObject(*(new QDeclarativeContextPrivate))
{
Q_D(QDeclarativeContext);
- d->engine = e;
- d->init();
+ d->data = new QDeclarativeContextData(this);
+
+ d->data->engine = e;
}
/*!
@@ -233,10 +164,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeEngine *engine, QObject *pa
: QObject(*(new QDeclarativeContextPrivate), parent)
{
Q_D(QDeclarativeContext);
- QDeclarativeContext *parentContext = engine?engine->rootContext():0;
- d->parent = parentContext;
- d->engine = parentContext->engine();
- d->init();
+ d->data = new QDeclarativeContextData(this);
+
+ d->data->setParent(engine?QDeclarativeContextData::get(engine->rootContext()):0);
}
/*!
@@ -247,22 +177,19 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb
: QObject(*(new QDeclarativeContextPrivate), parent)
{
Q_D(QDeclarativeContext);
- d->parent = parentContext;
- d->engine = parentContext->engine();
- d->init();
+ d->data = new QDeclarativeContextData(this);
+
+ d->data->setParent(parentContext?QDeclarativeContextData::get(parentContext):0);
}
/*!
\internal
*/
-QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QObject *parent, bool)
-: QObject(*(new QDeclarativeContextPrivate), parent)
+QDeclarativeContext::QDeclarativeContext(QDeclarativeContextData *data)
+: QObject(*(new QDeclarativeContextPrivate), 0)
{
Q_D(QDeclarativeContext);
- d->parent = parentContext;
- d->engine = parentContext->engine();
- d->isInternal = true;
- d->init();
+ d->data = data;
}
/*!
@@ -275,78 +202,9 @@ QDeclarativeContext::QDeclarativeContext(QDeclarativeContext *parentContext, QOb
QDeclarativeContext::~QDeclarativeContext()
{
Q_D(QDeclarativeContext);
- if (d->parent)
- d->parent->d_func()->childContexts.remove(this);
-
- for (QSet<QDeclarativeContext *>::ConstIterator iter = d->childContexts.begin();
- iter != d->childContexts.end();
- ++iter) {
- (*iter)->d_func()->invalidateEngines();
- (*iter)->d_func()->parent = 0;
- }
-
- QDeclarativeAbstractExpression *expression = d->expressions;
- while (expression) {
- QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression;
-
- expression->m_context = 0;
- expression->m_prevExpression = 0;
- expression->m_nextExpression = 0;
-
- expression = nextExpression;
- }
- while (d->contextObjects) {
- QDeclarativeDeclarativeData *co = d->contextObjects;
- d->contextObjects = d->contextObjects->nextContextObject;
-
- co->context = 0;
- co->nextContextObject = 0;
- co->prevContextObject = 0;
- }
-
- if (d->propertyNames)
- d->propertyNames->release();
-
- if (d->imports)
- d->imports->release();
-
- if (d->optimizedBindings)
- d->optimizedBindings->release();
-
- delete [] d->idValues;
-}
-
-void QDeclarativeContextPrivate::invalidateEngines()
-{
- if (!engine)
- return;
- engine = 0;
- for (QSet<QDeclarativeContext *>::ConstIterator iter = childContexts.begin();
- iter != childContexts.end();
- ++iter) {
- (*iter)->d_func()->invalidateEngines();
- }
-}
-
-/*
-Refreshes all expressions that could possibly depend on this context.
-Refreshing flushes all context-tree dependent caches in the expressions, and should occur every
-time the context tree *structure* (not values) changes.
-*/
-void QDeclarativeContextPrivate::refreshExpressions()
-{
- for (QSet<QDeclarativeContext *>::ConstIterator iter = childContexts.begin();
- iter != childContexts.end();
- ++iter) {
- (*iter)->d_func()->refreshExpressions();
- }
-
- QDeclarativeAbstractExpression *expression = expressions;
- while (expression) {
- expression->refresh();
- expression = expression->m_nextExpression;
- }
+ if (!d->data->isInternal)
+ d->data->destroy();
}
/*!
@@ -356,7 +214,7 @@ void QDeclarativeContextPrivate::refreshExpressions()
QDeclarativeEngine *QDeclarativeContext::engine() const
{
Q_D(const QDeclarativeContext);
- return d->engine;
+ return d->data->engine;
}
/*!
@@ -366,17 +224,25 @@ QDeclarativeEngine *QDeclarativeContext::engine() const
QDeclarativeContext *QDeclarativeContext::parentContext() const
{
Q_D(const QDeclarativeContext);
- return d->parent;
+ return d->data->parent?d->data->parent->asQDeclarativeContext():0;
}
/*!
- Add \a defaultObject to this context. The object will be added after
- any existing default objects.
+ Return the context object, or 0 if there is no context object.
*/
-void QDeclarativeContext::addDefaultObject(QObject *defaultObject)
+QObject *QDeclarativeContext::contextObject() const
+{
+ Q_D(const QDeclarativeContext);
+ return d->data->contextObject;
+}
+
+/*!
+ Set the context \a object.
+*/
+void QDeclarativeContext::setContextObject(QObject *object)
{
Q_D(QDeclarativeContext);
- d->defaultObjects.prepend(defaultObject);
+ d->data->contextObject = object;
}
/*!
@@ -388,50 +254,31 @@ void QDeclarativeContext::setContextProperty(const QString &name, const QVariant
if (d->notifyIndex == -1)
d->notifyIndex = this->metaObject()->methodCount();
- if (d->engine) {
+ QDeclarativeContextData *data = d->data;
+
+ if (data->engine) {
bool ok;
- QObject *o = QDeclarativeEnginePrivate::get(d->engine)->toQObject(value, &ok);
+ QObject *o = QDeclarativeEnginePrivate::get(data->engine)->toQObject(value, &ok);
if (ok) {
setContextProperty(name, o);
return;
}
}
- if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine);
+ if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine);
- int idx = d->propertyNames->value(name);
+ int idx = data->propertyNames->value(name);
if (idx == -1) {
- d->propertyNames->add(name, d->idValueCount + d->propertyValues.count());
+ data->propertyNames->add(name, data->idValueCount + d->propertyValues.count());
d->propertyValues.append(value);
- d->refreshExpressions();
+ data->refreshExpressions();
} else {
d->propertyValues[idx] = value;
QMetaObject::activate(this, idx + d->notifyIndex, 0);
}
}
-void QDeclarativeContextPrivate::setIdProperty(int idx, QObject *obj)
-{
- if (notifyIndex == -1) {
- Q_Q(QDeclarativeContext);
- notifyIndex = q->metaObject()->methodCount();
- }
-
- idValues[idx].priv = this;
- idValues[idx] = obj;
-}
-
-void QDeclarativeContextPrivate::setIdPropertyData(QDeclarativeIntegerCache *data)
-{
- Q_ASSERT(!propertyNames);
- propertyNames = data;
- propertyNames->addref();
-
- idValueCount = data->count();
- idValues = new ContextGuard[idValueCount];
-}
-
/*!
Set the \a value of the \a name property on this context.
@@ -443,14 +290,16 @@ void QDeclarativeContext::setContextProperty(const QString &name, QObject *value
if (d->notifyIndex == -1)
d->notifyIndex = this->metaObject()->methodCount();
- if (!d->propertyNames) d->propertyNames = new QDeclarativeIntegerCache(d->engine);
- int idx = d->propertyNames->value(name);
+ QDeclarativeContextData *data = d->data;
+
+ if (!data->propertyNames) data->propertyNames = new QDeclarativeIntegerCache(data->engine);
+ int idx = data->propertyNames->value(name);
if (idx == -1) {
- d->propertyNames->add(name, d->idValueCount + d->propertyValues.count());
+ data->propertyNames->add(name, data->idValueCount + d->propertyValues.count());
d->propertyValues.append(QVariant::fromValue(value));
- d->refreshExpressions();
+ data->refreshExpressions();
} else {
d->propertyValues[idx] = QVariant::fromValue(value);
QMetaObject::activate(this, idx + d->notifyIndex, 0);
@@ -466,26 +315,27 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
Q_D(const QDeclarativeContext);
QVariant value;
int idx = -1;
- if (d->propertyNames)
- idx = d->propertyNames->value(name);
+
+ QDeclarativeContextData *data = d->data;
+
+ if (data->propertyNames)
+ idx = data->propertyNames->value(name);
if (idx == -1) {
QByteArray utf8Name = name.toUtf8();
- for (int ii = d->defaultObjects.count() - 1; ii >= 0; --ii) {
- QObject *obj = d->defaultObjects.at(ii);
+ if (data->contextObject) {
+ QObject *obj = data->contextObject;
QDeclarativePropertyCache::Data local;
- QDeclarativePropertyCache::Data *property = QDeclarativePropertyCache::property(d->engine, obj, name, local);
+ QDeclarativePropertyCache::Data *property =
+ QDeclarativePropertyCache::property(data->engine, obj, name, local);
- if (property) {
- value = obj->metaObject()->property(property->coreIndex).read(obj);
- break;
- }
+ if (property) value = obj->metaObject()->property(property->coreIndex).read(obj);
}
if (!value.isValid() && parentContext())
value = parentContext()->contextProperty(name);
} else {
if (idx >= d->propertyValues.count())
- value = QVariant::fromValue(d->idValues[idx - d->propertyValues.count()].data());
+ value = QVariant::fromValue(data->idValues[idx - d->propertyValues.count()].data());
else
value = d->propertyValues[idx];
}
@@ -502,20 +352,26 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
QUrl QDeclarativeContext::resolvedUrl(const QUrl &src)
{
Q_D(QDeclarativeContext);
- QDeclarativeContext *ctxt = this;
+ return d->data->resolvedUrl(src);
+}
+
+QUrl QDeclarativeContextData::resolvedUrl(const QUrl &src)
+{
+ QDeclarativeContextData *ctxt = this;
+
if (src.isRelative() && !src.isEmpty()) {
if (ctxt) {
while(ctxt) {
- if(ctxt->d_func()->url.isValid())
+ if(ctxt->url.isValid())
break;
else
- ctxt = ctxt->parentContext();
+ ctxt = ctxt->parent;
}
if (ctxt)
- return ctxt->d_func()->url.resolved(src);
- else if (d->engine)
- return d->engine->baseUrl().resolved(src);
+ return ctxt->url.resolved(src);
+ else if (engine)
+ return engine->baseUrl().resolved(src);
}
return QUrl();
} else {
@@ -523,6 +379,7 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src)
}
}
+
/*!
Explicitly sets the url resolvedUrl() will use for relative references to \a baseUrl.
@@ -533,7 +390,9 @@ QUrl QDeclarativeContext::resolvedUrl(const QUrl &src)
*/
void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl)
{
- d_func()->url = baseUrl;
+ Q_D(QDeclarativeContext);
+
+ d->data->url = baseUrl;
}
/*!
@@ -542,12 +401,13 @@ void QDeclarativeContext::setBaseUrl(const QUrl &baseUrl)
*/
QUrl QDeclarativeContext::baseUrl() const
{
- const QDeclarativeContext* p = this;
- while (p && p->d_func()->url.isEmpty()) {
- p = p->parentContext();
- }
- if (p)
- return p->d_func()->url;
+ Q_D(const QDeclarativeContext);
+ const QDeclarativeContextData* data = d->data;
+ while (data && data->url.isEmpty())
+ data = data->parent;
+
+ if (data)
+ return data->url;
else
return QUrl();
}
@@ -578,4 +438,215 @@ QObject *QDeclarativeContextPrivate::context_at(QDeclarativeListProperty<QObject
}
}
+
+QDeclarativeContextData::QDeclarativeContextData()
+: parent(0), engine(0), isInternal(false), publicContext(0), propertyNames(0), contextObject(0),
+ imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
+ contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0)
+{
+}
+
+QDeclarativeContextData::QDeclarativeContextData(QDeclarativeContext *ctxt)
+: parent(0), engine(0), isInternal(false), publicContext(ctxt), propertyNames(0), contextObject(0),
+ imports(0), childContexts(0), nextChild(0), prevChild(0), expressions(0), contextObjects(0),
+ contextGuards(0), idValues(0), idValueCount(0), optimizedBindings(0), linkedContext(0)
+{
+}
+
+void QDeclarativeContextData::destroy()
+{
+ if (linkedContext)
+ linkedContext->destroy();
+
+ if (prevChild) {
+ *prevChild = nextChild;
+ if (nextChild) nextChild->prevChild = prevChild;
+ nextChild = 0;
+ prevChild = 0;
+ }
+
+ QDeclarativeContextData *child = childContexts;
+ while (child) {
+ QDeclarativeContextData *next = child->nextChild;
+
+ child->invalidateEngines();
+ child->parent = 0;
+ child->nextChild = 0;
+ child->prevChild = 0;
+
+ child = next;
+ }
+ childContexts = 0;
+
+ QDeclarativeAbstractExpression *expression = expressions;
+ while (expression) {
+ QDeclarativeAbstractExpression *nextExpression = expression->m_nextExpression;
+
+ expression->m_context = 0;
+ expression->m_prevExpression = 0;
+ expression->m_nextExpression = 0;
+
+ expression = nextExpression;
+ }
+ expressions = 0;
+
+ while (contextObjects) {
+ QDeclarativeDeclarativeData *co = contextObjects;
+ contextObjects = contextObjects->nextContextObject;
+
+ co->context = 0;
+ co->outerContext = 0;
+ co->nextContextObject = 0;
+ co->prevContextObject = 0;
+ }
+
+ QDeclarativeGuardedContextData *contextGuard = contextGuards;
+ while (contextGuard) {
+ QDeclarativeGuardedContextData *next = contextGuard->m_next;
+ contextGuard->m_next = 0;
+ contextGuard->m_prev = 0;
+ contextGuard->m_contextData = 0;
+ contextGuard = next;
+ }
+ contextGuards = 0;
+
+ if (propertyNames)
+ propertyNames->release();
+
+ if (imports)
+ imports->release();
+
+ if (optimizedBindings)
+ optimizedBindings->release();
+
+ delete [] idValues;
+
+ if (isInternal)
+ delete publicContext;
+
+ delete this;
+}
+
+void QDeclarativeContextData::setParent(QDeclarativeContextData *p)
+{
+ if (p) {
+ parent = p;
+ engine = p->engine;
+ nextChild = p->childContexts;
+ if (nextChild) nextChild->prevChild = &nextChild;
+ prevChild = &p->childContexts;
+ p->childContexts = this;
+ }
+}
+
+void QDeclarativeContextData::invalidateEngines()
+{
+ if (!engine)
+ return;
+ engine = 0;
+
+ QDeclarativeContextData *child = childContexts;
+ while (child) {
+ child->invalidateEngines();
+ child = child->nextChild;
+ }
+}
+
+/*
+Refreshes all expressions that could possibly depend on this context. Refreshing flushes all
+context-tree dependent caches in the expressions, and should occur every time the context tree
+ *structure* (not values) changes.
+*/
+void QDeclarativeContextData::refreshExpressions()
+{
+ QDeclarativeContextData *child = childContexts;
+ while (child) {
+ child->refreshExpressions();
+ child = child->nextChild;
+ }
+
+ QDeclarativeAbstractExpression *expression = expressions;
+ while (expression) {
+ expression->refresh();
+ expression = expression->m_nextExpression;
+ }
+}
+
+void QDeclarativeContextData::addObject(QObject *o)
+{
+ QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(o, true);
+
+ Q_ASSERT(data->context == 0);
+
+ data->context = this;
+ data->outerContext = this;
+
+ data->nextContextObject = contextObjects;
+ if (data->nextContextObject)
+ data->nextContextObject->prevContextObject = &data->nextContextObject;
+ data->prevContextObject = &contextObjects;
+ contextObjects = data;
+}
+
+void QDeclarativeContextData::addScript(const QDeclarativeParser::Object::ScriptBlock &script,
+ QObject *scopeObject)
+{
+ if (!engine)
+ return;
+
+ QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+
+ QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
+
+ scriptContext->pushScope(enginePriv->contextClass->newContext(this, scopeObject));
+ scriptContext->pushScope(enginePriv->globalClass->globalObject());
+
+ QScriptValue scope = scriptEngine->newObject();
+ scriptContext->setActivationObject(scope);
+ scriptContext->pushScope(scope);
+
+ for (int ii = 0; ii < script.codes.count(); ++ii) {
+ scriptEngine->evaluate(script.codes.at(ii), script.files.at(ii), script.lineNumbers.at(ii));
+
+ if (scriptEngine->hasUncaughtException()) {
+ QDeclarativeError error;
+ QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
+ qWarning().nospace() << qPrintable(error.toString());
+ }
+ }
+
+ scriptEngine->popContext();
+
+ scripts.append(scope);
+}
+
+void QDeclarativeContextData::setIdProperty(int idx, QObject *obj)
+{
+ idValues[idx] = obj;
+ idValues[idx].context = this;
+}
+
+void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data)
+{
+ Q_ASSERT(!propertyNames);
+ propertyNames = data;
+ propertyNames->addref();
+
+ idValueCount = data->count();
+ idValues = new ContextGuard[idValueCount];
+}
+
+QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext()
+{
+ if (!publicContext)
+ publicContext = new QDeclarativeContext(this);
+ return publicContext;
+}
+
+QDeclarativeContextPrivate *QDeclarativeContextData::asQDeclarativeContextPrivate()
+{
+ return QDeclarativeContextPrivate::get(asQDeclarativeContext());
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h
index 0fb9bee..a349628 100644
--- a/src/declarative/qml/qdeclarativecontext.h
+++ b/src/declarative/qml/qdeclarativecontext.h
@@ -58,6 +58,7 @@ class QDeclarativeEngine;
class QDeclarativeRefCount;
class QDeclarativeContextPrivate;
class QDeclarativeCompositeTypeData;
+class QDeclarativeContextData;
class Q_DECLARATIVE_EXPORT QDeclarativeContext : public QObject
{
@@ -72,11 +73,12 @@ public:
QDeclarativeEngine *engine() const;
QDeclarativeContext *parentContext() const;
- void addDefaultObject(QObject *);
- void setContextProperty(const QString &, QObject *);
- void setContextProperty(const QString &, const QVariant &);
+ QObject *contextObject() const;
+ void setContextObject(QObject *);
QVariant contextProperty(const QString &) const;
+ void setContextProperty(const QString &, QObject *);
+ void setContextProperty(const QString &, const QVariant &);
QUrl resolvedUrl(const QUrl &);
@@ -95,7 +97,8 @@ private:
friend class QDeclarativeComponentPrivate;
friend class QDeclarativeScriptPrivate;
friend class QDeclarativeBoundSignalProxy;
- QDeclarativeContext(QDeclarativeContext *parent, QObject *objParent, bool);
+ friend class QDeclarativeContextData;
+ QDeclarativeContext(QDeclarativeContextData *);
QDeclarativeContext(QDeclarativeEngine *, bool);
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 8297280..d74aa33 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -56,9 +56,11 @@
#include "qdeclarativecontext.h"
#include "qdeclarativedeclarativedata_p.h"
-#include "qdeclarativeengine_p.h"
#include "qdeclarativeintegercache_p.h"
#include "qdeclarativetypenamecache_p.h"
+#include "qdeclarativenotifier_p.h"
+#include "qdeclarativelist.h"
+#include "qdeclarativeparser_p.h"
#include <QtCore/qhash.h>
#include <QtScript/qscriptvalue.h>
@@ -77,6 +79,7 @@ class QDeclarativeExpressionPrivate;
class QDeclarativeAbstractExpression;
class QDeclarativeBinding_Id;
class QDeclarativeCompiledBindings;
+class QDeclarativeContextData;
class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate
{
@@ -84,110 +87,182 @@ class Q_DECLARATIVE_EXPORT QDeclarativeContextPrivate : public QObjectPrivate
public:
QDeclarativeContextPrivate();
- QDeclarativeContext *parent;
+ QDeclarativeContextData *data;
+
+ QList<QVariant> propertyValues;
+ int notifyIndex;
+
+ static QDeclarativeContextPrivate *get(QDeclarativeContext *context) {
+ return static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context));
+ }
+ static QDeclarativeContext *get(QDeclarativeContextPrivate *context) {
+ return static_cast<QDeclarativeContext *>(context->q_func());
+ }
+
+ // Only used for debugging
+ QList<QPointer<QObject> > instances;
+
+ static int context_count(QDeclarativeListProperty<QObject> *);
+ static QObject *context_at(QDeclarativeListProperty<QObject> *, int);
+};
+
+class QDeclarativeGuardedContextData;
+class QDeclarativeContextData
+{
+public:
+ QDeclarativeContextData();
+ QDeclarativeContextData(QDeclarativeContext *);
+ void destroy();
+
+ // My parent context and engine
+ QDeclarativeContextData *parent;
QDeclarativeEngine *engine;
+ void setParent(QDeclarativeContextData *);
+ void invalidateEngines();
+ void refreshExpressions();
+
+ void addObject(QObject *);
+
+ QUrl resolvedUrl(const QUrl &);
+
+ // My containing QDeclarativeContext. If isInternal is true this owns publicContext.
+ // If internal is false publicContext owns this.
+ QDeclarativeContext *asQDeclarativeContext();
+ QDeclarativeContextPrivate *asQDeclarativeContextPrivate();
bool isInternal;
+ QDeclarativeContext *publicContext;
+ // Property name cache
QDeclarativeIntegerCache *propertyNames;
- QList<QVariant> propertyValues;
- int notifyIndex;
- QObjectList defaultObjects;
- int highPriorityCount;
+ // Context object
+ QObject *contextObject;
+ // Any script blocks that exist on this context
QList<QScriptValue> scripts;
- void addScript(const QDeclarativeParser::Object::ScriptBlock &, QObject *);
+ void addScript(const QDeclarativeParser::Object::ScriptBlock &script, QObject *scopeObject);
+ // Context base url
QUrl url;
+ // List of imports that apply to this context
QDeclarativeTypeNameCache *imports;
- void init();
+ // My children
+ QDeclarativeContextData *childContexts;
- void invalidateEngines();
- void refreshExpressions();
- QSet<QDeclarativeContext *> childContexts;
+ // My peers in parent's childContexts list
+ QDeclarativeContextData *nextChild;
+ QDeclarativeContextData **prevChild;
+ // Expressions that use this context
QDeclarativeAbstractExpression *expressions;
+ // Doubly-linked list of objects that are owned by this context
QDeclarativeDeclarativeData *contextObjects;
- struct IdNotifier
- {
- inline IdNotifier();
- inline ~IdNotifier();
-
- inline void clear();
-
- IdNotifier *next;
- IdNotifier**prev;
- QObject *target;
- int methodIndex;
- };
+ // Doubly-linked list of context guards (XXX merge with contextObjects)
+ QDeclarativeGuardedContextData *contextGuards;
+ // id guards
struct ContextGuard : public QDeclarativeGuard<QObject>
{
- inline ContextGuard();
- inline ContextGuard &operator=(QObject *obj);
- inline virtual void objectDestroyed(QObject *);
-
- QDeclarativeContextPrivate *priv;
- IdNotifier *bindings;
+ ContextGuard() : context(0) {}
+ inline ContextGuard &operator=(QObject *obj)
+ { QDeclarativeGuard<QObject>::operator=(obj); return *this; }
+ virtual void objectDestroyed(QObject *) {
+ if (!QObjectPrivate::get(context->contextObject)->wasDeleted) bindings.notify();
+ }
+ QDeclarativeContextData *context;
+ QDeclarativeNotifier bindings;
};
ContextGuard *idValues;
int idValueCount;
void setIdProperty(int, QObject *);
void setIdPropertyData(QDeclarativeIntegerCache *);
- void destroyed(ContextGuard *);
- static QDeclarativeContextPrivate *get(QDeclarativeContext *context) {
- return static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(context));
- }
- static QDeclarativeContext *get(QDeclarativeContextPrivate *context) {
- return static_cast<QDeclarativeContext *>(context->q_func());
+ // Optimized binding pointer
+ QDeclarativeCompiledBindings *optimizedBindings;
+
+ // Linked contexts. this owns linkedContext.
+ QDeclarativeContextData *linkedContext;
+
+ static QDeclarativeContextData *get(QDeclarativeContext *context) {
+ return QDeclarativeContextPrivate::get(context)->data;
}
- QDeclarativeCompiledBindings *optimizedBindings;
+private:
+ ~QDeclarativeContextData() {}
+};
- // Only used for debugging
- QList<QPointer<QObject> > instances;
+class QDeclarativeGuardedContextData
+{
+public:
+ inline QDeclarativeGuardedContextData();
+ inline QDeclarativeGuardedContextData(QDeclarativeContextData *);
+ inline ~QDeclarativeGuardedContextData();
- static int context_count(QDeclarativeListProperty<QObject> *);
- static QObject *context_at(QDeclarativeListProperty<QObject> *, int);
+ inline void setContextData(QDeclarativeContextData *);
+
+ inline QDeclarativeContextData *contextData();
+
+ inline operator QDeclarativeContextData*() const { return m_contextData; }
+ inline QDeclarativeContextData* operator->() const { return m_contextData; }
+
+private:
+ friend class QDeclarativeContextData;
+
+ inline void clear();
+
+ QDeclarativeContextData *m_contextData;
+ QDeclarativeGuardedContextData *m_next;
+ QDeclarativeGuardedContextData **m_prev;
};
-QDeclarativeContextPrivate::IdNotifier::IdNotifier()
-: next(0), prev(0), target(0), methodIndex(-1)
+QDeclarativeGuardedContextData::QDeclarativeGuardedContextData()
+: m_contextData(0), m_next(0), m_prev(0)
{
}
-QDeclarativeContextPrivate::IdNotifier::~IdNotifier()
+QDeclarativeGuardedContextData::QDeclarativeGuardedContextData(QDeclarativeContextData *data)
+: m_contextData(0), m_next(0), m_prev(0)
{
- clear();
+ setContextData(data);
}
-void QDeclarativeContextPrivate::IdNotifier::clear()
+QDeclarativeGuardedContextData::~QDeclarativeGuardedContextData()
{
- if (next) next->prev = prev;
- if (prev) *prev = next;
- next = 0; prev = 0; target = 0;
- methodIndex = -1;
+ clear();
}
-QDeclarativeContextPrivate::ContextGuard::ContextGuard()
-: priv(0), bindings(0)
+void QDeclarativeGuardedContextData::setContextData(QDeclarativeContextData *contextData)
{
+ clear();
+
+ if (contextData) {
+ m_contextData = contextData;
+ m_next = contextData->contextGuards;
+ if (m_next) m_next->m_prev = &m_next;
+ m_prev = &contextData->contextGuards;
+ contextData->contextGuards = this;
+ }
}
-QDeclarativeContextPrivate::ContextGuard &QDeclarativeContextPrivate::ContextGuard::operator=(QObject *obj)
+QDeclarativeContextData *QDeclarativeGuardedContextData::contextData()
{
- (QDeclarativeGuard<QObject>&)*this = obj; return *this;
+ return m_contextData;
}
-void QDeclarativeContextPrivate::ContextGuard::objectDestroyed(QObject *)
-{
- priv->destroyed(this);
+void QDeclarativeGuardedContextData::clear()
+{
+ if (m_prev) {
+ *m_prev = m_next;
+ if (m_next) m_next->m_prev = m_prev;
+ m_contextData = 0;
+ m_next = 0;
+ m_prev = 0;
+ }
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontextscriptclass.cpp b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
index 5fcf4e2..847d632 100644
--- a/src/declarative/qml/qdeclarativecontextscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativecontextscriptclass.cpp
@@ -51,17 +51,17 @@ QT_BEGIN_NAMESPACE
struct ContextData : public QScriptDeclarativeClass::Object {
ContextData() : overrideObject(0), isSharedContext(true) {}
- ContextData(QDeclarativeContext *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {}
- QDeclarativeGuard<QDeclarativeContext> context;
+ ContextData(QDeclarativeContextData *c, QObject *o) : context(c), scopeObject(o), overrideObject(0), isSharedContext(false) {}
+ QDeclarativeGuardedContextData context;
QDeclarativeGuard<QObject> scopeObject;
QObject *overrideObject;
bool isSharedContext;
- QDeclarativeContext *getContext(QDeclarativeEngine *engine) {
+ QDeclarativeContextData *getContext(QDeclarativeEngine *engine) {
if (isSharedContext) {
return QDeclarativeEnginePrivate::get(engine)->sharedContext;
} else {
- return context.data();
+ return context.contextData();
}
}
@@ -80,7 +80,7 @@ struct ContextData : public QScriptDeclarativeClass::Object {
*/
QDeclarativeContextScriptClass::QDeclarativeContextScriptClass(QDeclarativeEngine *bindEngine)
: QDeclarativeScriptClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)), engine(bindEngine),
- lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1), lastDefaultObject(-1)
+ lastScopeObject(0), lastContext(0), lastData(0), lastPropertyIndex(-1)
{
}
@@ -88,7 +88,7 @@ QDeclarativeContextScriptClass::~QDeclarativeContextScriptClass()
{
}
-QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContext *context, QObject *scopeObject)
+QScriptValue QDeclarativeContextScriptClass::newContext(QDeclarativeContextData *context, QObject *scopeObject)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -102,7 +102,7 @@ QScriptValue QDeclarativeContextScriptClass::newSharedContext()
return newObject(scriptEngine, this, new ContextData());
}
-QDeclarativeContext *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v)
+QDeclarativeContextData *QDeclarativeContextScriptClass::contextFromValue(const QScriptValue &v)
{
if (scriptClass(v) != this)
return 0;
@@ -132,9 +132,8 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier &
lastContext = 0;
lastData = 0;
lastPropertyIndex = -1;
- lastDefaultObject = -1;
- QDeclarativeContext *bindContext = ((ContextData *)object)->getContext(engine);
+ QDeclarativeContextData *bindContext = ((ContextData *)object)->getContext(engine);
QObject *scopeObject = ((ContextData *)object)->getScope(engine);
if (!bindContext)
return 0;
@@ -160,29 +159,28 @@ QDeclarativeContextScriptClass::queryProperty(Object *object, const Identifier &
scopeObject = 0; // Only applies to the first context
includeTypes = false; // Only applies to the first context
if (rv) return rv;
- bindContext = bindContext->parentContext();
+ bindContext = bindContext->parent;
}
return 0;
}
QScriptClass::QueryFlags
-QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext, QObject *scopeObject,
- const Identifier &name,
- QScriptClass::QueryFlags flags,
- bool includeTypes)
+QDeclarativeContextScriptClass::queryProperty(QDeclarativeContextData *bindContext, QObject *scopeObject,
+ const Identifier &name,
+ QScriptClass::QueryFlags flags,
+ bool includeTypes)
{
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext);
- lastPropertyIndex = cp->propertyNames?cp->propertyNames->value(name):-1;
+ lastPropertyIndex = bindContext->propertyNames?bindContext->propertyNames->value(name):-1;
if (lastPropertyIndex != -1) {
lastContext = bindContext;
return QScriptClass::HandlesReadAccess;
}
- if (includeTypes && cp->imports) {
- QDeclarativeTypeNameCache::Data *data = cp->imports->data(name);
+ if (includeTypes && bindContext->imports) {
+ QDeclarativeTypeNameCache::Data *data = bindContext->imports->data(name);
if (data) {
lastData = data;
@@ -191,8 +189,8 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext,
}
}
- for (int ii = 0; ii < cp->scripts.count(); ++ii) {
- lastFunction = QScriptDeclarativeClass::function(cp->scripts.at(ii), name);
+ for (int ii = 0; ii < bindContext->scripts.count(); ++ii) {
+ lastFunction = QScriptDeclarativeClass::function(bindContext->scripts.at(ii), name);
if (lastFunction.isValid()) {
lastContext = bindContext;
return QScriptClass::HandlesReadAccess;
@@ -210,13 +208,13 @@ QDeclarativeContextScriptClass::queryProperty(QDeclarativeContext *bindContext,
}
}
- for (int ii = cp->defaultObjects.count() - 1; ii >= 0; --ii) {
+ if (bindContext->contextObject) {
QScriptClass::QueryFlags rv =
- ep->objectClass->queryProperty(cp->defaultObjects.at(ii), name, flags, bindContext,
+ ep->objectClass->queryProperty(bindContext->contextObject, name, flags, bindContext,
QDeclarativeObjectScriptClass::ImplicitObject | QDeclarativeObjectScriptClass::SkipAttachedProperties);
if (rv) {
- lastDefaultObject = ii;
+ lastScopeObject = bindContext->contextObject;
lastContext = bindContext;
return rv;
}
@@ -230,11 +228,10 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name)
{
Q_UNUSED(object);
- QDeclarativeContext *bindContext = lastContext;
+ QDeclarativeContextData *bindContext = lastContext;
Q_ASSERT(bindContext);
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
if (lastScopeObject) {
@@ -244,33 +241,33 @@ QDeclarativeContextScriptClass::property(Object *object, const Identifier &name)
} else if (lastData) {
if (lastData->type)
- return Value(scriptEngine, ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->type));
+ return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->type));
else
- return Value(scriptEngine, ep->typeNameClass->newObject(cp->defaultObjects.at(0), lastData->typeNamespace));
+ return Value(scriptEngine, ep->typeNameClass->newObject(bindContext->contextObject, lastData->typeNamespace));
} else if (lastPropertyIndex != -1) {
QScriptValue rv;
- if (lastPropertyIndex < cp->idValueCount) {
- rv = ep->objectClass->newQObject(cp->idValues[lastPropertyIndex].data());
+ if (lastPropertyIndex < bindContext->idValueCount) {
+ rv = ep->objectClass->newQObject(bindContext->idValues[lastPropertyIndex].data());
+
+ if (ep->captureProperties)
+ ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(&bindContext->idValues[lastPropertyIndex].bindings);
} else {
+ QDeclarativeContextPrivate *cp = bindContext->asQDeclarativeContextPrivate();
const QVariant &value = cp->propertyValues.at(lastPropertyIndex);
if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
- rv = ep->listClass->newList(QDeclarativeListProperty<QObject>(bindContext, (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId<QDeclarativeListProperty<QObject> >());
+ rv = ep->listClass->newList(QDeclarativeListProperty<QObject>(bindContext->asQDeclarativeContext(), (void*)lastPropertyIndex, 0, QDeclarativeContextPrivate::context_count, QDeclarativeContextPrivate::context_at), qMetaTypeId<QDeclarativeListProperty<QObject> >());
} else {
rv = ep->scriptValueFromVariant(value);
}
- }
- if (ep->captureProperties)
- ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext, -1, lastPropertyIndex + cp->notifyIndex);
+ if (ep->captureProperties)
+ ep->capturedProperties << QDeclarativeEnginePrivate::CapturedProperty(bindContext->asQDeclarativeContext(), -1, lastPropertyIndex + cp->notifyIndex);
+ }
return Value(scriptEngine, rv);
- } else if(lastDefaultObject != -1) {
-
- // Default object property
- return ep->objectClass->property(cp->defaultObjects.at(lastDefaultObject), name);
} else {
@@ -283,20 +280,14 @@ void QDeclarativeContextScriptClass::setProperty(Object *object, const Identifie
const QScriptValue &value)
{
Q_UNUSED(object);
- Q_ASSERT(lastScopeObject || lastDefaultObject != -1);
+ Q_ASSERT(lastScopeObject);
- QDeclarativeContext *bindContext = lastContext;
+ QDeclarativeContextData *bindContext = lastContext;
Q_ASSERT(bindContext);
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(bindContext);
- if (lastScopeObject) {
- ep->objectClass->setProperty(lastScopeObject, name, value, bindContext);
- } else {
- ep->objectClass->setProperty(cp->defaultObjects.at(lastDefaultObject), name, value,
- bindContext);
- }
+ ep->objectClass->setProperty(lastScopeObject, name, value, bindContext);
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontextscriptclass_p.h b/src/declarative/qml/qdeclarativecontextscriptclass_p.h
index 4b0dca0..93e4b20 100644
--- a/src/declarative/qml/qdeclarativecontextscriptclass_p.h
+++ b/src/declarative/qml/qdeclarativecontextscriptclass_p.h
@@ -60,16 +60,17 @@ QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QDeclarativeContext;
+class QDeclarativeContextData;
class QDeclarativeContextScriptClass : public QDeclarativeScriptClass
{
public:
QDeclarativeContextScriptClass(QDeclarativeEngine *);
~QDeclarativeContextScriptClass();
- QScriptValue newContext(QDeclarativeContext *, QObject * = 0);
+ QScriptValue newContext(QDeclarativeContextData *, QObject * = 0);
QScriptValue newSharedContext();
- QDeclarativeContext *contextFromValue(const QScriptValue &);
+ QDeclarativeContextData *contextFromValue(const QScriptValue &);
QObject *setOverrideObject(QScriptValue &, QObject *);
protected:
@@ -79,7 +80,7 @@ protected:
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &);
private:
- QScriptClass::QueryFlags queryProperty(QDeclarativeContext *, QObject *scopeObject,
+ QScriptClass::QueryFlags queryProperty(QDeclarativeContextData *, QObject *scopeObject,
const Identifier &,
QScriptClass::QueryFlags flags,
bool includeTypes);
@@ -87,10 +88,9 @@ private:
QDeclarativeEngine *engine;
QObject *lastScopeObject;
- QDeclarativeContext *lastContext;
+ QDeclarativeContextData *lastContext;
QDeclarativeTypeNameCache::Data *lastData;
int lastPropertyIndex;
- int lastDefaultObject;
QScriptValue lastFunction;
uint m_id;
diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h
index 99587a8..39bd43c 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p.h
@@ -128,9 +128,10 @@ private:
QList<QDeclarativeError> exceptions;
};
+#if 0
#define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \
qmlRegisterCustomType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN, #NAME, #TYPE, new CUSTOMTYPE)
-
+#endif
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativedeclarativedata_p.h b/src/declarative/qml/qdeclarativedeclarativedata_p.h
index ae40130..d1d063a 100644
--- a/src/declarative/qml/qdeclarativedeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedeclarativedata_p.h
@@ -63,18 +63,32 @@ class QDeclarativeCompiledData;
class QDeclarativeAbstractBinding;
class QDeclarativeContext;
class QDeclarativePropertyCache;
+class QDeclarativeContextData;
class Q_AUTOTEST_EXPORT QDeclarativeDeclarativeData : public QDeclarativeData
{
public:
- QDeclarativeDeclarativeData(QDeclarativeContext *ctxt = 0)
- : context(ctxt), bindings(0), nextContextObject(0), prevContextObject(0),
- bindingBitsSize(0), bindingBits(0), outerContext(0), lineNumber(0),
- columnNumber(0), deferredComponent(0), deferredIdx(0), attachedProperties(0),
- propertyCache(0), guards(0) {}
+ QDeclarativeDeclarativeData()
+ : ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false),
+ context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0),
+ bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0),
+ attachedProperties(0), propertyCache(0), guards(0) {}
virtual void destroyed(QObject *);
+ virtual void parentChanged(QObject *, QObject *);
+
+ void setImplicitDestructible() {
+ if (!explicitIndestructibleSet) indestructible = false;
+ }
+
+ quint32 ownMemory:1;
+ quint32 ownContext:1;
+ quint32 indestructible:1;
+ quint32 explicitIndestructibleSet:1;
+ quint32 dummy:28;
+
+ QDeclarativeContextData *context;
+ QDeclarativeContextData *outerContext;
- QDeclarativeContext *context;
QDeclarativeAbstractBinding *bindings;
// Linked list for QDeclarativeContext::contextObjects
@@ -87,7 +101,6 @@ public:
void clearBindingBit(int);
void setBindingBit(QObject *obj, int);
- QDeclarativeContext *outerContext; // Can't this be found from context?
ushort lineNumber;
ushort columnNumber;
diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp
index e730b92..b6d2115 100644
--- a/src/declarative/qml/qdeclarativedirparser.cpp
+++ b/src/declarative/qml/qdeclarativedirparser.cpp
@@ -151,13 +151,16 @@ bool QDeclarativeDirParser::parse()
_plugins.append(entry);
+ } else if (sectionCount == 2) {
+ // No version specified (should only be used for relative qmldir files)
+ const Component entry(sections[0], sections[1], -1, -1);
+ _components.append(entry);
} else if (sectionCount == 3) {
const QString &version = sections[1];
const int dotIndex = version.indexOf(QLatin1Char('.'));
if (dotIndex == -1) {
qWarning() << "expected '.'"; // ### use reportError
-
} else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) {
qWarning() << "unexpected '.'"; // ### use reportError
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index c23b17c..7c21ab8 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -146,12 +146,11 @@ static bool qt_QmlQtModule_registered = false;
void QDeclarativeEnginePrivate::defineModule()
{
- QML_REGISTER_TYPE(Qt,4,6,Component,QDeclarativeComponent);
- QML_REGISTER_TYPE(Qt,4,6,QtObject,QObject);
- QML_REGISTER_TYPE(Qt,4,6,WorkerScript,QDeclarativeWorkerScript);
- QML_REGISTER_TYPE(Qt,4,6,WorkerListModel,QDeclarativeWorkerListModel);
+ qmlRegisterType<QDeclarativeComponent>("Qt",4,6,"Component");
+ qmlRegisterType<QObject>("Qt",4,6,"QtObject");
+ qmlRegisterType<QDeclarativeWorkerScript>("Qt",4,6,"WorkerScript");
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeBinding);
+ qmlRegisterType<QDeclarativeBinding>();
}
QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
@@ -190,7 +189,7 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
{
if (p) {
- QDeclarativeContext *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context);
+ QDeclarativeContextData *ctxt = QDeclarativeEnginePrivate::get(this)->getContext(context);
Q_ASSERT(ctxt);
return ctxt->resolvedUrl(url);
}
@@ -243,7 +242,6 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr
qtObject.setProperty(QLatin1String("formatDateTime"),newFunction(QDeclarativeEnginePrivate::formatDateTime, 2));
//misc methods
- qtObject.setProperty(QLatin1String("closestAngle"), newFunction(QDeclarativeEnginePrivate::closestAngle, 2));
qtObject.setProperty(QLatin1String("openUrlExternally"),newFunction(QDeclarativeEnginePrivate::desktopOpenUrl, 1));
qtObject.setProperty(QLatin1String("md5"),newFunction(QDeclarativeEnginePrivate::md5, 1));
qtObject.setProperty(QLatin1String("btoa"),newFunction(QDeclarativeEnginePrivate::btoa, 1));
@@ -637,9 +635,9 @@ QDeclarativeContext *QDeclarativeEngine::contextForObject(const QObject *object)
if (!data)
return 0;
else if (data->outerContext)
- return data->outerContext;
+ return data->outerContext->asQDeclarativeContext();
else
- return data->context;
+ return 0;
}
/*!
@@ -660,12 +658,63 @@ void QDeclarativeEngine::setContextForObject(QObject *object, QDeclarativeContex
return;
}
- data->context = context;
- data->nextContextObject = context->d_func()->contextObjects;
- if (data->nextContextObject)
- data->nextContextObject->prevContextObject = &data->nextContextObject;
- data->prevContextObject = &context->d_func()->contextObjects;
- context->d_func()->contextObjects = data;
+ QDeclarativeContextData *contextData = QDeclarativeContextData::get(context);
+ contextData->addObject(object);
+}
+
+/*!
+\enum QDeclarativeEngine::ObjectOwnership
+
+Ownership controls whether or not QML automatically destroys the QObject when the object
+is garbage collected by the JavaScript engine. The two ownership options are:
+
+\list
+\o CppOwnership - The object is owned by C++ code, and will never be deleted by QML. The
+JavaScript destroy() method cannot be used on objects with CppOwnership. This option
+is similar to QScriptEngine::QtOwnership.
+
+\o JavaScriptOwnership - The object is owned by JavaScript. When the object is returned to QML
+as the return value of a method call or property access, QML will delete the object if there
+are no remaining JavaScript references to it and it has no QObject::parent(). This option
+is similar to QScriptEngine::ScriptOwnership.
+\endlist
+
+Generally an application doesn't need to set an object's ownership explicitly. QML uses
+a heuristic to set the default object ownership. By default, an object that is created by
+QML has JavaScriptOwnership. The exception to this are the root objects created by calling
+QDeclarativeCompnent::create() or QDeclarativeComponent::beginCreate() which have
+CppOwnership by default. The ownership of these root-level objects is considered to have
+been transfered to the C++ caller.
+
+Objects not-created by QML have CppOwnership by default. The exception to this is objects
+returned from a C++ method call. The ownership of these objects is passed to JavaScript.
+
+Calling setObjectOwnership() overrides the default ownership heuristic used by QML.
+*/
+
+/*!
+Sets the \a ownership of \a object.
+*/
+void QDeclarativeEngine::setObjectOwnership(QObject *object, ObjectOwnership ownership)
+{
+ QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true);
+ if (!ddata)
+ return;
+
+ ddata->indestructible = (ownership == CppOwnership)?true:false;
+ ddata->explicitIndestructibleSet = true;
+}
+
+/*!
+Returns the ownership of \a object.
+*/
+QDeclarativeEngine::ObjectOwnership QDeclarativeEngine::objectOwnership(QObject *object)
+{
+ QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, false);
+ if (!ddata)
+ return CppOwnership;
+ else
+ return ddata->indestructible?CppOwnership:JavaScriptOwnership;
}
void qmlExecuteDeferred(QObject *object)
@@ -674,7 +723,7 @@ void qmlExecuteDeferred(QObject *object)
if (data && data->deferredComponent) {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine());
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
QDeclarativeComponentPrivate::ConstructionState state;
QDeclarativeComponentPrivate::beginDeferred(data->context, ep, object, &state);
@@ -775,7 +824,18 @@ void QDeclarativeDeclarativeData::destroyed(QObject *object)
g->objectDestroyed(object);
}
- delete this;
+ if (ownContext)
+ context->destroy();
+
+ if (ownMemory)
+ delete this;
+ else
+ this->~QDeclarativeDeclarativeData();
+}
+
+void QDeclarativeDeclarativeData::parentChanged(QObject *, QObject *parent)
+{
+ if (!parent && scriptValue.isValid()) scriptValue = QScriptValue();
}
bool QDeclarativeDeclarativeData::hasBindingBit(int bit) const
@@ -832,7 +892,7 @@ QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
/*!
Returns the QDeclarativeContext for the executing QScript \a ctxt.
*/
-QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
+QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
{
QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
Q_ASSERT(scopeNode.isValid());
@@ -840,15 +900,15 @@ QDeclarativeContext *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
return contextClass->contextFromValue(scopeNode);
}
-QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt,
- QScriptEngine *engine)
+QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
{
QDeclarativeEnginePrivate *activeEnginePriv =
static_cast<QDeclarativeScriptEngine*>(engine)->p;
QDeclarativeEngine* activeEngine = activeEnginePriv->q_func();
- QDeclarativeContext* context = activeEnginePriv->getContext(ctxt);
+ QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
Q_ASSERT(context);
+
if(ctxt->argumentCount() != 1) {
return engine->nullValue();
}else{
@@ -857,7 +917,8 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt,
return engine->nullValue();
QUrl url = QUrl(context->resolvedUrl(QUrl(arg)));
QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine);
- c->setCreationContext(context);
+ QDeclarativeComponentPrivate::get(c)->creationContext = context;
+ QDeclarativeDeclarativeData::get(c, true)->setImplicitDestructible();
return activeEnginePriv->objectClass->newQObject(c, qMetaTypeId<QDeclarativeComponent*>());
}
}
@@ -871,7 +932,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
if(ctxt->argumentCount() < 2 || ctxt->argumentCount() > 3)
return engine->nullValue();
- QDeclarativeContext* context = activeEnginePriv->getContext(ctxt);
+ QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt);
Q_ASSERT(context);
QString qml = ctxt->argument(0).toString();
@@ -909,7 +970,7 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
return engine->nullValue();
}
- QObject *obj = component.create(context);
+ QObject *obj = component.create(context->asQDeclarativeContext());
if(component.isError()) {
QList<QDeclarativeError> errors = component.errors();
@@ -928,7 +989,8 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
if(gobj && gparent)
gobj->setParentItem(gparent);
- return qmlScriptObject(obj, activeEngine);
+ QDeclarativeDeclarativeData::get(obj, true)->setImplicitDestructible();
+ return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
}
QScriptValue QDeclarativeEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engine)
@@ -1177,25 +1239,6 @@ QScriptValue QDeclarativeEnginePrivate::quit(QScriptContext * /*ctxt*/, QScriptE
return QScriptValue();
}
-QScriptValue QDeclarativeEnginePrivate::closestAngle(QScriptContext *ctxt, QScriptEngine *e)
-{
- if(ctxt->argumentCount() < 2)
- return e->newVariant(QVariant(0.0));
- qreal a = ctxt->argument(0).toNumber();
- qreal b = ctxt->argument(1).toNumber();
- qreal ret = b;
- qreal diff = b-a;
- while(diff > 180.0){
- ret -= 360.0;
- diff -= 360.0;
- }
- while(diff < -180.0){
- ret += 360.0;
- diff += 360.0;
- }
- return e->newVariant(QVariant(ret));
-}
-
QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine *engine)
{
if(ctxt->argumentCount() != 2)
@@ -1301,10 +1344,13 @@ QVariant QDeclarativeScriptClass::toVariant(QDeclarativeEngine *engine, const QS
// XXX this beyonds in QUrl::toLocalFile()
static QString toLocalFileOrQrc(const QUrl& url)
{
- QString r = url.toLocalFile();
- if (r.isEmpty() && url.scheme() == QLatin1String("qrc"))
- r = QLatin1Char(':') + url.path();
- return r;
+ if (url.scheme() == QLatin1String("qrc")) {
+ if (url.authority().isEmpty())
+ return QLatin1Char(':') + url.path();
+ qWarning() << "Invalid url:" << url.toString() << "authority" << url.authority() << "not known.";
+ return QString();
+ }
+ return url.toLocalFile();
}
/////////////////////////////////////////////////////////////
@@ -1316,7 +1362,7 @@ struct QDeclarativeEnginePrivate::ImportedNamespace {
QList<bool> isLibrary;
QList<QString> qmlDirContent;
- bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) const
+ bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return)
{
for (int i=0; i<urls.count(); ++i) {
int vmaj = majversions.at(i);
@@ -1326,14 +1372,10 @@ struct QDeclarativeEnginePrivate::ImportedNamespace {
qt += '/';
qt += type;
- if (qmlImportTrace())
- qDebug() << "Look in" << qt;
QDeclarativeType *t = QDeclarativeMetaType::qmlType(qt,vmaj,vmin);
if (t) {
if (vmajor) *vmajor = vmaj;
if (vminor) *vminor = vmin;
- if (qmlImportTrace())
- qDebug() << "Found" << qt;
if (type_return)
*type_return = t;
return true;
@@ -1341,14 +1383,8 @@ struct QDeclarativeEnginePrivate::ImportedNamespace {
QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
QString qmldircontent = qmlDirContent.at(i);
- if (vmaj>=0 || !qmldircontent.isEmpty()) {
- // Check version file - XXX cache these in QDeclarativeEngine!
- if (qmldircontent.isEmpty()) {
- QFile qmldir(toLocalFileOrQrc(QUrl(urls.at(i)+QLatin1String("/qmldir"))));
- if (qmldir.open(QIODevice::ReadOnly)) {
- qmldircontent = QString::fromUtf8(qmldir.readAll());
- }
- }
+
+ if (!qmldircontent.isEmpty()) {
const QString typeName = QString::fromUtf8(type);
@@ -1362,7 +1398,6 @@ struct QDeclarativeEnginePrivate::ImportedNamespace {
if (c.typeName == typeName) {
if (url_return)
*url_return = url.resolved(QUrl(c.fileName));
-
return true;
}
}
@@ -1396,8 +1431,89 @@ public:
QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
- bool add(const QUrl& base, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QStringList& importPath, QDeclarativeEngine *engine)
+ QString importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeEngine *engine) {
+ QFile file(absoluteFilePath);
+ QString dir = QFileInfo(file).path();
+ QString qmldircontent;
+ if (file.open(QFile::ReadOnly)) {
+ qmldircontent = QString::fromUtf8(file.readAll());
+ if (qmlImportTrace())
+ qDebug() << "QDeclarativeEngine::add: loaded" << absoluteFilePath;
+ }
+
+ if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
+ qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);
+
+ QDeclarativeDirParser qmldirParser;
+ qmldirParser.setSource(qmldircontent);
+ qmldirParser.parse();
+
+ foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
+ QDir pluginDir(dir + QDir::separator() + plugin.path);
+ if (dir.startsWith(QLatin1Char(':')))
+ pluginDir = QDir(QCoreApplication::applicationDirPath());
+ QString resolvedFilePath =
+ QDeclarativeEnginePrivate::get(engine)
+ ->resolvePlugin(pluginDir,
+ plugin.name);
+
+ if (!resolvedFilePath.isEmpty()) {
+ engine->importExtension(resolvedFilePath, uri);
+ }
+ }
+ }
+ return qmldircontent;
+ }
+
+ QString resolvedUri(const QString &dir_arg, QDeclarativeEngine *engine)
+ {
+ QString dir = dir_arg;
+ if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\')))
+ dir.chop(1);
+
+ QStringList paths;
+
+ QUrl baseUrl = QDeclarativeEnginePrivate::get(engine)->baseUrl;
+ if (!baseUrl.isEmpty()) {
+ QString baseDir = QFileInfo(toLocalFileOrQrc(baseUrl)).path();
+ paths += baseDir;
+ }
+
+ QString applicationDirPath = QCoreApplication::applicationDirPath();
+ if (!applicationDirPath.isEmpty())
+ paths += applicationDirPath;
+
+ paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath;
+#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
+ QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
+#else
+ QString builtinPath;
+#endif
+ if (!builtinPath.isEmpty())
+ paths += builtinPath;
+
+ // add fileImportPath last, this is *not* search order.
+ paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath;
+
+ QString stableRelativePath = dir;
+ foreach( QString path, paths) {
+ if (dir.startsWith(path)) {
+ stableRelativePath = dir.mid(path.length()+1);
+ break;
+ }
+ }
+ stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.'));
+ stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('.'));
+ return stableRelativePath;
+ }
+
+
+
+
+ bool add(const QUrl& base, const QString &qmldircontentnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeEngine *engine)
{
+ QString qmldircontent = qmldircontentnetwork;
+ QString uri = uri_arg;
QDeclarativeEnginePrivate::ImportedNamespace *s;
if (prefix.isEmpty()) {
s = &unqualifiedset;
@@ -1406,30 +1522,40 @@ public:
if (!s)
set.insert(prefix,(s=new QDeclarativeEnginePrivate::ImportedNamespace));
}
+
+
+
QString url = uri;
if (importType == QDeclarativeScriptParser::Import::Library) {
url.replace(QLatin1Char('.'), QLatin1Char('/'));
bool found = false;
- QString content;
QString dir;
+
// user import paths
QStringList paths;
-
// base..
- paths += QFileInfo(base.toLocalFile()).path();
- paths += importPath;
+ QString localFileOrQrc = toLocalFileOrQrc(base);
+ QString localFileOrQrcPath = QFileInfo(localFileOrQrc).path();
+ paths += localFileOrQrcPath;
+ paths += QDeclarativeEnginePrivate::get(engine)->fileImportPath;
+
+ QString applicationDirPath = QCoreApplication::applicationDirPath();
+ if (!applicationDirPath.isEmpty())
+ paths += applicationDirPath;
+
paths += QDeclarativeEnginePrivate::get(engine)->environmentImportPath;
-#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
+ #if (QT_VERSION >= QT_VERSION_CHECK(4,7,0))
QString builtinPath = QLibraryInfo::location(QLibraryInfo::ImportsPath);
-#else
+ #else
QString builtinPath;
-#endif
+ #endif
if (!builtinPath.isEmpty())
paths += builtinPath;
foreach (const QString &p, paths) {
dir = p+QLatin1Char('/')+url;
+
QFileInfo fi(dir+QLatin1String("/qmldir"));
const QString absoluteFilePath = fi.absoluteFilePath();
@@ -1437,32 +1563,28 @@ public:
found = true;
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
-
- QFile file(absoluteFilePath);
- if (file.open(QFile::ReadOnly))
- content = QString::fromUtf8(file.readAll());
-
- if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
- qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);
-
- QDeclarativeDirParser qmldirParser;
- qmldirParser.setSource(content);
- qmldirParser.parse();
-
- foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {
- QString resolvedFilePath = QDeclarativeEnginePrivate::get(engine)->resolvePlugin(QDir(dir + QDir::separator() + plugin.path),
- plugin.name);
-
- if (!resolvedFilePath.isEmpty())
- engine->importExtension(resolvedFilePath, uri);
- }
- }
-
+ uri = resolvedUri(dir, engine);
+ qmldircontent = importExtension(absoluteFilePath, uri, engine);
break;
}
}
} else {
+
+ if (importType == QDeclarativeScriptParser::Import::File && qmldircontent.isEmpty()) {
+ QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir")));
+ QString localFileOrQrc = toLocalFileOrQrc(importUrl);
+ if (!localFileOrQrc.isEmpty()) {
+ uri = resolvedUri(toLocalFileOrQrc(base.resolved(QUrl(uri))), engine);
+ qmldircontent = importExtension(localFileOrQrc,
+ uri,
+ engine);
+
+ if (uri.endsWith(QLatin1Char('/')))
+ uri.chop(1);
+ }
+ }
+
url = base.resolved(QUrl(url)).toString();
}
@@ -1493,7 +1615,8 @@ public:
if (s) {
if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return))
return true;
- if (s->urls.count() == 1 && !s->isLibrary[0] && url_return) {
+ if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
+ // qualified, and only 1 url
*url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml")));
return true;
}
@@ -1642,9 +1765,10 @@ QUrl QDeclarativeEnginePrivate::Imports::baseUrl() const
type version mapping and possibly declarative extensions plugins.
The engine searches in the base directory of the qml file, then
- the paths added via addImportPath(), then the paths specified in the
- \c QML_IMPORT_PATH environment variable, then the builtin \c ImportsPath from
- QLibraryInfo.
+ the paths added via addImportPath(), then in the directory containing the
+ application executable (QCoreApplication::applicationDirPath()),
+ then the paths specified in the \c QML_IMPORT_PATH environment variable, then the
+ builtin \c ImportsPath from QLibraryInfo.
*/
void QDeclarativeEngine::addImportPath(const QString& path)
@@ -1661,6 +1785,8 @@ void QDeclarativeEngine::addImportPath(const QString& path)
*/
bool QDeclarativeEngine::importExtension(const QString &fileName, const QString &uri)
{
+ if (qmlImportTrace())
+ qDebug() << "QDeclarativeEngine::importExtension" << uri << "from" << fileName;
QFileInfo fileInfo(fileName);
const QString absoluteFilePath = fileInfo.absoluteFilePath();
QPluginLoader loader(absoluteFilePath);
@@ -1744,6 +1870,8 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString
return fileInfo.absoluteFilePath();
}
+ if (qmlImportTrace())
+ qDebug() << "QDeclarativeEngine::resolvePlugin: Could not resolve plugin" << baseName << "in" << dir.absolutePath();
return QString();
}
@@ -1784,6 +1912,9 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString
return resolvePlugin(dir, baseName,
QStringList()
+# ifdef QT_DEBUG
+ << QLatin1String("_debug.dylib") // try a qmake-style debug build first
+# endif
<< QLatin1String(".dylib")
<< QLatin1String(".so")
<< QLatin1String(".bundle"),
@@ -1830,12 +1961,12 @@ QString QDeclarativeEnginePrivate::resolvePlugin(const QDir &dir, const QString
The base URL must already have been set with Import::setBaseUrl().
*/
-bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString& qmldircontent, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const
+bool QDeclarativeEnginePrivate::addToImport(Imports* imports, const QString &qmldircontentnetwork, const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const
{
QDeclarativeEngine *engine = QDeclarativeEnginePrivate::get(const_cast<QDeclarativeEnginePrivate *>(this));
- bool ok = imports->d->add(imports->d->base,qmldircontent,uri,prefix,vmaj,vmin,importType,fileImportPath, engine);
if (qmlImportTrace())
- qDebug() << "QDeclarativeEngine::addToImport(" << imports << uri << prefix << vmaj << '.' << vmin << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << ": " << ok;
+ qDebug().nospace() << "QDeclarativeEngine::addToImport " << imports << " " << uri << " " << vmaj << '.' << vmin << " " << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") << " as " << prefix;
+ bool ok = imports->d->add(imports->d->base,qmldircontentnetwork, uri,prefix,vmaj,vmin,importType, engine);
return ok;
}
@@ -1855,8 +1986,6 @@ bool QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteA
{
ImportedNamespace* ns = imports.d->findNamespace(QString::fromUtf8(type));
if (ns) {
- if (qmlImportTrace())
- qDebug() << "QDeclarativeEngine::resolveType" << type << "is namespace for" << ns->urls;
if (ns_return)
*ns_return = ns;
return true;
@@ -1864,15 +1993,15 @@ bool QDeclarativeEnginePrivate::resolveType(const Imports& imports, const QByteA
if (type_return || url_return) {
if (imports.d->find(type,vmaj,vmin,type_return,url_return)) {
if (qmlImportTrace()) {
+ if (type_return && *type_return && url_return && !url_return->isEmpty())
+ qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName() << *url_return;
if (type_return && *type_return)
qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << (*type_return)->typeName();
- if (url_return)
+ if (url_return && !url_return->isEmpty())
qDebug() << "QDeclarativeEngine::resolveType" << type << '=' << *url_return;
}
return true;
}
- if (qmlImportTrace())
- qDebug() << "QDeclarativeEngine::resolveType" << type << "not found";
}
return false;
}
diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h
index fd66358..19e81b6 100644
--- a/src/declarative/qml/qdeclarativeengine.h
+++ b/src/declarative/qml/qdeclarativeengine.h
@@ -98,6 +98,10 @@ public:
static QDeclarativeContext *contextForObject(const QObject *);
static void setContextForObject(QObject *, QDeclarativeContext *);
+ enum ObjectOwnership { CppOwnership, JavaScriptOwnership };
+ static void setObjectOwnership(QObject *, ObjectOwnership);
+ static ObjectOwnership objectOwnership(QObject *);
+
Q_SIGNALS:
void quit ();
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index 459a325..f1b7b0e 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -61,6 +61,7 @@
#include "qdeclarative.h"
#include "qdeclarativevaluetype_p.h"
#include "qdeclarativecontext.h"
+#include "qdeclarativecontext_p.h"
#include "qdeclarativeexpression.h"
#include "qdeclarativeproperty_p.h"
#include "qdeclarativepropertycache_p.h"
@@ -144,10 +145,13 @@ public:
struct CapturedProperty {
CapturedProperty(QObject *o, int c, int n)
- : object(o), coreIndex(c), notifyIndex(n) {}
+ : object(o), coreIndex(c), notifier(0), notifyIndex(n) {}
+ CapturedProperty(QDeclarativeNotifier *n)
+ : object(0), coreIndex(-1), notifier(n), notifyIndex(-1) {}
QObject *object;
int coreIndex;
+ QDeclarativeNotifier *notifier;
int notifyIndex;
};
bool captureProperties;
@@ -159,7 +163,7 @@ public:
struct ImportedNamespace;
QDeclarativeContextScriptClass *contextClass;
- QDeclarativeContext *sharedContext;
+ QDeclarativeContextData *sharedContext;
QObject *sharedScope;
QDeclarativeObjectScriptClass *objectClass;
QDeclarativeValueTypeScriptClass *valueTypeClass;
@@ -276,7 +280,7 @@ public:
QString resolvePlugin(const QDir &dir, const QString &baseName);
- bool addToImport(Imports*, const QString& qmlDirContent,const QString& uri, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const;
+ bool addToImport(Imports*, const QString& uri, const QString &qmldircontentnetwork, const QString& prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType) const;
bool resolveType(const Imports&, const QByteArray& type,
QDeclarativeType** type_return, QUrl* url_return,
int *version_major, int *version_minor,
@@ -318,7 +322,6 @@ public:
static QScriptValue darker(QScriptContext*, QScriptEngine*);
static QScriptValue tint(QScriptContext*, QScriptEngine*);
- static QScriptValue closestAngle(QScriptContext*, QScriptEngine*);
static QScriptValue desktopOpenUrl(QScriptContext*, QScriptEngine*);
static QScriptValue md5(QScriptContext*, QScriptEngine*);
static QScriptValue btoa(QScriptContext*, QScriptEngine*);
@@ -334,9 +337,10 @@ public:
static QDeclarativeEngine *getEngine(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p->q_func(); }
static QDeclarativeEnginePrivate *get(QDeclarativeEngine *e) { return e->d_func(); }
static QDeclarativeEnginePrivate *get(QDeclarativeContext *c) { return (c && c->engine()) ? QDeclarativeEnginePrivate::get(c->engine()) : 0; }
+ static QDeclarativeEnginePrivate *get(QDeclarativeContextData *c) { return (c && c->engine) ? QDeclarativeEnginePrivate::get(c->engine) : 0; }
static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; }
static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
- QDeclarativeContext *getContext(QScriptContext *);
+ QDeclarativeContextData *getContext(QScriptContext *);
static void defineModule();
};
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index 3e4acbe..a377b35 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -49,6 +49,7 @@
#include "qdeclarativebinding_p.h"
#include "qdeclarativecontext_p.h"
#include "qdeclarativewatcher_p.h"
+#include "qdeclarativevaluetype_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
@@ -218,10 +219,9 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message,
message << fakeProperties[ii];
}
-void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message,
- QDeclarativeContext *ctxt)
+void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt)
{
- QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt);
+ QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt);
QString ctxtName = ctxt->objectName();
int ctxtId = QDeclarativeDebugService::idForObject(ctxt);
@@ -230,35 +230,34 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message,
int count = 0;
- for (QSet<QDeclarativeContext *>::ConstIterator iter = p->childContexts.begin();
- iter != p->childContexts.end(); ++iter) {
- QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(*iter);
- if (p->isInternal)
- continue;
- ++count;
+ QDeclarativeContextData *child = p->childContexts;
+ while (child) {
+ if (!child->isInternal)
+ ++count;
+ child = child->nextChild;
}
message << count;
- for (QSet<QDeclarativeContext *>::ConstIterator iter = p->childContexts.begin();
- iter != p->childContexts.end(); ++iter) {
- QDeclarativeContextPrivate *p = (QDeclarativeContextPrivate *)QObjectPrivate::get(*iter);
- if (p->isInternal)
- continue;
- buildObjectList(message, *iter);
+ child = p->childContexts;
+ while (child) {
+ if (!child->isInternal)
+ buildObjectList(message, child->asQDeclarativeContext());
+ child = child->nextChild;
}
// Clean deleted objects
- for (int ii = 0; ii < p->instances.count(); ++ii) {
- if (!p->instances.at(ii)) {
- p->instances.removeAt(ii);
+ QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt);
+ for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
+ if (!ctxtPriv->instances.at(ii)) {
+ ctxtPriv->instances.removeAt(ii);
--ii;
}
}
- message << p->instances.count();
- for (int ii = 0; ii < p->instances.count(); ++ii) {
- message << objectData(p->instances.at(ii));
+ message << ctxtPriv->instances.count();
+ for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
+ message << objectData(ctxtPriv->instances.at(ii));
}
}
@@ -267,8 +266,8 @@ QDeclarativeEngineDebugServer::objectData(QObject *object)
{
QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object);
QDeclarativeObjectData rv;
- if (ddata) {
- rv.url = ddata->outerContext->baseUrl();
+ if (ddata && ddata->outerContext) {
+ rv.url = ddata->outerContext->url;
rv.lineNumber = ddata->lineNumber;
rv.columnNumber = ddata->columnNumber;
} else {
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 899f402..609eb39 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -98,8 +98,8 @@ QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate()
if (data) { data->q = 0; data->release(); data = 0; }
}
-void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QString &expr,
- QObject *me)
+void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr,
+ QObject *me)
{
data->expression = expr;
@@ -107,8 +107,8 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, const QStrin
data->me = me;
}
-void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr, QDeclarativeRefCount *rc,
- QObject *me, const QString &url, int lineNumber)
+void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc,
+ QObject *me, const QString &url, int lineNumber)
{
data->url = url;
data->line = lineNumber;
@@ -127,7 +127,7 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr,
bool isShared = progIdx & 0x80000000;
progIdx &= 0x7FFFFFFF;
- QDeclarativeEngine *engine = ctxt->engine();
+ QDeclarativeEngine *engine = ctxt->engine;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -167,10 +167,10 @@ void QDeclarativeExpressionPrivate::init(QDeclarativeContext *ctxt, void *expr,
data->me = me;
}
-QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object,
+QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
const QString &program, QScriptValue *contextObject)
{
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine());
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
if (contextObject) {
*contextObject = ep->contextClass->newContext(context, object);
@@ -184,10 +184,11 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex
return rv;
}
-QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContext *context, QObject *object,
- const QScriptProgram &program, QScriptValue *contextObject)
+QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
+ const QScriptProgram &program,
+ QScriptValue *contextObject)
{
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine());
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine);
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(&ep->scriptEngine);
if (contextObject) {
*contextObject = ep->contextClass->newContext(context, object);
@@ -219,10 +220,10 @@ QDeclarativeExpression::QDeclarativeExpression()
}
/*! \internal */
-QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void *expr,
- QDeclarativeRefCount *rc, QObject *me,
- const QString &url, int lineNumber,
- QDeclarativeExpressionPrivate &dd)
+QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, void *expr,
+ QDeclarativeRefCount *rc, QObject *me,
+ const QString &url, int lineNumber,
+ QDeclarativeExpressionPrivate &dd)
: QObject(dd, 0)
{
Q_D(QDeclarativeExpression);
@@ -237,7 +238,18 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, void *
the expression's execution.
*/
QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression,
- QObject *scope)
+ QObject *scope)
+: QObject(*new QDeclarativeExpressionPrivate, 0)
+{
+ Q_D(QDeclarativeExpression);
+ d->init(QDeclarativeContextData::get(ctxt), expression, scope);
+}
+
+/*!
+ \internal
+*/
+QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression,
+ QObject *scope)
: QObject(*new QDeclarativeExpressionPrivate, 0)
{
Q_D(QDeclarativeExpression);
@@ -245,8 +257,8 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const
}
/*! \internal */
-QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt, const QString &expression,
- QObject *scope, QDeclarativeExpressionPrivate &dd)
+QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, const QString &expression,
+ QObject *scope, QDeclarativeExpressionPrivate &dd)
: QObject(dd, 0)
{
Q_D(QDeclarativeExpression);
@@ -267,7 +279,7 @@ QDeclarativeExpression::~QDeclarativeExpression()
QDeclarativeEngine *QDeclarativeExpression::engine() const
{
Q_D(const QDeclarativeExpression);
- return d->data->context()?d->data->context()->engine():0;
+ return d->data->context()?d->data->context()->engine:0;
}
/*!
@@ -277,7 +289,8 @@ QDeclarativeEngine *QDeclarativeExpression::engine() const
QDeclarativeContext *QDeclarativeExpression::context() const
{
Q_D(const QDeclarativeExpression);
- return d->data->context();
+ QDeclarativeContextData *data = d->data->context();
+ return data?data->asQDeclarativeContext():0;
}
/*!
@@ -338,8 +351,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo
#endif
QDeclarativeExpressionData *data = this->data;
- QDeclarativeContextPrivate *ctxtPriv = data->context()->d_func();
- QDeclarativeEngine *engine = data->context()->engine();
+ QDeclarativeEngine *engine = data->context()->engine;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -370,7 +382,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo
data->expressionFunctionValid = true;
}
- QDeclarativeContext *oldSharedContext = 0;
+ QDeclarativeContextData *oldSharedContext = 0;
QObject *oldSharedScope = 0;
QObject *oldOverride = 0;
if (data->isShared) {
@@ -622,137 +634,96 @@ void QDeclarativeExpression::__q_notify()
void QDeclarativeExpressionPrivate::clearGuards()
{
- Q_Q(QDeclarativeExpression);
-
- static int notifyIdx = -1;
- if (notifyIdx == -1)
- notifyIdx =
- QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()");
-
- for (int ii = 0; ii < data->guardListLength; ++ii) {
- if (data->guardList[ii].data()) {
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
- QMetaObject::disconnectOne(data->guardList[ii].data(),
- data->guardList[ii].notifyIndex,
- q, notifyIdx);
-#else
- // QTBUG-6781
- QMetaObject::disconnect(data->guardList[ii].data(),
- data->guardList[ii].notifyIndex,
- q, notifyIdx);
-#endif
- }
- }
-
- delete [] data->guardList; data->guardList = 0;
+ delete [] data->guardList;
+ data->guardList = 0;
data->guardListLength = 0;
}
void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties)
{
- //clearGuards();
Q_Q(QDeclarativeExpression);
static int notifyIdx = -1;
if (notifyIdx == -1)
- notifyIdx =
- QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()");
+ notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("__q_notify()");
- QDeclarativeExpressionData::SignalGuard *newGuardList = 0;
-
- if (properties.count() != data->guardListLength)
- newGuardList = new QDeclarativeExpressionData::SignalGuard[properties.count()];
+ if (properties.count() != data->guardListLength) {
+ QDeclarativeNotifierEndpoint *newGuardList =
+ new QDeclarativeNotifierEndpoint[properties.count()];
+
+ for (int ii = 0; ii < qMin(data->guardListLength, properties.count()); ++ii)
+ data->guardList[ii].copyAndClear(newGuardList[ii]);
+
+ delete [] data->guardList;
+ data->guardList = newGuardList;
+ data->guardListLength = properties.count();
+ }
bool outputWarningHeader = false;
- int hit = 0;
+ bool noChanges = true;
for (int ii = 0; ii < properties.count(); ++ii) {
+ QDeclarativeNotifierEndpoint &guard = data->guardList[ii];
const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
- bool needGuard = true;
- if (ii >= data->guardListLength) {
- // New guard
- } else if(data->guardList[ii].data() == property.object &&
- data->guardList[ii].notifyIndex == property.notifyIndex) {
- // Cache hit
- if (!data->guardList[ii].isDuplicate ||
- (data->guardList[ii].isDuplicate && hit == ii)) {
- needGuard = false;
- ++hit;
- }
- } else if(data->guardList[ii].data() && !data->guardList[ii].isDuplicate) {
- // Cache miss
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
- QMetaObject::disconnectOne(data->guardList[ii].data(),
- data->guardList[ii].notifyIndex,
- q, notifyIdx);
-#else
- // QTBUG-6781
- QMetaObject::disconnect(data->guardList[ii].data(),
- data->guardList[ii].notifyIndex,
- q, notifyIdx);
-#endif
- }
- /* else {
- // Cache miss, but nothing to do
- } */
-
- if (needGuard) {
- if (!newGuardList) {
- newGuardList = new QDeclarativeExpressionData::SignalGuard[properties.count()];
- for (int jj = 0; jj < ii; ++jj)
- newGuardList[jj] = data->guardList[jj];
- }
+ guard.target = q;
+ guard.targetMethod = notifyIdx;
+
+ if (property.notifier != 0) {
+
+ if (!noChanges && guard.isConnected(property.notifier)) {
+ // Nothing to do
+
+ } else {
+ noChanges = false;
- if (property.notifyIndex != -1) {
bool existing = false;
for (int jj = 0; !existing && jj < ii; ++jj)
- existing = newGuardList[jj].data() == property.object &&
- newGuardList[jj].notifyIndex == property.notifyIndex;
-
- newGuardList[ii] = property.object;
- newGuardList[ii].notifyIndex = property.notifyIndex;
- if (existing)
- newGuardList[ii].isDuplicate = true;
- else
- QMetaObject::connect(property.object, property.notifyIndex,
- q, notifyIdx);
- } else {
- if (!outputWarningHeader) {
- outputWarningHeader = true;
- qWarning() << "QDeclarativeExpression: Expression" << q->expression()
- << "depends on non-NOTIFYable properties:";
+ if (data->guardList[jj].isConnected(property.notifier))
+ existing = true;
+
+ if (existing) {
+ // duplicate
+ guard.disconnect();
+ } else {
+ guard.connect(property.notifier);
}
+ }
+
- const QMetaObject *metaObj = property.object->metaObject();
- QMetaProperty metaProp = metaObj->property(property.coreIndex);
+ } else if (property.notifyIndex != -1) {
- qWarning().nospace() << " " << metaObj->className()
- << "::" << metaProp.name();
+ if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
+ // Nothing to do
+
+ } else {
+ noChanges = false;
+
+ bool existing = false;
+ for (int jj = 0; !existing && jj < ii; ++jj)
+ if (data->guardList[jj].isConnected(property.object, property.notifyIndex))
+ existing = true;
+
+ if (existing) {
+ // duplicate
+ guard.disconnect();
+ } else {
+ guard.connect(property.object, property.notifyIndex);
+ }
}
- } else if (newGuardList) {
- newGuardList[ii] = data->guardList[ii];
- }
- }
- for (int ii = properties.count(); ii < data->guardListLength; ++ii) {
- if (data->guardList[ii].data() && !data->guardList[ii].isDuplicate) {
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 2))
- QMetaObject::disconnectOne(data->guardList[ii].data(),
- data->guardList[ii].notifyIndex,
- q, notifyIdx);
-#else
- // QTBUG-6781
- QMetaObject::disconnect(data->guardList[ii].data(),
- data->guardList[ii].notifyIndex,
- q, notifyIdx);
-#endif
- }
- }
+ } else {
+ if (!outputWarningHeader) {
+ outputWarningHeader = true;
+ qWarning() << "QDeclarativeExpression: Expression" << q->expression()
+ << "depends on non-NOTIFYable properties:";
+ }
- if (newGuardList) {
- if (data->guardList) delete [] data->guardList;
- data->guardList = newGuardList;
- data->guardListLength = properties.count();
+ const QMetaObject *metaObj = property.object->metaObject();
+ QMetaProperty metaProp = metaObj->property(property.coreIndex);
+
+ qWarning().nospace() << " " << metaObj->className()
+ << "::" << metaProp.name();
+ }
}
}
@@ -784,12 +755,12 @@ QDeclarativeAbstractExpression::~QDeclarativeAbstractExpression()
}
}
-QDeclarativeContext *QDeclarativeAbstractExpression::context() const
+QDeclarativeContextData *QDeclarativeAbstractExpression::context() const
{
return m_context;
}
-void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context)
+void QDeclarativeAbstractExpression::setContext(QDeclarativeContextData *context)
{
if (m_prevExpression) {
*m_prevExpression = m_nextExpression;
@@ -802,13 +773,11 @@ void QDeclarativeAbstractExpression::setContext(QDeclarativeContext *context)
m_context = context;
if (m_context) {
- QDeclarativeContextPrivate *cp =
- static_cast<QDeclarativeContextPrivate *>(QObjectPrivate::get(m_context));
- m_nextExpression = cp->expressions;
+ m_nextExpression = m_context->expressions;
if (m_nextExpression)
m_nextExpression->m_prevExpression = &m_nextExpression;
- m_prevExpression = &cp->expressions;
- cp->expressions = this;
+ m_prevExpression = &context->expressions;
+ m_context->expressions = this;
}
}
diff --git a/src/declarative/qml/qdeclarativeexpression.h b/src/declarative/qml/qdeclarativeexpression.h
index 911d328..73a5793 100644
--- a/src/declarative/qml/qdeclarativeexpression.h
+++ b/src/declarative/qml/qdeclarativeexpression.h
@@ -58,6 +58,7 @@ class QDeclarativeRefCount;
class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeExpressionPrivate;
+class QDeclarativeContextData;
class Q_DECLARATIVE_EXPORT QDeclarativeExpression : public QObject
{
Q_OBJECT
@@ -91,18 +92,21 @@ Q_SIGNALS:
void valueChanged();
protected:
- QDeclarativeExpression(QDeclarativeContext *, const QString &, QObject *,
- QDeclarativeExpressionPrivate &dd);
- QDeclarativeExpression(QDeclarativeContext *, void *, QDeclarativeRefCount *rc, QObject *me, const QString &,
- int, QDeclarativeExpressionPrivate &dd);
+ QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *,
+ QDeclarativeExpressionPrivate &dd);
+ QDeclarativeExpression(QDeclarativeContextData *, void *, QDeclarativeRefCount *rc,
+ QObject *me, const QString &, int, QDeclarativeExpressionPrivate &dd);
private Q_SLOTS:
void __q_notify();
private:
+ QDeclarativeExpression(QDeclarativeContextData *, const QString &, QObject *);
+
Q_DECLARE_PRIVATE(QDeclarativeExpression)
friend class QDeclarativeDebugger;
friend class QDeclarativeContext;
+ friend class QDeclarativeVME;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h
index cd1729d..5adaa89 100644
--- a/src/declarative/qml/qdeclarativeexpression_p.h
+++ b/src/declarative/qml/qdeclarativeexpression_p.h
@@ -70,15 +70,16 @@ public:
bool isValid() const;
- QDeclarativeContext *context() const;
- void setContext(QDeclarativeContext *);
+ QDeclarativeContextData *context() const;
+ void setContext(QDeclarativeContextData *);
virtual void refresh();
private:
friend class QDeclarativeContext;
+ friend class QDeclarativeContextData;
friend class QDeclarativeContextPrivate;
- QDeclarativeContext *m_context;
+ QDeclarativeContextData *m_context;
QDeclarativeAbstractExpression **m_prevExpression;
QDeclarativeAbstractExpression *m_nextExpression;
};
@@ -129,24 +130,7 @@ public:
QString url; // This is a QString for a reason. QUrls are slooooooow...
int line;
- struct SignalGuard : public QDeclarativeGuard<QObject> {
- SignalGuard() : isDuplicate(false), notifyIndex(-1) {}
-
- SignalGuard &operator=(QObject *obj) {
- QDeclarativeGuard<QObject>::operator=(obj);
- return *this;
- }
- SignalGuard &operator=(const SignalGuard &o) {
- QDeclarativeGuard<QObject>::operator=(o);
- isDuplicate = o.isDuplicate;
- notifyIndex = o.notifyIndex;
- return *this;
- }
-
- bool isDuplicate:1;
- int notifyIndex:31;
- };
- SignalGuard *guardList;
+ QDeclarativeNotifierEndpoint *guardList;
int guardListLength;
};
@@ -160,8 +144,8 @@ public:
QDeclarativeExpressionPrivate(QDeclarativeExpressionData *);
~QDeclarativeExpressionPrivate();
- void init(QDeclarativeContext *, const QString &, QObject *);
- void init(QDeclarativeContext *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
+ void init(QDeclarativeContextData *, const QString &, QObject *);
+ void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
QDeclarativeExpressionData *data;
@@ -181,8 +165,8 @@ public:
virtual void emitValueChanged();
static void exceptionToError(QScriptEngine *, QDeclarativeError &);
- static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QString &, QScriptValue * = 0);
- static QScriptValue evalInObjectScope(QDeclarativeContext *, QObject *, const QScriptProgram &, QScriptValue * = 0);
+ static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QString &, QScriptValue * = 0);
+ static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &, QScriptValue * = 0);
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativeinfo.cpp b/src/declarative/qml/qdeclarativeinfo.cpp
index 7dc61fd..5146bb6 100644
--- a/src/declarative/qml/qdeclarativeinfo.cpp
+++ b/src/declarative/qml/qdeclarativeinfo.cpp
@@ -43,6 +43,7 @@
#include "qdeclarativedeclarativedata_p.h"
#include "qdeclarativecontext.h"
+#include "qdeclarativecontext_p.h"
#include "qdeclarativemetatype_p.h"
#include <QCoreApplication>
@@ -102,8 +103,8 @@ QDeclarativeInfo::QDeclarativeInfo(const QObject *object)
QDeclarativeDeclarativeData *ddata = object?QDeclarativeDeclarativeData::get(object):0;
pos += QLatin1String(" (");
if (ddata) {
- if (ddata->outerContext) {
- pos += ddata->outerContext->baseUrl().toString();
+ if (ddata->outerContext && !ddata->outerContext->url.isEmpty()) {
+ pos += ddata->outerContext->url.toString();
pos += QLatin1Char(':');
pos += QString::number(ddata->lineNumber);
pos += QLatin1Char(':');
diff --git a/src/declarative/qml/qdeclarativeinstruction.cpp b/src/declarative/qml/qdeclarativeinstruction.cpp
index cf485fe..a23ff75 100644
--- a/src/declarative/qml/qdeclarativeinstruction.cpp
+++ b/src/declarative/qml/qdeclarativeinstruction.cpp
@@ -90,7 +90,7 @@ void QDeclarativeCompiledData::dump(QDeclarativeInstruction *instr, int idx)
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_STRING\t\t" << instr->storeString.propertyIndex << "\t" << instr->storeString.value << "\t\t" << primitives.at(instr->storeString.value);
break;
case QDeclarativeInstruction::StoreUrl:
- qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << primitives.at(instr->storeUrl.value);
+ qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_URL\t\t" << instr->storeUrl.propertyIndex << "\t" << instr->storeUrl.value << "\t\t" << urls.at(instr->storeUrl.value);
break;
case QDeclarativeInstruction::StoreColor:
qWarning().nospace() << idx << "\t\t" << line << "\t" << "STORE_COLOR\t\t" << instr->storeColor.propertyIndex << "\t\t\t" << QString::number(instr->storeColor.value, 16);
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index 50ab56b..b32e575 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -124,7 +124,10 @@ public:
int m_version_maj;
int m_version_min;
int m_typeId; int m_listId;
- QObject *(*m_newFunc)();
+
+ int m_allocationSize;
+ void (*m_newFunc)(void *);
+
const QMetaObject *m_baseMetaObject;
QDeclarativeAttachedPropertiesFunc m_attachedPropertiesFunc;
const QMetaObject *m_attachedPropertiesType;
@@ -141,7 +144,7 @@ public:
QDeclarativeTypePrivate::QDeclarativeTypePrivate()
: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0),
- m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0),
+ m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0),
m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_propertyValueInterceptorCast(-1),
m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false)
{
@@ -174,6 +177,7 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe
d->m_version_min = type.versionMinor;
d->m_typeId = type.typeId;
d->m_listId = type.listId;
+ d->m_allocationSize = type.objectSize;
d->m_newFunc = type.create;
d->m_baseMetaObject = type.metaObject;
d->m_attachedPropertiesFunc = type.attachedPropertiesFunction;
@@ -274,13 +278,29 @@ QObject *QDeclarativeType::create() const
{
d->init();
- QObject *rv = d->m_newFunc();
+ QObject *rv = (QObject *)operator new(d->m_allocationSize);
+ d->m_newFunc(rv);
+
if (rv && !d->m_metaObjects.isEmpty())
(void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects);
return rv;
}
+void QDeclarativeType::create(QObject **out, void **memory, size_t additionalMemory) const
+{
+ d->init();
+
+ QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory);
+ d->m_newFunc(rv);
+
+ if (rv && !d->m_metaObjects.isEmpty())
+ (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects);
+
+ *out = rv;
+ *memory = ((char *)rv) + d->m_allocationSize;
+}
+
QDeclarativeCustomParser *QDeclarativeType::customParser() const
{
return d->m_customParser;
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index cf8946d..1a36f10 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -111,6 +111,7 @@ public:
bool availableInVersion(int vmajor, int vminor) const;
QObject *create() const;
+ void create(QObject **, void **, size_t) const;
QDeclarativeCustomParser *customParser() const;
diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp
new file mode 100644
index 0000000..8e5904c
--- /dev/null
+++ b/src/declarative/qml/qdeclarativenotifier.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativenotifier_p.h"
+
+QT_BEGIN_NAMESPACE
+
+void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint)
+{
+ QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier();
+
+ QDeclarativeNotifierEndpoint::Notifier **oldDisconnected = n->disconnected;
+ n->disconnected = &n;
+
+ if (n->next)
+ emitNotify(n->next);
+
+ if (n) {
+ void *args[] = { 0 };
+
+ QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod,
+ endpoint->targetMethod, args);
+
+ if (n)
+ n->disconnected = oldDisconnected;
+ }
+
+ if (oldDisconnected) *oldDisconnected = n;
+}
+
+void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other)
+{
+ other.disconnect();
+
+ other.target = target;
+ other.targetMethod = targetMethod;
+
+ if (!isConnected())
+ return;
+
+ if (SignalType == type) {
+ Signal *other_s = other.toSignal();
+ Signal *s = asSignal();
+
+ other_s->source = s->source;
+ other_s->sourceSignal = s->sourceSignal;
+ s->source = 0;
+ } else if(NotifierType == type) {
+ Notifier *other_n = other.toNotifier();
+ Notifier *n = asNotifier();
+
+ other_n->notifier = n->notifier;
+ other_n->disconnected = n->disconnected;
+ if (other_n->disconnected) *other_n->disconnected = other_n;
+
+ if (n->next) {
+ other_n->next = n->next;
+ n->next->asNotifier()->prev = &other_n->next;
+ }
+ other_n->prev = n->prev;
+ *other_n->prev = &other;
+
+ n->prev = 0;
+ n->next = 0;
+ n->disconnected = 0;
+ n->notifier = 0;
+ }
+}
+
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h
new file mode 100644
index 0000000..a0e6b43
--- /dev/null
+++ b/src/declarative/qml/qdeclarativenotifier_p.h
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVENOTIFIER_P_H
+#define QDECLARATIVENOTIFIER_P_H
+
+#include "qdeclarativeguard_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeNotifierEndpoint;
+class QDeclarativeNotifier
+{
+public:
+ inline QDeclarativeNotifier();
+ inline ~QDeclarativeNotifier();
+ inline void notify();
+
+private:
+ friend class QDeclarativeNotifierEndpoint;
+
+ static void emitNotify(QDeclarativeNotifierEndpoint *);
+ QDeclarativeNotifierEndpoint *endpoints;
+};
+
+class QDeclarativeNotifierEndpoint
+{
+public:
+ inline QDeclarativeNotifierEndpoint();
+ inline QDeclarativeNotifierEndpoint(QObject *t, int m);
+ inline ~QDeclarativeNotifierEndpoint();
+
+ QObject *target;
+ int targetMethod;
+
+ inline bool isConnected();
+ inline bool isConnected(QObject *source, int sourceSignal);
+ inline bool isConnected(QDeclarativeNotifier *);
+
+ inline void connect(QObject *source, int sourceSignal);
+ inline void connect(QDeclarativeNotifier *);
+ inline void disconnect();
+
+ void copyAndClear(QDeclarativeNotifierEndpoint &other);
+
+private:
+ friend class QDeclarativeNotifier;
+
+ struct Signal {
+ QDeclarativeGuard<QObject> source;
+ int sourceSignal;
+ };
+
+ struct Notifier {
+ QDeclarativeNotifier *notifier;
+ Notifier **disconnected;
+
+ QDeclarativeNotifierEndpoint *next;
+ QDeclarativeNotifierEndpoint **prev;
+ };
+
+ enum { InvalidType, SignalType, NotifierType } type;
+ union {
+ char signalData[sizeof(Signal)];
+ char notifierData[sizeof(Notifier)];
+ };
+
+ inline Notifier *toNotifier();
+ inline Notifier *asNotifier();
+ inline Signal *toSignal();
+ inline Signal *asSignal();
+};
+
+QDeclarativeNotifier::QDeclarativeNotifier()
+: endpoints(0)
+{
+ QDeclarativeNotifierEndpoint *endpoint = endpoints;
+ while (endpoint) {
+ QDeclarativeNotifierEndpoint *next = endpoint->asNotifier()->next;
+ endpoint->asNotifier()->next = 0;
+ endpoint->asNotifier()->prev = 0;
+ endpoint->asNotifier()->notifier = 0;
+ endpoint = next;
+ }
+}
+
+QDeclarativeNotifier::~QDeclarativeNotifier()
+{
+}
+
+void QDeclarativeNotifier::notify()
+{
+ if (endpoints) emitNotify(endpoints);
+}
+
+QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint()
+: target(0), targetMethod(0), type(InvalidType)
+{
+}
+
+QDeclarativeNotifierEndpoint::QDeclarativeNotifierEndpoint(QObject *t, int m)
+: target(t), targetMethod(m), type(InvalidType)
+{
+}
+
+QDeclarativeNotifierEndpoint::~QDeclarativeNotifierEndpoint()
+{
+ disconnect();
+ if (SignalType == type) {
+ Signal *s = asSignal();
+ s->~Signal();
+ }
+}
+
+bool QDeclarativeNotifierEndpoint::isConnected()
+{
+ if (SignalType == type) {
+ return asSignal()->source;
+ } else if (NotifierType == type) {
+ return asNotifier()->notifier;
+ } else {
+ return false;
+ }
+}
+
+bool QDeclarativeNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
+{
+ return SignalType == type && asSignal()->source == source && asSignal()->sourceSignal == sourceSignal;
+}
+
+bool QDeclarativeNotifierEndpoint::isConnected(QDeclarativeNotifier *notifier)
+{
+ return NotifierType == type && asNotifier()->notifier == notifier;
+}
+
+void QDeclarativeNotifierEndpoint::connect(QObject *source, int sourceSignal)
+{
+ Signal *s = toSignal();
+
+ if (s->source == source && s->sourceSignal == sourceSignal)
+ return;
+
+ disconnect();
+
+ QMetaObject::connect(source, sourceSignal, target, targetMethod);
+
+ s->source = source;
+ s->sourceSignal = sourceSignal;
+}
+
+void QDeclarativeNotifierEndpoint::connect(QDeclarativeNotifier *notifier)
+{
+ Notifier *n = toNotifier();
+
+ if (n->notifier == notifier)
+ return;
+
+ disconnect();
+
+ n->next = notifier->endpoints;
+ if (n->next) { n->next->asNotifier()->prev = &n->next; }
+ notifier->endpoints = this;
+ n->prev = &notifier->endpoints;
+ n->notifier = notifier;
+}
+
+void QDeclarativeNotifierEndpoint::disconnect()
+{
+ if (type == SignalType) {
+ Signal *s = (Signal *)&signalData;
+ if (s->source) {
+ QMetaObject::disconnectOne(s->source, s->sourceSignal, target, targetMethod);
+ s->source = 0;
+ }
+ } else if (type == NotifierType) {
+ Notifier *n = asNotifier();
+
+ if (n->next) n->next->asNotifier()->prev = n->prev;
+ if (n->prev) *n->prev = n->next;
+ if (n->disconnected) *n->disconnected = 0;
+ n->next = 0;
+ n->prev = 0;
+ n->disconnected = 0;
+ n->notifier = 0;
+ }
+}
+
+QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::toNotifier()
+{
+ if (NotifierType == type)
+ return asNotifier();
+
+ if (SignalType == type) {
+ disconnect();
+ Signal *s = asSignal();
+ s->~Signal();
+ }
+
+ Notifier *n = asNotifier();
+ n->next = 0;
+ n->prev = 0;
+ n->disconnected = 0;
+ n->notifier = 0;
+ type = NotifierType;
+ return n;
+}
+
+QDeclarativeNotifierEndpoint::Notifier *QDeclarativeNotifierEndpoint::asNotifier()
+{
+ return (Notifier *)(&notifierData);
+}
+
+QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::toSignal()
+{
+ if (SignalType == type)
+ return asSignal();
+
+ disconnect();
+ Signal *s = asSignal();
+ new (s) Signal;
+ type = SignalType;
+
+ return s;
+}
+
+QDeclarativeNotifierEndpoint::Signal *QDeclarativeNotifierEndpoint::asSignal()
+{
+ return (Signal *)(&signalData);
+}
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVENOTIFIER_P_H
+
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index e6f6e5f..027166a 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -59,6 +59,15 @@ QT_BEGIN_NAMESPACE
struct ObjectData : public QScriptDeclarativeClass::Object {
ObjectData(QObject *o, int t) : object(o), type(t) {}
+
+ virtual ~ObjectData() {
+ if (object && !object->parent()) {
+ QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, false);
+ if (ddata && !ddata->indestructible)
+ object->deleteLater();
+ }
+ }
+
QDeclarativeGuard<QObject> object;
int type;
};
@@ -87,7 +96,7 @@ QDeclarativeObjectScriptClass::~QDeclarativeObjectScriptClass()
{
}
-QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type)
+QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type)
{
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -96,7 +105,11 @@ QScriptValue QDeclarativeObjectScriptClass::newQObject(QObject *object, int type
QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(object, true);
- if (!ddata->scriptValue.isValid()) {
+ if (!ddata) {
+ return scriptEngine->undefinedValue();
+ } else if (!ddata->indestructible && !object->parent()) {
+ return newObject(scriptEngine, this, new ObjectData(object, type));
+ } else if (!ddata->scriptValue.isValid()) {
ddata->scriptValue = newObject(scriptEngine, this, new ObjectData(object, type));
return ddata->scriptValue;
} else if (ddata->scriptValue.engine() == QDeclarativeEnginePrivate::getScriptEngine(engine)) {
@@ -129,7 +142,7 @@ QDeclarativeObjectScriptClass::queryProperty(Object *object, const Identifier &n
QScriptClass::QueryFlags
QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &name,
- QScriptClass::QueryFlags flags, QDeclarativeContext *evalContext,
+ QScriptClass::QueryFlags flags, QDeclarativeContextData *evalContext,
QueryHints hints)
{
Q_UNUSED(flags);
@@ -160,15 +173,11 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam
}
}
- if (evalContext) {
- QDeclarativeContextPrivate *cp = QDeclarativeContextPrivate::get(evalContext);
-
- if (cp->imports) {
- QDeclarativeTypeNameCache::Data *data = cp->imports->data(name);
- if (data) {
- lastTNData = data;
- return QScriptClass::HandlesReadAccess;
- }
+ if (evalContext && evalContext->imports) {
+ QDeclarativeTypeNameCache::Data *data = evalContext->imports->data(name);
+ if (data) {
+ lastTNData = data;
+ return QScriptClass::HandlesReadAccess;
}
}
}
@@ -303,7 +312,7 @@ void QDeclarativeObjectScriptClass::setProperty(Object *object,
void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
const Identifier &name,
const QScriptValue &value,
- QDeclarativeContext *evalContext)
+ QDeclarativeContextData *evalContext)
{
Q_UNUSED(name);
@@ -338,7 +347,8 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
}
}
- QDeclarativeAbstractBinding *delBinding = QDeclarativePropertyPrivate::setBinding(obj, *lastData, 0);
+ QDeclarativeAbstractBinding *delBinding =
+ QDeclarativePropertyPrivate::setBinding(obj, lastData->coreIndex, -1, 0);
if (delBinding)
delBinding->destroy();
@@ -392,17 +402,30 @@ QScriptValue QDeclarativeObjectScriptClass::tostring(QScriptContext *context, QS
QScriptValue QDeclarativeObjectScriptClass::destroy(QScriptContext *context, QScriptEngine *engine)
{
- QObject* obj = context->thisObject().toQObject();
- if(obj){
- int delay = 0;
- if(context->argumentCount() > 0)
- delay = context->argument(0).toInt32();
- if (delay > 0)
- QTimer::singleShot(delay, obj, SLOT(deleteLater()));
- else
- obj->deleteLater();
- }
- return engine->nullValue();
+ QDeclarativeEnginePrivate *p = QDeclarativeEnginePrivate::get(engine);
+ QScriptValue that = context->thisObject();
+
+ if (scriptClass(that) != p->objectClass)
+ return engine->undefinedValue();
+
+ ObjectData *data = (ObjectData *)p->objectClass->object(that);
+ if (!data->object)
+ return engine->undefinedValue();
+
+ QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(data->object, false);
+ if (!ddata || ddata->indestructible)
+ return engine->currentContext()->throwError(QLatin1String("Invalid attempt to destroy() an indestructible object"));
+
+ QObject *obj = data->object;
+ int delay = 0;
+ if (context->argumentCount() > 0)
+ delay = context->argument(0).toInt32();
+ if (delay > 0)
+ QTimer::singleShot(delay, obj, SLOT(deleteLater()));
+ else
+ obj->deleteLater();
+
+ return engine->undefinedValue();
}
QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object)
@@ -428,6 +451,14 @@ QStringList QDeclarativeObjectScriptClass::propertyNames(Object *object)
return cache->propertyNames();
}
+bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2)
+{
+ ObjectData *d1 = (ObjectData *)o1;
+ ObjectData *d2 = (ObjectData *)o2;
+
+ return d1 == d2 || d1->object == d2->object;
+}
+
#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
struct MethodData : public QScriptDeclarativeClass::Object {
@@ -441,6 +472,8 @@ QDeclarativeObjectMethodScriptClass::QDeclarativeObjectMethodScriptClass(QDeclar
: QScriptDeclarativeClass(QDeclarativeEnginePrivate::getScriptEngine(bindEngine)),
engine(bindEngine)
{
+ qRegisterMetaType<QList<QObject *> >("QList<QObject *>");
+
setSupportsCall(true);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
@@ -551,7 +584,7 @@ private:
inline void cleanup();
- char *data[16];
+ void *data[4];
int type;
};
}
@@ -569,11 +602,13 @@ MetaCallArgument::~MetaCallArgument()
void MetaCallArgument::cleanup()
{
if (type == QMetaType::QString) {
- ((QString *)data)->~QString();
+ ((QString *)&data)->~QString();
} else if (type == -1 || type == qMetaTypeId<QVariant>()) {
- ((QVariant *)data)->~QVariant();
+ ((QVariant *)&data)->~QVariant();
} else if (type == qMetaTypeId<QScriptValue>()) {
- ((QScriptValue *)data)->~QScriptValue();
+ ((QScriptValue *)&data)->~QScriptValue();
+ } else if (type == qMetaTypeId<QList<QObject *> >()) {
+ ((QList<QObject *> *)&data)->~QList<QObject *>();
}
}
@@ -582,7 +617,7 @@ void *MetaCallArgument::dataPtr()
if (type == -1)
return ((QVariant *)data)->data();
else
- return (void *)data;
+ return (void *)&data;
}
void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e)
@@ -593,7 +628,7 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e)
QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);
if (callType == qMetaTypeId<QScriptValue>()) {
- new (data) QScriptValue(engine->undefinedValue());
+ new (&data) QScriptValue(engine->undefinedValue());
type = callType;
} else if (callType == QMetaType::Int ||
callType == QMetaType::UInt ||
@@ -602,17 +637,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e)
callType == QMetaType::Float) {
type = callType;
} else if (callType == QMetaType::QObjectStar) {
- *((QObject **)data) = 0;
+ *((QObject **)&data) = 0;
type = callType;
} else if (callType == QMetaType::QString) {
- new (data) QString();
+ new (&data) QString();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
- type = qMetaTypeId<QVariant>();
- new (data) QVariant();
+ type = callType;
+ new (&data) QVariant();
+ } else if (callType == qMetaTypeId<QList<QObject *> >()) {
+ type = callType;
+ new (&data) QList<QObject *>();
} else {
type = -1;
- new (data) QVariant(callType, (void *)0);
+ new (&data) QVariant(callType, (void *)0);
}
}
@@ -621,47 +659,50 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine,
if (type != 0) { cleanup(); type = 0; }
if (callType == qMetaTypeId<QScriptValue>()) {
- new (data) QScriptValue(value);
+ new (&data) QScriptValue(value);
type = qMetaTypeId<QScriptValue>();
} else if (callType == QMetaType::Int) {
- *((int *)data) = int(value.toInt32());
+ *((int *)&data) = int(value.toInt32());
type = callType;
} else if (callType == QMetaType::UInt) {
- *((uint *)data) = uint(value.toUInt32());
+ *((uint *)&data) = uint(value.toUInt32());
type = callType;
} else if (callType == QMetaType::Bool) {
- *((bool *)data) = value.toBool();
+ *((bool *)&data) = value.toBool();
type = callType;
} else if (callType == QMetaType::Double) {
- *((double *)data) = double(value.toNumber());
+ *((double *)&data) = double(value.toNumber());
type = callType;
} else if (callType == QMetaType::Float) {
- *((float *)data) = float(value.toNumber());
+ *((float *)&data) = float(value.toNumber());
type = callType;
} else if (callType == QMetaType::QString) {
if (value.isNull() || value.isUndefined())
- new (data) QString();
+ new (&data) QString();
else
- new (data) QString(value.toString());
+ new (&data) QString(value.toString());
type = callType;
} else if (callType == QMetaType::QObjectStar) {
- *((QObject **)data) = value.toQObject();
+ *((QObject **)&data) = value.toQObject();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
- new (data) QVariant(QDeclarativeScriptClass::toVariant(engine, value));
+ new (&data) QVariant(QDeclarativeScriptClass::toVariant(engine, value));
+ type = callType;
+ } else if (callType == qMetaTypeId<QList<QObject*> >()) {
+ new (&data) QList<QObject *>(); // We don't support passing in QList<QObject*>
type = callType;
} else {
- new (data) QVariant();
+ new (&data) QVariant();
type = -1;
QVariant v = QDeclarativeScriptClass::toVariant(engine, value);
if (v.userType() == callType) {
- *((QVariant *)data) = v;
+ *((QVariant *)&data) = v;
} else if (v.canConvert((QVariant::Type)callType)) {
- *((QVariant *)data) = v;
- ((QVariant *)data)->convert((QVariant::Type)callType);
+ *((QVariant *)&data) = v;
+ ((QVariant *)&data)->convert((QVariant::Type)callType);
} else {
- *((QVariant *)data) = QVariant(callType, (void *)0);
+ *((QVariant *)&data) = QVariant(callType, (void *)0);
}
}
}
@@ -671,23 +712,36 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e)
QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);
if (type == qMetaTypeId<QScriptValue>()) {
- return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)data));
+ return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data));
} else if (type == QMetaType::Int) {
- return QScriptDeclarativeClass::Value(engine, *((int *)data));
+ return QScriptDeclarativeClass::Value(engine, *((int *)&data));
} else if (type == QMetaType::UInt) {
- return QScriptDeclarativeClass::Value(engine, *((uint *)data));
+ return QScriptDeclarativeClass::Value(engine, *((uint *)&data));
} else if (type == QMetaType::Bool) {
- return QScriptDeclarativeClass::Value(engine, *((bool *)data));
+ return QScriptDeclarativeClass::Value(engine, *((bool *)&data));
} else if (type == QMetaType::Double) {
- return QScriptDeclarativeClass::Value(engine, *((double *)data));
+ return QScriptDeclarativeClass::Value(engine, *((double *)&data));
} else if (type == QMetaType::Float) {
- return QScriptDeclarativeClass::Value(engine, *((float *)data));
+ return QScriptDeclarativeClass::Value(engine, *((float *)&data));
} else if (type == QMetaType::QString) {
- return QScriptDeclarativeClass::Value(engine, *((QString *)data));
+ return QScriptDeclarativeClass::Value(engine, *((QString *)&data));
} else if (type == QMetaType::QObjectStar) {
- return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->objectClass->newQObject(*((QObject **)data)));
+ QObject *object = *((QObject **)&data);
+ QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible();
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
+ return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object));
+ } else if (type == qMetaTypeId<QList<QObject *> >()) {
+ QList<QObject *> &list = *(QList<QObject *>*)&data;
+ QScriptValue rv = engine->newArray(list.count());
+ QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
+ for (int ii = 0; ii < list.count(); ++ii) {
+ QObject *object = list.at(ii);
+ QDeclarativeDeclarativeData::get(object, true)->setImplicitDestructible();
+ rv.setProperty(ii, priv->objectClass->newQObject(object));
+ }
+ return QScriptDeclarativeClass::Value(engine, rv);
} else if (type == -1 || type == qMetaTypeId<QVariant>()) {
- return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)data)));
+ return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data)));
} else {
return QScriptDeclarativeClass::Value();
}
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
index 04e760f..396b782 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h
@@ -57,13 +57,14 @@
#include "qdeclarativetypenamecache_p.h"
#include <private/qdeclarativescriptclass_p.h>
+#include <QtScript/qscriptengine.h>
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QScriptContext;
class QScriptEngine;
-class QDeclarativeContext;
+class QDeclarativeContextData;
#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE)
class Q_AUTOTEST_EXPORT QDeclarativeObjectMethodScriptClass : public QScriptDeclarativeClass
@@ -99,6 +100,7 @@ public:
~QDeclarativeObjectScriptClass();
QScriptValue newQObject(QObject *, int type = QMetaType::QObjectStar);
+
QObject *toQObject(const QScriptValue &) const;
int objectType(const QScriptValue &) const;
@@ -110,14 +112,15 @@ public:
QScriptClass::QueryFlags queryProperty(QObject *, const Identifier &,
QScriptClass::QueryFlags flags,
- QDeclarativeContext *evalContext,
+ QDeclarativeContextData *evalContext,
QueryHints hints = 0);
ScriptValue property(QObject *, const Identifier &);
void setProperty(QObject *, const Identifier &name, const QScriptValue &,
- QDeclarativeContext *evalContext = 0);
+ QDeclarativeContextData *evalContext = 0);
virtual QStringList propertyNames(Object *);
+ virtual bool compare(Object *, Object *);
protected:
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
diff --git a/src/declarative/qml/qdeclarativeparser.cpp b/src/declarative/qml/qdeclarativeparser.cpp
index b0599ad..51f1660 100644
--- a/src/declarative/qml/qdeclarativeparser.cpp
+++ b/src/declarative/qml/qdeclarativeparser.cpp
@@ -207,13 +207,14 @@ QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
}
QDeclarativeParser::Property::Property()
-: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false)
+: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
+ isValueTypeSubProperty(false)
{
}
QDeclarativeParser::Property::Property(const QByteArray &n)
: parent(0), type(0), index(-1), value(0), name(n), isDefault(false),
- isDeferred(false)
+ isDeferred(false), isValueTypeSubProperty(false)
{
}
diff --git a/src/declarative/qml/qdeclarativeparser_p.h b/src/declarative/qml/qdeclarativeparser_p.h
index 5bf4b68..9dfb86b 100644
--- a/src/declarative/qml/qdeclarativeparser_p.h
+++ b/src/declarative/qml/qdeclarativeparser_p.h
@@ -351,6 +351,8 @@ namespace QDeclarativeParser
// True if the setting of this property will be deferred. Set by the
// QDeclarativeCompiler
bool isDeferred;
+ // True if this property is a value-type psuedo-property
+ bool isValueTypeSubProperty;
LocationSpan location;
LocationRange listValueRange;
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index 01369d4..bebe82c 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -73,6 +73,9 @@ namespace QDeclarativePrivate
QObject *create() { return new T; }
template<typename T>
+ void createInto(void *memory) { new (memory) T; }
+
+ template<typename T>
QObject *createParent(QObject *p) { return new T(p); }
template<class From, class To, int N>
@@ -172,7 +175,8 @@ namespace QDeclarativePrivate
int typeId;
int listId;
- QObject *(*create)();
+ int objectSize;
+ void (*create)(void *);
const char *uri;
int versionMajor;
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 945d098..caa1acf 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -124,7 +124,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ct
: d(new QDeclarativePropertyPrivate)
{
d->q = this;
- d->context = ctxt;
+ d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
d->engine = ctxt?ctxt->engine():0;
d->initDefault(obj);
}
@@ -177,7 +177,7 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD
: d(new QDeclarativePropertyPrivate)
{
d->q = this;
- d->context = ctxt;
+ d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
d->engine = ctxt?ctxt->engine():0;
d->initProperty(obj, name);
if (!isValid()) { d->object = 0; d->context = 0; d->engine = 0; }
@@ -204,7 +204,7 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
{
if (!obj) return;
- QDeclarativeTypeNameCache *typeNameCache = context?QDeclarativeContextPrivate::get(context)->imports:0;
+ QDeclarativeTypeNameCache *typeNameCache = context?context->imports:0;
QStringList path = name.split(QLatin1Char('.'));
if (path.isEmpty()) return;
@@ -494,15 +494,13 @@ QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty
*/
bool QDeclarativeProperty::isWritable() const
{
- QDeclarativeProperty::PropertyTypeCategory category = propertyTypeCategory();
-
if (!d->object)
return false;
- if (category == List)
+ if (d->core.flags & QDeclarativePropertyCache::Data::IsQList) //list
return true;
- else if (type() & SignalProperty)
+ else if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction) //signal handler
return false;
- else if (d->core.isValid() && d->object)
+ else if (d->core.isValid()) //normal property
return d->core.flags & QDeclarativePropertyCache::Data::IsWritable;
else
return false;
@@ -598,7 +596,6 @@ QMetaMethod QDeclarativeProperty::method() const
return QMetaMethod();
}
-
/*!
Returns the binding associated with this property, or 0 if no binding
exists.
@@ -617,13 +614,18 @@ QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that)
return 0;
QDeclarativeAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == that.d->core.coreIndex)
- return binding;
+ while (binding && binding->propertyIndex() != that.d->core.coreIndex)
binding = binding->m_nextBinding;
+
+ if (binding && that.d->valueType.valueTypeCoreIdx != -1) {
+ if (binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) {
+ QDeclarativeValueTypeProxyBinding *proxy = static_cast<QDeclarativeValueTypeProxyBinding *>(binding);
+
+ binding = proxy->binding(bindingIndex(that));
+ }
}
- return 0;
+
+ return binding;
}
/*!
@@ -650,36 +652,36 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that,
return 0;
}
- return that.d->setBinding(that.d->object, that.d->core, newBinding, flags);
+ return that.d->setBinding(that.d->object, that.d->core.coreIndex,
+ that.d->valueType.valueTypeCoreIdx, newBinding, flags);
}
QDeclarativeAbstractBinding *
-QDeclarativePropertyPrivate::setBinding(QObject *object, const QDeclarativePropertyCache::Data &core,
- QDeclarativeAbstractBinding *newBinding, WriteFlags flags)
+QDeclarativePropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex,
+ QDeclarativeAbstractBinding *newBinding, WriteFlags flags)
{
QDeclarativeDeclarativeData *data = QDeclarativeDeclarativeData::get(object, 0 != newBinding);
+ QDeclarativeAbstractBinding *binding = 0;
- if (data && data->hasBindingBit(core.coreIndex)) {
- QDeclarativeAbstractBinding *binding = data->bindings;
- while (binding) {
- // ### This wont work for value types
- if (binding->propertyIndex() == core.coreIndex) {
- binding->setEnabled(false);
+ if (data && data->hasBindingBit(coreIndex)) {
+ binding = data->bindings;
- if (newBinding)
- newBinding->setEnabled(true, flags);
+ while (binding && binding->propertyIndex() != coreIndex)
+ binding = binding->m_nextBinding;
+ }
- return binding; // ### QDeclarativeAbstractBinding;
- }
+ if (binding && valueTypeIndex != -1 && binding->bindingType() == QDeclarativeAbstractBinding::ValueTypeProxy) {
+ int index = coreIndex | (valueTypeIndex << 24);
+ binding = static_cast<QDeclarativeValueTypeProxyBinding *>(binding)->binding(index);
+ }
- binding = binding->m_nextBinding;
- }
- }
+ if (binding)
+ binding->setEnabled(false);
- if (newBinding)
+ if (newBinding)
newBinding->setEnabled(true, flags);
- return 0;
+ return binding;
}
/*!
@@ -922,7 +924,7 @@ bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, Writ
}
bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePropertyCache::Data &property,
- const QVariant &value, QDeclarativeContext *context,
+ const QVariant &value, QDeclarativeContextData *context,
WriteFlags flags)
{
int coreIdx = property.coreIndex;
@@ -1253,6 +1255,18 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &
return that.d->valueType.valueTypeCoreIdx;
}
+/*!
+ Returns the "property index" for use in bindings. The top 8 bits are the value type
+ offset, and 0 otherwise. The bottom 24-bits are the regular property index.
+*/
+int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that)
+{
+ int rv = that.d->core.coreIndex;
+ if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1)
+ rv = rv | (that.d->valueType.valueTypeCoreIdx << 24);
+ return rv;
+}
+
struct SerializedData {
bool isValueType;
QDeclarativePropertyCache::Data core;
@@ -1291,7 +1305,7 @@ QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObje
}
QDeclarativeProperty
-QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContext *ctxt)
+QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QDeclarativeContextData *ctxt)
{
QDeclarativeProperty prop;
@@ -1300,7 +1314,7 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD
prop.d->object = object;
prop.d->context = ctxt;
- prop.d->engine = ctxt?ctxt->engine():0;
+ prop.d->engine = ctxt->engine;
const SerializedData *sd = (const SerializedData *)data.constData();
if (sd->isValueType) {
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index c31e2d3..1bbee64 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -82,7 +82,7 @@ public:
valueType(other.valueType) {}
QDeclarativeProperty *q;
- QDeclarativeContext *context;
+ QDeclarativeContextData *context;
QDeclarativeEngine *engine;
QDeclarativeGuard<QObject> object;
@@ -109,15 +109,15 @@ public:
static bool writeEnumProperty(const QMetaProperty &prop, int idx, QObject *object,
const QVariant &value, int flags);
static bool write(QObject *, const QDeclarativePropertyCache::Data &, const QVariant &,
- QDeclarativeContext *, WriteFlags flags = 0);
- static QDeclarativeAbstractBinding *setBinding(QObject *, const QDeclarativePropertyCache::Data &,
+ QDeclarativeContextData *, WriteFlags flags = 0);
+ static QDeclarativeAbstractBinding *setBinding(QObject *, int coreIndex, int valueTypeIndex /* -1 */,
QDeclarativeAbstractBinding *,
WriteFlags flags = DontRemoveBinding);
static QByteArray saveValueType(const QMetaObject *, int,
const QMetaObject *, int);
static QByteArray saveProperty(const QMetaObject *, int);
- static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContext *);
+ static QDeclarativeProperty restore(const QByteArray &, QObject *, QDeclarativeContextData *);
static bool equal(const QMetaObject *, const QMetaObject *);
static bool canConvert(const QMetaObject *from, const QMetaObject *to);
@@ -133,6 +133,7 @@ public:
QDeclarativeExpression *) ;
static bool write(const QDeclarativeProperty &that, const QVariant &, WriteFlags);
static int valueTypeCoreIndex(const QDeclarativeProperty &that);
+ static int bindingIndex(const QDeclarativeProperty &that);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePropertyPrivate::WriteFlags)
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index 68e6e6b..bfbeff4 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -55,15 +55,16 @@
#include "qdeclarativerefcount_p.h"
#include "qdeclarativecleanup_p.h"
+#include "qdeclarativenotifier_p.h"
#include <QtCore/qvector.h>
#include <QtScript/private/qscriptdeclarativeclass_p.h>
-
QT_BEGIN_NAMESPACE
class QDeclarativeEngine;
class QMetaProperty;
+
class QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup
{
public:
@@ -83,9 +84,9 @@ public:
IsResettable = 0x00000004,
// These are mutualy exclusive
- IsFunction = 0x00000008,
- IsQObjectDerived = 0x00000010,
- IsEnumType = 0x00000020,
+ IsFunction = 0x00000010,
+ IsQObjectDerived = 0x00000020,
+ IsEnumType = 0x00000040,
IsQList = 0x00000080,
IsQmlBinding = 0x00000100,
IsQScriptValue = 0x00000200,
@@ -96,7 +97,7 @@ public:
};
Q_DECLARE_FLAGS(Flags, Flag)
-
+
bool isValid() const { return coreIndex != -1; }
Flags flags;
@@ -114,9 +115,9 @@ public:
struct ValueTypeData {
inline ValueTypeData();
inline bool operator==(const ValueTypeData &);
- Data::Flags flags; // flags on the value type wrapper
- int valueTypeCoreIdx; // The prop index of the access property on the value type wrapper
- int valueTypePropType; // The QVariant::Type of access property on the value type wrapper
+ Data::Flags flags; // flags of the access property on the value type proxy object
+ int valueTypeCoreIdx; // The prop index of the access property on the value type proxy object
+ int valueTypePropType; // The QVariant::Type of access property on the value type proxy object
};
void update(QDeclarativeEngine *, const QMetaObject *);
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index c070123..00e6704 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -61,7 +61,7 @@ int qmlRegisterValueTypeEnums(const char *qmlName)
QDeclarativePrivate::RegisterType type = {
0,
- qRegisterMetaType<T *>(pointerName.constData()), 0, 0,
+ qRegisterMetaType<T *>(pointerName.constData()), 0, 0, 0,
"Qt", 4, 6, qmlName, &T::staticMetaObject,
diff --git a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
index 9cb65f8..a567c38 100644
--- a/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativevaluetypescriptclass.cpp
@@ -41,6 +41,8 @@
#include "qdeclarativevaluetypescriptclass_p.h"
+#include "qdeclarativebinding_p.h"
+#include "qdeclarativeproperty_p.h"
#include "qdeclarativeengine_p.h"
#include "qdeclarativeguard_p.h"
@@ -115,6 +117,11 @@ void QDeclarativeValueTypeScriptClass::setProperty(Object *obj, const Identifier
{
QDeclarativeValueTypeReference *ref = static_cast<QDeclarativeValueTypeReference *>(obj);
+ QDeclarativeAbstractBinding *delBinding =
+ QDeclarativePropertyPrivate::setBinding(ref->object, ref->property, m_lastIndex, 0);
+ if (delBinding)
+ delBinding->destroy();
+
QVariant v = QDeclarativeScriptClass::toVariant(engine, value);
ref->type->read(ref->object, ref->property);
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index 6a08674..4457404 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -100,9 +100,8 @@ struct ListInstance
QDeclarativeListProperty<void> qListProperty;
};
-QObject *QDeclarativeVME::run(QDeclarativeContext *ctxt, QDeclarativeCompiledData *comp,
- int start, int count,
- const QBitField &bindingSkipList)
+QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp,
+ int start, int count, const QBitField &bindingSkipList)
{
QDeclarativeVMEStack<QObject *> stack;
@@ -119,7 +118,7 @@ void QDeclarativeVME::runDeferred(QObject *object)
if (!data || !data->context || !data->deferredComponent)
return;
- QDeclarativeContext *ctxt = data->context;
+ QDeclarativeContextData *ctxt = data->context;
QDeclarativeCompiledData *comp = data->deferredComponent;
int start = data->deferredIdx + 1;
int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount;
@@ -129,10 +128,11 @@ void QDeclarativeVME::runDeferred(QObject *object)
run(stack, ctxt, comp, start, count, QBitField());
}
-QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarativeContext *ctxt,
- QDeclarativeCompiledData *comp,
- int start, int count,
- const QBitField &bindingSkipList)
+QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
+ QDeclarativeContextData *ctxt,
+ QDeclarativeCompiledData *comp,
+ int start, int count,
+ const QBitField &bindingSkipList)
{
Q_ASSERT(comp);
Q_ASSERT(ctxt);
@@ -152,8 +152,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
QDeclarativeVMEStack<ListInstance> qliststack;
vmeErrors.clear();
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine());
- QDeclarativeContextPrivate *cp = (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt);
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
int status = -1; //for dbus
QDeclarativePropertyPrivate::WriteFlags flags = QDeclarativePropertyPrivate::BypassInterceptor;
@@ -169,9 +168,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
if (instr.init.parserStatusSize)
parserStatus = QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus>(instr.init.parserStatusSize);
if (instr.init.contextCache != -1)
- cp->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache));
+ ctxt->setIdPropertyData(comp->contextCaches.at(instr.init.contextCache));
if (instr.init.compiledBinding != -1)
- cp->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt);
+ ctxt->optimizedBindings = new QDeclarativeCompiledBindings(datas.at(instr.init.compiledBinding).constData(), ctxt);
}
break;
@@ -188,6 +187,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
QObject *o =
types.at(instr.create.type).createInstance(ctxt, bindings);
+
if (!o) {
if(types.at(instr.create.type).component)
vmeErrors << types.at(instr.create.type).component->errors();
@@ -197,6 +197,25 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(o);
Q_ASSERT(ddata);
+
+ if (stack.isEmpty()) {
+ if (ddata->context) {
+ Q_ASSERT(ddata->context != ctxt);
+ Q_ASSERT(ddata->outerContext);
+ Q_ASSERT(ddata->outerContext != ctxt);
+ QDeclarativeContextData *c = ddata->context;
+ while (c->linkedContext) c = c->linkedContext;
+ c->linkedContext = ctxt;
+ } else {
+ ctxt->addObject(o);
+ }
+
+ ddata->ownContext = true;
+ } else if (!ddata->context) {
+ ctxt->addObject(o);
+ }
+
+ ddata->setImplicitDestructible();
ddata->outerContext = ctxt;
ddata->lineNumber = instr.line;
ddata->columnNumber = instr.create.column;
@@ -228,25 +247,31 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
case QDeclarativeInstruction::SetId:
{
QObject *target = stack.top();
- cp->setIdProperty(instr.setId.index, target);
+ ctxt->setIdProperty(instr.setId.index, target);
}
break;
case QDeclarativeInstruction::SetDefault:
{
- QObject *target = stack.top();
- ctxt->addDefaultObject(target);
+ ctxt->contextObject = stack.top();
}
break;
case QDeclarativeInstruction::CreateComponent:
{
- QObject *qcomp = new QDeclarativeComponent(ctxt->engine(), comp, ii + 1, instr.createComponent.count, stack.isEmpty() ? 0 : stack.top());
+ QObject *qcomp = new QDeclarativeComponent(ctxt->engine, comp, ii + 1, instr.createComponent.count,
+ stack.isEmpty() ? 0 : stack.top());
- QDeclarativeEngine::setContextForObject(qcomp, ctxt);
- QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp);
+ QDeclarativeDeclarativeData *ddata = QDeclarativeDeclarativeData::get(qcomp, true);
Q_ASSERT(ddata);
+
+ ctxt->addObject(qcomp);
+
+ if (stack.isEmpty())
+ ddata->ownContext = true;
+
+ ddata->setImplicitDestructible();
ddata->outerContext = ctxt;
ddata->lineNumber = instr.line;
ddata->columnNumber = instr.create.column;
@@ -553,7 +578,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
case QDeclarativeInstruction::StoreScript:
{
QObject *target = stack.top();
- cp->addScript(scripts.at(instr.storeScript.value), target);
+ ctxt->addScript(scripts.at(instr.storeScript.value), target);
}
break;
@@ -562,7 +587,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
QObject *target = stack.top();
QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope);
QDeclarativeScriptString ss;
- ss.setContext(ctxt);
+ ss.setContext(ctxt->asQDeclarativeContext());
ss.setScopeObject(scope);
ss.setScript(primitives.at(instr.storeScriptString.value));
@@ -618,7 +643,7 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
break;
QDeclarativeAbstractBinding *binding =
- cp->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property);
+ ctxt->optimizedBindings->configBinding(instr.assignBinding.value, target, scope, property);
bindValues.append(binding);
binding->m_mePtr = &bindValues.values[bindValues.count - 1];
binding->addToObject(target);
@@ -819,7 +844,9 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
if (isError()) {
if (!stack.isEmpty()) {
- delete stack.at(0);
+ delete stack.at(0); // ### What about failures in deferred creation?
+ } else {
+ ctxt->destroy();
}
QDeclarativeEnginePrivate::clear(bindValues);
@@ -832,11 +859,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, QDeclarati
if (parserStatus.count)
ep->parserStatus << parserStatus;
- if (stack.isEmpty())
- return 0;
- else
- return stack.top();
- return 0;
+ Q_ASSERT(stack.count() == 1);
+ return stack.top();
}
bool QDeclarativeVME::isError() const
@@ -849,4 +873,25 @@ QList<QDeclarativeError> QDeclarativeVME::errors() const
return vmeErrors;
}
+QObject *
+QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData *ctxt,
+ const QBitField &bindings) const
+{
+ if (type) {
+ QObject *rv = 0;
+ void *memory = 0;
+
+ type->create(&rv, &memory, sizeof(QDeclarativeDeclarativeData));
+ QDeclarativeDeclarativeData *ddata = new (memory) QDeclarativeDeclarativeData;
+ ddata->ownMemory = false;
+ QObjectPrivate::get(rv)->declarativeData = ddata;
+
+ return rv;
+ } else {
+ Q_ASSERT(component);
+ return QDeclarativeComponentPrivate::get(component)->create(ctxt, bindings);
+ }
+}
+
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h
index 951f6a7..1c6fd3c 100644
--- a/src/declarative/qml/qdeclarativevme_p.h
+++ b/src/declarative/qml/qdeclarativevme_p.h
@@ -65,13 +65,13 @@ class QObject;
class QDeclarativeInstruction;
class QDeclarativeCompiledData;
class QDeclarativeCompiledData;
-class QDeclarativeContext;
+class QDeclarativeContextData;
template<typename T, int N = 128>
class QDeclarativeVMEStack {
public:
- QDeclarativeVMEStack() : index(-1), maxSize(N), data(fixedData) {}
- ~QDeclarativeVMEStack() { if (data != fixedData) qFree(fixedData); }
+ QDeclarativeVMEStack() : index(-1), maxSize(N), data((T *)fixedData) {}
+ ~QDeclarativeVMEStack() { if (data != (T *)fixedData) qFree(data); }
bool isEmpty() const { return index == -1; }
const T &top() const { return data[index]; }
@@ -83,7 +83,7 @@ public:
private:
void realloc() {
maxSize += N;
- if (data != fixedData) {
+ if (data != (T *)fixedData) {
data = (T*)qRealloc(data, maxSize * sizeof(T));
} else {
data = (T*)qMalloc(maxSize * sizeof(T));
@@ -92,7 +92,7 @@ private:
int index;
int maxSize;
T *data;
- T fixedData[N];
+ char fixedData[N * sizeof(T)];
};
class QDeclarativeVME
@@ -100,7 +100,7 @@ class QDeclarativeVME
public:
QDeclarativeVME();
- QObject *run(QDeclarativeContext *, QDeclarativeCompiledData *,
+ QObject *run(QDeclarativeContextData *, QDeclarativeCompiledData *,
int start = -1, int count = -1,
const QBitField & = QBitField());
void runDeferred(QObject *);
@@ -109,8 +109,10 @@ public:
QList<QDeclarativeError> errors() const;
private:
- QObject *run(QDeclarativeVMEStack<QObject *> &, QDeclarativeContext *, QDeclarativeCompiledData *,
- int start, int count, const QBitField &);
+ QObject *run(QDeclarativeVMEStack<QObject *> &,
+ QDeclarativeContextData *, QDeclarativeCompiledData *,
+ int start, int count,
+ const QBitField &);
QList<QDeclarativeError> vmeErrors;
};
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index d67c834..f9c99ee 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -55,11 +55,11 @@
QT_BEGIN_NAMESPACE
QDeclarativeVMEMetaObject::QDeclarativeVMEMetaObject(QObject *obj,
- const QMetaObject *other,
- const QDeclarativeVMEMetaData *meta,
- QDeclarativeCompiledData *cdata)
-: object(obj), compiledData(cdata), ctxt(qmlContext(obj)), metaData(meta), methods(0),
- parent(0)
+ const QMetaObject *other,
+ const QDeclarativeVMEMetaData *meta,
+ QDeclarativeCompiledData *cdata)
+: object(obj), compiledData(cdata), ctxt(QDeclarativeDeclarativeData::get(obj)->outerContext),
+ metaData(meta), methods(0), parent(0)
{
compiledData->addref();
@@ -115,7 +115,7 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
if (type != QVariant::Invalid) {
if (valueIndex != -1) {
- QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine()):0;
+ QDeclarativeEnginePrivate *ep = ctxt?QDeclarativeEnginePrivate::get(ctxt->engine):0;
QDeclarativeValueType *valueType = 0;
if (ep) valueType = ep->valueTypes[type];
else valueType = QDeclarativeValueTypeFactory::valueType(type);
@@ -214,16 +214,17 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
*reinterpret_cast<void **>(a[0]) = 0;
if (!ctxt) return -1;
- QDeclarativeContextPrivate *ctxtPriv =
- (QDeclarativeContextPrivate *)QObjectPrivate::get(ctxt);
- QObject *target = ctxtPriv->idValues[d->contextIdx].data();
+ QDeclarativeContext *context = ctxt->asQDeclarativeContext();
+ QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(context);
+
+ QObject *target = ctxtPriv->data->idValues[d->contextIdx].data();
if (!target)
return -1;
if (c == QMetaObject::ReadProperty && !aConnected.testBit(id)) {
int sigIdx = methodOffset + id + metaData->propertyCount;
- QMetaObject::connect(ctxt, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx);
+ QMetaObject::connect(context, d->contextIdx + ctxtPriv->notifyIndex, object, sigIdx);
if (d->propertyIdx != -1) {
QMetaProperty prop =
@@ -262,10 +263,10 @@ int QDeclarativeVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
id -= plainSignals;
if (id < metaData->methodCount) {
- if (!ctxt->engine())
+ if (!ctxt->engine)
return -1; // We can't run the method
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine());
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(ctxt->engine);
QScriptValue function = method(id);
diff --git a/src/declarative/qml/qdeclarativevmemetaobject_p.h b/src/declarative/qml/qdeclarativevmemetaobject_p.h
index 37c0b7a..e11f6fa 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject_p.h
+++ b/src/declarative/qml/qdeclarativevmemetaobject_p.h
@@ -63,6 +63,7 @@
#include "qdeclarativeguard_p.h"
#include "qdeclarativecompiler_p.h"
+#include "qdeclarativecontext_p.h"
QT_BEGIN_NAMESPACE
@@ -121,7 +122,7 @@ protected:
private:
QObject *object;
QDeclarativeCompiledData *compiledData;
- QDeclarativeGuard<QDeclarativeContext> ctxt;
+ QDeclarativeGuardedContextData ctxt;
const QDeclarativeVMEMetaData *metaData;
int propOffset;
diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp
index 784353a..10c0b54 100644
--- a/src/declarative/qml/qdeclarativeworkerscript.cpp
+++ b/src/declarative/qml/qdeclarativeworkerscript.cpp
@@ -40,7 +40,8 @@
****************************************************************************/
#include "qdeclarativeworkerscript_p.h"
-
+#include "qdeclarativelistmodel_p.h"
+#include "qdeclarativelistmodelworkeragent_p.h"
#include "qdeclarativeengine_p.h"
#include <QtCore/qcoreevent.h>
@@ -104,6 +105,7 @@ private:
class QDeclarativeWorkerScriptEnginePrivate : public QObject
{
+ Q_OBJECT
public:
QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *eng);
@@ -165,87 +167,6 @@ private:
void processLoad(int, const QUrl &);
};
-// Currently this will leak as no-one releases it in the worker thread
-class QDeclarativeWorkerListModelAgent : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(int count READ count)
-
-public:
- QDeclarativeWorkerListModelAgent(QDeclarativeWorkerListModel *);
- ~QDeclarativeWorkerListModelAgent();
-
- void addref();
- void release();
-
- int count() const;
-
- Q_INVOKABLE void clear();
- Q_INVOKABLE void remove(int index);
- Q_INVOKABLE void append(const QScriptValue &);
- Q_INVOKABLE void insert(int index, const QScriptValue&);
- Q_INVOKABLE QScriptValue get(int index) const;
- Q_INVOKABLE void set(int index, const QScriptValue &);
- Q_INVOKABLE void sync();
-
- struct VariantRef
- {
- VariantRef() : a(0) {}
- VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); }
- VariantRef(QDeclarativeWorkerListModelAgent *_a) : a(_a) { if (a) a->addref(); }
- ~VariantRef() { if (a) a->release(); }
-
- VariantRef &operator=(const VariantRef &o) {
- if (o.a) o.a->addref();
- if (a) a->release(); a = o.a;
- return *this;
- }
-
- QDeclarativeWorkerListModelAgent *a;
- };
-protected:
- virtual bool event(QEvent *);
-
-private:
- friend class QDeclarativeWorkerScriptEnginePrivate;
- friend class QDeclarativeWorkerListModel;
- QScriptEngine *m_engine;
-
- struct Change {
- enum { Inserted, Removed, Moved, Changed } type;
- int index; // Inserted/Removed/Moved/Changed
- int count; // Inserted/Removed/Moved/Changed
- int to; // Moved
- };
-
- struct Data {
- QHash<int, QString> roles;
- QHash<QString, int> strings;
- QList<QHash<int, QVariant> > values;
- QList<Change> changes;
-
- void clearChange();
- void insertChange(int index, int count);
- void removeChange(int index, int count);
- void changedChange(int index, int count);
- };
- Data data;
-
- struct Sync : public QEvent {
- Sync() : QEvent(QEvent::User) {}
- Data data;
- };
-
- QAtomicInt m_ref;
- QDeclarativeWorkerListModel *m_model;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QDeclarativeWorkerListModelAgent::VariantRef);
-
-QT_BEGIN_NAMESPACE
-
QDeclarativeWorkerScriptEnginePrivate::QDeclarativeWorkerScriptEnginePrivate(QDeclarativeEngine *engine)
: workerEngine(0), qmlengine(engine), m_nextId(0)
{
@@ -390,10 +311,15 @@ QVariant QDeclarativeWorkerScriptEnginePrivate::scriptValueToVariant(const QScri
return QVariant(list);
} else if (value.isQObject()) {
- QDeclarativeWorkerListModel *lm = qobject_cast<QDeclarativeWorkerListModel *>(value.toQObject());
+ QDeclarativeListModel *lm = qobject_cast<QDeclarativeListModel *>(value.toQObject());
if (lm) {
- QDeclarativeWorkerListModelAgent::VariantRef v(lm->agent());
- return qVariantFromValue(v);
+ QDeclarativeListModelWorkerAgent *agent = lm->agent();
+ if (agent) {
+ QDeclarativeListModelWorkerAgent::VariantRef v(agent);
+ return qVariantFromValue(v);
+ } else {
+ return QVariant();
+ }
} else {
// No other QObject's are allowed to be sent
return QVariant();
@@ -423,11 +349,11 @@ QScriptValue QDeclarativeWorkerScriptEnginePrivate::variantToScriptValue(const Q
return QScriptValue(value.toString());
} else if (value.userType() == QMetaType::QReal) {
return QScriptValue(value.toReal());
- } else if (value.userType() == qMetaTypeId<QDeclarativeWorkerListModelAgent::VariantRef>()) {
- QDeclarativeWorkerListModelAgent::VariantRef vr = qvariant_cast<QDeclarativeWorkerListModelAgent::VariantRef>(value);
- if (vr.a->m_engine == 0)
- vr.a->m_engine = engine;
- else if (vr.a->m_engine != engine)
+ } else if (value.userType() == qMetaTypeId<QDeclarativeListModelWorkerAgent::VariantRef>()) {
+ QDeclarativeListModelWorkerAgent::VariantRef vr = qvariant_cast<QDeclarativeListModelWorkerAgent::VariantRef>(value);
+ if (vr.a->scriptEngine() == 0)
+ vr.a->setScriptEngine(engine);
+ else if (vr.a->scriptEngine() != engine)
return engine->nullValue();
QScriptValue o = engine->newQObject(vr.a);
o.setData(engine->newVariant(value)); // Keeps the agent ref so that it is cleaned up on gc
@@ -619,8 +545,6 @@ void QDeclarativeWorkerScriptEngine::run()
called, triggering the \tt WorkerScript.onMessage() handler in
\tt source.js. This in turn sends a reply message that is then received
by the \tt onMessage() handler of \tt myWorker.
-
- \sa WorkerListModel
*/
QDeclarativeWorkerScript::QDeclarativeWorkerScript(QObject *parent)
: QObject(parent), m_engine(0), m_scriptId(-1)
@@ -714,544 +638,7 @@ bool QDeclarativeWorkerScript::event(QEvent *event)
}
}
-void QDeclarativeWorkerListModelAgent::Data::clearChange()
-{
- changes.clear();
-}
-
-void QDeclarativeWorkerListModelAgent::Data::insertChange(int index, int count)
-{
- Change c = { Change::Inserted, index, count, 0 };
- changes << c;
-}
-
-void QDeclarativeWorkerListModelAgent::Data::removeChange(int index, int count)
-{
- Change c = { Change::Removed, index, count, 0 };
- changes << c;
-}
-
-void QDeclarativeWorkerListModelAgent::Data::changedChange(int index, int count)
-{
- Change c = { Change::Changed, index, count, 0 };
- changes << c;
-}
-
-QDeclarativeWorkerListModelAgent::QDeclarativeWorkerListModelAgent(QDeclarativeWorkerListModel *m)
-: m_engine(0), m_ref(1), m_model(m)
-{
- data.roles = m_model->m_roles;
- data.strings = m_model->m_strings;
- data.values = m_model->m_values;
-}
-
-QDeclarativeWorkerListModelAgent::~QDeclarativeWorkerListModelAgent()
-{
-}
-
-void QDeclarativeWorkerListModelAgent::addref()
-{
- m_ref.ref();
-}
-
-void QDeclarativeWorkerListModelAgent::release()
-{
- bool del = !m_ref.deref();
-
- if (del)
- delete this;
-}
-
-int QDeclarativeWorkerListModelAgent::count() const
-{
- return data.values.count();
-}
-
-void QDeclarativeWorkerListModelAgent::clear()
-{
- data.clearChange();
- data.removeChange(0, data.values.count());
- data.values.clear();
-}
-
-void QDeclarativeWorkerListModelAgent::remove(int index)
-{
- if (data.values.count() <= index)
- return;
-
- data.values.removeAt(index);
- data.removeChange(index, 1);
-}
-
-void QDeclarativeWorkerListModelAgent::append(const QScriptValue &value)
-{
- QHash<int, QVariant> row;
-
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = data.strings.find(name);
- if (iter == data.strings.end()) {
- int role = data.roles.count();
- data.roles.insert(role, name);
- iter = data.strings.insert(name, role);
- }
- row.insert(*iter, v);
- }
-
- data.values.append(row);
- data.insertChange(data.values.count() - 1, 1);
-}
-
-void QDeclarativeWorkerListModelAgent::insert(int index, const QScriptValue &value)
-{
- if (index > data.values.count())
- return;
-
- QHash<int, QVariant> row;
-
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = data.strings.find(name);
- if (iter == data.strings.end()) {
- int role = data.roles.count();
- data.roles.insert(role, name);
- iter = data.strings.insert(name, role);
- }
- row.insert(*iter, v);
- }
-
- data.values.insert(index, row);
- data.insertChange(index, 1);
-}
-
-void QDeclarativeWorkerListModelAgent::set(int index, const QScriptValue &value)
-{
- if (data.values.count() <= index)
- return;
-
- QHash<int, QVariant> row;
-
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = data.strings.find(name);
- if (iter == data.strings.end()) {
- int role = data.roles.count();
- data.roles.insert(role, name);
- iter = data.strings.insert(name, role);
- }
- row.insert(*iter, v);
- }
-
- if (data.values.at(index) != row) {
- data.values[index] = row;
- data.changedChange(index, 1);
- }
-}
-
-QScriptValue QDeclarativeWorkerListModelAgent::get(int index) const
-{
- if (data.values.count() <= index)
- return m_engine->undefinedValue();
-
- QScriptValue rv = m_engine->newObject();
-
- QHash<int, QVariant> row = data.values.at(index);
- for (QHash<int, QVariant>::ConstIterator iter = row.begin(); iter != row.end(); ++iter)
- rv.setProperty(data.roles.value(iter.key()), qScriptValueFromValue(m_engine, iter.value()));
-
- return rv;
-}
-
-void QDeclarativeWorkerListModelAgent::sync()
-{
- Sync *s = new Sync;
- s->data = data;
- data.changes.clear();
- QCoreApplication::postEvent(this, s);
-}
-
-bool QDeclarativeWorkerListModelAgent::event(QEvent *e)
-{
- if (e->type() == QEvent::User) {
- Sync *s = static_cast<Sync *>(e);
-
- const QList<Change> &changes = s->data.changes;
-
- if (m_model) {
- bool cc = m_model->m_values.count() != s->data.values.count();
-
- m_model->m_roles = s->data.roles;
- m_model->m_strings = s->data.strings;
- m_model->m_values = s->data.values;
-
- for (int ii = 0; ii < changes.count(); ++ii) {
- const Change &change = changes.at(ii);
- switch (change.type) {
- case Change::Inserted:
- emit m_model->itemsInserted(change.index, change.count);
- break;
- case Change::Removed:
- emit m_model->itemsRemoved(change.index, change.count);
- break;
- case Change::Moved:
- emit m_model->itemsMoved(change.index, change.to, change.count);
- break;
- case Change::Changed:
- emit m_model->itemsMoved(change.index, change.to, change.count);
- break;
- }
- }
-
- if (cc)
- emit m_model->countChanged();
- }
- }
-
- return QObject::event(e);
-}
-
-/*!
- \qmlclass WorkerListModel QDeclarativeWorkerListModel
- \brief The WorkerListModel element provides a threaded list model.
-
- Use WorkerListModel together with WorkerScript to define a list model
- that is controlled by a separate thread. This is useful if list modification
- operations are synchronous and take some time: using WorkerListModel
- moves these operations to a different thread and avoids blocking of the
- main GUI thread.
-
- The thread that creates the WorkerListModel can modify the model for any
- initial set-up requirements. However, once the model has been modified by
- the associated WorkerScript, the model can only be modified by that worker
- script and becomes read-only to all other threads.
-
- Here is an example application that uses WorkerScript to append the
- current time to a WorkerListModel:
-
- \snippet examples/declarative/workerlistmodel/timedisplay.qml 0
-
- The included file, \tt dataloader.js, looks like this:
-
- \snippet examples/declarative/workerlistmodel/dataloader.js 0
-
- The application's \tt Timer object periodically sends a message to the
- worker script by calling \tt WorkerScript::sendMessage(). When this message
- is received, \tt WorkerScript.onMessage() is invoked in
- \tt dataloader.js, which appends the current time to the worker list
- model.
-
- Note that unlike ListModel, WorkerListModel does not have \tt move() and
- \tt setProperty() methods.
-
- \sa WorkerScript, ListModel
-*/
-QDeclarativeWorkerListModel::QDeclarativeWorkerListModel(QObject *parent)
-: QListModelInterface(parent), m_agent(0)
-{
-}
-
-QDeclarativeWorkerListModel::~QDeclarativeWorkerListModel()
-{
- if (m_agent) {
- m_agent->m_model = 0;
- m_agent->release();
- }
-}
-
-/*!
- \qmlmethod WorkerListModel::clear()
-
- Deletes all content from the model. The properties are cleared such that
- different properties may be set on subsequent additions.
-
- \sa append() remove()
-*/
-void QDeclarativeWorkerListModel::clear()
-{
- if (m_agent) {
- qmlInfo(this) << "List can only be modified from a WorkerScript";
- return;
- }
-
- int count = m_values.count();
- m_values.clear();
- if (count) {
- emit itemsRemoved(0, count);
- emit countChanged();
- }
-}
-
-/*!
- \qmlmethod WorkerListModel::remove(int index)
-
- Deletes the content at \a index from the model.
-
- \sa clear()
-*/
-void QDeclarativeWorkerListModel::remove(int index)
-{
- if (m_agent) {
- qmlInfo(this) << "List can only be modified from a WorkerScript";
- return;
- }
-
- if (m_values.count() <= index)
- return;
-
- m_values.removeAt(index);
- emit itemsRemoved(index, 1);
- emit countChanged();
-}
-
-/*!
- \qmlmethod WorkerListModel::append(jsobject dict)
-
- Adds a new item to the end of the list model, with the
- values in \a dict.
-
- \code
- FruitModel.append({"cost": 5.95, "name":"Pizza"})
- \endcode
-
- \sa set() remove()
-*/
-void QDeclarativeWorkerListModel::append(const QScriptValue &value)
-{
- if (m_agent) {
- qmlInfo(this) << "List can only be modified from a WorkerScript";
- return;
- }
-
- QHash<int, QVariant> data;
-
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = m_strings.find(name);
- if (iter == m_strings.end()) {
- int role = m_roles.count();
- m_roles.insert(role, name);
- iter = m_strings.insert(name, role);
- }
- data.insert(*iter, v);
- }
-
- m_values.append(data);
-
- emit itemsInserted(m_values.count() - 1, 1);
- emit countChanged();
-}
-
-/*!
- \qmlmethod WorkerListModel::insert(int index, jsobject dict)
-
- Adds a new item to the list model at position \a index, with the
- values in \a dict.
-
- \code
- FruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})
- \endcode
-
- The \a index must be to an existing item in the list, or one past
- the end of the list (equivalent to append).
-
- \sa set() append()
-*/
-void QDeclarativeWorkerListModel::insert(int index, const QScriptValue &value)
-{
- if (m_agent) {
- qmlInfo(this) << "List can only be modified from a WorkerScript";
- return;
- }
-
- if (index > m_values.count())
- return;
-
- QHash<int, QVariant> data;
-
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = m_strings.find(name);
- if (iter == m_strings.end()) {
- int role = m_roles.count();
- m_roles.insert(role, name);
- iter = m_strings.insert(name, role);
- }
- data.insert(*iter, v);
- }
-
- m_values.insert(index, data);
- emit itemsInserted(index, 1);
- emit countChanged();
-}
-
-/*!
- \qmlmethod object ListModel::get(int index)
-
- Returns the item at \a index in the list model.
-
- \code
- FruitModel.append({"cost": 5.95, "name":"Jackfruit"})
- FruitModel.get(0).cost
- \endcode
-
- The \a index must be an element in the list.
-
- Note that properties of the returned object that are themselves objects
- will also be models, and this get() method is used to access elements:
-
- \code
- FruitModel.append(..., "attributes":
- [{"name":"spikes","value":"7mm"},
- {"name":"color","value":"green"}]);
- FruitModel.get(0).attributes.get(1).value; // == "green"
- \endcode
-
- \sa append()
-*/
-QScriptValue QDeclarativeWorkerListModel::get(int index) const
-{
- QDeclarativeEngine *engine = qmlEngine(this);
- if (!engine || m_values.count() <= index)
- return QScriptValue();
-
- QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
- QScriptValue rv = scriptEngine->newObject();
-
- QHash<int, QVariant> data = m_values.at(index);
- for (QHash<int, QVariant>::ConstIterator iter = data.begin(); iter != data.end(); ++iter)
- rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value()));
-
- return rv;
-}
-
-/*!
- \qmlmethod WorkerListModel::set(int index, jsobject dict)
-
- Changes the item at \a index in the list model with the
- values in \a dict. Properties not appearing in \a valuemap
- are left unchanged.
-
- \code
- FruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
- \endcode
-
- The \a index must be an element in the list.
-
- \sa append()
-*/
-void QDeclarativeWorkerListModel::set(int index, const QScriptValue &value)
-{
- if (m_agent) {
- qmlInfo(this) << "List can only be modified from a WorkerScript";
- return;
- }
-
- if (m_values.count() <= index)
- return;
-
- QHash<int, QVariant> data;
-
- QScriptValueIterator it(value);
- while (it.hasNext()) {
- it.next();
- QString name = it.name();
- QVariant v = it.value().toVariant();
-
- QHash<QString, int>::Iterator iter = m_strings.find(name);
- if (iter == m_strings.end()) {
- int role = m_roles.count();
- m_roles.insert(role, name);
- iter = m_strings.insert(name, role);
- }
- data.insert(*iter, v);
- }
-
- if (m_values.at(index) != data) {
- m_values[index] = data;
- emit itemsChanged(index, 1, m_roles.keys());
- }
-}
-
-/*!
- \qmlmethod WorkerListModel::sync()
-
- Writes any unsaved changes to the list model. This must be called after
- changes have been made to the list model in the worker script.
-
- Note that this method can only be called from the associated worker script.
-*/
-void QDeclarativeWorkerListModel::sync()
-{
- // This is really a dummy method to make it look like sync() exists in
- // WorkerListModel (and not QDeclarativeWorkerListModelAgent) and to let
- // us document sync().
- qmlInfo(this) << "sync() can only be called from a WorkerScript";
-}
-
-QDeclarativeWorkerListModelAgent *QDeclarativeWorkerListModel::agent()
-{
- if (!m_agent)
- m_agent = new QDeclarativeWorkerListModelAgent(this);
-
- return m_agent;
-}
-
-QList<int> QDeclarativeWorkerListModel::roles() const
-{
- return m_roles.keys();
-}
-
-QString QDeclarativeWorkerListModel::toString(int role) const
-{
- return m_roles.value(role);
-}
-
-/*!
- \qmlproperty int ListModel::count
- The number of data entries in the model.
-*/
-int QDeclarativeWorkerListModel::count() const
-{
- return m_values.count();
-}
-
-QHash<int,QVariant> QDeclarativeWorkerListModel::data(int index, const QList<int> &) const
-{
- if (m_values.count() <= index)
- return QHash<int, QVariant>();
- else
- return m_values.at(index);
-}
-
-QVariant QDeclarativeWorkerListModel::data(int index, int role) const
-{
- if (m_values.count() <= index)
- return QVariant();
- else
- return m_values.at(index).value(role);
-}
-
QT_END_NAMESPACE
-#include "qdeclarativeworkerscript.moc"
+#include <qdeclarativeworkerscript.moc>
diff --git a/src/declarative/qml/qdeclarativeworkerscript_p.h b/src/declarative/qml/qdeclarativeworkerscript_p.h
index 912eac9..6cce799 100644
--- a/src/declarative/qml/qdeclarativeworkerscript_p.h
+++ b/src/declarative/qml/qdeclarativeworkerscript_p.h
@@ -55,7 +55,6 @@
#include "qdeclarative.h"
#include "qdeclarativeparserstatus.h"
-#include <private/qlistmodelinterface_p.h>
#include <QtCore/qthread.h>
#include <QtScript/qscriptvalue.h>
@@ -118,49 +117,9 @@ private:
QUrl m_source;
};
-class QDeclarativeWorkerListModelAgent;
-class Q_DECLARATIVE_EXPORT QDeclarativeWorkerListModel : public QListModelInterface
-{
- Q_OBJECT
- Q_PROPERTY(int count READ count NOTIFY countChanged)
-
-public:
- QDeclarativeWorkerListModel(QObject * = 0);
- virtual ~QDeclarativeWorkerListModel();
-
- Q_INVOKABLE void clear();
- Q_INVOKABLE void remove(int index);
- Q_INVOKABLE void append(const QScriptValue &);
- Q_INVOKABLE void insert(int index, const QScriptValue&);
- Q_INVOKABLE QScriptValue get(int index) const;
- Q_INVOKABLE void set(int index, const QScriptValue &);
- Q_INVOKABLE void sync();
-
- QDeclarativeWorkerListModelAgent *agent();
-
- virtual QList<int> roles() const;
- virtual QString toString(int role) const;
- virtual int count() const;
- virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const;
- virtual QVariant data(int index, int role) const;
-
-Q_SIGNALS:
- void countChanged();
-
-private:
- friend class QDeclarativeWorkerListModelAgent;
-
- QHash<int, QString> m_roles;
- QHash<QString, int> m_strings;
- QList<QHash<int, QVariant> > m_values;
-
- QDeclarativeWorkerListModelAgent *m_agent;
-};
-
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeWorkerScript);
-QML_DECLARE_TYPE(QDeclarativeWorkerListModel);
QT_END_HEADER
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index 87cab85..58e67fa 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -1245,7 +1245,7 @@ void QDeclarativeXMLHttpRequest::finished()
if (m_redirectCount < XMLHTTPREQUEST_MAXIMUM_REDIRECT_RECURSION) {
QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
- QUrl url = redirect.toUrl();
+ QUrl url = m_network->url().resolved(redirect.toUrl());
destroyNetwork();
requestFromUrl(url);
return;
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index aa1a34b..49888c3 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -38,6 +38,7 @@ SOURCES += \
$$PWD/qdeclarativescript.cpp \
$$PWD/qdeclarativecleanup.cpp \
$$PWD/qdeclarativepropertycache.cpp \
+ $$PWD/qdeclarativenotifier.cpp \
$$PWD/qdeclarativeintegercache.cpp \
$$PWD/qdeclarativetypenamecache.cpp \
$$PWD/qdeclarativescriptstring.cpp \
@@ -108,6 +109,7 @@ HEADERS += \
$$PWD/qdeclarativewatcher_p.h \
$$PWD/qdeclarativecleanup_p.h \
$$PWD/qdeclarativepropertycache_p.h \
+ $$PWD/qdeclarativenotifier_p.h \
$$PWD/qdeclarativeintegercache_p.h \
$$PWD/qdeclarativetypenamecache_p.h \
$$PWD/qdeclarativescriptstring.h \
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 20449d7..49206b7 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -132,7 +132,7 @@ QDeclarativeAbstractAnimation::QDeclarativeAbstractAnimation(QDeclarativeAbstrac
using the \c start() and \c stop() methods.
By default, animations are not running. Though, when the animations are assigned to properties,
- as property value sources, they are set to running by default.
+ as property value sources using the \e on syntax, they are set to running by default.
*/
bool QDeclarativeAbstractAnimation::isRunning() const
{
@@ -1877,13 +1877,17 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t)
}
/*!
- \qmlproperty QEasingCurve PropertyAnimation::easing
- \brief the easing curve used for the transition.
+ \qmlproperty enum PropertyAnimation::easing.type
+ \qmlproperty real PropertyAnimation::easing.amplitude
+ \qmlproperty real PropertyAnimation::easing.overshoot
+ \qmlproperty real PropertyAnimation::easing.period
+ \brief the easing curve used for the animation.
- For the easing you can specify the following parameters: type, amplitude, period and overshoot.
+ To specify an easing curve you need to specify at least the type. For some curves you can also specify
+ amplitude, period and/or overshoot (more details provided after the table).
\qml
- PropertyAnimation { properties: "y"; easing.type: "InOutElastc"; easing.amplitude: 2.0; easing.period: 1.5 }
+ PropertyAnimation { properties: "y"; easing.type: "InOutElastic"; easing.amplitude: 2.0; easing.period: 1.5 }
\endqml
Available types are:
@@ -2447,12 +2451,15 @@ QDeclarativeParentAnimation::QDeclarativeParentAnimation(QObject *parent)
QDeclarative_setParent_noEvent(d->topLevelGroup, this);
d->startAction = new QActionAnimation;
+ QDeclarative_setParent_noEvent(d->startAction, d->topLevelGroup);
d->topLevelGroup->addAnimation(d->startAction);
d->ag = new QParallelAnimationGroup;
+ QDeclarative_setParent_noEvent(d->ag, d->topLevelGroup);
d->topLevelGroup->addAnimation(d->ag);
d->endAction = new QActionAnimation;
+ QDeclarative_setParent_noEvent(d->endAction, d->topLevelGroup);
d->topLevelGroup->addAnimation(d->endAction);
}
@@ -2743,4 +2750,99 @@ QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation()
return d->topLevelGroup;
}
+/*!
+ \qmlclass AnchorAnimation QDeclarativeAnchorAnimation
+ \since 4.7
+ \inherits Animation
+ \brief The AnchorAnimation element allows you to animate anchor changes.
+
+ AnchorAnimation will animated any changes specified by a state's AnchorChanges.
+ In the following snippet we animate the addition of a right anchor to our item.
+ \qml
+ Item {
+ id: myItem
+ width: 100
+ }
+ ...
+ State {
+ AnchorChanges {
+ target: myItem
+ anchors.right: container.right
+ }
+ }
+ ...
+ Transition {
+ //smoothly reanchor myItem and move into new position
+ AnchorAnimation {}
+ }
+ \endqml
+
+ \sa AnchorChanges
+*/
+
+QDeclarativeAnchorAnimation::QDeclarativeAnchorAnimation(QObject *parent)
+: QDeclarativeAbstractAnimation(*(new QDeclarativeAnchorAnimationPrivate), parent)
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ d->va = new QDeclarativeBulkValueAnimator;
+ QDeclarative_setParent_noEvent(d->va, this);
+}
+
+QDeclarativeAnchorAnimation::~QDeclarativeAnchorAnimation()
+{
+}
+
+QAbstractAnimation *QDeclarativeAnchorAnimation::qtAnimation()
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ return d->va;
+}
+
+/*!
+ \qmlproperty list<Item> AnchorAnimation::targets
+ The items to reanchor.
+
+ If no targets are specified all AnchorChanges will be
+ animated by the AnchorAnimation.
+*/
+QDeclarativeListProperty<QDeclarativeItem> QDeclarativeAnchorAnimation::targets()
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ return QDeclarativeListProperty<QDeclarativeItem>(this, d->targets);
+}
+
+void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QDeclarativeAnchorAnimation);
+ PropertyUpdater *data = new PropertyUpdater;
+ data->interpolatorType = QMetaType::QReal;
+ data->interpolator = d->interpolator;
+
+ data->reverse = direction == Backward ? true : false;
+ data->fromSourced = false;
+ data->fromDefined = false;
+
+ for (int ii = 0; ii < actions.count(); ++ii) {
+ QDeclarativeAction &action = actions[ii];
+ if (action.event && action.event->typeName() == QLatin1String("AnchorChanges")
+ && (d->targets.isEmpty() || d->targets.contains(static_cast<QDeclarativeAnchorChanges*>(action.event)->object()))) {
+ data->actions << static_cast<QDeclarativeAnchorChanges*>(action.event)->additionalActions();
+ }
+ }
+
+ if (data->actions.count()) {
+ if (!d->rangeIsSet) {
+ d->va->setStartValue(qreal(0));
+ d->va->setEndValue(qreal(1));
+ d->rangeIsSet = true;
+ }
+ d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+ d->va->setFromSourcedValue(&data->fromSourced);
+ } else {
+ delete data;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h
index af48309..eb339f6 100644
--- a/src/declarative/util/qdeclarativeanimation_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p.h
@@ -480,6 +480,26 @@ protected:
virtual QAbstractAnimation *qtAnimation();
};
+class QDeclarativeAnchorAnimationPrivate;
+class QDeclarativeAnchorAnimation : public QDeclarativeAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDeclarativeAnchorAnimation)
+ Q_PROPERTY(QDeclarativeListProperty<QDeclarativeItem> targets READ targets)
+
+public:
+ QDeclarativeAnchorAnimation(QObject *parent=0);
+ virtual ~QDeclarativeAnchorAnimation();
+
+ QDeclarativeListProperty<QDeclarativeItem> targets();
+
+protected:
+ virtual void transition(QDeclarativeStateActions &actions,
+ QDeclarativeProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativeAbstractAnimation)
@@ -495,6 +515,7 @@ QML_DECLARE_TYPE(QDeclarativeParallelAnimation)
QML_DECLARE_TYPE(QDeclarativeVector3dAnimation)
QML_DECLARE_TYPE(QDeclarativeRotationAnimation)
QML_DECLARE_TYPE(QDeclarativeParentAnimation)
+QML_DECLARE_TYPE(QDeclarativeAnchorAnimation)
QT_END_HEADER
diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h
index ae82a90..0460312 100644
--- a/src/declarative/util/qdeclarativeanimation_p_p.h
+++ b/src/declarative/util/qdeclarativeanimation_p_p.h
@@ -393,6 +393,19 @@ public:
QPointF computeTransformOrigin(QDeclarativeItem::TransformOrigin origin, qreal width, qreal height) const;
};
+class QDeclarativeAnchorAnimationPrivate : public QDeclarativeAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeAnchorAnimation)
+public:
+ QDeclarativeAnchorAnimationPrivate() : rangeIsSet(false), va(0),
+ interpolator(QVariantAnimationPrivate::getInterpolator(QMetaType::QReal)) {}
+
+ bool rangeIsSet;
+ QDeclarativeBulkValueAnimator *va;
+ QVariantAnimation::Interpolator interpolator;
+ QList<QDeclarativeItem*> targets;
+};
+
QT_END_NAMESPACE
#endif // QDECLARATIVEANIMATION_P_H
diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp
index 8f5f537..bf98d40 100644
--- a/src/declarative/util/qdeclarativefontloader.cpp
+++ b/src/declarative/util/qdeclarativefontloader.cpp
@@ -61,7 +61,7 @@ class QDeclarativeFontLoaderPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QDeclarativeFontLoader)
public:
- QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null) {}
+ QDeclarativeFontLoaderPrivate() : reply(0), status(QDeclarativeFontLoader::Null), redirectCount(0) {}
void addFontToDatabase(const QByteArray &);
@@ -69,6 +69,7 @@ public:
QString name;
QNetworkReply *reply;
QDeclarativeFontLoader::Status status;
+ int redirectCount;
};
@@ -206,15 +207,31 @@ QDeclarativeFontLoader::Status QDeclarativeFontLoader::status() const
return d->status;
}
+#define FONTLOADER_MAXIMUM_REDIRECT_RECURSION 16
+
void QDeclarativeFontLoader::replyFinished()
{
Q_D(QDeclarativeFontLoader);
if (d->reply) {
+ d->redirectCount++;
+ if (d->redirectCount < FONTLOADER_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = d->reply->url().resolved(redirect.toUrl());
+ d->reply->deleteLater();
+ d->reply = 0;
+ setSource(url);
+ return;
+ }
+ }
+ d->redirectCount=0;
+
if (!d->reply->error()) {
QByteArray ba = d->reply->readAll();
d->addFontToDatabase(ba);
} else {
d->status = Error;
+ qWarning() << "Cannot load font:" << d->reply->url();
emit statusChanged();
}
d->reply->deleteLater();
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index e3f26d7..61e49ce 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#include "qdeclarativelistmodel_p.h"
-
+#include "qdeclarativelistmodel_p_p.h"
+#include "qdeclarativelistmodelworkeragent_p.h"
#include "qdeclarativeopenmetaobject_p.h"
#include <qdeclarativecustomparser_p.h>
@@ -66,8 +66,6 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM
return (QDeclarativeListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData));
}
-static void dump(ModelNode *node, int ind);
-
/*!
\qmlclass ListModel QDeclarativeListModel
\since 4.7
@@ -193,253 +191,146 @@ static void dump(ModelNode *node, int ind);
except by first clearing the model - whatever properties are first added are then the
only permitted properties in the model.
- \sa {qmlmodels}{Data Models}
-*/
-class ModelObject : public QObject
-{
- Q_OBJECT
-public:
- ModelObject();
+ \section2 Using threaded list models with WorkerScript
- void setValue(const QByteArray &name, const QVariant &val)
- {
- _mo->setValue(name, val);
- }
+ ListModel can be used together with WorkerScript access a list model
+ from multiple threads. This is useful if list modifications are
+ synchronous and take some time: the list operations can be moved to a
+ different thread to avoid blocking of the main GUI thread.
-private:
- QDeclarativeOpenMetaObject *_mo;
-};
+ Here is an example that uses WorkerScript to periodically append the
+ current time to a list model:
-struct ModelNode
-{
- ModelNode();
- ~ModelNode();
+ \snippet examples/declarative/listmodel-threaded/timedisplay.qml 0
- QList<QVariant> values;
- QHash<QString, ModelNode *> properties;
+ The included file, \tt dataloader.js, looks like this:
- QDeclarativeListModel *model(const QDeclarativeListModel *parent) {
- if (!modelCache) {
- modelCache = new QDeclarativeListModel;
- QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(parent));
+ \snippet examples/declarative/listmodel-threaded/dataloader.js 0
- modelCache->_root = this;
- }
- return modelCache;
- }
+ The application's \tt Timer object periodically sends a message to the
+ worker script by calling \tt WorkerScript::sendMessage(). When this message
+ is received, \tt WorkerScript.onMessage() is invoked in
+ \tt dataloader.js, which appends the current time to the list model.
- ModelObject *object(const QDeclarativeListModel *parent) {
- if (!objectCache) {
- objectCache = new ModelObject();
- QHash<QString, ModelNode *>::iterator it;
- for (it = properties.begin(); it != properties.end(); ++it) {
- objectCache->setValue(it.key().toUtf8(), parent->valueForNode(*it));
- }
- }
- return objectCache;
- }
-
- void setObjectValue(const QScriptValue& valuemap);
- void setListValue(const QScriptValue& valuelist);
+ Note the call to sync() from the \c WorkerScript.onMessage() handler.
+ Without this call, the changes made to the list are not reflected in the
+ list model in the main thread.
- void setProperty(const QString& prop, const QVariant& val) {
- QHash<QString, ModelNode *>::const_iterator it = properties.find(prop);
- if (it != properties.end()) {
- (*it)->values[0] = val;
- } else {
- ModelNode *n = new ModelNode;
- n->values << val;
- properties.insert(prop,n);
- }
- if (objectCache)
- objectCache->setValue(prop.toUtf8(), val);
- }
+ \section3 Limitations
- QDeclarativeListModel *modelCache;
- ModelObject *objectCache;
- bool isArray;
-};
+ If a list model is to be accessed from a WorkerScript, it \bold cannot
+ contain nested list data. So, the following model cannot be used from a WorkerScript
+ because of the list contained in the "attributes" property:
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(ModelNode *)
-
-QT_BEGIN_NAMESPACE
-
-void ModelNode::setObjectValue(const QScriptValue& valuemap) {
- QScriptValueIterator it(valuemap);
- while (it.hasNext()) {
- it.next();
- ModelNode *value = new ModelNode;
- QScriptValue v = it.value();
- if (v.isArray()) {
- value->isArray = true;
- value->setListValue(v);
- } else {
- value->values << v.toVariant();
+ \code
+ ListModel {
+ id: fruitModel
+ ListElement {
+ name: "Apple"
+ cost: 2.45
+ attributes: [
+ ListElement { description: "Core" },
+ ListElement { description: "Deciduous" }
+ ]
}
- properties.insert(it.name(),value);
}
-}
+ \endcode
-void ModelNode::setListValue(const QScriptValue& valuelist) {
- QScriptValueIterator it(valuelist);
- values.clear();
- while (it.hasNext()) {
- it.next();
- ModelNode *value = new ModelNode;
- QScriptValue v = it.value();
- if (v.isArray()) {
- value->isArray = true;
- value->setListValue(v);
- } else if (v.isObject()) {
- value->setObjectValue(v);
- } else {
- value->values << v.toVariant();
- }
- values.append(qVariantFromValue(value));
+ In addition, the WorkerScript cannot add any nested list data to the model.
- }
-}
+ \sa {qmlmodels}{Data Models}, WorkerScript
+*/
-ModelObject::ModelObject()
-: _mo(new QDeclarativeOpenMetaObject(this))
+QDeclarativeListModel::QDeclarativeListModel(QObject *parent)
+: QListModelInterface(parent), m_agent(0), m_nested(new NestedListModel(this)), m_flat(0), m_isWorkerCopy(false)
{
}
-QDeclarativeListModel::QDeclarativeListModel(QObject *parent)
-: QListModelInterface(parent), _rolesOk(false), _root(0)
+QDeclarativeListModel::QDeclarativeListModel(bool workerCopy, QObject *parent)
+: QListModelInterface(parent), m_agent(0), m_nested(0), m_flat(0), m_isWorkerCopy(workerCopy)
{
+ if (workerCopy)
+ m_flat = new FlatListModel(this);
+ else
+ m_nested = new NestedListModel(this);
}
QDeclarativeListModel::~QDeclarativeListModel()
{
- delete _root;
+ delete m_nested;
+ delete m_flat;
}
-void QDeclarativeListModel::checkRoles() const
+bool QDeclarativeListModel::flatten()
{
- if (_rolesOk || !_root)
- return;
+ if (m_flat)
+ return true;
- for (int ii = 0; ii < _root->values.count(); ++ii) {
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(ii));
- if (node) {
- foreach (const QString &role, node->properties.keys())
- addRole(role);
- }
+ QList<int> roles = m_nested->roles();
+
+ QList<QHash<int, QVariant> > values;
+ bool hasNested = false;
+ for (int i=0; i<m_nested->count(); i++) {
+ values.append(m_nested->data(i, roles, &hasNested));
+ if (hasNested)
+ return false;
}
- _rolesOk = true;
+ FlatListModel *flat = new FlatListModel(this);
+ flat->m_values = values;
+
+ for (int i=0; i<roles.count(); i++) {
+ QString s = m_nested->toString(roles[i]);
+ flat->m_roles.insert(roles[i], s);
+ flat->m_strings.insert(s, roles[i]);
+ }
+
+ m_flat = flat;
+ delete m_nested;
+ m_nested = 0;
+ return true;
}
-void QDeclarativeListModel::addRole(const QString &role) const
+QDeclarativeListModelWorkerAgent *QDeclarativeListModel::agent()
{
- if (!roleStrings.contains(role))
- roleStrings << role;
+ if (m_agent)
+ return m_agent;
+
+ if (!flatten()) {
+ qmlInfo(this) << "List contains nested list values and cannot be used from a worker script";
+ return 0;
+ }
+
+ m_agent = new QDeclarativeListModelWorkerAgent(this);
+ return m_agent;
}
QList<int> QDeclarativeListModel::roles() const
{
- checkRoles();
- QList<int> rv;
- for (int ii = 0; ii < roleStrings.count(); ++ii)
- rv << ii;
- return rv;
+ return m_flat ? m_flat->roles() : m_nested->roles();
}
QString QDeclarativeListModel::toString(int role) const
{
- checkRoles();
- if (role < roleStrings.count())
- return roleStrings.at(role);
- else
- return QString();
-}
-
-QVariant QDeclarativeListModel::valueForNode(ModelNode *node) const
-{
- QObject *rv = 0;
-
- if (node->isArray) {
- // List
- rv = node->model(this);
- } else {
- if (!node->properties.isEmpty()) {
- // Object
- rv = node->object(this);
- } else if (node->values.count() == 0) {
- // Invalid
- return QVariant();
- } else if (node->values.count() == 1) {
- // Value
- QVariant &var = node->values[0];
- ModelNode *valueNode = qvariant_cast<ModelNode *>(var);
- if (valueNode) {
- if (!valueNode->properties.isEmpty())
- rv = valueNode->object(this);
- else
- rv = valueNode->model(this);
- } else {
- return var;
- }
- }
- }
-
- if (rv)
- return QVariant::fromValue(rv);
- else
- return QVariant();
+ return m_flat ? m_flat->toString(role) : m_nested->toString(role);
}
QHash<int,QVariant> QDeclarativeListModel::data(int index, const QList<int> &roles) const
{
- checkRoles();
- QHash<int, QVariant> rv;
if (index >= count() || index < 0)
- return rv;
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- if (!node)
- return rv;
-
- for (int ii = 0; ii < roles.count(); ++ii) {
- const QString &roleString = roleStrings.at(roles.at(ii));
-
- QHash<QString, ModelNode *>::ConstIterator iter =
- node->properties.find(roleString);
- if (iter != node->properties.end()) {
- ModelNode *row = *iter;
- rv.insert(roles.at(ii), valueForNode(row));
- }
- }
+ return QHash<int, QVariant>();
- return rv;
+ return m_flat ? m_flat->data(index, roles) : m_nested->data(index, roles);
}
QVariant QDeclarativeListModel::data(int index, int role) const
{
- checkRoles();
- QVariant rv;
if (index >= count() || index < 0)
- return rv;
-
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- if (!node)
- return rv;
-
- const QString &roleString = roleStrings.at(role);
-
- QHash<QString, ModelNode *>::ConstIterator iter =
- node->properties.find(roleString);
- if (iter != node->properties.end()) {
- ModelNode *row = *iter;
- rv = valueForNode(row);
- }
+ return QVariant();
- return rv;
+ return m_flat ? m_flat->data(index, role) : m_nested->data(index, role);
}
/*!
@@ -448,8 +339,7 @@ QVariant QDeclarativeListModel::data(int index, int role) const
*/
int QDeclarativeListModel::count() const
{
- if (!_root) return 0;
- return _root->values.count();
+ return m_flat ? m_flat->count() : m_nested->count();
}
/*!
@@ -463,12 +353,15 @@ int QDeclarativeListModel::count() const
void QDeclarativeListModel::clear()
{
int cleared = count();
- _rolesOk = false;
- delete _root;
- _root = 0;
- roleStrings.clear();
- emit itemsRemoved(0,cleared);
- emit countChanged(0);
+ if (m_flat)
+ m_flat->clear();
+ else
+ m_nested->clear();
+
+ if (!m_isWorkerCopy) {
+ emit itemsRemoved(0, cleared);
+ emit countChanged(0);
+ }
}
/*!
@@ -480,17 +373,18 @@ void QDeclarativeListModel::clear()
*/
void QDeclarativeListModel::remove(int index)
{
- if (!_root || index < 0 || index >= _root->values.count()) {
+ if (index < 0 || index >= count()) {
qmlInfo(this) << tr("remove: index %1 out of range").arg(index);
return;
}
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- _root->values.removeAt(index);
- if (node)
- delete node;
- emit itemsRemoved(index,1);
- emit countChanged(_root->values.count());
+ if (m_flat)
+ m_flat->remove(index);
+ else
+ m_nested->remove(index);
+
+ if (!m_isWorkerCopy)
+ emit countChanged(this->count());
}
/*!
@@ -514,20 +408,17 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap)
qmlInfo(this) << tr("insert: value is not an object");
return;
}
- if (!_root)
- _root = new ModelNode;
- if (index >= _root->values.count() || index<0) {
- if (index == _root->values.count())
- append(valuemap);
- else
- qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
+
+ if (index < 0 || index > count()) {
+ qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
return;
}
- ModelNode *mn = new ModelNode;
- mn->setObjectValue(valuemap);
- _root->values.insert(index,qVariantFromValue(mn));
- emit itemsInserted(index,1);
- emit countChanged(_root->values.count());
+
+ bool ok = m_flat ? m_flat->insert(index, valuemap) : m_nested->insert(index, valuemap);
+ if (ok && !m_isWorkerCopy) {
+ emit itemsInserted(index, 1);
+ emit countChanged(this->count());
+ }
}
/*!
@@ -552,9 +443,10 @@ void QDeclarativeListModel::move(int from, int to, int n)
qmlInfo(this) << tr("move: out of range");
return;
}
- int origfrom=from; // preserve actual move, so any animations are correct
- int origto=to;
- int orign=n;
+
+ int origfrom = from;
+ int origto = to;
+ int orign = n;
if (from > to) {
// Only move forwards - flip if backwards moving
int tfrom = from;
@@ -563,24 +455,14 @@ void QDeclarativeListModel::move(int from, int to, int n)
to = tto+n;
n = tfrom-tto;
}
- if (n==1) {
- _root->values.move(from,to);
- } else {
- QList<QVariant> replaced;
- int i=0;
- QVariantList::const_iterator it=_root->values.begin(); it += from+n;
- for (; i<to-from; ++i,++it)
- replaced.append(*it);
- i=0;
- it=_root->values.begin(); it += from;
- for (; i<n; ++i,++it)
- replaced.append(*it);
- QVariantList::const_iterator f=replaced.begin();
- QVariantList::iterator t=_root->values.begin(); t += from;
- for (; f != replaced.end(); ++f, ++t)
- *t = *f;
- }
- emit itemsMoved(origfrom,origto,orign);
+
+ if (m_flat)
+ m_flat->move(from, to, n);
+ else
+ m_nested->move(from, to, n);
+
+ if (!m_isWorkerCopy)
+ emit itemsMoved(origfrom, origto, orign);
}
/*!
@@ -601,13 +483,8 @@ void QDeclarativeListModel::append(const QScriptValue& valuemap)
qmlInfo(this) << tr("append: value is not an object");
return;
}
- if (!_root)
- _root = new ModelNode;
- ModelNode *mn = new ModelNode;
- mn->setObjectValue(valuemap);
- _root->values << qVariantFromValue(mn);
- emit itemsInserted(count()-1,1);
- emit countChanged(_root->values.count());
+
+ insert(count(), valuemap);
}
/*!
@@ -641,15 +518,7 @@ QScriptValue QDeclarativeListModel::get(int index) const
return 0;
}
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- if (!node)
- return 0;
- QDeclarativeEngine *eng = qmlEngine(this);
- if (!eng) {
- qWarning("Cannot call QDeclarativeListModel::get() without a QDeclarativeEngine");
- return 0;
- }
- return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng);
+ return m_flat ? m_flat->get(index) : m_nested->get(index);
}
/*!
@@ -673,27 +542,22 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap)
qmlInfo(this) << tr("set: value is not an object");
return;
}
- if ( !_root || index > _root->values.count() || index < 0) {
+ if (count() == 0 || index > count() || index < 0) {
qmlInfo(this) << tr("set: index %1 out of range").arg(index);
return;
}
- if (index == _root->values.count())
+
+ if (index == count()) {
append(valuemap);
- else {
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ } else {
QList<int> roles;
- node->setObjectValue(valuemap);
- QScriptValueIterator it(valuemap);
- while (it.hasNext()) {
- it.next();
- int r = roleStrings.indexOf(it.name());
- if (r<0) {
- r = roleStrings.count();
- roleStrings << it.name();
- }
- roles.append(r);
- }
- emit itemsChanged(index,1,roles);
+ if (m_flat)
+ m_flat->set(index, valuemap, &roles);
+ else
+ m_nested->set(index, valuemap, &roles);
+
+ if (!m_isWorkerCopy)
+ emit itemsChanged(index, 1, roles);
}
}
@@ -712,22 +576,33 @@ void QDeclarativeListModel::set(int index, const QScriptValue& valuemap)
*/
void QDeclarativeListModel::setProperty(int index, const QString& property, const QVariant& value)
{
- if ( !_root || index >= _root->values.count() || index < 0) {
+ if (count() == 0 || index >= count() || index < 0) {
qmlInfo(this) << tr("set: index %1 out of range").arg(index);
return;
}
- ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
- int r = roleStrings.indexOf(property);
- if (r<0) {
- r = roleStrings.count();
- roleStrings << property;
- }
+
QList<int> roles;
- roles.append(r);
+ if (m_flat)
+ m_flat->setProperty(index, property, value, &roles);
+ else
+ m_nested->setProperty(index, property, value, &roles);
- if (node)
- node->setProperty(property,value);
- emit itemsChanged(index,1,roles);
+ if (!m_isWorkerCopy)
+ emit itemsChanged(index, 1, roles);
+}
+
+/*!
+ \qmlmethod ListModel::sync()
+
+ Writes any unsaved changes to the list model after it has been modified
+ from a worker script.
+*/
+void QDeclarativeListModel::sync()
+{
+ // This is just a dummy method to make it look like sync() exists in
+ // ListModel (and not just QDeclarativeListModelWorkerAgent) and to let
+ // us document sync().
+ qmlInfo(this) << "List sync() can only be called from a WorkerScript";
}
bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data)
@@ -858,7 +733,7 @@ void QDeclarativeListModelParser::setCustomData(QObject *obj, const QByteArray &
QDeclarativeListModel *rv = static_cast<QDeclarativeListModel *>(obj);
ModelNode *root = new ModelNode;
- rv->_root = root;
+ rv->m_nested->_root = root;
QStack<ModelNode *> nodes;
nodes << root;
@@ -943,7 +818,491 @@ bool QDeclarativeListModelParser::definesEmptyList(const QString &s)
\sa ListModel
*/
-static void dump(ModelNode *node, int ind)
+FlatListModel::FlatListModel(QDeclarativeListModel *base)
+ : m_scriptEngine(0), m_listModel(base)
+{
+}
+
+FlatListModel::~FlatListModel()
+{
+}
+
+QHash<int,QVariant> FlatListModel::data(int index, const QList<int> &roles) const
+{
+ Q_ASSERT(index >= 0 && index < m_values.count());
+
+ QHash<int, QVariant> row;
+ for (int i=0; i<roles.count(); i++) {
+ int role = roles[i];
+ if (m_values[index].contains(role))
+ row.insert(role, m_values[index][role]);
+ }
+ return row;
+}
+
+QVariant FlatListModel::data(int index, int role) const
+{
+ Q_ASSERT(index >= 0 && index < m_values.count());
+ if (m_values[index].contains(role))
+ return m_values[index][role];
+ return QVariant();
+}
+
+QList<int> FlatListModel::roles() const
+{
+ return m_roles.keys();
+}
+
+QString FlatListModel::toString(int role) const
+{
+ if (m_roles.contains(role))
+ return m_roles[role];
+ return QString();
+}
+
+int FlatListModel::count() const
+{
+ return m_values.count();
+}
+
+void FlatListModel::clear()
+{
+ m_values.clear();
+}
+
+void FlatListModel::remove(int index)
+{
+ m_values.removeAt(index);
+}
+
+bool FlatListModel::append(const QScriptValue &value)
+{
+ return insert(m_values.count(), value);
+}
+
+bool FlatListModel::insert(int index, const QScriptValue &value)
+{
+ Q_ASSERT(index >= 0 && index <= m_values.count());
+
+ QHash<int, QVariant> row;
+ if (!addValue(value, &row, 0))
+ return false;
+
+ m_values.insert(index, row);
+ return true;
+}
+
+QScriptValue FlatListModel::get(int index) const
+{
+ Q_ASSERT(index >= 0 && index < m_values.count());
+
+ QScriptEngine *scriptEngine = m_scriptEngine ? m_scriptEngine : QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(m_listModel));
+
+ if (!scriptEngine)
+ return 0;
+
+ QScriptValue rv = scriptEngine->newObject();
+
+ QHash<int, QVariant> row = m_values.at(index);
+ for (QHash<int, QVariant>::ConstIterator iter = row.begin(); iter != row.end(); ++iter)
+ rv.setProperty(m_roles.value(iter.key()), qScriptValueFromValue(scriptEngine, iter.value()));
+
+ return rv;
+}
+
+void FlatListModel::set(int index, const QScriptValue &value, QList<int> *roles)
+{
+ Q_ASSERT(index >= 0 && index < m_values.count());
+
+ QHash<int, QVariant> row = m_values[index];
+ if (addValue(value, &row, roles))
+ m_values[index] = row;
+}
+
+void FlatListModel::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles)
+{
+ Q_ASSERT(index >= 0 && index < m_values.count());
+
+ QHash<QString, int>::Iterator iter = m_strings.find(property);
+ int role;
+ if (iter == m_strings.end()) {
+ role = m_roles.count();
+ m_roles.insert(role, property);
+ m_strings.insert(property, role);
+ } else {
+ role = iter.value();
+ }
+ roles->append(role);
+
+ m_values[index][role] = value;
+}
+
+void FlatListModel::move(int from, int to, int n)
+{
+ if (n == 1) {
+ m_values.move(from, to);
+ } else {
+ QList<QHash<int, QVariant> > replaced;
+ int i=0;
+ QList<QHash<int, QVariant> >::ConstIterator it=m_values.begin(); it += from+n;
+ for (; i<to-from; ++i,++it)
+ replaced.append(*it);
+ i=0;
+ it=m_values.begin(); it += from;
+ for (; i<n; ++i,++it)
+ replaced.append(*it);
+ QList<QHash<int, QVariant> >::ConstIterator f=replaced.begin();
+ QList<QHash<int, QVariant> >::Iterator t=m_values.begin(); t += from;
+ for (; f != replaced.end(); ++f, ++t)
+ *t = *f;
+ }
+}
+
+bool FlatListModel::addValue(const QScriptValue &value, QHash<int, QVariant> *row, QList<int> *roles)
+{
+ QScriptValueIterator it(value);
+ while (it.hasNext()) {
+ it.next();
+ if (it.value().isObject()) {
+ qmlInfo(m_listModel) << "Cannot add nested list values when modifying or after modification from a worker script";
+ return false;
+ }
+
+ QString name = it.name();
+ QVariant v = it.value().toVariant();
+
+ QHash<QString, int>::Iterator iter = m_strings.find(name);
+ if (iter == m_strings.end()) {
+ int role = m_roles.count();
+ m_roles.insert(role, name);
+ iter = m_strings.insert(name, role);
+ if (roles)
+ roles->append(role);
+ }
+ row->insert(*iter, v);
+ }
+ return true;
+}
+
+NestedListModel::NestedListModel(QDeclarativeListModel *base)
+ : _root(0), m_listModel(base), _rolesOk(false)
+{
+}
+
+NestedListModel::~NestedListModel()
+{
+ delete _root;
+}
+
+QVariant NestedListModel::valueForNode(ModelNode *node, bool *hasNested) const
+{
+ QObject *rv = 0;
+ if (hasNested)
+ *hasNested = false;
+
+ if (node->isArray) {
+ // List
+ rv = node->model(this);
+ if (hasNested)
+ *hasNested = true;
+ } else {
+ if (!node->properties.isEmpty()) {
+ // Object
+ rv = node->object(this);
+ } else if (node->values.count() == 0) {
+ // Invalid
+ return QVariant();
+ } else if (node->values.count() == 1) {
+ // Value
+ QVariant &var = node->values[0];
+ ModelNode *valueNode = qvariant_cast<ModelNode *>(var);
+ if (valueNode) {
+ if (!valueNode->properties.isEmpty())
+ rv = valueNode->object(this);
+ else
+ rv = valueNode->model(this);
+ } else {
+ return var;
+ }
+ }
+ }
+
+ if (rv) {
+ return QVariant::fromValue(rv);
+ } else {
+ return QVariant();
+ }
+}
+
+QHash<int,QVariant> NestedListModel::data(int index, const QList<int> &roles, bool *hasNested) const
+{
+ Q_ASSERT(_root && index >= 0 && index < _root->values.count());
+ checkRoles();
+ QHash<int, QVariant> rv;
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ if (!node)
+ return rv;
+
+ for (int ii = 0; ii < roles.count(); ++ii) {
+ const QString &roleString = roleStrings.at(roles.at(ii));
+
+ QHash<QString, ModelNode *>::ConstIterator iter = node->properties.find(roleString);
+ if (iter != node->properties.end()) {
+ ModelNode *row = *iter;
+ rv.insert(roles.at(ii), valueForNode(row, hasNested));
+ }
+ }
+
+ return rv;
+}
+
+QVariant NestedListModel::data(int index, int role) const
+{
+ Q_ASSERT(_root && index >= 0 && index < _root->values.count());
+ checkRoles();
+ QVariant rv;
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ if (!node)
+ return rv;
+
+ const QString &roleString = roleStrings.at(role);
+
+ QHash<QString, ModelNode *>::ConstIterator iter = node->properties.find(roleString);
+ if (iter != node->properties.end()) {
+ ModelNode *row = *iter;
+ rv = valueForNode(row);
+ }
+
+ return rv;
+}
+
+int NestedListModel::count() const
+{
+ if (!_root) return 0;
+ return _root->values.count();
+}
+
+void NestedListModel::clear()
+{
+ _rolesOk = false;
+ roleStrings.clear();
+
+ delete _root;
+ _root = 0;
+}
+
+void NestedListModel::remove(int index)
+{
+ if (!_root)
+ return;
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ _root->values.removeAt(index);
+ if (node)
+ delete node;
+}
+
+bool NestedListModel::insert(int index, const QScriptValue& valuemap)
+{
+ if (!_root)
+ _root = new ModelNode;
+
+ ModelNode *mn = new ModelNode;
+ mn->setObjectValue(valuemap);
+ _root->values.insert(index,qVariantFromValue(mn));
+ return true;
+}
+
+void NestedListModel::move(int from, int to, int n)
+{
+ if (n==1) {
+ _root->values.move(from,to);
+ } else {
+ QList<QVariant> replaced;
+ int i=0;
+ QVariantList::const_iterator it=_root->values.begin(); it += from+n;
+ for (; i<to-from; ++i,++it)
+ replaced.append(*it);
+ i=0;
+ it=_root->values.begin(); it += from;
+ for (; i<n; ++i,++it)
+ replaced.append(*it);
+ QVariantList::const_iterator f=replaced.begin();
+ QVariantList::iterator t=_root->values.begin(); t += from;
+ for (; f != replaced.end(); ++f, ++t)
+ *t = *f;
+ }
+}
+
+bool NestedListModel::append(const QScriptValue& valuemap)
+{
+ if (!_root)
+ _root = new ModelNode;
+ ModelNode *mn = new ModelNode;
+ mn->setObjectValue(valuemap);
+ _root->values << qVariantFromValue(mn);
+ return true;
+}
+
+QScriptValue NestedListModel::get(int index) const
+{
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ if (!node)
+ return 0;
+ QDeclarativeEngine *eng = qmlEngine(m_listModel);
+ if (!eng) {
+ qWarning("Cannot call QDeclarativeListModel::get() without a QDeclarativeEngine");
+ return 0;
+ }
+ return QDeclarativeEnginePrivate::qmlScriptObject(node->object(this), eng);
+}
+
+void NestedListModel::set(int index, const QScriptValue& valuemap, QList<int> *roles)
+{
+ Q_ASSERT(index >=0 && index < count());
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ node->setObjectValue(valuemap);
+
+ QScriptValueIterator it(valuemap);
+ while (it.hasNext()) {
+ it.next();
+ int r = roleStrings.indexOf(it.name());
+ if (r < 0) {
+ r = roleStrings.count();
+ roleStrings << it.name();
+ }
+ roles->append(r);
+ }
+}
+
+void NestedListModel::setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles)
+{
+ Q_ASSERT(index >=0 && index < count());
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ node->setProperty(property, value);
+
+ int r = roleStrings.indexOf(property);
+ if (r < 0) {
+ r = roleStrings.count();
+ roleStrings << property;
+ }
+ roles->append(r);
+}
+
+void NestedListModel::checkRoles() const
+{
+ if (_rolesOk || !_root)
+ return;
+
+ for (int i = 0; i<_root->values.count(); ++i) {
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i));
+ if (node) {
+ foreach (const QString &role, node->properties.keys()) {
+ if (!roleStrings.contains(role))
+ roleStrings.append(role);
+ }
+ }
+ }
+
+ _rolesOk = true;
+}
+
+QList<int> NestedListModel::roles() const
+{
+ checkRoles();
+ QList<int> rv;
+ for (int ii = 0; ii < roleStrings.count(); ++ii)
+ rv << ii;
+ return rv;
+}
+
+QString NestedListModel::toString(int role) const
+{
+ checkRoles();
+ if (role < roleStrings.count())
+ return roleStrings.at(role);
+ else
+ return QString();
+}
+
+
+ModelNode::ModelNode()
+: modelCache(0), objectCache(0), isArray(false)
+{
+}
+
+ModelNode::~ModelNode()
+{
+ ModelNode *node;
+
+ QList<ModelNode *> nodeValues = properties.values();
+ for (int ii = 0; ii < nodeValues.count(); ++ii) {
+ node = nodeValues[ii];
+ if (node) { delete node; node = 0; }
+ }
+
+ for (int ii = 0; ii < values.count(); ++ii) {
+ node = qvariant_cast<ModelNode *>(values.at(ii));
+ if (node) { delete node; node = 0; }
+ }
+
+ if (modelCache) { modelCache->m_nested->_root = 0/* ==this */; delete modelCache; modelCache = 0; }
+ if (objectCache) { delete objectCache; objectCache = 0; }
+}
+
+void ModelNode::setObjectValue(const QScriptValue& valuemap) {
+ QScriptValueIterator it(valuemap);
+ while (it.hasNext()) {
+ it.next();
+ ModelNode *value = new ModelNode;
+ QScriptValue v = it.value();
+ if (v.isArray()) {
+ value->isArray = true;
+ value->setListValue(v);
+ } else {
+ value->values << v.toVariant();
+ }
+ properties.insert(it.name(),value);
+ }
+}
+
+void ModelNode::setListValue(const QScriptValue& valuelist) {
+ QScriptValueIterator it(valuelist);
+ values.clear();
+ while (it.hasNext()) {
+ it.next();
+ ModelNode *value = new ModelNode;
+ QScriptValue v = it.value();
+ if (v.isArray()) {
+ value->isArray = true;
+ value->setListValue(v);
+ } else if (v.isObject()) {
+ value->setObjectValue(v);
+ } else {
+ value->values << v.toVariant();
+ }
+ values.append(qVariantFromValue(value));
+
+ }
+}
+
+void ModelNode::setProperty(const QString& prop, const QVariant& val) {
+ QHash<QString, ModelNode *>::const_iterator it = properties.find(prop);
+ if (it != properties.end()) {
+ (*it)->values[0] = val;
+ } else {
+ ModelNode *n = new ModelNode;
+ n->values << val;
+ properties.insert(prop,n);
+ }
+ if (objectCache)
+ objectCache->setValue(prop.toUtf8(), val);
+}
+
+void ModelNode::dump(ModelNode *node, int ind)
{
QByteArray indentBa(ind * 4, ' ');
const char *indent = indentBa.constData();
@@ -964,22 +1323,15 @@ static void dump(ModelNode *node, int ind)
}
}
-ModelNode::ModelNode()
-: modelCache(0), objectCache(0), isArray(false)
+ModelObject::ModelObject()
+: _mo(new QDeclarativeOpenMetaObject(this))
{
}
-ModelNode::~ModelNode()
+void ModelObject::setValue(const QByteArray &name, const QVariant &val)
{
- qDeleteAll(properties);
- for (int ii = 0; ii < values.count(); ++ii) {
- ModelNode *node = qvariant_cast<ModelNode *>(values.at(ii));
- if (node) { delete node; node = 0; }
- }
- if (modelCache) { modelCache->_root = 0/* ==this */; delete modelCache; modelCache = 0; }
- if (objectCache) { delete objectCache; }
+ _mo->setValue(name, val);
}
-QT_END_NAMESPACE
-#include <qdeclarativelistmodel.moc>
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativelistmodel_p.h b/src/declarative/util/qdeclarativelistmodel_p.h
index 8eb6583..6a0426b 100644
--- a/src/declarative/util/qdeclarativelistmodel_p.h
+++ b/src/declarative/util/qdeclarativelistmodel_p.h
@@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
+class FlatListModel;
+class NestedListModel;
+class QDeclarativeListModelWorkerAgent;
struct ModelNode;
class Q_DECLARATIVE_EXPORT QDeclarativeListModel : public QListModelInterface
{
@@ -83,20 +86,26 @@ public:
Q_INVOKABLE void set(int index, const QScriptValue&);
Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
Q_INVOKABLE void move(int from, int to, int count);
+ Q_INVOKABLE void sync();
+
+ QDeclarativeListModelWorkerAgent *agent();
Q_SIGNALS:
void countChanged(int);
private:
- QVariant valueForNode(ModelNode *) const;
- mutable QStringList roleStrings;
friend class QDeclarativeListModelParser;
+ friend class QDeclarativeListModelWorkerAgent;
friend struct ModelNode;
- void checkRoles() const;
- void addRole(const QString &) const;
- mutable bool _rolesOk;
- ModelNode *_root;
+ QDeclarativeListModel(bool workerCopy, QObject *parent=0);
+ bool flatten();
+ bool modifyCheck();
+
+ QDeclarativeListModelWorkerAgent *m_agent;
+ NestedListModel *m_nested;
+ FlatListModel *m_flat;
+ bool m_isWorkerCopy;
};
// ### FIXME
diff --git a/src/declarative/util/qdeclarativelistmodel_p_p.h b/src/declarative/util/qdeclarativelistmodel_p_p.h
new file mode 100644
index 0000000..8041561
--- /dev/null
+++ b/src/declarative/util/qdeclarativelistmodel_p_p.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVELISTMODEL_P_P_H
+#define QDECLARATIVELISTMODEL_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qdeclarativelistmodel_p.h"
+
+#include "qdeclarative.h"
+#include "qdeclarativeengine_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeOpenMetaObject;
+class QScriptEngine;
+class QDeclarativeListModelWorkerAgent;
+struct ModelNode;
+
+class FlatListModel
+{
+public:
+ FlatListModel(QDeclarativeListModel *base);
+ ~FlatListModel();
+
+ QHash<int,QVariant> data(int index, const QList<int> &roles) const;
+ QVariant data(int index, int role) const;
+
+ QList<int> roles() const;
+ QString toString(int role) const;
+
+ int count() const;
+ void clear();
+ void remove(int index);
+ bool append(const QScriptValue&);
+ bool insert(int index, const QScriptValue&);
+ QScriptValue get(int index) const;
+ void set(int index, const QScriptValue&, QList<int> *roles);
+ void setProperty(int index, const QString& property, const QVariant& value, QList<int> *roles);
+ void move(int from, int to, int count);
+
+private:
+ friend class QDeclarativeListModelWorkerAgent;
+ friend class QDeclarativeListModel;
+
+ bool addValue(const QScriptValue &value, QHash<int, QVariant> *row, QList<int> *roles);
+
+ QScriptEngine *m_scriptEngine;
+ QHash<int, QString> m_roles;
+ QHash<QString, int> m_strings;
+ QList<QHash<int, QVariant> > m_values;
+ QDeclarativeListModel *m_listModel;
+};
+
+class NestedListModel
+{
+public:
+ NestedListModel(QDeclarativeListModel *base);
+ ~NestedListModel();
+
+ QHash<int,QVariant> data(int index, const QList<int> &roles, bool *hasNested = 0) const;
+ QVariant data(int index, int role) const;
+
+ QList<int> roles() const;
+ QString toString(int role) const;
+
+ int count() const;
+ void clear();
+ void remove(int index);
+ bool append(const QScriptValue&);
+ bool insert(int index, const QScriptValue&);
+ QScriptValue get(int index) const;
+ void set(int index, const QScriptValue&, QList<int> *roles);
+ void setProperty(int index, const QString& property, const QVariant& value, QList<int> *role);
+ void move(int from, int to, int count);
+
+ QVariant valueForNode(ModelNode *, bool *hasNested = 0) const;
+ void checkRoles() const;
+
+ ModelNode *_root;
+ QDeclarativeListModel *m_listModel;
+
+private:
+ mutable QStringList roleStrings;
+ mutable bool _rolesOk;
+};
+
+
+class ModelObject : public QObject
+{
+ Q_OBJECT
+public:
+ ModelObject();
+ void setValue(const QByteArray &name, const QVariant &val);
+
+private:
+ QDeclarativeOpenMetaObject *_mo;
+};
+
+struct ModelNode
+{
+ ModelNode();
+ ~ModelNode();
+
+ QList<QVariant> values;
+ QHash<QString, ModelNode *> properties;
+
+ QDeclarativeListModel *model(const NestedListModel *model) {
+ if (!modelCache) {
+ modelCache = new QDeclarativeListModel;
+ QDeclarativeEngine::setContextForObject(modelCache,QDeclarativeEngine::contextForObject(model->m_listModel));
+ modelCache->m_nested->_root = this; // ListModel defaults to nestable model
+ }
+ return modelCache;
+ }
+
+ ModelObject *object(const NestedListModel *model) {
+ if (!objectCache) {
+ objectCache = new ModelObject();
+ QHash<QString, ModelNode *>::iterator it;
+ for (it = properties.begin(); it != properties.end(); ++it) {
+ objectCache->setValue(it.key().toUtf8(), model->valueForNode(*it));
+ }
+ }
+ return objectCache;
+ }
+
+
+ void setObjectValue(const QScriptValue& valuemap);
+ void setListValue(const QScriptValue& valuelist);
+ void setProperty(const QString& prop, const QVariant& val);
+ static void dump(ModelNode *node, int ind);
+
+ QDeclarativeListModel *modelCache;
+ ModelObject *objectCache;
+ bool isArray;
+};
+
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(ModelNode *)
+
+QT_END_HEADER
+
+#endif // QDECLARATIVELISTMODEL_P_P_H
+
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent.cpp b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
new file mode 100644
index 0000000..ee43447
--- /dev/null
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativelistmodelworkeragent_p.h"
+#include "qdeclarativelistmodel_p_p.h"
+#include "qdeclarativedeclarativedata_p.h"
+#include "qdeclarativeengine_p.h"
+#include "qdeclarativeinfo.h"
+
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdebug.h>
+
+
+QT_BEGIN_NAMESPACE
+
+
+void QDeclarativeListModelWorkerAgent::Data::clearChange()
+{
+ changes.clear();
+}
+
+void QDeclarativeListModelWorkerAgent::Data::insertChange(int index, int count)
+{
+ Change c = { Change::Inserted, index, count, 0 };
+ changes << c;
+}
+
+void QDeclarativeListModelWorkerAgent::Data::removeChange(int index, int count)
+{
+ Change c = { Change::Removed, index, count, 0 };
+ changes << c;
+}
+
+void QDeclarativeListModelWorkerAgent::Data::moveChange(int index, int count, int to)
+{
+ Change c = { Change::Moved, index, count, to };
+ changes << c;
+}
+
+void QDeclarativeListModelWorkerAgent::Data::changedChange(int index, int count)
+{
+ Change c = { Change::Changed, index, count, 0 };
+ changes << c;
+}
+
+QDeclarativeListModelWorkerAgent::QDeclarativeListModelWorkerAgent(QDeclarativeListModel *model)
+: m_engine(0), m_ref(1), m_orig(model), m_copy(new QDeclarativeListModel(true, this))
+{
+ m_copy->m_flat->m_roles = m_orig->m_flat->m_roles;
+ m_copy->m_flat->m_strings = m_orig->m_flat->m_strings;
+ m_copy->m_flat->m_values = m_orig->m_flat->m_values;
+}
+
+QDeclarativeListModelWorkerAgent::~QDeclarativeListModelWorkerAgent()
+{
+}
+
+void QDeclarativeListModelWorkerAgent::setScriptEngine(QScriptEngine *eng)
+{
+ m_engine = eng;
+ if (m_copy->m_flat)
+ m_copy->m_flat->m_scriptEngine = eng;
+}
+
+QScriptEngine *QDeclarativeListModelWorkerAgent::scriptEngine() const
+{
+ return m_engine;
+}
+
+void QDeclarativeListModelWorkerAgent::addref()
+{
+ m_ref.ref();
+}
+
+void QDeclarativeListModelWorkerAgent::release()
+{
+ bool del = !m_ref.deref();
+
+ if (del)
+ delete this;
+}
+
+int QDeclarativeListModelWorkerAgent::count() const
+{
+ return m_copy->count();
+}
+
+void QDeclarativeListModelWorkerAgent::clear()
+{
+ data.clearChange();
+ data.removeChange(0, m_copy->count());
+ m_copy->clear();
+}
+
+void QDeclarativeListModelWorkerAgent::remove(int index)
+{
+ int count = m_copy->count();
+ m_copy->remove(index);
+
+ if (m_copy->count() != count)
+ data.removeChange(index, 1);
+}
+
+void QDeclarativeListModelWorkerAgent::append(const QScriptValue &value)
+{
+ int count = m_copy->count();
+ m_copy->append(value);
+
+ if (m_copy->count() != count)
+ data.insertChange(m_copy->count() - 1, 1);
+}
+
+void QDeclarativeListModelWorkerAgent::insert(int index, const QScriptValue &value)
+{
+ int count = m_copy->count();
+ m_copy->insert(index, value);
+
+ if (m_copy->count() != count)
+ data.insertChange(index, 1);
+}
+
+QScriptValue QDeclarativeListModelWorkerAgent::get(int index) const
+{
+ if (index < 0 || index >= count())
+ return m_engine->undefinedValue();
+
+ return m_copy->get(index);
+}
+
+void QDeclarativeListModelWorkerAgent::set(int index, const QScriptValue &value)
+{
+ m_copy->set(index, value);
+ data.changedChange(index, 1);
+}
+
+void QDeclarativeListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value)
+{
+ m_copy->setProperty(index, property, value);
+ data.changedChange(index, 1);
+}
+
+void QDeclarativeListModelWorkerAgent::move(int from, int to, int count)
+{
+ m_copy->move(from, to, count);
+ data.moveChange(from, to, count);
+}
+
+void QDeclarativeListModelWorkerAgent::sync()
+{
+ Sync *s = new Sync;
+ s->data = data;
+ s->list = m_copy;
+ data.changes.clear();
+ QCoreApplication::postEvent(this, s);
+}
+
+bool QDeclarativeListModelWorkerAgent::event(QEvent *e)
+{
+ if (e->type() == QEvent::User) {
+ Sync *s = static_cast<Sync *>(e);
+
+ const QList<Change> &changes = s->data.changes;
+
+ if (m_copy) {
+ bool cc = m_copy->count() != s->list->count();
+
+ FlatListModel *orig = m_orig->m_flat;
+ FlatListModel *copy = s->list->m_flat;
+ if (!orig || !copy) {
+ qWarning("QML List worker: cannot synchronize lists");
+ return QObject::event(e);
+ }
+ orig->m_roles = copy->m_roles;
+ orig->m_strings = copy->m_strings;
+ orig->m_values = copy->m_values;
+
+ for (int ii = 0; ii < changes.count(); ++ii) {
+ const Change &change = changes.at(ii);
+ switch (change.type) {
+ case Change::Inserted:
+ emit m_orig->itemsInserted(change.index, change.count);
+ break;
+ case Change::Removed:
+ emit m_orig->itemsRemoved(change.index, change.count);
+ break;
+ case Change::Moved:
+ emit m_orig->itemsMoved(change.index, change.to, change.count);
+ break;
+ case Change::Changed:
+ emit m_orig->itemsMoved(change.index, change.to, change.count);
+ break;
+ }
+ }
+
+ if (cc)
+ emit m_orig->countChanged(m_copy->count());
+
+ //qDebug() << "------sync():" << m_copy->count() << s->list->count() << m_orig->count();
+ }
+ }
+
+ return QObject::event(e);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/util/qdeclarativelistmodelworkeragent_p.h b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
new file mode 100644
index 0000000..b6a643b
--- /dev/null
+++ b/src/declarative/util/qdeclarativelistmodelworkeragent_p.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVELISTMODELWORKERAGENT_P_H
+#define QDECLARATIVELISTMODELWORKERAGENT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qdeclarative.h"
+
+#include <QtScript/qscriptvalue.h>
+#include <QtGui/qevent.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeListModel;
+
+// Currently this will leak as no-one releases it in the worker thread
+class QDeclarativeListModelWorkerAgent : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int count READ count)
+
+public:
+ QDeclarativeListModelWorkerAgent(QDeclarativeListModel *);
+ ~QDeclarativeListModelWorkerAgent();
+
+ void setScriptEngine(QScriptEngine *eng);
+ QScriptEngine *scriptEngine() const;
+
+ void addref();
+ void release();
+
+ int count() const;
+
+ Q_INVOKABLE void clear();
+ Q_INVOKABLE void remove(int index);
+ Q_INVOKABLE void append(const QScriptValue &);
+ Q_INVOKABLE void insert(int index, const QScriptValue&);
+ Q_INVOKABLE QScriptValue get(int index) const;
+ Q_INVOKABLE void set(int index, const QScriptValue &);
+ Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value);
+ Q_INVOKABLE void move(int from, int to, int count);
+ Q_INVOKABLE void sync();
+
+ struct VariantRef
+ {
+ VariantRef() : a(0) {}
+ VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); }
+ VariantRef(QDeclarativeListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); }
+ ~VariantRef() { if (a) a->release(); }
+
+ VariantRef &operator=(const VariantRef &o) {
+ if (o.a) o.a->addref();
+ if (a) a->release(); a = o.a;
+ return *this;
+ }
+
+ QDeclarativeListModelWorkerAgent *a;
+ };
+protected:
+ virtual bool event(QEvent *);
+
+private:
+ friend class QDeclarativeWorkerScriptEnginePrivate;
+ QScriptEngine *m_engine;
+
+ struct Change {
+ enum { Inserted, Removed, Moved, Changed } type;
+ int index; // Inserted/Removed/Moved/Changed
+ int count; // Inserted/Removed/Moved/Changed
+ int to; // Moved
+ };
+
+ struct Data {
+ QList<Change> changes;
+
+ void clearChange();
+ void insertChange(int index, int count);
+ void removeChange(int index, int count);
+ void moveChange(int index, int count, int to);
+ void changedChange(int index, int count);
+ };
+ Data data;
+
+ struct Sync : public QEvent {
+ Sync() : QEvent(QEvent::User) {}
+ Data data;
+ QDeclarativeListModel *list;
+ };
+
+ QAtomicInt m_ref;
+ QDeclarativeListModel *m_orig;
+ QDeclarativeListModel *m_copy;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QDeclarativeListModelWorkerAgent::VariantRef);
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEWORKERSCRIPT_P_H
+
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index cfb25dd..942d5f6 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -137,7 +137,7 @@ class QDeclarativeImageRequestHandler : public QObject
Q_OBJECT
public:
QDeclarativeImageRequestHandler(QDeclarativeImageReader *read, QDeclarativeEngine *eng)
- : QObject(), accessManager(0), engine(eng), reader(read)
+ : QObject(), accessManager(0), engine(eng), reader(read), redirectCount(0)
{
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
@@ -162,18 +162,24 @@ private:
QNetworkAccessManager *accessManager;
QDeclarativeEngine *engine;
QDeclarativeImageReader *reader;
+ int redirectCount;
+
+ static int replyDownloadProgress;
+ static int replyFinished;
+ static int downloadProgress;
+ static int thisNetworkRequestDone;
};
//===========================================================================
+int QDeclarativeImageRequestHandler::replyDownloadProgress = -1;
+int QDeclarativeImageRequestHandler::replyFinished = -1;
+int QDeclarativeImageRequestHandler::downloadProgress = -1;
+int QDeclarativeImageRequestHandler::thisNetworkRequestDone = -1;
+
bool QDeclarativeImageRequestHandler::event(QEvent *event)
{
if (event->type() == QEvent::User) {
- static int replyDownloadProgress = -1;
- static int replyFinished = -1;
- static int downloadProgress = -1;
- static int thisNetworkRequestDone = -1;
-
if (replyDownloadProgress == -1) {
replyDownloadProgress = QNetworkReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
replyFinished = QNetworkReply::staticMetaObject.indexOfSignal("finished()");
@@ -264,10 +270,33 @@ bool QDeclarativeImageRequestHandler::event(QEvent *event)
return QObject::event(event);
}
+#define IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION 16
+
void QDeclarativeImageRequestHandler::networkRequestDone()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
QDeclarativePixmapReply *job = replies.take(reply);
+
+ redirectCount++;
+ if (redirectCount < IMAGEREQUESTHANDLER_MAX_REDIRECT_RECURSION) {
+ QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = reply->url().resolved(redirect.toUrl());
+ QNetworkRequest req(url);
+ req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+
+ reply->deleteLater();
+ reply = networkAccessManager()->get(req);
+
+ QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress);
+ QMetaObject::connect(reply, replyFinished, this, thisNetworkRequestDone);
+
+ replies.insert(reply, job);
+ return;
+ }
+ }
+ redirectCount=0;
+
if (job) {
QImage image;
QDeclarativeImageReaderEvent::ReadError error;
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index 9c2b1e6..8865e04 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -439,7 +439,8 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions()
if (d->isExplicit) {
a.toValue = d->expressions.at(ii).second->value();
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this));
+ QDeclarativeBinding *newBinding =
+ new QDeclarativeBinding(d->expressions.at(ii).second->expression(), object(), qmlContext(this));
newBinding->setTarget(prop);
a.toBinding = newBinding;
a.deletableToBinding = true;
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 1d70d33..802ff1c 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -96,21 +96,12 @@ void QDeclarativeActionEvent::reverse()
{
}
-QList<QDeclarativeAction> QDeclarativeActionEvent::extraActions()
-{
- return QList<QDeclarativeAction>();
-}
-
bool QDeclarativeActionEvent::changesBindings()
{
return false;
}
-void QDeclarativeActionEvent::clearForwardBindings()
-{
-}
-
-void QDeclarativeActionEvent::clearReverseBindings()
+void QDeclarativeActionEvent::clearBindings()
{
}
@@ -368,47 +359,60 @@ void QDeclarativeState::apply(QDeclarativeStateGroup *group, QDeclarativeTransit
for (int ii = 0; ii < applyList.count(); ++ii) {
QDeclarativeAction &action = applyList[ii];
- bool found = false;
-
- int jj;
if (action.event) {
if (!action.event->isReversable())
continue;
- for (jj = 0; jj < d->revertList.count(); ++jj) {
+ bool found = false;
+ for (int jj = 0; jj < d->revertList.count(); ++jj) {
QDeclarativeActionEvent *event = d->revertList.at(jj).event;
if (event && event->typeName() == action.event->typeName()) {
if (action.event->override(event)) {
found = true;
+
+ if (action.event != d->revertList.at(jj).event) {
+ action.event->copyOriginals(d->revertList.at(jj).event);
+
+ QDeclarativeSimpleAction r(action);
+ additionalReverts << r;
+ d->revertList.removeAt(jj);
+ } else if (action.event->isRewindable()) //###why needed?
+ action.event->saveCurrentValues();
+
break;
}
}
}
- if (!found || action.event != d->revertList.at(jj).event)
+ if (!found) {
action.event->saveOriginals();
- else if (action.event->isRewindable())
- action.event->saveCurrentValues();
+ // Only need to revert the applyList action if the previous
+ // state doesn't have a higher priority revert already
+ QDeclarativeSimpleAction r(action);
+ additionalReverts << r;
+ }
} else {
+ bool found = false;
action.fromBinding = QDeclarativePropertyPrivate::binding(action.property);
- for (jj = 0; jj < d->revertList.count(); ++jj) {
+ for (int jj = 0; jj < d->revertList.count(); ++jj) {
if (d->revertList.at(jj).property == action.property) {
found = true;
+ if (d->revertList.at(jj).binding != action.fromBinding) {
+ action.deleteFromBinding();
+ }
break;
}
}
- }
- if (!found) {
- if (!action.restore) {
- action.deleteFromBinding();
- } else {
- // Only need to revert the applyList action if the previous
- // state doesn't have a higher priority revert already
- QDeclarativeSimpleAction r(action);
- additionalReverts << r;
+ if (!found) {
+ if (!action.restore) {
+ action.deleteFromBinding();
+ } else {
+ // Only need to revert the applyList action if the previous
+ // state doesn't have a higher priority revert already
+ QDeclarativeSimpleAction r(action);
+ additionalReverts << r;
+ }
}
- } else if (d->revertList.at(jj).binding != action.fromBinding) {
- action.deleteFromBinding();
}
}
diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h
index 0c6e7a3..ee2b7e8 100644
--- a/src/declarative/util/qdeclarativestate_p.h
+++ b/src/declarative/util/qdeclarativestate_p.h
@@ -92,17 +92,15 @@ public:
virtual bool isReversable();
virtual void reverse();
virtual void saveOriginals() {}
+ virtual void copyOriginals(QDeclarativeActionEvent *) {}
virtual bool isRewindable() { return isReversable(); }
virtual void rewind() {}
virtual void saveCurrentValues() {}
-
- //virtual bool hasExtraActions();
- virtual QList<QDeclarativeAction> extraActions();
+ virtual void saveTargetValues() {}
virtual bool changesBindings();
- virtual void clearForwardBindings();
- virtual void clearReverseBindings();
+ virtual void clearBindings();
virtual bool override(QDeclarativeActionEvent*other);
};
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index 766d1bc..6f5bb66 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -403,6 +403,17 @@ void QDeclarativeParentChange::saveOriginals()
d->origStackBefore = d->rewindStackBefore;
}
+void QDeclarativeParentChange::copyOriginals(QDeclarativeActionEvent *other)
+{
+ Q_D(QDeclarativeParentChange);
+ QDeclarativeParentChange *pc = static_cast<QDeclarativeParentChange*>(other);
+
+ d->origParent = pc->d_func()->rewindParent;
+ d->origStackBefore = pc->d_func()->rewindStackBefore;
+
+ saveCurrentValues();
+}
+
void QDeclarativeParentChange::execute()
{
Q_D(QDeclarativeParentChange);
@@ -561,11 +572,17 @@ QString QDeclarativeStateChangeScript::typeName() const
\qmlclass AnchorChanges QDeclarativeAnchorChanges
\brief The AnchorChanges element allows you to change the anchors of an item in a state.
- AnchorChanges will 'inject' \c x, \c y, \c width, and \c height changes into the transition,
- so you can animate them as you would normally changes to these properties:
+ In the following example we change the top and bottom anchors of an item:
+ \qml
+ AnchorChanges {
+ target: content; top: window.top; bottom: window.bottom
+ }
+ \endqml
+
+ AnchorChanges can be animated using AnchorAnimation.
\qml
//animate our anchor changes
- NumberAnimation { targets: content; properties: "x,y,width,height" }
+ AnchorAnimation {}
\endqml
For more information on anchors see \l {anchor-layout}{Anchor Layouts}.
@@ -578,10 +595,10 @@ class QDeclarativeAnchorChangesPrivate : public QObjectPrivate
public:
QDeclarativeAnchorChangesPrivate() : target(0) {}
- QString name;
QDeclarativeItem *target;
QString resetString;
QStringList resetList;
+
QDeclarativeAnchorLine left;
QDeclarativeAnchorLine right;
QDeclarativeAnchorLine horizontalCenter;
@@ -610,6 +627,24 @@ public:
qreal fromY;
qreal fromWidth;
qreal fromHeight;
+
+ qreal toX;
+ qreal toY;
+ qreal toWidth;
+ qreal toHeight;
+
+ qreal rewindX;
+ qreal rewindY;
+ qreal rewindWidth;
+ qreal rewindHeight;
+
+ bool applyOrigLeft;
+ bool applyOrigRight;
+ bool applyOrigHCenter;
+ bool applyOrigTop;
+ bool applyOrigBottom;
+ bool applyOrigVCenter;
+ bool applyOrigBaseline;
};
/*!
@@ -762,6 +797,38 @@ void QDeclarativeAnchorChanges::execute()
if (!d->target)
return;
+ //incorporate any needed "reverts"
+ if (d->applyOrigLeft)
+ d->target->anchors()->setLeft(d->origLeft);
+ if (d->applyOrigRight)
+ d->target->anchors()->setRight(d->origRight);
+ if (d->applyOrigHCenter)
+ d->target->anchors()->setHorizontalCenter(d->origHCenter);
+ if (d->applyOrigTop)
+ d->target->anchors()->setTop(d->origTop);
+ if (d->applyOrigBottom)
+ d->target->anchors()->setBottom(d->origBottom);
+ if (d->applyOrigVCenter)
+ d->target->anchors()->setVerticalCenter(d->origVCenter);
+ if (d->applyOrigBaseline)
+ d->target->anchors()->setBaseline(d->origBaseline);
+
+ //reset any anchors that have been specified
+ if (d->resetList.contains(QLatin1String("left")))
+ d->target->anchors()->resetLeft();
+ if (d->resetList.contains(QLatin1String("right")))
+ d->target->anchors()->resetRight();
+ if (d->resetList.contains(QLatin1String("horizontalCenter")))
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->resetList.contains(QLatin1String("top")))
+ d->target->anchors()->resetTop();
+ if (d->resetList.contains(QLatin1String("bottom")))
+ d->target->anchors()->resetBottom();
+ if (d->resetList.contains(QLatin1String("verticalCenter")))
+ d->target->anchors()->resetVerticalCenter();
+ if (d->resetList.contains(QLatin1String("baseline")))
+ d->target->anchors()->resetBaseline();
+
//set any anchors that have been specified
if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
d->target->anchors()->setLeft(d->left);
@@ -790,6 +857,22 @@ void QDeclarativeAnchorChanges::reverse()
if (!d->target)
return;
+ //reset any anchors set by the state
+ if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetLeft();
+ if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetRight();
+ if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetTop();
+ if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBottom();
+ if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
+ d->target->anchors()->resetBaseline();
+
//restore previous anchors
if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
d->target->anchors()->setLeft(d->origLeft);
@@ -812,31 +895,33 @@ QString QDeclarativeAnchorChanges::typeName() const
return QLatin1String("AnchorChanges");
}
-QList<QDeclarativeAction> QDeclarativeAnchorChanges::extraActions()
+QList<QDeclarativeAction> QDeclarativeAnchorChanges::additionalActions()
{
Q_D(QDeclarativeAnchorChanges);
QList<QDeclarativeAction> extra;
- //### try to be smarter about which ones we add.
- // or short-circuit later on if they haven't actually changed.
- // we shouldn't set explicit width if there wasn't one before.
if (d->target) {
QDeclarativeAction a;
- a.fromValue = d->fromX;
- a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
- extra << a;
-
- a.fromValue = d->fromY;
- a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
- extra << a;
-
- a.fromValue = d->fromWidth;
- a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
- extra << a;
-
- a.fromValue = d->fromHeight;
- a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
- extra << a;
+ if (d->fromX != d->toX) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
+ a.toValue = d->toX;
+ extra << a;
+ }
+ if (d->fromY != d->toY) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
+ a.toValue = d->toY;
+ extra << a;
+ }
+ if (d->fromWidth != d->toWidth) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
+ a.toValue = d->toWidth;
+ extra << a;
+ }
+ if (d->fromHeight != d->toHeight) {
+ a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
+ a.toValue = d->toHeight;
+ extra << a;
+ }
}
return extra;
@@ -858,10 +943,52 @@ void QDeclarativeAnchorChanges::saveOriginals()
d->origVCenter = d->target->anchors()->verticalCenter();
d->origBaseline = d->target->anchors()->baseline();
+ d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
+ = d->applyOrigBottom = d->applyOrigHCenter = d->applyOrigBaseline = false;
+
saveCurrentValues();
}
-void QDeclarativeAnchorChanges::clearForwardBindings()
+void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
+{
+ Q_D(QDeclarativeAnchorChanges);
+ QDeclarativeAnchorChanges *ac = static_cast<QDeclarativeAnchorChanges*>(other);
+ QDeclarativeAnchorChangesPrivate *acp = ac->d_func();
+
+ //probably also need to revert some things
+ d->applyOrigLeft = (acp->left.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("left")));
+
+ d->applyOrigRight = (acp->right.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("right")));
+
+ d->applyOrigHCenter = (acp->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("horizontalCenter")));
+
+ d->applyOrigTop = (acp->top.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("top")));
+
+ d->applyOrigBottom = (acp->bottom.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("bottom")));
+
+ d->applyOrigVCenter = (acp->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("verticalCenter")));
+
+ d->applyOrigBaseline = (acp->baseline.anchorLine != QDeclarativeAnchorLine::Invalid ||
+ acp->resetList.contains(QLatin1String("baseline")));
+
+ d->origLeft = ac->d_func()->origLeft;
+ d->origRight = ac->d_func()->origRight;
+ d->origHCenter = ac->d_func()->origHCenter;
+ d->origTop = ac->d_func()->origTop;
+ d->origBottom = ac->d_func()->origBottom;
+ d->origVCenter = ac->d_func()->origVCenter;
+ d->origBaseline = ac->d_func()->origBaseline;
+
+ saveCurrentValues();
+}
+
+void QDeclarativeAnchorChanges::clearBindings()
{
Q_D(QDeclarativeAnchorChanges);
d->fromX = d->target->x();
@@ -869,6 +996,22 @@ void QDeclarativeAnchorChanges::clearForwardBindings()
d->fromWidth = d->target->width();
d->fromHeight = d->target->height();
+ //reset any anchors with corresponding reverts
+ if (d->applyOrigLeft)
+ d->target->anchors()->resetLeft();
+ if (d->applyOrigRight)
+ d->target->anchors()->resetRight();
+ if (d->applyOrigHCenter)
+ d->target->anchors()->resetHorizontalCenter();
+ if (d->applyOrigTop)
+ d->target->anchors()->resetTop();
+ if (d->applyOrigBottom)
+ d->target->anchors()->resetBottom();
+ if (d->applyOrigVCenter)
+ d->target->anchors()->resetVerticalCenter();
+ if (d->applyOrigBaseline)
+ d->target->anchors()->resetBaseline();
+
//reset any anchors that have been specified
if (d->resetList.contains(QLatin1String("left")))
d->target->anchors()->resetLeft();
@@ -902,47 +1045,6 @@ void QDeclarativeAnchorChanges::clearForwardBindings()
d->target->anchors()->resetBaseline();
}
-void QDeclarativeAnchorChanges::clearReverseBindings()
-{
- Q_D(QDeclarativeAnchorChanges);
- d->fromX = d->target->x();
- d->fromY = d->target->y();
- d->fromWidth = d->target->width();
- d->fromHeight = d->target->height();
-
- //reset any anchors that were set in the state
- if (d->left.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetLeft();
- if (d->right.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetRight();
- if (d->horizontalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetHorizontalCenter();
- if (d->top.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetTop();
- if (d->bottom.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBottom();
- if (d->verticalCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetVerticalCenter();
- if (d->baseline.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBaseline();
-
- //reset any anchors that were set in the original state
- if (d->origLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetLeft();
- if (d->origRight.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetRight();
- if (d->origHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetHorizontalCenter();
- if (d->origTop.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetTop();
- if (d->origBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBottom();
- if (d->origVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetVerticalCenter();
- if (d->origBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
- d->target->anchors()->resetBaseline();
-}
-
bool QDeclarativeAnchorChanges::override(QDeclarativeActionEvent*other)
{
if (other->typeName() != QLatin1String("AnchorChanges"))
@@ -975,6 +1077,11 @@ void QDeclarativeAnchorChanges::rewind()
d->target->anchors()->setVerticalCenter(d->rewindVCenter);
if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
d->target->anchors()->setBaseline(d->rewindBaseline);
+
+ d->target->setX(d->rewindX);
+ d->target->setY(d->rewindY);
+ d->target->setWidth(d->rewindWidth);
+ d->target->setHeight(d->rewindHeight);
}
void QDeclarativeAnchorChanges::saveCurrentValues()
@@ -987,6 +1094,20 @@ void QDeclarativeAnchorChanges::saveCurrentValues()
d->rewindBottom = d->target->anchors()->bottom();
d->rewindVCenter = d->target->anchors()->verticalCenter();
d->rewindBaseline = d->target->anchors()->baseline();
+
+ d->rewindX = d->target->x();
+ d->rewindY = d->target->y();
+ d->rewindWidth = d->target->width();
+ d->rewindHeight = d->target->height();
+}
+
+void QDeclarativeAnchorChanges::saveTargetValues()
+{
+ Q_D(QDeclarativeAnchorChanges);
+ d->toX = d->target->x();
+ d->toY = d->target->y();
+ d->toWidth = d->target->width();
+ d->toHeight = d->target->height();
}
#include <qdeclarativestateoperations.moc>
diff --git a/src/declarative/util/qdeclarativestateoperations_p.h b/src/declarative/util/qdeclarativestateoperations_p.h
index dd4248023..66a8717 100644
--- a/src/declarative/util/qdeclarativestateoperations_p.h
+++ b/src/declarative/util/qdeclarativestateoperations_p.h
@@ -107,6 +107,7 @@ public:
virtual ActionList actions();
virtual void saveOriginals();
+ virtual void copyOriginals(QDeclarativeActionEvent*);
virtual void execute();
virtual bool isReversable();
virtual void reverse();
@@ -196,13 +197,15 @@ public:
virtual void reverse();
virtual QString typeName() const;
virtual bool override(QDeclarativeActionEvent*other);
- virtual QList<QDeclarativeAction> extraActions();
virtual bool changesBindings();
virtual void saveOriginals();
- virtual void clearForwardBindings();
- virtual void clearReverseBindings();
+ virtual void copyOriginals(QDeclarativeActionEvent*);
+ virtual void clearBindings();
virtual void rewind();
virtual void saveCurrentValues();
+
+ QList<QDeclarativeAction> additionalActions();
+ virtual void saveTargetValues();
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/qdeclarativetransitionmanager.cpp b/src/declarative/util/qdeclarativetransitionmanager.cpp
index e1143fa..f07fb23 100644
--- a/src/declarative/util/qdeclarativetransitionmanager.cpp
+++ b/src/declarative/util/qdeclarativetransitionmanager.cpp
@@ -126,10 +126,7 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
QDeclarativePropertyPrivate::setBinding(action.property, 0); // Disable current binding
if (action.event && action.event->changesBindings()) { //### assume isReversable()?
d->bindingsList << action;
- if (action.reverseEvent)
- action.event->clearReverseBindings();
- else
- action.event->clearForwardBindings();
+ action.event->clearBindings();
}
}
@@ -144,8 +141,6 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
if (!d->bindingsList.isEmpty()) {
- //### do extra actions here?
-
// Apply all the property and binding changes
for (int ii = 0; ii < applyList.size(); ++ii) {
const QDeclarativeAction &action = applyList.at(ii);
@@ -158,17 +153,18 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
action.event->reverse();
else
action.event->execute();
- applyList << action.event->extraActions();
}
}
// Read all the end values for binding changes
for (int ii = 0; ii < applyList.size(); ++ii) {
QDeclarativeAction *action = &applyList[ii];
- if (action->event)
+ if (action->event) {
+ action->event->saveTargetValues();
continue;
+ }
const QDeclarativeProperty &prop = action->property;
- if (action->toBinding || !action->toValue.isValid()) { //### is this always right (used for exta actions)
+ if (action->toBinding || !action->toValue.isValid()) {
action->toValue = prop.read();
}
}
@@ -177,15 +173,9 @@ void QDeclarativeTransitionManager::transition(const QList<QDeclarativeAction> &
foreach(const QDeclarativeAction &action, applyList) {
if (action.event) {
if (action.event->isReversable()) {
- if (action.reverseEvent) { //reverse the reverse
- action.event->clearForwardBindings();
- action.event->rewind();
- action.event->clearReverseBindings();
- } else {
- action.event->clearReverseBindings();
- action.event->rewind();
- action.event->clearForwardBindings();
- }
+ action.event->clearBindings();
+ action.event->rewind();
+ action.event->clearBindings();
}
continue;
}
diff --git a/src/declarative/util/qdeclarativeutilmodule.cpp b/src/declarative/util/qdeclarativeutilmodule.cpp
index 65bfdc1..4d4678a 100644
--- a/src/declarative/util/qdeclarativeutilmodule.cpp
+++ b/src/declarative/util/qdeclarativeutilmodule.cpp
@@ -75,44 +75,48 @@
void QDeclarativeUtilModule::defineModule()
{
- QML_REGISTER_TYPE(Qt,4,6,AnchorChanges,QDeclarativeAnchorChanges);
- QML_REGISTER_TYPE(Qt,4,6,Behavior,QDeclarativeBehavior);
- QML_REGISTER_TYPE(Qt,4,6,Binding,QDeclarativeBind);
- QML_REGISTER_TYPE(Qt,4,6,ColorAnimation,QDeclarativeColorAnimation);
- QML_REGISTER_TYPE(Qt,4,6,Connections,QDeclarativeConnections);
- QML_REGISTER_TYPE(Qt,4,6,EaseFollow,QDeclarativeEaseFollow);;
- QML_REGISTER_TYPE(Qt,4,6,FontLoader,QDeclarativeFontLoader);
- QML_REGISTER_TYPE(Qt,4,6,ListElement,QDeclarativeListElement);
- QML_REGISTER_TYPE(Qt,4,6,NumberAnimation,QDeclarativeNumberAnimation);
- QML_REGISTER_TYPE(Qt,4,6,Package,QDeclarativePackage);
- QML_REGISTER_TYPE(Qt,4,6,ParallelAnimation,QDeclarativeParallelAnimation);
- QML_REGISTER_TYPE(Qt,4,6,ParentAction,QDeclarativeParentAction);
- QML_REGISTER_TYPE(Qt,4,6,ParentAnimation,QDeclarativeParentAnimation);
- QML_REGISTER_TYPE(Qt,4,6,ParentChange,QDeclarativeParentChange);
- QML_REGISTER_TYPE(Qt,4,6,PauseAnimation,QDeclarativePauseAnimation);
- QML_REGISTER_TYPE(Qt,4,6,PropertyAction,QDeclarativePropertyAction);
- QML_REGISTER_TYPE(Qt,4,6,PropertyAnimation,QDeclarativePropertyAnimation);
- QML_REGISTER_TYPE(Qt,4,6,RotationAnimation,QDeclarativeRotationAnimation);
- QML_REGISTER_TYPE(Qt,4,6,ScriptAction,QDeclarativeScriptAction);
- QML_REGISTER_TYPE(Qt,4,6,SequentialAnimation,QDeclarativeSequentialAnimation);
- QML_REGISTER_TYPE(Qt,4,6,SpringFollow,QDeclarativeSpringFollow);
- QML_REGISTER_TYPE(Qt,4,6,StateChangeScript,QDeclarativeStateChangeScript);
- QML_REGISTER_TYPE(Qt,4,6,StateGroup,QDeclarativeStateGroup);
- QML_REGISTER_TYPE(Qt,4,6,State,QDeclarativeState);
- QML_REGISTER_TYPE(Qt,4,6,SystemPalette,QDeclarativeSystemPalette);
- QML_REGISTER_TYPE(Qt,4,6,Timer,QDeclarativeTimer);
- QML_REGISTER_TYPE(Qt,4,6,Transition,QDeclarativeTransition);
- QML_REGISTER_TYPE(Qt,4,6,Vector3dAnimation,QDeclarativeVector3dAnimation);
+ qmlRegisterType<QDeclarativeAnchorAnimation>("Qt",4,6,"AnchorAnimation");
+ qmlRegisterType<QDeclarativeAnchorChanges>("Qt",4,6,"AnchorChanges");
+ qmlRegisterType<QDeclarativeBehavior>("Qt",4,6,"Behavior");
+ qmlRegisterType<QDeclarativeBind>("Qt",4,6,"Binding");
+ qmlRegisterType<QDeclarativeColorAnimation>("Qt",4,6,"ColorAnimation");
+ qmlRegisterType<QDeclarativeConnections>("Qt",4,6,"Connections");
+ qmlRegisterType<QDeclarativeEaseFollow>("Qt",4,6,"EaseFollow");
+ qmlRegisterType<QDeclarativeFontLoader>("Qt",4,6,"FontLoader");
+ qmlRegisterType<QDeclarativeListElement>("Qt",4,6,"ListElement");
+ qmlRegisterType<QDeclarativeNumberAnimation>("Qt",4,6,"NumberAnimation");
+ qmlRegisterType<QDeclarativePackage>("Qt",4,6,"Package");
+ qmlRegisterType<QDeclarativeParallelAnimation>("Qt",4,6,"ParallelAnimation");
+ qmlRegisterType<QDeclarativeParentAction>("Qt",4,6,"ParentAction");
+ qmlRegisterType<QDeclarativeParentAnimation>("Qt",4,6,"ParentAnimation");
+ qmlRegisterType<QDeclarativeParentChange>("Qt",4,6,"ParentChange");
+ qmlRegisterType<QDeclarativePauseAnimation>("Qt",4,6,"PauseAnimation");
+ qmlRegisterType<QDeclarativePropertyAction>("Qt",4,6,"PropertyAction");
+ qmlRegisterType<QDeclarativePropertyAnimation>("Qt",4,6,"PropertyAnimation");
+ qmlRegisterType<QDeclarativeRotationAnimation>("Qt",4,6,"RotationAnimation");
+ qmlRegisterType<QDeclarativeScriptAction>("Qt",4,6,"ScriptAction");
+ qmlRegisterType<QDeclarativeSequentialAnimation>("Qt",4,6,"SequentialAnimation");
+ qmlRegisterType<QDeclarativeSpringFollow>("Qt",4,6,"SpringFollow");
+ qmlRegisterType<QDeclarativeStateChangeScript>("Qt",4,6,"StateChangeScript");
+ qmlRegisterType<QDeclarativeStateGroup>("Qt",4,6,"StateGroup");
+ qmlRegisterType<QDeclarativeState>("Qt",4,6,"State");
+ qmlRegisterType<QDeclarativeSystemPalette>("Qt",4,6,"SystemPalette");
+ qmlRegisterType<QDeclarativeTimer>("Qt",4,6,"Timer");
+ qmlRegisterType<QDeclarativeTransition>("Qt",4,6,"Transition");
+ qmlRegisterType<QDeclarativeVector3dAnimation>("Qt",4,6,"Vector3dAnimation");
#ifndef QT_NO_XMLPATTERNS
- QML_REGISTER_TYPE(Qt,4,6,XmlListModel,QDeclarativeXmlListModel);
- QML_REGISTER_TYPE(Qt,4,6,XmlRole,QDeclarativeXmlListModelRole);
+ qmlRegisterType<QDeclarativeXmlListModel>("Qt",4,6,"XmlListModel");
+ qmlRegisterType<QDeclarativeXmlListModelRole>("Qt",4,6,"XmlRole");
#endif
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeAnchors);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeAbstractAnimation);
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeStateOperation);
+ qmlRegisterType<QDeclarativeAnchors>();
+ qmlRegisterType<QDeclarativeAbstractAnimation>();
+ qmlRegisterType<QDeclarativeStateOperation>();
- QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, ListModel, QDeclarativeListModel, QDeclarativeListModelParser);
- QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, PropertyChanges, QDeclarativePropertyChanges, QDeclarativePropertyChangesParser);
- QML_REGISTER_CUSTOM_TYPE(Qt, 4,6, Connections, QDeclarativeConnections, QDeclarativeConnectionsParser);
+ qmlRegisterCustomType<QDeclarativeListModel>("Qt", 4,6, "ListModel", "QDeclarativeListModel",
+ new QDeclarativeListModelParser);
+ qmlRegisterCustomType<QDeclarativePropertyChanges>("Qt", 4, 6, "PropertyChanges", "QDeclarativePropertyChanges",
+ new QDeclarativePropertyChangesParser);
+ qmlRegisterCustomType<QDeclarativeConnections>("Qt", 4, 6, "Connections", "QDeclarativeConnections",
+ new QDeclarativeConnectionsParser);
}
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index 735a009..59a062a 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -298,6 +298,7 @@ QDeclarativeView::~QDeclarativeView()
void QDeclarativeView::setSource(const QUrl& url)
{
d->source = url;
+ d->engine.setBaseUrl(url);
d->execute();
}
@@ -458,8 +459,8 @@ void QDeclarativeView::setRootObject(QObject *obj)
QPerformanceLog::clear();
d->root = item;
d->qmlRoot = item;
- connect(item, SIGNAL(widthChanged()), this, SLOT(sizeChanged()));
- connect(item, SIGNAL(heightChanged()), this, SLOT(sizeChanged()));
+ connect(item, SIGNAL(widthChanged(qreal)), this, SLOT(sizeChanged()));
+ connect(item, SIGNAL(heightChanged(qreal)), this, SLOT(sizeChanged()));
if (d->initialSize.height() <= 0 && d->qmlRoot->width() > 0)
d->initialSize.setWidth(d->qmlRoot->width());
if (d->initialSize.height() <= 0 && d->qmlRoot->height() > 0)
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 49dbb27..01ae2ed 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -61,6 +61,9 @@
QT_BEGIN_NAMESPACE
+
+
+
typedef QPair<int, int> QDeclarativeXmlListRange;
/*!
@@ -111,6 +114,9 @@ class QDeclarativeXmlQuery : public QThread
{
Q_OBJECT
public:
+ QDeclarativeXmlQuery(QObject *parent=0)
+ : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) {
+ }
~QDeclarativeXmlQuery() {
m_mutex.lock();
m_quit = true;
@@ -120,11 +126,6 @@ public:
wait();
}
- static QDeclarativeXmlQuery *instance() {
- static QDeclarativeXmlQuery *query = new QDeclarativeXmlQuery;
- return query;
- }
-
void abort() {
QMutexLocker locker(&m_mutex);
m_abort = true;
@@ -163,11 +164,6 @@ public:
return m_removedItemRanges;
}
-private:
- QDeclarativeXmlQuery(QObject *parent=0)
- : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) {
- }
-
Q_SIGNALS:
void queryCompleted(int queryId, int size);
@@ -217,8 +213,6 @@ private:
QList<QDeclarativeXmlListRange> m_removedItemRanges;
};
-//Q_GLOBAL_STATIC(QDeclarativeXmlQuery, QDeclarativeXmlQuery::instance());
-
void QDeclarativeXmlQuery::doQueryJob()
{
QString r;
@@ -396,7 +390,7 @@ public:
QDeclarativeXmlListModelPrivate()
: isComponentComplete(true), size(-1), highestRole(Qt::UserRole)
, reply(0), status(QDeclarativeXmlListModel::Null), progress(0.0)
- , queryId(-1), roleObjects() {}
+ , queryId(-1), roleObjects(), redirectCount(0) {}
bool isComponentComplete;
QUrl src;
@@ -410,6 +404,7 @@ public:
QNetworkReply *reply;
QDeclarativeXmlListModel::Status status;
qreal progress;
+ QDeclarativeXmlQuery qmlXmlQuery;
int queryId;
QList<QDeclarativeXmlListModelRole *> roleObjects;
static void append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role);
@@ -417,6 +412,7 @@ public:
static void removeAt_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, int i);
static void insert_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, int i, QDeclarativeXmlListModelRole *role);
QList<QList<QVariant> > data;
+ int redirectCount;
};
@@ -493,7 +489,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent)
: QListModelInterface(*(new QDeclarativeXmlListModelPrivate), parent)
{
- connect(QDeclarativeXmlQuery::instance(), SIGNAL(queryCompleted(int,int)),
+ Q_D(QDeclarativeXmlListModel);
+ connect(&d->qmlXmlQuery, SIGNAL(queryCompleted(int,int)),
this, SLOT(queryCompleted(int,int)));
}
@@ -575,8 +572,8 @@ void QDeclarativeXmlListModel::setSource(const QUrl &src)
{
Q_D(QDeclarativeXmlListModel);
if (d->src != src) {
- reload();
d->src = src;
+ reload();
emit sourceChanged();
}
}
@@ -726,7 +723,7 @@ void QDeclarativeXmlListModel::reload()
if (!d->isComponentComplete)
return;
- QDeclarativeXmlQuery::instance()->abort();
+ d->qmlXmlQuery.abort();
d->queryId = -1;
int count = d->size;
@@ -758,7 +755,7 @@ void QDeclarativeXmlListModel::reload()
}
if (!d->xml.isEmpty()) {
- d->queryId = QDeclarativeXmlQuery::instance()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects);
+ d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects);
d->progress = 1.0;
d->status = Ready;
emit progressChanged(d->progress);
@@ -778,9 +775,25 @@ void QDeclarativeXmlListModel::reload()
this, SLOT(requestProgress(qint64,qint64)));
}
+#define XMLLISTMODEL_MAX_REDIRECT 16
+
void QDeclarativeXmlListModel::requestFinished()
{
Q_D(QDeclarativeXmlListModel);
+
+ d->redirectCount++;
+ if (d->redirectCount < XMLLISTMODEL_MAX_REDIRECT) {
+ QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = d->reply->url().resolved(redirect.toUrl());
+ d->reply->deleteLater();
+ d->reply = 0;
+ setSource(url);
+ return;
+ }
+ }
+ d->redirectCount = 0;
+
if (d->reply->error() != QNetworkReply::NoError) {
disconnect(d->reply, 0, this, 0);
d->reply->deleteLater();
@@ -789,7 +802,7 @@ void QDeclarativeXmlListModel::requestFinished()
} else {
d->status = Ready;
QByteArray data = d->reply->readAll();
- d->queryId = QDeclarativeXmlQuery::instance()->doQuery(d->query, d->namespaces, data, &d->roleObjects);
+ d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, data, &d->roleObjects);
disconnect(d->reply, 0, this, 0);
d->reply->deleteLater();
d->reply = 0;
@@ -815,10 +828,10 @@ void QDeclarativeXmlListModel::queryCompleted(int id, int size)
return;
bool sizeChanged = size != d->size;
d->size = size;
- d->data = QDeclarativeXmlQuery::instance()->modelData();
+ d->data = d->qmlXmlQuery.modelData();
- QList<QDeclarativeXmlListRange> removed = QDeclarativeXmlQuery::instance()->removedItemRanges();
- QList<QDeclarativeXmlListRange> inserted = QDeclarativeXmlQuery::instance()->insertedItemRanges();
+ QList<QDeclarativeXmlListRange> removed = d->qmlXmlQuery.removedItemRanges();
+ QList<QDeclarativeXmlListRange> inserted = d->qmlXmlQuery.insertedItemRanges();
for (int i=0; i<removed.count(); i++)
emit itemsRemoved(removed[i].first, removed[i].second);
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index 26edecc..ddf00ea 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -27,7 +27,8 @@ SOURCES += \
$$PWD/qdeclarativepixmapcache.cpp \
$$PWD/qdeclarativebehavior.cpp \
$$PWD/qdeclarativefontloader.cpp \
- $$PWD/qdeclarativestyledtext.cpp
+ $$PWD/qdeclarativestyledtext.cpp \
+ $$PWD/qdeclarativelistmodelworkeragent.cpp
HEADERS += \
$$PWD/qdeclarativeutilmodule_p.h\
@@ -49,6 +50,7 @@ HEADERS += \
$$PWD/qdeclarativestategroup_p.h \
$$PWD/qdeclarativetransition_p.h \
$$PWD/qdeclarativelistmodel_p.h\
+ $$PWD/qdeclarativelistmodel_p_p.h\
$$PWD/qdeclarativelistaccessor_p.h \
$$PWD/qdeclarativeopenmetaobject_p.h \
$$PWD/qdeclarativenullablevalue_p_p.h \
@@ -59,7 +61,9 @@ HEADERS += \
$$PWD/qdeclarativepixmapcache_p.h \
$$PWD/qdeclarativebehavior_p.h \
$$PWD/qdeclarativefontloader_p.h \
- $$PWD/qdeclarativestyledtext_p.h
+ $$PWD/qdeclarativestyledtext_p.h \
+ $$PWD/qdeclarativelistmodelworkeragent_p.h \
+ $$PWD/qdeclarativelistmodelworkeragent_p_p.h
contains(QT_CONFIG, xmlpatterns) {
QT+=xmlpatterns
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index bea2b6e..bfeef72 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -704,28 +704,13 @@ bool QRegion::intersects(const QRegion &region) const
}
/*!
+ \fn bool QRegion::intersects(const QRect &rect) const
\since 4.2
Returns true if this region intersects with \a rect, otherwise
returns false.
*/
-bool QRegion::intersects(const QRect &rect) const
-{
- if (isEmpty() || rect.isNull())
- return false;
- const QRect r = rect.normalized();
- if (!rect_intersects(boundingRect(), r))
- return false;
- if (rectCount() == 1)
- return true;
-
- const QVector<QRect> myRects = rects();
- for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it)
- if (rect_intersects(r, *it))
- return true;
- return false;
-}
#if !defined (Q_OS_UNIX) && !defined (Q_WS_WIN)
/*!
@@ -4349,5 +4334,24 @@ bool QRegion::operator==(const QRegion &r) const
return EqualRegion(d->qt_rgn, r.d->qt_rgn);
}
+bool QRegion::intersects(const QRect &rect) const
+{
+ if (isEmptyHelper(d->qt_rgn) || rect.isNull())
+ return false;
+
+ const QRect r = rect.normalized();
+ if (!rect_intersects(d->qt_rgn->extents, r))
+ return false;
+ if (d->qt_rgn->numRects == 1)
+ return true;
+
+ const QVector<QRect> myRects = rects();
+ for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it)
+ if (rect_intersects(r, *it))
+ return true;
+ return false;
+}
+
+
#endif
QT_END_NAMESPACE
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index 8b47043..3886f5c 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
-SUBDIRS += widgets
+SUBDIRS += widgets particles
contains(QT_CONFIG, webkit): SUBDIRS += webkit
contains(QT_CONFIG, multimedia): SUBDIRS += multimedia
diff --git a/src/imports/multimedia/multimedia.pro b/src/imports/multimedia/multimedia.pro
index f7a1d1b..16b3ace 100644
--- a/src/imports/multimedia/multimedia.pro
+++ b/src/imports/multimedia/multimedia.pro
@@ -17,10 +17,10 @@ SOURCES += \
qdeclarativevideo.cpp \
qmetadatacontrolmetaobject.cpp
-QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/Qt/multimedia
-target.path = $$TARGETPATH
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
-qmldir.files += $$QT_BUILD_TREE/imports/Qt/multimedia/qmldir
+qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir
qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
INSTALLS += target qmldir
diff --git a/src/imports/webkit/webkitqmlplugin_export.h b/src/imports/particles/particles.cpp
index 974fd24..ae3f318 100644
--- a/src/imports/webkit/webkitqmlplugin_export.h
+++ b/src/imports/particles/particles.cpp
@@ -1,10 +1,10 @@
/****************************************************************************
**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -39,15 +39,31 @@
**
****************************************************************************/
-#ifndef WEBKITQMLPLUGIN_EXPORT_H
-#define WEBKITQMLPLUGIN_EXPORT_H
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
-#include <QtCore/QtGlobal>
+#include "qdeclarativeparticles_p.h"
-#if defined WEBKITQMLPLUGIN_EXPORTS
-# define WEBKITQMLPLUGIN_EXPORT Q_DECL_EXPORT
-#else
-# define WEBKITQMLPLUGIN_EXPORT Q_DECL_IMPORT
-#endif
+QT_BEGIN_NAMESPACE
+
+class QParticlesQmlModule : public QDeclarativeExtensionPlugin
+{
+ Q_OBJECT
+public:
+ virtual void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.particles"));
+ qmlRegisterType<QDeclarativeParticleMotion>(uri,1,0,"ParticleMotion");
+ qmlRegisterType<QDeclarativeParticleMotionGravity>(uri,1,0,"ParticleMotionGravity");
+ qmlRegisterType<QDeclarativeParticleMotionLinear>(uri,1,0,"ParticleMotionLinear");
+ qmlRegisterType<QDeclarativeParticleMotionWander>(uri,1,0,"ParticleMotionWander");
+ qmlRegisterType<QDeclarativeParticles>(uri,1,0,"Particles");
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "particles.moc"
+
+Q_EXPORT_PLUGIN2(particlesqmlmodule, QT_PREPEND_NAMESPACE(QParticlesQmlModule));
-#endif // WEBKITQMLPLUGIN_EXPORT_H
diff --git a/src/imports/particles/particles.pro b/src/imports/particles/particles.pro
new file mode 100644
index 0000000..02d9ea6
--- /dev/null
+++ b/src/imports/particles/particles.pro
@@ -0,0 +1,20 @@
+TARGET = particles
+TARGETPATH = Qt/labs/particles
+include(../qimportbase.pri)
+
+QT += declarative
+
+SOURCES += \
+ qdeclarativeparticles.cpp \
+ particles.cpp
+
+HEADERS += \
+ qdeclarativeparticles_p.h
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+
+INSTALLS += target qmldir
diff --git a/src/declarative/graphicsitems/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp
index 593c80a..bb6669a 100644
--- a/src/declarative/graphicsitems/qdeclarativeparticles.cpp
+++ b/src/imports/particles/qdeclarativeparticles.cpp
@@ -41,13 +41,12 @@
#include "qdeclarativeparticles_p.h"
-#include "qdeclarativeitem_p.h"
+#include <private/qdeclarativeitem_p.h>
-#include <qdeclarativepixmapcache_p.h>
-#include <qfxperf_p_p.h>
-#include <qdeclarativeanimation_p_p.h>
+#include <private/qdeclarativepixmapcache_p.h>
+#include <private/qfxperf_p_p.h>
+#include <QtCore/QAbstractAnimation>
-#include <QNetworkReply>
#include <QPainter>
#include <QtGui/qdrawutil.h>
#include <QVarLengthArray>
@@ -412,6 +411,20 @@ public:
QDeclarativeParticlesPrivate* d;
};
+//an animation that just gives a tick
+template<class T, void (T::*method)(int)>
+class TickAnimationProxy : public QAbstractAnimation
+{
+public:
+ TickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {}
+ virtual int duration() const { return -1; }
+protected:
+ virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); }
+
+private:
+ T *m_p;
+};
+
//---------------------------------------------------------------------------
class QDeclarativeParticlesPrivate : public QDeclarativeItemPrivate
{
@@ -464,7 +477,7 @@ public:
QList<QPair<int, int> > bursts;//countLeft, emissionRate pairs
QList<QDeclarativeParticle> particles;
- QTickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock;
+ TickAnimationProxy<QDeclarativeParticlesPrivate, &QDeclarativeParticlesPrivate::tick> clock;
};
diff --git a/src/declarative/graphicsitems/qdeclarativeparticles_p.h b/src/imports/particles/qdeclarativeparticles_p.h
index 06acbb9..993796d 100644
--- a/src/declarative/graphicsitems/qdeclarativeparticles_p.h
+++ b/src/imports/particles/qdeclarativeparticles_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVEPARTICLES_H
#define QDECLARATIVEPARTICLES_H
-#include "qdeclarativeitem.h"
+#include <QtDeclarative/qdeclarativeitem.h>
QT_BEGIN_HEADER
@@ -52,7 +52,7 @@ QT_MODULE(Declarative)
class QDeclarativeParticle;
class QDeclarativeParticles;
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotion : public QObject
+class QDeclarativeParticleMotion : public QObject
{
Q_OBJECT
public:
@@ -63,7 +63,7 @@ public:
virtual void destroy(QDeclarativeParticle &);
};
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion
+class QDeclarativeParticleMotionLinear : public QDeclarativeParticleMotion
{
Q_OBJECT
public:
@@ -73,7 +73,7 @@ public:
virtual void advance(QDeclarativeParticle &, int interval);
};
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion
+class QDeclarativeParticleMotionGravity : public QDeclarativeParticleMotion
{
Q_OBJECT
@@ -106,7 +106,7 @@ private:
qreal _accel;
};
-class Q_DECLARATIVE_EXPORT QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion
+class QDeclarativeParticleMotionWander : public QDeclarativeParticleMotion
{
Q_OBJECT
public:
@@ -142,7 +142,7 @@ Q_SIGNALS:
void xvarianceChanged();
void yvarianceChanged();
void paceChanged();
-
+
private:
QDeclarativeParticles *particles;
qreal _xvariance;
@@ -151,7 +151,7 @@ private:
};
class QDeclarativeParticlesPrivate;
-class Q_DECLARATIVE_EXPORT QDeclarativeParticles : public QDeclarativeItem
+class QDeclarativeParticles : public QDeclarativeItem
{
Q_OBJECT
diff --git a/src/imports/particles/qmldir b/src/imports/particles/qmldir
new file mode 100644
index 0000000..15456bb
--- /dev/null
+++ b/src/imports/particles/qmldir
@@ -0,0 +1 @@
+plugin particles
diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri
index 5433059..ea12356 100644
--- a/src/imports/qimportbase.pri
+++ b/src/imports/qimportbase.pri
@@ -22,7 +22,7 @@ QMAKE_EXTRA_COMPILERS += copy2build
TARGET = $$qtLibraryTarget($$TARGET)
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
-include(../../qt_targets.pri)
+include(../qt_targets.pri)
wince*:LIBS += $$QMAKE_LIBS_GUI
diff --git a/src/imports/webkit/plugin.cpp b/src/imports/webkit/plugin.cpp
index 799fe9e..e3d73ec 100644
--- a/src/imports/webkit/plugin.cpp
+++ b/src/imports/webkit/plugin.cpp
@@ -54,7 +54,7 @@ public:
virtual void registerTypes(const char *uri)
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.webkit"));
- QML_REGISTER_NOCREATE_TYPE(QDeclarativeWebSettings);
+ qmlRegisterType<QDeclarativeWebSettings>();
qmlRegisterType<QDeclarativeWebView>(uri,1,0,"WebView");
}
};
diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp
index d78ba28..f8b2b88 100644
--- a/src/imports/webkit/qdeclarativewebview.cpp
+++ b/src/imports/webkit/qdeclarativewebview.cpp
@@ -80,6 +80,7 @@ public:
rendering(true)
{
}
+ void focusChanged(bool);
QUrl url; // page url might be different if it has not loaded yet
QWebPage *page;
@@ -378,11 +379,12 @@ QVariant QDeclarativeWebView::evaluateJavaScript(const QString &scriptSource)
return this->page()->mainFrame()->evaluateJavaScript(scriptSource);
}
-void QDeclarativeWebView::focusChanged(bool hasFocus)
+void QDeclarativeWebViewPrivate::focusChanged(bool hasFocus)
{
+ Q_Q(QDeclarativeWebView);
QFocusEvent e(hasFocus ? QEvent::FocusIn : QEvent::FocusOut);
- page()->event(&e);
- QDeclarativeItem::focusChanged(hasFocus);
+ q->page()->event(&e);
+ QDeclarativeItemPrivate::focusChanged(hasFocus);
}
void QDeclarativeWebView::initialLayout()
diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h
index 145e74b..36b18a6 100644
--- a/src/imports/webkit/qdeclarativewebview_p.h
+++ b/src/imports/webkit/qdeclarativewebview_p.h
@@ -42,8 +42,6 @@
#ifndef QDECLARATIVEWEBVIEW_H
#define QDECLARATIVEWEBVIEW_H
-#include "webkitqmlplugin_export.h"
-
#include <private/qdeclarativepainteditem_p.h>
#include <QtGui/QAction>
@@ -64,7 +62,7 @@ class QDeclarativeWebViewPrivate;
class QNetworkRequest;
class QDeclarativeWebView;
-class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebPage : public QWebPage
+class QDeclarativeWebPage : public QWebPage
{
Q_OBJECT
public:
@@ -88,7 +86,7 @@ class QDeclarativeWebViewAttached;
//### TODO: browser plugins
-class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebView : public QDeclarativePaintedItem
+class QDeclarativeWebView : public QDeclarativePaintedItem
{
Q_OBJECT
@@ -239,7 +237,6 @@ protected:
void keyReleaseEvent(QKeyEvent* event);
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
- virtual void focusChanged(bool);
virtual bool sceneEvent(QEvent *event);
QDeclarativeWebView *createWindow(QWebPage::WebWindowType type);
diff --git a/src/imports/webkit/qdeclarativewebview_p_p.h b/src/imports/webkit/qdeclarativewebview_p_p.h
index 3ad9e9a..258b472 100644
--- a/src/imports/webkit/qdeclarativewebview_p_p.h
+++ b/src/imports/webkit/qdeclarativewebview_p_p.h
@@ -42,8 +42,6 @@
#ifndef QDECLARATIVEWEBVIEW_P_H
#define QDECLARATIVEWEBVIEW_P_H
-#include "webkitqmlplugin_export.h"
-
#include <qdeclarative.h>
#include <QtWebKit/QWebPage>
@@ -54,7 +52,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class WEBKITQMLPLUGIN_EXPORT QDeclarativeWebSettings : public QObject {
+class QDeclarativeWebSettings : public QObject {
Q_OBJECT
Q_PROPERTY(QString standardFontFamily READ standardFontFamily WRITE setStandardFontFamily)
diff --git a/src/imports/webkit/webkit.pro b/src/imports/webkit/webkit.pro
index fdc12cc..ef08efe 100644
--- a/src/imports/webkit/webkit.pro
+++ b/src/imports/webkit/webkit.pro
@@ -3,17 +3,15 @@ TARGETPATH = org/webkit
include(../qimportbase.pri)
QT += webkit declarative
-DEFINES += WEBKITQMLPLUGIN_EXPORTS
SOURCES += qdeclarativewebview.cpp plugin.cpp
HEADERS += qdeclarativewebview_p.h \
- qdeclarativewebview_p_p.h \
- webkitqmlplugin_export.h
+ qdeclarativewebview_p_p.h
-QTDIR_build:DESTDIR = $$TARGETPATH
-target.path = $$TARGETPATH
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
-qmldir.files += $$QT_BUILD_TREE/imports/org/webkit/qmldir
+qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir
qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
INSTALLS += target qmldir
diff --git a/src/imports/widgets/widgets.cpp b/src/imports/widgets/widgets.cpp
index ec21cc4..bc18e8a 100644
--- a/src/imports/widgets/widgets.cpp
+++ b/src/imports/widgets/widgets.cpp
@@ -118,15 +118,15 @@ public:
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.widgets"));
- QML_REGISTER_INTERFACE(QGraphicsLayoutItem);
- QML_REGISTER_INTERFACE(QGraphicsLayout);
+ qmlRegisterInterface<QGraphicsLayoutItem>("QGraphicsLayoutItem");
+ qmlRegisterInterface<QGraphicsLayout>("QGraphicsLayout");
qmlRegisterType<QGraphicsLinearLayoutStretchItemObject>(uri,4,6,"QGraphicsLinearLayoutStretchItem");
qmlRegisterType<QGraphicsLinearLayoutObject>(uri,4,6,"QGraphicsLinearLayout");
qmlRegisterType<QGraphicsGridLayoutObject>(uri,4,6,"QGraphicsGridLayout");
qmlRegisterExtendedType<QGraphicsView, QGraphicsViewDeclarativeUI>(uri,4,6,"QGraphicsView");
qmlRegisterExtendedType<QGraphicsScene,QGraphicsSceneDeclarativeUI>(uri,4,6,"QGraphicsScene");
qmlRegisterExtendedType<QGraphicsWidget,QGraphicsWidgetDeclarativeUI>(uri,4,6,"QGraphicsWidget");
- QML_REGISTER_INTERFACE(QGraphicsItem);
+ qmlRegisterInterface<QGraphicsItem>("QGraphicsItem");
}
};
diff --git a/src/imports/widgets/widgets.pro b/src/imports/widgets/widgets.pro
index 02223d7..aa09b3c 100644
--- a/src/imports/widgets/widgets.pro
+++ b/src/imports/widgets/widgets.pro
@@ -12,11 +12,10 @@ HEADERS += \
graphicswidgets_p.h \
graphicslayouts_p.h
-QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/Qt/widgets
-target.path = $$TARGETPATH
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/imports/$$TARGETPATH
+target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
-# install qmldir file
-qmldir.files += qmldir
-qmldir.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
+qmldir.files += $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir
+qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH
INSTALLS += target qmldir
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
index d1e7615..adc69ee 100644
--- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
+++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
@@ -132,6 +132,11 @@ public:
}
+ inline void addVertex(const GLfloat x, const GLfloat y)
+ {
+ vertexArray.add(QGLPoint(x, y));
+ }
+
void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true);
void clear();
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index b90f0c2..ad07d9d 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1706,23 +1706,23 @@ void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragmen
QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c);
QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c);
- vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
- vertexCoordinateArray.lineToArray(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y);
- vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
- vertexCoordinateArray.lineToArray(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
- vertexCoordinateArray.lineToArray(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y);
- vertexCoordinateArray.lineToArray(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y);
+ vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y);
QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy,
(fragments[i].sourceLeft + fragments[i].width) * dx,
(fragments[i].sourceTop + fragments[i].height) * dy);
- textureCoordinateArray.lineToArray(src.right, src.bottom);
- textureCoordinateArray.lineToArray(src.right, src.top);
- textureCoordinateArray.lineToArray(src.left, src.top);
- textureCoordinateArray.lineToArray(src.left, src.top);
- textureCoordinateArray.lineToArray(src.left, src.bottom);
- textureCoordinateArray.lineToArray(src.right, src.bottom);
+ textureCoordinateArray.addVertex(src.right, src.bottom);
+ textureCoordinateArray.addVertex(src.right, src.top);
+ textureCoordinateArray.addVertex(src.left, src.top);
+ textureCoordinateArray.addVertex(src.left, src.top);
+ textureCoordinateArray.addVertex(src.left, src.bottom);
+ textureCoordinateArray.addVertex(src.right, src.bottom);
qreal opacity = fragments[i].opacity * q->state()->opacity;
opacityArray << opacity << opacity << opacity << opacity << opacity << opacity;
diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp
index 1d11ede..46c68ed 100644
--- a/src/script/bridge/qscriptdeclarativeclass.cpp
+++ b/src/script/bridge/qscriptdeclarativeclass.cpp
@@ -493,6 +493,11 @@ QScriptDeclarativeClass::Value QScriptDeclarativeClass::call(Object *object,
return Value();
}
+bool QScriptDeclarativeClass::compare(Object *o, Object *o2)
+{
+ return o == o2;
+}
+
QStringList QScriptDeclarativeClass::propertyNames(Object *object)
{
Q_UNUSED(object);
diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h
index a0fd6d5..7037e22 100644
--- a/src/script/bridge/qscriptdeclarativeclass_p.h
+++ b/src/script/bridge/qscriptdeclarativeclass_p.h
@@ -129,6 +129,7 @@ public:
virtual void setProperty(Object *, const Identifier &name, const QScriptValue &);
virtual QScriptValue::PropertyFlags propertyFlags(Object *, const Identifier &);
virtual Value call(Object *, QScriptContext *);
+ virtual bool compare(Object *, Object *);
virtual QStringList propertyNames(Object *);
diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp
index c6ab6a7..70bb1bb 100644
--- a/src/script/bridge/qscriptdeclarativeobject.cpp
+++ b/src/script/bridge/qscriptdeclarativeobject.cpp
@@ -198,6 +198,23 @@ bool DeclarativeObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecStat
return QScriptObjectDelegate::hasInstance(object, exec, value, proto);
}
+bool DeclarativeObjectDelegate::compareToObject(QScriptObject *o, JSC::ExecState *exec, JSC::JSObject *o2)
+{
+ if (!o2->inherits(&QScriptObject::info))
+ return false;
+
+ QScriptObject *scriptObject = static_cast<QScriptObject*>(o2);
+ QScriptObjectDelegate *delegate = scriptObject->delegate();
+ if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject))
+ return false;
+
+ DeclarativeObjectDelegate *other = static_cast<DeclarativeObjectDelegate*>(delegate);
+ if (m_class != other->m_class)
+ return false;
+ else
+ return m_class->compare(m_object, other->m_object);
+}
+
} // namespace QScript
QT_END_NAMESPACE
diff --git a/src/script/bridge/qscriptdeclarativeobject_p.h b/src/script/bridge/qscriptdeclarativeobject_p.h
index ec8a43e..878af24 100644
--- a/src/script/bridge/qscriptdeclarativeobject_p.h
+++ b/src/script/bridge/qscriptdeclarativeobject_p.h
@@ -99,6 +99,8 @@ public:
virtual bool hasInstance(QScriptObject*, JSC::ExecState*,
JSC::JSValue value, JSC::JSValue proto);
+ bool compareToObject(QScriptObject *, JSC::ExecState *, JSC::JSObject *);
+
private:
QScriptDeclarativeClass *m_class;
QScriptDeclarativeClass::Object *m_object;