diff options
author | Aaron McCarthy <aaron.mccarthy@jollamobile.com> | 2014-02-19 16:38:10 +1000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-14 06:16:11 +0100 |
commit | 3f4a3acab163fa6675a1513ab1fccdbda7723dd6 (patch) | |
tree | 16e63e4fedd6c9c8391593b4ae41d83c7e09245a /src/plugins/geoservices/nokia | |
parent | 5f0023a7469e01bada70fbe677b76bb535eaa953 (diff) | |
download | qtlocation-3f4a3acab163fa6675a1513ab1fccdbda7723dd6.tar.gz |
Parse Nokia geocode response in helper thread.
Change-Id: I151bd5988d0340a8203aa9e014371989b023228b
Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/plugins/geoservices/nokia')
4 files changed, 79 insertions, 63 deletions
diff --git a/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp b/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp index cb76fbca..8690eb65 100644 --- a/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp +++ b/src/plugins/geoservices/nokia/qgeocodereply_nokia.cpp @@ -51,22 +51,19 @@ #include <QtPositioning/QGeoShape> +Q_DECLARE_METATYPE(QList<QGeoLocation>) + QT_BEGIN_NAMESPACE QGeoCodeReplyNokia::QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offset, const QGeoShape &viewport, QObject *parent) - : QGeoCodeReply(parent), - m_reply(reply) +: QGeoCodeReply(parent), m_reply(reply), m_parsing(false) { - connect(m_reply, - SIGNAL(finished()), - this, - SLOT(networkFinished())); + qRegisterMetaType<QList<QGeoLocation> >(); - connect(m_reply, - SIGNAL(error(QNetworkReply::NetworkError)), - this, - SLOT(networkError(QNetworkReply::NetworkError))); + connect(m_reply, SIGNAL(finished()), this, SLOT(networkFinished())); + connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), + this, SLOT(networkError(QNetworkReply::NetworkError))); setLimit(limit); setOffset(offset); @@ -75,18 +72,19 @@ QGeoCodeReplyNokia::QGeoCodeReplyNokia(QNetworkReply *reply, int limit, int offs QGeoCodeReplyNokia::~QGeoCodeReplyNokia() { - //TODO: possible mem leak -> m_reply->deleteLater() ? + abort(); } void QGeoCodeReplyNokia::abort() { - if (!m_reply) + if (!m_reply && !m_parsing) return; m_reply->abort(); m_reply->deleteLater(); m_reply = 0; + m_parsing = false; } void QGeoCodeReplyNokia::networkFinished() @@ -94,29 +92,17 @@ void QGeoCodeReplyNokia::networkFinished() if (!m_reply) return; - if (m_reply->error() != QNetworkReply::NoError) { - // Removed because this is already done in networkError, which previously caused _two_ errors to be raised for every error. - //setError(QGeoCodeReply::CommunicationError, m_reply->errorString()); - //m_reply->deleteLater(); - //m_reply = 0; + if (m_reply->error() != QNetworkReply::NoError) return; - } - - QGeoCodeXmlParser parser; - if (parser.parse(m_reply)) { - QList<QGeoLocation> locations = parser.results(); - QGeoShape bounds = viewport(); - if (bounds.isValid()) { - for (int i = locations.size() - 1; i >= 0; --i) { - if (!bounds.contains(locations[i].coordinate())) - locations.removeAt(i); - } - } - setLocations(locations); - setFinished(true); - } else { - setError(QGeoCodeReply::ParseError, parser.errorString()); - } + + QGeoCodeXmlParser *parser = new QGeoCodeXmlParser; + parser->setBounds(viewport()); + connect(parser, SIGNAL(results(QList<QGeoLocation>)), + this, SLOT(appendResults(QList<QGeoLocation>))); + connect(parser, SIGNAL(error(QString)), this, SLOT(parseError(QString))); + + m_parsing = true; + parser->parse(m_reply->readAll()); m_reply->deleteLater(); m_reply = 0; @@ -135,4 +121,23 @@ void QGeoCodeReplyNokia::networkError(QNetworkReply::NetworkError error) m_reply = 0; } +void QGeoCodeReplyNokia::appendResults(const QList<QGeoLocation> &locations) +{ + if (!m_parsing) + return; + + m_parsing = false; + setLocations(locations); + setFinished(true); +} + +void QGeoCodeReplyNokia::parseError(const QString &errorString) +{ + Q_UNUSED(errorString) + + setError(QGeoCodeReply::ParseError, + tr("The response from the service was not in a recognisable format.")); + abort(); +} + QT_END_NAMESPACE diff --git a/src/plugins/geoservices/nokia/qgeocodereply_nokia.h b/src/plugins/geoservices/nokia/qgeocodereply_nokia.h index 6b72cd40..af3f4dec 100644 --- a/src/plugins/geoservices/nokia/qgeocodereply_nokia.h +++ b/src/plugins/geoservices/nokia/qgeocodereply_nokia.h @@ -66,9 +66,12 @@ public: private Q_SLOTS: void networkFinished(); void networkError(QNetworkReply::NetworkError error); + void appendResults(const QList<QGeoLocation> &locations); + void parseError(const QString &errorString); private: QNetworkReply *m_reply; + bool m_parsing; }; QT_END_NAMESPACE diff --git a/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp b/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp index b9dbd934..d19246ff 100644 --- a/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp +++ b/src/plugins/geoservices/nokia/qgeocodexmlparser.cpp @@ -48,10 +48,9 @@ #include "qgeocodexmlparser.h" -#include <QXmlStreamReader> -#include <QIODevice> - -#include <qgeolocation.h> +#include <QtCore/QXmlStreamReader> +#include <QtCore/QThreadPool> +#include <QtPositioning/QGeoLocation> #include <QtPositioning/QGeoAddress> #include <QtPositioning/QGeoCoordinate> #include <QtPositioning/QGeoRectangle> @@ -66,28 +65,28 @@ QGeoCodeXmlParser::~QGeoCodeXmlParser() { } -bool QGeoCodeXmlParser::parse(QIODevice *source) +void QGeoCodeXmlParser::setBounds(const QGeoShape &bounds) { - m_reader.reset(new QXmlStreamReader(source)); - - if (!parseRootElement()) { - m_errorString = m_reader->errorString(); - return false; - } - - m_errorString = ""; - - return true; + m_bounds = bounds; } -QList<QGeoLocation> QGeoCodeXmlParser::results() const +void QGeoCodeXmlParser::parse(const QByteArray &data) { - return m_results; + m_data = data; + QThreadPool::globalInstance()->start(this); } -QString QGeoCodeXmlParser::errorString() const +void QGeoCodeXmlParser::run() { - return m_errorString; + m_reader = new QXmlStreamReader(m_data); + + if (!parseRootElement()) + emit error(m_reader->errorString()); + else + emit results(m_results); + + delete m_reader; + m_reader = 0; } bool QGeoCodeXmlParser::parseRootElement() @@ -137,7 +136,8 @@ bool QGeoCodeXmlParser::parseRootElement() if (!parsePlace(&location)) return false; - m_results.append(location); + if (!m_bounds.isValid() || m_bounds.contains(location.coordinate())) + m_results.append(location); } else { m_reader->raiseError(QString("The element \"places\" did not expect a child element named \"%1\".").arg(m_reader->name().toString())); return false; diff --git a/src/plugins/geoservices/nokia/qgeocodexmlparser.h b/src/plugins/geoservices/nokia/qgeocodexmlparser.h index 8eeb6cc3..67c9da9e 100644 --- a/src/plugins/geoservices/nokia/qgeocodexmlparser.h +++ b/src/plugins/geoservices/nokia/qgeocodexmlparser.h @@ -49,29 +49,35 @@ #ifndef QGEOCODEXMLPARSER_H #define QGEOCODEXMLPARSER_H -#include <QString> -#include <QList> -#include <QScopedPointer> +#include <QtCore/QObject> +#include <QtCore/QRunnable> +#include <QtCore/QString> +#include <QtCore/QList> +#include <QtPositioning/QGeoShape> QT_BEGIN_NAMESPACE -class QIODevice; class QGeoLocation; class QGeoAddress; class QGeoRectangle; class QGeoCoordinate; class QXmlStreamReader; -class QGeoCodeXmlParser +class QGeoCodeXmlParser : public QObject, public QRunnable { + Q_OBJECT + public: QGeoCodeXmlParser(); ~QGeoCodeXmlParser(); - bool parse(QIODevice *source); + void setBounds(const QGeoShape &bounds); + void parse(const QByteArray &data); + void run(); - QList<QGeoLocation> results() const; - QString errorString() const; +signals: + void results(const QList<QGeoLocation> &locations); + void error(const QString &errorString); private: bool parseRootElement(); @@ -81,7 +87,9 @@ private: bool parseBoundingBox(QGeoRectangle *bounds); bool parseCoordinate(QGeoCoordinate *coordinate, const QString &elementName); - QScopedPointer<QXmlStreamReader> m_reader; + QGeoShape m_bounds; + QByteArray m_data; + QXmlStreamReader *m_reader; QList<QGeoLocation> m_results; QString m_errorString; |