7548ec9bde107381f2cefd2b33ff9676a1cb3e29
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickstateoperations.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickstateoperations_p.h"
43 #include "qquickitem_p.h"
44
45 #include <private/qdeclarativestate_p_p.h>
46
47 #include <QtDeclarative/qdeclarativeinfo.h>
48 #include <QtCore/qmath.h>
49
50 QT_BEGIN_NAMESPACE
51
52 class QQuickParentChangePrivate : public QDeclarativeStateOperationPrivate
53 {
54     Q_DECLARE_PUBLIC(QQuickParentChange)
55 public:
56     QQuickParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
57         rewindParent(0), rewindStackBefore(0) {}
58
59     QQuickItem *target;
60     QDeclarativeGuard<QQuickItem> parent;
61     QDeclarativeGuard<QQuickItem> origParent;
62     QDeclarativeGuard<QQuickItem> origStackBefore;
63     QQuickItem *rewindParent;
64     QQuickItem *rewindStackBefore;
65
66     QDeclarativeNullableValue<QDeclarativeScriptString> xString;
67     QDeclarativeNullableValue<QDeclarativeScriptString> yString;
68     QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
69     QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
70     QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
71     QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
72
73     void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = 0);
74 };
75
76 void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore)
77 {
78     if (targetParent && target && target->parentItem()) {
79         Q_Q(QQuickParentChange);
80         bool ok;
81         const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
82         if (transform.type() >= QTransform::TxShear || !ok) {
83             qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
84             ok = false;
85         }
86
87         qreal scale = 1;
88         qreal rotation = 0;
89         bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
90         if (ok && !isRotate) {
91             if (transform.m11() == transform.m22())
92                 scale = transform.m11();
93             else {
94                 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
95                 ok = false;
96             }
97         } else if (ok && isRotate) {
98             if (transform.m11() == transform.m22())
99                 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
100             else {
101                 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
102                 ok = false;
103             }
104
105             if (scale != 0)
106                 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
107             else {
108                 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
109                 ok = false;
110             }
111         }
112
113         const QPointF &point = transform.map(QPointF(target->x(),target->y()));
114         qreal x = point.x();
115         qreal y = point.y();
116
117         // setParentItem will update the transformOriginPoint if needed
118         target->setParentItem(targetParent);
119
120         if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
121             qreal tempxt = target->transformOriginPoint().x();
122             qreal tempyt = target->transformOriginPoint().y();
123             QTransform t;
124             t.translate(-tempxt, -tempyt);
125             t.rotate(rotation);
126             t.scale(scale, scale);
127             t.translate(tempxt, tempyt);
128             const QPointF &offset = t.map(QPointF(0,0));
129             x += offset.x();
130             y += offset.y();
131         }
132
133         if (ok) {
134             //qDebug() << x << y << rotation << scale;
135             target->setX(x);
136             target->setY(y);
137             target->setRotation(target->rotation() + rotation);
138             target->setScale(target->scale() * scale);
139         }
140     } else if (target) {
141         target->setParentItem(targetParent);
142     }
143
144     //restore the original stack position.
145     //### if stackBefore has also been reparented this won't work
146     if (stackBefore)
147         target->stackBefore(stackBefore);
148 }
149
150 QQuickParentChange::QQuickParentChange(QObject *parent)
151     : QDeclarativeStateOperation(*(new QQuickParentChangePrivate), parent)
152 {
153 }
154
155 QQuickParentChange::~QQuickParentChange()
156 {
157 }
158
159 QDeclarativeScriptString QQuickParentChange::x() const
160 {
161     Q_D(const QQuickParentChange);
162     return d->xString.value;
163 }
164
165 void QQuickParentChange::setX(QDeclarativeScriptString x)
166 {
167     Q_D(QQuickParentChange);
168     d->xString = x;
169 }
170
171 bool QQuickParentChange::xIsSet() const
172 {
173     Q_D(const QQuickParentChange);
174     return d->xString.isValid();
175 }
176
177 QDeclarativeScriptString QQuickParentChange::y() const
178 {
179     Q_D(const QQuickParentChange);
180     return d->yString.value;
181 }
182
183 void QQuickParentChange::setY(QDeclarativeScriptString y)
184 {
185     Q_D(QQuickParentChange);
186     d->yString = y;
187 }
188
189 bool QQuickParentChange::yIsSet() const
190 {
191     Q_D(const QQuickParentChange);
192     return d->yString.isValid();
193 }
194
195 QDeclarativeScriptString QQuickParentChange::width() const
196 {
197     Q_D(const QQuickParentChange);
198     return d->widthString.value;
199 }
200
201 void QQuickParentChange::setWidth(QDeclarativeScriptString width)
202 {
203     Q_D(QQuickParentChange);
204     d->widthString = width;
205 }
206
207 bool QQuickParentChange::widthIsSet() const
208 {
209     Q_D(const QQuickParentChange);
210     return d->widthString.isValid();
211 }
212
213 QDeclarativeScriptString QQuickParentChange::height() const
214 {
215     Q_D(const QQuickParentChange);
216     return d->heightString.value;
217 }
218
219 void QQuickParentChange::setHeight(QDeclarativeScriptString height)
220 {
221     Q_D(QQuickParentChange);
222     d->heightString = height;
223 }
224
225 bool QQuickParentChange::heightIsSet() const
226 {
227     Q_D(const QQuickParentChange);
228     return d->heightString.isValid();
229 }
230
231 QDeclarativeScriptString QQuickParentChange::scale() const
232 {
233     Q_D(const QQuickParentChange);
234     return d->scaleString.value;
235 }
236
237 void QQuickParentChange::setScale(QDeclarativeScriptString scale)
238 {
239     Q_D(QQuickParentChange);
240     d->scaleString = scale;
241 }
242
243 bool QQuickParentChange::scaleIsSet() const
244 {
245     Q_D(const QQuickParentChange);
246     return d->scaleString.isValid();
247 }
248
249 QDeclarativeScriptString QQuickParentChange::rotation() const
250 {
251     Q_D(const QQuickParentChange);
252     return d->rotationString.value;
253 }
254
255 void QQuickParentChange::setRotation(QDeclarativeScriptString rotation)
256 {
257     Q_D(QQuickParentChange);
258     d->rotationString = rotation;
259 }
260
261 bool QQuickParentChange::rotationIsSet() const
262 {
263     Q_D(const QQuickParentChange);
264     return d->rotationString.isValid();
265 }
266
267 QQuickItem *QQuickParentChange::originalParent() const
268 {
269     Q_D(const QQuickParentChange);
270     return d->origParent;
271 }
272
273 QQuickItem *QQuickParentChange::object() const
274 {
275     Q_D(const QQuickParentChange);
276     return d->target;
277 }
278
279 void QQuickParentChange::setObject(QQuickItem *target)
280 {
281     Q_D(QQuickParentChange);
282     d->target = target;
283 }
284
285 QQuickItem *QQuickParentChange::parent() const
286 {
287     Q_D(const QQuickParentChange);
288     return d->parent;
289 }
290
291 void QQuickParentChange::setParent(QQuickItem *parent)
292 {
293     Q_D(QQuickParentChange);
294     d->parent = parent;
295 }
296
297 QDeclarativeStateOperation::ActionList QQuickParentChange::actions()
298 {
299     Q_D(QQuickParentChange);
300     if (!d->target || !d->parent)
301         return ActionList();
302
303     ActionList actions;
304
305     QDeclarativeAction a;
306     a.event = this;
307     actions << a;
308
309     if (d->xString.isValid()) {
310         bool ok = false;
311         QString script = d->xString.value.script();
312         qreal x = script.toFloat(&ok);
313         if (ok) {
314             QDeclarativeAction xa(d->target, QLatin1String("x"), x);
315             actions << xa;
316         } else {
317             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
318             QDeclarativeProperty property(d->target, QLatin1String("x"));
319             newBinding->setTarget(property);
320             QDeclarativeAction xa;
321             xa.property = property;
322             xa.toBinding = newBinding;
323             xa.fromValue = xa.property.read();
324             xa.deletableToBinding = true;
325             actions << xa;
326         }
327     }
328
329     if (d->yString.isValid()) {
330         bool ok = false;
331         QString script = d->yString.value.script();
332         qreal y = script.toFloat(&ok);
333         if (ok) {
334             QDeclarativeAction ya(d->target, QLatin1String("y"), y);
335             actions << ya;
336         } else {
337             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
338             QDeclarativeProperty property(d->target, QLatin1String("y"));
339             newBinding->setTarget(property);
340             QDeclarativeAction ya;
341             ya.property = property;
342             ya.toBinding = newBinding;
343             ya.fromValue = ya.property.read();
344             ya.deletableToBinding = true;
345             actions << ya;
346         }
347     }
348
349     if (d->scaleString.isValid()) {
350         bool ok = false;
351         QString script = d->scaleString.value.script();
352         qreal scale = script.toFloat(&ok);
353         if (ok) {
354             QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
355             actions << sa;
356         } else {
357             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
358             QDeclarativeProperty property(d->target, QLatin1String("scale"));
359             newBinding->setTarget(property);
360             QDeclarativeAction sa;
361             sa.property = property;
362             sa.toBinding = newBinding;
363             sa.fromValue = sa.property.read();
364             sa.deletableToBinding = true;
365             actions << sa;
366         }
367     }
368
369     if (d->rotationString.isValid()) {
370         bool ok = false;
371         QString script = d->rotationString.value.script();
372         qreal rotation = script.toFloat(&ok);
373         if (ok) {
374             QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
375             actions << ra;
376         } else {
377             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
378             QDeclarativeProperty property(d->target, QLatin1String("rotation"));
379             newBinding->setTarget(property);
380             QDeclarativeAction ra;
381             ra.property = property;
382             ra.toBinding = newBinding;
383             ra.fromValue = ra.property.read();
384             ra.deletableToBinding = true;
385             actions << ra;
386         }
387     }
388
389     if (d->widthString.isValid()) {
390         bool ok = false;
391         QString script = d->widthString.value.script();
392         qreal width = script.toFloat(&ok);
393         if (ok) {
394             QDeclarativeAction wa(d->target, QLatin1String("width"), width);
395             actions << wa;
396         } else {
397             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
398             QDeclarativeProperty property(d->target, QLatin1String("width"));
399             newBinding->setTarget(property);
400             QDeclarativeAction wa;
401             wa.property = property;
402             wa.toBinding = newBinding;
403             wa.fromValue = wa.property.read();
404             wa.deletableToBinding = true;
405             actions << wa;
406         }
407     }
408
409     if (d->heightString.isValid()) {
410         bool ok = false;
411         QString script = d->heightString.value.script();
412         qreal height = script.toFloat(&ok);
413         if (ok) {
414             QDeclarativeAction ha(d->target, QLatin1String("height"), height);
415             actions << ha;
416         } else {
417             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
418             QDeclarativeProperty property(d->target, QLatin1String("height"));
419             newBinding->setTarget(property);
420             QDeclarativeAction ha;
421             ha.property = property;
422             ha.toBinding = newBinding;
423             ha.fromValue = ha.property.read();
424             ha.deletableToBinding = true;
425             actions << ha;
426         }
427     }
428
429     return actions;
430 }
431
432 void QQuickParentChange::saveOriginals()
433 {
434     Q_D(QQuickParentChange);
435     saveCurrentValues();
436     d->origParent = d->rewindParent;
437     d->origStackBefore = d->rewindStackBefore;
438 }
439
440 /*void QQuickParentChange::copyOriginals(QDeclarativeActionEvent *other)
441 {
442     Q_D(QQuickParentChange);
443     QQuickParentChange *pc = static_cast<QQuickParentChange*>(other);
444
445     d->origParent = pc->d_func()->rewindParent;
446     d->origStackBefore = pc->d_func()->rewindStackBefore;
447
448     saveCurrentValues();
449 }*/
450
451 void QQuickParentChange::execute(Reason)
452 {
453     Q_D(QQuickParentChange);
454     d->doChange(d->parent);
455 }
456
457 bool QQuickParentChange::isReversable()
458 {
459     return true;
460 }
461
462 void QQuickParentChange::reverse(Reason)
463 {
464     Q_D(QQuickParentChange);
465     d->doChange(d->origParent, d->origStackBefore);
466 }
467
468 QString QQuickParentChange::typeName() const
469 {
470     return QLatin1String("ParentChange");
471 }
472
473 bool QQuickParentChange::override(QDeclarativeActionEvent*other)
474 {
475     Q_D(QQuickParentChange);
476     if (other->typeName() != QLatin1String("ParentChange"))
477         return false;
478     if (QQuickParentChange *otherPC = static_cast<QQuickParentChange*>(other))
479         return (d->target == otherPC->object());
480     return false;
481 }
482
483 void QQuickParentChange::saveCurrentValues()
484 {
485     Q_D(QQuickParentChange);
486     if (!d->target) {
487         d->rewindParent = 0;
488         d->rewindStackBefore = 0;
489         return;
490     }
491
492     d->rewindParent = d->target->parentItem();
493     d->rewindStackBefore = 0;
494
495     if (!d->rewindParent)
496         return;
497
498     QList<QQuickItem *> children = d->rewindParent->childItems();
499     for (int ii = 0; ii < children.count() - 1; ++ii) {
500         if (children.at(ii) == d->target) {
501             d->rewindStackBefore = children.at(ii + 1);
502             break;
503         }
504     }
505 }
506
507 void QQuickParentChange::rewind()
508 {
509     Q_D(QQuickParentChange);
510     d->doChange(d->rewindParent, d->rewindStackBefore);
511 }
512
513 class QQuickAnchorSetPrivate : public QObjectPrivate
514 {
515     Q_DECLARE_PUBLIC(QQuickAnchorSet)
516 public:
517     QQuickAnchorSetPrivate()
518       : usedAnchors(0), resetAnchors(0), fill(0),
519         centerIn(0)/*, leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
520         margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)*/
521     {
522     }
523
524     QQuickAnchors::Anchors usedAnchors;
525     QQuickAnchors::Anchors resetAnchors;
526
527     QQuickItem *fill;
528     QQuickItem *centerIn;
529
530     QDeclarativeScriptString leftScript;
531     QDeclarativeScriptString rightScript;
532     QDeclarativeScriptString topScript;
533     QDeclarativeScriptString bottomScript;
534     QDeclarativeScriptString hCenterScript;
535     QDeclarativeScriptString vCenterScript;
536     QDeclarativeScriptString baselineScript;
537
538     /*qreal leftMargin;
539     qreal rightMargin;
540     qreal topMargin;
541     qreal bottomMargin;
542     qreal margins;
543     qreal vCenterOffset;
544     qreal hCenterOffset;
545     qreal baselineOffset;*/
546 };
547
548 QQuickAnchorSet::QQuickAnchorSet(QObject *parent)
549   : QObject(*new QQuickAnchorSetPrivate, parent)
550 {
551 }
552
553 QQuickAnchorSet::~QQuickAnchorSet()
554 {
555 }
556
557 QDeclarativeScriptString QQuickAnchorSet::top() const
558 {
559     Q_D(const QQuickAnchorSet);
560     return d->topScript;
561 }
562
563 void QQuickAnchorSet::setTop(const QDeclarativeScriptString &edge)
564 {
565     Q_D(QQuickAnchorSet);
566     d->usedAnchors |= QQuickAnchors::TopAnchor;
567     d->topScript = edge;
568     if (edge.script() == QLatin1String("undefined"))
569         resetTop();
570 }
571
572 void QQuickAnchorSet::resetTop()
573 {
574     Q_D(QQuickAnchorSet);
575     d->usedAnchors &= ~QQuickAnchors::TopAnchor;
576     d->topScript = QDeclarativeScriptString();
577     d->resetAnchors |= QQuickAnchors::TopAnchor;
578 }
579
580 QDeclarativeScriptString QQuickAnchorSet::bottom() const
581 {
582     Q_D(const QQuickAnchorSet);
583     return d->bottomScript;
584 }
585
586 void QQuickAnchorSet::setBottom(const QDeclarativeScriptString &edge)
587 {
588     Q_D(QQuickAnchorSet);
589     d->usedAnchors |= QQuickAnchors::BottomAnchor;
590     d->bottomScript = edge;
591     if (edge.script() == QLatin1String("undefined"))
592         resetBottom();
593 }
594
595 void QQuickAnchorSet::resetBottom()
596 {
597     Q_D(QQuickAnchorSet);
598     d->usedAnchors &= ~QQuickAnchors::BottomAnchor;
599     d->bottomScript = QDeclarativeScriptString();
600     d->resetAnchors |= QQuickAnchors::BottomAnchor;
601 }
602
603 QDeclarativeScriptString QQuickAnchorSet::verticalCenter() const
604 {
605     Q_D(const QQuickAnchorSet);
606     return d->vCenterScript;
607 }
608
609 void QQuickAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
610 {
611     Q_D(QQuickAnchorSet);
612     d->usedAnchors |= QQuickAnchors::VCenterAnchor;
613     d->vCenterScript = edge;
614     if (edge.script() == QLatin1String("undefined"))
615         resetVerticalCenter();
616 }
617
618 void QQuickAnchorSet::resetVerticalCenter()
619 {
620     Q_D(QQuickAnchorSet);
621     d->usedAnchors &= ~QQuickAnchors::VCenterAnchor;
622     d->vCenterScript = QDeclarativeScriptString();
623     d->resetAnchors |= QQuickAnchors::VCenterAnchor;
624 }
625
626 QDeclarativeScriptString QQuickAnchorSet::baseline() const
627 {
628     Q_D(const QQuickAnchorSet);
629     return d->baselineScript;
630 }
631
632 void QQuickAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
633 {
634     Q_D(QQuickAnchorSet);
635     d->usedAnchors |= QQuickAnchors::BaselineAnchor;
636     d->baselineScript = edge;
637     if (edge.script() == QLatin1String("undefined"))
638         resetBaseline();
639 }
640
641 void QQuickAnchorSet::resetBaseline()
642 {
643     Q_D(QQuickAnchorSet);
644     d->usedAnchors &= ~QQuickAnchors::BaselineAnchor;
645     d->baselineScript = QDeclarativeScriptString();
646     d->resetAnchors |= QQuickAnchors::BaselineAnchor;
647 }
648
649 QDeclarativeScriptString QQuickAnchorSet::left() const
650 {
651     Q_D(const QQuickAnchorSet);
652     return d->leftScript;
653 }
654
655 void QQuickAnchorSet::setLeft(const QDeclarativeScriptString &edge)
656 {
657     Q_D(QQuickAnchorSet);
658     d->usedAnchors |= QQuickAnchors::LeftAnchor;
659     d->leftScript = edge;
660     if (edge.script() == QLatin1String("undefined"))
661         resetLeft();
662 }
663
664 void QQuickAnchorSet::resetLeft()
665 {
666     Q_D(QQuickAnchorSet);
667     d->usedAnchors &= ~QQuickAnchors::LeftAnchor;
668     d->leftScript = QDeclarativeScriptString();
669     d->resetAnchors |= QQuickAnchors::LeftAnchor;
670 }
671
672 QDeclarativeScriptString QQuickAnchorSet::right() const
673 {
674     Q_D(const QQuickAnchorSet);
675     return d->rightScript;
676 }
677
678 void QQuickAnchorSet::setRight(const QDeclarativeScriptString &edge)
679 {
680     Q_D(QQuickAnchorSet);
681     d->usedAnchors |= QQuickAnchors::RightAnchor;
682     d->rightScript = edge;
683     if (edge.script() == QLatin1String("undefined"))
684         resetRight();
685 }
686
687 void QQuickAnchorSet::resetRight()
688 {
689     Q_D(QQuickAnchorSet);
690     d->usedAnchors &= ~QQuickAnchors::RightAnchor;
691     d->rightScript = QDeclarativeScriptString();
692     d->resetAnchors |= QQuickAnchors::RightAnchor;
693 }
694
695 QDeclarativeScriptString QQuickAnchorSet::horizontalCenter() const
696 {
697     Q_D(const QQuickAnchorSet);
698     return d->hCenterScript;
699 }
700
701 void QQuickAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
702 {
703     Q_D(QQuickAnchorSet);
704     d->usedAnchors |= QQuickAnchors::HCenterAnchor;
705     d->hCenterScript = edge;
706     if (edge.script() == QLatin1String("undefined"))
707         resetHorizontalCenter();
708 }
709
710 void QQuickAnchorSet::resetHorizontalCenter()
711 {
712     Q_D(QQuickAnchorSet);
713     d->usedAnchors &= ~QQuickAnchors::HCenterAnchor;
714     d->hCenterScript = QDeclarativeScriptString();
715     d->resetAnchors |= QQuickAnchors::HCenterAnchor;
716 }
717
718 QQuickItem *QQuickAnchorSet::fill() const
719 {
720     Q_D(const QQuickAnchorSet);
721     return d->fill;
722 }
723
724 void QQuickAnchorSet::setFill(QQuickItem *f)
725 {
726     Q_D(QQuickAnchorSet);
727     d->fill = f;
728 }
729
730 void QQuickAnchorSet::resetFill()
731 {
732     setFill(0);
733 }
734
735 QQuickItem *QQuickAnchorSet::centerIn() const
736 {
737     Q_D(const QQuickAnchorSet);
738     return d->centerIn;
739 }
740
741 void QQuickAnchorSet::setCenterIn(QQuickItem* c)
742 {
743     Q_D(QQuickAnchorSet);
744     d->centerIn = c;
745 }
746
747 void QQuickAnchorSet::resetCenterIn()
748 {
749     setCenterIn(0);
750 }
751
752
753 class QQuickAnchorChangesPrivate : public QDeclarativeStateOperationPrivate
754 {
755 public:
756     QQuickAnchorChangesPrivate()
757         : target(0), anchorSet(new QQuickAnchorSet),
758           leftBinding(0), rightBinding(0), hCenterBinding(0),
759           topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
760           origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
761           origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
762           origBaselineBinding(0)
763     {
764
765     }
766     ~QQuickAnchorChangesPrivate() { delete anchorSet; }
767
768     QQuickItem *target;
769     QQuickAnchorSet *anchorSet;
770
771     QDeclarativeBinding *leftBinding;
772     QDeclarativeBinding *rightBinding;
773     QDeclarativeBinding *hCenterBinding;
774     QDeclarativeBinding *topBinding;
775     QDeclarativeBinding *bottomBinding;
776     QDeclarativeBinding *vCenterBinding;
777     QDeclarativeBinding *baselineBinding;
778
779     QDeclarativeAbstractBinding *origLeftBinding;
780     QDeclarativeAbstractBinding *origRightBinding;
781     QDeclarativeAbstractBinding *origHCenterBinding;
782     QDeclarativeAbstractBinding *origTopBinding;
783     QDeclarativeAbstractBinding *origBottomBinding;
784     QDeclarativeAbstractBinding *origVCenterBinding;
785     QDeclarativeAbstractBinding *origBaselineBinding;
786
787     QQuickAnchorLine rewindLeft;
788     QQuickAnchorLine rewindRight;
789     QQuickAnchorLine rewindHCenter;
790     QQuickAnchorLine rewindTop;
791     QQuickAnchorLine rewindBottom;
792     QQuickAnchorLine rewindVCenter;
793     QQuickAnchorLine rewindBaseline;
794
795     qreal fromX;
796     qreal fromY;
797     qreal fromWidth;
798     qreal fromHeight;
799
800     qreal toX;
801     qreal toY;
802     qreal toWidth;
803     qreal toHeight;
804
805     qreal rewindX;
806     qreal rewindY;
807     qreal rewindWidth;
808     qreal rewindHeight;
809
810     bool applyOrigLeft;
811     bool applyOrigRight;
812     bool applyOrigHCenter;
813     bool applyOrigTop;
814     bool applyOrigBottom;
815     bool applyOrigVCenter;
816     bool applyOrigBaseline;
817
818     QDeclarativeNullableValue<qreal> origWidth;
819     QDeclarativeNullableValue<qreal> origHeight;
820     qreal origX;
821     qreal origY;
822
823     QList<QDeclarativeAbstractBinding*> oldBindings;
824
825     QDeclarativeProperty leftProp;
826     QDeclarativeProperty rightProp;
827     QDeclarativeProperty hCenterProp;
828     QDeclarativeProperty topProp;
829     QDeclarativeProperty bottomProp;
830     QDeclarativeProperty vCenterProp;
831     QDeclarativeProperty baselineProp;
832 };
833
834 QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent)
835  : QDeclarativeStateOperation(*(new QQuickAnchorChangesPrivate), parent)
836 {
837 }
838
839 QQuickAnchorChanges::~QQuickAnchorChanges()
840 {
841 }
842
843 QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions()
844 {
845     Q_D(QQuickAnchorChanges);
846     d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
847                    = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
848
849     d->leftProp = QDeclarativeProperty(d->target, QLatin1String("anchors.left"));
850     d->rightProp = QDeclarativeProperty(d->target, QLatin1String("anchors.right"));
851     d->hCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.horizontalCenter"));
852     d->topProp = QDeclarativeProperty(d->target, QLatin1String("anchors.top"));
853     d->bottomProp = QDeclarativeProperty(d->target, QLatin1String("anchors.bottom"));
854     d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
855     d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
856
857     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::LeftAnchor) {
858         d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
859         d->leftBinding->setTarget(d->leftProp);
860     }
861     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::RightAnchor) {
862         d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
863         d->rightBinding->setTarget(d->rightProp);
864     }
865     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::HCenterAnchor) {
866         d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
867         d->hCenterBinding->setTarget(d->hCenterProp);
868     }
869     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::TopAnchor) {
870         d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
871         d->topBinding->setTarget(d->topProp);
872     }
873     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BottomAnchor) {
874         d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
875         d->bottomBinding->setTarget(d->bottomProp);
876     }
877     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::VCenterAnchor) {
878         d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
879         d->vCenterBinding->setTarget(d->vCenterProp);
880     }
881     if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BaselineAnchor) {
882         d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
883         d->baselineBinding->setTarget(d->baselineProp);
884     }
885
886     QDeclarativeAction a;
887     a.event = this;
888     return ActionList() << a;
889 }
890
891 QQuickAnchorSet *QQuickAnchorChanges::anchors()
892 {
893     Q_D(QQuickAnchorChanges);
894     return d->anchorSet;
895 }
896
897 QQuickItem *QQuickAnchorChanges::object() const
898 {
899     Q_D(const QQuickAnchorChanges);
900     return d->target;
901 }
902
903 void QQuickAnchorChanges::setObject(QQuickItem *target)
904 {
905     Q_D(QQuickAnchorChanges);
906     d->target = target;
907 }
908
909 void QQuickAnchorChanges::execute(Reason reason)
910 {
911     Q_D(QQuickAnchorChanges);
912     if (!d->target)
913         return;
914
915     QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
916     //incorporate any needed "reverts"
917     if (d->applyOrigLeft) {
918         if (!d->origLeftBinding)
919             targetPrivate->anchors()->resetLeft();
920         QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
921     }
922     if (d->applyOrigRight) {
923         if (!d->origRightBinding)
924             targetPrivate->anchors()->resetRight();
925         QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
926     }
927     if (d->applyOrigHCenter) {
928         if (!d->origHCenterBinding)
929             targetPrivate->anchors()->resetHorizontalCenter();
930         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
931     }
932     if (d->applyOrigTop) {
933         if (!d->origTopBinding)
934             targetPrivate->anchors()->resetTop();
935         QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
936     }
937     if (d->applyOrigBottom) {
938         if (!d->origBottomBinding)
939             targetPrivate->anchors()->resetBottom();
940         QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
941     }
942     if (d->applyOrigVCenter) {
943         if (!d->origVCenterBinding)
944             targetPrivate->anchors()->resetVerticalCenter();
945         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
946     }
947     if (d->applyOrigBaseline) {
948         if (!d->origBaselineBinding)
949             targetPrivate->anchors()->resetBaseline();
950         QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
951     }
952
953     //destroy old bindings
954     if (reason == ActualChange) {
955         for (int i = 0; i < d->oldBindings.size(); ++i) {
956             QDeclarativeAbstractBinding *binding = d->oldBindings.at(i);
957             if (binding)
958                 binding->destroy();
959         }
960         d->oldBindings.clear();
961     }
962
963     //reset any anchors that have been specified as "undefined"
964     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
965         targetPrivate->anchors()->resetLeft();
966         QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
967     }
968     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
969         targetPrivate->anchors()->resetRight();
970         QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
971     }
972     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
973         targetPrivate->anchors()->resetHorizontalCenter();
974         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
975     }
976     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
977         targetPrivate->anchors()->resetTop();
978         QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
979     }
980     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
981         targetPrivate->anchors()->resetBottom();
982         QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
983     }
984     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
985         targetPrivate->anchors()->resetVerticalCenter();
986         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
987     }
988     if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
989         targetPrivate->anchors()->resetBaseline();
990         QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
991     }
992
993     //set any anchors that have been specified
994     if (d->leftBinding)
995         QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
996     if (d->rightBinding)
997         QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
998     if (d->hCenterBinding)
999         QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
1000     if (d->topBinding)
1001         QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
1002     if (d->bottomBinding)
1003         QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
1004     if (d->vCenterBinding)
1005         QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
1006     if (d->baselineBinding)
1007         QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
1008 }
1009
1010 bool QQuickAnchorChanges::isReversable()
1011 {
1012     return true;
1013 }
1014
1015 void QQuickAnchorChanges::reverse(Reason reason)
1016 {
1017     Q_D(QQuickAnchorChanges);
1018     if (!d->target)
1019         return;
1020
1021     QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1022     //reset any anchors set by the state
1023     if (d->leftBinding) {
1024         targetPrivate->anchors()->resetLeft();
1025         QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0);
1026         if (reason == ActualChange) {
1027             d->leftBinding->destroy(); d->leftBinding = 0;
1028         }
1029     }
1030     if (d->rightBinding) {
1031         targetPrivate->anchors()->resetRight();
1032         QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0);
1033         if (reason == ActualChange) {
1034             d->rightBinding->destroy(); d->rightBinding = 0;
1035         }
1036     }
1037     if (d->hCenterBinding) {
1038         targetPrivate->anchors()->resetHorizontalCenter();
1039         QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
1040         if (reason == ActualChange) {
1041             d->hCenterBinding->destroy(); d->hCenterBinding = 0;
1042         }
1043     }
1044     if (d->topBinding) {
1045         targetPrivate->anchors()->resetTop();
1046         QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0);
1047         if (reason == ActualChange) {
1048             d->topBinding->destroy(); d->topBinding = 0;
1049         }
1050     }
1051     if (d->bottomBinding) {
1052         targetPrivate->anchors()->resetBottom();
1053         QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0);
1054         if (reason == ActualChange) {
1055             d->bottomBinding->destroy(); d->bottomBinding = 0;
1056         }
1057     }
1058     if (d->vCenterBinding) {
1059         targetPrivate->anchors()->resetVerticalCenter();
1060         QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
1061         if (reason == ActualChange) {
1062             d->vCenterBinding->destroy(); d->vCenterBinding = 0;
1063         }
1064     }
1065     if (d->baselineBinding) {
1066         targetPrivate->anchors()->resetBaseline();
1067         QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0);
1068         if (reason == ActualChange) {
1069             d->baselineBinding->destroy(); d->baselineBinding = 0;
1070         }
1071     }
1072
1073     //restore previous anchors
1074     if (d->origLeftBinding)
1075         QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
1076     if (d->origRightBinding)
1077         QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
1078     if (d->origHCenterBinding)
1079         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
1080     if (d->origTopBinding)
1081         QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
1082     if (d->origBottomBinding)
1083         QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
1084     if (d->origVCenterBinding)
1085         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
1086     if (d->origBaselineBinding)
1087         QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
1088
1089     //restore any absolute geometry changed by the state's anchors
1090     QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
1091     QQuickAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Vertical_Mask;
1092     QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
1093     QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
1094
1095     bool stateSetWidth = (stateHAnchors &&
1096                           stateHAnchors != QQuickAnchors::LeftAnchor &&
1097                           stateHAnchors != QQuickAnchors::RightAnchor &&
1098                           stateHAnchors != QQuickAnchors::HCenterAnchor);
1099     bool origSetWidth = (origHAnchors &&
1100                          origHAnchors != QQuickAnchors::LeftAnchor &&
1101                          origHAnchors != QQuickAnchors::RightAnchor &&
1102                          origHAnchors != QQuickAnchors::HCenterAnchor);
1103     if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
1104         d->target->setWidth(d->origWidth.value);
1105
1106     bool stateSetHeight = (stateVAnchors &&
1107                            stateVAnchors != QQuickAnchors::TopAnchor &&
1108                            stateVAnchors != QQuickAnchors::BottomAnchor &&
1109                            stateVAnchors != QQuickAnchors::VCenterAnchor &&
1110                            stateVAnchors != QQuickAnchors::BaselineAnchor);
1111     bool origSetHeight = (origVAnchors &&
1112                           origVAnchors != QQuickAnchors::TopAnchor &&
1113                           origVAnchors != QQuickAnchors::BottomAnchor &&
1114                           origVAnchors != QQuickAnchors::VCenterAnchor &&
1115                           origVAnchors != QQuickAnchors::BaselineAnchor);
1116     if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
1117         d->target->setHeight(d->origHeight.value);
1118
1119     if (stateHAnchors && !origHAnchors)
1120         d->target->setX(d->origX);
1121
1122     if (stateVAnchors && !origVAnchors)
1123         d->target->setY(d->origY);
1124 }
1125
1126 QString QQuickAnchorChanges::typeName() const
1127 {
1128     return QLatin1String("AnchorChanges");
1129 }
1130
1131 QList<QDeclarativeAction> QQuickAnchorChanges::additionalActions()
1132 {
1133     Q_D(QQuickAnchorChanges);
1134     QList<QDeclarativeAction> extra;
1135
1136     QQuickAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
1137     bool hChange = combined & QQuickAnchors::Horizontal_Mask;
1138     bool vChange = combined & QQuickAnchors::Vertical_Mask;
1139
1140     if (d->target) {
1141         QDeclarativeAction a;
1142         if (hChange && d->fromX != d->toX) {
1143             a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
1144             a.toValue = d->toX;
1145             extra << a;
1146         }
1147         if (vChange && d->fromY != d->toY) {
1148             a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
1149             a.toValue = d->toY;
1150             extra << a;
1151         }
1152         if (hChange && d->fromWidth != d->toWidth) {
1153             a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
1154             a.toValue = d->toWidth;
1155             extra << a;
1156         }
1157         if (vChange && d->fromHeight != d->toHeight) {
1158             a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
1159             a.toValue = d->toHeight;
1160             extra << a;
1161         }
1162     }
1163
1164     return extra;
1165 }
1166
1167 bool QQuickAnchorChanges::changesBindings()
1168 {
1169     return true;
1170 }
1171
1172 void QQuickAnchorChanges::saveOriginals()
1173 {
1174     Q_D(QQuickAnchorChanges);
1175     if (!d->target)
1176         return;
1177
1178     d->origLeftBinding = QDeclarativePropertyPrivate::binding(d->leftProp);
1179     d->origRightBinding = QDeclarativePropertyPrivate::binding(d->rightProp);
1180     d->origHCenterBinding = QDeclarativePropertyPrivate::binding(d->hCenterProp);
1181     d->origTopBinding = QDeclarativePropertyPrivate::binding(d->topProp);
1182     d->origBottomBinding = QDeclarativePropertyPrivate::binding(d->bottomProp);
1183     d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp);
1184     d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp);
1185
1186     QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1187     if (targetPrivate->widthValid)
1188         d->origWidth = d->target->width();
1189     if (targetPrivate->heightValid)
1190         d->origHeight = d->target->height();
1191     d->origX = d->target->x();
1192     d->origY = d->target->y();
1193
1194     d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
1195       = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
1196
1197     saveCurrentValues();
1198 }
1199
1200 void QQuickAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
1201 {
1202     Q_D(QQuickAnchorChanges);
1203     QQuickAnchorChanges *ac = static_cast<QQuickAnchorChanges*>(other);
1204     QQuickAnchorChangesPrivate *acp = ac->d_func();
1205
1206     QQuickAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
1207                                             acp->anchorSet->d_func()->resetAnchors;
1208
1209     //probably also need to revert some things
1210     d->applyOrigLeft = (combined & QQuickAnchors::LeftAnchor);
1211     d->applyOrigRight = (combined & QQuickAnchors::RightAnchor);
1212     d->applyOrigHCenter = (combined & QQuickAnchors::HCenterAnchor);
1213     d->applyOrigTop = (combined & QQuickAnchors::TopAnchor);
1214     d->applyOrigBottom = (combined & QQuickAnchors::BottomAnchor);
1215     d->applyOrigVCenter = (combined & QQuickAnchors::VCenterAnchor);
1216     d->applyOrigBaseline = (combined & QQuickAnchors::BaselineAnchor);
1217
1218     d->origLeftBinding = acp->origLeftBinding;
1219     d->origRightBinding = acp->origRightBinding;
1220     d->origHCenterBinding = acp->origHCenterBinding;
1221     d->origTopBinding = acp->origTopBinding;
1222     d->origBottomBinding = acp->origBottomBinding;
1223     d->origVCenterBinding = acp->origVCenterBinding;
1224     d->origBaselineBinding = acp->origBaselineBinding;
1225
1226     d->origWidth = acp->origWidth;
1227     d->origHeight = acp->origHeight;
1228     d->origX = acp->origX;
1229     d->origY = acp->origY;
1230
1231     d->oldBindings.clear();
1232     d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
1233                 << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
1234
1235     saveCurrentValues();
1236 }
1237
1238 void QQuickAnchorChanges::clearBindings()
1239 {
1240     Q_D(QQuickAnchorChanges);
1241     if (!d->target)
1242         return;
1243
1244     //### should this (saving "from" values) be moved to saveCurrentValues()?
1245     d->fromX = d->target->x();
1246     d->fromY = d->target->y();
1247     d->fromWidth = d->target->width();
1248     d->fromHeight = d->target->height();
1249
1250     QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1251     //reset any anchors with corresponding reverts
1252     //reset any anchors that have been specified as "undefined"
1253     //reset any anchors that we'll be setting in the state
1254     QQuickAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
1255                                             d->anchorSet->d_func()->usedAnchors;
1256     if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
1257         targetPrivate->anchors()->resetLeft();
1258         QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
1259     }
1260     if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
1261         targetPrivate->anchors()->resetRight();
1262         QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
1263     }
1264     if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
1265         targetPrivate->anchors()->resetHorizontalCenter();
1266         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
1267     }
1268     if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
1269         targetPrivate->anchors()->resetTop();
1270         QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
1271     }
1272     if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
1273         targetPrivate->anchors()->resetBottom();
1274         QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
1275     }
1276     if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
1277         targetPrivate->anchors()->resetVerticalCenter();
1278         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
1279     }
1280     if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
1281         targetPrivate->anchors()->resetBaseline();
1282         QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
1283     }
1284 }
1285
1286 bool QQuickAnchorChanges::override(QDeclarativeActionEvent*other)
1287 {
1288     if (other->typeName() != QLatin1String("AnchorChanges"))
1289         return false;
1290     if (static_cast<QDeclarativeActionEvent*>(this) == other)
1291         return true;
1292     if (static_cast<QQuickAnchorChanges*>(other)->object() == object())
1293         return true;
1294     return false;
1295 }
1296
1297 void QQuickAnchorChanges::rewind()
1298 {
1299     Q_D(QQuickAnchorChanges);
1300     if (!d->target)
1301         return;
1302
1303     QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1304
1305     //restore previous values (but not previous bindings, i.e. anchors)
1306     d->target->setX(d->rewindX);
1307     d->target->setY(d->rewindY);
1308     if (targetPrivate->widthValid) {
1309         d->target->setWidth(d->rewindWidth);
1310     }
1311     if (targetPrivate->heightValid) {
1312         d->target->setHeight(d->rewindHeight);
1313     }
1314 }
1315
1316 void QQuickAnchorChanges::saveCurrentValues()
1317 {
1318     Q_D(QQuickAnchorChanges);
1319     if (!d->target)
1320         return;
1321
1322     QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1323     d->rewindLeft = targetPrivate->anchors()->left();
1324     d->rewindRight = targetPrivate->anchors()->right();
1325     d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
1326     d->rewindTop = targetPrivate->anchors()->top();
1327     d->rewindBottom = targetPrivate->anchors()->bottom();
1328     d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
1329     d->rewindBaseline = targetPrivate->anchors()->baseline();
1330
1331     d->rewindX = d->target->x();
1332     d->rewindY = d->target->y();
1333     d->rewindWidth = d->target->width();
1334     d->rewindHeight = d->target->height();
1335 }
1336
1337 void QQuickAnchorChanges::saveTargetValues()
1338 {
1339     Q_D(QQuickAnchorChanges);
1340     if (!d->target)
1341         return;
1342
1343     d->toX = d->target->x();
1344     d->toY = d->target->y();
1345     d->toWidth = d->target->width();
1346     d->toHeight = d->target->height();
1347 }
1348
1349 #include <moc_qquickstateoperations_p.cpp>
1350
1351 QT_END_NAMESPACE
1352