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 | |
43 | QT_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 | */ |
137 | QPlaceManager::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 | */ |
174 | QPlaceManager::~QPlaceManager() |
175 | { |
176 | delete d; |
177 | } |
178 | |
179 | /*! |
180 | Returns the name of the manager |
181 | */ |
182 | QString QPlaceManager::managerName() const |
183 | { |
184 | return d->managerName(); |
185 | } |
186 | |
187 | /*! |
188 | Returns the manager version. |
189 | */ |
190 | int 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 | */ |
200 | QPlaceDetailsReply *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 | */ |
210 | QPlaceContentReply *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 | */ |
220 | QPlaceSearchReply *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 | */ |
232 | QPlaceSearchSuggestionReply *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 | */ |
242 | QPlaceIdReply *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 | */ |
252 | QPlaceIdReply *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 | */ |
263 | QPlaceIdReply *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 | */ |
273 | QPlaceIdReply *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 | */ |
283 | QPlaceReply *QPlaceManager::initializeCategories() |
284 | { |
285 | return d->initializeCategories(); |
286 | } |
287 | |
288 | /*! |
289 | Returns the parent category identifier of the category corresponding to \a categoryId. |
290 | */ |
291 | QString 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 | */ |
300 | QStringList 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 | */ |
308 | QPlaceCategory 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 | */ |
317 | QList<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 | */ |
340 | QList<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 | */ |
349 | void 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 | */ |
359 | void 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 | */ |
372 | QPlace 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 | */ |
382 | QPlaceMatchReply *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 | |
489 | QT_END_NAMESPACE |
490 | |