summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorabcd <qt-info@nokia.com>2011-06-03 16:25:00 +1000
committerabcd <qt-info@nokia.com>2011-06-03 16:25:00 +1000
commita64ddc2519d8dfd462575b231196c95667cc4040 (patch)
tree423268e0c32a3e8f6c95110309d5a88629b31aad
parent2cf5da0a7d62f314a828e5edefc02f3f6e281702 (diff)
downloadqtlocation-a64ddc2519d8dfd462575b231196c95667cc4040.tar.gz
Add places nokia plugin
-rw-r--r--src/plugins/places/nokia/nokia.pro87
-rw-r--r--src/plugins/places/nokia/placemanagerenginefactory_nokia.cpp71
-rw-r--r--src/plugins/places/nokia/placemanagerenginefactory_nokia.h71
-rw-r--r--src/plugins/places/nokia/qplacecategoriesrepository.cpp175
-rw-r--r--src/plugins/places/nokia/qplacecategoriesrepository.h45
-rw-r--r--src/plugins/places/nokia/qplacedetailsreplyimpl.cpp70
-rw-r--r--src/plugins/places/nokia/qplacedetailsreplyimpl.h37
-rw-r--r--src/plugins/places/nokia/qplacejsoncategoriesparser.cpp146
-rw-r--r--src/plugins/places/nokia/qplacejsoncategoriesparser.h48
-rw-r--r--src/plugins/places/nokia/qplacejsondetailsparser.cpp1018
-rw-r--r--src/plugins/places/nokia/qplacejsondetailsparser.h82
-rw-r--r--src/plugins/places/nokia/qplacejsonmediaparser.cpp115
-rw-r--r--src/plugins/places/nokia/qplacejsonmediaparser.h47
-rw-r--r--src/plugins/places/nokia/qplacejsonrecommendationparser.cpp82
-rw-r--r--src/plugins/places/nokia/qplacejsonrecommendationparser.h44
-rw-r--r--src/plugins/places/nokia/qplacejsonreviewparser.cpp177
-rw-r--r--src/plugins/places/nokia/qplacejsonreviewparser.h47
-rw-r--r--src/plugins/places/nokia/qplacejsonsearchparser.cpp350
-rw-r--r--src/plugins/places/nokia/qplacejsonsearchparser.h50
-rw-r--r--src/plugins/places/nokia/qplacejsontextpredictionparser.cpp43
-rw-r--r--src/plugins/places/nokia/qplacejsontextpredictionparser.h36
-rw-r--r--src/plugins/places/nokia/qplacemanagerengineimpl.cpp192
-rw-r--r--src/plugins/places/nokia/qplacemanagerengineimpl.h48
-rw-r--r--src/plugins/places/nokia/qplacemediareplyimpl.cpp71
-rw-r--r--src/plugins/places/nokia/qplacemediareplyimpl.h37
-rw-r--r--src/plugins/places/nokia/qplaceratingreplyimpl.cpp59
-rw-r--r--src/plugins/places/nokia/qplaceratingreplyimpl.h34
-rw-r--r--src/plugins/places/nokia/qplacerecommendationreplyimpl.cpp70
-rw-r--r--src/plugins/places/nokia/qplacerecommendationreplyimpl.h37
-rw-r--r--src/plugins/places/nokia/qplacerestmanager.cpp239
-rw-r--r--src/plugins/places/nokia/qplacerestmanager.h51
-rw-r--r--src/plugins/places/nokia/qplacerestreply.cpp94
-rw-r--r--src/plugins/places/nokia/qplacerestreply.h46
-rw-r--r--src/plugins/places/nokia/qplacereviewreplyimpl.cpp71
-rw-r--r--src/plugins/places/nokia/qplacereviewreplyimpl.h37
-rw-r--r--src/plugins/places/nokia/qplacesearchreplyimpl.cpp70
-rw-r--r--src/plugins/places/nokia/qplacesearchreplyimpl.h37
-rw-r--r--src/plugins/places/nokia/qplacesuppliersrepository.cpp58
-rw-r--r--src/plugins/places/nokia/qplacesuppliersrepository.h30
-rw-r--r--src/plugins/places/nokia/qplacetextpredictionreplyimpl.cpp72
-rw-r--r--src/plugins/places/nokia/qplacetextpredictionreplyimpl.h37
-rw-r--r--src/plugins/places/places.pro3
-rw-r--r--src/plugins/plugins.pro3
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> &parameters,
+ 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> &parameters,
+ 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 &params)
+{
+ Q_UNUSED(params)
+ return sendGeneralRequest(placeServer + placeId + images);
+}
+
+/*!
+ Predefines a review request and executes sendGeneralRequest().
+*/
+QPlaceRestReply *QPlaceRestManager::sendPlaceReviewRequest(const QString &placeId, const QPlaceQuery &params)
+{
+ 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 &params);
+ QPlaceRestReply *sendPlaceReviewRequest(const QString &placeId, const QPlaceQuery &params);
+ 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