aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-06-21 12:03:07 +1000
committerAlan Alpert <alan.alpert@nokia.com>2011-06-21 12:03:07 +1000
commit222b1e0784b0cdfe2933235a62823c5342618f14 (patch)
tree4a6679327b176150f2b4be64535dc5a5b4ec3c28
parentf0ab52c313076fce7e854fd494b88c5dd0f71af5 (diff)
parent0990f073953a499b1413b049c1909d09fec5a815 (diff)
Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into qtquick2
-rw-r--r--src/declarative/items/qsganchors.cpp1
-rw-r--r--src/declarative/items/qsganimatedimage.cpp1
-rw-r--r--src/declarative/items/qsganimation.cpp1
-rw-r--r--src/declarative/items/qsgborderimage.cpp1
-rw-r--r--src/declarative/items/qsgcanvas.cpp29
-rw-r--r--src/declarative/items/qsgclipnode.cpp1
-rw-r--r--src/declarative/items/qsgcontext2d.cpp15
-rw-r--r--src/declarative/items/qsgevents.cpp1
-rw-r--r--src/declarative/items/qsgflickable.cpp1
-rw-r--r--src/declarative/items/qsgflipable.cpp1
-rw-r--r--src/declarative/items/qsgfocusscope.cpp1
-rw-r--r--src/declarative/items/qsggridview.cpp1
-rw-r--r--src/declarative/items/qsgimage.cpp1
-rw-r--r--src/declarative/items/qsgimagebase.cpp1
-rw-r--r--src/declarative/items/qsgimplicitsizeitem.cpp1
-rw-r--r--src/declarative/items/qsgitem.cpp5
-rw-r--r--src/declarative/items/qsgitem_p.h2
-rw-r--r--src/declarative/items/qsgitemsmodule.cpp1
-rw-r--r--src/declarative/items/qsglistview.cpp1
-rw-r--r--src/declarative/items/qsgloader.cpp1
-rw-r--r--src/declarative/items/qsgmousearea.cpp1
-rw-r--r--src/declarative/items/qsgpathview.cpp1
-rw-r--r--src/declarative/items/qsgpincharea.cpp1
-rw-r--r--src/declarative/items/qsgpositioners.cpp1
-rw-r--r--src/declarative/items/qsgrectangle.cpp1
-rw-r--r--src/declarative/items/qsgrepeater.cpp1
-rw-r--r--src/declarative/items/qsgscalegrid.cpp1
-rw-r--r--src/declarative/items/qsgshadereffectmesh.cpp5
-rw-r--r--src/declarative/items/qsgshadereffectsource.cpp8
-rw-r--r--src/declarative/items/qsgstateoperations.cpp1
-rw-r--r--src/declarative/items/qsgtext.cpp1
-rw-r--r--src/declarative/items/qsgtextedit.cpp1
-rw-r--r--src/declarative/items/qsgtextinput.cpp1
-rw-r--r--src/declarative/items/qsgtextnode.cpp10
-rw-r--r--src/declarative/items/qsgtranslate.cpp1
-rw-r--r--src/declarative/items/qsgview.cpp1
-rw-r--r--src/declarative/items/qsgvisualitemmodel.cpp1
-rw-r--r--src/declarative/particles/qsgpointattractor.cpp4
-rw-r--r--src/declarative/qml/qdeclarativexmlhttprequest.cpp9
-rw-r--r--src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp141
-rw-r--r--src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h32
-rw-r--r--src/declarative/scenegraph/coreapi/qsgmaterial.cpp6
-rw-r--r--src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.cpp380
-rw-r--r--src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.h104
-rw-r--r--src/declarative/scenegraph/coreapi/qsgmatrix4x4stack_p.h73
-rw-r--r--src/declarative/scenegraph/coreapi/qsgnode.cpp175
-rw-r--r--src/declarative/scenegraph/coreapi/qsgnode.h28
-rw-r--r--src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp99
-rw-r--r--src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h20
-rw-r--r--src/declarative/scenegraph/coreapi/qsgrenderer.cpp34
-rw-r--r--src/declarative/scenegraph/coreapi/qsgrenderer_p.h26
-rw-r--r--src/declarative/scenegraph/qsgcontext.cpp9
-rw-r--r--src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp55
-rw-r--r--src/declarative/scenegraph/qsgflashnode.cpp2
-rw-r--r--src/declarative/scenegraph/scenegraph.pri3
-rw-r--r--src/declarative/util/qdeclarativechangeset.cpp440
-rw-r--r--src/declarative/util/qdeclarativechangeset_p.h160
-rw-r--r--src/declarative/util/util.pri2
-rw-r--r--tests/auto/declarative/declarative.pro1
-rw-r--r--tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro17
-rw-r--r--tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp614
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/data/idtranslation.qml7
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/data/qml_fr.qmbin0 -> 374 bytes
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/data/qml_fr.ts43
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.qmbin0 -> 119 bytes
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.ts13
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/data/translation.qml17
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro17
-rw-r--r--tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp113
-rw-r--r--tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData.qml2
-rw-r--r--tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_DELETE.expect7
-rw-r--r--tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_HEAD.expect (renamed from tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_PUT.expect)0
-rw-r--r--tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp23
-rw-r--r--tests/benchmarks/declarative/binding/tst_binding.cpp3
74 files changed, 1927 insertions, 856 deletions
diff --git a/src/declarative/items/qsganchors.cpp b/src/declarative/items/qsganchors.cpp
index ff9351edbc..b491894532 100644
--- a/src/declarative/items/qsganchors.cpp
+++ b/src/declarative/items/qsganchors.cpp
@@ -1,4 +1,3 @@
-// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsganimatedimage.cpp b/src/declarative/items/qsganimatedimage.cpp
index f036042ce2..0d7fb952d4 100644
--- a/src/declarative/items/qsganimatedimage.cpp
+++ b/src/declarative/items/qsganimatedimage.cpp
@@ -1,4 +1,3 @@
-// Commit: af33f9f2e7ec433b81f5c18e3e7395db4a56c5fe
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsganimation.cpp b/src/declarative/items/qsganimation.cpp
index ad6ed030fd..ef21ec5622 100644
--- a/src/declarative/items/qsganimation.cpp
+++ b/src/declarative/items/qsganimation.cpp
@@ -1,4 +1,3 @@
-// Commit: 91501cc9b542de644cd70098a6bc5ff738cdeb49
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgborderimage.cpp b/src/declarative/items/qsgborderimage.cpp
index 81df0a31e7..a0bb72ea35 100644
--- a/src/declarative/items/qsgborderimage.cpp
+++ b/src/declarative/items/qsgborderimage.cpp
@@ -1,4 +1,3 @@
-// Commit: 462429f5692f810bdd4e04b916db5f9af428d9e4
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
index fee58b87a8..30dc5cab02 100644
--- a/src/declarative/items/qsgcanvas.cpp
+++ b/src/declarative/items/qsgcanvas.cpp
@@ -394,7 +394,7 @@ void QSGCanvasPrivate::renderSceneGraph(const QSize &size)
{
context->renderer()->setDeviceRect(QRect(QPoint(0, 0), size));
context->renderer()->setViewportRect(QRect(QPoint(0, 0), size));
- context->renderer()->setProjectMatrixToDeviceRect();
+ context->renderer()->setProjectionMatrixToDeviceRect();
context->renderNextFrame();
@@ -1759,10 +1759,8 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
}
}
- if (dirty & QSGItemPrivate::ChildrenUpdateMask) {
- while (itemPriv->childContainerNode()->childCount())
- itemPriv->childContainerNode()->removeChildNode(itemPriv->childContainerNode()->childAtIndex(0));
- }
+ if (dirty & QSGItemPrivate::ChildrenUpdateMask)
+ itemPriv->childContainerNode()->removeAllChildNodes();
if (effectRefEffectivelyChanged) {
QSGNode *parent = itemPriv->clipNode;
@@ -1795,15 +1793,12 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
if (dirty & QSGItemPrivate::ChildrenUpdateMask) {
QSGNode *groupNode = itemPriv->groupNode;
- if (groupNode) {
- for (int count = groupNode->childCount(); count; --count)
- groupNode->removeChildNode(groupNode->childAtIndex(0));
- }
+ if (groupNode)
+ groupNode->removeAllChildNodes();
QList<QSGItem *> orderedChildren = itemPriv->paintOrderChildItems();
int ii = 0;
- itemPriv->paintNodeIndex = 0;
for (; ii < orderedChildren.count() && orderedChildren.at(ii)->z() < 0; ++ii) {
QSGItemPrivate *childPrivate = QSGItemPrivate::get(orderedChildren.at(ii));
if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
@@ -1812,8 +1807,8 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
itemPriv->childContainerNode()->appendChildNode(childPrivate->itemNode());
- itemPriv->paintNodeIndex++;
}
+ itemPriv->beforePaintNode = itemPriv->groupNode ? itemPriv->groupNode->lastChild() : 0;
if (itemPriv->paintNode)
itemPriv->childContainerNode()->appendChildNode(itemPriv->paintNode);
@@ -1869,10 +1864,10 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
itemPriv->paintNode->parent() == itemPriv->childContainerNode());
if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) {
- if (itemPriv->childContainerNode()->childCount() == itemPriv->paintNodeIndex)
- itemPriv->childContainerNode()->appendChildNode(itemPriv->paintNode);
- else
- itemPriv->childContainerNode()->insertChildNodeBefore(itemPriv->paintNode, itemPriv->childContainerNode()->childAtIndex(itemPriv->paintNodeIndex));
+ if (itemPriv->beforePaintNode)
+ itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, itemPriv->beforePaintNode);
+ else
+ itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
}
} else if (itemPriv->paintNode) {
delete itemPriv->paintNode;
@@ -1908,8 +1903,8 @@ void QSGCanvasPrivate::updateDirtyNode(QSGItem *item)
Q_ASSERT(parent == itemPriv->groupNode || parent->childCount() == 1);
Q_ASSERT(child->parent() == parent);
bool containsChild = false;
- for (int i = 0; i < parent->childCount(); ++i)
- containsChild |= (parent->childAtIndex(i) == child);
+ for (QSGNode *n = parent->firstChild(); n; n = n->nextSibling())
+ containsChild |= (n == child);
Q_ASSERT(containsChild);
}
ip = ic;
diff --git a/src/declarative/items/qsgclipnode.cpp b/src/declarative/items/qsgclipnode.cpp
index 2e40972620..b0a0a56534 100644
--- a/src/declarative/items/qsgclipnode.cpp
+++ b/src/declarative/items/qsgclipnode.cpp
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgcontext2d.cpp b/src/declarative/items/qsgcontext2d.cpp
index 2e60de189f..9dddc99557 100644
--- a/src/declarative/items/qsgcontext2d.cpp
+++ b/src/declarative/items/qsgcontext2d.cpp
@@ -786,12 +786,15 @@ static QScriptValue ctx2d_isPointInPath(QScriptContext *c, QScriptEngine *e)
// text
static QScriptValue ctx2d_font(QScriptContext *c, QScriptEngine *e)
{
+ return QScriptValue();
}
static QScriptValue ctx2d_textAlign(QScriptContext *c, QScriptEngine *e)
{
+ return QScriptValue();
}
static QScriptValue ctx2d_textBaseline(QScriptContext *c, QScriptEngine *e)
{
+ return QScriptValue();
}
static QScriptValue ctx2d_fillText(QScriptContext *c, QScriptEngine *e)
{
@@ -846,53 +849,61 @@ static QScriptValue ctx2d_drawImage(QScriptContext *c, QScriptEngine *e)
static QScriptValue ctx2d_createImageData(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
static QScriptValue ctx2d_getImageData(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
static QScriptValue ctx2d_putImageData(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
//Image Data Interface
static QScriptValue ctx2d_imageData_data(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
static QScriptValue ctx2d_imageData_height(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
static QScriptValue ctx2d_imageData_width(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
//CanvasPixelArray interface
static QScriptValue ctx2d_pixelArray_length(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
//getter/setter by index how to?
static QScriptValue ctx2d_pixelArray(QScriptContext *c, QScriptEngine *e)
{
//#TODO
+ return QScriptValue();
}
//CanvasGradient interface
static QScriptValue ctx2d_gradient_addColorStop(QScriptContext *c, QScriptEngine *e)
{
//#TODO
-
+ return QScriptValue();
}
//TextMetrics
static QScriptValue ctx2d_textMetrics_width(QScriptContext *c, QScriptEngine *e)
{
//#TODO
-
+ return QScriptValue();
}
diff --git a/src/declarative/items/qsgevents.cpp b/src/declarative/items/qsgevents.cpp
index 44ef38b037..773a3e3fe0 100644
--- a/src/declarative/items/qsgevents.cpp
+++ b/src/declarative/items/qsgevents.cpp
@@ -1,4 +1,3 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp
index be0ac13bbf..48beef8422 100644
--- a/src/declarative/items/qsgflickable.cpp
+++ b/src/declarative/items/qsgflickable.cpp
@@ -1,4 +1,3 @@
-// Commit: d4fa1878ff1e7628d3e984d54f8a93810353c71b
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgflipable.cpp b/src/declarative/items/qsgflipable.cpp
index a856d6360b..0439a4d827 100644
--- a/src/declarative/items/qsgflipable.cpp
+++ b/src/declarative/items/qsgflipable.cpp
@@ -1,4 +1,3 @@
-// Commit: caee66da925949cf7aef2ff8e1a86c38dd6e6efd
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgfocusscope.cpp b/src/declarative/items/qsgfocusscope.cpp
index 84f19b1671..07fafc367f 100644
--- a/src/declarative/items/qsgfocusscope.cpp
+++ b/src/declarative/items/qsgfocusscope.cpp
@@ -1,4 +1,3 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsggridview.cpp b/src/declarative/items/qsggridview.cpp
index b65cd39e8e..ef4e969a14 100644
--- a/src/declarative/items/qsggridview.cpp
+++ b/src/declarative/items/qsggridview.cpp
@@ -1,4 +1,3 @@
-// Commit: 806f031efeda71d3f4d7d2f949b437493e79cf52
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgimage.cpp b/src/declarative/items/qsgimage.cpp
index 706aaa7d5d..2e38313e80 100644
--- a/src/declarative/items/qsgimage.cpp
+++ b/src/declarative/items/qsgimage.cpp
@@ -1,4 +1,3 @@
-// Commit: 051a76c1d65d698f71dc75c89f91ae9021357eae
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgimagebase.cpp b/src/declarative/items/qsgimagebase.cpp
index 9f2de03bbe..70a6f6de4f 100644
--- a/src/declarative/items/qsgimagebase.cpp
+++ b/src/declarative/items/qsgimagebase.cpp
@@ -1,4 +1,3 @@
-// Commit: 051a76c1d65d698f71dc75c89f91ae9021357eae
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgimplicitsizeitem.cpp b/src/declarative/items/qsgimplicitsizeitem.cpp
index f2cc9bcbdb..f8e5b5f021 100644
--- a/src/declarative/items/qsgimplicitsizeitem.cpp
+++ b/src/declarative/items/qsgimplicitsizeitem.cpp
@@ -1,4 +1,3 @@
-// Commit: 6f78a6080b84cc3ef96b73a4ff58d1b5a72f08f4
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp
index 328da16ff4..b87ba296e2 100644
--- a/src/declarative/items/qsgitem.cpp
+++ b/src/declarative/items/qsgitem.cpp
@@ -1,4 +1,3 @@
-// Commit: c44be8c0b27756a2025ebad1945632f3f7e4bebc
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -1181,7 +1180,7 @@ void QSGItemPrivate::initCanvas(InitializationState *state, QSGCanvas *c)
rootNode = 0;
groupNode = 0;
paintNode = 0;
- paintNodeIndex = 0;
+ beforePaintNode = 0;
InitializationState _dummy;
InitializationState *childState = state;
@@ -1286,7 +1285,7 @@ QSGItemPrivate::QSGItemPrivate()
dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
- , paintNodeIndex(0), effectRefCount(0), hideRefCount(0)
+ , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
{
}
diff --git a/src/declarative/items/qsgitem_p.h b/src/declarative/items/qsgitem_p.h
index 300ccdc49e..0b3348d7fc 100644
--- a/src/declarative/items/qsgitem_p.h
+++ b/src/declarative/items/qsgitem_p.h
@@ -388,7 +388,7 @@ public:
QSGRootNode *rootNode;
QSGNode *groupNode;
QSGNode *paintNode;
- int paintNodeIndex;
+ QSGNode *beforePaintNode;
virtual QSGTransformNode *createTransformNode();
diff --git a/src/declarative/items/qsgitemsmodule.cpp b/src/declarative/items/qsgitemsmodule.cpp
index f1e3a0cb91..a3752fcec8 100644
--- a/src/declarative/items/qsgitemsmodule.cpp
+++ b/src/declarative/items/qsgitemsmodule.cpp
@@ -1,4 +1,3 @@
-// Commit: 2c7cab4172f1acc86fd49345a2847417e162f2c3
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsglistview.cpp b/src/declarative/items/qsglistview.cpp
index a61ca97256..eea546504a 100644
--- a/src/declarative/items/qsglistview.cpp
+++ b/src/declarative/items/qsglistview.cpp
@@ -1,4 +1,3 @@
-// Commit: 806f031efeda71d3f4d7d2f949b437493e79cf52
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgloader.cpp b/src/declarative/items/qsgloader.cpp
index 6717098506..e5b7e499ec 100644
--- a/src/declarative/items/qsgloader.cpp
+++ b/src/declarative/items/qsgloader.cpp
@@ -1,4 +1,3 @@
-// Commit: 501180c6fbed0857126da2bb0ff1f17ee35472c6
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp
index 6b4311e698..8ed72190f8 100644
--- a/src/declarative/items/qsgmousearea.cpp
+++ b/src/declarative/items/qsgmousearea.cpp
@@ -1,4 +1,3 @@
-// Commit: e1ffbc04131dc6f76fa76821c297d08162e4b1ee
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp
index fc3d39aef7..35b6e038ab 100644
--- a/src/declarative/items/qsgpathview.cpp
+++ b/src/declarative/items/qsgpathview.cpp
@@ -1,4 +1,3 @@
-// Commit: 806f031efeda71d3f4d7d2f949b437493e79cf52
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgpincharea.cpp b/src/declarative/items/qsgpincharea.cpp
index f21d873e5e..6fc0c61359 100644
--- a/src/declarative/items/qsgpincharea.cpp
+++ b/src/declarative/items/qsgpincharea.cpp
@@ -1,4 +1,3 @@
-// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgpositioners.cpp b/src/declarative/items/qsgpositioners.cpp
index f174612af6..0106d8fea9 100644
--- a/src/declarative/items/qsgpositioners.cpp
+++ b/src/declarative/items/qsgpositioners.cpp
@@ -1,4 +1,3 @@
-// Commit: 1f38d41854fa2daa51d938a4eb398752b1751e0b
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgrectangle.cpp b/src/declarative/items/qsgrectangle.cpp
index e97abe3e1c..09bf34dc15 100644
--- a/src/declarative/items/qsgrectangle.cpp
+++ b/src/declarative/items/qsgrectangle.cpp
@@ -1,4 +1,3 @@
-// Commit: acc903853d5ac54d646d324b7386c998bc07d464
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgrepeater.cpp b/src/declarative/items/qsgrepeater.cpp
index ac6086fc62..3a0ef84ed3 100644
--- a/src/declarative/items/qsgrepeater.cpp
+++ b/src/declarative/items/qsgrepeater.cpp
@@ -1,4 +1,3 @@
-// Commit: a9f1eaa6a368bf7a72b52c428728a3e3e0a76209
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgscalegrid.cpp b/src/declarative/items/qsgscalegrid.cpp
index 4a73801159..9f1b7bf8a6 100644
--- a/src/declarative/items/qsgscalegrid.cpp
+++ b/src/declarative/items/qsgscalegrid.cpp
@@ -1,4 +1,3 @@
-// Commit: 7ddec9f3179bfd854ae53e23ab292de1f9a26377
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgshadereffectmesh.cpp b/src/declarative/items/qsgshadereffectmesh.cpp
index dbc3472d09..05131285df 100644
--- a/src/declarative/items/qsgshadereffectmesh.cpp
+++ b/src/declarative/items/qsgshadereffectmesh.cpp
@@ -135,11 +135,6 @@ QSGGeometry *QSGGridMesh::updateGeometry(QSGGeometry *geometry, const QVector<QB
break;
}
- if (error) {
- delete geometry;
- return 0;
- }
-
geometry = new QSGGeometry(attrCount == 1
? QSGGeometry::defaultAttributes_Point2D()
: QSGGeometry::defaultAttributes_TexturedPoint2D(),
diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp
index e2c50bb80e..c4c09868d2 100644
--- a/src/declarative/items/qsgshadereffectsource.cpp
+++ b/src/declarative/items/qsgshadereffectsource.cpp
@@ -214,8 +214,8 @@ void QSGShaderEffectTexture::grab()
return;
}
QSGNode *root = m_item;
- while (root->childCount() && root->type() != QSGNode::RootNodeType)
- root = root->childAtIndex(0);
+ while (root->firstChild() && root->type() != QSGNode::RootNodeType)
+ root = root->firstChild();
if (root->type() != QSGNode::RootNodeType)
return;
@@ -310,7 +310,7 @@ void QSGShaderEffectTexture::grab()
m_renderer->setDeviceRect(m_size);
m_renderer->setViewportRect(m_size);
QRectF mirrored(m_rect.left(), m_rect.bottom(), m_rect.width(), -m_rect.height());
- m_renderer->setProjectMatrixToRect(mirrored);
+ m_renderer->setProjectionMatrixToRect(mirrored);
m_renderer->setClearColor(Qt::transparent);
if (m_multisampling) {
@@ -391,6 +391,7 @@ void QSGShaderEffectTexture::grab()
rather than each element individually.
\endlist
+ \table
\row
\o \image declarative-shadereffectsource.png
\o \qml
@@ -420,6 +421,7 @@ void QSGShaderEffectTexture::grab()
}
\endqml
\endrow
+ \endtable
The ShaderEffectSource element does not redirect any mouse or keyboard
input to \l sourceItem. If you hide the \l sourceItem by setting
diff --git a/src/declarative/items/qsgstateoperations.cpp b/src/declarative/items/qsgstateoperations.cpp
index 5390440e39..0c6491ed58 100644
--- a/src/declarative/items/qsgstateoperations.cpp
+++ b/src/declarative/items/qsgstateoperations.cpp
@@ -1,4 +1,3 @@
-// Commit: 726a8b16c52fe4608c89d740b47361a2b073ce01
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp
index ae9bffc795..3398824f69 100644
--- a/src/declarative/items/qsgtext.cpp
+++ b/src/declarative/items/qsgtext.cpp
@@ -1,4 +1,3 @@
-// Commit: cce89db1e2555cbca8fc28072e1c6dd737cec6c4
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgtextedit.cpp b/src/declarative/items/qsgtextedit.cpp
index 1c199ecc28..01d068d131 100644
--- a/src/declarative/items/qsgtextedit.cpp
+++ b/src/declarative/items/qsgtextedit.cpp
@@ -1,4 +1,3 @@
-// Commit: ec40dd2bb51868bca10dbd0c9116f3224ff2b29b
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp
index 1db4474d4a..94f54712c3 100644
--- a/src/declarative/items/qsgtextinput.cpp
+++ b/src/declarative/items/qsgtextinput.cpp
@@ -1,4 +1,3 @@
-// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index 876c9785b4..6909d8cfca 100644
--- a/src/declarative/items/qsgtextnode.cpp
+++ b/src/declarative/items/qsgtextnode.cpp
@@ -81,8 +81,7 @@ void QSGTextNode::setColor(const QColor &color)
if (m_usePixmapCache) {
setUpdateFlag(UpdateNodes);
} else {
- for (int i=0; i<childCount(); ++i) {
- QSGNode *childNode = childAtIndex(i);
+ for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
if (childNode->subType() == GlyphNodeSubType) {
QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
if (glyphNode->color() == m_color)
@@ -103,8 +102,7 @@ void QSGTextNode::setStyleColor(const QColor &styleColor)
if (m_usePixmapCache) {
setUpdateFlag(UpdateNodes);
} else {
- for (int i=0; i<childCount(); ++i) {
- QSGNode *childNode = childAtIndex(i);
+ for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) {
if (childNode->subType() == GlyphNodeSubType) {
QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode);
if (glyphNode->color() == m_styleColor)
@@ -371,8 +369,8 @@ void QSGTextNode::addTextBlock(const QPointF &position, QTextDocument *textDocum
void QSGTextNode::deleteContent()
{
- while (childCount() > 0)
- delete childAtIndex(0);
+ while (firstChild() > 0)
+ delete firstChild();
}
#if 0
diff --git a/src/declarative/items/qsgtranslate.cpp b/src/declarative/items/qsgtranslate.cpp
index 5f7112bd42..1c453d6f57 100644
--- a/src/declarative/items/qsgtranslate.cpp
+++ b/src/declarative/items/qsgtranslate.cpp
@@ -1,4 +1,3 @@
-// Commit: ac5c099cc3c5b8c7eec7a49fdeb8a21037230350
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgview.cpp b/src/declarative/items/qsgview.cpp
index 1169c59a1b..830a232db2 100644
--- a/src/declarative/items/qsgview.cpp
+++ b/src/declarative/items/qsgview.cpp
@@ -1,4 +1,3 @@
-// Commit: 55c4d94dfea78951f3371d3697a3cb28539b3012
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp
index daf67b573a..a24b65f766 100644
--- a/src/declarative/items/qsgvisualitemmodel.cpp
+++ b/src/declarative/items/qsgvisualitemmodel.cpp
@@ -1,4 +1,3 @@
-// Commit: dcb9148091cbf6872b60407c301d7c92427583a6
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
diff --git a/src/declarative/particles/qsgpointattractor.cpp b/src/declarative/particles/qsgpointattractor.cpp
index 0ee2fa4c27..6f57ecaa36 100644
--- a/src/declarative/particles/qsgpointattractor.cpp
+++ b/src/declarative/particles/qsgpointattractor.cpp
@@ -60,11 +60,11 @@ bool QSGPointAttractorAffector::affectParticle(QSGParticleData *d, qreal dt)
qreal ds = 0;
switch(m_proportionalToDistance){
case Quadratic:
- ds = (m_strength / qMax(1.,r*r)) * dt;
+ ds = (m_strength / qMax<qreal>(1.,r*r)) * dt;
break;
case Linear://also default
default:
- ds = (m_strength / qMax(1.,r)) * dt;
+ ds = (m_strength / qMax<qreal>(1.,r)) * dt;
}
dx = ds * cos(theta);
dy = ds * sin(theta);
diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
index 83b7d170a4..f74995ba0a 100644
--- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp
+++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp
@@ -1163,10 +1163,12 @@ void QDeclarativeXMLHttpRequest::requestFromUrl(const QUrl &url)
m_network = networkAccessManager()->get(request);
else if (m_method == QLatin1String("HEAD"))
m_network = networkAccessManager()->head(request);
- else if(m_method == QLatin1String("POST"))
+ else if (m_method == QLatin1String("POST"))
m_network = networkAccessManager()->post(request, m_data);
- else if(m_method == QLatin1String("PUT"))
+ else if (m_method == QLatin1String("PUT"))
m_network = networkAccessManager()->put(request, m_data);
+ else if (m_method == QLatin1String("DELETE"))
+ m_network = networkAccessManager()->deleteResource(request);
QObject::connect(m_network, SIGNAL(downloadProgress(qint64,qint64)),
this, SLOT(downloadProgress(qint64)));
@@ -1447,7 +1449,8 @@ static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngin
if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
- method != QLatin1String("POST"))
+ method != QLatin1String("POST") &&
+ method != QLatin1String("DELETE"))
THROW_DOM(SYNTAX_ERR, "Unsupported HTTP method type");
diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
index e2bd8f6134..7279ff0216 100644
--- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp
@@ -111,55 +111,54 @@ static bool nodeLessThanWithRenderOrder(QSGGeometryNode *a, QSGGeometryNode *b)
return a->matrix() < b->matrix();
}
-// Minimum heap.
-template <typename T, int prealloc = 256>
-class Heap
+
+IndexGeometryNodePair::IndexGeometryNodePair(int i, QSGGeometryNode *node)
+ : QPair<int, QSGGeometryNode *>(i, node)
+{
+}
+
+bool IndexGeometryNodePair::operator < (const IndexGeometryNodePair &other) const
+{
+ return nodeLessThan(second, other.second);
+}
+
+
+IndexGeometryNodePairHeap::IndexGeometryNodePairHeap()
+ : v(64)
{
-public:
- void insert(const T &x);
- const T &top() const { return v[0]; }
- T pop();
- bool isEmpty() const { return v.isEmpty(); }
-private:
- static int parent(int i) { return (i - 1) >> 1; }
- static int left(int i) { return (i << 1) | 1; }
- static int right(int i) { return (i + 1) << 1; }
- QVarLengthArray<T, prealloc> v;
-};
-
-template <typename T, int prealloc>
-void Heap<T, prealloc>::insert(const T &x)
+}
+
+void IndexGeometryNodePairHeap::insert(const IndexGeometryNodePair &x)
{
int i = v.size();
- v.append(x);
- while (i != 0 && v[i] < v[parent(i)]) {
- qSwap(v[parent(i)], v[i]);
+ v.add(x);
+ while (i != 0 && v.at(i) < v.at(parent(i))) {
+ qSwap(v.at(parent(i)), v.at(i));
i = parent(i);
}
}
-template <typename T, int prealloc>
-T Heap<T, prealloc>::pop()
+IndexGeometryNodePair IndexGeometryNodePairHeap::pop()
{
- T x = top();
+ IndexGeometryNodePair x = top();
if (v.size() > 1)
- qSwap(v[0], v[v.size() - 1]);
- v.resize(v.size() - 1);
+ qSwap(v.first(), v.last());
+ v.pop_back();
int i = 0;
while (left(i) < v.size()) {
int low = left(i);
- if (right(i) < v.size() && v[right(i)] < v[low])
+ if (right(i) < v.size() && v.at(right(i)) < v.at(low))
low = right(i);
- if (!(v[low] < v[i]))
+ if (!(v.at(low) < v.at(i)))
break;
- qSwap(v[i], v[low]);
+ qSwap(v.at(i), v.at(low));
i = low;
}
return x;
}
-QMLRenderer::QMLRenderer(QSGContext *context)
+QSGDefaultRenderer::QSGDefaultRenderer(QSGContext *context)
: QSGRenderer(context)
, m_opaqueNodes(64)
, m_transparentNodes(64)
@@ -176,7 +175,7 @@ QMLRenderer::QMLRenderer(QSGContext *context)
#endif
}
-void QMLRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags)
+void QSGDefaultRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags)
{
QSGRenderer::nodeChanged(node, flags);
@@ -191,7 +190,7 @@ void QMLRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags)
m_needs_sorting = true;
}
-void QMLRenderer::render()
+void QSGDefaultRenderer::render()
{
#if defined (QML_RUNTIME_TESTING)
static bool dumpTree = qApp->arguments().contains(QLatin1String("--dump-tree"));
@@ -238,9 +237,8 @@ void QMLRenderer::render()
QRect r = viewportRect();
glViewport(r.x(), deviceRect().bottom() - r.bottom(), r.width(), r.height());
- m_projectionMatrix = projectMatrix();
- m_projectionMatrix.push();
- m_modelViewMatrix.setToIdentity();
+ m_current_projection_matrix = projectionMatrix();
+ m_current_model_view_matrix.setToIdentity();
m_currentClip = 0;
glDisable(GL_STENCIL_TEST);
@@ -319,8 +317,6 @@ void QMLRenderer::render()
if (m_currentProgram)
m_currentProgram->deactivate();
- m_projectionMatrix.pop();
-
#ifdef RENDERER_DEBUG
if (debugTimer.elapsed() > DEBUG_THRESHOLD) {
printf(" --- Renderer breakdown:\n"
@@ -340,26 +336,18 @@ void QMLRenderer::render()
}
-class Foo : public QPair<int, QSGGeometryNode *>
-{
-public:
- Foo() { }
- Foo(int i, QSGGeometryNode *n) : QPair<int, QSGGeometryNode *>(i, n) { }
- bool operator < (const Foo &other) const { return nodeLessThan(second, other.second); }
-};
-
-void QMLRenderer::setSortFrontToBackEnabled(bool sort)
+void QSGDefaultRenderer::setSortFrontToBackEnabled(bool sort)
{
printf("setting sorting to... %d\n", sort);
m_sort_front_to_back = sort;
}
-bool QMLRenderer::isSortFrontToBackEnabled() const
+bool QSGDefaultRenderer::isSortFrontToBackEnabled() const
{
return m_sort_front_to_back;
}
-void QMLRenderer::buildLists(QSGNode *node)
+void QSGDefaultRenderer::buildLists(QSGNode *node)
{
if (node->isSubtreeBlocked())
return;
@@ -383,8 +371,7 @@ void QMLRenderer::buildLists(QSGNode *node)
}
}
- int count = node->childCount();
- if (!count)
+ if (!node->firstChild())
return;
#ifdef FORCE_NO_REORDER
@@ -393,33 +380,34 @@ void QMLRenderer::buildLists(QSGNode *node)
static bool reorder = !qApp->arguments().contains(QLatin1String("--no-reorder"));
#endif
- if (reorder && count > 1 && (node->flags() & QSGNode::ChildrenDoNotOverlap)) {
- QVarLengthArray<int, 16> beginIndices(count);
- QVarLengthArray<int, 16> endIndices(count);
+ if (reorder && node->firstChild() != node->lastChild() && (node->flags() & QSGNode::ChildrenDoNotOverlap)) {
+ QVarLengthArray<int, 16> beginIndices;
+ QVarLengthArray<int, 16> endIndices;
int baseCount = m_transparentNodes.size();
- for (int i = 0; i < count; ++i) {
- beginIndices[i] = m_transparentNodes.size();
- buildLists(node->childAtIndex(i));
- endIndices[i] = m_transparentNodes.size();
+ int count = 0;
+ for (QSGNode *c = node->firstChild(); c; c = c->nextSibling()) {
+ beginIndices.append(m_transparentNodes.size());
+ buildLists(c);
+ endIndices.append(m_transparentNodes.size());
+ ++count;
}
int childNodeCount = m_transparentNodes.size() - baseCount;
if (childNodeCount) {
- Heap<Foo, 16> heap;
m_tempNodes.reset();
m_tempNodes.reserve(childNodeCount);
while (childNodeCount) {
for (int i = 0; i < count; ++i) {
if (beginIndices[i] != endIndices[i])
- heap.insert(Foo(i, m_transparentNodes.at(beginIndices[i]++)));
+ m_heap.insert(IndexGeometryNodePair(i, m_transparentNodes.at(beginIndices[i]++)));
}
- while (!heap.isEmpty()) {
- Foo foo = heap.pop();
- m_tempNodes.add(foo.second);
+ while (!m_heap.isEmpty()) {
+ IndexGeometryNodePair pair = m_heap.pop();
+ m_tempNodes.add(pair.second);
--childNodeCount;
- int i = foo.first;
- if (beginIndices[i] != endIndices[i] && !nodeLessThan(m_transparentNodes.at(beginIndices[i]), foo.second))
- heap.insert(Foo(i, m_transparentNodes.at(beginIndices[i]++)));
+ int i = pair.first;
+ if (beginIndices[i] != endIndices[i] && !nodeLessThan(m_transparentNodes.at(beginIndices[i]), pair.second))
+ m_heap.insert(IndexGeometryNodePair(i, m_transparentNodes.at(beginIndices[i]++)));
}
}
Q_ASSERT(m_tempNodes.size() == m_transparentNodes.size() - baseCount);
@@ -427,16 +415,17 @@ void QMLRenderer::buildLists(QSGNode *node)
qMemCopy(&m_transparentNodes.at(baseCount), &m_tempNodes.at(0), m_tempNodes.size() * sizeof(QSGGeometryNode *));
}
} else {
- for (int i = 0; i < count; ++i)
- buildLists(node->childAtIndex(i));
+ for (QSGNode *c = node->firstChild(); c; c = c->nextSibling())
+ buildLists(c);
}
}
-void QMLRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
+void QSGDefaultRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
{
const float scale = 1.0f / m_currentRenderOrder;
int count = list.size();
int currentRenderOrder = 0x80000000;
+ m_current_projection_matrix.setColumn(2, scale * projectionMatrix().column(2));
//int clipChangeCount = 0;
//int programChangeCount = 0;
@@ -458,19 +447,18 @@ void QMLRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
if (changeMatrix) {
m_currentMatrix = geomNode->matrix();
if (m_currentMatrix)
- m_modelViewMatrix = *m_currentMatrix;
+ m_current_model_view_matrix = *m_currentMatrix;
else
- m_modelViewMatrix.setToIdentity();
+ m_current_model_view_matrix.setToIdentity();
updates |= QSGMaterialShader::RenderState::DirtyMatrix;
}
- bool changeOpacity = m_render_opacity != geomNode->inheritedOpacity();
+ bool changeOpacity = m_current_opacity != geomNode->inheritedOpacity();
if (changeOpacity) {
updates |= QSGMaterialShader::RenderState::DirtyOpacity;
- m_render_opacity = geomNode->inheritedOpacity();
+ m_current_opacity = geomNode->inheritedOpacity();
}
-
Q_ASSERT(geomNode->activeMaterial());
QSGMaterial *material = geomNode->activeMaterial();
@@ -485,7 +473,7 @@ void QMLRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
#ifdef FORCE_NO_REORDER
glDepthMask(false);
#else
- glDepthMask((material->flags() & QSGMaterial::Blending) == 0 && m_render_opacity == 1);
+ glDepthMask((material->flags() & QSGMaterial::Blending) == 0 && m_current_opacity == 1);
#endif
//++clipChangeCount;
}
@@ -507,10 +495,9 @@ void QMLRenderer::renderNodes(const QDataBuffer<QSGGeometryNode *> &list)
bool changeRenderOrder = currentRenderOrder != geomNode->renderOrder();
if (changeRenderOrder) {
currentRenderOrder = geomNode->renderOrder();
- m_renderOrderMatrix(2, 3) = currentRenderOrder * scale;
- m_projectionMatrix.pop();
- m_projectionMatrix.push();
- m_projectionMatrix *= m_renderOrderMatrix;
+ m_current_projection_matrix.setColumn(3, projectionMatrix().column(3)
+ + currentRenderOrder
+ * m_current_projection_matrix.column(2));
updates |= QSGMaterialShader::RenderState::DirtyMatrix;
}
diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
index ca1f5592cf..f2adb00391 100644
--- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
+++ b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer_p.h
@@ -52,11 +52,36 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QMLRenderer : public QSGRenderer
+class IndexGeometryNodePair : public QPair<int, QSGGeometryNode *>
+{
+public:
+ IndexGeometryNodePair(int i, QSGGeometryNode *n);
+ bool operator < (const IndexGeometryNodePair &other) const;
+};
+
+
+// Minimum heap.
+class IndexGeometryNodePairHeap
+{
+public:
+ IndexGeometryNodePairHeap();
+ void insert(const IndexGeometryNodePair &x);
+ const IndexGeometryNodePair &top() const { return v.first(); }
+ IndexGeometryNodePair pop();
+ bool isEmpty() const { return v.isEmpty(); }
+private:
+ static int parent(int i) { return (i - 1) >> 1; }
+ static int left(int i) { return (i << 1) | 1; }
+ static int right(int i) { return (i + 1) << 1; }
+ QDataBuffer<IndexGeometryNodePair> v;
+};
+
+
+class QSGDefaultRenderer : public QSGRenderer
{
Q_OBJECT
public:
- QMLRenderer(QSGContext *context);
+ QSGDefaultRenderer(QSGContext *context);
void render();
@@ -77,14 +102,13 @@ private:
QDataBuffer<QSGGeometryNode *> m_opaqueNodes;
QDataBuffer<QSGGeometryNode *> m_transparentNodes;
QDataBuffer<QSGGeometryNode *> m_tempNodes;
+ IndexGeometryNodePairHeap m_heap;
bool m_rebuild_lists;
bool m_needs_sorting;
bool m_sort_front_to_back;
int m_currentRenderOrder;
-
-
#ifdef QML_RUNTIME_TESTING
bool m_render_opaque_nodes;
bool m_render_alpha_nodes;
diff --git a/src/declarative/scenegraph/coreapi/qsgmaterial.cpp b/src/declarative/scenegraph/coreapi/qsgmaterial.cpp
index afec4a59f3..687f949dbf 100644
--- a/src/declarative/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgmaterial.cpp
@@ -331,7 +331,7 @@ void QSGMaterialShader::compile()
float QSGMaterialShader::RenderState::opacity() const
{
Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->renderOpacity();
+ return static_cast<const QSGRenderer *>(m_data)->currentOpacity();
}
@@ -343,7 +343,7 @@ float QSGMaterialShader::RenderState::opacity() const
QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const
{
Q_ASSERT(m_data);
- return static_cast<const QSGRenderer *>(m_data)->combinedMatrix();
+ return static_cast<const QSGRenderer *>(m_data)->currentCombinedMatrix();
}
@@ -355,7 +355,7 @@ QMatrix4x4 QSGMaterialShader::RenderState::combinedMatrix() const
QMatrix4x4 QSGMaterialShader::RenderState::modelViewMatrix() const
{
Q_ASSERT(m_data);
- return const_cast<QSGRenderer *>(static_cast<const QSGRenderer *>(m_data))->modelViewMatrix().top();
+ return static_cast<const QSGRenderer *>(m_data)->currentModelViewMatrix();
}
diff --git a/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.cpp b/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.cpp
deleted file mode 100644
index 07ba21d17c..0000000000
--- a/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/****************************************************************************
-**
-** 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 "qsgmatrix4x4stack.h"
-#include "qsgmatrix4x4stack_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QSGMatrix4x4Stack
- \brief The QSGMatrix4x4Stack class manages stacks of transformation matrices in GL applications.
- \since 4.8
- \ingroup qt3d
- \ingroup qt3d::enablers
-
- Transformation matrices are one of the basic building blocks of
- 3D applications, allowing object models to be positioned, scaled,
- rotated, and projected onto the screen.
-
- GL systems support several standard kinds of matrices, particularly
- modelview and projection matrices. These matrices are typically
- organized into stacks, which allow the current matrix state to be
- saved with push() and restored later with pop().
-
- QSGMatrix4x4Stack assists QGLPainter with the management of matrix
- stacks, providing operations to set and modify transformation
- matrices in each of the standard matrix stacks.
-
- In the following example, a standard orthographic projection matrix for a
- view is set via the QGLPainter::projectionMatrix() stack, and
- then a modelview matrix is set via the QGLPainter::modelViewMatrix()
- stack to scale and translate an object prior to drawing:
-
- \code
- QGLPainter painter(this);
-
- QMatrix4x4 projm;
- projm.ortho(window->rect());
- painter.projectionMatrix() = projm;
-
- painter.modelViewMatrix().setToIdentity();
- painter.modelViewMatrix().translate(-1.0f, 2.0f, 0.0f);
- painter.modelViewMatrix().scale(0.5f);
- \endcode
-
- Later, the application can save the current modelview matrix state
- and draw a different object with a different modelview matrix:
-
- \code
- painter.modelViewMatrix().push();
- painter.modelViewMatrix().setToIdentity();
- painter.modelViewMatrix().scale(2.0f);
- \endcode
-
- For efficiency, the matrix values are kept client-side until they
- are needed by a QGLPainter::draw() operation. Until then, changes
- to the matrix will not be reflected in the GL server. The application
- can force the GL server to update the server with a call to
- QGLPainter::update().
-
- QSGMatrix4x4Stack is supported on all GL platforms, including OpenGL/ES 2.0
- which doesn't support matrix stacks natively. On that platform, the
- matrix stack is simulated in client memory. When the application
- selects a shader program to draw under OpenGL/ES 2.0, it calls
- top() to obtain the actual value to be set on the shader program.
-
- \sa QGLPainter
-*/
-
-/*!
- Creates a matrix stack.
-*/
-QSGMatrix4x4Stack::QSGMatrix4x4Stack()
- : d_ptr(new QSGMatrix4x4StackPrivate)
-{
-}
-
-/*!
- Destroy this matrix stack.
-*/
-QSGMatrix4x4Stack::~QSGMatrix4x4Stack()
-{
-}
-
-/*!
- Pushes the current matrix onto the matrix stack. The matrix can
- be restored with pop(). The new top of stack will have the
- same value as the previous top of stack.
-
- The depths of the traditional \c{GL_MODELVIEW} and \c{GL_PROJECTION}
- matrix stacks in the GL server are system-dependent and easy to
- overflow in nested rendering code using \c{glPushMatrix()}.
- By contrast, the push() function provides an arbitrary-sized stack
- in client memory.
-
- \sa pop(), top()
-*/
-void QSGMatrix4x4Stack::push()
-{
- Q_D(QSGMatrix4x4Stack);
- d->stack.push(d->matrix);
-}
-
-/*!
- Pops the top-most matrix from this matrix stack and sets the
- current matrix to the next value down. Does nothing if the
- matrix stack contains a single entry.
-
- \sa push()
-*/
-void QSGMatrix4x4Stack::pop()
-{
- Q_D(QSGMatrix4x4Stack);
- if (!d->stack.isEmpty())
- d->matrix = d->stack.pop();
- d->isDirty = true;
-}
-
-/*!
- Set the matrix at the top of this matrix stack to the identity matrix.
-
- \sa operator=()
-*/
-void QSGMatrix4x4Stack::setToIdentity()
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.setToIdentity();
- d->isDirty = true;
-}
-
-/*!
- Returns a const reference to the current matrix at the top of this
- matrix stack. This is typically used to fetch the matrix so it can
- be set on user-defined shader programs.
-
- \sa operator=()
-*/
-const QMatrix4x4 &QSGMatrix4x4Stack::top() const
-{
- Q_D(const QSGMatrix4x4Stack);
- return d->matrix;
-}
-
-/*!
- \fn QSGMatrix4x4Stack::operator const QMatrix4x4 &() const
-
- Returns a const reference to the current matrix at the top of
- this matrix stack.
-
- \sa top()
-*/
-
-/*!
- Assigns \a matrix to the matrix at the top of this matrix stack.
-
- \sa top()
-*/
-QSGMatrix4x4Stack& QSGMatrix4x4Stack::operator=(const QMatrix4x4& matrix)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix = matrix;
- d->isDirty = true;
- return *this;
-}
-
-/*!
- Multiplies the matrix at the top of this matrix stack by \a matrix.
-
- \sa top()
-*/
-QSGMatrix4x4Stack& QSGMatrix4x4Stack::operator*=(const QMatrix4x4& matrix)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix *= matrix;
- d->isDirty = true;
- return *this;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by another
- that translates coordinates by (\a x, \a y, \a z). The following example
- translates the modelview matrix by (1, -3, 0):
-
- \code
- QGLPainter painter(this);
- painter.modelViewMatrix().translate(1.0f, -3.0f, 0.0f);
- \endcode
-
- \sa scale(), rotate()
-*/
-void QSGMatrix4x4Stack::translate(qreal x, qreal y, qreal z)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.translate(x, y, z);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix statck by another
- that translates coordinates by the components of \a vector.
-
- \sa scale(), rotate()
-*/
-void QSGMatrix4x4Stack::translate(const QVector3D& vector)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.translate(vector);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by another
- that scales coordinates by the components \a x, \a y, and \a z.
- The following example scales the modelview matrix by (1, 2, 1):
-
- \code
- QGLPainter painter(this);
- painter.modelViewMatrix().scale(1.0f, 2.0f, 1.0f);
- \endcode
-
- \sa translate(), rotate()
-*/
-void QSGMatrix4x4Stack::scale(qreal x, qreal y, qreal z)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.scale(x, y, z);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by another
- that scales coordinates by the given \a factor. The following example
- scales the modelview matrix by a factor of 2:
-
- \code
- QGLPainter painter(this);
- painter.modelViewMatrix().scale(2.0f);
- \endcode
-
- \sa translate(), rotate()
-*/
-void QSGMatrix4x4Stack::scale(qreal factor)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.scale(factor);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by another
- that scales coordinates by the components of \a vector.
-
- \sa translate(), rotate()
-*/
-void QSGMatrix4x4Stack::scale(const QVector3D& vector)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.scale(vector);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by another
- that rotates coordinates through \a angle degrees about the vector
- (\a x, \a y, \a z). The following example rotates the modelview
- matrix by 45 degress about the vector (1, -3, 0):
-
- \code
- QGLPainter painter(this);
- painter.modelViewMatrix().rotate(45.0f, 1.0f, -3.0f, 0.0f);
- \endcode
-
- \sa scale(), translate()
-*/
-void QSGMatrix4x4Stack::rotate(qreal angle, qreal x, qreal y, qreal z)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.rotate(angle, x, y, z);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by another
- that rotates coordinates through \a angle degrees about \a vector.
-
- \sa scale(), translate()
-*/
-void QSGMatrix4x4Stack::rotate(qreal angle, const QVector3D& vector)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.rotate(angle, vector);
- d->isDirty = true;
-}
-
-/*!
- Multiplies the current matrix at the top of this matrix stack by the
- \a quaternion. Thus \c {painter->modelViewMatrix().rotate(quaternion)}
- is equivalent to the following code:
- \code
- QMatrix4x4 mat;
- mat.rotate(quaternion);
- painter->modelViewMatrix() *= mat;
- \endcode
- which rotates coordinates according to the given \a quaternion.
-
- \sa scale(), translate()
-*/
-void QSGMatrix4x4Stack::rotate(const QQuaternion &quaternion)
-{
- Q_D(QSGMatrix4x4Stack);
- d->matrix.rotate(quaternion);
- d->isDirty = true;
-}
-
-/*!
- Returns true if the top of this matrix stack has been modified;
- false otherwise.
-
- \sa setDirty()
-*/
-bool QSGMatrix4x4Stack::isDirty() const
-{
- Q_D(const QSGMatrix4x4Stack);
- return d->isDirty;
-}
-
-/*!
- Sets the \a dirty flag on this matrix stack, which indicates
- if it has been modified.
-
- A matrix stack may also be set to dirty by translate(),
- scale(), operator*(), etc.
-
- \sa isDirty()
-*/
-void QSGMatrix4x4Stack::setDirty(bool dirty)
-{
- Q_D(QSGMatrix4x4Stack);
- d->isDirty = dirty;
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.h b/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.h
deleted file mode 100644
index 2336598fdc..0000000000
--- a/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** 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 QSGMATRIX4X4STACK_H
-#define QSGMATRIX4X4STACK_H
-
-#include <QtGui/qmatrix4x4.h>
-#include <QtCore/qscopedpointer.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QSGMatrix4x4StackPrivate;
-
-class Q_DECLARATIVE_EXPORT QSGMatrix4x4Stack
-{
-public:
- QSGMatrix4x4Stack();
- ~QSGMatrix4x4Stack();
-
- const QMatrix4x4 &top() const;
-
- void push();
- void pop();
-
- void setToIdentity();
-
- void translate(qreal x, qreal y, qreal z);
- void translate(const QVector3D& vector);
- void scale(qreal x, qreal y, qreal z);
- void scale(qreal factor);
- void scale(const QVector3D& vector);
- void rotate(qreal angle, qreal x, qreal y, qreal z);
- void rotate(qreal angle, const QVector3D& vector);
- void rotate(const QQuaternion &quaternion);
-
- QSGMatrix4x4Stack& operator=(const QMatrix4x4& matrix);
- QSGMatrix4x4Stack& operator*=(const QMatrix4x4& matrix);
-
- operator const QMatrix4x4 &() const;
-
- bool isDirty() const;
- void setDirty(bool dirty);
-
-private:
- Q_DISABLE_COPY(QSGMatrix4x4Stack)
- Q_DECLARE_PRIVATE(QSGMatrix4x4Stack)
-
- QScopedPointer<QSGMatrix4x4StackPrivate> d_ptr;
-
- friend class QGLPainter;
-};
-
-inline QSGMatrix4x4Stack::operator const QMatrix4x4 &() const
-{
- return top();
-}
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif
diff --git a/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack_p.h b/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack_p.h
deleted file mode 100644
index 6e5c08ca03..0000000000
--- a/src/declarative/scenegraph/coreapi/qsgmatrix4x4stack_p.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** 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 QSGMATRIX4X4STACK_P_H
-#define QSGMATRIX4X4STACK_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 <QtGui/qmatrix4x4.h>
-#include <QtCore/qstack.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGMatrix4x4StackPrivate
-{
-public:
- QSGMatrix4x4StackPrivate() : isDirty(true) {}
-
- QMatrix4x4 matrix;
- QStack<QMatrix4x4> stack;
- bool isDirty;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/declarative/scenegraph/coreapi/qsgnode.cpp b/src/declarative/scenegraph/coreapi/qsgnode.cpp
index 3472c933d7..bfe17ca72b 100644
--- a/src/declarative/scenegraph/coreapi/qsgnode.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgnode.cpp
@@ -60,7 +60,7 @@ static void qt_print_node_count()
/*!
\class QSGNode
- \bried The QSGNode class is the base class for all nodes in the scene graph.
+ \brief The QSGNode class is the base class for all nodes in the scene graph.
The QSGNode class can be used as a child container. Children are added with
the appendChildNode(), prependChildNode(), insertChildNodeBefore() and
@@ -84,8 +84,13 @@ static void qt_print_node_count()
QSGNode::QSGNode()
: m_parent(0)
, m_type(BasicNodeType)
+ , m_subtreeGeometryCount(0)
, m_nodeFlags(OwnedByParent)
, m_flags(0)
+ , m_firstChild(0)
+ , m_lastChild(0)
+ , m_nextSibling(0)
+ , m_previousSibling(0)
{
init();
}
@@ -93,8 +98,13 @@ QSGNode::QSGNode()
QSGNode::QSGNode(NodeType type)
: m_parent(0)
, m_type(type)
+ , m_subtreeGeometryCount(type == GeometryNodeType ? 1 : 0)
, m_nodeFlags(OwnedByParent)
, m_flags(0)
+ , m_firstChild(0)
+ , m_lastChild(0)
+ , m_nextSibling(0)
+ , m_previousSibling(0)
{
init();
}
@@ -150,8 +160,6 @@ QSGNode::~QSGNode()
/*!
- \fn bool QSGNode::isSubtreeBlocked() const
-
Returns whether this node and its subtree is available for use.
Blocked subtrees will not get their dirty states updated and they
@@ -161,6 +169,22 @@ QSGNode::~QSGNode()
is 0, for instance.
*/
+bool QSGNode::isSubtreeBlocked() const
+{
+ return m_subtreeGeometryCount == 0;
+}
+
+/*!
+ \internal
+ Detaches the node from the scene graph and deletes any children it owns.
+
+ This function is called from QSGNode's and QSGRootNode's destructor. It
+ should not be called explicitly in user code. QSGRootNode needs to call
+ destroy() because destroy() calls removeChildNode() which in turn calls
+ markDirty() which type-casts the node to QSGRootNode. This type-cast is not
+ valid at the time QSGNode's destructor is called because the node will
+ already be partially destroyed at that point.
+*/
void QSGNode::destroy()
{
@@ -168,14 +192,15 @@ void QSGNode::destroy()
m_parent->removeChildNode(this);
Q_ASSERT(m_parent == 0);
}
- for (int ii = m_children.count() - 1; ii >= 0; --ii) {
- QSGNode *child = m_children.at(ii);
+ while (m_firstChild) {
+ QSGNode *child = m_firstChild;
removeChildNode(child);
Q_ASSERT(child->m_parent == 0);
if (child->flags() & OwnedByParent)
delete child;
}
- Q_ASSERT(m_children.isEmpty());
+
+ Q_ASSERT(m_firstChild == 0 && m_lastChild == 0);
}
@@ -188,7 +213,7 @@ void QSGNode::destroy()
void QSGNode::prependChildNode(QSGNode *node)
{
- Q_ASSERT_X(!m_children.contains(node), "QSGNode::prependChildNode", "QSGNode is already a child!");
+ //Q_ASSERT_X(!m_children.contains(node), "QSGNode::prependChildNode", "QSGNode is already a child!");
Q_ASSERT_X(!node->m_parent, "QSGNode::prependChildNode", "QSGNode already has a parent");
#ifndef QT_NO_DEBUG
@@ -199,7 +224,12 @@ void QSGNode::prependChildNode(QSGNode *node)
}
#endif
- m_children.prepend(node);
+ if (m_firstChild)
+ m_firstChild->m_previousSibling = node;
+ else
+ m_lastChild = node;
+ node->m_nextSibling = m_firstChild;
+ m_firstChild = node;
node->m_parent = this;
node->markDirty(DirtyNodeAdded);
@@ -214,7 +244,7 @@ void QSGNode::prependChildNode(QSGNode *node)
void QSGNode::appendChildNode(QSGNode *node)
{
- Q_ASSERT_X(!m_children.contains(node), "QSGNode::appendChildNode", "QSGNode is already a child!");
+ //Q_ASSERT_X(!m_children.contains(node), "QSGNode::appendChildNode", "QSGNode is already a child!");
Q_ASSERT_X(!node->m_parent, "QSGNode::appendChildNode", "QSGNode already has a parent");
#ifndef QT_NO_DEBUG
@@ -225,7 +255,12 @@ void QSGNode::appendChildNode(QSGNode *node)
}
#endif
- m_children.append(node);
+ if (m_lastChild)
+ m_lastChild->m_nextSibling = node;
+ else
+ m_firstChild = node;
+ node->m_previousSibling = m_lastChild;
+ m_lastChild = node;
node->m_parent = this;
node->markDirty(DirtyNodeAdded);
@@ -242,9 +277,9 @@ void QSGNode::appendChildNode(QSGNode *node)
void QSGNode::insertChildNodeBefore(QSGNode *node, QSGNode *before)
{
- Q_ASSERT_X(!m_children.contains(node), "QSGNode::insertChildNodeBefore", "QSGNode is already a child!");
+ //Q_ASSERT_X(!m_children.contains(node), "QSGNode::insertChildNodeBefore", "QSGNode is already a child!");
Q_ASSERT_X(!node->m_parent, "QSGNode::insertChildNodeBefore", "QSGNode already has a parent");
- Q_ASSERT_X(node->type() != RootNodeType, "QSGNode::insertChildNodeBefore", "RootNodes cannot be children of other nodes");
+ Q_ASSERT_X(before && before->m_parent == this, "QSGNode::insertChildNodeBefore", "The parent of \'before\' is wrong");
#ifndef QT_NO_DEBUG
if (node->type() == QSGNode::GeometryNodeType) {
@@ -254,11 +289,14 @@ void QSGNode::insertChildNodeBefore(QSGNode *node, QSGNode *before)
}
#endif
- int idx = before?m_children.indexOf(before):-1;
- if (idx == -1)
- m_children.append(node);
+ QSGNode *previous = before->m_previousSibling;
+ if (previous)
+ previous->m_nextSibling = node;
else
- m_children.insert(idx, node);
+ m_firstChild = node;
+ node->m_previousSibling = previous;
+ node->m_nextSibling = before;
+ before->m_previousSibling = node;
node->m_parent = this;
node->markDirty(DirtyNodeAdded);
@@ -275,9 +313,9 @@ void QSGNode::insertChildNodeBefore(QSGNode *node, QSGNode *before)
void QSGNode::insertChildNodeAfter(QSGNode *node, QSGNode *after)
{
- Q_ASSERT_X(!m_children.contains(node), "QSGNode::insertChildNodeAfter", "QSGNode is already a child!");
+ //Q_ASSERT_X(!m_children.contains(node), "QSGNode::insertChildNodeAfter", "QSGNode is already a child!");
Q_ASSERT_X(!node->m_parent, "QSGNode::insertChildNodeAfter", "QSGNode already has a parent");
- Q_ASSERT_X(node->type() != RootNodeType, "QSGNode::insertChildNodeAfter", "RootNodes cannot be children of other nodes");
+ Q_ASSERT_X(after && after->m_parent == this, "QSGNode::insertChildNodeBefore", "The parent of \'before\' is wrong");
#ifndef QT_NO_DEBUG
if (node->type() == QSGNode::GeometryNodeType) {
@@ -287,11 +325,14 @@ void QSGNode::insertChildNodeAfter(QSGNode *node, QSGNode *after)
}
#endif
- int idx = after?m_children.indexOf(after):-1;
- if (idx == -1)
- m_children.append(node);
+ QSGNode *next = after->m_nextSibling;
+ if (next)
+ next->m_previousSibling = node;
else
- m_children.insert(idx + 1, node);
+ m_lastChild = node;
+ node->m_nextSibling = next;
+ node->m_previousSibling = after;
+ after->m_nextSibling = node;
node->m_parent = this;
node->markDirty(DirtyNodeAdded);
@@ -300,15 +341,26 @@ void QSGNode::insertChildNodeAfter(QSGNode *node, QSGNode *after)
/*!
- Removes \a node fromt his node's list of children.
+ Removes \a node from this node's list of children.
*/
void QSGNode::removeChildNode(QSGNode *node)
{
- Q_ASSERT(m_children.contains(node));
+ //Q_ASSERT(m_children.contains(node));
Q_ASSERT(node->parent() == this);
- m_children.removeOne(node);
+ QSGNode *previous = node->m_previousSibling;
+ QSGNode *next = node->m_nextSibling;
+ if (previous)
+ previous->m_nextSibling = next;
+ else
+ m_firstChild = next;
+ if (next)
+ next->m_previousSibling = previous;
+ else
+ m_lastChild = previous;
+ node->m_previousSibling = 0;
+ node->m_nextSibling = 0;
node->markDirty(DirtyNodeRemoved);
node->m_parent = 0;
@@ -316,6 +368,49 @@ void QSGNode::removeChildNode(QSGNode *node)
/*!
+ Removes all child nodes from this node's list of children.
+ */
+
+void QSGNode::removeAllChildNodes()
+{
+ while (m_firstChild) {
+ QSGNode *node = m_firstChild;
+ m_firstChild = node->m_nextSibling;
+ node->m_nextSibling = 0;
+ if (m_firstChild)
+ m_firstChild->m_previousSibling = 0;
+ else
+ m_lastChild = 0;
+ node->markDirty(DirtyNodeRemoved);
+ node->m_parent = 0;
+ }
+}
+
+
+int QSGNode::childCount() const
+{
+ int count = 0;
+ QSGNode *n = m_firstChild;
+ while (n) {
+ ++count;
+ n = n->m_nextSibling;
+ }
+ return count;
+}
+
+
+QSGNode *QSGNode::childAtIndex(int i) const
+{
+ QSGNode *n = m_firstChild;
+ while (i && n) {
+ --i;
+ n = n->m_nextSibling;
+ }
+ return n;
+}
+
+
+/*!
Sets the flag \a f on this node if \a enabled is true;
otherwise clears the flag.
@@ -360,9 +455,17 @@ void QSGNode::markDirty(DirtyFlags flags)
m_flags |= (flags & DirtyPropagationMask);
DirtyFlags subtreeFlags = DirtyFlags((flags & DirtyPropagationMask) << 16);
+
+ int geometryCountDiff = 0;
+ if (flags & DirtyNodeAdded)
+ geometryCountDiff = m_subtreeGeometryCount;
+ if (flags & DirtyNodeRemoved)
+ geometryCountDiff = -m_subtreeGeometryCount;
+
QSGNode *p = m_parent;
while (p) {
p->m_flags |= subtreeFlags;
+ p->m_subtreeGeometryCount += geometryCountDiff;
if (p->type() == RootNodeType)
static_cast<QSGRootNode *>(p)->notifyNodeChange(this, flags);
p = p->m_parent;
@@ -401,7 +504,6 @@ QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type)
QSGBasicGeometryNode::~QSGBasicGeometryNode()
{
- destroy();
if (flags() & OwnsGeometry)
delete m_geometry;
}
@@ -477,7 +579,6 @@ QSGGeometryNode::QSGGeometryNode()
QSGGeometryNode::~QSGGeometryNode()
{
- destroy();
if (flags() & OwnsMaterial)
delete m_material;
if (flags() & OwnsOpaqueMaterial)
@@ -639,7 +740,6 @@ QSGClipNode::QSGClipNode()
QSGClipNode::~QSGClipNode()
{
- destroy();
}
@@ -715,7 +815,6 @@ QSGTransformNode::QSGTransformNode()
QSGTransformNode::~QSGTransformNode()
{
- destroy();
}
@@ -789,7 +888,7 @@ QSGRootNode::~QSGRootNode()
{
while (!m_renderers.isEmpty())
m_renderers.last()->setRootNode(0);
- destroy();
+ destroy(); // Must call destroy() here because markDirty() casts this to QSGRootNode.
}
@@ -848,7 +947,6 @@ QSGOpacityNode::QSGOpacityNode()
QSGOpacityNode::~QSGOpacityNode()
{
- destroy();
}
@@ -912,22 +1010,21 @@ void QSGOpacityNode::setCombinedOpacity(qreal opacity)
/*!
- For performance reasons, we block the subtree when the nested opacity
- gets below a certain threshold.
+ For performance reasons, we block the subtree when the opacity
+ is below a certain threshold.
\internal
*/
bool QSGOpacityNode::isSubtreeBlocked() const
{
- return m_combined_opacity < 0.001;
+ return QSGNode::isSubtreeBlocked() || m_opacity < 0.001;
}
-
/*!
\class QSGNodeVisitor
- \bried The QSGNodeVisitor class is a helper class for traversing the scene graph.
+ \brief The QSGNodeVisitor class is a helper class for traversing the scene graph.
\internal
*/
@@ -973,10 +1070,8 @@ void QSGNodeVisitor::visitNode(QSGNode *n)
void QSGNodeVisitor::visitChildren(QSGNode *n)
{
- int count = n->childCount();
- for (int i=0; i<count; ++i) {
- visitNode(n->childAtIndex(i));
- }
+ for (QSGNode *c = n->firstChild(); c; c = c->nextSibling())
+ visitNode(c);
}
diff --git a/src/declarative/scenegraph/coreapi/qsgnode.h b/src/declarative/scenegraph/coreapi/qsgnode.h
index a391b55bc5..cee6b76869 100644
--- a/src/declarative/scenegraph/coreapi/qsgnode.h
+++ b/src/declarative/scenegraph/coreapi/qsgnode.h
@@ -118,13 +118,18 @@ public:
QSGNode *parent() const { return m_parent; }
void removeChildNode(QSGNode *node);
+ void removeAllChildNodes();
void prependChildNode(QSGNode *node);
void appendChildNode(QSGNode *node);
void insertChildNodeBefore(QSGNode *node, QSGNode *before);
void insertChildNodeAfter(QSGNode *node, QSGNode *after);
- int childCount() const { return m_children.size(); }
- QSGNode *childAtIndex(int i) const { return m_children.at(i); }
+ int childCount() const;
+ QSGNode *childAtIndex(int i) const;
+ QSGNode *firstChild() const { return m_firstChild; }
+ QSGNode *lastChild() const { return m_lastChild; }
+ QSGNode *nextSibling() const { return m_nextSibling; }
+ QSGNode* previousSibling() const { return m_previousSibling; }
inline NodeType type() const { return m_type; }
@@ -132,7 +137,7 @@ public:
void markDirty(DirtyFlags flags);
DirtyFlags dirtyFlags() const { return m_flags; }
- virtual bool isSubtreeBlocked() const { return false; }
+ virtual bool isSubtreeBlocked() const;
Flags flags() const { return m_nodeFlags; }
void setFlag(Flag, bool = true);
@@ -147,20 +152,19 @@ public:
protected:
QSGNode(NodeType type);
- // When a node is destroyed, it will detach from the scene graph and the renderer will be
- // notified about the change. If the node is detached in the base node's destructor, the
- // renderer can't safely cast the node to its original type, since at this point it has been
- // partly destroyed already. To solve this problem, all the node destructors must call a common
- // destroy method.
-
- void destroy();
-
private:
+ friend class QSGRootNode;
+
void init();
+ void destroy();
QSGNode *m_parent;
NodeType m_type;
- QList<QSGNode *> m_children;
+ QSGNode *m_firstChild;
+ QSGNode *m_lastChild;
+ QSGNode *m_nextSibling;
+ QSGNode *m_previousSibling;
+ int m_subtreeGeometryCount;
Flags m_nodeFlags;
DirtyFlags m_flags;
diff --git a/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp b/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp
index 6eff011e85..3c3ff31fd5 100644
--- a/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgnodeupdater.cpp
@@ -46,10 +46,14 @@ QT_BEGIN_NAMESPACE
// #define QSG_UPDATER_DEBUG
QSGNodeUpdater::QSGNodeUpdater()
- : m_current_clip(0)
+ : m_matrix_stack(64)
+ , m_combined_matrix_stack(64)
+ , m_opacity_stack(64)
+ , m_current_clip(0)
, m_force_update(0)
{
- m_opacity_stack.push(1);
+ m_opacity_stack.add(1);
+ m_matrix_stack.add(QMatrix4x4());
}
void QSGNodeUpdater::updateStates(QSGNode *n)
@@ -58,7 +62,6 @@ void QSGNodeUpdater::updateStates(QSGNode *n)
m_force_update = 0;
Q_ASSERT(m_opacity_stack.size() == 1); // The one we added in the constructr...
- // Q_ASSERT(m_matrix_stack.isEmpty()); ### no such function?
Q_ASSERT(m_combined_matrix_stack.isEmpty());
visitNode(n);
@@ -121,13 +124,11 @@ void QSGNodeUpdater::enterTransformNode(QSGTransformNode *t)
#endif
if (!t->matrix().isIdentity()) {
- m_combined_matrix_stack.push(&t->combinedMatrix());
-
- m_matrix_stack.push();
- m_matrix_stack *= t->matrix();
+ m_combined_matrix_stack.add(&t->combinedMatrix());
+ m_matrix_stack.add(m_matrix_stack.last() * t->matrix());
}
- t->setCombinedMatrix(m_matrix_stack.top());
+ t->setCombinedMatrix(m_matrix_stack.last());
}
@@ -141,8 +142,8 @@ void QSGNodeUpdater::leaveTransformNode(QSGTransformNode *t)
--m_force_update;
if (!t->matrix().isIdentity()) {
- m_matrix_stack.pop();
- m_combined_matrix_stack.pop();
+ m_matrix_stack.pop_back();
+ m_combined_matrix_stack.pop_back();
}
}
@@ -154,11 +155,10 @@ void QSGNodeUpdater::enterClipNode(QSGClipNode *c)
qDebug() << "enter clip:" << c;
#endif
- if (c->dirtyFlags() & QSGNode::DirtyClipList) {
+ if (c->dirtyFlags() & QSGNode::DirtyClipList)
++m_force_update;
- }
- c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.top();
+ c->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
c->m_clip_list = m_current_clip;
m_current_clip = c;
}
@@ -170,9 +170,8 @@ void QSGNodeUpdater::leaveClipNode(QSGClipNode *c)
qDebug() << "leave clip:" << c;
#endif
- if (c->dirtyFlags() & QSGNode::DirtyClipList) {
+ if (c->dirtyFlags() & QSGNode::DirtyClipList)
--m_force_update;
- }
m_current_clip = c->m_clip_list;
}
@@ -184,9 +183,16 @@ void QSGNodeUpdater::enterGeometryNode(QSGGeometryNode *g)
qDebug() << "enter geometry:" << g;
#endif
- g->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.top();
+ g->m_matrix = m_combined_matrix_stack.isEmpty() ? 0 : m_combined_matrix_stack.last();
g->m_clip_list = m_current_clip;
- g->setInheritedOpacity(m_opacity_stack.top());
+ g->setInheritedOpacity(m_opacity_stack.last());
+}
+
+void QSGNodeUpdater::leaveGeometryNode(QSGGeometryNode *g)
+{
+#ifdef QSG_UPDATER_DEBUG
+ qDebug() << "leave geometry" << g;
+#endif
}
void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o)
@@ -194,9 +200,9 @@ void QSGNodeUpdater::enterOpacityNode(QSGOpacityNode *o)
if (o->dirtyFlags() & QSGNode::DirtyOpacity)
++m_force_update;
- qreal opacity = m_opacity_stack.top() * o->opacity();
+ qreal opacity = m_opacity_stack.last() * o->opacity();
o->setCombinedOpacity(opacity);
- m_opacity_stack.push(opacity);
+ m_opacity_stack.add(opacity);
#ifdef QSG_UPDATER_DEBUG
qDebug() << "enter opacity" << o;
@@ -211,13 +217,13 @@ void QSGNodeUpdater::leaveOpacityNode(QSGOpacityNode *o)
if (o->flags() & QSGNode::DirtyOpacity)
--m_force_update;
- m_opacity_stack.pop();
+ m_opacity_stack.pop_back();
}
void QSGNodeUpdater::visitChildren(QSGNode *n)
{
- if (!n->isSubtreeBlocked())
- QSGNodeVisitor::visitChildren(n);
+ for (QSGNode *c = n->firstChild(); c; c = c->nextSibling())
+ visitNode(c);
}
void QSGNodeUpdater::visitNode(QSGNode *n)
@@ -226,18 +232,49 @@ void QSGNodeUpdater::visitNode(QSGNode *n)
qDebug() << "enter:" << n;
#endif
- if (n->dirtyFlags() || m_force_update) {
- bool forceUpdate = n->dirtyFlags() & (QSGNode::DirtyNodeAdded | QSGNode::DirtyForceUpdate);
- if (forceUpdate)
- ++m_force_update;
-
- QSGNodeVisitor::visitNode(n);
+ if (!n->dirtyFlags() && !m_force_update)
+ return;
+ if (n->isSubtreeBlocked())
+ return;
- if (forceUpdate)
- --m_force_update;
+ bool forceUpdate = n->dirtyFlags() & (QSGNode::DirtyNodeAdded | QSGNode::DirtyForceUpdate);
+ if (forceUpdate)
+ ++m_force_update;
- n->clearDirty();
+ switch (n->type()) {
+ case QSGNode::TransformNodeType: {
+ QSGTransformNode *t = static_cast<QSGTransformNode *>(n);
+ enterTransformNode(t);
+ visitChildren(t);
+ leaveTransformNode(t);
+ break; }
+ case QSGNode::GeometryNodeType: {
+ QSGGeometryNode *g = static_cast<QSGGeometryNode *>(n);
+ enterGeometryNode(g);
+ visitChildren(g);
+ leaveGeometryNode(g);
+ break; }
+ case QSGNode::ClipNodeType: {
+ QSGClipNode *c = static_cast<QSGClipNode *>(n);
+ enterClipNode(c);
+ visitChildren(c);
+ leaveClipNode(c);
+ break; }
+ case QSGNode::OpacityNodeType: {
+ QSGOpacityNode *o = static_cast<QSGOpacityNode *>(n);
+ enterOpacityNode(o);
+ visitChildren(o);
+ leaveOpacityNode(o);
+ break; }
+ default:
+ visitChildren(n);
+ break;
}
+
+ if (forceUpdate)
+ --m_force_update;
+
+ n->clearDirty();
}
QT_END_NAMESPACE
diff --git a/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h b/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h
index 518cf9eff9..a1ecc65220 100644
--- a/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h
+++ b/src/declarative/scenegraph/coreapi/qsgnodeupdater_p.h
@@ -43,12 +43,11 @@
#define NODEUPDATER_P_H
#include "qsgnode.h"
-#include "qsgmatrix4x4stack.h"
-#include <qstack.h>
+#include <QtGui/private/qdatabuffer_p.h>
QT_BEGIN_NAMESPACE
-class Q_DECLARATIVE_EXPORT QSGNodeUpdater : public QSGNodeVisitor
+class Q_DECLARATIVE_EXPORT QSGNodeUpdater
{
public:
QSGNodeUpdater();
@@ -56,25 +55,26 @@ public:
virtual void updateStates(QSGNode *n);
virtual bool isNodeBlocked(QSGNode *n, QSGNode *root) const;
- void setToplevelOpacity(qreal alpha) { m_opacity_stack.top() = alpha; }
- qreal toplevelOpacity() const { return m_opacity_stack.top(); }
+ void setToplevelOpacity(qreal alpha) { m_opacity_stack.last() = alpha; }
+ qreal toplevelOpacity() const { return m_opacity_stack.last(); }
protected:
- void enterTransformNode(QSGTransformNode *);
- void leaveTransformNode(QSGTransformNode *);
+ virtual void enterTransformNode(QSGTransformNode *);
+ virtual void leaveTransformNode(QSGTransformNode *);
void enterClipNode(QSGClipNode *c);
void leaveClipNode(QSGClipNode *c);
void enterOpacityNode(QSGOpacityNode *o);
void leaveOpacityNode(QSGOpacityNode *o);
void enterGeometryNode(QSGGeometryNode *);
+ void leaveGeometryNode(QSGGeometryNode *);
void visitNode(QSGNode *n);
void visitChildren(QSGNode *n);
- QSGMatrix4x4Stack m_matrix_stack;
- QStack<const QMatrix4x4 *> m_combined_matrix_stack;
- QStack<qreal> m_opacity_stack;
+ QDataBuffer<QMatrix4x4> m_matrix_stack;
+ QDataBuffer<const QMatrix4x4 *> m_combined_matrix_stack;
+ QDataBuffer<qreal> m_opacity_stack;
const QSGClipNode *m_current_clip;
int m_force_update;
diff --git a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp
index cc24cc066b..48c34d39dd 100644
--- a/src/declarative/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/declarative/scenegraph/coreapi/qsgrenderer.cpp
@@ -122,7 +122,7 @@ QSGRenderer::QSGRenderer(QSGContext *context)
: QObject()
, m_clear_color(Qt::transparent)
, m_clear_mode(ClearColorBuffer | ClearDepthBuffer)
- , m_render_opacity(1)
+ , m_current_opacity(1)
, m_context(context)
, m_root_node(0)
, m_node_updater(0)
@@ -264,12 +264,12 @@ void QSGRenderer::renderScene(const Bindable &bindable)
#endif
}
-void QSGRenderer::setProjectMatrixToDeviceRect()
+void QSGRenderer::setProjectionMatrixToDeviceRect()
{
- setProjectMatrixToRect(m_device_rect);
+ setProjectionMatrixToRect(m_device_rect);
}
-void QSGRenderer::setProjectMatrixToRect(const QRectF &rect)
+void QSGRenderer::setProjectionMatrixToRect(const QRectF &rect)
{
QMatrix4x4 matrix;
matrix.ortho(rect.x(),
@@ -278,10 +278,10 @@ void QSGRenderer::setProjectMatrixToRect(const QRectF &rect)
rect.y(),
qreal(0.01),
-1);
- setProjectMatrix(matrix);
+ setProjectionMatrix(matrix);
}
-void QSGRenderer::setProjectMatrix(const QMatrix4x4 &matrix)
+void QSGRenderer::setProjectionMatrix(const QMatrix4x4 &matrix)
{
m_projection_matrix = matrix;
// Mirrored relative to the usual Qt coordinate system with origin in the top left corner.
@@ -293,6 +293,14 @@ void QSGRenderer::setClearColor(const QColor &color)
m_clear_color = color;
}
+/*!
+ Updates internal data structures and emits the sceneGraphChanged() signal.
+
+ If \a flags contains the QSGNode::DirtyNodeRemoved flag, the node might be
+ in the process of being destroyed. It is then not safe to downcast the node
+ pointer.
+*/
+
void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags)
{
Q_UNUSED(node);
@@ -346,16 +354,16 @@ void QSGRenderer::preprocess()
void QSGRenderer::addNodesToPreprocess(QSGNode *node)
{
- for (int i = 0; i < node->childCount(); ++i)
- addNodesToPreprocess(node->childAtIndex(i));
+ for (QSGNode *c = node->firstChild(); c; c = c->nextSibling())
+ addNodesToPreprocess(c);
if (node->flags() & QSGNode::UsePreprocess)
m_nodes_to_preprocess.insert(node);
}
void QSGRenderer::removeNodesToPreprocess(QSGNode *node)
{
- for (int i = 0; i < node->childCount(); ++i)
- removeNodesToPreprocess(node->childAtIndex(i));
+ for (QSGNode *c = node->firstChild(); c; c = c->nextSibling())
+ removeNodesToPreprocess(c);
if (node->flags() & QSGNode::UsePreprocess)
m_nodes_to_preprocess.remove(node);
}
@@ -384,11 +392,9 @@ QSGRenderer::ClipType QSGRenderer::updateStencilClip(const QSGClipNode *clip)
int clipDepth = 0;
QRect clipRect;
while (clip) {
- QMatrix4x4 matrix = m_projectionMatrix.top();
+ QMatrix4x4 m = m_current_projection_matrix;
if (clip->matrix())
- matrix *= *clip->matrix();
-
- const QMatrix4x4 &m = matrix;
+ m *= *clip->matrix();
// TODO: Check for multisampling and pixel grid alignment.
bool canUseScissor = clip->isRectangular()
diff --git a/src/declarative/scenegraph/coreapi/qsgrenderer_p.h b/src/declarative/scenegraph/coreapi/qsgrenderer_p.h
index 272df8082c..0218caed15 100644
--- a/src/declarative/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/declarative/scenegraph/coreapi/qsgrenderer_p.h
@@ -45,8 +45,6 @@
#include <qset.h>
#include <qhash.h>
-#include "qsgmatrix4x4stack.h"
-
#include <qglfunctions.h>
#include <qglshaderprogram.h>
@@ -103,18 +101,18 @@ public:
inline void setViewportRect(const QSize &size) { setViewportRect(QRect(QPoint(), size)); }
QRect viewportRect() const { return m_viewport_rect; }
- QSGMatrix4x4Stack &projectionMatrix() { return m_projectionMatrix; }
- QSGMatrix4x4Stack &modelViewMatrix() { return m_modelViewMatrix; }
- QMatrix4x4 combinedMatrix() const { return m_projectionMatrix.top() * m_modelViewMatrix.top(); }
+ // Accessed by QSGMaterialShader::RenderState.
+ QMatrix4x4 currentProjectionMatrix() const { return m_current_projection_matrix; }
+ QMatrix4x4 currentModelViewMatrix() const { return m_current_model_view_matrix; }
+ QMatrix4x4 currentCombinedMatrix() const { return m_current_projection_matrix * m_current_model_view_matrix; }
+ qreal currentOpacity() const { return m_current_opacity; }
- void setProjectMatrixToDeviceRect();
- void setProjectMatrixToRect(const QRectF &rect);
- void setProjectMatrix(const QMatrix4x4 &matrix);
- QMatrix4x4 projectMatrix() const { return m_projection_matrix; }
+ void setProjectionMatrixToDeviceRect();
+ void setProjectionMatrixToRect(const QRectF &rect);
+ void setProjectionMatrix(const QMatrix4x4 &matrix);
+ QMatrix4x4 projectionMatrix() const { return m_projection_matrix; }
bool isMirrored() const { return m_mirrored; }
- qreal renderOpacity() const { return m_render_opacity; }
-
void setClearColor(const QColor &color);
QColor clearColor() const { return m_clear_color; }
@@ -155,9 +153,9 @@ protected:
QColor m_clear_color;
ClearMode m_clear_mode;
- QSGMatrix4x4Stack m_projectionMatrix;
- QSGMatrix4x4Stack m_modelViewMatrix;
- qreal m_render_opacity;
+ QMatrix4x4 m_current_projection_matrix;
+ QMatrix4x4 m_current_model_view_matrix;
+ qreal m_current_opacity;
QSGContext *m_context;
diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp
index 55942bebe4..682b514b9c 100644
--- a/src/declarative/scenegraph/qsgcontext.cpp
+++ b/src/declarative/scenegraph/qsgcontext.cpp
@@ -63,7 +63,7 @@
DEFINE_BOOL_CONFIG_OPTION(qmlFlashMode, QML_FLASH_MODE)
DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
-/*!
+/*
Comments about this class from Gunnar:
The QSGContext class is right now two things.. The first is the
@@ -78,8 +78,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlTranslucentMode, QML_TRANSLUCENT_MODE)
If we ever move the scene graph core API into its own thing, this class
needs to be split in two. Right now its one because we're lazy when it comes
to defining plugin interfaces..
-
- */
+*/
QT_BEGIN_NAMESPACE
@@ -308,7 +307,7 @@ QSGRenderer *QSGContext::createRenderer()
{
// ### Do something with this before release...
static bool doFrontToBack = qApp->arguments().contains(QLatin1String("--opaque-front-to-back"));
- QMLRenderer *renderer = new QMLRenderer(this);
+ QSGDefaultRenderer *renderer = new QSGDefaultRenderer(this);
if (doFrontToBack) {
printf("QSGContext: Sorting opaque nodes front to back...\n");
renderer->setSortFrontToBackEnabled(true);
@@ -400,7 +399,7 @@ QSGMaterialShader *QSGContext::prepareMaterial(QSGMaterial *material)
/*!
- Sets weither the scene graph should render with flashing update rectangles or not
+ Sets whether the scene graph should render with flashing update rectangles or not
*/
void QSGContext::setFlashModeEnabled(bool enabled)
diff --git a/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp b/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp
index 50c946a849..c63ff9d4cc 100644
--- a/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp
+++ b/src/declarative/scenegraph/qsgdistancefieldglyphcache.cpp
@@ -51,6 +51,7 @@
#include <qglfunctions.h>
#include <qglyphrun.h>
#include <qrawfont.h>
+#include <qdir.h>
QT_BEGIN_NAMESPACE
@@ -344,10 +345,8 @@ static QImage makeDistanceField(int imgSize, const QPainterPath &path, int dfSca
bool isShortData = polys.indices.type() == QVertexIndexVector::UnsignedShort;
const void *indices = polys.indices.data();
int index = 0;
- QVector<DFPoint> normals;
- QVector<DFVertex> vertices;
- normals.reserve(polys.vertices.count());
- vertices.reserve(polys.vertices.count());
+ QVarLengthArray<DFPoint> normals(polys.vertices.count());
+ QVarLengthArray<DFVertex> vertices(polys.vertices.count());
while (index < polys.indices.size()) {
normals.clear();
@@ -386,7 +385,7 @@ static QImage makeDistanceField(int imgSize, const QPainterPath &path, int dfSca
vertices.append(v);
}
- QVector<bool> isConvex(normals.count());
+ QVarLengthArray<bool> isConvex(normals.count());
for (int next = 0, prev = normals.count() - 1; next < normals.count(); prev = next++)
isConvex[prev] = (normals.at(prev).x * normals.at(next).y - normals.at(prev).y * normals.at(next).x > 0);
@@ -473,11 +472,14 @@ static void convert_to_Format_Alpha(QImage *image)
const int width = image->width();
const int height = image->height();
uchar *data = image->bits();
+ const uint *src = (const uint *) data;
+ int stride = image->bytesPerLine() / sizeof(uint);
for (int i = 0; i < height; ++i) {
uchar *o = data + i * width;
for (int x = 0; x < width; ++x)
- o[x] = (uchar)qAlpha(image->pixel(x, i));
+ o[x] = (uchar)qAlpha(src[x]);
+ src += stride;
}
}
@@ -910,17 +912,45 @@ void QSGDistanceFieldGlyphCache::updateCache()
if (m_textureData->pendingGlyphs.isEmpty())
return;
- int requiredWidth = m_textureData->currY == 0 ? m_textureData->currX : maxTextureSize();
- int requiredHeight = qMin(maxTextureSize(), m_textureData->currY + QT_DISTANCEFIELD_TILESIZE);
+ int requiredWidth = maxTextureSize();
+ int rows = 128 / (requiredWidth / QT_DISTANCEFIELD_TILESIZE); // Enough rows to fill the latin1 set by default..
+ int requiredHeight = qMin(maxTextureSize(), qMax(m_textureData->currY + QT_DISTANCEFIELD_TILESIZE, QT_DISTANCEFIELD_TILESIZE * rows));
resizeTexture((requiredWidth), (requiredHeight));
glBindTexture(GL_TEXTURE_2D, m_textureData->texture);
+ // ### Remove before final release
+ static bool cacheDistanceFields = QApplication::arguments().contains("--cache-distance-fields");
+
+ QString tmpPath = QString::fromLatin1("%1/.qt/").arg(QDir::tempPath());
+ QString keyBase = QString::fromLatin1("%1%2%3_%4_%5_%6.fontblob")
+ .arg(tmpPath)
+ .arg(m_font.familyName())
+ .arg(m_font.styleName())
+ .arg(m_font.weight())
+ .arg(m_font.style());
+
+ if (cacheDistanceFields && !QFile::exists(tmpPath))
+ QDir(tmpPath).mkpath(tmpPath);
+
for (int i = 0; i < m_textureData->pendingGlyphs.size(); ++i) {
glyph_t glyphIndex = m_textureData->pendingGlyphs.at(i);
- QImage glyph = renderDistanceFieldGlyph(glyphIndex);
TexCoord c = m_textureData->texCoords.value(glyphIndex);
+ if (cacheDistanceFields) {
+ QString key = keyBase.arg(glyphIndex);
+ QFile file(key);
+ if (file.open(QFile::ReadOnly)) {
+ int fileSize = file.size();
+ int dim = sqrt(float(fileSize));
+ QByteArray blob = file.readAll();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, dim, dim, GL_ALPHA, GL_UNSIGNED_BYTE, blob.constData());
+ continue;
+ }
+ }
+
+ QImage glyph = renderDistanceFieldGlyph(glyphIndex);
+
if (ctx->d_ptr->workaround_brokenFBOReadBack) {
QPainter p(&m_textureData->image);
p.setCompositionMode(QPainter::CompositionMode_Source);
@@ -930,6 +960,13 @@ void QSGDistanceFieldGlyphCache::updateCache()
convert_to_Format_Alpha(&glyph);
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, glyph.width(), glyph.height(), GL_ALPHA, GL_UNSIGNED_BYTE, glyph.constBits());
+
+ if (cacheDistanceFields) {
+ QString key = keyBase.arg(glyphIndex);
+ QFile file(key);
+ file.open(QFile::WriteOnly);
+ file.write((const char *) glyph.constBits(), glyph.width() * glyph.height());
+ }
}
m_textureData->pendingGlyphs.reset();
}
diff --git a/src/declarative/scenegraph/qsgflashnode.cpp b/src/declarative/scenegraph/qsgflashnode.cpp
index c2c1919f82..7573b182fc 100644
--- a/src/declarative/scenegraph/qsgflashnode.cpp
+++ b/src/declarative/scenegraph/qsgflashnode.cpp
@@ -30,7 +30,7 @@
**
**
**
-**˚
+**
**
**
**
diff --git a/src/declarative/scenegraph/scenegraph.pri b/src/declarative/scenegraph/scenegraph.pri
index 17370804a3..3a2a7fafee 100644
--- a/src/declarative/scenegraph/scenegraph.pri
+++ b/src/declarative/scenegraph/scenegraph.pri
@@ -9,8 +9,6 @@ HEADERS += \
$$PWD/coreapi/qsgdefaultrenderer_p.h \
$$PWD/coreapi/qsggeometry.h \
$$PWD/coreapi/qsgmaterial.h \
- $$PWD/coreapi/qsgmatrix4x4stack.h \
- $$PWD/coreapi/qsgmatrix4x4stack_p.h \
$$PWD/coreapi/qsgnode.h \
$$PWD/coreapi/qsgnodeupdater_p.h \
$$PWD/coreapi/qsgrenderer_p.h
@@ -18,7 +16,6 @@ SOURCES += \
$$PWD/coreapi/qsgdefaultrenderer.cpp \
$$PWD/coreapi/qsggeometry.cpp \
$$PWD/coreapi/qsgmaterial.cpp \
- $$PWD/coreapi/qsgmatrix4x4stack.cpp \
$$PWD/coreapi/qsgnode.cpp \
$$PWD/coreapi/qsgnodeupdater.cpp \
$$PWD/coreapi/qsgrenderer.cpp
diff --git a/src/declarative/util/qdeclarativechangeset.cpp b/src/declarative/util/qdeclarativechangeset.cpp
new file mode 100644
index 0000000000..d9a508ba13
--- /dev/null
+++ b/src/declarative/util/qdeclarativechangeset.cpp
@@ -0,0 +1,440 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 "qdeclarativechangeset_p.h"
+
+void QDeclarativeChangeSet::insertInsert(int start, int end)
+{
+ const int count = end - start;
+
+ // Moved signals.
+ QVector<Move>::iterator move = m_moves.begin();
+ for (; move != m_moves.end() && start >= move->maximum(); ++move) {}
+ for (; move != m_moves.end() && end >= move->minimum(); ++move) {
+ if (start <= move->tstart) {
+ move->tstart += count;
+ move->tend += count;
+ } else if (start < move->tend) {
+ int relativeStart = start - move->tstart;
+
+ move = m_moves.insert(move, Move(
+ move->fstart + count, move->fstart + count + relativeStart, move->tstart));
+ ++move;
+ move->fstart += relativeStart;
+ move->tstart += count + relativeStart;
+ move->tend += count;
+
+ start -= relativeStart;
+ end -= relativeStart;
+ } else {
+ start -= move->count();
+ end -= move->count();
+ }
+
+ if (start <= move->fstart) {
+ move->fstart += count;
+ move->fend += count;
+ } else if (start < move->tstart) {
+ start += move->count();
+ end += move->count();
+ }
+
+ }
+ for (; move != m_moves.end(); ++move) {
+ move->fstart += count;
+ move->fend += count;
+ move->tstart += count;
+ move->tend += count;
+ }
+
+ // Inserted signals.
+ QVector<Insert>::iterator insert = m_inserts.begin();
+ for (; insert != m_inserts.end(); ++insert) {
+ if (start < insert->start) {
+ insert = m_inserts.insert(insert, Insert(start, end));
+ break;
+ } else if (start <= insert->end) {
+ insert->end += count;
+ break;
+ }
+ }
+ if (insert == m_inserts.end()) {
+ m_inserts.append(Insert(start, end));
+ } else for (++insert; insert != m_inserts.end(); ++insert) {
+ insert->start += count;
+ insert->end += count;
+ }
+
+
+ // Changed signals.
+ QVector<Change>::iterator change = m_changes.begin();
+ for (; change != m_changes.end() && start != change->start && start < change->end; ++change) {
+ if (start > change->start) {
+ int relativeStart = start - change->start;
+ change = m_changes.insert(change, Change(change->start, change->start + relativeStart));
+ ++change;
+ change->start += count + relativeStart;
+ change->end += count - relativeStart;
+ break;
+ }
+ }
+ for (; change != m_changes.end(); ++change) {
+ change->start += count;
+ change->end += count;
+ }
+}
+
+void QDeclarativeChangeSet::insertRemove(int start, int end)
+{
+ // Changed Signals.
+ QVector<Change>::iterator change = m_changes.begin();
+ for (; change != m_changes.end() && start >= change->end; ++change) {}
+ for (; change != m_changes.end() && end < change->start; ++change) {
+ const int removeCount = qMin(change->end, end) - qMax(change->start, start);
+ change->end -= removeCount;
+ if (change->start == change->end) {
+ change = m_changes.erase(change);
+ } else if (start < change->start) {
+ change->start = start;
+ }
+ }
+ const int count = end - start;
+ for (; change != m_changes.end(); ++change) {
+ change->start -= count;
+ change->end -= count;
+ }
+
+ QVector<Remove> removeChanges;
+
+ // Moved signals.
+ QVector<Move>::iterator move = m_moves.begin();
+ for (; move != m_moves.end() && start >= move->maximum(); ++move) {}
+ for (; move != m_moves.end() && end >= move->minimum(); ++move) {
+ if (move->fstart < move->tstart) {
+ if (start < move->fstart) {
+ const int difference = move->fstart - start;
+ move->fend -= difference;
+ move->fstart = start;
+ move->tstart -= difference;
+ move->tend -= difference;
+
+ removeChanges.append(Remove(start, start + difference));
+ end -= difference;
+ }
+ if (end < move->tstart) {
+ move->tstart -= end - start;
+ move->tend -= end - start;
+ } else if (start < move->tend) {
+ const int difference = qMin(move->tend, end) - move->tstart;
+ removeChanges.append(Remove(
+ move->fstart , move->fstart + difference));
+ end -= difference;
+
+ move->fend -= difference;
+ move->tstart -= end - start;
+ move->tend -= end - start + difference;
+ }
+ start += move->count();
+ end += move->count();
+ } else {
+ if (start < move->tend) {
+ const int offset = qMax(0, start - move->tstart);
+ const int difference = qMin(move->tend, end) - qMax(move->tstart, start);
+
+ removeChanges.append(Remove(
+ move->fstart + offset, move->fstart + offset + difference));
+ start -= offset;
+ end -= offset + difference;
+
+ move->fend -= difference;
+ move->tstart = start;
+ move->tend = start + move->fend - move->fstart;
+ } else {
+ start -= move->count();
+ end -= move->count();
+ }
+
+ move->fstart -= end - start;
+ move->fend -= end - start;
+
+ if (start > move->fstart) {
+ const int offset = start - move->fstart;
+ const int difference = qMin(move->fend, end) - start;
+ removeChanges.append(Remove(
+ move->fstart + end - start + offset + difference ,
+ move->fend + end - start + offset));
+ end -= offset;
+ move->fstart += offset;
+ move->fend += offset;
+ }
+ }
+
+ if (move->tstart == move->tend || move->fstart == move->tstart) {
+ move = m_moves.erase(move);
+ --move;
+ }
+ }
+ for (; move != m_moves.end(); ++move) {
+ move->fstart -= count;
+ move->fend -= count;
+ move->tstart -= count;
+ move->tend -= count;
+ }
+
+ if (start != end)
+ removeChanges.append(Remove(start, end));
+
+ foreach (const Remove &r, removeChanges) {
+ int start = r.start;
+ int end = r.end;
+
+ QVector<Insert>::iterator insert = m_inserts.end() - 1;
+ for (const int count = end - start; insert != m_inserts.begin() - 1 && insert->start >= end; --insert) {
+ insert->start -= count;
+ insert->end -= count;
+ }
+ for (; insert != m_inserts.begin() - 1 && insert->end > start; --insert) {
+ const int removeCount = qMin(insert->end, end) - qMax(insert->start, start);
+ insert->end -= removeCount;
+ if (insert->start == insert->end) {
+ insert = m_inserts.erase(insert);
+ } else if (start < insert->start) {
+ insert->end -= insert->start - start;
+ insert->start = start;
+ } else {
+ start -= insert->count();
+ end -= insert->count();
+ }
+ end -= removeCount;
+ if (start == end)
+ return;
+ }
+ // Adjust the index to compensate for any inserts prior to the remove position..
+ for (; insert != m_inserts.begin() - 1; --insert) {
+ start -= insert->count();
+ end -= insert->count();
+ }
+
+ // Removed signals.
+ QVector<Remove>::iterator remove = m_removes.begin();
+ for (; remove != m_removes.end(); ++remove) {
+ if (end < remove->start) {
+ remove = m_removes.insert(remove, Remove(start, end));
+ break;
+ } else if (start <= remove->start) {
+ remove->end += end - remove->start;
+ remove->start = start;
+
+ QVector<Remove>::iterator rbegin = remove;
+ QVector<Remove>::iterator rend = ++rbegin;
+ for (; rend != m_removes.end() && rend->start <= remove->end; ++rend)
+ remove->end += rend->count();
+ if (rbegin != rend) {
+ remove = m_removes.erase(rbegin, rend);
+ }
+ break;
+ }
+ }
+ if (remove != m_removes.end()) {
+ const int count = end - start;
+ for (++remove; remove != m_removes.end(); ++remove) {
+ remove->start -= count;
+ remove->end -= count;
+ }
+ } else {
+ m_removes.append(Remove(start, end));
+ }
+ }
+}
+
+void QDeclarativeChangeSet::insertMove(int start, int end, int to)
+{
+ QVector<Insert> insertChanges;
+ QVector<Move> moveChanges;
+
+ int fStart = start;
+ int fTo = to;
+ int fEnd = end;
+ int &bStart = fTo;
+ int bEnd = to + end - start;
+
+ if (start > to) {
+ qSwap(fStart, bStart);
+ qSwap(fEnd, bEnd);
+ }
+
+ // Inserted signals.
+ QVector<Insert>::iterator insert = m_inserts.begin();
+ if (start < to) {
+ for (; insert != m_inserts.end() && fStart >= insert->end; ++insert) {}
+ for (; insert != m_inserts.end() && fEnd > insert->start; ++insert) {
+ const int removeCount = qMin(insert->end, fEnd) - qMax(insert->start, fStart);
+ const int relativeStart = fStart - insert->start;
+ const int relativeEnd = qMax(0, fEnd - insert->end);
+
+ insert->end -= removeCount;
+ if (insert->start == insert->end) {
+ insert = m_inserts.erase(insert);
+ --insert;
+ }
+
+ if (relativeStart < 0) {
+ moveChanges.append(Move(fStart, fStart - relativeStart, fTo + relativeEnd));
+ fTo -= relativeStart;
+ }
+
+ fTo += removeCount;
+ insertChanges.append(Insert(bEnd - removeCount, bEnd));
+ }
+ } else {
+ for (; insert != m_inserts.end() && bStart >= insert->end; ++insert) {}
+ for (; insert != m_inserts.end() && bEnd > insert->start; ++insert) {
+ const int removeCount = qMin(insert->end, bEnd) - qMax(insert->start, bStart);
+ const int relativeStart = bStart - insert->start;
+
+ insert->start += removeCount;
+ if (insert->start == insert->end) {
+ insert->start = fStart;
+ insert->end = insert->start + removeCount;
+ } else {
+ insert = m_inserts.insert(insert, Insert(fStart, fStart + removeCount));
+ ++insert;
+ }
+ if (relativeStart < 0) {
+ moveChanges.append(Move(fStart, fStart - relativeStart, fTo + removeCount));
+ fStart -= relativeStart;
+ fTo -= relativeStart;
+ }
+ fStart += removeCount;
+ fTo += removeCount;
+ }
+ }
+
+ if (fTo != bEnd)
+ moveChanges.append(Move(fStart, fStart + bEnd - fTo, fTo));
+
+ QVector<Insert>::iterator it = insertChanges.begin();
+ for (insert = m_inserts.begin(); it != insertChanges.end() && insert != m_inserts.end();++insert) {
+ if (it->start < insert->start) {
+ insert = m_inserts.insert(insert, *it);
+ ++it;
+ } else if (it->start <= insert->end) {
+ insert->end += it->count();
+ ++it;
+ }
+ }
+ for (; it != insertChanges.end(); ++it)
+ m_inserts.append(*it);
+
+ // Insert queued moved signals ordered by destination position.
+ QVector<Move>::iterator move = m_moves.begin();
+ if (start > to) {
+ for (QVector<Move>::iterator it = moveChanges.begin(); it != moveChanges.end(); ++it) {
+ it->fend += it->tstart - it->fstart;
+ it->tend -=it->tstart - it->fstart;
+ qSwap(it->fstart, it->tstart);
+ for (; move != m_moves.end() && it->to >= qMin(move->fstart, move->tstart); ++move) {}
+ move = m_moves.insert(move, *it);
+ }
+ } else {
+ for (QVector<Move>::iterator it = moveChanges.begin(); it != moveChanges.end(); ++it) {
+ for (; move != m_moves.end() && it->start >= qMin(move->fstart, move->tstart); ++move) {}
+ move = m_moves.insert(move, *it);
+ }
+ }
+}
+
+void QDeclarativeChangeSet::insertChange(int start, int end)
+{
+ QVector<Change> filteredChanges;
+
+ // Inserted signals (don't emit change signals on new items).
+ QVector<Insert>::iterator insert = m_inserts.begin();
+ for (; insert != m_inserts.end() && start >= insert->end; ++insert) {}
+ for (; insert != m_inserts.end() && end > insert->start; ++insert) {
+ if (start < insert->start)
+ filteredChanges.append(Change(start, insert->start));
+ start = insert->end;
+ }
+ if (start < end)
+ filteredChanges.append(Change(start, end));
+
+ // Find the union of the existing and filtered sets of change signals.
+ QVector<Change>::iterator change = m_changes.begin();
+ for (QVector<Change>::iterator it = filteredChanges.begin(); it != filteredChanges.end(); ++it) {
+ for (; change != m_changes.end() && change->end < it->start; ++change) {}
+ if (change == m_changes.end() || change->start > it->end) {
+ change = m_changes.insert(change, *it);
+ } else {
+ if (it->start < change->start)
+ change->start = it->start;
+
+ if (it->end > change->end) {
+ change->end = it->end;
+ QVector<Change>::iterator rbegin = change;
+ QVector<Change>::iterator rend = ++rbegin;
+ for (; rend != m_changes.end() && rend->start <= change->end; ++rend) {
+ if (rend->end > change->end)
+ change->end = rend->end;
+ }
+ if (rbegin != rend) {
+ change = m_changes.erase(rbegin, rend);
+ --change;
+ }
+ }
+ }
+ }
+
+}
+
+QDebug operator <<(QDebug debug, const QDeclarativeChangeSet &set)
+{
+ foreach (const QDeclarativeChangeSet::Remove &remove, set.removes())
+ debug.nospace() << "QDeclarativeChangeSet::Remove(" << remove.start << "," << remove.end << ")";
+ foreach (const QDeclarativeChangeSet::Insert &insert, set.inserts())
+ debug.nospace() << "QDeclarativeChangeSet::Insert(" << insert.start << "," << insert.end << ")";
+ foreach (const QDeclarativeChangeSet::Move &move, set.moves())
+ debug.nospace() << "QDeclarativeChangeSet::Move(" << move.start << "," << move.end << "," << move.to << ")";
+ foreach (const QDeclarativeChangeSet::Change &change, set.changes())
+ debug.nospace() << "QDeclarativeChangeSet::Change(" << change.start << "," << change.end << ")";
+ return debug;
+}
+
diff --git a/src/declarative/util/qdeclarativechangeset_p.h b/src/declarative/util/qdeclarativechangeset_p.h
new file mode 100644
index 0000000000..f911e658ea
--- /dev/null
+++ b/src/declarative/util/qdeclarativechangeset_p.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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 QDECLARATIVECHANGESET_P_H
+#define QDECLARATIVECHANGESET_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 <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QDeclarativeChangeSet
+{
+public:
+ struct Insert
+ {
+ Insert() {}
+ Insert(int start, int end) : start(start), end(end) {}
+
+ int count() const { return end - start; }
+
+ int start;
+ int end;
+ };
+
+ struct Remove
+ {
+ Remove() {}
+ Remove(int start, int end) : start(start), end(end) {}
+
+ int count() const { return end - start; }
+
+ int start;
+ int end;
+ };
+
+ struct Move
+ {
+ Move() {}
+ Move(int start, int end, int to) : fstart(start), fend(end), tstart(to), tend(to + end - start) {}
+
+ int minimum() const { return qMin(fstart, tstart); }
+ int maximum() const { return qMax(fend, tend); }
+ int count() const { return fend - fstart; }
+
+ union {
+ int start;
+ int fstart;
+ };
+ union {
+ int end;
+ int fend;
+ };
+ union {
+ int to;
+ int tstart;
+ };
+ int tend;
+ };
+
+ struct Change
+ {
+ Change() {}
+ Change(int start, int end) : start(start), end(end) {}
+
+ int count() const { return end - start; }
+
+ int start;
+ int end;
+ };
+
+ const QVector<Remove> &removes() const { return m_removes; }
+ const QVector<Insert> &inserts() const { return m_inserts; }
+ const QVector<Move> &moves() const { return m_moves; }
+ const QVector<Change> &changes() const {return m_changes; }
+
+ void insertInsert(int start, int end);
+ void insertRemove(int start, int end);
+ void insertMove(int start, int end, int to);
+ void insertChange(int start, int end);
+
+ void appendInsert(int start, int end) { m_inserts.append(Insert(start, end)); }
+ void appendRemove(int start, int end) { m_removes.append(Remove(start, end)); }
+ void appendMove(int start, int end, int to) { m_moves.append(Move(start, end, to)); }
+ void appendChange(int start, int end) { m_changes.append(Change(start, end)); }
+
+ void append(const QVector<Insert> &inserts) { m_inserts += inserts; }
+ void append(const QVector<Remove> &removes) { m_removes += removes; }
+ void append(const QVector<Move> &moves) { m_moves += moves; }
+ void append(const QVector<Change> &changes) { m_changes += changes; }
+
+ void clear()
+ {
+ m_removes.clear();
+ m_inserts.clear();
+ m_moves.clear();
+ m_changes.clear();
+ }
+
+private:
+ QVector<Remove> m_removes;
+ QVector<Insert> m_inserts;
+ QVector<Move> m_moves;
+ QVector<Change> m_changes;
+};
+
+Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QDeclarativeChangeSet &change);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index 5bc8b117c0..4bd1f1bb1b 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -28,6 +28,7 @@ SOURCES += \
$$PWD/qdeclarativefontloader.cpp \
$$PWD/qdeclarativestyledtext.cpp \
$$PWD/qdeclarativelistmodelworkeragent.cpp \
+ $$PWD/qdeclarativechangeset.cpp \
$$PWD/qlistmodelinterface.cpp
HEADERS += \
@@ -63,6 +64,7 @@ HEADERS += \
$$PWD/qdeclarativefontloader_p.h \
$$PWD/qdeclarativestyledtext_p.h \
$$PWD/qdeclarativelistmodelworkeragent_p.h \
+ $$PWD/qdeclarativechangeset_p.h \
$$PWD/qlistmodelinterface_p.h
contains(QT_CONFIG, xmlpatterns) {
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro
index 20fa8548fd..9ef9ce8a16 100644
--- a/tests/auto/declarative/declarative.pro
+++ b/tests/auto/declarative/declarative.pro
@@ -34,6 +34,7 @@ contains(QT_CONFIG, private_tests) {
qdeclarativebehaviors \
qdeclarativebinding \
qdeclarativeborderimage \
+ qdeclarativechangeset \
qdeclarativeconnection \
qdeclarativedebug \
qdeclarativedebugclient \
diff --git a/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro b/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro
new file mode 100644
index 0000000000..1c9a3c00f9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro
@@ -0,0 +1,17 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative gui
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativechangeset.cpp
+
+symbian: {
+ importFiles.files = data
+ importFiles.path = .
+ DEPLOYMENT += importFiles
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp b/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp
new file mode 100644
index 0000000000..018711ac64
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativechangeset/tst_qdeclarativechangeset.cpp
@@ -0,0 +1,614 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <private/qdeclarativechangeset_p.h>
+
+#define VERIFY_EXPECTED_OUTPUT
+
+
+
+class tst_qdeclarativemodelchange : public QObject
+{
+ Q_OBJECT
+public:
+ struct Signal
+ {
+ int start;
+ int end;
+ int to;
+
+ bool isInsert() const { return to == -1; }
+ bool isRemove() const { return to == -2; }
+ bool isMove() const { return to >= 0; }
+ bool isChange() const { return to == -3; }
+ };
+
+ static Signal Insert(int start, int end) { Signal signal = { start, end, -1 }; return signal; }
+ static Signal Remove(int start, int end) { Signal signal = { start, end, -2 }; return signal; }
+ static Signal Move(int start, int end, int to) { Signal signal = { start, end, to }; return signal; }
+ static Signal Change(int start, int end) { Signal signal = { start, end, -3 }; return signal; }
+
+ typedef QVector<Signal> SignalList;
+
+
+#ifdef VERIFY_EXPECTED_OUTPUT
+
+ template<typename T>
+ void move(int from, int to, int n, T *items)
+ {
+ if (from > to) {
+ // Only move forwards - flip if backwards moving
+ int tfrom = from;
+ int tto = to;
+ from = tto;
+ to = tto+n;
+ n = tfrom-tto;
+ }
+
+ T replaced;
+ int i=0;
+ typename T::ConstIterator it=items->begin(); it += from+n;
+ for (; i<to-from; ++i,++it)
+ replaced.append(*it);
+ i=0;
+ it=items->begin(); it += from;
+ for (; i<n; ++i,++it)
+ replaced.append(*it);
+ typename T::ConstIterator f=replaced.begin();
+ typename T::Iterator t=items->begin(); t += from;
+ for (; f != replaced.end(); ++f, ++t)
+ *t = *f;
+ }
+
+ QVector<int> applyChanges(const QVector<int> &list, const QVector<Signal> &changes)
+ {
+ QVector<int> alteredList = list;
+ foreach (const Signal &signal, changes) {
+ if (signal.isInsert()) {
+ alteredList.insert(signal.start, signal.end - signal.start, 100);
+ } else if (signal.isRemove()) {
+ alteredList.erase(alteredList.begin() + signal.start, alteredList.begin() + signal.end);
+ } else if (signal.isMove()) {
+ move(signal.start, signal.to, signal.end - signal.start, &alteredList);
+ } else if (signal.isChange()) {
+ for (int i = signal.start; i < signal.end; ++i) {
+ if (alteredList[i] < 100)
+ alteredList[i] = 100;
+ }
+ }
+ }
+ return alteredList;
+ }
+
+#endif
+
+private slots:
+ void sequence_data();
+ void sequence();
+};
+
+bool operator ==(const tst_qdeclarativemodelchange::Signal &left, const tst_qdeclarativemodelchange::Signal &right) {
+ return left.start == right.start && left.end == right.end && left.to == right.to; }
+
+
+QDebug operator <<(QDebug debug, const tst_qdeclarativemodelchange::Signal &signal)
+{
+ if (signal.isInsert())
+ debug.nospace() << "Insert(" << signal.start << "," << signal.end << ")";
+ else if (signal.isRemove())
+ debug.nospace() << "Remove(" << signal.start << "," << signal.end << ")";
+ else if (signal.isMove())
+ debug.nospace() << "Move(" << signal.start << "," << signal.end << "," << signal.to << ")";
+ else if (signal.isChange())
+ debug.nospace() << "Change(" << signal.start << "," << signal.end << ")";
+ return debug;
+}
+
+Q_DECLARE_METATYPE(tst_qdeclarativemodelchange::SignalList)
+
+void tst_qdeclarativemodelchange::sequence_data()
+{
+ QTest::addColumn<SignalList>("input");
+ QTest::addColumn<SignalList>("output");
+
+ // Insert
+ QTest::newRow("i(12-17)")
+ << (SignalList() << Insert(12, 17))
+ << (SignalList() << Insert(12, 17));
+ QTest::newRow("i(2-5),i(12-17)")
+ << (SignalList() << Insert(2, 5) << Insert(12, 17))
+ << (SignalList() << Insert(2, 5) << Insert(12, 17));
+ QTest::newRow("i(12-17),i(2-5)")
+ << (SignalList() << Insert(12, 17) << Insert(2, 5))
+ << (SignalList() << Insert(2, 5) << Insert(15, 20));
+ QTest::newRow("i(12-17),i(12-15)")
+ << (SignalList() << Insert(12, 17) << Insert(12, 15))
+ << (SignalList() << Insert(12, 20));
+ QTest::newRow("i(12-17),i(17-20)")
+ << (SignalList() << Insert(12, 17) << Insert(17, 20))
+ << (SignalList() << Insert(12, 20));
+ QTest::newRow("i(12-17),i(15-18)")
+ << (SignalList() << Insert(12, 17) << Insert(15, 18))
+ << (SignalList() << Insert(12, 20));
+
+ // Remove
+ QTest::newRow("r(3-12)")
+ << (SignalList() << Remove(3, 12))
+ << (SignalList() << Remove(3, 12));
+ QTest::newRow("r(3-7),r(3-5)")
+ << (SignalList() << Remove(3, 7) << Remove(3, 5))
+ << (SignalList() << Remove(3, 9));
+ QTest::newRow("r(4-3),r(14-19)")
+ << (SignalList() << Remove(4, 7) << Remove(14, 19))
+ << (SignalList() << Remove(4, 7) << Remove(14, 19));
+ QTest::newRow("r(14-19),r(4-7)")
+ << (SignalList() << Remove(14, 19) << Remove(4, 7))
+ << (SignalList() << Remove(4, 7) << Remove(11, 16));
+ QTest::newRow("r(4-7),r(2-11)")
+ << (SignalList() << Remove(4, 7) << Remove(2, 11))
+ << (SignalList() << Remove(2, 14));
+
+ // Move
+ QTest::newRow("m(8-10,10)")
+ << (SignalList() << Move(8, 10, 10))
+ << (SignalList() << Move(8, 10, 10));
+ // No merging of moves yet.
+// QTest::newRow("m(5-7,13),m(5-8,12)")
+// << (SignalList() << Move(5, 7, 13) << Move(5, 8, 12))
+// << (SignalList() << Move(5, 10, 10));
+
+ // Change
+ QTest::newRow("c(4-9)")
+ << (SignalList() << Change(4, 9))
+ << (SignalList() << Change(4, 9));
+ QTest::newRow("c(4-9),c(12-14)")
+ << (SignalList() << Change(4, 9) << Change(12, 14))
+ << (SignalList() << Change(4, 9) << Change(12, 14));
+ QTest::newRow("c(12-14),c(4-9)")
+ << (SignalList() << Change(12, 14) << Change(4, 9))
+ << (SignalList() << Change(4, 9) << Change(12, 14));
+ QTest::newRow("c(4-9),c(2-4)")
+ << (SignalList() << Change(4, 9) << Change(2, 4))
+ << (SignalList() << Change(2, 9));
+ QTest::newRow("c(4-9),c(9-11)")
+ << (SignalList() << Change(4, 9) << Change(9, 11))
+ << (SignalList() << Change(4, 11));
+ QTest::newRow("c(4-9),c(3-5)")
+ << (SignalList() << Change(4, 9) << Change(3, 5))
+ << (SignalList() << Change(3, 9));
+ QTest::newRow("c(4-9),c(8-10)")
+ << (SignalList() << Change(4, 9) << Change(8, 10))
+ << (SignalList() << Change(4, 10));
+ QTest::newRow("c(4-9),c(3-5)")
+ << (SignalList() << Change(4, 9) << Change(3, 5))
+ << (SignalList() << Change(3, 9));
+ QTest::newRow("c(4-9),c(2,11)")
+ << (SignalList() << Change(4, 9) << Change(2, 11))
+ << (SignalList() << Change(2, 11));
+ QTest::newRow("c(4-9),c(12-15),c(8-14)")
+ << (SignalList() << Change(4, 9) << Change(12, 15) << Change(8, 14))
+ << (SignalList() << Change(4, 15));
+
+ // Insert, then remove.
+ QTest::newRow("i(12-18),r(12-18)")
+ << (SignalList() << Insert(12, 18) << Remove(12, 18))
+ << (SignalList());
+ QTest::newRow("i(12-18),r(10-14)")
+ << (SignalList() << Insert(12, 18) << Remove(10, 14))
+ << (SignalList() << Remove(10, 12) << Insert(10, 14));
+ QTest::newRow("i(12-18),r(16-20)")
+ << (SignalList() << Insert(12, 18) << Remove(16, 20))
+ << (SignalList() << Remove(12, 14) << Insert(12, 16));
+ QTest::newRow("i(12-18),r(13-17)")
+ << (SignalList() << Insert(12, 18) << Remove(13, 17))
+ << (SignalList() << Insert(12, 14));
+ QTest::newRow("i(12-18),r(14,18)")
+ << (SignalList() << Insert(12, 18) << Remove(14, 18))
+ << (SignalList() << Insert(12, 14));
+ QTest::newRow("i(12-18),r(12-16)")
+ << (SignalList() << Insert(12, 18) << Remove(12, 16))
+ << (SignalList() << Insert(12, 14));
+ QTest::newRow("i(12-18),r(11-19)")
+ << (SignalList() << Insert(12, 18) << Remove(11, 19))
+ << (SignalList() << Remove(11, 13));
+ QTest::newRow("i(12-18),r(8-12)")
+ << (SignalList() << Insert(12, 18) << Remove(8, 12))
+ << (SignalList() << Remove(8, 12) << Insert(8, 14));
+ QTest::newRow("i(12-18),r(2-6)")
+ << (SignalList() << Insert(12, 18) << Remove(2, 6))
+ << (SignalList() << Remove(2, 6) << Insert(8, 14));
+ QTest::newRow("i(12-18),r(18-22)")
+ << (SignalList() << Insert(12, 18) << Remove(18, 22))
+ << (SignalList() << Remove(12, 16) << Insert(12, 18));
+ QTest::newRow("i(12-18),r(20-24)")
+ << (SignalList() << Insert(12, 18) << Remove(20, 24))
+ << (SignalList() << Remove(14, 18) << Insert(12, 18));
+
+ // Insert, then move
+ QTest::newRow("i(12-18),m(12-18,5)")
+ << (SignalList() << Insert(12, 18) << Move(12, 18, 5))
+ << (SignalList() << Insert(5, 11));
+ QTest::newRow("i(12-18),m(10-14,5)")
+ << (SignalList() << Insert(12, 18) << Move(10, 14, 5))
+ << (SignalList() << Insert(5, 7) << Insert(14, 18) << Move(12, 14, 5));
+ QTest::newRow("i(12-18),m(16-20,5)")
+ << (SignalList() << Insert(12, 18) << Move(16, 20, 5))
+ << (SignalList() << Insert(5, 7) << Insert(14, 18) << Move(18, 20, 7));
+ QTest::newRow("i(12-18),m(13-17,5)")
+ << (SignalList() << Insert(12, 18) << Move(13, 17, 5))
+ << (SignalList() << Insert(5, 9) << Insert(16, 18));
+ QTest::newRow("i(12-18),m(14-18,5)")
+ << (SignalList() << Insert(12, 18) << Move(14, 18, 5))
+ << (SignalList() << Insert(5, 9) << Insert(16, 18));
+ QTest::newRow("i(12-18),m(12-16,5)")
+ << (SignalList() << Insert(12, 18) << Move(12, 16, 5))
+ << (SignalList() << Insert(5, 9) << Insert(16, 18));
+ QTest::newRow("i(12-18),m(11-19,5)")
+ << (SignalList() << Insert(12, 18) << Move(11, 19, 5))
+ << (SignalList() << Insert(5, 11) << Move(17, 18, 5) << Move(18, 19, 12));
+ QTest::newRow("i(12-18),m(8-12,5)")
+ << (SignalList() << Insert(12, 18) << Move(8, 12, 5))
+ << (SignalList() << Insert(12, 18) << Move(8, 12, 5));
+ QTest::newRow("i(12-18),m(2-6,5)")
+ << (SignalList() << Insert(12, 18) << Move(2, 6, 5))
+ << (SignalList() << Insert(12, 18) << Move(2, 6, 5));
+ QTest::newRow("i(12-18),m(18-22,5)")
+ << (SignalList() << Insert(12, 18) << Move(18, 22, 5))
+ << (SignalList() << Insert(12, 18) << Move(18, 22, 5));
+ QTest::newRow("i(12-18),m(20-24,5)")
+ << (SignalList() << Insert(12, 18) << Move(20, 24, 5))
+ << (SignalList() << Insert(12, 18) << Move(20, 24, 5));
+
+ QTest::newRow("i(12-18),m(5-13,11)")
+ << (SignalList() << Insert(12, 18) << Move(5, 13, 11))
+ << (SignalList() << Insert(12, 17) << Insert(18, 19) << Move(5, 12, 11));
+
+ QTest::newRow("i(12-18),m(12-18,23)")
+ << (SignalList() << Insert(12, 18) << Move(12, 18, 23))
+ << (SignalList() << Insert(23, 29));
+ QTest::newRow("i(12-18),m(10-14,23)")
+ << (SignalList() << Insert(12, 18) << Move(10, 14, 23))
+ << (SignalList() << Insert(12, 16) << Insert(25, 27) << Move(10, 12, 23));
+ QTest::newRow("i(12-18),m(16-20,23)")
+ << (SignalList() << Insert(12, 18) << Move(16, 20, 23))
+ << (SignalList() << Insert(12, 16) << Insert(25, 27) << Move(16, 18, 25));
+ QTest::newRow("i(12-18),m(13-17,23)")
+ << (SignalList() << Insert(12, 18) << Move(13, 17, 23))
+ << (SignalList() << Insert(12, 14) << Insert(23, 27));
+ QTest::newRow("i(12-18),m(14-18,23)")
+ << (SignalList() << Insert(12, 18) << Move(14, 18, 23))
+ << (SignalList() << Insert(12, 14) << Insert(23, 27));
+ QTest::newRow("i(12-18),m(12-16,23)")
+ << (SignalList() << Insert(12, 18) << Move(12, 16, 23))
+ << (SignalList() << Insert(12, 14) << Insert(23, 27));
+ QTest::newRow("i(12-18),m(11-19,23)")
+ << (SignalList() << Insert(12, 18) << Move(11, 19, 23))
+ << (SignalList() << Insert(25, 31) << Move(11, 12, 24) << Move(11, 12, 30));
+ QTest::newRow("i(12-18),m(8-12,23)")
+ << (SignalList() << Insert(12, 18) << Move(8, 12, 23))
+ << (SignalList() << Insert(12, 18) << Move(8, 12, 23));
+ QTest::newRow("i(12-18),m(2-6,23)")
+ << (SignalList() << Insert(12, 18) << Move(2, 6, 23))
+ << (SignalList() << Insert(12, 18) << Move(2, 6, 23));
+ QTest::newRow("i(12-18),m(18-22,23)")
+ << (SignalList() << Insert(12, 18) << Move(18, 22, 23))
+ << (SignalList() << Insert(12, 18) << Move(18, 22, 23));
+ QTest::newRow("i(12-18),m(20-24,23)")
+ << (SignalList() << Insert(12, 18) << Move(20, 24, 23))
+ << (SignalList() << Insert(12, 18) << Move(20, 24, 23));
+
+ QTest::newRow("i(12-18),m(11-21,23)")
+ << (SignalList() << Insert(12, 18) << Move(11, 21, 23))
+ << (SignalList() << Insert(27, 33) << Move(11, 12, 26) << Move(11, 14, 30));
+
+ // Insert, then change
+ QTest::newRow("i(12-18),c(12-16)")
+ << (SignalList() << Insert(12, 18) << Change(12, 6))
+ << (SignalList() << Insert(12, 18));
+ QTest::newRow("i(12-18),c(10-14)")
+ << (SignalList() << Insert(12, 18) << Change(10, 16))
+ << (SignalList() << Insert(12, 18) << Change(10, 12));
+ QTest::newRow("i(12-18),c(16-20)")
+ << (SignalList() << Insert(12, 18) << Change(16, 20))
+ << (SignalList() << Insert(12, 18) << Change(18, 20));
+ QTest::newRow("i(12-18),c(13-17)")
+ << (SignalList() << Insert(12, 18) << Change(13, 17))
+ << (SignalList() << Insert(12, 18));
+ QTest::newRow("i(12-18),c(14-18)")
+ << (SignalList() << Insert(12, 18) << Change(14, 18))
+ << (SignalList() << Insert(12, 18));
+ QTest::newRow("i(12-18),c(12-16)")
+ << (SignalList() << Insert(12, 18) << Change(12, 16))
+ << (SignalList() << Insert(12, 18));
+ QTest::newRow("i(12-18),c(11-19)")
+ << (SignalList() << Insert(12, 18) << Change(11, 19))
+ << (SignalList() << Insert(12, 18) << Change(11, 12) << Change(18, 19));
+ QTest::newRow("i(12-18),c(8-12)")
+ << (SignalList() << Insert(12, 18) << Change(8, 12))
+ << (SignalList() << Insert(12, 18) << Change(8, 12));
+ QTest::newRow("i(12-18),c(2-6)")
+ << (SignalList() << Insert(12, 18) << Change(2, 6))
+ << (SignalList() << Insert(12, 18) << Change(2, 6));
+ QTest::newRow("i(12-18),c(18-22)")
+ << (SignalList() << Insert(12, 18) << Change(18, 22))
+ << (SignalList() << Insert(12, 18) << Change(18, 22));
+ QTest::newRow("i(12-18),c(20-24)")
+ << (SignalList() << Insert(12, 18) << Change(20, 24))
+ << (SignalList() << Insert(12, 18) << Change(20, 24));
+
+ // Remove, then insert
+ QTest::newRow("r(12-18),i(12-18)")
+ << (SignalList() << Remove(12, 18) << Insert(12, 18))
+ << (SignalList() << Remove(12, 18) << Insert(12, 18));
+ QTest::newRow("r(12-18),i(10-14)")
+ << (SignalList() << Remove(12, 18) << Insert(10, 14))
+ << (SignalList() << Remove(12, 18) << Insert(10, 14));
+ QTest::newRow("r(12-18),i(16-20)")
+ << (SignalList() << Remove(12, 18) << Insert(16, 20))
+ << (SignalList() << Remove(12, 18) << Insert(16, 20));
+ QTest::newRow("r(12-18),i(13-17)")
+ << (SignalList() << Remove(12, 18) << Insert(13, 17))
+ << (SignalList() << Remove(12, 18) << Insert(13, 17));
+ QTest::newRow("r(12-18),i(14-18)")
+ << (SignalList() << Remove(12, 18) << Insert(14, 18))
+ << (SignalList() << Remove(12, 18) << Insert(14, 18));
+ QTest::newRow("r(12-18),i(12-16)")
+ << (SignalList() << Remove(12, 18) << Insert(12, 16))
+ << (SignalList() << Remove(12, 18) << Insert(12, 16));
+ QTest::newRow("r(12-18),i(11-19)")
+ << (SignalList() << Remove(12, 18) << Insert(11, 19))
+ << (SignalList() << Remove(12, 18) << Insert(11, 19));
+ QTest::newRow("i(12-18),r(8-12)")
+ << (SignalList() << Remove(12, 18) << Insert(8, 12))
+ << (SignalList() << Remove(12, 18) << Insert(8, 12));
+ QTest::newRow("i(12-18),r(2-6)")
+ << (SignalList() << Remove(12, 18) << Insert(2, 6))
+ << (SignalList() << Remove(12, 18) << Insert(2, 6));
+ QTest::newRow("i(12-18),r(18-22)")
+ << (SignalList() << Remove(12, 18) << Insert(18, 22))
+ << (SignalList() << Remove(12, 18) << Insert(18, 22));
+ QTest::newRow("i(12-18),r(20-24)")
+ << (SignalList() << Remove(12, 18) << Insert(20, 24))
+ << (SignalList() << Remove(12, 18) << Insert(20, 24));
+
+ // Move, then insert
+ QTest::newRow("m(12-18,5),i(12-18)")
+ << (SignalList() << Move(12, 18, 5) << Insert(12, 18))
+ << (SignalList() << Insert(6, 12) << Move(18, 24, 5));
+ QTest::newRow("m(12-18,5),i(10-14)")
+ << (SignalList() << Move(12, 18, 5) << Insert(10, 14))
+ << (SignalList() << Insert(5, 9) << Move(16, 21, 5) << Move(21, 22, 14));
+ QTest::newRow("m(12-18,5),i(16-20)")
+ << (SignalList() << Move(12, 18, 5) << Insert(16, 20))
+ << (SignalList() << Insert(10, 14) << Move(16, 22, 5));
+ QTest::newRow("m(12-18,5),i(13-17)")
+ << (SignalList() << Move(12, 18, 5) << Insert(13, 17))
+ << (SignalList() << Insert(7, 11) << Move(16, 22, 5));
+ QTest::newRow("m(12-18,5),i(14-18)")
+ << (SignalList() << Move(12, 18, 5) << Insert(14, 18))
+ << (SignalList() << Insert(8, 12) << Move(16, 22, 5));
+ QTest::newRow("m(12-18,5),i(12-16)")
+ << (SignalList() << Move(12, 18, 5) << Insert(12, 16))
+ << (SignalList() << Insert(6, 10) << Move(16, 22, 5));
+ QTest::newRow("m(12-18,5),i(11-19)")
+ << (SignalList() << Move(12, 18, 5) << Insert(11, 19))
+ << (SignalList() << Insert(5, 13) << Move(20, 26, 5));
+ QTest::newRow("m(12-18,5),i(8-12)")
+ << (SignalList() << Move(12, 18, 5) << Insert(8, 12))
+ << (SignalList() << Insert(5, 9) << Move(16, 19, 5) << Move(19, 22, 12));
+ QTest::newRow("m(12-18,5),i(2-6)")
+ << (SignalList() << Move(12, 18, 5) << Insert(2, 6))
+ << (SignalList() << Insert(2, 6) << Move(16, 22, 9));
+ QTest::newRow("m(12-18,5),i(18-22)")
+ << (SignalList() << Move(12, 18, 5) << Insert(18, 22))
+ << (SignalList() << Insert(18, 22) << Move(12, 18, 5));
+ QTest::newRow("m(12-18,5),i(20-24)")
+ << (SignalList() << Move(12, 18, 5) << Insert(20, 24))
+ << (SignalList() << Insert(20, 24) << Move(12, 18, 5));
+
+ QTest::newRow("m(12-18,23),i(12-18)")
+ << (SignalList() << Move(12, 18, 23) << Insert(12, 18))
+ << (SignalList() << Insert(12, 18) << Move(18, 24, 29));
+ QTest::newRow("m(12-18,23),i(10-14)")
+ << (SignalList() << Move(12, 18, 23) << Insert(10, 14))
+ << (SignalList() << Insert(10, 14) << Move(16, 22, 27));
+ QTest::newRow("m(12-18,23),i(16-20)")
+ << (SignalList() << Move(12, 18, 23) << Insert(16, 20))
+ << (SignalList() << Insert(22, 26) << Move(12, 18, 27));
+ QTest::newRow("m(12-18,23),i(13-17)")
+ << (SignalList() << Move(12, 18, 23) << Insert(13, 17))
+ << (SignalList() << Insert(19, 23) << Move(12, 18, 27));
+ QTest::newRow("m(12-18,23),i(14-18)")
+ << (SignalList() << Move(12, 18, 23) << Insert(14, 18))
+ << (SignalList() << Insert(20, 24) << Move(12, 18, 27));
+ QTest::newRow("m(12-18,23),i(12-16)")
+ << (SignalList() << Move(12, 18, 23) << Insert(12, 16))
+ << (SignalList() << Insert(12, 16) << Move(16, 22, 27));
+ QTest::newRow("m(12-18,23),i(11-19)")
+ << (SignalList() << Move(12, 18, 23) << Insert(11, 19))
+ << (SignalList() << Insert(11, 19) << Move(20, 26, 31));
+ QTest::newRow("m(12-18,23),i(8-12)")
+ << (SignalList() << Move(12, 18, 23) << Insert(8, 12))
+ << (SignalList() << Insert(8, 12) << Move(16, 22, 27));
+ QTest::newRow("m(12-18,23),i(2-6)")
+ << (SignalList() << Move(12, 18, 23) << Insert(2, 6))
+ << (SignalList() << Insert(2, 6) << Move(16, 22, 27));
+ QTest::newRow("m(12-18,23),i(18-22)")
+ << (SignalList() << Move(12, 18, 23) << Insert(18, 22))
+ << (SignalList() << Insert(24, 28) << Move(12, 18, 27));
+ QTest::newRow("m(12-18,23),i(20-24)")
+ << (SignalList() << Move(12, 18, 23) << Insert(20, 24))
+ << (SignalList() << Insert(26, 30) << Move(12, 18, 27));
+
+ // Move, then remove
+ QTest::newRow("m(12-18,5),r(12-18)")
+ << (SignalList() << Move(12, 18, 5) << Remove(12, 18))
+ << (SignalList() << Remove(6, 12) << Move(6, 12, 5));
+ QTest::newRow("m(12-18,5),r(10-14)")
+ << (SignalList() << Move(12, 18, 5) << Remove(10, 14))
+ << (SignalList() << Remove(5, 8) << Remove(14, 15) << Move(9, 14, 5));
+ QTest::newRow("m(12-18,5),r(16-20)")
+ << (SignalList() << Move(12, 18, 5) << Remove(16, 20))
+ << (SignalList() << Remove(10, 12) << Remove(16, 18) << Move(10, 16, 5));
+ QTest::newRow("m(12-18,5),r(13-17)")
+ << (SignalList() << Move(12, 18, 5) << Remove(13, 17))
+ << (SignalList() << Remove(7, 11) << Move(8, 14, 5));
+ QTest::newRow("m(12-18,5),r(14-18)")
+ << (SignalList() << Move(12, 18, 5) << Remove(14, 18))
+ << (SignalList() << Remove(8, 12) << Move(8, 14, 5));
+ QTest::newRow("m(12-18,5),r(12-16)")
+ << (SignalList() << Move(12, 18, 5) << Remove(12, 16))
+ << (SignalList() << Remove(6, 10) << Move(8, 14, 5));
+ QTest::newRow("m(12-18,5),r(11-19)")
+ << (SignalList() << Move(12, 18, 5) << Remove(11, 19))
+ << (SignalList() << Remove(5, 12) << Remove(11, 12));
+ QTest::newRow("m(12-18,5),r(8-12)")
+ << (SignalList() << Move(12, 18, 5) << Remove(8, 12))
+ << (SignalList() << Remove(5, 6) << Remove(14, 17) << Move(11, 14, 5));
+ QTest::newRow("m(12-18,5),r(2-6)")
+ << (SignalList() << Move(12, 18, 5) << Remove(2, 6))
+ << (SignalList() << Remove(2, 5) << Remove(9, 10) << Move(9, 14, 2));
+ QTest::newRow("m(12-18,5),r(6-10)")
+ << (SignalList() << Move(12, 18, 5) << Remove(6, 10))
+ << (SignalList() << Remove(13, 17) << Move(12, 14, 5));
+ QTest::newRow("m(12-18,5),r(18-22)")
+ << (SignalList() << Move(12, 18, 5) << Remove(18, 22))
+ << (SignalList() << Remove(18, 22) << Move(12, 18, 5));
+ QTest::newRow("m(12-18,5),r(20-24)")
+ << (SignalList() << Move(12, 18, 5) << Remove(20, 24))
+ << (SignalList() << Remove(20, 24) << Move(12, 18, 5));
+
+ QTest::newRow("m(12-18,23),r(12-18)")
+ << (SignalList() << Move(12, 18, 23) << Remove(12, 18))
+ << (SignalList() << Remove(18, 24) << Move(12, 18, 17));
+ QTest::newRow("m(12-18,23),r(10-14)")
+ << (SignalList() << Move(12, 18, 23) << Remove(10, 14))
+ << (SignalList() << Remove(10, 12) << Remove(16, 18) << Move(10, 16, 19));
+ QTest::newRow("m(12-18,23),r(16-20)")
+ << (SignalList() << Move(12, 18, 23) << Remove(16, 20))
+ << (SignalList() << Remove(22, 26) << Move(12, 18, 19));
+ QTest::newRow("m(12-18,23),r(13-17)")
+ << (SignalList() << Move(12, 18, 23) << Remove(13, 17))
+ << (SignalList() << Remove(19, 23) << Move(12, 18, 19));
+ QTest::newRow("m(12-18,23),r(14-18)")
+ << (SignalList() << Move(12, 18, 23) << Remove(14, 18))
+ << (SignalList() << Remove(20, 24) << Move(12, 18, 19));
+ QTest::newRow("m(12-18,23),r(12-16)")
+ << (SignalList() << Move(12, 18, 23) << Remove(12, 16))
+ << (SignalList() << Remove(18, 22) << Move(12, 18, 19));
+ QTest::newRow("m(12-18,23),r(11-19)")
+ << (SignalList() << Move(12, 18, 23) << Remove(11, 19))
+ << (SignalList() << Remove(11, 12) << Remove(17, 24) << Move(11, 17, 15));
+ QTest::newRow("m(12-18,23),r(8-12)")
+ << (SignalList() << Move(12, 18, 23) << Remove(8, 12))
+ << (SignalList() << Remove(8, 12) << Move(8, 14, 19));
+ QTest::newRow("m(12-18,23),r(2-6)")
+ << (SignalList() << Move(12, 18, 23) << Remove(2, 6))
+ << (SignalList() << Remove(2, 6) << Move(8, 14, 19));
+ QTest::newRow("m(12-18,23),r(18-22)")
+ << (SignalList() << Move(12, 18, 23) << Remove(18, 22))
+ << (SignalList() << Remove(24, 28) << Move(12, 18, 19));
+ QTest::newRow("m(12-18,23),r(20-24)")
+ << (SignalList() << Move(12, 18, 23) << Remove(20, 24))
+ << (SignalList() << Remove(12, 13) << Remove(25, 28) << Move(12, 17, 20));
+}
+
+void tst_qdeclarativemodelchange::sequence()
+{
+ QFETCH(SignalList, input);
+ QFETCH(SignalList, output);
+
+ QDeclarativeChangeSet set;
+
+ foreach (const Signal &signal, input) {
+ if (signal.isRemove())
+ set.insertRemove(signal.start, signal.end);
+ else if (signal.isInsert())
+ set.insertInsert(signal.start, signal.end);
+ else if (signal.isMove())
+ set.insertMove(signal.start, signal.end, signal.to);
+ else if (signal.isChange())
+ set.insertChange(signal.start, signal.end);
+ }
+
+ SignalList changes;
+ foreach (const QDeclarativeChangeSet::Remove &remove, set.removes())
+ changes << Remove(remove.start, remove.end);
+ foreach (const QDeclarativeChangeSet::Insert &insert, set.inserts())
+ changes << Insert(insert.start, insert.end);
+ foreach (const QDeclarativeChangeSet::Move &move, set.moves())
+ changes << Move(move.start, move.end, move.to);
+ foreach (const QDeclarativeChangeSet::Change &change, set.changes())
+ changes << Change(change.start, change.end);
+
+#ifdef VERIFY_EXPECTED_OUTPUT
+ QVector<int> list;
+ for (int i = 0; i < 40; ++i)
+ list.append(i);
+ QVector<int> inputList = applyChanges(list, input);
+ QVector<int> outputList = applyChanges(list, output);
+ if (outputList != inputList /* || changes != output*/) {
+ qDebug() << input;
+ qDebug() << output;
+ qDebug() << changes;
+ qDebug() << inputList;
+ qDebug() << outputList;
+ } else if (changes != output) {
+ qDebug() << output;
+ qDebug() << changes;
+ }
+ QCOMPARE(outputList, inputList);
+#else
+
+ if (changes != output) {
+ qDebug() << output;
+ qDebug() << changes;
+ }
+
+#endif
+
+ QCOMPARE(changes, output);
+}
+
+
+QTEST_MAIN(tst_qdeclarativemodelchange)
+
+#include "tst_qdeclarativechangeset.moc"
diff --git a/tests/auto/declarative/qdeclarativetranslation/data/idtranslation.qml b/tests/auto/declarative/qdeclarativetranslation/data/idtranslation.qml
new file mode 100644
index 0000000000..4a5498281a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/data/idtranslation.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+QtObject {
+ property string _idTranslation2: QT_TRID_NOOP("qtn_hello_world")
+ property string idTranslation: qsTrId("qtn_hello_world")
+ property string idTranslation2: qsTrId(_idTranslation2)
+}
diff --git a/tests/auto/declarative/qdeclarativetranslation/data/qml_fr.qm b/tests/auto/declarative/qdeclarativetranslation/data/qml_fr.qm
new file mode 100644
index 0000000000..252022515a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/data/qml_fr.qm
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativetranslation/data/qml_fr.ts b/tests/auto/declarative/qdeclarativetranslation/data/qml_fr.ts
new file mode 100644
index 0000000000..b003e239bc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/data/qml_fr.ts
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr" sourcelanguage="en">
+<context>
+ <name>CustomContext</name>
+ <message>
+ <location filename="translation.qml" line="5"/>
+ <location filename="translation.qml" line="11"/>
+ <source>goodbye</source>
+ <translation>au revoir</translation>
+ </message>
+ <message>
+ <location filename="translation.qml" line="8"/>
+ <source>see ya</source>
+ <comment>informal &apos;goodbye&apos;</comment>
+ <translation>à plus tard</translation>
+ </message>
+</context>
+<context>
+ <name>translation</name>
+ <message>
+ <location filename="translation.qml" line="4"/>
+ <location filename="translation.qml" line="10"/>
+ <source>hello</source>
+ <translation>bonjour</translation>
+ </message>
+ <message>
+ <location filename="translation.qml" line="7"/>
+ <source>hi</source>
+ <comment>informal &apos;hello&apos;</comment>
+ <translation>salut</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="translation.qml" line="15"/>
+ <location filename="translation.qml" line="16"/>
+ <source>%n duck(s)</source>
+ <translation>
+ <numerusform>%n canard</numerusform>
+ <numerusform>%n canards</numerusform>
+ </translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.qm b/tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.qm
new file mode 100644
index 0000000000..265164916f
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.qm
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.ts b/tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.ts
new file mode 100644
index 0000000000..bff39b80b6
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/data/qmlid_fr.ts
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fr">
+<context>
+ <name></name>
+ <message id="qtn_hello_world">
+ <location filename="idtranslation.qml" line="4"/>
+ <location filename="idtranslation.qml" line="5"/>
+ <source></source>
+ <translation>bonjour tout le monde</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/declarative/qdeclarativetranslation/data/translation.qml b/tests/auto/declarative/qdeclarativetranslation/data/translation.qml
new file mode 100644
index 0000000000..89db1d2262
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/data/translation.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.0
+
+QtObject {
+ property string basic: qsTr("hello")
+ property string basic2: qsTranslate("CustomContext", "goodbye")
+
+ property string disambiguation: qsTr("hi", "informal 'hello'")
+ property string disambiguation2: qsTranslate("CustomContext", "see ya", "informal 'goodbye'")
+
+ property string _noop: QT_TR_NOOP("hello")
+ property string _noop2: QT_TRANSLATE_NOOP("CustomContext", "goodbye")
+ property string noop: qsTr(_noop)
+ property string noop2: qsTranslate("CustomContext", _noop2)
+
+ property string singular: qsTr("%n duck(s)", "", 1)
+ property string plural: qsTr("%n duck(s)", "", 2)
+}
diff --git a/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro b/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro
new file mode 100644
index 0000000000..c970a0c70e
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/qdeclarativetranslation.pro
@@ -0,0 +1,17 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativetranslation.cpp
+
+symbian: {
+ importFiles.files = data
+ importFiles.path = .
+ DEPLOYMENT += importFiles
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
+CONFIG += parallel_test
+
+QT += core-private gui-private declarative-private
diff --git a/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp b/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp
new file mode 100644
index 0000000000..5b88b548c9
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+#include <QDeclarativeEngine>
+#include <QDeclarativeComponent>
+#include <QTranslator>
+#include <QDebug>
+
+#ifdef Q_OS_SYMBIAN
+// In Symbian OS test data is located in applications private dir
+#define SRCDIR "."
+#endif
+
+class tst_qdeclarativetranslation : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qdeclarativetranslation() {}
+
+private slots:
+ void translation();
+ void idTranslation();
+};
+
+inline QUrl TEST_FILE(const QString &filename)
+{
+ return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
+}
+
+void tst_qdeclarativetranslation::translation()
+{
+ QTranslator translator;
+ translator.load(QLatin1String("qml_fr"), QLatin1String(SRCDIR) + QLatin1String("/data"));
+ QApplication::installTranslator(&translator);
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, TEST_FILE("translation.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("basic").toString(), QLatin1String("bonjour"));
+ QCOMPARE(object->property("basic2").toString(), QLatin1String("au revoir"));
+ QCOMPARE(object->property("disambiguation").toString(), QLatin1String("salut"));
+ QCOMPARE(object->property("disambiguation2").toString(), QString::fromUtf8("\xc3\xa0 plus tard"));
+ QCOMPARE(object->property("noop").toString(), QLatin1String("bonjour"));
+ QCOMPARE(object->property("noop2").toString(), QLatin1String("au revoir"));
+ QCOMPARE(object->property("singular").toString(), QLatin1String("1 canard"));
+ QCOMPARE(object->property("plural").toString(), QLatin1String("2 canards"));
+
+ QApplication::removeTranslator(&translator);
+ delete object;
+}
+
+void tst_qdeclarativetranslation::idTranslation()
+{
+ QTranslator translator;
+ translator.load(QLatin1String("qmlid_fr"), QLatin1String(SRCDIR) + QLatin1String("/data"));
+ QApplication::installTranslator(&translator);
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, TEST_FILE("idtranslation.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("idTranslation").toString(), QLatin1String("bonjour tout le monde"));
+ QCOMPARE(object->property("idTranslation2").toString(), QLatin1String("bonjour tout le monde"));
+
+ QApplication::removeTranslator(&translator);
+ delete object;
+}
+
+QTEST_MAIN(tst_qdeclarativetranslation)
+
+#include "tst_qdeclarativetranslation.moc"
diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData.qml b/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData.qml
index c98555cd2f..442932be26 100644
--- a/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData.qml
+++ b/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData.qml
@@ -14,7 +14,7 @@ QtObject {
// Test to the end
x.onreadystatechange = function() {
if (x.readyState == XMLHttpRequest.DONE) {
- if (reqType == "HEAD")
+ if (reqType == "HEAD" || reqType == "DELETE")
dataOK = (x.responseText == "");
else
dataOK = (x.responseText == "QML Rocks!\n");
diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_DELETE.expect b/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_DELETE.expect
new file mode 100644
index 0000000000..b2d177aa20
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_DELETE.expect
@@ -0,0 +1,7 @@
+DELETE /testdocument.html HTTP/1.1
+ACCEPT-LANGUAGE: en-US
+Connection: Keep-Alive
+Accept-Encoding: gzip
+User-Agent: Mozilla/5.0
+Host: 127.0.0.1:14445
+
diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_PUT.expect b/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_HEAD.expect
index 74a979817d..74a979817d 100644
--- a/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_PUT.expect
+++ b/tests/auto/declarative/qdeclarativexmlhttprequest/data/send_ignoreData_HEAD.expect
diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp b/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp
index de16cf41f5..aad68c5926 100644
--- a/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp
+++ b/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp
@@ -497,7 +497,7 @@ void tst_qdeclarativexmlhttprequest::send_alreadySent()
delete object;
}
-// Test that send for a GET or HEAD ignores data
+// Test that sends for GET, HEAD and DELETE ignore data
void tst_qdeclarativexmlhttprequest::send_ignoreData()
{
{
@@ -522,7 +522,7 @@ void tst_qdeclarativexmlhttprequest::send_ignoreData()
{
TestHTTPServer server(SERVER_PORT);
QVERIFY(server.isValid());
- QVERIFY(server.wait(TEST_FILE("send_ignoreData_PUT.expect"),
+ QVERIFY(server.wait(TEST_FILE("send_ignoreData_HEAD.expect"),
TEST_FILE("send_ignoreData.reply"),
QUrl()));
@@ -537,6 +537,25 @@ void tst_qdeclarativexmlhttprequest::send_ignoreData()
delete object;
}
+
+ {
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ QVERIFY(server.wait(TEST_FILE("send_ignoreData_DELETE.expect"),
+ TEST_FILE("send_ignoreData.reply"),
+ QUrl()));
+
+ QDeclarativeComponent component(&engine, TEST_FILE("send_ignoreData.qml"));
+ QObject *object = component.beginCreate(engine.rootContext());
+ QVERIFY(object != 0);
+ object->setProperty("reqType", "DELETE");
+ object->setProperty("url", "http://127.0.0.1:14445/testdocument.html");
+ component.completeCreate();
+
+ QTRY_VERIFY(object->property("dataOK").toBool() == true);
+
+ delete object;
+ }
}
// Test that send()'ing data works
diff --git a/tests/benchmarks/declarative/binding/tst_binding.cpp b/tests/benchmarks/declarative/binding/tst_binding.cpp
index 5dce36d31d..70796f682a 100644
--- a/tests/benchmarks/declarative/binding/tst_binding.cpp
+++ b/tests/benchmarks/declarative/binding/tst_binding.cpp
@@ -186,7 +186,8 @@ void tst_binding::creation()
COMPONENT(file, binding);
QBENCHMARK {
- c.create();
+ QObject *o = c.create();
+ delete o;
}
}