summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorjuhvu <qt-info@nokia.com>2011-08-11 15:02:29 +1000
committerabcd <qt_abcd1@ovi.com>2011-08-12 05:06:19 +0200
commit469170b584d14e045418a71b34fb648cc6f9b726 (patch)
tree05eca519008a620f109077838e8a6b2581e05b05 /tests
parent3f7102d1eef9f5070ecc0033415b057a966d9f0d (diff)
downloadqtlocation-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')
-rw-r--r--tests/auto/declarative/landmarks.dbbin26624 -> 0 bytes
-rw-r--r--tests/auto/declarative/tst_bounding_area.qml2
-rw-r--r--tests/auto/declarative/tst_map.qml (renamed from tests/auto/declarative/tst_map_qml1)2
-rw-r--r--tests/auto/declarative/tst_map_geocoding.qml118
-rw-r--r--tests/auto/declarative/tst_map_mouse.qml2
-rw-r--r--tests/auto/declarative/tst_map_objectview.qml (renamed from tests/auto/declarative/tst_map_objectview_qml1)92
-rw-r--r--tests/auto/declarative/tst_map_routing.qml16
-rw-r--r--tests/auto/declarative/tst_plugin.qml2
-rw-r--r--tests/auto/declarative/tst_qmlmapsandnav.cpp9
-rw-r--r--tests/auto/geotestplugin/qgeocodingmanagerengine_test.h41
-rw-r--r--tests/declarativetestplugin/location.pro36
-rw-r--r--tests/declarativetestplugin/locationtest.cpp71
-rw-r--r--tests/declarativetestplugin/qdeclarativelocationtestmodel.cpp129
-rw-r--r--tests/declarativetestplugin/qdeclarativelocationtestmodel_p.h81
-rw-r--r--tests/declarativetestplugin/qdeclarativepinchgenerator.cpp419
-rw-r--r--tests/declarativetestplugin/qdeclarativepinchgenerator_p.h125
-rw-r--r--tests/declarativetestplugin/qmldir1
17 files changed, 1075 insertions, 71 deletions
diff --git a/tests/auto/declarative/landmarks.db b/tests/auto/declarative/landmarks.db
deleted file mode 100644
index e3fb33ac..00000000
--- a/tests/auto/declarative/landmarks.db
+++ /dev/null
Binary files differ
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