| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the test suite of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #ifndef QPLACEMANAGERENGINE_TEST_H |
| #define QPLACEMANAGERENGINE_TEST_H |
| |
| #include <QtCore/QDateTime> |
| #include <QtCore/QFile> |
| #include <QtCore/QJsonDocument> |
| #include <QtCore/QJsonObject> |
| #include <QtCore/QJsonArray> |
| #include <QtCore/QUuid> |
| #include <QtPositioning/QGeoCoordinate> |
| #include <QtPositioning/QGeoLocation> |
| #include <QtLocation/QPlaceContentReply> |
| #include <QtLocation/QPlaceManager> |
| #include <QtLocation/QPlaceManagerEngine> |
| #include <QtLocation/QPlaceReply> |
| #include <QtLocation/QPlaceDetailsReply> |
| #include <QtLocation/QPlaceEditorial> |
| #include <QtLocation/QPlaceIdReply> |
| #include <QtLocation/QPlaceImage> |
| #include <QtLocation/QPlaceSearchSuggestionReply> |
| #include <QtLocation/QPlaceSearchReply> |
| #include <QtLocation/QPlaceResult> |
| #include <QtLocation/QPlaceCategory> |
| #include <QtLocation/QPlace> |
| #include <QtLocation/QPlaceReview> |
| #include <QtLocation/private/qplace_p.h> |
| #include <QtTest/QTest> |
| |
| QT_BEGIN_NAMESPACE |
| |
| inline uint qHash(const QPlaceCategory &category) |
| { |
| return qHash(QUuid(category.categoryId().toLatin1())); |
| } |
| |
| QT_END_NAMESPACE |
| |
| QT_USE_NAMESPACE |
| |
| class QPlacePrivateDefaultAlt : public QPlacePrivateDefault |
| { |
| public: |
| QPlacePrivateDefaultAlt() {} |
| QPlacePrivateDefaultAlt(const QPlacePrivateDefaultAlt &other) |
| : QPlacePrivateDefault(other) |
| { |
| } |
| ~QPlacePrivateDefaultAlt() {} |
| |
| QPlaceAttribute extendedAttribute(const QString &attributeType) const override |
| { |
| if (attributeType == QStringLiteral("x_provider")) { |
| QPlaceAttribute a; |
| a.setLabel(QStringLiteral("x_provider")); |
| a.setText(QStringLiteral("QPlacePrivateDefaultAlt")); |
| return a; |
| } else { |
| return QPlacePrivateDefault::extendedAttribute(attributeType); |
| } |
| } |
| }; |
| |
| class QPlaceAlt : public QPlace |
| { |
| public: |
| QPlaceAlt() : QPlace(QSharedDataPointer<QPlacePrivate>(new QPlacePrivateDefaultAlt())) |
| { |
| } |
| }; |
| |
| class PlaceReply : public QPlaceReply |
| { |
| Q_OBJECT |
| |
| friend class QPlaceManagerEngineTest; |
| |
| public: |
| PlaceReply(QObject *parent = 0) |
| : QPlaceReply(parent) |
| { } |
| |
| Q_INVOKABLE void emitFinished() |
| { |
| emit finished(); |
| } |
| }; |
| |
| class ContentReply : public QPlaceContentReply |
| { |
| Q_OBJECT |
| |
| friend class QPlaceManagerEngineTest; |
| |
| public: |
| ContentReply(QObject *parent = 0) |
| : QPlaceContentReply(parent) |
| {} |
| |
| Q_INVOKABLE void emitError() |
| { |
| emit error(error(), errorString()); |
| } |
| |
| Q_INVOKABLE void emitFinished() |
| { |
| emit finished(); |
| } |
| }; |
| |
| class DetailsReply : public QPlaceDetailsReply |
| { |
| Q_OBJECT |
| |
| friend class QPlaceManagerEngineTest; |
| |
| public: |
| DetailsReply(QObject *parent = 0) |
| : QPlaceDetailsReply(parent) |
| { } |
| |
| Q_INVOKABLE void emitError() |
| { |
| emit error(error(), errorString()); |
| } |
| |
| Q_INVOKABLE void emitFinished() |
| { |
| emit finished(); |
| } |
| }; |
| |
| class IdReply : public QPlaceIdReply |
| { |
| Q_OBJECT |
| |
| friend class QPlaceManagerEngineTest; |
| |
| public: |
| IdReply(QPlaceIdReply::OperationType type, QObject *parent = 0) |
| : QPlaceIdReply(type, parent) |
| { } |
| |
| Q_INVOKABLE void emitError() |
| { |
| emit error(error(), errorString()); |
| } |
| |
| Q_INVOKABLE void emitFinished() |
| { |
| emit finished(); |
| } |
| }; |
| |
| class PlaceSearchReply : public QPlaceSearchReply |
| { |
| Q_OBJECT |
| |
| public: |
| PlaceSearchReply(const QList<QPlaceSearchResult> &results, QObject *parent = 0) |
| : QPlaceSearchReply(parent) |
| { |
| setResults(results); |
| } |
| |
| Q_INVOKABLE void emitError() |
| { |
| emit error(error(), errorString()); |
| } |
| |
| Q_INVOKABLE void emitFinished() |
| { |
| emit finished(); |
| } |
| }; |
| |
| class SuggestionReply : public QPlaceSearchSuggestionReply |
| { |
| Q_OBJECT |
| |
| public: |
| SuggestionReply(const QStringList &suggestions, QObject *parent = 0) |
| : QPlaceSearchSuggestionReply(parent) |
| { |
| setSuggestions(suggestions); |
| } |
| |
| Q_INVOKABLE void emitError() |
| { |
| emit error(error(), errorString()); |
| } |
| |
| Q_INVOKABLE void emitFinished() |
| { |
| emit finished(); |
| } |
| }; |
| |
| class QPlaceManagerEngineTest : public QPlaceManagerEngine |
| { |
| Q_OBJECT |
| public: |
| QPlaceManagerEngineTest(const QVariantMap ¶meters) |
| : QPlaceManagerEngine(parameters) |
| { |
| m_locales << QLocale(); |
| if (parameters.value(QStringLiteral("initializePlaceData"), false).toBool()) { |
| QFile placeData(QFINDTESTDATA("place_data.json")); |
| QVERIFY(placeData.exists()); |
| if (placeData.open(QIODevice::ReadOnly)) { |
| QJsonDocument document = QJsonDocument::fromJson(placeData.readAll()); |
| |
| if (document.isObject()) { |
| QJsonObject o = document.object(); |
| |
| if (o.contains(QStringLiteral("categories"))) { |
| QJsonArray categories = o.value(QStringLiteral("categories")).toArray(); |
| |
| for (int i = 0; i < categories.count(); ++i) { |
| QJsonObject c = categories.at(i).toObject(); |
| |
| QPlaceCategory category; |
| |
| category.setName(c.value(QStringLiteral("name")).toString()); |
| category.setCategoryId(c.value(QStringLiteral("id")).toString()); |
| |
| m_categories.insert(category.categoryId(), category); |
| |
| const QString parentId = c.value(QStringLiteral("parentId")).toString(); |
| m_childCategories[parentId].append(category.categoryId()); |
| } |
| } |
| |
| if (o.contains(QStringLiteral("places"))) { |
| QJsonArray places = o.value(QStringLiteral("places")).toArray(); |
| |
| for (int i = 0; i < places.count(); ++i) { |
| QJsonObject p = places.at(i).toObject(); |
| |
| QPlace place; |
| if (p.value(QStringLiteral("alternateImplementation")).toBool(false)) { |
| place = QPlaceAlt(); |
| QPlaceAttribute att; |
| att.setLabel(QStringLiteral("x_provider")); |
| att.setText(QStringLiteral("42")); // Doesn't matter, wont be used. |
| place.setExtendedAttribute(QStringLiteral("x_provider"), att); |
| } |
| |
| place.setName(p.value(QStringLiteral("name")).toString()); |
| place.setPlaceId(p.value(QStringLiteral("id")).toString()); |
| |
| QList<QPlaceCategory> categories; |
| QJsonArray ca = p.value(QStringLiteral("categories")).toArray(); |
| for (int j = 0; j < ca.count(); ++j) { |
| QPlaceCategory c = m_categories.value(ca.at(j).toString()); |
| if (!c.isEmpty()) |
| categories.append(c); |
| } |
| place.setCategories(categories); |
| |
| QGeoCoordinate coordinate; |
| QJsonObject lo = p.value(QStringLiteral("location")).toObject(); |
| coordinate.setLatitude(lo.value(QStringLiteral("latitude")).toDouble()); |
| coordinate.setLongitude(lo.value(QStringLiteral("longitude")).toDouble()); |
| |
| QGeoLocation location; |
| location.setCoordinate(coordinate); |
| |
| place.setLocation(location); |
| |
| m_places.insert(place.placeId(), place); |
| |
| QStringList recommendations; |
| QJsonArray ra = p.value(QStringLiteral("recommendations")).toArray(); |
| for (int j = 0; j < ra.count(); ++j) |
| recommendations.append(ra.at(j).toString()); |
| m_placeRecommendations.insert(place.placeId(), recommendations); |
| |
| QJsonArray revArray = p.value(QStringLiteral("reviews")).toArray(); |
| QList<QPlaceReview> reviews; |
| for (int j = 0; j < revArray.count(); ++j) { |
| QJsonObject ro = revArray.at(j).toObject(); |
| QPlaceReview review; |
| if (ro.contains(QStringLiteral("title"))) |
| review.setTitle(ro.value(QStringLiteral("title")).toString()); |
| if (ro.contains(QStringLiteral("text"))) |
| review.setText(ro.value(QStringLiteral("text")).toString()); |
| |
| if (ro.contains(QStringLiteral("language"))) |
| review.setLanguage(ro.value("language").toString()); |
| |
| if (ro.contains(QStringLiteral("rating"))) |
| review.setRating(ro.value("rating").toDouble()); |
| |
| if (ro.contains(QStringLiteral("dateTime"))) |
| review.setDateTime(QDateTime::fromString( |
| ro.value(QStringLiteral("dateTime")).toString(), |
| QStringLiteral("hh:mm dd-MM-yyyy"))); |
| if (ro.contains(QStringLiteral("reviewId"))) |
| review.setReviewId(ro.value("reviewId").toString()); |
| |
| reviews << review; |
| } |
| m_placeReviews.insert(place.placeId(), reviews); |
| |
| QJsonArray imgArray = p.value(QStringLiteral("images")).toArray(); |
| QList<QPlaceImage> images; |
| for (int j = 0; j < imgArray.count(); ++j) { |
| QJsonObject imgo = imgArray.at(j).toObject(); |
| QPlaceImage image; |
| if (imgo.contains(QStringLiteral("url"))) |
| image.setUrl(imgo.value(QStringLiteral("url")).toString()); |
| |
| if (imgo.contains("imageId")) |
| image.setImageId(imgo.value(QStringLiteral("imageId")).toString()); |
| |
| if (imgo.contains("mimeType")) |
| image.setMimeType(imgo.value(QStringLiteral("mimeType")).toString()); |
| |
| images << image; |
| } |
| |
| m_placeImages.insert(place.placeId(), images); |
| |
| QJsonArray edArray = p.value(QStringLiteral("editorials")).toArray(); |
| QList<QPlaceEditorial> editorials; |
| for (int j = 0; j < edArray.count(); ++j) { |
| QJsonObject edo = edArray.at(j).toObject(); |
| QPlaceEditorial editorial; |
| if (edo.contains(QStringLiteral("title"))) |
| editorial.setTitle(edo.value(QStringLiteral("title")).toString()); |
| |
| if (edo.contains(QStringLiteral("text"))) |
| editorial.setText(edo.value(QStringLiteral("text")).toString()); |
| |
| if (edo.contains(QStringLiteral("language"))) |
| editorial.setLanguage(edo.value(QStringLiteral("language")).toString()); |
| |
| editorials << editorial; |
| } |
| |
| m_placeEditorials.insert(place.placeId(), editorials); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| QPlaceDetailsReply *getPlaceDetails(const QString &placeId) override |
| { |
| DetailsReply *reply = new DetailsReply(this); |
| |
| if (placeId.isEmpty() || !m_places.contains(placeId)) { |
| reply->setError(QPlaceReply::PlaceDoesNotExistError, tr("Place does not exist")); |
| QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); |
| } else { |
| reply->setPlace(m_places.value(placeId)); |
| } |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceContentReply *getPlaceContent(const QPlaceContentRequest &query) override |
| { |
| ContentReply *reply = new ContentReply(this); |
| if (query.placeId().isEmpty() || !m_places.contains(query.placeId())) { |
| reply->setError(QPlaceReply::PlaceDoesNotExistError, tr("Place does not exist")); |
| QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); |
| |
| } else { |
| QPlaceContent::Collection collection; |
| int totalCount = 0; |
| switch (query.contentType()) { |
| case QPlaceContent::ReviewType: |
| totalCount = m_placeReviews.value(query.placeId()).count(); |
| break; |
| case QPlaceContent::ImageType: |
| totalCount = m_placeImages.value(query.placeId()).count(); |
| break; |
| case QPlaceContent::EditorialType: |
| totalCount = m_placeEditorials.value(query.placeId()).count(); |
| default: |
| //do nothing |
| break; |
| } |
| |
| 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(query.placeId()).at(i)); |
| break; |
| case QPlaceContent::ImageType: |
| collection.insert(i, m_placeImages.value(query.placeId()).at(i)); |
| break; |
| case QPlaceContent::EditorialType: |
| collection.insert(i, m_placeEditorials.value(query.placeId()).at(i)); |
| default: |
| //do nothing |
| break; |
| } |
| } |
| |
| 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); |
| return reply; |
| } |
| |
| QPlaceSearchReply *search(const QPlaceSearchRequest &query) override |
| { |
| QList<QPlaceSearchResult> results; |
| |
| if (!query.searchTerm().isEmpty()) { |
| foreach (const QPlace &place, m_places) { |
| if (!place.name().contains(query.searchTerm(), Qt::CaseInsensitive)) |
| continue; |
| |
| QPlaceResult r; |
| r.setPlace(place); |
| r.setTitle(place.name()); |
| |
| results.append(r); |
| } |
| } else if (!query.categories().isEmpty()) { |
| const auto &categoryList = query.categories(); |
| const QSet<QPlaceCategory> categories(categoryList.cbegin(), categoryList.cend()); |
| for (const QPlace &place : qAsConst(m_places)) { |
| const auto &placeCategoryList = place.categories(); |
| const QSet<QPlaceCategory> placeCategories(placeCategoryList.cbegin(), placeCategoryList.cend()); |
| if (!placeCategories.intersects(categories)) |
| continue; |
| |
| QPlaceResult r; |
| r.setPlace(place); |
| r.setTitle(place.name()); |
| |
| results.append(r); |
| } |
| } else if (!query.recommendationId().isEmpty()) { |
| QStringList recommendations = m_placeRecommendations.value(query.recommendationId()); |
| foreach (const QString &id, recommendations) { |
| QPlaceResult r; |
| r.setPlace(m_places.value(id)); |
| r.setTitle(r.place().name()); |
| |
| results.append(r); |
| } |
| } |
| |
| PlaceSearchReply *reply = new PlaceSearchReply(results, this); |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceSearchSuggestionReply *searchSuggestions(const QPlaceSearchRequest &query) override |
| { |
| QStringList suggestions; |
| if (query.searchTerm() == QLatin1String("test")) { |
| suggestions << QStringLiteral("test1"); |
| suggestions << QStringLiteral("test2"); |
| suggestions << QStringLiteral("test3"); |
| } |
| |
| SuggestionReply *reply = new SuggestionReply(suggestions, this); |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceIdReply *savePlace(const QPlace &place) override |
| { |
| IdReply *reply = new IdReply(QPlaceIdReply::SavePlace, this); |
| |
| if (!place.placeId().isEmpty() && !m_places.contains(place.placeId())) { |
| reply->setError(QPlaceReply::PlaceDoesNotExistError, tr("Place does not exist")); |
| QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); |
| } else if (!place.placeId().isEmpty()) { |
| m_places.insert(place.placeId(), place); |
| reply->setId(place.placeId()); |
| } else { |
| QPlace p = place; |
| p.setPlaceId(QUuid::createUuid().toString()); |
| m_places.insert(p.placeId(), p); |
| |
| reply->setId(p.placeId()); |
| } |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceIdReply *removePlace(const QString &placeId) override |
| { |
| IdReply *reply = new IdReply(QPlaceIdReply::RemovePlace, this); |
| reply->setId(placeId); |
| |
| if (!m_places.contains(placeId)) { |
| reply->setError(QPlaceReply::PlaceDoesNotExistError, tr("Place does not exist")); |
| QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); |
| } else { |
| m_places.remove(placeId); |
| } |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceIdReply *saveCategory(const QPlaceCategory &category, const QString &parentId) override |
| { |
| IdReply *reply = new IdReply(QPlaceIdReply::SaveCategory, this); |
| |
| if ((!category.categoryId().isEmpty() && !m_categories.contains(category.categoryId())) || |
| (!parentId.isEmpty() && !m_categories.contains(parentId))) { |
| reply->setError(QPlaceReply::CategoryDoesNotExistError, tr("Category does not exist")); |
| QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); |
| } else if (!category.categoryId().isEmpty()) { |
| m_categories.insert(category.categoryId(), category); |
| QStringList children = m_childCategories.value(parentId); |
| |
| for (QStringList &c : m_childCategories) |
| c.removeAll(category.categoryId()); |
| |
| if (!children.contains(category.categoryId())) { |
| children.append(category.categoryId()); |
| m_childCategories.insert(parentId, children); |
| } |
| reply->setId(category.categoryId()); |
| } else { |
| QPlaceCategory c = category; |
| c.setCategoryId(QUuid::createUuid().toString()); |
| m_categories.insert(c.categoryId(), c); |
| QStringList children = m_childCategories.value(parentId); |
| if (!children.contains(c.categoryId())) { |
| children.append(c.categoryId()); |
| m_childCategories.insert(parentId, children); |
| } |
| |
| reply->setId(c.categoryId()); |
| } |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceIdReply *removeCategory(const QString &categoryId) override |
| { |
| IdReply *reply = new IdReply(QPlaceIdReply::RemoveCategory, this); |
| reply->setId(categoryId); |
| |
| if (!m_categories.contains(categoryId)) { |
| reply->setError(QPlaceReply::CategoryDoesNotExistError, tr("Category does not exist")); |
| QMetaObject::invokeMethod(reply, "emitError", Qt::QueuedConnection); |
| } else { |
| m_categories.remove(categoryId); |
| |
| for (auto &c : m_childCategories) |
| c.removeAll(categoryId); |
| } |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QPlaceReply *initializeCategories() override |
| { |
| QPlaceReply *reply = new PlaceReply(this); |
| |
| QMetaObject::invokeMethod(reply, "emitFinished", Qt::QueuedConnection); |
| |
| return reply; |
| } |
| |
| QString parentCategoryId(const QString &categoryId) const override |
| { |
| for (auto i = m_childCategories.cbegin(), end = m_childCategories.cend(); i != end; ++i) { |
| if (i.value().contains(categoryId)) |
| return i.key(); |
| } |
| |
| return QString(); |
| } |
| |
| virtual QStringList childCategoryIds(const QString &categoryId) const override |
| { |
| return m_childCategories.value(categoryId); |
| } |
| |
| virtual QPlaceCategory category(const QString &categoryId) const override |
| { |
| return m_categories.value(categoryId); |
| } |
| |
| QList<QPlaceCategory> childCategories(const QString &parentId) const override |
| { |
| QList<QPlaceCategory> categories; |
| |
| foreach (const QString &id, m_childCategories.value(parentId)) |
| categories.append(m_categories.value(id)); |
| |
| return categories; |
| } |
| |
| QList<QLocale> locales() const override |
| { |
| return m_locales; |
| } |
| |
| void setLocales(const QList<QLocale> &locales) override |
| { |
| m_locales = locales; |
| } |
| |
| QUrl constructIconUrl(const QPlaceIcon &icon, const QSize &size) const override |
| { |
| QList<QPair<int, QUrl> > candidates; |
| |
| QMap<QString, int> sizeDictionary; |
| sizeDictionary.insert(QStringLiteral("s"), 20); |
| sizeDictionary.insert(QStringLiteral("m"), 30); |
| sizeDictionary.insert(QStringLiteral("l"), 50); |
| |
| QStringList sizeKeys; |
| sizeKeys << QStringLiteral("s") << QStringLiteral("m") << QStringLiteral("l"); |
| |
| foreach (const QString &sizeKey, sizeKeys) |
| { |
| if (icon.parameters().contains(sizeKey)) |
| candidates.append(QPair<int, QUrl>(sizeDictionary.value(sizeKey), |
| icon.parameters().value(sizeKey).toUrl())); |
| } |
| |
| if (candidates.isEmpty()) |
| return QUrl(); |
| else if (candidates.count() == 1) { |
| return candidates.first().second; |
| } else { |
| //we assume icons are squarish so we can use height to |
| //determine which particular icon to return |
| int requestedHeight = size.height(); |
| |
| for (int i = 0; i < candidates.count() - 1; ++i) { |
| int thresholdHeight = (candidates.at(i).first + candidates.at(i+1).first) / 2; |
| if (requestedHeight < thresholdHeight) |
| return candidates.at(i).second; |
| } |
| return candidates.last().second; |
| } |
| } |
| |
| QPlace compatiblePlace(const QPlace &original) const override |
| { |
| QPlace place; |
| place.setName(original.name()); |
| return place; |
| } |
| |
| private: |
| QList<QLocale> m_locales; |
| QHash<QString, QPlace> m_places; |
| QHash<QString, QPlaceCategory> m_categories; |
| QHash<QString, QStringList> m_childCategories; |
| QHash<QString, QStringList> m_placeRecommendations; |
| QHash<QString, QList<QPlaceReview> > m_placeReviews; |
| QHash<QString, QList<QPlaceImage> > m_placeImages; |
| QHash<QString, QList<QPlaceEditorial> > m_placeEditorials; |
| }; |
| |
| #endif |