Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include "qquickstateoperations_p.h"
++ #include "qquickitem_p.h"
++
++ #include <private/qquickstate_p_p.h>
++
++ #include <QtQml/qqmlinfo.h>
++
++ #include <QtCore/qmath.h>
++ #include <QtCore/qpointer.h>
++
++ #include <memory>
++
++ QT_BEGIN_NAMESPACE
++
++ class QQuickParentChangePrivate : public QQuickStateOperationPrivate
++ {
++ Q_DECLARE_PUBLIC(QQuickParentChange)
++ public:
++ QQuickItem *target = nullptr;
++ QPointer<QQuickItem> parent;
++
++ struct StateSnapshot {
++ QPointer<QQuickItem> parent;
++ QPointer<QQuickItem> stackBefore;
++ qreal x = 0, y = 0, width = 0, height = 0, scale = 0, rotation = 0;
++ };
++
++ std::unique_ptr<StateSnapshot> orig;
++ std::unique_ptr<StateSnapshot> rewind;
++
++ QQmlNullableValue<QQmlScriptString> xString;
++ QQmlNullableValue<QQmlScriptString> yString;
++ QQmlNullableValue<QQmlScriptString> widthString;
++ QQmlNullableValue<QQmlScriptString> heightString;
++ QQmlNullableValue<QQmlScriptString> scaleString;
++ QQmlNullableValue<QQmlScriptString> rotationString;
++
++ void doChange(QQuickItem *targetParent);
++ void reverseRewindHelper(const std::unique_ptr<StateSnapshot> &snapshot);
++ };
++
++ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent)
++ {
++ if (targetParent && target && target->parentItem()) {
++ Q_Q(QQuickParentChange);
++ bool ok;
++ const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
++ if (transform.type() >= QTransform::TxShear || !ok) {
++ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
++ ok = false;
++ }
++
++ qreal scale = 1;
++ qreal rotation = 0;
++ bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
++ if (ok && !isRotate) {
++ if (transform.m11() == transform.m22())
++ scale = transform.m11();
++ else {
++ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
++ ok = false;
++ }
++ } else if (ok && isRotate) {
++ if (transform.m11() == transform.m22())
++ scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
++ else {
++ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
++ ok = false;
++ }
++
++ if (scale != 0)
++ rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
++ else {
++ qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
++ ok = false;
++ }
++ }
++
++ const QPointF &point = transform.map(QPointF(target->x(),target->y()));
++ qreal x = point.x();
++ qreal y = point.y();
++
++ // setParentItem will update the transformOriginPoint if needed
++ target->setParentItem(targetParent);
++
++ if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
++ qreal tempxt = target->transformOriginPoint().x();
++ qreal tempyt = target->transformOriginPoint().y();
++ QTransform t;
++ t.translate(-tempxt, -tempyt);
++ t.rotate(rotation);
++ t.scale(scale, scale);
++ t.translate(tempxt, tempyt);
++ const QPointF &offset = t.map(QPointF(0,0));
++ x += offset.x();
++ y += offset.y();
++ }
++
++ if (ok) {
++ //qDebug() << x << y << rotation << scale;
++ target->setPosition(QPointF(x, y));
++ target->setRotation(target->rotation() + rotation);
++ target->setScale(target->scale() * scale);
++ }
++ } else if (target) {
++ target->setParentItem(targetParent);
++ }
++ }
++
++ /*!
++ \qmltype ParentChange
++ \nativetype QQuickParentChange
++ \inqmlmodule QtQuick
++ \ingroup qtquick-states
++ \brief Specifies how to reparent an Item in a state change.
++
++ ParentChange reparents an item while preserving its visual appearance (position, size,
++ rotation, and scale) on screen. You can then specify a transition to move/resize/rotate/scale
++ the item to its final intended appearance.
++
++ ParentChange can only preserve visual appearance if no complex transforms are involved.
++ More specifically, it will not work if the transform property has been set for any
++ items involved in the reparenting (i.e. items in the common ancestor tree
++ for the original and new parent).
++
++ The example below displays a large red rectangle and a small blue rectangle, side by side.
++ When the \c blueRect is clicked, it changes to the "reparented" state: its parent is changed to \c redRect and it is
++ positioned at (10, 10) within the red rectangle, as specified in the ParentChange.
++
++ \snippet qml/parentchange.qml 0
++
++ \image parentchange.png {Blue square state change affecting parent
++ reassignment}
++
++ You can specify at which point in a transition you want a ParentChange to occur by
++ using a ParentAnimation.
++
++ Note that unlike PropertyChanges, ParentChange expects an Item-based target; it will not work with
++ arbitrary objects (for example, you couldn't use it to reparent a Timer).
++ */
++
++ QQuickParentChange::QQuickParentChange(QObject *parent)
++ : QQuickStateOperation(*(new QQuickParentChangePrivate), parent)
++ {
++ }
++
++ /*!
++ \qmlproperty real QtQuick::ParentChange::x
++ \qmlproperty real QtQuick::ParentChange::y
++ \qmlproperty real QtQuick::ParentChange::width
++ \qmlproperty real QtQuick::ParentChange::height
++ \qmlproperty real QtQuick::ParentChange::scale
++ \qmlproperty real QtQuick::ParentChange::rotation
++ These properties hold the new position, size, scale, and rotation
++ for the item in this state.
++ */
++ QQmlScriptString QQuickParentChange::x() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->xString.value();
++ }
++
++ void QQuickParentChange::setX(const QQmlScriptString &x)
++ {
++ Q_D(QQuickParentChange);
++ d->xString = x;
++ }
++
++ bool QQuickParentChange::xIsSet() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->xString.isValid();
++ }
++
++ QQmlScriptString QQuickParentChange::y() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->yString.value();
++ }
++
++ void QQuickParentChange::setY(const QQmlScriptString &y)
++ {
++ Q_D(QQuickParentChange);
++ d->yString = y;
++ }
++
++ bool QQuickParentChange::yIsSet() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->yString.isValid();
++ }
++
++ QQmlScriptString QQuickParentChange::width() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->widthString.value();
++ }
++
++ void QQuickParentChange::setWidth(const QQmlScriptString &width)
++ {
++ Q_D(QQuickParentChange);
++ d->widthString = width;
++ }
++
++ bool QQuickParentChange::widthIsSet() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->widthString.isValid();
++ }
++
++ QQmlScriptString QQuickParentChange::height() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->heightString.value();
++ }
++
++ void QQuickParentChange::setHeight(const QQmlScriptString &height)
++ {
++ Q_D(QQuickParentChange);
++ d->heightString = height;
++ }
++
++ bool QQuickParentChange::heightIsSet() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->heightString.isValid();
++ }
++
++ QQmlScriptString QQuickParentChange::scale() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->scaleString.value();
++ }
++
++ void QQuickParentChange::setScale(const QQmlScriptString &scale)
++ {
++ Q_D(QQuickParentChange);
++ d->scaleString = scale;
++ }
++
++ bool QQuickParentChange::scaleIsSet() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->scaleString.isValid();
++ }
++
++ QQmlScriptString QQuickParentChange::rotation() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->rotationString.value();
++ }
++
++ void QQuickParentChange::setRotation(const QQmlScriptString &rotation)
++ {
++ Q_D(QQuickParentChange);
++ d->rotationString = rotation;
++ }
++
++ bool QQuickParentChange::rotationIsSet() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->rotationString.isValid();
++ }
++
++ QQuickItem *QQuickParentChange::originalParent() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->orig ? d->orig->parent : nullptr;
++ }
++
++ /*!
++ \qmlproperty Item QtQuick::ParentChange::target
++ This property holds the item to be reparented
++ */
++ QQuickItem *QQuickParentChange::object() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->target;
++ }
++
++ void QQuickParentChange::setObject(QQuickItem *target)
++ {
++ Q_D(QQuickParentChange);
++ d->target = target;
++ }
++
++ /*!
++ \qmlproperty Item QtQuick::ParentChange::parent
++ This property holds the new parent for the item in this state.
++ */
++ QQuickItem *QQuickParentChange::parent() const
++ {
++ Q_D(const QQuickParentChange);
++ return d->parent;
++ }
++
++ void QQuickParentChange::setParent(QQuickItem *parent)
++ {
++ Q_D(QQuickParentChange);
++ d->parent = parent;
++ }
++
++ QQuickStateOperation::ActionList QQuickParentChange::actions()
++ {
++ Q_D(QQuickParentChange);
++ if (!d->target || !d->parent)
++ return ActionList();
++
++ ActionList actions;
++
++ QQuickStateAction a;
++ a.event = this;
++ actions << a;
++
++ if (d->xString.isValid()) {
++ bool ok = false;
++ qreal x = d->xString.value().numberLiteral(&ok);
++ if (ok) {
++ QQuickStateAction xa(d->target, QLatin1String("x"), x);
++ actions << xa;
++ } else {
++ QQmlProperty property(d->target, QLatin1String("x"));
++ auto newBinding = QQmlAnyBinding::createFromScriptString(
++ property, d->xString.value(), d->target, qmlContext(this));
++ QQuickStateAction xa;
++ xa.property = property;
++ xa.toBinding = newBinding;
++ xa.fromValue = xa.property.read();
++ xa.deletableToBinding = true;
++ actions << xa;
++ }
++ }
++
++ if (d->yString.isValid()) {
++ bool ok = false;
++ qreal y = d->yString.value().numberLiteral(&ok);
++ if (ok) {
++ QQuickStateAction ya(d->target, QLatin1String("y"), y);
++ actions << ya;
++ } else {
++ QQmlProperty property(d->target, QLatin1String("y"));
++ auto newBinding = QQmlAnyBinding::createFromScriptString(
++ property, d->yString.value(), d->target, qmlContext(this));
++ QQuickStateAction ya;
++ ya.property = property;
++ ya.toBinding = newBinding;
++ ya.fromValue = ya.property.read();
++ ya.deletableToBinding = true;
++ actions << ya;
++ }
++ }
++
++ if (d->scaleString.isValid()) {
++ bool ok = false;
++ qreal scale = d->scaleString.value().numberLiteral(&ok);
++ if (ok) {
++ QQuickStateAction sa(d->target, QLatin1String("scale"), scale);
++ actions << sa;
++ } else {
++ QQmlProperty property(d->target, QLatin1String("scale"));
++ auto newBinding = QQmlAnyBinding::createFromScriptString(
++ property, d->scaleString.value(), d->target, qmlContext(this));
++ QQuickStateAction sa;
++ sa.property = property;
++ sa.toBinding = newBinding;
++ sa.fromValue = sa.property.read();
++ sa.deletableToBinding = true;
++ actions << sa;
++ }
++ }
++
++ if (d->rotationString.isValid()) {
++ bool ok = false;
++ qreal rotation = d->rotationString.value().numberLiteral(&ok);
++ if (ok) {
++ QQuickStateAction ra(d->target, QLatin1String("rotation"), rotation);
++ actions << ra;
++ } else {
++ QQmlProperty property(d->target, QLatin1String("rotation"));
++ auto newBinding = QQmlAnyBinding::createFromScriptString(
++ property, d->rotationString.value(), d->target, qmlContext(this));
++ QQuickStateAction ra;
++ ra.property = property;
++ ra.toBinding = newBinding;
++ ra.fromValue = ra.property.read();
++ ra.deletableToBinding = true;
++ actions << ra;
++ }
++ }
++
++ if (d->widthString.isValid()) {
++ bool ok = false;
++ qreal width = d->widthString.value().numberLiteral(&ok);
++ if (ok) {
++ QQuickStateAction wa(d->target, QLatin1String("width"), width);
++ actions << wa;
++ } else {
++ QQmlProperty property(d->target, QLatin1String("width"));
++ auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->widthString, d->target, qmlContext(this));
++ QQuickStateAction wa;
++ wa.property = property;
++ wa.toBinding = newBinding;
++ wa.fromValue = wa.property.read();
++ wa.deletableToBinding = true;
++ actions << wa;
++ }
++ }
++
++ if (d->heightString.isValid()) {
++ bool ok = false;
++ qreal height = d->heightString.value().numberLiteral(&ok);
++ if (ok) {
++ QQuickStateAction ha(d->target, QLatin1String("height"), height);
++ actions << ha;
++ } else {
++ QQmlProperty property(d->target, QLatin1String("height"));
++ auto newBinding = QQmlAnyBinding::createFromScriptString(property, d->heightString, d->target, qmlContext(this));
++ QQuickStateAction ha;
++ ha.property = property;
++ ha.toBinding = newBinding;
++ ha.fromValue = ha.property.read();
++ ha.deletableToBinding = true;
++ actions << ha;
++ }
++ }
++
++ return actions;
++ }
++
++ void QQuickParentChange::saveOriginals()
++ {
++ Q_D(QQuickParentChange);
++ saveCurrentValues();
++ if (!d->orig)
++ d->orig.reset(new QQuickParentChangePrivate::StateSnapshot);
++ *d->orig = *d->rewind;
++ }
++
++ void QQuickParentChange::execute()
++ {
++ Q_D(QQuickParentChange);
++ d->doChange(d->parent);
++ }
++
++ bool QQuickParentChange::isReversable()
++ {
++ return true;
++ }
++
++ void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuickParentChangePrivate::StateSnapshot> &snapshot)
++ {
++ if (!target || !snapshot)
++ return;
++
++ // leave existing bindings alive; new bindings are applied in applyBindings
++ // setPosition and setSize update the geometry without invalidating bindings
++ target->setPosition(QPointF(snapshot->x, snapshot->y));
++ target->setSize(QSizeF(snapshot->width, snapshot->height));
++
++ target->setScale(snapshot->scale);
++ target->setRotation(snapshot->rotation);
++ target->setParentItem(snapshot->parent);
++ if (snapshot->stackBefore)
++ target->stackBefore(snapshot->stackBefore);
++ }
++
++
++ void QQuickParentChange::reverse()
++ {
++ Q_D(QQuickParentChange);
++ d->reverseRewindHelper(d->orig);
++ }
++
++ QQuickStateActionEvent::EventType QQuickParentChange::type() const
++ {
++ return ParentChange;
++ }
++
++ bool QQuickParentChange::mayOverride(QQuickStateActionEvent*other)
++ {
++ Q_D(QQuickParentChange);
++ if (other->type() != ParentChange)
++ return false;
++ if (QQuickParentChange *otherPC = static_cast<QQuickParentChange*>(other))
++ return (d->target == otherPC->object());
++ return false;
++ }
++
++ void QQuickParentChange::saveCurrentValues()
++ {
++ Q_D(QQuickParentChange);
++ if (!d->target) {
++ d->rewind = nullptr;
++ return;
++ }
++
++ d->rewind.reset(new QQuickParentChangePrivate::StateSnapshot);
++ d->rewind->x = d->target->x();
++ d->rewind->y = d->target->y();
++ d->rewind->scale = d->target->scale();
++ d->rewind->width = d->target->width();
++ d->rewind->height = d->target->height();
++ d->rewind->rotation = d->target->rotation();
++
++ d->rewind->parent = d->target->parentItem();
++ d->rewind->stackBefore = nullptr;
++
++ if (!d->rewind->parent)
++ return;
++
++ QList<QQuickItem *> children = d->rewind->parent->childItems();
++ for (int ii = 0; ii < children.size() - 1; ++ii) {
++ if (children.at(ii) == d->target) {
++ d->rewind->stackBefore = children.at(ii + 1);
++ break;
++ }
++ }
++ }
++
++ void QQuickParentChange::rewind()
++ {
++ Q_D(QQuickParentChange);
++ d->reverseRewindHelper(d->rewind);
++ d->rewind.reset();
++ }
++
++ /*!
++ \qmltype AnchorChanges
++ \nativetype QQuickAnchorChanges
++ \inqmlmodule QtQuick
++ \ingroup qtquick-states
++ \brief Specifies how to change the anchors of an item in a state.
++
++ The AnchorChanges type is used to modify the anchors of an item in a \l State.
++
++ AnchorChanges cannot be used to modify the margins on an item. For this, use
++ PropertyChanges instead.
++
++ In the following example we change the top and bottom anchors of an item
++ using AnchorChanges, and the top and bottom anchor margins using
++ PropertyChanges:
++
++ \snippet qml/anchorchanges.qml 0
++
++ \image anchorchanges.png {Red square changing anchor position
++ between two states}
++
++ AnchorChanges can be animated using AnchorAnimation.
++ \qml
++ //animate our anchor changes
++ Transition {
++ AnchorAnimation {}
++ }
++ \endqml
++
++ Changes to anchor margins can be animated using NumberAnimation.
++
++ For more information on anchors see \l {anchor-layout}{Anchor Layouts}.
++ */
++
++ class QQuickAnchorSetPrivate : public QObjectPrivate
++ {
++ Q_DECLARE_PUBLIC(QQuickAnchorSet)
++ public:
++ QQuickAnchors::Anchors usedAnchors;
++ QQuickAnchors::Anchors resetAnchors;
++
++ QQmlScriptString leftScript;
++ QQmlScriptString rightScript;
++ QQmlScriptString topScript;
++ QQmlScriptString bottomScript;
++ QQmlScriptString hCenterScript;
++ QQmlScriptString vCenterScript;
++ QQmlScriptString baselineScript;
++ };
++
++ QQuickAnchorSet::QQuickAnchorSet(QObject *parent)
++ : QObject(*new QQuickAnchorSetPrivate, parent)
++ {
++ }
++
++ QQuickAnchorSet::~QQuickAnchorSet()
++ {
++ }
++
++ QQmlScriptString QQuickAnchorSet::top() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->topScript;
++ }
++
++ void QQuickAnchorSet::setTop(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::TopAnchor;
++ d->topScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetTop();
++ }
++
++ void QQuickAnchorSet::resetTop()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::TopAnchor;
++ d->resetAnchors |= QQuickAnchors::TopAnchor;
++ }
++
++ QQmlScriptString QQuickAnchorSet::bottom() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->bottomScript;
++ }
++
++ void QQuickAnchorSet::setBottom(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::BottomAnchor;
++ d->bottomScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetBottom();
++ }
++
++ void QQuickAnchorSet::resetBottom()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::BottomAnchor;
++ d->resetAnchors |= QQuickAnchors::BottomAnchor;
++ }
++
++ QQmlScriptString QQuickAnchorSet::verticalCenter() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->vCenterScript;
++ }
++
++ void QQuickAnchorSet::setVerticalCenter(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::VCenterAnchor;
++ d->vCenterScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetVerticalCenter();
++ }
++
++ void QQuickAnchorSet::resetVerticalCenter()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::VCenterAnchor;
++ d->resetAnchors |= QQuickAnchors::VCenterAnchor;
++ }
++
++ QQmlScriptString QQuickAnchorSet::baseline() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->baselineScript;
++ }
++
++ void QQuickAnchorSet::setBaseline(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::BaselineAnchor;
++ d->baselineScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetBaseline();
++ }
++
++ void QQuickAnchorSet::resetBaseline()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::BaselineAnchor;
++ d->resetAnchors |= QQuickAnchors::BaselineAnchor;
++ }
++
++ QQmlScriptString QQuickAnchorSet::left() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->leftScript;
++ }
++
++ void QQuickAnchorSet::setLeft(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::LeftAnchor;
++ d->leftScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetLeft();
++ }
++
++ void QQuickAnchorSet::resetLeft()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::LeftAnchor;
++ d->resetAnchors |= QQuickAnchors::LeftAnchor;
++ }
++
++ QQmlScriptString QQuickAnchorSet::right() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->rightScript;
++ }
++
++ void QQuickAnchorSet::setRight(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::RightAnchor;
++ d->rightScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetRight();
++ }
++
++ void QQuickAnchorSet::resetRight()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::RightAnchor;
++ d->resetAnchors |= QQuickAnchors::RightAnchor;
++ }
++
++ QQmlScriptString QQuickAnchorSet::horizontalCenter() const
++ {
++ Q_D(const QQuickAnchorSet);
++ return d->hCenterScript;
++ }
++
++ void QQuickAnchorSet::setHorizontalCenter(const QQmlScriptString &edge)
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors |= QQuickAnchors::HCenterAnchor;
++ d->hCenterScript = edge;
++ if (edge.isUndefinedLiteral())
++ resetHorizontalCenter();
++ }
++
++ void QQuickAnchorSet::resetHorizontalCenter()
++ {
++ Q_D(QQuickAnchorSet);
++ d->usedAnchors &= ~QQuickAnchors::HCenterAnchor;
++ d->resetAnchors |= QQuickAnchors::HCenterAnchor;
++ }
++
++ class QQuickAnchorChangesPrivate : public QQuickStateOperationPrivate
++ {
++ public:
++ QQuickAnchorChangesPrivate()
++ : target(nullptr), anchorSet(new QQuickAnchorSet)
++ {
++
++ }
++ ~QQuickAnchorChangesPrivate() { delete anchorSet; }
++
++ QQuickItem *target;
++ QQuickAnchorSet *anchorSet;
++
++ QQmlBinding::Ptr leftBinding;
++ QQmlBinding::Ptr rightBinding;
++ QQmlBinding::Ptr hCenterBinding;
++ QQmlBinding::Ptr topBinding;
++ QQmlBinding::Ptr bottomBinding;
++ QQmlBinding::Ptr vCenterBinding;
++ QQmlBinding::Ptr baselineBinding;
++
++ QQmlAbstractBinding::Ptr origLeftBinding;
++ QQmlAbstractBinding::Ptr origRightBinding;
++ QQmlAbstractBinding::Ptr origHCenterBinding;
++ QQmlAbstractBinding::Ptr origTopBinding;
++ QQmlAbstractBinding::Ptr origBottomBinding;
++ QQmlAbstractBinding::Ptr origVCenterBinding;
++ QQmlAbstractBinding::Ptr origBaselineBinding;
++
++ QQuickAnchorLine rewindLeft;
++ QQuickAnchorLine rewindRight;
++ QQuickAnchorLine rewindHCenter;
++ QQuickAnchorLine rewindTop;
++ QQuickAnchorLine rewindBottom;
++ QQuickAnchorLine rewindVCenter;
++ QQuickAnchorLine rewindBaseline;
++
++ qreal fromX;
++ qreal fromY;
++ qreal fromWidth;
++ qreal fromHeight;
++
++ qreal toX;
++ qreal toY;
++ qreal toWidth;
++ qreal toHeight;
++
++ qreal rewindX;
++ qreal rewindY;
++ qreal rewindWidth;
++ qreal rewindHeight;
++
++ bool applyOrigLeft;
++ bool applyOrigRight;
++ bool applyOrigHCenter;
++ bool applyOrigTop;
++ bool applyOrigBottom;
++ bool applyOrigVCenter;
++ bool applyOrigBaseline;
++
++ QQmlNullableValue<qreal> origWidth;
++ QQmlNullableValue<qreal> origHeight;
++ qreal origX;
++ qreal origY;
++
++ QQmlProperty leftProp;
++ QQmlProperty rightProp;
++ QQmlProperty hCenterProp;
++ QQmlProperty topProp;
++ QQmlProperty bottomProp;
++ QQmlProperty vCenterProp;
++ QQmlProperty baselineProp;
++ };
++
++ QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent)
++ : QQuickStateOperation(*(new QQuickAnchorChangesPrivate), parent)
++ {
++ }
++
++ QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions()
++ {
++ Q_D(QQuickAnchorChanges);
++ //### ASSERT these are all 0?
++ d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
++ = d->bottomBinding = d->vCenterBinding = d->baselineBinding = nullptr;
++
++ d->leftProp = QQmlProperty(d->target, QLatin1String("anchors.left"));
++ d->rightProp = QQmlProperty(d->target, QLatin1String("anchors.right"));
++ d->hCenterProp = QQmlProperty(d->target, QLatin1String("anchors.horizontalCenter"));
++ d->topProp = QQmlProperty(d->target, QLatin1String("anchors.top"));
++ d->bottomProp = QQmlProperty(d->target, QLatin1String("anchors.bottom"));
++ d->vCenterProp = QQmlProperty(d->target, QLatin1String("anchors.verticalCenter"));
++ d->baselineProp = QQmlProperty(d->target, QLatin1String("anchors.baseline"));
++
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::LeftAnchor) {
++ d->leftBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->leftProp)->core, d->anchorSet->d_func()->leftScript, d->target, qmlContext(this));
++ d->leftBinding->setTarget(d->leftProp);
++ }
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::RightAnchor) {
++ d->rightBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->rightProp)->core, d->anchorSet->d_func()->rightScript, d->target, qmlContext(this));
++ d->rightBinding->setTarget(d->rightProp);
++ }
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::HCenterAnchor) {
++ d->hCenterBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->hCenterProp)->core, d->anchorSet->d_func()->hCenterScript, d->target, qmlContext(this));
++ d->hCenterBinding->setTarget(d->hCenterProp);
++ }
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::TopAnchor) {
++ d->topBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->topProp)->core, d->anchorSet->d_func()->topScript, d->target, qmlContext(this));
++ d->topBinding->setTarget(d->topProp);
++ }
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BottomAnchor) {
++ d->bottomBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->bottomProp)->core, d->anchorSet->d_func()->bottomScript, d->target, qmlContext(this));
++ d->bottomBinding->setTarget(d->bottomProp);
++ }
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::VCenterAnchor) {
++ d->vCenterBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->vCenterProp)->core, d->anchorSet->d_func()->vCenterScript, d->target, qmlContext(this));
++ d->vCenterBinding->setTarget(d->vCenterProp);
++ }
++ if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BaselineAnchor) {
++ d->baselineBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(d->baselineProp)->core, d->anchorSet->d_func()->baselineScript, d->target, qmlContext(this));
++ d->baselineBinding->setTarget(d->baselineProp);
++ }
++
++ QQuickStateAction a;
++ a.event = this;
++ return ActionList() << a;
++ }
++
++ QQuickAnchorSet *QQuickAnchorChanges::anchors() const
++ {
++ Q_D(const QQuickAnchorChanges);
++ return d->anchorSet;
++ }
++
++ /*!
++ \qmlproperty Item QtQuick::AnchorChanges::target
++ This property holds the \l Item for which the anchor changes will be applied.
++ */
++ QQuickItem *QQuickAnchorChanges::object() const
++ {
++ Q_D(const QQuickAnchorChanges);
++ return d->target;
++ }
++
++ void QQuickAnchorChanges::setObject(QQuickItem *target)
++ {
++ Q_D(QQuickAnchorChanges);
++ d->target = target;
++ }
++
++ /*!
++ \qmlpropertygroup QtQuick::AnchorChanges::anchors
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.left
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.right
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.horizontalCenter
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.top
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.bottom
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.verticalCenter
++ \qmlproperty AnchorLine QtQuick::AnchorChanges::anchors.baseline
++
++ These properties change the respective anchors of the item.
++
++ To reset an anchor you can assign \c undefined:
++ \qml
++ AnchorChanges {
++ target: myItem
++ anchors.left: undefined //remove myItem's left anchor
++ anchors.right: otherItem.right
++ }
++ \endqml
++ */
++
++ void QQuickAnchorChanges::execute()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
++ //incorporate any needed "reverts"
++ if (d->applyOrigLeft) {
++ if (!d->origLeftBinding)
++ targetPrivate->anchors()->resetLeft();
++ QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
++ }
++ if (d->applyOrigRight) {
++ if (!d->origRightBinding)
++ targetPrivate->anchors()->resetRight();
++ QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
++ }
++ if (d->applyOrigHCenter) {
++ if (!d->origHCenterBinding)
++ targetPrivate->anchors()->resetHorizontalCenter();
++ QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
++ }
++ if (d->applyOrigTop) {
++ if (!d->origTopBinding)
++ targetPrivate->anchors()->resetTop();
++ QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
++ }
++ if (d->applyOrigBottom) {
++ if (!d->origBottomBinding)
++ targetPrivate->anchors()->resetBottom();
++ QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
++ }
++ if (d->applyOrigVCenter) {
++ if (!d->origVCenterBinding)
++ targetPrivate->anchors()->resetVerticalCenter();
++ QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
++ }
++ if (d->applyOrigBaseline) {
++ if (!d->origBaselineBinding)
++ targetPrivate->anchors()->resetBaseline();
++ QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
++ }
++
++ //reset any anchors that have been specified as "undefined"
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
++ targetPrivate->anchors()->resetLeft();
++ QQmlPropertyPrivate::removeBinding(d->leftProp);
++ }
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
++ targetPrivate->anchors()->resetRight();
++ QQmlPropertyPrivate::removeBinding(d->rightProp);
++ }
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
++ targetPrivate->anchors()->resetHorizontalCenter();
++ QQmlPropertyPrivate::removeBinding(d->hCenterProp);
++ }
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
++ targetPrivate->anchors()->resetTop();
++ QQmlPropertyPrivate::removeBinding(d->topProp);
++ }
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
++ targetPrivate->anchors()->resetBottom();
++ QQmlPropertyPrivate::removeBinding(d->bottomProp);
++ }
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
++ targetPrivate->anchors()->resetVerticalCenter();
++ QQmlPropertyPrivate::removeBinding(d->vCenterProp);
++ }
++ if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
++ targetPrivate->anchors()->resetBaseline();
++ QQmlPropertyPrivate::removeBinding(d->baselineProp);
++ }
++
++ //set any anchors that have been specified
++ if (d->leftBinding)
++ QQmlPropertyPrivate::setBinding(d->leftBinding.data());
++ if (d->rightBinding)
++ QQmlPropertyPrivate::setBinding(d->rightBinding.data());
++ if (d->hCenterBinding)
++ QQmlPropertyPrivate::setBinding(d->hCenterBinding.data());
++ if (d->topBinding)
++ QQmlPropertyPrivate::setBinding(d->topBinding.data());
++ if (d->bottomBinding)
++ QQmlPropertyPrivate::setBinding(d->bottomBinding.data());
++ if (d->vCenterBinding)
++ QQmlPropertyPrivate::setBinding(d->vCenterBinding.data());
++ if (d->baselineBinding)
++ QQmlPropertyPrivate::setBinding(d->baselineBinding.data());
++ }
++
++ bool QQuickAnchorChanges::isReversable()
++ {
++ return true;
++ }
++
++ void QQuickAnchorChanges::reverse()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
++ //reset any anchors set by the state
++ if (d->leftBinding) {
++ targetPrivate->anchors()->resetLeft();
++ QQmlPropertyPrivate::removeBinding(d->leftBinding.data());
++ }
++ if (d->rightBinding) {
++ targetPrivate->anchors()->resetRight();
++ QQmlPropertyPrivate::removeBinding(d->rightBinding.data());
++ }
++ if (d->hCenterBinding) {
++ targetPrivate->anchors()->resetHorizontalCenter();
++ QQmlPropertyPrivate::removeBinding(d->hCenterBinding.data());
++ }
++ if (d->topBinding) {
++ targetPrivate->anchors()->resetTop();
++ QQmlPropertyPrivate::removeBinding(d->topBinding.data());
++ }
++ if (d->bottomBinding) {
++ targetPrivate->anchors()->resetBottom();
++ QQmlPropertyPrivate::removeBinding(d->bottomBinding.data());
++ }
++ if (d->vCenterBinding) {
++ targetPrivate->anchors()->resetVerticalCenter();
++ QQmlPropertyPrivate::removeBinding(d->vCenterBinding.data());
++ }
++ if (d->baselineBinding) {
++ targetPrivate->anchors()->resetBaseline();
++ QQmlPropertyPrivate::removeBinding(d->baselineBinding.data());
++ }
++
++ //restore previous anchors
++ if (d->origLeftBinding)
++ QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data());
++ if (d->origRightBinding)
++ QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data());
++ if (d->origHCenterBinding)
++ QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data());
++ if (d->origTopBinding)
++ QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data());
++ if (d->origBottomBinding)
++ QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data());
++ if (d->origVCenterBinding)
++ QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data());
++ if (d->origBaselineBinding)
++ QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data());
++
++ //restore any absolute geometry changed by the state's anchors
++ QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
++ QQuickAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Vertical_Mask;
++ QQuickAnchors::Anchors resetVAnchors = d->anchorSet->d_func()->resetAnchors & QQuickAnchors::Vertical_Mask;
++ QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
++ QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
++ QQuickAnchors::Anchors resetHAnchors = d->anchorSet->d_func()->resetAnchors & QQuickAnchors::Horizontal_Mask;
++
++ const QRectF oldGeometry(d->target->position(), d->target->size());
++ bool stateSetWidth = (stateHAnchors &&
++ stateHAnchors != QQuickAnchors::LeftAnchor &&
++ stateHAnchors != QQuickAnchors::RightAnchor &&
++ stateHAnchors != QQuickAnchors::HCenterAnchor);
++ // in case of an additive AnchorChange, we _did_ end up modifying the width, unless opposite
++ // edge was set to undefined in state
++ stateSetWidth |= ((stateHAnchors & QQuickAnchors::LeftAnchor)
++ && (origHAnchors & QQuickAnchors::RightAnchor)
++ && !(resetHAnchors & QQuickAnchors::RightAnchor))
++ || ((stateHAnchors & QQuickAnchors::RightAnchor)
++ && (origHAnchors & QQuickAnchors::LeftAnchor)
++ && !(resetHAnchors & QQuickAnchors::LeftAnchor));
++ bool origSetWidth = (origHAnchors &&
++ origHAnchors != QQuickAnchors::LeftAnchor &&
++ origHAnchors != QQuickAnchors::RightAnchor &&
++ origHAnchors != QQuickAnchors::HCenterAnchor);
++ if (d->origWidth.isValid() && stateSetWidth && !origSetWidth && !qt_is_nan(d->origWidth)) {
++ targetPrivate->widthValidFlag = true;
++ if (targetPrivate->width != d->origWidth)
++ targetPrivate->width.setValueBypassingBindings(d->origWidth);
++ }
++
++ bool stateSetHeight = (stateVAnchors &&
++ stateVAnchors != QQuickAnchors::TopAnchor &&
++ stateVAnchors != QQuickAnchors::BottomAnchor &&
++ stateVAnchors != QQuickAnchors::VCenterAnchor &&
++ stateVAnchors != QQuickAnchors::BaselineAnchor);
++ // in case of an additive AnchorChange, we _did_ end up modifying the height, unless opposite
++ // edge was set to undefined in state
++ stateSetHeight |= ((stateVAnchors & QQuickAnchors::TopAnchor)
++ && (origVAnchors & QQuickAnchors::BottomAnchor)
++ && !(resetVAnchors & QQuickAnchors::BottomAnchor))
++ || ((stateVAnchors & QQuickAnchors::BottomAnchor)
++ && (origVAnchors & QQuickAnchors::TopAnchor)
++ && !(resetVAnchors & QQuickAnchors::TopAnchor));
++ bool origSetHeight = (origVAnchors &&
++ origVAnchors != QQuickAnchors::TopAnchor &&
++ origVAnchors != QQuickAnchors::BottomAnchor &&
++ origVAnchors != QQuickAnchors::VCenterAnchor &&
++ origVAnchors != QQuickAnchors::BaselineAnchor);
++ if (d->origHeight.isValid() && stateSetHeight && !origSetHeight && !qt_is_nan(d->origHeight)) {
++ targetPrivate->heightValidFlag = true;
++ if (targetPrivate->height != d->origHeight)
++ targetPrivate->height.setValueBypassingBindings(d->origHeight);
++ }
++
++ if (stateHAnchors && !origHAnchors && !qt_is_nan(d->origX) && d->origX != targetPrivate->x)
++ targetPrivate->x.setValueBypassingBindings(d->origX);
++
++ if (stateVAnchors && !origVAnchors && !qt_is_nan(d->origY) && d->origY != targetPrivate->y)
++ targetPrivate->y.setValueBypassingBindings(d->origY);
++
++ const QRectF newGeometry(d->target->position(), d->target->size());
++ if (newGeometry != oldGeometry) {
++ QQuickItemPrivate::DirtyType dirtyFlags {};
++ if (newGeometry.topLeft() != oldGeometry.topLeft())
++ dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Position);
++ if (newGeometry.size() != oldGeometry.size())
++ dirtyFlags = QQuickItemPrivate::DirtyType(dirtyFlags | QQuickItemPrivate::Size);
++ targetPrivate->dirty(dirtyFlags);
++ d->target->geometryChange(newGeometry, oldGeometry);
++ }
++ }
++
++ QQuickStateActionEvent::EventType QQuickAnchorChanges::type() const
++ {
++ return AnchorChanges;
++ }
++
++ QList<QQuickStateAction> QQuickAnchorChanges::additionalActions() const
++ {
++ Q_D(const QQuickAnchorChanges);
++ QList<QQuickStateAction> extra;
++
++ QQuickAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
++ bool hChange = combined & QQuickAnchors::Horizontal_Mask;
++ bool vChange = combined & QQuickAnchors::Vertical_Mask;
++
++ if (d->target) {
++ QQuickStateAction a;
++ if (hChange && d->fromX != d->toX) {
++ a.property = QQmlProperty(d->target, QLatin1String("x"));
++ a.toValue = d->toX;
++ extra << a;
++ }
++ if (vChange && d->fromY != d->toY) {
++ a.property = QQmlProperty(d->target, QLatin1String("y"));
++ a.toValue = d->toY;
++ extra << a;
++ }
++ if (hChange && d->fromWidth != d->toWidth) {
++ a.property = QQmlProperty(d->target, QLatin1String("width"));
++ a.toValue = d->toWidth;
++ extra << a;
++ }
++ if (vChange && d->fromHeight != d->toHeight) {
++ a.property = QQmlProperty(d->target, QLatin1String("height"));
++ a.toValue = d->toHeight;
++ extra << a;
++ }
++ }
++
++ return extra;
++ }
++
++ bool QQuickAnchorChanges::changesBindings()
++ {
++ return true;
++ }
++
++ void QQuickAnchorChanges::saveOriginals()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ d->origLeftBinding = QQmlPropertyPrivate::binding(d->leftProp);
++ d->origRightBinding = QQmlPropertyPrivate::binding(d->rightProp);
++ d->origHCenterBinding = QQmlPropertyPrivate::binding(d->hCenterProp);
++ d->origTopBinding = QQmlPropertyPrivate::binding(d->topProp);
++ d->origBottomBinding = QQmlPropertyPrivate::binding(d->bottomProp);
++ d->origVCenterBinding = QQmlPropertyPrivate::binding(d->vCenterProp);
++ d->origBaselineBinding = QQmlPropertyPrivate::binding(d->baselineProp);
++
++ QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
++ if (targetPrivate->widthValid())
++ d->origWidth = d->target->width();
++ if (targetPrivate->heightValid())
++ d->origHeight = d->target->height();
++ d->origX = d->target->x();
++ d->origY = d->target->y();
++
++ d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
++ = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
++
++ saveCurrentValues();
++ }
++
++ void QQuickAnchorChanges::copyOriginals(QQuickStateActionEvent *other)
++ {
++ Q_D(QQuickAnchorChanges);
++ QQuickAnchorChanges *ac = static_cast<QQuickAnchorChanges*>(other);
++ QQuickAnchorChangesPrivate *acp = ac->d_func();
++
++ QQuickAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
++ acp->anchorSet->d_func()->resetAnchors;
++
++ //probably also need to revert some things
++ d->applyOrigLeft = (combined & QQuickAnchors::LeftAnchor);
++ d->applyOrigRight = (combined & QQuickAnchors::RightAnchor);
++ d->applyOrigHCenter = (combined & QQuickAnchors::HCenterAnchor);
++ d->applyOrigTop = (combined & QQuickAnchors::TopAnchor);
++ d->applyOrigBottom = (combined & QQuickAnchors::BottomAnchor);
++ d->applyOrigVCenter = (combined & QQuickAnchors::VCenterAnchor);
++ d->applyOrigBaseline = (combined & QQuickAnchors::BaselineAnchor);
++
++ d->origLeftBinding = acp->origLeftBinding;
++ d->origRightBinding = acp->origRightBinding;
++ d->origHCenterBinding = acp->origHCenterBinding;
++ d->origTopBinding = acp->origTopBinding;
++ d->origBottomBinding = acp->origBottomBinding;
++ d->origVCenterBinding = acp->origVCenterBinding;
++ d->origBaselineBinding = acp->origBaselineBinding;
++
++ d->origWidth = acp->origWidth;
++ d->origHeight = acp->origHeight;
++ d->origX = acp->origX;
++ d->origY = acp->origY;
++
++ //clear old values from other
++ //### could this be generalized for all QQuickStateActionEvents, and called after copyOriginals?
++ acp->leftBinding = nullptr;
++ acp->rightBinding = nullptr;
++ acp->hCenterBinding = nullptr;
++ acp->topBinding = nullptr;
++ acp->bottomBinding = nullptr;
++ acp->vCenterBinding = nullptr;
++ acp->baselineBinding = nullptr;
++ acp->origLeftBinding = nullptr;
++ acp->origRightBinding = nullptr;
++ acp->origHCenterBinding = nullptr;
++ acp->origTopBinding = nullptr;
++ acp->origBottomBinding = nullptr;
++ acp->origVCenterBinding = nullptr;
++ acp->origBaselineBinding = nullptr;
++
++ saveCurrentValues();
++ }
++
++ void QQuickAnchorChanges::clearBindings()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ //### should this (saving "from" values) be moved to saveCurrentValues()?
++ d->fromX = d->target->x();
++ d->fromY = d->target->y();
++ d->fromWidth = d->target->width();
++ d->fromHeight = d->target->height();
++
++ QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
++ //reset any anchors with corresponding reverts
++ //reset any anchors that have been specified as "undefined"
++ //reset any anchors that we'll be setting in the state
++ QQuickAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
++ d->anchorSet->d_func()->usedAnchors;
++ if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
++ targetPrivate->anchors()->resetLeft();
++ QQmlPropertyPrivate::removeBinding(d->leftProp);
++ }
++ if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
++ targetPrivate->anchors()->resetRight();
++ QQmlPropertyPrivate::removeBinding(d->rightProp);
++ }
++ if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
++ targetPrivate->anchors()->resetHorizontalCenter();
++ QQmlPropertyPrivate::removeBinding(d->hCenterProp);
++ }
++ if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
++ targetPrivate->anchors()->resetTop();
++ QQmlPropertyPrivate::removeBinding(d->topProp);
++ }
++ if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
++ targetPrivate->anchors()->resetBottom();
++ QQmlPropertyPrivate::removeBinding(d->bottomProp);
++ }
++ if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
++ targetPrivate->anchors()->resetVerticalCenter();
++ QQmlPropertyPrivate::removeBinding(d->vCenterProp);
++ }
++ if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
++ targetPrivate->anchors()->resetBaseline();
++ QQmlPropertyPrivate::removeBinding(d->baselineProp);
++ }
++ }
++
++ bool QQuickAnchorChanges::mayOverride(QQuickStateActionEvent*other)
++ {
++ if (other->type() != AnchorChanges)
++ return false;
++ if (static_cast<QQuickStateActionEvent*>(this) == other)
++ return true;
++ if (static_cast<QQuickAnchorChanges*>(other)->object() == object())
++ return true;
++ return false;
++ }
++
++ void QQuickAnchorChanges::rewind()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
++ const QRectF oldGeometry(d->target->position(), d->target->size());
++
++ // Restore previous values (but not previous bindings, i.e. anchors).
++ // Also, don't drop any new bindings.
++ if (!qt_is_nan(d->rewindX) && d->rewindX != targetPrivate->x)
++ targetPrivate->x.setValueBypassingBindings(d->rewindX);
++ if (!qt_is_nan(d->rewindY) && d->rewindY != targetPrivate->y)
++ targetPrivate->y.setValueBypassingBindings(d->rewindY);
++
++ if (targetPrivate->widthValid() && !qt_is_nan(d->rewindWidth)) {
++ targetPrivate->widthValidFlag = true;
++ if (d->rewindWidth != targetPrivate->width)
++ targetPrivate->width.setValueBypassingBindings(d->rewindWidth);
++ }
++
++ if (targetPrivate->heightValid() && !qt_is_nan(d->rewindHeight)) {
++ targetPrivate->heightValidFlag = true;
++ if (d->rewindHeight != targetPrivate->height)
++ targetPrivate->height.setValueBypassingBindings(d->rewindHeight);
++ }
++
++ const QRectF newGeometry(d->target->position(), d->target->size());
++ if (newGeometry != oldGeometry) {
++ targetPrivate->dirty(QQuickItemPrivate::Position);
++ d->target->geometryChange(newGeometry, oldGeometry);
++ }
++ }
++
++ void QQuickAnchorChanges::saveCurrentValues()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
++ d->rewindLeft = targetPrivate->anchors()->left();
++ d->rewindRight = targetPrivate->anchors()->right();
++ d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
++ d->rewindTop = targetPrivate->anchors()->top();
++ d->rewindBottom = targetPrivate->anchors()->bottom();
++ d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
++ d->rewindBaseline = targetPrivate->anchors()->baseline();
++
++ d->rewindX = d->target->x();
++ d->rewindY = d->target->y();
++ d->rewindWidth = d->target->width();
++ d->rewindHeight = d->target->height();
++ }
++
++ void QQuickAnchorChanges::saveTargetValues()
++ {
++ Q_D(QQuickAnchorChanges);
++ if (!d->target)
++ return;
++
++ d->toX = d->target->x();
++ d->toY = d->target->y();
++ d->toWidth = d->target->width();
++ d->toHeight = d->target->height();
++ }
++
++ QT_END_NAMESPACE
++
++ #include <moc_qquickstateoperations_p.cpp>