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