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 "qdeclarativegeoserviceprovider_p.h" |
38 | #include <QtQml/QQmlInfo> |
39 | #include <QtQml/QQmlEngine> |
40 | |
41 | QT_BEGIN_NAMESPACE |
42 | |
43 | /*! |
44 | \qmltype Plugin |
45 | //! \instantiates QDeclarativeGeoServiceProvider |
46 | \inqmlmodule QtLocation |
47 | \ingroup qml-QtLocation5-common |
48 | \since QtLocation 5.5 |
49 | |
50 | \brief The Plugin type describes a Location based services plugin. |
51 | |
52 | The Plugin type is used to declaratively specify which available |
53 | GeoServices plugin should be used for various tasks in the Location API. |
54 | Plugins are used by \l Map, \l RouteModel, and \l GeocodeModel |
55 | types, as well as a variety of others. |
56 | |
57 | Plugins recognized by the system have a \l name property, a simple string |
58 | normally indicating the name of the service that the Plugin retrieves |
59 | data from. They also have a variety of features, which can be test for using the |
60 | \l {supportsRouting()}, \l {supportsGeocoding()}, \l {supportsMapping()}, |
61 | \l {supportsPlaces()} and \l {supportsNavigation()} methods. |
62 | |
63 | When a Plugin object is created, it is "detached" and not associated with |
64 | any actual service plugin. Once it has received information via setting |
65 | its \l name, \l preferred, or \l required properties, it will choose an |
66 | appropriate service plugin to attach to. Plugin objects can only be |
67 | attached once; to use multiple plugins, create multiple Plugin objects. |
68 | |
69 | \section2 Example Usage |
70 | |
71 | The following snippet shows a Plugin object being created with the |
72 | \l required and \l preferred properties set. This Plugin will attach to the |
73 | first found plugin that supports both mapping and geocoding, and will |
74 | prefer plugins named "here" or "osm" to any others. |
75 | |
76 | \code |
77 | Plugin { |
78 | id: plugin |
79 | preferred: ["here", "osm"] |
80 | required: Plugin.AnyMappingFeatures | Plugin.AnyGeocodingFeatures |
81 | } |
82 | \endcode |
83 | */ |
84 | |
85 | QDeclarativeGeoServiceProvider::QDeclarativeGeoServiceProvider(QObject *parent) |
86 | : QObject(parent), |
87 | sharedProvider_(0), |
88 | required_(new QDeclarativeGeoServiceProviderRequirements), |
89 | complete_(false), |
90 | experimental_(false) |
91 | { |
92 | locales_.append(t: QLocale().name()); |
93 | } |
94 | |
95 | QDeclarativeGeoServiceProvider::~QDeclarativeGeoServiceProvider() |
96 | { |
97 | delete required_; |
98 | delete sharedProvider_; |
99 | } |
100 | |
101 | |
102 | |
103 | /*! |
104 | \qmlproperty string Plugin::name |
105 | |
106 | This property holds the name of the plugin. Setting this property |
107 | will cause the Plugin to only attach to a plugin with exactly this |
108 | name. The value of \l required will be ignored. |
109 | */ |
110 | void QDeclarativeGeoServiceProvider::setName(const QString &name) |
111 | { |
112 | if (name_ == name) |
113 | return; |
114 | |
115 | name_ = name; |
116 | |
117 | if (complete_) |
118 | tryAttach(); |
119 | |
120 | emit nameChanged(name: name_); |
121 | } |
122 | |
123 | /*! |
124 | \internal |
125 | */ |
126 | bool QDeclarativeGeoServiceProvider::parametersReady() { |
127 | for (const QDeclarativePluginParameter *p: qAsConst(t&: parameters_)) { |
128 | if (!p->isInitialized()) |
129 | return false; |
130 | } |
131 | return true; |
132 | } |
133 | |
134 | /*! |
135 | \internal |
136 | */ |
137 | void QDeclarativeGeoServiceProvider::tryAttach() |
138 | { |
139 | if (!parametersReady()) |
140 | return; |
141 | |
142 | delete sharedProvider_; |
143 | sharedProvider_ = nullptr; |
144 | |
145 | if (name_.isEmpty()) |
146 | return; |
147 | |
148 | sharedProvider_ = new QGeoServiceProvider(name_, parameterMap()); |
149 | sharedProvider_->setQmlEngine(qmlEngine(this)); |
150 | sharedProvider_->setLocale(locales_.at(i: 0)); |
151 | sharedProvider_->setAllowExperimental(experimental_); |
152 | |
153 | emit attached(); |
154 | } |
155 | |
156 | QString QDeclarativeGeoServiceProvider::name() const |
157 | { |
158 | return name_; |
159 | } |
160 | |
161 | |
162 | /*! |
163 | \qmlproperty stringlist Plugin::availableServiceProviders |
164 | |
165 | This property holds a list of all available service plugins' names. This |
166 | can be used to manually enumerate the available plugins if the |
167 | control provided by \l name and \l required is not sufficient for your |
168 | needs. |
169 | */ |
170 | QStringList QDeclarativeGeoServiceProvider::availableServiceProviders() |
171 | { |
172 | return QGeoServiceProvider::availableServiceProviders(); |
173 | } |
174 | |
175 | /*! |
176 | \internal |
177 | */ |
178 | void QDeclarativeGeoServiceProvider::componentComplete() |
179 | { |
180 | complete_ = true; |
181 | |
182 | for (QDeclarativePluginParameter *p: qAsConst(t&: parameters_)) { |
183 | if (!p->isInitialized()) { |
184 | connect(sender: p, signal: &QDeclarativePluginParameter::initialized, |
185 | receiver: this, slot: &QDeclarativeGeoServiceProvider::tryAttach); |
186 | } |
187 | } |
188 | |
189 | if (!name_.isEmpty()) { |
190 | tryAttach(); |
191 | } else if (!prefer_.isEmpty() |
192 | || required_->mappingRequirements() != NoMappingFeatures |
193 | || required_->routingRequirements() != NoRoutingFeatures |
194 | || required_->geocodingRequirements() != NoGeocodingFeatures |
195 | || required_->placesRequirements() != NoPlacesFeatures |
196 | || required_->navigationRequirements() != NoNavigationFeatures) { |
197 | |
198 | QStringList providers = QGeoServiceProvider::availableServiceProviders(); |
199 | |
200 | /* first check any preferred plugins */ |
201 | foreach (const QString &name, prefer_) { |
202 | if (providers.contains(str: name)) { |
203 | // so we don't try it again later |
204 | providers.removeAll(t: name); |
205 | |
206 | QGeoServiceProvider sp(name, parameterMap(), experimental_); |
207 | if (required_->matches(provider: &sp)) { |
208 | setName(name); |
209 | return; |
210 | } |
211 | } |
212 | } |
213 | |
214 | /* then try the rest */ |
215 | foreach (const QString &name, providers) { |
216 | QGeoServiceProvider sp(name, parameterMap(), experimental_); |
217 | if (required_->matches(provider: &sp)) { |
218 | setName(name); |
219 | return; |
220 | } |
221 | } |
222 | |
223 | qmlWarning(me: this) << "Could not find a plugin with the required features to attach to" ; |
224 | } |
225 | } |
226 | |
227 | /*! |
228 | \qmlmethod bool Plugin::supportsGeocoding(GeocodingFeatures features) |
229 | |
230 | This method returns a boolean indicating whether the specified set of \a features are supported |
231 | by the geo service provider plugin. \c True is returned if all specified \a features are |
232 | supported; otherwise \c false is returned. |
233 | |
234 | The \a features parameter can be any flag combination of: |
235 | \table |
236 | \header |
237 | \li Feature |
238 | \li Description |
239 | \row |
240 | \li Plugin.NoGeocodingFeatures |
241 | \li No geocoding features are supported. |
242 | \row |
243 | \li Plugin.OnlineGeocodingFeature |
244 | \li Online geocoding is supported. |
245 | \row |
246 | \li Plugin.OfflineGeocodingFeature |
247 | \li Offline geocoding is supported. |
248 | \row |
249 | \li Plugin.ReverseGeocodingFeature |
250 | \li Reverse geocoding is supported. |
251 | \row |
252 | \li Plugin.LocalizedGeocodingFeature |
253 | \li Supports returning geocoding results with localized addresses. |
254 | \row |
255 | \li Plugin.AnyGeocodingFeatures |
256 | \li Matches a geo service provider that provides any geocoding features. |
257 | \endtable |
258 | */ |
259 | bool QDeclarativeGeoServiceProvider::supportsGeocoding(const GeocodingFeatures &feature) const |
260 | { |
261 | QGeoServiceProvider *sp = sharedGeoServiceProvider(); |
262 | QGeoServiceProvider::GeocodingFeatures f = |
263 | static_cast<QGeoServiceProvider::GeocodingFeature>(int(feature)); |
264 | if (f == QGeoServiceProvider::AnyGeocodingFeatures) |
265 | return (sp && (sp->geocodingFeatures() != QGeoServiceProvider::NoGeocodingFeatures)); |
266 | else |
267 | return (sp && (sp->geocodingFeatures() & f) == f); |
268 | } |
269 | |
270 | /*! |
271 | \qmlmethod bool Plugin::supportsMapping(MappingFeatures features) |
272 | |
273 | This method returns a boolean indicating whether the specified set of \a features are supported |
274 | by the geo service provider plugin. True is returned if all specified \a features are |
275 | supported; otherwise false is returned. |
276 | |
277 | The \a features parameter can be any flag combination of: |
278 | \table |
279 | \header |
280 | \li Feature |
281 | \li Description |
282 | \row |
283 | \li Plugin.NoMappingFeatures |
284 | \li No mapping features are supported. |
285 | \row |
286 | \li Plugin.OnlineMappingFeature |
287 | \li Online mapping is supported. |
288 | \row |
289 | \li Plugin.OfflineMappingFeature |
290 | \li Offline mapping is supported. |
291 | \row |
292 | \li Plugin.LocalizedMappingFeature |
293 | \li Supports returning localized map data. |
294 | \row |
295 | \li Plugin.AnyMappingFeatures |
296 | \li Matches a geo service provider that provides any mapping features. |
297 | \endtable |
298 | */ |
299 | bool QDeclarativeGeoServiceProvider::supportsMapping(const MappingFeatures &feature) const |
300 | { |
301 | QGeoServiceProvider *sp = sharedGeoServiceProvider(); |
302 | QGeoServiceProvider::MappingFeatures f = |
303 | static_cast<QGeoServiceProvider::MappingFeature>(int(feature)); |
304 | if (f == QGeoServiceProvider::AnyMappingFeatures) |
305 | return (sp && (sp->mappingFeatures() != QGeoServiceProvider::NoMappingFeatures)); |
306 | else |
307 | return (sp && (sp->mappingFeatures() & f) == f); |
308 | } |
309 | |
310 | /*! |
311 | \qmlmethod bool Plugin::supportsRouting(RoutingFeatures features) |
312 | |
313 | This method returns a boolean indicating whether the specified set of \a features are supported |
314 | by the geo service provider plugin. True is returned if all specified \a features are |
315 | supported; otherwise false is returned. |
316 | |
317 | The \a features parameter can be any flag combination of: |
318 | \table |
319 | \header |
320 | \li Feature |
321 | \li Description |
322 | \row |
323 | \li Plugin.NoRoutingFeatures |
324 | \li No routing features are supported. |
325 | \row |
326 | \li Plugin.OnlineRoutingFeature |
327 | \li Online routing is supported. |
328 | \row |
329 | \li Plugin.OfflineRoutingFeature |
330 | \li Offline routing is supported. |
331 | \row |
332 | \li Plugin.LocalizedRoutingFeature |
333 | \li Supports returning routes with localized addresses and instructions. |
334 | \row |
335 | \li Plugin.RouteUpdatesFeature |
336 | \li Updating an existing route based on the current position is supported. |
337 | \row |
338 | \li Plugin.AlternativeRoutesFeature |
339 | \li Supports returning alternative routes. |
340 | \row |
341 | \li Plugin.ExcludeAreasRoutingFeature |
342 | \li Supports specifying a areas which the returned route must not cross. |
343 | \row |
344 | \li Plugin.AnyRoutingFeatures |
345 | \li Matches a geo service provider that provides any routing features. |
346 | \endtable |
347 | */ |
348 | bool QDeclarativeGeoServiceProvider::supportsRouting(const RoutingFeatures &feature) const |
349 | { |
350 | QGeoServiceProvider *sp = sharedGeoServiceProvider(); |
351 | QGeoServiceProvider::RoutingFeatures f = |
352 | static_cast<QGeoServiceProvider::RoutingFeature>(int(feature)); |
353 | if (f == QGeoServiceProvider::AnyRoutingFeatures) |
354 | return (sp && (sp->routingFeatures() != QGeoServiceProvider::NoRoutingFeatures)); |
355 | else |
356 | return (sp && (sp->routingFeatures() & f) == f); |
357 | } |
358 | |
359 | /*! |
360 | \qmlmethod bool Plugin::supportsPlaces(PlacesFeatures features) |
361 | |
362 | This method returns a boolean indicating whether the specified set of \a features are supported |
363 | by the geo service provider plugin. True is returned if all specified \a features are |
364 | supported; otherwise false is returned. |
365 | |
366 | The \a features parameter can be any flag combination of: |
367 | \table |
368 | \header |
369 | \li Feature |
370 | \li Description |
371 | \row |
372 | \li Plugin.NoPlacesFeatures |
373 | \li No places features are supported. |
374 | \row |
375 | \li Plugin.OnlinePlacesFeature |
376 | \li Online places is supported. |
377 | \row |
378 | \li Plugin.OfflinePlacesFeature |
379 | \li Offline places is supported. |
380 | \row |
381 | \li Plugin.SavePlaceFeature |
382 | \li Saving categories is supported. |
383 | \row |
384 | \li Plugin.RemovePlaceFeature |
385 | \li Removing or deleting places is supported. |
386 | \row |
387 | \li Plugin.PlaceRecommendationsFeature |
388 | \li Searching for recommended places similar to another place is supported. |
389 | \row |
390 | \li Plugin.SearchSuggestionsFeature |
391 | \li Search suggestions is supported. |
392 | \row |
393 | \li Plugin.LocalizedPlacesFeature |
394 | \li Supports returning localized place data. |
395 | \row |
396 | \li Plugin.NotificationsFeature |
397 | \li Notifications of place and category changes is supported. |
398 | \row |
399 | \li Plugin.PlaceMatchingFeature |
400 | \li Supports matching places from two different geo service providers. |
401 | \row |
402 | \li Plugin.AnyPlacesFeatures |
403 | \li Matches a geo service provider that provides any places features. |
404 | \endtable |
405 | */ |
406 | bool QDeclarativeGeoServiceProvider::supportsPlaces(const PlacesFeatures &feature) const |
407 | { |
408 | QGeoServiceProvider *sp = sharedGeoServiceProvider(); |
409 | QGeoServiceProvider::PlacesFeatures f = |
410 | static_cast<QGeoServiceProvider::PlacesFeature>(int(feature)); |
411 | if (f == QGeoServiceProvider::AnyPlacesFeatures) |
412 | return (sp && (sp->placesFeatures() != QGeoServiceProvider::NoPlacesFeatures)); |
413 | else |
414 | return (sp && (sp->placesFeatures() & f) == f); |
415 | } |
416 | |
417 | /*! |
418 | \qmlmethod bool Plugin::supportsNavigation(NavigationFeatures features) |
419 | |
420 | This method returns a boolean indicating whether the specified set of \a features are supported |
421 | by the geo service provider plugin. True is returned if all specified \a features are |
422 | supported; otherwise false is returned. |
423 | |
424 | The \a features parameter can be any flag combination of: |
425 | \table |
426 | \header |
427 | \li Feature |
428 | \li Description |
429 | \row |
430 | \li Plugin.NoNavigationFeatures |
431 | \li No navigation features are supported. |
432 | \row |
433 | \li Plugin.OnlineNavigationFeature |
434 | \li Online navigation is supported. |
435 | \row |
436 | \li Plugin.OfflineNavigationFeature |
437 | \li Offline navigation is supported. |
438 | \row |
439 | \li Plugin.AnyNavigationFeatures |
440 | \li Matches a geo service provider that provides any navigation features. |
441 | \endtable |
442 | */ |
443 | bool QDeclarativeGeoServiceProvider::supportsNavigation(const QDeclarativeGeoServiceProvider::NavigationFeature &feature) const |
444 | { |
445 | QGeoServiceProvider *sp = sharedGeoServiceProvider(); |
446 | QGeoServiceProvider::NavigationFeatures f = |
447 | static_cast<QGeoServiceProvider::NavigationFeature>(int(feature)); |
448 | if (f == QGeoServiceProvider::AnyNavigationFeatures) |
449 | return (sp && (sp->navigationFeatures() != QGeoServiceProvider::NoNavigationFeatures)); |
450 | else |
451 | return (sp && (sp->navigationFeatures() & f) == f); |
452 | } |
453 | |
454 | /*! |
455 | \qmlproperty enumeration Plugin::required |
456 | |
457 | This property contains the set of features that will be required by the |
458 | Plugin object when choosing which service plugin to attach to. If the |
459 | \l name property is set, this has no effect. |
460 | |
461 | Any of the following values or a bitwise combination of multiple values |
462 | may be set: |
463 | |
464 | \list |
465 | \li Plugin.NoFeatures |
466 | \li Plugin.GeocodingFeature |
467 | \li Plugin.ReverseGeocodingFeature |
468 | \li Plugin.RoutingFeature |
469 | \li Plugin.MappingFeature |
470 | \li Plugin.AnyPlacesFeature |
471 | \endlist |
472 | */ |
473 | QDeclarativeGeoServiceProviderRequirements *QDeclarativeGeoServiceProvider::requirements() const |
474 | { |
475 | return required_; |
476 | } |
477 | |
478 | void QDeclarativeGeoServiceProvider::setRequirements(QDeclarativeGeoServiceProviderRequirements *req) |
479 | { |
480 | if (!name().isEmpty() || !req) |
481 | return; |
482 | |
483 | if (required_ && *required_ == *req) |
484 | return; |
485 | |
486 | delete required_; |
487 | required_ = req; |
488 | QQmlEngine::setObjectOwnership(req, QQmlEngine::CppOwnership); // To prevent the engine from making this object disappear |
489 | } |
490 | |
491 | /*! |
492 | \qmlproperty stringlist Plugin::preferred |
493 | |
494 | This property contains an ordered list of preferred plugin names, which |
495 | will be checked for the required features set in \l{Plugin::required}{required} |
496 | before any other available plugins are checked. |
497 | */ |
498 | QStringList QDeclarativeGeoServiceProvider::preferred() const |
499 | { |
500 | return prefer_; |
501 | } |
502 | |
503 | void QDeclarativeGeoServiceProvider::setPreferred(const QStringList &val) |
504 | { |
505 | prefer_ = val; |
506 | emit preferredChanged(preferences: prefer_); |
507 | } |
508 | |
509 | /*! |
510 | \qmlproperty bool Plugin::isAttached |
511 | |
512 | This property indicates if the Plugin item is attached to a geoservice provider plugin. |
513 | */ |
514 | bool QDeclarativeGeoServiceProvider::isAttached() const |
515 | { |
516 | return (sharedProvider_ != 0); |
517 | } |
518 | |
519 | /*! |
520 | \qmlproperty bool Plugin::allowExperimental |
521 | |
522 | This property indicates if experimental plugins can be used. |
523 | */ |
524 | bool QDeclarativeGeoServiceProvider::allowExperimental() const |
525 | { |
526 | return experimental_; |
527 | } |
528 | |
529 | void QDeclarativeGeoServiceProvider::setAllowExperimental(bool allow) |
530 | { |
531 | if (experimental_ == allow) |
532 | return; |
533 | |
534 | experimental_ = allow; |
535 | if (sharedProvider_) |
536 | sharedProvider_->setAllowExperimental(allow); |
537 | |
538 | emit allowExperimentalChanged(allow); |
539 | } |
540 | |
541 | /*! |
542 | \internal |
543 | */ |
544 | QGeoServiceProvider *QDeclarativeGeoServiceProvider::sharedGeoServiceProvider() const |
545 | { |
546 | return sharedProvider_; |
547 | } |
548 | |
549 | /*! |
550 | \qmlproperty stringlist Plugin::locales |
551 | |
552 | This property contains an ordered list of preferred plugin locales. If the first locale cannot be accommodated, then |
553 | the backend falls back to using the second, and so on. By default the locales property contains the system locale. |
554 | |
555 | The locales are specified as strings which have the format |
556 | "language[_script][_country]" or "C", where: |
557 | |
558 | \list |
559 | \li language is a lowercase, two-letter, ISO 639 language code, |
560 | \li script is a titlecase, four-letter, ISO 15924 script code, |
561 | \li country is an uppercase, two- or three-letter, ISO 3166 country code (also "419" as defined by United Nations), |
562 | \li the "C" locale is identical in behavior to English/UnitedStates as per QLocale |
563 | \endlist |
564 | |
565 | If the first specified locale cannot be accommodated, the \l {Plugin} falls back to the next and so forth. |
566 | Some \l {Plugin} backends may not support a set of locales which are rigidly defined. An arbitrary |
567 | example is that some \l {Place}'s in France could have French and English localizations, while |
568 | certain areas in America may only have the English localization available. In the above scenario, |
569 | the set of supported locales is context dependent on the search location. |
570 | |
571 | If the \l {Plugin} cannot accommodate any of the preferred locales, the manager falls |
572 | back to using a supported language that is backend specific. |
573 | |
574 | For \l {Plugin}'s that do not support locales, the locales list is always empty. |
575 | |
576 | The following code demonstrates how to set a single and multiple locales: |
577 | \snippet declarative/plugin.qml Plugin locale |
578 | */ |
579 | QStringList QDeclarativeGeoServiceProvider::locales() const |
580 | { |
581 | return locales_; |
582 | } |
583 | |
584 | void QDeclarativeGeoServiceProvider::setLocales(const QStringList &locales) |
585 | { |
586 | if (locales_ == locales) |
587 | return; |
588 | |
589 | locales_ = locales; |
590 | |
591 | if (locales_.isEmpty()) |
592 | locales_.append(t: QLocale().name()); |
593 | |
594 | if (sharedProvider_) |
595 | sharedProvider_->setLocale(locales_.at(i: 0)); |
596 | |
597 | emit localesChanged(); |
598 | } |
599 | |
600 | /*! |
601 | \qmlproperty list<PluginParameter> Plugin::parameters |
602 | \default |
603 | |
604 | This property holds the list of plugin parameters. |
605 | */ |
606 | QQmlListProperty<QDeclarativePluginParameter> QDeclarativeGeoServiceProvider::parameters() |
607 | { |
608 | return QQmlListProperty<QDeclarativePluginParameter>(this, |
609 | 0, |
610 | parameter_append, |
611 | parameter_count, |
612 | parameter_at, |
613 | parameter_clear); |
614 | } |
615 | |
616 | /*! |
617 | \internal |
618 | */ |
619 | void QDeclarativeGeoServiceProvider::parameter_append(QQmlListProperty<QDeclarativePluginParameter> *prop, QDeclarativePluginParameter *parameter) |
620 | { |
621 | QDeclarativeGeoServiceProvider *p = static_cast<QDeclarativeGeoServiceProvider *>(prop->object); |
622 | p->parameters_.append(t: parameter); |
623 | if (p->sharedProvider_) |
624 | p->sharedProvider_->setParameters(p->parameterMap()); |
625 | } |
626 | |
627 | /*! |
628 | \internal |
629 | */ |
630 | int QDeclarativeGeoServiceProvider::parameter_count(QQmlListProperty<QDeclarativePluginParameter> *prop) |
631 | { |
632 | return static_cast<QDeclarativeGeoServiceProvider *>(prop->object)->parameters_.count(); |
633 | } |
634 | |
635 | /*! |
636 | \internal |
637 | */ |
638 | QDeclarativePluginParameter *QDeclarativeGeoServiceProvider::parameter_at(QQmlListProperty<QDeclarativePluginParameter> *prop, int index) |
639 | { |
640 | return static_cast<QDeclarativeGeoServiceProvider *>(prop->object)->parameters_[index]; |
641 | } |
642 | |
643 | /*! |
644 | \internal |
645 | */ |
646 | void QDeclarativeGeoServiceProvider::parameter_clear(QQmlListProperty<QDeclarativePluginParameter> *prop) |
647 | { |
648 | QDeclarativeGeoServiceProvider *p = static_cast<QDeclarativeGeoServiceProvider *>(prop->object); |
649 | p->parameters_.clear(); |
650 | if (p->sharedProvider_) |
651 | p->sharedProvider_->setParameters(p->parameterMap()); |
652 | } |
653 | |
654 | /*! |
655 | \internal |
656 | */ |
657 | QVariantMap QDeclarativeGeoServiceProvider::parameterMap() const |
658 | { |
659 | QVariantMap map; |
660 | |
661 | for (int i = 0; i < parameters_.size(); ++i) { |
662 | QDeclarativePluginParameter *parameter = parameters_.at(i); |
663 | map.insert(akey: parameter->name(), avalue: parameter->value()); |
664 | } |
665 | |
666 | return map; |
667 | } |
668 | |
669 | /******************************************************************************* |
670 | *******************************************************************************/ |
671 | |
672 | QDeclarativeGeoServiceProviderRequirements::QDeclarativeGeoServiceProviderRequirements(QObject *parent) |
673 | : QObject(parent), |
674 | mapping_(QDeclarativeGeoServiceProvider::NoMappingFeatures), |
675 | routing_(QDeclarativeGeoServiceProvider::NoRoutingFeatures), |
676 | geocoding_(QDeclarativeGeoServiceProvider::NoGeocodingFeatures), |
677 | places_(QDeclarativeGeoServiceProvider::NoPlacesFeatures), |
678 | navigation_(QDeclarativeGeoServiceProvider::NoNavigationFeatures) |
679 | { |
680 | } |
681 | |
682 | QDeclarativeGeoServiceProviderRequirements::~QDeclarativeGeoServiceProviderRequirements() |
683 | { |
684 | } |
685 | |
686 | /*! |
687 | \internal |
688 | */ |
689 | QDeclarativeGeoServiceProvider::MappingFeatures QDeclarativeGeoServiceProviderRequirements::mappingRequirements() const |
690 | { |
691 | return mapping_; |
692 | } |
693 | |
694 | /*! |
695 | \internal |
696 | */ |
697 | void QDeclarativeGeoServiceProviderRequirements::setMappingRequirements(const QDeclarativeGeoServiceProvider::MappingFeatures &features) |
698 | { |
699 | if (mapping_ == features) |
700 | return; |
701 | |
702 | mapping_ = features; |
703 | emit mappingRequirementsChanged(features: mapping_); |
704 | emit requirementsChanged(); |
705 | } |
706 | |
707 | /*! |
708 | \internal |
709 | */ |
710 | QDeclarativeGeoServiceProvider::RoutingFeatures QDeclarativeGeoServiceProviderRequirements::routingRequirements() const |
711 | { |
712 | return routing_; |
713 | } |
714 | |
715 | /*! |
716 | \internal |
717 | */ |
718 | void QDeclarativeGeoServiceProviderRequirements::setRoutingRequirements(const QDeclarativeGeoServiceProvider::RoutingFeatures &features) |
719 | { |
720 | if (routing_ == features) |
721 | return; |
722 | |
723 | routing_ = features; |
724 | emit routingRequirementsChanged(features: routing_); |
725 | emit requirementsChanged(); |
726 | } |
727 | |
728 | /*! |
729 | \internal |
730 | */ |
731 | QDeclarativeGeoServiceProvider::GeocodingFeatures QDeclarativeGeoServiceProviderRequirements::geocodingRequirements() const |
732 | { |
733 | return geocoding_; |
734 | } |
735 | |
736 | /*! |
737 | \internal |
738 | */ |
739 | void QDeclarativeGeoServiceProviderRequirements::setGeocodingRequirements(const QDeclarativeGeoServiceProvider::GeocodingFeatures &features) |
740 | { |
741 | if (geocoding_ == features) |
742 | return; |
743 | |
744 | geocoding_ = features; |
745 | emit geocodingRequirementsChanged(features: geocoding_); |
746 | emit requirementsChanged(); |
747 | } |
748 | |
749 | /*! |
750 | \internal |
751 | |
752 | */ |
753 | QDeclarativeGeoServiceProvider::PlacesFeatures QDeclarativeGeoServiceProviderRequirements::placesRequirements() const |
754 | { |
755 | return places_; |
756 | } |
757 | |
758 | /*! |
759 | \internal |
760 | */ |
761 | void QDeclarativeGeoServiceProviderRequirements::setPlacesRequirements(const QDeclarativeGeoServiceProvider::PlacesFeatures &features) |
762 | { |
763 | if (places_ == features) |
764 | return; |
765 | |
766 | places_ = features; |
767 | emit placesRequirementsChanged(features: places_); |
768 | emit requirementsChanged(); |
769 | } |
770 | |
771 | /*! |
772 | \internal |
773 | */ |
774 | QDeclarativeGeoServiceProvider::NavigationFeatures QDeclarativeGeoServiceProviderRequirements::navigationRequirements() const |
775 | { |
776 | return navigation_; |
777 | } |
778 | |
779 | /*! |
780 | \internal |
781 | */ |
782 | void QDeclarativeGeoServiceProviderRequirements::setNavigationRequirements(const QDeclarativeGeoServiceProvider::NavigationFeatures &features) |
783 | { |
784 | if (navigation_ == features) |
785 | return; |
786 | |
787 | navigation_ = features; |
788 | emit navigationRequirementsChanged(features: navigation_); |
789 | emit requirementsChanged(); |
790 | } |
791 | |
792 | /*! |
793 | \internal |
794 | */ |
795 | bool QDeclarativeGeoServiceProviderRequirements::matches(const QGeoServiceProvider *provider) const |
796 | { |
797 | QGeoServiceProvider::MappingFeatures mapping = |
798 | static_cast<QGeoServiceProvider::MappingFeatures>(int(mapping_)); |
799 | |
800 | // extra curlies here to avoid "dangling" else, which could belong to either if |
801 | // same goes for all the rest of these blocks |
802 | if (mapping == QGeoServiceProvider::AnyMappingFeatures) { |
803 | if (provider->mappingFeatures() == QGeoServiceProvider::NoMappingFeatures) |
804 | return false; |
805 | } else { |
806 | if ((provider->mappingFeatures() & mapping) != mapping) |
807 | return false; |
808 | } |
809 | |
810 | QGeoServiceProvider::RoutingFeatures routing = |
811 | static_cast<QGeoServiceProvider::RoutingFeatures>(int(routing_)); |
812 | |
813 | if (routing == QGeoServiceProvider::AnyRoutingFeatures) { |
814 | if (provider->routingFeatures() == QGeoServiceProvider::NoRoutingFeatures) |
815 | return false; |
816 | } else { |
817 | if ((provider->routingFeatures() & routing) != routing) |
818 | return false; |
819 | } |
820 | |
821 | QGeoServiceProvider::GeocodingFeatures geocoding = |
822 | static_cast<QGeoServiceProvider::GeocodingFeatures>(int(geocoding_)); |
823 | |
824 | if (geocoding == QGeoServiceProvider::AnyGeocodingFeatures) { |
825 | if (provider->geocodingFeatures() == QGeoServiceProvider::NoGeocodingFeatures) |
826 | return false; |
827 | } else { |
828 | if ((provider->geocodingFeatures() & geocoding) != geocoding) |
829 | return false; |
830 | } |
831 | |
832 | QGeoServiceProvider::PlacesFeatures places = |
833 | static_cast<QGeoServiceProvider::PlacesFeatures>(int(places_)); |
834 | |
835 | if (places == QGeoServiceProvider::AnyPlacesFeatures) { |
836 | if (provider->placesFeatures() == QGeoServiceProvider::NoPlacesFeatures) |
837 | return false; |
838 | } else { |
839 | if ((provider->placesFeatures() & places) != places) |
840 | return false; |
841 | } |
842 | |
843 | QGeoServiceProvider::NavigationFeatures navigation = |
844 | static_cast<QGeoServiceProvider::NavigationFeatures>(int(navigation_)); |
845 | |
846 | if (navigation == QGeoServiceProvider::AnyNavigationFeatures) { |
847 | if (provider->navigationFeatures() == QGeoServiceProvider::NoNavigationFeatures) |
848 | return false; |
849 | } else { |
850 | if ((provider->navigationFeatures() & navigation) != navigation) |
851 | return false; |
852 | } |
853 | |
854 | return true; |
855 | } |
856 | |
857 | bool QDeclarativeGeoServiceProviderRequirements::operator == (const QDeclarativeGeoServiceProviderRequirements &rhs) const |
858 | { |
859 | return (mapping_ == rhs.mapping_ && routing_ == rhs.routing_ |
860 | && geocoding_ == rhs.geocoding_ && places_ == rhs.places_ |
861 | && navigation_ == rhs.navigation_); |
862 | } |
863 | |
864 | /******************************************************************************* |
865 | *******************************************************************************/ |
866 | |
867 | /*! |
868 | \qmltype PluginParameter |
869 | //! \instantiates QDeclarativePluginParameter |
870 | \inqmlmodule QtLocation |
871 | \ingroup qml-QtLocation5-common |
872 | \since QtLocation 5.5 |
873 | |
874 | \brief The PluginParameter type describes a parameter for a plugin, either |
875 | geo service \l Plugin, or \l{Qt Positioning plugins}{position Plugin}. |
876 | |
877 | The PluginParameter object is used to provide a parameter of some kind |
878 | to a plugin. Typically these parameters contain details like an application |
879 | token for access to a service, or a proxy server to use for network access, |
880 | or the serial port to which a serial GPS receiver is connected. |
881 | |
882 | To set such a parameter, declare a PluginParameter inside an element that accepts |
883 | plugin parameters as configuration objects, such as a \l Plugin object, or a |
884 | \l PositionSource object, and give it \l{name} and \l{value} properties. A list of valid |
885 | parameter names for each plugin is available from the |
886 | \l {Qt Location#Plugin References and Parameters}{plugin reference pages} for geoservice plugins, |
887 | and \l {Qt Positioning plugins#Default plugins} for position plugins. |
888 | |
889 | \section2 Example Usage |
890 | |
891 | The following example shows an instantiation of the \l {Qt Location HERE Plugin}{HERE} plugin |
892 | with a mapping API \e app_id and \e token pair specific to the application. |
893 | |
894 | \code |
895 | Plugin { |
896 | name: "here" |
897 | PluginParameter { name: "here.app_id"; value: "EXAMPLE_API_ID" } |
898 | PluginParameter { name: "here.token"; value: "EXAMPLE_TOKEN_123" } |
899 | } |
900 | \endcode |
901 | */ |
902 | |
903 | /*! |
904 | \qmlproperty string PluginParameter::name |
905 | |
906 | This property holds the name of the plugin parameter as a single formatted string. |
907 | This property is a write-once property. |
908 | */ |
909 | |
910 | /*! |
911 | \qmlproperty QVariant PluginParameter::value |
912 | |
913 | This property holds the value of the plugin parameter which support different types of values (variant). |
914 | This property is a write-once property. |
915 | */ |
916 | |
917 | /******************************************************************************* |
918 | * Implementation now in positioningquick |
919 | *******************************************************************************/ |
920 | |
921 | QT_END_NAMESPACE |
922 | |
923 | |