summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/place-crossref.qdocinc7
-rw-r--r--doc/src/places.qdoc29
-rw-r--r--doc/src/plugins/jsondb.qdoc18
-rw-r--r--doc/src/plugins/nokia.qdoc3
-rw-r--r--doc/src/plugins/places-backend.qdoc57
-rw-r--r--doc/src/snippets/declarative/places.qml54
-rw-r--r--doc/src/snippets/places/requesthandler.h30
-rw-r--r--examples/declarative/common/imports/QtLocation/examples/components/Optionbutton.qml15
-rw-r--r--examples/declarative/places/content/places/OptionsDialog.qml172
-rw-r--r--examples/declarative/places/content/places/PlaceDelegate.qml36
-rw-r--r--examples/declarative/places/content/places/SearchResultDelegate.qml12
-rw-r--r--examples/declarative/places/places.pri3
-rw-r--r--examples/declarative/places/places.qml23
-rw-r--r--examples/declarative/places/placeswrapper.qrc1
-rw-r--r--src/imports/location/declarativeplaces/declarativeplaces.pri2
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativeplace.cpp94
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativeplace_p.h8
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativeplaceattribute.cpp13
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativerecommendationmodel.cpp107
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativerecommendationmodel_p.h22
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativeresultmodelbase.cpp215
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativeresultmodelbase_p.h99
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp32
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h14
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp127
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativesearchresultmodel_p.h26
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp34
-rw-r--r--src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h4
-rw-r--r--src/imports/location/qdeclarativegeoserviceprovider_p.h3
-rw-r--r--src/location/places/places.pri5
-rw-r--r--src/location/places/qplaceattribute.cpp18
-rw-r--r--src/location/places/qplaceattribute.h1
-rw-r--r--src/location/places/qplacemanager.cpp11
-rw-r--r--src/location/places/qplacemanager.h8
-rw-r--r--src/location/places/qplacemanagerengine.cpp16
-rw-r--r--src/location/places/qplacemanagerengine.h2
-rw-r--r--src/location/places/qplacematchreply.cpp140
-rw-r--r--src/location/places/qplacematchreply.h77
-rw-r--r--src/location/places/qplacematchrequest.cpp257
-rw-r--r--src/location/places/qplacematchrequest.h92
-rw-r--r--src/location/places/qplacereply.cpp3
-rw-r--r--src/location/places/qplacereply.h12
-rw-r--r--src/location/places/unsupportedreplies_p.h79
-rw-r--r--src/plugins/geoservices/nokia/places/qplacejsondetailsparser.cpp6
-rw-r--r--src/plugins/geoservices/nokia/places/qplacejsonsearchparser.cpp6
-rw-r--r--src/plugins/geoservices/nokia/qplacemanagerengine_nokia.cpp1
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/jsonconverter.cpp24
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/jsonconverter.h3
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/matchreply.cpp185
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/matchreply.h90
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/nokia_places_jsondb.pro2
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.cpp33
-rw-r--r--src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.h2
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/qplacemanager/tst_qplacemanager.cpp109
-rw-r--r--tests/auto/qplacemanager_jsondb/tst_qplacemanager_jsondb.cpp107
-rw-r--r--tests/auto/qplacemanager_nokia/tst_qplacemanager_nokia.cpp2
-rw-r--r--tests/auto/qplacematchreply/qplacematchreply.pro7
-rw-r--r--tests/auto/qplacematchreply/tst_qplacematchreply.cpp124
-rw-r--r--tests/auto/qplacematchrequest/qplacematchrequest.pro6
-rw-r--r--tests/auto/qplacematchrequest/tst_qplacematchrequest.cpp179
61 files changed, 2580 insertions, 289 deletions
diff --git a/doc/src/place-crossref.qdocinc b/doc/src/place-crossref.qdocinc
new file mode 100644
index 00000000..010154e9
--- /dev/null
+++ b/doc/src/place-crossref.qdocinc
@@ -0,0 +1,7 @@
+ \code
+ origin R/O manager(nokia) destination R/W manager (nokia_places_jsondb)
+ Save
+ Place id: ae246 ---> Place id: 0001
+ Attribute type: x_provider Attribute type: x_id_nokia
+ Attribute value: nokia Attribute text value: ae246
+ \endcode
diff --git a/doc/src/places.qdoc b/doc/src/places.qdoc
index ee749873..2373974d 100644
--- a/doc/src/places.qdoc
+++ b/doc/src/places.qdoc
@@ -161,7 +161,8 @@
The typical approach is to use the QPlaceManager::compatiblePlace() function,
it creates a copy of a place, but only copies data that the manager supports.
Manager specific data such as the place id is not copied over. The new
- copy is now suitable for saving into the manager.
+ copy is now suitable for saving into the manager. If the manager supports matching by alternative
+ ids, an alternative id attribute is assigned to the copy (see \l {Matching places between managers})
\snippet snippets/places/requesthandler.h Save to different manager
@@ -225,6 +226,32 @@
manager does so is provider specific. Managers accessing places from a web service will typically not emit
these signals, while managers accessing places stored locally generally will.
+ \section2 Matching places between managers
+ Sometimes you may want to cross reference whether places from one manager match those from another manager.
+ Such a situation may arise where one manager provides read-only access to places (origin manager) while another second r/w
+ manager (destination manager) is used to save selected favorites from the first. During a search
+ of the origin manager we may want to know which ones have been 'favorited' into the destination manager and perhaps display
+ a customized favorite name rather than the original name.
+
+ The matching mechanism can vary between managers, but is typically accomplished through an alternative id.
+ As part of the save process, the place id from the origin manager is saved as an alternative id attribute in the destination manager
+ (which can have it's own place id scheme). In the following example, the origin manager is from the 'nokia' QGeoServiceProider, therefore
+ as part of the saving process an alternative id attriubute, x_id_nokia, is set for the place saved into the destination manager
+ (when QPlaceManager::compatiblePlace() is called)
+
+ \input place-crossref.qdocinc
+
+ In order to perform the matching, we create a QPlaceMatchRequest and assign it the search results from the origin manager.
+ The QPlaceMatchRequest will be used on the destination manager to return corresponding places. We also specify
+ matching parameters which are key value pairs. As mentioned previously, this can vary depending on the manager but typically
+ the key is QPlaceMatchRequest::AlternativeId to indicate we are matching by alternative id, the value in this case would be
+ x_id_nokia which specifies which alternative id attribute we are using to do the matching.
+
+ \snippet snippets/places/requesthandler.h Match places
+ \dots
+ \dots
+ \snippet snippets/places/requesthandler.h Match places handler
+
\section1 Classes in Places
\section2 Data classes
diff --git a/doc/src/plugins/jsondb.qdoc b/doc/src/plugins/jsondb.qdoc
index 7ec31fcc..452db4b8 100644
--- a/doc/src/plugins/jsondb.qdoc
+++ b/doc/src/plugins/jsondb.qdoc
@@ -102,6 +102,9 @@ capabiliies are outlined below:
\row
\o visibility scopes
\o device
+ \row
+ \o favorites matching/(usable as favoritesPlugin)
+ \o yes
\endtable
\section2 Plugin specific behaviours
@@ -129,4 +132,19 @@ supported.
The JsonDb plugin only supports places of the QtLocation::PrivateVisibility scope.
Specifying the QtLocation::UnspecifiedVisibility when saving a place will default
to the QtLocation::PrivateVisibility scope.
+
+\section3 Favorites Matching Parameters
+The JsonDb plugin can be used as a favorites store and thus supports the following
+parameters.
+\table
+ \header
+ \o key
+ \o value
+ \row
+ \o "alternativeId" (aka QPlaceMatchRequest::AlternativeId)
+ \o alternative id attribute type, of the form "x_id_<provider name>" eg "x_id_nokia"
+ \row
+ \o "proximity"
+ \o The distance (m) allowed between places in order to be considered a match.
+\endtable
*/
diff --git a/doc/src/plugins/nokia.qdoc b/doc/src/plugins/nokia.qdoc
index bda543fb..2c882cda 100644
--- a/doc/src/plugins/nokia.qdoc
+++ b/doc/src/plugins/nokia.qdoc
@@ -167,6 +167,9 @@ and behaviours are outlined below:
\row
\o visibility scopes
\o public
+ \row
+ \o favorites matching/(usable as favoritesPlugin)
+ \o no
\endtable
\section2 Plugin specific behaviours
diff --git a/doc/src/plugins/places-backend.qdoc b/doc/src/plugins/places-backend.qdoc
index 6be766fc..05696727 100644
--- a/doc/src/plugins/places-backend.qdoc
+++ b/doc/src/plugins/places-backend.qdoc
@@ -46,7 +46,7 @@ the appropriate \l {Places Reply Classes}{reply classes}. The reply objects are
an asynchronous request; they are used to notify when a request is complete
and hold the results of that request.
-\section2 Implementing/Inheriting reply objects
+\section1 Implementing/Inheriting reply objects
A reply object would be inherited as follows:
\snippet snippets/places/requesthandler.h Implement reply pt1
\dots
@@ -83,7 +83,7 @@ Also note that the \c finished signals should always be emitted when a reply is
an error has been encountred, i.e. if there is an error, both the \c error and \c finished signals
should be emitted while if there is no error, only the \c finished signals are emitted.
-\section2 Icon Urls
+\section1 Icon Urls
Icon URLs are provided through the QPlaceManagerEngine::constructIconUrl() function.
Two important concepts regarding icons that needs to be discused
@@ -136,10 +136,61 @@ the variation parameters specified.
\note It is possible for icon URLs to be \l {http://dataurl.net}{data URLs} where the icon image
itself is embedded into the URL.
-\section2 Categories
+\section1 Categories
The categories of a manager engine are relatively static entities; for engines accessing
remote place datastores it may be desirable to cache the category structure rather than
querying a server every time QPlaceManagerEngine::initializeCategories() is called.
Depending on how dynamic the categories are, always downloading the freshest
set of categories may be more appropriate.
+
+\section1 Saving between managers.
+A place generally cannot be saved directly between managers as is because it contains manager specific data such as icons
+and categories. In order to facilitate saving between managers, engine implementers should implement
+the QPlaceManagerEngine::compatiblePlace() function. This function returns a copy of the input place
+with properties pruned or modified as necessary such that the copy can be saved into manager.
+
+\section1 Cross-referencing places between managers.
+Sometimes a situation may arise where we wish to cross-reference and match places between managers.
+Such a situation may arise where one manager provides read-only access to places (origin manager), while another second r/w
+manager (destnation manager) is used to save selected favorites from the first. During a search of the origin manager, we may want to
+know which ones have been 'favorited' into the destination manager and perhaps display the customized favorite name
+rather than the original name.
+
+\section2 Alternative Id cross-referencing
+In order to accomplish cross-referencing, there needs to be a link from between the original place and the favorited place
+and this is typically handled via an alternative id attribute. The favorited place contains an alternative id attrbute which has the
+id of the original place.
+
+\input place-crossref.qdocinc
+
+There are 3 prerequisites for implementing cross-referencing by alternative id. The first is that the origin manager must provide the x_provider attribute
+with the value being the name of the manager's QGeoServiceProvider. The attribute label should be kept empty, indicating the attribute should not
+be displayed to users. \note It is generally expected that all managers should set the \c x_provider attribute.
+
+The second is that QPlaceManager::compatiblePlace() of the destination manager use the \c x_provider attribute of the initial place
+and set an alternative id attribute of the place to be saved. The key of the alternative id attribute is \c x_id_<provider name> and
+the text value is the id of the initial place. The \c x_provider attribute should not be passed to the compatible place. When
+it is saved, the x_provider of the saved place is considered to be the destination manager.
+
+The third is that QPlaceManager::matchingPlaces() of the destination manager accept the QPlaceMatchRequest::AlternativeId as a parameter key
+and the alternative id attribute key as the value, in this case \c x_id_<provider name> would be the expected value.
+This indicates that the ids of places in the QPlaceMatchRequest should be matched against the \c x_id_<provider name> alternative id attributes.
+
+Note that if the destination manager is to facilitate saving and cross-referencing from any arbitrary manager, it internally must
+accommodate saving of arbitrary key value pairs since we cannot know the provider names before hand, nor can we know what structure the
+ids will be.
+
+\section3 Other methods of linking
+If an origin manager does not supply a place id, it may be necessary to provide some other means of cross-referencing/matching.
+One approach might be to do so via the place coordinates, if the coordinate of a place in the origin manager is identical or close
+to a place in the destination manager, there is a high likelihood that they are the same place.
+In this case, the manager might implement QPlaceManager::matchingPlaces() to accept a QPlaceMatchRequest with a parameter key of 'proximity'
+and a parameter value of the distance two places must be in order to detect a match. e.g. if an origin place and destination place are within 50m
+of each other, they can be considered the same place.
+
+Generally however it is recommended that cross referencing be implemented via alternative ids as mentioned above.
+
+\section3 User readable vs non-user readable extended attributes
+If an attribute is not intended to be readble by end users, the label field should be kept
+empty as an indicator of this fact.
*/
diff --git a/doc/src/snippets/declarative/places.qml b/doc/src/snippets/declarative/places.qml
index e3f241a3..9f72fabc 100644
--- a/doc/src/snippets/declarative/places.qml
+++ b/doc/src/snippets/declarative/places.qml
@@ -95,7 +95,8 @@ Item {
var keys = extendedAttributes.keys();
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
- console.log(extendedAttributes[key].label + ": " + extendedAttributes[key].text);
+ if (extendedAttributes[key].label !== "")
+ console.log(extendedAttributes[key].label + ": " + extendedAttributes[key].text);
}
}
//! [ExtendedAttributes read]
@@ -291,4 +292,55 @@ Item {
primaryWebsite = place.contactDetails["website"][0].value;
//! [Place primaryWebsite]
}
+
+ //! [Place favorite]
+ Text { text: place.favorite ? place.favorite.name : place.name }
+ //! [Place favorite]
+
+ function saveFavorite() {
+ var place;
+ var destinationPlugin
+ //! [Place saveFavorite]
+ place.initializeFavorite(destinationPlugin);
+ //if necessary customizations to the favorite can be made here.
+ //...
+ place.favorite.save();
+ //! [Place saveFavorite]
+ }
+
+ function removeFavorite() {
+ var place;
+ //! [Place removeFavorite 1]
+ place.favorite.remove();
+ //! [Place removeFavorite 1]
+
+ //! [Place removeFavorite 2]
+ //after detecting successful favorite removal by checking its status
+ place.favorite = null;
+ //! [Place removeFavorite 2]
+ }
+
+ function connectStatusChangedHandler() {
+ //! [Place checkStatus]
+ place.statusChanged.connect(statusChangedHandler);
+ //! [Place checkStatus]
+ }
+
+ //! [Place checkStatus handler]
+ function statusChangedHandler() {
+ if (statusChangedHandler.prevStatus === Place.Saving) {
+ switch (place.status) {
+ case Place.Ready:
+ console.log('Save successful');
+ break;
+ case Place.Error:
+ console.log('Save failed');
+ break;
+ default:
+ break;
+ }
+ }
+ statusChangedHandler.prevStatus = place.status;
+ }
+ //! [Place checkStatus handler]
}
diff --git a/doc/src/snippets/places/requesthandler.h b/doc/src/snippets/places/requesthandler.h
index 6ab87def..b3dccac4 100644
--- a/doc/src/snippets/places/requesthandler.h
+++ b/doc/src/snippets/places/requesthandler.h
@@ -316,6 +316,18 @@ public:
//! [Ratings]
}
+ void matchPlaces() {
+ QList<QPlaceSearchResult> results;
+ //! [Match places]
+ QPlaceMatchRequest request;
+ request.setResults(results);
+ QVariantMap parameters;
+ parameters.insert(QPlaceMatchRequest::AlternativeId, "x_id_nokia");
+ request.setParameters(parameters);
+ matchReply = manager->matchingPlaces(request);
+ //! [Match places]
+ }
+
public slots:
// ![Simple search handler]
//4) Have the slot appropriately process the results of the operation
@@ -486,7 +498,6 @@ public slots:
}
//! [Remove category handler]
-
//! [Content handler]
void contentHandler() {
if (contentReply->error() == QPlaceReply::NoError) {
@@ -513,6 +524,22 @@ public slots:
//! [Opening hours]
}
+ //! [Match places handler]
+ void matchHandler() {
+ if (matchReply->error() == QPlaceReply::NoError) {
+ foreach (const QPlace place, matchReply->places()) {
+ if (place != QPlace())
+ qDebug() << "Place is a favorite with name" << place.name();
+ else
+ qDebug() << "Place is not a favorite";
+ }
+ }
+
+ matchReply->deleteLater();
+ matchReply = 0;
+ }
+ //! [Match places handler]
+
QPlaceSearchReply *searchReply;
QPlaceSearchReply *recommendationReply;
QPlaceManager *manager;
@@ -524,6 +551,7 @@ QPlaceIdReply *removePlaceReply;
QPlaceIdReply *saveCategoryReply;
QPlaceIdReply *removeCategoryReply;
QPlaceReply *initCatReply;
+QPlaceMatchReply *matchReply;
QPlace place;
};
diff --git a/examples/declarative/common/imports/QtLocation/examples/components/Optionbutton.qml b/examples/declarative/common/imports/QtLocation/examples/components/Optionbutton.qml
index 064b90a4..6b311c6c 100644
--- a/examples/declarative/common/imports/QtLocation/examples/components/Optionbutton.qml
+++ b/examples/declarative/common/imports/QtLocation/examples/components/Optionbutton.qml
@@ -41,10 +41,14 @@ import QtQuick 2.0
Item {
id: optionbutton
+
+ signal clicked
+
property bool selected: false
property alias text: optionbuttonText.text
+ property bool toggle: false
+
height: optionbuttonText.height
- signal clicked
Row {
id: optionbuttonRow
@@ -61,7 +65,14 @@ Item {
MouseArea {
anchors.fill: parent
onClicked: {
- optionbutton.selected = true
+ if (toggle) {
+ if (optionbutton.selected)
+ optionbutton.selected = false
+ else
+ optionbutton.selected = true
+ } else {
+ optionbutton.selected = true
+ }
optionbutton.clicked()
}
}
diff --git a/examples/declarative/places/content/places/OptionsDialog.qml b/examples/declarative/places/content/places/OptionsDialog.qml
new file mode 100644
index 00000000..b7e59b23
--- /dev/null
+++ b/examples/declarative/places/content/places/OptionsDialog.qml
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtLocation 5.0
+import QtLocation.examples 5.0
+
+Item {
+ id: dialog
+
+ property int gap: 10
+ property int listItemHeight: titleBar.font.pixelSize * 1.5
+ property alias isFavoritesEnabled: enableFavoritesButton.selected
+ property alias locales: localesInput.text
+
+ signal goButtonClicked
+ signal cancelButtonClicked
+
+ opacity: 0
+ anchors.fill: parent
+
+ Fader{}
+
+ Rectangle {
+ id: dialogRectangle
+ color: "white"
+ opacity: 1
+ width: parent.width - gap
+ height: titleBar.height + options.height + gap * 1.5
+
+ anchors {
+ verticalCenter: parent.verticalCenter
+ left: parent.left
+ leftMargin: gap/2
+ }
+
+ border.width: 1
+ border.color: "dodgerblue"
+ radius: 5
+
+ TitleBar {
+ id: titleBar;
+ width: parent.width; height: 40;
+ anchors.top: parent.top; anchors.left: parent.left;
+ opacity: 0.9
+ text: "Options"
+
+ onClicked: { dialog.cancelButtonClicked() }
+ }
+
+ Column {
+ id: options
+ height: childrenRect.height
+ width: parent.width
+ spacing: gap
+
+ anchors {
+ top: titleBar.bottom
+ topMargin: gap
+ left: dialogRectangle.left
+ right: dialogRectangle.right
+ leftMargin: gap
+ rightMargin: gap
+ }
+
+ TextWithLabel {
+ id: localesInput
+
+ function resetVisibility() {
+ visible = placesPlugin.supportedPlacesFeatures & Plugin.LocaleFeature
+ }
+
+ width: parent.width - gap
+ height: listItemHeight
+ label: "Locale(s)"
+ enabled: true
+
+ Component.onCompleted: {
+ resetVisibility();
+ placesPlugin.nameChanged.connect(resetVisibility);
+ }
+ }
+
+ Optionbutton {
+ id: enableFavoritesButton
+
+ function resetVisibility() {
+ if (placesPlugin.name !== "nokia_places_jsondb") {
+ var pluginNames = placesPlugin.availableServiceProviders;
+ for (var i= 0; i < pluginNames.length; ++i) {
+ if (pluginNames[i] === "nokia_places_jsondb") {
+ enableFavoritesButton.visible = true;
+ return;
+ }
+ }
+ }
+ enableFavoritesButton.visible = false;
+ }
+
+ width: parent.width
+ text: "Enable favorites"
+ toggle: true
+ visible: false
+
+ Component.onCompleted: {
+ resetVisibility();
+ placesPlugin.nameChanged.connect(resetVisibility);
+ }
+ }
+
+ Row {
+ id: buttons
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: gap/3
+ height: 32
+
+ Button {
+ id: cancelButton
+ text: "Cancel"
+ width: 80; height: parent.height
+
+ onClicked: dialog.cancelButtonClicked()
+ }
+
+ Button {
+ id: okButton
+ text: "Ok"
+ width:80; height: parent.height
+
+ onClicked: dialog.goButtonClicked()
+ }
+ }
+ }
+ }
+}
diff --git a/examples/declarative/places/content/places/PlaceDelegate.qml b/examples/declarative/places/content/places/PlaceDelegate.qml
index 5fe20860..18fea193 100644
--- a/examples/declarative/places/content/places/PlaceDelegate.qml
+++ b/examples/declarative/places/content/places/PlaceDelegate.qml
@@ -188,31 +188,34 @@ Item {
Item {
width: parent.width
height: childrenRect.height
+
Button {
id: saveButton;
- property Place favoritePlace
function updateSaveStatus() {
if (updateSaveStatus.prevStatus === Place.Saving) {
- switch (favoritePlace.status) {
+ switch (place.favorite.status) {
case Place.Ready:
- visible = false;
- saveStatus.text = "Save Successful";
- saveStatus.visible = true;
break;
case Place.Error:
- saveStatus.anchors.top = saveButton.bottom
saveStatus.text = "Save Failed";
saveStatus.visible = true;
break;
default:
}
+ } else if (updateSaveStatus.prevStatus == Place.Removing) {
+ place.favorite = null;
+ updateSaveStatus.prevStatus = Place.Ready
+ return;
+
}
- updateSaveStatus.prevStatus = favoritePlace.status;
+
+ updateSaveStatus.prevStatus = place.favorite.status;
}
function reset()
{
- saveButton.visible = (placesPlugin.name !== "nokia_places_jsondb");
+ saveButton.visible = (placesPlugin.name !== "nokia_places_jsondb")
+ && (placeSearchModel.favoritesPlugin !== null);
saveStatus.visible = false;
}
@@ -221,18 +224,23 @@ Item {
placeDelegate.placeChanged.connect(reset);
}
- text: qsTr("Save as Favorite");
+ text: (place.favorite !== null) ? qsTr("Remove Favorite") : qsTr("Save as Favorite");
onClicked: {
- favoritePlace = Qt.createQmlObject('import QtLocation 5.0; Place { }', saveButton);
- favoritePlace.plugin = jsonDbPlugin;
- favoritePlace.copyFrom(place);
- favoritePlace.statusChanged.connect(updateSaveStatus);
- favoritePlace.save();
+ if (place.favorite === null) {
+ place.initializeFavorite(jsonDbPlugin);
+ place.favorite.statusChanged.connect(updateSaveStatus);
+ place.favorite.save();
+ } else {
+ place.favorite.statusChanged.connect(updateSaveStatus);
+ place.favorite.remove();
+ }
}
}
Text {
id: saveStatus
+ anchors.top: saveButton.bottom
+ visible: false
}
}
}
diff --git a/examples/declarative/places/content/places/SearchResultDelegate.qml b/examples/declarative/places/content/places/SearchResultDelegate.qml
index 42520113..c9c13e99 100644
--- a/examples/declarative/places/content/places/SearchResultDelegate.qml
+++ b/examples/declarative/places/content/places/SearchResultDelegate.qml
@@ -63,8 +63,16 @@ Item {
Column {
width: parent.width
- Text { text: place.name }
-
+ Row {
+ Image {
+ visible: (place.favorite != null)
+ source: "../../resources/star.png"
+ height: placeName.height
+ fillMode: Image.PreserveAspectFit
+ }
+
+ Text { id: placeName; text: place.favorite ? place.favorite.name : place.name }
+ }
Text { text: distance + "m" }
}
}
diff --git a/examples/declarative/places/places.pri b/examples/declarative/places/places.pri
index 34c1f946..b588d27c 100644
--- a/examples/declarative/places/places.pri
+++ b/examples/declarative/places/places.pri
@@ -20,7 +20,8 @@ qmlcontentplaces.files += \
content/places/ReviewDelegate.qml \
content/places/ReviewPage.qml \
content/places/PlaceImages.qml \
- content/places/MapComponent.qml
+ content/places/MapComponent.qml \
+ content/places/OptionsDialog.qml
OTHER_FILES += $$qmlcontentplaces.files
include(../common/common.pri)
diff --git a/examples/declarative/places/places.qml b/examples/declarative/places/places.qml
index 403d5168..571c083f 100644
--- a/examples/declarative/places/places.qml
+++ b/examples/declarative/places/places.qml
@@ -211,7 +211,7 @@ Item {
}
}
- Dialog {
+ OptionsDialog {
id: optionsDialog
z: backgroundRect.z + 3
@@ -220,15 +220,25 @@ Item {
Component.onCompleted: prepareDialog()
function prepareDialog() {
- setModel([
- ["Locale(s)", placesPlugin.locales.toString()]
- ]);
+ if (placeSearchModel.favoritesPlugin !== null)
+ isFavoritesEnabled = true;
+ else
+ isFavoritesEnabled = false;
+
+ locales = placesPlugin.locales.join(Qt.locale().groupSeparator);
}
onCancelButtonClicked: page.state = ""
onGoButtonClicked: {
- var locales = dialogModel.get(0).inputText.split(Qt.locale().groupSeparator);
- placesPlugin.locales = locales;
+ if (isFavoritesEnabled) {
+ placeSearchModel.favoritesPlugin = jsonDbPlugin;
+ recommendationModel.favoritesPlugin = jsonDbPlugin;
+ } else {
+ placeSearchModel.favoritesPlugin = null;
+ recommendationModel.favoritesPlugin = null;
+ }
+
+ placesPlugin.locales = locales.split(Qt.locale().groupSeparator);
categoryModel.update();
page.state = "";
}
@@ -296,7 +306,6 @@ Item {
id: placesPlugin
parameters: pluginParametersFromMap(pluginParameters)
-
onNameChanged: createMap(placesPlugin);
}
diff --git a/examples/declarative/places/placeswrapper.qrc b/examples/declarative/places/placeswrapper.qrc
index f4e15bd4..b32438f6 100644
--- a/examples/declarative/places/placeswrapper.qrc
+++ b/examples/declarative/places/placeswrapper.qrc
@@ -7,6 +7,7 @@
<file>content/places/EditorialPage.qml</file>
<file>content/places/Group.qml</file>
<file>content/places/MapComponent.qml</file>
+ <file>content/places/OptionsDialog.qml</file>
<file>content/places/PlaceDelegate.qml</file>
<file>content/places/PlaceDialog.qml</file>
<file>content/places/PlaceEditorials.qml</file>
diff --git a/src/imports/location/declarativeplaces/declarativeplaces.pri b/src/imports/location/declarativeplaces/declarativeplaces.pri
index 1896a31b..a55d8340 100644
--- a/src/imports/location/declarativeplaces/declarativeplaces.pri
+++ b/src/imports/location/declarativeplaces/declarativeplaces.pri
@@ -3,6 +3,7 @@ SOURCES += \
#models
declarativeplaces/qdeclarativeplacecontentmodel.cpp \
declarativeplaces/qdeclarativerecommendationmodel.cpp \
+ declarativeplaces/qdeclarativeresultmodelbase.cpp \
declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp \
declarativeplaces/qdeclarativesearchsuggestionmodel.cpp \
declarativeplaces/qdeclarativesearchresultmodel.cpp \
@@ -24,6 +25,7 @@ HEADERS += \
#models
declarativeplaces/qdeclarativeplacecontentmodel.h \
declarativeplaces/qdeclarativerecommendationmodel_p.h \
+ declarativeplaces/qdeclarativeresultmodelbase_p.h \
declarativeplaces/qdeclarativesupportedcategoriesmodel_p.h \
declarativeplaces/qdeclarativesearchsuggestionmodel_p.h \
declarativeplaces/qdeclarativesearchresultmodel_p.h \
diff --git a/src/imports/location/declarativeplaces/qdeclarativeplace.cpp b/src/imports/location/declarativeplaces/qdeclarativeplace.cpp
index c2acc095..a3a7c56c 100644
--- a/src/imports/location/declarativeplaces/qdeclarativeplace.cpp
+++ b/src/imports/location/declarativeplaces/qdeclarativeplace.cpp
@@ -45,6 +45,7 @@
#include "qdeclarativeplaceattribute_p.h"
#include "qdeclarativeplaceicon_p.h"
+#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeInfo>
#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/QPlaceManager>
@@ -130,10 +131,12 @@ QT_USE_NAMESPACE
the categories in one manager may not be recognised in another.
Therefore trying to save a place directly from one plugin to another is not possible.
- The typical approach is to create a new place, set its (destination) plugin and then use the \l copyFrom() method
- to copy the details of the original place. Using \l copyFrom() only copies data
- that is supported by the destination plugin, plugin specific data such as the place id is not copied over.
- Once the copy is done, the place is in a suitable state to be saved.
+ It is generally recommended that saving across plugins be handled as saving \l {Favorites}{favorites}
+ as explained below. However there is another approach which is to create a new place,
+ set its (destination) plugin and then use the \l copyFrom() method to copy the details of the original place.
+ Using \l copyFrom() only copies data that is supported by the destination plugin,
+ plugin specific data such as the place id is not copied over. Once the copy is done,
+ the place is in a suitable state to be saved. The call to initializeFavorite
\snippet snippets/declarative/places.qml Place save to different plugin
@@ -143,6 +146,35 @@ QT_USE_NAMESPACE
its \l remove() method. The \l status property will change to Place.Removing and then to
Place.Ready if the save was successful or to Place.Error if an error occurs.
+ \section2 Favorites
+ The Places API supports the concept of favorites. Favorites are generally implemented
+ by using two plugins, the first plugin is typically a r/o source of places(origin plugin) and a second
+ r/w plugin (destination plugin) is used to store places from the origin as favorites.
+
+ Each Place has a favorite property which is intended to contain the corresponding place
+ from the destination plugin (the place itself is sourced from the origin plugin). Because both the original
+ place and favorite instances are available, the developer can choose which
+ properties to show to the user. e.g. the favorite may have a modified name which should
+ be displayed rather than the original name.
+
+ \snippet snippets/declarative/places.qml Place favorite
+
+ The following demonstrates how to save a new favorite instance. A call is made
+ to create/initialize the favorite instance and then the instance is saved.
+
+ \snippet snippets/declarative/places.qml Place saveFavorite
+
+ The following demonstrates favorite removal:
+
+ \snippet snippets/declarative/places.qml Place removeFavorite 1
+ \dots
+ \snippet snippets/declarative/places.qml Place removeFavorite 2
+
+ The PlaceSearchModel and PlaceRecommendationModel have a favoritesPlugin property.
+ If the property is set, any places found during a search are checked against the favoritesPlugin
+ to see if there is a matching/corresponding favorite place. If so, the favorite property of the Place
+ is set, otherwise the favorite property is remains null.
+
\sa PlaceSearchModel, PlaceRecommendationModel
*/
@@ -151,7 +183,7 @@ QDeclarativePlace::QDeclarativePlace(QObject* parent)
m_reviewModel(0), m_imageModel(0), m_editorialModel(0),
m_extendedAttributes(new QDeclarativePropertyMap(this)),
m_contactDetails(new QDeclarativePropertyMap(this)), m_reply(0), m_plugin(0),
- m_complete(false), m_status(QDeclarativePlace::Ready), m_errorString(QString())
+ m_complete(false), m_favorite(0), m_status(QDeclarativePlace::Ready)
{
connect(m_contactDetails, SIGNAL(valueChanged(QString,QVariant)),
this, SLOT(contactsModified(QString,QVariant)));
@@ -164,7 +196,7 @@ QDeclarativePlace::QDeclarativePlace(const QPlace &src, QDeclarativeGeoServicePr
m_reviewModel(0), m_imageModel(0), m_editorialModel(0),
m_extendedAttributes(new QDeclarativePropertyMap(this)),
m_contactDetails(new QDeclarativePropertyMap(this)), m_reply(0), m_plugin(plugin),
- m_complete(false), m_status(QDeclarativePlace::Ready)
+ m_complete(false), m_favorite(0), m_status(QDeclarativePlace::Ready)
{
Q_ASSERT(plugin);
@@ -587,6 +619,16 @@ bool QDeclarativePlace::detailsFetched() const
\o An error occurred during the last operation, further operations can still be
performed on the place.
\endtable
+
+ The status of a place can be checked by connecting the status property
+ to a handler function, and then have the handler function process the change
+ in status.
+
+ \snippet snippets/declarative/places.qml Place checkStatus
+ \dots
+ \dots
+ \snippet snippets/declarative/places.qml Place checkStatus handler
+
*/
void QDeclarativePlace::setStatus(Status status)
{
@@ -921,6 +963,29 @@ void QDeclarativePlace::setVisibility(Visibility visibility)
}
/*!
+ \qmlproperty Place Place::favorite
+
+ This property holds the favorite instance of a place.
+*/
+QDeclarativePlace *QDeclarativePlace::favorite() const
+{
+ return m_favorite;
+}
+
+void QDeclarativePlace::setFavorite(QDeclarativePlace *favorite)
+{
+
+ if (m_favorite == favorite)
+ return;
+
+ if (m_favorite && m_favorite->parent() == this)
+ delete m_favorite;
+
+ m_favorite = favorite;
+ emit favoriteChanged();
+}
+
+/*!
\qmlmethod Place::copyFrom(Place original)
Copies data from an \a original place into this place. Only data that is supported by this
@@ -935,6 +1000,23 @@ void QDeclarativePlace::copyFrom(QDeclarativePlace *original)
setPlace(placeManager->compatiblePlace(original->place()));
}
+/*!
+ \qmlmethod Place::initializeFavorite(Plugin destinationPlugin)
+
+ Creates a favorite instance for the place which is to be saved into the
+ \a destination plugin. This method does nothing if the favorite property is
+ not null.
+*/
+void QDeclarativePlace::initializeFavorite(QDeclarativeGeoServiceProvider *plugin)
+{
+ if (m_favorite == 0) {
+ QDeclarativePlace *place = new QDeclarativePlace(this);
+ place->setPlugin(plugin);
+ place->copyFrom(this);
+ setFavorite(place);
+ }
+}
+
void QDeclarativePlace::synchronizeExtendedAttributes()
{
QStringList keys = m_extendedAttributes->keys();
diff --git a/src/imports/location/declarativeplaces/qdeclarativeplace_p.h b/src/imports/location/declarativeplaces/qdeclarativeplace_p.h
index 98986146..d87cc7e7 100644
--- a/src/imports/location/declarativeplaces/qdeclarativeplace_p.h
+++ b/src/imports/location/declarativeplaces/qdeclarativeplace_p.h
@@ -95,6 +95,7 @@ class QDeclarativePlace : public QObject, public QDeclarativeParserStatus
Q_PROPERTY(QUrl primaryWebsite READ primaryWebsite NOTIFY primaryWebsiteChanged);
Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
+ Q_PROPERTY(QDeclarativePlace *favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
Q_INTERFACES(QDeclarativeParserStatus)
@@ -168,7 +169,11 @@ public:
Visibility visibility() const;
void setVisibility(Visibility visibility);
+ QDeclarativePlace *favorite() const;
+ void setFavorite(QDeclarativePlace *favorite);
+
Q_INVOKABLE void copyFrom(QDeclarativePlace *original);
+ Q_INVOKABLE void initializeFavorite(QDeclarativeGeoServiceProvider *plugin);
signals:
void pluginChanged();
@@ -194,6 +199,7 @@ signals:
void contactDetailsChanged();
void statusChanged();
void visibilityChanged();
+ void favoriteChanged();
private slots:
void finished();
@@ -232,6 +238,8 @@ private:
QString m_prevPrimaryFax;
QUrl m_prevPrimaryWebsite;
+ QDeclarativePlace *m_favorite;
+
Status m_status;
QString m_errorString;
};
diff --git a/src/imports/location/declarativeplaces/qdeclarativeplaceattribute.cpp b/src/imports/location/declarativeplaces/qdeclarativeplaceattribute.cpp
index 2997cda0..5e3f8911 100644
--- a/src/imports/location/declarativeplaces/qdeclarativeplaceattribute.cpp
+++ b/src/imports/location/declarativeplaces/qdeclarativeplaceattribute.cpp
@@ -54,7 +54,8 @@
use the \c {[]} operator to access the \l PlaceAttribute items.
The following are standard keys that are defined by the API. \l Plugin
- implementations are free to define additional keys.
+ implementations are free to define additional keys. Custom keys should
+ be qualified by a unique prefix to avoid clashes.
\table
\header
\o key
@@ -65,8 +66,18 @@
\row
\o payment
\o The types of payment the place accepts, e.g. visa, mastercard etc.
+ \row
+ \o x_provider
+ \o The name of the provider that a place is sourced from
+ \row
+ \o x_id_<provider> (e.g x_id_nokia)
+ \o An alterantive id which identifies the place from the
+ persective of the specified provider.
\endtable
+ Some attributes may not be intended to be readable by end users, the label field
+ of such attributes is empty to indicate this fact.
+
The following example shows how to access all \l {PlaceAttribute}{PlaceAttributes} and print
them to the console:
diff --git a/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel.cpp
index 93f39399..0845823b 100644
--- a/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel.cpp
+++ b/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel.cpp
@@ -42,11 +42,14 @@
#include "qdeclarativerecommendationmodel_p.h"
#include "qdeclarativeplace_p.h"
+#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeInfo>
#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/QPlaceManager>
-#include <qplacesearchreply.h>
+#include <QtLocation/QPlaceSearchReply>
+#include <QtLocation/QPlaceMatchRequest>
+#include <QtLocation/QPlaceMatchReply>
QT_USE_NAMESPACE
@@ -100,6 +103,35 @@ QT_USE_NAMESPACE
*/
/*!
+ \qmlproperty Plugin PlaceRecommendationModel::favoritesPlugin
+
+ This property holds the \l Plugin which will be used to look for favorites.
+ Any places from the recommendation search which can be cross-referenced/matched
+ in the favorites \l Plugin will have their \l {Place::favorite}{favorite} property
+ set with the \l Place from the favorites \l Plugin.
+
+ If the favoritesPlugin is not set, the \l {Place::favorite}{favorite} property
+ of the places in the results will always be null.
+
+ \sa Favorites
+*/
+
+/*!
+ \qmlproperty VariantMap PlaceRecommendationModel::favoritesMatchParameters
+
+ This property holds a set of parameters used to specify how recommended places
+ are matched to favorites in the favoritesPlugin.
+
+ By default the parameter map is empty and implies that the favorites plugin
+ matches by \l {Alternative Id cross-referencing}{alternative ids}. Generally,
+ an application developer will not need to set this property.
+
+ In cases where the favorites plugin does not support matching by alternative ids,
+ then the \l {Information about plugins} {backend plugin documentation} should be consulted
+ to see precisely what key-value parameters to set.
+*/
+
+/*!
\qmlproperty BoundingArea PlaceRecommendationModel::searchArea
This property holds the search area. Search results returned by the model will be within the
@@ -163,12 +195,8 @@ QT_USE_NAMESPACE
*/
QDeclarativeRecommendationModel::QDeclarativeRecommendationModel(QObject *parent)
-: QDeclarativeSearchModelBase(parent)
+: QDeclarativeResultModelBase(parent)
{
- QHash<int, QByteArray> roles = roleNames();
- roles.insert(DistanceRole, "distance");
- roles.insert(PlaceRole, "place");
- setRoleNames(roles);
}
QDeclarativeRecommendationModel::~QDeclarativeRecommendationModel()
@@ -194,80 +222,17 @@ void QDeclarativeRecommendationModel::setPlaceId(const QString &placeId)
emit placeIdChanged();
}
-void QDeclarativeRecommendationModel::clearData()
-{
- qDeleteAll(m_places);
- m_places.clear();
- m_results.clear();
-}
-
-void QDeclarativeRecommendationModel::updateSearchRequest()
-{
- QDeclarativeSearchModelBase::updateSearchRequest();
-}
-
-void QDeclarativeRecommendationModel::processReply(QPlaceReply *reply)
-{
- QPlaceSearchReply *searchReply = qobject_cast<QPlaceSearchReply *>(reply);
- if (!searchReply)
- return;
-
- m_results = searchReply->results();
-
- foreach (const QPlaceSearchResult &result, m_results) {
- QDeclarativePlace *place = new QDeclarativePlace(result.place(), plugin(), this);
- m_places.append(place);
- }
-
- emit rowCountChanged();
-}
-
/*!
- \qmlproperty string PlaceRecommendationModel::row
+ \qmlproperty string PlaceRecommendationModel::count
- This properties holds the number of rows/results the model has.
+ This properties holds the number of results the model has.
*/
-int QDeclarativeRecommendationModel::rowCount(const QModelIndex &parent) const
-{
- Q_UNUSED(parent)
-
- return m_results.count();
-}
-
-QVariant QDeclarativeRecommendationModel::data(const QModelIndex& index, int role) const
-{
- if (index.row() > m_results.count())
- return QVariant();
-
- const QPlaceSearchResult &result = m_results.at(index.row());
-
- if (result.type() != QPlaceSearchResult::PlaceResult)
- return QVariant();
-
- switch (role) {
- case Qt::DisplayRole:
- return result.place().name();
- case DistanceRole:
- return result.distance();
- case PlaceRole:
- return QVariant::fromValue(static_cast<QObject *>(m_places.at(index.row())));
- default:
- return QVariant();
- }
-
- return QVariant();
-}
/*!
\qmlmethod PlaceRecommendationModel::data(int index, string role)
Returns the data for a given \a role at the specified row \a index.
*/
-QVariant QDeclarativeRecommendationModel::data(int index, const QString &role) const
-{
- QModelIndex modelIndex = createIndex(index, 0);
- return data(modelIndex, roleNames().key(role.toLatin1()));
-}
QPlaceReply *QDeclarativeRecommendationModel::sendQuery(QPlaceManager *manager,
const QPlaceSearchRequest &request)
diff --git a/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel_p.h b/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel_p.h
index 03794556..19522002 100644
--- a/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel_p.h
+++ b/src/imports/location/declarativeplaces/qdeclarativerecommendationmodel_p.h
@@ -43,17 +43,15 @@
#define QDECLARATIVERECOMMENDATIONMODEL_P_H
#include <QtDeclarative/QDeclarativeParserStatus>
-#include "qdeclarativesearchmodelbase.h"
+#include "qdeclarativeresultmodelbase_p.h"
QT_BEGIN_NAMESPACE
-class QDeclarativeRecommendationModel : public QDeclarativeSearchModelBase
+class QDeclarativeRecommendationModel : public QDeclarativeResultModelBase
{
Q_OBJECT
Q_PROPERTY(QString placeId READ placeId WRITE setPlaceId NOTIFY placeIdChanged)
- Q_PROPERTY(int count READ rowCount NOTIFY rowCountChanged)
-
Q_INTERFACES(QDeclarativeParserStatus)
public:
@@ -63,29 +61,13 @@ public:
QString placeId() const;
void setPlaceId(const QString &placeId);
- void clearData();
- void updateSearchRequest();
- void processReply(QPlaceReply *reply);
-
- // From QAbstractListModel
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
- Q_INVOKABLE QVariant data(int index, const QString &roleName) const;
- enum Roles {
- DistanceRole = Qt::UserRole,
- PlaceRole
- };
-
signals:
void placeIdChanged();
- void rowCountChanged();
protected:
QPlaceReply *sendQuery(QPlaceManager *manager, const QPlaceSearchRequest &request);
private:
- QList<QPlaceSearchResult> m_results;
- QList<QDeclarativePlace *> m_places;
QString m_placeId;
};
diff --git a/src/imports/location/declarativeplaces/qdeclarativeresultmodelbase.cpp b/src/imports/location/declarativeplaces/qdeclarativeresultmodelbase.cpp
new file mode 100644
index 00000000..3ee75210
--- /dev/null
+++ b/src/imports/location/declarativeplaces/qdeclarativeresultmodelbase.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#include "qdeclarativeresultmodelbase_p.h"
+
+QDeclarativeResultModelBase::QDeclarativeResultModelBase(QObject *parent)
+: QDeclarativeSearchModelBase(parent)
+{
+ QHash<int, QByteArray> roles = roleNames();
+ roles.insert(DistanceRole, "distance");
+ roles.insert(PlaceRole, "place");
+ setRoleNames(roles);
+}
+
+QDeclarativeGeoServiceProvider* QDeclarativeResultModelBase::favoritesPlugin() const
+{
+ return m_favoritesPlugin;
+}
+
+void QDeclarativeResultModelBase::setFavoritesPlugin(QDeclarativeGeoServiceProvider *plugin)
+{
+
+ if (m_favoritesPlugin == plugin)
+ return;
+
+ m_favoritesPlugin = plugin;
+ emit favoritesPluginChanged();
+}
+
+QVariantMap QDeclarativeResultModelBase::favoritesMatchParameters() const
+{
+ return m_matchParameters;
+}
+
+void QDeclarativeResultModelBase::setFavoritesMatchParameters(const QVariantMap &parameters)
+{
+ if (m_matchParameters == parameters)
+ return;
+
+ m_matchParameters = parameters;
+ emit favoritesMatchParametersChanged();
+}
+
+void QDeclarativeResultModelBase::clearData()
+{
+ qDeleteAll(m_places);
+ m_places.clear();
+ m_results.clear();
+}
+
+int QDeclarativeResultModelBase::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+
+ return m_results.count();
+}
+
+QVariant QDeclarativeResultModelBase::data(int index, const QString &role) const
+{
+ QModelIndex modelIndex = createIndex(index, 0);
+ return data(modelIndex, roleNames().key(role.toLatin1()));
+}
+
+QVariant QDeclarativeResultModelBase::data(const QModelIndex &index, int role) const
+{
+ if (index.row() > m_results.count())
+ return QVariant();
+
+ const QPlaceSearchResult &result = m_results.at(index.row());
+
+ switch (role) {
+ case Qt::DisplayRole:
+ if (result.type() == QPlaceSearchResult::PlaceResult)
+ return m_places.at(index.row())->name();
+ else
+ return QVariant();
+ case DistanceRole:
+ return result.distance();
+ case PlaceRole:
+ return QVariant::fromValue(static_cast<QObject *>(m_places.at(index.row())));
+ default:
+ return QVariant();
+ }
+}
+
+void QDeclarativeResultModelBase::queryFinished()
+{
+ if (!m_reply)
+ return;
+ QPlaceReply *reply = m_reply;
+ m_reply = 0;
+ if (reply->error() != QPlaceReply::NoError) {
+ m_resultsBuffer.clear();
+ updateLayout();
+ setStatus(Error, reply->errorString());
+ reply->deleteLater();
+ }
+
+ if (reply->type() == QPlaceReply::SearchReply) {
+ QPlaceSearchReply *searchReply = qobject_cast<QPlaceSearchReply *>(reply);
+ Q_ASSERT(searchReply);
+
+ m_resultsBuffer = searchReply->results();
+ reply->deleteLater();
+
+ if (!m_favoritesPlugin) {
+ updateLayout();
+ setStatus(Ready);
+ } else {
+ QGeoServiceProvider *serviceProvider = m_favoritesPlugin->sharedGeoServiceProvider();
+ if (!serviceProvider) {
+ updateLayout();
+ setStatus(Error, QLatin1String("Favorites plugin returns a null QGeoServiceProvider instance"));
+ }
+
+ QPlaceManager *favoritesManager = serviceProvider->placeManager();
+ if (!favoritesManager) {
+ updateLayout();
+ setStatus(Error, QLatin1String("Favorites plugin returns a null QPlaceManager"));
+ }
+
+ QPlaceMatchRequest request;
+ if (m_matchParameters.isEmpty()) {
+ if (!m_plugin) {
+ reply->deleteLater();
+ setStatus(Error, QLatin1String("Plugin not assigned"));
+ return;
+ }
+
+ QVariantMap params;
+ params.insert(QPlaceMatchRequest::AlternativeId, QString::fromLatin1("x_id_") + m_plugin->name());
+ request.setParameters(params);
+ } else {
+ request.setParameters(m_matchParameters);
+ }
+
+ request.setResults(m_resultsBuffer);
+ m_reply = favoritesManager->matchingPlaces(request);
+ connect(m_reply, SIGNAL(finished()), this, SLOT(queryFinished()));
+ }
+ } else if (reply->type() == QPlaceReply::MatchReply){
+ QPlaceMatchReply *matchReply = qobject_cast<QPlaceMatchReply *>(reply);
+ Q_ASSERT(matchReply);
+ updateLayout(matchReply->places());
+ setStatus(Ready);
+ reply->deleteLater();
+ } else {
+ setStatus(Error, QLatin1String("Unknown reply type"));
+ reply->deleteLater();
+ }
+}
+
+
+//Note: m_results buffer should be correctly populated before
+//calling this function
+void QDeclarativeResultModelBase::updateLayout(const QList<QPlace> &favoritePlaces)
+{
+ int oldRowCount = rowCount();
+
+ beginResetModel();
+ clearData();
+ m_results = m_resultsBuffer;
+ m_resultsBuffer.clear();
+
+ for (int i=0 ;i < m_results.count(); ++i) {
+ QDeclarativePlace *place = new QDeclarativePlace(m_results.at(i).place(),plugin(), this);
+ m_places.append(place);
+
+ if ((favoritePlaces.count() == m_results.count()) && favoritePlaces.at(i) != QPlace())
+ m_places[i]->setFavorite(new QDeclarativePlace(favoritePlaces.at(i), m_favoritesPlugin, m_places[i]));
+ }
+
+ endResetModel();
+ if (m_results.count() != oldRowCount)
+ emit rowCountChanged();
+}
+
diff --git a/src/imports/location/declarativeplaces/qdeclarativeresultmodelbase_p.h b/src/imports/location/declarativeplaces/qdeclarativeresultmodelbase_p.h
new file mode 100644
index 00000000..69216df9
--- /dev/null
+++ b/src/imports/location/declarativeplaces/qdeclarativeresultmodelbase_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVERESULTMODELBASE_H
+#define QDECLARATIVERESULTMODELBASE_H
+
+#include "qdeclarativesearchmodelbase.h"
+#include "qdeclarativeplace_p.h"
+
+#include <QtLocation/QGeoServiceProvider>
+#include <QtLocation/QPlaceSearchReply>
+
+class QDeclarativeResultModelBase : public QDeclarativeSearchModelBase
+{
+ Q_OBJECT
+
+public:
+ Q_PROPERTY(int count READ rowCount NOTIFY rowCountChanged)
+ Q_PROPERTY(QDeclarativeGeoServiceProvider *favoritesPlugin READ favoritesPlugin WRITE setFavoritesPlugin NOTIFY favoritesPluginChanged)
+ Q_PROPERTY(QVariantMap favoritesMatchParameters READ favoritesMatchParameters WRITE setFavoritesMatchParameters NOTIFY favoritesMatchParametersChanged)
+
+ explicit QDeclarativeResultModelBase(QObject *parent = 0);
+
+ QDeclarativeGeoServiceProvider* favoritesPlugin() const;
+ void setFavoritesPlugin(QDeclarativeGeoServiceProvider *plugin);
+
+ QVariantMap favoritesMatchParameters() const;
+ void setFavoritesMatchParameters(const QVariantMap &parameters);
+
+ virtual void clearData();
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const;
+ Q_INVOKABLE QVariant data(int index, const QString &roleName) const;
+
+signals:
+ void rowCountChanged();
+ void favoritesPluginChanged();
+ void favoritesMatchParametersChanged();
+
+protected slots:
+ virtual void queryFinished();
+
+private slots:
+ void updateLayout(const QList<QPlace> &favoritePlaces = QList<QPlace>());
+
+protected:
+ enum Roles {
+ DistanceRole = Qt::UserRole,
+ PlaceRole
+ };
+
+ QList<QPlaceSearchResult> m_results;
+ QList<QPlaceSearchResult> m_resultsBuffer;
+ QList<QDeclarativePlace *> m_places;
+
+ QDeclarativeGeoServiceProvider *m_favoritesPlugin;
+ QVariantMap m_matchParameters;
+};
+
+#endif
diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
index 3b3bd70d..a02eb011 100644
--- a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
+++ b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
@@ -121,12 +121,13 @@ QDeclarativeSearchModelBase::Status QDeclarativeSearchModelBase::status() const
return m_status;
}
-void QDeclarativeSearchModelBase::setStatus(Status status)
+void QDeclarativeSearchModelBase::setStatus(Status status, const QString &errorString)
{
if (m_status == status)
return;
m_status = status;
+ m_errorString = errorString;
emit statusChanged();
}
@@ -158,8 +159,6 @@ void QDeclarativeSearchModelBase::execute()
m_reply->setParent(this);
connect(m_reply, SIGNAL(finished()), this, SLOT(queryFinished()));
- connect(m_reply, SIGNAL(error(QPlaceReply::Error,QString)),
- this, SLOT(queryError(QPlaceReply::Error,QString)));
setStatus(Executing);
}
@@ -229,33 +228,6 @@ void QDeclarativeSearchModelBase::initializePlugin(QDeclarativeGeoServiceProvide
reset(); // reset the model
}
-void QDeclarativeSearchModelBase::queryFinished()
-{
- if (!m_reply)
- return;
-
- QPlaceReply *reply = m_reply;
- m_reply = 0;
-
- beginResetModel();
-
- clearData();
-
- processReply(reply);
-
- endResetModel();
-
- reply->deleteLater();
- setStatus(Ready);
-}
-
-void QDeclarativeSearchModelBase::queryError(QPlaceReply::Error error, const QString &errorString)
-{
- Q_UNUSED(error)
-
- m_errorString = errorString;
-}
-
void QDeclarativeSearchModelBase::pluginNameChanged()
{
initializePlugin(m_plugin);
diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h
index f087a9eb..c13e9a64 100644
--- a/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h
+++ b/src/imports/location/declarativeplaces/qdeclarativesearchmodelbase.h
@@ -95,7 +95,7 @@ public:
void setLimit(int limit);
Status status() const;
- void setStatus(Status status);
+ void setStatus(Status status, const QString &errorString = QString());
Q_INVOKABLE void execute();
Q_INVOKABLE void cancel();
@@ -104,7 +104,6 @@ public:
virtual void clearData();
virtual void updateSearchRequest();
- virtual void processReply(QPlaceReply *reply) = 0;
// From QDeclarativeParserStatus
virtual void classBegin();
@@ -120,9 +119,10 @@ signals:
protected:
virtual void initializePlugin(QDeclarativeGeoServiceProvider *plugin);
+protected slots:
+ virtual void queryFinished() = 0;
+
private slots:
- void queryFinished();
- void queryError(QPlaceReply::Error error, const QString &errorString);
void pluginNameChanged();
protected:
@@ -130,16 +130,14 @@ protected:
QPlaceSearchRequest m_request;
QDeclarativeGeoServiceProvider *m_plugin;
-
-private:
QPlaceReply *m_reply;
+private:
QDeclarativeGeoBoundingArea *m_searchArea;
- QString m_errorString;
-
bool m_complete;
Status m_status;
+ QString m_errorString;
};
QT_END_NAMESPACE
diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
index 65fe3d50..12f94cef 100644
--- a/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
+++ b/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel.cpp
@@ -43,10 +43,13 @@
#include "qdeclarativeplace_p.h"
#include "qdeclarativeplaceicon_p.h"
+#include <QtDeclarative/QDeclarativeEngine>
#include <QtDeclarative/QDeclarativeInfo>
#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/QPlaceSearchReply>
#include <QtLocation/QPlaceManager>
+#include <QtLocation/QPlaceMatchRequest>
+#include <QtLocation/QPlaceMatchReply>
QT_USE_NAMESPACE
@@ -115,6 +118,35 @@ QT_USE_NAMESPACE
*/
/*!
+ \qmlproperty Plugin PlaceSearchModel::favoritesPlugin
+
+ This property holds the \l Plugin which will be used to search for favorites.
+ Any places from the search which can be cross-referenced/matched
+ in the favorites \l Plugin will have their \l {Place::favorite}{favorite} property
+ set with the \l Place from the favorites \l Plugin.
+
+ If the favoritesPlugin is not set, the \l {Place::favorite}{favorite} property
+ of the places in the results will always be null.
+
+ \sa Favorites
+*/
+
+/*!
+ \qmlproperty VariantMap PlaceSearchModel::favoritesMatchParameters
+
+ This property holds a set of parameters used to specify how search result places
+ are matched to favorites in the favoritesPlugin.
+
+ By default the parameter map is empty and implies that the favorites plugin
+ matches by \l {Alternative Id cross-referencing}{alternative ids}. Generally,
+ an application developer will not need to set this property.
+
+ In cases where the favorites plugin does not support matching by alternative ids,
+ then the \l {Information about plugins} {backend plugin documentation} should be consulted
+ to see precisely what key-value parameters to set.
+*/
+
+/*!
\qmlproperty BoundingArea PlaceSearchModel::searchArea
This property holds the search area. The search result returned by the model will be within
@@ -177,12 +209,10 @@ QT_USE_NAMESPACE
*/
QDeclarativeSearchResultModel::QDeclarativeSearchResultModel(QObject *parent)
-: QDeclarativeSearchModelBase(parent)
+: QDeclarativeResultModelBase(parent)
{
QHash<int, QByteArray> roles = roleNames();
roles.insert(SearchResultTypeRole, "type");
- roles.insert(DistanceRole, "distance");
- roles.insert(PlaceRole, "place");
roles.insert(CorrectionRole, "correction");
setRoleNames(roles);
}
@@ -364,84 +394,19 @@ void QDeclarativeSearchResultModel::setVisibilityScope(QDeclarativePlace::Visibi
emit visibilityScopeChanged();
}
-void QDeclarativeSearchResultModel::clearData()
-{
- qDeleteAll(m_places);
- m_places.clear();
- m_results.clear();
-}
-
-void QDeclarativeSearchResultModel::updateSearchRequest()
-{
- QDeclarativeSearchModelBase::updateSearchRequest();
-}
-
-void QDeclarativeSearchResultModel::processReply(QPlaceReply *reply)
-{
- QPlaceSearchReply *searchReply = qobject_cast<QPlaceSearchReply *>(reply);
- if (!searchReply)
- return;
-
- m_results = searchReply->results();
-
- foreach (const QPlaceSearchResult &result, m_results) {
- QDeclarativePlace *place = new QDeclarativePlace(result.place(),plugin(), this);
- m_places.append(place);
- }
- emit rowCountChanged();
-}
-
-int QDeclarativeSearchResultModel::rowCount(const QModelIndex &parent) const
-{
- Q_UNUSED(parent);
-
- return m_results.count();
-}
-
-/*!
- \qmlmethod PlaceSearchResult::data(int index, string role)
-
- Returns the data for a given \a role at the specified \a index.
-*/
-QVariant QDeclarativeSearchResultModel::data(int index, const QString &role) const
-{
- QModelIndex modelIndex = createIndex(index, 0);
- return data(modelIndex, roleNames().key(role.toLatin1()));
-}
-
QVariant QDeclarativeSearchResultModel::data(const QModelIndex &index, int role) const
{
if (index.row() > m_results.count())
return QVariant();
- const QPlaceSearchResult &result = m_results.at(index.row());
-
- if (result.type() == QPlaceSearchResult::PlaceResult) {
- switch (role) {
- case Qt::DisplayRole:
- return result.place().name();
- case SearchResultTypeRole:
- return result.type();
- case DistanceRole:
- return result.distance();
- case PlaceRole:
- return QVariant::fromValue(static_cast<QObject *>(m_places.at(index.row())));
- default:
- return QVariant();
- }
- } else if (result.type() == QPlaceSearchResult::CorrectionResult) {
- switch (role) {
- case Qt::DisplayRole:
- case CorrectionRole:
- return result.correction();
- case SearchResultTypeRole:
- return result.type();
- default:
- return QVariant();
- }
+ switch (role) {
+ case SearchResultTypeRole:
+ return m_results.at(index.row()).type();
+ case CorrectionRole:
+ return m_results.at(index.row()).correction();
+ default:
+ return QDeclarativeResultModelBase::data(index, role);
}
-
- return QVariant();
}
QPlaceReply *QDeclarativeSearchResultModel::sendQuery(QPlaceManager *manager,
@@ -479,6 +444,18 @@ void QDeclarativeSearchResultModel::initializePlugin(QDeclarativeGeoServiceProvi
QDeclarativeSearchModelBase::initializePlugin(plugin);
}
+/*!
+ \qmlmethod PlaceSearchModel::data(int index, string role)
+
+ Returns the data for a given \a role at the specified row \a index.
+*/
+
+/*!
+ \qmlproperty string PlaceSearchModel::count
+
+ This properties holds the number of results the model has.
+*/
+
void QDeclarativeSearchResultModel::placeUpdated(const QString &placeId)
{
int row = getRow(placeId);
diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel_p.h b/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel_p.h
index a0bd5039..09fd1f63 100644
--- a/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel_p.h
+++ b/src/imports/location/declarativeplaces/qdeclarativesearchresultmodel_p.h
@@ -42,7 +42,7 @@
#ifndef QDECLARATIVESEARCHRESULTMODEL_P_H
#define QDECLARATIVESEARCHRESULTMODEL_P_H
-#include "qdeclarativesearchmodelbase.h"
+#include "qdeclarativeresultmodelbase_p.h"
#include "qdeclarativecategory_p.h"
#include "qdeclarativeplace_p.h"
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
class QDeclarativeGeoServiceProvider;
-class QDeclarativeSearchResultModel : public QDeclarativeSearchModelBase
+class QDeclarativeSearchResultModel : public QDeclarativeResultModelBase
{
Q_OBJECT
@@ -59,7 +59,6 @@ class QDeclarativeSearchResultModel : public QDeclarativeSearchModelBase
Q_PROPERTY(int maximumCorrections READ maximumCorrections WRITE setMaximumCorrections NOTIFY maximumCorrectionsChanged)
Q_PROPERTY(RelevanceHint relevanceHint READ relevanceHint WRITE setRelevanceHint NOTIFY relevanceHintChanged)
Q_PROPERTY(QDeclarativePlace::Visibility visibilityScope READ visibilityScope WRITE setVisibilityScope NOTIFY visibilityScopeChanged)
- Q_PROPERTY(int count READ rowCount NOTIFY rowCountChanged)
Q_ENUMS(SearchResultType RelevanceHint)
@@ -98,20 +97,7 @@ public:
QDeclarativePlace::Visibility visibilityScope() const;
void setVisibilityScope(QDeclarativePlace::Visibility visibilityScope);
- void clearData();
- void updateSearchRequest();
- void processReply(QPlaceReply *reply);
-
- // From QAbstractListModel
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
- enum Roles {
- SearchResultTypeRole = Qt::UserRole,
- DistanceRole,
- PlaceRole,
- CorrectionRole
- };
- Q_INVOKABLE QVariant data(int index, const QString &roleName) const;
signals:
void searchTermChanged();
@@ -119,7 +105,6 @@ signals:
void maximumCorrectionsChanged();
void relevanceHintChanged();
void visibilityScopeChanged();
- void rowCountChanged();
protected:
QPlaceReply *sendQuery(QPlaceManager *manager, const QPlaceSearchRequest &request);
@@ -130,9 +115,12 @@ private slots:
void placeRemoved(const QString &placeId);
private:
+ enum Roles {
+ SearchResultTypeRole = QDeclarativeResultModelBase::PlaceRole + 1,
+ CorrectionRole
+ };
+
int getRow(const QString &placeId) const;
- QList<QPlaceSearchResult> m_results;
- QList<QDeclarativePlace *> m_places;
QList<QDeclarativeCategory*> m_categories;
QtLocation::VisibilityScope m_visibilityScope;
};
diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp
index adba0a2c..b9a6cf17 100644
--- a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp
+++ b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel.cpp
@@ -217,13 +217,6 @@ void QDeclarativeSearchSuggestionModel::updateSearchRequest()
QDeclarativeSearchModelBase::updateSearchRequest();
}
-void QDeclarativeSearchSuggestionModel::processReply(QPlaceReply *reply)
-{
- QPlaceSearchSuggestionReply *suggestionReply = qobject_cast<QPlaceSearchSuggestionReply *>(reply);
- m_suggestions = suggestionReply->suggestions();
- emit suggestionsChanged();
-}
-
int QDeclarativeSearchSuggestionModel::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent)
@@ -248,6 +241,33 @@ QVariant QDeclarativeSearchSuggestionModel::data(const QModelIndex& index, int r
return QVariant();
}
+void QDeclarativeSearchSuggestionModel::queryFinished()
+{
+ if (!m_reply)
+ return;
+
+ QPlaceReply *reply = m_reply;
+ m_reply = 0;
+
+ beginResetModel();
+
+ clearData();
+
+ QPlaceSearchSuggestionReply *suggestionReply = qobject_cast<QPlaceSearchSuggestionReply *>(reply);
+ m_suggestions = suggestionReply->suggestions();
+ emit suggestionsChanged();
+
+ endResetModel();
+
+ if (suggestionReply->error() != QPlaceReply::NoError)
+ setStatus(Error, suggestionReply->errorString());
+ else
+ setStatus(Ready);
+
+
+ reply->deleteLater();
+}
+
QPlaceReply *QDeclarativeSearchSuggestionModel::sendQuery(QPlaceManager *manager,
const QPlaceSearchRequest &request)
{
diff --git a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h
index 63251f17..47489002 100644
--- a/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h
+++ b/src/imports/location/declarativeplaces/qdeclarativesearchsuggestionmodel_p.h
@@ -69,7 +69,6 @@ public:
void clearData();
void updateSearchRequest();
- void processReply(QPlaceReply *reply);
// From QAbstractListModel
int rowCount(const QModelIndex &parent) const;
@@ -78,6 +77,9 @@ public:
SearchSuggestionRole = Qt::UserRole
};
+protected slots:
+ virtual void queryFinished();
+
signals:
void searchTermChanged();
void suggestionsChanged();
diff --git a/src/imports/location/qdeclarativegeoserviceprovider_p.h b/src/imports/location/qdeclarativegeoserviceprovider_p.h
index c1384d68..1fc75adb 100644
--- a/src/imports/location/qdeclarativegeoserviceprovider_p.h
+++ b/src/imports/location/qdeclarativegeoserviceprovider_p.h
@@ -124,7 +124,8 @@ public:
SearchSuggestionsFeature = QPlaceManager::SearchSuggestionsFeature,
CorrectionsFeature = QPlaceManager::CorrectionsFeature,
LocaleFeature = QPlaceManager::LocaleFeature,
- NotificationsFeature = QPlaceManager::NotificationsFeature
+ NotificationsFeature = QPlaceManager::NotificationsFeature,
+ FavoritesMatchingFeature = QPlaceManager::MatchingFeature
};
Q_DECLARE_FLAGS(PlacesFeatures, PlacesFeature)
diff --git a/src/location/places/places.pri b/src/location/places/places.pri
index b64b78b7..db221368 100644
--- a/src/location/places/places.pri
+++ b/src/location/places/places.pri
@@ -20,13 +20,16 @@ PUBLIC_HEADERS += \
places/qplacesearchresult.h \
#request classes
places/qplacecontentrequest.h \
+ places/qplacematchrequest.h \
places/qplacesearchrequest.h \
#reply classes
places/qplacereply.h \
places/qplacedetailsreply.h \
places/qplaceidreply.h \
+ places/qplacematchreply.h \
places/qplacesearchreply.h \
places/qplacesearchsuggestionreply.h \
+ places/unsupportedreplies_p.h \
#manager and engine
places/qplacemanager.h \
places/qplacemanagerengine.h
@@ -70,10 +73,12 @@ SOURCES += \
places/qplacesearchresult.cpp \
#request classes
places/qplacecontentrequest.cpp \
+ places/qplacematchrequest.cpp \
places/qplacesearchrequest.cpp \
#reply classes
places/qplacereply.cpp \
places/qplacedetailsreply.cpp \
+ places/qplacematchreply.cpp \
places/qplacesearchreply.cpp \
places/qplacesearchsuggestionreply.cpp \
#manager and engine
diff --git a/src/location/places/qplaceattribute.cpp b/src/location/places/qplaceattribute.cpp
index e22e2bc3..8b83dc80 100644
--- a/src/location/places/qplaceattribute.cpp
+++ b/src/location/places/qplaceattribute.cpp
@@ -84,8 +84,12 @@ bool QPlaceAttributePrivate::operator== (const QPlaceAttributePrivate &other) co
\list
\o QPlaceAttribute::OpeningHours
\o QPlaceAttribute::Payment
+ \o QPlaceAttribute::Provider
\endlist
+ There is a class of attributes types of the format x_id_<provider> e.g. x_id_nokia.
+ This class of attributes are alternative ids of the place, from the specified provider's
+ perspective.
The above types are used to access and modify attributes in QPlace via:
\list
@@ -96,7 +100,12 @@ bool QPlaceAttributePrivate::operator== (const QPlaceAttributePrivate &other) co
\endlist
The \e {attribute type} is a string type so that providers are able to introduce
- new attributes as necessary.
+ new attributes as necessary. Custom attribute types should always be prefixed
+ by a qualifier in order to avoid conflicts.
+
+ \section3 User readable vs non-user readable attributes
+ Some attributes may not be intended to be readable by end users, the label field
+ of such attributes are empty to indicate this fact.
*/
/*!
@@ -112,6 +121,13 @@ const QString QPlaceAttribute::OpeningHours(QLatin1String("openingHours"));
const QString QPlaceAttribute::Payment(QLatin1String("payment"));
/*!
+ \variable QPlaceAttribute::Provider
+ The constant to specify an attribute that defines which
+ provider the place came from.
+*/
+const QString QPlaceAttribute::Provider(QLatin1String("x_provider"));
+
+/*!
Constructs an attribute.
*/
QPlaceAttribute::QPlaceAttribute()
diff --git a/src/location/places/qplaceattribute.h b/src/location/places/qplaceattribute.h
index 2a49ab7a..4934321f 100644
--- a/src/location/places/qplaceattribute.h
+++ b/src/location/places/qplaceattribute.h
@@ -60,6 +60,7 @@ class Q_LOCATION_EXPORT QPlaceAttribute
public:
static const QString OpeningHours;
static const QString Payment;
+ static const QString Provider;
QPlaceAttribute();
QPlaceAttribute(const QPlaceAttribute &other);
diff --git a/src/location/places/qplacemanager.cpp b/src/location/places/qplacemanager.cpp
index cf6f08c6..e270a3ad 100644
--- a/src/location/places/qplacemanager.cpp
+++ b/src/location/places/qplacemanager.cpp
@@ -145,6 +145,7 @@ QT_BEGIN_NAMESPACE
according to locale
\value NotificationsFeature The manager has signal notifications for when
places/categories are added/modified/removed.
+ \value MatchingFeature The manager support matching places from other managers.
*/
/*!
@@ -406,6 +407,16 @@ QPlaceManager::ManagerFeatures QPlaceManager::supportedFeatures() const
}
/*!
+ Returns a reply which contains a list of places which correspond/match those
+ specified in the \a request. The places specified in the request come from a
+ different manager.
+*/
+QPlaceMatchReply *QPlaceManager::matchingPlaces(const QPlaceMatchRequest &request) const
+{
+ return d->matchingPlaces(request);
+}
+
+/*!
\fn void QPlaceManager::finished(QPlaceReply* reply)
This signal is emitted when \a reply has finished processing.
diff --git a/src/location/places/qplacemanager.h b/src/location/places/qplacemanager.h
index 4f380548..b6228851 100644
--- a/src/location/places/qplacemanager.h
+++ b/src/location/places/qplacemanager.h
@@ -47,8 +47,11 @@
#include "qplaceidreply.h"
#include "qplacereply.h"
#include "qplacedetailsreply.h"
+#include "qplacematchreply.h"
+#include "qplacematchrequest.h"
#include "qplacesearchsuggestionreply.h"
#include "qplacesearchrequest.h"
+#include "qplacesearchresult.h"
#include <QLocale>
#include <QVector>
@@ -79,7 +82,8 @@ public:
SearchSuggestionsFeature = 0x20,
CorrectionsFeature = 0x40,
LocaleFeature = 0x80,
- NotificationsFeature = 0x100
+ NotificationsFeature = 0x100,
+ MatchingFeature = 0x200
};
Q_DECLARE_FLAGS(ManagerFeatures, ManagerFeature)
@@ -121,6 +125,8 @@ public:
ManagerFeatures supportedFeatures() const;
+ QPlaceMatchReply *matchingPlaces(const QPlaceMatchRequest &request) const;
+
Q_SIGNALS:
void finished(QPlaceReply *reply);
void error(QPlaceReply *, QPlaceReply::Error error, const QString &errorString = QString());
diff --git a/src/location/places/qplacemanagerengine.cpp b/src/location/places/qplacemanagerengine.cpp
index fed808c8..bf86694c 100644
--- a/src/location/places/qplacemanagerengine.cpp
+++ b/src/location/places/qplacemanagerengine.cpp
@@ -41,6 +41,9 @@
#include "qplacemanagerengine.h"
#include "qplacemanagerengine_p.h"
+#include "unsupportedreplies_p.h"
+
+#include <QtCore/QMetaType>
QT_BEGIN_NAMESPACE
@@ -73,6 +76,8 @@ QPlaceManagerEngine::QPlaceManagerEngine(const QMap<QString, QVariant> &paramete
QObject *parent)
: QObject(parent), d_ptr(new QPlaceManagerEnginePrivate)
{
+ qRegisterMetaType<QPlaceReply::Error>("QPlaceReply::Error");
+ qRegisterMetaType<QPlaceReply *>("QPlaceReply *");
Q_UNUSED(parameters)
}
@@ -155,6 +160,17 @@ QPlace QPlaceManagerEngine::compatiblePlace(const QPlace &original) const
return QPlace();
}
+/*!
+ Returns a reply which contains a list of places which correspond/match those
+ specified in \a request.
+*/
+QPlaceMatchReply * QPlaceManagerEngine::matchingPlaces(const QPlaceMatchRequest &request)
+{
+ MatchReply *reply = new MatchReply(this);
+ reply->triggerDone(QPlaceReply::UnsupportedError, "Place matching is not supported");
+ return reply;
+}
+
QPlaceManagerEnginePrivate::QPlaceManagerEnginePrivate()
: managerVersion(-1), manager(0)
{
diff --git a/src/location/places/qplacemanagerengine.h b/src/location/places/qplacemanagerengine.h
index 990a1bff..1d8d3642 100644
--- a/src/location/places/qplacemanagerengine.h
+++ b/src/location/places/qplacemanagerengine.h
@@ -94,6 +94,8 @@ public:
virtual QPlaceManager::ManagerFeatures supportedFeatures() const = 0;
+ virtual QPlaceMatchReply *matchingPlaces(const QPlaceMatchRequest &request);
+
Q_SIGNALS:
void finished(QPlaceReply *reply);
void error(QPlaceReply *, QPlaceReply::Error error, const QString &errorString = QString());
diff --git a/src/location/places/qplacematchreply.cpp b/src/location/places/qplacematchreply.cpp
new file mode 100644
index 00000000..439a32c0
--- /dev/null
+++ b/src/location/places/qplacematchreply.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#include "qplacematchreply.h"
+#include "qplacereply_p.h"
+
+
+QT_BEGIN_NAMESPACE
+class QPlaceMatchReplyPrivate : public QPlaceReplyPrivate
+{
+public:
+ QPlaceMatchReplyPrivate(){}
+ QList<QPlace> places;
+ QPlaceMatchRequest request;
+};
+
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+/*!
+ \class QPlaceMatchReply
+ \inmodule QtLocation
+ \ingroup QtLocation-places
+ \ingroup QtLocation-places-replies
+ \since QtLocation 5.0
+
+ \brief The QPlaceMatchReply class manages a place matching operation started by an
+ instance of QPlaceManager.
+
+ If the operation is successful, the number of places in the reply matches those
+ in the request. If a particular place in the request is not found, a default
+ constructed place is used as a place holder in the reply. In this way, there
+ is always a one is to one relationship between input places in the request,
+ and output places in the reply.
+
+ If the operation is not successful the number of places is always zero.
+
+ See \l {Matching places between managers} for an example on how to use
+ a match reply.
+
+ \sa QPlaceMatchRequest, QPlaceManager
+*/
+
+/*!
+ Constructs a match reply with a given \a parent.
+*/
+QPlaceMatchReply::QPlaceMatchReply(QObject *parent)
+ : QPlaceReply(new QPlaceMatchReplyPrivate, parent)
+{
+}
+
+/*!
+ Destroys the match reply.
+*/
+QPlaceMatchReply::~QPlaceMatchReply()
+{
+}
+
+/*!
+ Returns the type of reply.
+*/
+QPlaceReply::Type QPlaceMatchReply::type() const
+{
+ return QPlaceReply::MatchReply;
+}
+
+ /*!
+ Returns a list of matching places;
+*/
+QList<QPlace> QPlaceMatchReply::places() const
+{
+ Q_D(const QPlaceMatchReply);
+ return d->places;
+}
+
+/*!
+ Sets the list of matching \a places.
+*/
+void QPlaceMatchReply::setPlaces(const QList<QPlace> &places)
+{
+ Q_D(QPlaceMatchReply);
+ d->places = places;
+}
+
+/*!
+ Returns the match request that was used to generate this reply.
+*/
+QPlaceMatchRequest QPlaceMatchReply::request() const
+{
+ Q_D(const QPlaceMatchReply);
+ return d->request;
+}
+
+/*!
+ Sets the match \a request used to generate this reply.
+*/
+void QPlaceMatchReply::setRequest(const QPlaceMatchRequest &request)
+{
+ Q_D(QPlaceMatchReply);
+ d->request = request;
+}
diff --git a/src/location/places/qplacematchreply.h b/src/location/places/qplacematchreply.h
new file mode 100644
index 00000000..7f499dd2
--- /dev/null
+++ b/src/location/places/qplacematchreply.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef QPLACEMATCHREPLY_H
+#define QPLACEMATCHREPLY_H
+
+#include "qplacereply.h"
+#include "qplacematchrequest.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QPlaceMatchReplyPrivate;
+class Q_LOCATION_EXPORT QPlaceMatchReply : public QPlaceReply
+{
+ Q_OBJECT
+public:
+ explicit QPlaceMatchReply(QObject *parent = 0);
+ ~QPlaceMatchReply();
+
+ QPlaceReply::Type type() const;
+
+ QList<QPlace> places() const;
+ QPlaceMatchRequest request() const;
+
+protected:
+ void setPlaces(const QList<QPlace> &results);
+ void setRequest(const QPlaceMatchRequest &request);
+private:
+ Q_DISABLE_COPY(QPlaceMatchReply)
+ Q_DECLARE_PRIVATE(QPlaceMatchReply)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/location/places/qplacematchrequest.cpp b/src/location/places/qplacematchrequest.cpp
new file mode 100644
index 00000000..56dd4a36
--- /dev/null
+++ b/src/location/places/qplacematchrequest.cpp
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#include "qplacematchrequest.h"
+
+#include <QtCore/QSharedData>
+#include <QtCore/QList>
+
+QT_BEGIN_NAMESPACE
+
+class QPlaceMatchRequestPrivate : public QSharedData
+{
+public:
+ QPlaceMatchRequestPrivate();
+ QPlaceMatchRequestPrivate(const QPlaceMatchRequestPrivate &other);
+ ~QPlaceMatchRequestPrivate();
+
+ QPlaceMatchRequestPrivate &operator=(const QPlaceMatchRequestPrivate &other);
+ bool operator==(const QPlaceMatchRequestPrivate &other) const;
+
+ void clear();
+
+ QList<QPlace> places;
+ QVariantMap parameters;
+};
+
+QPlaceMatchRequestPrivate::QPlaceMatchRequestPrivate()
+ : QSharedData()
+{
+}
+
+QPlaceMatchRequestPrivate::QPlaceMatchRequestPrivate(const QPlaceMatchRequestPrivate &other)
+ : QSharedData(other),
+ places(other.places),
+ parameters(other.parameters)
+{
+}
+
+QPlaceMatchRequestPrivate::~QPlaceMatchRequestPrivate()
+{
+}
+
+QPlaceMatchRequestPrivate &QPlaceMatchRequestPrivate::operator=(const QPlaceMatchRequestPrivate &other)
+{
+ if (this != &other) {
+ places = other.places;
+ parameters = other.parameters;
+ }
+
+ return *this;
+}
+
+bool QPlaceMatchRequestPrivate::operator==(const QPlaceMatchRequestPrivate &other) const
+{
+ return (places == other.places
+ && parameters == other.parameters);
+}
+
+void QPlaceMatchRequestPrivate::clear()
+{
+ places.clear();
+ parameters.clear();
+}
+
+/*!
+ \class QPlaceMatchRequest
+ \inmodule QtLocation
+ \ingroup QtLocation-places
+ \ingroup QtLocation-places-requests
+ \since QtLocation 5.0
+
+ \brief The QPlaceMatchRequest class is used to find places from one manager that match those from another. It represents
+ a set of request parameters.
+
+ Places from another manager that may have corresponding/matching places in the current manager are assigned using setPlaces() or setResults().
+ A set of further parameters are specified which determines the criteria for matching.
+
+ The typical key for matching is the QPlaceMatchRequest::AlternativeId, the value is an alternative id attribute type of the format
+ x_id_<provider name> eg x_id_nokia. The provider name is name supplied to the QGeoServiceProvider instance.
+
+ See \l {Matching places between managers} for an example on how to use a match request.
+
+ \sa QPlaceMatchReply, QPlaceManager
+*/
+
+/*!
+ \variable QPlaceMatchRequest::AlternativeId
+ The key to specify that matching is to be accomplished via an alternative place id.
+*/
+const QString QPlaceMatchRequest::AlternativeId("alternativeId");
+
+/*!
+ Default constructor. Constructs an new request object.
+*/
+QPlaceMatchRequest::QPlaceMatchRequest()
+ : d_ptr(new QPlaceMatchRequestPrivate())
+{
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+QPlaceMatchRequest::QPlaceMatchRequest(const QPlaceMatchRequest &other)
+ : d_ptr(other.d_ptr)
+{
+}
+
+/*!
+ Destroys the request object.
+*/
+QPlaceMatchRequest::~QPlaceMatchRequest()
+{
+}
+
+/*!
+ Assigns \a other to this search request and returns a reference
+ to this match request.
+*/
+QPlaceMatchRequest &QPlaceMatchRequest::operator= (const QPlaceMatchRequest & other)
+{
+ d_ptr = other.d_ptr;
+ return *this;
+}
+
+/*!
+ Returns true if \a other is equal to this match request,
+ otherwise returns false.
+*/
+bool QPlaceMatchRequest::operator== (const QPlaceMatchRequest &other) const
+{
+ Q_D(const QPlaceMatchRequest);
+ return *d == *other.d_func();
+}
+
+/*!
+ Returns true if \a other is not equal to this match request,
+ otherwise returns false.
+*/
+bool QPlaceMatchRequest::operator!= (const QPlaceMatchRequest &other) const
+{
+ Q_D(const QPlaceMatchRequest);
+ return !(*d == *other.d_func());
+}
+
+
+/*!
+ Returns a list of places which are to be matched.
+*/
+QList<QPlace> QPlaceMatchRequest::places() const
+{
+ Q_D(const QPlaceMatchRequest);
+ return d->places;
+}
+
+/*!
+ Sets a list of \a places which are to be matched.
+
+ \sa setResults()
+*/
+void QPlaceMatchRequest::setPlaces(const QList<QPlace> places)
+{
+ Q_D(QPlaceMatchRequest);
+ d->places = places;
+}
+
+/*!
+ Convenience function which uses a set of search \a results to set
+ the places which should be matched.
+
+ \sa setPlaces()
+*/
+void QPlaceMatchRequest::setResults(const QList<QPlaceSearchResult> &results)
+{
+ Q_D(QPlaceMatchRequest);
+ QList<QPlace> places;
+ foreach (const QPlaceSearchResult &result, results)
+ places.append(result.place());
+
+ d->places = places;
+}
+
+/*!
+ Returns the paramaters for matching places.
+*/
+QVariantMap QPlaceMatchRequest::parameters() const
+{
+ Q_D(const QPlaceMatchRequest);
+ return d->parameters;
+}
+
+/*!
+ Sets the \a parameters for matching places.
+*/
+void QPlaceMatchRequest::setParameters(const QVariantMap &parameters)
+{
+ Q_D(QPlaceMatchRequest);
+ d->parameters = parameters;
+}
+
+/*!
+ Clears the match request.
+*/
+void QPlaceMatchRequest::clear()
+{
+ Q_D(QPlaceMatchRequest);
+ d->clear();
+}
+
+inline QPlaceMatchRequestPrivate* QPlaceMatchRequest::d_func()
+{
+ return static_cast<QPlaceMatchRequestPrivate *>(d_ptr.data());
+}
+
+inline const QPlaceMatchRequestPrivate* QPlaceMatchRequest::d_func() const
+{
+ return static_cast<const QPlaceMatchRequestPrivate *>(d_ptr.constData());
+}
+
+QT_END_NAMESPACE
diff --git a/src/location/places/qplacematchrequest.h b/src/location/places/qplacematchrequest.h
new file mode 100644
index 00000000..2a00556a
--- /dev/null
+++ b/src/location/places/qplacematchrequest.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef QPLACEMATCHREQUEST_H
+#define QPLACEMATCHREQUEST_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtLocation/qtlocation.h>
+
+#include "qplacesearchresult.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QPlaceMatchRequestPrivate;
+
+class Q_LOCATION_EXPORT QPlaceMatchRequest
+{
+public:
+ static const QString AlternativeId;
+
+ QPlaceMatchRequest();
+ QPlaceMatchRequest(const QPlaceMatchRequest &other);
+
+
+ QPlaceMatchRequest& operator=(const QPlaceMatchRequest &other);
+
+ bool operator==(const QPlaceMatchRequest &other) const;
+ bool operator!=(const QPlaceMatchRequest &other) const;
+
+ ~QPlaceMatchRequest();
+
+ QList<QPlace> places() const;
+ void setPlaces(const QList<QPlace> places);
+
+ void setResults(const QList<QPlaceSearchResult> &results);
+
+ QVariantMap parameters() const;
+ void setParameters(const QVariantMap &parameters);
+
+ void clear();
+
+private:
+ QSharedDataPointer<QPlaceMatchRequestPrivate> d_ptr;
+ inline QPlaceMatchRequestPrivate *d_func();
+ inline const QPlaceMatchRequestPrivate *d_func() const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/location/places/qplacereply.cpp b/src/location/places/qplacereply.cpp
index 0190eaa3..3a068eb8 100644
--- a/src/location/places/qplacereply.cpp
+++ b/src/location/places/qplacereply.cpp
@@ -111,6 +111,9 @@ QT_USE_NAMESPACE
\value IdReply
This is a reply that returns an id of a place/category.
Typically used for place/category save and remove operations.
+ \value MatchReply
+ This is a reply that returns places that match
+ those from another provider.
*/
/*!
diff --git a/src/location/places/qplacereply.h b/src/location/places/qplacereply.h
index 8d155ca2..e64e18e5 100644
--- a/src/location/places/qplacereply.h
+++ b/src/location/places/qplacereply.h
@@ -42,16 +42,14 @@
#ifndef QPLACEREPLY_H
#define QPLACEREPLY_H
+#include <QtCore/QMetaType>
+#include <QtCore/QObject>
#include <QtLocation/qlocationglobal.h>
-#include <QObject>
-
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-
-
class QPlaceReplyPrivate;
class Q_LOCATION_EXPORT QPlaceReply : public QObject
{
@@ -76,7 +74,8 @@ public:
SearchReply,
SearchSuggestionReply,
ContentReply,
- IdReply
+ IdReply,
+ MatchReply
};
explicit QPlaceReply(QObject *parent = 0);
@@ -108,6 +107,9 @@ private:
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QPlaceReply::Error)
+Q_DECLARE_METATYPE(QPlaceReply *)
+
QT_END_HEADER
#endif // QPLACEREPLY_H
diff --git a/src/location/places/unsupportedreplies_p.h b/src/location/places/unsupportedreplies_p.h
new file mode 100644
index 00000000..b3c72f72
--- /dev/null
+++ b/src/location/places/unsupportedreplies_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#ifndef UNSUPPORTEDREPLIES_P_H
+#define UNSUPPORTEDREPLIES_P_H
+
+#include "qplacematchreply.h"
+#include "qplacemanagerengine.h"
+
+class MatchReply : public QPlaceMatchReply
+{
+ Q_OBJECT
+public:
+ MatchReply(QPlaceManagerEngine *engine)
+ : QPlaceMatchReply(engine), m_engine(engine)
+ {}
+ virtual ~MatchReply() {}
+
+ void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError,
+ const QString &errorString = QString()) {
+ if (error != QPlaceReply::NoError) {
+ this->setError(error,errorString);
+ QMetaObject::invokeMethod(m_engine, "error", Qt::QueuedConnection,
+ Q_ARG(QPlaceReply *,this),
+ Q_ARG(QPlaceReply::Error, error),
+ Q_ARG(QString, errorString));
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QPlaceReply::Error, error),
+ Q_ARG(QString, errorString));
+ }
+ this->setFinished(true);
+ QMetaObject::invokeMethod(m_engine, "finished", Qt::QueuedConnection,
+ Q_ARG(QPlaceReply *,this));
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+ }
+
+private:
+ QPlaceManagerEngine *m_engine;
+};
+
+#endif
diff --git a/src/plugins/geoservices/nokia/places/qplacejsondetailsparser.cpp b/src/plugins/geoservices/nokia/places/qplacejsondetailsparser.cpp
index 15bf9411..48ebda58 100644
--- a/src/plugins/geoservices/nokia/places/qplacejsondetailsparser.cpp
+++ b/src/plugins/geoservices/nokia/places/qplacejsondetailsparser.cpp
@@ -63,6 +63,7 @@
#include <qplaceratings.h>
#include <qgeolocation.h>
#include <qplacesupplier.h>
+#include <qplacemanager.h>
#include "qplacejsoncategoriesparser.h"
#include "qplacesuppliersrepository.h"
@@ -216,6 +217,11 @@ QPlace QPlaceJSonDetailsParser::buildPlace(const QJSValue &placeValue, QPlaceMan
newPlace.setIcon(icon);
}
+ QPlaceAttribute managerName;
+ managerName.setText(manager->managerName());
+
+ newPlace.setExtendedAttribute(QLatin1String("x_provider"), managerName);
+
return newPlace;
}
diff --git a/src/plugins/geoservices/nokia/places/qplacejsonsearchparser.cpp b/src/plugins/geoservices/nokia/places/qplacejsonsearchparser.cpp
index 643a82ba..096519d7 100644
--- a/src/plugins/geoservices/nokia/places/qplacejsonsearchparser.cpp
+++ b/src/plugins/geoservices/nokia/places/qplacejsonsearchparser.cpp
@@ -220,6 +220,12 @@ QPlaceSearchResult QPlaceJSonSearchParser::processPlaceElement(const QJSValue &r
processCategories(value, &newPlace);
}
}
+
+ QPlaceAttribute managerName;
+ managerName.setText(QLatin1String("nokia")); //provider name
+
+ newPlace.setExtendedAttribute(QLatin1String("x_provider"), managerName);
+
result.setPlace(newPlace);
return result;
}
diff --git a/src/plugins/geoservices/nokia/qplacemanagerengine_nokia.cpp b/src/plugins/geoservices/nokia/qplacemanagerengine_nokia.cpp
index f66869c5..23f8b91b 100644
--- a/src/plugins/geoservices/nokia/qplacemanagerengine_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qplacemanagerengine_nokia.cpp
@@ -62,7 +62,6 @@
#include "places/unsupportedreplies.h"
QT_USE_NAMESPACE
-Q_DECLARE_METATYPE(QPlaceReply::Error)
QPlaceManagerEngineNokia::QPlaceManagerEngineNokia(const QMap<QString, QVariant> &parameters,
QGeoServiceProvider::Error *error,
diff --git a/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.cpp b/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.cpp
index 7e6d8f48..6cd1c5e2 100644
--- a/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.cpp
+++ b/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.cpp
@@ -176,6 +176,18 @@ QVariantMap JsonConverter::addToJsonMap(const QVariant &var, const QPlace &place
categoryUuids.append(category.categoryId());
map.insert(JsonConverter::CategoryUuids, categoryUuids);
+ QVariantMap extendedAttributes;
+ QVariantMap attribute;
+ QStringList attributeTypes = place.extendedAttributeTypes();
+ foreach (const QString attributeType, attributeTypes) {
+ if (attributeType.startsWith("x_id")) {
+ attribute.insert(JsonConverter::Label, place.extendedAttribute(attributeType).label());
+ attribute.insert(JsonConverter::Text, place.extendedAttribute(attributeType).text());
+ extendedAttributes.insert(attributeType, attribute);
+ }
+ }
+ map.insert(JsonConverter::ExtendedAttributes, extendedAttributes);
+
return map;
}
@@ -281,6 +293,18 @@ QPlace JsonConverter::convertJsonMapToPlace(const QVariantMap &placeMap,
place.setCategories(categories);
+ if (placeMap.keys().contains(JsonConverter::ExtendedAttributes)) {
+ QVariantMap attributesMap = placeMap.value(JsonConverter::ExtendedAttributes).toMap();
+ QVariantMap attributeMap;
+ QPlaceAttribute attribute;
+ foreach (const QString &attributeType, attributesMap.keys()) {
+ attributeMap = attributesMap.value(attributeType).toMap();
+ attribute.setLabel(attributeMap.value(JsonConverter::Label).toString());
+ attribute.setText(attributeMap.value(JsonConverter::Text).toString());
+ place.setExtendedAttribute(attributeType, attribute);
+ }
+ }
+
return place;
}
diff --git a/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.h b/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.h
index b14ff8a2..c41434cb 100644
--- a/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.h
+++ b/src/plugins/geoservices/nokia_places_jsondb/jsonconverter.h
@@ -120,6 +120,9 @@ namespace JsonConverter
static QLatin1String Url("url");
static QLatin1String IconUrl("iconUrl");
+
+ static QLatin1String ExtendedAttributes("extendedAttributes");
+ static QLatin1String Text("text");
}
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia_places_jsondb/matchreply.cpp b/src/plugins/geoservices/nokia_places_jsondb/matchreply.cpp
new file mode 100644
index 00000000..b401026d
--- /dev/null
+++ b/src/plugins/geoservices/nokia_places_jsondb/matchreply.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#include "matchreply.h"
+#include "jsonconverter.h"
+
+#include <QtAddOnJsonDb/jsondb-client.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/QDebug>
+#include <QtLocation/QGeoBoundingCircle>
+
+MatchReply::MatchReply(QPlaceManagerEngineJsonDb *engine)
+ : QPlaceMatchReply(engine), m_engine(engine)
+{
+}
+
+MatchReply::~MatchReply()
+{
+}
+
+void MatchReply::setPlaces(const QList<QPlace> &places)
+{
+ QPlaceMatchReply::setPlaces(places);
+}
+
+void MatchReply::setRequest(const QPlaceMatchRequest &request)
+{
+ QPlaceMatchReply::setRequest(request);
+}
+
+void MatchReply::start()
+{
+ connect(db(), SIGNAL(response(int,QVariant)), this, SLOT(processResponse(int,QVariant)));
+ connect(db(), SIGNAL(error(int,int,QString)), this, SLOT(processError(int,int,QString)));
+
+ m_inputPlaces = request().places();
+
+ if (m_inputPlaces.count() > 0) {
+ if (request().parameters().contains(QPlaceMatchRequest::AlternativeId)) {
+ QString alternativeId = m_inputPlaces.takeFirst().placeId();
+ findPlace(alternativeId);
+ } else if (request().parameters().contains(QLatin1String("proximityRange"))) {
+ findPlaceByProximity();
+ } else {
+ for (int i=0; i < m_inputPlaces.count(); ++i)
+ m_outputPlaces.append(QPlace());
+ triggerDone();
+ }
+ } else {
+ triggerDone();
+ }
+}
+
+void MatchReply::processResponse(int id, const QVariant &data)
+{
+ if (id != m_reqId)
+ return;
+
+ if (request().parameters().contains(QPlaceMatchRequest::AlternativeId)) {
+ if (data.toMap().value(JsonConverter::Length).toInt() > 0) {
+ QList<QPlace> places = JsonConverter::convertJsonResponseToPlaces(data, m_engine);
+ m_outputPlaces.append(places.first());
+ } else {
+ m_outputPlaces.append(QPlace());
+ }
+
+ if (!m_inputPlaces.isEmpty()) {
+ QString alternativeId = m_inputPlaces.takeFirst().placeId();
+ findPlace(alternativeId);
+ return;
+ } else {
+ setPlaces(m_outputPlaces);
+ triggerDone();
+ }
+ } else if (request().parameters().contains(QLatin1String("proximityRange"))) {
+ qreal range = request().parameters().value(QLatin1String("proximityRange")).toReal();
+
+ //TODO: optimize proximity match
+ if (data.toMap().value(JsonConverter::Length).toInt() > 0) {
+ QList<QPlace> candidatePlaces = JsonConverter::convertJsonResponseToPlaces(data, m_engine);
+
+ bool isFound;
+ foreach (const QPlace &m_inputPlace, request().places()) {
+ isFound = false;
+ foreach (const QPlace &candidatePlace, candidatePlaces) {
+ qreal dist = candidatePlace.location().coordinate().distanceTo(m_inputPlace.location().coordinate());
+ if ((dist < range) || qFuzzyCompare(dist, range)) {
+ m_outputPlaces.append(candidatePlace);
+ isFound = true;
+ break;
+ }
+ }
+ if (!isFound)
+ m_outputPlaces.append(QPlace());
+ }
+ } else {
+ //no matches, therefore output places are filled with a default constructed place for each input place
+ for (int i=0; i < m_inputPlaces.count(); ++i)
+ m_outputPlaces.append(QPlace());
+ }
+
+ setPlaces(m_outputPlaces);
+ triggerDone();
+ }
+}
+
+void MatchReply::processError(int id, int code, const QString &jsonDbErrorString)
+{
+ QPlaceReply::Error error = QPlaceReply::UnknownError;
+ QString errorString = QString::fromLatin1("Unknown error occurred operation: jsondb error code =%1, erroString=%2").
+ arg(code).arg(jsonDbErrorString);
+ triggerDone(error, errorString);
+}
+
+void MatchReply::findPlace(const QString &alternativeId)
+{
+ QString extId = QString(JsonConverter::ExtendedAttributes) + QLatin1String(".")
+ + request().parameters().value(QPlaceMatchRequest::AlternativeId).toString() + QLatin1String(".") +
+ JsonConverter::Text;
+
+ QString queryString = QString::fromLatin1("[?%1 = %placeType]").arg(JsonConverter::Type)
+ + QString::fromLatin1("[?%1 = %expectedId]").arg(extId);
+
+ QVariantMap bindingsMap;
+ bindingsMap.insert(QLatin1String("placeType"), JsonConverter::PlaceType);
+ bindingsMap.insert(QLatin1String("expectedId"), alternativeId);
+ QVariantMap queryObj;
+ queryObj.insert(JsonConverter::Query, queryString);
+ queryObj.insert(JsonConverter::Bindings, bindingsMap);
+ m_state = MatchReply::GetPlaces;
+ m_reqId = db()->find(queryObj);
+}
+
+void MatchReply::findPlaceByProximity()
+{
+ //TODO: optimize proximity match
+ QString queryString = QString::fromLatin1("[?%1= %placeType]").arg(JsonConverter::Type);
+ QVariantMap bindingsMap;
+ bindingsMap.insert(QLatin1String("placeType"), JsonConverter::PlaceType);
+
+ QVariantMap queryObj;
+ queryObj.insert(JsonConverter::Query, queryString);
+ queryObj.insert(JsonConverter::Bindings, bindingsMap);
+ m_state = MatchReply::GetPlaces;
+ m_reqId = db()->find(queryObj);
+}
+
diff --git a/src/plugins/geoservices/nokia_places_jsondb/matchreply.h b/src/plugins/geoservices/nokia_places_jsondb/matchreply.h
new file mode 100644
index 00000000..83427d1e
--- /dev/null
+++ b/src/plugins/geoservices/nokia_places_jsondb/matchreply.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+#ifndef MATCHREPLY_H
+#define MATCHREPLY_H
+
+#include "macro.h"
+#include "qplacemanagerengine_jsondb.h"
+
+#include <qplacematchreply.h>
+
+#include <QObject>
+
+QT_USE_NAMESPACE
+
+class MatchReply : public QPlaceMatchReply
+{
+ Q_OBJECT
+
+ enum State {
+ Initial,
+ GetPlaces
+ };
+
+public:
+ MatchReply(QPlaceManagerEngineJsonDb *engine);
+ virtual ~MatchReply();
+ void setPlaces(const QList<QPlace> &places);
+ void setRequest(const QPlaceMatchRequest &request);
+
+ DECLARE_TRIGGER_DONE_FN
+
+ void start();
+
+protected:
+ JsonDbClient *db() {return m_engine->db();}
+
+private slots:
+ void processResponse(int id, const QVariant &data);
+ void processError(int id, int code, const QString &);
+
+private:
+ void findPlace(const QString &id);
+ void findPlaceByProximity();
+
+ QPlaceManagerEngineJsonDb *m_engine;
+ State m_state;
+ int m_reqId;
+ QList<QPlace> m_inputPlaces;
+ QList<QPlace> m_outputPlaces;
+};
+
+#endif
diff --git a/src/plugins/geoservices/nokia_places_jsondb/nokia_places_jsondb.pro b/src/plugins/geoservices/nokia_places_jsondb/nokia_places_jsondb.pro
index 8d5bdeba..901ff697 100644
--- a/src/plugins/geoservices/nokia_places_jsondb/nokia_places_jsondb.pro
+++ b/src/plugins/geoservices/nokia_places_jsondb/nokia_places_jsondb.pro
@@ -13,6 +13,7 @@ HEADERS += \
qgeoserviceproviderplugin_jsondb.h \
qplacemanagerengine_jsondb.h \
jsonconverter.h \
+ matchreply.h \
searchreply.h \
detailsreply.h \
reply.h \
@@ -24,6 +25,7 @@ SOURCES += \
qgeoserviceproviderplugin_jsondb.cpp \
qplacemanagerengine_jsondb.cpp \
jsonconverter.cpp \
+ matchreply.cpp \
searchreply.cpp \
detailsreply.cpp \
reply.cpp \
diff --git a/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.cpp b/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.cpp
index b39a0f21..ddb96a33 100644
--- a/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.cpp
+++ b/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.cpp
@@ -50,14 +50,12 @@
#include "detailsreply.h"
#include "reply.h"
#include "idreply.h"
+#include "matchreply.h"
#include "searchreply.h"
#include "unsupportedreplies.h"
QT_USE_NAMESPACE
-Q_DECLARE_METATYPE(QPlaceReply::Error)
-Q_DECLARE_METATYPE(QPlaceReply *)
-
QPlaceManagerEngineJsonDb::QPlaceManagerEngineJsonDb(const QMap<QString, QVariant> &parameters,
QGeoServiceProvider::Error *error,
QString *errorString)
@@ -259,7 +257,23 @@ QPlace QPlaceManagerEngineJsonDb::compatiblePlace(const QPlace &original) const
foreach (const QString &contactType, original.contactTypes())
place.setContactDetails(contactType, original.contactDetails(contactType));
- place.setVisibility(QtLocation::DeviceVisibility);
+
+ place.setVisibility(QtLocation::UnspecifiedVisibility);
+
+
+ QStringList attributeTypes = original.extendedAttributeTypes();
+ foreach (const QString &attributeType, attributeTypes) {
+ if (attributeType.startsWith(QLatin1String("x_id")))
+ place.setExtendedAttribute(attributeType, original.extendedAttribute(attributeType));
+ }
+
+ if (attributeTypes.contains(QLatin1String("x_provider")) && !original.extendedAttribute(QLatin1String("x_provider")).text().isEmpty()) {
+ QPlaceAttribute alternativeId;
+ alternativeId.setText(original.placeId());
+ place.setExtendedAttribute(QString::fromLatin1("x_id_") + original.extendedAttribute(QLatin1String("x_provider")).text(),
+ alternativeId);
+ }
+
return place;
}
@@ -276,7 +290,16 @@ QPlaceManager::ManagerFeatures QPlaceManagerEngineJsonDb::supportedFeatures() co
return QPlaceManager::SavePlaceFeature |
QPlaceManager::RemovePlaceFeature |
QPlaceManager::SaveCategoryFeature |
- QPlaceManager::RemoveCategoryFeature;
+ QPlaceManager::RemoveCategoryFeature |
+ QPlaceManager::MatchingFeature;
+}
+
+QPlaceMatchReply * QPlaceManagerEngineJsonDb::matchingPlaces(const QPlaceMatchRequest &request)
+{
+ MatchReply *reply = new MatchReply(this);
+ reply->setRequest(request);
+ reply->start();
+ return reply;
}
void QPlaceManagerEngineJsonDb::processJsonDbResponse(int id, const QVariant &data)
diff --git a/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.h b/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.h
index c63c0d91..99522f56 100644
--- a/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.h
+++ b/src/plugins/geoservices/nokia_places_jsondb/qplacemanagerengine_jsondb.h
@@ -105,6 +105,8 @@ public:
return QString::fromLatin1("[?%1=\"%2\"][?%3 = \"%4\"]")
.arg(JsonConverter::Type).arg(JsonConverter::CategoryType).arg(JsonConverter::Uuid).arg(categoryUuid);
}
+
+ QPlaceMatchReply * matchingPlaces(const QPlaceMatchRequest &request);
public slots:
void processJsonDbResponse(int id, const QVariant &data);
void processJsonDbError(int id, int code, const QString &error);
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 0157b2c2..3b7c032e 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -9,6 +9,8 @@ SUBDIRS += qplace \
qplaceeditorial \
qplacemanager \
qplacemanager_nokia \
+ qplacematchreply \
+ qplacematchrequest \
qplaceimage \
qplaceratings \
qplacereply \
diff --git a/tests/auto/qplacemanager/tst_qplacemanager.cpp b/tests/auto/qplacemanager/tst_qplacemanager.cpp
index 74864630..e42ea0ff 100644
--- a/tests/auto/qplacemanager/tst_qplacemanager.cpp
+++ b/tests/auto/qplacemanager/tst_qplacemanager.cpp
@@ -39,12 +39,28 @@
**
****************************************************************************/
+#include <QtCore/QMetaType>
#include <QString>
#include <QtTest/QtTest>
#include <qgeoserviceprovider.h>
#include <qplacemanager.h>
+
+#ifndef WAIT_UNTIL
+#define WAIT_UNTIL(__expr) \
+ do { \
+ const int __step = 50; \
+ const int __timeout = 5000; \
+ if (!(__expr)) { \
+ QTest::qWait(0); \
+ } \
+ for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+ QTest::qWait(__step); \
+ } \
+ } while (0)
+#endif
+
QT_USE_NAMESPACE
class tst_QPlaceManager : public QObject
@@ -58,8 +74,11 @@ private Q_SLOTS:
void compatiblePlace();
void testMetadata();
void testLocales();
+ void testMatchUnsupported();
private:
+ bool checkSignals(QPlaceReply *reply, QPlaceReply::Error expectedError);
+
QGeoServiceProvider *provider;
QPlaceManager *placeManager;
};
@@ -102,6 +121,13 @@ void tst_QPlaceManager::testLocales()
QCOMPARE(placeManager->locales().at(1), en_UK);
}
+void tst_QPlaceManager::testMatchUnsupported()
+{
+ QPlaceMatchRequest request;
+ QPlaceMatchReply *reply = placeManager->matchingPlaces(request);
+ QVERIFY(checkSignals(reply, QPlaceReply::UnsupportedError));
+}
+
void tst_QPlaceManager::compatiblePlace()
{
QPlace place;
@@ -120,6 +146,89 @@ void tst_QPlaceManager::cleanupTestCase()
delete provider;
}
+bool tst_QPlaceManager::checkSignals(QPlaceReply *reply, QPlaceReply::Error expectedError)
+{
+ QSignalSpy finishedSpy(reply, SIGNAL(finished()));
+ QSignalSpy errorSpy(reply, SIGNAL(error(QPlaceReply::Error,QString)));
+ QSignalSpy managerFinishedSpy(placeManager, SIGNAL(finished(QPlaceReply*)));
+ QSignalSpy managerErrorSpy(placeManager,SIGNAL(error(QPlaceReply*,QPlaceReply::Error,QString)));
+
+ if (expectedError != QPlaceReply::NoError) {
+ //check that we get an error signal from the reply
+ WAIT_UNTIL(errorSpy.count() == 1);
+ if (errorSpy.count() != 1) {
+ qWarning() << "Error signal for search operation not received";
+ return false;
+ }
+
+ //check that we get the correct error from the reply's signal
+ QPlaceReply::Error actualError = qvariant_cast<QPlaceReply::Error>(errorSpy.at(0).at(0));
+ if (actualError != expectedError) {
+ qWarning() << "Actual error code in reply signal does not match expected error code";
+ qWarning() << "Actual error code = " << actualError;
+ qWarning() << "Expected error coe =" << expectedError;
+ return false;
+ }
+
+ //check that we get an error signal from the manager
+ WAIT_UNTIL(managerErrorSpy.count() == 1);
+ if (managerErrorSpy.count() !=1) {
+ qWarning() << "Error signal from manager for search operation not received";
+ return false;
+ }
+
+ //check that we get the correct reply instance in the error signal from the manager
+ if (qvariant_cast<QPlaceReply*>(managerErrorSpy.at(0).at(0)) != reply) {
+ qWarning() << "Reply instance in error signal from manager is incorrect";
+ return false;
+ }
+
+ //check that we get the correct error from the signal of the manager
+ actualError = qvariant_cast<QPlaceReply::Error>(managerErrorSpy.at(0).at(1));
+ if (actualError != expectedError) {
+ qWarning() << "Actual error code from manager signal does not match expected error code";
+ qWarning() << "Actual error code =" << actualError;
+ qWarning() << "Expected error code = " << expectedError;
+ return false;
+ }
+ }
+
+ //check that we get a finished signal
+ WAIT_UNTIL(finishedSpy.count() == 1);
+ if (finishedSpy.count() !=1) {
+ qWarning() << "Finished signal from reply not received";
+ return false;
+ }
+
+ if (reply->error() != expectedError) {
+ qWarning() << "Actual error code does not match expected error code";
+ qWarning() << "Actual error code: " << reply->error();
+ qWarning() << "Expected error code" << expectedError;
+ return false;
+ }
+
+ if (expectedError == QPlaceReply::NoError && !reply->errorString().isEmpty()) {
+ qWarning() << "Expected error was no error but error string was not empty";
+ qWarning() << "Error string=" << reply->errorString();
+ return false;
+ }
+
+ //check that we get the finished signal from the manager
+ WAIT_UNTIL(managerFinishedSpy.count() == 1);
+ if (managerFinishedSpy.count() != 1) {
+ qWarning() << "Finished signal from manager not received";
+ return false;
+ }
+
+ //check that the reply instance in the finished signal from the manager is correct
+ if (qvariant_cast<QPlaceReply *>(managerFinishedSpy.at(0).at(0)) != reply) {
+ qWarning() << "Reply instance in finished signal from manager is incorrect";
+ return false;
+ }
+
+ return true;
+}
+
QTEST_GUILESS_MAIN(tst_QPlaceManager)
#include "tst_qplacemanager.moc"
diff --git a/tests/auto/qplacemanager_jsondb/tst_qplacemanager_jsondb.cpp b/tests/auto/qplacemanager_jsondb/tst_qplacemanager_jsondb.cpp
index 57c484aa..3d0f5e38 100644
--- a/tests/auto/qplacemanager_jsondb/tst_qplacemanager_jsondb.cpp
+++ b/tests/auto/qplacemanager_jsondb/tst_qplacemanager_jsondb.cpp
@@ -50,6 +50,7 @@
#include <qplacemanager.h>
#include <qplacecategory.h>
#include <qplacecontentreply.h>
+#include <qplacematchreply.h>
#include <qplacesearchsuggestionreply.h>
#include <qplacesearchrequest.h>
#include <qplacesearchresult.h>
@@ -74,8 +75,6 @@
} while (0)
#endif
-Q_DECLARE_METATYPE(QPlaceReply::Error);
-Q_DECLARE_METATYPE(QPlaceReply *);
Q_DECLARE_METATYPE(QPlaceIdReply *);
QT_USE_NAMESPACE
@@ -113,6 +112,8 @@ private Q_SLOTS:
void placeNotifications();
void categoryNotifications();
void compatiblePlace();
+ void extendedAttribute();
+ void matchingPlaces();
private:
bool doSavePlace(const QPlace &place,
@@ -148,6 +149,10 @@ private:
bool doRemoveCategory(const QPlaceCategory &category,
QPlaceReply::Error expectedError = QPlaceReply::NoError);
+ bool doMatch(const QPlaceMatchRequest &request,
+ QList<QPlace> *places,
+ QPlaceReply::Error expectedError = QPlaceReply::NoError);
+
bool checkSignals(QPlaceReply *reply, QPlaceReply::Error expectedError);
@@ -1522,7 +1527,92 @@ void tst_QPlaceManagerJsonDb::compatiblePlace()
QVERIFY(compatPlace.extendedAttributeTypes().isEmpty());
QCOMPARE(compatPlace.extendedAttribute(QLatin1String("Smoking")), QPlaceAttribute());
- QCOMPARE(compatPlace.visibility(), QtLocation::DeviceVisibility);
+ QCOMPARE(compatPlace.visibility(), QtLocation::UnspecifiedVisibility);
+}
+
+void tst_QPlaceManagerJsonDb::extendedAttribute()
+{
+ QPlaceAttribute attribute;
+ attribute.setLabel(QLatin1String("x_id_nokia"));
+ attribute.setText(QLatin1String("ae562"));
+ QPlace place;
+ place.setExtendedAttribute(QLatin1String("x_id_nokia"), attribute);
+
+ QString placeId;
+ QVERIFY(doSavePlace(place, QPlaceReply::NoError, &placeId));
+
+ QPlace retrievedPlace;
+ QVERIFY(doFetchDetails(placeId,&retrievedPlace));
+ QVERIFY(retrievedPlace.extendedAttributeTypes().contains(QLatin1String("x_id_nokia")));
+}
+
+void tst_QPlaceManagerJsonDb::matchingPlaces()
+{
+ QPlace place1;
+ place1.setPlaceId(QLatin1String("abcd"));
+ place1.setName("place1");
+
+ QPlaceAttribute origin1;
+ origin1.setText("nokia");
+ place1.setExtendedAttribute(QLatin1String("x_provider"), origin1);
+
+ QPlace place1Saved;
+ place1Saved = placeManager->compatiblePlace(place1);
+
+ QString placeId;
+ QVERIFY(doSavePlace(place1Saved, QPlaceReply::NoError, &placeId));
+ place1Saved.setPlaceId(placeId);
+
+ QPlaceSearchResult result1;
+ result1.setPlace(place1);
+
+ QList<QPlaceSearchResult> results;
+ results << result1;
+
+ QPlaceMatchRequest matchRequest;
+ QVariantMap parameters;
+ parameters.insert(QPlaceMatchRequest::AlternativeId, QLatin1String("x_id_nokia"));
+ matchRequest.setParameters(parameters);
+ matchRequest.setResults(results);
+ QList<QPlace> places;
+ QVERIFY(doMatch(matchRequest,&places));
+ QCOMPARE(places.count(), 1);
+ QCOMPARE(place1Saved, places.at(0));
+
+ //try matching multiple places
+ QPlace nonMatchingPlace;
+ nonMatchingPlace.setName("Non matching");
+ nonMatchingPlace.setPlaceId(QLatin1String("1234"));
+ QPlaceAttribute originNonMatch;
+ originNonMatch.setText(QLatin1String("nokia"));
+ nonMatchingPlace.setExtendedAttribute(QLatin1String("x_provider"),originNonMatch);
+ QPlaceSearchResult nonMatchingResult;
+ nonMatchingResult.setPlace(nonMatchingPlace);
+ results.insert(1, nonMatchingResult);
+
+ QPlace place2;
+ place2.setName(QLatin1String("place2"));
+ place2.setPlaceId(QLatin1String("efgh"));
+
+ QPlaceAttribute origin2;
+ origin2.setText(QLatin1String("nokia"));
+ place2.setExtendedAttribute(QLatin1String("x_provider"), origin2);
+
+ QPlace place2Saved = placeManager->compatiblePlace(place2);
+ QVERIFY(doSavePlace(place2Saved, QPlaceReply::NoError, &placeId));
+ place2Saved.setPlaceId(placeId);
+
+ QPlaceSearchResult result2;
+ result2.setPlace(place2);
+ results.clear();
+ results << result1 << nonMatchingResult << result2;
+
+ matchRequest.setResults(results);
+ QVERIFY(doMatch(matchRequest, &places));
+ QCOMPARE(places.count(), 3);
+ QCOMPARE(places.at(0), place1Saved);
+ QCOMPARE(places.at(1), QPlace());
+ QCOMPARE(places.at(2), place2Saved);
}
void tst_QPlaceManagerJsonDb::cleanup()
@@ -1737,6 +1827,17 @@ bool tst_QPlaceManagerJsonDb::checkSignals(QPlaceReply *reply, QPlaceReply::Erro
return true;
}
+bool tst_QPlaceManagerJsonDb::doMatch(const QPlaceMatchRequest &request,
+ QList<QPlace> *places,
+ QPlaceReply::Error expectedError)
+{
+ QPlaceMatchReply *reply = placeManager->matchingPlaces(request);
+ bool isSuccessful = checkSignals(reply, expectedError) &&
+ (reply->error() == expectedError);
+ *places = reply->places();
+ return isSuccessful;
+}
+
bool tst_QPlaceManagerJsonDb::compareResults(const QList<QPlaceSearchResult> &results,
const QList<QPlace> &expectedResults)
{
diff --git a/tests/auto/qplacemanager_nokia/tst_qplacemanager_nokia.cpp b/tests/auto/qplacemanager_nokia/tst_qplacemanager_nokia.cpp
index c78b11f5..4102a968 100644
--- a/tests/auto/qplacemanager_nokia/tst_qplacemanager_nokia.cpp
+++ b/tests/auto/qplacemanager_nokia/tst_qplacemanager_nokia.cpp
@@ -60,8 +60,6 @@
} while (0)
#endif
-Q_DECLARE_METATYPE(QPlaceReply::Error);
-Q_DECLARE_METATYPE(QPlaceReply *);
Q_DECLARE_METATYPE(QPlaceIdReply *);
QT_USE_NAMESPACE
diff --git a/tests/auto/qplacematchreply/qplacematchreply.pro b/tests/auto/qplacematchreply/qplacematchreply.pro
new file mode 100644
index 00000000..00c1dcd9
--- /dev/null
+++ b/tests/auto/qplacematchreply/qplacematchreply.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+CONFIG += testcase
+TARGET = tst_qplacematchreply
+
+SOURCES += tst_qplacematchreply.cpp
+
+QT += location testlib
diff --git a/tests/auto/qplacematchreply/tst_qplacematchreply.cpp b/tests/auto/qplacematchreply/tst_qplacematchreply.cpp
new file mode 100644
index 00000000..05b4d695
--- /dev/null
+++ b/tests/auto/qplacematchreply/tst_qplacematchreply.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#include <QtCore/QString>
+#include <QtTest/QtTest>
+
+#include <QtLocation/QPlaceMatchReply>
+
+QT_USE_NAMESPACE
+
+class TestMatchReply : public QPlaceMatchReply
+{
+ Q_OBJECT
+public:
+ TestMatchReply(QObject *parent) : QPlaceMatchReply(parent) {}
+ TestMatchReply() {}
+
+ void setPlaces(const QList<QPlace> &places) {
+ QPlaceMatchReply::setPlaces(places);
+ }
+
+ void setRequest(const QPlaceMatchRequest &request) {
+ QPlaceMatchReply::setRequest(request);
+ }
+};
+
+class tst_QPlaceMatchReply : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QPlaceMatchReply();
+
+private Q_SLOTS:
+ void constructorTest();
+ void typeTest();
+ void requestTest();
+// void resultsTest();
+};
+
+tst_QPlaceMatchReply::tst_QPlaceMatchReply()
+{
+}
+
+void tst_QPlaceMatchReply::constructorTest()
+{
+ QPlaceMatchReply *reply = new TestMatchReply(this);
+ QVERIFY(reply->parent() == this);
+ delete reply;
+}
+
+void tst_QPlaceMatchReply::typeTest()
+{
+ TestMatchReply *reply = new TestMatchReply(this);
+ QVERIFY(reply->type() == QPlaceReply::MatchReply);
+ delete reply;
+}
+
+void tst_QPlaceMatchReply::requestTest()
+{
+ TestMatchReply *reply = new TestMatchReply(this);
+ QPlaceMatchRequest request;
+
+ QPlace place1;
+ place1.setName(QLatin1String("place1"));
+
+ QPlace place2;
+ place2.setName(QLatin1String("place2"));
+
+ QList<QPlace> places;
+ places << place1 << place2;
+
+ request.setPlaces(places);
+
+ reply->setRequest(request);
+ QCOMPARE(reply->request(), request);
+
+ reply->setRequest(QPlaceMatchRequest());
+ QCOMPARE(reply->request(), QPlaceMatchRequest());
+ delete reply;
+}
+
+
+QTEST_APPLESS_MAIN(tst_QPlaceMatchReply)
+
+#include "tst_qplacematchreply.moc"
diff --git a/tests/auto/qplacematchrequest/qplacematchrequest.pro b/tests/auto/qplacematchrequest/qplacematchrequest.pro
new file mode 100644
index 00000000..558cd2ef
--- /dev/null
+++ b/tests/auto/qplacematchrequest/qplacematchrequest.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+CONFIG += testcase
+TARGET = tst_qplacematchrequest
+SOURCES += tst_qplacematchrequest.cpp
+
+QT += location testlib
diff --git a/tests/auto/qplacematchrequest/tst_qplacematchrequest.cpp b/tests/auto/qplacematchrequest/tst_qplacematchrequest.cpp
new file mode 100644
index 00000000..11fb6794
--- /dev/null
+++ b/tests/auto/qplacematchrequest/tst_qplacematchrequest.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $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$
+**
+****************************************************************************/
+
+#include <QtCore/QString>
+#include <QtTest/QtTest>
+
+#include <qplacematchrequest.h>
+
+
+QT_USE_NAMESPACE
+
+class tst_QPlaceMatchRequest : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QPlaceMatchRequest();
+
+private Q_SLOTS:
+ void constructorTest();
+ void placesTest();
+ void resultsTest();
+ void parametersTest();
+ void clearTest();
+};
+
+tst_QPlaceMatchRequest::tst_QPlaceMatchRequest()
+{
+}
+
+void tst_QPlaceMatchRequest::constructorTest()
+{
+ QPlaceMatchRequest request;
+ QVariantMap params;
+ params.insert(QLatin1String("key"), QLatin1String("val"));
+
+ QPlace place1;
+ place1.setName(QLatin1String("place1"));
+
+ QPlace place2;
+ place2.setName(QLatin1String("place2"));
+
+ QList<QPlace> places;
+ places << place1 << place2;
+
+ request.setPlaces(places);
+ request.setParameters(params);
+
+ QPlaceMatchRequest copy(request);
+ QCOMPARE(copy, request);
+ QCOMPARE(copy.places(), places);
+ QCOMPARE(copy.parameters(), params);
+}
+
+void tst_QPlaceMatchRequest::placesTest()
+{
+ QPlaceMatchRequest request;
+ QCOMPARE(request.places().count(), 0);
+
+ QPlace place1;
+ place1.setName(QLatin1String("place1"));
+
+ QPlace place2;
+ place2.setName(QLatin1String("place2"));
+
+ QList<QPlace> places;
+ places << place1 << place2;
+
+ request.setPlaces(places);
+ QCOMPARE(request.places(), places);
+
+ request.setPlaces(QList<QPlace>());
+ QCOMPARE(request.places().count(), 0);
+}
+
+void tst_QPlaceMatchRequest::resultsTest()
+{
+ QPlaceMatchRequest request;
+ QCOMPARE(request.places().count(), 0);
+
+ QPlace place1;
+ place1.setName(QLatin1String("place1"));
+ QPlaceSearchResult result1;
+ result1.setPlace(place1);
+
+ QPlace place2;
+ place2.setName(QLatin1String("place2"));
+ QPlaceSearchResult result2;
+ result2.setPlace(place2);
+
+ QList<QPlaceSearchResult> results;
+ results << result1 << result2;
+
+ request.setResults(results);
+
+ QCOMPARE(request.places().count(), 2);
+ QCOMPARE(request.places().at(0), place1);
+ QCOMPARE(request.places().at(1), place2);
+
+ request.setResults(QList<QPlaceSearchResult>());
+ QCOMPARE(request.places().count(), 0);
+}
+
+void tst_QPlaceMatchRequest::parametersTest()
+{
+ QPlaceMatchRequest request;
+ QVERIFY(request.parameters().isEmpty());
+
+ QVariantMap params;
+ params.insert(QLatin1String("key"), QLatin1String("value"));
+
+ request.setParameters(params);
+ QCOMPARE(request.parameters(), params);
+}
+
+void tst_QPlaceMatchRequest::clearTest()
+{
+ QPlaceMatchRequest request;
+ QVariantMap params;
+ params.insert(QLatin1String("key"), QLatin1String("value"));
+
+ QPlace place1;
+ place1.setName(QLatin1String("place1"));
+
+ QPlace place2;
+ place2.setName(QLatin1String("place2"));
+
+ QList<QPlace> places;
+ places << place1 << place2;
+
+ request.setPlaces(places);
+ request.setParameters(params);
+
+ request.clear();
+ QVERIFY(request.places().isEmpty());
+ QVERIFY(request.parameters().isEmpty());
+}
+
+QTEST_APPLESS_MAIN(tst_QPlaceMatchRequest)
+
+#include "tst_qplacematchrequest.moc"