aboutsummaryrefslogtreecommitdiffstats
path: root/src/templates/qquickcontainer.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-11-05 18:35:36 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-11-06 18:36:33 +0000
commit5cc36f74ef86e0fcc5a44c8ca32448a8efeaa8d3 (patch)
tree920dae0917fcd85638e6d1a58f95bcc1f6d1c675 /src/templates/qquickcontainer.cpp
parentdbdb8960ebc3e2fe7a91185c521d53c688411930 (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.cpp36
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)