From 3307ee4fdf5c79a7f93f4edc8820990bf3432cf0 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 17 Nov 2009 13:24:54 +1000 Subject: Add offset tests and more invalid anchor tests --- tests/auto/declarative/anchors/data/anchors.qml | 18 +++++ tests/auto/declarative/anchors/data/illegal1.qml | 12 --- tests/auto/declarative/anchors/data/illegal2.qml | 13 ---- tests/auto/declarative/anchors/data/illegal3.qml | 12 --- tests/auto/declarative/anchors/tst_anchors.cpp | 96 +++++++++++++++++------- 5 files changed, 86 insertions(+), 65 deletions(-) delete mode 100644 tests/auto/declarative/anchors/data/illegal1.qml delete mode 100644 tests/auto/declarative/anchors/data/illegal2.qml delete mode 100644 tests/auto/declarative/anchors/data/illegal3.qml diff --git a/tests/auto/declarative/anchors/data/anchors.qml b/tests/auto/declarative/anchors/data/anchors.qml index b880762..b64d0b0 100644 --- a/tests/auto/declarative/anchors/data/anchors.qml +++ b/tests/auto/declarative/anchors/data/anchors.qml @@ -130,6 +130,24 @@ Rectangle { anchors.bottom: masterRect.bottom anchors.bottomMargin: 5 } + Rectangle { + id: rect24; objectName: "rect24" + width: 10; height: 10 + anchors.horizontalCenter: masterRect.left + anchors.horizontalCenterOffset: width/2 + } + Rectangle { + id: rect25; objectName: "rect25" + width: 10; height: 10 + anchors.verticalCenter: rect12.top + anchors.verticalCenterOffset: height/2 + } + Rectangle { + id: rect26; objectName: "rect26" + width: 10; height: 10 + anchors.baseline: masterRect.top + anchors.baselineOffset: height/2 + } Text { id: text1; objectName: "text1" y: 200; diff --git a/tests/auto/declarative/anchors/data/illegal1.qml b/tests/auto/declarative/anchors/data/illegal1.qml deleted file mode 100644 index 53af443..0000000 --- a/tests/auto/declarative/anchors/data/illegal1.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: rect - width: 120; height: 200; color: "white" - Rectangle { id: theRect; width: 100; height: 100 } - Rectangle { - anchors.left: theRect.left - anchors.right: theRect.right - anchors.horizontalCenter: theRect.horizontalCenter - } -} diff --git a/tests/auto/declarative/anchors/data/illegal2.qml b/tests/auto/declarative/anchors/data/illegal2.qml deleted file mode 100644 index 978be52..0000000 --- a/tests/auto/declarative/anchors/data/illegal2.qml +++ /dev/null @@ -1,13 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: rect - width: 120; height: 200; color: "white" - Text { id: text1; text: "Hello" } - Text { - id: text2; - anchors.baseline: text1.baseline; - anchors.top: text1.top; - text: "World" - } -} diff --git a/tests/auto/declarative/anchors/data/illegal3.qml b/tests/auto/declarative/anchors/data/illegal3.qml deleted file mode 100644 index 065ceb5..0000000 --- a/tests/auto/declarative/anchors/data/illegal3.qml +++ /dev/null @@ -1,12 +0,0 @@ -import Qt 4.6 - -Rectangle { - id: rect - width: 120; height: 200; color: "white" - Item { - Rectangle { id: theRect; width: 100; height: 100 } - } - Rectangle { - anchors.left: theRect.left - } -} diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp index 34c1e01..22f8327 100644 --- a/tests/auto/declarative/anchors/tst_anchors.cpp +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -60,6 +60,7 @@ private slots: void basicAnchors(); void loops(); void illegalSets(); + void illegalSets_data(); void reset(); void nullItem(); void crash1(); @@ -143,6 +144,11 @@ void tst_anchors::basicAnchors() QCOMPARE(findItem(view->root(), QLatin1String("rect23"))->width(), 86.0); QCOMPARE(findItem(view->root(), QLatin1String("rect23"))->height(), 10.0); + // offsets + QCOMPARE(findItem(view->root(), QLatin1String("rect24"))->x(), 26.0); + QCOMPARE(findItem(view->root(), QLatin1String("rect25"))->y(), 60.0); + QCOMPARE(findItem(view->root(), QLatin1String("rect26"))->y(), 5.0); + //baseline QmlGraphicsText *text1 = findItem(view->root(), QLatin1String("text1")); QmlGraphicsText *text2 = findItem(view->root(), QLatin1String("text2")); @@ -185,44 +191,71 @@ void tst_anchors::loops() void tst_anchors::illegalSets() { - { - QmlView *view = new QmlView; + QFETCH(QString, qml); + QFETCH(QString, warning); + + QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); + + QmlEngine engine; + QmlComponent component(&engine, QByteArray("import Qt 4.6\n" + qml.toUtf8()), QUrl("file://")); + if (!component.isReady()) + qWarning() << "Test errors:" << component.errors(); + QVERIFY(component.isReady()); + QObject *o = component.create(); + delete o; +} - view->setUrl(QUrl("file://" SRCDIR "/data/illegal1.qml")); +void tst_anchors::illegalSets_data() +{ + QTest::addColumn("qml"); + QTest::addColumn("warning"); - QString expect = "QML QmlGraphicsRectangle (" + view->url().toString() + ":7:5" + ") Can't specify left, right, and hcenter anchors."; - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - view->execute(); - qApp->processEvents(); + QTest::newRow("H - too many anchors") + << "Rectangle { id: rect; Rectangle { anchors.left: rect.left; anchors.right: rect.right; anchors.horizontalCenter: rect.horizontalCenter } }" + << "QML QmlGraphicsRectangle (file::2:23) Can't specify left, right, and hcenter anchors."; - delete view; - } + QTest::newRow("H - anchor to V") + << "Rectangle { Rectangle { anchors.left: parent.top } }" + << "QML QmlGraphicsRectangle (file::2:13) Can't anchor a horizontal edge to a vertical edge."; - { - QmlView *view = new QmlView; + QTest::newRow("H - anchor to non parent/sibling") + << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.left: rect.left } }" + << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; - view->setUrl(QUrl("file://" SRCDIR "/data/illegal2.qml")); + QTest::newRow("H - anchor to self") + << "Rectangle { id: rect; anchors.left: rect.left }" + << "QML QmlGraphicsRectangle (file::2:1) Can't anchor item to self."; - QString expect = "QML QmlGraphicsText (" + view->url().toString() + ":7:5" + ") Baseline anchor can't be used in conjunction with top, bottom, or vcenter anchors."; - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - view->execute(); - //qApp->processEvents(); - delete view; - } + QTest::newRow("V - too many anchors") + << "Rectangle { id: rect; Rectangle { anchors.top: rect.top; anchors.bottom: rect.bottom; anchors.verticalCenter: rect.verticalCenter } }" + << "QML QmlGraphicsRectangle (file::2:23) Can't specify top, bottom, and vcenter anchors."; - { - QmlView *view = new QmlView; + QTest::newRow("V - too many anchors with baseline") + << "Rectangle { Text { id: text1; text: \"Hello\" } Text { anchors.baseline: text1.baseline; anchors.top: text1.top; } }" + << "QML QmlGraphicsText (file::2:47) Baseline anchor can't be used in conjunction with top, bottom, or vcenter anchors."; - view->setUrl(QUrl("file://" SRCDIR "/data/illegal3.qml")); + QTest::newRow("V - anchor to H") + << "Rectangle { Rectangle { anchors.top: parent.left } }" + << "QML QmlGraphicsRectangle (file::2:13) Can't anchor a vertical edge to a horizontal edge."; - QString expect = "QML QmlGraphicsRectangle (" + view->url().toString() + ":9:5" + ") Can't anchor to an item that isn't a parent or sibling."; - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - view->execute(); - //qApp->processEvents(); + QTest::newRow("V - anchor to non parent/sibling") + << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.top: rect.top } }" + << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; - delete view; - } + QTest::newRow("V - anchor to self") + << "Rectangle { id: rect; anchors.top: rect.top }" + << "QML QmlGraphicsRectangle (file::2:1) Can't anchor item to self."; + + + QTest::newRow("centerIn - anchor to non parent/sibling") + << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.centerIn: rect} }" + << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; + + + QTest::newRow("fill - anchor to non parent/sibling") + << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.fill: rect} }" + << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; } void tst_anchors::reset() @@ -243,10 +276,17 @@ void tst_anchors::reset() void tst_anchors::nullItem() { QmlGraphicsAnchorLine anchor; + QmlGraphicsItem *item; QTest::ignoreMessage(QtWarningMsg, "QML QmlGraphicsItem (unknown location) Can't anchor to a null item."); - QmlGraphicsItem *item = new QmlGraphicsItem; + item = new QmlGraphicsItem; + item->anchors()->setLeft(anchor); + delete item; + + QTest::ignoreMessage(QtWarningMsg, "QML QmlGraphicsItem (unknown location) Can't anchor to a null item."); + item = new QmlGraphicsItem; item->anchors()->setBottom(anchor); + delete item; } void tst_anchors::crash1() -- cgit v0.12 From a493a5e104579c0a7908fc600be1fd622d6447ae Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 17 Nov 2009 13:47:16 +1000 Subject: Move debugger tests out of debugger/ subdir --- tests/auto/declarative/debugger/debugger.pro | 5 - tests/auto/declarative/debugger/debugutil.cpp | 173 ----- tests/auto/declarative/debugger/debugutil_p.h | 142 ---- .../declarative/debugger/qmldebug/qmldebug.pro | 7 - .../declarative/debugger/qmldebug/tst_qmldebug.cpp | 831 --------------------- .../debugger/qmldebugclient/qmldebugclient.pro | 7 - .../debugger/qmldebugclient/tst_qmldebugclient.cpp | 156 ---- .../debugger/qmldebugservice/qmldebugservice.pro | 7 - .../qmldebugservice/tst_qmldebugservice.cpp | 189 ----- .../debugger/qpacketprotocol/qpacketprotocol.pro | 7 - .../qpacketprotocol/tst_qpacketprotocol.cpp | 270 ------- tests/auto/declarative/declarative.pro | 7 +- tests/auto/declarative/qmldebug/qmldebug.pro | 7 + tests/auto/declarative/qmldebug/tst_qmldebug.cpp | 831 +++++++++++++++++++++ .../declarative/qmldebugclient/qmldebugclient.pro | 7 + .../qmldebugclient/tst_qmldebugclient.cpp | 156 ++++ .../qmldebugservice/qmldebugservice.pro | 7 + .../qmldebugservice/tst_qmldebugservice.cpp | 189 +++++ .../qpacketprotocol/qpacketprotocol.pro | 7 + .../qpacketprotocol/tst_qpacketprotocol.cpp | 270 +++++++ 20 files changed, 1478 insertions(+), 1797 deletions(-) delete mode 100644 tests/auto/declarative/debugger/debugger.pro delete mode 100644 tests/auto/declarative/debugger/debugutil.cpp delete mode 100644 tests/auto/declarative/debugger/debugutil_p.h delete mode 100644 tests/auto/declarative/debugger/qmldebug/qmldebug.pro delete mode 100644 tests/auto/declarative/debugger/qmldebug/tst_qmldebug.cpp delete mode 100644 tests/auto/declarative/debugger/qmldebugclient/qmldebugclient.pro delete mode 100644 tests/auto/declarative/debugger/qmldebugclient/tst_qmldebugclient.cpp delete mode 100644 tests/auto/declarative/debugger/qmldebugservice/qmldebugservice.pro delete mode 100644 tests/auto/declarative/debugger/qmldebugservice/tst_qmldebugservice.cpp delete mode 100644 tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro delete mode 100644 tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp create mode 100644 tests/auto/declarative/qmldebug/qmldebug.pro create mode 100644 tests/auto/declarative/qmldebug/tst_qmldebug.cpp create mode 100644 tests/auto/declarative/qmldebugclient/qmldebugclient.pro create mode 100644 tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp create mode 100644 tests/auto/declarative/qmldebugservice/qmldebugservice.pro create mode 100644 tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp create mode 100644 tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro create mode 100644 tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp diff --git a/tests/auto/declarative/debugger/debugger.pro b/tests/auto/declarative/debugger/debugger.pro deleted file mode 100644 index a341ca9..0000000 --- a/tests/auto/declarative/debugger/debugger.pro +++ /dev/null @@ -1,5 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += qmldebug \ - qmldebugclient \ - qmldebugservice \ - qpacketprotocol diff --git a/tests/auto/declarative/debugger/debugutil.cpp b/tests/auto/declarative/debugger/debugutil.cpp deleted file mode 100644 index 7008529..0000000 --- a/tests/auto/declarative/debugger/debugutil.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include - -#include -#include - -#include "debugutil_p.h" - -bool QmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) { - QEventLoop loop; - QTimer timer; - QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - QObject::connect(receiver, member, &loop, SLOT(quit())); - timer.start(timeout); - loop.exec(); - return timer.isActive(); -} - - -QmlDebugTestData::QmlDebugTestData(QEventLoop *el) - : exitCode(-1), loop(el) -{ -} - -QmlDebugTestData::~QmlDebugTestData() -{ - qDeleteAll(items); -} - -void QmlDebugTestData::testsFinished(int code) -{ - exitCode = code; - loop->quit(); -} - - - -QmlDebugTestService::QmlDebugTestService(const QString &s, QObject *parent) - : QmlDebugService(s, parent), enabled(false) -{ -} - -void QmlDebugTestService::messageReceived(const QByteArray &ba) -{ - sendMessage(ba); -} - -void QmlDebugTestService::enabledChanged(bool e) -{ - emit enabledStateChanged(); - enabled = e; -} - - -QmlDebugTestClient::QmlDebugTestClient(const QString &s, QmlDebugConnection *c) - : QmlDebugClient(s, c) -{ -} - -QByteArray QmlDebugTestClient::waitForResponse() -{ - QSignalSpy spy(this, SIGNAL(serverMessage(QByteArray))); - QmlDebugTest::waitForSignal(this, SIGNAL(serverMessage(QByteArray))); - if (spy.count() == 0) { - qWarning() << "tst_QmlDebugClient: no response from server!"; - return QByteArray(); - } - return spy.at(0).at(0).value(); -} - -void QmlDebugTestClient::messageReceived(const QByteArray &ba) -{ - emit serverMessage(ba); -} - - -tst_QmlDebug_Thread::tst_QmlDebug_Thread(QmlDebugTestData *data, QmlTestFactory *factory) - : m_ready(false), m_data(data), m_factory(factory) -{ -} - -void tst_QmlDebug_Thread::run() -{ - QTest::qWait(1000); - - QmlDebugConnection conn; - conn.connectToHost("127.0.0.1", 3768); - bool ok = conn.waitForConnected(5000); - Q_ASSERT(ok); - - while (!m_ready) - QTest::qWait(100); - - m_data->conn = &conn; - - Q_ASSERT(m_factory); - QObject *test = m_factory->createTest(m_data); - Q_ASSERT(test); - int code = QTest::qExec(test); - emit testsFinished(code); -} - - -int QmlDebugTest::runTests(QmlTestFactory *factory, const QList &qml) -{ - qputenv("QML_DEBUG_SERVER_PORT", "3768"); - - QEventLoop loop; - QmlDebugTestData data(&loop); - - tst_QmlDebug_Thread thread(&data, factory); - QObject::connect(&thread, SIGNAL(testsFinished(int)), &data, SLOT(testsFinished(int))); - thread.start(); - - QmlEngine engine; // blocks until client connects - - foreach (const QByteArray &code, qml) { - QmlComponent c(&engine, code, QUrl("file://")); - Q_ASSERT(c.isReady()); // fails if bad syntax - data.items << qobject_cast(c.create()); - } - - // start the test - data.engine = &engine; - thread.m_ready = true; - - loop.exec(); - - return data.exitCode; -} - - diff --git a/tests/auto/declarative/debugger/debugutil_p.h b/tests/auto/declarative/debugger/debugutil_p.h deleted file mode 100644 index 665aeda..0000000 --- a/tests/auto/declarative/debugger/debugutil_p.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - - -class QmlDebugTestData : public QObject -{ - Q_OBJECT -public: - QmlDebugTestData(QEventLoop *el); - - ~QmlDebugTestData(); - - QmlEngine *engine; - QmlDebugConnection *conn; - - int exitCode; - QEventLoop *loop; - - QList items; - -public slots: - void testsFinished(int code); -}; - - -class QmlTestFactory -{ -public: - QmlTestFactory() {} - virtual ~QmlTestFactory() {} - - virtual QObject *createTest(QmlDebugTestData *data) = 0; -}; - - -namespace QmlDebugTest { - - bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000); - - int runTests(QmlTestFactory *factory, const QList &qml = QList()); -} - -class QmlDebugTestService : public QmlDebugService -{ - Q_OBJECT -public: - QmlDebugTestService(const QString &s, QObject *parent = 0); - bool enabled; - -signals: - void enabledStateChanged(); - -protected: - virtual void messageReceived(const QByteArray &ba); - - virtual void enabledChanged(bool e); -}; - -class QmlDebugTestClient : public QmlDebugClient -{ - Q_OBJECT -public: - QmlDebugTestClient(const QString &s, QmlDebugConnection *c); - - QByteArray waitForResponse(); - -signals: - void serverMessage(const QByteArray &); - -protected: - virtual void messageReceived(const QByteArray &ba); -}; - -class tst_QmlDebug_Thread : public QThread -{ - Q_OBJECT -public: - tst_QmlDebug_Thread(QmlDebugTestData *data, QmlTestFactory *factory); - - void run(); - - bool m_ready; - -signals: - void testsFinished(int); - -private: - QmlDebugTestData *m_data; - QmlTestFactory *m_factory; -}; - - diff --git a/tests/auto/declarative/debugger/qmldebug/qmldebug.pro b/tests/auto/declarative/debugger/qmldebug/qmldebug.pro deleted file mode 100644 index 0af30e1..0000000 --- a/tests/auto/declarative/debugger/qmldebug/qmldebug.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += network declarative -macx:CONFIG -= app_bundle - -HEADERS += ../debugutil_p.h -SOURCES += tst_qmldebug.cpp \ - ../debugutil.cpp diff --git a/tests/auto/declarative/debugger/qmldebug/tst_qmldebug.cpp b/tests/auto/declarative/debugger/qmldebug/tst_qmldebug.cpp deleted file mode 100644 index 70404f6..0000000 --- a/tests/auto/declarative/debugger/qmldebug/tst_qmldebug.cpp +++ /dev/null @@ -1,831 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "../debugutil_p.h" - -Q_DECLARE_METATYPE(QmlDebugWatch::State) - - -class tst_QmlDebug : public QObject -{ - Q_OBJECT - -public: - tst_QmlDebug(QmlDebugTestData *data) - { - m_conn = data->conn; - m_engine = data->engine; - m_rootItem = data->items[0]; - } - -private: - QmlDebugObjectReference findRootObject(); - QmlDebugPropertyReference findProperty(const QList &props, const QString &name) const; - void waitForQuery(QmlDebugQuery *query); - - void recursiveObjectTest(QObject *o, const QmlDebugObjectReference &oref, bool recursive) const; - - void recursiveCompareObjects(const QmlDebugObjectReference &a, const QmlDebugObjectReference &b) const; - void recursiveCompareContexts(const QmlDebugContextReference &a, const QmlDebugContextReference &b) const; - void compareProperties(const QmlDebugPropertyReference &a, const QmlDebugPropertyReference &b) const; - - QmlDebugConnection *m_conn; - QmlEngineDebug *m_dbg; - QmlEngine *m_engine; - QmlGraphicsItem *m_rootItem; - -private slots: - void initTestCase(); - - void watch_property(); - void watch_object(); - void watch_expression(); - void watch_expression_data(); - void watch_context(); - void watch_file(); - - void queryAvailableEngines(); - void queryRootContexts(); - void queryObject(); - void queryObject_data(); - void queryExpressionResult(); - void queryExpressionResult_data(); - - void tst_QmlDebugFileReference(); - void tst_QmlDebugEngineReference(); - void tst_QmlDebugObjectReference(); - void tst_QmlDebugContextReference(); - void tst_QmlDebugPropertyReference(); -}; - -QmlDebugObjectReference tst_QmlDebug::findRootObject() -{ - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); - - if (q_engines->engines().count() == 0) - return QmlDebugObjectReference(); - QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); - waitForQuery(q_context); - - if (q_context->rootContext().objects().count() == 0) - return QmlDebugObjectReference(); - QmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); - waitForQuery(q_obj); - - QmlDebugObjectReference result = q_obj->object(); - - delete q_engines; - delete q_context; - delete q_obj; - - return result; -} - -QmlDebugPropertyReference tst_QmlDebug::findProperty(const QList &props, const QString &name) const -{ - foreach(const QmlDebugPropertyReference &p, props) { - if (p.name() == name) - return p; - } - return QmlDebugPropertyReference(); -} - -void tst_QmlDebug::waitForQuery(QmlDebugQuery *query) -{ - QVERIFY(query); - QCOMPARE(query->parent(), this); - QVERIFY(query->state() == QmlDebugQuery::Waiting); - if (!QmlDebugTest::waitForSignal(query, SIGNAL(stateChanged(QmlDebugQuery::State)))) - QFAIL("query timed out"); -} - -void tst_QmlDebug::recursiveObjectTest(QObject *o, const QmlDebugObjectReference &oref, bool recursive) const -{ - const QMetaObject *meta = o->metaObject(); - - QmlType *type = QmlMetaType::qmlType(o->metaObject()); - QString className = type ? type->qmlTypeName() : QString(); - className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1); - - QCOMPARE(oref.debugId(), QmlDebugService::idForObject(o)); - QCOMPARE(oref.name(), o->objectName()); - QCOMPARE(oref.className(), className); - QCOMPARE(oref.contextDebugId(), QmlDebugService::idForObject(qmlContext(o))); - - const QObjectList &children = o->children(); - for (int i=0; i= 0); - - QmlDebugObjectReference cref; - foreach (const QmlDebugObjectReference &ref, oref.children()) { - if (ref.debugId() == debugId) { - cref = ref; - break; - } - } - QVERIFY(cref.debugId() >= 0); - - if (recursive) - recursiveObjectTest(child, cref, true); - } - - foreach (const QmlDebugPropertyReference &p, oref.properties()) { - QCOMPARE(p.objectDebugId(), QmlDebugService::idForObject(o)); - - // signal properties are fake - they are generated from QmlBoundSignal children - if (p.name().startsWith("on") && p.name().length() > 2 && p.name()[2].isUpper()) { - QVERIFY(p.value().toString().startsWith('{') && p.value().toString().endsWith('}')); - QVERIFY(p.valueTypeName().isEmpty()); - QVERIFY(p.binding().isEmpty()); - QVERIFY(!p.hasNotifySignal()); - continue; - } - - QMetaProperty pmeta = meta->property(meta->indexOfProperty(p.name().toUtf8().constData())); - - QCOMPARE(p.name(), QString::fromUtf8(pmeta.name())); - - if (pmeta.type() < QVariant::UserType) // TODO test complex types - QCOMPARE(p.value(), pmeta.read(o)); - - if (p.name() == "parent") - QVERIFY(p.valueTypeName() == "QGraphicsObject*" || p.valueTypeName() == "QmlGraphicsItem*"); - else - QCOMPARE(p.valueTypeName(), QString::fromUtf8(pmeta.typeName())); - - QmlAbstractBinding *binding = QmlMetaProperty(o, p.name()).binding(); - if (binding) - QCOMPARE(binding->expression(), p.binding()); - - QCOMPARE(p.hasNotifySignal(), pmeta.hasNotifySignal()); - - QVERIFY(pmeta.isValid()); - } -} - -void tst_QmlDebug::recursiveCompareObjects(const QmlDebugObjectReference &a, const QmlDebugObjectReference &b) const -{ - QCOMPARE(a.debugId(), b.debugId()); - QCOMPARE(a.className(), b.className()); - QCOMPARE(a.name(), b.name()); - QCOMPARE(a.contextDebugId(), b.contextDebugId()); - - QCOMPARE(a.source().url(), b.source().url()); - QCOMPARE(a.source().lineNumber(), b.source().lineNumber()); - QCOMPARE(a.source().columnNumber(), b.source().columnNumber()); - - QCOMPARE(a.properties().count(), b.properties().count()); - QCOMPARE(a.children().count(), b.children().count()); - - QList aprops = a.properties(); - QList bprops = b.properties(); - - for (int i=0; i(); -} - -void tst_QmlDebug::watch_property() -{ - QmlDebugObjectReference obj = findRootObject(); - QmlDebugPropertyReference prop = findProperty(obj.properties(), "width"); - - QmlDebugPropertyWatch *watch; - - QmlEngineDebug unconnected(0); - watch = unconnected.addWatch(prop, this); - QCOMPARE(watch->state(), QmlDebugWatch::Dead); - delete watch; - - watch = m_dbg->addWatch(QmlDebugPropertyReference(), this); - QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); - QCOMPARE(watch->state(), QmlDebugWatch::Inactive); - delete watch; - - watch = m_dbg->addWatch(prop, this); - QCOMPARE(watch->state(), QmlDebugWatch::Waiting); - QCOMPARE(watch->objectDebugId(), obj.debugId()); - QCOMPARE(watch->name(), prop.name()); - - QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); - - int origWidth = m_rootItem->property("width").toInt(); - m_rootItem->setProperty("width", origWidth*2); - - // stateChanged() is received before valueChanged() - QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); - QCOMPARE(watch->state(), QmlDebugWatch::Active); - QCOMPARE(spy.count(), 1); - - m_dbg->removeWatch(watch); - delete watch; - - // restore original value and verify spy doesn't get additional signal since watch has been removed - m_rootItem->setProperty("width", origWidth); - QTest::qWait(100); - QCOMPARE(spy.count(), 1); - - QCOMPARE(spy.at(0).at(0).value(), prop.name().toUtf8()); - QCOMPARE(spy.at(0).at(1).value(), qVariantFromValue(origWidth*2)); -} - -void tst_QmlDebug::watch_object() -{ - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); - - QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); - waitForQuery(q_context); - - QmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); - waitForQuery(q_obj); - - QmlDebugObjectReference obj = q_obj->object(); - - delete q_engines; - delete q_context; - delete q_obj; - - QmlDebugWatch *watch; - - QmlEngineDebug unconnected(0); - watch = unconnected.addWatch(obj, this); - QCOMPARE(watch->state(), QmlDebugWatch::Dead); - delete watch; - - watch = m_dbg->addWatch(QmlDebugObjectReference(), this); - QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); - QCOMPARE(watch->state(), QmlDebugWatch::Inactive); - delete watch; - - watch = m_dbg->addWatch(obj, this); - QCOMPARE(watch->state(), QmlDebugWatch::Waiting); - QCOMPARE(watch->objectDebugId(), obj.debugId()); - - QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); - - int origWidth = m_rootItem->property("width").toInt(); - int origHeight = m_rootItem->property("height").toInt(); - m_rootItem->setProperty("width", origWidth*2); - m_rootItem->setProperty("height", origHeight*2); - - // stateChanged() is received before any valueChanged() signals - QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); - QCOMPARE(watch->state(), QmlDebugWatch::Active); - QVERIFY(spy.count() > 0); - - int newWidth = -1; - int newHeight = -1; - for (int i=0; i() == "width") - newWidth = values[1].value().toInt(); - else if (values[0].value() == "height") - newHeight = values[1].value().toInt(); - - } - - m_dbg->removeWatch(watch); - delete watch; - - // since watch has been removed, restoring the original values should not trigger a valueChanged() - spy.clear(); - m_rootItem->setProperty("width", origWidth); - m_rootItem->setProperty("height", origHeight); - QTest::qWait(100); - QCOMPARE(spy.count(), 0); - - QCOMPARE(newWidth, origWidth * 2); - QCOMPARE(newHeight, origHeight * 2); -} - -void tst_QmlDebug::watch_expression() -{ - QFETCH(QString, expr); - QFETCH(int, increment); - QFETCH(int, incrementCount); - - int origWidth = m_rootItem->property("width").toInt(); - - QmlDebugObjectReference obj = findRootObject(); - - QmlDebugObjectExpressionWatch *watch; - - QmlEngineDebug unconnected(0); - watch = unconnected.addWatch(obj, expr, this); - QCOMPARE(watch->state(), QmlDebugWatch::Dead); - delete watch; - - watch = m_dbg->addWatch(QmlDebugObjectReference(), expr, this); - QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); - QCOMPARE(watch->state(), QmlDebugWatch::Inactive); - delete watch; - - watch = m_dbg->addWatch(obj, expr, this); - QCOMPARE(watch->state(), QmlDebugWatch::Waiting); - QCOMPARE(watch->objectDebugId(), obj.debugId()); - QCOMPARE(watch->expression(), expr); - - QSignalSpy spyState(watch, SIGNAL(stateChanged(QmlDebugWatch::State))); - - QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); - int expectedSpyCount = incrementCount + 1; // should also get signal with expression's initial value - - int width = origWidth; - for (int i=0; i 0) { - width += increment; - m_rootItem->setProperty("width", width); - } - if (!QmlDebugTest::waitForSignal(watch, SIGNAL(valueChanged(QByteArray,QVariant)))) - QFAIL("Did not receive valueChanged() for expression"); - } - - if (spyState.count() == 0) - QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); - QCOMPARE(spyState.count(), 1); - QCOMPARE(watch->state(), QmlDebugWatch::Active); - - m_dbg->removeWatch(watch); - delete watch; - - // restore original value and verify spy doesn't get a signal since watch has been removed - m_rootItem->setProperty("width", origWidth); - QTest::qWait(100); - QCOMPARE(spy.count(), expectedSpyCount); - - width = origWidth + increment; - for (int i=0; i().toInt(), width); - width += increment; - } -} - -void tst_QmlDebug::watch_expression_data() -{ - QTest::addColumn("expr"); - QTest::addColumn("increment"); - QTest::addColumn("incrementCount"); - - QTest::newRow("width") << "width" << 0 << 0; - QTest::newRow("width+10") << "width + 10" << 10 << 5; -} - -void tst_QmlDebug::watch_context() -{ - QmlDebugContextReference c; - QTest::ignoreMessage(QtWarningMsg, "QmlEngineDebug::addWatch(): Not implemented"); - QVERIFY(!m_dbg->addWatch(c, QString(), this)); -} - -void tst_QmlDebug::watch_file() -{ - QmlDebugFileReference f; - QTest::ignoreMessage(QtWarningMsg, "QmlEngineDebug::addWatch(): Not implemented"); - QVERIFY(!m_dbg->addWatch(f, this)); -} - -void tst_QmlDebug::queryAvailableEngines() -{ - QmlDebugEnginesQuery *q_engines; - - QmlEngineDebug unconnected(0); - q_engines = unconnected.queryAvailableEngines(0); - QCOMPARE(q_engines->state(), QmlDebugQuery::Error); - delete q_engines; - - q_engines = m_dbg->queryAvailableEngines(this); - delete q_engines; - - q_engines = m_dbg->queryAvailableEngines(this); - QVERIFY(q_engines->engines().isEmpty()); - waitForQuery(q_engines); - - // TODO test multiple engines - QList engines = q_engines->engines(); - QCOMPARE(engines.count(), 1); - - foreach(const QmlDebugEngineReference &e, engines) { - QCOMPARE(e.debugId(), QmlDebugService::idForObject(m_engine)); - QCOMPARE(e.name(), m_engine->objectName()); - } - - delete q_engines; -} - -void tst_QmlDebug::queryRootContexts() -{ - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); - int engineId = q_engines->engines()[0].debugId(); - - QmlDebugRootContextQuery *q_context; - - QmlEngineDebug unconnected(0); - q_context = unconnected.queryRootContexts(engineId, this); - QCOMPARE(q_context->state(), QmlDebugQuery::Error); - delete q_context; - - q_context = m_dbg->queryRootContexts(engineId, this); - delete q_context; - - q_context = m_dbg->queryRootContexts(engineId, this); - waitForQuery(q_context); - - QmlContext *actualContext = m_engine->rootContext(); - QmlDebugContextReference context = q_context->rootContext(); - QCOMPARE(context.debugId(), QmlDebugService::idForObject(actualContext)); - QCOMPARE(context.name(), actualContext->objectName()); - - QCOMPARE(context.objects().count(), 2); // 2 qml component objects created for context in main() - - // root context query sends only root object data - it doesn't fill in - // the children or property info - QCOMPARE(context.objects()[0].properties().count(), 0); - QCOMPARE(context.objects()[0].children().count(), 0); - - QCOMPARE(context.contexts().count(), 1); - QVERIFY(context.contexts()[0].debugId() >= 0); - QCOMPARE(context.contexts()[0].name(), QString("tst_QmlDebug_childContext")); - - delete q_engines; - delete q_context; -} - -void tst_QmlDebug::queryObject() -{ - QFETCH(bool, recursive); - - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); - - QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); - waitForQuery(q_context); - QmlDebugObjectReference rootObject = q_context->rootContext().objects()[0]; - - QmlDebugObjectQuery *q_obj = 0; - - QmlEngineDebug unconnected(0); - q_obj = recursive ? unconnected.queryObjectRecursive(rootObject, this) : unconnected.queryObject(rootObject, this); - QCOMPARE(q_obj->state(), QmlDebugQuery::Error); - delete q_obj; - - q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); - delete q_obj; - - q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); - waitForQuery(q_obj); - - QmlDebugObjectReference obj = q_obj->object(); - - delete q_engines; - delete q_context; - delete q_obj; - - // check source as defined in main() - QmlDebugFileReference source = obj.source(); - QCOMPARE(source.url(), QUrl("file://")); - QCOMPARE(source.lineNumber(), 2); - QCOMPARE(source.columnNumber(), 1); - - // generically test all properties, children and childrens' properties - recursiveObjectTest(m_rootItem, obj, recursive); - - if (recursive) { - foreach(const QmlDebugObjectReference &child, obj.children()) - QVERIFY(child.properties().count() > 0); - - QmlDebugObjectReference rect; - QmlDebugObjectReference text; - foreach (const QmlDebugObjectReference &child, obj.children()) { - if (child.className() == "Rectangle") - rect = child; - else if (child.className() == "Text") - text = child; - } - - // test specific property values - QCOMPARE(findProperty(rect.properties(), "width").value(), qVariantFromValue(500)); - QCOMPARE(findProperty(rect.properties(), "height").value(), qVariantFromValue(600)); - QCOMPARE(findProperty(rect.properties(), "color").value(), qVariantFromValue(QColor("blue"))); - - QCOMPARE(findProperty(text.properties(), "color").value(), qVariantFromValue(QColor("blue"))); - - } else { - foreach(const QmlDebugObjectReference &child, obj.children()) - QCOMPARE(child.properties().count(), 0); - } -} - -void tst_QmlDebug::queryObject_data() -{ - QTest::addColumn("recursive"); - - QTest::newRow("non-recursive") << false; - QTest::newRow("recursive") << true; -} - -void tst_QmlDebug::queryExpressionResult() -{ - QFETCH(QString, expr); - QFETCH(QVariant, result); - - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); // check immediate deletion is ok - - QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); - waitForQuery(q_context); - int objectId = q_context->rootContext().objects()[0].debugId(); - - QmlDebugExpressionQuery *q_expr; - - QmlEngineDebug unconnected(0); - q_expr = unconnected.queryExpressionResult(objectId, expr, this); - QCOMPARE(q_expr->state(), QmlDebugQuery::Error); - delete q_expr; - - q_expr = m_dbg->queryExpressionResult(objectId, expr, this); - delete q_expr; - - q_expr = m_dbg->queryExpressionResult(objectId, expr, this); - QCOMPARE(q_expr->expression(), expr); - waitForQuery(q_expr); - - QCOMPARE(q_expr->result(), result); - - delete q_engines; - delete q_context; - delete q_expr; -} - -void tst_QmlDebug::queryExpressionResult_data() -{ - QTest::addColumn("expr"); - QTest::addColumn("result"); - - QTest::newRow("width + 50") << "width + 50" << qVariantFromValue(60); - QTest::newRow("blueRect.width") << "blueRect.width" << qVariantFromValue(500); - QTest::newRow("bad expr") << "aeaef" << qVariantFromValue(QString("")); -} - -void tst_QmlDebug::tst_QmlDebugFileReference() -{ - QmlDebugFileReference ref; - QVERIFY(ref.url().isEmpty()); - QCOMPARE(ref.lineNumber(), -1); - QCOMPARE(ref.columnNumber(), -1); - - ref.setUrl(QUrl("http://test")); - QCOMPARE(ref.url(), QUrl("http://test")); - ref.setLineNumber(1); - QCOMPARE(ref.lineNumber(), 1); - ref.setColumnNumber(1); - QCOMPARE(ref.columnNumber(), 1); - - QmlDebugFileReference copy(ref); - QmlDebugFileReference copyAssign; - copyAssign = ref; - foreach (const QmlDebugFileReference &r, (QList() << copy << copyAssign)) { - QCOMPARE(r.url(), ref.url()); - QCOMPARE(r.lineNumber(), ref.lineNumber()); - QCOMPARE(r.columnNumber(), ref.columnNumber()); - } -} - -void tst_QmlDebug::tst_QmlDebugEngineReference() -{ - QmlDebugEngineReference ref; - QCOMPARE(ref.debugId(), -1); - QVERIFY(ref.name().isEmpty()); - - ref = QmlDebugEngineReference(1); - QCOMPARE(ref.debugId(), 1); - QVERIFY(ref.name().isEmpty()); - - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); - ref = q_engines->engines()[0]; - delete q_engines; - - QmlDebugEngineReference copy(ref); - QmlDebugEngineReference copyAssign; - copyAssign = ref; - foreach (const QmlDebugEngineReference &r, (QList() << copy << copyAssign)) { - QCOMPARE(r.debugId(), ref.debugId()); - QCOMPARE(r.name(), ref.name()); - } -} - -void tst_QmlDebug::tst_QmlDebugObjectReference() -{ - QmlDebugObjectReference ref; - QCOMPARE(ref.debugId(), -1); - QCOMPARE(ref.className(), QString()); - QCOMPARE(ref.name(), QString()); - QCOMPARE(ref.contextDebugId(), -1); - QVERIFY(ref.properties().isEmpty()); - QVERIFY(ref.children().isEmpty()); - - QmlDebugFileReference source = ref.source(); - QVERIFY(source.url().isEmpty()); - QVERIFY(source.lineNumber() < 0); - QVERIFY(source.columnNumber() < 0); - - ref = QmlDebugObjectReference(1); - QCOMPARE(ref.debugId(), 1); - - QmlDebugObjectReference rootObject = findRootObject(); - QmlDebugObjectQuery *query = m_dbg->queryObjectRecursive(rootObject, this); - waitForQuery(query); - ref = query->object(); - delete query; - - QVERIFY(ref.debugId() >= 0); - - QmlDebugObjectReference copy(ref); - QmlDebugObjectReference copyAssign; - copyAssign = ref; - foreach (const QmlDebugObjectReference &r, (QList() << copy << copyAssign)) - recursiveCompareObjects(r, ref); -} - -void tst_QmlDebug::tst_QmlDebugContextReference() -{ - QmlDebugContextReference ref; - QCOMPARE(ref.debugId(), -1); - QVERIFY(ref.name().isEmpty()); - QVERIFY(ref.objects().isEmpty()); - QVERIFY(ref.contexts().isEmpty()); - - QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); - waitForQuery(q_engines); - QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); - waitForQuery(q_context); - - ref = q_context->rootContext(); - delete q_engines; - delete q_context; - QVERIFY(ref.debugId() >= 0); - - QmlDebugContextReference copy(ref); - QmlDebugContextReference copyAssign; - copyAssign = ref; - foreach (const QmlDebugContextReference &r, (QList() << copy << copyAssign)) - recursiveCompareContexts(r, ref); -} - -void tst_QmlDebug::tst_QmlDebugPropertyReference() -{ - QmlDebugObjectReference rootObject = findRootObject(); - QmlDebugObjectQuery *query = m_dbg->queryObject(rootObject, this); - waitForQuery(query); - QmlDebugObjectReference obj = query->object(); - delete query; - - QmlDebugPropertyReference ref = findProperty(obj.properties(), "scale"); - QVERIFY(ref.objectDebugId() > 0); - QVERIFY(!ref.name().isEmpty()); - QVERIFY(!ref.value().isNull()); - QVERIFY(!ref.valueTypeName().isEmpty()); - QVERIFY(!ref.binding().isEmpty()); - QVERIFY(ref.hasNotifySignal()); - - QmlDebugPropertyReference copy(ref); - QmlDebugPropertyReference copyAssign; - copyAssign = ref; - foreach (const QmlDebugPropertyReference &r, (QList() << copy << copyAssign)) - compareProperties(r, ref); -} - - -class tst_QmlDebug_Factory : public QmlTestFactory -{ -public: - QObject *createTest(QmlDebugTestData *data) - { - QmlContext *c = new QmlContext(data->engine->rootContext()); - c->setObjectName("tst_QmlDebug_childContext"); - return new tst_QmlDebug(data); - } -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - QList qml; - qml << "import Qt 4.6\n" - "Item {" - "width: 10; height: 20; scale: blueRect.scale;" - "Rectangle { id: blueRect; width: 500; height: 600; color: \"blue\"; }" - "Text { color: blueRect.color; }" - "MouseRegion {" - "onEntered: { print('hello') }" - "}" - "}"; - // add second component to test multiple root contexts - qml << "import Qt 4.6\n" - "Item {}"; - tst_QmlDebug_Factory factory; - return QmlDebugTest::runTests(&factory, qml); -} - -//QTEST_MAIN(tst_QmlDebug) - -#include "tst_qmldebug.moc" diff --git a/tests/auto/declarative/debugger/qmldebugclient/qmldebugclient.pro b/tests/auto/declarative/debugger/qmldebugclient/qmldebugclient.pro deleted file mode 100644 index c0aa7b2..0000000 --- a/tests/auto/declarative/debugger/qmldebugclient/qmldebugclient.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += network declarative -macx:CONFIG -= app_bundle - -HEADERS += ../debugutil_p.h -SOURCES += tst_qmldebugclient.cpp \ - ../debugutil.cpp diff --git a/tests/auto/declarative/debugger/qmldebugclient/tst_qmldebugclient.cpp b/tests/auto/declarative/debugger/qmldebugclient/tst_qmldebugclient.cpp deleted file mode 100644 index 6c4a1a3..0000000 --- a/tests/auto/declarative/debugger/qmldebugclient/tst_qmldebugclient.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "../debugutil_p.h" - -class tst_QmlDebugClient : public QObject -{ - Q_OBJECT - -public: - tst_QmlDebugClient(QmlDebugTestData *data) - { - m_conn = data->conn; - m_engine = data->engine; - } - - QmlDebugConnection *m_conn; - QmlEngine *m_engine; - -private slots: - void name(); - void isEnabled(); - void setEnabled(); - void isConnected(); - void sendMessage(); -}; - -void tst_QmlDebugClient::name() -{ - QString name = "tst_QmlDebugClient::name()"; - - QmlDebugClient client(name, m_conn); - QCOMPARE(client.name(), name); -} - -void tst_QmlDebugClient::isEnabled() -{ - QmlDebugClient client("tst_QmlDebugClient::isEnabled()", m_conn); - QCOMPARE(client.isEnabled(), false); -} - -void tst_QmlDebugClient::setEnabled() -{ - QmlDebugTestService service("tst_QmlDebugClient::setEnabled()"); - QmlDebugTestClient client("tst_QmlDebugClient::setEnabled()", m_conn); - - QCOMPARE(service.isEnabled(), false); - - client.setEnabled(true); - QCOMPARE(client.isEnabled(), true); - QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); - QCOMPARE(service.isEnabled(), true); - - client.setEnabled(false); - QCOMPARE(client.isEnabled(), false); - QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); - QCOMPARE(service.isEnabled(), false); -} - -void tst_QmlDebugClient::isConnected() -{ - QmlDebugClient client1("tst_QmlDebugClient::isConnected() A", m_conn); - QCOMPARE(client1.isConnected(), true); - - QmlDebugConnection conn; - QmlDebugClient client2("tst_QmlDebugClient::isConnected() B", &conn); - QCOMPARE(client2.isConnected(), false); - - QmlDebugClient client3("tst_QmlDebugClient::isConnected() C", 0); - QCOMPARE(client3.isConnected(), false); - - // duplicate plugin name - QTest::ignoreMessage(QtWarningMsg, "QmlDebugClient: Conflicting plugin name \"tst_QmlDebugClient::isConnected() A\" "); - QmlDebugClient client4("tst_QmlDebugClient::isConnected() A", m_conn); - QCOMPARE(client4.isConnected(), false); -} - -void tst_QmlDebugClient::sendMessage() -{ - QmlDebugTestService service("tst_QmlDebugClient::sendMessage()"); - QmlDebugTestClient client("tst_QmlDebugClient::sendMessage()", m_conn); - - QByteArray msg = "hello!"; - - client.sendMessage(msg); - QByteArray resp = client.waitForResponse(); - QCOMPARE(resp, msg); -} - - -class tst_QmlDebugClient_Factory : public QmlTestFactory -{ -public: - QObject *createTest(QmlDebugTestData *data) { return new tst_QmlDebugClient(data); } -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - tst_QmlDebugClient_Factory factory; - return QmlDebugTest::runTests(&factory); -} - -#include "tst_qmldebugclient.moc" diff --git a/tests/auto/declarative/debugger/qmldebugservice/qmldebugservice.pro b/tests/auto/declarative/debugger/qmldebugservice/qmldebugservice.pro deleted file mode 100644 index cce277a..0000000 --- a/tests/auto/declarative/debugger/qmldebugservice/qmldebugservice.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += network declarative -macx:CONFIG -= app_bundle - -HEADERS += ../debugutil_p.h -SOURCES += tst_qmldebugservice.cpp \ - ../debugutil.cpp diff --git a/tests/auto/declarative/debugger/qmldebugservice/tst_qmldebugservice.cpp b/tests/auto/declarative/debugger/qmldebugservice/tst_qmldebugservice.cpp deleted file mode 100644 index 0c02929..0000000 --- a/tests/auto/declarative/debugger/qmldebugservice/tst_qmldebugservice.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "../debugutil_p.h" - -class tst_QmlDebugService : public QObject -{ - Q_OBJECT - -public: - tst_QmlDebugService(QmlDebugTestData *data) - { - m_conn = data->conn; - m_engine = data->engine; - } - - QmlDebugConnection *m_conn; - QmlEngine *m_engine; - -private slots: - void name(); - void isEnabled(); - void enabledChanged(); - void sendMessage(); - void idForObject(); - void objectForId(); - void objectToString(); -}; - -void tst_QmlDebugService::name() -{ - QString name = "tst_QmlDebugService::name()"; - - QmlDebugService service(name); - QCOMPARE(service.name(), name); -} - -void tst_QmlDebugService::isEnabled() -{ - QmlDebugTestService service("tst_QmlDebugService::isEnabled()", m_conn); - QCOMPARE(service.isEnabled(), false); - - QmlDebugTestClient client("tst_QmlDebugService::isEnabled()", m_conn); - client.setEnabled(true); - QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); - QCOMPARE(service.isEnabled(), true); - - QTest::ignoreMessage(QtWarningMsg, "QmlDebugService: Conflicting plugin name \"tst_QmlDebugService::isEnabled()\" "); - QmlDebugService duplicate("tst_QmlDebugService::isEnabled()", m_conn); - QCOMPARE(duplicate.isEnabled(), false); -} - -void tst_QmlDebugService::enabledChanged() -{ - QmlDebugTestService service("tst_QmlDebugService::enabledChanged()"); - QmlDebugTestClient client("tst_QmlDebugService::enabledChanged()", m_conn); - - QCOMPARE(service.enabled, false); - - client.setEnabled(true); - QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); - QCOMPARE(service.enabled, true); -} - -void tst_QmlDebugService::sendMessage() -{ - QmlDebugTestService service("tst_QmlDebugService::sendMessage()"); - QmlDebugTestClient client("tst_QmlDebugService::sendMessage()", m_conn); - - QByteArray msg = "hello!"; - - client.sendMessage(msg); - QByteArray resp = client.waitForResponse(); - QCOMPARE(resp, msg); -} - -void tst_QmlDebugService::idForObject() -{ - QCOMPARE(QmlDebugService::idForObject(0), -1); - - QObject *objA = new QObject; - - int idA = QmlDebugService::idForObject(objA); - QVERIFY(idA >= 0); - QCOMPARE(QmlDebugService::objectForId(idA), objA); - - int idAA = QmlDebugService::idForObject(objA); - QCOMPARE(idAA, idA); - - QObject *objB = new QObject; - int idB = QmlDebugService::idForObject(objB); - QVERIFY(idB != idA); - QCOMPARE(QmlDebugService::objectForId(idB), objB); - - delete objA; - delete objB; -} - -void tst_QmlDebugService::objectForId() -{ - QCOMPARE(QmlDebugService::objectForId(-1), static_cast(0)); - QCOMPARE(QmlDebugService::objectForId(1), static_cast(0)); - - QObject *obj = new QObject; - int id = QmlDebugService::idForObject(obj); - QCOMPARE(QmlDebugService::objectForId(id), obj); - - delete obj; - QCOMPARE(QmlDebugService::objectForId(id), static_cast(0)); -} - -void tst_QmlDebugService::objectToString() -{ - QCOMPARE(QmlDebugService::objectToString(0), QString("NULL")); - - QObject *obj = new QObject; - QCOMPARE(QmlDebugService::objectToString(obj), QString("QObject: ")); - - obj->setObjectName("Hello"); - QCOMPARE(QmlDebugService::objectToString(obj), QString("QObject: Hello")); -} - - -class tst_QmlDebugService_Factory : public QmlTestFactory -{ -public: - QObject *createTest(QmlDebugTestData *data) { return new tst_QmlDebugService(data); } -}; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - tst_QmlDebugService_Factory factory; - return QmlDebugTest::runTests(&factory); -} - -#include "tst_qmldebugservice.moc" diff --git a/tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro deleted file mode 100644 index 800e5e0..0000000 --- a/tests/auto/declarative/debugger/qpacketprotocol/qpacketprotocol.pro +++ /dev/null @@ -1,7 +0,0 @@ -load(qttest_p4) -contains(QT_CONFIG,declarative): QT += network declarative -macx:CONFIG -= app_bundle - -HEADERS += ../debugutil_p.h -SOURCES += tst_qpacketprotocol.cpp \ - ../debugutil.cpp diff --git a/tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp deleted file mode 100644 index 36b6317..0000000 --- a/tests/auto/declarative/debugger/qpacketprotocol/tst_qpacketprotocol.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../debugutil_p.h" - -class tst_QPacketProtocol : public QObject -{ - Q_OBJECT - -private: - QTcpServer *m_server; - QTcpSocket *m_client; - QTcpSocket *m_serverConn; - -private slots: - void init(); - void cleanup(); - - void maximumPacketSize(); - void setMaximumPacketSize(); - void setMaximumPacketSize_data(); - void send(); - void send_data(); - void packetsAvailable(); - void packetsAvailable_data(); - void clear(); - void read(); - void device(); - - void tst_QPacket_clear(); -}; - -void tst_QPacketProtocol::init() -{ - m_server = new QTcpServer(this); - QVERIFY(m_server->listen()); - - m_client = new QTcpSocket(this); - m_client->connectToHost(m_server->serverAddress(), m_server->serverPort()); - - QVERIFY(m_client->waitForConnected()); - QVERIFY(m_server->waitForNewConnection()); - m_serverConn = m_server->nextPendingConnection(); -} - -void tst_QPacketProtocol::cleanup() -{ - delete m_client; - delete m_serverConn; - delete m_server; -} - -void tst_QPacketProtocol::maximumPacketSize() -{ - QPacketProtocol p(m_client); - QCOMPARE(p.maximumPacketSize(), 0x7FFFFFFF); -} - -void tst_QPacketProtocol::setMaximumPacketSize() -{ - QFETCH(qint32, size); - QFETCH(qint32, expected); - - QPacketProtocol out(m_serverConn); - QCOMPARE(out.setMaximumPacketSize(size), expected); - - if (size == expected) { - QPacketProtocol in(m_client); - QByteArray b; - b.fill('a', size + 1); - out.send() << b.constData(); - QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(invalidPacket()))); - } -} - -void tst_QPacketProtocol::setMaximumPacketSize_data() -{ - QTest::addColumn("size"); - QTest::addColumn("expected"); - - QTest::newRow("invalid") << qint32(sizeof(qint32) - 1) << qint32(0x7FFFFFFF); - QTest::newRow("still invalid") << qint32(sizeof(qint32)) << qint32(0x7FFFFFFF); - QTest::newRow("valid") << qint32(sizeof(qint32) + 1) << qint32(sizeof(qint32) + 1); -} - -void tst_QPacketProtocol::send() -{ - QFETCH(bool, useAutoSend); - - QPacketProtocol in(m_client); - QPacketProtocol out(m_serverConn); - - QByteArray ba; - int num; - - if (useAutoSend) { - out.send() << "Hello world" << 123; - } else { - QPacket packet; - packet << "Hello world" << 123; - out.send(packet); - } - - QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - - QPacket p = in.read(); - p >> ba >> num; - QCOMPARE(ba, QByteArray("Hello world") + '\0'); - QCOMPARE(num, 123); -} - -void tst_QPacketProtocol::send_data() -{ - QTest::addColumn("useAutoSend"); - - QTest::newRow("auto send") << true; - QTest::newRow("no auto send") << false; -} - -void tst_QPacketProtocol::packetsAvailable() -{ - QFETCH(int, packetCount); - - QPacketProtocol out(m_client); - QPacketProtocol in(m_serverConn); - - QCOMPARE(out.packetsAvailable(), qint64(0)); - QCOMPARE(in.packetsAvailable(), qint64(0)); - - for (int i=0; i("packetCount"); - - QTest::newRow("1") << 1; - QTest::newRow("2") << 2; - QTest::newRow("10") << 10; -} - -void tst_QPacketProtocol::clear() -{ - QPacketProtocol in(m_client); - QPacketProtocol out(m_serverConn); - - out.send() << 123; - out.send() << 456; - QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - - in.clear(); - QVERIFY(in.read().isEmpty()); -} - -void tst_QPacketProtocol::read() -{ - QPacketProtocol in(m_client); - QPacketProtocol out(m_serverConn); - - QVERIFY(in.read().isEmpty()); - - out.send() << 123; - out.send() << 456; - QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - - int num; - - QPacket p1 = in.read(); - QVERIFY(!p1.isEmpty()); - p1 >> num; - QCOMPARE(num, 123); - - QPacket p2 = in.read(); - QVERIFY(!p2.isEmpty()); - p2 >> num; - QCOMPARE(num, 456); - - QVERIFY(in.read().isEmpty()); -} - -void tst_QPacketProtocol::device() -{ - QPacketProtocol p(m_client); - QCOMPARE(p.device(), m_client); -} - -void tst_QPacketProtocol::tst_QPacket_clear() -{ - QPacketProtocol protocol(m_client); - - QPacket packet; - - packet << "Hello world!" << 123; - protocol.send(packet); - - packet.clear(); - QVERIFY(packet.isEmpty()); - packet << "Goodbyte world!" << 789; - protocol.send(packet); - - QByteArray ba; - int num; - QPacketProtocol in(m_serverConn); - QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); - - QPacket p1 = in.read(); - p1 >> ba >> num; - QCOMPARE(ba, QByteArray("Hello world!") + '\0'); - QCOMPARE(num, 123); - - QPacket p2 = in.read(); - p2 >> ba >> num; - QCOMPARE(ba, QByteArray("Goodbyte world!") + '\0'); - QCOMPARE(num, 789); -} - -QTEST_MAIN(tst_QPacketProtocol) - -#include "tst_qpacketprotocol.moc" diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index ec2c7d0..c45a05e 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -2,10 +2,7 @@ TEMPLATE = subdirs SUBDIRS += \ anchors \ # Cover animatedimage \ # Cover - animations \ # Cover - behaviors \ # Cover datetimeformatter \ # Cover - debugger \ # Cover examples \ layouts \ # Cover numberformatter \ # Cover @@ -15,6 +12,9 @@ SUBDIRS += \ qmlbinding \ # Cover qmlconnection \ # Cover qmlcontext \ # Cover + qmldebug \ # Cover + qmldebugclient \ # Cover + qmldebugservice \ # Cover qmldom \ # Cover qmleasefollow \ # Cover qmlecmascript \ # Cover @@ -49,6 +49,7 @@ SUBDIRS += \ qmlsystempalette \ # Cover qmltimer \ # Cover qmlxmllistmodel \ # Cover + qpacketprotocol \ # Cover repeater \ # Cover sql \ # Cover states \ # Cover diff --git a/tests/auto/declarative/qmldebug/qmldebug.pro b/tests/auto/declarative/qmldebug/qmldebug.pro new file mode 100644 index 0000000..f79829d --- /dev/null +++ b/tests/auto/declarative/qmldebug/qmldebug.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += network declarative +macx:CONFIG -= app_bundle + +HEADERS += ../shared/debugutil_p.h +SOURCES += tst_qmldebug.cpp \ + ../shared/debugutil.cpp diff --git a/tests/auto/declarative/qmldebug/tst_qmldebug.cpp b/tests/auto/declarative/qmldebug/tst_qmldebug.cpp new file mode 100644 index 0000000..6916cc9 --- /dev/null +++ b/tests/auto/declarative/qmldebug/tst_qmldebug.cpp @@ -0,0 +1,831 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../shared/debugutil_p.h" + +Q_DECLARE_METATYPE(QmlDebugWatch::State) + + +class tst_QmlDebug : public QObject +{ + Q_OBJECT + +public: + tst_QmlDebug(QmlDebugTestData *data) + { + m_conn = data->conn; + m_engine = data->engine; + m_rootItem = data->items[0]; + } + +private: + QmlDebugObjectReference findRootObject(); + QmlDebugPropertyReference findProperty(const QList &props, const QString &name) const; + void waitForQuery(QmlDebugQuery *query); + + void recursiveObjectTest(QObject *o, const QmlDebugObjectReference &oref, bool recursive) const; + + void recursiveCompareObjects(const QmlDebugObjectReference &a, const QmlDebugObjectReference &b) const; + void recursiveCompareContexts(const QmlDebugContextReference &a, const QmlDebugContextReference &b) const; + void compareProperties(const QmlDebugPropertyReference &a, const QmlDebugPropertyReference &b) const; + + QmlDebugConnection *m_conn; + QmlEngineDebug *m_dbg; + QmlEngine *m_engine; + QmlGraphicsItem *m_rootItem; + +private slots: + void initTestCase(); + + void watch_property(); + void watch_object(); + void watch_expression(); + void watch_expression_data(); + void watch_context(); + void watch_file(); + + void queryAvailableEngines(); + void queryRootContexts(); + void queryObject(); + void queryObject_data(); + void queryExpressionResult(); + void queryExpressionResult_data(); + + void tst_QmlDebugFileReference(); + void tst_QmlDebugEngineReference(); + void tst_QmlDebugObjectReference(); + void tst_QmlDebugContextReference(); + void tst_QmlDebugPropertyReference(); +}; + +QmlDebugObjectReference tst_QmlDebug::findRootObject() +{ + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + + if (q_engines->engines().count() == 0) + return QmlDebugObjectReference(); + QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); + waitForQuery(q_context); + + if (q_context->rootContext().objects().count() == 0) + return QmlDebugObjectReference(); + QmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); + waitForQuery(q_obj); + + QmlDebugObjectReference result = q_obj->object(); + + delete q_engines; + delete q_context; + delete q_obj; + + return result; +} + +QmlDebugPropertyReference tst_QmlDebug::findProperty(const QList &props, const QString &name) const +{ + foreach(const QmlDebugPropertyReference &p, props) { + if (p.name() == name) + return p; + } + return QmlDebugPropertyReference(); +} + +void tst_QmlDebug::waitForQuery(QmlDebugQuery *query) +{ + QVERIFY(query); + QCOMPARE(query->parent(), this); + QVERIFY(query->state() == QmlDebugQuery::Waiting); + if (!QmlDebugTest::waitForSignal(query, SIGNAL(stateChanged(QmlDebugQuery::State)))) + QFAIL("query timed out"); +} + +void tst_QmlDebug::recursiveObjectTest(QObject *o, const QmlDebugObjectReference &oref, bool recursive) const +{ + const QMetaObject *meta = o->metaObject(); + + QmlType *type = QmlMetaType::qmlType(o->metaObject()); + QString className = type ? type->qmlTypeName() : QString(); + className = className.mid(className.lastIndexOf(QLatin1Char('/'))+1); + + QCOMPARE(oref.debugId(), QmlDebugService::idForObject(o)); + QCOMPARE(oref.name(), o->objectName()); + QCOMPARE(oref.className(), className); + QCOMPARE(oref.contextDebugId(), QmlDebugService::idForObject(qmlContext(o))); + + const QObjectList &children = o->children(); + for (int i=0; i= 0); + + QmlDebugObjectReference cref; + foreach (const QmlDebugObjectReference &ref, oref.children()) { + if (ref.debugId() == debugId) { + cref = ref; + break; + } + } + QVERIFY(cref.debugId() >= 0); + + if (recursive) + recursiveObjectTest(child, cref, true); + } + + foreach (const QmlDebugPropertyReference &p, oref.properties()) { + QCOMPARE(p.objectDebugId(), QmlDebugService::idForObject(o)); + + // signal properties are fake - they are generated from QmlBoundSignal children + if (p.name().startsWith("on") && p.name().length() > 2 && p.name()[2].isUpper()) { + QVERIFY(p.value().toString().startsWith('{') && p.value().toString().endsWith('}')); + QVERIFY(p.valueTypeName().isEmpty()); + QVERIFY(p.binding().isEmpty()); + QVERIFY(!p.hasNotifySignal()); + continue; + } + + QMetaProperty pmeta = meta->property(meta->indexOfProperty(p.name().toUtf8().constData())); + + QCOMPARE(p.name(), QString::fromUtf8(pmeta.name())); + + if (pmeta.type() < QVariant::UserType) // TODO test complex types + QCOMPARE(p.value(), pmeta.read(o)); + + if (p.name() == "parent") + QVERIFY(p.valueTypeName() == "QGraphicsObject*" || p.valueTypeName() == "QmlGraphicsItem*"); + else + QCOMPARE(p.valueTypeName(), QString::fromUtf8(pmeta.typeName())); + + QmlAbstractBinding *binding = QmlMetaProperty(o, p.name()).binding(); + if (binding) + QCOMPARE(binding->expression(), p.binding()); + + QCOMPARE(p.hasNotifySignal(), pmeta.hasNotifySignal()); + + QVERIFY(pmeta.isValid()); + } +} + +void tst_QmlDebug::recursiveCompareObjects(const QmlDebugObjectReference &a, const QmlDebugObjectReference &b) const +{ + QCOMPARE(a.debugId(), b.debugId()); + QCOMPARE(a.className(), b.className()); + QCOMPARE(a.name(), b.name()); + QCOMPARE(a.contextDebugId(), b.contextDebugId()); + + QCOMPARE(a.source().url(), b.source().url()); + QCOMPARE(a.source().lineNumber(), b.source().lineNumber()); + QCOMPARE(a.source().columnNumber(), b.source().columnNumber()); + + QCOMPARE(a.properties().count(), b.properties().count()); + QCOMPARE(a.children().count(), b.children().count()); + + QList aprops = a.properties(); + QList bprops = b.properties(); + + for (int i=0; i(); +} + +void tst_QmlDebug::watch_property() +{ + QmlDebugObjectReference obj = findRootObject(); + QmlDebugPropertyReference prop = findProperty(obj.properties(), "width"); + + QmlDebugPropertyWatch *watch; + + QmlEngineDebug unconnected(0); + watch = unconnected.addWatch(prop, this); + QCOMPARE(watch->state(), QmlDebugWatch::Dead); + delete watch; + + watch = m_dbg->addWatch(QmlDebugPropertyReference(), this); + QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); + QCOMPARE(watch->state(), QmlDebugWatch::Inactive); + delete watch; + + watch = m_dbg->addWatch(prop, this); + QCOMPARE(watch->state(), QmlDebugWatch::Waiting); + QCOMPARE(watch->objectDebugId(), obj.debugId()); + QCOMPARE(watch->name(), prop.name()); + + QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); + + int origWidth = m_rootItem->property("width").toInt(); + m_rootItem->setProperty("width", origWidth*2); + + // stateChanged() is received before valueChanged() + QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); + QCOMPARE(watch->state(), QmlDebugWatch::Active); + QCOMPARE(spy.count(), 1); + + m_dbg->removeWatch(watch); + delete watch; + + // restore original value and verify spy doesn't get additional signal since watch has been removed + m_rootItem->setProperty("width", origWidth); + QTest::qWait(100); + QCOMPARE(spy.count(), 1); + + QCOMPARE(spy.at(0).at(0).value(), prop.name().toUtf8()); + QCOMPARE(spy.at(0).at(1).value(), qVariantFromValue(origWidth*2)); +} + +void tst_QmlDebug::watch_object() +{ + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + + QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); + waitForQuery(q_context); + + QmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); + waitForQuery(q_obj); + + QmlDebugObjectReference obj = q_obj->object(); + + delete q_engines; + delete q_context; + delete q_obj; + + QmlDebugWatch *watch; + + QmlEngineDebug unconnected(0); + watch = unconnected.addWatch(obj, this); + QCOMPARE(watch->state(), QmlDebugWatch::Dead); + delete watch; + + watch = m_dbg->addWatch(QmlDebugObjectReference(), this); + QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); + QCOMPARE(watch->state(), QmlDebugWatch::Inactive); + delete watch; + + watch = m_dbg->addWatch(obj, this); + QCOMPARE(watch->state(), QmlDebugWatch::Waiting); + QCOMPARE(watch->objectDebugId(), obj.debugId()); + + QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); + + int origWidth = m_rootItem->property("width").toInt(); + int origHeight = m_rootItem->property("height").toInt(); + m_rootItem->setProperty("width", origWidth*2); + m_rootItem->setProperty("height", origHeight*2); + + // stateChanged() is received before any valueChanged() signals + QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); + QCOMPARE(watch->state(), QmlDebugWatch::Active); + QVERIFY(spy.count() > 0); + + int newWidth = -1; + int newHeight = -1; + for (int i=0; i() == "width") + newWidth = values[1].value().toInt(); + else if (values[0].value() == "height") + newHeight = values[1].value().toInt(); + + } + + m_dbg->removeWatch(watch); + delete watch; + + // since watch has been removed, restoring the original values should not trigger a valueChanged() + spy.clear(); + m_rootItem->setProperty("width", origWidth); + m_rootItem->setProperty("height", origHeight); + QTest::qWait(100); + QCOMPARE(spy.count(), 0); + + QCOMPARE(newWidth, origWidth * 2); + QCOMPARE(newHeight, origHeight * 2); +} + +void tst_QmlDebug::watch_expression() +{ + QFETCH(QString, expr); + QFETCH(int, increment); + QFETCH(int, incrementCount); + + int origWidth = m_rootItem->property("width").toInt(); + + QmlDebugObjectReference obj = findRootObject(); + + QmlDebugObjectExpressionWatch *watch; + + QmlEngineDebug unconnected(0); + watch = unconnected.addWatch(obj, expr, this); + QCOMPARE(watch->state(), QmlDebugWatch::Dead); + delete watch; + + watch = m_dbg->addWatch(QmlDebugObjectReference(), expr, this); + QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); + QCOMPARE(watch->state(), QmlDebugWatch::Inactive); + delete watch; + + watch = m_dbg->addWatch(obj, expr, this); + QCOMPARE(watch->state(), QmlDebugWatch::Waiting); + QCOMPARE(watch->objectDebugId(), obj.debugId()); + QCOMPARE(watch->expression(), expr); + + QSignalSpy spyState(watch, SIGNAL(stateChanged(QmlDebugWatch::State))); + + QSignalSpy spy(watch, SIGNAL(valueChanged(QByteArray,QVariant))); + int expectedSpyCount = incrementCount + 1; // should also get signal with expression's initial value + + int width = origWidth; + for (int i=0; i 0) { + width += increment; + m_rootItem->setProperty("width", width); + } + if (!QmlDebugTest::waitForSignal(watch, SIGNAL(valueChanged(QByteArray,QVariant)))) + QFAIL("Did not receive valueChanged() for expression"); + } + + if (spyState.count() == 0) + QVERIFY(QmlDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QmlDebugWatch::State)))); + QCOMPARE(spyState.count(), 1); + QCOMPARE(watch->state(), QmlDebugWatch::Active); + + m_dbg->removeWatch(watch); + delete watch; + + // restore original value and verify spy doesn't get a signal since watch has been removed + m_rootItem->setProperty("width", origWidth); + QTest::qWait(100); + QCOMPARE(spy.count(), expectedSpyCount); + + width = origWidth + increment; + for (int i=0; i().toInt(), width); + width += increment; + } +} + +void tst_QmlDebug::watch_expression_data() +{ + QTest::addColumn("expr"); + QTest::addColumn("increment"); + QTest::addColumn("incrementCount"); + + QTest::newRow("width") << "width" << 0 << 0; + QTest::newRow("width+10") << "width + 10" << 10 << 5; +} + +void tst_QmlDebug::watch_context() +{ + QmlDebugContextReference c; + QTest::ignoreMessage(QtWarningMsg, "QmlEngineDebug::addWatch(): Not implemented"); + QVERIFY(!m_dbg->addWatch(c, QString(), this)); +} + +void tst_QmlDebug::watch_file() +{ + QmlDebugFileReference f; + QTest::ignoreMessage(QtWarningMsg, "QmlEngineDebug::addWatch(): Not implemented"); + QVERIFY(!m_dbg->addWatch(f, this)); +} + +void tst_QmlDebug::queryAvailableEngines() +{ + QmlDebugEnginesQuery *q_engines; + + QmlEngineDebug unconnected(0); + q_engines = unconnected.queryAvailableEngines(0); + QCOMPARE(q_engines->state(), QmlDebugQuery::Error); + delete q_engines; + + q_engines = m_dbg->queryAvailableEngines(this); + delete q_engines; + + q_engines = m_dbg->queryAvailableEngines(this); + QVERIFY(q_engines->engines().isEmpty()); + waitForQuery(q_engines); + + // TODO test multiple engines + QList engines = q_engines->engines(); + QCOMPARE(engines.count(), 1); + + foreach(const QmlDebugEngineReference &e, engines) { + QCOMPARE(e.debugId(), QmlDebugService::idForObject(m_engine)); + QCOMPARE(e.name(), m_engine->objectName()); + } + + delete q_engines; +} + +void tst_QmlDebug::queryRootContexts() +{ + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + int engineId = q_engines->engines()[0].debugId(); + + QmlDebugRootContextQuery *q_context; + + QmlEngineDebug unconnected(0); + q_context = unconnected.queryRootContexts(engineId, this); + QCOMPARE(q_context->state(), QmlDebugQuery::Error); + delete q_context; + + q_context = m_dbg->queryRootContexts(engineId, this); + delete q_context; + + q_context = m_dbg->queryRootContexts(engineId, this); + waitForQuery(q_context); + + QmlContext *actualContext = m_engine->rootContext(); + QmlDebugContextReference context = q_context->rootContext(); + QCOMPARE(context.debugId(), QmlDebugService::idForObject(actualContext)); + QCOMPARE(context.name(), actualContext->objectName()); + + QCOMPARE(context.objects().count(), 2); // 2 qml component objects created for context in main() + + // root context query sends only root object data - it doesn't fill in + // the children or property info + QCOMPARE(context.objects()[0].properties().count(), 0); + QCOMPARE(context.objects()[0].children().count(), 0); + + QCOMPARE(context.contexts().count(), 1); + QVERIFY(context.contexts()[0].debugId() >= 0); + QCOMPARE(context.contexts()[0].name(), QString("tst_QmlDebug_childContext")); + + delete q_engines; + delete q_context; +} + +void tst_QmlDebug::queryObject() +{ + QFETCH(bool, recursive); + + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + + QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); + waitForQuery(q_context); + QmlDebugObjectReference rootObject = q_context->rootContext().objects()[0]; + + QmlDebugObjectQuery *q_obj = 0; + + QmlEngineDebug unconnected(0); + q_obj = recursive ? unconnected.queryObjectRecursive(rootObject, this) : unconnected.queryObject(rootObject, this); + QCOMPARE(q_obj->state(), QmlDebugQuery::Error); + delete q_obj; + + q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); + delete q_obj; + + q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); + waitForQuery(q_obj); + + QmlDebugObjectReference obj = q_obj->object(); + + delete q_engines; + delete q_context; + delete q_obj; + + // check source as defined in main() + QmlDebugFileReference source = obj.source(); + QCOMPARE(source.url(), QUrl("file://")); + QCOMPARE(source.lineNumber(), 2); + QCOMPARE(source.columnNumber(), 1); + + // generically test all properties, children and childrens' properties + recursiveObjectTest(m_rootItem, obj, recursive); + + if (recursive) { + foreach(const QmlDebugObjectReference &child, obj.children()) + QVERIFY(child.properties().count() > 0); + + QmlDebugObjectReference rect; + QmlDebugObjectReference text; + foreach (const QmlDebugObjectReference &child, obj.children()) { + if (child.className() == "Rectangle") + rect = child; + else if (child.className() == "Text") + text = child; + } + + // test specific property values + QCOMPARE(findProperty(rect.properties(), "width").value(), qVariantFromValue(500)); + QCOMPARE(findProperty(rect.properties(), "height").value(), qVariantFromValue(600)); + QCOMPARE(findProperty(rect.properties(), "color").value(), qVariantFromValue(QColor("blue"))); + + QCOMPARE(findProperty(text.properties(), "color").value(), qVariantFromValue(QColor("blue"))); + + } else { + foreach(const QmlDebugObjectReference &child, obj.children()) + QCOMPARE(child.properties().count(), 0); + } +} + +void tst_QmlDebug::queryObject_data() +{ + QTest::addColumn("recursive"); + + QTest::newRow("non-recursive") << false; + QTest::newRow("recursive") << true; +} + +void tst_QmlDebug::queryExpressionResult() +{ + QFETCH(QString, expr); + QFETCH(QVariant, result); + + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); // check immediate deletion is ok + + QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); + waitForQuery(q_context); + int objectId = q_context->rootContext().objects()[0].debugId(); + + QmlDebugExpressionQuery *q_expr; + + QmlEngineDebug unconnected(0); + q_expr = unconnected.queryExpressionResult(objectId, expr, this); + QCOMPARE(q_expr->state(), QmlDebugQuery::Error); + delete q_expr; + + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); + delete q_expr; + + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); + QCOMPARE(q_expr->expression(), expr); + waitForQuery(q_expr); + + QCOMPARE(q_expr->result(), result); + + delete q_engines; + delete q_context; + delete q_expr; +} + +void tst_QmlDebug::queryExpressionResult_data() +{ + QTest::addColumn("expr"); + QTest::addColumn("result"); + + QTest::newRow("width + 50") << "width + 50" << qVariantFromValue(60); + QTest::newRow("blueRect.width") << "blueRect.width" << qVariantFromValue(500); + QTest::newRow("bad expr") << "aeaef" << qVariantFromValue(QString("")); +} + +void tst_QmlDebug::tst_QmlDebugFileReference() +{ + QmlDebugFileReference ref; + QVERIFY(ref.url().isEmpty()); + QCOMPARE(ref.lineNumber(), -1); + QCOMPARE(ref.columnNumber(), -1); + + ref.setUrl(QUrl("http://test")); + QCOMPARE(ref.url(), QUrl("http://test")); + ref.setLineNumber(1); + QCOMPARE(ref.lineNumber(), 1); + ref.setColumnNumber(1); + QCOMPARE(ref.columnNumber(), 1); + + QmlDebugFileReference copy(ref); + QmlDebugFileReference copyAssign; + copyAssign = ref; + foreach (const QmlDebugFileReference &r, (QList() << copy << copyAssign)) { + QCOMPARE(r.url(), ref.url()); + QCOMPARE(r.lineNumber(), ref.lineNumber()); + QCOMPARE(r.columnNumber(), ref.columnNumber()); + } +} + +void tst_QmlDebug::tst_QmlDebugEngineReference() +{ + QmlDebugEngineReference ref; + QCOMPARE(ref.debugId(), -1); + QVERIFY(ref.name().isEmpty()); + + ref = QmlDebugEngineReference(1); + QCOMPARE(ref.debugId(), 1); + QVERIFY(ref.name().isEmpty()); + + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + ref = q_engines->engines()[0]; + delete q_engines; + + QmlDebugEngineReference copy(ref); + QmlDebugEngineReference copyAssign; + copyAssign = ref; + foreach (const QmlDebugEngineReference &r, (QList() << copy << copyAssign)) { + QCOMPARE(r.debugId(), ref.debugId()); + QCOMPARE(r.name(), ref.name()); + } +} + +void tst_QmlDebug::tst_QmlDebugObjectReference() +{ + QmlDebugObjectReference ref; + QCOMPARE(ref.debugId(), -1); + QCOMPARE(ref.className(), QString()); + QCOMPARE(ref.name(), QString()); + QCOMPARE(ref.contextDebugId(), -1); + QVERIFY(ref.properties().isEmpty()); + QVERIFY(ref.children().isEmpty()); + + QmlDebugFileReference source = ref.source(); + QVERIFY(source.url().isEmpty()); + QVERIFY(source.lineNumber() < 0); + QVERIFY(source.columnNumber() < 0); + + ref = QmlDebugObjectReference(1); + QCOMPARE(ref.debugId(), 1); + + QmlDebugObjectReference rootObject = findRootObject(); + QmlDebugObjectQuery *query = m_dbg->queryObjectRecursive(rootObject, this); + waitForQuery(query); + ref = query->object(); + delete query; + + QVERIFY(ref.debugId() >= 0); + + QmlDebugObjectReference copy(ref); + QmlDebugObjectReference copyAssign; + copyAssign = ref; + foreach (const QmlDebugObjectReference &r, (QList() << copy << copyAssign)) + recursiveCompareObjects(r, ref); +} + +void tst_QmlDebug::tst_QmlDebugContextReference() +{ + QmlDebugContextReference ref; + QCOMPARE(ref.debugId(), -1); + QVERIFY(ref.name().isEmpty()); + QVERIFY(ref.objects().isEmpty()); + QVERIFY(ref.contexts().isEmpty()); + + QmlDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); + waitForQuery(q_engines); + QmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); + waitForQuery(q_context); + + ref = q_context->rootContext(); + delete q_engines; + delete q_context; + QVERIFY(ref.debugId() >= 0); + + QmlDebugContextReference copy(ref); + QmlDebugContextReference copyAssign; + copyAssign = ref; + foreach (const QmlDebugContextReference &r, (QList() << copy << copyAssign)) + recursiveCompareContexts(r, ref); +} + +void tst_QmlDebug::tst_QmlDebugPropertyReference() +{ + QmlDebugObjectReference rootObject = findRootObject(); + QmlDebugObjectQuery *query = m_dbg->queryObject(rootObject, this); + waitForQuery(query); + QmlDebugObjectReference obj = query->object(); + delete query; + + QmlDebugPropertyReference ref = findProperty(obj.properties(), "scale"); + QVERIFY(ref.objectDebugId() > 0); + QVERIFY(!ref.name().isEmpty()); + QVERIFY(!ref.value().isNull()); + QVERIFY(!ref.valueTypeName().isEmpty()); + QVERIFY(!ref.binding().isEmpty()); + QVERIFY(ref.hasNotifySignal()); + + QmlDebugPropertyReference copy(ref); + QmlDebugPropertyReference copyAssign; + copyAssign = ref; + foreach (const QmlDebugPropertyReference &r, (QList() << copy << copyAssign)) + compareProperties(r, ref); +} + + +class tst_QmlDebug_Factory : public QmlTestFactory +{ +public: + QObject *createTest(QmlDebugTestData *data) + { + QmlContext *c = new QmlContext(data->engine->rootContext()); + c->setObjectName("tst_QmlDebug_childContext"); + return new tst_QmlDebug(data); + } +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QList qml; + qml << "import Qt 4.6\n" + "Item {" + "width: 10; height: 20; scale: blueRect.scale;" + "Rectangle { id: blueRect; width: 500; height: 600; color: \"blue\"; }" + "Text { color: blueRect.color; }" + "MouseRegion {" + "onEntered: { print('hello') }" + "}" + "}"; + // add second component to test multiple root contexts + qml << "import Qt 4.6\n" + "Item {}"; + tst_QmlDebug_Factory factory; + return QmlDebugTest::runTests(&factory, qml); +} + +//QTEST_MAIN(tst_QmlDebug) + +#include "tst_qmldebug.moc" diff --git a/tests/auto/declarative/qmldebugclient/qmldebugclient.pro b/tests/auto/declarative/qmldebugclient/qmldebugclient.pro new file mode 100644 index 0000000..36aa818 --- /dev/null +++ b/tests/auto/declarative/qmldebugclient/qmldebugclient.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += network declarative +macx:CONFIG -= app_bundle + +HEADERS += ../shared/debugutil_p.h +SOURCES += tst_qmldebugclient.cpp \ + ../shared/debugutil.cpp diff --git a/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp b/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp new file mode 100644 index 0000000..8325731 --- /dev/null +++ b/tests/auto/declarative/qmldebugclient/tst_qmldebugclient.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "../shared/debugutil_p.h" + +class tst_QmlDebugClient : public QObject +{ + Q_OBJECT + +public: + tst_QmlDebugClient(QmlDebugTestData *data) + { + m_conn = data->conn; + m_engine = data->engine; + } + + QmlDebugConnection *m_conn; + QmlEngine *m_engine; + +private slots: + void name(); + void isEnabled(); + void setEnabled(); + void isConnected(); + void sendMessage(); +}; + +void tst_QmlDebugClient::name() +{ + QString name = "tst_QmlDebugClient::name()"; + + QmlDebugClient client(name, m_conn); + QCOMPARE(client.name(), name); +} + +void tst_QmlDebugClient::isEnabled() +{ + QmlDebugClient client("tst_QmlDebugClient::isEnabled()", m_conn); + QCOMPARE(client.isEnabled(), false); +} + +void tst_QmlDebugClient::setEnabled() +{ + QmlDebugTestService service("tst_QmlDebugClient::setEnabled()"); + QmlDebugTestClient client("tst_QmlDebugClient::setEnabled()", m_conn); + + QCOMPARE(service.isEnabled(), false); + + client.setEnabled(true); + QCOMPARE(client.isEnabled(), true); + QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); + QCOMPARE(service.isEnabled(), true); + + client.setEnabled(false); + QCOMPARE(client.isEnabled(), false); + QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); + QCOMPARE(service.isEnabled(), false); +} + +void tst_QmlDebugClient::isConnected() +{ + QmlDebugClient client1("tst_QmlDebugClient::isConnected() A", m_conn); + QCOMPARE(client1.isConnected(), true); + + QmlDebugConnection conn; + QmlDebugClient client2("tst_QmlDebugClient::isConnected() B", &conn); + QCOMPARE(client2.isConnected(), false); + + QmlDebugClient client3("tst_QmlDebugClient::isConnected() C", 0); + QCOMPARE(client3.isConnected(), false); + + // duplicate plugin name + QTest::ignoreMessage(QtWarningMsg, "QmlDebugClient: Conflicting plugin name \"tst_QmlDebugClient::isConnected() A\" "); + QmlDebugClient client4("tst_QmlDebugClient::isConnected() A", m_conn); + QCOMPARE(client4.isConnected(), false); +} + +void tst_QmlDebugClient::sendMessage() +{ + QmlDebugTestService service("tst_QmlDebugClient::sendMessage()"); + QmlDebugTestClient client("tst_QmlDebugClient::sendMessage()", m_conn); + + QByteArray msg = "hello!"; + + client.sendMessage(msg); + QByteArray resp = client.waitForResponse(); + QCOMPARE(resp, msg); +} + + +class tst_QmlDebugClient_Factory : public QmlTestFactory +{ +public: + QObject *createTest(QmlDebugTestData *data) { return new tst_QmlDebugClient(data); } +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + tst_QmlDebugClient_Factory factory; + return QmlDebugTest::runTests(&factory); +} + +#include "tst_qmldebugclient.moc" diff --git a/tests/auto/declarative/qmldebugservice/qmldebugservice.pro b/tests/auto/declarative/qmldebugservice/qmldebugservice.pro new file mode 100644 index 0000000..9995f1f --- /dev/null +++ b/tests/auto/declarative/qmldebugservice/qmldebugservice.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += network declarative +macx:CONFIG -= app_bundle + +HEADERS += ../shared/debugutil_p.h +SOURCES += tst_qmldebugservice.cpp \ + ../shared/debugutil.cpp diff --git a/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp b/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp new file mode 100644 index 0000000..625d1f5 --- /dev/null +++ b/tests/auto/declarative/qmldebugservice/tst_qmldebugservice.cpp @@ -0,0 +1,189 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "../shared/debugutil_p.h" + +class tst_QmlDebugService : public QObject +{ + Q_OBJECT + +public: + tst_QmlDebugService(QmlDebugTestData *data) + { + m_conn = data->conn; + m_engine = data->engine; + } + + QmlDebugConnection *m_conn; + QmlEngine *m_engine; + +private slots: + void name(); + void isEnabled(); + void enabledChanged(); + void sendMessage(); + void idForObject(); + void objectForId(); + void objectToString(); +}; + +void tst_QmlDebugService::name() +{ + QString name = "tst_QmlDebugService::name()"; + + QmlDebugService service(name); + QCOMPARE(service.name(), name); +} + +void tst_QmlDebugService::isEnabled() +{ + QmlDebugTestService service("tst_QmlDebugService::isEnabled()", m_conn); + QCOMPARE(service.isEnabled(), false); + + QmlDebugTestClient client("tst_QmlDebugService::isEnabled()", m_conn); + client.setEnabled(true); + QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); + QCOMPARE(service.isEnabled(), true); + + QTest::ignoreMessage(QtWarningMsg, "QmlDebugService: Conflicting plugin name \"tst_QmlDebugService::isEnabled()\" "); + QmlDebugService duplicate("tst_QmlDebugService::isEnabled()", m_conn); + QCOMPARE(duplicate.isEnabled(), false); +} + +void tst_QmlDebugService::enabledChanged() +{ + QmlDebugTestService service("tst_QmlDebugService::enabledChanged()"); + QmlDebugTestClient client("tst_QmlDebugService::enabledChanged()", m_conn); + + QCOMPARE(service.enabled, false); + + client.setEnabled(true); + QmlDebugTest::waitForSignal(&service, SIGNAL(enabledStateChanged())); + QCOMPARE(service.enabled, true); +} + +void tst_QmlDebugService::sendMessage() +{ + QmlDebugTestService service("tst_QmlDebugService::sendMessage()"); + QmlDebugTestClient client("tst_QmlDebugService::sendMessage()", m_conn); + + QByteArray msg = "hello!"; + + client.sendMessage(msg); + QByteArray resp = client.waitForResponse(); + QCOMPARE(resp, msg); +} + +void tst_QmlDebugService::idForObject() +{ + QCOMPARE(QmlDebugService::idForObject(0), -1); + + QObject *objA = new QObject; + + int idA = QmlDebugService::idForObject(objA); + QVERIFY(idA >= 0); + QCOMPARE(QmlDebugService::objectForId(idA), objA); + + int idAA = QmlDebugService::idForObject(objA); + QCOMPARE(idAA, idA); + + QObject *objB = new QObject; + int idB = QmlDebugService::idForObject(objB); + QVERIFY(idB != idA); + QCOMPARE(QmlDebugService::objectForId(idB), objB); + + delete objA; + delete objB; +} + +void tst_QmlDebugService::objectForId() +{ + QCOMPARE(QmlDebugService::objectForId(-1), static_cast(0)); + QCOMPARE(QmlDebugService::objectForId(1), static_cast(0)); + + QObject *obj = new QObject; + int id = QmlDebugService::idForObject(obj); + QCOMPARE(QmlDebugService::objectForId(id), obj); + + delete obj; + QCOMPARE(QmlDebugService::objectForId(id), static_cast(0)); +} + +void tst_QmlDebugService::objectToString() +{ + QCOMPARE(QmlDebugService::objectToString(0), QString("NULL")); + + QObject *obj = new QObject; + QCOMPARE(QmlDebugService::objectToString(obj), QString("QObject: ")); + + obj->setObjectName("Hello"); + QCOMPARE(QmlDebugService::objectToString(obj), QString("QObject: Hello")); +} + + +class tst_QmlDebugService_Factory : public QmlTestFactory +{ +public: + QObject *createTest(QmlDebugTestData *data) { return new tst_QmlDebugService(data); } +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + tst_QmlDebugService_Factory factory; + return QmlDebugTest::runTests(&factory); +} + +#include "tst_qmldebugservice.moc" diff --git a/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro b/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro new file mode 100644 index 0000000..f42cecc --- /dev/null +++ b/tests/auto/declarative/qpacketprotocol/qpacketprotocol.pro @@ -0,0 +1,7 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += network declarative +macx:CONFIG -= app_bundle + +HEADERS += ../shared/debugutil_p.h +SOURCES += tst_qpacketprotocol.cpp \ + ../shared/debugutil.cpp diff --git a/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp b/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp new file mode 100644 index 0000000..b54f133 --- /dev/null +++ b/tests/auto/declarative/qpacketprotocol/tst_qpacketprotocol.cpp @@ -0,0 +1,270 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../shared/debugutil_p.h" + +class tst_QPacketProtocol : public QObject +{ + Q_OBJECT + +private: + QTcpServer *m_server; + QTcpSocket *m_client; + QTcpSocket *m_serverConn; + +private slots: + void init(); + void cleanup(); + + void maximumPacketSize(); + void setMaximumPacketSize(); + void setMaximumPacketSize_data(); + void send(); + void send_data(); + void packetsAvailable(); + void packetsAvailable_data(); + void clear(); + void read(); + void device(); + + void tst_QPacket_clear(); +}; + +void tst_QPacketProtocol::init() +{ + m_server = new QTcpServer(this); + QVERIFY(m_server->listen()); + + m_client = new QTcpSocket(this); + m_client->connectToHost(m_server->serverAddress(), m_server->serverPort()); + + QVERIFY(m_client->waitForConnected()); + QVERIFY(m_server->waitForNewConnection()); + m_serverConn = m_server->nextPendingConnection(); +} + +void tst_QPacketProtocol::cleanup() +{ + delete m_client; + delete m_serverConn; + delete m_server; +} + +void tst_QPacketProtocol::maximumPacketSize() +{ + QPacketProtocol p(m_client); + QCOMPARE(p.maximumPacketSize(), 0x7FFFFFFF); +} + +void tst_QPacketProtocol::setMaximumPacketSize() +{ + QFETCH(qint32, size); + QFETCH(qint32, expected); + + QPacketProtocol out(m_serverConn); + QCOMPARE(out.setMaximumPacketSize(size), expected); + + if (size == expected) { + QPacketProtocol in(m_client); + QByteArray b; + b.fill('a', size + 1); + out.send() << b.constData(); + QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(invalidPacket()))); + } +} + +void tst_QPacketProtocol::setMaximumPacketSize_data() +{ + QTest::addColumn("size"); + QTest::addColumn("expected"); + + QTest::newRow("invalid") << qint32(sizeof(qint32) - 1) << qint32(0x7FFFFFFF); + QTest::newRow("still invalid") << qint32(sizeof(qint32)) << qint32(0x7FFFFFFF); + QTest::newRow("valid") << qint32(sizeof(qint32) + 1) << qint32(sizeof(qint32) + 1); +} + +void tst_QPacketProtocol::send() +{ + QFETCH(bool, useAutoSend); + + QPacketProtocol in(m_client); + QPacketProtocol out(m_serverConn); + + QByteArray ba; + int num; + + if (useAutoSend) { + out.send() << "Hello world" << 123; + } else { + QPacket packet; + packet << "Hello world" << 123; + out.send(packet); + } + + QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); + + QPacket p = in.read(); + p >> ba >> num; + QCOMPARE(ba, QByteArray("Hello world") + '\0'); + QCOMPARE(num, 123); +} + +void tst_QPacketProtocol::send_data() +{ + QTest::addColumn("useAutoSend"); + + QTest::newRow("auto send") << true; + QTest::newRow("no auto send") << false; +} + +void tst_QPacketProtocol::packetsAvailable() +{ + QFETCH(int, packetCount); + + QPacketProtocol out(m_client); + QPacketProtocol in(m_serverConn); + + QCOMPARE(out.packetsAvailable(), qint64(0)); + QCOMPARE(in.packetsAvailable(), qint64(0)); + + for (int i=0; i("packetCount"); + + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; + QTest::newRow("10") << 10; +} + +void tst_QPacketProtocol::clear() +{ + QPacketProtocol in(m_client); + QPacketProtocol out(m_serverConn); + + out.send() << 123; + out.send() << 456; + QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); + + in.clear(); + QVERIFY(in.read().isEmpty()); +} + +void tst_QPacketProtocol::read() +{ + QPacketProtocol in(m_client); + QPacketProtocol out(m_serverConn); + + QVERIFY(in.read().isEmpty()); + + out.send() << 123; + out.send() << 456; + QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); + + int num; + + QPacket p1 = in.read(); + QVERIFY(!p1.isEmpty()); + p1 >> num; + QCOMPARE(num, 123); + + QPacket p2 = in.read(); + QVERIFY(!p2.isEmpty()); + p2 >> num; + QCOMPARE(num, 456); + + QVERIFY(in.read().isEmpty()); +} + +void tst_QPacketProtocol::device() +{ + QPacketProtocol p(m_client); + QCOMPARE(p.device(), m_client); +} + +void tst_QPacketProtocol::tst_QPacket_clear() +{ + QPacketProtocol protocol(m_client); + + QPacket packet; + + packet << "Hello world!" << 123; + protocol.send(packet); + + packet.clear(); + QVERIFY(packet.isEmpty()); + packet << "Goodbyte world!" << 789; + protocol.send(packet); + + QByteArray ba; + int num; + QPacketProtocol in(m_serverConn); + QVERIFY(QmlDebugTest::waitForSignal(&in, SIGNAL(readyRead()))); + + QPacket p1 = in.read(); + p1 >> ba >> num; + QCOMPARE(ba, QByteArray("Hello world!") + '\0'); + QCOMPARE(num, 123); + + QPacket p2 = in.read(); + p2 >> ba >> num; + QCOMPARE(ba, QByteArray("Goodbyte world!") + '\0'); + QCOMPARE(num, 789); +} + +QTEST_MAIN(tst_QPacketProtocol) + +#include "tst_qpacketprotocol.moc" -- cgit v0.12 From 9600df5fa3661addb8aaa817e64a2bc6c3abbcc3 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 17 Nov 2009 15:02:00 +1000 Subject: Restore methods removed by f01e6e8993856cdcddc51868e91ef25b35695546 --- src/declarative/util/qmllistaccessor.cpp | 128 +++++++++++++++++++++++++++++++ src/declarative/util/qmllistaccessor_p.h | 5 ++ 2 files changed, 133 insertions(+) diff --git a/src/declarative/util/qmllistaccessor.cpp b/src/declarative/util/qmllistaccessor.cpp index 2c01081..910f2a5 100644 --- a/src/declarative/util/qmllistaccessor.cpp +++ b/src/declarative/util/qmllistaccessor.cpp @@ -149,6 +149,134 @@ QVariant QmlListAccessor::at(int idx) const return QVariant(); } +void QmlListAccessor::append(const QVariant &value) +{ + switch(m_type) { + case Invalid: + break; + case StringList: + { + const QString &str = value.toString(); + qvariant_cast(d).append(str); + break; + } + case VariantList: + { + qvariant_cast(d).append(value); + break; + } + case QmlList: + { + QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData(); + li->append(const_cast(value.constData())); //XXX + break; + } + case QList: + QmlMetaType::append(d, value); + break; + case Instance: + case Integer: + //do nothing + break; + } +} + +void QmlListAccessor::insert(int index, const QVariant &value) +{ + switch(m_type) { + case Invalid: + break; + case StringList: + { + const QString &str = value.toString(); + qvariant_cast(d).insert(index, str); + break; + } + case VariantList: + { + qvariant_cast(d).insert(index, value); + break; + } + case QmlList: + { + QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData(); + li->insert(index, const_cast(value.constData())); //XXX + break; + } + case QList: + //XXX needs implementation + qWarning() << "insert function not yet implemented for QLists"; + break; + case Instance: + //XXX do nothing? + if (index == 0) + setList(value); + break; + case Integer: + break; + } +} + +void QmlListAccessor::removeAt(int index) +{ + switch(m_type) { + case Invalid: + break; + case StringList: + qvariant_cast(d).removeAt(index); + break; + case VariantList: + qvariant_cast(d).removeAt(index); + break; + case QmlList: + { + QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData(); + li->removeAt(index); + break; + } + case QList: + //XXX needs implementation + qWarning() << "removeAt function not yet implemented for QLists"; + break; + case Instance: + //XXX do nothing? + if (index == 0) + setList(QVariant()); + break; + case Integer: + break; + } +} + +void QmlListAccessor::clear() +{ + switch(m_type) { + case Invalid: + break; + case StringList: + qvariant_cast(d).clear(); + break; + case VariantList: + qvariant_cast(d).clear(); + break; + case QmlList: + { + QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData(); + li->clear(); + break; + } + case QList: + QmlMetaType::clear(d); + break; + case Instance: + //XXX what should we do here? + setList(QVariant()); + break; + case Integer: + d = 0; + } +} + bool QmlListAccessor::isValid() const { return m_type != Invalid; diff --git a/src/declarative/util/qmllistaccessor_p.h b/src/declarative/util/qmllistaccessor_p.h index 7b34d75..2697606 100644 --- a/src/declarative/util/qmllistaccessor_p.h +++ b/src/declarative/util/qmllistaccessor_p.h @@ -65,6 +65,11 @@ public: int count() const; QVariant at(int) const; + virtual void append(const QVariant &); + virtual void insert(int, const QVariant &); + virtual void removeAt(int); + virtual void clear(); + enum Type { Invalid, StringList, VariantList, QmlList, QList, Instance, Integer }; Type type() const { return m_type; } -- cgit v0.12 From 6f3b799d5c1fff8ffe77c874f4c25461464b6958 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 17 Nov 2009 15:10:33 +1000 Subject: Add additional anchor test. --- .../declarative/states/data/anchorChanges3.qml | 29 ++++++++++++++++++++++ tests/auto/declarative/states/tst_states.cpp | 28 +++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/auto/declarative/states/data/anchorChanges3.qml diff --git a/tests/auto/declarative/states/data/anchorChanges3.qml b/tests/auto/declarative/states/data/anchorChanges3.qml new file mode 100644 index 0000000..8a74595 --- /dev/null +++ b/tests/auto/declarative/states/data/anchorChanges3.qml @@ -0,0 +1,29 @@ +import Qt 4.6 + +Rectangle { + id: container + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + color: "green"; + anchors.left: parent.left + anchors.right: rightGuideline.left + anchors.top: topGuideline.top + anchors.bottom: container.bottom + } + Item { id: leftGuideline; x: 10 } + Item { id: rightGuideline; x: 150 } + Item { id: topGuideline; y: 10 } + Item { id: bottomGuideline; y: 150 } + states: State { + name: "reanchored" + AnchorChanges { + target: myRect; + left: leftGuideline.left + right: container.right + top: container.top + bottom: bottomGuideline.bottom + } + } +} diff --git a/tests/auto/declarative/states/tst_states.cpp b/tests/auto/declarative/states/tst_states.cpp index fe90191..4f8b9c2 100644 --- a/tests/auto/declarative/states/tst_states.cpp +++ b/tests/auto/declarative/states/tst_states.cpp @@ -484,6 +484,8 @@ void tst_states::anchorChanges() rect->setState(""); QCOMPARE(innerRect->x(), qreal(5)); + + delete rect; } { @@ -495,10 +497,36 @@ void tst_states::anchorChanges() QVERIFY(innerRect != 0); rect->setState("right"); + QEXPECT_FAIL("", "QTBUG-5338", Continue); QCOMPARE(innerRect->x(), qreal(150)); rect->setState(""); QCOMPARE(innerRect->x(), qreal(5)); + + delete rect; + } + + { + QmlComponent rectComponent(&engine, SRCDIR "/data/anchorChanges3.qml"); + QmlGraphicsRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QmlGraphicsRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + rect->setState("reanchored"); + QCOMPARE(innerRect->x(), qreal(10)); + QCOMPARE(innerRect->y(), qreal(0)); + QCOMPARE(innerRect->width(), qreal(190)); + QCOMPARE(innerRect->height(), qreal(150)); + + rect->setState(""); + QCOMPARE(innerRect->x(), qreal(0)); + QCOMPARE(innerRect->y(), qreal(10)); + QCOMPARE(innerRect->width(), qreal(150)); + QCOMPARE(innerRect->height(), qreal(190)); + + delete rect; } } -- cgit v0.12 From 400565d14a8c7a6a668a8db75de5ddff2a0061c9 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Tue, 17 Nov 2009 16:02:09 +1000 Subject: More tests --- tests/auto/declarative/anchors/tst_anchors.cpp | 116 ++++++++++++++++++------- 1 file changed, 84 insertions(+), 32 deletions(-) diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp index 22f8327..d340a7d 100644 --- a/tests/auto/declarative/anchors/tst_anchors.cpp +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -46,6 +46,9 @@ #include #include +Q_DECLARE_METATYPE(QmlGraphicsAnchors::UsedAnchor) +Q_DECLARE_METATYPE(QmlGraphicsAnchorLine::AnchorLine) + class tst_anchors : public QObject { @@ -62,7 +65,9 @@ private slots: void illegalSets(); void illegalSets_data(); void reset(); + void reset_data(); void nullItem(); + void nullItem_data(); void crash1(); }; @@ -214,17 +219,19 @@ void tst_anchors::illegalSets_data() << "Rectangle { id: rect; Rectangle { anchors.left: rect.left; anchors.right: rect.right; anchors.horizontalCenter: rect.horizontalCenter } }" << "QML QmlGraphicsRectangle (file::2:23) Can't specify left, right, and hcenter anchors."; - QTest::newRow("H - anchor to V") - << "Rectangle { Rectangle { anchors.left: parent.top } }" - << "QML QmlGraphicsRectangle (file::2:13) Can't anchor a horizontal edge to a vertical edge."; + foreach (const QString &side, QStringList() << "left" << "right") { + QTest::newRow("H - anchor to V") + << QString("Rectangle { Rectangle { anchors.%1: parent.top } }").arg(side) + << "QML QmlGraphicsRectangle (file::2:13) Can't anchor a horizontal edge to a vertical edge."; - QTest::newRow("H - anchor to non parent/sibling") - << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.left: rect.left } }" - << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; + QTest::newRow("H - anchor to non parent/sibling") + << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side) + << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; - QTest::newRow("H - anchor to self") - << "Rectangle { id: rect; anchors.left: rect.left }" - << "QML QmlGraphicsRectangle (file::2:1) Can't anchor item to self."; + QTest::newRow("H - anchor to self") + << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side) + << "QML QmlGraphicsRectangle (file::2:1) Can't anchor item to self."; + } QTest::newRow("V - too many anchors") @@ -235,17 +242,20 @@ void tst_anchors::illegalSets_data() << "Rectangle { Text { id: text1; text: \"Hello\" } Text { anchors.baseline: text1.baseline; anchors.top: text1.top; } }" << "QML QmlGraphicsText (file::2:47) Baseline anchor can't be used in conjunction with top, bottom, or vcenter anchors."; - QTest::newRow("V - anchor to H") - << "Rectangle { Rectangle { anchors.top: parent.left } }" - << "QML QmlGraphicsRectangle (file::2:13) Can't anchor a vertical edge to a horizontal edge."; + foreach (const QString &side, QStringList() << "top" << "bottom" << "baseline") { - QTest::newRow("V - anchor to non parent/sibling") - << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.top: rect.top } }" - << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; + QTest::newRow("V - anchor to H") + << QString("Rectangle { Rectangle { anchors.%1: parent.left } }").arg(side) + << "QML QmlGraphicsRectangle (file::2:13) Can't anchor a vertical edge to a horizontal edge."; - QTest::newRow("V - anchor to self") - << "Rectangle { id: rect; anchors.top: rect.top }" - << "QML QmlGraphicsRectangle (file::2:1) Can't anchor item to self."; + QTest::newRow("V - anchor to non parent/sibling") + << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side) + << "QML QmlGraphicsRectangle (file::2:45) Can't anchor to an item that isn't a parent or sibling."; + + QTest::newRow("V - anchor to self") + << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side) + << "QML QmlGraphicsRectangle (file::2:1) Can't anchor item to self."; + } QTest::newRow("centerIn - anchor to non parent/sibling") @@ -260,35 +270,77 @@ void tst_anchors::illegalSets_data() void tst_anchors::reset() { - QmlGraphicsItem *aItem = new QmlGraphicsItem; + QFETCH(QString, side); + QFETCH(QmlGraphicsAnchorLine::AnchorLine, anchorLine); + QFETCH(QmlGraphicsAnchors::UsedAnchor, usedAnchor); + + QmlGraphicsItem *baseItem = new QmlGraphicsItem; + QmlGraphicsAnchorLine anchor; - anchor.item = aItem; - anchor.anchorLine = QmlGraphicsAnchorLine::Top; + anchor.item = baseItem; + anchor.anchorLine = anchorLine; QmlGraphicsItem *item = new QmlGraphicsItem; - item->anchors()->setBottom(anchor); - QCOMPARE(item->anchors()->usedAnchors().testFlag(QmlGraphicsAnchors::HasBottomAnchor), true); - item->anchors()->resetBottom(); - QCOMPARE(item->anchors()->usedAnchors().testFlag(QmlGraphicsAnchors::HasBottomAnchor), false); + const QMetaObject *meta = item->anchors()->metaObject(); + QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData())); + + QVERIFY(p.write(item->anchors(), qVariantFromValue(anchor))); + QCOMPARE(item->anchors()->usedAnchors().testFlag(usedAnchor), true); + + QVERIFY(p.reset(item->anchors())); + QCOMPARE(item->anchors()->usedAnchors().testFlag(usedAnchor), false); + + delete item; + delete baseItem; +} + +void tst_anchors::reset_data() +{ + QTest::addColumn("side"); + QTest::addColumn("anchorLine"); + QTest::addColumn("usedAnchor"); + + QTest::newRow("left") << "left" << QmlGraphicsAnchorLine::Left << QmlGraphicsAnchors::HasLeftAnchor; + QTest::newRow("top") << "top" << QmlGraphicsAnchorLine::Top << QmlGraphicsAnchors::HasTopAnchor; + QTest::newRow("right") << "right" << QmlGraphicsAnchorLine::Right << QmlGraphicsAnchors::HasRightAnchor; + QTest::newRow("bottom") << "bottom" << QmlGraphicsAnchorLine::Bottom << QmlGraphicsAnchors::HasBottomAnchor; + + QTest::newRow("hcenter") << "horizontalCenter" << QmlGraphicsAnchorLine::HCenter << QmlGraphicsAnchors::HasHCenterAnchor; + QTest::newRow("vcenter") << "verticalCenter" << QmlGraphicsAnchorLine::VCenter << QmlGraphicsAnchors::HasVCenterAnchor; + QTest::newRow("baseline") << "baseline" << QmlGraphicsAnchorLine::Baseline << QmlGraphicsAnchors::HasBaselineAnchor; } void tst_anchors::nullItem() { + QFETCH(QString, side); + QmlGraphicsAnchorLine anchor; - QmlGraphicsItem *item; + QmlGraphicsItem *item = new QmlGraphicsItem; - QTest::ignoreMessage(QtWarningMsg, "QML QmlGraphicsItem (unknown location) Can't anchor to a null item."); - item = new QmlGraphicsItem; - item->anchors()->setLeft(anchor); - delete item; + const QMetaObject *meta = item->anchors()->metaObject(); + QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData())); QTest::ignoreMessage(QtWarningMsg, "QML QmlGraphicsItem (unknown location) Can't anchor to a null item."); - item = new QmlGraphicsItem; - item->anchors()->setBottom(anchor); + QVERIFY(p.write(item->anchors(), qVariantFromValue(anchor))); + delete item; } +void tst_anchors::nullItem_data() +{ + QTest::addColumn("side"); + + QTest::newRow("left") << "left"; + QTest::newRow("top") << "top"; + QTest::newRow("right") << "right"; + QTest::newRow("bottom") << "bottom"; + + QTest::newRow("hcenter") << "horizontalCenter"; + QTest::newRow("vcenter") << "verticalCenter"; + QTest::newRow("baseline") << "baseline"; +} + void tst_anchors::crash1() { QmlView *view = new QmlView; -- cgit v0.12 From 9b4124c699a7c958ffa132e31db6901cd719847c Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 17 Nov 2009 16:05:23 +1000 Subject: Fix AnchorChange when multiple states in a stategroup are involved. --- src/declarative/util/qmlstateoperations.cpp | 6 +- .../visual/animation/reanchor/data/reanchor.0.png | Bin 0 -> 622 bytes .../visual/animation/reanchor/data/reanchor.1.png | Bin 0 -> 626 bytes .../visual/animation/reanchor/data/reanchor.2.png | Bin 0 -> 622 bytes .../visual/animation/reanchor/data/reanchor.3.png | Bin 0 -> 622 bytes .../visual/animation/reanchor/data/reanchor.4.png | Bin 0 -> 632 bytes .../visual/animation/reanchor/data/reanchor.5.png | Bin 0 -> 622 bytes .../visual/animation/reanchor/data/reanchor.6.png | Bin 0 -> 622 bytes .../visual/animation/reanchor/data/reanchor.7.png | Bin 0 -> 622 bytes .../visual/animation/reanchor/data/reanchor.8.png | Bin 0 -> 634 bytes .../visual/animation/reanchor/data/reanchor.qml | 2471 ++++++++++++++++++++ .../visual/animation/reanchor/reanchor.qml | 68 + 12 files changed, 2543 insertions(+), 2 deletions(-) create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png create mode 100644 tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml create mode 100644 tests/auto/declarative/visual/animation/reanchor/reanchor.qml diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index 0d977de..e2933b2 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -475,6 +475,8 @@ void QmlAnchorChanges::setReset(const QString &reset) Q_D(QmlAnchorChanges); d->resetString = reset; d->resetList = d->resetString.split(QLatin1Char(',')); + for (int i = 0; i < d->resetList.count(); ++i) + d->resetList[i] = d->resetList.at(i).trimmed(); } /*! @@ -766,8 +768,8 @@ bool QmlAnchorChanges::override(ActionEvent*other) return false; if (static_cast(this) == other) return true; - //### can we do any other meaningful comparison? Do we need to attempt to merge the two - // somehow if they have the same target and some of the same anchors? + if (static_cast(other)->object() == object()) + return true; return false; } diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png new file mode 100644 index 0000000..c7bbf38 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.0.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png new file mode 100644 index 0000000..612500b Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.1.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png new file mode 100644 index 0000000..c7bbf38 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.2.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png new file mode 100644 index 0000000..c7bbf38 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.3.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png new file mode 100644 index 0000000..1910eb4 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.4.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png new file mode 100644 index 0000000..3b8eebd Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.5.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png new file mode 100644 index 0000000..c7bbf38 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.6.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png new file mode 100644 index 0000000..c7bbf38 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.7.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png new file mode 100644 index 0000000..960be31 Binary files /dev/null and b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.8.png differ diff --git a/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml new file mode 100644 index 0000000..0f58de5 --- /dev/null +++ b/tests/auto/declarative/visual/animation/reanchor/data/reanchor.qml @@ -0,0 +1,2471 @@ +import Qt.VisualTest 4.6 + +VisualTest { + Frame { + msec: 0 + } + Frame { + msec: 16 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 32 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 48 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 64 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 80 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 96 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 112 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 128 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 144 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 160 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 176 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 192 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 208 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 224 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 240 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 256 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 272 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 288 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 304 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 320 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 336 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 352 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 368 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 384 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 400 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 416 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 432 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 448 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 464 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 480 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 496 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 512 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 528 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 544 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 560 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 576 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 592 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 608 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 624 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 640 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 656 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 672 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 688 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 704 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 720 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 736 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 752 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 768 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 784 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 800 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 816 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 832 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 848 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 864 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 880 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 896 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 912 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 928 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 944 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 960 + image: "reanchor.0.png" + } + Frame { + msec: 976 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 992 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1008 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1024 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1040 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1056 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1072 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1088 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1104 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1120 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1136 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1152 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1168 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1184 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1200 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1216 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1232 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1248 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1264 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1280 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1296 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1312 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1328 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1344 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1360 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 88; y: 115 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1376 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1392 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1408 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1424 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1440 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 88; y: 115 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 1456 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 1472 + hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + } + Frame { + msec: 1488 + hash: "1098ea19aecebd71208e101d522c1981" + } + Frame { + msec: 1504 + hash: "8cc59c20d796c073038518d2855fb6f0" + } + Frame { + msec: 1520 + hash: "914a89d0cfdc68145024ce2305a5e76e" + } + Frame { + msec: 1536 + hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + } + Frame { + msec: 1552 + hash: "b71496d986d5f0aa76b4f1663627f1f7" + } + Frame { + msec: 1568 + hash: "41b29a523db919bc0a4e0a9a88bfc873" + } + Frame { + msec: 1584 + hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + } + Frame { + msec: 1600 + hash: "94cc196e62c150008461ff9996b4cae8" + } + Frame { + msec: 1616 + hash: "32e96ad2d15fa2386d365ab249ddf4f4" + } + Frame { + msec: 1632 + hash: "209394314f971b12fbc61ca45010cc62" + } + Frame { + msec: 1648 + hash: "b917c2684dda8af00278b34ababdcf5c" + } + Frame { + msec: 1664 + hash: "92b506860c1c5dc52f87c24c89921b05" + } + Frame { + msec: 1680 + hash: "7b7e96113fa9359954be9b3ac87943c3" + } + Frame { + msec: 1696 + hash: "42bc69db42c5df902038cec414246ec5" + } + Frame { + msec: 1712 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1728 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1744 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1760 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1776 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1792 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1808 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1824 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1840 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1856 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1872 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1888 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1904 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1920 + image: "reanchor.1.png" + } + Frame { + msec: 1936 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1952 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1968 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 1984 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2000 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2016 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2032 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2048 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2064 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2080 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2096 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 87; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2112 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2128 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2144 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2160 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2176 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2192 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2208 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 87; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2224 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 2240 + hash: "2d1aa011f2008a6147ba593e3cf272d7" + } + Frame { + msec: 2256 + hash: "206699ea84ce9fd60c1603b7a48a5134" + } + Frame { + msec: 2272 + hash: "68eb6df93a2b6db7023f7c3cc71d5b5f" + } + Frame { + msec: 2288 + hash: "5a4cd0620959dde92eeeaaa4dcd13091" + } + Frame { + msec: 2304 + hash: "17b763187a777253b25b22f5dd7253ae" + } + Frame { + msec: 2320 + hash: "1de9dcf4d385266f4482e2d0967d9119" + } + Frame { + msec: 2336 + hash: "833496add6dbc3103a28a47e453a738b" + } + Frame { + msec: 2352 + hash: "b3bab2e9c56db60cd54e68369e6b790d" + } + Frame { + msec: 2368 + hash: "ee91c6cd909bec401a1a7eebd10b8b02" + } + Frame { + msec: 2384 + hash: "0ed679ad0ab7bd3544947bccda88647b" + } + Frame { + msec: 2400 + hash: "d7dfcdc8a4233821919f1732d8c39712" + } + Frame { + msec: 2416 + hash: "c52829ee689e4c312a9dff8dbd4a79f9" + } + Frame { + msec: 2432 + hash: "7962badda0e80a61b67943d3b31f892d" + } + Frame { + msec: 2448 + hash: "fc5f2c24e3d8743ab5b20aaa122bacc2" + } + Frame { + msec: 2464 + hash: "201b9ee6c9ac6208ef812fe2e95020ef" + } + Frame { + msec: 2480 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2496 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2512 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2528 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2544 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2560 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2576 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2592 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2608 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2624 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2640 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2656 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2672 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2688 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2704 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2720 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2736 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2752 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 87; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2768 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2784 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2800 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2816 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2832 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2848 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 2864 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 87; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 2880 + image: "reanchor.2.png" + } + Frame { + msec: 2896 + hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + } + Frame { + msec: 2912 + hash: "1098ea19aecebd71208e101d522c1981" + } + Frame { + msec: 2928 + hash: "8cc59c20d796c073038518d2855fb6f0" + } + Frame { + msec: 2944 + hash: "914a89d0cfdc68145024ce2305a5e76e" + } + Frame { + msec: 2960 + hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + } + Frame { + msec: 2976 + hash: "b71496d986d5f0aa76b4f1663627f1f7" + } + Frame { + msec: 2992 + hash: "41b29a523db919bc0a4e0a9a88bfc873" + } + Frame { + msec: 3008 + hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + } + Frame { + msec: 3024 + hash: "94cc196e62c150008461ff9996b4cae8" + } + Frame { + msec: 3040 + hash: "32e96ad2d15fa2386d365ab249ddf4f4" + } + Frame { + msec: 3056 + hash: "209394314f971b12fbc61ca45010cc62" + } + Frame { + msec: 3072 + hash: "b917c2684dda8af00278b34ababdcf5c" + } + Frame { + msec: 3088 + hash: "92b506860c1c5dc52f87c24c89921b05" + } + Frame { + msec: 3104 + hash: "7b7e96113fa9359954be9b3ac87943c3" + } + Frame { + msec: 3120 + hash: "42bc69db42c5df902038cec414246ec5" + } + Frame { + msec: 3136 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3152 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3168 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3184 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3200 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3216 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3232 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3248 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3264 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3280 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3296 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3312 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3328 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3344 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3360 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 87; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3376 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3392 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3408 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3424 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3440 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3456 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3472 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 87; y: 114 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 3488 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 3504 + hash: "2d1aa011f2008a6147ba593e3cf272d7" + } + Frame { + msec: 3520 + hash: "206699ea84ce9fd60c1603b7a48a5134" + } + Frame { + msec: 3536 + hash: "68eb6df93a2b6db7023f7c3cc71d5b5f" + } + Frame { + msec: 3552 + hash: "5a4cd0620959dde92eeeaaa4dcd13091" + } + Frame { + msec: 3568 + hash: "17b763187a777253b25b22f5dd7253ae" + } + Frame { + msec: 3584 + hash: "1de9dcf4d385266f4482e2d0967d9119" + } + Frame { + msec: 3600 + hash: "833496add6dbc3103a28a47e453a738b" + } + Frame { + msec: 3616 + hash: "b3bab2e9c56db60cd54e68369e6b790d" + } + Frame { + msec: 3632 + hash: "ee91c6cd909bec401a1a7eebd10b8b02" + } + Frame { + msec: 3648 + hash: "0ed679ad0ab7bd3544947bccda88647b" + } + Frame { + msec: 3664 + hash: "d7dfcdc8a4233821919f1732d8c39712" + } + Frame { + msec: 3680 + hash: "c52829ee689e4c312a9dff8dbd4a79f9" + } + Frame { + msec: 3696 + hash: "7962badda0e80a61b67943d3b31f892d" + } + Frame { + msec: 3712 + hash: "fc5f2c24e3d8743ab5b20aaa122bacc2" + } + Frame { + msec: 3728 + hash: "201b9ee6c9ac6208ef812fe2e95020ef" + } + Frame { + msec: 3744 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3760 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3776 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3792 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3808 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3824 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3840 + image: "reanchor.3.png" + } + Frame { + msec: 3856 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3872 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3888 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3904 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3920 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3936 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3952 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3968 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 3984 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4000 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4016 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4032 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4048 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4064 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4080 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4096 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4112 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4128 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4144 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4160 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4176 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4192 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4208 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4224 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4240 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4256 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4272 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4288 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4304 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4320 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4336 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4352 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4368 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4384 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4400 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4416 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4432 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4448 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4464 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4480 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4496 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4512 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4528 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 174; y: 174 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4544 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4560 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4576 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4592 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4608 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4624 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4640 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4656 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 174; y: 174 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 4672 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 4688 + hash: "5d38bf4a033de31985ae9989107908af" + } + Frame { + msec: 4704 + hash: "ed1bd2abd42848ecd07f0f0654c2b80f" + } + Frame { + msec: 4720 + hash: "588de6662123733303d93f62c6481f6a" + } + Frame { + msec: 4736 + hash: "aae79c2fbb2fd1ac7efa9802bff40f95" + } + Frame { + msec: 4752 + hash: "f17512798136f67f25aaa0aeb60678e1" + } + Frame { + msec: 4768 + hash: "79578a1e0e3e9cd45c210d0c5d3e75d6" + } + Frame { + msec: 4784 + hash: "5dad4ff201744cda6ff41f89414c8d11" + } + Frame { + msec: 4800 + image: "reanchor.4.png" + } + Frame { + msec: 4816 + hash: "c4559982aa3f3d291364deed4bd96d65" + } + Frame { + msec: 4832 + hash: "0dff03ea9154bdb2a813358b04cfbde9" + } + Frame { + msec: 4848 + hash: "09bdf2869dee1c0cbe3c8c2e9254580b" + } + Frame { + msec: 4864 + hash: "ba7762978bbd63d624029910fe16fb6d" + } + Frame { + msec: 4880 + hash: "f00d198ab8f4f625b60e9e2071d8adfd" + } + Frame { + msec: 4896 + hash: "adcec9c9a5b0d60cf45b2915365ea09c" + } + Frame { + msec: 4912 + hash: "a65cd6fbb26d618692ef23148015a4f2" + } + Frame { + msec: 4928 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 4944 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 4960 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 4976 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 4992 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5008 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5024 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5040 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5056 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5072 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5088 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5104 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5120 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5136 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5152 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5168 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5184 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5200 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5216 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5232 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5248 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5264 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5280 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5296 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5312 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5328 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5344 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5360 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5376 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5392 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5408 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5424 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5440 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5456 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5472 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5488 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5504 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5520 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5536 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5552 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5568 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5584 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5600 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5616 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5632 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5648 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5664 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5680 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5696 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5712 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5728 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5744 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5760 + image: "reanchor.5.png" + } + Frame { + msec: 5776 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5792 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5808 + hash: "1137e22c68e043950811dee295e19b04" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 95; y: 78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5824 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5840 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5856 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5872 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5888 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5904 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5920 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5936 + hash: "1137e22c68e043950811dee295e19b04" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 95; y: 78 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 5952 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 5968 + hash: "103bbc9ce594851f5243b103f8fef1c1" + } + Frame { + msec: 5984 + hash: "c381148b052be2e6244f24c2292b89cf" + } + Frame { + msec: 6000 + hash: "2fda1d635fa47bff7de867df3dadfb4f" + } + Frame { + msec: 6016 + hash: "4d35e00af33ad5dc84998cda2d066b4e" + } + Frame { + msec: 6032 + hash: "14005d52d372acf6d3495f69bbf00b7d" + } + Frame { + msec: 6048 + hash: "29728f64d12e858d960c4e197824ef43" + } + Frame { + msec: 6064 + hash: "798822f0c20ef87cb01fe1dcd76c7585" + } + Frame { + msec: 6080 + hash: "4cdeea0f91587ef32a2c2e282f6d00e6" + } + Frame { + msec: 6096 + hash: "08ca5d16771e58da6cdd20b86dc65f03" + } + Frame { + msec: 6112 + hash: "e9aeb432709d275048ad9d84fb21db1a" + } + Frame { + msec: 6128 + hash: "3b642f27d356fd1815dc50f8e750623d" + } + Frame { + msec: 6144 + hash: "7c1db0ec278849ec044ea0aa3383075b" + } + Frame { + msec: 6160 + hash: "da902850879c95d4ddffbb1ba0060f25" + } + Frame { + msec: 6176 + hash: "e4053bd0db7752e7a47e096da645b69b" + } + Frame { + msec: 6192 + hash: "aabbb6d34399818347db265151a547b7" + } + Frame { + msec: 6208 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6224 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6240 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6256 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6272 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6288 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6304 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6320 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6336 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6352 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6368 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6384 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6400 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6416 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6432 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6448 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6464 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6480 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6496 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6512 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6528 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6544 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6560 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6576 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6592 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6608 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6624 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6640 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6656 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6672 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6688 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6704 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6720 + image: "reanchor.6.png" + } + Frame { + msec: 6736 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6752 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6768 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6784 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6800 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6816 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6832 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6848 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6864 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6880 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6896 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6912 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6928 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6944 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6960 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6976 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 6992 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7008 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7024 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7040 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7056 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7072 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7088 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7104 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7120 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7136 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7152 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7168 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7184 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7200 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7216 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7232 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7248 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7264 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7280 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7296 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7312 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7328 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7344 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7360 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7376 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7392 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7408 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7424 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7440 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7456 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7472 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7488 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7504 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7520 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7536 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7552 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7568 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7584 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7600 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 86; y: 136 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 7616 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7632 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7648 + hash: "213811853dbefdc418099721e3bf8651" + } + Frame { + msec: 7664 + hash: "213811853dbefdc418099721e3bf8651" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 86; y: 136 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 7680 + image: "reanchor.7.png" + } + Frame { + msec: 7696 + hash: "c2d6dd91f3e9cdcacbadcb449c8a9896" + } + Frame { + msec: 7712 + hash: "1098ea19aecebd71208e101d522c1981" + } + Frame { + msec: 7728 + hash: "8cc59c20d796c073038518d2855fb6f0" + } + Frame { + msec: 7744 + hash: "914a89d0cfdc68145024ce2305a5e76e" + } + Frame { + msec: 7760 + hash: "7a2e3ca2660df24d9a6ec49a7422ebe1" + } + Frame { + msec: 7776 + hash: "b71496d986d5f0aa76b4f1663627f1f7" + } + Frame { + msec: 7792 + hash: "41b29a523db919bc0a4e0a9a88bfc873" + } + Frame { + msec: 7808 + hash: "97632a0de766b9ffbf71f21eeb0ff9a2" + } + Frame { + msec: 7824 + hash: "94cc196e62c150008461ff9996b4cae8" + } + Frame { + msec: 7840 + hash: "32e96ad2d15fa2386d365ab249ddf4f4" + } + Frame { + msec: 7856 + hash: "209394314f971b12fbc61ca45010cc62" + } + Frame { + msec: 7872 + hash: "b917c2684dda8af00278b34ababdcf5c" + } + Frame { + msec: 7888 + hash: "92b506860c1c5dc52f87c24c89921b05" + } + Frame { + msec: 7904 + hash: "7b7e96113fa9359954be9b3ac87943c3" + } + Frame { + msec: 7920 + hash: "42bc69db42c5df902038cec414246ec5" + } + Frame { + msec: 7936 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 7952 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 7968 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 7984 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8000 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8016 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8032 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8048 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8064 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8080 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8096 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8112 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8128 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8144 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8160 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8176 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8192 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8208 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8224 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8240 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8256 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8272 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8288 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8304 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8320 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8336 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8352 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8368 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8384 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8400 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Mouse { + type: 2 + button: 1 + buttons: 1 + x: 177; y: 173 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8416 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8432 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8448 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8464 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8480 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8496 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8512 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Mouse { + type: 3 + button: 1 + buttons: 0 + x: 177; y: 173 + modifiers: 0 + sendToViewport: true + } + Frame { + msec: 8528 + hash: "7eb4027421fd6aa7d668a704e40a6e61" + } + Frame { + msec: 8544 + hash: "b4f30663a9b21e42375645e970f57d0b" + } + Frame { + msec: 8560 + hash: "6c12dbf4af8801573515b61123d4b1d7" + } + Frame { + msec: 8576 + hash: "facc61397c734bb4409d5664dc059a14" + } + Frame { + msec: 8592 + hash: "897e15e37276454d11fac6a528e967a6" + } + Frame { + msec: 8608 + hash: "cf8173519f1e042c227ff61c62308640" + } + Frame { + msec: 8624 + hash: "d0fcda14ea4bcfebf04ccf99e292ac6a" + } + Frame { + msec: 8640 + image: "reanchor.8.png" + } + Frame { + msec: 8656 + hash: "74b4ababa97def538f5340e88a4419a4" + } + Frame { + msec: 8672 + hash: "b96b5b64505b1814ddd42a52569d7fd9" + } + Frame { + msec: 8688 + hash: "0e3e07aad030b2075c4bc61b02ebe49e" + } + Frame { + msec: 8704 + hash: "c5eebc652c58e3a44d5ed481100ef242" + } + Frame { + msec: 8720 + hash: "d4a74185304c126739af728ddda40e0c" + } + Frame { + msec: 8736 + hash: "448572d3c1060b8311952429a7f9430d" + } + Frame { + msec: 8752 + hash: "00f64c09657a8afd6caa186efb6ad860" + } + Frame { + msec: 8768 + hash: "2a360e6feaaf303e9ee63145085796e6" + } + Frame { + msec: 8784 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8800 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8816 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8832 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8848 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8864 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8880 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8896 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8912 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8928 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8944 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8960 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8976 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 8992 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9008 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9024 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9040 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9056 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9072 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9088 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9104 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9120 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9136 + hash: "1137e22c68e043950811dee295e19b04" + } + Key { + type: 6 + key: 16777249 + modifiers: 67108864 + text: "" + autorep: false + count: 1 + } + Frame { + msec: 9152 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9168 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9184 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9200 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9216 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9232 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9248 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9264 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9280 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9296 + hash: "1137e22c68e043950811dee295e19b04" + } + Frame { + msec: 9312 + hash: "1137e22c68e043950811dee295e19b04" + } +} diff --git a/tests/auto/declarative/visual/animation/reanchor/reanchor.qml b/tests/auto/declarative/visual/animation/reanchor/reanchor.qml new file mode 100644 index 0000000..1cc68a9 --- /dev/null +++ b/tests/auto/declarative/visual/animation/reanchor/reanchor.qml @@ -0,0 +1,68 @@ +import Qt 4.6 + +Rectangle { + id: container + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + color: "green"; + anchors.left: parent.left + anchors.right: rightGuideline.left + anchors.top: topGuideline.top + anchors.bottom: container.bottom + } + Item { id: leftGuideline; x: 10 } + Item { id: rightGuideline; x: 150 } + Item { id: topGuideline; y: 10 } + Item { id: bottomGuideline; y: 150 } + Item { id: topGuideline2; y: 50 } + Item { id: bottomGuideline2; y: 175 } + + MouseRegion { + id: wholeArea + anchors.fill: parent + onClicked: { + if (container.state == "") { + container.state = "reanchored"; + } else if (container.state == "reanchored") { + container.state = "reanchored2"; + } else if (container.state == "reanchored2") + container.state = "reanchored"; + } + } + + states: [ State { + name: "reanchored" + AnchorChanges { + target: myRect; + left: leftGuideline.left + right: container.right + top: container.top + bottom: bottomGuideline.bottom + } + }, State { + name: "reanchored2" + AnchorChanges { + target: myRect; + reset: "left, right" + top: topGuideline2.top + bottom: bottomGuideline2.bottom + } + }] + + transitions: Transition { + NumberAnimation { matchProperties: "x,y,width,height" } + } + + MouseRegion { + width: 50; height: 50 + anchors.right: parent.right + anchors.bottom: parent.bottom + onClicked: { + container.state = ""; + } + } + + state: "reanchored" +} -- cgit v0.12