aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-03-13 15:06:40 +1000
committerMatthew Vogt <matthew.vogt@nokia.com>2012-03-13 15:22:14 +1000
commit784555f3032194a8923d804a8ce84957f113caf6 (patch)
tree6b538cea5bf82bd5288ac180125abd1bb312ddad /src
parent1f52c5430144eb7ba6baa7e3954675ca0707b947 (diff)
parent648c80c4c0759efb6e35fac7acc8daad5aab13e2 (diff)
Merge branch 'master' of git://gitorious.org/qt/qtdeclarative into merge-master
Diffstat (limited to 'src')
-rw-r--r--src/imports/testlib/SignalSpy.qml4
-rw-r--r--src/plugins/accessible/quick/qaccessiblequickitem.cpp2
-rw-r--r--src/plugins/accessible/quick/qaccessiblequickview.cpp5
-rw-r--r--src/qml/animations/qabstractanimationjob.cpp15
-rw-r--r--src/qml/qml/qqmlcomponent_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype_p.h1
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp38
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp46
-rw-r--r--src/qml/qml/v4/qv4instruction.cpp12
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h4
-rw-r--r--src/qml/qml/v4/qv4ir.cpp12
-rw-r--r--src/qml/qml/v4/qv4ir_p.h4
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp7
-rw-r--r--src/qmltest/qmltest.pro3
-rw-r--r--src/qmltest/quicktest.cpp95
-rw-r--r--src/qmltest/quicktestevent.cpp35
-rw-r--r--src/qmltest/quicktestresult.cpp18
-rw-r--r--src/quick/items/qquickcanvas.cpp24
-rw-r--r--src/quick/items/qquickflickable.cpp22
-rw-r--r--src/quick/items/qquickitem.cpp13
-rw-r--r--src/quick/items/qquickitemview.cpp5
-rw-r--r--src/quick/items/qquickitemviewtransition.cpp86
-rw-r--r--src/quick/items/qquickitemviewtransition_p.h8
-rw-r--r--src/quick/items/qquickpathview.cpp4
-rw-r--r--src/quick/items/qquickpathview_p_p.h3
-rw-r--r--src/quick/items/qquickrepeater.cpp10
-rw-r--r--src/quick/items/qquickrepeater_p_p.h2
-rw-r--r--src/quick/util/qquickchangeset_p.h5
-rw-r--r--src/quick/util/qquicklistcompositor_p.h4
29 files changed, 322 insertions, 167 deletions
diff --git a/src/imports/testlib/SignalSpy.qml b/src/imports/testlib/SignalSpy.qml
index 8b74132806..539cb178f5 100644
--- a/src/imports/testlib/SignalSpy.qml
+++ b/src/imports/testlib/SignalSpy.qml
@@ -92,7 +92,9 @@ Item {
function qtest_update() {
if (qtest_prevTarget != null) {
- qtest_prevTarget[qtest_prevSignalName].disconnect(spy, "qtest_activated")
+ var prevFunc = qtest_prevTarget[qtest_prevSignalName]
+ if (prevFunc)
+ prevFunc.disconnect(spy.qtest_activated)
qtest_prevTarget = null
qtest_prevSignalName = ""
}
diff --git a/src/plugins/accessible/quick/qaccessiblequickitem.cpp b/src/plugins/accessible/quick/qaccessiblequickitem.cpp
index 6c13377b3f..45db9fa795 100644
--- a/src/plugins/accessible/quick/qaccessiblequickitem.cpp
+++ b/src/plugins/accessible/quick/qaccessiblequickitem.cpp
@@ -95,7 +95,7 @@ QAccessibleInterface *QAccessibleQuickItem::parent() const
// QQuickView::declarativeRoot. The former is the true root item,
// but is not a part of the accessibility tree. Check if we hit
// it here and return an interface for the scene instead.
- if (parent == canvas->rootItem()) {
+ if (canvas && (parent == canvas->rootItem())) {
return QAccessible::queryAccessibleInterface(canvas);
} else {
return QAccessible::queryAccessibleInterface(parent);
diff --git a/src/plugins/accessible/quick/qaccessiblequickview.cpp b/src/plugins/accessible/quick/qaccessiblequickview.cpp
index 042d8dcf06..1823dfea42 100644
--- a/src/plugins/accessible/quick/qaccessiblequickview.cpp
+++ b/src/plugins/accessible/quick/qaccessiblequickview.cpp
@@ -119,6 +119,11 @@ static QQuickItem *childAt_helper(QQuickItem *item, int x, int y)
return 0;
}
+ QScopedPointer<QAccessibleInterface> accessibleInterface(QAccessible::queryAccessibleInterface(item));
+ if (accessibleInterface->childCount() == 0) {
+ return (itemScreenRect(item).contains(x, y)) ? item : 0;
+ }
+
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp
index 2bfc66fea0..a540382847 100644
--- a/src/qml/animations/qabstractanimationjob.cpp
+++ b/src/qml/animations/qabstractanimationjob.cpp
@@ -499,8 +499,9 @@ void QAbstractAnimationJob::finished()
//TODO: update this code so it is valid to delete the animation in animationFinished
for (int i = 0; i < changeListeners.count(); ++i) {
const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
- if (change.types & QAbstractAnimationJob::Completion)
- change.listener->animationFinished(this);
+ if (change.types & QAbstractAnimationJob::Completion) {
+ RETURN_IF_DELETED(change.listener->animationFinished(this));
+ }
}
if (m_group && (duration() == -1 || loopCount() < 0)) {
@@ -513,8 +514,9 @@ void QAbstractAnimationJob::stateChanged(QAbstractAnimationJob::State newState,
{
for (int i = 0; i < changeListeners.count(); ++i) {
const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
- if (change.types & QAbstractAnimationJob::StateChange)
- change.listener->animationStateChanged(this, newState, oldState);
+ if (change.types & QAbstractAnimationJob::StateChange) {
+ RETURN_IF_DELETED(change.listener->animationStateChanged(this, newState, oldState));
+ }
}
}
@@ -523,8 +525,9 @@ void QAbstractAnimationJob::currentLoopChanged(int currentLoop)
Q_UNUSED(currentLoop);
for (int i = 0; i < changeListeners.count(); ++i) {
const QAbstractAnimationJob::ChangeListener &change = changeListeners.at(i);
- if (change.types & QAbstractAnimationJob::CurrentLoop)
- change.listener->animationCurrentLoopChanged(this);
+ if (change.types & QAbstractAnimationJob::CurrentLoop) {
+ RETURN_IF_DELETED(change.listener->animationCurrentLoopChanged(this));
+ }
}
}
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index b03dd68936..dda5bd0b71 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -62,7 +62,7 @@
#include "qqmlvme_p.h"
#include "qqmlerror.h"
#include "qqml.h"
-#include "../debugger/qqmlprofilerservice_p.h"
+#include <private/qqmlprofilerservice_p.h>
#include <QtCore/QString>
#include <QtCore/QStringList>
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index ad6a2aa055..b715d0c8f2 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -180,7 +180,6 @@ public:
int attachedPropertiesId() const;
int parserStatusCast() const;
- QVariant fromObject(QObject *) const;
const char *interfaceIId() const;
int propertyValueSourceCast() const;
int propertyValueInterceptorCast() const;
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 4fd84945fc..93c7820ca2 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -1172,6 +1172,15 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(MathCosReal, unaryop)
+ QML_V4_BEGIN_INSTR(MathAbsReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setqreal(qAbs(src.getqreal()));
+ }
+ QML_V4_END_INSTR(MathAbsReal, unaryop)
+
QML_V4_BEGIN_INSTR(MathRoundReal, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1190,6 +1199,15 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(MathFloorReal, unaryop)
+ QML_V4_BEGIN_INSTR(MathCeilReal, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) output.setUndefined();
+ else output.setint(qCeil(src.getqreal()));
+ }
+ QML_V4_END_INSTR(MathCeilReal, unaryop)
+
QML_V4_BEGIN_INSTR(MathPIReal, unaryop)
{
static const qreal qmlPI = 2.0 * qAsin(1.0);
@@ -1480,6 +1498,26 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(StrictNotEqualString, binaryop)
+ QML_V4_BEGIN_INSTR(MathMaxReal, binaryop)
+ {
+ const Register &left = registers[instr->binaryop.left];
+ const Register &right = registers[instr->binaryop.right];
+ Register &output = registers[instr->binaryop.output];
+ if (left.isUndefined() || right.isUndefined()) output.setUndefined();
+ else output.setqreal(qMax(left.getqreal(), right.getqreal()));
+ }
+ QML_V4_END_INSTR(MathMaxReal, binaryop)
+
+ QML_V4_BEGIN_INSTR(MathMinReal, binaryop)
+ {
+ const Register &left = registers[instr->binaryop.left];
+ const Register &right = registers[instr->binaryop.right];
+ Register &output = registers[instr->binaryop.output];
+ if (left.isUndefined() || right.isUndefined()) output.setUndefined();
+ else output.setqreal(qMin(left.getqreal(), right.getqreal()));
+ }
+ QML_V4_END_INSTR(MathMinReal, binaryop)
+
QML_V4_BEGIN_INSTR(NewString, construct)
{
Register &output = registers[instr->construct.reg];
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 608368afc2..620d260053 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -803,6 +803,12 @@ void QV4CompilerPrivate::visitCall(IR::Call *call)
gen(i);
} return;
+ case IR::MathAbsBuiltinFunction: {
+ Instr::MathAbsReal i;
+ i.output = i.src = currentReg;
+ gen(i);
+ } return;
+
case IR::MathRoundBultinFunction: {
Instr::MathRoundReal i;
i.output = i.src = currentReg;
@@ -815,9 +821,49 @@ void QV4CompilerPrivate::visitCall(IR::Call *call)
gen(i);
} return;
+ case IR::MathCeilBuiltinFunction: {
+ Instr::MathCeilReal i;
+ i.output = i.src = currentReg;
+ gen(i);
+ } return;
+
case IR::MathPIBuiltinConstant:
+ default:
break;
} // switch
+ } else {
+ if (name->builtin == IR::MathMaxBuiltinFunction ||
+ name->builtin == IR::MathMinBuiltinFunction) {
+
+ //only handles the most common case of exactly two arguments
+ if (call->args && call->args->next && !call->args->next->next) {
+ IR::Expr *arg1 = call->args->expr;
+ IR::Expr *arg2 = call->args->next->expr;
+
+ if (arg1 != 0 && arg1->type == IR::RealType &&
+ arg2 != 0 && arg2->type == IR::RealType) {
+
+ traceExpression(arg1, currentReg);
+ traceExpression(arg2, currentReg + 1);
+
+ if (name->builtin == IR::MathMaxBuiltinFunction) {
+ Instr::MathMaxReal i;
+ i.left = currentReg;
+ i.right = currentReg + 1;
+ i.output = currentReg;
+ gen(i);
+ return;
+ } else if (name->builtin == IR::MathMinBuiltinFunction) {
+ Instr::MathMinReal i;
+ i.left = currentReg;
+ i.right = currentReg + 1;
+ i.output = currentReg;
+ gen(i);
+ return;
+ }
+ }
+ }
+ }
}
}
diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp
index efbd2b2c1c..a392c9392c 100644
--- a/src/qml/qml/v4/qv4instruction.cpp
+++ b/src/qml/qml/v4/qv4instruction.cpp
@@ -195,12 +195,18 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::MathCosReal:
INSTR_DUMP << "\t" << "MathCosReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::MathAbsReal:
+ INSTR_DUMP << "\t" << "MathAbsReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::MathRoundReal:
INSTR_DUMP << "\t" << "MathRoundReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::MathFloorReal:
INSTR_DUMP << "\t" << "MathFloorReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::MathCeilReal:
+ INSTR_DUMP << "\t" << "MathCeilReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::MathPIReal:
INSTR_DUMP << "\t" << "MathPIReal" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -306,6 +312,12 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::StrictNotEqualString:
INSTR_DUMP << "\t" << "StrictNotEqualString" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
break;
+ case V4Instr::MathMaxReal:
+ INSTR_DUMP << "\t" << "MathMaxReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
+ case V4Instr::MathMinReal:
+ INSTR_DUMP << "\t" << "MathMinReal" << "\t" << "Input_Reg(" << i->binaryop.left << ") Input_Reg(" << i->binaryop.right << ") -> Output_Reg(" << i->binaryop.output << ")";
+ break;
case V4Instr::NewString:
INSTR_DUMP << "\t" << "NewString" << "\t\t" << "Register(" << i->construct.reg << ")";
break;
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index 964c95513f..9727c23959 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -100,8 +100,10 @@ QT_BEGIN_NAMESPACE
F(ResolveUrl, unaryop) \
F(MathSinReal, unaryop) \
F(MathCosReal, unaryop) \
+ F(MathAbsReal, unaryop) \
F(MathRoundReal, unaryop) \
F(MathFloorReal, unaryop) \
+ F(MathCeilReal, unaryop) \
F(MathPIReal, unaryop) \
F(LoadReal, real_value) \
F(LoadInt, int_value) \
@@ -137,6 +139,8 @@ QT_BEGIN_NAMESPACE
F(NotEqualString, binaryop) \
F(StrictEqualString, binaryop) \
F(StrictNotEqualString, binaryop) \
+ F(MathMaxReal, binaryop) \
+ F(MathMinReal, binaryop) \
F(NewString, construct) \
F(NewUrl, construct) \
F(CleanupRegister, cleanup) \
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index 68175d3bf4..54679c3d8c 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -219,10 +219,18 @@ void Name::init(Name *base, Type type, const QString *id, Symbol symbol, quint32
builtin = MathSinBultinFunction;
} else if (id->length() == 8 && *id == QLatin1String("Math.cos")) {
builtin = MathCosBultinFunction;
+ } else if (id->length() == 8 && *id == QLatin1String("Math.abs")) {
+ builtin = MathAbsBuiltinFunction;
} else if (id->length() == 10 && *id == QLatin1String("Math.round")) {
builtin = MathRoundBultinFunction;
} else if (id->length() == 10 && *id == QLatin1String("Math.floor")) {
builtin = MathFloorBultinFunction;
+ } else if (id->length() == 9 && *id == QLatin1String("Math.ceil")) {
+ builtin = MathCeilBuiltinFunction;
+ } else if (id->length() == 8 && *id == QLatin1String("Math.max")) {
+ builtin = MathMaxBuiltinFunction;
+ } else if (id->length() == 8 && *id == QLatin1String("Math.min")) {
+ builtin = MathMinBuiltinFunction;
} else if (id->length() == 7 && *id == QLatin1String("Math.PI")) {
builtin = MathPIBuiltinConstant;
this->type = RealType;
@@ -353,10 +361,14 @@ Type Call::typeForFunction(Expr *base)
switch (name->builtin) {
case MathSinBultinFunction:
case MathCosBultinFunction:
+ case MathAbsBuiltinFunction: //### type could also be Int if input was Int
+ case MathMaxBuiltinFunction:
+ case MathMinBuiltinFunction:
return RealType;
case MathRoundBultinFunction:
case MathFloorBultinFunction:
+ case MathCeilBuiltinFunction:
return IntType;
case NoBuiltinSymbol:
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 3d3288b65f..79f50cd6c9 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -239,6 +239,10 @@ enum BuiltinSymbol {
MathCosBultinFunction,
MathRoundBultinFunction,
MathFloorBultinFunction,
+ MathCeilBuiltinFunction,
+ MathAbsBuiltinFunction,
+ MathMaxBuiltinFunction,
+ MathMinBuiltinFunction,
MathPIBuiltinConstant
};
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 36e88e5276..06f4024423 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -628,7 +628,8 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
case IR::Name::Property:
if (baseName->type == IR::ObjectType && baseName->meta && baseName->property->isFinal()) {
- QQmlPropertyCache *cache = m_engine->cache(baseName->meta);
+ const QMetaObject *meta = m_engine->metaObjectForType(baseName->property->propType);
+ QQmlPropertyCache *cache = m_engine->cache(meta);
if (!cache)
return false;
@@ -640,9 +641,9 @@ bool QV4IRBuilder::visit(AST::FieldMemberExpression *ast)
return false; // We don't know enough about this property
}
- IR::Type irType = irTypeFromVariantType(data->propType, m_engine, baseName->meta);
+ IR::Type irType = irTypeFromVariantType(data->propType, m_engine, meta);
_expr.code = _block->SYMBOL(baseName, irType, name,
- baseName->meta, data, line, column);
+ meta, data, line, column);
}
}
break;
diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro
index d2e90c2b5d..b1c99d2739 100644
--- a/src/qmltest/qmltest.pro
+++ b/src/qmltest/qmltest.pro
@@ -7,7 +7,7 @@ CONFIG += module
CONFIG += dll warn_on declarative_debug
MODULE_PRI += ../../modules/qt_qmltest.pri
-QT += testlib-private qml testlib quick widgets widgets-private gui
+QT += testlib testlib-private qml quick gui
DEFINES += QT_BUILD_QUICK_TEST_LIB QT_NO_URL_CAST_FROM_STRING
load(qt_module_config)
@@ -34,4 +34,3 @@ HEADERS += \
DEFINES += QT_BUILD_QUICK_TEST_LIB
-
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index e6c27eec00..2e32a60b2d 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -43,14 +43,10 @@
#include "quicktestresult_p.h"
#include <QtTest/qtestsystem.h>
#include "qtestoptions_p.h"
-#include <QApplication>
#include <QtQml/qqml.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcontext.h>
-#if defined(QML_VERSION) && QML_VERSION >= 0x020000
#include <QtQuick/qquickview.h>
-#define QUICK_TEST_SCENEGRAPH 1
-#endif
#include <QtQml/qjsvalue.h>
#include <QtQml/qjsengine.h>
#include <QtGui/qopengl.h>
@@ -160,12 +156,10 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
// Look for QML-specific command-line options.
// -import dir Specify an import directory.
// -input dir Specify the input directory for test cases.
- // -qtquick1 Run with QtQuick 1 rather than QtQuick 2.
// -translation file Specify the translation file.
QStringList imports;
QString testPath;
QString translationFile;
- bool qtQuick2 = true;
int outargc = 1;
int index = 1;
while (index < argc) {
@@ -177,9 +171,6 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
index += 2;
} else if (strcmp(argv[index], "-opengl") == 0) {
++index;
- } else if (strcmp(argv[index], "-qtquick1") == 0) {
- qtQuick2 = false;
- ++index;
} else if (strcmp(argv[index], "-translation") == 0 && (index + 1) < argc) {
translationFile = stripQuotes(QString::fromLocal8Bit(argv[index + 1]));
index += 2;
@@ -255,57 +246,49 @@ int quick_test_main(int argc, char **argv, const char *name, quick_test_viewport
// Scan through all of the "tst_*.qml" files and run each of them
// in turn with a QQuickView.
-#ifdef QUICK_TEST_SCENEGRAPH
- if (qtQuick2) {
- QQuickView view;
- QTestRootObject rootobj;
- QEventLoop eventLoop;
- QObject::connect(view.engine(), SIGNAL(quit()),
- &rootobj, SLOT(quit()));
- QObject::connect(view.engine(), SIGNAL(quit()),
- &eventLoop, SLOT(quit()));
- view.rootContext()->setContextProperty
- (QLatin1String("qtest"), &rootobj);
- foreach (const QString &path, imports)
- view.engine()->addImportPath(path);
+ QQuickView view;
+ QTestRootObject rootobj;
+ QEventLoop eventLoop;
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &rootobj, SLOT(quit()));
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &eventLoop, SLOT(quit()));
+ view.rootContext()->setContextProperty
+ (QLatin1String("qtest"), &rootobj);
+ foreach (const QString &path, imports)
+ view.engine()->addImportPath(path);
- foreach (QString file, files) {
- QFileInfo fi(file);
- if (!fi.exists())
- continue;
+ foreach (QString file, files) {
+ QFileInfo fi(file);
+ if (!fi.exists())
+ continue;
- rootobj.setHasTestCase(false);
- rootobj.setWindowShown(false);
- rootobj.hasQuit = false;
- QString path = fi.absoluteFilePath();
- if (path.startsWith(QLatin1String(":/")))
- view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2)));
- else
- view.setSource(QUrl::fromLocalFile(path));
+ rootobj.setHasTestCase(false);
+ rootobj.setWindowShown(false);
+ rootobj.hasQuit = false;
+ QString path = fi.absoluteFilePath();
+ if (path.startsWith(QLatin1String(":/")))
+ view.setSource(QUrl(QLatin1String("qrc:") + path.mid(2)));
+ else
+ view.setSource(QUrl::fromLocalFile(path));
- if (QTest::printAvailableFunctions)
- continue;
- if (view.status() == QQuickView::Error) {
- handleCompileErrors(fi, view);
- continue;
- }
- if (!rootobj.hasQuit) {
- // If the test already quit, then it was performed
- // synchronously during setSource(). Otherwise it is
- // an asynchronous test and we need to show the window
- // and wait for the quit indication.
- view.show();
- QTest::qWaitForWindowShown(&view);
- rootobj.setWindowShown(true);
- if (!rootobj.hasQuit && rootobj.hasTestCase())
- eventLoop.exec();
- }
+ if (QTest::printAvailableFunctions)
+ continue;
+ if (view.status() == QQuickView::Error) {
+ handleCompileErrors(fi, view);
+ continue;
+ }
+ if (!rootobj.hasQuit) {
+ // If the test already quit, then it was performed
+ // synchronously during setSource(). Otherwise it is
+ // an asynchronous test and we need to show the window
+ // and wait for the quit indication.
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ rootobj.setWindowShown(true);
+ if (!rootobj.hasQuit && rootobj.hasTestCase())
+ eventLoop.exec();
}
- } else
-#endif
- {
- qWarning("No suitable QtQuick1 implementation is available!");
- return 1;
}
// Flush the current logging stream.
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index f996adbeca..94051711f1 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -42,12 +42,8 @@
#include "quicktestevent_p.h"
#include <QtTest/qtestkeyboard.h>
#include <QtQml/qqml.h>
-#if defined(QML_VERSION) && QML_VERSION >= 0x020000
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickcanvas.h>
-#define QUICK_TEST_SCENEGRAPH 1
-#endif
-#include <QtWidgets/qgraphicsscene.h>
QT_BEGIN_NAMESPACE
@@ -114,15 +110,9 @@ namespace QtQuickTest
}
QPoint pos;
-#ifdef QUICK_TEST_SCENEGRAPH
QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
- if (sgitem) {
+ if (sgitem)
pos = sgitem->mapToScene(_pos).toPoint();
- } else
-#endif
- {
- qWarning("No suitable QtQuick1 implementation is available!");
- }
QTEST_ASSERT(button == Qt::NoButton || button & Qt::MouseButtonMask);
QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
@@ -168,15 +158,10 @@ namespace QtQuickTest
QTest::qWait(delay);
QPoint pos;
-#ifdef QUICK_TEST_SCENEGRAPH
QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
- if (sgitem) {
+ if (sgitem)
pos = sgitem->mapToScene(_pos).toPoint();
- } else
-#endif
- {
- qWarning("No suitable QtQuick1 implementation is available!");
- }
+
QTEST_ASSERT(buttons == Qt::NoButton || buttons & Qt::MouseButtonMask);
QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask);
@@ -272,24 +257,10 @@ bool QuickTestEvent::mouseMove
QWindow *QuickTestEvent::eventWindow()
{
-#ifdef QUICK_TEST_SCENEGRAPH
QQuickItem *sgitem = qobject_cast<QQuickItem *>(parent());
if (sgitem)
return sgitem->canvas();
-#endif
return 0;
- /*
- QQuickItem *item = qobject_cast<QQuickItem *>(parent());
- if (!item)
- return 0;
- QGraphicsScene *s = item->scene();
- if (!s)
- return 0;
- QList<QGraphicsView *> views = s->views();
- if (views.isEmpty())
- return 0;
- return views.at(0)->windowHandle();
- */
}
QT_END_NAMESPACE
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index 33c5fef96a..d33eab4943 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -379,18 +379,12 @@ bool QuickTestResult::compare
const QString &val1, const QString &val2,
const QUrl &location, int line)
{
- if (success) {
- return QTestResult::compare
- (success, message.toLocal8Bit().constData(),
- qtestFixUrl(location).toLatin1().constData(), line);
- } else {
- return QTestResult::compare
- (success, message.toLocal8Bit().constData(),
- QTest::toString(val1.toLatin1().constData()),
- QTest::toString(val2.toLatin1().constData()),
- "", "",
- qtestFixUrl(location).toLatin1().constData(), line);
- }
+ return QTestResult::compare
+ (success, message.toLocal8Bit().constData(),
+ QTest::toString(val1.toLatin1().constData()),
+ QTest::toString(val2.toLatin1().constData()),
+ "", "",
+ qtestFixUrl(location).toLatin1().constData(), line);
}
void QuickTestResult::skip
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index 60f1992b57..f14eccd9a9 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -376,10 +376,8 @@ void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event)
{
if (event->type() == QEvent::TouchCancel) {
touchMouseId = -1;
- if (!mouseGrabberItem)
- return;
- mouseGrabberItem->ungrabMouse();
- mouseGrabberItem = 0;
+ if (mouseGrabberItem)
+ mouseGrabberItem->ungrabMouse();
return;
}
for (int i = 0; i < event->touchPoints().count(); ++i) {
@@ -447,7 +445,8 @@ void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event)
me.setTimestamp(event->timestamp());
me.setCapabilities(event->device()->capabilities());
deliverMouseEvent(&me);
- mouseGrabberItem = 0;
+ if (mouseGrabberItem)
+ mouseGrabberItem->ungrabMouse();
}
break;
}
@@ -947,13 +946,13 @@ bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
QMouseEvent me(event->type(), p, event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
me.accept();
- mouseGrabberItem = item;
+ item->grabMouse();
q->sendEvent(item, &me);
event->setAccepted(me.isAccepted());
if (me.isAccepted())
return true;
- mouseGrabberItem->ungrabMouse();
- mouseGrabberItem = 0;
+ if (mouseGrabberItem)
+ mouseGrabberItem->ungrabMouse();
}
}
@@ -1023,7 +1022,8 @@ void QQuickCanvas::mouseReleaseEvent(QMouseEvent *event)
}
d->deliverMouseEvent(event);
- d->mouseGrabberItem = 0;
+ if (d->mouseGrabberItem)
+ d->mouseGrabberItem->ungrabMouse();
}
/*! \reimp */
@@ -1560,6 +1560,12 @@ bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e)
QQuickItemPrivate::get(item)->deliverMouseEvent(static_cast<QMouseEvent *>(e));
}
break;
+ case QEvent::UngrabMouse:
+ if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) {
+ e->accept();
+ item->mouseUngrabEvent();
+ }
+ break;
case QEvent::Wheel:
QQuickItemPrivate::get(item)->deliverWheelEvent(static_cast<QWheelEvent *>(e));
break;
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index f75ca14989..82f674741f 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -107,7 +107,7 @@ static const int FlickThreshold = 20;
// RetainGrabVelocity is the maxmimum instantaneous velocity that
// will ensure the Flickable retains the grab on consecutive flicks.
-static const int RetainGrabVelocity = 15;
+static const int RetainGrabVelocity = 100;
QQuickFlickableVisibleArea::QQuickFlickableVisibleArea(QQuickFlickable *parent)
: QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
@@ -823,8 +823,8 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
Q_Q(QQuickFlickable);
QQuickItemPrivate::start(timer);
if (interactive && timeline.isActive()
- && (qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity
- || qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity)) {
+ && ((qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity && !hData.fixingUp && !hData.inOvershoot)
+ || (qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity && !vData.fixingUp && !vData.inOvershoot))) {
stealMouse = true; // If we've been flicked then steal the click.
int flickTime = timeline.time();
if (flickTime > 600) {
@@ -846,7 +846,10 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
}
q->setKeepMouseGrab(stealMouse);
pressed = true;
- timeline.clear();
+ if (!hData.fixingUp)
+ timeline.reset(hData.move);
+ if (!vData.fixingUp)
+ timeline.reset(vData.move);
hData.reset();
vData.reset();
hData.dragMinBound = q->minXExtent();
@@ -910,6 +913,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
}
}
if (!rejectY && stealMouse && dy != 0.0) {
+ timeline.clear();
vData.move.setValue(newY);
vMoved = true;
}
@@ -942,6 +946,7 @@ void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
}
}
if (!rejectX && stealMouse && dx != 0.0) {
+ timeline.clear();
hData.move.setValue(newX);
hMoved = true;
}
@@ -1753,6 +1758,7 @@ void QQuickFlickable::mouseUngrabEvent()
if (d->pressed) {
// if our mouse grab has been removed (probably by another Flickable),
// fix our state
+ d->clearDelayedPress();
d->pressed = false;
d->draggingEnding();
d->stealMouse = false;
@@ -1838,13 +1844,19 @@ bool QQuickFlickable::sendMouseEvent(QMouseEvent *event)
bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
Q_D(QQuickFlickable);
- if (!isVisible() || !d->interactive || !isEnabled())
+ if (!isVisible() || !isEnabled())
return QQuickItem::childMouseEventFilter(i, e);
switch (e->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
return sendMouseEvent(static_cast<QMouseEvent *>(e));
+ case QEvent::UngrabMouse:
+ if (d->canvas && d->canvas->mouseGrabberItem() && d->canvas->mouseGrabberItem() != this) {
+ // The grab has been taken away from a child and given to some other item.
+ mouseUngrabEvent();
+ }
+ break;
default:
break;
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 1af4c31d75..8e351f1527 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3040,9 +3040,8 @@ void QQuickItem::mouseReleaseEvent(QMouseEvent *event)
event->ignore();
}
-void QQuickItem::mouseDoubleClickEvent(QMouseEvent *event)
+void QQuickItem::mouseDoubleClickEvent(QMouseEvent *)
{
- mousePressEvent(event);
}
void QQuickItem::mouseUngrabEvent()
@@ -4751,8 +4750,10 @@ void QQuickItem::grabMouse()
QQuickItem *oldGrabber = canvasPriv->mouseGrabberItem;
canvasPriv->mouseGrabberItem = this;
- if (oldGrabber)
- oldGrabber->mouseUngrabEvent();
+ if (oldGrabber) {
+ QEvent ev(QEvent::UngrabMouse);
+ d->canvas->sendEvent(oldGrabber, &ev);
+ }
}
void QQuickItem::ungrabMouse()
@@ -4767,7 +4768,9 @@ void QQuickItem::ungrabMouse()
}
canvasPriv->mouseGrabberItem = 0;
- mouseUngrabEvent();
+
+ QEvent ev(QEvent::UngrabMouse);
+ d->canvas->sendEvent(this, &ev);
}
bool QQuickItem::keepMouseGrab() const
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index c6f45aaf0b..501b206ef6 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1658,10 +1658,11 @@ void QQuickItemViewPrivate::updateViewport()
{
Q_Q(QQuickItemView);
if (isValid()) {
+ qreal extra = headerSize() + footerSize();
if (layoutOrientation() == Qt::Vertical)
- q->setContentHeight(endPosition() - startPosition());
+ q->setContentHeight(endPosition() - startPosition() + extra);
else
- q->setContentWidth(endPosition() - startPosition());
+ q->setContentWidth(endPosition() - startPosition() + extra);
}
}
diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp
index d9dce49349..823269bfc1 100644
--- a/src/quick/items/qquickitemviewtransition.cpp
+++ b/src/quick/items/qquickitemviewtransition.cpp
@@ -333,6 +333,8 @@ QQuickItemViewTransitionableItem::QQuickItemViewTransitionableItem(QQuickItem *i
, nextTransitionType(QQuickItemViewTransitioner::NoTransition)
, isTransitionTarget(false)
, nextTransitionToSet(false)
+ , nextTransitionFromSet(false)
+ , lastMovedToSet(false)
, prepared(false)
{
}
@@ -367,12 +369,17 @@ qreal QQuickItemViewTransitionableItem::itemY() const
void QQuickItemViewTransitionableItem::moveTo(const QPointF &pos, bool immediate)
{
+ if (!nextTransitionFromSet && nextTransitionType != QQuickItemViewTransitioner::NoTransition) {
+ nextTransitionFrom = item->pos();
+ nextTransitionFromSet = true;
+ }
+
+ lastMovedTo = pos;
+ lastMovedToSet = true;
+
if (immediate || !transitionScheduledOrRunning()) {
- if (immediate) {
- if (transition)
- transition->cancel();
- resetTransitionData();
- }
+ if (immediate)
+ stopTransition();
item->setPos(pos);
} else {
nextTransitionTo = pos;
@@ -402,17 +409,27 @@ bool QQuickItemViewTransitionableItem::isPendingRemoval() const
bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds)
{
- bool doTransition = false;
+ if (nextTransitionType == QQuickItemViewTransitioner::NoTransition)
+ return false;
+
+ if (isTransitionTarget) {
+ // If item is not already moving somewhere, set it to not move anywhere.
+ // This ensures that removed targets don't transition to the default (0,0) and that
+ // items set for other transition types only transition if they actually move somewhere.
+ if (!nextTransitionToSet)
+ moveTo(item->pos());
+ } else {
+ // don't start displaced transitions that don't move anywhere
+ if (!nextTransitionToSet || (nextTransitionFromSet && nextTransitionFrom == nextTransitionTo)) {
+ clearCurrentScheduledTransition();
+ return false;
+ }
+ }
- // If item is not already moving somewhere, set it to not move anywhere.
- // This ensures that removed targets don't transition to the default (0,0) and that
- // items set for other transition types only transition if they actually move somewhere.
- if (nextTransitionType != QQuickItemViewTransitioner::NoTransition && !nextTransitionToSet)
- moveTo(item->pos());
+ bool doTransition = false;
// For move transitions (both target and displaced) and displaced transitions of other
// types, only run the transition if the item is actually moving to another position.
-
switch (nextTransitionType) {
case QQuickItemViewTransitioner::NoTransition:
{
@@ -465,10 +482,8 @@ bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitio
if (!doTransition) {
// if transition type is not valid, the previous transition still has to be
// canceled so that the item can move immediately to the right position
- if (transition)
- transition->cancel();
item->setPos(nextTransitionTo);
- resetTransitionData();
+ stopTransition();
}
prepared = true;
@@ -490,14 +505,8 @@ void QQuickItemViewTransitionableItem::startTransition(QQuickItemViewTransitione
transition = new QQuickItemViewTransitionJob;
}
- // if item is not already moving somewhere, set it to not move anywhere
- // so that removed items do not move to the default (0,0)
- if (!nextTransitionToSet)
- moveTo(item->pos());
-
transition->startTransition(this, index, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget);
- nextTransitionType = QQuickItemViewTransitioner::NoTransition;
- prepared = false;
+ clearCurrentScheduledTransition();
}
void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem)
@@ -507,27 +516,50 @@ void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitio
// to calculate positions for transitions for other items in the view.
nextTransitionType = type;
isTransitionTarget = isTargetItem;
+
+ if (!nextTransitionFromSet && lastMovedToSet) {
+ nextTransitionFrom = lastMovedTo;
+ nextTransitionFromSet = true;
+ }
}
bool QQuickItemViewTransitionableItem::transitionWillChangePosition() const
{
if (transitionRunning() && transition->m_toPos != nextTransitionTo)
return true;
- return nextTransitionTo != item->pos();
+ if (!nextTransitionFromSet)
+ return false;
+ return nextTransitionTo != nextTransitionFrom;
}
-void QQuickItemViewTransitionableItem::finishedTransition()
+void QQuickItemViewTransitionableItem::resetNextTransitionPos()
{
nextTransitionToSet = false;
nextTransitionTo = QPointF();
}
-void QQuickItemViewTransitionableItem::resetTransitionData()
+void QQuickItemViewTransitionableItem::finishedTransition()
+{
+ resetNextTransitionPos();
+}
+
+void QQuickItemViewTransitionableItem::clearCurrentScheduledTransition()
{
+ // Just clear the current scheduled transition - don't touch the nextTransitionTo
+ // which may have already been set for a previously scheduled transition
+
nextTransitionType = QQuickItemViewTransitioner::NoTransition;
isTransitionTarget = false;
- nextTransitionTo = QPointF();
- nextTransitionToSet = false;
+ prepared = false;
+ nextTransitionFromSet = false;
+}
+
+void QQuickItemViewTransitionableItem::stopTransition()
+{
+ if (transition)
+ transition->cancel();
+ clearCurrentScheduledTransition();
+ resetNextTransitionPos();
}
diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h
index a4babdca05..9e17385c46 100644
--- a/src/quick/items/qquickitemviewtransition_p.h
+++ b/src/quick/items/qquickitemviewtransition_p.h
@@ -142,11 +142,15 @@ public:
void startTransition(QQuickItemViewTransitioner *transitioner, int index);
QPointF nextTransitionTo;
+ QPointF lastMovedTo;
+ QPointF nextTransitionFrom;
QQuickItem *item;
QQuickItemViewTransitionJob *transition;
QQuickItemViewTransitioner::TransitionType nextTransitionType;
bool isTransitionTarget;
bool nextTransitionToSet;
+ bool nextTransitionFromSet;
+ bool lastMovedToSet;
bool prepared;
private:
@@ -155,7 +159,9 @@ private:
void setNextTransition(QQuickItemViewTransitioner::TransitionType, bool isTargetItem);
bool transitionWillChangePosition() const;
void finishedTransition();
- void resetTransitionData();
+ void resetNextTransitionPos();
+ void clearCurrentScheduledTransition();
+ void stopTransition();
};
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index f8098c8f65..0526187531 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1224,7 +1224,8 @@ void QQuickPathViewPrivate::handleMousePressEvent(QMouseEvent *event)
return;
}
- if (tl.isActive() && flicking)
+
+ if (tl.isActive() && flicking && flickDuration && qreal(tl.time())/flickDuration < 0.8)
stealMouse = true; // If we've been flicked then steal the click.
else
stealMouse = false;
@@ -1335,6 +1336,7 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *)
} else {
dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2.0)));
}
+ flickDuration = static_cast<int>(1000 * qAbs(velocity) / accel);
offsetAdj = 0.0;
moveOffset.setValue(offset);
tl.accel(moveOffset, velocity, accel, dist);
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index a80c01f320..412caa6d2b 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -81,7 +81,7 @@ public:
, autoHighlight(true), highlightUp(false), layoutScheduled(false)
, moving(false), flicking(false), requestedOnPath(false), inRequest(false)
, dragMargin(0), deceleration(100)
- , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset)
+ , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
, firstIndex(-1), pathItems(-1), requestedIndex(-1), requestedZ(0)
, moveReason(Other), moveDirection(Shortest), attType(0), highlightComponent(0), highlightItem(0)
, moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
@@ -171,6 +171,7 @@ public:
qreal deceleration;
QQuickTimeLine tl;
QQuickTimeLineValueProxy<QQuickPathViewPrivate> moveOffset;
+ int flickDuration;
int firstIndex;
int pathItems;
int requestedIndex;
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index d26ebed85e..1f7578c583 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
QQuickRepeaterPrivate::QQuickRepeaterPrivate()
- : model(0), ownModel(false), inRequest(false), itemCount(0), createFrom(-1)
+ : model(0), ownModel(false), inRequest(false), dataSourceIsObject(false), itemCount(0), createFrom(-1)
{
}
@@ -175,6 +175,12 @@ QQuickRepeater::~QQuickRepeater()
QVariant QQuickRepeater::model() const
{
Q_D(const QQuickRepeater);
+
+ if (d->dataSourceIsObject) {
+ QObject *o = d->dataSourceAsObject;
+ return QVariant::fromValue(o);
+ }
+
return d->dataSource;
}
@@ -194,6 +200,8 @@ void QQuickRepeater::setModel(const QVariant &model)
}
d->dataSource = model;
QObject *object = qvariant_cast<QObject*>(model);
+ d->dataSourceAsObject = object;
+ d->dataSourceIsObject = object != 0;
QQuickVisualModel *vim = 0;
if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) {
if (d->ownModel) {
diff --git a/src/quick/items/qquickrepeater_p_p.h b/src/quick/items/qquickrepeater_p_p.h
index 88e0c94218..41d77ad977 100644
--- a/src/quick/items/qquickrepeater_p_p.h
+++ b/src/quick/items/qquickrepeater_p_p.h
@@ -75,8 +75,10 @@ private:
QQuickVisualModel *model;
QVariant dataSource;
+ QQmlGuard<QObject> dataSourceAsObject;
bool ownModel : 1;
bool inRequest : 1;
+ bool dataSourceIsObject : 1;
int itemCount;
int createFrom;
diff --git a/src/quick/util/qquickchangeset_p.h b/src/quick/util/qquickchangeset_p.h
index 64179666c7..04a1e77c24 100644
--- a/src/quick/util/qquickchangeset_p.h
+++ b/src/quick/util/qquickchangeset_p.h
@@ -152,6 +152,11 @@ private:
int m_difference;
};
+Q_DECLARE_TYPEINFO(QQuickChangeSet::Change, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQuickChangeSet::Remove, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQuickChangeSet::Insert, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQuickChangeSet::MoveKey, Q_PRIMITIVE_TYPE);
+
inline uint qHash(const QQuickChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); }
inline bool operator ==(const QQuickChangeSet::MoveKey &l, const QQuickChangeSet::MoveKey &r) {
return l.moveId == r.moveId && l.offset == r.offset; }
diff --git a/src/quick/util/qquicklistcompositor_p.h b/src/quick/util/qquicklistcompositor_p.h
index b12ee8025f..5c9d679fa4 100644
--- a/src/quick/util/qquicklistcompositor_p.h
+++ b/src/quick/util/qquicklistcompositor_p.h
@@ -317,6 +317,10 @@ private:
friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor &list);
};
+Q_DECLARE_TYPEINFO(QQuickListCompositor::Change, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQuickListCompositor::Remove, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QQuickListCompositor::Insert, Q_PRIMITIVE_TYPE);
+
inline QQuickListCompositor::iterator::iterator()
: range(0), offset(0), group(Default), groupCount(0) {}
inline QQuickListCompositor::iterator::iterator(const iterator &it)