From fd9312e358a9ee24f8a83a6d4c78c7816ab3c95c Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 14 Oct 2009 14:37:04 +1000 Subject: Add toArrayIndex method --- src/script/bridge/qscriptdeclarativeclass.cpp | 7 +++++++ src/script/bridge/qscriptdeclarativeclass_p.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index d019839..1e59f66 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -258,6 +258,13 @@ QString QScriptDeclarativeClass::toString(const Identifier &identifier) return QString((QChar *)r->data(), r->size()); } +quint32 QScriptDeclarativeClass::toArrayIndex(const Identifier &identifier, bool *ok) +{ + JSC::UString::Rep *r = (JSC::UString::Rep *)identifier; + JSC::UString s(r); + return s.toArrayIndex(ok); +} + QScriptClass::QueryFlags QScriptDeclarativeClass::queryProperty(Object *object, const Identifier &name, QScriptClass::QueryFlags flags) diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index b28209a..559e842 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -103,6 +103,7 @@ public: PersistentIdentifier createPersistentIdentifier(const Identifier &); QString toString(const Identifier &); + quint32 toArrayIndex(const Identifier &, bool *ok); virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, QScriptClass::QueryFlags flags); -- cgit v0.12 From 339c91215f0bae4af44fe3124f41244541607a2b Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 14 Oct 2009 14:49:45 +1000 Subject: Add QML_REWRITE_DUMP env flag --- src/declarative/qml/qmlrewrite.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/declarative/qml/qmlrewrite.cpp b/src/declarative/qml/qmlrewrite.cpp index 5166c96..a41b571 100644 --- a/src/declarative/qml/qmlrewrite.cpp +++ b/src/declarative/qml/qmlrewrite.cpp @@ -40,9 +40,13 @@ ****************************************************************************/ #include "qmlrewrite_p.h" +#include +#include QT_BEGIN_NAMESPACE +DEFINE_BOOL_CONFIG_OPTION(rewriteDump, QML_REWRITE_DUMP); + namespace QmlRewrite { QString RewriteBinding::operator()(const QString &code) @@ -76,8 +80,20 @@ QString RewriteBinding::rewrite(QString code, unsigned position, _writer->replace(startOfStatement, 0, QLatin1String("(function() { ")); _writer->replace(endOfStatement, 0, QLatin1String(" })")); + if (rewriteDump()) { + qWarning() << "============================================================="; + qWarning() << "Rewrote:"; + qWarning() << qPrintable(code); + } + w.write(&code); + if (rewriteDump()) { + qWarning() << "To:"; + qWarning() << qPrintable(code); + qWarning() << "============================================================="; + } + return code; } -- cgit v0.12 From 4922be635aeaf25343892a73b30ec0d99d467e37 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 14 Oct 2009 15:12:55 +1000 Subject: Support read-only iteration of list properties Eventually this should be extended to support modifying list properties. --- src/declarative/qml/qml.pri | 6 +- src/declarative/qml/qmlengine.cpp | 4 + src/declarative/qml/qmlengine_p.h | 2 + src/declarative/qml/qmllistscriptclass.cpp | 141 +++++++++++++++++++++ src/declarative/qml/qmllistscriptclass_p.h | 85 +++++++++++++ src/declarative/qml/qmlobjectscriptclass.cpp | 12 +- .../qmlecmascript/data/listProperties.qml | 44 +++++++ tests/auto/declarative/qmlecmascript/testtypes.h | 13 +- .../qmlecmascript/tst_qmlecmascript.cpp | 20 +++ 9 files changed, 320 insertions(+), 7 deletions(-) create mode 100644 src/declarative/qml/qmllistscriptclass.cpp create mode 100644 src/declarative/qml/qmllistscriptclass_p.h create mode 100644 tests/auto/declarative/qmlecmascript/data/listProperties.qml diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 2e62a3b..58a18a2 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -44,7 +44,8 @@ SOURCES += qml/qmlparser.cpp \ qml/qmlcontextscriptclass.cpp \ qml/qmlglobalscriptclass.cpp \ qml/qmlvaluetypescriptclass.cpp \ - qml/qmltypenamescriptclass.cpp + qml/qmltypenamescriptclass.cpp \ + qml/qmllistscriptclass.cpp HEADERS += qml/qmlparser_p.h \ qml/qmlinstruction_p.h \ @@ -105,7 +106,8 @@ HEADERS += qml/qmlparser_p.h \ qml/qmlcontextscriptclass_p.h \ qml/qmlglobalscriptclass_p.h \ qml/qmlvaluetypescriptclass_p.h \ - qml/qmltypenamescriptclass_p.h + qml/qmltypenamescriptclass_p.h \ + qml/qmllistscriptclass_p.h # for qtscript debugger contains(QT_CONFIG, scripttools):QT += scripttools diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 7e95428..4dbc336 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -86,6 +86,7 @@ #include #include #include +#include #ifdef Q_OS_WIN // for %APPDATA% #include "qt_windows.h" @@ -173,6 +174,8 @@ QmlEnginePrivate::~QmlEnginePrivate() valueTypeClass = 0; delete typeNameClass; typeNameClass = 0; + delete listClass; + listClass = 0; delete networkAccessManager; networkAccessManager = 0; delete nodeListClass; @@ -218,6 +221,7 @@ void QmlEnginePrivate::init() objectClass = new QmlObjectScriptClass(q); valueTypeClass = new QmlValueTypeScriptClass(q); typeNameClass = new QmlTypeNameScriptClass(q); + listClass = new QmlListScriptClass(q); rootContext = new QmlContext(q,true); #ifdef QT_SCRIPTTOOLS_LIB if (qmlDebugger()){ diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 4c90a80..a85ac55 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -96,6 +96,7 @@ class QScriptDeclarativeClass; class QmlTypeNameScriptClass; class QmlTypeNameCache; class QmlComponentAttached; +class QmlListScriptClass; class QmlEnginePrivate : public QObjectPrivate { @@ -129,6 +130,7 @@ public: QmlObjectScriptClass *objectClass; QmlValueTypeScriptClass *valueTypeClass; QmlTypeNameScriptClass *typeNameClass; + QmlListScriptClass *listClass; // Global script class QScriptClass *globalClass; // Used by DOM Core 3 API diff --git a/src/declarative/qml/qmllistscriptclass.cpp b/src/declarative/qml/qmllistscriptclass.cpp new file mode 100644 index 0000000..09bde8c --- /dev/null +++ b/src/declarative/qml/qmllistscriptclass.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmllistscriptclass_p.h" +#include + +QT_BEGIN_NAMESPACE + +struct ListData : public QScriptDeclarativeClass::Object { + QGuard object; + int propertyIdx; + QmlListScriptClass::ListType type; +}; + +QmlListScriptClass::QmlListScriptClass(QmlEngine *e) +: QScriptDeclarativeClass(QmlEnginePrivate::getScriptEngine(e)), engine(e) +{ + QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); + + m_lengthId = createPersistentIdentifier(QLatin1String("length")); +} + +QmlListScriptClass::~QmlListScriptClass() +{ +} + +QScriptValue QmlListScriptClass::newList(QObject *object, int propId, ListType type) +{ + QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); + + if (!object || propId == -1) + return scriptEngine->nullValue(); + + ListData *data = new ListData; + data->object = object; + data->propertyIdx = propId; + data->type = type; + + return newObject(scriptEngine, this, data); +} + +QScriptClass::QueryFlags +QmlListScriptClass::queryProperty(Object *object, const Identifier &name, + QScriptClass::QueryFlags flags) +{ + if (name == m_lengthId.identifier) + return QScriptClass::HandlesReadAccess; + + bool ok = false; + quint32 idx = toArrayIndex(name, &ok); + + if (ok) { + lastIndex = idx; + return QScriptClass::HandlesReadAccess; + } else { + return 0; + } +} + +QScriptValue QmlListScriptClass::property(Object *obj, const Identifier &name) +{ + QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); + QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine); + + ListData *data = (ListData *)obj; + if (!data->object) + return scriptEngine->undefinedValue(); + + void *list = 0; + void *args[] = { &list, 0 }; + QMetaObject::metacall(data->object, QMetaObject::ReadProperty, + data->propertyIdx, args); + + if (!list) + return scriptEngine->undefinedValue(); + + if (data->type == QListPtr) { + const QList &qlist = *((QList*)list); + + if (name == m_lengthId.identifier) + return qlist.count(); + else if (lastIndex < qlist.count()) + return enginePriv->objectClass->newQObject(qlist.at(lastIndex)); + else + return scriptEngine->undefinedValue(); + + } else { + Q_ASSERT(data->type == QmlListPtr); + const QmlList &qmllist = *((QmlList*)list); + + int count = qmllist.count(); + + if (name == m_lengthId.identifier) + return count; + else if (lastIndex < count) + return enginePriv->objectClass->newQObject(qmllist.at(lastIndex)); + else + return scriptEngine->undefinedValue(); + } +} + +QT_END_NAMESPACE + diff --git a/src/declarative/qml/qmllistscriptclass_p.h b/src/declarative/qml/qmllistscriptclass_p.h new file mode 100644 index 0000000..7592098 --- /dev/null +++ b/src/declarative/qml/qmllistscriptclass_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLLISTSCRIPTCLASS_P_H +#define QMLLISTSCRIPTCLASS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QmlEngine; +class QmlListScriptClass : public QScriptDeclarativeClass +{ +public: + QmlListScriptClass(QmlEngine *); + ~QmlListScriptClass(); + + enum ListType { QListPtr, QmlListPtr }; + QScriptValue newList(QObject *, int, ListType); + +protected: + virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &, + QScriptClass::QueryFlags flags); + virtual QScriptValue property(Object *, const Identifier &); + +private: + PersistentIdentifier m_lengthId; + QmlEngine *engine; + + quint32 lastIndex; +}; + +QT_END_NAMESPACE + +#endif // QMLLISTSCRIPTCLASS_P_H + diff --git a/src/declarative/qml/qmlobjectscriptclass.cpp b/src/declarative/qml/qmlobjectscriptclass.cpp index 80f2786..122db51 100644 --- a/src/declarative/qml/qmlobjectscriptclass.cpp +++ b/src/declarative/qml/qmlobjectscriptclass.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -64,8 +65,7 @@ QmlObjectScriptClass::QmlObjectScriptClass(QmlEngine *bindEngine) : QScriptDeclarativeClass(QmlEnginePrivate::getScriptEngine(bindEngine)), lastData(0), engine(bindEngine) { - engine = bindEngine; - QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(bindEngine); + QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine); m_destroy = scriptEngine->newFunction(destroy); m_destroyId = createPersistentIdentifier(QLatin1String("destroy")); @@ -214,7 +214,13 @@ QScriptValue QmlObjectScriptClass::property(QObject *obj, const Identifier &name return enginePriv->valueTypeClass->newObject(obj, lastData->coreIndex, valueType); } - if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) { + if (lastData->flags & QmlPropertyCache::Data::IsQList) { + return enginePriv->listClass->newList(obj, lastData->coreIndex, + QmlListScriptClass::QListPtr); + } else if (lastData->flags & QmlPropertyCache::Data::IsQmlList) { + return enginePriv->listClass->newList(obj, lastData->coreIndex, + QmlListScriptClass::QmlListPtr); + } if (lastData->flags & QmlPropertyCache::Data::IsQObjectDerived) { QObject *rv = 0; void *args[] = { &rv, 0 }; QMetaObject::metacall(obj, QMetaObject::ReadProperty, lastData->coreIndex, args); diff --git a/tests/auto/declarative/qmlecmascript/data/listProperties.qml b/tests/auto/declarative/qmlecmascript/data/listProperties.qml new file mode 100644 index 0000000..73a1d6f --- /dev/null +++ b/tests/auto/declarative/qmlecmascript/data/listProperties.qml @@ -0,0 +1,44 @@ +import Qt.test 1.0 +import Qt 4.6 + +MyQmlObject { + id: root + + objectListProperty: [ + Object { property int a: 10 }, + Object { property int a: 11 } + ] + + objectQmlListProperty: [ + Object { property int a: 10 }, + Object { property int a: 1 }, + Object { property int a: 39 } + ] + + Script { + function calcTest1() { + var rv = 0; + for (var ii = 0; ii < root.objectListProperty.length; ++ii) { + rv += root.objectListProperty[ii].a; + } + return rv; + } + + function calcTest2() { + var rv = 0; + for (var ii = 0; ii < root.objectQmlListProperty.length; ++ii) { + rv += root.objectQmlListProperty[ii].a; + } + return rv; + } + } + + property int test1: calcTest1(); + property int test2: root.objectListProperty.length + property int test3: calcTest2(); + property int test4: root.objectQmlListProperty.length + property bool test5: root.objectQmlListProperty[1] != undefined + property bool test6: root.objectQmlListProperty[100] == undefined + property bool test7: root.objectListProperty[1] != undefined + property bool test8: root.objectListProperty[100] == undefined +} diff --git a/tests/auto/declarative/qmlecmascript/testtypes.h b/tests/auto/declarative/qmlecmascript/testtypes.h index e6c2c20..ae3a954 100644 --- a/tests/auto/declarative/qmlecmascript/testtypes.h +++ b/tests/auto/declarative/qmlecmascript/testtypes.h @@ -6,6 +6,7 @@ #include #include #include +#include #include class MyQmlAttachedObject : public QObject @@ -23,11 +24,14 @@ class MyQmlObject : public QObject Q_OBJECT Q_ENUMS(MyEnum) Q_ENUMS(MyEnum2) - Q_PROPERTY(int deleteOnSet READ deleteOnSet WRITE setDeleteOnSet); + Q_PROPERTY(int deleteOnSet READ deleteOnSet WRITE setDeleteOnSet) Q_PROPERTY(bool trueProperty READ trueProperty CONSTANT) Q_PROPERTY(bool falseProperty READ falseProperty CONSTANT) Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringChanged) - Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged); + Q_PROPERTY(QObject *objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectChanged) + Q_PROPERTY(QmlList *objectQmlListProperty READ objectQmlListProperty CONSTANT) + Q_PROPERTY(QList *objectListProperty READ objectListProperty CONSTANT) + public: MyQmlObject(): m_methodCalled(false), m_methodIntCalled(false), m_object(0) {} @@ -54,6 +58,9 @@ public: emit objectChanged(); } + QmlList *objectQmlListProperty() { return &m_objectQmlList; } + QList *objectListProperty() { return &m_objectQList; } + bool methodCalled() const { return m_methodCalled; } bool methodIntCalled() const { return m_methodIntCalled; } @@ -84,6 +91,8 @@ private: QObject *m_object; QString m_string; + QmlConcreteList m_objectQmlList; + QList m_objectQList; }; QML_DECLARE_TYPE(MyQmlObject); diff --git a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp index 7fb1703..f24882a 100644 --- a/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp +++ b/tests/auto/declarative/qmlecmascript/tst_qmlecmascript.cpp @@ -63,6 +63,7 @@ private slots: void extendedObjectPropertyLookup(); void scriptErrors(); void signalTriggeredBindings(); + void listProperties(); private: QmlEngine engine; @@ -787,6 +788,25 @@ void tst_qmlecmascript::signalTriggeredBindings() QCOMPARE(object->property("test2").toReal(), 400.); } +/* +Test that list properties can be iterated from ECMAScript +*/ +void tst_qmlecmascript::listProperties() +{ + QmlComponent component(&engine, TEST_FILE("listProperties.qml")); + MyQmlObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QCOMPARE(object->property("test1").toInt(), 21); + QCOMPARE(object->property("test2").toInt(), 2); + QCOMPARE(object->property("test3").toInt(), 50); + QCOMPARE(object->property("test4").toInt(), 3); + QCOMPARE(object->property("test5").toBool(), true); + QCOMPARE(object->property("test6").toBool(), true); + QCOMPARE(object->property("test7").toBool(), true); + QCOMPARE(object->property("test8").toBool(), true); +} + QTEST_MAIN(tst_qmlecmascript) #include "tst_qmlecmascript.moc" -- cgit v0.12 From c84227fbd5e068859f8de15e4c522b076885b9dc Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 14 Oct 2009 15:15:10 +1000 Subject: Add list accessors for Item::children and Item::resources --- src/declarative/fx/qfxitem.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index 6324724..903fad7 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -1483,8 +1483,8 @@ void QFxItemPrivate::resources_removeAt(int) int QFxItemPrivate::resources_count() const { - // ### - return 0; + Q_Q(const QFxItem); + return q->children().count(); } void QFxItemPrivate::resources_append(QObject *o) @@ -1498,10 +1498,14 @@ void QFxItemPrivate::resources_insert(int, QObject *) // ### } -QObject *QFxItemPrivate::resources_at(int) const +QObject *QFxItemPrivate::resources_at(int idx) const { - // ### - return 0; + Q_Q(const QFxItem); + QObjectList children = q->children(); + if (idx < children.count()) + return children.at(idx); + else + return 0; } void QFxItemPrivate::resources_clear() @@ -1516,8 +1520,8 @@ void QFxItemPrivate::children_removeAt(int) int QFxItemPrivate::children_count() const { - // ### - return 0; + Q_Q(const QFxItem); + return q->childItems().count(); } void QFxItemPrivate::children_append(QFxItem *i) @@ -1531,10 +1535,14 @@ void QFxItemPrivate::children_insert(int, QFxItem *) // ### } -QFxItem *QFxItemPrivate::children_at(int) const +QFxItem *QFxItemPrivate::children_at(int idx) const { - // ### - return 0; + Q_Q(const QFxItem); + QList children = q->childItems(); + if (idx < children.count()) + return qobject_cast(children.at(idx)); + else + return 0; } void QFxItemPrivate::children_clear() -- cgit v0.12 From ce33aa1fd8973cf066d0e5b8fc88971404d6b037 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 14 Oct 2009 15:46:37 +1000 Subject: Fix memory leak and remove redundant ContextIdRole. --- tools/qmldebugger/objectpropertiesview.cpp | 22 ++++++++++++++++------ tools/qmldebugger/objecttree.cpp | 4 ++-- tools/qmldebugger/objecttree.h | 4 ---- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/tools/qmldebugger/objectpropertiesview.cpp b/tools/qmldebugger/objectpropertiesview.cpp index 2237fbb..f725194 100644 --- a/tools/qmldebugger/objectpropertiesview.cpp +++ b/tools/qmldebugger/objectpropertiesview.cpp @@ -1,3 +1,5 @@ +#include + #include #include @@ -53,6 +55,9 @@ ObjectPropertiesView::ObjectPropertiesView(QmlEngineDebug *client, QWidget *pare void ObjectPropertiesView::reload(const QmlDebugObjectReference &obj) { + if (m_query) + delete m_query; + m_query = m_client->queryObjectRecursive(obj, this); if (!m_query->isWaiting()) queryFinished(); @@ -63,16 +68,20 @@ void ObjectPropertiesView::reload(const QmlDebugObjectReference &obj) void ObjectPropertiesView::queryFinished() { - if (m_watch) { - m_client->removeWatch(m_watch); - delete m_watch; - m_watch = 0; - } + if (!m_query) + return; QmlDebugObjectReference obj = m_query->object(); QmlDebugWatch *watch = m_client->addWatch(obj, this); - if (watch->state() != QmlDebugWatch::Dead) { + if (watch->state() == QmlDebugWatch::Dead) { + delete watch; + watch = 0; + } else { + if (m_watch) { + m_client->removeWatch(m_watch); + delete m_watch; + } m_watch = watch; QObject::connect(watch, SIGNAL(valueChanged(QByteArray,QVariant)), this, SLOT(valueChanged(QByteArray,QVariant))); @@ -89,6 +98,7 @@ void ObjectPropertiesView::setObject(const QmlDebugObjectReference &object) m_object = object; m_tree->clear(); + QList properties = object.properties(); for (int i=0; isetText(0, obj.className()); item->setData(0, Qt::UserRole, qVariantFromValue(obj)); - item->setData(0, ObjectTree::ContextIdRole, obj.contextDebugId()); if (parent && obj.contextDebugId() >= 0 - && obj.contextDebugId() != parent->data(0, ObjectTree::ContextIdRole).toInt()) { + && obj.contextDebugId() != parent->data(0, Qt::UserRole + ).value().contextDebugId()) { QmlDebugFileReference source = obj.source(); if (!source.url().isEmpty()) { QString toolTipString = QLatin1String("URL: ") + source.url().toString(); diff --git a/tools/qmldebugger/objecttree.h b/tools/qmldebugger/objecttree.h index a924ec5..bba6c08 100644 --- a/tools/qmldebugger/objecttree.h +++ b/tools/qmldebugger/objecttree.h @@ -17,10 +17,6 @@ class ObjectTree : public QTreeWidget { Q_OBJECT public: - enum AdditionalRoles { - ContextIdRole = Qt::UserRole + 1 - }; - ObjectTree(QmlEngineDebug *client, QWidget *parent = 0); signals: -- cgit v0.12 From 11ad93f85fb888cfdfb8a534dcde7f536f13e1a2 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 14 Oct 2009 15:42:58 +1000 Subject: Preserve visual appearance in more cases for ParentChange. Task-number: QT-747 --- src/declarative/util/qmlstateoperations.cpp | 77 ++++++++++++----------------- 1 file changed, 32 insertions(+), 45 deletions(-) diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index 716cec4..07eb641 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -48,11 +48,14 @@ #include #include #include +#include +#include QT_BEGIN_NAMESPACE class QmlParentChangePrivate : public QObjectPrivate { + Q_DECLARE_PUBLIC(QmlParentChange) public: QmlParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0) {} @@ -67,53 +70,37 @@ public: void QmlParentChangePrivate::doChange(QFxItem *targetParent, QFxItem *stackBefore) { if (targetParent && target && target->parentItem()) { - QPointF me = target->parentItem()->mapToScene(QPointF(0,0)); - QPointF them = targetParent->mapToScene(QPointF(0,0)); - - QPointF themx = targetParent->mapToScene(QPointF(1,0)); - QPointF themy = targetParent->mapToScene(QPointF(0,1)); - - themx -= them; - themy -= them; - - target->setParentItem(targetParent); - - // XXX - this is silly and will only work in a few cases - - /* - xDiff = rx * themx_x + ry * themy_x - yDiff = rx * themx_y + ry * themy_y - */ - - qreal rx = 0; - qreal ry = 0; - qreal xDiff = them.x() - me.x(); - qreal yDiff = them.y() - me.y(); - - - if (themx.x() == 0.) { - ry = xDiff / themy.x(); - rx = (yDiff - ry * themy.y()) / themx.y(); - } else if (themy.x() == 0.) { - rx = xDiff / themx.x(); - ry = (yDiff - rx * themx.y()) / themy.y(); - } else if (themx.y() == 0.) { - ry = yDiff / themy.y(); - rx = (xDiff - ry * themy.x()) / themx.x(); - } else if (themy.y() == 0.) { - rx = yDiff / themx.y(); - ry = (xDiff - rx * themx.x()) / themy.x(); - } else { - qreal div = (themy.x() * themx.y() - themy.y() * themx.x()); - - if (div != 0.) - rx = (themx.y() * xDiff - themx.x() * yDiff) / div; - - if (themy.y() != 0.) ry = (yDiff - rx * themx.y()) / themy.y(); + //### for backwards direction, we can just restore original x, y, scale, rotation + Q_Q(QmlParentChange); + const QTransform &transform = target->itemTransform(targetParent); + if (transform.type() >= QTransform::TxShear) { + qmlInfo(QObject::tr("Unable to preserve appearance under complex transform"), q); } - target->setX(target->x() - rx); - target->setY(target->y() - ry); + qreal scale = 1; + qreal rotation = 0; + if (transform.type() != QTransform::TxRotate) { + if (transform.m11() == transform.m22()) + scale = transform.m11(); + else + qmlInfo(QObject::tr("Unable to preserve appearance under non-uniform scale"), q); + } else if (transform.type() == QTransform::TxRotate) { + if (transform.m11() == transform.m22()) + scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12()); + else + qmlInfo(QObject::tr("Unable to preserve appearance under non-uniform scale"), q); + + if (scale != 0) + rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI; + else + qmlInfo(QObject::tr("Unable to preserve appearance under scale of 0"), q); + } + target->setParentItem(targetParent); + //qDebug() << transform.dx() << transform.dy() << rotation << scale; + target->setX(transform.dx()); + target->setY(transform.dy()); + target->setRotation(rotation); + target->setScale(scale); } else if (target) { target->setParentItem(targetParent); } -- cgit v0.12 From 984cb207df0c409ff166d12a194e6e8340950ba1 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 14 Oct 2009 15:46:13 +1000 Subject: Minor fixes for qmlInfo. --- src/declarative/qml/qmlinfo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qmlinfo.cpp b/src/declarative/qml/qmlinfo.cpp index 862d6ba..119641f 100644 --- a/src/declarative/qml/qmlinfo.cpp +++ b/src/declarative/qml/qmlinfo.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE For example, \code - qmlInfo(object, tr("component property is a write-once property")); + qmlInfo(tr("component property is a write-once property"), object); \endcode prints @@ -77,7 +77,7 @@ void qmlInfo(const QString& msg, QObject* object) { QString pos = QLatin1String("QML"); if (object) { - pos += " "; + pos += QLatin1Char(' '); pos += QLatin1String(object->metaObject()->className()); } QmlDeclarativeData *ddata = QmlDeclarativeData::get(object); -- cgit v0.12 From 82412ca0e8afde645b0e515b36b1c7ccf00c78ab Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 14 Oct 2009 15:47:52 +1000 Subject: Doc --- doc/src/declarative/qmldocument.qdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/declarative/qmldocument.qdoc b/doc/src/declarative/qmldocument.qdoc index 84e7926..2775ea6 100644 --- a/doc/src/declarative/qmldocument.qdoc +++ b/doc/src/declarative/qmldocument.qdoc @@ -71,6 +71,8 @@ Rectangle { } \endcode +QML documents are always encoded in UTF-8 format. + A QML document always begins with one or more import statements. To prevent elements introduced in later versions from affecting existing QML programs, the element types available within a document are controlled by the imported QML \l {Modules}. That is, -- cgit v0.12 From 2cb6b94e4587f32a109e0b7c2283978f3d78c649 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Wed, 14 Oct 2009 16:07:44 +1000 Subject: ParentChange docs --- src/declarative/util/qmlstateoperations.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index 07eb641..60fd421 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -114,7 +114,16 @@ void QmlParentChangePrivate::doChange(QFxItem *targetParent, QFxItem *stackBefor /*! \preliminary \qmlclass ParentChange - \brief The ParentChange element allows you to reparent an object in a state. + \brief The ParentChange element allows you to reparent an Item in a state change. + + ParentChange reparents an Item while preserving its visual appearance (position, rotation, + and scale) on screen. You can then specify a transition to move/rotate/scale the Item to + its final intended appearance. + + ParentChange can only preserve visual appearance if no complex transforms are involved. + More specifically, it will not work if the transform property has been set for any + Items involved in the reparenting (defined as any Items in the common ancestor tree + for the original and new parent). */ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,ParentChange,QmlParentChange) -- cgit v0.12 From d03a920b47a863a73e73d200b91baf5368ba6f7f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 14 Oct 2009 16:18:24 +1000 Subject: Doc --- doc/src/declarative/binding.qdoc | 123 ------------------------------------- doc/src/declarative/qtbinding.qdoc | 123 +++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 123 deletions(-) delete mode 100644 doc/src/declarative/binding.qdoc create mode 100644 doc/src/declarative/qtbinding.qdoc diff --git a/doc/src/declarative/binding.qdoc b/doc/src/declarative/binding.qdoc deleted file mode 100644 index 94465a1..0000000 --- a/doc/src/declarative/binding.qdoc +++ /dev/null @@ -1,123 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\page qtbinding.html -\target qtbinding -\title QML/C++ Data Binding - -The QML mechanisms of data binding can also be used to bind Qt C++ objects. - -The data binding framework is based on Qt's property system (see the Qt documentation for more details on this system). If a binding is meant to be dynamic (where changes in one object are reflected in another object), \c NOTIFY must be specified for the property being tracked. If \c NOTIFY is not specified, any binding to that property will be an 'intialization' binding (the tracking object will be updated only once with the initial value of the tracked object). - -Relevant items can also be bound to the contents of a Qt model. -For example, ListView can make use of data from a QAbstractItemModel-derived model. - - -\section1 Passing Data Between C++ and QML - -Data binding provides one method of data transfer between C++ and QML. - -For example, lets say you want to implement a slider in QML that changes the screen brightness of the device it is running on. You would start by declaring a brightness property on your QObject-derived class: -\code -class MyScreen : public QObject -{ - Q_OBJECT -public: - MyScreen(QObject *parent=0); - - Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged); - int brightness() const; - void setBrightness(int b); - ... - -signals: - void brightnessChanged(); - -private: - int m_brightness; -}; - -int brightness() const -{ - return m_brightness; -} - -void setBrightness(int b) -{ - if (b != m_brightness) { - m_brightness = b; - emit brightnessChanged(); - - //set device brightness - ... - } -} -\endcode - -\note One important thing to keep in mind is that the changed signal should only be emitted when there is a real change ( \c b \c != \c m_brightness ), or you may get an infinite loop. - -Next, make an instance of this class visible to the QML bind engine: -\code -QmlView *view = new QmlView; -view->setUrl("MyUI.qml"); - -MyScreen *screen = new MyScreen; -QmlContext *ctxt = view->rootContext(); -ctxt->setContextProperty("screen", screen); - -view->execute(); -\endcode - -\note Bindings must be made after setUrl() but before execute(). - -Finally, in QML you can make the appropriate bindings, so in \c "MyUI.qml": - -\code -Slider { value: screen.brightness } -Binding { target: screen; property: "brightness"; value: slider.value } -\endcode - -The \l QBindableMap class provides a convenient way to make data visible to the bind engine. - -C++ \l {qmlmodels}{Data Models} may also be provided to QML. - -*/ diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc new file mode 100644 index 0000000..94465a1 --- /dev/null +++ b/doc/src/declarative/qtbinding.qdoc @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qtbinding.html +\target qtbinding +\title QML/C++ Data Binding + +The QML mechanisms of data binding can also be used to bind Qt C++ objects. + +The data binding framework is based on Qt's property system (see the Qt documentation for more details on this system). If a binding is meant to be dynamic (where changes in one object are reflected in another object), \c NOTIFY must be specified for the property being tracked. If \c NOTIFY is not specified, any binding to that property will be an 'intialization' binding (the tracking object will be updated only once with the initial value of the tracked object). + +Relevant items can also be bound to the contents of a Qt model. +For example, ListView can make use of data from a QAbstractItemModel-derived model. + + +\section1 Passing Data Between C++ and QML + +Data binding provides one method of data transfer between C++ and QML. + +For example, lets say you want to implement a slider in QML that changes the screen brightness of the device it is running on. You would start by declaring a brightness property on your QObject-derived class: +\code +class MyScreen : public QObject +{ + Q_OBJECT +public: + MyScreen(QObject *parent=0); + + Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged); + int brightness() const; + void setBrightness(int b); + ... + +signals: + void brightnessChanged(); + +private: + int m_brightness; +}; + +int brightness() const +{ + return m_brightness; +} + +void setBrightness(int b) +{ + if (b != m_brightness) { + m_brightness = b; + emit brightnessChanged(); + + //set device brightness + ... + } +} +\endcode + +\note One important thing to keep in mind is that the changed signal should only be emitted when there is a real change ( \c b \c != \c m_brightness ), or you may get an infinite loop. + +Next, make an instance of this class visible to the QML bind engine: +\code +QmlView *view = new QmlView; +view->setUrl("MyUI.qml"); + +MyScreen *screen = new MyScreen; +QmlContext *ctxt = view->rootContext(); +ctxt->setContextProperty("screen", screen); + +view->execute(); +\endcode + +\note Bindings must be made after setUrl() but before execute(). + +Finally, in QML you can make the appropriate bindings, so in \c "MyUI.qml": + +\code +Slider { value: screen.brightness } +Binding { target: screen; property: "brightness"; value: slider.value } +\endcode + +The \l QBindableMap class provides a convenient way to make data visible to the bind engine. + +C++ \l {qmlmodels}{Data Models} may also be provided to QML. + +*/ -- cgit v0.12