aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2015-10-11 00:04:55 +0200
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2015-10-11 13:05:28 +0000
commitaa634f86429ad15fced74a5a65e7d170b5e7e9ff (patch)
tree21e24400e65ff10e5f45a6b93230de77b9f36aa1
parent9d4c6278217fecefa15c52073f8de0e6f0e7700d (diff)
Fix StackView attached property
The attached properties weren't initialized at all for the initial item. Furthermore, the properties were initialized lazily, which made them work for imperative tests, but not correctly in bindings. Change-Id: I783c406dcf4e1cf27a6b4e6ddd43214cb06a3c7a Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
-rw-r--r--src/templates/qquickstackview.cpp44
-rw-r--r--src/templates/qquickstackview_p.cpp28
-rw-r--r--src/templates/qquickstackview_p.h1
-rw-r--r--src/templates/qquickstackview_p_p.h8
-rw-r--r--tests/auto/controls/data/tst_stackview.qml35
5 files changed, 75 insertions, 41 deletions
diff --git a/src/templates/qquickstackview.cpp b/src/templates/qquickstackview.cpp
index 4439e176..1883d9d0 100644
--- a/src/templates/qquickstackview.cpp
+++ b/src/templates/qquickstackview.cpp
@@ -673,6 +673,7 @@ void QQuickStackView::componentComplete()
if (d->pushElement(element)) {
emit depthChanged();
d->setCurrentItem(element->item);
+ element->setStatus(QQuickStackView::Active);
}
}
@@ -702,39 +703,40 @@ bool QQuickStackView::childMouseEventFilter(QQuickItem *, QEvent *)
return true;
}
-void QQuickStackAttachedPrivate::init()
-{
- QQuickItem *item = qobject_cast<QQuickItem *>(parent);
- if (item) {
- QQuickStackView *view = qobject_cast<QQuickStackView *>(item->parentItem());
- if (view) {
- element = QQuickStackViewPrivate::get(view)->findElement(item);
- if (element)
- initialized = true;
- }
- }
-}
-
-void QQuickStackAttachedPrivate::reset()
+void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent)
{
Q_Q(QQuickStackAttached);
int oldIndex = element ? element->index : -1;
QQuickStackView *oldView = element ? element->view : Q_NULLPTR;
QQuickStackView::Status oldStatus = element ? element->status : QQuickStackView::Inactive;
- element = Q_NULLPTR;
+ QQuickStackView *newView = qobject_cast<QQuickStackView *>(parent);
+ element = newView ? QQuickStackViewPrivate::get(newView)->findElement(item) : Q_NULLPTR;
- if (oldIndex != -1)
+ int newIndex = element ? element->index : -1;
+ QQuickStackView::Status newStatus = element ? element->status : QQuickStackView::Inactive;
+
+ if (oldIndex != newIndex)
emit q->indexChanged();
- if (oldView)
+ if (oldView != newView)
emit q->viewChanged();
- if (oldStatus != QQuickStackView::Inactive)
+ if (oldStatus != newStatus)
emit q->statusChanged();
}
QQuickStackAttached::QQuickStackAttached(QQuickItem *parent) :
QObject(*(new QQuickStackAttachedPrivate), parent)
{
+ Q_D(QQuickStackAttached);
+ QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Parent);
+ d->itemParentChanged(parent, parent->parentItem());
+}
+
+QQuickStackAttached::~QQuickStackAttached()
+{
+ Q_D(QQuickStackAttached);
+ QQuickItem *parentItem = static_cast<QQuickItem *>(parent());
+ QQuickItemPrivate::get(parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Parent);
}
/*!
@@ -745,8 +747,6 @@ QQuickStackAttached::QQuickStackAttached(QQuickItem *parent) :
int QQuickStackAttached::index() const
{
Q_D(const QQuickStackAttached);
- if (!d->initialized)
- const_cast<QQuickStackAttachedPrivate *>(d)->init();
return d->element ? d->element->index : -1;
}
@@ -758,8 +758,6 @@ int QQuickStackAttached::index() const
QQuickStackView *QQuickStackAttached::view() const
{
Q_D(const QQuickStackAttached);
- if (!d->initialized)
- const_cast<QQuickStackAttachedPrivate *>(d)->init();
return d->element ? d->element->view : Q_NULLPTR;
}
@@ -771,8 +769,6 @@ QQuickStackView *QQuickStackAttached::view() const
QQuickStackView::Status QQuickStackAttached::status() const
{
Q_D(const QQuickStackAttached);
- if (!d->initialized)
- const_cast<QQuickStackAttachedPrivate *>(d)->init();
return d->element ? d->element->status : QQuickStackView::Inactive;
}
diff --git a/src/templates/qquickstackview_p.cpp b/src/templates/qquickstackview_p.cpp
index 498cc44c..a66e7d21 100644
--- a/src/templates/qquickstackview_p.cpp
+++ b/src/templates/qquickstackview_p.cpp
@@ -48,9 +48,12 @@
QT_BEGIN_NAMESPACE
-static QQuickStackAttached *attachedStackObject(QQuickItem *item)
+static QQuickStackAttached *attachedStackObject(QQuickStackElement *element)
{
- return qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(item, false));
+ QQuickStackAttached *attached = qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item, false));
+ if (attached)
+ QQuickStackAttachedPrivate::get(attached)->element = element;
+ return attached;
}
class QQuickStackIncubator : public QQmlIncubator
@@ -74,14 +77,9 @@ QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(Q_NU
QQuickStackElement::~QQuickStackElement()
{
- if (item) {
+ if (item)
QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
- QQuickStackAttached *attached = attachedStackObject(item);
- if (attached)
- QQuickStackAttachedPrivate::get(attached)->reset();
- }
-
if (ownComponent)
delete component;
@@ -91,7 +89,13 @@ QQuickStackElement::~QQuickStackElement()
item = Q_NULLPTR;
} else if (item) {
item->setVisible(false);
- item->setParentItem(originalParent);
+ if (item->parentItem() != originalParent) {
+ item->setParentItem(originalParent);
+ } else {
+ QQuickStackAttached *attached = attachedStackObject(this);
+ if (attached)
+ QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, Q_NULLPTR);
+ }
}
delete context;
@@ -182,7 +186,7 @@ void QQuickStackElement::setIndex(int value)
{
if (index != value) {
index = value;
- QQuickStackAttached *attached = attachedStackObject(item);
+ QQuickStackAttached *attached = attachedStackObject(this);
if (attached)
emit attached->indexChanged();
}
@@ -192,7 +196,7 @@ void QQuickStackElement::setView(QQuickStackView *value)
{
if (view != value) {
view = value;
- QQuickStackAttached *attached = attachedStackObject(item);
+ QQuickStackAttached *attached = attachedStackObject(this);
if (attached)
emit attached->viewChanged();
}
@@ -202,7 +206,7 @@ void QQuickStackElement::setStatus(QQuickStackView::Status value)
{
if (status != value) {
status = value;
- QQuickStackAttached *attached = attachedStackObject(item);
+ QQuickStackAttached *attached = attachedStackObject(this);
if (attached)
emit attached->statusChanged();
}
diff --git a/src/templates/qquickstackview_p.h b/src/templates/qquickstackview_p.h
index a530738a..7f989faf 100644
--- a/src/templates/qquickstackview_p.h
+++ b/src/templates/qquickstackview_p.h
@@ -157,6 +157,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickStackAttached : public QObject
public:
explicit QQuickStackAttached(QQuickItem *parent = Q_NULLPTR);
+ ~QQuickStackAttached();
int index() const;
QQuickStackView *view() const;
diff --git a/src/templates/qquickstackview_p_p.h b/src/templates/qquickstackview_p_p.h
index 39a57a5d..5dfe7037 100644
--- a/src/templates/qquickstackview_p_p.h
+++ b/src/templates/qquickstackview_p_p.h
@@ -139,22 +139,20 @@ public:
QQuickItemViewTransitioner *transitioner;
};
-class QQuickStackAttachedPrivate : public QObjectPrivate
+class QQuickStackAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickStackAttached)
public:
- QQuickStackAttachedPrivate() : initialized(false), element(Q_NULLPTR) { }
+ QQuickStackAttachedPrivate() : element(Q_NULLPTR) { }
static QQuickStackAttachedPrivate *get(QQuickStackAttached *attached)
{
return attached->d_func();
}
- void init();
- void reset();
+ void itemParentChanged(QQuickItem *item, QQuickItem *parent);
- bool initialized;
QQuickStackElement *element;
};
diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml
index f54cd9ae..3dc6d0c9 100644
--- a/tests/auto/controls/data/tst_stackview.qml
+++ b/tests/auto/controls/data/tst_stackview.qml
@@ -540,4 +540,39 @@ TestCase {
control.destroy()
}
+
+ Component {
+ id: attachedItem
+ Item {
+ property int index: StackView.index
+ property StackView view: StackView.view
+ property int status: StackView.status
+ }
+ }
+
+ function test_attached() {
+ var control = stackView.createObject(testCase, {initialItem: attachedItem})
+
+ compare(control.get(0).index, 0)
+ compare(control.get(0).view, control)
+ compare(control.get(0).status, StackView.Active)
+
+ control.push(attachedItem, StackView.Immediate)
+
+ compare(control.get(0).index, 0)
+ compare(control.get(0).view, control)
+ compare(control.get(0).status, StackView.Inactive)
+
+ compare(control.get(1).index, 1)
+ compare(control.get(1).view, control)
+ compare(control.get(1).status, StackView.Active)
+
+ control.pop(StackView.Immediate)
+
+ compare(control.get(0).index, 0)
+ compare(control.get(0).view, control)
+ compare(control.get(0).status, StackView.Active)
+
+ control.destroy()
+ }
}