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 "qdeclarativeplaceicon_p.h"
38 #include "error_messages_p.h"
39 
40 #include <QtLocation/QGeoServiceProvider>
41 #include <QtLocation/QPlaceManager>
42 #include <QtQml/QQmlInfo>
43 #include <QCoreApplication>
44 
45 QT_BEGIN_NAMESPACE
46 
47 /*!
48     \qmltype Icon
49     \instantiates QDeclarativePlaceIcon
50     \inqmlmodule QtLocation
51     \ingroup qml-QtLocation5-places
52     \ingroup qml-QtLocation5-places-data
53     \since QtLocation 5.5
54 
55     \brief The Icon type represents an icon image source which can have multiple sizes.
56 
57     The Icon type can be used in conjunction with an \l Image type to display an icon.
58     The \l url() function is used to construct an icon URL of a requested size,
59     the icon which most closely matches the requested size is returned.
60 
61     The Icon type also has a parameters map which is a set of key value pairs.  The precise
62     keys to use depend on the
63     \l {Qt Location#Plugin References and Parameters}{plugin} being used.
64     The parameters map is used by the \l Plugin to determine which URL to return.
65 
66     In the case where an icon can only possibly have one image URL, the
67     parameter key of \c "singleUrl" can be used with a QUrl value.  Any Icon with this
68     parameter will always return the specified URL regardless of the requested icon
69     size and not defer to any Plugin.
70 
71     The following code shows how to display a 64x64 pixel icon:
72 
73     \snippet declarative/places.qml QtQuick import
74     \snippet declarative/maps.qml QtLocation import
75     \codeline
76     \snippet declarative/places.qml Icon
77 
78     Alternatively, a default sized icon can be specified like so:
79     \snippet declarative/places.qml Icon default
80 */
81 
QDeclarativePlaceIcon(QObject * parent)82 QDeclarativePlaceIcon::QDeclarativePlaceIcon(QObject *parent)
83 :   QObject(parent), m_plugin(0), m_parameters(new QQmlPropertyMap(this))
84 {
85 }
86 
QDeclarativePlaceIcon(const QPlaceIcon & icon,QDeclarativeGeoServiceProvider * plugin,QObject * parent)87 QDeclarativePlaceIcon::QDeclarativePlaceIcon(const QPlaceIcon &icon, QDeclarativeGeoServiceProvider *plugin, QObject *parent)
88 :   QObject(parent), m_parameters(new QQmlPropertyMap(this))
89 {
90     if (icon.isEmpty())
91         m_plugin = 0;
92     else
93         m_plugin = plugin;
94 
95     initParameters(icon.parameters());
96 }
97 
~QDeclarativePlaceIcon()98 QDeclarativePlaceIcon::~QDeclarativePlaceIcon()
99 {
100 }
101 
102 /*!
103     \qmlproperty QPlaceIcon Icon::icon
104 
105     For details on how to use this property to interface between C++ and QML see
106     "\l {Icon - QPlaceIcon} {Interfaces between C++ and QML Code}".
107 */
icon() const108 QPlaceIcon QDeclarativePlaceIcon::icon() const
109 {
110     QPlaceIcon result;
111 
112     if (m_plugin)
113         result.setManager(manager());
114     else
115         result.setManager(0);
116 
117     QVariantMap params;
118     foreach (const QString &key, m_parameters->keys()) {
119         const QVariant value = m_parameters->value(key);
120         if (value.isValid()) {
121             params.insert(key, value);
122         }
123     }
124 
125     result.setParameters(params);
126 
127     return result;
128 }
129 
setIcon(const QPlaceIcon & src)130 void QDeclarativePlaceIcon::setIcon(const QPlaceIcon &src)
131 {
132     initParameters(src.parameters());
133 }
134 
135 /*!
136     \qmlmethod url Icon::url(size size)
137 
138     Returns a URL for the icon image that most closely matches the given \a size.
139 
140     If no plugin has been assigned to the icon, and the parameters do not contain the 'singleUrl' key, a default constructed URL
141     is returned.
142 
143 */
url(const QSize & size) const144 QUrl QDeclarativePlaceIcon::url(const QSize &size) const
145 {
146     return icon().url(size);
147 }
148 
149 /*!
150     \qmlproperty Object Icon::parameters
151 
152     This property holds the parameters of the icon and is a map.  These parameters
153     are used by the plugin to return the appropriate URL when url() is called and to
154     specify locations to save to when saving icons.
155 
156     Consult the \l {Qt Location#Plugin References and Parameters}{plugin documentation}
157     for what parameters are supported and how they should be used.
158 
159     Note, due to limitations of the QQmlPropertyMap, it is not possible
160     to declaratively specify the parameters in QML, assignment of parameters keys
161     and values can only be accomplished by JavaScript.
162 
163 */
parameters() const164 QQmlPropertyMap *QDeclarativePlaceIcon::parameters() const
165 {
166     return m_parameters;
167 }
168 
169 /*!
170     \qmlproperty Plugin Icon::plugin
171 
172     The property holds the plugin that is responsible for managing this icon.
173 */
plugin() const174 QDeclarativeGeoServiceProvider *QDeclarativePlaceIcon::plugin() const
175 {
176     return m_plugin;
177 }
178 
setPlugin(QDeclarativeGeoServiceProvider * plugin)179 void QDeclarativePlaceIcon::setPlugin(QDeclarativeGeoServiceProvider *plugin)
180 {
181     if (m_plugin == plugin)
182         return;
183 
184     m_plugin = plugin;
185     emit pluginChanged();
186 
187     if (!m_plugin)
188         return;
189 
190     if (m_plugin->isAttached()) {
191         pluginReady();
192     } else {
193         connect(m_plugin, SIGNAL(attached()),
194                 this, SLOT(pluginReady()));
195     }
196 }
197 
198 /*!
199     \internal
200 */
pluginReady()201 void QDeclarativePlaceIcon::pluginReady()
202 {
203     QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
204     QPlaceManager *placeManager = serviceProvider->placeManager();
205     if (!placeManager || serviceProvider->error() != QGeoServiceProvider::NoError) {
206         qmlWarning(this) << QCoreApplication::translate(CONTEXT_NAME, PLUGIN_ERROR)
207                          .arg(m_plugin->name()).arg(serviceProvider->errorString());
208         return;
209     }
210 }
211 
212 /*!
213     \internal
214     Helper function to return the manager from the plugin
215 */
manager() const216 QPlaceManager *QDeclarativePlaceIcon::manager() const
217 {
218     if (!m_plugin) {
219            qmlWarning(this) << QStringLiteral("Plugin is not assigned to place.");
220            return 0;
221     }
222 
223     QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
224     if (!serviceProvider)
225         return 0;
226 
227     QPlaceManager *placeManager = serviceProvider->placeManager();
228 
229     if (!placeManager)
230         return 0;
231 
232     return placeManager;
233 }
234 
235 /*!
236     \internal
237 */
initParameters(const QVariantMap & parameterMap)238 void QDeclarativePlaceIcon::initParameters(const QVariantMap &parameterMap)
239 {
240     //clear out old parameters
241     foreach (const QString &key, m_parameters->keys())
242         m_parameters->clear(key);
243 
244     foreach (const QString &key, parameterMap.keys()) {
245         QVariant value = parameterMap.value(key);
246         m_parameters->insert(key, value);
247     }
248 }
249 
250 QT_END_NAMESPACE
251