Merge branch 'master' into refactor
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick1 / qdeclarativeitem / tst_qdeclarativeitem.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 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 test suite 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 #include <qtest.h>
42 #include <QtTest/QSignalSpy>
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <QtDeclarative/qdeclarativecontext.h>
46 #include <QtQuick1/qdeclarativeview.h>
47 #include <QtQuick1/private/qdeclarativerectangle_p.h>
48 #include <QtQuick1/private/qdeclarativeitem_p.h>
49 #include "../../../shared/util.h"
50
51 #ifdef Q_OS_SYMBIAN
52 // In Symbian OS test data is located in applications private dir
53 #define SRCDIR "."
54 #endif
55
56 class tst_QDeclarativeItem : public QObject
57
58 {
59     Q_OBJECT
60 public:
61     tst_QDeclarativeItem();
62
63 private slots:
64     void initTestCase();
65     void keys();
66     void keysProcessingOrder();
67     void keyNavigation();
68     void keyNavigation_RightToLeft();
69     void keyNavigation_skipNotVisible();
70     void keyNavigation_implicitSetting();
71     void layoutMirroring();
72     void layoutMirroringIllegalParent();
73     void smooth();
74     void clip();
75     void mapCoordinates();
76     void mapCoordinates_data();
77     void propertyChanges();
78     void transforms();
79     void transforms_data();
80     void childrenRect();
81     void childrenRectBug();
82     void childrenRectBug2();
83     void childrenRectBug3();
84
85     void childrenProperty();
86     void resourcesProperty();
87     void mouseFocus();
88
89     void transformCrash();
90     void implicitSize();
91     void testQtQuick11Attributes();
92     void testQtQuick11Attributes_data();
93     void qtbug_16871();
94     void qtbug_21045();
95 private:
96     QDeclarativeEngine engine;
97 };
98
99 template<typename T>
100 T *findItem(QGraphicsObject *parent, const QString &objectName)
101 {
102     if (!parent)
103         return 0;
104
105     const QMetaObject &mo = T::staticMetaObject;
106     //qDebug() << parent->QGraphicsObject::children().count() << "children";
107     for (int i = 0; i < parent->childItems().count(); ++i) {
108         QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
109         if(!item)
110             continue;
111         //qDebug() << "try" << item;
112         if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName))
113             return static_cast<T*>(item);
114         item = findItem<T>(item, objectName);
115         if (item)
116             return static_cast<T*>(item);
117     }
118
119     return 0;
120 }
121
122 class KeysTestObject : public QObject
123 {
124     Q_OBJECT
125
126     Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged)
127
128 public:
129     KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false) {}
130
131     void reset() {
132         mKey = 0;
133         mText = QString();
134         mModifiers = 0;
135         mForwardedKey = 0;
136     }
137
138     bool processLast() const { return mLast; }
139     void setProcessLast(bool b) {
140         if (b != mLast) {
141             mLast = b;
142             emit processLastChanged();
143         }
144     }
145
146 public slots:
147     void keyPress(int key, QString text, int modifiers) {
148         mKey = key;
149         mText = text;
150         mModifiers = modifiers;
151     }
152     void keyRelease(int key, QString text, int modifiers) {
153         mKey = key;
154         mText = text;
155         mModifiers = modifiers;
156     }
157     void forwardedKey(int key) {
158         mForwardedKey = key;
159     }
160
161 signals:
162     void processLastChanged();
163
164 public:
165     int mKey;
166     QString mText;
167     int mModifiers;
168     int mForwardedKey;
169     bool mLast;
170
171 private:
172 };
173
174 class KeyTestItem : public QDeclarativeItem
175 {
176     Q_OBJECT
177 public:
178     KeyTestItem(QDeclarativeItem *parent=0) : QDeclarativeItem(parent), mKey(0) {}
179
180 protected:
181     void keyPressEvent(QKeyEvent *e) {
182         keyPressPreHandler(e);
183         if (e->isAccepted())
184             return;
185
186         mKey = e->key();
187
188         if (e->key() == Qt::Key_A)
189             e->accept();
190         else
191             e->ignore();
192
193         if (!e->isAccepted())
194             QDeclarativeItem::keyPressEvent(e);
195     }
196
197     void keyReleaseEvent(QKeyEvent *e) {
198         keyReleasePreHandler(e);
199
200         if (e->isAccepted())
201             return;
202
203         if (e->key() == Qt::Key_B)
204             e->accept();
205         else
206             e->ignore();
207
208         if (!e->isAccepted())
209             QDeclarativeItem::keyReleaseEvent(e);
210     }
211
212 public:
213     int mKey;
214 };
215
216 QML_DECLARE_TYPE(KeyTestItem);
217
218
219 tst_QDeclarativeItem::tst_QDeclarativeItem()
220 {
221 }
222
223 void tst_QDeclarativeItem::initTestCase()
224 {
225     qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
226 }
227
228 void tst_QDeclarativeItem::keys()
229 {
230     QDeclarativeView *canvas = new QDeclarativeView(0);
231     canvas->setFixedSize(240,320);
232
233     KeysTestObject *testObject = new KeysTestObject;
234     canvas->rootContext()->setContextProperty("keysTestObject", testObject);
235
236     canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
237     canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true));
238
239     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keystest.qml"));
240     canvas->show();
241     qApp->processEvents();
242
243     QEvent wa(QEvent::WindowActivate);
244     QApplication::sendEvent(canvas, &wa);
245     QFocusEvent fe(QEvent::FocusIn);
246     QApplication::sendEvent(canvas, &fe);
247
248     QVERIFY(canvas->rootObject());
249     QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
250
251     QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
252     QApplication::sendEvent(canvas, &key);
253     QCOMPARE(testObject->mKey, int(Qt::Key_A));
254     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
255     QCOMPARE(testObject->mText, QLatin1String("A"));
256     QVERIFY(testObject->mModifiers == Qt::NoModifier);
257     QVERIFY(!key.isAccepted());
258
259     testObject->reset();
260
261     key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1);
262     QApplication::sendEvent(canvas, &key);
263     QCOMPARE(testObject->mKey, int(Qt::Key_A));
264     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
265     QCOMPARE(testObject->mText, QLatin1String("A"));
266     QVERIFY(testObject->mModifiers == Qt::ShiftModifier);
267     QVERIFY(key.isAccepted());
268
269     testObject->reset();
270
271     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
272     QApplication::sendEvent(canvas, &key);
273     QCOMPARE(testObject->mKey, int(Qt::Key_Return));
274     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return));
275     QCOMPARE(testObject->mText, QLatin1String("Return"));
276     QVERIFY(testObject->mModifiers == Qt::NoModifier);
277     QVERIFY(key.isAccepted());
278
279     testObject->reset();
280
281     key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1);
282     QApplication::sendEvent(canvas, &key);
283     QCOMPARE(testObject->mKey, int(Qt::Key_0));
284     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0));
285     QCOMPARE(testObject->mText, QLatin1String("0"));
286     QVERIFY(testObject->mModifiers == Qt::NoModifier);
287     QVERIFY(key.isAccepted());
288
289     testObject->reset();
290
291     key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1);
292     QApplication::sendEvent(canvas, &key);
293     QCOMPARE(testObject->mKey, int(Qt::Key_9));
294     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9));
295     QCOMPARE(testObject->mText, QLatin1String("9"));
296     QVERIFY(testObject->mModifiers == Qt::NoModifier);
297     QVERIFY(!key.isAccepted());
298
299     testObject->reset();
300
301     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
302     QApplication::sendEvent(canvas, &key);
303     QCOMPARE(testObject->mKey, int(Qt::Key_Tab));
304     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab));
305     QCOMPARE(testObject->mText, QLatin1String("Tab"));
306     QVERIFY(testObject->mModifiers == Qt::NoModifier);
307     QVERIFY(key.isAccepted());
308
309     testObject->reset();
310
311     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
312     QApplication::sendEvent(canvas, &key);
313     QCOMPARE(testObject->mKey, int(Qt::Key_Backtab));
314     QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab));
315     QCOMPARE(testObject->mText, QLatin1String("Backtab"));
316     QVERIFY(testObject->mModifiers == Qt::NoModifier);
317     QVERIFY(key.isAccepted());
318
319     testObject->reset();
320
321     canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false));
322     key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
323     QApplication::sendEvent(canvas, &key);
324     QCOMPARE(testObject->mKey, int(Qt::Key_A));
325     QCOMPARE(testObject->mForwardedKey, 0);
326     QCOMPARE(testObject->mText, QLatin1String("A"));
327     QVERIFY(testObject->mModifiers == Qt::NoModifier);
328     QVERIFY(!key.isAccepted());
329
330     testObject->reset();
331
332     canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false));
333     QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false);
334
335     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
336     QApplication::sendEvent(canvas, &key);
337     QCOMPARE(testObject->mKey, 0);
338     QVERIFY(!key.isAccepted());
339
340     canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
341     QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true);
342
343     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
344     QApplication::sendEvent(canvas, &key);
345     QCOMPARE(testObject->mKey, int(Qt::Key_Return));
346     QVERIFY(key.isAccepted());
347
348     delete canvas;
349     delete testObject;
350 }
351
352 void tst_QDeclarativeItem::keysProcessingOrder()
353 {
354     QDeclarativeView *canvas = new QDeclarativeView(0);
355     canvas->setFixedSize(240,320);
356
357     KeysTestObject *testObject = new KeysTestObject;
358     canvas->rootContext()->setContextProperty("keysTestObject", testObject);
359
360     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keyspriority.qml"));
361     canvas->show();
362     qApp->processEvents();
363
364     KeyTestItem *testItem = qobject_cast<KeyTestItem*>(canvas->rootObject());
365     QVERIFY(testItem);
366
367     QEvent wa(QEvent::WindowActivate);
368     QApplication::sendEvent(canvas, &wa);
369     QFocusEvent fe(QEvent::FocusIn);
370     QApplication::sendEvent(canvas, &fe);
371
372     QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
373     QApplication::sendEvent(canvas, &key);
374     QCOMPARE(testObject->mKey, int(Qt::Key_A));
375     QCOMPARE(testObject->mText, QLatin1String("A"));
376     QVERIFY(testObject->mModifiers == Qt::NoModifier);
377     QVERIFY(key.isAccepted());
378
379     testObject->reset();
380
381     testObject->setProcessLast(true);
382
383     key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
384     QApplication::sendEvent(canvas, &key);
385     QCOMPARE(testObject->mKey, 0);
386     QVERIFY(key.isAccepted());
387
388     testObject->reset();
389
390     key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1);
391     QApplication::sendEvent(canvas, &key);
392     QCOMPARE(testObject->mKey, int(Qt::Key_B));
393     QCOMPARE(testObject->mText, QLatin1String("B"));
394     QVERIFY(testObject->mModifiers == Qt::NoModifier);
395     QVERIFY(!key.isAccepted());
396
397     testObject->reset();
398
399     key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1);
400     QApplication::sendEvent(canvas, &key);
401     QCOMPARE(testObject->mKey, 0);
402     QVERIFY(key.isAccepted());
403
404     delete canvas;
405     delete testObject;
406 }
407
408 QDeclarativeItemPrivate *childPrivate(QGraphicsObject *rootItem, const char * itemString)
409 {
410     QDeclarativeItem *item = findItem<QDeclarativeItem>(rootItem, QString(QLatin1String(itemString)));
411     QDeclarativeItemPrivate* itemPrivate = QDeclarativeItemPrivate::get(item);
412     return itemPrivate;
413 }
414
415 QVariant childProperty(QGraphicsObject *rootItem, const char * itemString, const char * property)
416 {
417     QDeclarativeItem *item = findItem<QDeclarativeItem>(rootItem, QString(QLatin1String(itemString)));
418     return item->property(property);
419 }
420
421 bool anchorsMirrored(QGraphicsObject *rootItem, const char * itemString)
422 {
423     QDeclarativeItem *item = findItem<QDeclarativeItem>(rootItem, QString(QLatin1String(itemString)));
424     QDeclarativeItemPrivate* itemPrivate = QDeclarativeItemPrivate::get(item);
425     return itemPrivate->anchors()->mirrored();
426 }
427
428 void tst_QDeclarativeItem::layoutMirroring()
429 {
430     QDeclarativeView *canvas = new QDeclarativeView(0);
431     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/layoutmirroring.qml"));
432     canvas->show();
433
434     QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
435     QVERIFY(rootItem);
436     QDeclarativeItemPrivate *rootPrivate = QDeclarativeItemPrivate::get(rootItem);
437     QVERIFY(rootPrivate);
438
439     QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
440     QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true);
441     QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
442     QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false);
443     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
444     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
445
446     QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true);
447     QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true);
448     QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false);
449     QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false);
450     QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true);
451     QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true);
452
453     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
454     QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false);
455     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
456     QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false);
457     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
458     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
459
460     QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false);
461     QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false);
462     QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false);
463     QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true);
464     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true);
465     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true);
466
467     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true);
468     QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false);
469     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true);
470     QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false);
471     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true);
472     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true);
473
474     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true);
475     QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false);
476     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false);
477     QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false);
478     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false);
479     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false);
480
481     // load dynamic content using Loader that needs to inherit mirroring
482     rootItem->setProperty("state", "newContent");
483     QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false);
484     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true);
485
486     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true);
487     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true);
488
489     QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false);
490     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true);
491
492     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true);
493     QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true);
494
495     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
496     QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
497
498     // disable inheritance
499     rootItem->setProperty("childrenInherit", false);
500
501     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false);
502     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false);
503     QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
504     QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
505
506     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false);
507     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false);
508     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false);
509     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false);
510
511     // re-enable inheritance
512     rootItem->setProperty("childrenInherit", true);
513
514     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
515     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
516     QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
517     QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
518
519     QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
520     QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
521     QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
522     QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
523     
524     //
525     // dynamic parenting
526     //
527     QDeclarativeItem *parentItem1 = new QDeclarativeItem();
528     QDeclarativeItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
529     QDeclarativeItemPrivate::get(parentItem1)->isMirrorImplicit = false;
530     QDeclarativeItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
531     QDeclarativeItemPrivate::get(parentItem1)->resolveLayoutMirror();
532
533     // inherit in constructor
534     QDeclarativeItem *childItem1 = new QDeclarativeItem(parentItem1);
535     QCOMPARE(QDeclarativeItemPrivate::get(childItem1)->effectiveLayoutMirror, true);
536     QCOMPARE(QDeclarativeItemPrivate::get(childItem1)->inheritMirrorFromParent, true);
537
538     // inherit through a parent change
539     QDeclarativeItem *childItem2 = new QDeclarativeItem();
540     QCOMPARE(QDeclarativeItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
541     QCOMPARE(QDeclarativeItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
542     childItem2->setParentItem(parentItem1);
543     QCOMPARE(QDeclarativeItemPrivate::get(childItem2)->effectiveLayoutMirror, true);
544     QCOMPARE(QDeclarativeItemPrivate::get(childItem2)->inheritMirrorFromParent, true);
545
546     // stop inherting through a parent change
547     QDeclarativeItem *parentItem2 = new QDeclarativeItem();
548     QDeclarativeItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
549     QDeclarativeItemPrivate::get(parentItem2)->resolveLayoutMirror();
550     childItem2->setParentItem(parentItem2);
551     QCOMPARE(QDeclarativeItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
552     QCOMPARE(QDeclarativeItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
553     
554     delete parentItem1;
555     delete parentItem2;
556 }
557
558 void tst_QDeclarativeItem::layoutMirroringIllegalParent()
559 {
560     QDeclarativeComponent component(&engine);
561     component.setData("import QtQuick 1.1; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile(""));
562     QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items");
563     QObject *object = component.create();
564     QVERIFY(object != 0);
565 }
566
567 void tst_QDeclarativeItem::keyNavigation()
568 {
569     QDeclarativeView *canvas = new QDeclarativeView(0);
570     canvas->setFixedSize(240,320);
571
572     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
573     canvas->show();
574     qApp->processEvents();
575
576     QEvent wa(QEvent::WindowActivate);
577     QApplication::sendEvent(canvas, &wa);
578     QFocusEvent fe(QEvent::FocusIn);
579     QApplication::sendEvent(canvas, &fe);
580
581     QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
582     QVERIFY(item);
583     QVERIFY(item->hasActiveFocus());
584
585     QVariant result;
586     QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
587             Q_RETURN_ARG(QVariant, result)));
588     QVERIFY(result.toBool());
589
590     // right
591     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
592     QApplication::sendEvent(canvas, &key);
593     QVERIFY(key.isAccepted());
594
595     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
596     QVERIFY(item);
597     QVERIFY(item->hasActiveFocus());
598
599     // down
600     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
601     QApplication::sendEvent(canvas, &key);
602     QVERIFY(key.isAccepted());
603
604     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
605     QVERIFY(item);
606     QVERIFY(item->hasActiveFocus());
607
608     // left
609     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
610     QApplication::sendEvent(canvas, &key);
611     QVERIFY(key.isAccepted());
612
613     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
614     QVERIFY(item);
615     QVERIFY(item->hasActiveFocus());
616
617     // up
618     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
619     QApplication::sendEvent(canvas, &key);
620     QVERIFY(key.isAccepted());
621
622     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
623     QVERIFY(item);
624     QVERIFY(item->hasActiveFocus());
625
626     // tab
627     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
628     QApplication::sendEvent(canvas, &key);
629     QVERIFY(key.isAccepted());
630
631     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
632     QVERIFY(item);
633     QVERIFY(item->hasActiveFocus());
634
635     // backtab
636     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
637     QApplication::sendEvent(canvas, &key);
638     QVERIFY(key.isAccepted());
639
640     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
641     QVERIFY(item);
642     QVERIFY(item->hasActiveFocus());
643
644     delete canvas;
645 }
646
647 void tst_QDeclarativeItem::keyNavigation_RightToLeft()
648 {
649     QDeclarativeView *canvas = new QDeclarativeView(0);
650     canvas->setFixedSize(240,320);
651
652     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
653     canvas->show();
654     qApp->processEvents();
655
656     QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
657     QVERIFY(rootItem);
658     QDeclarativeItemPrivate* rootItemPrivate = QDeclarativeItemPrivate::get(rootItem);
659
660     rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true
661     rootItemPrivate->isMirrorImplicit = false;
662     rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true
663     rootItemPrivate->resolveLayoutMirror();
664
665     QEvent wa(QEvent::WindowActivate);
666     QApplication::sendEvent(canvas, &wa);
667     QFocusEvent fe(QEvent::FocusIn);
668     QApplication::sendEvent(canvas, &fe);
669
670     QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
671     QVERIFY(item);
672     QVERIFY(item->hasActiveFocus());
673
674     QVariant result;
675     QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
676             Q_RETURN_ARG(QVariant, result)));
677     QVERIFY(result.toBool());
678
679     // right
680     QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
681     QApplication::sendEvent(canvas, &key);
682     QVERIFY(key.isAccepted());
683
684     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
685     QVERIFY(item);
686     QVERIFY(item->hasActiveFocus());
687
688     // left
689     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
690     QApplication::sendEvent(canvas, &key);
691     QVERIFY(key.isAccepted());
692
693     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
694     QVERIFY(item);
695     QVERIFY(item->hasActiveFocus());
696
697     delete canvas;
698 }
699
700 void tst_QDeclarativeItem::keyNavigation_skipNotVisible()
701 {
702     QDeclarativeView *canvas = new QDeclarativeView(0);
703     canvas->setFixedSize(240,320);
704
705     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
706     canvas->show();
707     qApp->processEvents();
708
709     QEvent wa(QEvent::WindowActivate);
710     QApplication::sendEvent(canvas, &wa);
711     QFocusEvent fe(QEvent::FocusIn);
712     QApplication::sendEvent(canvas, &fe);
713
714     QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
715     QVERIFY(item);
716     QVERIFY(item->hasActiveFocus());
717
718     // Set item 2 to not visible
719     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
720     QVERIFY(item);
721     item->setVisible(false);
722     QVERIFY(!item->isVisible());
723
724     // right
725     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
726     QApplication::sendEvent(canvas, &key);
727     QVERIFY(key.isAccepted());
728
729     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
730     QVERIFY(item);
731     QVERIFY(item->hasActiveFocus());
732
733     // tab
734     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
735     QApplication::sendEvent(canvas, &key);
736     QVERIFY(key.isAccepted());
737
738     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
739     QVERIFY(item);
740     QVERIFY(item->hasActiveFocus());
741
742     // backtab
743     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
744     QApplication::sendEvent(canvas, &key);
745     QVERIFY(key.isAccepted());
746
747     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
748     QVERIFY(item);
749     QVERIFY(item->hasActiveFocus());
750
751     //Set item 3 to not visible
752     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
753     QVERIFY(item);
754     item->setVisible(false);
755     QVERIFY(!item->isVisible());
756
757     // tab
758     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
759     QApplication::sendEvent(canvas, &key);
760     QVERIFY(key.isAccepted());
761
762     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
763     QVERIFY(item);
764     QVERIFY(item->hasActiveFocus());
765
766     // backtab
767     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
768     QApplication::sendEvent(canvas, &key);
769     QVERIFY(key.isAccepted());
770
771     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
772     QVERIFY(item);
773     QVERIFY(item->hasActiveFocus());
774
775     delete canvas;
776 }
777
778 void tst_QDeclarativeItem::keyNavigation_implicitSetting()
779 {
780     QDeclarativeView *canvas = new QDeclarativeView(0);
781     canvas->setFixedSize(240,320);
782
783     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest_implicit.qml"));
784     canvas->show();
785     qApp->processEvents();
786
787     QEvent wa(QEvent::WindowActivate);
788     QApplication::sendEvent(canvas, &wa);
789     QFocusEvent fe(QEvent::FocusIn);
790     QApplication::sendEvent(canvas, &fe);
791
792     QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
793     QVERIFY(item);
794     QVERIFY(item->hasActiveFocus());
795
796     QVariant result;
797     QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify",
798             Q_RETURN_ARG(QVariant, result)));
799     QVERIFY(result.toBool());
800
801     // right
802     QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
803     QApplication::sendEvent(canvas, &key);
804     QVERIFY(key.isAccepted());
805
806     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
807     QVERIFY(item);
808     QVERIFY(item->hasActiveFocus());
809
810     // back to item1
811     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
812     QApplication::sendEvent(canvas, &key);
813     QVERIFY(key.isAccepted());
814
815     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
816     QVERIFY(item);
817     QVERIFY(item->hasActiveFocus());
818
819     // down
820     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
821     QApplication::sendEvent(canvas, &key);
822     QVERIFY(key.isAccepted());
823
824     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
825     QVERIFY(item);
826     QVERIFY(item->hasActiveFocus());
827
828     // move to item4
829     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
830     QApplication::sendEvent(canvas, &key);
831     QVERIFY(key.isAccepted());
832
833     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
834     QVERIFY(item);
835     QVERIFY(item->hasActiveFocus());
836
837     // left
838     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
839     QApplication::sendEvent(canvas, &key);
840     QVERIFY(key.isAccepted());
841
842     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
843     QVERIFY(item);
844     QVERIFY(item->hasActiveFocus());
845
846     // back to item4
847     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
848     QApplication::sendEvent(canvas, &key);
849     QVERIFY(key.isAccepted());
850
851     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
852     QVERIFY(item);
853     QVERIFY(item->hasActiveFocus());
854
855     // up
856     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
857     QApplication::sendEvent(canvas, &key);
858     QVERIFY(key.isAccepted());
859
860     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
861     QVERIFY(item);
862     QVERIFY(item->hasActiveFocus());
863
864     // back to item4
865     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
866     QApplication::sendEvent(canvas, &key);
867     QVERIFY(key.isAccepted());
868
869     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
870     QVERIFY(item);
871     QVERIFY(item->hasActiveFocus());
872
873     // tab
874     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
875     QApplication::sendEvent(canvas, &key);
876     QVERIFY(key.isAccepted());
877
878     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
879     QVERIFY(item);
880     QVERIFY(item->hasActiveFocus());
881
882     // back to item4
883     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
884     QApplication::sendEvent(canvas, &key);
885     QVERIFY(key.isAccepted());
886
887     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
888     QVERIFY(item);
889     QVERIFY(item->hasActiveFocus());
890
891     // backtab
892     key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
893     QApplication::sendEvent(canvas, &key);
894     QVERIFY(key.isAccepted());
895
896     item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
897     QVERIFY(item);
898     QVERIFY(item->hasActiveFocus());
899
900     delete canvas;
901 }
902
903 void tst_QDeclarativeItem::smooth()
904 {
905     QDeclarativeComponent component(&engine);
906     component.setData("import QtQuick 1.0; Item { smooth: false; }", QUrl::fromLocalFile(""));
907     QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create());
908     QSignalSpy spy(item, SIGNAL(smoothChanged(bool)));
909
910     QVERIFY(item);
911     QVERIFY(!item->smooth());
912
913     item->setSmooth(true);
914     QVERIFY(item->smooth());
915     QCOMPARE(spy.count(),1);
916     QList<QVariant> arguments = spy.first();
917     QVERIFY(arguments.count() == 1);
918     QVERIFY(arguments.at(0).toBool() == true);
919
920     item->setSmooth(true);
921     QCOMPARE(spy.count(),1);
922
923     item->setSmooth(false);
924     QVERIFY(!item->smooth());
925     QCOMPARE(spy.count(),2);
926     item->setSmooth(false);
927     QCOMPARE(spy.count(),2);
928
929     delete item;
930 }
931
932 void tst_QDeclarativeItem::clip()
933 {
934     QDeclarativeComponent component(&engine);
935     component.setData("import QtQuick 1.0\nItem { clip: false\n }", QUrl::fromLocalFile(""));
936     QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create());
937     QSignalSpy spy(item, SIGNAL(clipChanged(bool)));
938
939     QVERIFY(item);
940     QVERIFY(!item->clip());
941
942     item->setClip(true);
943     QVERIFY(item->clip());
944
945     QList<QVariant> arguments = spy.first();
946     QVERIFY(arguments.count() == 1);
947     QVERIFY(arguments.at(0).toBool() == true);
948
949     QCOMPARE(spy.count(),1);
950     item->setClip(true);
951     QCOMPARE(spy.count(),1);
952
953     item->setClip(false);
954     QVERIFY(!item->clip());
955     QCOMPARE(spy.count(),2);
956     item->setClip(false);
957     QCOMPARE(spy.count(),2);
958
959     delete item;
960 }
961
962 void tst_QDeclarativeItem::mapCoordinates()
963 {
964     QFETCH(int, x);
965     QFETCH(int, y);
966
967     QDeclarativeView *canvas = new QDeclarativeView(0);
968     canvas->setFixedSize(300, 300);
969     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml"));
970     canvas->show();
971     qApp->processEvents();
972
973     QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
974     QVERIFY(root != 0);
975     QDeclarativeItem *a = findItem<QDeclarativeItem>(canvas->rootObject(), "itemA");
976     QVERIFY(a != 0);
977     QDeclarativeItem *b = findItem<QDeclarativeItem>(canvas->rootObject(), "itemB");
978     QVERIFY(b != 0);
979
980     QVariant result;
981
982     QVERIFY(QMetaObject::invokeMethod(root, "mapAToB",
983             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
984     QCOMPARE(result.value<QPointF>(), qobject_cast<QGraphicsItem*>(a)->mapToItem(b, x, y));
985
986     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
987             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
988     QCOMPARE(result.value<QPointF>(), qobject_cast<QGraphicsItem*>(a)->mapFromItem(b, x, y));
989
990     QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
991             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
992     QCOMPARE(result.value<QPointF>(), qobject_cast<QGraphicsItem*>(a)->mapToScene(x, y));
993
994     QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull",
995             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
996     QCOMPARE(result.value<QPointF>(), qobject_cast<QGraphicsItem*>(a)->mapFromScene(x, y));
997
998     QString warning1 = QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml").toString() + ":7:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item";
999     QString warning2 = QUrl::fromLocalFile(SRCDIR "/data/mapCoordinates.qml").toString() + ":7:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item";
1000
1001     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
1002     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid",
1003             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1004     QVERIFY(result.toBool());
1005
1006     QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1007     QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid",
1008             Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1009     QVERIFY(result.toBool());
1010
1011     delete canvas;
1012 }
1013
1014 void tst_QDeclarativeItem::mapCoordinates_data()
1015 {
1016     QTest::addColumn<int>("x");
1017     QTest::addColumn<int>("y");
1018
1019     for (int i=-20; i<=20; i+=10)
1020         QTest::newRow(QTest::toString(i)) << i << i;
1021 }
1022
1023 void tst_QDeclarativeItem::transforms_data()
1024 {
1025     QTest::addColumn<QByteArray>("qml");
1026     QTest::addColumn<QMatrix>("matrix");
1027     QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }")
1028         << QMatrix(1,0,0,1,10,20);
1029     QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }")
1030         << QMatrix(0,1,-1,0,0,0);
1031     QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2  }")
1032         << QMatrix(1.5,0,0,-2,0,0);
1033     QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2  } ]")
1034         << QMatrix(1,0,0,1,10,20) * QMatrix(1.5,0,0,-2,0,0);
1035 }
1036
1037 void tst_QDeclarativeItem::transforms()
1038 {
1039     QFETCH(QByteArray, qml);
1040     QFETCH(QMatrix, matrix);
1041     QDeclarativeComponent component(&engine);
1042     component.setData("import QtQuick 1.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
1043     QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create());
1044     QVERIFY(item);
1045     QCOMPARE(item->sceneMatrix(), matrix);
1046 }
1047
1048 void tst_QDeclarativeItem::childrenProperty()
1049 {
1050     QDeclarativeComponent component(&engine, SRCDIR "/data/childrenProperty.qml");
1051     
1052     QObject *o = component.create();
1053     QVERIFY(o != 0);
1054
1055     QCOMPARE(o->property("test1").toBool(), true);
1056     QCOMPARE(o->property("test2").toBool(), true);
1057     QCOMPARE(o->property("test3").toBool(), true);
1058     QCOMPARE(o->property("test4").toBool(), true);
1059     QCOMPARE(o->property("test5").toBool(), true);
1060     delete o;
1061 }
1062
1063 void tst_QDeclarativeItem::resourcesProperty()
1064 {
1065     QDeclarativeComponent component(&engine, SRCDIR "/data/resourcesProperty.qml");
1066     
1067     QObject *o = component.create();
1068     QVERIFY(o != 0);
1069
1070     QCOMPARE(o->property("test1").toBool(), true);
1071     QCOMPARE(o->property("test2").toBool(), true);
1072     QCOMPARE(o->property("test3").toBool(), true);
1073     QCOMPARE(o->property("test4").toBool(), true);
1074     QCOMPARE(o->property("test5").toBool(), true);
1075     delete o;
1076 }
1077
1078 void tst_QDeclarativeItem::mouseFocus()
1079 {
1080     QDeclarativeView *canvas = new QDeclarativeView(0);
1081     QVERIFY(canvas);
1082     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/mouseFocus.qml"));
1083     canvas->show();
1084     QVERIFY(canvas->rootObject());
1085     QApplication::setActiveWindow(canvas);
1086     QTest::qWaitForWindowShown(canvas);
1087     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas));
1088
1089     QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "declarativeItem");
1090     QVERIFY(item);
1091     QSignalSpy focusSpy(item, SIGNAL(activeFocusChanged(bool)));
1092
1093     QTest::mouseClick(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(item->scenePos()));
1094     QApplication::processEvents();
1095     QCOMPARE(focusSpy.count(), 1);
1096     QVERIFY(item->hasActiveFocus());
1097
1098     // make sure focusable graphics widget underneath does not steal focus
1099     QTest::mouseClick(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(item->scenePos()));
1100     QApplication::processEvents();
1101     QCOMPARE(focusSpy.count(), 1);
1102     QVERIFY(item->hasActiveFocus());
1103
1104     item->setFocus(false);
1105     QVERIFY(!item->hasActiveFocus());
1106     QCOMPARE(focusSpy.count(), 2);
1107     item->setFocus(true);
1108     QCOMPARE(focusSpy.count(), 3);
1109
1110     delete canvas;
1111 }
1112
1113 void tst_QDeclarativeItem::propertyChanges()
1114 {
1115     QDeclarativeView *canvas = new QDeclarativeView(0);
1116     canvas->setFixedSize(240,320);
1117     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
1118     canvas->show();
1119
1120     QEvent wa(QEvent::WindowActivate);
1121     QApplication::sendEvent(canvas, &wa);
1122     QFocusEvent fe(QEvent::FocusIn);
1123     QApplication::sendEvent(canvas, &fe);
1124
1125     QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item");
1126     QDeclarativeItem *parentItem = findItem<QDeclarativeItem>(canvas->rootObject(), "parentItem");
1127
1128     QVERIFY(item);
1129     QVERIFY(parentItem);
1130
1131     QSignalSpy parentSpy(item, SIGNAL(parentChanged(QDeclarativeItem *)));
1132     QSignalSpy widthSpy(item, SIGNAL(widthChanged()));
1133     QSignalSpy heightSpy(item, SIGNAL(heightChanged()));
1134     QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal)));
1135     QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF)));
1136     QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool)));
1137     QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool)));
1138     QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged()));
1139     QSignalSpy xSpy(item, SIGNAL(xChanged()));
1140     QSignalSpy ySpy(item, SIGNAL(yChanged()));
1141
1142     item->setParentItem(parentItem);
1143     item->setWidth(100.0);
1144     item->setHeight(200.0);
1145     item->setFocus(true);
1146     item->setBaselineOffset(10.0);
1147
1148     QCOMPARE(item->parentItem(), parentItem);
1149     QCOMPARE(parentSpy.count(),1);
1150     QList<QVariant> parentArguments = parentSpy.first();
1151     QVERIFY(parentArguments.count() == 1);
1152     QCOMPARE(item->parentItem(), qvariant_cast<QDeclarativeItem *>(parentArguments.at(0)));
1153     QCOMPARE(childrenChangedSpy.count(),1);
1154
1155     item->setParentItem(parentItem);
1156     QCOMPARE(childrenChangedSpy.count(),1);
1157
1158     QCOMPARE(item->width(), 100.0);
1159     QCOMPARE(widthSpy.count(),1);
1160
1161     QCOMPARE(item->height(), 200.0);
1162     QCOMPARE(heightSpy.count(),1);
1163
1164     QCOMPARE(item->baselineOffset(), 10.0);
1165     QCOMPARE(baselineOffsetSpy.count(),1);
1166     QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first();
1167     QVERIFY(baselineOffsetArguments.count() == 1);
1168     QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal());
1169
1170     QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0));
1171     QCOMPARE(childrenRectSpy.count(),2);
1172     QList<QVariant> childrenRectArguments = childrenRectSpy.at(1);
1173     QVERIFY(childrenRectArguments.count() == 1);
1174     QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF());
1175
1176     QCOMPARE(item->hasActiveFocus(), true);
1177     QCOMPARE(focusSpy.count(),1);
1178     QList<QVariant> focusArguments = focusSpy.first();
1179     QVERIFY(focusArguments.count() == 1);
1180     QCOMPARE(focusArguments.at(0).toBool(), true);
1181
1182     QCOMPARE(parentItem->hasActiveFocus(), false);
1183     QCOMPARE(parentItem->hasFocus(), false);
1184     QCOMPARE(wantsFocusSpy.count(),0);
1185
1186     item->setX(10.0);
1187     QCOMPARE(item->x(), 10.0);
1188     QCOMPARE(xSpy.count(), 1);
1189
1190     item->setY(10.0);
1191     QCOMPARE(item->y(), 10.0);
1192     QCOMPARE(ySpy.count(), 1);
1193
1194     delete canvas;
1195 }
1196
1197 void tst_QDeclarativeItem::childrenRect()
1198 {
1199     QDeclarativeView *canvas = new QDeclarativeView(0);
1200     canvas->setFixedSize(240,320);
1201     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRect.qml"));
1202     canvas->show();
1203
1204     QGraphicsObject *o = canvas->rootObject();
1205     QDeclarativeItem *item = o->findChild<QDeclarativeItem*>("testItem");
1206     QCOMPARE(item->width(), qreal(0));
1207     QCOMPARE(item->height(), qreal(0));
1208
1209     o->setProperty("childCount", 1);
1210     QCOMPARE(item->width(), qreal(10));
1211     QCOMPARE(item->height(), qreal(20));
1212
1213     o->setProperty("childCount", 5);
1214     QCOMPARE(item->width(), qreal(50));
1215     QCOMPARE(item->height(), qreal(100));
1216
1217     o->setProperty("childCount", 0);
1218     QCOMPARE(item->width(), qreal(0));
1219     QCOMPARE(item->height(), qreal(0));
1220
1221     delete o;
1222     delete canvas;
1223 }
1224
1225 // QTBUG-11383
1226 void tst_QDeclarativeItem::childrenRectBug()
1227 {
1228     QDeclarativeView *canvas = new QDeclarativeView(0);
1229     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug.qml"));
1230     canvas->show();
1231
1232     QGraphicsObject *o = canvas->rootObject();
1233     QDeclarativeItem *item = o->findChild<QDeclarativeItem*>("theItem");
1234     QCOMPARE(item->width(), qreal(200));
1235     QCOMPARE(item->height(), qreal(100));
1236     QCOMPARE(item->x(), qreal(100));
1237
1238     delete canvas;
1239 }
1240
1241 // QTBUG-11465
1242 void tst_QDeclarativeItem::childrenRectBug2()
1243 {
1244     QDeclarativeView *canvas = new QDeclarativeView(0);
1245     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug2.qml"));
1246     canvas->show();
1247
1248     QDeclarative1Rectangle *rect = qobject_cast<QDeclarative1Rectangle*>(canvas->rootObject());
1249     QVERIFY(rect);
1250     QDeclarativeItem *item = rect->findChild<QDeclarativeItem*>("theItem");
1251     QCOMPARE(item->width(), qreal(100));
1252     QCOMPARE(item->height(), qreal(110));
1253     QCOMPARE(item->x(), qreal(130));
1254
1255     QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
1256     rectPrivate->setState("row");
1257     QCOMPARE(item->width(), qreal(210));
1258     QCOMPARE(item->height(), qreal(50));
1259     QCOMPARE(item->x(), qreal(75));
1260
1261     delete canvas;
1262 }
1263
1264 // QTBUG-12722
1265 void tst_QDeclarativeItem::childrenRectBug3()
1266 {
1267     QDeclarativeView *canvas = new QDeclarativeView(0);
1268     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug3.qml"));
1269     canvas->show();
1270
1271     //don't crash on delete
1272     delete canvas;
1273 }
1274
1275 // QTBUG-13893
1276 void tst_QDeclarativeItem::transformCrash()
1277 {
1278     QDeclarativeView *canvas = new QDeclarativeView(0);
1279     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/transformCrash.qml"));
1280     canvas->show();
1281
1282     delete canvas;
1283 }
1284
1285 void tst_QDeclarativeItem::implicitSize()
1286 {
1287     QDeclarativeView *canvas = new QDeclarativeView(0);
1288     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/implicitsize.qml"));
1289     canvas->show();
1290
1291     QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
1292     QVERIFY(item);
1293     QCOMPARE(item->width(), qreal(80));
1294     QCOMPARE(item->height(), qreal(60));
1295
1296     QCOMPARE(item->implicitWidth(), qreal(200));
1297     QCOMPARE(item->implicitHeight(), qreal(100));
1298
1299     QMetaObject::invokeMethod(item, "resetSize");
1300
1301     QCOMPARE(item->width(), qreal(200));
1302     QCOMPARE(item->height(), qreal(100));
1303
1304     QMetaObject::invokeMethod(item, "changeImplicit");
1305
1306     QCOMPARE(item->implicitWidth(), qreal(150));
1307     QCOMPARE(item->implicitHeight(), qreal(80));
1308     QCOMPARE(item->width(), qreal(150));
1309     QCOMPARE(item->height(), qreal(80));
1310
1311     delete canvas;
1312 }
1313
1314 void tst_QDeclarativeItem::testQtQuick11Attributes()
1315 {
1316     QFETCH(QString, code);
1317     QFETCH(QString, warning);
1318     QFETCH(QString, error);
1319
1320     QDeclarativeEngine engine;
1321     QObject *obj;
1322
1323     QDeclarativeComponent valid(&engine);
1324     valid.setData("import QtQuick 1.1; Item { " + code.toUtf8() + " }", QUrl(""));
1325     obj = valid.create();
1326     QVERIFY(obj);
1327     QVERIFY(valid.errorString().isEmpty());
1328     delete obj;
1329
1330     QDeclarativeComponent invalid(&engine);
1331     invalid.setData("import QtQuick 1.0; Item { " + code.toUtf8() + " }", QUrl(""));
1332     QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
1333     obj = invalid.create();
1334     QCOMPARE(invalid.errorString(), error);
1335     delete obj;
1336 }
1337
1338 void tst_QDeclarativeItem::testQtQuick11Attributes_data()
1339 {
1340     QTest::addColumn<QString>("code");
1341     QTest::addColumn<QString>("warning");
1342     QTest::addColumn<QString>("error");
1343
1344     QTest::newRow("implicitWidth") << "implicitWidth: 100"
1345         << "QDeclarativeComponent: Component is not ready"
1346         << ":1 \"Item.implicitWidth\" is not available in QtQuick 1.0.\n";
1347
1348     QTest::newRow("implicitHeight") << "implicitHeight: 100"
1349         << "QDeclarativeComponent: Component is not ready"
1350         << ":1 \"Item.implicitHeight\" is not available in QtQuick 1.0.\n";
1351
1352     QTest::newRow("onImplicitWidthChanged") << "onImplicitWidthChanged: x"
1353         << "QDeclarativeComponent: Component is not ready"
1354         << ":1 \"Item.onImplicitWidthChanged\" is not available in QtQuick 1.0.\n";
1355
1356     QTest::newRow("onImplicitHeightChanged") << "onImplicitHeightChanged: x"
1357         << "QDeclarativeComponent: Component is not ready"
1358         << ":1 \"Item.onImplicitHeightChanged\" is not available in QtQuick 1.0.\n";
1359 }
1360
1361 void tst_QDeclarativeItem::qtbug_16871()
1362 {
1363     QDeclarativeComponent component(&engine, SRCDIR "/data/qtbug_16871.qml");
1364     QObject *o = component.create();
1365     QVERIFY(o != 0);
1366     delete o;
1367 }
1368
1369 void tst_QDeclarativeItem::qtbug_21045()
1370 {
1371     QDeclarativeComponent component(&engine);
1372     QGraphicsScene scene;
1373     component.setData("import QtQuick 1.1\nItem{visible: false; focus: true}", QUrl::fromLocalFile("file:"));
1374     QObject *o = component.create();
1375     QDeclarativeItem* i = qobject_cast<QDeclarativeItem*>(o);
1376     QVERIFY(i);
1377     scene.addItem(i);
1378     QVERIFY(!i->hasActiveFocus());
1379 }
1380
1381 QTEST_MAIN(tst_QDeclarativeItem)
1382
1383 #include "tst_qdeclarativeitem.moc"