diff options
28 files changed, 298 insertions, 224 deletions
diff --git a/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.cpp index 6f0ad05e..2308ba96 100644 --- a/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.cpp +++ b/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.cpp @@ -121,26 +121,6 @@ int QDeclarativePlaceContentModel::totalCount() const /*! \internal -*/ -static QPair<int, int> findMissingKey(const QMap<int, QPlaceContent> &map) -{ - int start = 0; - while (map.contains(start)) - ++start; - - QMap<int, QPlaceContent>::const_iterator it = map.lowerBound(start); - if (it == map.end()) - return qMakePair(start, -1); - - int end = start; - while (!map.contains(end)) - ++end; - - return qMakePair(start, end - 1); -} - -/*! - \internal Clears the model data but does not reset it. */ void QDeclarativePlaceContentModel::clearData() @@ -160,6 +140,8 @@ void QDeclarativePlaceContentModel::clearData() m_reply->deleteLater(); m_reply = 0; } + + m_nextRequest.clear(); } /*! @@ -288,22 +270,17 @@ void QDeclarativePlaceContentModel::fetchMore(const QModelIndex &parent) if (!placeManager) return; - QPlaceContentRequest request; - request.setContentType(m_type); - - if (m_contentCount == -1) { - request.setOffset(0); + if (m_nextRequest == QPlaceContentRequest()) { + QPlaceContentRequest request; + request.setContentType(m_type); + request.setPlaceId(m_place->place().placeId()); request.setLimit(m_batchSize); + + m_reply = placeManager->getPlaceContent(request); } else { - QPair<int, int> missing = findMissingKey(m_content); - request.setOffset(missing.first); - if (missing.second == -1) - request.setLimit(m_batchSize); - else - request.setLimit(qMin(m_batchSize, missing.second - missing.first + 1)); + m_reply = placeManager->getPlaceContent(m_nextRequest); } - m_reply = placeManager->getPlaceContent(m_place->place().placeId(), request); connect(m_reply, SIGNAL(finished()), this, SLOT(fetchFinished()), Qt::QueuedConnection); } @@ -334,6 +311,8 @@ void QDeclarativePlaceContentModel::fetchFinished() QPlaceContentReply *reply = m_reply; m_reply = 0; + m_nextRequest = reply->nextPageRequest(); + if (m_contentCount != reply->totalCount()) { m_contentCount = reply->totalCount(); emit totalCountChanged(); @@ -409,6 +388,12 @@ void QDeclarativePlaceContentModel::fetchFinished() startIndex = -1; } } + + // The fetch didn't add any new content and we haven't fetched all content yet. This is + // likely due to the model being prepopulated by Place::getDetails(). Keep fetching more + // data until new content is available. + if (newIndexes.isEmpty() && m_content.count() != m_contentCount) + fetchMore(QModelIndex()); } reply->deleteLater(); diff --git a/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.h b/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.h index 930726cb..b5a8a56d 100644 --- a/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.h +++ b/src/imports/location/declarativeplaces/qdeclarativeplacecontentmodel.h @@ -120,6 +120,7 @@ private: int m_contentCount; QPlaceContentReply *m_reply; + QPlaceContentRequest m_nextRequest; bool m_complete; }; diff --git a/src/location/doc/snippets/places/requesthandler.h b/src/location/doc/snippets/places/requesthandler.h index 8771d294..e18b6276 100644 --- a/src/location/doc/snippets/places/requesthandler.h +++ b/src/location/doc/snippets/places/requesthandler.h @@ -122,9 +122,9 @@ public: //! [Image request] QPlaceContentRequest request; request.setContentType(QPlaceContent::ImageType); - request.setOffset(0); + request.setPlaceId(place.placeId()); request.setLimit(5); - /*QPlaceContentReply * */ contentReply = manager->getPlaceContent(place.placeId(), request); + /*QPlaceContentReply * */ contentReply = manager->getPlaceContent(request); connect(contentReply, SIGNAL(finished()), this, SLOT(handleImagesReply())); //! [Image request] } @@ -235,10 +235,10 @@ public: //! [Content request] QPlaceContentRequest request; request.setContentType(QPlaceContent::ImageType); - request.setOffset(9); + request.setPlaceId(place.placeId()); request.setLimit(5); - QPlaceContentReply *contentReply = manager->getPlaceContent(place.placeId(), request); + QPlaceContentReply *contentReply = manager->getPlaceContent(request); //..connect signals..// //! [Content request] diff --git a/src/location/places/qplacecontentreply.cpp b/src/location/places/qplacecontentreply.cpp index 23252ea0..3b7d40f2 100644 --- a/src/location/places/qplacecontentreply.cpp +++ b/src/location/places/qplacecontentreply.cpp @@ -53,6 +53,8 @@ public: QPlaceContent::Collection contentCollection; int totalCount; QPlaceContentRequest contentRequest; + QPlaceContentRequest previousPageRequest; + QPlaceContentRequest nextPageRequest; }; QT_END_NAMESPACE @@ -145,6 +147,26 @@ QPlaceContentRequest QPlaceContentReply::request() const } /*! + Returns a place content request that can be used to request the previous batch of place content + results. +*/ +QPlaceContentRequest QPlaceContentReply::previousPageRequest() const +{ + Q_D(const QPlaceContentReply); + return d->previousPageRequest; +} + +/*! + Returns a place content request that can be used to request the next batch of place content + results. +*/ +QPlaceContentRequest QPlaceContentReply::nextPageRequest() const +{ + Q_D(const QPlaceContentReply); + return d->nextPageRequest; +} + +/*! Sets the content \a request used to generate this this reply. */ void QPlaceContentReply::setRequest(const QPlaceContentRequest &request) @@ -152,3 +174,23 @@ void QPlaceContentReply::setRequest(const QPlaceContentRequest &request) Q_D(QPlaceContentReply); d->contentRequest = request; } + +/*! + Sets the place content request that can be used to request the previous batch of place content + results to \a previous. +*/ +void QPlaceContentReply::setPreviousPageRequest(const QPlaceContentRequest &previous) +{ + Q_D(QPlaceContentReply); + d->previousPageRequest = previous; +} + +/*! + Sets the place content request that can be used to request the next batch of place content + results to \a next. +*/ +void QPlaceContentReply::setNextPageRequest(const QPlaceContentRequest &next) +{ + Q_D(QPlaceContentReply); + d->nextPageRequest = next; +} diff --git a/src/location/places/qplacecontentreply.h b/src/location/places/qplacecontentreply.h index 8d781a46..dcdcddc4 100644 --- a/src/location/places/qplacecontentreply.h +++ b/src/location/places/qplacecontentreply.h @@ -65,10 +65,15 @@ public: QPlaceContentRequest request() const; + QPlaceContentRequest previousPageRequest() const; + QPlaceContentRequest nextPageRequest() const; + protected: void setContent(const QPlaceContent::Collection &content); void setTotalCount(int total); void setRequest(const QPlaceContentRequest &request); + void setPreviousPageRequest(const QPlaceContentRequest &previous); + void setNextPageRequest(const QPlaceContentRequest &next); private: Q_DISABLE_COPY(QPlaceContentReply) diff --git a/src/location/places/qplacecontentrequest.cpp b/src/location/places/qplacecontentrequest.cpp index 1353ada4..9ad82149 100644 --- a/src/location/places/qplacecontentrequest.cpp +++ b/src/location/places/qplacecontentrequest.cpp @@ -46,14 +46,13 @@ QT_BEGIN_NAMESPACE QPlaceContentRequestPrivate::QPlaceContentRequestPrivate() - : QSharedData(), contentType(QPlaceContent::NoType), - limit(-1), offset(0) +: QSharedData(), contentType(QPlaceContent::NoType), limit(-1) { } QPlaceContentRequestPrivate::QPlaceContentRequestPrivate(const QPlaceContentRequestPrivate &other) - : QSharedData(other), contentType(other.contentType), - limit(other.limit), offset(other.offset) +: QSharedData(other), contentType(other.contentType), placeId(other.placeId), + contentContext(other.contentContext), limit(other.limit) { } @@ -64,15 +63,13 @@ QPlaceContentRequestPrivate::~QPlaceContentRequestPrivate() bool QPlaceContentRequestPrivate::operator==(const QPlaceContentRequestPrivate &other) const { return contentType == other.contentType - && limit == other.limit - && offset == other.offset; + && limit == other.limit; } void QPlaceContentRequestPrivate::clear() { contentType = QPlaceContent::NoType; limit = -1; - offset = 0; } /*! @@ -171,48 +168,75 @@ void QPlaceContentRequest::setContentType(QPlaceContent::Type type) } /*! - Returns the maximum number of content items to retrieve. + Returns the identifier of the place content is to be fetched for. +*/ +QString QPlaceContentRequest::placeId() const +{ + Q_D(const QPlaceContentRequest); + return d->placeId; +} - A negative value for limit means that it is undefined. It is left up to the backend - provider to choose an appropriate number of items to return. +/*! + Sets the identifier of the place to fetch content for to \a identifier. +*/ +void QPlaceContentRequest::setPlaceId(const QString &identifier) +{ + Q_D(QPlaceContentRequest); + d->placeId = identifier; +} - The default limit is -1. +/*! + Returns backend specific additional content context associated with this place content request. */ -int QPlaceContentRequest::limit() const +QVariant QPlaceContentRequest::contentContext() const { Q_D(const QPlaceContentRequest); - return d->limit; + return d->contentContext; } /*! - Set the maximum number of content items to retrieve to - \a limit. + Sets the content context to \a context. + + \note This method is intended to be used by geo service plugins when returning place content + results. + + The content context is used by backends to store additional content context related to the + content request. Other relevant fields should also be filled in. For example, if the content + request is for image content the content type should also be set with \l setContentType(). The + content context allows additional context to be kept which is not directly accessible via the + Qt Location API. + + The content context can be of any type storable in a QVariant. The value of the content context + is not intended to be used directly by applications. */ -void QPlaceContentRequest::setLimit(int limit) +void QPlaceContentRequest::setContentContext(const QVariant &context) { Q_D(QPlaceContentRequest); - d->limit = limit; + d->contentContext = context; } /*! - Returns the offset index of the first item that is to be retrieved. + Returns the maximum number of content items to retrieve. - The default offset is 0. + A negative value for limit means that it is undefined. It is left up to the backend + provider to choose an appropriate number of items to return. + + The default limit is -1. */ -int QPlaceContentRequest::offset() const +int QPlaceContentRequest::limit() const { Q_D(const QPlaceContentRequest); - return d->offset; + return d->limit; } /*! - Sets the starting index of the first item to be retrieved - to \a offset. + Set the maximum number of content items to retrieve to + \a limit. */ -void QPlaceContentRequest::setOffset(int offset) +void QPlaceContentRequest::setLimit(int limit) { Q_D(QPlaceContentRequest); - d->offset = offset; + d->limit = limit; } /*! diff --git a/src/location/places/qplacecontentrequest.h b/src/location/places/qplacecontentrequest.h index b535a133..164c4df9 100644 --- a/src/location/places/qplacecontentrequest.h +++ b/src/location/places/qplacecontentrequest.h @@ -65,8 +65,12 @@ public: QPlaceContent::Type contentType() const; void setContentType(QPlaceContent::Type type); - int offset() const; - void setOffset(int offset); + QString placeId() const; + void setPlaceId(const QString &identifier); + + QVariant contentContext() const; + void setContentContext(const QVariant &context); + int limit() const; void setLimit(int limit); diff --git a/src/location/places/qplacecontentrequest_p.h b/src/location/places/qplacecontentrequest_p.h index 05fb580b..213bdb58 100644 --- a/src/location/places/qplacecontentrequest_p.h +++ b/src/location/places/qplacecontentrequest_p.h @@ -43,7 +43,8 @@ #define QPLACECONTENTREQUEST_P_H #include <QtCore/QSharedData> -#include "qplacecontent.h" +#include <QtCore/QVariant> +#include <QtLocation/QPlaceContent> QT_BEGIN_NAMESPACE @@ -60,8 +61,9 @@ public: void clear(); QPlaceContent::Type contentType; + QString placeId; + QVariant contentContext; int limit; - int offset; }; QT_END_NAMESPACE diff --git a/src/location/places/qplacemanager.cpp b/src/location/places/qplacemanager.cpp index d0e91312..863e8adc 100644 --- a/src/location/places/qplacemanager.cpp +++ b/src/location/places/qplacemanager.cpp @@ -208,14 +208,13 @@ QPlaceDetailsReply *QPlaceManager::getPlaceDetails(const QString &placeId) const } /*! - Retrieves content for the place corresponding to \a placeId, according to the parameters specified in - \a request. + Retrieves content for a place according to the parameters specified in \a request. See \l {Fetching Rich Content} for an example of usage. */ -QPlaceContentReply *QPlaceManager::getPlaceContent(const QString &placeId, const QPlaceContentRequest &request) const +QPlaceContentReply *QPlaceManager::getPlaceContent(const QPlaceContentRequest &request) const { - return d->getPlaceContent(placeId, request); + return d->getPlaceContent(request); } /*! diff --git a/src/location/places/qplacemanager.h b/src/location/places/qplacemanager.h index 786fdc1d..a29e5ea6 100644 --- a/src/location/places/qplacemanager.h +++ b/src/location/places/qplacemanager.h @@ -76,7 +76,7 @@ public: QPlaceDetailsReply *getPlaceDetails(const QString &placeId) const; - QPlaceContentReply *getPlaceContent(const QString &placeId, const QPlaceContentRequest &request) const; + QPlaceContentReply *getPlaceContent(const QPlaceContentRequest &request) const; QPlaceSearchReply *search(const QPlaceSearchRequest &query) const; diff --git a/src/location/places/qplacemanagerengine.cpp b/src/location/places/qplacemanagerengine.cpp index 89bf6100..74d96f0f 100644 --- a/src/location/places/qplacemanagerengine.cpp +++ b/src/location/places/qplacemanagerengine.cpp @@ -151,13 +151,10 @@ QPlaceDetailsReply *QPlaceManagerEngine::getPlaceDetails(const QString &placeId) } /*! - Retrieves content for the place corresponding to \a placeId, according to the parameters - specified in \a request. + Retrieves content for a place according to the parameters specified in \a request. */ -QPlaceContentReply *QPlaceManagerEngine::getPlaceContent(const QString &placeId, - const QPlaceContentRequest &request) +QPlaceContentReply *QPlaceManagerEngine::getPlaceContent(const QPlaceContentRequest &request) { - Q_UNUSED(placeId) Q_UNUSED(request) return new QPlaceContentReplyUnsupported(this); diff --git a/src/location/places/qplacemanagerengine.h b/src/location/places/qplacemanagerengine.h index 13512955..0eefa7ca 100644 --- a/src/location/places/qplacemanagerengine.h +++ b/src/location/places/qplacemanagerengine.h @@ -66,8 +66,7 @@ public: virtual QPlaceDetailsReply *getPlaceDetails(const QString &placeId); - virtual QPlaceContentReply *getPlaceContent(const QString &placeId, - const QPlaceContentRequest &request); + virtual QPlaceContentReply *getPlaceContent(const QPlaceContentRequest &request); virtual QPlaceSearchReply *search(const QPlaceSearchRequest &request); diff --git a/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.cpp b/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.cpp index 1a18d15d..ac294d6e 100644 --- a/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.cpp +++ b/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.cpp @@ -200,6 +200,7 @@ QPlaceEditorial parseEditorial(const QJsonObject &editorialObject, void parseCollection(QPlaceContent::Type type, const QJsonObject &object, QPlaceContent::Collection *collection, int *totalCount, + QPlaceContentRequest *previous, QPlaceContentRequest *next, const QPlaceManagerEngineNokiaV2 *engine) { Q_ASSERT(engine); @@ -211,6 +212,16 @@ void parseCollection(QPlaceContent::Type type, const QJsonObject &object, if (object.contains(QLatin1String("offset"))) offset = object.value(QLatin1String("offset")).toDouble(); + if (previous && object.contains(QStringLiteral("previous"))) { + previous->setContentType(type); + previous->setContentContext(QUrl(object.value(QStringLiteral("previous")).toString())); + } + + if (next && object.contains(QStringLiteral("next"))) { + next->setContentType(type); + next->setContentContext(QUrl(object.value(QStringLiteral("next")).toString())); + } + if (collection) { QJsonArray items = object.value(QLatin1String("items")).toArray(); for (int i = 0; i < items.count(); ++i) { diff --git a/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.h b/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.h index 092addb9..ef01de19 100644 --- a/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.h +++ b/src/plugins/geoservices/nokia/placesv2/jsonparserhelpers.h @@ -54,6 +54,7 @@ class QPlaceImage; class QPlaceReview; class QPlaceEditorial; class QPlaceCategory; +class QPlaceContentRequest; class QPlaceManagerEngineNokiaV2; QGeoCoordinate parseCoordinate(const QJsonArray &coordinateArray); @@ -74,6 +75,7 @@ QPlaceEditorial parseEditorial(const QJsonObject &editorialObject, void parseCollection(QPlaceContent::Type type, const QJsonObject &object, QPlaceContent::Collection *collection, int *totalCount, + QPlaceContentRequest *previous, QPlaceContentRequest *next, const QPlaceManagerEngineNokiaV2 *engine); QT_END_NAMESPACE diff --git a/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp b/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp index e47bd4d5..1b5a1776 100644 --- a/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp +++ b/src/plugins/geoservices/nokia/placesv2/qplacecontentreplyimpl.cpp @@ -94,22 +94,29 @@ void QPlaceContentReplyImpl::setError(QPlaceReply::Error error_, const QString & void QPlaceContentReplyImpl::replyFinished() { - QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll()); - if (!document.isObject()) { - setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR)); - return; + if (m_reply->isOpen()) { + QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll()); + if (!document.isObject()) { + setError(ParseError, QCoreApplication::translate(NOKIA_PLUGIN_CONTEXT_NAME, PARSE_ERROR)); + return; + } + + QJsonObject object = document.object(); + + QPlaceContent::Collection collection; + int totalCount; + QPlaceContentRequest previous; + QPlaceContentRequest next; + + parseCollection(request().contentType(), object, &collection, &totalCount, + &previous, &next, m_engine); + + setTotalCount(totalCount); + setContent(collection); + setPreviousPageRequest(previous); + setNextPageRequest(next); } - QJsonObject object = document.object(); - - QPlaceContent::Collection collection; - int totalCount; - - parseCollection(request().contentType(), object, &collection, &totalCount, m_engine); - - setTotalCount(totalCount); - setContent(collection); - m_reply->deleteLater(); m_reply = 0; diff --git a/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp b/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp index fda0c776..a5386341 100644 --- a/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp +++ b/src/plugins/geoservices/nokia/placesv2/qplacedetailsreplyimpl.cpp @@ -307,7 +307,7 @@ void QPlaceDetailsReplyImpl::replyFinished() parseCollection(QPlaceContent::ImageType, mediaObject.value(QLatin1String("images")).toObject(), - &collection, &totalCount, m_engine); + &collection, &totalCount, 0, 0, m_engine); place.setTotalContentCount(QPlaceContent::ImageType, totalCount); place.setContent(QPlaceContent::ImageType, collection); @@ -318,7 +318,7 @@ void QPlaceDetailsReplyImpl::replyFinished() parseCollection(QPlaceContent::EditorialType, mediaObject.value(QLatin1String("editorials")).toObject(), - &collection, &totalCount, m_engine); + &collection, &totalCount, 0, 0, m_engine); place.setTotalContentCount(QPlaceContent::EditorialType, totalCount); place.setContent(QPlaceContent::EditorialType, collection); @@ -329,7 +329,7 @@ void QPlaceDetailsReplyImpl::replyFinished() parseCollection(QPlaceContent::ReviewType, mediaObject.value(QLatin1String("reviews")).toObject(), - &collection, &totalCount, m_engine); + &collection, &totalCount, 0, 0, m_engine); place.setTotalContentCount(QPlaceContent::ReviewType, totalCount); place.setContent(QPlaceContent::ReviewType, collection); diff --git a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp index c0b265d2..5543d001 100644 --- a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp +++ b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp @@ -261,75 +261,63 @@ QPlaceDetailsReply *QPlaceManagerEngineNokiaV2::getPlaceDetails(const QString &p return reply; } -QPlaceContentReply *QPlaceManagerEngineNokiaV2::getPlaceContent(const QString &placeId, - const QPlaceContentRequest &request) +QPlaceContentReply *QPlaceManagerEngineNokiaV2::getPlaceContent(const QPlaceContentRequest &request) { - QUrl requestUrl(QString::fromLatin1("http://") + m_uriProvider->getCurrentHost() + - QLatin1String("/places/v1/places/") + placeId + QLatin1String("/media/")); - QNetworkReply *networkReply = 0; - QUrlQuery queryItems; + if (request.contentContext().userType() == qMetaTypeId<QUrl>()) { + QUrl u = request.contentContext().value<QUrl>(); - switch (request.contentType()) { - case QPlaceContent::ImageType: - requestUrl.setPath(requestUrl.path() + QLatin1String("images")); + networkReply = sendRequest(u); + } else { + QUrl requestUrl(QString::fromLatin1("http://") + m_uriProvider->getCurrentHost() + + QLatin1String("/places/v1/places/") + request.placeId() + + QLatin1String("/media/")); - queryItems.addQueryItem(QLatin1String("tf"), QLatin1String("html")); + QUrlQuery queryItems; - if (request.limit() > 0) { - queryItems.addQueryItem(QLatin1String("size"), - QString::number(request.limit())); - } - if (request.offset() > -1) { - queryItems.addQueryItem(QLatin1String("offset"), - QString::number(request.offset())); - } + switch (request.contentType()) { + case QPlaceContent::ImageType: + requestUrl.setPath(requestUrl.path() + QLatin1String("images")); - //queryItems.append(qMakePair<QString, QString>(QLatin1String("image_dimensions"), QLatin1String("w64-h64,w100"))); + queryItems.addQueryItem(QLatin1String("tf"), QLatin1String("html")); - requestUrl.setQuery(queryItems); + if (request.limit() > 0) + queryItems.addQueryItem(QLatin1String("size"), QString::number(request.limit())); - networkReply = sendRequest(requestUrl); - break; - case QPlaceContent::ReviewType: - requestUrl.setPath(requestUrl.path() + QLatin1String("reviews")); + //queryItems.append(qMakePair<QString, QString>(QLatin1String("image_dimensions"), QLatin1String("w64-h64,w100"))); - queryItems.addQueryItem(QLatin1String("tf"), QLatin1String("html")); + requestUrl.setQuery(queryItems); - if (request.limit() > 0) { - queryItems.addQueryItem(QLatin1String("size"), - QString::number(request.limit())); - } - if (request.offset() > -1) { - queryItems.addQueryItem(QLatin1String("offset"), - QString::number(request.offset())); - } + networkReply = sendRequest(requestUrl); + break; + case QPlaceContent::ReviewType: + requestUrl.setPath(requestUrl.path() + QLatin1String("reviews")); - requestUrl.setQuery(queryItems); + queryItems.addQueryItem(QLatin1String("tf"), QLatin1String("html")); - networkReply = sendRequest(requestUrl); - break; - case QPlaceContent::EditorialType: - requestUrl.setPath(requestUrl.path() + QLatin1String("editorials")); + if (request.limit() > 0) + queryItems.addQueryItem(QLatin1String("size"), QString::number(request.limit())); - queryItems.addQueryItem(QLatin1String("tf"), QLatin1String("html")); + requestUrl.setQuery(queryItems); - if (request.limit() > 0) { - queryItems.addQueryItem(QLatin1String("size"), - QString::number(request.limit())); - } - if (request.offset() > -1) { - queryItems.addQueryItem(QLatin1String("offset"), - QString::number(request.offset())); - } + networkReply = sendRequest(requestUrl); + break; + case QPlaceContent::EditorialType: + requestUrl.setPath(requestUrl.path() + QLatin1String("editorials")); - requestUrl.setQuery(queryItems); + queryItems.addQueryItem(QLatin1String("tf"), QLatin1String("html")); - networkReply = sendRequest(requestUrl); - break; - case QPlaceContent::NoType: - ; + if (request.limit() > 0) + queryItems.addQueryItem(QLatin1String("size"), QString::number(request.limit())); + + requestUrl.setQuery(queryItems); + + networkReply = sendRequest(requestUrl); + break; + case QPlaceContent::NoType: + ; + } } QPlaceContentReply *reply = new QPlaceContentReplyImpl(request, networkReply, this); diff --git a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.h b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.h index fc26b1b5..c186d6bd 100644 --- a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.h +++ b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.h @@ -85,7 +85,7 @@ public: QPlaceDetailsReply *getPlaceDetails(const QString &placeId); - QPlaceContentReply *getPlaceContent(const QString &placeId, const QPlaceContentRequest &request); + QPlaceContentReply *getPlaceContent(const QPlaceContentRequest &request) Q_DECL_OVERRIDE; QPlaceSearchReply *search(const QPlaceSearchRequest &query); diff --git a/tests/auto/declarative_core/tst_editorialmodel.qml b/tests/auto/declarative_core/tst_editorialmodel.qml index 9c551972..ae01b4fd 100644 --- a/tests/auto/declarative_core/tst_editorialmodel.qml +++ b/tests/auto/declarative_core/tst_editorialmodel.qml @@ -93,7 +93,16 @@ TestCase { Utils.testObjectProperties(testCase, testModel, data); } - function test_consecutive_fetch() { + function test_consecutive_fetch_data() { + return [ + { tag: "batchSize 1", batchSize: 1 }, + { tag: "batchSize 2", batchSize: 2 }, + { tag: "batchSize 5", batchSize: 5 }, + { tag: "batchSize 10", batchSize: 10 }, + ]; + } + + function test_consecutive_fetch(data) { var expectedEditorials = [ { "title": "Editorial 1", @@ -123,7 +132,7 @@ TestCase { ] var model = createModel(); - Utils.testConsecutiveFetch(testCase, model, parkViewHotel, expectedEditorials); + Utils.testConsecutiveFetch(testCase, model, parkViewHotel, expectedEditorials, data); model.destroy(); } diff --git a/tests/auto/declarative_core/tst_imagemodel.qml b/tests/auto/declarative_core/tst_imagemodel.qml index afb596e4..31f1e448 100644 --- a/tests/auto/declarative_core/tst_imagemodel.qml +++ b/tests/auto/declarative_core/tst_imagemodel.qml @@ -93,7 +93,16 @@ TestCase { Utils.testObjectProperties(testCase, testModel, data); } - function test_consecutive_fetch() { + function test_consecutive_fetch_data() { + return [ + { tag: "batchSize 1", batchSize: 1 }, + { tag: "batchSize 2", batchSize: 2 }, + { tag: "batchSize 5", batchSize: 5 }, + { tag: "batchSize 10", batchSize: 10 }, + ]; + } + + function test_consecutive_fetch(data) { var expectedImages = [ { "url": "http://somewhere.com/image1.png", @@ -123,7 +132,7 @@ TestCase { ] var model = createModel(); - Utils.testConsecutiveFetch(testCase, model, parkViewHotel, expectedImages); + Utils.testConsecutiveFetch(testCase, model, parkViewHotel, expectedImages, data); model.destroy(); } diff --git a/tests/auto/declarative_core/tst_reviewmodel.qml b/tests/auto/declarative_core/tst_reviewmodel.qml index ca195077..62a7ac5e 100644 --- a/tests/auto/declarative_core/tst_reviewmodel.qml +++ b/tests/auto/declarative_core/tst_reviewmodel.qml @@ -92,7 +92,16 @@ TestCase { Utils.testObjectProperties(testCase, testModel, data); } - function test_consecutive_fetch() { + function test_consecutive_fetch_data() { + return [ + { tag: "batchSize 1", batchSize: 1 }, + { tag: "batchSize 2", batchSize: 2 }, + { tag: "batchSize 5", batchSize: 5 }, + { tag: "batchSize 10", batchSize: 10 }, + ]; + } + + function test_consecutive_fetch(data) { //Note: in javascript the months go from 0(Jan) to 11(Dec) var expectedReviews = [ { @@ -138,7 +147,7 @@ TestCase { ] var model = createModel(); - Utils.testConsecutiveFetch(testCase, model, parkViewHotel, expectedReviews); + Utils.testConsecutiveFetch(testCase, model, parkViewHotel, expectedReviews, data); model.destroy(); } diff --git a/tests/auto/declarative_core/utils.js b/tests/auto/declarative_core/utils.js index 0a659ab2..5370bab5 100644 --- a/tests/auto/declarative_core/utils.js +++ b/tests/auto/declarative_core/utils.js @@ -91,7 +91,7 @@ function compareObj(testCase, obj1, obj2) { } } -function testConsecutiveFetch(testCase, model, place, expectedValues) +function testConsecutiveFetch(testCase, model, place, expectedValues, data) { var signalSpy = Qt.createQmlObject('import QtTest 1.0; SignalSpy {}', testCase, "SignalSpy"); signalSpy.target = model; @@ -108,35 +108,31 @@ function testConsecutiveFetch(testCase, model, place, expectedValues) testCase.compare(visDataModel.items.count, 0); //perform an initial fetch with the default batch size + model.batchSize = data.batchSize model.place = place; testCase.tryCompare(signalSpy, "count", 1); signalSpy.clear(); var totalCount = model.totalCount; testCase.compare(totalCount, 5); - testCase.compare(visDataModel.items.count, 1); + testCase.compare(visDataModel.items.count, Math.min(data.batchSize, totalCount)); compareObj(testCase, visDataModel.items.get(0).model, expectedValues[0]); - //set a non-default batch size and fetch the next batch - model.batchSize = 2; - visDataModel.items.create(0); //'creating' the last item will trigger a fetch - testCase.tryCompare(visDataModel.items, "count", 3); - testCase.compare(signalSpy.count, 0); - testCase.compare(model.totalCount, totalCount); - - compareObj(testCase, visDataModel.items.get(1).model, expectedValues[1]); - compareObj(testCase, visDataModel.items.get(2).model, expectedValues[2]); - - //set a batch size greater than the number of remaining items and fetch that batch - model.batchSize = 10; - visDataModel.items.create(2); - testCase.tryCompare(visDataModel.items, "count", totalCount); - testCase.compare(signalSpy.count, 0); - testCase.compare(model.totalCount, totalCount); - - compareObj(testCase, visDataModel.items.get(3).model, expectedValues[3]); - compareObj(testCase, visDataModel.items.get(4).model, expectedValues[4]); + //fetch remaining items, in batchSize batches + while (visDataModel.items.count < totalCount) { + var startIndex = visDataModel.items.count + + //'creating' the last item will trigger a fetch + visDataModel.items.create(visDataModel.items.count - 1); + + testCase.tryCompare(visDataModel.items, "count", Math.min(totalCount, startIndex + data.batchSize)); + testCase.compare(signalSpy.count, 0); + testCase.compare(model.totalCount, totalCount); + + for (var i = startIndex; i < Math.min(totalCount, startIndex + data.batchSize); ++i) + compareObj(testCase, visDataModel.items.get(i).model, expectedValues[i]); + } visDataModel.destroy(); signalSpy.destroy(); diff --git a/tests/auto/geotestplugin/qplacemanagerengine_test.h b/tests/auto/geotestplugin/qplacemanagerengine_test.h index 816493d0..edcf09b7 100644 --- a/tests/auto/geotestplugin/qplacemanagerengine_test.h +++ b/tests/auto/geotestplugin/qplacemanagerengine_test.h @@ -363,10 +363,10 @@ public: return reply; } - QPlaceContentReply *getPlaceContent(const QString &placeId, const QPlaceContentRequest &query) + QPlaceContentReply *getPlaceContent(const QPlaceContentRequest &query) Q_DECL_OVERRIDE { ContentReply *reply = new ContentReply(this); - if (placeId.isEmpty() || !m_places.contains(placeId)) { + if (query.placeId().isEmpty() || !m_places.contains(query.placeId())) { reply->setError(QPlaceReply::PlaceDoesNotExistError, tr("Place does not exist")); QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); @@ -375,31 +375,33 @@ public: int totalCount = 0; switch (query.contentType()) { case QPlaceContent::ReviewType: - totalCount = m_placeReviews.value(placeId).count(); + totalCount = m_placeReviews.value(query.placeId()).count(); break; case QPlaceContent::ImageType: - totalCount = m_placeImages.value(placeId).count(); + totalCount = m_placeImages.value(query.placeId()).count(); break; case QPlaceContent::EditorialType: - totalCount = m_placeEditorials.value(placeId).count(); + totalCount = m_placeEditorials.value(query.placeId()).count(); default: //do nothing break; } - int offset = qMax(query.offset(), 0); + QVariantMap context = query.contentContext().toMap(); + + int offset = context.value(QStringLiteral("offset"), 0).toInt(); int max = (query.limit() == -1) ? totalCount : qMin(offset + query.limit(), totalCount); for (int i = offset; i < max; ++i) { switch (query.contentType()) { case QPlaceContent::ReviewType: - collection.insert(i, m_placeReviews.value(placeId).at(i)); + collection.insert(i, m_placeReviews.value(query.placeId()).at(i)); break; case QPlaceContent::ImageType: - collection.insert(i, m_placeImages.value(placeId).at(i)); + collection.insert(i, m_placeImages.value(query.placeId()).at(i)); break; case QPlaceContent::EditorialType: - collection.insert(i, m_placeEditorials.value(placeId).at(i)); + collection.insert(i, m_placeEditorials.value(query.placeId()).at(i)); default: //do nothing break; @@ -408,6 +410,21 @@ public: reply->setContent(collection); reply->setTotalCount(totalCount); + + if (max != totalCount) { + context.clear(); + context.insert(QStringLiteral("offset"), offset + query.limit()); + QPlaceContentRequest request = query; + request.setContentContext(context); + reply->setNextPageRequest(request); + } + if (offset > 0) { + context.clear(); + context.insert(QStringLiteral("offset"), qMin(0, offset - query.limit())); + QPlaceContentRequest request = query; + request.setContentContext(context); + reply->setPreviousPageRequest(request); + } } QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); diff --git a/tests/auto/nokia_services/places_semiauto/tst_places.cpp b/tests/auto/nokia_services/places_semiauto/tst_places.cpp index b22fa573..a0170144 100644 --- a/tests/auto/nokia_services/places_semiauto/tst_places.cpp +++ b/tests/auto/nokia_services/places_semiauto/tst_places.cpp @@ -597,9 +597,9 @@ void tst_QPlaceManagerNokia::content() //check fetching of content QPlaceContentRequest request; request.setContentType(type); + request.setPlaceId(ValidKnownPlaceId); QPlaceContent::Collection results; - QVERIFY(doFetchContent(ValidKnownPlaceId, - request, &results)); + QVERIFY(doFetchContent(request, &results)); QVERIFY(results.count() > 0); @@ -633,39 +633,18 @@ void tst_QPlaceManagerNokia::content() } //check total count - QPlaceContentReply *contentReply = - placeManager->getPlaceContent(ValidKnownPlaceId, - request); + QPlaceContentReply *contentReply = placeManager->getPlaceContent(request); QSignalSpy contentSpy(contentReply, SIGNAL(finished())); QTRY_VERIFY_WITH_TIMEOUT(contentSpy.count() ==1, Timeout); QVERIFY(contentReply->totalCount() > 0); if (contentReply->totalCount() >= 2) { - //try testing with an offset - request.setOffset(1); - QPlaceContent::Collection newResults; - QVERIFY(doFetchContent(ValidKnownPlaceId, - request, &newResults)); - QVERIFY(!newResults.keys().contains(0)); - QCOMPARE(newResults.value(1), results.value(1)); - //try testing with a limit - request.setOffset(0); request.setLimit(1); - QVERIFY(doFetchContent(ValidKnownPlaceId, - request, &newResults)); + QPlaceContent::Collection newResults; + QVERIFY(doFetchContent(request, &newResults)); QCOMPARE(newResults.count(), 1); QCOMPARE(newResults.values().first(), results.value(0)); - - //try testing both limit and offset - if (contentReply->totalCount() >= 3) { - request.setLimit(1); - request.setOffset(1); - QVERIFY(doFetchContent(ValidKnownPlaceId, - request, &newResults)); - QCOMPARE(newResults.count(), 1); - QCOMPARE(newResults.values().first(), results.value(1)); - } } } diff --git a/tests/auto/placemanager_utils/placemanager_utils.cpp b/tests/auto/placemanager_utils/placemanager_utils.cpp index 8934790a..205d0c39 100644 --- a/tests/auto/placemanager_utils/placemanager_utils.cpp +++ b/tests/auto/placemanager_utils/placemanager_utils.cpp @@ -244,13 +244,12 @@ bool PlaceManagerUtils::doFetchCategory(QPlaceManager *manager, } bool PlaceManagerUtils::doFetchContent(QPlaceManager *manager, - const QString &placeId, const QPlaceContentRequest &request, QPlaceContent::Collection *results, QPlaceReply::Error expectedError) { Q_ASSERT(results); - QPlaceContentReply *reply = manager->getPlaceContent(placeId, request); + QPlaceContentReply *reply = manager->getPlaceContent(request); bool isSuccessful = checkSignals(reply, expectedError, manager); *results = reply->content(); diff --git a/tests/auto/placemanager_utils/placemanager_utils.h b/tests/auto/placemanager_utils/placemanager_utils.h index 88a857e0..a8edede4 100644 --- a/tests/auto/placemanager_utils/placemanager_utils.h +++ b/tests/auto/placemanager_utils/placemanager_utils.h @@ -128,7 +128,6 @@ public: QPlaceReply::Error expectedError = QPlaceReply::NoError); static bool doFetchContent(QPlaceManager *manager, - const QString &placeId, const QPlaceContentRequest &request, QPlaceContent::Collection *results, QPlaceReply::Error expectedError = QPlaceReply::NoError); @@ -219,13 +218,11 @@ protected: category, expectedError); } - bool doFetchContent(const QString &placeId, - const QPlaceContentRequest &request, + bool doFetchContent(const QPlaceContentRequest &request, QPlaceContent::Collection *results, QPlaceReply::Error expectedError = QPlaceReply::NoError) { - return doFetchContent(placeManager, placeId, - request, results, expectedError); + return doFetchContent(placeManager, request, results, expectedError); } bool doMatch(const QPlaceMatchRequest &request, diff --git a/tests/auto/qplacecontentrequest/tst_qplacecontentrequest.cpp b/tests/auto/qplacecontentrequest/tst_qplacecontentrequest.cpp index 13bc2998..c5b72e35 100644 --- a/tests/auto/qplacecontentrequest/tst_qplacecontentrequest.cpp +++ b/tests/auto/qplacecontentrequest/tst_qplacecontentrequest.cpp @@ -66,25 +66,20 @@ void tst_QPlaceContentRequest::contentTest() { QPlaceContentRequest req; QCOMPARE(req.limit(), -1); - QCOMPARE(req.offset(), 0); QCOMPARE(req.contentType(), QPlaceContent::NoType); //check that we can set the request fields req.setLimit(100); - req.setOffset(5); req.setContentType(QPlaceContent::ImageType); QCOMPARE(req.limit(), 100); - QCOMPARE(req.offset(), 5); QCOMPARE(req.contentType(), QPlaceContent::ImageType); //check that we assignment works correctly QPlaceContentRequest otherReq; otherReq.setLimit(10); - otherReq.setOffset(15); otherReq.setContentType(QPlaceContent::ReviewType); req = otherReq; QCOMPARE(req.limit(), 10); - QCOMPARE(req.offset(), 15); QCOMPARE(req.contentType(), QPlaceContent::ReviewType); QCOMPARE(req, otherReq); @@ -98,11 +93,9 @@ void tst_QPlaceContentRequest::clearTest() QPlaceContentRequest req; req.setContentType(QPlaceContent::ReviewType); req.setLimit(9000); - req.setOffset(1); req.clear(); QVERIFY(req.contentType() == QPlaceContent::NoType); QVERIFY(req.limit() == -1); - QVERIFY(req.offset() == 0); } QTEST_APPLESS_MAIN(tst_QPlaceContentRequest) diff --git a/tests/auto/qplacemanager_unsupported/tst_qplacemanager_unsupported.cpp b/tests/auto/qplacemanager_unsupported/tst_qplacemanager_unsupported.cpp index f1615536..ad14db1e 100644 --- a/tests/auto/qplacemanager_unsupported/tst_qplacemanager_unsupported.cpp +++ b/tests/auto/qplacemanager_unsupported/tst_qplacemanager_unsupported.cpp @@ -149,7 +149,7 @@ void tst_QPlaceManagerUnsupported::testGetPlaceDetails() void tst_QPlaceManagerUnsupported::testGetPlaceContent() { - QPlaceContentReply *reply = m_manager->getPlaceContent(QString(), QPlaceContentRequest()); + QPlaceContentReply *reply = m_manager->getPlaceContent(QPlaceContentRequest()); if (!checkSignals(reply, QPlaceReply::UnsupportedError)) return; } |