diff options
author | Aaron McCarthy <aaron.mccarthy@nokia.com> | 2012-08-16 13:32:43 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-28 10:07:49 +0200 |
commit | 059388adce26be48868cd741b4c5d751298fb4d8 (patch) | |
tree | 1a8a41c0f280b7ab3c502b49527bd609d1c0884a | |
parent | 7dd46f8c96a4bdaca2809ff97b773f358392516f (diff) |
Convert GeoShape, GeoRectangle and GeoCircle into QML value types.v5.0.0-beta1
This replaces the GeoShape, GeoRectangle and GeoCircle QML elements with
value types. A value type is a better fit for shape types. It is very
similar to a rect with some utility functions.
Declare QGeoShape, QGeoRectangle and QGeoCircle as movable types.
Update documentation.
Change-Id: Id6c48e1e841c68f2f0c5c6a9c4a6580a57e2dfb6
Reviewed-by: abcd <amos.choy@nokia.com>
50 files changed, 1192 insertions, 1097 deletions
diff --git a/doc/src/cpp-qml.qdoc b/doc/src/cpp-qml.qdoc index 28bc6620..47b2175e 100644 --- a/doc/src/cpp-qml.qdoc +++ b/doc/src/cpp-qml.qdoc @@ -132,29 +132,6 @@ The following sets the properties of this object based on a QGeoAddress object f \snippet snippets/cpp/cppqml.cpp Address set -\section2 GeoRectangle - QGeoRectangle -\target georectangle -The \l {GeoRectangle::rectangle}{GeoRectangle.rectangle} property is used to provide an interface -between C++ and QML code. First a pointer to a GeoRectangle object must be obtained from C++, then -use the \l {QObject::property()}{property()} and \l {QObject::setProperty()}{setProperty()} -functions to get and set the \c rectangle property. The following gets the QGeoRectangle -representing this object from C++: -\snippet snippets/cpp/cppqml.cpp GeoRectangle get -The following sets the properties of this object based on a QGeoRectangle object from C++: -\snippet snippets/cpp/cppqml.cpp GeoRectangle set - - -\section2 GeoCircle - QGeoCircle -\target geocircle -The \l {GeoCircle::circle} {GeoCircle.circle} property is used to provide an interface between C++ and QML code. First a pointer to a -GeoCircle object must be obtained from C++, then use the -\l {QObject::property()}{property()} and \l {QObject::setProperty()}{setProperty()} functions -to get and set the \c circle property. -The following gets the QGeoCircle representing this object from C++: -\snippet snippets/cpp/cppqml.cpp GeoCircle get -The following sets the properties of this object based on a QGeoCircle object from C++: -\snippet snippets/cpp/cppqml.cpp GeoCircle set - \section2 Location - QGeoLocation \target location The \l {Location::location} {Location.location} property is used to provide an interface between C++ and QML code. First a pointer to a diff --git a/doc/src/snippets/cpp/cppqml.cpp b/doc/src/snippets/cpp/cppqml.cpp index 0e7158a7..d5d4bad9 100644 --- a/doc/src/snippets/cpp/cppqml.cpp +++ b/doc/src/snippets/cpp/cppqml.cpp @@ -127,22 +127,6 @@ void cppQmlInterface(QObject *qmlObject) qmlObject->setProperty("address", QVariant::fromValue(geoAddress)); //! [Address set] - //! [GeoRectangle get] - QGeoRectangle geoRectangle = qmlObject->property("rectangle").value<QGeoRectangle>(); - //! [GeoRectangle get] - - //! [GeoRectangle set] - qmlObject->setProperty("rectangle", QVariant::fromValue(geoRectangle)); - //! [GeoRectangle set] - - //! [GeoCircle get] - QGeoCircle geoCircle = qmlObject->property("circle").value<QGeoCircle>(); - //! [GeoCircle get] - - //! [GeoCircle set] - qmlObject->setProperty("circle", QVariant::fromValue(geoCircle)); - //! [GeoCircle set] - //! [Location get] QGeoLocation geoLocation = qmlObject->property("location").value<QGeoLocation>(); //! [Location get] diff --git a/doc/src/snippets/declarative/places.qml b/doc/src/snippets/declarative/places.qml index dbc7f8d6..11a0f3b3 100644 --- a/doc/src/snippets/declarative/places.qml +++ b/doc/src/snippets/declarative/places.qml @@ -128,13 +128,8 @@ Item { plugin: myPlugin - searchArea: GeoCircle { - center { - // Brisbane - longitude: 153.02778 - latitude: -27.46778 - } - } + // Brisbane + searchArea: QtLocation.circle(QtLocation.coordinate(-27.46778, 153.02778)) onSearchTermChanged: update() } diff --git a/examples/declarative/places/places.qml b/examples/declarative/places/places.qml index 35911a4c..df9ec2f3 100644 --- a/examples/declarative/places/places.qml +++ b/examples/declarative/places/places.qml @@ -48,12 +48,19 @@ Item { width: (parent && parent.width > 0) ? parent.width : 360 height: (parent && parent.height > 0) ? parent.height : 640 property variant map - property variant searchRegion : startLocation + property variant startLocation + property variant searchRegion: QtLocation.circle(startLocation) property variant searchRegionItem property Plugin favoritesPlugin onMapChanged: editPlaceDialog.prepareDialog() + Binding { + target: page + property: "startLocation" + value: map ? map.center : QtLocation.coordinate() + } + Rectangle { id: backgroundRect anchors.fill: parent @@ -207,10 +214,11 @@ Item { onGoButtonClicked: { var c = QtLocation.coordinate(parseFloat(dialogModel.get(0).inputText), parseFloat(dialogModel.get(1).inputText)); - searchRegion = startLocation; map.center = c; + searchRegion = Qt.binding(function() { return QtLocation.circle(startLocation) }); + if (searchRegionItem) { map.removeMapItem(searchRegionItem); searchRegionItem.destroy(); @@ -241,16 +249,14 @@ Item { onCancelButtonClicked: page.state = "" onGoButtonClicked: { - var newRegion = Qt.createQmlObject('import QtLocation 5.0; GeoRectangle {}', page, "GeoCircle"); var c = QtLocation.coordinate(parseFloat(dialogModel.get(0).inputText), parseFloat(dialogModel.get(1).inputText)); - newRegion.center = c; - newRegion.width = dialogModel.get(2).inputText; - newRegion.height = dialogModel.get(3).inputText; + var r = QtLocation.rectangle(c, parseFloat(dialogModel.get(2).inputText), + parseFloat(dialogModel.get(3).inputText)); map.center = c; - searchRegion = newRegion; + searchRegion = r; if (searchRegionItem) { map.removeMapItem(searchRegionItem); @@ -258,8 +264,8 @@ Item { } searchRegionItem = Qt.createQmlObject('import QtLocation 5.0; MapRectangle { color: "red"; opacity: 0.4 }', page, "MapRectangle"); - searchRegionItem.topLeft = newRegion.topLeft; - searchRegionItem.bottomRight = newRegion.bottomRight; + searchRegionItem.topLeft = r.topLeft; + searchRegionItem.bottomRight = r.bottomRight; map.addMapItem(searchRegionItem); page.state = ""; @@ -286,15 +292,13 @@ Item { onCancelButtonClicked: page.state = "" onGoButtonClicked: { - var newRegion = Qt.createQmlObject('import QtLocation 5.0; GeoCircle {}', page, "GeoCircle"); var c = QtLocation.coordinate(parseFloat(dialogModel.get(0).inputText), parseFloat(dialogModel.get(1).inputText)); - newRegion.center = c; - newRegion.radius = dialogModel.get(2).inputText; + var circle = QtLocation.circle(c, parseFloat(dialogModel.get(2).inputText)); map.center = c; - searchRegion = newRegion; + searchRegion = circle; if (searchRegionItem) { map.removeMapItem(searchRegionItem); @@ -302,8 +306,8 @@ Item { } searchRegionItem = Qt.createQmlObject('import QtLocation 5.0; MapCircle { color: "red"; opacity: 0.4 }', page, "MapRectangle"); - searchRegionItem.center = newRegion.center; - searchRegionItem.radius = newRegion.radius; + searchRegionItem.center = circle.center; + searchRegionItem.radius = circle.radius; map.addMapItem(searchRegionItem); page.state = ""; @@ -347,16 +351,6 @@ Item { } } - GeoCircle { - id: startLocation - } - - Binding { - target: startLocation - property: "center" - value: map ? map.center : QtLocation.coordinate() - } - //! [PlaceSearchModel model] PlaceSearchModel { id: placeSearchModel diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp index 11ebcdd6..6f89b6ab 100644 --- a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp +++ b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp @@ -48,10 +48,10 @@ #include <QtLocation/QPlaceManager> #include <QtLocation/QPlaceSearchRequest> #include <QtLocation/QPlaceSearchReply> +#include <QtLocation/QGeoCircle> QDeclarativeSearchModelBase::QDeclarativeSearchModelBase(QObject *parent) -: QAbstractListModel(parent), m_plugin(0), m_reply(0), m_searchArea(0), m_complete(false), - m_status(Null) +: QAbstractListModel(parent), m_plugin(0), m_reply(0), m_complete(false), m_status(Null) { } @@ -84,20 +84,35 @@ void QDeclarativeSearchModelBase::setPlugin(QDeclarativeGeoServiceProvider *plug /*! \internal */ -QDeclarativeGeoShape *QDeclarativeSearchModelBase::searchArea() const +QVariant QDeclarativeSearchModelBase::searchArea() const { - return m_searchArea; + QGeoShape s = m_request.searchArea(); + if (s.type() == QGeoShape::RectangleType) + return QVariant::fromValue(QGeoRectangle(s)); + else if (s.type() == QGeoShape::CircleType) + return QVariant::fromValue(QGeoCircle(s)); + else + return QVariant::fromValue(s); } /*! \internal */ -void QDeclarativeSearchModelBase::setSearchArea(QDeclarativeGeoShape *searchArea) +void QDeclarativeSearchModelBase::setSearchArea(const QVariant &searchArea) { - if (m_searchArea == searchArea) + QGeoShape s; + + if (searchArea.userType() == qMetaTypeId<QGeoRectangle>()) + s = searchArea.value<QGeoRectangle>(); + else if (searchArea.userType() == qMetaTypeId<QGeoCircle>()) + s = searchArea.value<QGeoCircle>(); + else if (searchArea.userType() == qMetaTypeId<QGeoShape>()) + s = searchArea.value<QGeoShape>(); + + if (m_request.searchArea() == s) return; - m_searchArea = searchArea; + m_request.setSearchArea(s); emit searchAreaChanged(); } @@ -195,7 +210,6 @@ void QDeclarativeSearchModelBase::update() return; } - updateSearchRequest(); m_reply = sendQuery(placeManager, m_request); if (!m_reply) { clearData(); @@ -256,17 +270,6 @@ void QDeclarativeSearchModelBase::clearData(bool suppressSignal) /*! \internal */ -void QDeclarativeSearchModelBase::updateSearchRequest() -{ - if (m_searchArea) - m_request.setSearchArea(m_searchArea->shape()); - else - m_request.setSearchArea(QGeoShape()); -} - -/*! - \internal -*/ void QDeclarativeSearchModelBase::classBegin() { } diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h index 34fb8763..67d31542 100644 --- a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h +++ b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h @@ -56,14 +56,13 @@ class QPlaceManager; class QPlaceSearchRequest; class QPlaceSearchReply; class QDeclarativePlace; -class QDeclarativeGeoShape; class QDeclarativeSearchModelBase : public QAbstractListModel, public QQmlParserStatus { Q_OBJECT Q_PROPERTY(QDeclarativeGeoServiceProvider *plugin READ plugin WRITE setPlugin NOTIFY pluginChanged) - Q_PROPERTY(QDeclarativeGeoShape *searchArea READ searchArea WRITE setSearchArea NOTIFY searchAreaChanged) + Q_PROPERTY(QVariant searchArea READ searchArea WRITE setSearchArea NOTIFY searchAreaChanged) Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged) Q_PROPERTY(int limit READ limit WRITE setLimit NOTIFY limitChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) @@ -86,8 +85,8 @@ public: QDeclarativeGeoServiceProvider *plugin() const; void setPlugin(QDeclarativeGeoServiceProvider *plugin); - QDeclarativeGeoShape *searchArea() const; - void setSearchArea(QDeclarativeGeoShape *searchArea); + QVariant searchArea() const; + void setSearchArea(const QVariant &searchArea); int offset() const; void setOffset(int offset); @@ -106,7 +105,6 @@ public: Q_INVOKABLE QString errorString() const; virtual void clearData(bool suppressSignal = false); - virtual void updateSearchRequest(); // From QQmlParserStatus virtual void classBegin(); @@ -136,8 +134,6 @@ protected: QPlaceReply *m_reply; private: - QDeclarativeGeoShape *m_searchArea; - bool m_complete; Status m_status; QString m_errorString; diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp index 87194ad3..42afc88b 100644 --- a/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp +++ b/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp @@ -205,14 +205,14 @@ QT_USE_NAMESPACE */ /*! - \qmlproperty GeoShape PlaceSearchModel::searchArea + \qmlproperty variant PlaceSearchModel::searchArea This property holds the search area. The search result returned by the model will be within the search area. - If this property is set to a \l GeoCircle its \l {GeoCircle::radius}{radius} property - may be left unset, in which case the \l Plugin will choose an appropriate radius for the - search. + If this property is set to a \l {QtLocation5::geocircle}{geocircle} its + \l {QtLocation5::geocircle}{radius} property may be left unset, in which case the \l Plugin + will choose an appropriate radius for the search. Support for specifying a search area can vary according to the \l plugin backend implementation. For example, some may support a search center only while others may only @@ -271,18 +271,10 @@ QT_USE_NAMESPACE \c PlaceSearchModel.Error and the model cleared. \code - GeoCircle { - id: searchLocation - center { - latitude: 10 - longitude: 10 - } - } - PlaceSearchModel { id: model plugin: backendPlugin - searchArea : searchLocation + searchArea: QtLocation.circle(QtLocation.coordinate(10, 10)) ... } @@ -291,8 +283,8 @@ QT_USE_NAMESPACE onClicked: { model.searchTerm = "pizza"; model.categories = null; //not searching by any category - searchLocation.center.latitude = -27.5 - searchLocation.center.longitude = 153 + model.searchArea.center.latitude = -27.5; + model.searchArea.center.longitude = 153; model.update(); } } diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp index ca963e30..8f15d170 100644 --- a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp +++ b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp @@ -111,9 +111,9 @@ QT_USE_NAMESPACE This property holds the search area. Search suggestion results returned by the model will be relevant to the given search area. - If this property is set to a \l GeoCircle its \l {GeoCircle::radius}{radius} property - may be left unset, in which case the \l Plugin will choose an appropriate radius for the - search. + If this property is set to a \l {QtLocation5::geocircle}{geocircle} its + \l {QtLocation5::geocircle}{radius} property may be left unset, in which case the \l Plugin + will choose an appropriate radius for the search. */ /*! @@ -169,18 +169,10 @@ QT_USE_NAMESPACE This example shows use of the model \code - GeoCircle { - id: searchLocation - center { - latitude: 10 - longitude: 10 - } - } - PlaceSeachSuggestionModel { id: model plugin: backendPlugin - searchArea: searchLocation + searchArea: QtLocation.circle(QtLocation.coordinate(10, 10)) ... } @@ -188,8 +180,8 @@ QT_USE_NAMESPACE ... onClicked: { model.searchTerm = "piz" - searchLocation.center.latitude = -27.5 - searchLocation.cetner.longitude = 153 + model.searchArea.center.latitude = -27.5; + model.searchArea.cetner.longitude = 153; model.update(); } } @@ -287,14 +279,6 @@ void QDeclarativeSearchSuggestionModel::clearData(bool suppressSignal) /*! \internal */ -void QDeclarativeSearchSuggestionModel::updateSearchRequest() -{ - QDeclarativeSearchModelBase::updateSearchRequest(); -} - -/*! - \internal -*/ int QDeclarativeSearchSuggestionModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h index 0ff6bcd3..786b71f9 100644 --- a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h +++ b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h @@ -68,7 +68,6 @@ public: QStringList suggestions() const; void clearData(bool suppressSignal = false); - void updateSearchRequest(); // From QAbstractListModel int rowCount(const QModelIndex &parent) const; diff --git a/src/imports/location/location.cpp b/src/imports/location/location.cpp index 0f6b4162..3013dbe4 100644 --- a/src/imports/location/location.cpp +++ b/src/imports/location/location.cpp @@ -93,6 +93,9 @@ #include <QtQml/private/qqmlglobal_p.h> #include <QtQml/private/qqmlmetatype_p.h> +#include <QtLocation/QGeoRectangle> +#include <QtLocation/QGeoCircle> + #include <QtCore/QDebug> QT_BEGIN_NAMESPACE @@ -132,13 +135,10 @@ public: qmlRegisterSingletonType<LocationSingleton>(uri, 5, 0, "QtLocation", singleton_type_factory); QQml_addValueTypeProvider(getValueTypeProvider()); - QQmlMetaType::registerCustomStringConverter(qMetaTypeId<QGeoCoordinate>(), stringToCoordinate); + qmlRegisterValueTypeEnums<GeoShapeValueType>("QtLocation", 5, 0, "GeoShape"); qmlRegisterType<QDeclarativePosition>(uri, 5, 0, "Position"); qmlRegisterType<QDeclarativePositionSource>(uri, 5, 0, "PositionSource"); - qmlRegisterUncreatableType<QDeclarativeGeoShape>(uri, 5, 0, "GeoShape", QCoreApplication::translate(CONTEXT_NAME, NOT_INSTANTIABLE_BY_DEVELOPER).arg("(Positioning)GeoShape")); - qmlRegisterType<QDeclarativeGeoRectangle>(uri, 5, 0, "GeoRectangle"); - qmlRegisterType<QDeclarativeGeoCircle>(uri, 5, 0, "GeoCircle"); qmlRegisterType<QDeclarativeGeoAddress>(uri, 5, 0, "Address"); qmlRegisterType<QDeclarativeGeoServiceProvider>(uri, 5, 0, "Plugin"); diff --git a/src/imports/location/locationsingleton.cpp b/src/imports/location/locationsingleton.cpp index e5997627..7caa76f4 100644 --- a/src/imports/location/locationsingleton.cpp +++ b/src/imports/location/locationsingleton.cpp @@ -89,3 +89,77 @@ QGeoCoordinate LocationSingleton::coordinate(double latitude, double longitude, return QGeoCoordinate(latitude, longitude, altitude); } +/*! + \qmlmethod geoshape QtLocation5::QtLocation::shape() const + + Constructs an invalid geoshape. + + \sa {QtLocation5::geoshape}{geoshape} +*/ +QGeoShape LocationSingleton::shape() const +{ + return QGeoShape(); +} + +/*! + \qmlmethod georectangle QtLocation5::QtLocation::rectangle() const + + Constructs an invalid georectangle. + + \sa {QtLocation5::georectangle}{georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle() const +{ + return QGeoRectangle(); +} + +/*! + \qmlmethod georectangle QtLocation5::QtLocation::rectangle(coordinate center, real width, real height) const + + Constructs a georectangle centered at \a center with a width of \a width degrees and a hight of + \a height degrees. + + \sa {QtLocation5::georectangle}{georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate ¢er, + double width, double height) const +{ + return QGeoRectangle(center, width, height); +} + +/*! + \qmlmethod georectangle QtLocation5::QtLocation::rectangle(coordinate topLeft, coordinate bottomRight) const + + Constructs a georectangle with its top left corner positioned at \a topLeft and its bottom + right corner positioned at \a {bottomLeft}. + + \sa {QtLocation5::georectangle}{georectangle} +*/ +QGeoRectangle LocationSingleton::rectangle(const QGeoCoordinate &topLeft, + const QGeoCoordinate &bottomRight) const +{ + return QGeoRectangle(topLeft, bottomRight); +} + +/*! + \qmlmethod geocircle QtLocation5::QtLocation::circle() const + + Constructs an invalid geocircle. + + \sa {QtLocation5::geocircle}{geocircle} +*/ +QGeoCircle LocationSingleton::circle() const +{ + return QGeoCircle(); +} + +/*! + \qmlmethod geocircle QtLocation5::QtLocation::circle(coordinate center, real radius) const + + Constructs a geocircle centered at \a center with a radius of \a radius meters. +*/ +QGeoCircle LocationSingleton::circle(const QGeoCoordinate ¢er, qreal radius) const +{ + return QGeoCircle(center, radius); +} + diff --git a/src/imports/location/locationsingleton.h b/src/imports/location/locationsingleton.h index ae356e87..a2a8aa32 100644 --- a/src/imports/location/locationsingleton.h +++ b/src/imports/location/locationsingleton.h @@ -45,6 +45,9 @@ #include <QtCore/QObject> #include <QtCore/qnumeric.h> #include <QtLocation/QGeoCoordinate> +#include <QtLocation/QGeoShape> +#include <QtLocation/QGeoRectangle> +#include <QtLocation/QGeoCircle> class LocationSingleton : public QObject { @@ -56,6 +59,17 @@ public: Q_INVOKABLE QGeoCoordinate coordinate() const; Q_INVOKABLE QGeoCoordinate coordinate(double latitude, double longitude, double altitude = qQNaN()) const; + + Q_INVOKABLE QGeoShape shape() const; + + Q_INVOKABLE QGeoRectangle rectangle() const; + Q_INVOKABLE QGeoRectangle rectangle(const QGeoCoordinate ¢er, + double width, double height) const; + Q_INVOKABLE QGeoRectangle rectangle(const QGeoCoordinate &topLeft, + const QGeoCoordinate &bottomRight) const; + + Q_INVOKABLE QGeoCircle circle() const; + Q_INVOKABLE QGeoCircle circle(const QGeoCoordinate ¢er, qreal radius = -1.0) const; }; #endif // LOCATIONSINGLETON_H diff --git a/src/imports/location/locationvaluetypeprovider.cpp b/src/imports/location/locationvaluetypeprovider.cpp index 85197413..d5202d9f 100644 --- a/src/imports/location/locationvaluetypeprovider.cpp +++ b/src/imports/location/locationvaluetypeprovider.cpp @@ -41,23 +41,91 @@ #include "locationvaluetypeprovider.h" #include "qdeclarativecoordinate_p.h" +#include "qdeclarativegeoshape.h" +#include "qdeclarativegeorectangle.h" +#include "qdeclarativegeocircle.h" +#include <QtLocation/QGeoRectangle> +#include <QtLocation/QGeoCircle> QT_BEGIN_NAMESPACE -QVariant stringToCoordinate(const QString &s) +QGeoCoordinate parseCoordinate(const QJSValue &value, bool *ok) { QGeoCoordinate c; - QStringList fields = s.split(QLatin1Char(',')); - switch (fields.length()) { - case 2: - c = QGeoCoordinate(fields.at(0).toDouble(), fields.at(1).toDouble()); - break; - case 3: - c = QGeoCoordinate(fields.at(0).toDouble(), fields.at(1).toDouble(), fields.at(2).toDouble()); - break; + + if (value.isObject()) { + if (value.hasProperty(QStringLiteral("latitude"))) + c.setLatitude(value.property(QStringLiteral("latitude")).toNumber()); + if (value.hasProperty(QStringLiteral("longitude"))) + c.setLongitude(value.property(QStringLiteral("longitude")).toNumber()); + if (value.hasProperty(QStringLiteral("altitude"))) + c.setAltitude(value.property(QStringLiteral("altitude")).toNumber()); + + if (ok) + *ok = true; + } + + return c; +} + +QGeoRectangle parseRectangle(const QJSValue &value, bool *ok) +{ + QGeoRectangle r; + + *ok = false; + + if (value.isObject()) { + if (value.hasProperty(QStringLiteral("bottomLeft"))) { + QGeoCoordinate c = parseCoordinate(value.property(QStringLiteral("bottomLeft")), ok); + if (*ok) + r.setBottomLeft(c); + } + if (value.hasProperty(QStringLiteral("bottomRight"))) { + QGeoCoordinate c = parseCoordinate(value.property(QStringLiteral("bottomRight")), ok); + if (*ok) + r.setBottomRight(c); + } + if (value.hasProperty(QStringLiteral("topLeft"))) { + QGeoCoordinate c = parseCoordinate(value.property(QStringLiteral("topLeft")), ok); + if (*ok) + r.setTopLeft(c); + } + if (value.hasProperty(QStringLiteral("topRight"))) { + QGeoCoordinate c = parseCoordinate(value.property(QStringLiteral("topRight")), ok); + if (*ok) + r.setTopRight(c); + } + if (value.hasProperty(QStringLiteral("center"))) { + QGeoCoordinate c = parseCoordinate(value.property(QStringLiteral("center")), ok); + if (*ok) + r.setCenter(c); + } + if (value.hasProperty(QStringLiteral("height"))) + r.setHeight(value.property(QStringLiteral("height")).toNumber()); + if (value.hasProperty(QStringLiteral("width"))) + r.setWidth(value.property(QStringLiteral("width")).toNumber()); } - return QVariant::fromValue(c); + return r; +} + +QGeoCircle parseCircle(const QJSValue &value, bool *ok) +{ + QGeoCircle c; + + *ok = false; + + if (value.isObject()) { + if (value.hasProperty(QStringLiteral("center"))) { + QGeoCoordinate coord = parseCoordinate(value.property(QStringLiteral("center")), ok); + if (*ok) + c.setCenter(coord); + } + if (value.hasProperty(QStringLiteral("radius"))) + c.setRadius(value.property(QStringLiteral("radius")).toNumber()); + } + + return c; } LocationValueTypeProvider::LocationValueTypeProvider() @@ -67,47 +135,56 @@ LocationValueTypeProvider::LocationValueTypeProvider() bool LocationValueTypeProvider::create(int type, QQmlValueType *&v) { - if (type == qMetaTypeId<QGeoCoordinate>()) { - v = new CoordinateValueType; - return true; - } + if (type == qMetaTypeId<QGeoCoordinate>()) + return typedCreate<CoordinateValueType>(v); + else if (type == qMetaTypeId<QGeoShape>()) + return typedCreate<GeoShapeValueType>(v); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedCreate<GeoRectangleValueType>(v); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedCreate<GeoCircleValueType>(v); return false; } -bool LocationValueTypeProvider::init(int type, void *data, size_t n) +bool LocationValueTypeProvider::init(int type, void *data, size_t dataSize) { - if (type == qMetaTypeId<QGeoCoordinate>()) { - Q_ASSERT(n >= sizeof(QGeoCoordinate)); - QGeoCoordinate *c = reinterpret_cast<QGeoCoordinate *>(data); - new (c) QGeoCoordinate(); - return true; - } + if (type == qMetaTypeId<QGeoCoordinate>()) + return typedInit<QGeoCoordinate>(data, dataSize); + else if (type == qMetaTypeId<QGeoShape>()) + return typedInit<QGeoShape>(data, dataSize); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedInit<QGeoRectangle>(data, dataSize); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedInit<QGeoCircle>(data, dataSize); return false; } -bool LocationValueTypeProvider::destroy(int type, void *data, size_t n) +bool LocationValueTypeProvider::destroy(int type, void *data, size_t dataSize) { - if (type == qMetaTypeId<QGeoCoordinate>()) { - Q_ASSERT(n >= sizeof(QGeoCoordinate)); - QGeoCoordinate *c = reinterpret_cast<QGeoCoordinate *>(data); - c->~QGeoCoordinate(); - return true; - } + if (type == qMetaTypeId<QGeoCoordinate>()) + return typedDestroy<QGeoCoordinate>(data, dataSize); + else if (type == qMetaTypeId<QGeoShape>()) + return typedDestroy<QGeoShape>(data, dataSize); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedDestroy<QGeoRectangle>(data, dataSize); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedDestroy<QGeoCircle>(data, dataSize); return false; } -bool LocationValueTypeProvider::copy(int type, const void *src, void *dst, size_t n) +bool LocationValueTypeProvider::copy(int type, const void *src, void *dst, size_t dstSize) { - if (type == qMetaTypeId<QGeoCoordinate>()) { - Q_ASSERT(n >= sizeof(QGeoCoordinate)); - const QGeoCoordinate *srcC = reinterpret_cast<const QGeoCoordinate *>(src); - QGeoCoordinate *dstC = reinterpret_cast<QGeoCoordinate *>(dst); - new (dstC) QGeoCoordinate(*srcC); - return true; - } + if (type == qMetaTypeId<QGeoCoordinate>()) + return typedCopyConstruct<QGeoCoordinate>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoShape>()) + return typedCopyConstruct<QGeoShape>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedCopyConstruct<QGeoRectangle>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedCopyConstruct<QGeoCircle>(src, dst, dstSize); return false; } @@ -132,65 +209,100 @@ bool LocationValueTypeProvider::create(int type, int argc, const void *argv[], Q return false; } -bool LocationValueTypeProvider::createFromString(int, const QString &, void *, size_t) +bool LocationValueTypeProvider::createFromString(int type, const QString &s, void *data, size_t dataSize) { + Q_UNUSED(data) + Q_UNUSED(dataSize) + + if (type == qMetaTypeId<QGeoCoordinate>() || type == qMetaTypeId<QGeoShape>() || + type == qMetaTypeId<QGeoRectangle>() || type == qMetaTypeId<QGeoCircle>()) { + qWarning("Cannot create value type %d from string '%s'", type, qPrintable(s)); + } + return false; } -bool LocationValueTypeProvider::createStringFrom(int, const void *, QString *) +bool LocationValueTypeProvider::createStringFrom(int type, const void *data, QString *s) { + Q_UNUSED(data) + Q_UNUSED(s) + + if (type == qMetaTypeId<QGeoCoordinate>() || type == qMetaTypeId<QGeoShape>() || + type == qMetaTypeId<QGeoRectangle>() || type == qMetaTypeId<QGeoCircle>()) { + qWarning("Cannot create string from value type %d", type); + } + return false; } -bool LocationValueTypeProvider::variantFromJsObject(int, QQmlV8Handle, QV8Engine *, QVariant *) +bool LocationValueTypeProvider::variantFromJsObject(int type, QQmlV8Handle h, QV8Engine *e, QVariant *v) { + Q_UNUSED(h) + Q_UNUSED(e) + Q_UNUSED(v) + + if (type == qMetaTypeId<QGeoCoordinate>() || type == qMetaTypeId<QGeoShape>() || + type == qMetaTypeId<QGeoRectangle>() || type == qMetaTypeId<QGeoCircle>()) { + qWarning("Cannot create variant from js object for type %d", type); + } + return false; } -bool LocationValueTypeProvider::equal(int type, const void *lhs, const void *rhs, size_t n) +bool LocationValueTypeProvider::equal(int type, const void *lhs, const void *rhs, size_t rhsSize) { - if (type == qMetaTypeId<QGeoCoordinate>()) { - Q_ASSERT(n >= sizeof(QGeoCoordinate)); - const QGeoCoordinate *lhsC = reinterpret_cast<const QGeoCoordinate *>(lhs); - const QGeoCoordinate *rhsC = reinterpret_cast<const QGeoCoordinate *>(rhs); - return *lhsC == *rhsC; - } + Q_UNUSED(rhsSize) + + if (type == qMetaTypeId<QGeoCoordinate>()) + return typedEqual<QGeoCoordinate>(lhs, rhs); + else if (type == qMetaTypeId<QGeoShape>()) + return typedEqual<QGeoShape>(lhs, rhs); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedEqual<QGeoRectangle>(lhs, rhs); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedEqual<QGeoCircle>(lhs, rhs); return false; } -bool LocationValueTypeProvider::store(int type, const void *src, void *dst, size_t n) +bool LocationValueTypeProvider::store(int type, const void *src, void *dst, size_t dstSize) { if (type == qMetaTypeId<QGeoCoordinate>()) - return copy(type, src, dst, n); + return typedStore<QGeoCoordinate>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoShape>()) + return typedStore<QGeoShape>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedStore<QGeoRectangle>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedStore<QGeoCircle>(src, dst, dstSize); return false; } -bool LocationValueTypeProvider::read(int srcType, const void *src, size_t n, int dstType, void *dst) +bool LocationValueTypeProvider::read(int srcType, const void *src, size_t srcSize, int dstType, void *dst) { - if (dstType == qMetaTypeId<QGeoCoordinate>()) { - QGeoCoordinate *dstC = reinterpret_cast<QGeoCoordinate *>(dst); - if (srcType == qMetaTypeId<QGeoCoordinate>()) - return copy(srcType, src, dst, n); - *dstC = QGeoCoordinate(); - return true; - } + if (srcType == qMetaTypeId<QGeoCoordinate>()) + return typedRead<QGeoCoordinate>(srcType, src, srcSize, dstType, dst); + else if (srcType == qMetaTypeId<QGeoShape>()) + return typedRead<QGeoShape>(srcType, src, srcSize, dstType, dst); + else if (srcType == qMetaTypeId<QGeoRectangle>()) + return typedRead<QGeoRectangle>(srcType, src, srcSize, dstType, dst); + else if (srcType == qMetaTypeId<QGeoCircle>()) + return typedRead<QGeoCircle>(srcType, src, srcSize, dstType, dst); return false; } -bool LocationValueTypeProvider::write(int type, const void *src, void *dst, size_t n) +bool LocationValueTypeProvider::write(int type, const void *src, void *dst, size_t dstSize) { - if (type == qMetaTypeId<QGeoCoordinate>()) { - Q_ASSERT(n >= sizeof(QGeoCoordinate)); - const QGeoCoordinate *srcC = reinterpret_cast<const QGeoCoordinate *>(src); - QGeoCoordinate *dstC = reinterpret_cast<QGeoCoordinate *>(dst); - if (*dstC != *srcC) { - *dstC = *srcC; - return true; - } - } + if (type == qMetaTypeId<QGeoCoordinate>()) + return typedWrite<QGeoCoordinate>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoShape>()) + return typedWrite<QGeoShape>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoRectangle>()) + return typedWrite<QGeoRectangle>(src, dst, dstSize); + else if (type == qMetaTypeId<QGeoCircle>()) + return typedWrite<QGeoCircle>(src, dst, dstSize); return false; } diff --git a/src/imports/location/locationvaluetypeprovider.h b/src/imports/location/locationvaluetypeprovider.h index 3f7b1b02..a0c79887 100644 --- a/src/imports/location/locationvaluetypeprovider.h +++ b/src/imports/location/locationvaluetypeprovider.h @@ -46,7 +46,13 @@ QT_BEGIN_NAMESPACE -QVariant stringToCoordinate(const QString &s); +class QGeoCoordinate; +class QGeoRectangle; +class QGeoCircle; + +QGeoCoordinate parseCoordinate(const QJSValue &value, bool *ok); +QGeoRectangle parseRectangle(const QJSValue &value, bool *ok); +QGeoCircle parseCircle(const QJSValue &value, bool *ok); class LocationValueTypeProvider : public QQmlValueTypeProvider { @@ -54,22 +60,105 @@ public: LocationValueTypeProvider(); private: + template<typename T> + bool typedCreate(QQmlValueType *&v) + { + v = new T; + return true; + } + bool create(int type, QQmlValueType *&v) Q_DECL_OVERRIDE; - bool init(int type, void *data, size_t n) Q_DECL_OVERRIDE; - bool destroy(int type, void *data, size_t n) Q_DECL_OVERRIDE; - bool copy(int type, const void *src, void *dst, size_t n) Q_DECL_OVERRIDE; + template<typename T> + bool typedInit(void *data, size_t dataSize) + { + Q_ASSERT(dataSize >= sizeof(T)); + T *t = reinterpret_cast<T *>(data); + new (t) T(); + return true; + } + + bool init(int type, void *data, size_t dataSize) Q_DECL_OVERRIDE; + + template<typename T> + bool typedDestroy(void *data, size_t dataSize) + { + Q_ASSERT(dataSize >= sizeof(T)); + T *t = reinterpret_cast<T *>(data); + t->~T(); + return true; + } + + bool destroy(int type, void *data, size_t dataSize) Q_DECL_OVERRIDE; + + template<typename T> + bool typedCopyConstruct(const void *src, void *dst, size_t dstSize) + { + Q_ASSERT(dstSize >= sizeof(T)); + const T *srcT = reinterpret_cast<const T *>(src); + T *dstT = reinterpret_cast<T *>(dst); + new (dstT) T(*srcT); + return true; + } + + bool copy(int type, const void *src, void *dst, size_t dstSize) Q_DECL_OVERRIDE; bool create(int type, int argc, const void *argv[], QVariant *v) Q_DECL_OVERRIDE; - bool createFromString(int type, const QString &s, void *data, size_t n) Q_DECL_OVERRIDE; + bool createFromString(int type, const QString &s, void *data, size_t dataSize) Q_DECL_OVERRIDE; bool createStringFrom(int type, const void *data, QString *s) Q_DECL_OVERRIDE; bool variantFromJsObject(int type, QQmlV8Handle h, QV8Engine *e, QVariant *v) Q_DECL_OVERRIDE; - bool equal(int type, const void *lhs, const void *rhs, size_t n) Q_DECL_OVERRIDE; - bool store(int type, const void *src, void *dst, size_t n) Q_DECL_OVERRIDE; - bool read(int srcType, const void *src, size_t n, int dstType, void *dst) Q_DECL_OVERRIDE; - bool write(int type, const void *src, void *dst, size_t n) Q_DECL_OVERRIDE; + template<typename T> + bool typedEqual(const void *lhs, const void *rhs) + { + return *reinterpret_cast<const T *>(lhs) == *reinterpret_cast<const T *>(rhs); + } + + bool equal(int type, const void *lhs, const void *rhs, size_t rhsSize) Q_DECL_OVERRIDE; + + template<typename T> + bool typedStore(const void *src, void *dst, size_t dstSize) + { + Q_ASSERT(dstSize >= sizeof(T)); + const T *srcT = reinterpret_cast<const T *>(src); + T *dstT = reinterpret_cast<T *>(dst); + new (dstT) T(*srcT); + return true; + } + + bool store(int type, const void *src, void *dst, size_t dstSize) Q_DECL_OVERRIDE; + + template<typename T> + bool typedRead(int srcType, const void *src, size_t srcSize, int dstType, void *dst) + { + T *dstT = reinterpret_cast<T *>(dst); + if (srcType == dstType) { + Q_ASSERT(srcSize >= sizeof(T)); + const T *srcT = reinterpret_cast<const T *>(src); + *dstT = *srcT; + } else { + *dstT = T(); + } + return true; + } + + bool read(int srcType, const void *src, size_t srcSize, int dstType, void *dst) Q_DECL_OVERRIDE; + + template<typename T> + bool typedWrite(const void *src, void *dst, size_t dstSize) + { + Q_ASSERT(dstSize >= sizeof(T)); + const T *srcT = reinterpret_cast<const T *>(src); + T *dstT = reinterpret_cast<T *>(dst); + if (*dstT != *srcT) { + *dstT = *srcT; + return true; + } + return false; + } + + bool write(int type, const void *src, void *dst, size_t dstSize) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/imports/location/qdeclarativecoordinate.cpp b/src/imports/location/qdeclarativecoordinate.cpp index 2987a6ce..64246ae5 100644 --- a/src/imports/location/qdeclarativecoordinate.cpp +++ b/src/imports/location/qdeclarativecoordinate.cpp @@ -221,6 +221,14 @@ QString CoordinateValueType::toString() const .arg(v.latitude()).arg(v.longitude()).arg(v.altitude()); } +bool CoordinateValueType::isEqual(const QVariant &other) const +{ + if (other.userType() != qMetaTypeId<QGeoCoordinate>()) + return false; + + return v == other.value<QGeoCoordinate>(); +} + /* Returns the distance (in meters) from this coordinate to the coordinate specified by other. Altitude is not used in the calculation. diff --git a/src/imports/location/qdeclarativecoordinate_p.h b/src/imports/location/qdeclarativecoordinate_p.h index f598dfb7..5c3e5dc5 100644 --- a/src/imports/location/qdeclarativecoordinate_p.h +++ b/src/imports/location/qdeclarativecoordinate_p.h @@ -77,6 +77,7 @@ public: bool isValid() const; QString toString() const Q_DECL_OVERRIDE; + bool isEqual(const QVariant &other) const Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/imports/location/qdeclarativegeocircle.cpp b/src/imports/location/qdeclarativegeocircle.cpp index 568c9598..4312074b 100644 --- a/src/imports/location/qdeclarativegeocircle.cpp +++ b/src/imports/location/qdeclarativegeocircle.cpp @@ -39,140 +39,146 @@ ** ***************************************************************************/ -#include <qnumeric.h> #include "qdeclarativegeocircle.h" +#include <QtCore/qnumeric.h> +#include <QtLocation/QGeoCircle> + +#include <QtCore/QDebug> + QT_BEGIN_NAMESPACE /*! - \qmltype GeoCircle - \instantiates QDeclarativeGeoCircle + \qmlbasictype geocircle \inqmlmodule QtLocation 5.0 \ingroup qml-QtLocation5-positioning \since Qt Location 5.0 - \brief The GeoCircle type represents a circular geographic area. + \brief The geocircle type represents a circular geographic area. - The circle is defined in terms of a \l {QtLocation5::coordinate}{coordinate} which specifies - the center of the circle and a qreal which specifies the radius of the circle in meters. + The \c geocircle type is a \l {QtLocation5::geoshape}{geoshape} that represents a circular + geographic area. It is defined in terms of a \l {QtLocation5::coordinate}{coordinate} which + specifies the \c center of the circle and a qreal which specifies the \c radius of the circle + in meters. - The circle is considered invalid if the center coordinate is invalid - or if the radius is less than zero. + The circle is considered invalid if the center coordinate is invalid or if the radius is less + than zero. \section2 Example Usage - The following code snippet shows the declaration of a GeoCircle object. + Use properties of type \l variant to store a \c {geocircle}. To create a \c geocircle value, + use the \l {QtLocation5::QtLocation}{QtLocation.circle()} function: - \code - GeoCircle { - radius: 25.0 - center { - latitude: 23.34 - longitude: 44.4 - } - } - \endcode + \qml + import QtLocation 5.0 - This could then be used, for example, as a region to scan for landmarks, - or refining searches. + Item { + property variant region: QtLocation.circle(QtLocation.coordinate(-27.5, 153.1), 1000) + } + \endqml - \sa QGeoCircle + When integrating with C++, note that any QGeoCircle value passed into QML from C++ is + automatically converted into a \c geocircle value, and vise-versa. */ -QDeclarativeGeoCircle::QDeclarativeGeoCircle(QObject *parent) -: QDeclarativeGeoShape(parent) +GeoCircleValueType::GeoCircleValueType(QObject *parent) +: GeoShapeValueType(qMetaTypeId<QGeoCircle>(), parent) { } -QDeclarativeGeoCircle::QDeclarativeGeoCircle(const QGeoCircle &circle, QObject *parent) -: QDeclarativeGeoShape(parent), m_circle(circle) +GeoCircleValueType::~GeoCircleValueType() { } -/*! - \qmlproperty QGeoCircle GeoCircle::circle - - For details on how to use this property to interface between C++ and QML see - "\l {location-cpp-qml.html#geocircle}{Interfaces between C++ and QML Code}". +/* + This property holds the coordinate of the center of the geocircle. */ -void QDeclarativeGeoCircle::setCircle(const QGeoCircle &circle) +QGeoCoordinate GeoCircleValueType::center() { - if (m_circle == circle) - return; - - QGeoCircle oldCircle = m_circle; - m_circle = circle; - - if (oldCircle.center() != m_circle.center()) - emit centerChanged(); - if (oldCircle.radius() != m_circle.radius()) - emit radiusChanged(); + return QGeoCircle(v).center(); } -QGeoCircle QDeclarativeGeoCircle::circle() const +void GeoCircleValueType::setCenter(const QGeoCoordinate &coordinate) { - return m_circle; -} + QGeoCircle c = v; -/*! - \internal -*/ -QGeoShape QDeclarativeGeoCircle::shape() const -{ - return circle(); + if (c.center() == coordinate) + return; + + c.setCenter(coordinate); + v = c; } /*! - \qmlmethod bool QDeclarativeGeoCircle::contains(coordinate coordinate) + This property holds the radius of the geocircle in meters. - Returns the true if \a coordinate is within the bounding circle; otherwise returns false. + The default value for the radius is -1 indicating an invalid geocircle area. */ -bool QDeclarativeGeoCircle::contains(const QGeoCoordinate &coordinate) +qreal GeoCircleValueType::radius() const { - return m_circle.contains(coordinate); + return QGeoCircle(v).radius(); } -/*! - \qmlproperty coordinate GeoCircle::center +void GeoCircleValueType::setRadius(qreal radius) +{ + QGeoCircle c = v; - This property holds the coordinate of the center of the bounding circle. + if (c.radius() == radius) + return; - \note this property's changed() signal is currently emitted only if the - whole object changes, not if only the contents of the object change. -*/ -QGeoCoordinate QDeclarativeGeoCircle::center() -{ - return m_circle.center(); + c.setRadius(radius); + v = c; } -void QDeclarativeGeoCircle::setCenter(const QGeoCoordinate &coordinate) +QString GeoCircleValueType::toString() const { - if (m_circle.center() == coordinate) - return; + if (v.type() != QGeoShape::CircleType) { + qWarning("Not a circle"); + return QStringLiteral("QGeoCircle(not a circle)"); + } - m_circle.setCenter(coordinate); - emit centerChanged(); + QGeoCircle c = v; + return QStringLiteral("QGeoCircle({%1, %2}, %3)") + .arg(c.center().latitude()) + .arg(c.center().longitude()) + .arg(c.radius()); } -/*! - \qmlproperty real GeoCircle::radius - - This property holds the radius of the bounding circle in meters. +void GeoCircleValueType::setValue(const QVariant &value) +{ + if (value.userType() == qMetaTypeId<QGeoCircle>()) + v = value.value<QGeoCircle>(); + else if (value.userType() == qMetaTypeId<QGeoShape>()) + v = value.value<QGeoShape>(); + else + v = QGeoCircle(); + + onLoad(); +} - The default value for the radius is -1 indicating an invalid bounding circle area. -*/ -qreal QDeclarativeGeoCircle::radius() const +QVariant GeoCircleValueType::value() { - return m_circle.radius(); + return QVariant::fromValue(QGeoCircle(v)); } -void QDeclarativeGeoCircle::setRadius(qreal radius) +void GeoCircleValueType::write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags) { - if (m_circle.radius() == radius) - return; + QGeoCircle c = v; + writeProperty(obj, idx, flags, &c); +} - m_circle.setRadius(radius); - emit radiusChanged(); +void GeoCircleValueType::writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from) +{ + if (from->userType() == qMetaTypeId<QGeoCircle>()) { + writeProperty(obj, idx, flags, from); + } else if (from->userType() == qMetaTypeId<QGeoShape>()) { + QGeoCircle c = from->value<QGeoShape>(); + QVariant v = QVariant::fromValue(c); + writeProperty(obj, idx, flags, &v); + } else { + QVariant v = QVariant::fromValue(QGeoCircle()); + writeProperty(obj, idx, flags, &v); + } } #include "moc_qdeclarativegeocircle.cpp" diff --git a/src/imports/location/qdeclarativegeocircle.h b/src/imports/location/qdeclarativegeocircle.h index 5a628147..5d0d6fe4 100644 --- a/src/imports/location/qdeclarativegeocircle.h +++ b/src/imports/location/qdeclarativegeocircle.h @@ -43,29 +43,19 @@ #define QDECLARATIVEGEOCIRCLE_H #include "qdeclarativegeoshape.h" -#include "qdeclarativecoordinate_p.h" - -#include <QtQml/qqml.h> -#include <QtLocation/QGeoCircle> QT_BEGIN_NAMESPACE -class QDeclarativeGeoCircle : public QDeclarativeGeoShape +class GeoCircleValueType : public GeoShapeValueType { Q_OBJECT - Q_PROPERTY(QGeoCircle circle READ circle WRITE setCircle) - Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged) - Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged) + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter) + Q_PROPERTY(qreal radius READ radius WRITE setRadius) public: - explicit QDeclarativeGeoCircle(QObject *parent = 0); - explicit QDeclarativeGeoCircle(const QGeoCircle &circle, QObject *parent = 0); - void setCircle(const QGeoCircle &circle); - QGeoCircle circle() const; - QGeoShape shape() const; - - Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate); + explicit GeoCircleValueType(QObject *parent = 0); + ~GeoCircleValueType(); QGeoCoordinate center(); void setCenter(const QGeoCoordinate &coordinate); @@ -73,16 +63,13 @@ public: qreal radius() const; void setRadius(qreal radius); -Q_SIGNALS: - void centerChanged(); - void radiusChanged(); - -private: - QGeoCircle m_circle; + QString toString() const Q_DECL_OVERRIDE; + void setValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant value() Q_DECL_OVERRIDE; + void write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags) Q_DECL_OVERRIDE; + void writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags, QVariant *from) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QDeclarativeGeoCircle) - #endif diff --git a/src/imports/location/qdeclarativegeocodemodel.cpp b/src/imports/location/qdeclarativegeocodemodel.cpp index 761f43ba..87eb7522 100644 --- a/src/imports/location/qdeclarativegeocodemodel.cpp +++ b/src/imports/location/qdeclarativegeocodemodel.cpp @@ -44,9 +44,9 @@ #include "qdeclarativegeolocation_p.h" #include <QtQml/qqmlinfo.h> - -#include <qgeoserviceprovider.h> -#include <qgeocodingmanager.h> +#include <QtLocation/QGeoServiceProvider> +#include <QtLocation/QGeocodingManager> +#include <QtLocation/QGeoCircle> QT_BEGIN_NAMESPACE @@ -109,17 +109,9 @@ QT_BEGIN_NAMESPACE */ QDeclarativeGeocodeModel::QDeclarativeGeocodeModel(QObject *parent) - : QAbstractListModel(parent), - autoUpdate_(false), - complete_(false), - reply_(0), - plugin_(0), - boundingArea_(0), - status_(QDeclarativeGeocodeModel::Null), - error_(QDeclarativeGeocodeModel::NoError), - address_(0), - limit_(-1), - offset_(0) +: QAbstractListModel(parent), autoUpdate_(false), complete_(false), reply_(0), plugin_(0), + status_(QDeclarativeGeocodeModel::Null), error_(QDeclarativeGeocodeModel::NoError), + address_(0), limit_(-1), offset_(0) { } @@ -142,19 +134,6 @@ void QDeclarativeGeocodeModel::componentComplete() } /*! - \internal -*/ -QGeoShape QDeclarativeGeocodeModel::boundingArea() -{ - if (qobject_cast<QDeclarativeGeoRectangle *>(boundingArea_) && boundingBox_.isValid()) { - return boundingBox_; - } else if (qobject_cast<QDeclarativeGeoCircle *>(boundingArea_) && boundingCircle_.isValid()) { - return boundingCircle_; - } - return QGeoShape(); -} - -/*! \qmlmethod QtLocation5::GeocodeModel::update() Instructs the GeocodeModel to update its data. This is most useful @@ -191,7 +170,7 @@ void QDeclarativeGeocodeModel::update() if (coordinate_.isValid()) { setStatus(QDeclarativeGeocodeModel::Loading); - reply_ = geocodingManager->reverseGeocode(coordinate_, boundingArea()); + reply_ = geocodingManager->reverseGeocode(coordinate_, boundingArea_); if (reply_->isFinished()) { if (reply_->error() == QGeocodeReply::NoError) { geocodeFinished(reply_); @@ -201,7 +180,7 @@ void QDeclarativeGeocodeModel::update() } } else if (address_) { setStatus(QDeclarativeGeocodeModel::Loading); - reply_ = geocodingManager->geocode(address_->address(), boundingArea()); + reply_ = geocodingManager->geocode(address_->address(), boundingArea_); if (reply_->isFinished()) { if (reply_->error() == QGeocodeReply::NoError) { geocodeFinished(reply_); @@ -211,7 +190,7 @@ void QDeclarativeGeocodeModel::update() } } else if (!searchString_.isEmpty()) { setStatus(QDeclarativeGeocodeModel::Loading); - reply_ = geocodingManager->geocode(searchString_, limit_, offset_, boundingArea()); + reply_ = geocodingManager->geocode(searchString_, limit_, offset_, boundingArea_); if (reply_->isFinished()) { if (reply_->error() == QGeocodeReply::NoError) { geocodeFinished(reply_); @@ -333,19 +312,22 @@ QDeclarativeGeoServiceProvider *QDeclarativeGeocodeModel::plugin() const return plugin_; } -void QDeclarativeGeocodeModel::setBounds(QObject *bounds) +void QDeclarativeGeocodeModel::setBounds(const QVariant &boundingArea) { - if (boundingArea_ == bounds) - return; - if (qobject_cast<QDeclarativeGeoRectangle *>(bounds)) { - boundingBox_ = qobject_cast<QDeclarativeGeoRectangle *>(bounds)->rectangle(); - } else if (qobject_cast<QDeclarativeGeoCircle *>(bounds)) { - boundingCircle_ = qobject_cast<QDeclarativeGeoCircle *>(bounds)->circle(); - } else { - qmlInfo(this) << QCoreApplication::translate(CONTEXT_NAME, UNSUPPORTED_BOUND_TYPE); + QGeoShape s; + + if (boundingArea.userType() == qMetaTypeId<QGeoRectangle>()) + s = boundingArea.value<QGeoRectangle>(); + else if (boundingArea.userType() == qMetaTypeId<QGeoCircle>()) + s = boundingArea.value<QGeoCircle>(); + else if (boundingArea.userType() == qMetaTypeId<QGeoShape>()) + s = boundingArea.value<QGeoShape>(); + + + if (boundingArea_ == s) return; - } - boundingArea_ = bounds; + + boundingArea_ = s; emit boundsChanged(); } @@ -356,13 +338,17 @@ void QDeclarativeGeocodeModel::setBounds(QObject *bounds) within the area. his is particularly useful if query is only partially filled out, as the service will attempt to (reverse) geocode all matches for the specified data. - Accepted types are \l BoundingBox and \l BoundingCircle. - + Accepted types are \l {QtLocation5::georectangle}{georectangle} and + \l {QtLocation5::geocircle}{geocircle}. */ - -QObject *QDeclarativeGeocodeModel::bounds() const -{ - return boundingArea_; +QVariant QDeclarativeGeocodeModel::bounds() const +{ + if (boundingArea_.type() == QGeoShape::RectangleType) + return QVariant::fromValue(QGeoRectangle(boundingArea_)); + else if (boundingArea_.type() == QGeoShape::CircleType) + return QVariant::fromValue(QGeoCircle(boundingArea_)); + else + return QVariant::fromValue(boundingArea_); } void QDeclarativeGeocodeModel::geocodeFinished(QGeocodeReply *reply) diff --git a/src/imports/location/qdeclarativegeocodemodel_p.h b/src/imports/location/qdeclarativegeocodemodel_p.h index 15e712e3..ccc3a4e0 100644 --- a/src/imports/location/qdeclarativegeocodemodel_p.h +++ b/src/imports/location/qdeclarativegeocodemodel_p.h @@ -73,7 +73,7 @@ class QDeclarativeGeocodeModel : public QAbstractListModel, public QQmlParserSta Q_PROPERTY(int limit READ limit WRITE setLimit NOTIFY limitChanged) Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged) Q_PROPERTY(QVariant query READ query WRITE setQuery NOTIFY queryChanged) - Q_PROPERTY(QObject *bounds READ bounds WRITE setBounds NOTIFY boundsChanged) + Q_PROPERTY(QVariant bounds READ bounds WRITE setBounds NOTIFY boundsChanged) Q_PROPERTY(GeocodeError error READ error NOTIFY errorChanged) Q_INTERFACES(QQmlParserStatus) @@ -114,8 +114,8 @@ public: void setPlugin(QDeclarativeGeoServiceProvider *plugin); QDeclarativeGeoServiceProvider *plugin() const; - void setBounds(QObject *bounds); - QObject *bounds() const; + void setBounds(const QVariant &boundingArea); + QVariant bounds() const; Status status() const; QString errorString() const; @@ -171,14 +171,11 @@ protected: private: void setLocations(const QList<QGeoLocation> &locations); - QGeoShape boundingArea(); void abortRequest(); QGeocodeReply *reply_; QDeclarativeGeoServiceProvider *plugin_; - QPointer<QObject> boundingArea_; - QGeoRectangle boundingBox_; - QGeoCircle boundingCircle_; + QGeoShape boundingArea_; QList<QDeclarativeGeoLocation *> declarativeLocations_; diff --git a/src/imports/location/qdeclarativegeolocation.cpp b/src/imports/location/qdeclarativegeolocation.cpp index 0ae3836e..ea0decce 100644 --- a/src/imports/location/qdeclarativegeolocation.cpp +++ b/src/imports/location/qdeclarativegeolocation.cpp @@ -79,14 +79,14 @@ QT_USE_NAMESPACE */ QDeclarativeGeoLocation::QDeclarativeGeoLocation(QObject *parent) -: QObject(parent), m_address(0), m_boundingBox(0) +: QObject(parent), m_address(0) { setLocation(QGeoLocation()); } QDeclarativeGeoLocation::QDeclarativeGeoLocation(const QGeoLocation &src, QObject *parent) -: QObject(parent), m_address(0), m_boundingBox(0) +: QObject(parent), m_address(0) { setLocation(src); } @@ -110,25 +110,16 @@ void QDeclarativeGeoLocation::setLocation(const QGeoLocation &src) emit addressChanged(); } - if (m_coordinate != src.coordinate()) { - m_coordinate = src.coordinate(); - emit coordinateChanged(); - } - - if (m_boundingBox && m_boundingBox->parent() == this) { - m_boundingBox->setRectangle(src.boundingBox()); - } else if (!m_boundingBox || m_boundingBox->parent() != this) { - m_boundingBox = new QDeclarativeGeoRectangle(src.boundingBox(), this); - emit boundingBoxChanged(); - } + setCoordinate(src.coordinate()); + setBoundingBox(src.boundingBox()); } -QGeoLocation QDeclarativeGeoLocation::location() +QGeoLocation QDeclarativeGeoLocation::location() const { QGeoLocation retValue; retValue.setAddress(m_address ? m_address->address() : QGeoAddress()); retValue.setCoordinate(m_coordinate); - retValue.setBoundingBox(m_boundingBox ? m_boundingBox->rectangle() : QGeoRectangle()); + retValue.setBoundingBox(m_boundingBox); return retValue; } @@ -149,7 +140,7 @@ void QDeclarativeGeoLocation::setAddress(QDeclarativeGeoAddress *address) emit addressChanged(); } -QDeclarativeGeoAddress *QDeclarativeGeoLocation::address() +QDeclarativeGeoAddress *QDeclarativeGeoLocation::address() const { return m_address; } @@ -171,7 +162,7 @@ void QDeclarativeGeoLocation::setCoordinate(const QGeoCoordinate coordinate) emit coordinateChanged(); } -QGeoCoordinate QDeclarativeGeoLocation::coordinate() +QGeoCoordinate QDeclarativeGeoLocation::coordinate() const { return m_coordinate; } @@ -187,19 +178,16 @@ QGeoCoordinate QDeclarativeGeoLocation::coordinate() Note: this property's changed() signal is currently emitted only if the whole object changes, not if only the contents of the object change. */ -void QDeclarativeGeoLocation::setBoundingBox(QDeclarativeGeoRectangle *boundingBox) +void QDeclarativeGeoLocation::setBoundingBox(const QGeoRectangle &boundingBox) { if (m_boundingBox == boundingBox) return; - if (m_boundingBox && m_boundingBox->parent() == this) - delete m_boundingBox; - m_boundingBox = boundingBox; emit boundingBoxChanged(); } -QDeclarativeGeoRectangle *QDeclarativeGeoLocation::boundingBox() +QGeoRectangle QDeclarativeGeoLocation::boundingBox() const { return m_boundingBox; } diff --git a/src/imports/location/qdeclarativegeolocation_p.h b/src/imports/location/qdeclarativegeolocation_p.h index 9d39ef42..253b49c3 100644 --- a/src/imports/location/qdeclarativegeolocation_p.h +++ b/src/imports/location/qdeclarativegeolocation_p.h @@ -42,12 +42,12 @@ #ifndef QDECLARATIVEGEOLOCATION_P_H #define QDECLARATIVEGEOLOCATION_P_H +#include "qdeclarativegeoaddress_p.h" + #include <QtCore/QObject> #include <QtQml/QQmlListProperty> #include <QtLocation/QGeoLocation> -#include "qdeclarativecoordinate_p.h" -#include "qdeclarativegeorectangle.h" -#include "qdeclarativegeoaddress_p.h" +#include <QtLocation/QGeoRectangle> QT_BEGIN_NAMESPACE @@ -58,23 +58,23 @@ class QDeclarativeGeoLocation : public QObject Q_PROPERTY(QGeoLocation location READ location WRITE setLocation) Q_PROPERTY(QDeclarativeGeoAddress *address READ address WRITE setAddress NOTIFY addressChanged) Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged) - Q_PROPERTY(QDeclarativeGeoRectangle *boundingBox READ boundingBox WRITE setBoundingBox NOTIFY boundingBoxChanged) + Q_PROPERTY(QGeoRectangle boundingBox READ boundingBox WRITE setBoundingBox NOTIFY boundingBoxChanged) public: explicit QDeclarativeGeoLocation(QObject *parent = 0); explicit QDeclarativeGeoLocation(const QGeoLocation &src, QObject *parent = 0); ~QDeclarativeGeoLocation(); - QGeoLocation location() ; + QGeoLocation location() const; void setLocation(const QGeoLocation &src); - QDeclarativeGeoAddress *address(); + QDeclarativeGeoAddress *address() const; void setAddress(QDeclarativeGeoAddress *address); - QGeoCoordinate coordinate(); + QGeoCoordinate coordinate() const; void setCoordinate(const QGeoCoordinate coordinate); - QDeclarativeGeoRectangle *boundingBox(); - void setBoundingBox(QDeclarativeGeoRectangle *boundingBox); + QGeoRectangle boundingBox() const; + void setBoundingBox(const QGeoRectangle &boundingBox); Q_SIGNALS: void addressChanged(); @@ -83,7 +83,7 @@ Q_SIGNALS: private: QDeclarativeGeoAddress *m_address; - QDeclarativeGeoRectangle *m_boundingBox; + QGeoRectangle m_boundingBox; QGeoCoordinate m_coordinate; }; diff --git a/src/imports/location/qdeclarativegeorectangle.cpp b/src/imports/location/qdeclarativegeorectangle.cpp index 0cc75e36..64b0e41d 100644 --- a/src/imports/location/qdeclarativegeorectangle.cpp +++ b/src/imports/location/qdeclarativegeorectangle.cpp @@ -39,290 +39,255 @@ ** ***************************************************************************/ -#include <qnumeric.h> #include "qdeclarativegeorectangle.h" +#include <QtCore/qnumeric.h> +#include <QtLocation/QGeoRectangle> + +#include <QtCore/QDebug> + QT_BEGIN_NAMESPACE /*! - \qmltype GeoRectangle - \instantiates QDeclarativeGeoRectangle + \qmlbasictype georectangle \inqmlmodule QtLocation 5.0 \ingroup qml-QtLocation5-positioning \since Qt Location 5.0 - \brief The GeoRectangle type represents a rectangular geographic area. + \brief The georectangle type represents a rectangular geographic area. - A GeoRectangle is described by a \l {QtLocation5::coordinate}{coordinate} which represents the - top-left of the GeoRectangle and a second \l {QtLocation5::coordinate}{coordinate} which - represents the bottom-right of GeoRectangle. + The \c georectangle type is a \l {QtLocation5::geoshape}{geoshape} that represents a + rectangular geographic area. It is defined by a pair of + \l {QtLocation5::coordinate}{coordinates} which represent the top-left and bottom-right corners + of the \c {georectangle}. The coordinates are accessible from the \c topLeft and + \c bottomRight attributes. - A GeoRectangle is considered invalid if the top-left or bottom-right - coordinates are invalid or if the top-left coordinate is South of the - bottom-right coordinate. + A \c georectangle is considered invalid if the top-left or bottom-right coordinates are invalid + or if the top-left coordinate is South of the bottom-right coordinate. - GeoRectangles can never cross the poles. + The coordinates of the four corners of the \c georectangle can be accessed with the + \c {topLeft}, \c {topRight}, \c {bottomLeft} and \c {bottomRight} attributes. The \c center + attribute can be used to get the coordinate of the center of the \c georectangle. The \c width + and \c height attributes can be used to get the width and height of the \c georectangle in + degrees. Setting one of these attributes will cause the other attributes to be adjusted + accordingly. - If the height or center of a geo rectangle is adjusted such that it would - cross one of the poles the height is modified such that the geo rectangle - touches but does not cross the pole and that the center coordinate is still - in the center of the geo rectangle. + \section2 Limitations - \section2 Example Usage + A \c georectangle can never cross the poles. - The following code snippet shows the declaration of a GeoRectangle object. - - \code - GeoRectangle { - topLeft { - latitude: 23.34 - longitude: 44.4 - } - bottomRight { - latitude: 22.25 - longitude: 42.88 - } - } - \endcode + If the height or center of a \c georectangle is adjusted such that it would cross one of the + poles the height is modified such that the \c georectangle touches but does not cross the pole + and that the center coordinate is still in the center of the \c georectangle. - This could then be used, for example, as a region to search for places. + \section2 Example Usage - \sa QGeoRectangle -*/ + Use properties of type \l variant to store a \c {georectangle}. To create a \c georectangle + value, use the \l {QtLocation5::QtLocation}{QtLocation.rectangle()} function: -QDeclarativeGeoRectangle::QDeclarativeGeoRectangle(QObject *parent) -: QDeclarativeGeoShape(parent), m_width(qQNaN()), m_height(qQNaN()) -{ -} + \qml + import QtLocation 5.0 -QDeclarativeGeoRectangle::QDeclarativeGeoRectangle(const QGeoRectangle &box, QObject *parent) -: QDeclarativeGeoShape(parent), m_box(box), m_width(qQNaN()), m_height(qQNaN()) -{ - emitChanged(box); -} - -/*! - \qmlproperty QGeoRectangle GeoRectangle::rectangle + Item { + property variant region: QtLocation.rectangle(QtLocation.coordinate(-27.5, 153.1), QtLocation.coordinate(-27.6, 153.2)) + } + \endqml - For details on how to use this property to interface between C++ and QML see - "\l {location-cpp-qml.html#georectangle}{Interfaces between C++ and QML Code}". + When integrating with C++, note that any QGeoRectangle value passed into QML from C++ is + automatically converted into a \c georectangle value, and vice-versa. */ -void QDeclarativeGeoRectangle::setRectangle(const QGeoRectangle &box) + +GeoRectangleValueType::GeoRectangleValueType(QObject *parent) +: GeoShapeValueType(qMetaTypeId<QGeoRectangle>(), parent) { - QGeoRectangle oldBox = m_box; - m_box = box; - emitChanged(oldBox); } -QGeoRectangle QDeclarativeGeoRectangle::rectangle() const +GeoRectangleValueType::~GeoRectangleValueType() { - return m_box; } -QGeoShape QDeclarativeGeoRectangle::shape() const +QGeoCoordinate GeoRectangleValueType::bottomLeft() { - return m_box; + return QGeoRectangle(v).bottomLeft(); } -/*! - \qmlmethod bool QDeclarativeGeoRectangle::contains(coordinate coordinate) - - Returns the true if \a coordinate is within the geo rectangle; otherwise returns false. +/* + This property holds the bottom left coordinate of this georectangle. */ -bool QDeclarativeGeoRectangle::contains(const QGeoCoordinate &coordinate) +void GeoRectangleValueType::setBottomLeft(const QGeoCoordinate &coordinate) { - return m_box.contains(coordinate); + QGeoRectangle r = v; + + if (r.bottomLeft() == coordinate) + return; + + r.setBottomLeft(coordinate); + v = r; } -QGeoCoordinate QDeclarativeGeoRectangle::bottomLeft() +QGeoCoordinate GeoRectangleValueType::bottomRight() { - return m_box.bottomLeft(); + return QGeoRectangle(v).bottomRight(); } -/*! - \qmlproperty coordinate GeoRectangle::bottomLeft - - This property holds the bottom left coordinate of this geo rectangle. - - \sa {QGeoRectangle} +/* + This property holds the bottom right coordinate of this georectangle. */ -void QDeclarativeGeoRectangle::setBottomLeft(const QGeoCoordinate &coordinate) +void GeoRectangleValueType::setBottomRight(const QGeoCoordinate &coordinate) { - if (m_box.bottomLeft() == coordinate) + QGeoRectangle r = v; + + if (r.bottomRight() == coordinate) return; - QGeoRectangle old = m_box; - m_box.setBottomLeft(coordinate); - emitChanged(old); + r.setBottomRight(coordinate); + v = r; } -QGeoCoordinate QDeclarativeGeoRectangle::bottomRight() +QGeoCoordinate GeoRectangleValueType::topLeft() { - return m_box.bottomRight(); + return QGeoRectangle(v).topLeft(); } -/*! - \qmlproperty coordinate GeoRectangle::bottomRight - - This property holds the bottom right coordinate of this geo rectangle. - - \sa {QGeoRectangle} +/* + This property holds the top left coordinate of this georectangle. */ -void QDeclarativeGeoRectangle::setBottomRight(const QGeoCoordinate &coordinate) +void GeoRectangleValueType::setTopLeft(const QGeoCoordinate &coordinate) { - if (m_box.bottomRight() == coordinate) + QGeoRectangle r = v; + + if (r.topLeft() == coordinate) return; - QGeoRectangle old = m_box; - m_box.setBottomRight(coordinate); - emitChanged(old); + r.setTopLeft(coordinate); + v = r; } -QGeoCoordinate QDeclarativeGeoRectangle::topLeft() +QGeoCoordinate GeoRectangleValueType::topRight() { - return m_box.topLeft(); + return QGeoRectangle(v).topRight(); } -/*! - \qmlproperty coordinate GeoRectangle::topLeft - - This property holds the top left coordinate of this geo rectangle. - - \sa {QGeoRectangle} +/* + This property holds the top right coordinate of this georectangle. */ -void QDeclarativeGeoRectangle::setTopLeft(const QGeoCoordinate &coordinate) +void GeoRectangleValueType::setTopRight(QGeoCoordinate &coordinate) { - if (m_box.topLeft() == coordinate) + QGeoRectangle r = v; + + if (r.topRight() == coordinate) return; - QGeoRectangle old = m_box; - m_box.setTopLeft(coordinate); - emitChanged(old); + r.setTopRight(coordinate); + v = r; } -QGeoCoordinate QDeclarativeGeoRectangle::topRight() +QGeoCoordinate GeoRectangleValueType::center() { - return m_box.topRight(); + return QGeoRectangle(v).center(); } -/*! - \qmlproperty coordinate GeoRectangle::topRight - - This property holds the top right coordinate of this geo rectangle. - - \note this property's changed() signal is currently emitted only if the - whole type changes, not if only the contents of the type change. - - \sa {QGeoRectangle} - */ - -void QDeclarativeGeoRectangle::setTopRight(QGeoCoordinate &coordinate) +/* + This property holds the center coordinate of this georectangle. +*/ +void GeoRectangleValueType::setCenter(const QGeoCoordinate &coordinate) { - if (m_box.topRight() == coordinate) + QGeoRectangle r = v; + + if (r.center() == coordinate) return; - QGeoRectangle old = m_box; - m_box.setTopRight(coordinate); - emitChanged(old); + r.setCenter(coordinate); + v = r; } -QGeoCoordinate QDeclarativeGeoRectangle::center() +double GeoRectangleValueType::height() { - return m_box.center(); + return QGeoRectangle(v).height(); } -/*! - \qmlproperty coordinate GeoRectangle::center - - This property holds the center coordinate of this geo rectangle. - - \note this property's changed() signal is currently emitted only if the - whole object changes, not if only the contents of the object change. - - \sa {QGeoRectangle} - - */ - -void QDeclarativeGeoRectangle::setCenter(const QGeoCoordinate &coordinate) +/* + This property holds the height of this georectangle (in degrees). +*/ +void GeoRectangleValueType::setHeight(double height) { - if (m_box.center() == coordinate) - return; + QGeoRectangle r = v; + + if (!r.isValid()) + r.setCenter(QGeoCoordinate(0.0, 0.0)); - QGeoRectangle old = m_box; - m_box.setCenter(coordinate); - emitChanged(old); + r.setHeight(height); + v = r; } -double QDeclarativeGeoRectangle::height() +double GeoRectangleValueType::width() { - return m_height; + return QGeoRectangle(v).width(); } -/*! - \qmlproperty double GeoRectangle::height +/* + This property holds the width of this georectangle (in degrees). +*/ +void GeoRectangleValueType::setWidth(double width) +{ + QGeoRectangle r = v; - This property holds the height of this geo rectangle (in degrees). + if (!r.isValid()) + r.setCenter(QGeoCoordinate(0.0, 0.0)); - \sa {QGeoRectangle} - */ + r.setWidth(width); + v = r; +} -void QDeclarativeGeoRectangle::setHeight(double height) +QString GeoRectangleValueType::toString() const { - QGeoRectangle oldBox = m_box; - if (!m_box.isValid()) - m_box.setCenter(QGeoCoordinate(0.0, 0.0)); - m_box.setHeight(height); - emitChanged(oldBox); + if (v.type() != QGeoShape::RectangleType) { + qWarning("Not a rectangle a %d\n", v.type()); + return QStringLiteral("QGeoRectangle(not a rectangle)"); + } + + QGeoRectangle r = v; + return QStringLiteral("QGeoRectangle({%1, %2}, {%3, %4})") + .arg(r.topLeft().latitude()) + .arg(r.topLeft().longitude()) + .arg(r.bottomRight().latitude()) + .arg(r.bottomRight().longitude()); } -double QDeclarativeGeoRectangle::width() +void GeoRectangleValueType::setValue(const QVariant &value) { - return m_width; + if (value.userType() == qMetaTypeId<QGeoRectangle>()) + v = value.value<QGeoRectangle>(); + else if (value.userType() == qMetaTypeId<QGeoShape>()) + v = value.value<QGeoShape>(); + else + v = QGeoRectangle(); + + onLoad(); } -/*! - \qmlproperty double GeoRectangle::width - - This property holds the width of this geo rectangle (in degrees). - - \sa {QGeoRectangle} - - */ - -void QDeclarativeGeoRectangle::setWidth(double width) +QVariant GeoRectangleValueType::value() { - QGeoRectangle oldBox = m_box; - if (!m_box.isValid()) - m_box.setCenter(QGeoCoordinate(0.0, 0.0)); - m_box.setWidth(width); - emitChanged(oldBox); + return QVariant::fromValue(QGeoRectangle(v)); } -void QDeclarativeGeoRectangle::emitChanged(const QGeoRectangle &old) +void GeoRectangleValueType::write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags) { - if (old.bottomLeft() != m_box.bottomLeft()) - emit bottomLeftChanged(); - - if (old.bottomRight() != m_box.bottomRight()) - emit bottomRightChanged(); - - if (old.topLeft() != m_box.topLeft()) - emit topLeftChanged(); - - if (old.topRight() != m_box.topRight()) - emit topRightChanged(); - - if (old.center() != m_box.center()) - emit centerChanged(); + QGeoRectangle r = v; + writeProperty(obj, idx, flags, &r); +} - // Check not to compare two Not a Numbers, which by definition is 'false'. - if ((!qIsNaN(old.width()) || !qIsNaN(m_box.width())) && old.width() != m_box.width()) { - m_width = m_box.width(); - emit widthChanged(); - } - if ((!qIsNaN(old.height()) || !qIsNaN(m_box.height())) && old.height() != m_box.height()) { - m_height = m_box.height(); - emit heightChanged(); +void GeoRectangleValueType::writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from) +{ + if (from->userType() == qMetaTypeId<QGeoRectangle>()) { + writeProperty(obj, idx, flags, from); + } else if (from->userType() == qMetaTypeId<QGeoShape>()) { + QGeoRectangle r = from->value<QGeoShape>(); + QVariant v = QVariant::fromValue(r); + writeProperty(obj, idx, flags, &v); + } else { + QVariant v = QVariant::fromValue(QGeoRectangle()); + writeProperty(obj, idx, flags, &v); } } diff --git a/src/imports/location/qdeclarativegeorectangle.h b/src/imports/location/qdeclarativegeorectangle.h index edcc855e..aacd6e7c 100644 --- a/src/imports/location/qdeclarativegeorectangle.h +++ b/src/imports/location/qdeclarativegeorectangle.h @@ -43,34 +43,25 @@ #define QDECLARATIVEGEORECTANGLE_H #include "qdeclarativegeoshape.h" -#include "qdeclarativecoordinate_p.h" - -#include <QtQml/qqml.h> -#include <QtLocation/QGeoRectangle> QT_BEGIN_NAMESPACE -class QDeclarativeGeoRectangle : public QDeclarativeGeoShape +class GeoRectangleValueType : public GeoShapeValueType { Q_OBJECT - Q_PROPERTY(QGeoRectangle rectangle READ rectangle WRITE setRectangle) - Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft NOTIFY bottomLeftChanged) - Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight NOTIFY bottomRightChanged) - Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft NOTIFY topLeftChanged) - Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight NOTIFY topRightChanged) - Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged) - Q_PROPERTY(double height READ height WRITE setHeight NOTIFY heightChanged) - Q_PROPERTY(double width READ width WRITE setWidth NOTIFY widthChanged) + Q_PROPERTY(QGeoCoordinate bottomLeft READ bottomLeft WRITE setBottomLeft) + Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight) + Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft) + Q_PROPERTY(QGeoCoordinate topRight READ topRight WRITE setTopRight) + Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter) + Q_PROPERTY(double height READ height WRITE setHeight) + Q_PROPERTY(double width READ width WRITE setWidth) public: - explicit QDeclarativeGeoRectangle(QObject *parent = 0); - explicit QDeclarativeGeoRectangle(const QGeoRectangle &rectangle, QObject *parent = 0); - void setRectangle(const QGeoRectangle &rectangle); - QGeoRectangle rectangle() const; - QGeoShape shape() const; + explicit GeoRectangleValueType(QObject *parent = 0); + ~GeoRectangleValueType(); - Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate); QGeoCoordinate bottomLeft(); void setBottomLeft(const QGeoCoordinate &coordinate); QGeoCoordinate bottomRight(); @@ -86,25 +77,13 @@ public: double width(); void setWidth(double width); -Q_SIGNALS: - void bottomLeftChanged(); - void bottomRightChanged(); - void topLeftChanged(); - void topRightChanged(); - void centerChanged(); - void heightChanged(); - void widthChanged(); - -private: - void emitChanged(const QGeoRectangle &old); - - QGeoRectangle m_box; - double m_width; - double m_height; + QString toString() const Q_DECL_OVERRIDE; + void setValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant value() Q_DECL_OVERRIDE; + void write(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags) Q_DECL_OVERRIDE; + void writeVariantValue(QObject *obj, int idx, QQmlPropertyPrivate::WriteFlags flags, QVariant *from) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QDeclarativeGeoRectangle) - #endif diff --git a/src/imports/location/qdeclarativegeoroute.cpp b/src/imports/location/qdeclarativegeoroute.cpp index cab02f00..143089ff 100644 --- a/src/imports/location/qdeclarativegeoroute.cpp +++ b/src/imports/location/qdeclarativegeoroute.cpp @@ -46,6 +46,7 @@ #include <QtQml/QQmlContext> #include <QtQml/qqmlinfo.h> #include <QtQml/private/qqmlengine_p.h> +#include <QtLocation/QGeoRectangle> QT_BEGIN_NAMESPACE @@ -95,8 +96,6 @@ QDeclarativeGeoRoute::~QDeclarativeGeoRoute() {} void QDeclarativeGeoRoute::init() { - bounds_ = new QDeclarativeGeoRectangle(route_.bounds(), this); - QGeoRouteSegment segment = route_.firstRouteSegment(); while (segment.isValid()) { segments_.append(new QDeclarativeGeoRouteSegment(segment, this)); @@ -119,9 +118,9 @@ QList<QGeoCoordinate> QDeclarativeGeoRoute::routePath() */ -QDeclarativeGeoRectangle *QDeclarativeGeoRoute::bounds() const +QGeoRectangle QDeclarativeGeoRoute::bounds() const { - return bounds_; + return route_.bounds(); } /*! @@ -190,22 +189,10 @@ void QDeclarativeGeoRoute::setPath(const QJSValue &value) QList<QGeoCoordinate> pathList; quint32 length = value.property(QStringLiteral("length")).toUInt(); for (quint32 i = 0; i < length; ++i) { - QJSValue v = value.property(i); - - QGeoCoordinate c; - - if (v.isObject()) { - if (v.hasProperty(QStringLiteral("latitude"))) - c.setLatitude(v.property(QStringLiteral("latitude")).toNumber()); - if (v.hasProperty(QStringLiteral("longitude"))) - c.setLongitude(v.property(QStringLiteral("longitude")).toNumber()); - if (v.hasProperty(QStringLiteral("altitude"))) - c.setAltitude(v.property(QStringLiteral("altitude")).toNumber()); - } else if (v.isString()) { - c = stringToCoordinate(v.toString()).value<QGeoCoordinate>(); - } + bool ok; + QGeoCoordinate c = parseCoordinate(value.property(i), &ok); - if (!c.isValid()) { + if (!ok || !c.isValid()) { qmlInfo(this) << "Unsupported path type"; return; } diff --git a/src/imports/location/qdeclarativegeoroute_p.h b/src/imports/location/qdeclarativegeoroute_p.h index aed81351..558a64d7 100644 --- a/src/imports/location/qdeclarativegeoroute_p.h +++ b/src/imports/location/qdeclarativegeoroute_p.h @@ -42,8 +42,6 @@ #ifndef QDECLARATIVEGEOROUTE_H #define QDECLARATIVEGEOROUTE_H -#include "qdeclarativegeorectangle.h" -#include "qdeclarativecoordinate_p.h" #include "qdeclarativegeoroutesegment_p.h" #include <QtCore/QObject> @@ -56,7 +54,7 @@ class QDeclarativeGeoRoute : public QObject { Q_OBJECT - Q_PROPERTY(QDeclarativeGeoRectangle *bounds READ bounds CONSTANT) + Q_PROPERTY(QGeoRectangle bounds READ bounds CONSTANT) Q_PROPERTY(int travelTime READ travelTime CONSTANT) Q_PROPERTY(qreal distance READ distance CONSTANT) Q_PROPERTY(QJSValue path READ path WRITE setPath NOTIFY pathChanged) @@ -67,7 +65,7 @@ public: QDeclarativeGeoRoute(const QGeoRoute &route, QObject *parent = 0); ~QDeclarativeGeoRoute(); - QDeclarativeGeoRectangle *bounds() const; + QGeoRectangle bounds() const; int travelTime() const; qreal distance() const; @@ -92,7 +90,6 @@ private: QList<QGeoCoordinate> routePath(); QGeoRoute route_; - QDeclarativeGeoRectangle *bounds_; QList<QDeclarativeGeoRouteSegment *> segments_; friend class QDeclarativeRouteMapItem; }; diff --git a/src/imports/location/qdeclarativegeoroutemodel.cpp b/src/imports/location/qdeclarativegeoroutemodel.cpp index 6ae0563a..36045855 100644 --- a/src/imports/location/qdeclarativegeoroutemodel.cpp +++ b/src/imports/location/qdeclarativegeoroutemodel.cpp @@ -49,8 +49,8 @@ #include <QtQml/QQmlContext> #include <QtQml/qqmlinfo.h> #include <QtQml/private/qqmlengine_p.h> -#include <qgeoserviceprovider.h> -#include <qgeoroutingmanager.h> +#include <QtLocation/QGeoRoutingManager> +#include <QtLocation/QGeoRectangle> QT_BEGIN_NAMESPACE @@ -645,8 +645,6 @@ QDeclarativeGeoRouteQuery::QDeclarativeGeoRouteQuery(QObject *parent) QDeclarativeGeoRouteQuery::~QDeclarativeGeoRouteQuery() { - if (!exclusions_.isEmpty()) - exclusions_.clear(); } /*! @@ -756,22 +754,10 @@ void QDeclarativeGeoRouteQuery::setWaypoints(const QJSValue &value) QList<QGeoCoordinate> waypointList; quint32 length = value.property(QStringLiteral("length")).toUInt(); for (quint32 i = 0; i < length; ++i) { - QJSValue v = value.property(i); - - QGeoCoordinate c; - - if (v.isObject()) { - if (v.hasProperty(QStringLiteral("latitude"))) - c.setLatitude(v.property(QStringLiteral("latitude")).toNumber()); - if (v.hasProperty(QStringLiteral("longitude"))) - c.setLongitude(v.property(QStringLiteral("longitude")).toNumber()); - if (v.hasProperty(QStringLiteral("altitude"))) - c.setAltitude(v.property(QStringLiteral("altitude")).toNumber()); - } else if (v.isString()) { - c = stringToCoordinate(v.toString()).value<QGeoCoordinate>(); - } + bool ok; + QGeoCoordinate c = parseCoordinate(value.property(i), &ok); - if (!c.isValid()) { + if (!ok || !c.isValid()) { qmlInfo(this) << "Unsupported waypoint type"; return; } @@ -798,48 +784,52 @@ void QDeclarativeGeoRouteQuery::setWaypoints(const QJSValue &value) \sa addExcludedArea, removeExcludedArea, clearExcludedAreas */ -QQmlListProperty<QDeclarativeGeoRectangle> QDeclarativeGeoRouteQuery::excludedAreas() +QJSValue QDeclarativeGeoRouteQuery::excludedAreas() const { - return QQmlListProperty<QDeclarativeGeoRectangle>(this, 0, exclusions_append, - exclusions_count, exclusions_at, - exclusions_clear); -} + QQmlContext *context = QQmlEngine::contextForObject(parent()); + QQmlEngine *engine = context->engine(); + QV8Engine *v8Engine = QQmlEnginePrivate::getV8Engine(engine); + QV8ValueTypeWrapper *valueTypeWrapper = v8Engine->valueTypeWrapper(); -/*! - \internal -*/ -void QDeclarativeGeoRouteQuery::exclusions_append(QQmlListProperty<QDeclarativeGeoRectangle> *prop, QDeclarativeGeoRectangle *area) -{ - QDeclarativeGeoRouteQuery *model = static_cast<QDeclarativeGeoRouteQuery *>(prop->object); - model->addExcludedArea(area); -} + v8::Local<v8::Array> excludedAreasArray = v8::Array::New(request_.excludeAreas().length()); + for (int i = 0; i < request_.excludeAreas().length(); ++i) { + const QGeoRectangle &r = request_.excludeAreas().at(i); -/*! - \internal -*/ -int QDeclarativeGeoRouteQuery::exclusions_count(QQmlListProperty<QDeclarativeGeoRectangle> *prop) -{ - QDeclarativeGeoRouteQuery *model = static_cast<QDeclarativeGeoRouteQuery *>(prop->object); - return model->exclusions_.count(); -} + QQmlValueType *vt = QQmlValueTypeFactory::valueType(qMetaTypeId<QGeoRectangle>()); + v8::Local<v8::Object> cv = valueTypeWrapper->newValueType(QVariant::fromValue(r), vt); -/*! - \internal -*/ -QDeclarativeGeoRectangle *QDeclarativeGeoRouteQuery::exclusions_at(QQmlListProperty<QDeclarativeGeoRectangle> *prop, int index) -{ - QDeclarativeGeoRouteQuery *model = static_cast<QDeclarativeGeoRouteQuery *>(prop->object); - Q_ASSERT(index < model->exclusions_.count()); - return model->exclusions_.at(index); + excludedAreasArray->Set(i, cv); + } + + return v8Engine->scriptValueFromInternal(excludedAreasArray); } -/*! - \internal -*/ -void QDeclarativeGeoRouteQuery::exclusions_clear(QQmlListProperty<QDeclarativeGeoRectangle> *prop) +void QDeclarativeGeoRouteQuery::setExcludedAreas(const QJSValue &value) { - QDeclarativeGeoRouteQuery *model = static_cast<QDeclarativeGeoRouteQuery *>(prop->object); - model->clearExcludedAreas(); + if (!value.isArray()) + return; + + QList<QGeoRectangle> excludedAreasList; + quint32 length = value.property(QStringLiteral("length")).toUInt(); + for (quint32 i = 0; i < length; ++i) { + bool ok; + QGeoRectangle r = parseRectangle(value.property(i), &ok); + + if (!ok || !r.isValid()) { + qmlInfo(this) << "Unsupported waypoint type"; + return; + } + + excludedAreasList.append(r); + } + + if (request_.excludeAreas() == excludedAreasList) + return; + + request_.setExcludeAreas(excludedAreasList); + + emit excludedAreasChanged(); + emit queryDetailsChanged(); } /*! @@ -852,22 +842,20 @@ void QDeclarativeGeoRouteQuery::exclusions_clear(QQmlListProperty<QDeclarativeGe */ -void QDeclarativeGeoRouteQuery::addExcludedArea(QDeclarativeGeoRectangle *area) +void QDeclarativeGeoRouteQuery::addExcludedArea(const QGeoRectangle &area) { - if (!area) + if (!area.isValid()) return; - if (exclusions_.contains(area)) + + QList<QGeoRectangle> excludedAreas = request_.excludeAreas(); + + if (excludedAreas.contains(area)) return; - connect(area, SIGNAL(bottomLeftChanged()), this, SLOT(excludedAreaCoordinateChanged())); - connect(area, SIGNAL(bottomRightChanged()), this, SLOT(excludedAreaCoordinateChanged())); - connect(area, SIGNAL(topLeftChanged()), this, SLOT(excludedAreaCoordinateChanged())); - connect(area, SIGNAL(topRightChanged()), this, SLOT(excludedAreaCoordinateChanged())); - connect(area, SIGNAL(centerChanged()), this, SLOT(excludedAreaCoordinateChanged())); - connect(area, SIGNAL(widthChanged()), this, SLOT(excludedAreaCoordinateChanged())); - connect(area, SIGNAL(heightChanged()), this, SLOT(excludedAreaCoordinateChanged())); + excludedAreas.append(area); + + request_.setExcludeAreas(excludedAreas); - exclusions_.append(area); if (complete_) { emit excludedAreasChanged(); emit queryDetailsChanged(); @@ -882,18 +870,21 @@ void QDeclarativeGeoRouteQuery::addExcludedArea(QDeclarativeGeoRectangle *area) \sa addExcludedArea, clearExcludedAreas */ -void QDeclarativeGeoRouteQuery::removeExcludedArea(QDeclarativeGeoRectangle *area) +void QDeclarativeGeoRouteQuery::removeExcludedArea(const QGeoRectangle &area) { - if (!area) + if (!area.isValid()) return; - int index = exclusions_.lastIndexOf(area); + QList<QGeoRectangle> excludedAreas = request_.excludeAreas(); + + int index = excludedAreas.lastIndexOf(area); if (index == -1) { qmlInfo(this) << QCoreApplication::translate(CONTEXT_NAME, CANNOT_REMOVE_AREA); return; } - exclusions_.removeAt(index); - area->disconnect(this); + excludedAreas.removeAt(index); + request_.setExcludeAreas(excludedAreas); + emit excludedAreasChanged(); emit queryDetailsChanged(); } @@ -908,11 +899,11 @@ void QDeclarativeGeoRouteQuery::removeExcludedArea(QDeclarativeGeoRectangle *are void QDeclarativeGeoRouteQuery::clearExcludedAreas() { - if (!exclusions_.count()) + if (request_.excludeAreas().isEmpty()) return; - for (int i = 0; i < exclusions_.count(); ++i) - exclusions_.at(i)->disconnect(this); - exclusions_.clear(); + + request_.setExcludeAreas(QList<QGeoRectangle>()); + emit excludedAreasChanged(); emit queryDetailsChanged(); } @@ -1248,14 +1239,8 @@ void QDeclarativeGeoRouteQuery::setRouteOptimizations(QDeclarativeGeoRouteQuery: /*! \internal */ -QGeoRouteRequest &QDeclarativeGeoRouteQuery::routeRequest() +QGeoRouteRequest QDeclarativeGeoRouteQuery::routeRequest() const { - // Bit inefficient, but excludearea count is not big - QList<QGeoRectangle> exclusions; - for (int i = 0; i < exclusions_.count(); ++i) - exclusions.append(exclusions_.at(i)->rectangle()); - - request_.setExcludeAreas(exclusions); return request_; } diff --git a/src/imports/location/qdeclarativegeoroutemodel_p.h b/src/imports/location/qdeclarativegeoroutemodel_p.h index 67aecf10..d296c560 100644 --- a/src/imports/location/qdeclarativegeoroutemodel_p.h +++ b/src/imports/location/qdeclarativegeoroutemodel_p.h @@ -190,7 +190,7 @@ class QDeclarativeGeoRouteQuery : public QObject, public QQmlParserStatus Q_PROPERTY(SegmentDetail segmentDetail READ segmentDetail WRITE setSegmentDetail NOTIFY segmentDetailChanged) Q_PROPERTY(ManeuverDetail maneuverDetail READ maneuverDetail WRITE setManeuverDetail NOTIFY maneuverDetailChanged) Q_PROPERTY(QJSValue waypoints READ waypoints WRITE setWaypoints NOTIFY waypointsChanged) - Q_PROPERTY(QQmlListProperty<QDeclarativeGeoRectangle> excludedAreas READ excludedAreas NOTIFY excludedAreasChanged) + Q_PROPERTY(QJSValue excludedAreas READ excludedAreas WRITE setExcludedAreas NOTIFY excludedAreasChanged) Q_PROPERTY(QList<int> featureTypes READ featureTypes NOTIFY featureTypesChanged) Q_INTERFACES(QQmlParserStatus) @@ -203,7 +203,7 @@ public: void classBegin() {} void componentComplete(); - QGeoRouteRequest &routeRequest(); + QGeoRouteRequest routeRequest() const; enum TravelMode { CarTravel = QGeoRouteRequest::CarTravel, @@ -267,14 +267,15 @@ public: void setWaypoints(const QJSValue &value); // READ functions for list properties - QQmlListProperty<QDeclarativeGeoRectangle> excludedAreas(); + QJSValue excludedAreas() const; + void setExcludedAreas(const QJSValue &value); Q_INVOKABLE void addWaypoint(const QGeoCoordinate &waypoint); Q_INVOKABLE void removeWaypoint(const QGeoCoordinate &waypoint); Q_INVOKABLE void clearWaypoints(); - Q_INVOKABLE void addExcludedArea(QDeclarativeGeoRectangle *area); - Q_INVOKABLE void removeExcludedArea(QDeclarativeGeoRectangle *area); + Q_INVOKABLE void addExcludedArea(const QGeoRectangle &area); + Q_INVOKABLE void removeExcludedArea(const QGeoRectangle &area); Q_INVOKABLE void clearExcludedAreas(); Q_INVOKABLE void setFeatureWeight(FeatureType featureType, FeatureWeight featureWeight); @@ -317,13 +318,6 @@ private Q_SLOTS: private: Q_INVOKABLE void doCoordinateChanged(); - static void exclusions_append(QQmlListProperty<QDeclarativeGeoRectangle> *prop, QDeclarativeGeoRectangle *area); - static int exclusions_count(QQmlListProperty<QDeclarativeGeoRectangle> *prop); - static QDeclarativeGeoRectangle *exclusions_at(QQmlListProperty<QDeclarativeGeoRectangle> *prop, int index); - static void exclusions_clear(QQmlListProperty<QDeclarativeGeoRectangle> *prop); - - QList<QDeclarativeGeoRectangle *> exclusions_; - QGeoRouteRequest request_; bool complete_; bool m_excludedAreaCoordinateChanged; diff --git a/src/imports/location/qdeclarativegeoshape.cpp b/src/imports/location/qdeclarativegeoshape.cpp index b65974dc..35a80483 100644 --- a/src/imports/location/qdeclarativegeoshape.cpp +++ b/src/imports/location/qdeclarativegeoshape.cpp @@ -41,21 +41,157 @@ #include "qdeclarativegeoshape.h" +#include <QtLocation/QGeoRectangle> +#include <QtLocation/QGeoCircle> + QT_BEGIN_NAMESPACE /*! - \qmltype GeoShape - \instantiates QDeclarativeGeoShape + \qmlbasictype geoshape \inqmlmodule QtLocation 5.0 - \ingroup qml-QtLocation5-positioning + \ingroup qml-QtLocation5-basictypes \since Qt Location 5.0 - \brief The GeoShape type represents an abstract geographic area. + \brief A geoshape type represents an abstract geographic area. + + The \c geoshape type represents an abstract geographic area. It includes attributes and + methods common to all geographic areas. To create objects that represent a valid geographic + area use \l {QtLocation5::georectangle}{georectangle} or + \l {QtLocation5::geocircle}{geocircle}. + + The \c isValid attribute can be used to test if the geoshape represents a valid geographic + area. + + The \c isEmpty attribute can be used to test if the geoshape represents a region with a + geomatrical area of 0. + + The \l contains() method can be used to test if a \l {QtLocation5::coordinate}{coordinate} is + within the geoshape. + + \section2 Example Usage + + Use properties of type \l variant to store a \c {geoshape}. To create a \c geoshape use one + of the methods described below. + + To create a \c geoshape value, specify it as a "shape()" string: + + \qml + import QtLocation + + Item { + property variant region: "shape()" + } + \endqml + + or with the \l {QtLocation5::QtLocation}{QtLocation.shape()} function: + + \qml + import QtLocation 5.0 + + Item { + property variant region: QtLocation.shape() + } + \endqml + + When integrating with C++, note that any QGeoShape value passed into QML from C++ is + automatically converted into a \c geoshape value, and vice-versa. - The GeoShape type is not intended to be instantiated by the developer. Use GeoRectangle - or GeoCircle instead. + \section2 Methods - \sa GeoRectangle, GeoCircle + \section3 contains() + + \code + bool contains(coordinate coord) + \endcode + + Returns true if the \l {QtLocation5::coordinate}{coordinate} specified by \a coord is within + this geoshape; Otherwise returns false. */ +GeoShapeValueType::GeoShapeValueType(QObject *parent) +: QQmlValueTypeBase<QGeoShape>(qMetaTypeId<QGeoShape>(), parent) +{ +} + +GeoShapeValueType::~GeoShapeValueType() +{ +} + +GeoShapeValueType::ShapeType GeoShapeValueType::type() const +{ + return static_cast<GeoShapeValueType::ShapeType>(v.type()); +} + +bool GeoShapeValueType::isValid() const +{ + return v.isValid(); +} + +bool GeoShapeValueType::isEmpty() const +{ + return v.isEmpty(); +} + +bool GeoShapeValueType::contains(const QGeoCoordinate &coordinate) const +{ + return v.contains(coordinate); +} + +QString GeoShapeValueType::toString() const +{ + switch (v.type()) { + case QGeoShape::UnknownType: + return QStringLiteral("QGeoShape()"); + case QGeoShape::RectangleType: { + QGeoRectangle r = v; + return QStringLiteral("QGeoRectangle({%1, %2}, {%3, %4})") + .arg(r.topLeft().latitude()) + .arg(r.topLeft().longitude()) + .arg(r.bottomRight().latitude()) + .arg(r.bottomRight().longitude()); + } + case QGeoShape::CircleType: { + QGeoCircle c = v; + return QStringLiteral("QGeoCircle({%1, %2}, %3)") + .arg(c.center().latitude()) + .arg(c.center().longitude()) + .arg(c.radius()); + } + } + + return QStringLiteral("QGeoShape(%1)").arg(v.type()); +} + +void GeoShapeValueType::setValue(const QVariant &value) +{ + if (value.userType() == qMetaTypeId<QGeoShape>()) + v = value.value<QGeoShape>(); + else if (value.userType() == qMetaTypeId<QGeoRectangle>()) + v = value.value<QGeoRectangle>(); + else if (value.userType() == qMetaTypeId<QGeoCircle>()) + v = value.value<QGeoCircle>(); + else + v = QGeoShape(); + + onLoad(); +} + +bool GeoShapeValueType::isEqual(const QVariant &other) const +{ + if (other.userType() == qMetaTypeId<QGeoShape>()) + return v == other.value<QGeoShape>(); + else if (other.userType() == qMetaTypeId<QGeoRectangle>()) + return v == other.value<QGeoRectangle>(); + else if (other.userType() == qMetaTypeId<QGeoCircle>()) + return v == other.value<QGeoCircle>(); + else + return false; +} + +GeoShapeValueType::GeoShapeValueType(int userType, QObject *parent) +: QQmlValueTypeBase<QGeoShape>(userType, parent) +{ + QMetaType::construct(userType, &v, 0); +} + QT_END_NAMESPACE diff --git a/src/imports/location/qdeclarativegeoshape.h b/src/imports/location/qdeclarativegeoshape.h index 526c0e6f..00e8c596 100644 --- a/src/imports/location/qdeclarativegeoshape.h +++ b/src/imports/location/qdeclarativegeoshape.h @@ -42,23 +42,45 @@ #ifndef QDECLARATIVEGEOSHAPE_H #define QDECLARATIVEGEOSHAPE_H -#include <QtCore/QObject> -#include <QtQml/qqml.h> +#include <QtQml/private/qqmlvaluetype_p.h> #include <QtLocation/QGeoShape> QT_BEGIN_NAMESPACE -class QDeclarativeGeoShape : public QObject +class GeoShapeValueType : public QQmlValueTypeBase<QGeoShape> { Q_OBJECT + Q_PROPERTY(ShapeType type READ type) + Q_PROPERTY(bool isValid READ isValid) + Q_PROPERTY(bool isEmpty READ isEmpty) + + Q_ENUMS(ShapeType) + public: - explicit QDeclarativeGeoShape(QObject *parent) :QObject(parent){} - virtual QGeoShape shape() const = 0; + explicit GeoShapeValueType(QObject *parent = 0); + ~GeoShapeValueType(); + + enum ShapeType { + UnknownType = QGeoShape::UnknownType, + RectangleType = QGeoShape::RectangleType, + CircleType = QGeoShape::CircleType + }; + + ShapeType type() const; + bool isValid() const; + bool isEmpty() const; + + Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate) const; + + QString toString() const Q_DECL_OVERRIDE; + void setValue(const QVariant &value) Q_DECL_OVERRIDE; + bool isEqual(const QVariant &other) const Q_DECL_OVERRIDE; + +protected: + explicit GeoShapeValueType(int userType, QObject *parent = 0); }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QDeclarativeGeoShape) - #endif diff --git a/src/imports/location/qdeclarativepolygonmapitem.cpp b/src/imports/location/qdeclarativepolygonmapitem.cpp index d2ff46d0..2dd0bfb2 100644 --- a/src/imports/location/qdeclarativepolygonmapitem.cpp +++ b/src/imports/location/qdeclarativepolygonmapitem.cpp @@ -406,22 +406,10 @@ void QDeclarativePolygonMapItem::setPath(const QJSValue &value) QList<QGeoCoordinate> pathList; quint32 length = value.property(QStringLiteral("length")).toUInt(); for (quint32 i = 0; i < length; ++i) { - QJSValue v = value.property(i); - - QGeoCoordinate c; - - if (v.isObject()) { - if (v.hasProperty(QStringLiteral("latitude"))) - c.setLatitude(v.property(QStringLiteral("latitude")).toNumber()); - if (v.hasProperty(QStringLiteral("longitude"))) - c.setLongitude(v.property(QStringLiteral("longitude")).toNumber()); - if (v.hasProperty(QStringLiteral("altitude"))) - c.setAltitude(v.property(QStringLiteral("altitude")).toNumber()); - } else if (v.isString()) { - c = stringToCoordinate(v.toString()).value<QGeoCoordinate>(); - } + bool ok; + QGeoCoordinate c = parseCoordinate(value.property(i), &ok); - if (!c.isValid()) { + if (!ok || !c.isValid()) { qmlInfo(this) << "Unsupported path type"; return; } diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index f0f15a24..bf6b2855 100644 --- a/src/imports/location/qdeclarativepolylinemapitem.cpp +++ b/src/imports/location/qdeclarativepolylinemapitem.cpp @@ -520,22 +520,10 @@ void QDeclarativePolylineMapItem::setPath(const QJSValue &value) QList<QGeoCoordinate> pathList; quint32 length = value.property(QStringLiteral("length")).toUInt(); for (quint32 i = 0; i < length; ++i) { - QJSValue v = value.property(i); - - QGeoCoordinate c; - - if (v.isObject()) { - if (v.hasProperty(QStringLiteral("latitude"))) - c.setLatitude(v.property(QStringLiteral("latitude")).toNumber()); - if (v.hasProperty(QStringLiteral("longitude"))) - c.setLongitude(v.property(QStringLiteral("longitude")).toNumber()); - if (v.hasProperty(QStringLiteral("altitude"))) - c.setAltitude(v.property(QStringLiteral("altitude")).toNumber()); - } else if (v.isString()) { - c = stringToCoordinate(v.toString()).value<QGeoCoordinate>(); - } + bool ok; + QGeoCoordinate c = parseCoordinate(value.property(i), &ok); - if (!c.isValid()) { + if (!ok || !c.isValid()) { qmlInfo(this) << "Unsupported path type"; return; } diff --git a/src/location/qgeocircle.h b/src/location/qgeocircle.h index a38acb1b..ad6b191f 100644 --- a/src/location/qgeocircle.h +++ b/src/location/qgeocircle.h @@ -97,6 +97,8 @@ private: inline const QGeoCirclePrivate *d_func() const; }; +Q_DECLARE_TYPEINFO(QGeoCircle, Q_MOVABLE_TYPE); + QT_END_NAMESPACE Q_DECLARE_METATYPE(QGeoCircle) diff --git a/src/location/qgeorectangle.h b/src/location/qgeorectangle.h index f031ab0b..3409730e 100644 --- a/src/location/qgeorectangle.h +++ b/src/location/qgeorectangle.h @@ -128,6 +128,8 @@ private: inline const QGeoRectanglePrivate *d_func() const; }; +Q_DECLARE_TYPEINFO(QGeoRectangle, Q_MOVABLE_TYPE); + inline QGeoRectangle QGeoRectangle::operator|(const QGeoRectangle &rectangle) const { return united(rectangle); diff --git a/src/location/qgeoshape.cpp b/src/location/qgeoshape.cpp index 2c47fdde..c62269e0 100644 --- a/src/location/qgeoshape.cpp +++ b/src/location/qgeoshape.cpp @@ -41,6 +41,16 @@ #include "qgeoshape.h" #include "qgeoshape_p.h" +#include "qgeorectangle.h" +#include "qgeocircle.h" + +#ifndef QT_NO_DEBUG_STREAM +#include <QtCore/QDebug> +#endif + +#ifndef QT_NO_DATASTREAM +#include <QtCore/QDataStream> +#endif QT_BEGIN_NAMESPACE @@ -221,4 +231,77 @@ QGeoShape &QGeoShape::operator=(const QGeoShape &other) return *this; } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QGeoShape &shape) +{ + //dbg << *shape.d_func(); + dbg.nospace() << "QGeoShape("; + switch (shape.type()) { + case QGeoShape::UnknownType: + dbg.nospace() << "Unknown"; + break; + case QGeoShape::RectangleType: + dbg.nospace() << "Rectangle"; + break; + case QGeoShape::CircleType: + dbg.nospace() << "Circle"; + } + + dbg.nospace() << ')'; + + return dbg; +} +#endif + +#ifndef QT_NO_DATASTREAM +QDataStream &operator<<(QDataStream &stream, const QGeoShape &shape) +{ + stream << quint32(shape.type()); + switch (shape.type()) { + case QGeoShape::UnknownType: + break; + case QGeoShape::RectangleType: { + QGeoRectangle r = shape; + stream << r.topLeft() << r.bottomRight(); + break; + } + case QGeoShape::CircleType: { + QGeoCircle c = shape; + stream << c.center() << c.radius(); + break; + } + } + + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QGeoShape &shape) +{ + quint32 type; + stream >> type; + + switch (type) { + case QGeoShape::UnknownType: + shape = QGeoShape(); + break; + case QGeoShape::RectangleType: { + QGeoCoordinate tl; + QGeoCoordinate br; + stream >> tl >> br; + shape = QGeoRectangle(tl, br); + break; + } + case QGeoShape::CircleType: { + QGeoCoordinate c; + qreal r; + stream >> c >> r; + shape = QGeoCircle(c, r); + break; + } + } + + return stream; +} +#endif + QT_END_NAMESPACE diff --git a/src/location/qgeoshape.h b/src/location/qgeoshape.h index 28a87ae3..9dc8f046 100644 --- a/src/location/qgeoshape.h +++ b/src/location/qgeoshape.h @@ -49,6 +49,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +class QDebug; class QGeoShapePrivate; class Q_LOCATION_EXPORT QGeoShape @@ -85,6 +86,17 @@ private: inline const QGeoShapePrivate *d_func() const; }; +Q_DECLARE_TYPEINFO(QGeoShape, Q_MOVABLE_TYPE); + +#ifndef QT_NO_DEBUG_STREAM +Q_LOCATION_EXPORT QDebug operator<<(QDebug, const QGeoShape &); +#endif + +#ifndef QT_NO_DATASTREAM +Q_LOCATION_EXPORT QDataStream &operator<<(QDataStream &stream, const QGeoShape &shape); +Q_LOCATION_EXPORT QDataStream &operator>>(QDataStream &stream, QGeoShape &shape); +#endif + QT_END_NAMESPACE Q_DECLARE_METATYPE(QGeoShape) diff --git a/src/plugins/geoservices/places_jsondb/jsondb.cpp b/src/plugins/geoservices/places_jsondb/jsondb.cpp index c260d505..4d463ad8 100644 --- a/src/plugins/geoservices/places_jsondb/jsondb.cpp +++ b/src/plugins/geoservices/places_jsondb/jsondb.cpp @@ -53,7 +53,6 @@ #include <QtJsonDb/QJsonDbWriteRequest> #include <QtLocation/QPlaceSearchRequest> #include <QtLocation/QPlaceCategory> -#include <QtLocation/QGeoCircle> const QLatin1String JsonDb::Uuid("_uuid"); const QLatin1String JsonDb::Type("_type"); diff --git a/src/plugins/geoservices/places_jsondb/matchreply.cpp b/src/plugins/geoservices/places_jsondb/matchreply.cpp index e90e5c38..7cd05861 100644 --- a/src/plugins/geoservices/places_jsondb/matchreply.cpp +++ b/src/plugins/geoservices/places_jsondb/matchreply.cpp @@ -46,7 +46,6 @@ #include <QtCore/QJsonArray> #include <QtCore/QDebug> #include <QtJsonDb/QJsonDbReadRequest> -#include <QtLocation/QGeoCircle> MatchReply::MatchReply(QPlaceManagerEngineJsonDb *engine) : QPlaceMatchReply(engine), m_engine(engine) diff --git a/tests/auto/declarative_core/tst_geoshape.qml b/tests/auto/declarative_core/tst_geoshape.qml index 9cb06745..ff30548e 100644 --- a/tests/auto/declarative_core/tst_geoshape.qml +++ b/tests/auto/declarative_core/tst_geoshape.qml @@ -44,40 +44,42 @@ import QtTest 1.0 import QtLocation 5.0 Item { + id: testCase + property variant coordinate1: QtLocation.coordinate(1, 1) property variant coordinate2: QtLocation.coordinate(2, 2) property variant coordinate3: QtLocation.coordinate(80, 80) - GeoCircle { id: emptyCircle } - GeoCircle { id: circle1; center: coordinate1; radius: 200000 } + property variant emptyCircle: QtLocation.circle() + property variant circle1: QtLocation.circle(coordinate1, 200000) - SignalSpy {id: radiusSpy; target: emptyCircle; signalName: "radiusChanged"} - SignalSpy {id: centerSpy; target: emptyCircle; signalName: "centerChanged"} + SignalSpy { id: circleChangedSpy; target: testCase; signalName: "emptyCircleChanged" } TestCase { name: "Bounding circle" function test_circle_defaults_and_setters() { + circleChangedSpy.clear(); compare (emptyCircle.radius, -1) compare (circle1.radius, 200000) emptyCircle.radius = 200 - compare (radiusSpy.count, 1) - emptyCircle.radius = 200 - compare (radiusSpy.count, 1) + compare(circleChangedSpy.count, 1); + emptyCircle.radius = 200; + compare(circleChangedSpy.count, 1); + emptyCircle.center = coordinate1; + compare(circleChangedSpy.count, 2); emptyCircle.center = coordinate1 - compare (centerSpy.count, 1) - emptyCircle.center = coordinate1 - compare (centerSpy.count, 1) + compare(circleChangedSpy.count, 2); emptyCircle.center = coordinate2 - compare (centerSpy.count, 2) + compare(circleChangedSpy.count, 3); emptyCircle.center = coordinate1 emptyCircle.radius = 200000 - // TODO - //compare(emptyCircle.contains(coordinate1), true) - //compare(emptyCircle.contains(coordinate2), true) - //compare(emptyCircle.contains(coordinate3), false) + + compare(emptyCircle.contains(coordinate1), true); + compare(emptyCircle.contains(coordinate2), true); + compare(emptyCircle.contains(coordinate3), false); } } @@ -91,13 +93,7 @@ Item { property variant inside: QtLocation.coordinate(0.5, 0.5) property variant outside: QtLocation.coordinate(2, 2) - GeoRectangle { - id: box; - bottomLeft: bl - topLeft: tl - topRight: tr - bottomRight: br - } + property variant box: QtLocation.rectangle(tl, br) // C++ auto test exists for basics of bounding box, testing here // only added functionality diff --git a/tests/auto/declarative_core/tst_map_routing.qml b/tests/auto/declarative_core/tst_map_routing.qml index 5ec1c8dc..da0af8db 100644 --- a/tests/auto/declarative_core/tst_map_routing.qml +++ b/tests/auto/declarative_core/tst_map_routing.qml @@ -50,8 +50,18 @@ Item { property variant coordinate1: QtLocation.coordinate(51, 0) property variant coordinate2: QtLocation.coordinate(52, 0) - GeoRectangle { id: boundingBox1; topLeft: coordinate2; bottomLeft: coordinate1; width: 1000 } - GeoRectangle { id: boundingBox2; topLeft: coordinate2; bottomLeft: coordinate1; width: 1000 } + property variant boundingBox1: QtLocation.rectangle() + property variant boundingBox2: QtLocation.rectangle() + + Component.onCompleted: { + boundingBox1.topLeft = coordinate1; + boundingBox1.bottomRight = coordinate2; + boundingBox1.width = 10; + + boundingBox2.topLeft = coordinate2; + boundingBox2.bottomLeft = coordinate1; + boundingBox2.width = 20; + } property variant bl: QtLocation.coordinate(0, 0) property variant tl: QtLocation.coordinate(1, 0) @@ -59,13 +69,7 @@ Item { property variant br: QtLocation.coordinate(0, 1) property variant ntr: QtLocation.coordinate(3, 3) - GeoRectangle { - id: unitBox; - bottomLeft: bl - topLeft: tl - topRight: tr - bottomRight: br - } + property variant unitBox: QtLocation.rectangle(tl, br) Route {id: emptyRoute} TestCase { @@ -76,7 +80,7 @@ Item { // TODO enable when we have map route //MapRoute {id: emptyMapRoute} - GeoRectangle {id: emptyBox} + property variant emptyBox: QtLocation.rectangle() property variant emptyCoordinate: QtLocation.coordinate() @@ -313,42 +317,13 @@ Item { compare(emptyQuery.excludedAreas.length, 0) compare(exclusionSpy.count, 1) - // Altering exclusion area details should trigger signals - emptyQuery.clearExcludedAreas() - emptyQuery.addExcludedArea(unitBox) - queryDetailsChangedSpy.clear() - compare (emptyQuery.excludedAreas.length, 1) - unitBox.width = 200 - tryCompare(queryDetailsChangedSpy, "count", 1); - unitBox.height = 200 - tryCompare(queryDetailsChangedSpy , "count", 2); - unitBox.topRight = ntr - tryCompare(queryDetailsChangedSpy, "count", 3); - - // verify box is disconnected - emptyQuery.removeExcludedArea(unitBox) - compare(queryDetailsChangedSpy.count, 4); - unitBox.height = 400 - tryCompare(queryDetailsChangedSpy, "count", 4); - - // verify that same box instance only produces one set of changes - compare (emptyQuery.excludedAreas.length, 0) - emptyQuery.addExcludedArea(unitBox) - emptyQuery.addExcludedArea(unitBox) - compare (emptyQuery.excludedAreas.length, 1) - queryDetailsChangedSpy.clear() - unitBox.width = 777 - tryCompare(queryDetailsChangedSpy, "count", 1); - compare (emptyQuery.excludedAreas.length, 1) - unitBox.width = 200 - tryCompare(queryDetailsChangedSpy, "count", 2); - // verify that clearing works - emptyQuery.clearExcludedAreas() - compare (queryDetailsChangedSpy.count, 3) - compare (emptyQuery.excludedAreas.length, 0) - unitBox.width = 717 - tryCompare(queryDetailsChangedSpy, "count", 3); + emptyQuery.addExcludedArea(unitBox); + compare(emptyQuery.excludedAreas.length, 1); + queryDetailsChangedSpy.clear(); + emptyQuery.clearExcludedAreas(); + compare(queryDetailsChangedSpy.count, 1); + compare(emptyQuery.excludedAreas.length, 0) // Feature types and weights queryDetailsChangedSpy.clear() diff --git a/tests/auto/declarative_core/tst_place.qml b/tests/auto/declarative_core/tst_place.qml index 9b4ae991..95d0f538 100644 --- a/tests/auto/declarative_core/tst_place.qml +++ b/tests/auto/declarative_core/tst_place.qml @@ -91,12 +91,8 @@ TestCase { altitude: 100 } - boundingBox: GeoRectangle { - center { - latitude: 10 - longitude: 10 - altitude: 100 - } + boundingBox { + center: QtLocation.coordinate(10, 10, 100) width: 100 height: 100 } @@ -146,13 +142,6 @@ TestCase { visibility: Place.PublicVisibility } - // compares two coordinates property by property - function compare_coordinate(coord1, coord2) { - return coord1.latitude === coord2.latitude && - coord1.longitude === coord2.longitude && - coord1.altitude === coord2.altitude; - } - // compares two places property by property function compare_place(place1, place2) { // check simple properties @@ -244,33 +233,10 @@ TestCase { if (place1.location.address.postalCode !== place2.location.address.postalCode) return false; - /* - if (!compare_coordinate(place1.location.coordinate, place2.location.coordinate)) - return false; - console.log("location.coordinate is equal"); - if (!compare_coordinate(place1.location.boundingBox.bottomLeft, place2.location.boundingBox.bottomLeft)) - return false; - console.log("location.boundingBox.bottomLeft is equal"); - if (!compare_coordinate(place1.location.boundingBox.bottomRight, place2.location.boundingBox.bottomRight)) - return false; - console.log("location.boundingBox.bottomRight is equal"); - if (!compare_coordinate(place1.location.boundingBox.topLeft, place2.location.boundingBox.topLeft)) - return false; - console.log("location.boundingBox.topLeft is equal"); - if (!compare_coordinate(place1.location.boundingBox.topRight, place2.location.boundingBox.topRight)) - return false; - console.log("location.boundingBox.topRight is equal"); - if (!compare_coordinate(place1.location.boundingBox.center, place2.location.boundingBox.center)) - return false; - console.log("location.boundingBox.center is equal"); - console.log(place1.location.boundingBox.height + " eq " + place2.location.boundingBox.height); - if (place1.location.boundingBox.height !== place2.location.boundingBox.height) + if (place1.location.coordinate !== place2.location.coordinate) return false; - console.log(place1.location.boundingBox.width + " eq " + place2.location.boundingBox.width); - if (place1.location.boundingBox.width !== place2.location.boundingBox.width) + if (place1.location.boundingBox !== place2.location.boundingBox) return false; - console.log("location.boundingBox is equal"); - */ } // check icon diff --git a/tests/auto/declarative_core/tst_placesearchmodel.qml b/tests/auto/declarative_core/tst_placesearchmodel.qml index 8ec3c0a2..aef710d9 100644 --- a/tests/auto/declarative_core/tst_placesearchmodel.qml +++ b/tests/auto/declarative_core/tst_placesearchmodel.qml @@ -66,17 +66,8 @@ TestCase { name: "foo" } - Plugin { - id: uninitializedPlugin - } - - GeoCircle { - id: testSearchArea - center { - latitude: 10 - longitude: 20 - } - radius: 5000 + Plugin { + id: uninitializedPlugin } Category { @@ -104,9 +95,11 @@ TestCase { } function test_setAndGet_data() { + var testSearchArea = QtLocation.circle(QtLocation.coordinate(10, 20), 5000); + return [ { tag: "plugin", property: "plugin", signal: "pluginChanged", value: testPlugin }, - { tag: "searchArea", property: "searchArea", signal: "searchAreaChanged", value: testSearchArea }, + { tag: "searchArea", property: "searchArea", signal: "searchAreaChanged", value: testSearchArea, reset: QtLocation.shape() }, { tag: "offset", property: "offset", signal: "offsetChanged", value: 10, reset: 0 }, { tag: "limit", property: "limit", signal: "limitChanged", value: 10, reset: -1 }, diff --git a/tests/auto/declarative_core/tst_placesearchsuggestionmodel.qml b/tests/auto/declarative_core/tst_placesearchsuggestionmodel.qml index b2c8b73e..bc4fbd80 100644 --- a/tests/auto/declarative_core/tst_placesearchsuggestionmodel.qml +++ b/tests/auto/declarative_core/tst_placesearchsuggestionmodel.qml @@ -64,23 +64,15 @@ TestCase { name: "nonExistantName" } - Plugin { - id: uninitializedPlugin - } - - GeoCircle { - id: testSearchArea - center { - latitude: 10 - longitude: 20 - } - radius: 5000 + Plugin { + id: uninitializedPlugin } function test_setAndGet_data() { + var testSearchArea = QtLocation.circle(QtLocation.coordinate(10, 20), 5000); return [ { tag: "plugin", property: "plugin", signal: "pluginChanged", value: testPlugin }, - { tag: "searchArea", property: "searchArea", signal: "searchAreaChanged", value: testSearchArea }, + { tag: "searchArea", property: "searchArea", signal: "searchAreaChanged", value: testSearchArea, reset: QtLocation.shape() }, { tag: "offset", property: "offset", signal: "offsetChanged", value: 10, reset: 0 }, { tag: "limit", property: "limit", signal: "limitChanged", value: 10, reset: -1 }, diff --git a/tests/auto/declarative_ui/tst_map_geocoding.qml b/tests/auto/declarative_ui/tst_map_geocoding.qml index 2d64fcd6..072b27ee 100644 --- a/tests/auto/declarative_ui/tst_map_geocoding.qml +++ b/tests/auto/declarative_ui/tst_map_geocoding.qml @@ -49,14 +49,16 @@ Item { property variant coordinate1: QtLocation.coordinate(51, 41) property variant coordinate2: QtLocation.coordinate(52, 42) + property variant coordinate3: QtLocation.coordinate(53, 43) property variant emptyCoordinate: QtLocation.coordinate() - GeoRectangle { id: boundingBox1; topLeft: coordinate2; bottomLeft: coordinate1; width: 1000 } - GeoRectangle { id: boundingBox2; topLeft: coordinate2; bottomLeft: coordinate1; width: 1000 } - GeoCircle { id: boundingCircle1; center: coordinate1; radius: 100 } - GeoCircle { id: boundingCircle2; center: coordinate2; radius: 100 } + property variant boundingBox1: QtLocation.rectangle(coordinate1, coordinate2) + property variant boundingBox2: QtLocation.rectangle(coordinate1, coordinate3) + property variant boundingCircle1: QtLocation.circle(coordinate1, 100) + property variant boundingCircle2: QtLocation.circle(coordinate2, 100) + + property variant emptyBox: QtLocation.rectangle() - GeoRectangle {id: emptyBox} GeocodeModel {id: emptyModel} Address {id: emptyAddress} @@ -122,8 +124,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 2.0; import QtLocation 5.0; GeoRectangle { id: dynBox }", testCase1) - emptyModel.bounds = dynamicBox + emptyModel.bounds = QtLocation.rectangle(); compare(boundsSpy.count, 3) @@ -138,7 +139,7 @@ Item { emptyModel.bounds = boundingCircle2 compare(boundsSpy.count, 2) compare(emptyModel.bounds.center.latitude, coordinate2.latitude) - var dynamicCircle = Qt.createQmlObject("import QtQuick 2.0; import QtLocation 5.0; GeoCircle { id: dynCircle; center { latitude: 8; longitude: 9 } }", testCase1) + var dynamicCircle = QtLocation.circle(QtLocation.coordinate(8, 9)); emptyModel.bounds = dynamicCircle compare(boundsSpy.count, 3) compare(emptyModel.bounds.center.latitude, dynamicCircle.center.latitude) diff --git a/tests/auto/declarative_ui/tst_map_item_fit_viewport.qml b/tests/auto/declarative_ui/tst_map_item_fit_viewport.qml index 8073e638..4cbbab74 100644 --- a/tests/auto/declarative_ui/tst_map_item_fit_viewport.qml +++ b/tests/auto/declarative_ui/tst_map_item_fit_viewport.qml @@ -110,17 +110,8 @@ Item { property variant mapRouteTopLeft: QtLocation.coordinate(0, 0) property variant mapRouteBottomRight: QtLocation.coordinate(0, 0) - GeoRectangle { - id: boundingBox - topLeft { - latitude: 0 - longitude: 0 - } - bottomRight { - latitude: 0 - longitude: 0 - } - } + property variant boundingBox: QtLocation.rectangle(QtLocation.coordinate(0, 0), + QtLocation.coordinate(0, 0)) Map { id: map; @@ -477,9 +468,7 @@ Item { point.y = maxY var itemBottomRight = map.toCoordinate(point) - boundingBox.topLeft = itemTopLeft; - boundingBox.bottomRight = itemBottomRight; - return boundingBox + return QtLocation.rectangle(itemTopLeft, itemBottomRight); } function verify_visibility_all_items(){ diff --git a/tests/auto/qmlinterface/data/TestGeoCircle.qml b/tests/auto/qmlinterface/data/TestGeoCircle.qml deleted file mode 100644 index d645cef2..00000000 --- a/tests/auto/qmlinterface/data/TestGeoCircle.qml +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtLocation 5.0 - -GeoCircle { - center { - longitude: 10.0 - latitude: 20.0 - altitude: 30.0 - } - radius: 30.0 -} diff --git a/tests/auto/qmlinterface/data/TestGeoRectangle.qml b/tests/auto/qmlinterface/data/TestGeoRectangle.qml deleted file mode 100644 index 00e0fea6..00000000 --- a/tests/auto/qmlinterface/data/TestGeoRectangle.qml +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtLocation 5.0 - -GeoRectangle { - center { - longitude: 10.0 - latitude: 20.0 - altitude: 30.0 - } - height: 30.0 - width: 40.0 -} diff --git a/tests/auto/qmlinterface/data/TestLocation.qml b/tests/auto/qmlinterface/data/TestLocation.qml index 97c25e5a..6ba74fd8 100644 --- a/tests/auto/qmlinterface/data/TestLocation.qml +++ b/tests/auto/qmlinterface/data/TestLocation.qml @@ -43,7 +43,16 @@ import QtLocation 5.0 Location { address: TestAddress { } - boundingBox: TestGeoRectangle { } + boundingBox { + center { + longitude: 10.0 + latitude: 20.0 + altitude: 30.0 + } + height: 30.0 + width: 40.0 + } + coordinate { longitude: 10.0 latitude: 20.0 diff --git a/tests/auto/qmlinterface/qmlinterface.pro b/tests/auto/qmlinterface/qmlinterface.pro index 6571fe90..8dbd9bbe 100644 --- a/tests/auto/qmlinterface/qmlinterface.pro +++ b/tests/auto/qmlinterface/qmlinterface.pro @@ -28,8 +28,6 @@ OTHER_FILES += \ data/TestSupplier.qml \ data/TestUser.qml \ data/TestPlaceAttribute.qml \ - data/TestContactDetail.qml \ - data/TestGeoRectangle.qml \ - data/TestGeoCircle.qml + data/TestContactDetail.qml DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/qmlinterface/tst_qmlinterface.cpp b/tests/auto/qmlinterface/tst_qmlinterface.cpp index 0b529e9e..49a769a0 100644 --- a/tests/auto/qmlinterface/tst_qmlinterface.cpp +++ b/tests/auto/qmlinterface/tst_qmlinterface.cpp @@ -66,8 +66,6 @@ public: private Q_SLOTS: void testAddress(); - void testGeoRectangle(); - void testGeoCircle(); void testLocation(); void testCategory(); void testIcon(); @@ -82,7 +80,6 @@ private: QGeoCoordinate m_coordinate; QGeoAddress m_address; QGeoRectangle m_rectangle; - QGeoCircle m_boundingCircle; QGeoLocation m_location; QPlaceCategory m_category; QPlaceIcon m_icon; @@ -112,9 +109,6 @@ tst_qmlinterface::tst_qmlinterface() m_rectangle.setHeight(30.0); m_rectangle.setWidth(40.0); - m_boundingCircle.setCenter(m_coordinate); - m_boundingCircle.setRadius(30.0); - m_location.setAddress(m_address); m_location.setBoundingBox(m_rectangle); m_location.setCoordinate(m_coordinate); @@ -186,45 +180,6 @@ void tst_qmlinterface::testAddress() delete qmlObject; } -void tst_qmlinterface::testGeoRectangle() -{ - QQmlEngine engine; - QQmlComponent component(&engine, SRCDIR "data/TestGeoRectangle.qml"); - QVERIFY(component.isReady()); - QObject *qmlObject = component.create(); - - QGeoRectangle rectangle = qmlObject->property("rectangle").value<QGeoRectangle>(); - - QCOMPARE(rectangle, m_rectangle); - - qmlObject->setProperty("rectangle", QVariant::fromValue(QGeoRectangle())); - - QCOMPARE(qmlObject->property("center").value<QGeoCoordinate>(), QGeoCoordinate()); - QVERIFY(qIsNaN(qmlObject->property("height").toDouble())); - QVERIFY(qIsNaN(qmlObject->property("width").toDouble())); - - delete qmlObject; -} - -void tst_qmlinterface::testGeoCircle() -{ - QQmlEngine engine; - QQmlComponent component(&engine, SRCDIR "data/TestGeoCircle.qml"); - QVERIFY(component.isReady()); - QObject *qmlObject = component.create(); - - QGeoCircle boundingCircle = qmlObject->property("circle").value<QGeoCircle>(); - - QCOMPARE(boundingCircle, m_boundingCircle); - - qmlObject->setProperty("circle", QVariant::fromValue(QGeoCircle())); - - QCOMPARE(qmlObject->property("center").value<QGeoCoordinate>(), QGeoCoordinate()); - QCOMPARE(qmlObject->property("radius").toDouble(), -1.0); - - delete qmlObject; -} - void tst_qmlinterface::testLocation() { QQmlEngine engine; |