Say hello to QtQuick module
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / qquickmousearea / tst_qquickmousearea.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 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
42 #include <QtTest/QtTest>
43 #include <QtTest/QSignalSpy>
44 #include <QtQuick/private/qquickmousearea_p.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <private/qquickflickable_p.h>
47 #include <QtQuick/qquickview.h>
48 #include <QtDeclarative/qdeclarativecontext.h>
49 #include <QtDeclarative/qdeclarativeengine.h>
50 #include <QtOpenGL/QGLShaderProgram>
51 #include "../../shared/util.h"
52
53 //#define OLDWAY
54
55 class tst_QQuickMouseArea: public QObject
56 {
57     Q_OBJECT
58 private slots:
59     void initTestCase();
60     void cleanupTestCase();
61     void dragProperties();
62     void resetDrag();
63     void dragging();
64     void updateMouseAreaPosOnClick();
65     void updateMouseAreaPosOnResize();
66     void noOnClickedWithPressAndHold();
67     void onMousePressRejected();
68     void pressedCanceledOnWindowDeactivate();
69     void doubleClick();
70     void clickTwice();
71     void pressedOrdering();
72     void preventStealing();
73     void clickThrough();
74     void testQtQuick11Attributes();
75     void testQtQuick11Attributes_data();
76     void hoverPosition();
77     void hoverPropagation();
78
79 private:
80     QQuickView *createView();
81 };
82
83 void tst_QQuickMouseArea::initTestCase()
84 {
85
86 }
87
88 void tst_QQuickMouseArea::cleanupTestCase()
89 {
90
91 }
92
93 void tst_QQuickMouseArea::dragProperties()
94 {
95     QQuickView *canvas = createView();
96
97     canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragproperties.qml")));
98     canvas->show();
99     canvas->requestActivateWindow();
100     QVERIFY(canvas->rootObject() != 0);
101
102     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
103     QQuickDrag *drag = mouseRegion->drag();
104     QVERIFY(mouseRegion != 0);
105     QVERIFY(drag != 0);
106
107     // target
108     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
109     QVERIFY(blackRect != 0);
110     QVERIFY(blackRect == drag->target());
111     QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
112     QVERIFY(rootItem != 0);
113     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
114     drag->setTarget(rootItem);
115     QCOMPARE(targetSpy.count(),1);
116     drag->setTarget(rootItem);
117     QCOMPARE(targetSpy.count(),1);
118
119     // axis
120     QCOMPARE(drag->axis(), QQuickDrag::XandYAxis);
121     QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
122     drag->setAxis(QQuickDrag::XAxis);
123     QCOMPARE(drag->axis(), QQuickDrag::XAxis);
124     QCOMPARE(axisSpy.count(),1);
125     drag->setAxis(QQuickDrag::XAxis);
126     QCOMPARE(axisSpy.count(),1);
127
128     // minimum and maximum properties
129     QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
130     QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
131     QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
132     QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
133
134     QCOMPARE(drag->xmin(), 0.0);
135     QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
136     QCOMPARE(drag->ymin(), 0.0);
137     QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
138
139     drag->setXmin(10);
140     drag->setXmax(10);
141     drag->setYmin(10);
142     drag->setYmax(10);
143
144     QCOMPARE(drag->xmin(), 10.0);
145     QCOMPARE(drag->xmax(), 10.0);
146     QCOMPARE(drag->ymin(), 10.0);
147     QCOMPARE(drag->ymax(), 10.0);
148
149     QCOMPARE(xminSpy.count(),1);
150     QCOMPARE(xmaxSpy.count(),1);
151     QCOMPARE(yminSpy.count(),1);
152     QCOMPARE(ymaxSpy.count(),1);
153
154     drag->setXmin(10);
155     drag->setXmax(10);
156     drag->setYmin(10);
157     drag->setYmax(10);
158
159     QCOMPARE(xminSpy.count(),1);
160     QCOMPARE(xmaxSpy.count(),1);
161     QCOMPARE(yminSpy.count(),1);
162     QCOMPARE(ymaxSpy.count(),1);
163
164     // filterChildren
165     QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
166
167     drag->setFilterChildren(true);
168
169     QVERIFY(drag->filterChildren());
170     QCOMPARE(filterChildrenSpy.count(), 1);
171
172     drag->setFilterChildren(true);
173     QCOMPARE(filterChildrenSpy.count(), 1);
174
175     delete canvas;
176 }
177
178 void tst_QQuickMouseArea::resetDrag()
179 {
180     QQuickView *canvas = createView();
181
182     canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
183     canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragreset.qml")));
184     canvas->show();
185     canvas->requestActivateWindow();
186     QVERIFY(canvas->rootObject() != 0);
187
188     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
189     QQuickDrag *drag = mouseRegion->drag();
190     QVERIFY(mouseRegion != 0);
191     QVERIFY(drag != 0);
192
193     // target
194     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
195     QVERIFY(blackRect != 0);
196     QVERIFY(blackRect == drag->target());
197     QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
198     QVERIFY(rootItem != 0);
199     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
200     QVERIFY(drag->target() != 0);
201     canvas->rootContext()->setContextProperty("haveTarget", QVariant(false));
202     QCOMPARE(targetSpy.count(),1);
203     QVERIFY(drag->target() == 0);
204
205     delete canvas;
206 }
207
208
209 void tst_QQuickMouseArea::dragging()
210 {
211     QQuickView *canvas = createView();
212
213     canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragging.qml")));
214     canvas->show();
215     canvas->requestActivateWindow();
216     QTest::qWait(20);
217     QVERIFY(canvas->rootObject() != 0);
218
219     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
220     QQuickDrag *drag = mouseRegion->drag();
221     QVERIFY(mouseRegion != 0);
222     QVERIFY(drag != 0);
223
224     // target
225     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
226     QVERIFY(blackRect != 0);
227     QVERIFY(blackRect == drag->target());
228
229     QVERIFY(!drag->active());
230
231 #ifdef OLDWAY
232     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
233     QApplication::sendEvent(canvas, &pressEvent);
234 #else
235     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
236 #endif
237
238     QVERIFY(!drag->active());
239     QCOMPARE(blackRect->x(), 50.0);
240     QCOMPARE(blackRect->y(), 50.0);
241
242     // First move event triggers drag, second is acted upon.
243     // This is due to possibility of higher stacked area taking precedence.
244
245     QTest::mouseMove(canvas, QPoint(111,111));
246     QTest::qWait(50);
247     QTest::mouseMove(canvas, QPoint(122,122));
248     QTest::qWait(50);
249
250     QVERIFY(drag->active());
251     QCOMPARE(blackRect->x(), 72.0);
252     QCOMPARE(blackRect->y(), 72.0);
253
254 #ifdef OLDWAY
255     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
256     QApplication::sendEvent(canvas, &releaseEvent);
257 #else
258     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122));
259     QTest::qWait(50);
260 #endif
261
262     QVERIFY(!drag->active());
263     QCOMPARE(blackRect->x(), 72.0);
264     QCOMPARE(blackRect->y(), 72.0);
265
266     delete canvas;
267 }
268
269 QQuickView *tst_QQuickMouseArea::createView()
270 {
271     QQuickView *canvas = new QQuickView(0);
272     canvas->setBaseSize(QSize(240,320));
273
274     return canvas;
275 }
276
277 void tst_QQuickMouseArea::updateMouseAreaPosOnClick()
278 {
279     QQuickView *canvas = createView();
280     canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnClick.qml")));
281     canvas->show();
282     canvas->requestActivateWindow();
283     QVERIFY(canvas->rootObject() != 0);
284
285     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
286     QVERIFY(mouseRegion != 0);
287
288     QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("ball");
289     QVERIFY(rect != 0);
290
291     QCOMPARE(mouseRegion->mouseX(), rect->x());
292     QCOMPARE(mouseRegion->mouseY(), rect->y());
293
294     QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
295     QApplication::sendEvent(canvas, &event);
296
297     QCOMPARE(mouseRegion->mouseX(), 100.0);
298     QCOMPARE(mouseRegion->mouseY(), 100.0);
299
300     QCOMPARE(mouseRegion->mouseX(), rect->x());
301     QCOMPARE(mouseRegion->mouseY(), rect->y());
302
303     delete canvas;
304 }
305
306 void tst_QQuickMouseArea::updateMouseAreaPosOnResize()
307 {
308     QQuickView *canvas = createView();
309     canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnResize.qml")));
310     canvas->show();
311     canvas->requestActivateWindow();
312     QVERIFY(canvas->rootObject() != 0);
313
314     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
315     QVERIFY(mouseRegion != 0);
316
317     QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("brother");
318     QVERIFY(rect != 0);
319
320     QCOMPARE(mouseRegion->mouseX(), 0.0);
321     QCOMPARE(mouseRegion->mouseY(), 0.0);
322
323     QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0);
324     QApplication::sendEvent(canvas, &event);
325
326     QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
327     QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
328
329     QCOMPARE(mouseRegion->property("x1").toReal(), 0.0);
330     QCOMPARE(mouseRegion->property("y1").toReal(), 0.0);
331
332     QCOMPARE(mouseRegion->property("x2").toReal(), rect->x());
333     QCOMPARE(mouseRegion->property("y2").toReal(), rect->y());
334
335     QCOMPARE(mouseRegion->mouseX(), rect->x());
336     QCOMPARE(mouseRegion->mouseY(), rect->y());
337
338     delete canvas;
339 }
340
341 void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
342 {
343     {
344         // We handle onPressAndHold, therefore no onClicked
345         QQuickView *canvas = createView();
346         canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickandhold.qml")));
347         canvas->show();
348         canvas->requestActivateWindow();
349         QVERIFY(canvas->rootObject() != 0);
350
351         QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
352         QApplication::sendEvent(canvas, &pressEvent);
353
354         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
355         QVERIFY(!canvas->rootObject()->property("held").toBool());
356
357         QTest::qWait(1000);
358
359         QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
360         QApplication::sendEvent(canvas, &releaseEvent);
361
362         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
363         QVERIFY(canvas->rootObject()->property("held").toBool());
364
365         delete canvas;
366     }
367
368     {
369         // We do not handle onPressAndHold, therefore we get onClicked
370         QQuickView *canvas = createView();
371         canvas->setSource(QUrl::fromLocalFile(TESTDATA("noclickandhold.qml")));
372         canvas->show();
373         canvas->requestActivateWindow();
374         QVERIFY(canvas->rootObject() != 0);
375
376         QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
377         QApplication::sendEvent(canvas, &pressEvent);
378
379         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
380
381         QTest::qWait(1000);
382
383         QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
384         QApplication::sendEvent(canvas, &releaseEvent);
385
386         QVERIFY(canvas->rootObject()->property("clicked").toBool());
387
388         delete canvas;
389     }
390 }
391
392 void tst_QQuickMouseArea::onMousePressRejected()
393 {
394     QQuickView *canvas = createView();
395     canvas->setSource(QUrl::fromLocalFile(TESTDATA("rejectEvent.qml")));
396     canvas->show();
397     canvas->requestActivateWindow();
398     QVERIFY(canvas->rootObject() != 0);
399     QVERIFY(canvas->rootObject()->property("enabled").toBool());
400
401     QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool());
402     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
403     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
404     QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool());
405     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
406     QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool());
407
408     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
409     QApplication::sendEvent(canvas, &pressEvent);
410
411     QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool());
412     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
413     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
414     QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool());
415     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
416     QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool());
417
418     QTest::qWait(200);
419
420     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
421     QApplication::sendEvent(canvas, &releaseEvent);
422
423     QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
424     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
425     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
426
427     delete canvas;
428 }
429 void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
430 {
431     QQuickView *canvas = createView();
432     canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedCanceled.qml")));
433     canvas->show();
434     canvas->requestActivateWindow();
435     QVERIFY(canvas->rootObject() != 0);
436     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
437     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
438     QVERIFY(!canvas->rootObject()->property("released").toBool());
439
440     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
441     QApplication::sendEvent(canvas, &pressEvent);
442
443     QVERIFY(canvas->rootObject()->property("pressed").toBool());
444     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
445     QVERIFY(!canvas->rootObject()->property("released").toBool());
446
447     QTest::qWait(200);
448
449     QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
450     QApplication::sendEvent(canvas, &windowDeactivateEvent);
451     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
452     QVERIFY(canvas->rootObject()->property("canceled").toBool());
453     QVERIFY(!canvas->rootObject()->property("released").toBool());
454
455     QTest::qWait(200);
456
457     //press again
458     QApplication::sendEvent(canvas, &pressEvent);
459     QVERIFY(canvas->rootObject()->property("pressed").toBool());
460     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
461     QVERIFY(!canvas->rootObject()->property("released").toBool());
462
463     QTest::qWait(200);
464
465     //release
466     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
467     QApplication::sendEvent(canvas, &releaseEvent);
468     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
469     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
470     QVERIFY(canvas->rootObject()->property("released").toBool());
471
472     delete canvas;
473 }
474 void tst_QQuickMouseArea::doubleClick()
475 {
476     QQuickView *canvas = createView();
477     canvas->setSource(QUrl::fromLocalFile(TESTDATA("doubleclick.qml")));
478     canvas->show();
479     canvas->requestActivateWindow();
480     QVERIFY(canvas->rootObject() != 0);
481
482     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
483     QApplication::sendEvent(canvas, &pressEvent);
484
485     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
486     QApplication::sendEvent(canvas, &releaseEvent);
487
488     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
489
490     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
491     QApplication::sendEvent(canvas, &pressEvent);
492
493     QApplication::sendEvent(canvas, &releaseEvent);
494
495     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
496     QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
497     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
498
499     delete canvas;
500 }
501
502 // QTBUG-14832
503 void tst_QQuickMouseArea::clickTwice()
504 {
505     QQuickView *canvas = createView();
506     canvas->setSource(QUrl::fromLocalFile(TESTDATA("clicktwice.qml")));
507     canvas->show();
508     canvas->requestActivateWindow();
509     QVERIFY(canvas->rootObject() != 0);
510
511     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
512     QApplication::sendEvent(canvas, &pressEvent);
513
514     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
515     QApplication::sendEvent(canvas, &releaseEvent);
516
517     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1);
518     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
519     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
520
521     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
522     QApplication::sendEvent(canvas, &pressEvent);
523
524     QApplication::sendEvent(canvas, &pressEvent);
525     QApplication::sendEvent(canvas, &releaseEvent);
526
527     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
528     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
529     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
530
531     delete canvas;
532 }
533
534 void tst_QQuickMouseArea::pressedOrdering()
535 {
536     QQuickView *canvas = createView();
537     canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedOrdering.qml")));
538     canvas->show();
539     canvas->requestActivateWindow();
540     QVERIFY(canvas->rootObject() != 0);
541
542     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base"));
543
544     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
545     QApplication::sendEvent(canvas, &pressEvent);
546
547     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
548
549     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
550     QApplication::sendEvent(canvas, &releaseEvent);
551
552     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled"));
553
554     QApplication::sendEvent(canvas, &pressEvent);
555
556     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
557
558     delete canvas;
559 }
560
561 void tst_QQuickMouseArea::preventStealing()
562 {
563     QQuickView *canvas = createView();
564
565     canvas->setSource(QUrl::fromLocalFile(TESTDATA("preventstealing.qml")));
566     canvas->show();
567     canvas->requestActivateWindow();
568     QVERIFY(canvas->rootObject() != 0);
569
570     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
571     QVERIFY(flickable != 0);
572
573     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea*>("mousearea");
574     QVERIFY(mouseArea != 0);
575
576     QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
577
578     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
579
580     // Without preventStealing, mouse movement over MouseArea would
581     // cause the Flickable to steal mouse and trigger content movement.
582
583     QTest::mouseMove(canvas,QPoint(69,69));
584     QTest::mouseMove(canvas,QPoint(58,58));
585     QTest::mouseMove(canvas,QPoint(47,47));
586
587     // We should have received all three move events
588     QCOMPARE(mousePositionSpy.count(), 3);
589     QVERIFY(mouseArea->pressed());
590
591     // Flickable content should not have moved.
592     QCOMPARE(flickable->contentX(), 0.);
593     QCOMPARE(flickable->contentY(), 0.);
594
595     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47));
596
597     // Now allow stealing and confirm Flickable does its thing.
598     canvas->rootObject()->setProperty("stealing", false);
599
600     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
601
602     // Without preventStealing, mouse movement over MouseArea would
603     // cause the Flickable to steal mouse and trigger content movement.
604
605     QTest::mouseMove(canvas,QPoint(69,69));
606     QTest::mouseMove(canvas,QPoint(58,58));
607     QTest::mouseMove(canvas,QPoint(47,47));
608
609     // We should only have received the first move event
610     QCOMPARE(mousePositionSpy.count(), 4);
611     // Our press should be taken away
612     QVERIFY(!mouseArea->pressed());
613
614     // Flickable content should have moved.
615
616     QCOMPARE(flickable->contentX(), 11.);
617     QCOMPARE(flickable->contentY(), 11.);
618
619     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50));
620
621     delete canvas;
622 }
623
624 void tst_QQuickMouseArea::clickThrough()
625 {
626     //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers
627     QQuickView *canvas = createView();
628     canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough.qml")));
629     canvas->show();
630     canvas->requestActivateWindow();
631     QVERIFY(canvas->rootObject() != 0);
632
633     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
634     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
635
636     QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
637     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
638
639     QTest::qWait(800); // to avoid generating a double click.
640
641     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
642     QTest::qWait(1000);
643     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
644
645     QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
646     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
647     QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
648
649     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
650     QTest::qWait(100);
651
652     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
653     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
654     QTRY_COMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
655     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
656
657     delete canvas;
658
659     //With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored
660     canvas = createView();
661     canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough2.qml")));
662     canvas->show();
663     canvas->requestActivateWindow();
664     QVERIFY(canvas->rootObject() != 0);
665
666     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
667     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
668
669     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
670     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
671
672     QTest::qWait(800); // to avoid generating a double click.
673
674     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
675     QTest::qWait(1000);
676     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
677     QTest::qWait(100);
678
679     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
680     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
681     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
682
683     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
684     QTest::qWait(100);
685
686     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
687     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
688     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0);
689     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
690
691     canvas->rootObject()->setProperty("letThrough", QVariant(true));
692
693     QTest::qWait(800); // to avoid generating a double click.
694     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
695     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
696
697     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
698     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
699
700     QTest::qWait(800); // to avoid generating a double click.
701     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
702     QTest::qWait(1000);
703     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
704     QTest::qWait(100);
705
706     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
707     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
708     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
709
710     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
711     QTest::qWait(100);
712
713     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
714     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
715     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
716     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
717
718     canvas->rootObject()->setProperty("noPropagation", QVariant(true));
719
720     QTest::qWait(800); // to avoid generating a double click.
721     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
722     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
723
724     QTest::qWait(800); // to avoid generating a double click.
725     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
726     QTest::qWait(1000);
727     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
728     QTest::qWait(100);
729
730     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
731     QTest::qWait(100);
732
733     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
734     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
735     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
736     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
737
738     delete canvas;
739 }
740
741 void tst_QQuickMouseArea::testQtQuick11Attributes()
742 {
743     QFETCH(QString, code);
744     QFETCH(QString, warning);
745     QFETCH(QString, error);
746
747     QDeclarativeEngine engine;
748     QObject *obj;
749
750     QDeclarativeComponent valid(&engine);
751     valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl(""));
752     obj = valid.create();
753     QVERIFY(obj);
754     QVERIFY(valid.errorString().isEmpty());
755     delete obj;
756
757     QDeclarativeComponent invalid(&engine);
758     invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl(""));
759     QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
760     obj = invalid.create();
761     QCOMPARE(invalid.errorString(), error);
762     delete obj;
763 }
764
765 void tst_QQuickMouseArea::testQtQuick11Attributes_data()
766 {
767     QTest::addColumn<QString>("code");
768     QTest::addColumn<QString>("warning");
769     QTest::addColumn<QString>("error");
770
771     QTest::newRow("preventStealing") << "preventStealing: true"
772         << "QDeclarativeComponent: Component is not ready"
773         << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n";
774 }
775
776 void tst_QQuickMouseArea::hoverPosition()
777 {
778     QQuickView *canvas = createView();
779     canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPosition.qml")));
780
781     QQuickItem *root = canvas->rootObject();
782     QVERIFY(root != 0);
783
784     QCOMPARE(root->property("mouseX").toReal(), qreal(0));
785     QCOMPARE(root->property("mouseY").toReal(), qreal(0));
786
787     QTest::mouseMove(canvas,QPoint(10,32));
788
789
790     QCOMPARE(root->property("mouseX").toReal(), qreal(10));
791     QCOMPARE(root->property("mouseY").toReal(), qreal(32));
792
793     delete canvas;
794 }
795
796 void tst_QQuickMouseArea::hoverPropagation()
797 {
798     //QTBUG-18175, to behave like GV did.
799     QQuickView *canvas = createView();
800     canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPropagation.qml")));
801
802     QQuickItem *root = canvas->rootObject();
803     QVERIFY(root != 0);
804
805     QCOMPARE(root->property("point1").toBool(), false);
806     QCOMPARE(root->property("point2").toBool(), false);
807
808     QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
809     QApplication::sendEvent(canvas, &moveEvent);
810
811     QCOMPARE(root->property("point1").toBool(), true);
812     QCOMPARE(root->property("point2").toBool(), false);
813
814     QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
815     QApplication::sendEvent(canvas, &moveEvent2);
816     QCOMPARE(root->property("point1").toBool(), false);
817     QCOMPARE(root->property("point2").toBool(), true);
818
819     delete canvas;
820 }
821
822 QTEST_MAIN(tst_QQuickMouseArea)
823
824 #include "tst_qquickmousearea.moc"