1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 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 "qmappolylineobject_p.h"
38 #include "qmappolylineobject_p_p.h"
39 #include <QtLocation/private/locationvaluetypehelper_p.h>
40 #include <QtPositioning/QGeoPath>
41 
42 QT_BEGIN_NAMESPACE
43 
44 /*!
45     \qmltype MapPolylineObject
46     \instantiates QMapPolylineObject
47     \inqmlmodule Qt.labs.location
48     \ingroup qml-QtLocation5-maps
49     \inherits QGeoMapObject
50 
51     \brief The MapPolylineObject displays a polyline on a Map.
52 
53     The MapPolylineObject displays a polyline on a Map.
54     The MapPolylineObject type only makes sense when contained in a Map or in a \l MapObjectView.
55 */
56 
QMapPolylineObjectPrivate(QGeoMapObject * q)57 QMapPolylineObjectPrivate::QMapPolylineObjectPrivate(QGeoMapObject *q) : QGeoMapObjectPrivate(q)
58 {
59 
60 }
61 
~QMapPolylineObjectPrivate()62 QMapPolylineObjectPrivate::~QMapPolylineObjectPrivate()
63 {
64 
65 }
66 
type() const67 QGeoMapObject::Type QMapPolylineObjectPrivate::type() const
68 {
69     return QGeoMapObject::PolylineType;
70 }
71 
QMapPolylineObjectPrivateDefault(QGeoMapObject * q)72 QMapPolylineObjectPrivateDefault::QMapPolylineObjectPrivateDefault(QGeoMapObject *q) : QMapPolylineObjectPrivate(q)
73 {
74 
75 }
76 
QMapPolylineObjectPrivateDefault(const QMapPolylineObjectPrivate & other)77 QMapPolylineObjectPrivateDefault::QMapPolylineObjectPrivateDefault(const QMapPolylineObjectPrivate &other) : QMapPolylineObjectPrivate(other.q)
78 {
79     m_path.setPath(other.path());
80     m_color = other.color();
81     m_width = other.width();
82 }
83 
~QMapPolylineObjectPrivateDefault()84 QMapPolylineObjectPrivateDefault::~QMapPolylineObjectPrivateDefault()
85 {
86 
87 }
88 
path() const89 QList<QGeoCoordinate> QMapPolylineObjectPrivateDefault::path() const
90 {
91     return m_path.path();
92 }
93 
setPath(const QList<QGeoCoordinate> & path)94 void QMapPolylineObjectPrivateDefault::setPath(const QList<QGeoCoordinate> &path)
95 {
96     m_path.setPath(path);
97 }
98 
color() const99 QColor QMapPolylineObjectPrivateDefault::color() const
100 {
101     return m_color;
102 }
103 
setColor(const QColor & color)104 void QMapPolylineObjectPrivateDefault::setColor(const QColor &color)
105 {
106     m_color = color;
107 }
108 
width() const109 qreal QMapPolylineObjectPrivateDefault::width() const
110 {
111     return m_width;
112 }
113 
setWidth(qreal width)114 void QMapPolylineObjectPrivateDefault::setWidth(qreal width)
115 {
116     m_width = width;
117 }
118 
equals(const QGeoMapObjectPrivate & other) const119 bool QMapPolylineObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
120 {
121     if (other.type() != type()) // This check might be unnecessary, depending on how equals gets used
122         return false;
123 
124     const QMapPolylineObjectPrivate &o = static_cast<const QMapPolylineObjectPrivate &>(other);
125     return (QGeoMapObjectPrivate::equals(o)
126             && path() == o.path()
127             && color() == o.color()
128             && width() == o.width());
129 }
130 
geoShape() const131 QGeoShape QMapPolylineObjectPrivate::geoShape() const
132 {
133     return QGeoPath(path());
134 }
135 
setGeoShape(const QGeoShape & shape)136 void QMapPolylineObjectPrivate::setGeoShape(const QGeoShape &shape)
137 {
138     const QGeoPath p(shape);
139     if (p == path())
140         return;
141 
142     setPath(p.path()); // to handle overrides
143     emit static_cast<QMapPolylineObject *>(q)->pathChanged();
144 }
145 
146 
147 
clone()148 QGeoMapObjectPrivate *QMapPolylineObjectPrivateDefault::clone()
149 {
150     return new QMapPolylineObjectPrivateDefault(static_cast<QMapPolylineObjectPrivate &>(*this));
151 }
152 
QMapPolylineObject(QObject * parent)153 QMapPolylineObject::QMapPolylineObject(QObject *parent)
154  : QGeoMapObject(QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(new QMapPolylineObjectPrivateDefault(this)), parent)
155 {
156     QMapPolylineObjectPrivate *d = static_cast<QMapPolylineObjectPrivate*>(d_ptr.data());
157     d->setColor(QColor(Qt::black)); // These are QDeclarativeMapLineProperties defaults
158     d->setWidth(1.0);
159 }
160 
~QMapPolylineObject()161 QMapPolylineObject::~QMapPolylineObject()
162 {}
163 
164 /*!
165     \qmlproperty VariantList Qt.labs.location::MapPolylineObject::path
166 
167     This property holds the ordered list of coordinates which
168     define the polyline.
169 */
path() const170 QVariantList QMapPolylineObject::path() const
171 {
172     QVariantList p;
173     for (const QGeoCoordinate &c: static_cast<const QMapPolylineObjectPrivate*>(d_ptr.data())->path())
174         p << QVariant::fromValue(c);
175     return p;
176 }
177 
178 /*!
179     \qmlpropertygroup Qt.labs.location::MapPolylineObject::line
180     \qmlproperty int MapPolylineObject::line.width
181     \qmlproperty color MapPolylineObject::line.color
182 
183     This property is part of the line property group. The line
184     property group holds the width and color used to draw the line.
185 
186     The width is in pixels and is independent of the zoom level of the map.
187     The default values correspond to a black border with a width of 1 pixel.
188 
189     For no line, use a width of 0 or a transparent color.
190 */
border()191 QDeclarativeMapLineProperties *QMapPolylineObject::border()
192 {
193     if (!m_border) {
194         m_border = new QDeclarativeMapLineProperties(this);
195         connect(m_border, &QDeclarativeMapLineProperties::colorChanged, this, [this](const QColor &color){
196             static_cast<QMapPolylineObjectPrivate*>(d_ptr.data())->setColor(color);
197         });
198         connect(m_border, &QDeclarativeMapLineProperties::widthChanged, this, [this](qreal width){
199             static_cast<QMapPolylineObjectPrivate*>(d_ptr.data())->setWidth(width);
200         });
201     }
202     return m_border;
203 }
204 
setPath(const QVariantList & path)205 void QMapPolylineObject::setPath(const QVariantList &path)
206 {
207     QList<QGeoCoordinate> p;
208     bool ok = false;
209     for (const auto &c: path) {
210         const QGeoCoordinate coord = parseCoordinate(c, &ok);
211         if (ok)
212             p << coord;
213     }
214     auto pimpl = static_cast<QMapPolylineObjectPrivate *>(d_ptr.data());
215     if (p != pimpl->path()) {
216         pimpl->setPath(p);
217         emit pathChanged();
218     }
219 }
220 
setMap(QGeoMap * map)221 void QMapPolylineObject::setMap(QGeoMap *map)
222 {
223     QMapPolylineObjectPrivate *d = static_cast<QMapPolylineObjectPrivate *>(d_ptr.data());
224     if (d->m_map == map)
225         return;
226 
227     QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
228 
229     if (!map) {
230         // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
231         // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
232         d_ptr = new QMapPolylineObjectPrivateDefault(*d);
233         // Old pimpl deleted implicitly by QExplicitlySharedDataPointer
234     }
235 }
236 
237 QT_END_NAMESPACE
238