diff options
author | juhvu <qt-info@nokia.com> | 2011-08-11 15:02:29 +1000 |
---|---|---|
committer | abcd <qt_abcd1@ovi.com> | 2011-08-12 05:06:19 +0200 |
commit | 469170b584d14e045418a71b34fb648cc6f9b726 (patch) | |
tree | 05eca519008a620f109077838e8a6b2581e05b05 /tests | |
parent | 3f7102d1eef9f5070ecc0033415b057a966d9f0d (diff) | |
download | qtlocation-469170b584d14e045418a71b34fb648cc6f9b726.tar.gz |
Modified location QML tests to work in QML2 environment.
Also added freetext geocoding and a small feature for clearing
all featureWeights of a routing query.
Change-Id: Idfe5000bb335fc2825fc14108de154e6e86ba0ef
Reviewed-on: http://codereview.qt.nokia.com/2840
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: abcd <qt_abcd1@ovi.com>
Diffstat (limited to 'tests')
17 files changed, 1075 insertions, 71 deletions
diff --git a/tests/auto/declarative/landmarks.db b/tests/auto/declarative/landmarks.db Binary files differdeleted file mode 100644 index e3fb33ac..00000000 --- a/tests/auto/declarative/landmarks.db +++ /dev/null diff --git a/tests/auto/declarative/tst_bounding_area.qml b/tests/auto/declarative/tst_bounding_area.qml index f8f0264f..4db0fd17 100644 --- a/tests/auto/declarative/tst_bounding_area.qml +++ b/tests/auto/declarative/tst_bounding_area.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 diff --git a/tests/auto/declarative/tst_map_qml1 b/tests/auto/declarative/tst_map.qml index cf235727..10504c8c 100644 --- a/tests/auto/declarative/tst_map_qml1 +++ b/tests/auto/declarative/tst_map.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 diff --git a/tests/auto/declarative/tst_map_geocoding.qml b/tests/auto/declarative/tst_map_geocoding.qml index 593e4ea4..124cb3a1 100644 --- a/tests/auto/declarative/tst_map_geocoding.qml +++ b/tests/auto/declarative/tst_map_geocoding.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 @@ -63,6 +63,8 @@ Item { SignalSpy {id: autoUpdateSpy; target: emptyModel; signalName: "autoUpdateChanged"} SignalSpy {id: pluginSpy; target: emptyModel ; signalName: "pluginChanged"} SignalSpy {id: boundsSpy; target: emptyModel; signalName: "boundsChanged"} + SignalSpy {id: limitSpy; target: emptyModel; signalName: "limitChanged"} + SignalSpy {id: offsetSpy; target: emptyModel; signalName: "offsetChanged"} TestCase { id: testCase1 @@ -76,13 +78,34 @@ Item { emptyModel.query = address1 compare (querySpy.count, 1) compare (emptyModel.query.street, address1.street) - // Query:: coordinate + // Query: coordinate emptyModel.query = coordinate1 compare (querySpy.count, 2) compare (emptyModel.query.latitude, coordinate1.latitude) emptyModel.query = coordinate1 compare (querySpy.count, 2) compare (emptyModel.query.latitude, coordinate1.latitude) + // Query: string + emptyModel.query = "Kuortane, Finland" + compare (querySpy.count, 3) + compare (emptyModel.query, "Kuortane, Finland") + emptyModel.query = "Kuortane, Finland" + compare (querySpy.count, 3) + compare (emptyModel.query, "Kuortane, Finland") + + // limit and offset + compare (limitSpy.count, 0) + compare (offsetSpy.count, 0) + compare(emptyModel.limit, -1) + compare(emptyModel.offset, 0) + emptyModel.limit = 2 + compare (limitSpy.count, 1) + emptyModel.limit = 2 + compare (limitSpy.count, 1) + emptyModel.offset = 10 + compare (offsetSpy.count, 1) + emptyModel.offset = 10 + compare (offsetSpy.count, 1) // bounding box compare(boundsSpy.count, 0) @@ -98,7 +121,7 @@ Item { compare(boundsSpy.count, 2) compare(emptyModel.bounds.topLeft.latitude, boundingBox2.topLeft.latitude) compare(emptyModel.bounds.bottomRight.longitude, boundingBox2.bottomRight.longitude) - var dynamicBox = Qt.createQmlObject("import QtQuick 1.0; import Qt.location 5.0; BoundingBox { id: dynBox}", testCase1) + var dynamicBox = Qt.createQmlObject("import QtQuick 2.0; import Qt.location 5.0; BoundingBox { id: dynBox}", testCase1) emptyModel.bounds = dynamicBox compare(boundsSpy.count, 3) @@ -114,7 +137,7 @@ Item { emptyModel.bounds = boundingCircle2 compare(boundsSpy.count, 2) compare(emptyModel.bounds.center.latitude, coordinate2.latitude) - var dynamicCircle = Qt.createQmlObject("import QtQuick 1.0; import Qt.location 5.0; BoundingCircle { id: dynCircle; center: Coordinate {id: dynCoord; latitude: 8; longitude: 9}}", testCase1) + var dynamicCircle = Qt.createQmlObject("import QtQuick 2.0; import Qt.location 5.0; BoundingCircle { id: dynCircle; center: Coordinate {id: dynCoord; latitude: 8; longitude: 9}}", testCase1) emptyModel.bounds = dynamicCircle compare(boundsSpy.count, 3) compare(emptyModel.bounds.center.latitude, dynamicCircle.center.latitude) @@ -250,6 +273,8 @@ Item { countSlackSpy.clear() querySlackSpy.clear() errorSlackSpy.clear() + slackModel.limit = -1 + slackModel.offset = 0 } function clear_immediate_model() { immediateModel.clear() @@ -258,6 +283,8 @@ Item { queryImmediateSpy.clear() errorImmediateSpy.clear() statusImmediateSpy.clear() + immediateModel.limit = -1 + immediateModel.offset = 0 } function test_reset() { clear_immediate_model(); @@ -371,7 +398,7 @@ Item { compare (errorSlackSpy.count, 2) compare (slackModel.error, "") } - function test_basic_geocode() { + function test_basic_address_geocode() { testQuerySpy.clear() locationsSpy.clear() testStatusSpy.clear() @@ -393,6 +420,80 @@ Item { compare (testModel.get(0).address.city, "expected city") } + function test_basic_freetext_geocode() { + testQuerySpy.clear() + locationsSpy.clear() + testStatusSpy.clear() + testModel.clear() + countSpy.clear() + compare (locationsSpy.count, 0) + compare (testModel.error, "") + compare (testModel.count, 0) + testModel.limit = 5 // number of places echoed back + testModel.offset = 10 // 'county' set in the places + // Test successful case + testModel.query = "Freetext geocode" + compare(testQuerySpy.count, 1) + testModel.update(); + tryCompare (locationsSpy, "count", 1) // 5 sec + tryCompare(countSpy, "count", 1) + tryCompare(testModel, "count", 5) + compare(testModel.get(0).address.county, "10") + // Test error case + testModel.query = "2" // tells plugin to echo error '2' + compare(testQuerySpy.count, 2) + testModel.update(); + tryCompare (locationsSpy, "count", 2) // 5 sec + tryCompare(countSpy, "count", 2) + tryCompare(testModel, "count", 0) + compare(testModel.error, "2") + testModel.clear() + tryCompare(countSpy, "count", 2) + compare (testModel.count, 0) + } + + function test_delayed_freetext_geocode() { + clear_slack_model() + slackModel.limit = 5 // number of places echoed back + slackModel.offset = 10 // 'county' set in the places + // Basic successful case + slackModel.query = "freetext geocode" + compare (querySlackSpy.count, 1) + slackModel.update() + wait (100) + compare (countSlackSpy.count, 0) + compare (locationsSlackSpy.count, 0) + compare (slackModel.count, 0) + wait (200) + compare (slackModel.count, 5) + compare (countSlackSpy.count, 1) + compare (locationsSlackSpy.count, 1) + // Frequent updates, previous requests are aborted + slackModel.clear() + locationsSlackSpy.clear() + countSlackSpy.clear() + slackModel.update() + wait (100) + compare(locationsSlackSpy.count, 0) + compare(countSlackSpy.count, 0) + slackModel.update() + wait (100) + compare(locationsSlackSpy.count, 0) + compare(countSlackSpy.count, 0) + slackModel.update() + wait (100) + compare(locationsSlackSpy.count, 0) + compare(countSlackSpy.count, 0) + slackModel.update() + wait (100) + compare(locationsSlackSpy.count, 0) + compare(countSlackSpy.count, 0) + wait (200) + compare (locationsSlackSpy.count, 1) + compare(countSlackSpy.count, 1) + compare(slackModel.count, 5) // limit + } + function test_geocode_auto_updates() { compare (automaticModel.count, 4) // should be something already compare (automaticLocationsSpy.count, 1) @@ -459,7 +560,7 @@ Item { compare(slackModel.count, 7) // slackAddress1.county } function test_basic_reverse_geocode() { - testModel.clear() + testModel.reset() testQuerySpy.clear() locationsSpy.clear() testStatusSpy.clear() @@ -479,10 +580,7 @@ Item { compare (testModel.count, 0) } function test_delayed_reverse_geocode() { - slackModel.clear() - querySlackSpy.clear() - countSlackSpy.clear() - locationsSlackSpy.clear() + clear_slack_model() slackModel.query = slackCoordinate1 compare (querySlackSpy.count, 1) slackModel.update() diff --git a/tests/auto/declarative/tst_map_mouse.qml b/tests/auto/declarative/tst_map_mouse.qml index 416fd18d..92d86e41 100644 --- a/tests/auto/declarative/tst_map_mouse.qml +++ b/tests/auto/declarative/tst_map_mouse.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 diff --git a/tests/auto/declarative/tst_map_objectview_qml1 b/tests/auto/declarative/tst_map_objectview.qml index 4e262c1b..245e1805 100644 --- a/tests/auto/declarative/tst_map_objectview_qml1 +++ b/tests/auto/declarative/tst_map_objectview.qml @@ -39,9 +39,10 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 +import Qt.location.test 5.0 Item { id: masterItem @@ -51,31 +52,26 @@ Item { Plugin { id: testPlugin; name : "nokia"; PluginParameter {name: "mapping.host"; value: "for.nonexistent"}} Coordinate{ id: mapDefaultCenter; latitude: 10; longitude: 30} - // This model results in 7 landmarks - LandmarkModel { - id: landmarkModelAll - autoUpdate: true - //onLandmarksChanged: console.log('all landmarks changed, count: ' + count) - } - // This model results in 2 landmarks - LandmarkModel { - id: landmarkModelNearMe - autoUpdate: true - //onLandmarksChanged: console.log('nearme landmarks changed, count: ' + count) - filter: proximityFilter - } - LandmarkProximityFilter { - id: proximityFilter - center: mapDefaultCenter - radius: 6000000 - } - MapCircle { id: externalCircle radius: 2000000 center: mapDefaultCenter } + TestModel { + id: testModel + datatype: 'coordinate' + datacount: 7 + delay: 0 + } + + TestModel { + id: testModel2 + datatype: 'coordinate' + datacount: 3 + delay: 0 + } + Map { id: mapWithPlugin; center: mapDefaultCenter; plugin: testPlugin; anchors.fill: parent; size.width: parent.width; size.height: parent.height; zoomLevel: 2 @@ -86,11 +82,14 @@ Item { } MapObjectView { id: theObjectView - model: landmarkModelAll + model: testModel delegate: Component { MapCircle { radius: 1500000 - center: landmark.coordinate + center: Coordinate { + latitude: modeldata.coordinate.latitude; + longitude: modeldata.coordinate.longitude; + } } } } @@ -105,11 +104,14 @@ Item { } MapObjectView { id: theObjectView2 - model: landmarkModelAll + model: testModel delegate: Component { MapCircle { radius: 1500000 - center: landmark.coordinate + center: Coordinate { + latitude: modeldata.coordinate.latitude; + longitude: modeldata.coordinate.longitude; + } } } } @@ -119,46 +121,44 @@ Item { name: "MapObjectView" function test_a_add_and_remove() { // Basic adding and removing of static object - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 1) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 8) mapWithPlugin.addMapObject(internalCircle) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 1) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 8) mapWithPlugin.removeMapObject(internalCircle) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 0) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 7) mapWithPlugin.removeMapObject(internalCircle) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 0) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 7) // Basic adding and removing of dynamic object - var dynamicCircle = Qt.createQmlObject( "import QtQuick 1.0; import Qt.location 5.0; MapCircle {radius: 4000; center: mapDefaultCenter}", mapWithPlugin, ""); + var dynamicCircle = Qt.createQmlObject( "import QtQuick 2.0; import Qt.location 5.0; MapCircle {radius: 4000; center: mapDefaultCenter}", mapWithPlugin, ""); mapWithPlugin.addMapObject(dynamicCircle) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 1) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 8) mapWithPlugin.removeMapObject(dynamicCircle) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 0) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 7) mapWithPlugin.removeMapObject(dynamicCircle) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 0) + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 7) } - SignalSpy {id: allCountSpy; target: landmarkModelAll; signalName: "countChanged"} - SignalSpy {id: nearMeCountSpy; target: landmarkModelNearMe; signalName: "countChanged"} + + SignalSpy {id: model1Spy; target: testModel; signalName: "modelChanged"} + SignalSpy {id: model2Spy; target: testModel2; signalName: "modelChanged"} function test_b_model_change() { // Change the model of an MapObjectView on the fly // and verify that object counts change accordingly. - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 0) - landmarkModelAll.setDbFileName("landmarks.db") - landmarkModelNearMe.setDbFileName("landmarks.db") - tryCompare(allCountSpy, "count", 1, 1000) - tryCompare(nearMeCountSpy, "count", 1, 1000) - compare(landmarkModelAll.count, 7) - compare(landmarkModelNearMe.count, 2) - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 7) - theObjectView.model = landmarkModelNearMe - compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 2) - theObjectView.model = landmarkModelAll compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 7) + testModel.datacount += 2 + testModel2.datacount += 1 + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 9) + theObjectView.model = testModel + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 9) + theObjectView.model = testModel2 + compare(mapWithPlugin.testGetDeclarativeMapObjectCount(), 4) } + SignalSpy {id: pluginChangedSpy; target: mapWithoutPlugin; signalName: "pluginChanged"} function test_c_plugin_set_later() { compare(mapWithoutPlugin.testGetDeclarativeMapObjectCount(), 0) mapWithoutPlugin.plugin = testPlugin tryCompare(pluginChangedSpy, "count", 1, 1000) - compare(mapWithoutPlugin.testGetDeclarativeMapObjectCount(), 8) // 7 + 1 + compare(mapWithoutPlugin.testGetDeclarativeMapObjectCount(), 10) // 9 from testModel, + 1 from mapcircle } } } diff --git a/tests/auto/declarative/tst_map_routing.qml b/tests/auto/declarative/tst_map_routing.qml index 5b4de8dd..11e9bb40 100644 --- a/tests/auto/declarative/tst_map_routing.qml +++ b/tests/auto/declarative/tst_map_routing.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 @@ -361,6 +361,20 @@ Item { compare(emptyQuery.featureWeight(RouteQuery.HighwayFeature), RouteQuery.PreferFeatureWeight); compare(emptyQuery.featureTypes[0], RouteQuery.HighwayFeature) compare(emptyQuery.featureWeight(emptyQuery.featureTypes[0]), RouteQuery.PreferFeatureWeight) + compare(featureTypesSpy.count, 3) + compare(queryDetailsChangedSpy.count, 3) + compare(emptyQuery.featureTypes.length, 1) + + // Put some feature weights and then reset them with NoFeature + emptyQuery.setFeatureWeight(RouteQuery.FerryFeature, RouteQuery.RequireFeatureWeight); + emptyQuery.setFeatureWeight(RouteQuery.MotorPoolLaneFeature, RouteQuery.DisallowFeatureWeight); + compare(featureTypesSpy.count, 5) + compare(queryDetailsChangedSpy.count, 5) + compare(emptyQuery.featureTypes.length, 3) + emptyQuery.setFeatureWeight(RouteQuery.NoFeature, RouteQuery.NeutralFeatureWeight) + compare(featureTypesSpy.count, 6) + compare(queryDetailsChangedSpy.count, 6) + compare(emptyQuery.featureTypes.length, 0) // Segment details queryDetailsChangedSpy.clear() diff --git a/tests/auto/declarative/tst_plugin.qml b/tests/auto/declarative/tst_plugin.qml index cac9d025..d0d25164 100644 --- a/tests/auto/declarative/tst_plugin.qml +++ b/tests/auto/declarative/tst_plugin.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 1.0 +import QtQuick 2.0 import QtTest 1.0 import Qt.location 5.0 diff --git a/tests/auto/declarative/tst_qmlmapsandnav.cpp b/tests/auto/declarative/tst_qmlmapsandnav.cpp index 3b55a989..ca772515 100644 --- a/tests/auto/declarative/tst_qmlmapsandnav.cpp +++ b/tests/auto/declarative/tst_qmlmapsandnav.cpp @@ -41,12 +41,3 @@ #include <QtQuickTest/quicktest.h> QUICK_TEST_MAIN(qmlmapsandnav) -//QTQUICK1_TEST_MAIN(qmlmapsandnav) - -// temproray hack: put '-qtuick1' into argument vector -// to enforce QML1 testing until location QML elements are QML2 -// compatible. TODO -//int main(int argc, char **argv) -// { -// return quick_test_main(argc, argv, #name, 0, QUICK_TEST_SOURCE_DIR); - // } diff --git a/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h b/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h index 6c21e4f3..481b505e 100644 --- a/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h +++ b/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h @@ -51,6 +51,7 @@ #include <qgeocodereply.h> #include <QTimer> +#include <QDebug> #include <QTimerEvent> QT_USE_NAMESPACE @@ -105,6 +106,41 @@ public: setLocale(*(new QLocale (QLocale::German, QLocale::Germany))); } + QGeocodeReply* geocode(const QString &searchString, + int limit = -1, + int offset = 0, + QGeoBoundingArea *bounds = 0) + { + geocodeReply_ = new GeocodeReplyTest(); + connect(geocodeReply_, SIGNAL(aborted()), this, SLOT(requestAborted())); + geocodeReply_->callSetViewport(bounds); + + if (searchString.length() == 1) { + errorString_ = searchString; + errorCode_ = (QGeocodeReply::Error)searchString.toInt(); + } else { + errorString_ = ""; + errorCode_ = QGeocodeReply::NoError; + } + + if (errorCode_ == QGeocodeReply::NoError) + setLocations(geocodeReply_, searchString, limit, offset); + + if (finishRequestImmediately_) { + // check if we should finish with error + if (errorCode_) { + geocodeReply_->callSetError(errorCode_, errorString_); + } else { + geocodeReply_->callSetFinished(true); + } + } else { + // we only allow serialized requests in QML - previous must have been aborted + Q_ASSERT(timerId_ == 0); + timerId_ = startTimer(200); + } + return static_cast<QGeocodeReply*>(geocodeReply_); + } + QGeocodeReply* geocode ( const QGeoAddress & address, QGeoBoundingArea * bounds ) { geocodeReply_ = new GeocodeReplyTest(); @@ -158,12 +194,15 @@ public Q_SLOTS: } public: - void setLocations(GeocodeReplyTest* reply, const QString searchString, int limit ) + void setLocations(GeocodeReplyTest* reply, const QString searchString, int limit, int offset) { + if (limit < 0) + limit = 0; for (int i = 0; i < limit; ++i) { QGeoLocation location; QGeoAddress address; address.setStreet(searchString); + address.setCounty(QString::number(offset)); location.setAddress(address); reply->callAddLocation(location); } diff --git a/tests/declarativetestplugin/location.pro b/tests/declarativetestplugin/location.pro new file mode 100644 index 00000000..e6c22071 --- /dev/null +++ b/tests/declarativetestplugin/location.pro @@ -0,0 +1,36 @@ +TARGET = declarative_location_test +TARGETPATH = Qt/location/test + +include(../../src/imports/qimportbase.pri) + +QT += declarative location + +DESTDIR = $$QT.location.imports/$$TARGETPATH +target.path = $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INCLUDEPATH += ../../src/imports/location +INCLUDEPATH += ../../src/location + +# On some platforms, build both versions because debug and release +# versions are incompatible +#win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release + +HEADERS += qdeclarativepinchgenerator_p.h \ + qdeclarativelocationtestmodel_p.h \ + ../../src/imports/location/qdeclarativecoordinate_p.h + + +SOURCES += locationtest.cpp \ + qdeclarativepinchgenerator.cpp \ + qdeclarativelocationtestmodel.cpp \ + ../../src/imports/location/qdeclarativecoordinate.cpp + +# Tell qmake to create such makefile that qmldir and target (i.e. declarative_location) +# are both copied to qt/imports/QtMobility/location -directory, +# as the "/imports" is the default place where qmlviewer looks for plugins +# (otherwise qmlviewer -I <path> -option is needed) + +qmldir.files += $$PWD/qmldir +qmldir.path += $$[QT_INSTALL_IMPORTS]/$$TARGETPATH + +INSTALLS += target qmldir diff --git a/tests/declarativetestplugin/locationtest.cpp b/tests/declarativetestplugin/locationtest.cpp new file mode 100644 index 00000000..4dac0664 --- /dev/null +++ b/tests/declarativetestplugin/locationtest.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 <QtDeclarative/qdeclarativeextensionplugin.h> +#include "qdeclarativepinchgenerator_p.h" +#include "qdeclarativelocationtestmodel_p.h" +#include <QtDeclarative/qdeclarative.h> +#include <QDebug> + +QT_BEGIN_NAMESPACE + +class QLocationDeclarativeTestModule: public QDeclarativeExtensionPlugin +{ + Q_OBJECT + +public: + virtual void registerTypes(const char* uri) { + qDebug() << "registerTypes in new test plugin: " << uri; + if (QLatin1String(uri) == QLatin1String("Qt.location.test")) { + // This version numbering is not correct. It is just something to get going + // until the proper versioning scheme of QML plugins in Qt5 is agreed upon. + qmlRegisterType<QDeclarativePinchGenerator>(uri, 5, 0, "PinchGenerator"); + qmlRegisterType<QDeclarativeLocationTestModel>(uri, 5, 0, "TestModel"); + } else { + qDebug() << "Unsupported URI given to load location test QML plugin: " << QLatin1String(uri); + } + } +}; + +QT_END_NAMESPACE +#include "locationtest.moc" + +Q_EXPORT_PLUGIN2(declarative_location_test, QT_PREPEND_NAMESPACE(QLocationDeclarativeTestModule)); diff --git a/tests/declarativetestplugin/qdeclarativelocationtestmodel.cpp b/tests/declarativetestplugin/qdeclarativelocationtestmodel.cpp new file mode 100644 index 00000000..e75bea72 --- /dev/null +++ b/tests/declarativetestplugin/qdeclarativelocationtestmodel.cpp @@ -0,0 +1,129 @@ +#include "qdeclarativelocationtestmodel_p.h" +#include <qgeocoordinate.h> +#include <QtGui/QApplication> + +QDeclarativeLocationTestModel::QDeclarativeLocationTestModel(QObject *parent): + QAbstractListModel(parent), + delay_(0), + datacount_(0), + componentCompleted_(false) +{ + timer_.setSingleShot(true); + connect(&timer_, SIGNAL(timeout()), this, SLOT(repopulate())); + // Establish role names so that they can be queried from this model + QHash<int, QByteArray> roleNames; + roleNames = QAbstractItemModel::roleNames(); + roleNames.insert(TestDataRole, "modeldata"); + setRoleNames(roleNames); +} + +QDeclarativeLocationTestModel::~QDeclarativeLocationTestModel() +{ + if (timer_.isActive()) + timer_.stop(); + if (!dataobjects_.isEmpty()) { + qDeleteAll(dataobjects_); + dataobjects_.clear(); + } +} + +void QDeclarativeLocationTestModel::componentComplete() +{ + componentCompleted_ = true; + scheduleRepopulation(); +} + + +int QDeclarativeLocationTestModel::datacount() const +{ + return datacount_; +} + +void QDeclarativeLocationTestModel::setDatacount(int datacount) +{ + if (datacount_ == datacount) + return; + datacount_ = datacount; + emit datacountChanged(); + scheduleRepopulation(); +} + +int QDeclarativeLocationTestModel::delay() const +{ + return delay_; +} + +void QDeclarativeLocationTestModel::setDelay(int delay) +{ + if (delay_ == delay) + return; + delay_ = delay; + emit delayChanged(); +} + +QString QDeclarativeLocationTestModel::datatype() const +{ + return datatype_; +} + +void QDeclarativeLocationTestModel::setDatatype(QString datatype) +{ + if (datatype_ == datatype) + return; + datatype_ = datatype; + emit datatypeChanged(); + scheduleRepopulation(); +} + +// only coordinate datatype for now to get started with, +// refactor if more usecases for the model emerge. +void QDeclarativeLocationTestModel::repopulate() +{ + double latitude = 0.0; + double longitude = 1.0; + beginResetModel(); + if (!dataobjects_.isEmpty()) { + qDeleteAll(dataobjects_); + dataobjects_.clear(); + } + for (int i = 0; i < datacount_; ++i) { + DataObject* dataobject = new DataObject; + QDeclarativeCoordinate* coordinate = new QDeclarativeCoordinate(QGeoCoordinate(latitude,longitude)); + dataobject->coordinate_ = coordinate; + dataobjects_.append(dataobject); + longitude += 1.0; + latitude += 1.0; + } + endResetModel(); +} + +void QDeclarativeLocationTestModel::scheduleRepopulation() +{ + if (!componentCompleted_) + return; + if (timer_.isActive()) + timer_.stop(); + if (delay_ > 0) + timer_.start(delay_); + else + repopulate(); +} + +int QDeclarativeLocationTestModel::rowCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent); + return dataobjects_.count(); +} + +// Returns the stored under the given role for the item referred to by the index. +QVariant QDeclarativeLocationTestModel::data(const QModelIndex& index, int role) const +{ + switch (role) { + case TestDataRole: + if (dataobjects_.at(index.row())) { + return QVariant::fromValue(qobject_cast<QObject*>(dataobjects_.at(index.row()))); + } + break; + } + return QVariant(); +} diff --git a/tests/declarativetestplugin/qdeclarativelocationtestmodel_p.h b/tests/declarativetestplugin/qdeclarativelocationtestmodel_p.h new file mode 100644 index 00000000..def3d62b --- /dev/null +++ b/tests/declarativetestplugin/qdeclarativelocationtestmodel_p.h @@ -0,0 +1,81 @@ +#ifndef QDECLARATIVELOCATIONTESTMODEL_H +#define QDECLARATIVELOCATIONTESTMODEL_H + +#include <QtDeclarative/QSGItem> +#include <QAbstractListModel> +#include <QTimer> +#include <QDebug> +#include <QList> +#include <qdeclarativecoordinate_p.h> + +class DataObject: public QObject +{ + Q_OBJECT + Q_PROPERTY(QDeclarativeCoordinate* coordinate READ coordinate CONSTANT) + +public: + DataObject() : coordinate_(0) {} + ~DataObject() {delete coordinate_;} + + QDeclarativeCoordinate* coordinate_; + QDeclarativeCoordinate* coordinate() const {return coordinate_;} +}; + +class QDeclarativeLocationTestModel : public QAbstractListModel, public QDeclarativeParserStatus +{ + Q_OBJECT + Q_PROPERTY(int datacount READ datacount WRITE setDatacount NOTIFY datacountChanged) + Q_PROPERTY(int delay READ delay WRITE setDelay NOTIFY delayChanged) + Q_PROPERTY(QString datatype READ datatype WRITE setDatatype NOTIFY datatypeChanged) + Q_INTERFACES(QDeclarativeParserStatus) + +public: + QDeclarativeLocationTestModel(QObject* parent = 0); + ~QDeclarativeLocationTestModel(); + + enum Roles { + TestDataRole = Qt::UserRole + 500 + }; + + // from QDeclarativeParserStatus + virtual void componentComplete(); + virtual void classBegin() {} + + // From QAbstractListModel + virtual int rowCount(const QModelIndex &parent) const; + virtual QVariant data(const QModelIndex &index, int role) const; + + int datacount() const; + void setDatacount(int datacount); + + int delay() const; + void setDelay(int delay); + + QString datatype() const; + void setDatatype(QString datatype); + + //Q_INVOKABLE void reset(); + +signals: + void countChanged(); + void datacountChanged(); + void datatypeChanged(); + void delayChanged(); + void modelChanged(); + +private slots: + void repopulate(); + +private: + void scheduleRepopulation(); + +private: + int delay_; + int datacount_; + bool componentCompleted_; + QString datatype_; + QTimer timer_; + QList<DataObject*> dataobjects_; +}; + +#endif diff --git a/tests/declarativetestplugin/qdeclarativepinchgenerator.cpp b/tests/declarativetestplugin/qdeclarativepinchgenerator.cpp new file mode 100644 index 00000000..388d798f --- /dev/null +++ b/tests/declarativetestplugin/qdeclarativepinchgenerator.cpp @@ -0,0 +1,419 @@ +#include "qdeclarativepinchgenerator_p.h" +#include <QtGui/QApplication> +#include <qsgengine.h> + + +QDeclarativePinchGenerator::QDeclarativePinchGenerator(): + target_(0), + state_(Invalid), + canvas_(0), + activeSwipe_(0), + replayTimer_(-1), + replayBookmark_(-1), + masterSwipe_(-1), + touchPointId_(0), + replaySpeedFactor_(1.0), + enabled_(true) +{ + setAcceptedMouseButtons(Qt::LeftButton | Qt::MidButton | Qt::RightButton); + swipeTimer_.invalidate(); +} + +QDeclarativePinchGenerator::~QDeclarativePinchGenerator() +{ + if (!swipeList1_.isEmpty()) { + qDeleteAll(swipeList1_); + swipeList1_.clear(); + } + if (!swipeList2_.isEmpty()) { + qDeleteAll(swipeList2_); + swipeList2_.clear(); + } +} + +void QDeclarativePinchGenerator::componentComplete() +{ + QSGItem::componentComplete(); +} + +void QDeclarativePinchGenerator::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (state_ != Idle || !enabled_) { + event->ignore(); + return; + } + Q_ASSERT(!activeSwipe_); + Q_ASSERT(!swipeTimer_.isValid()); + // Start recording a pinch gesture. + QTouchEvent::TouchPoint touchPoint = mouseEventToTouchPoint(event); + if (touchPoint.state() == Qt::TouchPointPressed) { + activeSwipe_ = new Swipe; + //touchPointId_ = 0; + activeSwipe_->touchPoints.append(touchPoint); + activeSwipe_->totalDuration = 0; + activeSwipe_->touchPointDurations.append(0); + swipeTimer_.start(); + setState(Recording); + } else { + Q_ASSERT(false); // no! + } +} + +bool QDeclarativePinchGenerator::enabled() const +{ + return enabled_; +} + + +void QDeclarativePinchGenerator::setEnabled(bool enabled) +{ + if (enabled == enabled_) + return; + enabled_ = enabled; + if (!enabled_) { + stop(); + clear(); + } + emit enabledChanged(); +} + +QTouchEvent::TouchPoint QDeclarativePinchGenerator::mouseEventToTouchPoint(QGraphicsSceneMouseEvent *event) +{ + QTouchEvent::TouchPoint touchPoint; + switch (event->type()) { + case QEvent::GraphicsSceneMousePress: + touchPoint.setState(Qt::TouchPointPressed); + break; + case QEvent::GraphicsSceneMouseMove: + touchPoint.setState(Qt::TouchPointMoved); + break; + case QEvent::GraphicsSceneMouseRelease: + touchPoint.setState(Qt::TouchPointReleased); + break; + default: + break; + } + //touchPoint.setId(touchPointId_++); // running number + touchPoint.setId(0); + touchPoint.setPressure(0.75); + touchPoint.setPos(event->pos()); + touchPoint.setLastPos(event->lastPos()); + touchPoint.setScenePos(target_->mapToScene(event->pos())); + touchPoint.setLastScenePos(target_->mapToScene(event->lastPos())); + return touchPoint; +} + +// fixme this is excessive +QTouchEvent::TouchPoint QDeclarativePinchGenerator::convertToPrimary(QTouchEvent::TouchPoint original) +{ + QTouchEvent::TouchPoint touchPoint; + touchPoint.setState(original.state() | Qt::TouchPointPrimary); + touchPoint.setId(original.id() + 1); + touchPoint.setPressure(original.pressure()); + touchPoint.setPos(original.pos()); + touchPoint.setLastPos(original.lastPos()); + touchPoint.setScenePos(original.scenePos()); + touchPoint.setLastScenePos(original.lastScenePos()); + return touchPoint; + +} + +void QDeclarativePinchGenerator::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if (state_ != Recording || !enabled_) { + event->ignore(); + return; + } + Q_ASSERT(activeSwipe_); + Q_ASSERT(swipeTimer_.isValid()); + QTouchEvent::TouchPoint touchPoint = mouseEventToTouchPoint(event); + if (touchPoint.state() == Qt::TouchPointMoved) { + activeSwipe_->touchPoints.append(touchPoint); + activeSwipe_->totalDuration += swipeTimer_.elapsed(); + activeSwipe_->touchPointDurations.append(swipeTimer_.elapsed()); + swipeTimer_.restart(); + } else { + Q_ASSERT(false); // no! + } +} + +void QDeclarativePinchGenerator::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + if (state_ != Recording || !enabled_) { + event->ignore(); + return; + } + Q_ASSERT(activeSwipe_); + Q_ASSERT(swipeTimer_.isValid()); + QTouchEvent::TouchPoint touchPoint = mouseEventToTouchPoint(event); + if (touchPoint.state() == Qt::TouchPointReleased) { + activeSwipe_->touchPoints.append(touchPoint); + activeSwipe_->totalDuration += swipeTimer_.elapsed(); + activeSwipe_->touchPointDurations.append(swipeTimer_.elapsed()); + } else { + Q_ASSERT(false); // no! + } + if (swipes_.count() == SWIPES_REQUIRED) + delete swipes_.takeFirst(); + swipes_.append(activeSwipe_); + activeSwipe_ = 0; + swipeTimer_.invalidate(); + if (canvas_ && target_) setState(Idle); else setState(Invalid); + emit swipesChanged(); +} + +QList<QObject*> QDeclarativePinchGenerator::swipe1() +{ + if (swipes_.count() < 1) + return QList<QObject*>(); + if (!swipeList1_.isEmpty()) { + qDeleteAll(swipeList1_); + swipeList1_.clear(); + } + for (int i = 0; i < swipes_.at(0)->touchPoints.count(); ++i) { + TouchPoint* touchPoint = new TouchPoint( + swipes_.at(0)->touchPoints.at(i).scenePos().x(), + swipes_.at(0)->touchPoints.at(i).scenePos().y(), + static_cast<int>(swipes_.at(0)->touchPoints.at(i).state())); + swipeList1_.append(touchPoint); + } + return swipeList1_; +} + +QList<QObject*> QDeclarativePinchGenerator::swipe2() +{ + if (swipes_.count() < 2) + return QList<QObject*>(); + if (!swipeList2_.isEmpty()) { + qDeleteAll(swipeList2_); + swipeList2_.clear(); + } + for (int i = 0; i < swipes_.at(1)->touchPoints.count(); ++i) { + TouchPoint* touchPoint = new TouchPoint( + static_cast<double>(swipes_.at(1)->touchPoints.at(i).scenePos().x()), + static_cast<double>(swipes_.at(1)->touchPoints.at(i).scenePos().y()), + static_cast<int>(swipes_.at(1)->touchPoints.at(i).state())); + swipeList2_.append(touchPoint); + } + return swipeList2_; +} + +qreal QDeclarativePinchGenerator::replaySpeedFactor() const +{ + return replaySpeedFactor_; +} + +void QDeclarativePinchGenerator::setReplaySpeedFactor(qreal factor) +{ + if (factor == replaySpeedFactor_ || factor < 0.001) + return; + replaySpeedFactor_ = factor; + emit replaySpeedFactorChanged(); +} + +void QDeclarativePinchGenerator::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); + if (!enabled_) { + event->ignore(); + return; + } + stop(); + clear(); + if (canvas_ && target_) setState(Idle); else setState(Invalid); +} + +QString QDeclarativePinchGenerator::state() const +{ + switch (state_) { + case Invalid: + return "Invalid"; + case Idle: + return "Idle"; + break; + case Recording: + return "Recording"; + break; + case Replaying: + return "Replaying"; + break; + default: + Q_ASSERT(false); + } + return "How emberassing"; +} + +int QDeclarativePinchGenerator::count() const +{ + return swipes_.count(); +} + +void QDeclarativePinchGenerator::keyPressEvent(QKeyEvent *e) +{ + if (!enabled_) { + e->ignore(); + } + + if (e->key() == Qt::Key_C) { + clear(); + } else if (e->key() == Qt::Key_R) { + replay(); + } else if (e->key() == Qt::Key_S) { + stop(); + } else if (e->key() == Qt::Key_Plus) { + setReplaySpeedFactor(replaySpeedFactor() + 0.1); + } else if (e->key() == Qt::Key_Minus) { + setReplaySpeedFactor(replaySpeedFactor() - 0.1); + } else { + qDebug() << metaObject()->className() << "Unsupported key event."; + } +} +void QDeclarativePinchGenerator::setState(GeneratorState state) +{ + if (state == state_) + return; + state_ = state; + emit stateChanged(); +} + +void QDeclarativePinchGenerator::itemChange(ItemChange change, const ItemChangeData & data) +{ + if (change == ItemSceneChange) { + canvas_ = data.canvas; + if (target_) + setState(Idle); + } +} + +void QDeclarativePinchGenerator::timerEvent(QTimerEvent *event) +{ + Q_ASSERT(replayTimer_ == event->timerId()); + Q_ASSERT(state_ == Replaying); + + // Create touchevent. May have one or two touchpoints. + QTouchEvent* touchEvent; + switch (swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_).state()) { + case (Qt::TouchPointPressed): + touchEvent = new QTouchEvent(QEvent::TouchBegin,QTouchEvent::TouchScreen,Qt::NoModifier,Qt::TouchPointReleased); + break; + case (Qt::TouchPointMoved): + touchEvent = new QTouchEvent(QEvent::TouchUpdate,QTouchEvent::TouchScreen,Qt::NoModifier,Qt::TouchPointReleased); + break; + case (Qt::TouchPointReleased): + touchEvent = new QTouchEvent(QEvent::TouchEnd,QTouchEvent::TouchScreen,Qt::NoModifier,Qt::TouchPointReleased); + break; + default: + Q_ASSERT(false); + break; + } + // Set touch points. Master swipe has touchpoints as it was chosen to have more touchpoints. + // For the other swipe we need to check. + QList<QTouchEvent::TouchPoint> touchPoints; + // The primary touch point generates also mouse events. Does not work at the moment because + // we dispatch the touch event via canvas rather than the qApp. However qApp dispatching + // seems to miss some events arbitrarily. + touchPoints.append(convertToPrimary(swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_))); + //touchPoints.append(swipes_.at(masterSwipe_)->touchPoints.at(replayBookmark_)); + + int slaveSwipe(1); + if (masterSwipe_ == 1) + slaveSwipe = 0; + if (replayBookmark_ < swipes_.at(slaveSwipe)->touchPoints.count()) + touchPoints.append(swipes_.at(slaveSwipe)->touchPoints.at(replayBookmark_)); + touchEvent->setTouchPoints(touchPoints); + canvas_->sendEvent(target_, touchEvent); + delete touchEvent; + + replayBookmark_++; + if (replayBookmark_ >= swipes_.at(masterSwipe_)->touchPoints.count()) { + qDebug() << "Pinch replay finished!"; + stop(); + } else { + killTimer(replayTimer_); + replayTimer_ = startTimer((swipes_.at(masterSwipe_)->touchPointDurations.at(replayBookmark_) + 5) / replaySpeedFactor_ ); + } +} + +QSGItem* QDeclarativePinchGenerator::target() const +{ + return target_; +} + +void QDeclarativePinchGenerator::setTarget(QSGItem* target) +{ + if (target == target_) + return; + target_ = target; + stop(); + clear(); + if (canvas_) + setState(Idle); + else + setState(Invalid); + emit targetChanged(); +} + +Q_INVOKABLE void QDeclarativePinchGenerator::replay() +{ + if (state_ != Idle) { + qDebug() << "Wrong state, will not replay pinch, state: " << state_; + return; + } + if (swipes_.count() < SWIPES_REQUIRED) { + qDebug() << "Too few swipes, cannot replay, amount: " << swipes_.count(); + return; + } + if ((swipes_.at(0)->touchPoints.count() < 2) || (swipes_.at(1)->touchPoints.count() < 2)) { + qDebug() << "Too few touchpoints, won't replay, amount: " << swipes_.at(0)->touchPoints.count() << (swipes_.at(1)->touchPoints.count() < 2); + return; + } + if (swipes_.at(0)->touchPoints.back().state() != Qt::TouchPointReleased) { + qDebug() << "Swipe misses release event, won't replay."; + return; + } + if (swipes_.at(1)->touchPoints.back().state() != Qt::TouchPointReleased) { + qDebug() << "Swipe misses release event, won't replay."; + return; + } + + Q_ASSERT(swipes_.at(0)->touchPoints.count() == swipes_.at(0)->touchPointDurations.count()); + Q_ASSERT(swipes_.at(1)->touchPoints.count() == swipes_.at(1)->touchPointDurations.count()); + + // 'nuff checkin' already, start replay. let the one with more swipes dictate + if (swipes_.at(0)->touchPoints.count() >= swipes_.at(1)->touchPoints.count()) + masterSwipe_ = 0; + else + masterSwipe_ = 1; + + replayTimer_ = startTimer(swipes_.at(masterSwipe_)->touchPointDurations.at(0) / replaySpeedFactor_); + replayBookmark_ = 0; + setState(Replaying); + //qDebug() << "Started replay. Master total duration, first timeout, swipe counts respectively: " + // << swipes_.at(masterSwipe_)->totalDuration << swipes_.at(masterSwipe_)->touchPointDurations.at(0) + // << swipes_.at(0)->touchPoints.count() + // << swipes_.at(1)->touchPoints.count(); +} + +Q_INVOKABLE void QDeclarativePinchGenerator::clear() +{ + stop(); + delete activeSwipe_; + activeSwipe_ = 0; + if (!swipes_.isEmpty()) { + qDeleteAll(swipes_); + swipes_.clear(); + emit countChanged(); + emit swipesChanged(); + } +} + +Q_INVOKABLE void QDeclarativePinchGenerator::stop() +{ + if (state_ != Replaying) + return; + // stop replay + Q_ASSERT(replayTimer_ != -1); + killTimer(replayTimer_); + replayTimer_ = -1; + setState(Idle); +} diff --git a/tests/declarativetestplugin/qdeclarativepinchgenerator_p.h b/tests/declarativetestplugin/qdeclarativepinchgenerator_p.h new file mode 100644 index 00000000..cb86a990 --- /dev/null +++ b/tests/declarativetestplugin/qdeclarativepinchgenerator_p.h @@ -0,0 +1,125 @@ +#ifndef QDECLARATIVEPINCHGENERATOR_H +#define QDECLARATIVEPINCHGENERATOR_H + +#include <QtDeclarative/QSGItem> +#include <QGraphicsSceneMouseEvent> +#include <QElapsedTimer> +#include <QTouchEvent> +#include <QSGCanvas> +#include <QKeyEvent> +#include <QList> +#include <QDebug> + +// how many concurrent "swipes" should we have +// bit overkill here first I thought support random about of swipes (1..x) +// but thats for later +#define SWIPES_REQUIRED 2 + +typedef struct { + int totalDuration; // not sure if needed + QList<QTouchEvent::TouchPoint> touchPoints; + QList<int> touchPointDurations; +} Swipe; + +// total overkill fixme +class TouchPoint: public QObject +{ + Q_OBJECT + Q_PROPERTY(double targetX READ targetX CONSTANT) + Q_PROPERTY(double targetY READ targetY CONSTANT) + Q_PROPERTY(int touchState READ touchState CONSTANT) +public: + TouchPoint(double x, double y, int state): targetX_(x), targetY_(y),touchState_(state) {} + double targetX() {return targetX_;} + double targetY() {return targetY_;} + double touchState() {return touchState_;} + double targetX_; + double targetY_; + int touchState_; +}; + +class QDeclarativePinchGenerator : public QSGItem +{ + Q_OBJECT + + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + Q_PROPERTY(QString state READ state NOTIFY stateChanged) + Q_PROPERTY(int count READ count NOTIFY countChanged) + Q_PROPERTY(qreal replaySpeedFactor READ replaySpeedFactor WRITE setReplaySpeedFactor NOTIFY replaySpeedFactorChanged) + Q_PROPERTY(QSGItem* target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QList<QObject*> swipe1 READ swipe1 NOTIFY swipesChanged) + Q_PROPERTY(QList<QObject*> swipe2 READ swipe2 NOTIFY swipesChanged) + Q_INTERFACES(QDeclarativeParserStatus) + +public: + QDeclarativePinchGenerator(); + ~QDeclarativePinchGenerator(); + + QString state() const; + int count() const; + QSGItem* target() const; + void setTarget(QSGItem* target); + qreal replaySpeedFactor() const; + void setReplaySpeedFactor(qreal factor); + bool enabled() const; + void setEnabled(bool enabled); + + QList<QObject*> swipe1(); + QList<QObject*> swipe2(); + + Q_INVOKABLE void replay(); + Q_INVOKABLE void clear(); + Q_INVOKABLE void stop(); + +signals: + void stateChanged(); + void countChanged(); + void targetChanged(); + void swipesChanged(); + void replaySpeedFactorChanged(); + void enabledChanged(); + +public: + enum GeneratorState { + Invalid = 0, + Idle = 1, + Recording = 2, + Replaying = 3 + }; + + // from QDeclarativeParserStatus + virtual void componentComplete(); + // from QSGItem + void itemChange(ItemChange change, const ItemChangeData & data); + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void timerEvent(QTimerEvent *event); + +private: + void setState(GeneratorState state); + QTouchEvent::TouchPoint mouseEventToTouchPoint(QGraphicsSceneMouseEvent* event); + QTouchEvent::TouchPoint convertToPrimary(QTouchEvent::TouchPoint original); + +private: + QSGItem* target_; + GeneratorState state_; + QSGCanvas* canvas_; + QList<Swipe*> swipes_; + Swipe* activeSwipe_; + QElapsedTimer swipeTimer_; + int replayTimer_; + int replayBookmark_; + int masterSwipe_; + int touchPointId_; + qreal replaySpeedFactor_; + QList<QObject*> swipeList1_; + QList<QObject*> swipeList2_; + bool enabled_; +}; + +#endif diff --git a/tests/declarativetestplugin/qmldir b/tests/declarativetestplugin/qmldir new file mode 100644 index 00000000..f35dd9c1 --- /dev/null +++ b/tests/declarativetestplugin/qmldir @@ -0,0 +1 @@ +plugin declarative_location_test |