diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-04-10 12:55:44 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2019-04-10 13:06:13 +0000 |
commit | 5c53cd23351a1850f170dcf2fdcab7545cac3ddc (patch) | |
tree | 512c84a05e9898e98f2cd7ecbfbcede030ad22ea /src/location/declarativemaps | |
parent | c5311b1e937320f78fdd752704b6a34b34a522ca (diff) | |
parent | e4bbd4d159b493b6045c867d508bb0bd59cca847 (diff) | |
download | qtlocation-5c53cd23351a1850f170dcf2fdcab7545cac3ddc.tar.gz |
Merge "Merge remote-tracking branch 'origin/5.13' into dev" into refs/staging/dev
Diffstat (limited to 'src/location/declarativemaps')
4 files changed, 77 insertions, 42 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index 31935faa..4074bcad 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -234,33 +234,45 @@ QDeclarativeGeoMap::~QDeclarativeGeoMap() m_map->clearMapItems(); } - // This forces the destruction of the associated items now, not when QObject destructor is called, at which point - // QDeclarativeGeoMap is long gone + // Remove the items from the map, making them deletable. + // Go in the same order as in removeMapChild: views, groups, then items if (!m_mapViews.isEmpty()) { - for (QDeclarativeGeoMapItemView *v : qAsConst(m_mapViews)) { + const auto mapViews = m_mapViews; + for (QDeclarativeGeoMapItemView *v : mapViews) { // so that removeMapItemView_real can safely modify m_mapViews; if (!v) continue; - if (v->parent() == this) { - delete v; - } else { - // FIXME: removeInstantiatedItems should abort, as well as exit transitions terminated - v->removeInstantiatedItems(false); - v->m_map = nullptr; - } + + QQuickItem *parent = v->parentItem(); + QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent); + if (group) + continue; // Ignore non-top-level MIVs. They will be recursively processed. + // Identify them as being parented by a MapItemGroup. + + removeMapItemView_real(v); } } - // remove any map items associations - for (int i = 0; i < m_mapItems.count(); ++i) { - if (m_mapItems.at(i)) - m_mapItems.at(i).data()->setMap(0,0); - } - // remove any map item groups associations - for (int i = 0; i < m_mapItemGroups.count(); ++i) { - if (m_mapItemGroups.at(i)) - m_mapItemGroups.at(i).data()->setQuickMap(nullptr); + if (!m_mapItemGroups.isEmpty()) { + const auto mapGroups = m_mapItemGroups; + for (QDeclarativeGeoMapItemGroup *g : mapGroups) { + if (!g) + continue; + + QQuickItem *parent =g->parentItem(); + QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(parent); + if (group) + continue; // Ignore non-top-level Groups. They will be recursively processed. + // Identify them as being parented by a MapItemGroup. + + removeMapItemGroup_real(g); + } } + // remove any remaining map items associations + const auto mapItems = m_mapItems; + for (auto mi: mapItems) + removeMapItem_real(mi.data()); + if (m_copyrights.data()) delete m_copyrights.data(); m_copyrights.clear(); @@ -2135,14 +2147,10 @@ bool QDeclarativeGeoMap::removeMapItemView_real(QDeclarativeGeoMapItemView *item if (!itemView || itemView->m_map != this) // can't remove a view that is already added to another map return false; - // Leaving this as void since the removal is async (potentially transitioned) - // && the delegates *could* be empty mapItemGroups. - itemView->removeInstantiatedItems(); + itemView->removeInstantiatedItems(false); // remove the items without using transitions AND abort ongoing ones itemView->m_map = 0; - // it can be removed from the list at this point, since no operations that require a Map have to be done - // anymore on destruction. m_mapViews.removeOne(itemView); - return removeMapItemGroup_real(itemView); // at this point, delegate instances have been removed. + return removeMapItemGroup_real(itemView); // at this point, all delegate instances have been removed. } /*! diff --git a/src/location/declarativemaps/qdeclarativegeomapitemview.cpp b/src/location/declarativemaps/qdeclarativegeomapitemview.cpp index a769a0c9..3208829c 100644 --- a/src/location/declarativemaps/qdeclarativegeomapitemview.cpp +++ b/src/location/declarativemaps/qdeclarativegeomapitemview.cpp @@ -107,7 +107,8 @@ QDeclarativeGeoMapItemView::QDeclarativeGeoMapItemView(QQuickItem *parent) QDeclarativeGeoMapItemView::~QDeclarativeGeoMapItemView() { - removeInstantiatedItems(); + // No need to remove instantiated items: if the MIV has instantiated items because it has been added + // to a Map (or is child of a Map), the Map destructor takes care of removing it and the instantiated items. } /*! @@ -309,7 +310,7 @@ void QDeclarativeGeoMapItemView::removeInstantiatedItems(bool transition) if (!m_map) return; - // FIXME: removeInstantiatedItems should abort, as well as exit transitions terminated QTBUG-69195 + // with transition = false removeInstantiatedItems aborts ongoing exit transitions //QTBUG-69195 // Backward as removeItemFromMap modifies m_instantiatedItems for (int i = m_instantiatedItems.size() -1; i >= 0 ; i--) removeDelegateFromMap(i, transition); @@ -356,24 +357,38 @@ QList<QQuickItem *> QDeclarativeGeoMapItemView::mapItems() return m_instantiatedItems; } +QQmlInstanceModel::ReleaseFlags QDeclarativeGeoMapItemView::disposeDelegate(QQuickItem *item) +{ + disconnect(item, 0, this, 0); + removeDelegateFromMap(item); + item->setParentItem(nullptr); // Needed because + item->setParent(nullptr); // m_delegateModel->release(item) does not destroy the item most of the times!! + QQmlInstanceModel::ReleaseFlags releaseStatus = m_delegateModel->release(item); + return releaseStatus; +} + void QDeclarativeGeoMapItemView::removeDelegateFromMap(int index, bool transition) { if (index >= 0 && index < m_instantiatedItems.size()) { QQuickItem *item = m_instantiatedItems.takeAt(index); if (!item) { // not yet incubated - // Don't cancel incubation explicitly, as DelegateModel apparently takes care of incubating elements when the model - // remove those indices. + // Don't cancel incubation explicitly when model rows are removed, as DelegateModel + // apparently takes care of incubating elements when the model remove those indices. + // Cancel them explicitly only when a MIV is removed from a map. + if (!transition) + m_delegateModel->cancel(index); return; } // item can be either a QDeclarativeGeoMapItemBase or a QDeclarativeGeoMapItemGroup (subclass) - if (m_exit && m_map && transition) { + if (m_exit && m_map && transition) { transitionItemOut(item); } else { - disconnect(item, 0, this, 0); - removeDelegateFromMap(item); - item->setParentItem(nullptr); // Needed because - item->setParent(nullptr); // m_delegateModel->release(item) does not destroy the item most of the times!! - QQmlInstanceModel::ReleaseFlags releaseStatus = m_delegateModel->release(item); + if (m_exit && m_map && !transition) { + // check if the exit transition is still running, if so stop it. + // This can happen when explicitly calling Map.removeMapItemView, soon after adding it. + terminateExitTransition(item); + } + QQmlInstanceModel::ReleaseFlags releaseStatus = disposeDelegate(item); #ifdef QT_DEBUG if (releaseStatus == QQmlInstanceModel::Referenced) qWarning() << "item "<< index << "(" << item << ") still referenced"; @@ -436,16 +451,26 @@ void QDeclarativeGeoMapItemView::transitionItemOut(QQuickItem *o) } } +void QDeclarativeGeoMapItemView::terminateExitTransition(QQuickItem *o) +{ + QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(o); + if (group && group->m_transitionManager) { + group->m_transitionManager->cancel(); + return; + } + QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(o); + if (item && item->m_transitionManager) { + item->m_transitionManager->cancel(); + return; + } +} + void QDeclarativeGeoMapItemView::exitTransitionFinished() { QQuickItem *item = qobject_cast<QQuickItem *>(sender()); if (!item) return; - disconnect(item, 0, this, 0); - removeDelegateFromMap(item); - item->setParentItem(nullptr); - item->setParent(nullptr); - QQmlInstanceModel::ReleaseFlags releaseStatus = m_delegateModel->release(item); + QQmlInstanceModel::ReleaseFlags releaseStatus = disposeDelegate(item); #ifdef QT_DEBUG if (releaseStatus == QQmlInstanceModel::Referenced) qWarning() << "item "<<item<<" still referenced"; diff --git a/src/location/declarativemaps/qdeclarativegeomapitemview_p.h b/src/location/declarativemaps/qdeclarativegeomapitemview_p.h index 43ca685a..abac5bd5 100644 --- a/src/location/declarativemaps/qdeclarativegeomapitemview_p.h +++ b/src/location/declarativemaps/qdeclarativegeomapitemview_p.h @@ -130,6 +130,8 @@ private: void removeDelegateFromMap(int index, bool transition = true); void removeDelegateFromMap(QQuickItem *o); void transitionItemOut(QQuickItem *o); + void terminateExitTransition(QQuickItem *o); + QQmlInstanceModel::ReleaseFlags disposeDelegate(QQuickItem *item); void insertInstantiatedItem(int index, QQuickItem *o, bool createdItem); void addItemToMap(QDeclarativeGeoMapItemBase *item, int index, bool createdItem); diff --git a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp index 06a03791..4be64642 100644 --- a/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp +++ b/src/location/declarativemaps/qdeclarativegeoroutemodel.cpp @@ -115,8 +115,8 @@ static QList<QVariantMap> waypointMetadata(const QList<QDeclarativeGeoWaypoint * geographic routes from a backend provider. Routes include data about driving directions between two points, walking directions with multiple waypoints, and various other similar concepts. It functions much like other Model - types in QML (see for example \l {Models and Views in Qt Quick#Models}{ListModel} and - \l XmlListModel), and interacts with views such as \l MapItemView, and \l{ListView}. + types in QML (see for example \l {Models and Views in Qt Quick#Models}{ListModel}), + and interacts with views such as \l MapItemView, and \l{ListView}. Like \l Map and \l GeocodeModel, all the data for a RouteModel to work comes from a services plugin. This is contained in the \l{plugin} property, and |