1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtLocation module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qplacemanager.h"
38#include "qplacemanagerengine.h"
39#include "qplacemanagerengine_p.h"
40
41#include <QtCore/QDebug>
42
43QT_BEGIN_NAMESPACE
44
45/*!
46 \class QPlaceManager
47 \inmodule QtLocation
48 \ingroup QtLocation-places
49 \ingroup QtLocation-places-manager
50 \since 5.6
51
52 \brief The QPlaceManager class provides the interface which allows clients to access
53 places stored in a particular backend.
54
55 The following table gives an overview of the functionality provided by the QPlaceManager
56 \table
57 \header
58 \li Functionality
59 \li Description
60 \row
61 \li Searching for places
62 \li Using set of parameters such as a search term and search area, relevant places
63 can be returned to the user.
64 \row
65 \li Categories
66 \li Places can be classified as belonging to different categories. The
67 manager supports access to these categories.
68 \row
69 \li Search term suggestions
70 \li Given a partially complete search term, a list of potential
71 search terms can be given.
72 \row
73 \li Recommendations
74 \li Given an existing place, a set of similar recommended places can
75 be suggested to the user.
76 \row
77 \li Rich Content
78 \li Rich content such as images, reviews etc can be retrieved in a paged
79 fashion.
80 \row
81 \li Place or Category management
82 \li Places and categories may be saved and removed. It is possible
83 for notifications to be given when this happens.
84 \row
85 \li Localization
86 \li Different locales may be specified to return place
87 data in different languages.
88 \endtable
89
90 \section1 Obtaining a QPlaceManager Instance
91 Creation of a QPlaceManager is facilitated by the QGeoServiceProvider.
92 See \l {Initializing a manager} for an example on how to create a manager.
93
94
95 \section1 Asynchronous Interface
96 The QPlaceManager class provides an abstraction of the datastore which contains place information.
97 The functions provided by the QPlaceManager and primarily asynchronous and follow
98 a request-reply model. Typically a request is given to the manager, consisting
99 of a various set of parameters and a reply object is created. The reply object
100 has a signal to notify when the request is done, and once completed, the reply
101 contains the results of the request, along with any errors that occurred, if any.
102
103 An asynchronous request is generally handled as follows:
104 \snippet places/requesthandler.h Simple search
105 \dots
106 \dots
107 \snippet places/requesthandler.h Simple search handler
108
109 See \l {Common Operations} for a list of examples demonstrating how the QPlaceManger
110 is used.
111
112 \section1 Category Initialization
113 Sometime during startup of an application, the initializeCategories() function should
114 be called to setup the categories. Initializing the categories enables the usage of the
115 following functions:
116
117 \list
118 \li QPlaceManager::childCategories()
119 \li QPlaceManager::category()
120 \li QPlaceManager::parentCategoryId()
121 \li QPlaceManager::childCategoryIds();
122 \endlist
123
124 If the categories need to be refreshed or reloaded, the initializeCategories() function
125 may be called again.
126
127*/
128
129/*!
130 Constructs a new manager with the specified \a parent and with the
131 implementation provided by \a engine.
132
133 This constructor is used internally by QGeoServiceProviderFactory. Regular
134 users should acquire instances of QGeoRoutingManager with
135 QGeoServiceProvider::routingManager();
136*/
137QPlaceManager::QPlaceManager(QPlaceManagerEngine *engine, QObject *parent)
138 : QObject(parent), d(engine)
139{
140 if (d) {
141 d->setParent(this);
142 d->d_ptr->manager = this;
143
144 qRegisterMetaType<QPlaceCategory>();
145
146 connect(sender: d, SIGNAL(finished(QPlaceReply*)), receiver: this, SIGNAL(finished(QPlaceReply*)));
147 connect(sender: d, SIGNAL(error(QPlaceReply*,QPlaceReply::Error)),
148 receiver: this, SIGNAL(error(QPlaceReply*,QPlaceReply::Error)));
149
150 connect(sender: d, SIGNAL(placeAdded(QString)),
151 receiver: this, SIGNAL(placeAdded(QString)), Qt::QueuedConnection);
152 connect(sender: d, SIGNAL(placeUpdated(QString)),
153 receiver: this, SIGNAL(placeUpdated(QString)), Qt::QueuedConnection);
154 connect(sender: d, SIGNAL(placeRemoved(QString)),
155 receiver: this, SIGNAL(placeRemoved(QString)), Qt::QueuedConnection);
156
157 connect(sender: d, SIGNAL(categoryAdded(QPlaceCategory,QString)),
158 receiver: this, SIGNAL(categoryAdded(QPlaceCategory,QString)));
159 connect(sender: d, SIGNAL(categoryUpdated(QPlaceCategory,QString)),
160 receiver: this, SIGNAL(categoryUpdated(QPlaceCategory,QString)));
161 connect(sender: d, SIGNAL(categoryRemoved(QString,QString)),
162 receiver: this, SIGNAL(categoryRemoved(QString,QString)));
163 connect(sender: d, SIGNAL(dataChanged()),
164 receiver: this, SIGNAL(dataChanged()), Qt::QueuedConnection);
165 } else {
166 qFatal(msg: "The place manager engine that was set for this place manager was NULL.");
167 }
168}
169
170/*!
171 Destroys the manager. This destructor is used internally by QGeoServiceProvider
172 and should never need to be called in application code.
173*/
174QPlaceManager::~QPlaceManager()
175{
176 delete d;
177}
178
179/*!
180 Returns the name of the manager
181*/
182QString QPlaceManager::managerName() const
183{
184 return d->managerName();
185}
186
187/*!
188 Returns the manager version.
189*/
190int QPlaceManager::managerVersion() const
191{
192 return d->managerVersion();
193}
194
195/*!
196 Retrieves a details of place corresponding to the given \a placeId.
197
198 See \l {QML Places API#Fetching Place Details}{Fetching Place Details} for an example of usage.
199*/
200QPlaceDetailsReply *QPlaceManager::getPlaceDetails(const QString &placeId) const
201{
202 return d->getPlaceDetails(placeId);
203}
204
205/*!
206 Retrieves content for a place according to the parameters specified in \a request.
207
208 See \l {Fetching Rich Content} for an example of usage.
209*/
210QPlaceContentReply *QPlaceManager::getPlaceContent(const QPlaceContentRequest &request) const
211{
212 return d->getPlaceContent(request);
213}
214
215/*!
216 Searches for places according to the parameters specified in \a request.
217
218 See \l {Discovery/Search} for an example of usage.
219*/
220QPlaceSearchReply *QPlaceManager::search(const QPlaceSearchRequest &request) const
221{
222 return d->search(request);
223}
224
225/*!
226 Requests a set of search term suggestions according to the parameters specified in \a request.
227 The \a request can hold the incomplete search term, along with other data such
228 as a search area to narrow down relevant results.
229
230 See \l {Search Suggestions} for an example of usage.
231*/
232QPlaceSearchSuggestionReply *QPlaceManager::searchSuggestions(const QPlaceSearchRequest &request) const
233{
234 return d->searchSuggestions(request);
235}
236
237/*!
238 Saves a specified \a place.
239
240 See \l {Saving a place cpp} for an example of usage.
241*/
242QPlaceIdReply *QPlaceManager::savePlace(const QPlace &place)
243{
244 return d->savePlace(place);
245}
246
247/*!
248 Removes the place corresponding to \a placeId from the manager.
249
250 See \l {Removing a place cpp} for an example of usage.
251*/
252QPlaceIdReply *QPlaceManager::removePlace(const QString &placeId)
253{
254 return d->removePlace(placeId);
255}
256
257/*!
258 Saves a \a category that is a child of the category specified by \a parentId.
259 An empty \a parentId means \a category is saved as a top level category.
260
261 See \l {Saving a category} for an example of usage.
262*/
263QPlaceIdReply *QPlaceManager::saveCategory(const QPlaceCategory &category, const QString &parentId)
264{
265 return d->saveCategory(category, parentId);
266}
267
268/*!
269 Removes the category corresponding to \a categoryId from the manager.
270
271 See \l {Removing a category} for an example of usage.
272*/
273QPlaceIdReply *QPlaceManager::removeCategory(const QString &categoryId)
274{
275 return d->removeCategory(categoryId);
276}
277
278/*!
279 Initializes the categories of the manager.
280
281 See \l {Using Categories} for an example of usage.
282*/
283QPlaceReply *QPlaceManager::initializeCategories()
284{
285 return d->initializeCategories();
286}
287
288/*!
289 Returns the parent category identifier of the category corresponding to \a categoryId.
290*/
291QString QPlaceManager::parentCategoryId(const QString &categoryId) const
292{
293 return d->parentCategoryId(categoryId);
294}
295
296/*!
297 Returns the child category identifiers of the category corresponding to \a parentId.
298 If \a parentId is empty then all top level category identifiers are returned.
299*/
300QStringList QPlaceManager::childCategoryIds(const QString &parentId) const
301{
302 return d->childCategoryIds(categoryId: parentId);
303}
304
305/*!
306 Returns the category corresponding to the given \a categoryId.
307*/
308QPlaceCategory QPlaceManager::category(const QString &categoryId) const
309{
310 return d->category(categoryId);
311}
312
313/*!
314 Returns a list of categories that are children of the category corresponding to \a parentId.
315 If \a parentId is empty, all the top level categories are returned.
316*/
317QList<QPlaceCategory> QPlaceManager::childCategories(const QString &parentId) const
318{
319 return d->childCategories(parentId);
320}
321
322/*!
323 Returns a list of preferred locales. The locales are used as a hint to the manager for what language
324 place and category details should be returned in.
325
326 If the first specified locale cannot be accommodated, the manager falls back to the next and so forth.
327 Some manager backends may not support a set of locales which are rigidly defined. An arbitrary
328 example is that some places in France could have French and English localizations, while
329 certain areas in America may only have the English localization available. In this example,
330 the set of supported locales is context dependent on the search location.
331
332 If the manager cannot accommodate any of the preferred locales, the manager falls
333 back to using a supported language that is backend specific.
334
335 Support for locales may vary from provider to provider. For those that do support it,
336 by default, the global default locale is set as the manager's only locale.
337
338 For managers that do not support locales, the locale list is always empty.
339*/
340QList<QLocale> QPlaceManager::locales() const
341{
342 return d->locales();
343}
344
345/*!
346 Convenience function which sets the manager's list of preferred locales
347 to a single \a locale.
348*/
349void QPlaceManager::setLocale(const QLocale &locale)
350{
351 QList<QLocale> locales;
352 locales << locale;
353 d->setLocales(locales);
354}
355
356/*!
357 Set the list of preferred \a locales.
358*/
359void QPlaceManager::setLocales(const QList<QLocale> &locales)
360{
361 d->setLocales(locales);
362}
363
364/*!
365 Returns a pruned or modified version of the \a original place
366 which is suitable to be saved into this manager.
367
368 Only place details that are supported by this manager is
369 present in the modified version. Manager specific data such
370 as the place id, is not copied over from the \a original.
371*/
372QPlace QPlaceManager::compatiblePlace(const QPlace &original)
373{
374 return d->compatiblePlace(original);
375}
376
377/*!
378 Returns a reply which contains a list of places which correspond/match those
379 specified in the \a request. The places specified in the request come from a
380 different manager.
381*/
382QPlaceMatchReply *QPlaceManager::matchingPlaces(const QPlaceMatchRequest &request) const
383{
384 return d->matchingPlaces(request);
385}
386
387/*!
388 \fn void QPlaceManager::finished(QPlaceReply *reply)
389
390 This signal is emitted when \a reply has finished processing.
391
392 If reply->error() equals QPlaceReply::NoError then the processing
393 finished successfully.
394
395 This signal and QPlaceReply::finished() will be emitted at the same time.
396
397 \note Do not delete the \a reply object in the slot connected to this signal.
398 Use deleteLater() instead.
399*/
400
401/*!
402 \fn void QPlaceManager::error(QPlaceReply *reply, QPlaceReply::Error error, const QString &errorString)
403
404 This signal is emitted when an error has been detected in the processing of
405 \a reply. The QPlaceManager::finished() signal will probably follow.
406
407 The error will be described by the error code \a error. If \a errorString is
408 not empty it will contain a textual description of the error meant for developers
409 and not end users.
410
411 This signal and QPlaceReply::error() will be emitted at the same time.
412
413 \note Do not delete the \a reply object in the slot connected to this signal.
414 Use deleteLater() instead.
415*/
416
417/*!
418 \fn void QPlaceManager::placeAdded(const QString &placeId)
419
420 This signal is emitted if a place has been added to the manager engine's datastore.
421 The particular added place is specified by \a placeId.
422
423 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
424 \sa dataChanged()
425*/
426
427/*!
428 \fn void QPlaceManager::placeUpdated(const QString &placeId)
429
430 This signal is emitted if a place has been modified in the manager's datastore.
431 The particular modified place is specified by \a placeId.
432
433 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
434 \sa dataChanged()
435*/
436
437/*!
438 \fn void QPlaceManager::placeRemoved(const QString &placeId)
439
440 This signal is emitted if a place has been removed from the manager's datastore.
441 The particular place that has been removed is specified by \a placeId.
442
443 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
444 \sa dataChanged()
445*/
446
447/*!
448 \fn void QPlaceManager::categoryAdded(const QPlaceCategory &category, const QString &parentId)
449
450 This signal is emitted if a \a category has been added to the manager's datastore.
451 The parent of the \a category is specified by \a parentId.
452
453 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
454 \sa dataChanged()
455*/
456
457/*!
458 \fn void QPlaceManager::categoryUpdated(const QPlaceCategory &category, const QString &parentId)
459
460 This signal is emitted if a \a category has been modified in the manager's datastore.
461 The parent of the modified category is specified by \a parentId.
462
463 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
464 \sa dataChanged()
465*/
466
467/*!
468 \fn void QPlaceManager::categoryRemoved(const QString &categoryId, const QString &parentId)
469
470 This signal is emitted when the category corresponding to \a categoryId has
471 been removed from the manager's datastore. The parent of the removed category
472 is specified by \a parentId.
473
474 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
475 \sa dataChanged()
476*/
477
478/*!
479 \fn QPlaceManager::dataChanged()
480 This signal is emitted by the manager if there are large scale changes to its
481 underlying datastore and the manager considers these changes radical enough
482 to require clients to reload all data.
483
484 If the signal is emitted, no other signals will be emitted for the associated changes.
485
486 This signal is only emitted by managers that support the QPlaceManager::NotificationsFeature.
487*/
488
489QT_END_NAMESPACE
490

source code of qtlocation/src/location/places/qplacemanager.cpp