/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickstateoperations_p.h"
#include "qquickitem_p.h"

#include <private/qquickstate_p_p.h>

#include <QtQml/qqmlinfo.h>
#include <QtCore/qmath.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
    \instantiates 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

    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)
{
}

QQuickParentChange::~QQuickParentChange()
{
}

/*!
    \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"));
            QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->xString.value, d->target, qmlContext(this));
            newBinding->setTarget(property);
            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"));
            QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->yString.value, d->target, qmlContext(this));
            newBinding->setTarget(property);
            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"));
            QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->scaleString.value, d->target, qmlContext(this));
            newBinding->setTarget(property);
            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"));
            QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->rotationString.value, d->target, qmlContext(this));
            newBinding->setTarget(property);
            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"));
            QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->widthString.value, d->target, qmlContext(this));
            newBinding->setTarget(property);
            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"));
            QQmlBinding *newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, d->heightString.value, d->target, qmlContext(this));
            newBinding->setTarget(property);
            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;
    target->setX(snapshot->x);
    target->setY(snapshot->y);
    target->setScale(snapshot->scale);
    target->setWidth(snapshot->width);
    target->setHeight(snapshot->height);
    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.count() - 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
    \instantiates 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 intead.

    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

    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;

    QExplicitlySharedDataPointer<QQmlBinding> leftBinding;
    QExplicitlySharedDataPointer<QQmlBinding> rightBinding;
    QExplicitlySharedDataPointer<QQmlBinding> hCenterBinding;
    QExplicitlySharedDataPointer<QQmlBinding> topBinding;
    QExplicitlySharedDataPointer<QQmlBinding> bottomBinding;
    QExplicitlySharedDataPointer<QQmlBinding> vCenterBinding;
    QExplicitlySharedDataPointer<QQmlBinding> 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::~QQuickAnchorChanges()
{
}

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 stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
    QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;

    bool stateSetWidth = (stateHAnchors &&
                          stateHAnchors != QQuickAnchors::LeftAnchor &&
                          stateHAnchors != QQuickAnchors::RightAnchor &&
                          stateHAnchors != QQuickAnchors::HCenterAnchor);
    bool origSetWidth = (origHAnchors &&
                         origHAnchors != QQuickAnchors::LeftAnchor &&
                         origHAnchors != QQuickAnchors::RightAnchor &&
                         origHAnchors != QQuickAnchors::HCenterAnchor);
    if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
        d->target->setWidth(d->origWidth.value);

    bool stateSetHeight = (stateVAnchors &&
                           stateVAnchors != QQuickAnchors::TopAnchor &&
                           stateVAnchors != QQuickAnchors::BottomAnchor &&
                           stateVAnchors != QQuickAnchors::VCenterAnchor &&
                           stateVAnchors != QQuickAnchors::BaselineAnchor);
    bool origSetHeight = (origVAnchors &&
                          origVAnchors != QQuickAnchors::TopAnchor &&
                          origVAnchors != QQuickAnchors::BottomAnchor &&
                          origVAnchors != QQuickAnchors::VCenterAnchor &&
                          origVAnchors != QQuickAnchors::BaselineAnchor);
    if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
        d->target->setHeight(d->origHeight.value);

    if (stateHAnchors && !origHAnchors)
        d->target->setX(d->origX);

    if (stateVAnchors && !origVAnchors)
        d->target->setY(d->origY);
}

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);

    //restore previous values (but not previous bindings, i.e. anchors)
    d->target->setX(d->rewindX);
    d->target->setY(d->rewindY);
    if (targetPrivate->widthValid) {
        d->target->setWidth(d->rewindWidth);
    }
    if (targetPrivate->heightValid) {
        d->target->setHeight(d->rewindHeight);
    }
}

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();
}

#include <moc_qquickstateoperations_p.cpp>

QT_END_NAMESPACE

