diff options
author | abcd <qt-info@nokia.com> | 2011-06-03 16:25:00 +1000 |
---|---|---|
committer | abcd <qt-info@nokia.com> | 2011-06-03 16:25:00 +1000 |
commit | a64ddc2519d8dfd462575b231196c95667cc4040 (patch) | |
tree | 423268e0c32a3e8f6c95110309d5a88629b31aad | |
parent | 2cf5da0a7d62f314a828e5edefc02f3f6e281702 (diff) | |
download | qtlocation-a64ddc2519d8dfd462575b231196c95667cc4040.tar.gz |
Add places nokia plugin
43 files changed, 4236 insertions, 1 deletions
diff --git a/src/plugins/places/nokia/nokia.pro b/src/plugins/places/nokia/nokia.pro new file mode 100644 index 00000000..cdee54ab --- /dev/null +++ b/src/plugins/places/nokia/nokia.pro @@ -0,0 +1,87 @@ +load(qt_module) + +TARGET = qtplaces_nokia +QT += location network script + +include($$QT_SOURCE_TREE/src/plugins/qpluginbase.pri) + +DESTDIR = $$QT.location.plugins/places +#QTDIR_build:REQUIRES += "contains(QT_CONFIG, location)" + +HEADERS += \ +#data classes +#parsers + qplacejsoncategoriesparser.h \ + qplacejsondetailsparser.h \ + qplacejsonmediaparser.h \ + qplacejsonrecommendationparser.h \ + qplacejsonreviewparser.h \ + qplacejsonsearchparser.h \ + qplacejsontextpredictionparser.h \ +#query classes +#reply classes + qplacemediareplyimpl.h \ + qplacedetailsreplyimpl.h \ + qplaceratingreplyimpl.h \ + pqplacerecommendationreplyimpl.h \ + qplacereviewreplyimpl.h \ + qplacesearchreplyimpl.h \ + qplacetextpredictionreplyimpl.h \ +#manager and engine + qplacemanagerengineimpl.h \ + qplacecategoriesrepository.h \ + qplacerestreply.h \ + qplacerestmanager.h \ + qplacesuppliersrepository.h \ + placemanagerenginefactory_nokia.h + +SOURCES += \ +#data classes +#parsers + qplacejsoncategoriesparser.cpp \ + qplacejsondetailsparser.cpp \ + qplacejsonmediaparser.cpp \ + qplacejsonrecommendationparser.cpp \ + qplacejsonreviewparser.cpp \ + qplacejsonsearchparser.cpp \ + qplacejsontextpredictionparser.cpp \ +#query classes +#reply classes + qplacedetailsreplyimpl.cpp \ + qplacemediareplyimpl.cpp \ + qplaceratingreplyimpl.cpp \ + qplacerecommendationreplyimpl.cpp \ + qplacereviewreplyimpl.cpp \ + qplacesearchreplyimpl.cpp \ + qplacetextpredictionreplyimpl.cpp \ +#manager and engine + qplacemanagerengineimpl.cpp \ + qplacecategoriesrepository.cpp \ + qplacerestreply.cpp \ + qplacerestmanager.cpp \ + qplacesuppliersrepository.cpp \ + placemanagerenginefactory_nokia.cpp + + +INCLUDEPATH += $$QT.location.includes + +message($$QT.location.includes) + +#INCLUDEPATH += $$SOURCE_DIR/src/location \ +# $$SOURCE_DIR/src/location/maps \ +# $$SOURCE_DIR/src/location/maps/tiled + +symbian { + TARGET.EPOCALLOWDLLDATA = 1 + TARGET.CAPABILITY = ALL -TCB + #TODO: Fill in uid3 id for Symbian + TARGET.UID3 = + pluginDep.sources = $${TARGET}.dll + pluginDep.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE} + DEPLOYMENT += pluginDep + LIBS += -lefsrv +} + +target.path += $$[QT_INSTALL_PLUGINS]/places +INSTALLS += target + diff --git a/src/plugins/places/nokia/placemanagerenginefactory_nokia.cpp b/src/plugins/places/nokia/placemanagerenginefactory_nokia.cpp new file mode 100644 index 00000000..a7502aa9 --- /dev/null +++ b/src/plugins/places/nokia/placemanagerenginefactory_nokia.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $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$ +** +** This file is part of the Ovi services plugin for the Maps and +** Navigation API. The use of these services, whether by use of the +** plugin or by other means, is governed by the terms and conditions +** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in +** this package, located in the directory containing the Ovi services +** plugin source code. +** +****************************************************************************/ + +#include "placemanagerenginefactory_nokia.h" + +#include <QtPlugin> + + +PlaceManagerEngineFactoryNokia::PlaceManagerEngineFactoryNokia() {} + +PlaceManagerEngineFactoryNokia::~PlaceManagerEngineFactoryNokia() {} + +QString PlaceManagerEngineFactoryNokia::managerName() const +{ + return "nokia"; +} + +QPlaceManagerEngine * PlaceManagerEngineFactoryNokia::engine(const QMap<QString, QString> ¶meters, + QPlaceManager::Error *error, + QString *errorString) { + //TODO: AMOS Replace with realimplementation + return NULL; +} + + +Q_EXPORT_PLUGIN2(qtplaces_nokia, PlaceManagerEngineFactoryNokia) diff --git a/src/plugins/places/nokia/placemanagerenginefactory_nokia.h b/src/plugins/places/nokia/placemanagerenginefactory_nokia.h new file mode 100644 index 00000000..23d0ad85 --- /dev/null +++ b/src/plugins/places/nokia/placemanagerenginefactory_nokia.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $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$ +** +** This file is part of the Ovi services plugin for the Maps and +** Navigation API. The use of these services, whether by use of the +** plugin or by other means, is governed by the terms and conditions +** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in +** this package, located in the directory containing the Ovi services +** plugin source code. +** +****************************************************************************/ + +#ifndef PLACEMANAGERENGINEFACTORY_NOKIA_H +#define PLACEMANAGERENGINEFACTORY_NOKIA_H + +#include <qplacemanagerenginefactory.h> +#include <QObject> + +QTM_USE_NAMESPACE + +class PlaceManagerEngineFactoryNokia : public QObject, public QPlaceManagerEngineFactory +{ + Q_OBJECT + Q_INTERFACES(QPlaceManagerEngineFactory) +public: + PlaceManagerEngineFactoryNokia(); + ~PlaceManagerEngineFactoryNokia(); + + QString managerName() const; + + QPlaceManagerEngine* engine(const QMap<QString, QString> ¶meters, + QPlaceManager::Error *error, QString *errorString); +}; + +#endif diff --git a/src/plugins/places/nokia/qplacecategoriesrepository.cpp b/src/plugins/places/nokia/qplacecategoriesrepository.cpp new file mode 100644 index 00000000..a13cefc1 --- /dev/null +++ b/src/plugins/places/nokia/qplacecategoriesrepository.cpp @@ -0,0 +1,175 @@ +#include "qplacecategoriesrepository.h" +#include "qplacejsoncategoriesparser.h" + +QTM_USE_NAMESPACE + +static const char *supportedCategories = "{\"categories\":{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Accommodation\",\"language\":\"en\",\"name\":\"accommodation\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Administrative Areas & Buildings\",\"language\":\"en\",\"name\":\"administrative-areas-buildings\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Business & Services\",\"language\":\"en\",\"name\":\"business-services\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Eat & Drink\",\"language\":\"en\",\"name\":\"eat-drink\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Facilities\",\"language\":\"en\",\"name\":\"facilities\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Going Out\",\"language\":\"en\",\"name\":\"going-out\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Leisure & Outdoor\",\"language\":\"en\",\"name\":\"leisure-outdoor\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Natural & Geographical\",\"language\":\"en\",\"name\":\"natural-geographical\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Shopping\",\"language\":\"en\",\"name\":\"shopping\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Sights & Museums\",\"language\":\"en\",\"name\":\"sights-museums\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Public Toilet \\/ Rest Area\",\"language\":\"en\",\"name\":\"toilet-rest-area\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Transport\",\"language\":\"en\",\"name\":\"transport\"}],\"group\":[{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Administrative Region\",\"language\":\"en\",\"name\":\"administrative-region\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Building\",\"language\":\"en\",\"name\":\"building\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"City, Town or Village\",\"language\":\"en\",\"name\":\"city-town-village\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Outdoor Area \\/ Complex\",\"language\":\"en\",\"name\":\"outdoor-area-complex\"}],\"groupingCategory\":{\"displayName\":\"Administrative Areas & Buildings\",\"language\":\"en\",\"name\":\"administrative-areas-buildings\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Airport\",\"language\":\"en\",\"name\":\"airport\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Ferry Terminal\",\"language\":\"en\",\"name\":\"ferry-terminal\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Public Transport\",\"language\":\"en\",\"name\":\"public-transport\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Train Station\",\"language\":\"en\",\"name\":\"railway-station\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Taxi Stand\",\"language\":\"en\",\"name\":\"taxi-stand\"}],\"groupingCategory\":{\"displayName\":\"Transport\",\"language\":\"en\",\"name\":\"transport\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Amusement or Holiday Park\",\"language\":\"en\",\"name\":\"amusement-holiday-park\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Recreation\",\"language\":\"en\",\"name\":\"recreation\"}],\"groupingCategory\":{\"displayName\":\"Leisure & Outdoor\",\"language\":\"en\",\"name\":\"leisure-outdoor\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"ATM \\/ Bank Exchange\",\"language\":\"en\",\"name\":\"atm-bank-exchange\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Business \\/ Industry\",\"language\":\"en\",\"name\":\"business-industry\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Car Dealer \\/ Repair\",\"language\":\"en\",\"name\":\"car-dealer-repair\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Car Rental\",\"language\":\"en\",\"name\":\"car-rental\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Communication \\/ Media\",\"language\":\"en\",\"name\":\"communication-media\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Petrol Station\",\"language\":\"en\",\"name\":\"petrol-station\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Police \\/ Emergency\",\"language\":\"en\",\"name\":\"police-emergency\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Post Office\",\"language\":\"en\",\"name\":\"post-office\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Service\",\"language\":\"en\",\"name\":\"service\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Tourist Information\",\"language\":\"en\",\"name\":\"tourist-information\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Travel Agency\",\"language\":\"en\",\"name\":\"travel-agency\"}],\"groupingCategory\":{\"displayName\":\"Business & Services\",\"language\":\"en\",\"name\":\"business-services\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Bar \\/ Pub\",\"language\":\"en\",\"name\":\"bar-pub\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Coffee \\/ Tea\",\"language\":\"en\",\"name\":\"coffee-tea\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Restaurant\",\"language\":\"en\",\"name\":\"restaurant\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Snacks \\/ Fast food\",\"language\":\"en\",\"name\":\"snacks-fast-food\"}],\"groupingCategory\":{\"displayName\":\"Eat & Drink\",\"language\":\"en\",\"name\":\"eat-drink\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Body of Water\",\"language\":\"en\",\"name\":\"body-of-water\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Forest, Heath or Other Vegetation\",\"language\":\"en\",\"name\":\"forest-heath-vegetation\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Mountain or Hill\",\"language\":\"en\",\"name\":\"mountain-hill\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Undersea Feature\",\"language\":\"en\",\"name\":\"undersea-feature\"}],\"groupingCategory\":{\"displayName\":\"Natural & Geographical\",\"language\":\"en\",\"name\":\"natural-geographical\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Bookshop\",\"language\":\"en\",\"name\":\"bookshop\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Clothing & Accessories\",\"language\":\"en\",\"name\":\"clothing-accessories-shop\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Department Store\",\"language\":\"en\",\"name\":\"department-store\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Electronics\",\"language\":\"en\",\"name\":\"electronics-shop\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Food & Drink\",\"language\":\"en\",\"name\":\"food-drink\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Hardware, House & Garden\",\"language\":\"en\",\"name\":\"hardware-house-garden-shop\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Kiosk \\/ 24\\/7 \\/ Convenience Store\",\"language\":\"en\",\"name\":\"kiosk-convenience-store\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Mall\",\"language\":\"en\",\"name\":\"mall\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Pharmacy\",\"language\":\"en\",\"name\":\"pharmacy\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Sport & Outdoor\",\"language\":\"en\",\"name\":\"sport-outdoor-shop\"}],\"groupingCategory\":{\"displayName\":\"Shopping\",\"language\":\"en\",\"name\":\"shopping\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Camping\",\"language\":\"en\",\"name\":\"camping\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Hostel\",\"language\":\"en\",\"name\":\"hostel\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Hotel\",\"language\":\"en\",\"name\":\"hotel\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Motel\",\"language\":\"en\",\"name\":\"motel\"}],\"groupingCategory\":{\"displayName\":\"Accommodation\",\"language\":\"en\",\"name\":\"accommodation\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Casino\",\"language\":\"en\",\"name\":\"casino\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Movie Theater\",\"language\":\"en\",\"name\":\"cinema\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Dance or Night Club\",\"language\":\"en\",\"name\":\"dance-night-club\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Theater, Music & Culture\",\"language\":\"en\",\"name\":\"theatre-music-culture\"}],\"groupingCategory\":{\"displayName\":\"Going Out\",\"language\":\"en\",\"name\":\"going-out\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Education Facility\",\"language\":\"en\",\"name\":\"education-facility\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Fair & Convention Facility\",\"language\":\"en\",\"name\":\"fair-convention-facility\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Government or Community Facility\",\"language\":\"en\",\"name\":\"government-community-facility\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Hospital or Health Care Facility\",\"language\":\"en\",\"name\":\"hospital-health-care-facility\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Library\",\"language\":\"en\",\"name\":\"library\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Parking Facility\",\"language\":\"en\",\"name\":\"parking-facility\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Sports Facility \\/ Venue\",\"language\":\"en\",\"name\":\"sports-facility-venue\"}],\"groupingCategory\":{\"displayName\":\"Facilities\",\"language\":\"en\",\"name\":\"facilities\"}},{\"category\":[{\"categorySystemName\":\"find-places\",\"displayName\":\"Landmark \\/ Attraction\",\"language\":\"en\",\"name\":\"landmark-attraction\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Museum\",\"language\":\"en\",\"name\":\"museum\"},{\"categorySystemName\":\"find-places\",\"displayName\":\"Religious Place\",\"language\":\"en\",\"name\":\"religious-place\"}],\"groupingCategory\":{\"displayName\":\"Sights & Museums\",\"language\":\"en\",\"name\":\"sights-museums\"}}]}}"; + +static QMap<QString, QString> categoriesMap; +static QPlaceCategory *secondSearchCenter = NULL; + +QPlaceCategoriesRepository *QPlaceCategoriesRepository::repositoryInstance = NULL; + +QPlaceCategoriesRepository *QPlaceCategoriesRepository::instance() +{ + if (!repositoryInstance) { + repositoryInstance = new QPlaceCategoriesRepository(); + } + return repositoryInstance; +} + +QPlaceCategoriesRepository::QPlaceCategoriesRepository(QObject *parent) + : QObject(parent), + categoriesParser(NULL) +{ + setupCategoriesMapper(); + + if (!categoriesParser) { + categoriesParser = new QPlaceJSonCategoriesParser(this); + } + connect(categoriesParser, SIGNAL(finished(const QPlaceJSonCategoriesParser::Error &error, const QString &errorMessage)), + this, SLOT(categoriesReady(const QPlaceJSonCategoriesParser::Error &error, const QString &errorMessage))); + categoriesParser->processData(supportedCategories); +} + +QPlaceCategoriesRepository::~QPlaceCategoriesRepository() +{ +} + +QPlaceReply *QPlaceCategoriesRepository::initializeCategories(const QString &categorySystemId) +{ + // to be implemented + return NULL; +} + +QList<QPlaceCategory> QPlaceCategoriesRepository::categories() const +{ + return allCategories.values(); +} + +QPlaceCategory QPlaceCategoriesRepository::mapCategory(const QString &number) +{ + QString categoryId = categoriesMap.value(number, ""); + if (categoryId == "second-search-center") { + if (!secondSearchCenter) { + secondSearchCenter = new QPlaceCategory(); + secondSearchCenter->setCategoryId("second-search-center"); + } + return *secondSearchCenter; + } else if (!categoryId.isEmpty()) { + return findCategoryById(categoryId); + } + return QPlaceCategory(); +} + +QString QPlaceCategoriesRepository::getCategoryTagId(const QPlaceCategory &category) +{ + return categoriesMap.key(category.categoryId(), QString()); +} + +QPlaceCategory QPlaceCategoriesRepository::findCategoryById(const QString &id) +{ + return allCategories.value(id, QPlaceCategory()); +} + +void QPlaceCategoriesRepository::categoriesReady(const QPlaceJSonCategoriesParser::Error &error, const QString &errorMessage) +{ + Q_UNUSED(errorMessage); + + if (!error) { + foreach (QPlaceCategory cat, categoriesParser->resultCategories()) { + allCategories.insert(cat.categoryId(), cat); + } + } + delete categoriesParser; + categoriesParser = NULL; +} + +void QPlaceCategoriesRepository::setupCategoriesMapper() +{ + // setup mapper + if (!categoriesMap.count()) { + //BusinessServices + categoriesMap.insert(QString("9000269"),QString("business-services")); + categoriesMap.insert(QString("9000005"),QString("business-industry")); + categoriesMap.insert(QString("9000277"),QString("travel-agency")); + categoriesMap.insert(QString("9000028"),QString("tourist-information")); + categoriesMap.insert(QString("9000040"),QString("police-emergency")); + categoriesMap.insert(QString("9000017"),QString("petrol-station")); + categoriesMap.insert(QString("9000278"),QString("communication-media")); + categoriesMap.insert(QString("9000047"),QString("atm-bank-exchange")); + categoriesMap.insert(QString("9000002"),QString("car-dealer-repair")); + categoriesMap.insert(QString("9000020"),QString("car-rental")); + categoriesMap.insert(QString("9000215"),QString("service")); + categoriesMap.insert(QString("9000019"),QString("post-office")); + // Transport + categoriesMap.insert(QString("9000272"),QString("transport")); + categoriesMap.insert(QString("9000216"),QString("taxi-stand")); + categoriesMap.insert(QString("9000043"),QString("airport")); + categoriesMap.insert(QString("9000041"),QString("railway-station")); + categoriesMap.insert(QString("9000058"),QString("public-transport")); + categoriesMap.insert(QString("9000035"),QString("ferry-terminal")); + // Shopping + categoriesMap.insert(QString("9000270"),QString("shopping")); + categoriesMap.insert(QString("9000205"),QString("clothing-accessories-shop")); + categoriesMap.insert(QString("9000276"),QString("bookshop")); + categoriesMap.insert(QString("9000194"),QString("hardware-house-garden-shop")); + categoriesMap.insert(QString("9000049"),QString("pharmacy")); + categoriesMap.insert(QString("9000024"),QString("mall")); + categoriesMap.insert(QString("9000197"),QString("kiosk-convenience-store")); + categoriesMap.insert(QString("9000196"),QString("electronics-shop")); + categoriesMap.insert(QString("9000191"),QString("sport-outdoor-shop")); + categoriesMap.insert(QString("9000189"),QString("department-store")); + // Accomodation + categoriesMap.insert(QString("9000271"),QString("accommodation")); + categoriesMap.insert(QString("9000032"),QString("camping")); + categoriesMap.insert(QString("9000174"),QString("motel")); + categoriesMap.insert(QString("9000038"),QString("hotel")); + categoriesMap.insert(QString("9000173"),QString("hostel")); + // GoingOut + categoriesMap.insert(QString("9000274"),QString("going-out")); + categoriesMap.insert(QString("9000203"),QString("dance-night-club")); + categoriesMap.insert(QString("9000003"),QString("casino")); + categoriesMap.insert(QString("9000004"),QString("cinema")); + categoriesMap.insert(QString("9000181"),QString("theatre-music-culture")); + // Facility + categoriesMap.insert(QString("9000261"),QString("facilities")); + categoriesMap.insert(QString("9000039"),QString("parking-facility")); + categoriesMap.insert(QString("9000007"),QString("fair-convention-facility")); + categoriesMap.insert(QString("9000012"),QString("government-community-facility")); + categoriesMap.insert(QString("9000200"),QString("hospital-health-care-facility")); + categoriesMap.insert(QString("9000106"),QString("education-facility")); + categoriesMap.insert(QString("9000220"),QString("sports-facility-venue")); + categoriesMap.insert(QString("9000031"),QString("library")); + // NatureGeography + categoriesMap.insert(QString("9000265"),QString("natural-geographical")); + categoriesMap.insert(QString("9000262"),QString("body-of-water")); + categoriesMap.insert(QString("9000045"),QString("mountain-hill")); + categoriesMap.insert(QString("9000259"),QString("forest-health-vegetation")); + categoriesMap.insert(QString("9000260"),QString("undersea-feature")); + // AreasInfrastructure + categoriesMap.insert(QString("9000266"),QString("administrative-areas-buildings")); + categoriesMap.insert(QString("9000279"),QString("administrative-region")); + categoriesMap.insert(QString("9000263"),QString("outdoor-area-complex")); + categoriesMap.insert(QString("9000283"),QString("city-town-village")); + categoriesMap.insert(QString("9000280"),QString("building")); + // EatDrink + categoriesMap.insert(QString("9000275"),QString("eat-drink")); + categoriesMap.insert(QString("9000063"),QString("coffee-tea")); + categoriesMap.insert(QString("9000022"),QString("restaurant")); + categoriesMap.insert(QString("9000064"),QString("snacks-fast-food")); + categoriesMap.insert(QString("9000033"),QString("bar-pub")); + categoriesMap.insert(QString("9000143"),QString("food-drink")); + // Leisure + categoriesMap.insert(QString("9000267"),QString("leisure-outdoor")); + categoriesMap.insert(QString("9000048"),QString("recreation")); + categoriesMap.insert(QString("9000001"),QString("amusement-holiday-park")); + // SightsMuseums + categoriesMap.insert(QString("9000273"),QString("sights-museums")); + categoriesMap.insert(QString("9000014"),QString("museum")); + categoriesMap.insert(QString("9000158"),QString("religious-place")); + categoriesMap.insert(QString("9000211"),QString("landmark-attraction")); + // SSC + categoriesMap.insert(QString("9000282"),QString("second-search-center")); + } +} diff --git a/src/plugins/places/nokia/qplacecategoriesrepository.h b/src/plugins/places/nokia/qplacecategoriesrepository.h new file mode 100644 index 00000000..73322a9f --- /dev/null +++ b/src/plugins/places/nokia/qplacecategoriesrepository.h @@ -0,0 +1,45 @@ +#ifndef QPLACECATEGORIESREPOSITORY_H +#define QPLACECATEGORIESREPOSITORY_H + +#include <QObject> +#include <QList> + +#include <qmobilityglobal.h> +#include <qplacecategory.h> +#include <qplacereply.h> +#include "qplacejsoncategoriesparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceCategoriesRepository : public QObject +{ + Q_OBJECT +public: + static QPlaceCategoriesRepository *instance(); + + ~QPlaceCategoriesRepository(); + + QPlaceReply *initializeCategories(const QString &categorySystemId); + QList<QPlaceCategory> categories() const; + + QPlaceCategory mapCategory(const QString &number); + QString getCategoryTagId(const QPlaceCategory &category); + QPlaceCategory findCategoryById(const QString &id); + +public slots: + void categoriesReady(const QPlaceJSonCategoriesParser::Error &error, const QString &errorMessage); + +private: + void setupCategoriesMapper(); + +private: + QPlaceCategoriesRepository(QObject *parent = 0); + + QHash<QString, QPlaceCategory> allCategories; + static QPlaceCategoriesRepository *repositoryInstance; + QPlaceJSonCategoriesParser *categoriesParser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACECATEGORIESREPOSITORY_H diff --git a/src/plugins/places/nokia/qplacedetailsreplyimpl.cpp b/src/plugins/places/nokia/qplacedetailsreplyimpl.cpp new file mode 100644 index 00000000..ace41188 --- /dev/null +++ b/src/plugins/places/nokia/qplacedetailsreplyimpl.cpp @@ -0,0 +1,70 @@ +#include "qplacedetailsreplyimpl.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceDetailsReplyImpl::QPlaceDetailsReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceDetailsReply(parent), + restReply(reply) +{ + parser = new QPlaceJSonDetailsParser(this); + + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + parser, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + connect(parser, SIGNAL(finished(QPlaceJSonDetailsParser::Error,QString)), + this, SLOT(predictionsReady(QPlaceJSonDetailsParser::Error,QString))); + } +} + +/*! + Destructor. +*/ +QPlaceDetailsReplyImpl::~QPlaceDetailsReplyImpl() +{ +} + +void QPlaceDetailsReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceDetailsReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceDetailsReplyImpl::predictionsReady(const QPlaceJSonDetailsParser::Error &errorId, + const QString &errorMessage) +{ + if (errorId == QPlaceJSonDetailsParser::NoError) { + setResult(parser->result()); + } else if (errorId == QPlaceJSonDetailsParser::ParsingError) { + setError(ParseError, errorMessage); + emit error(this->error(), this->errorString()); + emit processingError(this, ParseError, errorMessage); + } + emit finished(); + emit processingFinished(this); + delete parser; + parser = NULL; + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplacedetailsreplyimpl.h b/src/plugins/places/nokia/qplacedetailsreplyimpl.h new file mode 100644 index 00000000..e8d33822 --- /dev/null +++ b/src/plugins/places/nokia/qplacedetailsreplyimpl.h @@ -0,0 +1,37 @@ +#ifndef QPLACEDETAILSREPLYIMPL_H +#define QPLACEDETAILSREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacedetailsreply.h> +#include "qplacerestreply.h" +#include "qplacejsondetailsparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceDetailsReplyImpl : public QPlaceDetailsReply +{ + Q_OBJECT +public: + explicit QPlaceDetailsReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceDetailsReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void predictionsReady(const QPlaceJSonDetailsParser::Error &error, + const QString &errorMessage); + +private: + QPlaceRestReply *restReply; + QPlaceJSonDetailsParser *parser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEDETAILSREPLYIMPL_H diff --git a/src/plugins/places/nokia/qplacejsoncategoriesparser.cpp b/src/plugins/places/nokia/qplacejsoncategoriesparser.cpp new file mode 100644 index 00000000..ba14bb6a --- /dev/null +++ b/src/plugins/places/nokia/qplacejsoncategoriesparser.cpp @@ -0,0 +1,146 @@ +#include "qplacejsoncategoriesparser.h" + +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> +#include <QtScript/QScriptValueIterator> +#include <qmobilityglobal.h> + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +static const char *place_categories_element = "categories"; +static const char *place_category_element = "category"; +static const char *place_category_name_element = "displayName"; +static const char *place_category_systemname_element = "categorySystemName"; +static const char *place_category_id_element = "name"; + +static const char *place_group_element = "group"; +static const char *place_groupingcategory_element = "groupingCategory"; + +QTM_USE_NAMESPACE + +QPlaceJSonCategoriesParser::QPlaceJSonCategoriesParser(QObject *parent) : + QObject(parent), + engine(NULL) +{ +} + +QPlaceJSonCategoriesParser::~QPlaceJSonCategoriesParser() +{ + allCategories.clear(); +} + +QList<QPlaceCategory> QPlaceJSonCategoriesParser::resultCategories() +{ + return allCategories; +} + +void QPlaceJSonCategoriesParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + allCategories.clear(); + + QScriptValue sv = engine->evaluate("(" + data + ")"); + if (sv.isValid()) { + sv = sv.property(place_categories_element); + if (sv.isValid()) { + allCategories = processCategories(sv); + emit finished(NoError, QString()); + } + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } +} + +QList<QPlaceCategory> QPlaceJSonCategoriesParser::processCategories(const QScriptValue &categories) +{ + QHash<QString, QPlaceCategory> results; + QPlaceCategory cat; + QScriptValue value = categories.property(place_category_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + cat = processCategory(it.value()); + if (!cat.isEmpty() && !results.contains(cat.categoryId())) { + results.insert(cat.categoryId(), cat); + } + } + } + } else { + cat = processCategory(value); + if (!cat.isEmpty() && !results.contains(cat.categoryId())) { + results.insert(cat.categoryId(), cat); + } + } + } + foreach (cat, processGroups(categories)) { + if (!results.contains(cat.categoryId())) { + results.insert(cat.categoryId(), cat); + } + } + + return results.values(); +} + +QPlaceCategory QPlaceJSonCategoriesParser::processCategory(const QScriptValue &categoryValue) +{ + QPlaceCategory category; + QScriptValue value = categoryValue.property(place_category_id_element); + if (value.isValid() && !value.toString().isEmpty()) { + category.setCategoryId(value.toString()); + value = categoryValue.property(place_category_name_element); + if (value.isValid() && !value.toString().isEmpty()) { + category.setName(value.toString()); + } + value = categoryValue.property(place_category_systemname_element); + if (value.isValid() && !value.toString().isEmpty()) { + category.setCategorySystemId(value.toString()); + } + } + return category; +} + +QList<QPlaceCategory> QPlaceJSonCategoriesParser::processGroups(const QScriptValue &categories) +{ + QList<QPlaceCategory> results; + QScriptValue value = categories.property(place_group_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + results.append(processGroup(it.value())); + } + } + } else { + results.append(processGroup(value)); + } + } + return results; +} + +QList<QPlaceCategory> QPlaceJSonCategoriesParser::processGroup(const QScriptValue &group) +{ + QList<QPlaceCategory> results; + QPlaceCategory parentCategory; + + QScriptValue value = group.property(place_groupingcategory_element); + if (value.isValid()) { + parentCategory = processCategory(value); + } + if (!parentCategory.isEmpty()) { + results = processCategories(group); + results.append(parentCategory); + } + + return results; +} diff --git a/src/plugins/places/nokia/qplacejsoncategoriesparser.h b/src/plugins/places/nokia/qplacejsoncategoriesparser.h new file mode 100644 index 00000000..4c652528 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsoncategoriesparser.h @@ -0,0 +1,48 @@ +#ifndef QPLACEJSONCATEGORIESPARSER_H +#define QPLACEJSONCATEGORIESPARSER_H + +#include <QObject> +#include <QList> +#include <QHash> + +#include <qplacecategory.h> + +class QScriptEngine; +class QScriptValue; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonCategoriesParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonCategoriesParser(QObject *parent = 0); + virtual ~QPlaceJSonCategoriesParser(); + + static QList<QPlaceCategory> processCategories(const QScriptValue &categories); + + QList<QPlaceCategory> resultCategories(); + +signals: + void finished(const Error &error, const QString &errorMessage); + +public slots: + void processData(const QString &data); + +private: + static QPlaceCategory processCategory(const QScriptValue &categoryValue); + static QList<QPlaceCategory> processGroups(const QScriptValue &categories); + static QList<QPlaceCategory> processGroup(const QScriptValue &group); +private: + QScriptEngine *engine; + QList<QPlaceCategory> allCategories; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONCATEGORIESPARSER_H diff --git a/src/plugins/places/nokia/qplacejsondetailsparser.cpp b/src/plugins/places/nokia/qplacejsondetailsparser.cpp new file mode 100644 index 00000000..d6efa6b6 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsondetailsparser.cpp @@ -0,0 +1,1018 @@ +#include "qplacejsondetailsparser.h" + +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> +#include <QtScript/QScriptValueIterator> + +#include <qplace.h> +#include <qplacegeocoordinate.h> +#include <qplacecontact.h> +#include <qplacecategory.h> +#include <qplacedescription.h> +#include <qplacerating.h> +#include <qplaceaddress.h> +#include <qplacebusinessinformation.h> +#include <qplacelocation.h> +#include <qplacealternativevalue.h> +#include <qplacemediaobject.h> +#include <qplaceperiod.h> +#include <qplaceweekdayhours.h> +#include <qplacesupplier.h> +#include "qplacejsoncategoriesparser.h" +#include "qplacesuppliersrepository.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +//search const +static const char *place_place_element = "place"; +static const char *place_id_element = "a_id"; +static const char *place_is_ad_place_value = "isAdPlace"; + +static const char *place_provider = "provider"; +static const char *place_provider_url = "providerUrl"; + +static const char *place_categories_element = "categories"; + +static const char *place_contact_element = "contact"; +static const char *place_contact_email_element = "email"; +static const char *place_contact_fax_element = "fax"; +static const char *place_contact_phone_element = "phone"; +static const char *place_contact_website_element = "website"; +static const char *place_contact_im_element = "im"; + +static const char *place_tags_element = "tags"; +static const char *place_tags_value_element = "value"; + +static const char *place_names_element = "names"; +static const char *place_alternativenames_element = "alternativeNames"; +static const char *place_name_default_element = "defaultName"; +static const char *place_name_localized_element = "localizedName"; +static const char *place_name_value_element = "name"; +static const char *place_name_language_element = "language"; + +static const char *place_ratings_element = "averageRatings"; +static const char *place_rating_element = "averageRating"; +static const char *place_rating_rating_element = "rating"; +static const char *place_rating_count_element = "ratingCount"; +static const char *place_rating_type_element = "ratingType"; +static const char *place_rating_type_overall_element = "OVERALL"; + +static const char *place_location_element = "location"; +static const char *place_geoCoordinates_element = "geoCoordinates"; +static const char *place_geoCoordinates_longitude_value = "longitude"; +static const char *place_geoCoordinates_latitude_value = "latitude"; +//! @todo check if bounding box should be supported +//static const char *place_geoCoordinates_longitude_bb1_value = "GEO_BBX_LONGITUDE_1"; +//static const char *place_geoCoordinates_latitude_bb1_value = "GEO_BBX_LATITUDE_1"; +//static const char *place_geoCoordinates_longitude_bb2_value = "GEO_BBX_LONGITUDE_2"; +//static const char *place_geoCoordinates_latitude_bb2_value = "GEO_BBX_LATITUDE_2"; + +static const char *place_address_element = "address"; +static const char *place_address_country = "localizedCountryName"; +static const char *place_address_county = "county"; +static const char *place_address_country_code = "countryCode3L"; +static const char *place_address_state = "state"; +static const char *place_address_code = "zipCode"; +static const char *place_address_city = "city"; +static const char *place_address_district = "district"; +static const char *place_address_street = "street"; +static const char *place_address_house_number = "houseNumber"; + +static const char *place_adcontent_element = "adPlaceContent"; +static const char *place_adcontent_descriptions_element = "descriptions"; +static const char *place_adcontent_description_element = "description"; +static const char *place_adcontent_localizedDescription_element = "localizedDescription"; +static const char *place_adcontent_descriptionLanguage_element = "languageOfDescription"; +static const char *place_adcontent_medias_element = "mediaTypes"; +static const char *place_adcontent_media_element = "adPlaceMedia"; +static const char *place_adcontent_media_mime_element = "mediaMimeType"; +static const char *place_adcontent_media_url_element = "mediaUrl"; +static const char *place_adcontent_paymentmethods_element = "paymentMethods"; +static const char *place_adcontent_paymentmethod_element = "paymentMetod"; +static const char *place_adcontent_paymentmethod_name_element = "name"; +static const char *place_adcontent_hours_element = "businessHours"; +static const char *place_adcontent_hours_annualclosingsnotes_element = "annualclosingsnotes"; +static const char *place_adcontent_hours_annualclosingsnote_element = "annualclosingsnote"; +static const char *place_adcontent_hours_annualclosingsnote_v_element = "_v"; +static const char *place_adcontent_hours_open_element = "openingSchedule"; +static const char *place_adcontent_hours_open_hours_element = "openingHours"; +static const char *place_adcontent_hours_open_day_element = "dayOfWeek"; +static const char *place_adcontent_hours_open_from_element = "openFrom"; +static const char *place_adcontent_hours_open_to_element = "openTo"; +static const char *place_adcontent_hours_openingnotes_element = "openingnotes"; +static const char *place_adcontent_hours_openingnote_element = "openingnote"; +static const char *place_adcontent_hours_openingnote_v_element = "_v"; +static const char *place_adcontent_packages_element = "packages"; +static const char *place_adcontent_package_element = "package"; +static const char *place_adcontent_package_type_element = "packageType"; +static const char *place_adcontent_package_type_plus_value = "PLUS"; +static const char *place_adcontent_package_type_plus_plus_value = "PLUS+"; + +static const char *place_package_type = "type"; +static const char *place_package_type_ad_place = "ADPLACE"; +static const char *place_package_type_ad_place_prime_plus = "ADPLACE, PRIME_PLUS"; +static const char *place_package_type_ad_place_prime_plus_plus = "ADPLACE, PRIME_PLUS_PLUS"; +static const char *place_package_type_place = "PLACE"; + +static const char *place_premiumcontent_element = "premiumContent"; +static const char *place_premiumcontent_version_element = "version"; +static const char *place_premiumcontent_content_element = "content"; +static const char *place_premiumcontent_content_desc_element = "description"; +static const char *place_premiumcontent_content_shortdesc_element = "short-description"; +static const char *place_premiumcontent_content_name_element = "name"; +static const char *place_premiumcontent_content_providername_element = "providerDisplayName"; +static const char *place_premiumcontent_content_provider_element = "provider"; +static const char *place_premiumcontent_content_vendorurl_element = "vendor-url"; +static const char *place_premiumcontent_content_providerIconUrl_element = "providerIconUrl"; +static const char *place_premiumcontent_content_language_element = "language"; +static const char *place_premiumcontent_content_media_element = "media"; +static const char *place_premiumcontent_content_mediaurl_element = "content"; +static const char *place_premiumcontent_content_mediamimetype_element = "mimeType"; + +static const char *place_premiumcontent_content_monday = "MON"; +static const char *place_premiumcontent_content_tuesday = "TUE"; +static const char *place_premiumcontent_content_wednesday = "WED"; +static const char *place_premiumcontent_content_thursday = "THU"; +static const char *place_premiumcontent_content_friday = "FRI"; +static const char *place_premiumcontent_content_saturday = "SAT"; +static const char *place_premiumcontent_content_sunday = "SUN"; + +QTM_USE_NAMESPACE + +QPlaceJSonDetailsParser::QPlaceJSonDetailsParser(QObject *parent) : + QObject(parent), + engine(NULL) +{ +} + +QPlaceJSonDetailsParser::~QPlaceJSonDetailsParser() +{ +} + +QPlace QPlaceJSonDetailsParser::buildPlace(const QScriptValue &placeValue) +{ + QPlace newPlace; + if (placeValue.isValid()) { + buildPlace(placeValue, &newPlace); + } + return newPlace; +} + +QPlace QPlaceJSonDetailsParser::result() +{ + return place; +} + +void QPlaceJSonDetailsParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + + QScriptValue sv = engine->evaluate("(" + data + ")"); + if (sv.isValid()) { + buildPlace(sv.property(place_place_element), &place); + emit finished(NoError, QString()); + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } +} + +void QPlaceJSonDetailsParser::buildPlace(const QScriptValue &placeValue, QPlace *targetPlace) +{ + if (placeValue.isValid()) { + QScriptValue value = placeValue.property(place_id_element); + if (value.isValid() && !value.toString().isEmpty()) { + targetPlace->setPlaceId(value.toString()); + } + processMainProvider(placeValue, targetPlace); + value = placeValue.property(place_categories_element); + if (value.isValid()) { + processCategories(value, targetPlace); + } + value = placeValue.property(place_contact_element); + if (value.isValid()) { + processContacts(value, targetPlace); + } + value = placeValue.property(place_tags_element); + if (value.isValid()) { + processTags(value, targetPlace); + } + value = placeValue.property(place_names_element); + if (value.isValid()) { + processNames(value, targetPlace); + } + value = placeValue.property(place_ratings_element); + if (value.isValid()) { + processRatings(value, targetPlace); + } + value = placeValue.property(place_location_element); + if (value.isValid()) { + processLocations(value, targetPlace); + } + value = placeValue.property(place_adcontent_element); + if (value.isValid()) { + processAdContent(value, targetPlace); + } + value = placeValue.property(place_premiumcontent_element); + if (value.isValid()) { + processPremiumContents(value, targetPlace); + } + } +} + +void QPlaceJSonDetailsParser::processMainProvider(const QScriptValue &placeValue, QPlace *targetPlace) +{ + QPlaceSupplier sup; + QScriptValue value = placeValue.property(place_provider); + if (value.isValid() && !value.toString().isEmpty()) { + sup.setName(value.toString()); + } + else { + return; + } + value = placeValue.property(place_provider_url); + if (value.isValid() && !value.toString().isEmpty()){ + sup.setSupplierIconURL(value.toString()); + } + QList<QPlaceSupplier> list; + list.append(QPlaceSuppliersRepository::instance()->addSupplier(sup)); + targetPlace->setSuppliers(list); +} + +void QPlaceJSonDetailsParser::processContacts(const QScriptValue &contactsValue, QPlace *targetPlace) +{ + QList<QPlaceContact> contacts; + QScriptValueIterator it(contactsValue); + while (it.hasNext()) { + it.next(); + QPlaceContact contact; + if (it.name() == place_contact_website_element) { + contact.setType(QPlaceContact::URL); + } + if (it.name() == place_contact_phone_element) { + contact.setType(QPlaceContact::Phone); + } + if (it.name() == place_contact_fax_element) { + contact.setType(QPlaceContact::Fax); + } + if (it.name() == place_contact_im_element) { + contact.setType(QPlaceContact::IM); + } + if (it.name() == place_contact_email_element) { + contact.setType(QPlaceContact::Email); + } + contact.setValue(it.value().toString()); + contacts.append(contact); + } + targetPlace->setContacts(contacts); +} + +void QPlaceJSonDetailsParser::processCategories(const QScriptValue &categories, QPlace *targetPlace) +{ + targetPlace->setCategories(QPlaceJSonCategoriesParser::processCategories(categories)); +} + +void QPlaceJSonDetailsParser::processRatings(const QScriptValue &ratings, QPlace *targetPlace) +{ + QPlaceRating *rating = NULL; + QScriptValue value = ratings.property(place_rating_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + rating = processRating(it.value()); + if (rating) { + break; + } + } + } + } else { + rating = processRating(value); + } + } + if (rating) { + targetPlace->setRating(*rating); + delete rating; + rating = NULL; + } +} + +QPlaceRating *QPlaceJSonDetailsParser::processRating(const QScriptValue &ratingElement) +{ + QPlaceRating *rating = NULL; + QScriptValue value = ratingElement.property(place_rating_type_element); + // Only overall elements are interesting + if (value.isValid() && value.toString() == place_rating_type_overall_element) { + rating = new QPlaceRating(); + value = ratingElement.property(place_rating_count_element); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + uint ratingValue = value.toString().toUInt(&isConverted); + if (isConverted) { + rating->setCount(ratingValue); + } + } + value = ratingElement.property(place_rating_rating_element); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + double ratingValue = value.toString().toDouble(&isConverted); + if (isConverted) { + rating->setValue(ratingValue); + } + } + } + return rating; +} + +void QPlaceJSonDetailsParser::processAddress(const QScriptValue &address, QPlaceLocation *location) +{ + QPlaceAddress newAddress; + QScriptValue value = address.property(place_address_street); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setStreet(value.toString()); + } + value = address.property(place_address_country); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCountryName(value.toString()); + } + value = address.property(place_address_county); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCounty(value.toString()); + } + value = address.property(place_address_country_code); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCountry(value.toString()); + } + value = address.property(place_address_state); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setState(value.toString()); + } + value = address.property(place_address_city); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCity(value.toString()); + } + value = address.property(place_address_code); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setPostalCode(value.toString()); + } + value = address.property(place_address_district); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setDistrict(value.toString()); + } + value = address.property(place_address_house_number); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setHouseNumber(value.toString()); + } + location->setAddress(newAddress); +} + +void QPlaceJSonDetailsParser::processLocations(const QScriptValue &locations, QPlace *targetPlace) +{ + if (locations.isArray()) { + QList<QPlaceLocation> list; + bool isFirst = true; + QScriptValueIterator it(locations); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QPlaceLocation loc = processLocation(it.value()); + if (isFirst) { + targetPlace->setLocation(loc); + isFirst = false; + } else { + list.append(loc); + } + } + } + targetPlace->setAlternativeLocations(list); + } else { + QPlaceLocation loc = processLocation(locations); + targetPlace->setLocation(loc); + } +} + +QPlaceLocation QPlaceJSonDetailsParser::processLocation(const QScriptValue &location) +{ + QPlaceLocation newLocation; + QScriptValue property = location.property(place_geoCoordinates_element); + if (property.isValid()) { + QPlaceGeoCoordinate pos; + QScriptValue value = property.property(place_geoCoordinates_longitude_value); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + double longitude = value.toString().toDouble(&isConverted); + if (isConverted) { + pos.setLongitude(longitude); + } + } + value = property.property(place_geoCoordinates_latitude_value); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + double latitude = value.toString().toDouble(&isConverted); + if (isConverted) { + pos.setLatitude(latitude); + } + } + newLocation.setDisplayPosition(pos); + } + property = location.property(place_address_element); + if (property.isValid()) { + processAddress(property, &newLocation); + } + return newLocation; +} + +void QPlaceJSonDetailsParser::processTags(const QScriptValue &tags, QPlace *targetPlace) +{ + QStringList newTags; + if (tags.isValid()) { + if (tags.isArray()) { + QScriptValueIterator it(tags); + while (it.hasNext()) { + it.next(); + QScriptValue value = it.value().property(place_tags_value_element); + if (value.isValid() && !value.toString().isEmpty()) { + newTags.append(value.toString()); + } + } + } else { + QScriptValue value = tags.property(place_tags_value_element); + if (value.isValid() && !value.toString().isEmpty()) { + newTags.append(value.toString()); + } + } + } + targetPlace->setTags(newTags); +} + +void QPlaceJSonDetailsParser::processNames(const QScriptValue &names, QPlace *targetPlace) +{ + QScriptValue value = names.property(place_alternativenames_element); + if (value.isValid()) { + value = value.property(place_name_localized_element); + if (value.isValid()) { + QList<QPlaceAlternativeValue> list; + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QPlaceAlternativeValue *name = processName(it.value()); + if (name) { + list.append(*name); + delete name; + name = NULL; + } + } + } + } else { + QPlaceAlternativeValue *name = processName(value); + if (name) { + list.append(*name); + delete name; + name = NULL; + } + } + targetPlace->setAlternativeNames(list); + } + } + value = names.property(place_name_default_element); + if (value.isValid()) { + QPlaceAlternativeValue *name = processName(value); + if (name) { + targetPlace->setName(name->value()); + delete name; + name = NULL; + } + } +} + +QPlaceAlternativeValue *QPlaceJSonDetailsParser::processName(const QScriptValue &nameValue) +{ + QPlaceAlternativeValue *name = NULL; + QScriptValue value = nameValue.property(place_name_value_element); + if (value.isValid() && !value.toString().isEmpty()) { + name = new QPlaceAlternativeValue(); + name->setValue(value.toString()); + value = nameValue.property(place_name_language_element); + if (value.isValid() && !value.toString().isEmpty()) { + name->setLanguage(value.toString()); + } + } + return name; +} + +void QPlaceJSonDetailsParser::processPremiumContents(const QScriptValue &premiumContent, QPlace *targetPlace) +{ + QScriptValue value = premiumContent.property(place_premiumcontent_version_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + processPremiumVersion(it.value(), targetPlace); + } + } + } else { + processPremiumVersion(value, targetPlace); + } + } +} + +void QPlaceJSonDetailsParser::processPremiumVersion(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_premiumcontent_content_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + processPremiumContent(it.value(), targetPlace); + } + } + } else { + processPremiumContent(value, targetPlace); + } + } +} + +void QPlaceJSonDetailsParser::processPremiumContent(const QScriptValue &content, QPlace *targetPlace) +{ + QString name, id, iconURL; + QScriptValue value = content.property(place_premiumcontent_content_providername_element); + if (value.isValid() && !value.toString().isEmpty()) { + name = value.toString(); + } + value = content.property(place_premiumcontent_content_provider_element); + if (value.isValid() && !value.toString().isEmpty()) { + id = value.toString(); + } + value = content.property(place_premiumcontent_content_providerIconUrl_element); + if (value.isValid() && !value.toString().isEmpty()) { + iconURL = value.toString(); + } + QPlaceSupplier supplier; + if (!name.isEmpty() || !id.isEmpty()) { + supplier.setName(name); + supplier.setSupplierId(id); + supplier.setSupplierIconURL(iconURL); + supplier = QPlaceSuppliersRepository::instance()->addSupplier(supplier); + } + processPremiumContentDescription(content, supplier, targetPlace); + processPremiumContentMediaObjects(content, supplier, targetPlace); +} + +void QPlaceJSonDetailsParser::processPremiumContentDescription(const QScriptValue &content, + const QPlaceSupplier &supplier, + QPlace *targetPlace) +{ + QScriptValue value = content.property(place_premiumcontent_content_desc_element); + QPlaceDescription desc; + if (value.isValid() && !value.toString().isEmpty()) { + desc.setContent(value.toString()); + } else { + value = content.property(place_premiumcontent_content_shortdesc_element); + if (value.isValid() && !value.toString().isEmpty()) { + desc.setContent(value.toString()); + } + } + // if no description do not continue + if (desc.content().isEmpty()) { + return; + } + value = content.property(place_premiumcontent_content_name_element); + if (value.isValid() && !value.toString().isEmpty()) { + desc.setContentTitle(value.toString()); + } + value = content.property(place_premiumcontent_content_vendorurl_element); + if (value.isValid() && !value.toString().isEmpty()) { + desc.setSourceURL(value.toString()); + } + value = content.property(place_premiumcontent_content_language_element); + if (value.isValid() && !value.toString().isEmpty()) { + desc.setLanguage(value.toString()); + } + desc.setSupplier(supplier); + QList<QPlaceDescription> list = targetPlace->descriptions(); + list.append(desc); + targetPlace->setDescriptions(list); +} + +void QPlaceJSonDetailsParser::processPremiumContentMediaObjects(const QScriptValue &content, + const QPlaceSupplier &supplier, + QPlace *targetPlace) +{ + QScriptValue value = content.property(place_premiumcontent_content_media_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QPlaceMediaObject *obj = processPremiumContentMediaObject(it.value()); + if (obj) { + obj->setSupplier(supplier); + QPlacePaginationList<QPlaceMediaObject> list = targetPlace->media(); + list.addItem(*obj); + targetPlace->setMedia(list); + delete obj; + obj = NULL; + } + } + } + } else { + QPlaceMediaObject *obj = processPremiumContentMediaObject(value); + if (obj) { + obj->setSupplier(supplier); + QPlacePaginationList<QPlaceMediaObject> list = targetPlace->media(); + list.addItem(*obj); + targetPlace->setMedia(list); + delete obj; + obj = NULL; + } + } + } +} + +QPlaceMediaObject *QPlaceJSonDetailsParser::processPremiumContentMediaObject(const QScriptValue &content) +{ + QPlaceMediaObject *obj = NULL; + QScriptValue value = content.property(place_premiumcontent_content_mediaurl_element); + if (value.isValid() && !value.toString().isEmpty()) { + obj = new QPlaceMediaObject(); + obj->setUrl(value.toString()); + obj->setId(value.toString()); + value = content.property(place_premiumcontent_content_mediamimetype_element); + if (value.isValid() && !value.toString().isEmpty()) { + obj->setMimeType(value.toString()); + } + } + return obj; +} + +void QPlaceJSonDetailsParser::processAdContent(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_descriptions_element); + if (value.isValid()) { + processAdContentDescriptions(value, targetPlace); + } + value = content.property(place_adcontent_medias_element); + if (value.isValid()) { + processAdContentMediaObjects(value, targetPlace); + } + value = content.property(place_adcontent_paymentmethods_element); + if (value.isValid()) { + processAdContentPaymentMethods(value, targetPlace); + } + value = content.property(place_adcontent_hours_element); + if (value.isValid()) { + processAdContentBusinessHours(value, targetPlace); + } + value = content.property(place_adcontent_packages_element); + if (value.isValid()) { + processAdContentPackages(value, targetPlace); + } +} + +void QPlaceJSonDetailsParser::processAdContentPackages(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_package_element); + if (value.isValid()) { + value = value.property(place_adcontent_package_type_element); + if (value.isValid() && !value.toString().isEmpty()) { + QString package = value.toString(); + QVariantHash data = targetPlace->additionalData(); + if (package == place_adcontent_package_type_plus_value) { + data[place_package_type] = place_package_type_ad_place_prime_plus; + } else if (package == place_adcontent_package_type_plus_plus_value) { + data[place_package_type] = place_package_type_ad_place_prime_plus_plus; + } + targetPlace->setAdditionalData(data); + } + } +} + +void QPlaceJSonDetailsParser::processAdContentDescriptions(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_description_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QPlaceDescription *des = processAdContentDescription(it.value()); + if (des) { + QList<QPlaceDescription> list = targetPlace->descriptions(); + list.append(*des); + targetPlace->setDescriptions(list); + delete des; + des = NULL; + } + } + } + } else { + QPlaceDescription *des = processAdContentDescription(value); + if (des) { + QList<QPlaceDescription> list = targetPlace->descriptions(); + list.append(*des); + targetPlace->setDescriptions(list); + delete des; + des = NULL; + } + } + } +} + +QPlaceDescription *QPlaceJSonDetailsParser::processAdContentDescription(const QScriptValue &content) +{ + QPlaceDescription *description = NULL; + QScriptValue value = content.property(place_adcontent_localizedDescription_element); + if (value.isValid() && !value.toString().isEmpty()) { + description = new QPlaceDescription(); + description->setContent(value.toString()); + value = content.property(place_adcontent_descriptionLanguage_element); + if (value.isValid() && !value.toString().isEmpty()) { + description->setLanguage(value.toString()); + } + } + return description; +} + +void QPlaceJSonDetailsParser::processAdContentMediaObjects(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_media_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QPlaceMediaObject *obj = processAdContentMediaObject(it.value()); + if (obj) { + QPlacePaginationList<QPlaceMediaObject> list = targetPlace->media(); + list.addItem(*obj); + targetPlace->setMedia(list); + delete obj; + obj = NULL; + } + } + } + } else { + QPlaceMediaObject *obj = processAdContentMediaObject(value); + if (obj) { + QPlacePaginationList<QPlaceMediaObject> list = targetPlace->media(); + list.addItem(*obj); + targetPlace->setMedia(list); + delete obj; + obj = NULL; + } + } + } +} + +QPlaceMediaObject *QPlaceJSonDetailsParser::processAdContentMediaObject(const QScriptValue &content) +{ + QPlaceMediaObject *obj = NULL; + QString mediaMimeType; + QString mediaUrl; + + QScriptValue value = content.property(place_adcontent_media_mime_element); + if (value.isValid() && !value.toString().isEmpty()) { + mediaMimeType = value.toString(); + } + value = content.property(place_adcontent_media_url_element); + if (value.isValid() && !value.toString().isEmpty()) { + mediaUrl = value.toString(); + } + if (!mediaMimeType.isEmpty() || !mediaUrl.isEmpty()) { + obj = new QPlaceMediaObject(); + obj->setUrl(mediaUrl); + obj->setId(mediaUrl); + obj->setMimeType(mediaMimeType); + } + return obj; +} + +void QPlaceJSonDetailsParser::processAdContentPaymentMethods(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_paymentmethod_element); + if (value.isValid()) { + QStringList list; + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QString obj = processAdContentPaymentMethod(it.value()); + if (!obj.isEmpty()) { + list.append(obj); + } + } + } + } else { + QString obj = processAdContentPaymentMethod(value); + if (!obj.isEmpty()) { + list.append(obj); + } + } + if (list.count()) { + QPlaceBusinessInformation busInfo = targetPlace->businessInformation(); + busInfo.setPaymentMethods(list); + targetPlace->setBusinessInformation(busInfo); + } + } +} + +QString QPlaceJSonDetailsParser::processAdContentPaymentMethod(const QScriptValue &content) +{ + QString obj; + QScriptValue value = content.property(place_adcontent_paymentmethod_name_element); + if (value.isValid() && !value.toString().isEmpty()) { + obj = value.toString(); + } + return obj; +} + +void QPlaceJSonDetailsParser::processAdContentBusinessHours(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_hours_annualclosingsnotes_element); + if (value.isValid()) { + processAdContentClosingsNotes(value, targetPlace); + } + value = content.property(place_adcontent_hours_open_element); + if (value.isValid()) { + processAdContentOpeningHours(value, targetPlace); + } + value = content.property(place_adcontent_hours_openingnotes_element); + if (value.isValid()) { + processAdContentOpeningNotes(value, targetPlace); + } +} + +void QPlaceJSonDetailsParser::processAdContentClosingsNotes(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_hours_annualclosingsnote_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QString obj = processAdContentClosingsNote(it.value()); + if (!obj.isEmpty()) { + QPlaceBusinessInformation busInfo = targetPlace->businessInformation(); + busInfo.setAnnualClosingNote(obj); + targetPlace->setBusinessInformation(busInfo); + //! @todo only one is used + break; + } + } + } + } else { + QString obj = processAdContentClosingsNote(value); + if (!obj.isEmpty()) { + QPlaceBusinessInformation busInfo = targetPlace->businessInformation(); + busInfo.setAnnualClosingNote(obj); + targetPlace->setBusinessInformation(busInfo); + } + } + } +} + +QString QPlaceJSonDetailsParser::processAdContentClosingsNote(const QScriptValue &content) +{ + QString ret; + QScriptValue value = content.property(place_adcontent_hours_annualclosingsnote_v_element); + if (value.isValid() && !value.toString().isEmpty()) { + ret = value.toString(); + } + return ret; +} + +void QPlaceJSonDetailsParser::processAdContentOpeningHours(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_hours_open_hours_element); + if (value.isValid()) { + QList<QPlaceWeekdayHours> list; + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QPlaceWeekdayHours *obj = processAdContentOpeningHoursElement(it.value()); + if (obj) { + list.append(*obj); + delete obj; + obj = NULL; + } + } + } + } else { + QPlaceWeekdayHours *obj = processAdContentOpeningHoursElement(value); + if (obj) { + list.append(*obj); + delete obj; + obj = NULL; + } + } + QPlaceBusinessInformation busInfo = targetPlace->businessInformation(); + busInfo.setOpeningHours(list); + targetPlace->setBusinessInformation(busInfo); + } +} + +QPlaceWeekdayHours *QPlaceJSonDetailsParser::processAdContentOpeningHoursElement(const QScriptValue &content) +{ + QPlaceWeekdayHours *openH = new QPlaceWeekdayHours(); + QScriptValue value = content.property(place_adcontent_hours_open_day_element); + if (value.isValid() && !value.toString().isEmpty()) { + QString day = value.toString(); + if (place_premiumcontent_content_monday == day) { + openH->setWeekday(Qt::Monday); + } else if (place_premiumcontent_content_tuesday == day) { + openH->setWeekday(Qt::Tuesday); + } else if (place_premiumcontent_content_wednesday == day) { + openH->setWeekday(Qt::Wednesday); + } else if (place_premiumcontent_content_thursday == day) { + openH->setWeekday(Qt::Thursday); + } else if (place_premiumcontent_content_friday == day) { + openH->setWeekday(Qt::Friday); + } else if (place_premiumcontent_content_saturday == day) { + openH->setWeekday(Qt::Saturday); + } else if (place_premiumcontent_content_sunday == day) { + openH->setWeekday(Qt::Sunday); + } + } + QTime start, end; + value = content.property(place_adcontent_hours_open_from_element); + if (value.isValid() && !value.toString().isEmpty()) { + start = QTime::fromString(value.toString(),"hh:mm"); + } + value = content.property(place_adcontent_hours_open_to_element); + if (value.isValid() && !value.toString().isEmpty()) { + end = QTime::fromString(value.toString(),"hh:mm"); + } + QPlacePeriod period(start.hour(), start.minute(), end.hour(), end.minute()); + openH->setPeriod(period); + return openH; +} + +void QPlaceJSonDetailsParser::processAdContentOpeningNotes(const QScriptValue &content, QPlace *targetPlace) +{ + QScriptValue value = content.property(place_adcontent_hours_openingnote_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QString obj = processAdContentOpeningNote(it.value()); + if (!obj.isEmpty()) { + QPlaceBusinessInformation busInfo = targetPlace->businessInformation(); + busInfo.setOpeningNote(obj); + targetPlace->setBusinessInformation(busInfo); + //! @todo only one is used + break; + } + } + } + } else { + QString obj = processAdContentOpeningNote(value); + if (!obj.isEmpty()) { + QPlaceBusinessInformation busInfo = targetPlace->businessInformation(); + busInfo.setOpeningNote(obj); + targetPlace->setBusinessInformation(busInfo); + } + } + } +} + +QString QPlaceJSonDetailsParser::processAdContentOpeningNote(const QScriptValue &content) +{ + QString ret; + QScriptValue value = content.property(place_adcontent_hours_openingnote_v_element); + if (value.isValid() && !value.toString().isEmpty()) { + ret = value.toString(); + } + return ret; +} diff --git a/src/plugins/places/nokia/qplacejsondetailsparser.h b/src/plugins/places/nokia/qplacejsondetailsparser.h new file mode 100644 index 00000000..8b3dc690 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsondetailsparser.h @@ -0,0 +1,82 @@ +#ifndef QPLACEJSONDETAILSPARSER_H +#define QPLACEJSONDETAILSPARSER_H + +#include <QObject> +#include <QList> + +#include <qplace.h> + +class QScriptEngine; +class QScriptValue; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonDetailsParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonDetailsParser(QObject *parent = 0); + virtual ~QPlaceJSonDetailsParser(); + + static QPlace buildPlace(const QScriptValue &place); + QPlace result(); + +signals: + void finished(const Error &error, const QString &errorMessage); + +public slots: + void processData(const QString &data); + +private: + static void buildPlace(const QScriptValue &place, QPlace *targetPlace); + static void processMainProvider(const QScriptValue &place, QPlace *targetPlace); + static void processContacts(const QScriptValue &contacts, QPlace *targetPlace); + static void processCategories(const QScriptValue &categories, QPlace *targetPlace); + static QPlaceCategory processCategory(const QScriptValue &category); + static void processRatings(const QScriptValue &ratings, QPlace *targetPlace); + static QPlaceRating *processRating(const QScriptValue &rating); + static void processAddress(const QScriptValue &address, QPlaceLocation *location); + static void processLocations(const QScriptValue &locations, QPlace *targetPlace); + static QPlaceLocation processLocation(const QScriptValue &location); + static void processTags(const QScriptValue &locations, QPlace *targetPlace); + static void processNames(const QScriptValue &locations, QPlace *targetPlace); + static QPlaceAlternativeValue *processName(const QScriptValue &nameValue); + static void processPremiumContents(const QScriptValue &content, QPlace *targetPlace); + static void processPremiumVersion(const QScriptValue &content, QPlace *targetPlace); + static void processPremiumContent(const QScriptValue &content, QPlace *targetPlace); + static void processPremiumContentDescription(const QScriptValue &content, + const QPlaceSupplier &supplier, + QPlace *targetPlace); + static void processPremiumContentMediaObjects(const QScriptValue &content, + const QPlaceSupplier &supplier, + QPlace *targetPlace); + static QPlaceMediaObject *processPremiumContentMediaObject(const QScriptValue &content); + static void processAdContent(const QScriptValue &content, QPlace *targetPlace); + static void processAdContentPackages(const QScriptValue &content, QPlace *targetPlace); + static void processAdContentDescriptions(const QScriptValue &content, QPlace *targetPlace); + static QPlaceDescription *processAdContentDescription(const QScriptValue &content); + static void processAdContentMediaObjects(const QScriptValue &content, QPlace *targetPlace); + static QPlaceMediaObject *processAdContentMediaObject(const QScriptValue &content); + static void processAdContentPaymentMethods(const QScriptValue &content, QPlace *targetPlace); + static QString processAdContentPaymentMethod(const QScriptValue &content); + static void processAdContentBusinessHours(const QScriptValue &content, QPlace *targetPlace); + static void processAdContentClosingsNotes(const QScriptValue &content, QPlace *targetPlace); + static QString processAdContentClosingsNote(const QScriptValue &content); + static void processAdContentOpeningHours(const QScriptValue &content, QPlace *targetPlace); + static QPlaceWeekdayHours *processAdContentOpeningHoursElement(const QScriptValue &content); + static void processAdContentOpeningNotes(const QScriptValue &content, QPlace *targetPlace); + static QString processAdContentOpeningNote(const QScriptValue &content); + +private: + QScriptEngine *engine; + QPlace place; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONDETAILSPARSER_H diff --git a/src/plugins/places/nokia/qplacejsonmediaparser.cpp b/src/plugins/places/nokia/qplacejsonmediaparser.cpp new file mode 100644 index 00000000..80f313ba --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonmediaparser.cpp @@ -0,0 +1,115 @@ +#include "qplacejsonmediaparser.h" + +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> +#include <QtScript/QScriptValueIterator> + +#include <qplacemediaobject.h> +#include <qplacesupplier.h> +#include "qplacesuppliersrepository.h" + +#if defined(QT_PLACE_LIBRARY) + #include <QDebug> +#endif + +static const char *media_objects_element = "images"; +static const char *media_element = "image"; +static const char *media_count = "totalNumberOfImages"; +static const char *media_url = "url"; +static const char *media_provider_id = "provider"; +static const char *media_provider_name = "providerDisplayName"; + +QTM_USE_NAMESPACE + +QPlaceJSonMediaParser::QPlaceJSonMediaParser(QObject *parent) : + QObject(parent), + engine(NULL), + allMedia(0) +{ +} + +QPlaceJSonMediaParser::~QPlaceJSonMediaParser() +{ +} + +QList<QPlaceMediaObject> QPlaceJSonMediaParser::resultMedia() +{ + return media; +} + +uint QPlaceJSonMediaParser::allMediaCount() +{ + return allMedia; +} + +QPlaceMediaObject QPlaceJSonMediaParser::buildMediaObject(const QScriptValue &media) +{ + QPlaceMediaObject newMedia; + QScriptValue value = media.property(media_url); + if (value.isValid() && !value.toString().isEmpty()) { + newMedia.setUrl(value.toString()); + newMedia.setId(value.toString()); + } + + QString name, id, icon; + value = media.property(media_provider_name); + if (value.isValid() && !value.toString().isEmpty()) { + name = value.toString(); + } + value = media.property(media_provider_id); + if (value.isValid() && !value.toString().isEmpty()) { + id = value.toString(); + } + if (!name.isEmpty() || !id.isEmpty()) { + QPlaceSupplier sup; + sup.setName(name); + sup.setSupplierId(id); + newMedia.setSupplier(QPlaceSuppliersRepository::instance()->addSupplier(sup)); + } + + return newMedia; +} + +void QPlaceJSonMediaParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + media.clear(); + + QScriptValue sv = engine->evaluate("(" + data + ")"); + if (sv.isValid()) { + sv = sv.property(media_objects_element); + if (sv.isValid()) { + processMedia(sv); + emit finished(NoError, QString()); + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } +} + +void QPlaceJSonMediaParser::processMedia(const QScriptValue &mediaElement) +{ + QScriptValue value = mediaElement.property(media_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + media.append(buildMediaObject(it.value())); + } + } + } else { + media.append(buildMediaObject(value)); + } + } + value = mediaElement.property(media_count); + if (value.isValid()) { + allMedia = value.toUInt32(); + } +} diff --git a/src/plugins/places/nokia/qplacejsonmediaparser.h b/src/plugins/places/nokia/qplacejsonmediaparser.h new file mode 100644 index 00000000..c3d63f96 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonmediaparser.h @@ -0,0 +1,47 @@ +#ifndef QPLACEJSONMEDIAPARSER_H +#define QPLACEJSONMEDIAPARSER_H + +#include <QObject> +#include <QList> + +#include <qplacemediaobject.h> + +class QScriptEngine; +class QScriptValue; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonMediaParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonMediaParser(QObject *parent = 0); + virtual ~QPlaceJSonMediaParser(); + + QList<QPlaceMediaObject> resultMedia(); + uint allMediaCount(); + static QPlaceMediaObject buildMediaObject(const QScriptValue &place); + +signals: + void finished(const Error &error, const QString &errorMessage); + +public slots: + void processData(const QString &data); + +private: + void processMedia(const QScriptValue &contacts); + +private: + QScriptEngine *engine; + QList<QPlaceMediaObject> media; + uint allMedia; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONMEDIAPARSER_H diff --git a/src/plugins/places/nokia/qplacejsonrecommendationparser.cpp b/src/plugins/places/nokia/qplacejsonrecommendationparser.cpp new file mode 100644 index 00000000..947a299a --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonrecommendationparser.cpp @@ -0,0 +1,82 @@ +#include "qplacejsonrecommendationparser.h" + +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> +#include <QtScript/QScriptValueIterator> + +#include "qplacejsondetailsparser.h" +#include <qplace.h> + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +static const char *recommendations_element = "recommendations"; +static const char *recommendations_nearby_element = "nearby"; +static const char *recommendations_distance_element = "distance"; +static const char *recommendations_place_element = "place"; + +QTM_USE_NAMESPACE + +QPlaceJSonRecommendationParser::QPlaceJSonRecommendationParser(QObject *parent) : + QObject(parent), + engine(NULL) +{ +} + +QPlaceJSonRecommendationParser::~QPlaceJSonRecommendationParser() +{ +} + +QList<QPlaceSearchResult> QPlaceJSonRecommendationParser::results() +{ + return searchResults; +} + +void QPlaceJSonRecommendationParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + searchResults.clear(); + + QScriptValue sv = engine->evaluate("(" + data + ")"); + if (sv.isValid()) { + sv = sv.property(recommendations_element); + if (sv.isValid()) { + QScriptValueIterator it(sv.property(recommendations_nearby_element)); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + processResultElement(it.value()); + } + } + emit finished(NoError, QString()); + return; + } + } + emit finished(ParsingError, QString("JSON data are invalid")); +} + +void QPlaceJSonRecommendationParser::processResultElement(const QScriptValue &value) +{ + QPlaceSearchResult result; + result.setType(QPlaceSearchResult::Place); + + // Processing properties + QScriptValue distance = value.property(recommendations_distance_element); + if (distance.isValid() && !distance.toString().isEmpty()) { + bool isConverted; + double distanceValue = distance.toString().toDouble(&isConverted); + if (isConverted) { + result.setDistance(distanceValue); + } + } + QScriptValue place = value.property(recommendations_place_element); + if (place.isValid()) { + QPlace newPlace = QPlaceJSonDetailsParser::buildPlace(place); + result.setPlace(newPlace); + searchResults.append(result); + } +} diff --git a/src/plugins/places/nokia/qplacejsonrecommendationparser.h b/src/plugins/places/nokia/qplacejsonrecommendationparser.h new file mode 100644 index 00000000..168d1369 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonrecommendationparser.h @@ -0,0 +1,44 @@ +#ifndef QPLACEJSONRECOMENDATIONPARSER_H +#define QPLACEJSONRECOMENDATIONPARSER_H + +#include <QObject> +#include <QList> + +#include <qplacesearchresult.h> + +class QScriptEngine; +class QScriptValue; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonRecommendationParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonRecommendationParser(QObject *parent = 0); + virtual ~QPlaceJSonRecommendationParser(); + + QList<QPlaceSearchResult> results(); + +signals: + void finished(const Error &error, const QString &errorMessage); + +public slots: + void processData(const QString &data); + +private: + void processResultElement(const QScriptValue &value); + +private: + QScriptEngine *engine; + QList<QPlaceSearchResult> searchResults; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONRECOMENDATIONPARSER_H diff --git a/src/plugins/places/nokia/qplacejsonreviewparser.cpp b/src/plugins/places/nokia/qplacejsonreviewparser.cpp new file mode 100644 index 00000000..022495c7 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonreviewparser.cpp @@ -0,0 +1,177 @@ +#include "qplacejsonreviewparser.h" + +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> +#include <QtScript/QScriptValueIterator> + +#include <qplacereview.h> +#include <qplacesupplier.h> +#include "qplacesuppliersrepository.h" + +#if defined(QT_PLACES_LIBRARY) + #include <QDebug> +#endif + +static const char *reviews_element = "reviews"; +static const char *review_element = "review"; +static const char *review_count = "totalNumberOfReviews"; +static const char *review_id_element = "a_id"; +static const char *review_date_element = "creationDate"; +static const char *review_description_element = "description"; +static const char *review_minus_element = "minusCount"; +static const char *review_originator_element = "originatorUrl"; +static const char *review_plus_element = "plusCount"; +static const char *review_rating_element = "rating"; +static const char *review_title_element = "title"; +static const char *review_username_element = "user"; +static const char *review_userid_element = "uuid"; +static const char *review_vendor_element = "vendor"; +static const char *review_vendorname_element = "vendorDisplayName"; +static const char *review_vendoricon_element = "vendorIconUrl"; + +QTM_USE_NAMESPACE + +QPlaceJSonReviewParser::QPlaceJSonReviewParser(QObject *parent) : + QObject(parent), + engine(NULL), + allReviews(0) +{ +} + +QPlaceJSonReviewParser::~QPlaceJSonReviewParser() +{ +} + +QList<QPlaceReview> QPlaceJSonReviewParser::results() +{ + return reviews; +} + +uint QPlaceJSonReviewParser::allReviewsCount() +{ + return allReviews; +} + +QPlaceReview QPlaceJSonReviewParser::buildReview(const QScriptValue &review) +{ + QPlaceReview newReview; + QScriptValue value = review.property(review_id_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setReviewId(value.toString()); + } + value = review.property(review_date_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setDate(value.toString()); + } + value = review.property(review_minus_element); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + uint number = value.toString().toUInt(&isConverted); + if (isConverted) { + newReview.setNotHelpfulVotings(number); + } + } + value = review.property(review_plus_element); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + uint number = value.toString().toUInt(&isConverted); + if (isConverted) { + newReview.setHelpfulVotings(number); + } + } + value = review.property(review_originator_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setOriginatorURL(value.toString()); + } + value = review.property(review_description_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setDescription(value.toString()); + } + value = review.property(review_title_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setTitle(value.toString()); + } + value = review.property(review_username_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setUserName(value.toString()); + } + value = review.property(review_userid_element); + if (value.isValid() && !value.toString().isEmpty()) { + newReview.setUserId(value.toString()); + } + + QString name, id, icon; + value = review.property(review_vendorname_element); + if (value.isValid() && !value.toString().isEmpty()) { + name = value.toString(); + } + value = review.property(review_vendor_element); + if (value.isValid() && !value.toString().isEmpty()) { + id = value.toString(); + } + value = review.property(review_vendoricon_element); + if (value.isValid() && !value.toString().isEmpty()) { + icon = value.toString(); + } + if (!name.isEmpty() || !id.isEmpty()) { + QPlaceSupplier sup; + sup.setName(name); + sup.setSupplierId(id); + sup.setSupplierIconURL(icon); + newReview.setSupplier(QPlaceSuppliersRepository::instance()->addSupplier(sup)); + } + + value = review.property(review_rating_element); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + double number = value.toString().toDouble(&isConverted); + if (isConverted) { + newReview.setRating(number); + } + } + return newReview; +} + +void QPlaceJSonReviewParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + reviews.clear(); + + QScriptValue sv = engine->evaluate("(" + data + ")"); + if (sv.isValid()) { + sv = sv.property(reviews_element); + if (sv.isValid()) { + processReviews(sv); + emit finished(NoError, QString()); + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } +} + +void QPlaceJSonReviewParser::processReviews(const QScriptValue &reviewsElement) +{ + QScriptValue value = reviewsElement.property(review_element); + if (value.isValid()) { + if (value.isArray()) { + QScriptValueIterator it(value); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + reviews.append(buildReview(it.value())); + } + } + } else { + reviews.append(buildReview(value)); + } + } + value = reviewsElement.property(review_count); + if (value.isValid()) { + allReviews = value.toUInt32(); + } +} diff --git a/src/plugins/places/nokia/qplacejsonreviewparser.h b/src/plugins/places/nokia/qplacejsonreviewparser.h new file mode 100644 index 00000000..70adcbfd --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonreviewparser.h @@ -0,0 +1,47 @@ +#ifndef QPLACEJSONREVIEWPARSER_H +#define QPLACEJSONREVIEWPARSER_H + +#include <QObject> +#include <QList> + +#include <qplacesearchresult.h> + +class QScriptEngine; +class QScriptValue; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonReviewParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonReviewParser(QObject *parent = 0); + virtual ~QPlaceJSonReviewParser(); + + QList<QPlaceReview> results(); + uint allReviewsCount(); + static QPlaceReview buildReview(const QScriptValue &place); + +signals: + void finished(const Error &error, const QString &errorMessage); + +public slots: + void processData(const QString &data); + +private: + void processReviews(const QScriptValue &contacts); + +private: + QScriptEngine *engine; + QList<QPlaceReview> reviews; + uint allReviews; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONREVIEWPARSER_H diff --git a/src/plugins/places/nokia/qplacejsonsearchparser.cpp b/src/plugins/places/nokia/qplacejsonsearchparser.cpp new file mode 100644 index 00000000..109da7a7 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonsearchparser.cpp @@ -0,0 +1,350 @@ +#include "qplacejsonsearchparser.h" + +#include <QtScript/QScriptEngine> +#include <QtScript/QScriptValue> +#include <QtScript/QScriptValueIterator> + +#include <qplace.h> +#include <qplacegeocoordinate.h> +#include <qplacecontact.h> +#include <qplacelocation.h> +#include <qplaceaddress.h> +#include <qplacerating.h> +#include <qplacecategory.h> +#include <qplacesupplier.h> +#include <qplacesearchresult.h> + +#include "qplacesuppliersrepository.h" +#include "qplacecategoriesrepository.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +//search const +static const char *search_results_element = "results"; +static const char *search_type_element = "type"; +static const char *search_type_dym_value = "DID_YOU_MEAN_SEARCH"; +static const char *search_type_addplace_value = "ADPLACE"; + +static const char *search_categories_element = "categories"; +static const char *search_categories_id_value = "id"; +static const char *search_properties_element = "properties"; +static const char *search_properties_title_value = "title"; +static const char *search_properties_distance_value = "geoDistance"; + +static const char *search_properties_placeid_value = "placesId"; +static const char *search_properties_description_value = "description"; +static const char *search_properties_supliers_value = "dataProvider"; +static const char *search_properties_phone_value = "phoneNumber"; +static const char *search_properties_url_value = "url"; +static const char *search_properties_rating_value = "placesRating"; + +static const char *search_properties_longitude_value = "geoLongitude"; +static const char *search_properties_latitude_value = "geoLatitude"; +static const char *search_properties_longitude_bb1_value = "GEO_BBX_LONGITUDE_1"; +static const char *search_properties_latitude_bb1_value = "GEO_BBX_LATITUDE_1"; +static const char *search_properties_longitude_bb2_value = "GEO_BBX_LONGITUDE_2"; +static const char *search_properties_latitude_bb2_value = "GEO_BBX_LATITUDE_2"; + +static const char *search_properties_address_country = "addrCountryName"; +static const char *search_properties_address_county = "addrCountyName"; +static const char *search_properties_address_country_code = "addrCountryCode"; +static const char *search_properties_address_state = "addrStateName"; +static const char *search_properties_address_code = "addrPostalCode"; +static const char *search_properties_address_city = "addrCityName"; +static const char *search_properties_address_district = "addrDistrictName"; +static const char *search_properties_address_street = "addrStreetName"; +static const char *search_properties_address_house_number = "addrHouseNumber"; + +QTM_USE_NAMESPACE + +QPlaceJSonSearchParser::QPlaceJSonSearchParser(QObject *parent) : + QObject(parent), + engine(NULL) +{ +} + +QPlaceJSonSearchParser::~QPlaceJSonSearchParser() +{ + searchResultsList.clear(); +} + +QList<QPlaceSearchResult> QPlaceJSonSearchParser::searchResults() +{ + return searchResultsList; +} + +void QPlaceJSonSearchParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + searchResultsList.clear(); + + QScriptValue sv = engine->evaluate("(" + data + ")"); + if (sv.isValid()) { + QScriptValueIterator it(sv.property(search_results_element)); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + processResultElement(it.value()); + } + } + emit finished(NoError, QString()); + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } +} + +void QPlaceJSonSearchParser::processResultElement(const QScriptValue &value) +{ + // Procesing DYM string + QScriptValue type = value.property(search_type_element); + if (type.isValid() && type.toString() == search_type_dym_value) { + QScriptValue properties = value.property(search_properties_element); + if (properties.isValid()) { + QScriptValue title = properties.property(search_properties_title_value); + if (title.isValid() && !title.toString().isEmpty()) { + QPlaceSearchResult result; + QScriptValue type = properties.property(search_type_element); + if (type.isValid()) { + result = processPlaceElement(value); + } + result.setType(QPlaceSearchResult::DidYouMeanSuggestion); + result.setDidYouMeanSuggestion(title.toString()); + searchResultsList.append(result); + } + } + // processing place element + } else { + searchResultsList.append(processPlaceElement(value)); + } +} + +QPlaceSearchResult QPlaceJSonSearchParser::processPlaceElement(const QScriptValue &results) +{ + QPlaceSearchResult result; + result.setType(QPlaceSearchResult::Place); + QPlace newPlace; + result.setPlace(newPlace); + + // Processing properties + QScriptValue properties = results.property(search_properties_element); + if (properties.isValid()) { + // QSearchResult properties + QScriptValue distance = properties.property(search_properties_distance_value); + if (distance.isValid() && !distance.toString().isEmpty()) { + bool isConverted; + double distanceValue = distance.toString().toDouble(&isConverted); + if (isConverted) { + result.setDistance(distanceValue); + } + } + // Place properties + QScriptValue value = properties.property(search_properties_title_value); + if (value.isValid() && !value.toString().isEmpty()) { + newPlace.setName(value.toString()); + } + value = properties.property(search_type_element); + if (value.isValid() && !value.toString().isEmpty()) { + QVariantHash addData; + QString type = value.toString(); + addData.insert(search_type_element, type); + newPlace.setAdditionalData(addData); + } + value = properties.property(search_properties_placeid_value); + if (value.isValid() && !value.toString().isEmpty()) { + newPlace.setPlaceId(value.toString()); + } + value = properties.property(search_properties_description_value); + if (value.isValid() && !value.toString().isEmpty()) { + newPlace.setShortDescription(value.toString()); + } + value = properties.property(search_properties_supliers_value); + if (value.isValid() && !value.toString().isEmpty()) { + QPlaceSupplier sup; + sup.setName(value.toString()); + QList<QPlaceSupplier> list; + list.append(QPlaceSuppliersRepository::instance()->addSupplier(sup)); + newPlace.setSuppliers(list); + } + processContacts(properties, &newPlace); + processRating(properties, &newPlace); + processLocation(properties, &newPlace); + + value = results.property(search_categories_element); + if (value.isValid()) { + processCategories(value, &newPlace); + } + } + return result; +} + +void QPlaceJSonSearchParser::processContacts(const QScriptValue &properties, QPlace *place) +{ + QList<QPlaceContact> contacts; + QScriptValue value = properties.property(search_properties_url_value); + if (value.isValid() && !value.toString().isEmpty()) { + QPlaceContact contact; + contact.setType(QPlaceContact::URL); + contact.setValue(value.toString()); + contacts.append(contact); + } + value = properties.property(search_properties_phone_value); + if (value.isValid() && !value.toString().isEmpty()) { + QPlaceContact contact; + contact.setType(QPlaceContact::Phone); + contact.setValue(value.toString()); + contacts.append(contact); + } + place->setContacts(contacts); +} + + +void QPlaceJSonSearchParser::processCategories(const QScriptValue &categories, QPlace *place) +{ + QList<QPlaceCategory> categoriesList; + QScriptValueIterator it(categories); + while (it.hasNext()) { + it.next(); + // array contains count as last element + if (it.name() != "length") { + QScriptValue value = it.value().property(search_categories_id_value); + if (value.isValid() && !value.toString().isEmpty()) { + QPlaceCategory category = QPlaceCategoriesRepository::instance()->mapCategory( + value.toString()); + if (!category.isEmpty()) { + categoriesList.append(category); + } + } + } + } + place->setCategories(categoriesList); +} + +void QPlaceJSonSearchParser::processRating(const QScriptValue &properties, QPlace *place) +{ + QScriptValue value = properties.property(search_properties_rating_value); + if (value.isValid() && !value.toString().isEmpty()) { + bool isConverted; + double ratingValue = value.toString().toDouble(&isConverted); + if (isConverted) { + QPlaceRating rating; + rating.setValue(ratingValue); + place->setRating(rating); + } + } +} + +void QPlaceJSonSearchParser::processAddress(const QScriptValue &properties, QPlaceLocation *location) +{ + QPlaceAddress newAddress; + QScriptValue value = properties.property(search_properties_address_country); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCountryName(value.toString()); + } + value = properties.property(search_properties_address_county); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCounty(value.toString()); + } + value = properties.property(search_properties_address_country_code); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCountry(value.toString()); + } + value = properties.property(search_properties_address_state); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setState(value.toString()); + } + value = properties.property(search_properties_address_code); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setPostalCode(value.toString()); + } + value = properties.property(search_properties_address_city); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setCity(value.toString()); + } + value = properties.property(search_properties_address_district); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setDistrict(value.toString()); + } + value = properties.property(search_properties_address_street); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setStreet(value.toString()); + } + value = properties.property(search_properties_address_house_number); + if (value.isValid() && !value.toString().isEmpty()) { + newAddress.setHouseNumber(value.toString()); + } + location->setAddress(newAddress); +} + +void QPlaceJSonSearchParser::processLocation(const QScriptValue &properties, QPlace *place) +{ + QPlaceLocation location; + + bool latOK(false); + bool lonOK(false); + double latitude; + double longitude; + + // display position + QScriptValue value = properties.property(search_properties_latitude_value); + if (value.isValid() && !value.toString().isEmpty()) { + latitude = value.toString().toDouble(&latOK); + } + value = properties.property(search_properties_longitude_value); + if (value.isValid() && !value.toString().isEmpty()) { + longitude = value.toString().toDouble(&lonOK); + } + if (latOK && lonOK) { + QPlaceGeoCoordinate pos; + pos.setLatitude(latitude); + pos.setLongitude(longitude); + location.setDisplayPosition(pos); + } + + // bounding box + QPlaceGeoCoordinate bottomRight; + QPlaceGeoCoordinate topLeft; + latOK = false; + lonOK = false; + value = properties.property(search_properties_latitude_bb1_value); + if (value.isValid() && !value.toString().isEmpty()) { + latitude = value.toString().toDouble(&latOK); + } + value = properties.property(search_properties_longitude_bb1_value); + if (value.isValid() && !value.toString().isEmpty()) { + longitude = value.toString().toDouble(&lonOK); + } + if (latOK && lonOK) { + topLeft.setLatitude(latitude); + topLeft.setLongitude(longitude); + } + + latOK = false; + lonOK = false; + value = properties.property(search_properties_latitude_bb2_value); + if (value.isValid() && !value.toString().isEmpty()) { + latitude = value.toString().toDouble(&latOK); + } + value = properties.property(search_properties_longitude_bb2_value); + if (value.isValid() && !value.toString().isEmpty()) { + longitude = value.toString().toDouble(&lonOK); + } + if (latOK && lonOK) { + bottomRight.setLatitude(latitude); + bottomRight.setLongitude(longitude); + } + + if (topLeft.isValid() && bottomRight.isValid()) { + QPlaceGeoBoundingBox boundingBox; + boundingBox.setTopLeft(topLeft); + boundingBox.setBottomRight(bottomRight); + location.setMapView(boundingBox); + } + + processAddress(properties, &location); + place->setLocation(location); +} diff --git a/src/plugins/places/nokia/qplacejsonsearchparser.h b/src/plugins/places/nokia/qplacejsonsearchparser.h new file mode 100644 index 00000000..6a87f9ff --- /dev/null +++ b/src/plugins/places/nokia/qplacejsonsearchparser.h @@ -0,0 +1,50 @@ +#ifndef QPLACEJSONSEARCHPARSER_H +#define QPLACEJSONSEARCHPARSER_H + +#include <QObject> +#include <QList> + +#include <qplacecategory.h> +#include <qplacesearchresult.h> + +class QScriptEngine; +class QScriptValue; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonSearchParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonSearchParser(QObject *parent = 0); + virtual ~QPlaceJSonSearchParser(); + + QList<QPlaceSearchResult> searchResults(); + +signals: + void finished(const Error &error, const QString &errorMessage); + +public slots: + void processData(const QString &data); + +private: + void processResultElement(const QScriptValue &value); + QPlaceSearchResult processPlaceElement(const QScriptValue &value); + void processContacts(const QScriptValue &properties, QPlace *place); + void processCategories(const QScriptValue &categories, QPlace *place); + void processRating(const QScriptValue &properties, QPlace *place); + void processAddress(const QScriptValue &properties, QPlaceLocation *location); + void processLocation(const QScriptValue &properties, QPlace *place); +private: + QScriptEngine *engine; + QList<QPlaceSearchResult> searchResultsList; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONSEARCHPARSER_H diff --git a/src/plugins/places/nokia/qplacejsontextpredictionparser.cpp b/src/plugins/places/nokia/qplacejsontextpredictionparser.cpp new file mode 100644 index 00000000..445fcfca --- /dev/null +++ b/src/plugins/places/nokia/qplacejsontextpredictionparser.cpp @@ -0,0 +1,43 @@ +#include "qplacejsontextpredictionparser.h" + +#include <QtScript/QScriptEngine> + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +QPlaceJSonTextPredictionParser::QPlaceJSonTextPredictionParser(QObject *parent) : + QObject(parent), + engine(NULL) +{ +} + +QStringList QPlaceJSonTextPredictionParser::predictions() +{ + return suggestions; +} + +void QPlaceJSonTextPredictionParser::processData(const QString &data) +{ + if (!engine) { + engine = new QScriptEngine(this); + } + suggestions.clear(); + + QScriptValue sv = engine->evaluate(data); + if (sv.isValid() && sv.isArray()) { + qScriptValueToSequence(sv, suggestions); + +#if defined(QT_PLACES_LOGGING) + qDebug() << "QJSonParserSuggestions::processData - list value: "; + foreach (QString str, suggestions) { + qDebug() << str; + } +#endif + emit finished(NoError, QString()); + } else { + emit finished(ParsingError, QString("JSON data are invalid")); + } +} diff --git a/src/plugins/places/nokia/qplacejsontextpredictionparser.h b/src/plugins/places/nokia/qplacejsontextpredictionparser.h new file mode 100644 index 00000000..be0e8970 --- /dev/null +++ b/src/plugins/places/nokia/qplacejsontextpredictionparser.h @@ -0,0 +1,36 @@ +#ifndef QPLACEJSONTEXTPREDICTIONPARSER_H +#define QPLACEJSONTEXTPREDICTIONPARSER_H + +#include <QObject> +#include <QStringList> + +#include <qmobilityglobal.h> + +class QScriptEngine; + +QTM_BEGIN_NAMESPACE + +class QPlaceJSonTextPredictionParser : public QObject +{ + Q_OBJECT +public: + enum Error { + NoError, + ParsingError + }; + + explicit QPlaceJSonTextPredictionParser(QObject *parent = 0); + + QStringList predictions(); +signals: + void finished(const QPlaceJSonTextPredictionParser::Error &error, const QString &errorMessage); +public slots: + void processData(const QString &data); +private: + QScriptEngine *engine; + QStringList suggestions; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEJSONTEXTPREDICTIONPARSER_H diff --git a/src/plugins/places/nokia/qplacemanagerengineimpl.cpp b/src/plugins/places/nokia/qplacemanagerengineimpl.cpp new file mode 100644 index 00000000..77908477 --- /dev/null +++ b/src/plugins/places/nokia/qplacemanagerengineimpl.cpp @@ -0,0 +1,192 @@ +#include "qplacemanagerengineimpl.h" + +#include "qplacecategoriesrepository.h" +#include "qplacetextpredictionreplyimpl.h" +#include "qplacesearchreplyimpl.h" +#include "qplacereviewreplyimpl.h" +#include "qplacemediareplyimpl.h" +#include "qplacerecommendationreplyimpl.h" +#include "qplacedetailsreplyimpl.h" +#include "qplaceratingreplyimpl.h" +#include "qplacerestmanager.h" +#include "qplacerestreply.h" + +QTM_USE_NAMESPACE + +const char *MANAGER_NAME = "com.nokia.places/0.9"; + +QPlaceManagerEngineImpl::QPlaceManagerEngineImpl(QObject *parent) + : QPlaceManagerEngine(parent) +{ +} + +QPlaceManagerEngineImpl::~QPlaceManagerEngineImpl() +{ +} + +QString QPlaceManagerEngineImpl::managerName() const +{ + return MANAGER_NAME; +} + +QPlaceDetailsReply *QPlaceManagerEngineImpl::getPlaceDetails(const QString &placeId) +{ + QPlaceDetailsReplyImpl *reply = NULL; + QPlaceRestReply *restReply = QPlaceRestManager::instance()->sendPlaceRequest(placeId); + if (restReply) { + reply = new QPlaceDetailsReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceMediaReply *QPlaceManagerEngineImpl::getMedia(const QPlace &place, const QPlaceQuery &query) +{ + QPlaceMediaReplyImpl *reply = NULL; + QPlaceRestReply *restReply = QPlaceRestManager::instance()->sendPlaceImagesRequest(place.placeId(), + query); + if (restReply) { + reply = new QPlaceMediaReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceReply *QPlaceManagerEngineImpl::postRating(const QPlace &place, qreal value) +{ + QPlaceRatingReplyImpl *reply = NULL; + QPlaceRestReply *restReply = QPlaceRestManager::instance()->postRatingRequest(place.placeId(), + QString(), + value); + if (restReply) { + reply = new QPlaceRatingReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceReviewReply *QPlaceManagerEngineImpl::getReviews(const QPlace &place, const QPlaceQuery &query) +{ + QPlaceReviewReplyImpl *reply = NULL; + QPlaceRestReply *restReply = QPlaceRestManager::instance()->sendPlaceReviewRequest(place.placeId(), + query); + if (restReply) { + reply = new QPlaceReviewReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceSearchReply *QPlaceManagerEngineImpl::searchForPlaces(const QPlaceSearchQuery &query) +{ + QPlaceSearchReplyImpl *reply = NULL; + QPlaceRestReply *restReply = QPlaceRestManager::instance()->sendSuggestionRequest(query); + if (restReply) { + reply = new QPlaceSearchReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceSearchReply *QPlaceManagerEngineImpl::recommendations(const QPlace &place, const QPlaceSearchQuery &query) +{ + QPlaceRecommendationReplyImpl *reply = NULL; + QPlaceSearchQuery newQuery = query; + newQuery.setSearchTerm(place.placeId()); + QPlaceRestReply *restReply = QPlaceRestManager::instance()->sendRecommendationRequest(newQuery, QString()); + if (restReply) { + reply = new QPlaceRecommendationReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceTextPredictionReply *QPlaceManagerEngineImpl::textPredictions(const QPlaceSearchQuery &query) +{ + QPlaceTextPreditionReplyImpl *reply = NULL; + QPlaceRestReply *restReply = QPlaceRestManager::instance()->sendSuggestionRequest(query); + if (restReply) { + reply = new QPlaceTextPreditionReplyImpl(restReply, this); + connect(reply, SIGNAL(processingError(QPlaceReply*,QPlaceReply::Error,QString)), + this, SLOT(processingError(QPlaceReply*,QPlaceReply::Error,QString))); + connect(reply, SIGNAL(processingFinished(QPlaceReply*)), + this, SLOT(processingFinished(QPlaceReply*))); + } + return reply; +} + +QPlaceManager::ConnectivityMode QPlaceManagerEngineImpl::connectivityMode() const +{ + return QPlaceManager::OnlineMode; +} + +void QPlaceManagerEngineImpl::setConnectivityMode(QPlaceManager::ConnectivityMode connectivityMode) +{ + Q_UNUSED(connectivityMode) + // only QPlaceManager::OnlineMode is suppoerted +} + +QList<QPlaceManager::ConnectivityMode> QPlaceManagerEngineImpl::supportedConnectivityModes() const +{ + QList<QPlaceManager::ConnectivityMode> modes; + modes.append(QPlaceManager::OnlineMode); + return modes; +} + +QPlaceManager::SearchVisibilityScope QPlaceManagerEngineImpl::searchVisibilityScope() const +{ + return QPlaceManager::PublicSearch; +} + +void QPlaceManagerEngineImpl::setSearchVisbilityScope(QPlaceManager::SearchVisibilityScope scope) +{ + Q_UNUSED(scope) + // only QPlaceManager::PublicSearch is supported +} + +QList<QPlaceManager::SearchVisibilityScope> QPlaceManagerEngineImpl::supportedSearchVisibilityScopes() const +{ + QList<QPlaceManager::SearchVisibilityScope> modes; + modes.append(QPlaceManager::PublicSearch); + return modes; +} + +QPlaceReply *QPlaceManagerEngineImpl::initializeCategories(const QString &categorySystemId) +{ + return QPlaceCategoriesRepository::instance()->initializeCategories(categorySystemId); +} + +QList<QPlaceCategory> QPlaceManagerEngineImpl::categories() const +{ + return QPlaceCategoriesRepository::instance()->categories(); +} + +void QPlaceManagerEngineImpl::processingError(QPlaceReply *reply, + const QPlaceReply::Error &errorId, + const QString &errorMessage) +{ + emit error(reply, errorId, errorMessage); +} + +void QPlaceManagerEngineImpl::processingFinished(QPlaceReply *reply) +{ + emit finished(reply); +} diff --git a/src/plugins/places/nokia/qplacemanagerengineimpl.h b/src/plugins/places/nokia/qplacemanagerengineimpl.h new file mode 100644 index 00000000..14b1714d --- /dev/null +++ b/src/plugins/places/nokia/qplacemanagerengineimpl.h @@ -0,0 +1,48 @@ +#ifndef QPLACEMANAGERENGINEIMPL_H +#define QPLACEMANAGERENGINEIMPL_H + +#include <qplacemanagerengine.h> + +QTM_BEGIN_NAMESPACE + +class QPlaceManagerEngineImpl : public QPlaceManagerEngine +{ + Q_OBJECT +public: + + QPlaceManagerEngineImpl(QObject *parent = 0); + ~QPlaceManagerEngineImpl(); + + QString managerName() const; + + QPlaceDetailsReply *getPlaceDetails(const QString &placeId); + + QPlaceMediaReply * getMedia(const QPlace &place, const QPlaceQuery &query); + + QPlaceReply *postRating(const QPlace &place, qreal value); + + QPlaceReviewReply *getReviews(const QPlace &place, const QPlaceQuery &query); + + QPlaceSearchReply *searchForPlaces(const QPlaceSearchQuery &query); + QPlaceSearchReply *recommendations(const QPlace &place, const QPlaceSearchQuery &query); + QPlaceTextPredictionReply *textPredictions(const QPlaceSearchQuery &query); + + QPlaceManager::ConnectivityMode connectivityMode() const; + void setConnectivityMode(QPlaceManager::ConnectivityMode connectivityMode); + QList<QPlaceManager::ConnectivityMode> supportedConnectivityModes() const; + + QPlaceManager::SearchVisibilityScope searchVisibilityScope() const; + void setSearchVisbilityScope(QPlaceManager::SearchVisibilityScope scope); + QList<QPlaceManager::SearchVisibilityScope> supportedSearchVisibilityScopes() const; + + QPlaceReply *initializeCategories(const QString &categorySystemId); + QList<QPlaceCategory> categories() const; + +private slots: + void processingError(QPlaceReply *reply, const QPlaceReply::Error &error, const QString &errorMessage); + void processingFinished(QPlaceReply *reply); +}; + +QTM_END_NAMESPACE + +#endif // QPLACEMANAGERENGINEIMPL_H diff --git a/src/plugins/places/nokia/qplacemediareplyimpl.cpp b/src/plugins/places/nokia/qplacemediareplyimpl.cpp new file mode 100644 index 00000000..3158ea78 --- /dev/null +++ b/src/plugins/places/nokia/qplacemediareplyimpl.cpp @@ -0,0 +1,71 @@ +#include "qplacemediareplyimpl.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceMediaReplyImpl::QPlaceMediaReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceMediaReply(parent), + restReply(reply) +{ + parser = new QPlaceJSonMediaParser(this); + + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + parser, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + connect(parser, SIGNAL(finished(QPlaceJSonMediaParser::Error,QString)), + this, SLOT(predictionsReady(QPlaceJSonMediaParser::Error,QString))); + } +} + +/*! + Destructor. +*/ +QPlaceMediaReplyImpl::~QPlaceMediaReplyImpl() +{ +} + +void QPlaceMediaReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceMediaReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceMediaReplyImpl::predictionsReady(const QPlaceJSonMediaParser::Error &errorId, + const QString &errorMessage) +{ + if (errorId == QPlaceJSonMediaParser::NoError) { + setMediaObjects(parser->resultMedia()); + setTotalCount(parser->allMediaCount()); + } else if (errorId == QPlaceJSonMediaParser::ParsingError) { + setError(ParseError, errorMessage); + emit error(this->error(), this->errorString()); + emit processingError(this, ParseError, errorMessage); + } + emit finished(); + emit processingFinished(this); + delete parser; + parser = NULL; + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplacemediareplyimpl.h b/src/plugins/places/nokia/qplacemediareplyimpl.h new file mode 100644 index 00000000..e3a7845d --- /dev/null +++ b/src/plugins/places/nokia/qplacemediareplyimpl.h @@ -0,0 +1,37 @@ +#ifndef QPLACEMEDIAREPLYIMPL_H +#define QPLACEMEDIAREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacemediareply.h> +#include "qplacerestreply.h" +#include "qplacejsonmediaparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceMediaReplyImpl : public QPlaceMediaReply +{ + Q_OBJECT +public: + explicit QPlaceMediaReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceMediaReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void predictionsReady(const QPlaceJSonMediaParser::Error &error, + const QString &errorMessage); + +private: + QPlaceRestReply *restReply; + QPlaceJSonMediaParser *parser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEMEDIAREPLYIMPL_H diff --git a/src/plugins/places/nokia/qplaceratingreplyimpl.cpp b/src/plugins/places/nokia/qplaceratingreplyimpl.cpp new file mode 100644 index 00000000..731ae6aa --- /dev/null +++ b/src/plugins/places/nokia/qplaceratingreplyimpl.cpp @@ -0,0 +1,59 @@ +#include "qplaceratingreplyimpl.h" + +#include <QHash> + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceRatingReplyImpl::QPlaceRatingReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceReply(parent), + restReply(reply) +{ + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + this, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + } +} + +/*! + Destructor. +*/ +QPlaceRatingReplyImpl::~QPlaceRatingReplyImpl() +{ +} + +void QPlaceRatingReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceRatingReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceRatingReplyImpl::restFinished(const QString &data) +{ + Q_UNUSED(data); + emit finished(); + emit processingFinished(this); + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplaceratingreplyimpl.h b/src/plugins/places/nokia/qplaceratingreplyimpl.h new file mode 100644 index 00000000..741adfeb --- /dev/null +++ b/src/plugins/places/nokia/qplaceratingreplyimpl.h @@ -0,0 +1,34 @@ +#ifndef QPLACERATINGREPLYIMPL_H +#define QPLACERATINGREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacereply.h> +#include "qplacerestreply.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceRatingReplyImpl : public QPlaceReply +{ + Q_OBJECT +public: + explicit QPlaceRatingReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceRatingReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void restFinished(const QString &data); + +private: + QPlaceRestReply *restReply; +}; + +QTM_END_NAMESPACE + +#endif // QPLACERATINGREPLYIMPL_H diff --git a/src/plugins/places/nokia/qplacerecommendationreplyimpl.cpp b/src/plugins/places/nokia/qplacerecommendationreplyimpl.cpp new file mode 100644 index 00000000..b7e0b178 --- /dev/null +++ b/src/plugins/places/nokia/qplacerecommendationreplyimpl.cpp @@ -0,0 +1,70 @@ +#include "qplacerecommendationreplyimpl.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceRecommendationReplyImpl::QPlaceRecommendationReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceSearchReply(parent), + restReply(reply) +{ + parser = new QPlaceJSonRecommendationParser(this); + + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + parser, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + connect(parser, SIGNAL(finished(QPlaceJSonRecommendationParser::Error,QString)), + this, SLOT(predictionsReady(QPlaceJSonRecommendationParser::Error,QString))); + } +} + +/*! + Destructor. +*/ +QPlaceRecommendationReplyImpl::~QPlaceRecommendationReplyImpl() +{ +} + +void QPlaceRecommendationReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceRecommendationReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceRecommendationReplyImpl::predictionsReady(const QPlaceJSonRecommendationParser::Error &errorId, + const QString &errorMessage) +{ + if (errorId == QPlaceJSonRecommendationParser::NoError) { + setResults(parser->results()); + } else if (errorId == QPlaceJSonRecommendationParser::ParsingError) { + setError(ParseError, errorMessage); + emit error(this->error(), this->errorString()); + emit processingError(this, ParseError, errorMessage); + } + emit finished(); + emit processingFinished(this); + delete parser; + parser = NULL; + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplacerecommendationreplyimpl.h b/src/plugins/places/nokia/qplacerecommendationreplyimpl.h new file mode 100644 index 00000000..525351c6 --- /dev/null +++ b/src/plugins/places/nokia/qplacerecommendationreplyimpl.h @@ -0,0 +1,37 @@ +#ifndef QPLACERECOMMENDATIONREPLYIMPL_H +#define QPLACERECOMMENDATIONREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacesearchreply.h> +#include "qplacerestreply.h" +#include "qplacejsonrecommendationparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceRecommendationReplyImpl : public QPlaceSearchReply +{ + Q_OBJECT +public: + explicit QPlaceRecommendationReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceRecommendationReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void predictionsReady(const QPlaceJSonRecommendationParser::Error &error, + const QString &errorMessage); + +private: + QPlaceRestReply *restReply; + QPlaceJSonRecommendationParser *parser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACERECOMMENDATIONREPLYIMPL_H diff --git a/src/plugins/places/nokia/qplacerestmanager.cpp b/src/plugins/places/nokia/qplacerestmanager.cpp new file mode 100644 index 00000000..f9f9ad87 --- /dev/null +++ b/src/plugins/places/nokia/qplacerestmanager.cpp @@ -0,0 +1,239 @@ +#include "qplacerestmanager.h" + +#include <QtNetwork> +#include <QHash> + +#include <qplacesearchquery.h> +#include "qplacerestreply.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +const char *placesServerUrl = "http://places.maps.ovi.com/rest/v1/places/"; +const char *searchServerUrl = "http://where.desktop.mos.svc.ovi.com/NOSe/json"; +const char *recomendation = "/recommendations/nearby"; +const char *reviews = "/reviews"; +const char *images = "/images"; +const char *categoriesTree = "categories/find-places/grouped"; + +const char *const_query = "&q="; +const char *const_tag = "&ta="; +const char *const_lat = "&lat="; +const char *const_lon = "&lon="; +const char *const_top = "&vpn="; +const char *const_bottom = "&vps="; +const char *const_left = "&vpw="; +const char *const_right = "&vpe="; +const char *const_limit = "&to="; +const char *const_offset = "&of="; +const char *const_dym = "&dym="; +const char *const_views = "?vi=where"; // address, poi or where (both) +const char *const_deviceproductid = "&dv=oviMaps"; // oviMaps, ml, rv + +const char *const_review_start = ";start="; +const char *const_review_limit = ";limit="; + +static QString searchServer; +static QString placeServer; + +QPlaceRestManager *QPlaceRestManager::mInstance = NULL; + +/*! + Constructor. +*/ +QPlaceRestManager::QPlaceRestManager(QObject *parent) : + QObject(parent) +{ + mManager = new QNetworkAccessManager(this); + + if (searchServer.isNull()) { + QSettings settings("Nokia"); + // no app name, they are in Nokia/OrganizationDefaults + searchServer = settings.value("searchURI").toString(); + if (searchServer.isEmpty()) { + searchServer = searchServerUrl; + } + placeServer = settings.value("placesURI").toString(); + if (placeServer.isEmpty()) { + placeServer = placesServerUrl; + } + } +} + +/*! + Method creating instance of rest provider. +*/ +QPlaceRestManager *QPlaceRestManager::instance() +{ + if (!mInstance) { + mInstance = new QPlaceRestManager(); + } + return mInstance; +} + +/*! + Predefines a places request and executes sendGeneralRequest(). +*/ +QPlaceRestReply *QPlaceRestManager::sendPlaceRequest(const QString &placeId) +{ + return sendGeneralRequest(placeServer + placeId); +} + +QPlaceRestReply *QPlaceRestManager::sendPlaceImagesRequest(const QString &placeId, const QPlaceQuery ¶ms) +{ + Q_UNUSED(params) + return sendGeneralRequest(placeServer + placeId + images); +} + +/*! + Predefines a review request and executes sendGeneralRequest(). +*/ +QPlaceRestReply *QPlaceRestManager::sendPlaceReviewRequest(const QString &placeId, const QPlaceQuery ¶ms) +{ + QString query = placeServer + placeId + reviews; + if (params.offset() > -1) { + query += const_review_start + QString::number(params.offset()); + } + if (params.limit() > 0) { + query += const_review_limit + QString::number(params.limit()); + } + + return sendGeneralRequest(query); +} + +/*! + Predefines a recomendation request and executes sendGeneralRequest(). +*/ +QPlaceRestReply *QPlaceRestManager::sendRecommendationRequest(const QPlaceSearchQuery &query, const QString &userId) +{ + Q_UNUSED(userId); + return sendGeneralRequest(placeServer + query.searchTerm() + recomendation); +} + +/*! + Predefines a categories tree request and executes sendGeneralRequest(). +*/ +QPlaceRestReply *QPlaceRestManager::sendCategoriesTreeRequest() +{ + return sendGeneralRequest(placeServer + categoriesTree); +} + +/*! + Predefines a suggestion request and executes sendGeneralRequest(). +*/ +QPlaceRestReply *QPlaceRestManager::sendSuggestionRequest(const QPlaceSearchQuery &query) +{ + return sendGeneralRequest(prepareSearchRequest(query) + + const_query + query.searchTerm() + "&lh=1"); +} + +/*! + Predefines a search request and executes sendGeneralRequest(). +*/ +QPlaceRestReply *QPlaceRestManager::sendSearchRequest(const QPlaceSearchQuery &query) +{ + return sendGeneralRequest(prepareSearchRequest(query) + + const_query + query.searchTerm()); +} + +QPlaceRestReply *QPlaceRestManager::sendSearchByCategoryRequest(const QPlaceSearchQuery &query) +{ + return sendGeneralRequest(prepareSearchRequest(query) + + const_tag + query.searchTerm()); +} + +QPlaceRestReply *QPlaceRestManager::postRatingRequest(const QString &placeId, const QString &userId, const int &value) +{ + QNetworkRequest request; + + QString url = placesServerUrl + placeId + "/ugc/ratings"; + request.setUrl(url); + + QByteArray language; + language.append(QLocale::system().name().toLatin1()); + language.append(","); + language.append(QLocale::system().name().left(2).toLatin1()); + + request.setRawHeader("Accept-Language", language); + request.setRawHeader("Content-Type", "application/json"); + request.setRawHeader("Accept", "application/json"); + request.setRawHeader("X-Ovi-NcimUser", userId.toUtf8()); + +#if defined(QPLACES_LOGGING) + qDebug() << "QRestDataProvider::sendGeneralRequest: " + url; +#endif + QByteArray data = "{ratings:{rating:[{value:" + QString::number(value).toAscii() + ",type:OVERALL}]}}"; + return new QPlaceRestReply(mManager->post(request, data)); +} + +/*! + Sends a general predefined request. Is private. +*/ +QPlaceRestReply *QPlaceRestManager::sendGeneralRequest(const QUrl &url) +{ + QNetworkRequest request; + request.setUrl(url); + + QByteArray language; + language.append(QLocale::system().name().toLatin1()); + language.append(","); + language.append(QLocale::system().name().toLatin1()); + +#if defined(QPLACES_LOGGING) + qDebug() << "QRestDataProvider::sendGeneralRequest: Language - " + language; +#endif + + request.setRawHeader("Accept-Language", language); + +#if defined(QPLACES_LOGGING) + qDebug() << "QRestDataProvider::sendGeneralRequest: " + url.toString(); +#endif + + return new QPlaceRestReply(mManager->get(request)); +} + +/*! + Returns prepared search string. +*/ +QString QPlaceRestManager::prepareSearchRequest(const QPlaceSearchQuery &query) +{ + QString searchString(searchServer); + // add view and device parameters + searchString += const_views; + searchString += const_deviceproductid; + // process search center + QPlaceGeoCoordinate searchCentre = query.searchCenter(); + if (searchCentre.isValid()) { + searchString += const_lat + QString::number(searchCentre.latitude()); + searchString += const_lon + QString::number(searchCentre.longitude()); + } + // process view port + if (query.boundingBox().isValid()) { + searchString += const_top + QString::number(query.boundingBox().topLeft().latitude()); + searchString += const_left + QString::number(query.boundingBox().topLeft().longitude()); + searchString += const_bottom + QString::number(query.boundingBox().bottomRight().latitude()); + searchString += const_right + QString::number(query.boundingBox().bottomRight().longitude()); + } + + // processing limit + if (query.limit() > 0){ + searchString += const_limit + QString::number(query.limit()); + } + // processing offset + if (query.offset() > -1){ + searchString += const_offset + QString::number(query.offset()); + } + // process DYM + if (query.didYouMeanSuggestionNumber() > 0){ + searchString += const_dym + QString::number(query.didYouMeanSuggestionNumber()); + } + +#if defined(QPLACES_LOGGING) + qDebug() << "QRestDataProvider::prepareSearchRequest: " + searchString; +#endif + + return searchString; +} diff --git a/src/plugins/places/nokia/qplacerestmanager.h b/src/plugins/places/nokia/qplacerestmanager.h new file mode 100644 index 00000000..ffe2bdf0 --- /dev/null +++ b/src/plugins/places/nokia/qplacerestmanager.h @@ -0,0 +1,51 @@ +#ifndef QPLACERESTMANAGER_H +#define QPLACERESTMANAGER_H + +#include <QObject> + +#include <QtNetwork/QNetworkProxy> +#include <QtNetwork/QNetworkAccessManager> +#include <QtNetwork/QNetworkReply> + +#include <qmobilityglobal.h> +#include <qplacesearchquery.h> +#include "qplacerestreply.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceRestManager : public QObject +{ + Q_OBJECT + +public: + static QPlaceRestManager *instance(); + + QPlaceRestReply *sendPlaceRequest(const QString &placeId); + QPlaceRestReply *sendPlaceImagesRequest(const QString &placeId, const QPlaceQuery ¶ms); + QPlaceRestReply *sendPlaceReviewRequest(const QString &placeId, const QPlaceQuery ¶ms); + QPlaceRestReply *sendRecommendationRequest(const QPlaceSearchQuery &query, const QString &userId); + QPlaceRestReply *sendCategoriesTreeRequest(); + QPlaceRestReply *sendSearchRequest(const QPlaceSearchQuery &query); + QPlaceRestReply *sendSearchByCategoryRequest(const QPlaceSearchQuery &query); + QPlaceRestReply *sendSuggestionRequest(const QPlaceSearchQuery &query); + + QPlaceRestReply *postRatingRequest(const QString &placeId, const QString &userId, const int &value); + +private: + explicit QPlaceRestManager(QObject *parent = 0); + QPlaceRestReply *sendGeneralRequest(const QUrl &url); + //TODO: remove when engine is refactored out + QPlaceRestReply *sendGeneralRequest(const QString &url) { + return sendGeneralRequest(QUrl(url)); + } + + QString prepareSearchRequest(const QPlaceSearchQuery &query); + +private: + QNetworkAccessManager *mManager; + static QPlaceRestManager *mInstance; +}; + +QTM_END_NAMESPACE + +#endif // QPLACERESTMANAGER_H diff --git a/src/plugins/places/nokia/qplacerestreply.cpp b/src/plugins/places/nokia/qplacerestreply.cpp new file mode 100644 index 00000000..d6272cfe --- /dev/null +++ b/src/plugins/places/nokia/qplacerestreply.cpp @@ -0,0 +1,94 @@ +#include "qplacerestreply.h" + +#include <QtNetwork> +#include <QHash> + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceRestReply::QPlaceRestReply(QNetworkReply *reply, QObject *parent) : + QObject(parent), + mReply(reply), + mCanceled(false) +{ + if (mReply) { + connect(mReply, SIGNAL(error(QNetworkReply::NetworkError)), + this, SLOT(replyError(QNetworkReply::NetworkError))); + connect(mReply, SIGNAL(finished()), this, SLOT(replyFinished())); + } +} + +/*! + Destructor. +*/ +QPlaceRestReply::~QPlaceRestReply() +{ +#if defined(QT_PLACES_LOGGING) + qDebug() << "QRestReply::~QRestReply"; +#endif + if (mReply) { + if (!mReply->isFinished()) { + mReply->disconnect(this); + mReply->abort(); + } + mReply->deleteLater(); + } +} + +/*! + Emits signal 'replyReady' if request is done. +*/ +void QPlaceRestReply::replyFinished() +{ +#if defined(QT_PLACES_LOGGING) + qDebug() << "QRestReply::replyFinished"; +#endif + if (!mCanceled && (mReply->error() == QNetworkReply::NoError)) { + QByteArray response = mReply->readAll(); + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + QString string = codec->toUnicode(response); +#if defined(QT_PLACES_LOGGING) + qDebug() << "Data received: " + string; +#endif + emit finished(string); + } else if (mCanceled) { +#if defined(QT_PLACES_LOGGING) + qDebug() << "Canceled"; +#endif + emit error(QPlaceRestReply::Canceled); + } else { +#if defined(QT_PLACES_LOGGING) + qDebug() << "Network Error - " + QString::number(error); +#endif + emit error(QPlaceRestReply::NetworkError); + } + + mReply->deleteLater(); + mReply = NULL; +} + +void QPlaceRestReply::replyError(QNetworkReply::NetworkError error) +{ +#if defined(QT_PLACES_LOGGING) + qDebug() << "QRestReply::replyError: Network Error - " + QString::number(error); +#else + Q_UNUSED(error); +#endif +} + +void QPlaceRestReply::cancelProcessing() +{ +#if defined(QT_PLACES_LOGGING) + qDebug() << "QRestReply::cancelProcessing"; +#endif + mCanceled = true; + if (mReply && mReply->isRunning()) { + mReply->abort(); + } +} diff --git a/src/plugins/places/nokia/qplacerestreply.h b/src/plugins/places/nokia/qplacerestreply.h new file mode 100644 index 00000000..1ef9b416 --- /dev/null +++ b/src/plugins/places/nokia/qplacerestreply.h @@ -0,0 +1,46 @@ +#ifndef QPLACERESTREPLY_H +#define QPLACERESTREPLY_H + +#include <QObject> +#include <QHash> +#include <QtNetwork/QNetworkProxy> +#include <QtNetwork/QNetworkAccessManager> +#include <QtNetwork/QNetworkReply> + +#include <qmobilityglobal.h> + +QTM_BEGIN_NAMESPACE + +class QPlaceRestReply : public QObject +{ + Q_OBJECT +public: + explicit QPlaceRestReply(QNetworkReply *reply, QObject *parent = 0); + enum Error { + NoError, + Canceled, + NetworkError + }; + + ~QPlaceRestReply(); + + void cancelProcessing(); + +signals: + void finished(const QString &reply); + void error(QPlaceRestReply::Error error); + +private slots: + void replyFinished(); + void replyError(QNetworkReply::NetworkError error); + +private: + QNetworkReply *mReply; + bool mCanceled; + +friend class QRestManager; +}; + +QTM_END_NAMESPACE + +#endif // QPLACERESTREPLY_H diff --git a/src/plugins/places/nokia/qplacereviewreplyimpl.cpp b/src/plugins/places/nokia/qplacereviewreplyimpl.cpp new file mode 100644 index 00000000..edb068c3 --- /dev/null +++ b/src/plugins/places/nokia/qplacereviewreplyimpl.cpp @@ -0,0 +1,71 @@ +#include "qplacereviewreplyimpl.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceReviewReplyImpl::QPlaceReviewReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceReviewReply(parent), + restReply(reply) +{ + parser = new QPlaceJSonReviewParser(this); + + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + parser, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + connect(parser, SIGNAL(finished(QPlaceJSonReviewParser::Error,QString)), + this, SLOT(predictionsReady(QPlaceJSonReviewParser::Error,QString))); + } +} + +/*! + Destructor. +*/ +QPlaceReviewReplyImpl::~QPlaceReviewReplyImpl() +{ +} + +void QPlaceReviewReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceReviewReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceReviewReplyImpl::predictionsReady(const QPlaceJSonReviewParser::Error &errorId, + const QString &errorMessage) +{ + if (errorId == QPlaceJSonReviewParser::NoError) { + setReviews(parser->results()); + setTotalCount(parser->allReviewsCount()); + } else if (errorId == QPlaceJSonReviewParser::ParsingError) { + setError(ParseError, errorMessage); + emit error(this->error(), this->errorString()); + emit processingError(this, ParseError, errorMessage); + } + emit finished(); + emit processingFinished(this); + delete parser; + parser = NULL; + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplacereviewreplyimpl.h b/src/plugins/places/nokia/qplacereviewreplyimpl.h new file mode 100644 index 00000000..af439795 --- /dev/null +++ b/src/plugins/places/nokia/qplacereviewreplyimpl.h @@ -0,0 +1,37 @@ +#ifndef QPLACEREVIEWREPLYIMPL_H +#define QPLACEREVIEWREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacereviewreply.h> +#include "qplacerestreply.h" +#include "qplacejsonreviewparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceReviewReplyImpl : public QPlaceReviewReply +{ + Q_OBJECT +public: + explicit QPlaceReviewReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceReviewReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void predictionsReady(const QPlaceJSonReviewParser::Error &error, + const QString &errorMessage); + +private: + QPlaceRestReply *restReply; + QPlaceJSonReviewParser *parser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACEREVIEWREPLYIMPL_H diff --git a/src/plugins/places/nokia/qplacesearchreplyimpl.cpp b/src/plugins/places/nokia/qplacesearchreplyimpl.cpp new file mode 100644 index 00000000..cf4c713d --- /dev/null +++ b/src/plugins/places/nokia/qplacesearchreplyimpl.cpp @@ -0,0 +1,70 @@ +#include "qplacesearchreplyimpl.h" + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceSearchReplyImpl::QPlaceSearchReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceSearchReply(parent), + restReply(reply) +{ + parser = new QPlaceJSonSearchParser(this); + + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + parser, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + connect(parser, SIGNAL(finished(QPlaceJSonSearchParser::Error,QString)), + this, SLOT(predictionsReady(QPlaceJSonSearchParser::Error,QString))); + } +} + +/*! + Destructor. +*/ +QPlaceSearchReplyImpl::~QPlaceSearchReplyImpl() +{ +} + +void QPlaceSearchReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceSearchReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceSearchReplyImpl::predictionsReady(const QPlaceJSonSearchParser::Error &errorId, + const QString &errorMessage) +{ + if (errorId == QPlaceJSonSearchParser::NoError) { + setResults(parser->searchResults()); + } else if (errorId == QPlaceJSonSearchParser::ParsingError) { + setError(ParseError, errorMessage); + emit error(this->error(), this->errorString()); + emit processingError(this, ParseError, errorMessage); + } + emit finished(); + emit processingFinished(this); + delete parser; + parser = NULL; + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplacesearchreplyimpl.h b/src/plugins/places/nokia/qplacesearchreplyimpl.h new file mode 100644 index 00000000..5dfcb588 --- /dev/null +++ b/src/plugins/places/nokia/qplacesearchreplyimpl.h @@ -0,0 +1,37 @@ +#ifndef QPLACESEARCHREPLYIMPL_H +#define QPLACESEARCHREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacesearchreply.h> +#include "qplacerestreply.h" +#include "qplacejsonsearchparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceSearchReplyImpl : public QPlaceSearchReply +{ + Q_OBJECT +public: + explicit QPlaceSearchReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceSearchReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void predictionsReady(const QPlaceJSonSearchParser::Error &error, + const QString &errorMessage); + +private: + QPlaceRestReply *restReply; + QPlaceJSonSearchParser *parser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACESEARCHREPLYIMPL_H diff --git a/src/plugins/places/nokia/qplacesuppliersrepository.cpp b/src/plugins/places/nokia/qplacesuppliersrepository.cpp new file mode 100644 index 00000000..63a6aaf9 --- /dev/null +++ b/src/plugins/places/nokia/qplacesuppliersrepository.cpp @@ -0,0 +1,58 @@ +#include "qplacesuppliersrepository.h" + +#include <qplacesupplier.h> + +QTM_USE_NAMESPACE + +QPlaceSuppliersRepository *QPlaceSuppliersRepository::instance() +{ + static QPlaceSuppliersRepository instance; + return &instance; +} + +QPlaceSuppliersRepository::QPlaceSuppliersRepository(QObject *parent) + : QObject(parent) +{ +} + +QPlaceSuppliersRepository::~QPlaceSuppliersRepository() +{ + suppliers.clear(); +} + +QPlaceSupplier QPlaceSuppliersRepository::addSupplier(const QPlaceSupplier &src) +{ + QPlaceSupplier res; + QPlaceSupplier tmp; + + foreach (tmp, suppliers) { + if ((!src.supplierId().isEmpty() && src.supplierId() == tmp.supplierId()) + || (!src.name().isEmpty() && src.name() == tmp.name())) { + copyMissingData(src, tmp); + res = tmp; + break; + } + } + if (res.supplierId().isEmpty() && res.name().isEmpty()) { + res = src; + suppliers.append(res); + } + return res; +} + +void QPlaceSuppliersRepository::copyMissingData(const QPlaceSupplier &src, + QPlaceSupplier &target) +{ + if (target.name().isEmpty() && !src.name().isEmpty()) { + target.setName(src.name()); + } + if (target.supplierId().isEmpty() && !src.supplierId().isEmpty()) { + target.setSupplierId(src.supplierId()); + } + if (target.URL().isEmpty() && !src.URL().isEmpty()) { + target.setURL(src.URL()); + } + if (target.supplierIconURL().isEmpty() && !src.supplierIconURL().isEmpty()) { + target.setSupplierIconURL(src.supplierIconURL()); + } +} diff --git a/src/plugins/places/nokia/qplacesuppliersrepository.h b/src/plugins/places/nokia/qplacesuppliersrepository.h new file mode 100644 index 00000000..88b0d18f --- /dev/null +++ b/src/plugins/places/nokia/qplacesuppliersrepository.h @@ -0,0 +1,30 @@ +#ifndef QPLACESUPPLIERSREPOSITORY_H +#define QPLACESUPPLIERSREPOSITORY_H + +#include <QObject> +#include <QList> + +#include <qplacesupplier.h> +#include <qmobilityglobal.h> + +QTM_BEGIN_NAMESPACE + +class QPlaceSuppliersRepository : public QObject +{ +public: + static QPlaceSuppliersRepository *instance(); + ~QPlaceSuppliersRepository(); + + QPlaceSupplier addSupplier(const QPlaceSupplier &src); +private: + explicit QPlaceSuppliersRepository(QObject *parent = 0); + +private: + void copyMissingData(const QPlaceSupplier &src, QPlaceSupplier &target); + + QList<QPlaceSupplier> suppliers; +}; + +QTM_END_NAMESPACE + +#endif // QPLACESUPPLIERSREPOSITORY_H diff --git a/src/plugins/places/nokia/qplacetextpredictionreplyimpl.cpp b/src/plugins/places/nokia/qplacetextpredictionreplyimpl.cpp new file mode 100644 index 00000000..45c54aa4 --- /dev/null +++ b/src/plugins/places/nokia/qplacetextpredictionreplyimpl.cpp @@ -0,0 +1,72 @@ +#include "qplacetextpredictionreplyimpl.h" + +#include <QHash> + +#if defined(QT_PLACES_LOGGING) + #include <QDebug> +#endif + +QTM_USE_NAMESPACE + +/*! + Constructor. +*/ +QPlaceTextPreditionReplyImpl::QPlaceTextPreditionReplyImpl(QPlaceRestReply *reply, QObject *parent) : + QPlaceTextPredictionReply(parent), + restReply(reply) +{ + parser = new QPlaceJSonTextPredictionParser(this); + + if (restReply) { + restReply->setParent(this); + connect(restReply, SIGNAL(finished(const QString &reply)), + parser, SLOT(processData(const QString &data))); + connect(restReply, SIGNAL(error(QPlaceRestReply::Error error)), + this, SLOT(restError(QPlaceRestReply::Error))); + connect(parser, SIGNAL(finished(QPlaceJSonTextPredictionParser::Error,QString)), + this, SLOT(predictionsReady(QPlaceJSonTextPredictionParser::Error,QString))); + } +} + +/*! + Destructor. +*/ +QPlaceTextPreditionReplyImpl::~QPlaceTextPreditionReplyImpl() +{ +} + +void QPlaceTextPreditionReplyImpl::abort() +{ + restReply->cancelProcessing(); +} + +void QPlaceTextPreditionReplyImpl::restError(QPlaceRestReply::Error errorId) +{ + if (errorId == QPlaceRestReply::Canceled) { + this->setError(CancelError, "ReauestCanceled"); + } else if (errorId == QPlaceRestReply::NetworkError) { + this->setError(CommunicationError, "Network error"); + } + emit error(this->error(), this->errorString()); + emit processingError(this, this->error(), this->errorString()); + emit finished(); + emit processingFinished(this); +} + +void QPlaceTextPreditionReplyImpl::predictionsReady(const QPlaceJSonTextPredictionParser::Error &errorId, + const QString &errorMessage) +{ + if (errorId == QPlaceJSonTextPredictionParser::NoError) { + setTextPredictions(parser->predictions()); + } else if (errorId == QPlaceJSonTextPredictionParser::ParsingError) { + setError(ParseError, errorMessage); + emit error(this->error(), this->errorString()); + emit processingError(this, ParseError, errorMessage); + } + emit finished(); + emit processingFinished(this); + delete parser; + parser = NULL; + restReply->deleteLater(); + restReply = NULL; +} diff --git a/src/plugins/places/nokia/qplacetextpredictionreplyimpl.h b/src/plugins/places/nokia/qplacetextpredictionreplyimpl.h new file mode 100644 index 00000000..599617e0 --- /dev/null +++ b/src/plugins/places/nokia/qplacetextpredictionreplyimpl.h @@ -0,0 +1,37 @@ +#ifndef QPLACETEXTPREDICTIONREPLYIMPL_H +#define QPLACETEXTPREDICTIONREPLYIMPL_H + +#include <QObject> +#include <QHash> + +#include <qplacetextpredictionreply.h> +#include "qplacerestreply.h" +#include "qplacejsontextpredictionparser.h" + +QTM_BEGIN_NAMESPACE + +class QPlaceTextPreditionReplyImpl : public QPlaceTextPredictionReply +{ + Q_OBJECT +public: + explicit QPlaceTextPreditionReplyImpl(QPlaceRestReply *reply, QObject *parent = 0); + ~QPlaceTextPreditionReplyImpl(); + void abort(); + +Q_SIGNALS: + void processingFinished(QPlaceReply *reply); + void processingError(QPlaceReply *reply, const Error &error, const QString &errorMessage); + +private slots: + void restError(QPlaceRestReply::Error error); + void predictionsReady(const QPlaceJSonTextPredictionParser::Error &error, + const QString &errorMessage); + +private: + QPlaceRestReply *restReply; + QPlaceJSonTextPredictionParser *parser; +}; + +QTM_END_NAMESPACE + +#endif // QPLACETEXTPREDICTIONREPLYIMPL_H diff --git a/src/plugins/places/places.pro b/src/plugins/places/places.pro new file mode 100644 index 00000000..85243cc6 --- /dev/null +++ b/src/plugins/places/places.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs + +SUBDIRS = nokia diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 94f3a9d9..60dc0954 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -1,2 +1,3 @@ TEMPLATE = subdirs -SUBDIRS += geoservices +SUBDIRS += geoservices \ + places |