diff options
author | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-11-05 18:35:36 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2015-11-06 18:36:33 +0000 |
commit | 5cc36f74ef86e0fcc5a44c8ca32448a8efeaa8d3 (patch) | |
tree | 920dae0917fcd85638e6d1a58f95bcc1f6d1c675 /src/templates/qquickcontainer.cpp | |
parent | dbdb8960ebc3e2fe7a91185c521d53c688411930 (diff) |
Container: fix stack before/after warnings
When inserting items to a Container, reparent them to the "effective"
content item. If the Container's content item is a ListView (Flickable),
the effective content item is the content item of the ListView, not the
ListView itself.
Change-Id: I8c4abbac811b0aa6b56f2cdf87656a01279d5bf7
Task-number: QTBUG-48720
Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
Diffstat (limited to 'src/templates/qquickcontainer.cpp')
-rw-r--r-- | src/templates/qquickcontainer.cpp | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/src/templates/qquickcontainer.cpp b/src/templates/qquickcontainer.cpp index ce2031a5..9a021aa3 100644 --- a/src/templates/qquickcontainer.cpp +++ b/src/templates/qquickcontainer.cpp @@ -37,6 +37,8 @@ #include "qquickcontainer_p.h" #include "qquickcontainer_p_p.h" +#include <QtQuick/private/qquickflickable_p.h> + QT_BEGIN_NAMESPACE /*! @@ -52,6 +54,14 @@ QT_BEGIN_NAMESPACE \sa {Container Controls} */ +static QQuickItem *effectiveContentItem(QQuickItem *item) +{ + QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(item); + if (flickable) + return flickable->contentItem(); + return item; +} + QQuickContainerPrivate::QQuickContainerPrivate() : contentModel(Q_NULLPTR), currentIndex(-1), updatingCurrent(false) { } @@ -87,10 +97,11 @@ QQuickItem *QQuickContainerPrivate::itemAt(int index) const void QQuickContainerPrivate::insertItem(int index, QQuickItem *item) { Q_Q(QQuickContainer); - contentData.append(item); if (!q->isContent(item)) return; + contentData.append(item); + item->setParentItem(effectiveContentItem(contentItem)); QQuickItemPrivate::get(item)->addItemChangeListener(this, QQuickItemPrivate::Destroyed | QQuickItemPrivate::Parent); contentModel->insert(index, item); @@ -119,9 +130,9 @@ void QQuickContainerPrivate::moveItem(int from, int to) void QQuickContainerPrivate::removeItem(int index, QQuickItem *item) { Q_Q(QQuickContainer); - contentData.removeOne(item); if (!q->isContent(item)) return; + contentData.removeOne(item); bool currentChanged = false; if (index == currentIndex) { @@ -151,7 +162,7 @@ void QQuickContainerPrivate::_q_currentIndexChanged() void QQuickContainerPrivate::itemChildAdded(QQuickItem *, QQuickItem *child) { // add dynamically reparented items (eg. by a Repeater) - if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && contentModel->indexOf(child, Q_NULLPTR) == -1) + if (!QQuickItemPrivate::get(child)->isTransparentForPositioner() && !contentData.contains(child)) insertItem(contentModel->count(), child); } @@ -166,7 +177,7 @@ void QQuickContainerPrivate::itemSiblingOrderChanged(QQuickItem *) { // reorder the restacked items (eg. by a Repeater) Q_Q(QQuickContainer); - QList<QQuickItem *> siblings = contentItem->childItems(); + QList<QQuickItem *> siblings = effectiveContentItem(contentItem)->childItems(); for (int i = 0; i < siblings.count(); ++i) { QQuickItem* sibling = siblings.at(i); int index = contentModel->indexOf(sibling, Q_NULLPTR); @@ -189,7 +200,7 @@ void QQuickContainerPrivate::contentData_append(QQmlListProperty<QObject> *prop, if (item) { if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder); - item->setParentItem(p->contentItem); + item->setParentItem(effectiveContentItem(p->contentItem)); } else if (p->contentModel->indexOf(item, Q_NULLPTR) == -1) { q->addItem(item); } @@ -454,6 +465,9 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem if (oldItem) { QQuickItemPrivate::get(oldItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItem *oldContentItem = effectiveContentItem(oldItem); + if (oldContentItem != oldItem) + QQuickItemPrivate::get(oldContentItem)->removeItemChangeListener(d, QQuickItemPrivate::Children); int signalIndex = oldItem->metaObject()->indexOfSignal("currentIndexChanged()"); if (signalIndex != -1) @@ -462,6 +476,9 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem if (newItem) { QQuickItemPrivate::get(newItem)->addItemChangeListener(d, QQuickItemPrivate::Children); + QQuickItem *newContentItem = effectiveContentItem(newItem); + if (newContentItem != newItem) + QQuickItemPrivate::get(newContentItem)->addItemChangeListener(d, QQuickItemPrivate::Children); int signalIndex = newItem->metaObject()->indexOfSignal("currentIndexChanged()"); if (signalIndex != -1) @@ -471,8 +488,13 @@ void QQuickContainer::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem bool QQuickContainer::isContent(QQuickItem *item) const { - Q_UNUSED(item); - return true; + // If the item has a QML context associated to it (it was created in QML), + // we add it to the content model. Otherwise, it's probably the default + // highlight item that is always created by the item views, which we need + // to exclude. + // + // TODO: Find a better way to identify/exclude the highlight item... + return qmlContext(item); } void QQuickContainer::itemAdded(int index, QQuickItem *item) |