Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdeclarativecategory.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
7
8#include <QtQml/QQmlInfo>
9#include <QtLocation/QGeoServiceProvider>
10#include <QtLocation/QPlaceIcon>
11#include <QtLocation/QPlaceManager>
12#include <QtLocation/QPlaceIdReply>
13#include <QCoreApplication>
14
16
17/*!
18 \qmltype Category
19 \nativetype QDeclarativeCategory
20 \inqmlmodule QtLocation
21 \ingroup qml-QtLocation5-places
22 \ingroup qml-QtLocation5-places-data
23
24 \since QtLocation 5.5
25
26 \brief The Category type represents a category that a \l Place can be associated with.
27
28 Categories are used to search for places based on the categories they are associated with. The
29 list of available categories can be obtained from the \l CategoryModel. The
30 \l PlaceSearchModel has a \l {PlaceSearchModel::categories}{categories} property that is used
31 to limit the search results to places with the specified categories.
32
33 If the \l Plugin supports it, categories can be created or removed. To create a new category
34 construct a new Category object and set its properties, then invoke the \l save() method.
35
36 \snippet declarative/maps.qml QtLocation import
37 \codeline
38 \snippet declarative/places.qml Category
39 \dots 0
40 \snippet declarative/places.qml Category save
41
42 To remove a category ensure that the \l plugin and categoryId properties are set and call the
43 \l remove() method.
44
45 \sa CategoryModel
46*/
47
48QDeclarativeCategory::QDeclarativeCategory(QObject *parent)
49 : QObject(parent)
50{
51}
52
53QDeclarativeCategory::QDeclarativeCategory(const QPlaceCategory &category,
54 QDeclarativeGeoServiceProvider *plugin,
55 QObject *parent)
56 : QObject(parent), m_category(category), m_plugin(plugin)
57{
58 setCategory(category);
59}
60
61QDeclarativeCategory::~QDeclarativeCategory() {}
62
63// From QQmlParserStatus
64void QDeclarativeCategory::componentComplete()
65{
66 m_complete = true;
67}
68
69/*!
70 \qmlproperty Plugin Category::plugin
71
72 This property holds the location based service to which the category belongs.
73*/
74void QDeclarativeCategory::setPlugin(QDeclarativeGeoServiceProvider *plugin)
75{
76 if (m_plugin == plugin)
77 return;
78
79 m_plugin = plugin;
80 if (m_complete)
81 emit pluginChanged();
82
83 if (!m_plugin)
84 return;
85
86 if (m_plugin->isAttached()) {
87 pluginReady();
88 } else {
89 connect(m_plugin, &QDeclarativeGeoServiceProvider::attached,
90 this, &QDeclarativeCategory::pluginReady);
91 }
92}
93
94QDeclarativeGeoServiceProvider *QDeclarativeCategory::plugin() const
95{
96 return m_plugin;
97}
98
99/*!
100 \internal
101*/
102void QDeclarativeCategory::pluginReady()
103{
104 QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
105 QPlaceManager *placeManager = serviceProvider->placeManager();
106 if (!placeManager || serviceProvider->error() != QGeoServiceProvider::NoError) {
107 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_ERROR)
108 .arg(m_plugin->name()).arg(serviceProvider->errorString()));
109 return;
110 }
111}
112
113
114/*!
115 \internal
116*/
117void QDeclarativeCategory::setCategory(const QPlaceCategory &category)
118{
119 QPlaceCategory previous = m_category;
120 m_category = category;
121
122 if (category.name() != previous.name())
123 emit nameChanged();
124
125 if (category.categoryId() != previous.categoryId())
126 emit categoryIdChanged();
127
128 if (category.icon() != previous.icon())
129 emit iconChanged();
130}
131
132QPlaceCategory QDeclarativeCategory::category()
133{
134 return m_category;
135}
136
137/*!
138 \qmlproperty string Category::categoryId
139
140 This property holds the identifier of the category. The categoryId is a string which uniquely
141 identifies this category within the categories \l plugin.
142*/
143void QDeclarativeCategory::setCategoryId(const QString &id)
144{
145 if (m_category.categoryId() != id) {
146 m_category.setCategoryId(id);
147 emit categoryIdChanged();
148 }
149}
150
151QString QDeclarativeCategory::categoryId() const
152{
153 return m_category.categoryId();
154}
155
156/*!
157 \qmlproperty string Category::name
158
159 This property holds string based name of the category.
160*/
161void QDeclarativeCategory::setName(const QString &name)
162{
163 if (m_category.name() != name) {
164 m_category.setName(name);
165 emit nameChanged();
166 }
167}
168
169QString QDeclarativeCategory::name() const
170{
171 return m_category.name();
172}
173
174/*!
175 \qmlproperty enumeration Category::visibility
176
177 This property holds the visibility of the category. It can be one of:
178
179 \table
180 \row
181 \li Category.UnspecifiedVisibility
182 \li The visibility of the category is unspecified. If saving a category, the
183 plugin will automatically set a default visibility to the category saved in the backend.
184 This default is dependent on the plugin implementation.
185 \row
186 \li Category.DeviceVisibility
187 \li The category is limited to the current device. The category will not be transferred
188 off of the device.
189 \row
190 \li Category.PrivateVisibility
191 \li The category is private to the current user. The category may be transferred to an
192 online service but is only ever visible to the current user.
193 \row
194 \li Category.PublicVisibility
195 \li The category is public.
196 \endtable
197
198 Note that visibility does not affect how \l{Place}s associated with
199 the category are displayed in the user-interface of an application
200 on the device. Instead, it defines the sharing semantics of the
201 category.
202*/
203QDeclarativeCategory::Visibility QDeclarativeCategory::visibility() const
204{
205 return static_cast<QDeclarativeCategory::Visibility>(m_category.visibility());
206}
207
208void QDeclarativeCategory::setVisibility(Visibility visibility)
209{
210 if (static_cast<QDeclarativeCategory::Visibility>(m_category.visibility()) == visibility)
211 return;
212
213 m_category.setVisibility(static_cast<QLocation::Visibility>(visibility));
214 emit visibilityChanged();
215}
216
217/*!
218 \qmlproperty PlaceIcon Category::icon
219
220 This property holds the image source associated with the category. To display the icon you can use
221 the \l Image type.
222*/
223QPlaceIcon QDeclarativeCategory::icon() const
224{
225 return m_category.icon();
226}
227
228void QDeclarativeCategory::setIcon(const QPlaceIcon &icon)
229{
230 if (m_category.icon() != icon) {
231 m_category.setIcon(icon);
232 emit iconChanged();
233 }
234}
235
236/*!
237 \qmlmethod string Category::errorString()
238
239 Returns a string description of the error of the last operation.
240 If the last operation completed successfully then the string is empty.
241*/
242QString QDeclarativeCategory::errorString() const
243{
244 return m_errorString;
245}
246
247void QDeclarativeCategory::setStatus(Status status, const QString &errorString)
248{
249 Status originalStatus = m_status;
250 m_status = status;
251 m_errorString = errorString;
252
253 if (originalStatus != m_status)
254 emit statusChanged();
255}
256
257/*!
258 \qmlproperty enumeration Category::status
259
260 This property holds the status of the category. It can be one of:
261
262 \table
263 \row
264 \li Category.Ready
265 \li No error occurred during the last operation, further operations may be performed on
266 the category.
267 \row
268 \li Category.Saving
269 \li The category is currently being saved, no other operations may be performed until the
270 current operation completes.
271 \row
272 \li Category.Removing
273 \li The category is currently being removed, no other operations can be performed until
274 the current operation completes.
275 \row
276 \li Category.Error
277 \li An error occurred during the last operation, further operations can still be
278 performed on the category.
279 \endtable
280*/
281QDeclarativeCategory::Status QDeclarativeCategory::status() const
282{
283 return m_status;
284}
285
286/*!
287 \qmlmethod void Category::save()
288
289 This method saves the category to the backend service.
290*/
291void QDeclarativeCategory::save(const QString &parentId)
292{
293 QPlaceManager *placeManager = manager();
294 if (!placeManager)
295 return;
296
297 m_reply = placeManager->saveCategory(category(), parentId);
298 connect(m_reply, &QPlaceReply::finished,
299 this, &QDeclarativeCategory::replyFinished);
300 setStatus(QDeclarativeCategory::Saving);
301}
302
303/*!
304 \qmlmethod void Category::remove()
305
306 This method permanently removes the category from the backend service.
307*/
308void QDeclarativeCategory::remove()
309{
310 QPlaceManager *placeManager = manager();
311 if (!placeManager)
312 return;
313
314 m_reply = placeManager->removeCategory(m_category.categoryId());
315 connect(m_reply, &QPlaceReply::finished,
316 this, &QDeclarativeCategory::replyFinished);
317 setStatus(QDeclarativeCategory::Removing);
318}
319
320/*!
321 \internal
322*/
323void QDeclarativeCategory::replyFinished()
324{
325 if (!m_reply)
326 return;
327
328 if (m_reply->error() == QPlaceReply::NoError) {
329 switch (m_reply->type()) {
330 case (QPlaceReply::IdReply) : {
331 QPlaceIdReply *idReply = qobject_cast<QPlaceIdReply *>(m_reply);
332
333 switch (idReply->operationType()) {
334 case QPlaceIdReply::SaveCategory:
335 setCategoryId(idReply->id());
336 break;
337 case QPlaceIdReply::RemoveCategory:
338 setCategoryId(QString());
339 break;
340 default:
341 //Other operation types shouldn't ever be received.
342 break;
343 }
344 break;
345 }
346 default:
347 //other types of replies shouldn't ever be received.
348 break;
349 }
350
351 m_errorString.clear();
352
353 m_reply->deleteLater();
354 m_reply = nullptr;
355
356 setStatus(QDeclarativeCategory::Ready);
357 } else {
358 QString errorString = m_reply->errorString();
359
360 m_reply->deleteLater();
361 m_reply = nullptr;
362
363 setStatus(QDeclarativeCategory::Error, errorString);
364 }
365}
366
367/*!
368 \internal
369 Helper function to return the manager, this manager is intended to be used to perform the next
370 operation. Sets status to Error and an appropriate m_errorString if the manager cannot be
371 obtained.
372*/
373QPlaceManager *QDeclarativeCategory::manager()
374{
375 if (m_status != QDeclarativeCategory::Ready && m_status != QDeclarativeCategory::Error)
376 return nullptr;
377
378 if (m_reply) {
379 m_reply->abort();
380 m_reply->deleteLater();
381 m_reply = nullptr;
382 }
383
384 if (!m_plugin) {
385 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_PROPERTY_NOT_SET));
386 return nullptr;
387 }
388
389 QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider();
390 if (!serviceProvider) {
391 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_NOT_VALID));
392 return nullptr;
393 }
394 QPlaceManager *placeManager = serviceProvider->placeManager();
395 if (!placeManager) {
396 setStatus(Error, QCoreApplication::translate(CONTEXT_NAME, PLUGIN_ERROR)
397 .arg(m_plugin->name()).arg(serviceProvider->errorString()));
398 return nullptr;
399 }
400
401 return placeManager;
402}
403
404QT_END_NAMESPACE