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