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