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