From 9d9161446bfad883c298d54a122e822c5e273a9c Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 8 Apr 2010 10:21:46 +1000 Subject: Support QList properties We already supported returning QList from methods, but there wasn't really much that could be done with the return value. This closes the loop on QList support by allowing them to be properties, and used as models. --- src/declarative/qml/qdeclarativebinding.cpp | 24 +++++-- src/declarative/qml/qdeclarativeengine.cpp | 34 +++++++--- src/declarative/qml/qdeclarativeengine_p.h | 2 +- src/declarative/qml/qdeclarativeexpression.cpp | 66 +++++++------------ src/declarative/qml/qdeclarativeexpression_p.h | 4 +- .../qml/qdeclarativeobjectscriptclass.cpp | 22 +++---- src/declarative/qml/qdeclarativeproperty.cpp | 15 +++++ src/declarative/util/qdeclarativelistaccessor.cpp | 6 ++ src/declarative/util/qdeclarativelistaccessor_p.h | 2 +- .../data/qlistOfQObjects.1.qml | 16 +++++ .../data/qlistOfQObjects.2.qml | 17 +++++ .../data/qlistOfQObjects.3.qml | 21 ++++++ .../data/qlistOfQObjects.4.qml | 22 +++++++ .../data/qlistOfQObjects.5.qml | 35 ++++++++++ .../declarative/qdeclarativeecmascript/testtypes.h | 6 ++ .../tst_qdeclarativeecmascript.cpp | 75 ++++++++++++++++++++++ 16 files changed, 297 insertions(+), 70 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index 71cf3cb..bed1956 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -148,8 +148,26 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) idx, a); } else { + QDeclarativeEnginePrivate *ep = (data->context() && data->context()->engine)? + QDeclarativeEnginePrivate::get(data->context()->engine):0; + bool isUndefined = false; - QVariant value = this->value(&isUndefined); + QVariant value; + + if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) { + QScriptValue scriptValue = d->scriptValue(0, &isUndefined); + value = ep->scriptValueToVariant(scriptValue, qMetaTypeId >()); + } else { + QScriptValue scriptValue = d->scriptValue(0, &isUndefined); + value = ep->scriptValueToVariant(scriptValue); + if (value.userType() == QMetaType::QObjectStar && !qvariant_cast(value)) { + // If the object is null, we extract the predicted type. While this isn't + // 100% reliable, in many cases it gives us better error messages if we + // assign this null-object to an incompatible property + int type = ep->objectClass->objectType(scriptValue); + value = QVariant(type, (void *)0); + } + } if (isUndefined && !data->error.isValid() && data->property.isResettable()) { @@ -187,9 +205,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) } if (data->error.isValid()) { - QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)? - QDeclarativeEnginePrivate::get(data->context()->engine):0; - if (!data->addError(p)) + if (!data->addError(ep)) qWarning().nospace() << qPrintable(this->error().toString()); } else { data->removeError(); diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index e8b6913..3c66efb 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1324,7 +1324,6 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine return qScriptValueFromValue(engine, qVariantFromValue(finalColor)); } - QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val) { if (val.userType() == qMetaTypeId()) { @@ -1335,6 +1334,14 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v } else { return scriptEngine.nullValue(); } + } else if (val.userType() == qMetaTypeId >()) { + const QList &list = *(QList*)val.constData(); + QScriptValue rv = scriptEngine.newArray(list.count()); + for (int ii = 0; ii < list.count(); ++ii) { + QObject *object = list.at(ii); + rv.setProperty(ii, objectClass->newQObject(object)); + } + return rv; } bool objOk; @@ -1346,22 +1353,31 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v } } -QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val) +QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint) { QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val); if (dc == objectClass) return QVariant::fromValue(objectClass->toQObject(val)); + else if (dc == valueTypeClass) + return valueTypeClass->toVariant(val); else if (dc == contextClass) return QVariant(); - QScriptDeclarativeClass *sc = QScriptDeclarativeClass::scriptClass(val); - if (!sc) { - return val.toVariant(); - } else if (sc == valueTypeClass) { - return valueTypeClass->toVariant(val); - } else { - return QVariant(); + // Convert to a QList if val is an array and we were explicitly hinted, or + // if the first element is a QObject* + if ((hint == qMetaTypeId >() && val.isArray()) || + (val.isArray() && QScriptDeclarativeClass::scriptClass(val.property(0)) == objectClass)) { + QList list; + int length = val.property(QLatin1String("length")).toInt32(); + for (int ii = 0; ii < length; ++ii) { + QScriptValue arrayItem = val.property(ii); + QObject *d = arrayItem.toQObject(); + list << d; + } + return QVariant::fromValue(list); } + + return val.toVariant(); } // XXX this beyonds in QUrl::toLocalFile() diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 45089d0..3f22d61 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -308,7 +308,7 @@ public: QHash m_sharedScriptImports; QScriptValue scriptValueFromVariant(const QVariant &); - QVariant scriptValueToVariant(const QScriptValue &); + QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid); void sendQuit (); diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index a250f21..e0aee52 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -351,7 +351,7 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine } } -QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined) +QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool *isUndefined) { QDeclarativeExpressionData *data = this->data; QDeclarativeEngine *engine = data->context()->engine; @@ -376,7 +376,7 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo const QString code = rewriteBinding(data->expression, &ok); if (!ok) { scriptEngine->popContext(); - return QVariant(); + return QScriptValue(); } data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line); } @@ -413,54 +413,20 @@ QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bo if (scriptEngine->hasUncaughtException()) { exceptionToError(scriptEngine, data->error); scriptEngine->clearExceptions(); - return QVariant(); + return QScriptValue(); } else { data->error = QDeclarativeError(); + return svalue; } - - QVariant rv; - - if (svalue.isArray()) { - int length = svalue.property(QLatin1String("length")).toInt32(); - if (length && svalue.property(0).isObject()) { - QList list; - for (int ii = 0; ii < length; ++ii) { - QScriptValue arrayItem = svalue.property(ii); - QObject *d = arrayItem.toQObject(); - list << d; - } - rv = QVariant::fromValue(list); - } - } else if (svalue.isObject() && - ep->objectClass->scriptClass(svalue) == ep->objectClass) { - QObject *o = svalue.toQObject(); - int type = QMetaType::QObjectStar; - // If the object is null, we extract the predicted type. While this isn't - // 100% reliable, in many cases it gives us better error messages if we - // assign this null-object to an incompatible property - if (!o) type = ep->objectClass->objectType(svalue); - - return QVariant(type, &o); - } - - if (rv.isNull()) - rv = svalue.toVariant(); - - return rv; } -QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) +QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined) { Q_Q(QDeclarativeExpression); - - QVariant rv; - if (!q->engine()) { - qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context"); - return rv; - } + Q_ASSERT(q->engine()); if (data->expression.isEmpty()) - return rv; + return QScriptValue(); QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); @@ -476,7 +442,7 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU QDeclarativeExpressionData *localData = data; localData->addref(); - rv = evalQtScript(secondaryScope, isUndefined); + QScriptValue value = eval(secondaryScope, isUndefined); ep->currentExpression = lastCurrentExpression; ep->captureProperties = lastCaptureProperties; @@ -494,7 +460,21 @@ QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isU lastCapturedProperties.copyAndClear(ep->capturedProperties); - return rv; + return value; +} + +QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) +{ + Q_Q(QDeclarativeExpression); + + if (!q->engine()) { + qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context"); + return QVariant(); + } + + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); + + return ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined)); } /*! diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index 9a90fb6..1a0e4dd 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -150,7 +150,9 @@ public: QDeclarativeExpressionData *data; QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0); - QVariant evalQtScript(QObject *secondaryScope, bool *isUndefined = 0); + QScriptValue scriptValue(QObject *secondaryScope = 0, bool *isUndefined = 0); + + QScriptValue eval(QObject *secondaryScope, bool *isUndefined = 0); void updateGuards(const QPODVector &properties); void clearGuards(); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 10b9fab..0e230e8 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -222,15 +222,10 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) if (lastData->flags & QDeclarativePropertyCache::Data::IsVMEFunction) { return Value(scriptEngine, ((QDeclarativeVMEMetaObject *)(obj->metaObject()))->vmeMethod(lastData->coreIndex)); } else { -#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) // Uncomment to use QtScript method call logic // QScriptValue sobj = scriptEngine->newQObject(obj); // return Value(scriptEngine, sobj.property(toString(name))); return Value(scriptEngine, methods.newMethod(obj, lastData)); -#else - QScriptValue sobj = scriptEngine->newQObject(obj); - return Value(scriptEngine, sobj.property(toString(name))); -#endif } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { @@ -295,7 +290,6 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj); return Value(scriptEngine, enginePriv->scriptValueFromVariant(var)); } - } } @@ -456,8 +450,6 @@ bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2) return d1 == d2 || d1->object == d2->object; } -#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) - struct MethodData : public QScriptDeclarativeClass::Object { MethodData(QObject *o, const QDeclarativePropertyCache::Data &d) : object(o), data(d) {} @@ -687,7 +679,17 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); type = callType; } else if (callType == qMetaTypeId >()) { - new (&data) QList(); // We don't support passing in QList + QList *list = new (&data) QList(); + if (value.isArray()) { + int length = value.property(QLatin1String("length")).toInt32(); + for (int ii = 0; ii < length; ++ii) { + QScriptValue arrayItem = value.property(ii); + QObject *d = arrayItem.toQObject(); + list->append(d); + } + } else if (QObject *d = value.toQObject()) { + list->append(d); + } type = callType; } else { new (&data) QVariant(); @@ -800,7 +802,5 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: return Value(); } -#endif - QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index affb6b9..d33f29e 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -1045,6 +1045,21 @@ bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePrope prop.append(&prop, (void *)o); } + } else if (propertyType == qMetaTypeId >()) { + + QList list; + + if (value.userType() == qMetaTypeId >()) { + list = qvariant_cast >(value); + } else { + QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value); + if (o) + list.append(o); + } + + void *args[] = { &list, 0, &status, &flags }; + QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args); + } else { Q_ASSERT(variantType != propertyType); diff --git a/src/declarative/util/qdeclarativelistaccessor.cpp b/src/declarative/util/qdeclarativelistaccessor.cpp index 4ac587f..f91b2fb 100644 --- a/src/declarative/util/qdeclarativelistaccessor.cpp +++ b/src/declarative/util/qdeclarativelistaccessor.cpp @@ -84,6 +84,8 @@ void QDeclarativeListAccessor::setList(const QVariant &v, QDeclarativeEngine *en QObject *data = enginePrivate?enginePrivate->toQObject(v):QDeclarativeMetaType::toQObject(v); d = QVariant::fromValue(data); m_type = Instance; + } else if (d.userType() == qMetaTypeId >()) { + m_type = ObjectList; } else if (d.userType() == qMetaTypeId()) { m_type = ListProperty; } else { @@ -98,6 +100,8 @@ int QDeclarativeListAccessor::count() const return qvariant_cast(d).count(); case VariantList: return qvariant_cast(d).count(); + case ObjectList: + return qvariant_cast >(d).count(); case ListProperty: return ((QDeclarativeListReference *)d.constData())->count(); case Instance: @@ -118,6 +122,8 @@ QVariant QDeclarativeListAccessor::at(int idx) const return QVariant::fromValue(qvariant_cast(d).at(idx)); case VariantList: return qvariant_cast(d).at(idx); + case ObjectList: + return QVariant::fromValue(qvariant_cast >(d).at(idx)); case ListProperty: return QVariant::fromValue(((QDeclarativeListReference *)d.constData())->at(idx)); case Instance: diff --git a/src/declarative/util/qdeclarativelistaccessor_p.h b/src/declarative/util/qdeclarativelistaccessor_p.h index d8bb8af..10d944a 100644 --- a/src/declarative/util/qdeclarativelistaccessor_p.h +++ b/src/declarative/util/qdeclarativelistaccessor_p.h @@ -65,7 +65,7 @@ public: int count() const; QVariant at(int) const; - enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer }; + enum Type { Invalid, StringList, VariantList, ObjectList, ListProperty, Instance, Integer }; Type type() const { return m_type; } private: diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml new file mode 100644 index 0000000..9c289be --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml @@ -0,0 +1,16 @@ +import Qt.test 1.0 +import Qt 4.6 + +MyQmlObject { + id: root + + property bool test1 + property bool test2 + + qlistProperty: root + + Component.onCompleted: { + test1 = (qlistProperty.length == 1) + test2 = (qlistProperty[0] == root) + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml new file mode 100644 index 0000000..8041f5c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml @@ -0,0 +1,17 @@ +import Qt.test 1.0 +import Qt 4.6 + +MyQmlObject { + id: root + + property bool test1 + property bool test2 + + Component.onCompleted: { + qlistProperty = root + + test1 = (qlistProperty.length == 1) + test2 = (qlistProperty[0] == root) + } +} + diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml new file mode 100644 index 0000000..df44e48 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml @@ -0,0 +1,21 @@ +import Qt.test 1.0 +import Qt 4.6 + +MyQmlObject { + id: root + + property bool test1 + property bool test2 + property bool test3 + property bool test4 + + objectProperty: QtObject { id: obj } + qlistProperty: [ root, obj ] + + Component.onCompleted: { + test1 = (qlistProperty.length == 2) + test2 = (qlistProperty[0] == root) + test3 = (qlistProperty[1] == obj) + test4 = (qlistProperty[2] == null) + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml new file mode 100644 index 0000000..33c3576 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml @@ -0,0 +1,22 @@ +import Qt.test 1.0 +import Qt 4.6 + +MyQmlObject { + id: root + + property bool test1 + property bool test2 + property bool test3 + property bool test4 + + objectProperty: QtObject { id: obj } + + Component.onCompleted: { + qlistProperty = [ root, obj ] + + test1 = (qlistProperty.length == 2) + test2 = (qlistProperty[0] == root) + test3 = (qlistProperty[1] == obj) + test4 = (qlistProperty[2] == null) + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml new file mode 100644 index 0000000..3fd497c --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml @@ -0,0 +1,35 @@ +import Qt.test 1.0 +import Qt 4.6 + +MyQmlObject { + id: root + + property bool test1 + property bool test2 + property bool test3 + property bool test4 + property bool test5 + property bool test6 + property bool test7 + property bool test8 + + objectProperty: QtObject { id: obj } + + Component.onCompleted: { + qlistProperty = [ root, obj ] + + test1 = (qlistProperty.length == 2) + test2 = (qlistProperty[0] == root) + test3 = (qlistProperty[1] == obj) + test4 = (qlistProperty[2] == null) + + var a = qlistProperty; + a.reverse(); + qlistProperty = a + + test5 = (qlistProperty.length == 2) + test7 = (qlistProperty[0] == obj) + test6 = (qlistProperty[1] == root) + test8 = (qlistProperty[2] == null) + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index faad8b7..d8ec452 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -91,6 +91,7 @@ class MyQmlObject : public QObject Q_PROPERTY(QDeclarativeListProperty objectListProperty READ objectListProperty CONSTANT) Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp) + Q_PROPERTY(QList qlistProperty READ qlistProperty WRITE setQListProperty) public: MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} @@ -142,6 +143,9 @@ public: QRegExp regExp() { return m_regExp; } void setRegExp(const QRegExp ®Exp) { m_regExp = regExp; } + QList qlistProperty() const { return m_objectQList2; } + void setQListProperty(const QList &v) { m_objectQList2 = v; } + signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); @@ -167,6 +171,8 @@ private: int m_value; int m_resetProperty; QRegExp m_regExp; + + QList m_objectQList2; }; QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES) diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 77dd4b8..a2625da 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -130,6 +130,7 @@ private slots: void qlistqobjectMethods(); void strictlyEquals(); void compiled(); + void qlistOfQObjects(); void bug1(); void dynamicCreationCrash(); @@ -2065,6 +2066,80 @@ void tst_qdeclarativeecmascript::compiled() delete object; } +// Test manipulating QList properties +void tst_qdeclarativeecmascript::qlistOfQObjects() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.1.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.2.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.3.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + QCOMPARE(object->property("test3").toBool(), true); + QCOMPARE(object->property("test4").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.4.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + QCOMPARE(object->property("test3").toBool(), true); + QCOMPARE(object->property("test4").toBool(), true); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.5.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toBool(), true); + QCOMPARE(object->property("test2").toBool(), true); + QCOMPARE(object->property("test3").toBool(), true); + QCOMPARE(object->property("test4").toBool(), true); + QCOMPARE(object->property("test5").toBool(), true); + QCOMPARE(object->property("test6").toBool(), true); + QCOMPARE(object->property("test7").toBool(), true); + QCOMPARE(object->property("test8").toBool(), true); + + delete object; + } +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" -- cgit v0.12 From fac110fd9313972f001bf8b52b0254cc2d67ef66 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 8 Apr 2010 10:49:46 +1000 Subject: Fix setting of pointSize and pixelSize in different items. Also ensure warning is issued regardless of the order both pointSize and pixelSize are set in the same item. Task-number: QTBUG-9665 --- src/declarative/qml/qdeclarativevaluetype.cpp | 18 +++++++++++----- src/declarative/qml/qdeclarativevaluetype_p.h | 3 ++- .../qdeclarativevaluetypes/data/font_write.4.qml | 7 +++++++ .../qdeclarativevaluetypes/data/font_write.5.qml | 14 +++++++++++++ .../tst_qdeclarativevaluetypes.cpp | 24 ++++++++++++++++++++++ 5 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/font_write.4.qml create mode 100644 tests/auto/declarative/qdeclarativevaluetypes/data/font_write.5.qml diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index 839e0dd..49e7b79 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -619,7 +619,7 @@ void QDeclarativeEasingValueType::setPeriod(qreal period) } QDeclarativeFontValueType::QDeclarativeFontValueType(QObject *parent) -: QDeclarativeValueType(parent), hasPixelSize(false) +: QDeclarativeValueType(parent), pixelSizeSet(false), pointSizeSet(false) { } @@ -627,6 +627,8 @@ void QDeclarativeFontValueType::read(QObject *obj, int idx) { void *a[] = { &font, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); + pixelSizeSet = false; + pointSizeSet = false; } void QDeclarativeFontValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags) @@ -724,13 +726,17 @@ qreal QDeclarativeFontValueType::pointSize() const void QDeclarativeFontValueType::setPointSize(qreal size) { - if (hasPixelSize) { + if (pixelSizeSet) { qWarning() << "Both point size and pixel size set. Using pixel size."; return; } - if (size >= 0.0) + if (size >= 0.0) { + pointSizeSet = true; font.setPointSizeF(size); + } else { + pointSizeSet = false; + } } int QDeclarativeFontValueType::pixelSize() const @@ -741,10 +747,12 @@ int QDeclarativeFontValueType::pixelSize() const void QDeclarativeFontValueType::setPixelSize(int size) { if (size >=0) { + if (pointSizeSet) + qWarning() << "Both point size and pixel size set. Using pixel size."; font.setPixelSize(size); - hasPixelSize = true; + pixelSizeSet = true; } else { - hasPixelSize = false; + pixelSizeSet = false; } } diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h index 1fe8bd2..763177d 100644 --- a/src/declarative/qml/qdeclarativevaluetype_p.h +++ b/src/declarative/qml/qdeclarativevaluetype_p.h @@ -399,7 +399,8 @@ public: private: QFont font; - bool hasPixelSize; + bool pixelSizeSet; + bool pointSizeSet; }; QT_END_NAMESPACE diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/font_write.4.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/font_write.4.qml new file mode 100644 index 0000000..2ec69d7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/font_write.4.qml @@ -0,0 +1,7 @@ +import Test 1.0 + +MyTypeObject { + font.pointSize: 19 + font.pixelSize: 10 +} + diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/font_write.5.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/font_write.5.qml new file mode 100644 index 0000000..4c12f21 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/font_write.5.qml @@ -0,0 +1,14 @@ +import Qt 4.6 +import Test 1.0 + +Item { + MyTypeObject { + objectName: "object1" + font.pixelSize: 19 + } + MyTypeObject { + objectName: "object2" + font.pointSize: 14 + } +} + diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index 4e254eb..fb487f0 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -352,6 +352,30 @@ void tst_qdeclarativevaluetypes::font() delete object; } + { + QDeclarativeComponent component(&engine, TEST_FILE("font_write.4.qml")); + QTest::ignoreMessage(QtWarningMsg, "Both point size and pixel size set. Using pixel size. "); + MyTypeObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->font().pixelSize(), 10); + + delete object; + } + { + QDeclarativeComponent component(&engine, TEST_FILE("font_write.5.qml")); + QObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + MyTypeObject *object1 = object->findChild("object1"); + QVERIFY(object1 != 0); + MyTypeObject *object2 = object->findChild("object2"); + QVERIFY(object2 != 0); + + QCOMPARE(object1->font().pixelSize(), 19); + QCOMPARE(object2->font().pointSize(), 14); + + delete object; + } } // Test bindings can write to value types -- cgit v0.12 From 80cd83d3b09b2271d183a51d2e6453924c535dce Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 8 Apr 2010 11:13:33 +1000 Subject: Document behavior of conflicting when clauses. Task-number: QTBUG-9371 --- src/declarative/util/qdeclarativestate.cpp | 18 +++++++++++++---- .../qdeclarativestates/data/whenOrdering.qml | 11 +++++++++++ .../qdeclarativestates/tst_qdeclarativestates.cpp | 23 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index 5e6c35e..e4c968e 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -121,14 +121,13 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje /*! \qmlclass State QDeclarativeState - \since 4.7 + \since 4.7 \brief The State element defines configurations of objects and properties. A state is specified as a set of batched changes from the default configuration. - Note that setting the state of an object from within another state of the same object is - inadvisible. Not only would this have the same effect as going directly to the second state - it may cause the program to crash. + \note setting the state of an object from within another state of the same object is + not allowed. \sa {qmlstates}{States}, {state-transitions}{Transitions} */ @@ -191,6 +190,17 @@ bool QDeclarativeState::isWhenKnown() const This should be set to an expression that evaluates to true when you want the state to be applied. + + If multiple states in a group have \c when clauses that evaluate to true at the same time, + the first matching state will be applied. For example, in the following snippet + \c state1 will always be selected rather than \c state2 when sharedCondition becomes + \c true. + \qml + states: [ + State { name: "state1"; when: sharedCondition }, + State { name: "state2"; when: sharedCondition } + ] + \endqml */ QDeclarativeBinding *QDeclarativeState::when() const { diff --git a/tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml b/tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml new file mode 100644 index 0000000..7369c63 --- /dev/null +++ b/tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml @@ -0,0 +1,11 @@ +import Qt 4.6 + +Rectangle { + property bool condition1: false + property bool condition2: false + + states: [ + State { name: "state1"; when: condition1 }, + State { name: "state2"; when: condition2 } + ] +} diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp index e7c595a..f0b6759 100644 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp @@ -108,6 +108,7 @@ private slots: void nonExistantProperty(); void reset(); void illegalObjectCreation(); + void whenOrdering(); }; void tst_qdeclarativestates::initTestCase() @@ -993,6 +994,28 @@ void tst_qdeclarativestates::illegalObjectCreation() QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects."); } +void tst_qdeclarativestates::whenOrdering() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, SRCDIR "/data/whenOrdering.qml"); + QDeclarativeRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->state(), QLatin1String("")); + rect->setProperty("condition2", true); + QCOMPARE(rect->state(), QLatin1String("state2")); + rect->setProperty("condition1", true); + QCOMPARE(rect->state(), QLatin1String("state1")); + rect->setProperty("condition2", false); + QCOMPARE(rect->state(), QLatin1String("state1")); + rect->setProperty("condition2", true); + QCOMPARE(rect->state(), QLatin1String("state1")); + rect->setProperty("condition1", false); + rect->setProperty("condition2", false); + QCOMPARE(rect->state(), QLatin1String("")); +} + QTEST_MAIN(tst_qdeclarativestates) #include "tst_qdeclarativestates.moc" -- cgit v0.12 From 198377b456c494272e9a73a872478c5d5ae94af4 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 8 Apr 2010 11:16:49 +1000 Subject: Don't emit clicked() after pressAndHold() Task-number: QTBUG-9676 --- .../graphicsitems/qdeclarativemousearea.cpp | 2 +- .../qdeclarativemousearea/data/clickandhold.qml | 13 +++++++++ .../tst_qdeclarativemousearea.cpp | 31 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/auto/declarative/qdeclarativemousearea/data/clickandhold.qml diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index c95bd29..a6cc75e 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -651,7 +651,7 @@ bool QDeclarativeMouseArea::setPressed(bool p) emit positionChanged(&me); } else { emit released(&me); - if (isclick) + if (isclick && !d->longPress) emit clicked(&me); } diff --git a/tests/auto/declarative/qdeclarativemousearea/data/clickandhold.qml b/tests/auto/declarative/qdeclarativemousearea/data/clickandhold.qml new file mode 100644 index 0000000..e800f98 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemousearea/data/clickandhold.qml @@ -0,0 +1,13 @@ +import Qt 4.6 + +Item { + id: root + property bool clicked: false + property bool held: false + + MouseArea { + width: 200; height: 200 + onClicked: { root.clicked = true } + onPressAndHold: { root.held = true } + } +} diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index dfe46e4..bdb8eca 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -53,6 +53,7 @@ private slots: void dragProperties(); void resetDrag(); void updateMouseAreaPosOnClick(); + void noOnClickedWithPressAndHold(); private: QDeclarativeView *createView(); }; @@ -202,6 +203,36 @@ void tst_QDeclarativeMouseArea::updateMouseAreaPosOnClick() delete canvas; } +void tst_QDeclarativeMouseArea::noOnClickedWithPressAndHold() +{ + QDeclarativeView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clickandhold.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QGraphicsScene *scene = canvas->scene(); + QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress); + pressEvent.setScenePos(QPointF(100, 100)); + pressEvent.setButton(Qt::LeftButton); + pressEvent.setButtons(Qt::LeftButton); + QApplication::sendEvent(scene, &pressEvent); + + QVERIFY(!canvas->rootObject()->property("clicked").toBool()); + QVERIFY(!canvas->rootObject()->property("held").toBool()); + + QTest::qWait(1000); + + QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMousePress); + releaseEvent.setScenePos(QPointF(100, 100)); + releaseEvent.setButton(Qt::LeftButton); + releaseEvent.setButtons(Qt::LeftButton); + QApplication::sendEvent(scene, &releaseEvent); + + QVERIFY(!canvas->rootObject()->property("clicked").toBool()); + QVERIFY(canvas->rootObject()->property("held").toBool()); +} + QTEST_MAIN(tst_QDeclarativeMouseArea) #include "tst_qdeclarativemousearea.moc" -- cgit v0.12 From e74bd7d0b1a2ed47f41fba47caa542ca5b29880e Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 8 Apr 2010 11:19:35 +1000 Subject: Revert "Support QList properties" This reverts commit 9d9161446bfad883c298d54a122e822c5e273a9c. This was a bad idea. It complicates the "property var" are not really JavaScript var problem. Some of the patch is valid, and it will be applied separately. --- src/declarative/qml/qdeclarativebinding.cpp | 24 ++----- src/declarative/qml/qdeclarativeengine.cpp | 34 +++------- src/declarative/qml/qdeclarativeengine_p.h | 2 +- src/declarative/qml/qdeclarativeexpression.cpp | 66 ++++++++++++------- src/declarative/qml/qdeclarativeexpression_p.h | 4 +- .../qml/qdeclarativeobjectscriptclass.cpp | 22 +++---- src/declarative/qml/qdeclarativeproperty.cpp | 15 ----- src/declarative/util/qdeclarativelistaccessor.cpp | 6 -- src/declarative/util/qdeclarativelistaccessor_p.h | 2 +- .../data/qlistOfQObjects.1.qml | 16 ----- .../data/qlistOfQObjects.2.qml | 17 ----- .../data/qlistOfQObjects.3.qml | 21 ------ .../data/qlistOfQObjects.4.qml | 22 ------- .../data/qlistOfQObjects.5.qml | 35 ---------- .../declarative/qdeclarativeecmascript/testtypes.h | 6 -- .../tst_qdeclarativeecmascript.cpp | 75 ---------------------- 16 files changed, 70 insertions(+), 297 deletions(-) delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml delete mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp index bed1956..71cf3cb 100644 --- a/src/declarative/qml/qdeclarativebinding.cpp +++ b/src/declarative/qml/qdeclarativebinding.cpp @@ -148,26 +148,8 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) idx, a); } else { - QDeclarativeEnginePrivate *ep = (data->context() && data->context()->engine)? - QDeclarativeEnginePrivate::get(data->context()->engine):0; - bool isUndefined = false; - QVariant value; - - if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) { - QScriptValue scriptValue = d->scriptValue(0, &isUndefined); - value = ep->scriptValueToVariant(scriptValue, qMetaTypeId >()); - } else { - QScriptValue scriptValue = d->scriptValue(0, &isUndefined); - value = ep->scriptValueToVariant(scriptValue); - if (value.userType() == QMetaType::QObjectStar && !qvariant_cast(value)) { - // If the object is null, we extract the predicted type. While this isn't - // 100% reliable, in many cases it gives us better error messages if we - // assign this null-object to an incompatible property - int type = ep->objectClass->objectType(scriptValue); - value = QVariant(type, (void *)0); - } - } + QVariant value = this->value(&isUndefined); if (isUndefined && !data->error.isValid() && data->property.isResettable()) { @@ -205,7 +187,9 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags) } if (data->error.isValid()) { - if (!data->addError(ep)) + QDeclarativeEnginePrivate *p = (data->context() && data->context()->engine)? + QDeclarativeEnginePrivate::get(data->context()->engine):0; + if (!data->addError(p)) qWarning().nospace() << qPrintable(this->error().toString()); } else { data->removeError(); diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 3c66efb..e8b6913 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1324,6 +1324,7 @@ QScriptValue QDeclarativeEnginePrivate::tint(QScriptContext *ctxt, QScriptEngine return qScriptValueFromValue(engine, qVariantFromValue(finalColor)); } + QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &val) { if (val.userType() == qMetaTypeId()) { @@ -1334,14 +1335,6 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v } else { return scriptEngine.nullValue(); } - } else if (val.userType() == qMetaTypeId >()) { - const QList &list = *(QList*)val.constData(); - QScriptValue rv = scriptEngine.newArray(list.count()); - for (int ii = 0; ii < list.count(); ++ii) { - QObject *object = list.at(ii); - rv.setProperty(ii, objectClass->newQObject(object)); - } - return rv; } bool objOk; @@ -1353,31 +1346,22 @@ QScriptValue QDeclarativeEnginePrivate::scriptValueFromVariant(const QVariant &v } } -QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val, int hint) +QVariant QDeclarativeEnginePrivate::scriptValueToVariant(const QScriptValue &val) { QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(val); if (dc == objectClass) return QVariant::fromValue(objectClass->toQObject(val)); - else if (dc == valueTypeClass) - return valueTypeClass->toVariant(val); else if (dc == contextClass) return QVariant(); - // Convert to a QList if val is an array and we were explicitly hinted, or - // if the first element is a QObject* - if ((hint == qMetaTypeId >() && val.isArray()) || - (val.isArray() && QScriptDeclarativeClass::scriptClass(val.property(0)) == objectClass)) { - QList list; - int length = val.property(QLatin1String("length")).toInt32(); - for (int ii = 0; ii < length; ++ii) { - QScriptValue arrayItem = val.property(ii); - QObject *d = arrayItem.toQObject(); - list << d; - } - return QVariant::fromValue(list); + QScriptDeclarativeClass *sc = QScriptDeclarativeClass::scriptClass(val); + if (!sc) { + return val.toVariant(); + } else if (sc == valueTypeClass) { + return valueTypeClass->toVariant(val); + } else { + return QVariant(); } - - return val.toVariant(); } // XXX this beyonds in QUrl::toLocalFile() diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 3f22d61..45089d0 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -308,7 +308,7 @@ public: QHash m_sharedScriptImports; QScriptValue scriptValueFromVariant(const QVariant &); - QVariant scriptValueToVariant(const QScriptValue &, int hint = QVariant::Invalid); + QVariant scriptValueToVariant(const QScriptValue &); void sendQuit (); diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index e0aee52..a250f21 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -351,7 +351,7 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine } } -QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool *isUndefined) +QVariant QDeclarativeExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined) { QDeclarativeExpressionData *data = this->data; QDeclarativeEngine *engine = data->context()->engine; @@ -376,7 +376,7 @@ QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool * const QString code = rewriteBinding(data->expression, &ok); if (!ok) { scriptEngine->popContext(); - return QScriptValue(); + return QVariant(); } data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line); } @@ -413,20 +413,54 @@ QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool * if (scriptEngine->hasUncaughtException()) { exceptionToError(scriptEngine, data->error); scriptEngine->clearExceptions(); - return QScriptValue(); + return QVariant(); } else { data->error = QDeclarativeError(); - return svalue; } + + QVariant rv; + + if (svalue.isArray()) { + int length = svalue.property(QLatin1String("length")).toInt32(); + if (length && svalue.property(0).isObject()) { + QList list; + for (int ii = 0; ii < length; ++ii) { + QScriptValue arrayItem = svalue.property(ii); + QObject *d = arrayItem.toQObject(); + list << d; + } + rv = QVariant::fromValue(list); + } + } else if (svalue.isObject() && + ep->objectClass->scriptClass(svalue) == ep->objectClass) { + QObject *o = svalue.toQObject(); + int type = QMetaType::QObjectStar; + // If the object is null, we extract the predicted type. While this isn't + // 100% reliable, in many cases it gives us better error messages if we + // assign this null-object to an incompatible property + if (!o) type = ep->objectClass->objectType(svalue); + + return QVariant(type, &o); + } + + if (rv.isNull()) + rv = svalue.toVariant(); + + return rv; } -QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined) +QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) { Q_Q(QDeclarativeExpression); - Q_ASSERT(q->engine()); + + QVariant rv; + if (!q->engine()) { + qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context"); + return rv; + } if (data->expression.isEmpty()) - return QScriptValue(); + return rv; QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); @@ -442,7 +476,7 @@ QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, QDeclarativeExpressionData *localData = data; localData->addref(); - QScriptValue value = eval(secondaryScope, isUndefined); + rv = evalQtScript(secondaryScope, isUndefined); ep->currentExpression = lastCurrentExpression; ep->captureProperties = lastCaptureProperties; @@ -460,21 +494,7 @@ QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, lastCapturedProperties.copyAndClear(ep->capturedProperties); - return value; -} - -QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) -{ - Q_Q(QDeclarativeExpression); - - if (!q->engine()) { - qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context"); - return QVariant(); - } - - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine()); - - return ep->scriptValueToVariant(scriptValue(secondaryScope, isUndefined)); + return rv; } /*! diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index 1a0e4dd..9a90fb6 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -150,9 +150,7 @@ public: QDeclarativeExpressionData *data; QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0); - QScriptValue scriptValue(QObject *secondaryScope = 0, bool *isUndefined = 0); - - QScriptValue eval(QObject *secondaryScope, bool *isUndefined = 0); + QVariant evalQtScript(QObject *secondaryScope, bool *isUndefined = 0); void updateGuards(const QPODVector &properties); void clearGuards(); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 0e230e8..10b9fab 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -222,10 +222,15 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) if (lastData->flags & QDeclarativePropertyCache::Data::IsVMEFunction) { return Value(scriptEngine, ((QDeclarativeVMEMetaObject *)(obj->metaObject()))->vmeMethod(lastData->coreIndex)); } else { +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) // Uncomment to use QtScript method call logic // QScriptValue sobj = scriptEngine->newQObject(obj); // return Value(scriptEngine, sobj.property(toString(name))); return Value(scriptEngine, methods.newMethod(obj, lastData)); +#else + QScriptValue sobj = scriptEngine->newQObject(obj); + return Value(scriptEngine, sobj.property(toString(name))); +#endif } } else { if (enginePriv->captureProperties && !(lastData->flags & QDeclarativePropertyCache::Data::IsConstant)) { @@ -290,6 +295,7 @@ QDeclarativeObjectScriptClass::property(QObject *obj, const Identifier &name) QVariant var = obj->metaObject()->property(lastData->coreIndex).read(obj); return Value(scriptEngine, enginePriv->scriptValueFromVariant(var)); } + } } @@ -450,6 +456,8 @@ bool QDeclarativeObjectScriptClass::compare(Object *o1, Object *o2) return d1 == d2 || d1->object == d2->object; } +#if (QT_VERSION > QT_VERSION_CHECK(4, 6, 2)) || defined(QT_HAVE_QSCRIPTDECLARATIVECLASS_VALUE) + struct MethodData : public QScriptDeclarativeClass::Object { MethodData(QObject *o, const QDeclarativePropertyCache::Data &d) : object(o), data(d) {} @@ -679,17 +687,7 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); type = callType; } else if (callType == qMetaTypeId >()) { - QList *list = new (&data) QList(); - if (value.isArray()) { - int length = value.property(QLatin1String("length")).toInt32(); - for (int ii = 0; ii < length; ++ii) { - QScriptValue arrayItem = value.property(ii); - QObject *d = arrayItem.toQObject(); - list->append(d); - } - } else if (QObject *d = value.toQObject()) { - list->append(d); - } + new (&data) QList(); // We don't support passing in QList type = callType; } else { new (&data) QVariant(); @@ -802,5 +800,7 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: return Value(); } +#endif + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index d33f29e..affb6b9 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -1045,21 +1045,6 @@ bool QDeclarativePropertyPrivate::write(QObject *object, const QDeclarativePrope prop.append(&prop, (void *)o); } - } else if (propertyType == qMetaTypeId >()) { - - QList list; - - if (value.userType() == qMetaTypeId >()) { - list = qvariant_cast >(value); - } else { - QObject *o = enginePriv?enginePriv->toQObject(value):QDeclarativeMetaType::toQObject(value); - if (o) - list.append(o); - } - - void *args[] = { &list, 0, &status, &flags }; - QMetaObject::metacall(object, QMetaObject::WriteProperty, coreIdx, args); - } else { Q_ASSERT(variantType != propertyType); diff --git a/src/declarative/util/qdeclarativelistaccessor.cpp b/src/declarative/util/qdeclarativelistaccessor.cpp index f91b2fb..4ac587f 100644 --- a/src/declarative/util/qdeclarativelistaccessor.cpp +++ b/src/declarative/util/qdeclarativelistaccessor.cpp @@ -84,8 +84,6 @@ void QDeclarativeListAccessor::setList(const QVariant &v, QDeclarativeEngine *en QObject *data = enginePrivate?enginePrivate->toQObject(v):QDeclarativeMetaType::toQObject(v); d = QVariant::fromValue(data); m_type = Instance; - } else if (d.userType() == qMetaTypeId >()) { - m_type = ObjectList; } else if (d.userType() == qMetaTypeId()) { m_type = ListProperty; } else { @@ -100,8 +98,6 @@ int QDeclarativeListAccessor::count() const return qvariant_cast(d).count(); case VariantList: return qvariant_cast(d).count(); - case ObjectList: - return qvariant_cast >(d).count(); case ListProperty: return ((QDeclarativeListReference *)d.constData())->count(); case Instance: @@ -122,8 +118,6 @@ QVariant QDeclarativeListAccessor::at(int idx) const return QVariant::fromValue(qvariant_cast(d).at(idx)); case VariantList: return qvariant_cast(d).at(idx); - case ObjectList: - return QVariant::fromValue(qvariant_cast >(d).at(idx)); case ListProperty: return QVariant::fromValue(((QDeclarativeListReference *)d.constData())->at(idx)); case Instance: diff --git a/src/declarative/util/qdeclarativelistaccessor_p.h b/src/declarative/util/qdeclarativelistaccessor_p.h index 10d944a..d8bb8af 100644 --- a/src/declarative/util/qdeclarativelistaccessor_p.h +++ b/src/declarative/util/qdeclarativelistaccessor_p.h @@ -65,7 +65,7 @@ public: int count() const; QVariant at(int) const; - enum Type { Invalid, StringList, VariantList, ObjectList, ListProperty, Instance, Integer }; + enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer }; Type type() const { return m_type; } private: diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml deleted file mode 100644 index 9c289be..0000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.1.qml +++ /dev/null @@ -1,16 +0,0 @@ -import Qt.test 1.0 -import Qt 4.6 - -MyQmlObject { - id: root - - property bool test1 - property bool test2 - - qlistProperty: root - - Component.onCompleted: { - test1 = (qlistProperty.length == 1) - test2 = (qlistProperty[0] == root) - } -} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml deleted file mode 100644 index 8041f5c..0000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.2.qml +++ /dev/null @@ -1,17 +0,0 @@ -import Qt.test 1.0 -import Qt 4.6 - -MyQmlObject { - id: root - - property bool test1 - property bool test2 - - Component.onCompleted: { - qlistProperty = root - - test1 = (qlistProperty.length == 1) - test2 = (qlistProperty[0] == root) - } -} - diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml deleted file mode 100644 index df44e48..0000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.3.qml +++ /dev/null @@ -1,21 +0,0 @@ -import Qt.test 1.0 -import Qt 4.6 - -MyQmlObject { - id: root - - property bool test1 - property bool test2 - property bool test3 - property bool test4 - - objectProperty: QtObject { id: obj } - qlistProperty: [ root, obj ] - - Component.onCompleted: { - test1 = (qlistProperty.length == 2) - test2 = (qlistProperty[0] == root) - test3 = (qlistProperty[1] == obj) - test4 = (qlistProperty[2] == null) - } -} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml deleted file mode 100644 index 33c3576..0000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.4.qml +++ /dev/null @@ -1,22 +0,0 @@ -import Qt.test 1.0 -import Qt 4.6 - -MyQmlObject { - id: root - - property bool test1 - property bool test2 - property bool test3 - property bool test4 - - objectProperty: QtObject { id: obj } - - Component.onCompleted: { - qlistProperty = [ root, obj ] - - test1 = (qlistProperty.length == 2) - test2 = (qlistProperty[0] == root) - test3 = (qlistProperty[1] == obj) - test4 = (qlistProperty[2] == null) - } -} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml deleted file mode 100644 index 3fd497c..0000000 --- a/tests/auto/declarative/qdeclarativeecmascript/data/qlistOfQObjects.5.qml +++ /dev/null @@ -1,35 +0,0 @@ -import Qt.test 1.0 -import Qt 4.6 - -MyQmlObject { - id: root - - property bool test1 - property bool test2 - property bool test3 - property bool test4 - property bool test5 - property bool test6 - property bool test7 - property bool test8 - - objectProperty: QtObject { id: obj } - - Component.onCompleted: { - qlistProperty = [ root, obj ] - - test1 = (qlistProperty.length == 2) - test2 = (qlistProperty[0] == root) - test3 = (qlistProperty[1] == obj) - test4 = (qlistProperty[2] == null) - - var a = qlistProperty; - a.reverse(); - qlistProperty = a - - test5 = (qlistProperty.length == 2) - test7 = (qlistProperty[0] == obj) - test6 = (qlistProperty[1] == root) - test8 = (qlistProperty[2] == null) - } -} diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index d8ec452..faad8b7 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -91,7 +91,6 @@ class MyQmlObject : public QObject Q_PROPERTY(QDeclarativeListProperty objectListProperty READ objectListProperty CONSTANT) Q_PROPERTY(int resettableProperty READ resettableProperty WRITE setResettableProperty RESET resetProperty) Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp) - Q_PROPERTY(QList qlistProperty READ qlistProperty WRITE setQListProperty) public: MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0), m_value(0), m_resetProperty(13) {} @@ -143,9 +142,6 @@ public: QRegExp regExp() { return m_regExp; } void setRegExp(const QRegExp ®Exp) { m_regExp = regExp; } - QList qlistProperty() const { return m_objectQList2; } - void setQListProperty(const QList &v) { m_objectQList2 = v; } - signals: void basicSignal(); void argumentSignal(int a, QString b, qreal c); @@ -171,8 +167,6 @@ private: int m_value; int m_resetProperty; QRegExp m_regExp; - - QList m_objectQList2; }; QML_DECLARE_TYPEINFO(MyQmlObject, QML_HAS_ATTACHED_PROPERTIES) diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index a2625da..77dd4b8 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -130,7 +130,6 @@ private slots: void qlistqobjectMethods(); void strictlyEquals(); void compiled(); - void qlistOfQObjects(); void bug1(); void dynamicCreationCrash(); @@ -2066,80 +2065,6 @@ void tst_qdeclarativeecmascript::compiled() delete object; } -// Test manipulating QList properties -void tst_qdeclarativeecmascript::qlistOfQObjects() -{ - { - QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.1.qml")); - - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(object->property("test1").toBool(), true); - QCOMPARE(object->property("test2").toBool(), true); - - delete object; - } - - { - QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.2.qml")); - - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(object->property("test1").toBool(), true); - QCOMPARE(object->property("test2").toBool(), true); - - delete object; - } - - { - QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.3.qml")); - - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(object->property("test1").toBool(), true); - QCOMPARE(object->property("test2").toBool(), true); - QCOMPARE(object->property("test3").toBool(), true); - QCOMPARE(object->property("test4").toBool(), true); - - delete object; - } - - { - QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.4.qml")); - - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(object->property("test1").toBool(), true); - QCOMPARE(object->property("test2").toBool(), true); - QCOMPARE(object->property("test3").toBool(), true); - QCOMPARE(object->property("test4").toBool(), true); - - delete object; - } - - { - QDeclarativeComponent component(&engine, TEST_FILE("qlistOfQObjects.5.qml")); - - QObject *object = component.create(); - QVERIFY(object != 0); - - QCOMPARE(object->property("test1").toBool(), true); - QCOMPARE(object->property("test2").toBool(), true); - QCOMPARE(object->property("test3").toBool(), true); - QCOMPARE(object->property("test4").toBool(), true); - QCOMPARE(object->property("test5").toBool(), true); - QCOMPARE(object->property("test6").toBool(), true); - QCOMPARE(object->property("test7").toBool(), true); - QCOMPARE(object->property("test8").toBool(), true); - - delete object; - } -} - QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" -- cgit v0.12 From cb22daf607a99bf01a8e3263599f0dd8ee018707 Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 8 Apr 2010 11:38:47 +1000 Subject: Remove flickr-desktop --- demos/declarative/flickr/common/ImageDetails.qml | 160 ------------------ demos/declarative/flickr/common/MediaButton.qml | 41 ----- demos/declarative/flickr/common/MediaLineEdit.qml | 104 ------------ demos/declarative/flickr/flickr-90.qml | 11 ++ demos/declarative/flickr/flickr-desktop.qml | 194 ---------------------- demos/declarative/flickr/flickr-mobile-90.qml | 11 -- demos/declarative/flickr/flickr-mobile.qml | 82 --------- demos/declarative/flickr/flickr.qml | 82 +++++++++ 8 files changed, 93 insertions(+), 592 deletions(-) delete mode 100644 demos/declarative/flickr/common/ImageDetails.qml delete mode 100644 demos/declarative/flickr/common/MediaButton.qml delete mode 100644 demos/declarative/flickr/common/MediaLineEdit.qml create mode 100644 demos/declarative/flickr/flickr-90.qml delete mode 100644 demos/declarative/flickr/flickr-desktop.qml delete mode 100644 demos/declarative/flickr/flickr-mobile-90.qml delete mode 100644 demos/declarative/flickr/flickr-mobile.qml create mode 100644 demos/declarative/flickr/flickr.qml diff --git a/demos/declarative/flickr/common/ImageDetails.qml b/demos/declarative/flickr/common/ImageDetails.qml deleted file mode 100644 index 862eeb1..0000000 --- a/demos/declarative/flickr/common/ImageDetails.qml +++ /dev/null @@ -1,160 +0,0 @@ -import Qt 4.6 -import org.webkit 1.0 - -Flipable { - id: container - - property var frontContainer: containerFront - property string photoTitle: "" - property string photoDescription: "" - property string photoTags: "" - property int photoWidth - property int photoHeight - property string photoType - property string photoAuthor - property string photoDate - property string photoUrl - property int rating: 2 - property var prevScale: 1.0 - - signal closed - - transform: Rotation { - id: detailsRotation - origin.y: container.height / 2; - origin.x: container.width / 2; - axis.y: 1; axis.z: 0 - } - - front: Item { - id: containerFront; anchors.fill: container - - Rectangle { - anchors.fill: parent - color: "black"; opacity: 0.4 - border.color: "white"; border.width: 2 - } - - MediaButton { - id: backButton; x: 630; y: 370; text: "Back" - onClicked: { container.closed() } - } - - MediaButton { - id: moreButton; x: 530; y: 370; text: "View..." - onClicked: { container.state='Back' } - } - - Text { id: titleText; style: Text.Raised; styleColor: "black"; color: "white"; elide: Text.ElideRight - x: 220; y: 30; width: parent.width - 240; text: container.photoTitle; font.pointSize: 22 } - - LikeOMeter { x: 40; y: 250; rating: container.rating } - - Flickable { id: flickable; x: 220; width: 480; height: 210; y: 130; clip: true - contentWidth: 480; contentHeight: descriptionText.height - - WebView { id: descriptionText; width: parent.width - html: "" + container.photoDescription } - } - - Text { id: size; color: "white"; width: 300; x: 40; y: 300 - text: "Size: " + container.photoWidth + 'x' + container.photoHeight } - Text { id: type; color: "white"; width: 300; x: 40; anchors.top: size.bottom - text: "Type: " + container.photoType } - - Text { id: author; color: "white"; width: 300; x: 220; y: 80 - text: "Author: " + container.photoAuthor } - Text { id: date; color: "white"; width: 300; x: 220; anchors.top: author.bottom - text: "Published: " + container.photoDate } - Text { id: tagsLabel; color: "white"; x: 220; anchors.top: date.bottom; - text: container.photoTags == "" ? "" : "Tags: " } - Text { id: tags; color: "white"; width: parent.width-x-20; - anchors.left: tagsLabel.right; anchors.top: date.bottom; - elide: Text.ElideRight; text: container.photoTags } - - ScrollBar { id: scrollBar; x: 720; y: flickable.y; width: 7; height: flickable.height; opacity: 0; - flickableArea: flickable; clip: true } - } - - back: Item { - anchors.fill: container - - Rectangle { anchors.fill: parent; color: "black"; opacity: 0.4; border.color: "white"; border.width: 2 } - - Progress { anchors.centerIn: parent; width: 200; height: 18; progress: bigImage.progress; visible: bigImage.status!=1 } - Flickable { - id: flick; width: container.width - 10; height: container.height - 10 - x: 5; y: 5; clip: true; - contentWidth: imageContainer.width; contentHeight: imageContainer.height - - Item { - id: imageContainer - width: Math.max(bigImage.width * bigImage.scale, flick.width); - height: Math.max(bigImage.height * bigImage.scale, flick.height); - - Image { - id: bigImage; source: container.photoUrl; scale: slider.value - anchors.centerIn: parent; - smooth: !flick.moving - onStatusChanged : { - // Default scale shows the entire image. - if (status == 1 && width != 0) { - slider.minimum = Math.min(flick.width / width, flick.height / height); - prevScale = Math.min(slider.minimum, 1); - slider.value = prevScale; - } - } - } - } - } - - MediaButton { - id: backButton2; x: 630; y: 370; text: "Back"; onClicked: { container.state = '' } - } - Text { - text: "Image Unavailable" - visible: bigImage.status == 'Error' - anchors.centerIn: parent; color: "white"; font.bold: true - } - - Slider { - id: slider; x: 25; y: 374; visible: { bigImage.status == 1 && maximum > minimum } - onValueChanged: { - if (bigImage.width * value > flick.width) { - var xoff = (flick.width/2 + flick.contentX) * value / prevScale; - flick.contentX = xoff - flick.width/2; - } - if (bigImage.height * value > flick.height) { - var yoff = (flick.height/2 + flick.contentY) * value / prevScale; - flick.contentY = yoff - flick.height/2; - } - prevScale = value; - } - } - } - - states: [ - State { - name: "Back" - PropertyChanges { target: detailsRotation; angle: 180 } - } - ] - - transitions: [ - Transition { - SequentialAnimation { - PropertyAction { - target: bigImage - property: "smooth" - value: false - } - NumberAnimation { easing.type: "InOutQuad"; properties: "angle"; duration: 500 } - PropertyAction { - target: bigImage - property: "smooth" - value: !flick.moving - } - } - } - ] -} diff --git a/demos/declarative/flickr/common/MediaButton.qml b/demos/declarative/flickr/common/MediaButton.qml deleted file mode 100644 index 86ac948..0000000 --- a/demos/declarative/flickr/common/MediaButton.qml +++ /dev/null @@ -1,41 +0,0 @@ -import Qt 4.6 - -Item { - id: container - - signal clicked - - property string text - - Image { - id: buttonImage - source: "pics/button.png" - } - Image { - id: pressed - source: "pics/button-pressed.png" - opacity: 0 - } - MouseArea { - id: mouseRegion - anchors.fill: buttonImage - onClicked: { container.clicked(); } - } - Text { - font.bold: true - color: "white" - anchors.centerIn: buttonImage - text: container.text - } - width: buttonImage.width - states: [ - State { - name: "Pressed" - when: mouseRegion.pressed == true - PropertyChanges { - target: pressed - opacity: 1 - } - } - ] -} diff --git a/demos/declarative/flickr/common/MediaLineEdit.qml b/demos/declarative/flickr/common/MediaLineEdit.qml deleted file mode 100644 index 9559f6a..0000000 --- a/demos/declarative/flickr/common/MediaLineEdit.qml +++ /dev/null @@ -1,104 +0,0 @@ -import Qt 4.6 - -Item { - id: container - - property string label - property string text - - width: Math.max(94,labeltext.width + editor.width + 20) - height: buttonImage.height - - states: [ - State { - name: "Edit" - PropertyChanges { - target: labeltext - text: container.label + ": " - } - PropertyChanges { - target: labeltext - x: 10 - } - PropertyChanges { - target: editor - cursorVisible: true - width: 100 - } - PropertyChanges { - target: container - focus: true - } - StateChangeScript { - script:editor.selectAll() - } - }, - State { - // When returning to default state, typed text is propagated - StateChangeScript { - script: container.text = editor.text - } - } - ] - transitions: [ - Transition { - NumberAnimation { properties: "x,width"; duration: 500; easing.type: "InOutQuad" } - } - ] - - - BorderImage { - id: buttonImage - source: "pics/button.sci" - anchors.left: container.left - anchors.right: container.right - } - - BorderImage { - id: pressed - source: "pics/button-pressed.sci" - opacity: 0 - anchors.left: container.left - anchors.right: container.right - } - - MouseArea { - id: mouseRegion - anchors.fill: buttonImage - onClicked: { container.state = container.state=="Edit" ? "" : "Edit" } - states: [ - State { - when: mouseRegion.pressed == true - PropertyChanges { - target: pressed - opacity: 1 - } - } - ] - } - - Text { - id: labeltext - font.bold: true - color: "white" - anchors.verticalCenter: container.verticalCenter - x: (container.width - width)/2 - text: container.label + "..." - } - - TextInput { - id: editor - font.bold: true - color: "white" - selectionColor: "green" - width: 0 - clip: true - anchors.left: labeltext.right - anchors.verticalCenter: container.verticalCenter - } - Keys.forwardTo: [(returnKey), (editor)] - Item { - id: returnKey - Keys.onReturnPressed: "container.state = ''" - } -} diff --git a/demos/declarative/flickr/flickr-90.qml b/demos/declarative/flickr/flickr-90.qml new file mode 100644 index 0000000..1d1ac40 --- /dev/null +++ b/demos/declarative/flickr/flickr-90.qml @@ -0,0 +1,11 @@ +import Qt 4.6 + +Item { + width: 480; height: 320 + + Loader { + y: 320; rotation: -90 + transformOrigin: Item.TopLeft + source: "flickr.qml" + } +} diff --git a/demos/declarative/flickr/flickr-desktop.qml b/demos/declarative/flickr/flickr-desktop.qml deleted file mode 100644 index 63b6ea2..0000000 --- a/demos/declarative/flickr/flickr-desktop.qml +++ /dev/null @@ -1,194 +0,0 @@ -import Qt 4.6 - -import "common" - -Item { - id: mainWindow; width: 800; height: 450 - - property bool showPathView : false - - resources: [ - Component { - id: photoDelegate - Item { - id: wrapper; width: 85; height: 85 - scale: wrapper.PathView.scale ? wrapper.PathView.scale : 1 - z: wrapper.PathView.z ? wrapper.PathView.z : 0 - - transform: Rotation { - id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 - axis.y: 1; axis.z: 0 - angle: wrapper.PathView.angle ? wrapper.PathView.angle : 0 - } - - Connections { - target: imageDetails - onClosed: { - if (wrapper.state == 'Details') { - wrapper.state = ''; - imageDetails.photoUrl = ""; - } - } - } - - function photoClicked() { - imageDetails.photoTitle = title; - imageDetails.photoDescription = description; - imageDetails.photoTags = tags; - imageDetails.photoWidth = photoWidth; - imageDetails.photoHeight = photoHeight; - imageDetails.photoType = photoType; - imageDetails.photoAuthor = photoAuthor; - imageDetails.photoDate = photoDate; - imageDetails.photoUrl = url; - imageDetails.rating = 0; - wrapper.state = "Details"; - } - - Rectangle { - id: whiteRect; anchors.fill: parent; color: "white"; radius: 5 - - Loading { x: 26; y: 26; visible: thumb.status!=1 } - Image { id: thumb; source: imagePath; x: 5; y: 5 } - - Item { - id: shadows - Image { source: "common/pics/shadow-right.png"; x: whiteRect.width; height: whiteRect.height } - Image { source: "common/pics/shadow-bottom.png"; y: whiteRect.height; width: whiteRect.width } - Image { id: corner; source: "common/pics/shadow-corner.png"; x: whiteRect.width; y: whiteRect.height } - } - } - - MouseArea { anchors.fill: wrapper; onClicked: { photoClicked() } } - - states: [ - State { - name: "Details" - PropertyChanges { target: imageDetails; z: 2 } - ParentChange { target: wrapper; parent: imageDetails.frontContainer } - PropertyChanges { target: wrapper; x: 45; y: 35; scale: 1; z: 1000 } - PropertyChanges { target: itemRotation; angle: 0 } - PropertyChanges { target: shadows; opacity: 0 } - PropertyChanges { target: imageDetails; y: 20 } - PropertyChanges { target: photoGridView; y: -480 } - PropertyChanges { target: photoPathView; y: -480 } - PropertyChanges { target: viewModeButton; opacity: 0 } - PropertyChanges { target: tagsEdit; opacity: 0 } - PropertyChanges { target: fetchButton; opacity: 0 } - PropertyChanges { target: categoryText; y: "-50" } - } - ] - - transitions: [ - Transition { - from: "*"; to: "Details" - SequentialAnimation { - ParentAnimation { - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } - } - } - }, - Transition { - from: "Details"; to: "*" - SequentialAnimation { - ParentAnimation { - NumberAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing.type: "InOutQuad" } - } - PropertyAction { targets: wrapper; properties: "z" } - } - } - ] - - } - } - ] - - Item { - id: background - - anchors.fill: parent - - Image { source: "common/pics/background.png"; anchors.fill: parent } - RssModel { id: rssModel; tags : tagsEdit.text } - Loading { anchors.centerIn: parent; visible: rssModel.status == 2 } - - GridView { - id: photoGridView; model: rssModel; delegate: photoDelegate; cacheBuffer: 100 - cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 - } - - PathView { - id: photoPathView; model: rssModel; delegate: photoDelegate - y: -380; width: 800; height: 330; pathItemCount: 10; z: 1 - path: Path { - startX: -50; startY: 40; - - PathAttribute { name: "scale"; value: 1 } - PathAttribute { name: "angle"; value: -45 } - - PathCubic { - x: 400; y: 220 - control1X: 140; control1Y: 40 - control2X: 210; control2Y: 220 - } - - PathAttribute { name: "scale"; value: 1.2 } - PathAttribute { name: "z"; value: 1 } - PathAttribute { name: "angle"; value: 0 } - - PathCubic { - x: 850; y: 40 - control2X: 660; control2Y: 40 - control1X: 590; control1Y: 220 - } - - PathAttribute { name: "scale"; value: 1 } - PathAttribute { name: "angle"; value: 45 } - } - - } - - ImageDetails { id: imageDetails; width: 750; x: 25; y: 500; height: 410 } - - MediaButton { - id: viewModeButton; x: 680; y: 410; text: "View Mode" - onClicked: { if (mainWindow.showPathView == true) mainWindow.showPathView = false; else mainWindow.showPathView = true } - } - - MediaButton { - id: fetchButton - text: "Update" - anchors.right: viewModeButton.left; anchors.rightMargin: 5 - anchors.top: viewModeButton.top - onClicked: { rssModel.reload(); } - } - - MediaLineEdit { - id: tagsEdit; - label: "Tags" - anchors.right: fetchButton.left; anchors.rightMargin: 5 - anchors.top: viewModeButton.top - } - - states: State { - name: "PathView" - when: mainWindow.showPathView == true - PropertyChanges { target: photoPathView; y: 80 } - PropertyChanges { target: photoGridView; y: -380 } - } - - transitions: [ - Transition { - from: "*"; to: "*" - NumberAnimation { properties: "y"; duration: 1000; easing.type: "OutBounce"; easing.amplitude: 0.5 } - } - ] - } - - Text { - id: categoryText; anchors.horizontalCenter: parent.horizontalCenter; y: 15; - text: "Flickr - " + - (rssModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + rssModel.tags) - font.pointSize: 20; font.bold: true; color: "white"; style: Text.Raised; styleColor: "black" - } -} diff --git a/demos/declarative/flickr/flickr-mobile-90.qml b/demos/declarative/flickr/flickr-mobile-90.qml deleted file mode 100644 index 9fec242..0000000 --- a/demos/declarative/flickr/flickr-mobile-90.qml +++ /dev/null @@ -1,11 +0,0 @@ -import Qt 4.6 - -Item { - width: 480; height: 320 - - Loader { - y: 320; rotation: -90 - transformOrigin: Item.TopLeft - source: "flickr-mobile.qml" - } -} diff --git a/demos/declarative/flickr/flickr-mobile.qml b/demos/declarative/flickr/flickr-mobile.qml deleted file mode 100644 index 21e4c49..0000000 --- a/demos/declarative/flickr/flickr-mobile.qml +++ /dev/null @@ -1,82 +0,0 @@ -import Qt 4.6 -import "common" as Common -import "mobile" as Mobile - -Item { - id: screen; width: 320; height: 480 - property bool inListView : false - - Rectangle { - id: background - anchors.fill: parent; color: "#343434"; - - Image { source: "mobile/images/stripes.png"; fillMode: Image.Tile; anchors.fill: parent; opacity: 0.3 } - - Common.RssModel { id: rssModel } - Common.Loading { anchors.centerIn: parent; visible: rssModel.status == 2 } - - Item { - id: views - x: 2; width: parent.width - 4 - anchors.top: titleBar.bottom; anchors.bottom: toolBar.top - - Mobile.GridDelegate { id: gridDelegate } - GridView { - id: photoGridView; model: rssModel; delegate: gridDelegate; cacheBuffer: 100 - cellWidth: 79; cellHeight: 79; width: parent.width; height: parent.height - 1; z: 6 - } - - Mobile.ListDelegate { id: listDelegate } - ListView { - id: photoListView; model: rssModel; delegate: listDelegate; z: 6 - width: parent.width; height: parent.height; x: -(parent.width * 1.5); cacheBuffer: 100; - } - states: State { - name: "ListView"; when: screen.inListView == true - PropertyChanges { target: photoListView; x: 0 } - PropertyChanges { target: photoGridView; x: -(parent.width * 1.5) } - } - - transitions: Transition { - NumberAnimation { properties: "x"; duration: 500; easing.type: "InOutQuad" } - } - } - - Mobile.ImageDetails { id: imageDetails; width: parent.width; anchors.left: views.right; height: parent.height; z:1 } - Mobile.TitleBar { id: titleBar; z: 5; width: parent.width; height: 40; opacity: 0.9 } - - Mobile.ToolBar { - id: toolBar; z: 5 - height: 40; anchors.bottom: parent.bottom; width: parent.width; opacity: 0.9 - button1Label: "Update"; button2Label: "View mode" - onButton1Clicked: rssModel.reload() - onButton2Clicked: if (screen.inListView == true) screen.inListView = false; else screen.inListView = true - } - - Connections { - target: imageDetails - onClosed: { - if (background.state == "DetailedView") { - background.state = ''; - imageDetails.photoUrl = ""; - } - } - } - - states: State { - name: "DetailedView" - PropertyChanges { target: views; x: -parent.width } - PropertyChanges { target: toolBar; button1Label: "More..." } - PropertyChanges { - target: toolBar - onButton1Clicked: if (imageDetails.state=='') imageDetails.state='Back'; else imageDetails.state='' - } - PropertyChanges { target: toolBar; button2Label: "Back" } - PropertyChanges { target: toolBar; onButton2Clicked: imageDetails.closed() } - } - - transitions: Transition { - NumberAnimation { properties: "x"; duration: 500; easing.type: "InOutQuad" } - } - } -} diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr.qml new file mode 100644 index 0000000..21e4c49 --- /dev/null +++ b/demos/declarative/flickr/flickr.qml @@ -0,0 +1,82 @@ +import Qt 4.6 +import "common" as Common +import "mobile" as Mobile + +Item { + id: screen; width: 320; height: 480 + property bool inListView : false + + Rectangle { + id: background + anchors.fill: parent; color: "#343434"; + + Image { source: "mobile/images/stripes.png"; fillMode: Image.Tile; anchors.fill: parent; opacity: 0.3 } + + Common.RssModel { id: rssModel } + Common.Loading { anchors.centerIn: parent; visible: rssModel.status == 2 } + + Item { + id: views + x: 2; width: parent.width - 4 + anchors.top: titleBar.bottom; anchors.bottom: toolBar.top + + Mobile.GridDelegate { id: gridDelegate } + GridView { + id: photoGridView; model: rssModel; delegate: gridDelegate; cacheBuffer: 100 + cellWidth: 79; cellHeight: 79; width: parent.width; height: parent.height - 1; z: 6 + } + + Mobile.ListDelegate { id: listDelegate } + ListView { + id: photoListView; model: rssModel; delegate: listDelegate; z: 6 + width: parent.width; height: parent.height; x: -(parent.width * 1.5); cacheBuffer: 100; + } + states: State { + name: "ListView"; when: screen.inListView == true + PropertyChanges { target: photoListView; x: 0 } + PropertyChanges { target: photoGridView; x: -(parent.width * 1.5) } + } + + transitions: Transition { + NumberAnimation { properties: "x"; duration: 500; easing.type: "InOutQuad" } + } + } + + Mobile.ImageDetails { id: imageDetails; width: parent.width; anchors.left: views.right; height: parent.height; z:1 } + Mobile.TitleBar { id: titleBar; z: 5; width: parent.width; height: 40; opacity: 0.9 } + + Mobile.ToolBar { + id: toolBar; z: 5 + height: 40; anchors.bottom: parent.bottom; width: parent.width; opacity: 0.9 + button1Label: "Update"; button2Label: "View mode" + onButton1Clicked: rssModel.reload() + onButton2Clicked: if (screen.inListView == true) screen.inListView = false; else screen.inListView = true + } + + Connections { + target: imageDetails + onClosed: { + if (background.state == "DetailedView") { + background.state = ''; + imageDetails.photoUrl = ""; + } + } + } + + states: State { + name: "DetailedView" + PropertyChanges { target: views; x: -parent.width } + PropertyChanges { target: toolBar; button1Label: "More..." } + PropertyChanges { + target: toolBar + onButton1Clicked: if (imageDetails.state=='') imageDetails.state='Back'; else imageDetails.state='' + } + PropertyChanges { target: toolBar; button2Label: "Back" } + PropertyChanges { target: toolBar; onButton2Clicked: imageDetails.closed() } + } + + transitions: Transition { + NumberAnimation { properties: "x"; duration: 500; easing.type: "InOutQuad" } + } + } +} -- cgit v0.12