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 "qplace.h"
38#include "qplace_p.h"
39
40#ifdef QPLACE_DEBUG
41#include <QDebug>
42#endif
43
44#include <QStringList>
45
46QT_BEGIN_NAMESPACE
47
48template<>
49QPlacePrivate *QSharedDataPointer<QPlacePrivate>::clone()
50{
51 return d->clone();
52}
53
54/*!
55 \class QPlace
56 \inmodule QtLocation
57 \ingroup QtLocation-places
58 \ingroup QtLocation-places-data
59 \since 5.6
60
61 \brief The QPlace class represents a set of data about a place.
62
63 \input place-definition.qdocinc
64
65 \section2 Contact Information
66 The contact information of a place is based around a common set of
67 \l {Contact Types}{contact types}. To retrieve all the phone numbers
68 of a place, one would do:
69
70 \snippet places/requesthandler.h Phone numbers
71
72 The contact types are string values by design to allow for providers
73 to introduce new contact types.
74
75 For convenience there are a set of functions which return the value
76 of the first contact detail of each type.
77 \list
78 \li QPlace::primaryPhone()
79 \li QPlace::primaryEmail()
80 \li QPlace::primaryWebsite()
81 \li QPlace::primaryFax()
82 \endlist
83
84 \section2 Extended Attributes
85 Places may have additional attributes which are not covered in the formal API.
86 Similar to contacts attributes are based around a common set of
87 \l {Attribute Types}{attribute types}. To retrieve an extended attribute one
88 would do:
89 \snippet places/requesthandler.h Opening hours
90
91 The attribute types are string values by design to allow providers
92 to introduce new attribute types.
93
94 \section2 Content
95 The QPlace object is only meant to be a convenient container to hold
96 rich content such as images, reviews and so on. Retrieval of content
97 should happen via QPlaceManager::getPlaceContent().
98
99 The content is stored as a QPlaceContent::Collection which contains
100 both the index of the content, as well as the content itself. This enables
101 developers to check whether a particular item has already been retrieved
102 and if not, then request that content.
103
104 \section3 Attribution
105 Places have a field for a rich text attribution string. Some providers
106 may require that the attribution be shown when a place is displayed
107 to a user.
108
109 \section2 Categories
110 Different categories may be assigned to a place to indicate that the place
111 is associated with those categories. When saving a place, the only meaningful
112 data is the category id, the rest of the category data is effectively ignored.
113 The category must already exist before saving the place (it is not possible
114 to create a new category, assign it to the place, save the place and expect
115 the category to be created).
116
117 \section2 Saving Caveats
118 \input place-caveats.qdocinc
119*/
120
121/*!
122 Constructs an empty place object.
123*/
124QPlace::QPlace()
125 : d_ptr(new QPlacePrivateDefault())
126{
127}
128
129/*!
130 Constructs an place object using \a dd as private implementation.
131*/
132QPlace::QPlace(const QSharedDataPointer<QPlacePrivate> &dd): d_ptr(dd)
133{
134}
135
136/*!
137 Returns the d-pointer.
138*/
139QSharedDataPointer<QPlacePrivate> &QPlace::d()
140{
141 return d_ptr;
142}
143
144/*!
145 Constructs a copy of \a other.
146*/
147QPlace::QPlace(const QPlace &other)
148 : d_ptr(other.d_ptr)
149{
150}
151
152/*!
153 Destroys this place.
154*/
155QPlace::~QPlace()
156{
157}
158
159/*!
160 Assigns \a other to this place and returns a reference
161 to this place.
162*/
163QPlace &QPlace::operator= (const QPlace & other)
164{
165 if (this == &other)
166 return *this;
167
168 d_ptr = other.d_ptr;
169 return *this;
170}
171
172inline QPlacePrivate *QPlace::d_func()
173{
174 return static_cast<QPlacePrivate *>(d_ptr.data());
175}
176
177inline const QPlacePrivate *QPlace::d_func() const
178{
179 return static_cast<const QPlacePrivate *>(d_ptr.constData());
180}
181
182/*!
183 Returns true if \a other is equal to this place,
184 otherwise returns false.
185*/
186bool QPlace::operator== (const QPlace &other) const
187{
188 return ( (d_ptr.constData() == other.d_ptr.constData())
189 || (*d_ptr) == (*other.d_ptr));
190}
191
192/*!
193 Returns true if \a other is not equal to this place,
194 otherwise returns false.
195*/
196bool QPlace::operator!= (const QPlace &other) const
197{
198 return !(operator==(other));
199}
200
201/*!
202 Returns categories that this place belongs to.
203*/
204QList<QPlaceCategory> QPlace::categories() const
205{
206 return d_ptr->categories();
207}
208
209/*!
210 Sets a single \a category that this place belongs to.
211*/
212void QPlace::setCategory(const QPlaceCategory &category)
213{
214 d_ptr->setCategories(QList<QPlaceCategory>());
215 d_ptr->setCategories(QList<QPlaceCategory>() << category);
216}
217
218/*!
219 Sets the \a categories that this place belongs to.
220*/
221void QPlace::setCategories(const QList<QPlaceCategory> &categories)
222{
223 d_ptr->setCategories(categories);
224}
225
226/*!
227 Returns the location of the place.
228*/
229QGeoLocation QPlace::location() const
230{
231 return d_ptr->location();
232}
233
234/*!
235 Sets the \a location of the place.
236*/
237void QPlace::setLocation(const QGeoLocation &location)
238{
239 d_ptr->setLocation(location);
240}
241
242/*!
243 Returns an aggregated rating of the place.
244*/
245QPlaceRatings QPlace::ratings() const
246{
247 return d_ptr->ratings();
248}
249
250/*!
251 Sets the aggregated \a rating of the place.
252*/
253void QPlace::setRatings(const QPlaceRatings &rating)
254{
255 d_ptr->setRatings(rating);
256}
257
258/*!
259 Returns the supplier of this place.
260*/
261QPlaceSupplier QPlace::supplier() const
262{
263 return d_ptr->supplier();
264}
265
266/*!
267 Sets the supplier of this place to \a supplier.
268*/
269void QPlace::setSupplier(const QPlaceSupplier &supplier)
270{
271 d_ptr->setSupplier(supplier);
272}
273
274/*!
275 Returns a collection of content associated with a place.
276 This collection is a map with the key being the index of the content object
277 and value being the content object itself.
278
279 The \a type specifies which kind of content is to be retrieved.
280*/
281QPlaceContent::Collection QPlace::content(QPlaceContent::Type type) const
282{
283 return d_ptr->m_contentCollections.value(akey: type);
284}
285
286/*!
287 Sets a collection of \a content for the given \a type.
288*/
289void QPlace::setContent(QPlaceContent::Type type, const QPlaceContent::Collection &content)
290{
291 d_ptr->m_contentCollections.insert(akey: type, avalue: content);
292}
293
294/*!
295 Adds a collection of \a content of the given \a type to the place. Any index in \a content
296 that already exists is overwritten.
297*/
298void QPlace::insertContent(QPlaceContent::Type type, const QPlaceContent::Collection &content)
299{
300 for (auto iter = content.cbegin(), end = content.cend(); iter != end; ++iter)
301 d_ptr->m_contentCollections[type].insert(akey: iter.key(), avalue: iter.value());
302}
303
304/*!
305 Returns the total count of content objects of the given \a type.
306 This total count indicates how many the manager/provider should have available.
307 (As opposed to how many objects this place instance is currently assigned).
308
309 A negative count indicates that the total number of items is unknown.
310 By default the total content count is set to 0.
311*/
312int QPlace::totalContentCount(QPlaceContent::Type type) const
313{
314 return d_ptr->m_contentCounts.value(akey: type, adefaultValue: 0);
315}
316
317/*!
318 Sets the \a totalCount of content objects of the given \a type.
319*/
320void QPlace::setTotalContentCount(QPlaceContent::Type type, int totalCount)
321{
322 d_ptr->m_contentCounts.insert(akey: type, avalue: totalCount);
323}
324
325/*!
326 Returns the name of the place.
327*/
328QString QPlace::name() const
329{
330 return d_ptr->name();
331}
332
333/*!
334 Sets the \a name of the place.
335*/
336void QPlace::setName(const QString &name)
337{
338 d_ptr->setName(name);
339}
340
341/*!
342 Returns the identifier of the place. The place identifier is only meaningful to the QPlaceManager that
343 generated it and is not transferable between managers. The place identifier is not guaranteed
344 to be universally unique, but unique for the manager that generated it.
345*/
346QString QPlace::placeId() const
347{
348 return d_ptr->placeId();
349}
350
351/*!
352 Sets the \a identifier of the place.
353*/
354void QPlace::setPlaceId(const QString &identifier)
355{
356 d_ptr->setPlaceId(identifier);
357}
358
359/*!
360 Returns a rich text attribution string of the place. Note, some providers may have a
361 requirement where the attribution must be shown whenever a place is displayed to an end user.
362*/
363QString QPlace::attribution() const
364{
365 return d_ptr->attribution();
366}
367
368/*!
369 Sets the \a attribution string of the place.
370*/
371void QPlace::setAttribution(const QString &attribution)
372{
373 d_ptr->setAttribution(attribution);
374}
375
376/*!
377 Returns the icon of the place.
378*/
379QPlaceIcon QPlace::icon() const
380{
381 return d_ptr->icon();
382}
383
384/*!
385 Sets the \a icon of the place.
386*/
387void QPlace::setIcon(const QPlaceIcon &icon)
388{
389 d_ptr->setIcon(icon);
390}
391
392/*!
393 Returns the primary phone number for this place. This accesses the first contact detail
394 of the \l {QPlaceContactDetail::Phone}{phone number type}. If no phone details exist, then an empty string is returned.
395*/
396QString QPlace::primaryPhone() const
397{
398 QList<QPlaceContactDetail> phoneNumbers = d_ptr->contacts().value(akey: QPlaceContactDetail::Phone);
399 if (!phoneNumbers.isEmpty())
400 return phoneNumbers.at(i: 0).value();
401 else
402 return QString();
403}
404
405/*!
406 Returns the primary fax number for this place. This convenience function accesses the first contact
407 detail of the \l {QPlaceContactDetail::Fax}{fax type}. If no fax details exist, then an empty string is returned.
408*/
409QString QPlace::primaryFax() const
410{
411 QList<QPlaceContactDetail> faxNumbers = d_ptr->contacts().value(akey: QPlaceContactDetail::Fax);
412 if (!faxNumbers.isEmpty())
413 return faxNumbers.at(i: 0).value();
414 else
415 return QString();
416}
417
418/*!
419 Returns the primary email address for this place. This convenience function accesses the first
420 contact detail of the \l {QPlaceContactDetail::Email}{email type}. If no email addresses exist, then
421 an empty string is returned.
422*/
423QString QPlace::primaryEmail() const
424{
425 QList<QPlaceContactDetail> emailAddresses = d_ptr->contacts().value(akey: QPlaceContactDetail::Email);
426 if (!emailAddresses.isEmpty())
427 return emailAddresses.at(i: 0).value();
428 else
429 return QString();
430}
431
432/*!
433 Returns the primary website of the place. This convenience function accesses the first
434 contact detail of the \l {QPlaceContactDetail::Website}{website type}. If no websites exist,
435 then an empty string is returned.
436*/
437QUrl QPlace::primaryWebsite() const
438{
439 QList<QPlaceContactDetail> websites = d_ptr->contacts().value(akey: QPlaceContactDetail::Website);
440 if (!websites.isEmpty())
441 return QUrl(websites.at(i: 0).value());
442 else
443 return QString();
444}
445
446/*!
447 Returns true if the details of this place have been fetched,
448 otherwise returns false.
449*/
450bool QPlace::detailsFetched() const
451{
452 return d_ptr->detailsFetched();
453}
454
455/*!
456 Sets whether the details of this place have been \a fetched or not.
457*/
458void QPlace::setDetailsFetched(bool fetched)
459{
460 d_ptr->setDetailsFetched(fetched);
461}
462
463/*!
464 Returns the types of extended attributes that this place has.
465*/
466QStringList QPlace::extendedAttributeTypes() const
467{
468 return d_ptr->extendedAttributes().keys();
469}
470
471/*!
472 Returns the exteded attribute corresponding to the specified \a attributeType.
473 If the place does not have that particular attribute type, a default constructed
474 QPlaceExtendedAttribute is returned.
475*/
476QPlaceAttribute QPlace::extendedAttribute(const QString &attributeType) const
477{
478 return d_ptr->extendedAttribute(attributeType);
479}
480
481/*!
482 Assigns an \a attribute of the given \a attributeType to a place. If the given \a attributeType
483 already exists in the place, then it is overwritten.
484
485 If \a attribute is a default constructed QPlaceAttribute, then the \a attributeType
486 is removed from the place which means it will not be listed by QPlace::extendedAttributeTypes().
487*/
488void QPlace::setExtendedAttribute(const QString &attributeType,
489 const QPlaceAttribute &attribute)
490{
491 if (attribute == QPlaceAttribute())
492 d_ptr->extendedAttributes().remove(akey: attributeType);
493 else
494 d_ptr->extendedAttributes().insert(akey: attributeType, avalue: attribute);
495}
496
497/*!
498 Remove the attribute of \a attributeType from the place.
499
500 The attribute will no longer be listed by QPlace::extendedAttributeTypes()
501*/
502void QPlace::removeExtendedAttribute(const QString &attributeType)
503{
504 setExtendedAttribute(attributeType, attribute: QPlaceAttribute());
505}
506
507/*!
508 Returns the type of contact details this place has.
509
510 See QPlaceContactDetail for a list of common \l {QPlaceContactDetail::Email}{contact types}.
511*/
512QStringList QPlace::contactTypes() const
513{
514 return d_ptr->contacts().keys();
515}
516
517/*!
518 Returns a list of contact details of the specified \a contactType.
519
520 See QPlaceContactDetail for a list of common \l {QPlaceContactDetail::Email}{contact types}.
521*/
522QList<QPlaceContactDetail> QPlace::contactDetails(const QString &contactType) const
523{
524 return d_ptr->contacts().value(akey: contactType);
525}
526
527/*!
528 Sets the contact \a details of a specified \a contactType.
529
530 If \a details is empty, then the \a contactType is removed from the place such
531 that it is no longer returned by QPlace::contactTypes().
532
533 See QPlaceContactDetail for a list of common \l {QPlaceContactDetail::Email}{contact types}.
534*/
535void QPlace::setContactDetails(const QString &contactType, QList<QPlaceContactDetail> details)
536{
537 if (details.isEmpty())
538 d_ptr->contacts().remove(akey: contactType);
539 else
540 d_ptr->contacts().insert(akey: contactType, avalue: details);
541}
542
543/*!
544 Appends a contact \a detail of a specified \a contactType.
545
546 See QPlaceContactDetail for a list of common \l {QPlaceContactDetail::Email}{contact types}.
547*/
548void QPlace::appendContactDetail(const QString &contactType, const QPlaceContactDetail &detail)
549{
550 QList<QPlaceContactDetail> details = d_ptr->contacts().value(akey: contactType);
551 details.append(t: detail);
552 d_ptr->contacts().insert(akey: contactType, avalue: details);
553}
554
555/*!
556 Removes all the contact details of a given \a contactType.
557
558 The \a contactType is no longer returned when QPlace::contactTypes() is called.
559*/
560void QPlace::removeContactDetails(const QString &contactType)
561{
562 d_ptr->contacts().remove(akey: contactType);
563}
564
565/*!
566 Sets the visibility of the place to \a visibility.
567*/
568void QPlace::setVisibility(QLocation::Visibility visibility)
569{
570 d_ptr->setVisibility(visibility);
571}
572
573/*!
574 Returns the visibility of the place.
575
576 The default visibility of a new place is set to QtLocatin::Unspecified visibility.
577 If a place is saved with unspecified visibility the backend chooses an appropriate
578 default visibility to use when saving.
579*/
580QLocation::Visibility QPlace::visibility() const
581{
582 return d_ptr->visibility();
583}
584
585/*!
586 Returns a boolean indicating whether the all the fields of the place are empty or not.
587*/
588bool QPlace::isEmpty() const
589{
590 return d_ptr->isEmpty();
591}
592
593/*******************************************************************************
594*******************************************************************************/
595
596QPlacePrivate::QPlacePrivate()
597: QSharedData()
598{
599}
600
601QPlacePrivate::QPlacePrivate(const QPlacePrivate &other)
602 : QSharedData(other),
603 m_contentCollections(other.m_contentCollections),
604 m_contentCounts(other.m_contentCounts)
605{
606}
607
608QPlacePrivate::~QPlacePrivate() {}
609
610bool QPlacePrivate::operator== (const QPlacePrivate &other) const
611{
612 return (categories() == other.categories()
613 && location() == other.location()
614 && ratings() == other.ratings()
615 && supplier() == other.supplier()
616 && m_contentCollections == other.m_contentCollections
617 && m_contentCounts == other.m_contentCounts
618 && name() == other.name()
619 && placeId() == other.placeId()
620 && attribution() == other.attribution()
621 && contacts() == other.contacts()
622 && extendedAttributes() == other.extendedAttributes()
623 && visibility() == other.visibility()
624 && icon() == other.icon()
625 );
626}
627
628
629bool QPlacePrivate::isEmpty() const
630{
631 return (categories().isEmpty()
632 && location().isEmpty()
633 && ratings().isEmpty()
634 && supplier().isEmpty()
635 && m_contentCollections.isEmpty()
636 && m_contentCounts.isEmpty()
637 && name().isEmpty()
638 && placeId().isEmpty()
639 && attribution().isEmpty()
640 && contacts().isEmpty()
641 && extendedAttributes().isEmpty()
642 && QLocation::UnspecifiedVisibility == visibility()
643 && icon().isEmpty()
644 );
645}
646
647QPlaceAttribute QPlacePrivate::extendedAttribute(const QString &attributeType) const
648{
649 return extendedAttributes().value(akey: attributeType);
650}
651
652
653
654//
655// Default implementation
656//
657
658QPlacePrivateDefault::QPlacePrivateDefault()
659 : QPlacePrivate(), m_visibility(QLocation::UnspecifiedVisibility), m_detailsFetched(false)
660{
661}
662
663QPlacePrivateDefault::QPlacePrivateDefault(const QPlacePrivateDefault &other)
664 : QPlacePrivate(other),
665 m_categories(other.m_categories),
666 m_location(other.m_location),
667 m_ratings(other.m_ratings),
668 m_supplier(other.m_supplier),
669 m_name(other.m_name),
670 m_placeId(other.m_placeId),
671 m_attribution(other.m_attribution),
672 m_extendedAttributes(other.m_extendedAttributes),
673 m_contacts(other.m_contacts),
674 m_visibility(other.m_visibility),
675 m_icon(other.m_icon),
676 m_detailsFetched(other.m_detailsFetched)
677{
678}
679
680QPlacePrivateDefault::~QPlacePrivateDefault()
681{
682}
683
684QPlacePrivate *QPlacePrivateDefault::clone()
685{
686 return new QPlacePrivateDefault(*this);
687}
688
689QList<QPlaceCategory> QPlacePrivateDefault::categories() const
690{
691 return m_categories;
692}
693
694void QPlacePrivateDefault::setCategories(const QList<QPlaceCategory> &categories)
695{
696 m_categories = categories;
697}
698
699QGeoLocation QPlacePrivateDefault::location() const
700{
701 return m_location;
702}
703
704void QPlacePrivateDefault::setLocation(const QGeoLocation &location)
705{
706 m_location = location;
707}
708
709QPlaceRatings QPlacePrivateDefault::ratings() const
710{
711 return m_ratings;
712}
713
714void QPlacePrivateDefault::setRatings(const QPlaceRatings &ratings)
715{
716 m_ratings = ratings;
717}
718
719QPlaceSupplier QPlacePrivateDefault::supplier() const
720{
721 return m_supplier;
722}
723
724void QPlacePrivateDefault::setSupplier(const QPlaceSupplier &supplier)
725{
726 m_supplier = supplier;
727}
728
729QString QPlacePrivateDefault::name() const
730{
731 return m_name;
732}
733
734void QPlacePrivateDefault::setName(const QString &name)
735{
736 m_name = name;
737}
738
739QString QPlacePrivateDefault::placeId() const
740{
741 return m_placeId;
742}
743
744void QPlacePrivateDefault::setPlaceId(const QString &placeIdentifier)
745{
746 m_placeId = placeIdentifier;
747}
748
749QString QPlacePrivateDefault::attribution() const
750{
751 return m_attribution;
752}
753
754void QPlacePrivateDefault::setAttribution(const QString &attribution)
755{
756 m_attribution = attribution;
757}
758
759QLocation::Visibility QPlacePrivateDefault::visibility() const
760{
761 return m_visibility;
762}
763
764void QPlacePrivateDefault::setVisibility(QLocation::Visibility visibility)
765{
766 m_visibility = visibility;
767}
768
769QPlaceIcon QPlacePrivateDefault::icon() const
770{
771 return m_icon;
772}
773
774void QPlacePrivateDefault::setIcon(const QPlaceIcon &icon)
775{
776 m_icon = icon;
777}
778
779bool QPlacePrivateDefault::detailsFetched() const
780{
781 return m_detailsFetched;
782}
783
784void QPlacePrivateDefault::setDetailsFetched(bool fetched)
785{
786 m_detailsFetched = fetched;
787}
788
789QMap<QString, QPlaceAttribute> QPlacePrivateDefault::extendedAttributes() const
790{
791 return m_extendedAttributes;
792}
793
794QMap<QString, QPlaceAttribute> &QPlacePrivateDefault::extendedAttributes()
795{
796 return m_extendedAttributes;
797}
798
799QMap<QString, QList<QPlaceContactDetail> > QPlacePrivateDefault::contacts() const
800{
801 return m_contacts;
802}
803
804QMap<QString, QList<QPlaceContactDetail> > &QPlacePrivateDefault::contacts()
805{
806 return m_contacts;
807}
808
809
810
811QT_END_NAMESPACE
812

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