From 1e1a76b88192713bbdfd3b81f7310d496a644e9c Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Wed, 3 Jun 2015 15:55:30 +0200 Subject: Item views: don't assume that attached objects exist Attached properties are only on objects created by QML. In case a QQmlInstanceModel contains items that were created in C++, the attached properties object doesn't exist. Adding the missing null checks avoids a crash in such scenario. Change-Id: I93148ac6cefa4cb83a8a7eb24a84b125aaa443d2 Reviewed-by: Alan Alpert --- src/quick/items/qquickitemview.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 20d7eba45a..ce4d9b6313 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1199,7 +1199,7 @@ void QQuickItemView::destroyRemoved() for (QList::Iterator it = d->visibleItems.begin(); it != d->visibleItems.end();) { FxViewItem *item = *it; - if (item->index == -1 && item->attached->delayRemove() == false) { + if (item->index == -1 && (!item->attached || item->attached->delayRemove() == false)) { if (d->transitioner && d->transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true)) { // don't remove from visibleItems until next layout() d->runDelayedRemoveTransition = true; @@ -1641,7 +1641,8 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) applyPendingChanges(); if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) { if (currentItem) { - currentItem->attached->setIsCurrentItem(false); + if (currentItem->attached) + currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); currentItem = 0; currentIndex = modelIndex; @@ -1664,11 +1665,12 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex) int oldCurrentIndex = currentIndex; currentIndex = modelIndex; currentItem = createItem(modelIndex, false); - if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item)) + if (oldCurrentItem && oldCurrentItem->attached && (!currentItem || oldCurrentItem->item != currentItem->item)) oldCurrentItem->attached->setIsCurrentItem(false); if (currentItem) { currentItem->item->setFocus(true); - currentItem->attached->setIsCurrentItem(true); + if (currentItem->attached) + currentItem->attached->setIsCurrentItem(true); initializeCurrentItem(); } @@ -1967,7 +1969,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult QQmlChangeSet::Change removal; for (QList::Iterator it = visibleItems.begin(); it != visibleItems.end();) { FxViewItem *item = *it; - if (item->index == -1 && !item->attached->delayRemove()) { + if (item->index == -1 && (!item->attached || !item->attached->delayRemove())) { removeItem(item, removal, &removalResult); removedCount++; it = visibleItems.erase(it); @@ -2007,8 +2009,10 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult } itemCount += insertions[i].count; } - for (int i=0; iattached->emitAdd(); + for (int i=0; iattached) + newItems.at(i)->attached->emitAdd(); + } // for each item that was moved directly into the view as a result of a move(), // find the index it was moved from in order to set its initial position, so that we @@ -2039,7 +2043,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult currentChanges.removedItems.clear(); if (currentChanges.currentChanged) { - if (currentChanges.currentRemoved && currentItem) { + if (currentChanges.currentRemoved && currentItem && currentItem->attached) { currentItem->attached->setIsCurrentItem(false); releaseItem(currentItem); currentItem = 0; @@ -2092,10 +2096,10 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQmlChangeSet::Change &remo } else { // removed item visibleAffected = true; - if (!removal.isMove()) + if (!removal.isMove() && item->attached) item->attached->emitRemove(); - if (item->attached->delayRemove() && !removal.isMove()) { + if (item->attached && item->attached->delayRemove() && !removal.isMove()) { item->index = -1; QObject::connect(item->attached, SIGNAL(delayRemoveChanged()), q, SLOT(destroyRemoved()), Qt::QueuedConnection); ++it; -- cgit v1.2.3