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