Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdeclarativegeomapitemview.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 Jolla Ltd.
2// Copyright (C) 2022 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
8
9#include <QtCore/QAbstractItemModel>
10#include <QtQml/QQmlContext>
11#include <QtQuick/private/qquickanimation_p.h>
12#include <QtQml/QQmlListProperty>
13
15
61{
62 m_exit = new QQuickTransition(this);
63 QQmlListProperty<QQuickAbstractAnimation> anims = m_exit->animations();
65 ani->setProperty(QStringLiteral("opacity"));
66 ani->setTo(0.0);
67 ani->setDuration(300.0);
68 anims.append(&anims, ani);
69}
70
72{
73 // No need to remove instantiated items: if the MIV has instantiated items because it has been added
74 // to a Map (or is child of a Map), the Map destructor takes care of removing it and the instantiated items.
75}
76
81{
83 m_componentCompleted = true;
84 if (!m_itemModel.isNull())
85 m_delegateModel->setModel(m_itemModel);
86
87 if (m_delegate)
88 m_delegateModel->setDelegate(m_delegate);
89
90 m_delegateModel->componentComplete();
91}
92
94{
96 QQmlContext *ctx = qmlContext(this);
97 m_delegateModel = new QQmlDelegateModel(ctx, this);
98 m_delegateModel->classBegin();
99
100 connect(m_delegateModel, &QQmlInstanceModel::modelUpdated, this, &QDeclarativeGeoMapItemView::modelUpdated);
101 connect(m_delegateModel, &QQmlInstanceModel::createdItem, this, &QDeclarativeGeoMapItemView::createdItem);
102// connect(m_delegateModel, &QQmlInstanceModel::destroyingItem, this, &QDeclarativeGeoMapItemView::destroyingItem);
103// connect(m_delegateModel, &QQmlInstanceModel::initItem, this, &QDeclarativeGeoMapItemView::initItem);
104}
105
106void QDeclarativeGeoMapItemView::destroyingItem(QObject * /*object*/)
107{
108
109}
110
111void QDeclarativeGeoMapItemView::initItem(int /*index*/, QObject * /*object*/)
112{
113
114}
115
116void QDeclarativeGeoMapItemView::createdItem(int index, QObject * /*object*/)
117{
118 if (!m_map)
119 return;
120 // createdItem is emitted on asynchronous creation. In which case, object has to be invoked again.
121 // See QQmlDelegateModel::object for further info.
122
123 // DelegateModel apparently triggers this method in any case, that is:
124 // 1. Synchronous incubation, delegate instantiated on the first object() call (during the object() call!)
125 // 2. Async incubation, delegate not instantiated on the first object() call
126 // 3. Async incubation, delegate present in the cache, and returned on the first object() call.
127 // createdItem also called during the object() call.
128 if (m_creatingObject) {
129 // Falling into case 1. or 3. Returning early to prevent double referencing the delegate instance.
130 return;
131 }
132
133 QQuickItem *item = qobject_cast<QQuickItem *>(m_delegateModel->object(index, m_incubationMode));
134 if (item)
135 addDelegateToMap(item, index, true);
136 else
137 qWarning() << "QQmlDelegateModel:: object called in createdItem for " << index << " produced a null item";
138}
139
140void QDeclarativeGeoMapItemView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
141{
142 if (!m_map) // everything will be done in instantiateAllItems. Removal is done by declarativegeomap.
143 return;
144
145 // move changes are expressed as one remove + one insert, with the same moveId.
146 // For simplicity, they will be treated as remove + insert.
147 // Changes will be also ignored, as they represent only data changes, not layout changes
148 if (reset) { // Assuming this means "remove everything already instantiated"
150 } else {
151 // Remove items from the back to the front to retain the mapping to what is received from the changesets
152 const QList<QQmlChangeSet::Change> &removes = changeSet.removes();
153 std::map<int, int> mapRemoves;
154 for (qsizetype i = 0; i < removes.size(); i++)
155 mapRemoves.insert(std::pair<int, int>(removes.at(i).start(), i));
156
157 for (auto rit = mapRemoves.rbegin(); rit != mapRemoves.rend(); ++rit) {
158 const QQmlChangeSet::Change &c = removes.at(rit->second);
159 for (auto idx = c.end() - 1; idx >= c.start(); --idx)
160 removeDelegateFromMap(idx);
161 }
162 }
163
164 QScopedValueRollback createBlocker(m_creatingObject, true);
165 for (const QQmlChangeSet::Change &c: changeSet.inserts()) {
166 for (auto idx = c.start(); idx < c.end(); idx++) {
167 QObject *delegateInstance = m_delegateModel->object(idx, m_incubationMode);
168 addDelegateToMap(qobject_cast<QQuickItem *>(delegateInstance), idx);
169 }
170 }
171
172 fitViewport();
173}
174
182{
183 return m_itemModel;
184}
185
187{
188 if (model == m_itemModel)
189 return;
190
191 m_itemModel = model;
192 if (m_componentCompleted)
193 m_delegateModel->setModel(m_itemModel);
194
196}
197
206{
207 return m_delegate;
208}
209
211{
212 if (m_delegate == delegate)
213 return;
214
215 m_delegate = delegate;
216 if (m_componentCompleted)
217 m_delegateModel->setDelegate(m_delegate);
218
220}
221
231{
232 return m_fitViewport;
233}
234
236{
237 if (fit == m_fitViewport)
238 return;
239 m_fitViewport = fit;
240 fitViewport();
242}
243
247void QDeclarativeGeoMapItemView::fitViewport()
248{
249
250 if (!m_map || !m_map->mapReady() || !m_fitViewport)
251 return;
252
253 if (m_map->mapItems().size() > 0)
254 m_map->fitViewportToMapItems();
255}
256
261{
262 if (!map || m_map) // changing map on the fly not supported
263 return;
264 m_map = map;
266}
267
272{
273 if (!m_map)
274 return;
275
276 // with transition = false removeInstantiatedItems aborts ongoing exit transitions //QTBUG-69195
277 // Backward as removeItemFromMap modifies m_instantiatedItems
278 for (qsizetype i = m_instantiatedItems.size() -1; i >= 0 ; i--)
279 removeDelegateFromMap(i, transition);
280}
281
288{
289 // The assumption is that if m_instantiatedItems isn't empty, instantiated items have been already added
290 if (!m_componentCompleted || !m_map || !m_delegate || m_itemModel.isNull() || !m_instantiatedItems.isEmpty())
291 return;
292
293 // If here, m_delegateModel may contain data, but QQmlInstanceModel::object for each row hasn't been called yet.
294 QScopedValueRollback createBlocker(m_creatingObject, true);
295 for (qsizetype i = 0; i < m_delegateModel->count(); i++) {
296 QObject *delegateInstance = m_delegateModel->object(i, m_incubationMode);
297 addDelegateToMap(qobject_cast<QQuickItem *>(delegateInstance), i);
298 }
299
300 fitViewport();
301}
302
304{
305 const QQmlIncubator::IncubationMode incubationMode =
307 if (m_incubationMode == incubationMode)
308 return;
309 m_incubationMode = incubationMode;
311}
312
314{
315 return m_incubationMode == QQmlIncubator::Asynchronous;
316}
317
318QList<QQuickItem *> QDeclarativeGeoMapItemView::mapItems()
319{
320 return m_instantiatedItems;
321}
322
323QQmlInstanceModel::ReleaseFlags QDeclarativeGeoMapItemView::disposeDelegate(QQuickItem *item)
324{
325 disconnect(item, 0, this, 0);
326 removeDelegateFromMap(item);
327 item->setParentItem(nullptr); // Needed because
328 item->setParent(nullptr); // m_delegateModel->release(item) does not destroy the item most of the times!!
329 QQmlInstanceModel::ReleaseFlags releaseStatus = m_delegateModel->release(item);
330 return releaseStatus;
331}
332
333void QDeclarativeGeoMapItemView::removeDelegateFromMap(int index, bool transition)
334{
335 if (index >= 0 && index < m_instantiatedItems.size()) {
336 QQuickItem *item = m_instantiatedItems.takeAt(index);
337 if (!item) { // not yet incubated
338 // Don't cancel incubation explicitly when model rows are removed, as DelegateModel
339 // apparently takes care of incubating elements when the model remove those indices.
340 // Cancel them explicitly only when a MIV is removed from a map.
341 if (!transition)
342 m_delegateModel->cancel(index);
343 return;
344 }
345 // item can be either a QDeclarativeGeoMapItemBase or a QDeclarativeGeoMapItemGroup (subclass)
346 if (m_exit && m_map && transition) {
347 transitionItemOut(item);
348 } else {
349 if (m_exit && m_map && !transition) {
350 // check if the exit transition is still running, if so stop it.
351 // This can happen when explicitly calling Map.removeMapItemView, soon after adding it.
352 terminateExitTransition(item);
353 }
354 QQmlInstanceModel::ReleaseFlags releaseStatus = disposeDelegate(item);
355#ifdef QT_DEBUG
356 if (releaseStatus == QQmlInstanceModel::Referenced)
357 qWarning() << "item "<< index << "(" << item << ") still referenced";
358#else
359 Q_UNUSED(releaseStatus);
360#endif
361 }
362 }
363}
364
365void QDeclarativeGeoMapItemView::removeDelegateFromMap(QQuickItem *o)
366{
367 if (!m_map)
368 return;
369
370 QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(o);
371 if (item) {
372 m_map->removeMapItem(item);
373 return;
374 }
375 QDeclarativeGeoMapItemView *view = qobject_cast<QDeclarativeGeoMapItemView *>(o);
376 if (view) {
377 m_map->removeMapItemView(view);
378 return;
379 }
380 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(o);
381 if (group) {
383 return;
384 }
385}
386
387void QDeclarativeGeoMapItemView::transitionItemOut(QQuickItem *o)
388{
389 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(o);
390 if (group) {
391 if (!group->m_transitionManager) {
392 std::unique_ptr<QDeclarativeGeoMapItemTransitionManager>manager(new QDeclarativeGeoMapItemTransitionManager(group));
393 group->m_transitionManager.swap(manager);
394 group->m_transitionManager->m_view = this;
395 }
397 this, &QDeclarativeGeoMapItemView::exitTransitionFinished);
398
399 group->m_transitionManager->transitionExit();
400 return;
401 }
402 QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(o);
403 if (item) {
404 if (!item->m_transitionManager) {
405 std::unique_ptr<QDeclarativeGeoMapItemTransitionManager> manager(new QDeclarativeGeoMapItemTransitionManager(item));
406 item->m_transitionManager.swap(manager);
407 item->m_transitionManager->m_view = this;
408 }
409 connect(item, &QDeclarativeGeoMapItemBase::removeTransitionFinished,
410 this, &QDeclarativeGeoMapItemView::exitTransitionFinished);
411
412 item->m_transitionManager->transitionExit();
413 return;
414 }
415}
416
417void QDeclarativeGeoMapItemView::terminateExitTransition(QQuickItem *o)
418{
419 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(o);
420 if (group && group->m_transitionManager) {
421 group->m_transitionManager->cancel();
422 return;
423 }
424 QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(o);
425 if (item && item->m_transitionManager) {
426 item->m_transitionManager->cancel();
427 return;
428 }
429}
430
431void QDeclarativeGeoMapItemView::exitTransitionFinished()
432{
434 if (!item)
435 return;
436 QQmlInstanceModel::ReleaseFlags releaseStatus = disposeDelegate(item);
437#ifdef QT_DEBUG
438 if (releaseStatus == QQmlInstanceModel::Referenced)
439 qWarning() << "item "<<item<<" still referenced";
440#else
441 Q_UNUSED(releaseStatus);
442#endif
443}
444
445void QDeclarativeGeoMapItemView::addItemToMap(QDeclarativeGeoMapItemBase *item, int index, bool createdItem)
446{
447
448 if (m_map && item->quickMap() == m_map) // test for *item done in the caller
449 return;
450
451 if (m_map) {
452 insertInstantiatedItem(index, item, createdItem);
453 item->setParentItem(this);
454 m_map->addMapItem(item);
455 if (m_enter) {
456 if (!item->m_transitionManager) {
457 std::unique_ptr<QDeclarativeGeoMapItemTransitionManager>manager(new QDeclarativeGeoMapItemTransitionManager(item));
458 item->m_transitionManager.swap(manager);
459 }
460 item->m_transitionManager->m_view = this;
461 item->m_transitionManager->transitionEnter();
462 }
463 }
464}
465
466void QDeclarativeGeoMapItemView::insertInstantiatedItem(int index, QQuickItem *o, bool createdItem)
467{
468 if (createdItem)
469 m_instantiatedItems.replace(index, o);
470 else
471 m_instantiatedItems.insert(index, o);
472}
473
474void QDeclarativeGeoMapItemView::addItemViewToMap(QDeclarativeGeoMapItemView *item, int index, bool createdItem)
475{
476 if (m_map && item->quickMap() == m_map) // test for *item done in the caller
477 return;
478
479 if (m_map) {
480 insertInstantiatedItem(index, item, createdItem);
481 item->setParentItem(this);
482 m_map->addMapItemView(item);
483 if (m_enter) {
484 if (!item->m_transitionManager) {
485 std::unique_ptr<QDeclarativeGeoMapItemTransitionManager> manager(new QDeclarativeGeoMapItemTransitionManager(item));
486 item->m_transitionManager.swap(manager);
487 }
488 item->m_transitionManager->m_view = this;
489 item->m_transitionManager->transitionEnter();
490 }
491 }
492}
493
494void QDeclarativeGeoMapItemView::addItemGroupToMap(QDeclarativeGeoMapItemGroup *item, int index, bool createdItem)
495{
496 if (m_map && item->quickMap() == m_map) // test for *item done in the caller
497 return;
498
499 if (m_map) {
500 insertInstantiatedItem(index, item, createdItem);
501 item->setParentItem(this);
502 m_map->addMapItemGroup(item);
503 if (m_enter) {
504 if (!item->m_transitionManager) {
505 std::unique_ptr<QDeclarativeGeoMapItemTransitionManager>manager(new QDeclarativeGeoMapItemTransitionManager(item));
506 item->m_transitionManager.swap(manager);
507 }
508 item->m_transitionManager->m_view = this;
509 item->m_transitionManager->transitionEnter();
510 }
511 }
512}
513
514void QDeclarativeGeoMapItemView::addDelegateToMap(QQuickItem *object, int index, bool createdItem)
515{
516 if (!object) {
517 if (!createdItem)
518 m_instantiatedItems.insert(index, nullptr); // insert placeholder
519 return;
520 }
521 QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(object);
522 if (item) { // else createdItem will be emitted.
523 addItemToMap(item, index, createdItem);
524 return;
525 }
526 QDeclarativeGeoMapItemView *view = qobject_cast<QDeclarativeGeoMapItemView *>(object);
527 if (view) {
528 addItemViewToMap(view, index, createdItem);
529 return;
530 }
531 QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(object);
532 if (group) {
533 addItemGroupToMap(group, index, createdItem);
534 return;
535 }
536 qWarning() << "addDelegateToMap called with a "<< object->metaObject()->className();
537}
538
540
541
void classBegin() override
Invoked after class creation, but before any properties have been set.
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void removeInstantiatedItems(bool transition=true)
void classBegin() override
Invoked after class creation, but before any properties have been set.
void setIncubateDelegates(bool useIncubators)
Q_INVOKABLE void removeMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
\qmlmethod void QtLocation::Map::removeMapItemGroup(MapItemGroup itemGroup)
Q_INVOKABLE void fitViewportToMapItems(const QVariantList &items={})
\qmlmethod void QtLocation::Map::fitViewportToMapItems(list<MapItems> items = {})
Q_INVOKABLE void removeMapItemView(QDeclarativeGeoMapItemView *itemView)
\qmlmethod void QtLocation::Map::removeMapItemView(MapItemView itemView)
Q_INVOKABLE void addMapItemGroup(QDeclarativeGeoMapItemGroup *itemGroup)
\qmlmethod void QtLocation::Map::addMapItemGroup(MapItemGroup itemGroup)
Q_INVOKABLE void removeMapItem(QDeclarativeGeoMapItemBase *item)
\qmlmethod void QtLocation::Map::removeMapItem(MapItem item)
QList< QObject * > mapItems
\qmlproperty list<MapItem> QtLocation::Map::mapItems
Q_INVOKABLE void addMapItemView(QDeclarativeGeoMapItemView *itemView)
\qmlmethod void QtLocation::Map::addMapItemView(MapItemView itemView)
Q_INVOKABLE void addMapItem(QDeclarativeGeoMapItemBase *item)
\qmlmethod void QtLocation::Map::addMapItem(MapItem item)
void setParentItem(QGraphicsItem *parent)
Sets this item's parent item to newParent.
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:488
T takeAt(qsizetype i)
Definition qlist.h:609
void replace(qsizetype i, parameter_type t)
Definition qlist.h:543
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QObject * sender() const
Returns a pointer to the object that sent the signal, if called in a slot activated by a signal; othe...
Definition qobject.cpp:2658
The QQmlChangeSet class stores an ordered list of notifications about changes to a linear data set.
const QVector< Change > & removes() const
The QQmlComponent class encapsulates a QML component definition.
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
void setModel(const QVariant &)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setDelegate(QQmlComponent *)
int count() const override
\qmlproperty int QtQml.Models::DelegateModel::count
void classBegin() override
Invoked after class creation, but before any properties have been set.
QObject * object(int index, QQmlIncubator::IncubationMode incubationMode=QQmlIncubator::AsynchronousIfNested) override
ReleaseFlags release(QObject *object, ReusableFlag reusableFlag=NotReusable) override
void cancel(int index) override
IncubationMode
Specifies the mode the incubator operates in.
void createdItem(int index, QObject *object)
void modelUpdated(const QQmlChangeSet &changeSet, bool reset)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QQmlListProperty< QQuickAbstractAnimation > animations
\qmlproperty list<Animation> QtQuick::Transition::animations \qmldefault
\inmodule QtCore
Definition qvariant.h:65
bool isNull() const
Returns true if this is a null variant, false otherwise.
EGLContext ctx
QMap< QString, QString > map
[6]
Combined button and popup list for selecting options.
#define qWarning
Definition qlogging.h:166
GLuint index
[2]
GLboolean GLuint group
GLboolean reset
const GLubyte * c
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:492
#define QStringLiteral(str)
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
QSqlQueryModel * model
[16]
myObject disconnect()
[26]
QGraphicsItem * item
QNetworkAccessManager manager
QQuickView * view
[0]