e9b81a18bdf1c1ccbe518a928043c6242dfffb3a
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick1 / qdeclarativemousearea / tst_qdeclarativemousearea.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 <QtQuick1/private/qdeclarativemousearea_p.h>
45 #include <QtQuick1/private/qdeclarativerectangle_p.h>
46 #include <QtQuick1/private/qdeclarativeflickable_p.h>
47 #include <QtQuick1/qdeclarativeview.h>
48 #include <QtDeclarative/qdeclarativecontext.h>
49 #include <QtDeclarative/qdeclarativeengine.h>
50 #include <QtDeclarative/qdeclarativeproperty.h>
51
52 class tst_QDeclarative1MouseArea: public QObject
53 {
54     Q_OBJECT
55 private slots:
56     void dragProperties();
57     void resetDrag();
58     void dragging();
59     void updateMouseAreaPosOnClick();
60     void updateMouseAreaPosOnResize();
61     void noOnClickedWithPressAndHold();
62     void onMousePressRejected();
63     void doubleClick();
64     void clickTwice();
65     void pressedOrdering();
66     void preventStealing();
67     void testQtQuick11Attributes();
68     void testQtQuick11Attributes_data();
69 #ifndef QT_NO_CONTEXTMENU
70     void preventContextMenu();
71 #endif // QT_NO_CONTEXTMENU
72
73 private:
74     QDeclarativeView *createView();
75 };
76
77 void tst_QDeclarative1MouseArea::dragProperties()
78 {
79     QDeclarativeView *canvas = createView();
80     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragproperties.qml"));
81     canvas->show();
82     canvas->setFocus();
83     QVERIFY(canvas->rootObject() != 0);
84
85     QDeclarative1MouseArea *mouseRegion = canvas->rootObject()->findChild<QDeclarative1MouseArea*>("mouseregion");
86     QDeclarative1Drag *drag = mouseRegion->drag();
87     QVERIFY(mouseRegion != 0);
88     QVERIFY(drag != 0);
89
90     // target
91     QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect");
92     QVERIFY(blackRect != 0);
93     QVERIFY(blackRect == drag->target());
94     QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
95     QVERIFY(rootItem != 0);
96     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
97     drag->setTarget(rootItem);
98     QCOMPARE(targetSpy.count(),1);
99     drag->setTarget(rootItem);
100     QCOMPARE(targetSpy.count(),1);
101
102     // axis
103     QCOMPARE(drag->axis(), QDeclarative1Drag::XandYAxis);
104     QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
105     drag->setAxis(QDeclarative1Drag::XAxis);
106     QCOMPARE(drag->axis(), QDeclarative1Drag::XAxis);
107     QCOMPARE(axisSpy.count(),1);
108     drag->setAxis(QDeclarative1Drag::XAxis);
109     QCOMPARE(axisSpy.count(),1);
110
111     // minimum and maximum properties
112     QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
113     QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
114     QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
115     QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
116
117     QCOMPARE(drag->xmin(), 0.0);
118     QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
119     QCOMPARE(drag->ymin(), 0.0);
120     QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
121
122     drag->setXmin(10);
123     drag->setXmax(10);
124     drag->setYmin(10);
125     drag->setYmax(10);
126
127     QCOMPARE(drag->xmin(), 10.0);
128     QCOMPARE(drag->xmax(), 10.0);
129     QCOMPARE(drag->ymin(), 10.0);
130     QCOMPARE(drag->ymax(), 10.0);
131
132     QCOMPARE(xminSpy.count(),1);
133     QCOMPARE(xmaxSpy.count(),1);
134     QCOMPARE(yminSpy.count(),1);
135     QCOMPARE(ymaxSpy.count(),1);
136
137     drag->setXmin(10);
138     drag->setXmax(10);
139     drag->setYmin(10);
140     drag->setYmax(10);
141
142     QCOMPARE(xminSpy.count(),1);
143     QCOMPARE(xmaxSpy.count(),1);
144     QCOMPARE(yminSpy.count(),1);
145     QCOMPARE(ymaxSpy.count(),1);
146
147     // filterChildren
148     QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
149
150     drag->setFilterChildren(true);
151
152     QVERIFY(drag->filterChildren());
153     QCOMPARE(filterChildrenSpy.count(), 1);
154
155     drag->setFilterChildren(true);
156     QCOMPARE(filterChildrenSpy.count(), 1);
157
158     delete canvas;
159 }
160
161 void tst_QDeclarative1MouseArea::resetDrag()
162 {
163     QDeclarativeView *canvas = createView();
164
165     canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
166     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragreset.qml"));
167     canvas->show();
168     canvas->setFocus();
169     QVERIFY(canvas->rootObject() != 0);
170
171     QDeclarative1MouseArea *mouseRegion = canvas->rootObject()->findChild<QDeclarative1MouseArea*>("mouseregion");
172     QDeclarative1Drag *drag = mouseRegion->drag();
173     QVERIFY(mouseRegion != 0);
174     QVERIFY(drag != 0);
175
176     // target
177     QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect");
178     QVERIFY(blackRect != 0);
179     QVERIFY(blackRect == drag->target());
180     QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
181     QVERIFY(rootItem != 0);
182     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
183     QVERIFY(drag->target() != 0);
184     canvas->rootContext()->setContextProperty("haveTarget", QVariant(false));
185     QCOMPARE(targetSpy.count(),1);
186     QVERIFY(drag->target() == 0);
187
188     delete canvas;
189 }
190
191
192 void tst_QDeclarative1MouseArea::dragging()
193 {
194     QDeclarativeView *canvas = createView();
195
196     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/dragging.qml"));
197     canvas->show();
198     canvas->setFocus();
199     QVERIFY(canvas->rootObject() != 0);
200
201     QDeclarative1MouseArea *mouseRegion = canvas->rootObject()->findChild<QDeclarative1MouseArea*>("mouseregion");
202     QDeclarative1Drag *drag = mouseRegion->drag();
203     QVERIFY(mouseRegion != 0);
204     QVERIFY(drag != 0);
205
206     // target
207     QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect");
208     QVERIFY(blackRect != 0);
209     QVERIFY(blackRect == drag->target());
210
211     QVERIFY(!drag->active());
212
213     QGraphicsScene *scene = canvas->scene();
214     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
215     pressEvent.setScenePos(QPointF(100, 100));
216     pressEvent.setButton(Qt::LeftButton);
217     pressEvent.setButtons(Qt::LeftButton);
218     QApplication::sendEvent(scene, &pressEvent);
219
220     QVERIFY(!drag->active());
221     QCOMPARE(blackRect->x(), 50.0);
222     QCOMPARE(blackRect->y(), 50.0);
223
224     // First move event triggers drag, second is acted upon.
225     // This is due to possibility of higher stacked area taking precedence.
226     QGraphicsSceneMouseEvent moveEvent(QEvent::GraphicsSceneMouseMove);
227     moveEvent.setScenePos(QPointF(106, 106));
228     moveEvent.setButton(Qt::LeftButton);
229     moveEvent.setButtons(Qt::LeftButton);
230     QApplication::sendEvent(scene, &moveEvent);
231
232     moveEvent.setScenePos(QPointF(110, 110));
233     moveEvent.setButton(Qt::LeftButton);
234     moveEvent.setButtons(Qt::LeftButton);
235     QApplication::sendEvent(scene, &moveEvent);
236
237     QVERIFY(drag->active());
238     QCOMPARE(blackRect->x(), 60.0);
239     QCOMPARE(blackRect->y(), 60.0);
240
241     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
242     releaseEvent.setScenePos(QPointF(110, 110));
243     releaseEvent.setButton(Qt::LeftButton);
244     releaseEvent.setButtons(Qt::LeftButton);
245     QApplication::sendEvent(scene, &releaseEvent);
246
247     QVERIFY(!drag->active());
248     QCOMPARE(blackRect->x(), 60.0);
249     QCOMPARE(blackRect->y(), 60.0);
250
251     delete canvas;
252 }
253
254 QDeclarativeView *tst_QDeclarative1MouseArea::createView()
255 {
256     QDeclarativeView *canvas = new QDeclarativeView(0);
257     canvas->setFixedSize(240,320);
258
259     return canvas;
260 }
261
262 void tst_QDeclarative1MouseArea::updateMouseAreaPosOnClick()
263 {
264     QDeclarativeView *canvas = createView();
265     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/updateMousePosOnClick.qml"));
266     canvas->show();
267     canvas->setFocus();
268     QVERIFY(canvas->rootObject() != 0);
269
270     QDeclarative1MouseArea *mouseRegion = canvas->rootObject()->findChild<QDeclarative1MouseArea*>("mouseregion");
271     QVERIFY(mouseRegion != 0);
272
273     QDeclarative1Rectangle *rect = canvas->rootObject()->findChild<QDeclarative1Rectangle*>("ball");
274     QVERIFY(rect != 0);
275
276     QCOMPARE(mouseRegion->mouseX(), rect->x());
277     QCOMPARE(mouseRegion->mouseY(), rect->y());
278
279     QGraphicsScene *scene = canvas->scene();
280     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
281     event.setScenePos(QPointF(100, 100));
282     event.setButton(Qt::LeftButton);
283     event.setButtons(Qt::LeftButton);
284     QApplication::sendEvent(scene, &event);
285
286     QCOMPARE(mouseRegion->mouseX(), 100.0);
287     QCOMPARE(mouseRegion->mouseY(), 100.0);
288
289     QCOMPARE(mouseRegion->mouseX(), rect->x());
290     QCOMPARE(mouseRegion->mouseY(), rect->y());
291
292     delete canvas;
293 }
294
295 void tst_QDeclarative1MouseArea::updateMouseAreaPosOnResize()
296 {
297     QDeclarativeView *canvas = createView();
298     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/updateMousePosOnResize.qml"));
299     canvas->show();
300     canvas->setFocus();
301     QVERIFY(canvas->rootObject() != 0);
302
303     QDeclarative1MouseArea *mouseRegion = canvas->rootObject()->findChild<QDeclarative1MouseArea*>("mouseregion");
304     QVERIFY(mouseRegion != 0);
305
306     QDeclarative1Rectangle *rect = canvas->rootObject()->findChild<QDeclarative1Rectangle*>("brother");
307     QVERIFY(rect != 0);
308
309     QCOMPARE(mouseRegion->mouseX(), 0.0);
310     QCOMPARE(mouseRegion->mouseY(), 0.0);
311
312     QGraphicsScene *scene = canvas->scene();
313     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
314     event.setScenePos(rect->pos());
315     event.setButton(Qt::LeftButton);
316     event.setButtons(Qt::LeftButton);
317     QApplication::sendEvent(scene, &event);
318
319     QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
320     QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
321
322     QCOMPARE(mouseRegion->property("x1").toInt(), 0);
323     QCOMPARE(mouseRegion->property("y1").toInt(), 0);
324
325     // XXX: is it on purpose that mouseX is real and mouse.x is int?
326     QCOMPARE(mouseRegion->property("x2").toInt(), (int) rect->x());
327     QCOMPARE(mouseRegion->property("y2").toInt(), (int) rect->y());
328
329     QCOMPARE(mouseRegion->mouseX(), rect->x());
330     QCOMPARE(mouseRegion->mouseY(), rect->y());
331
332     delete canvas;
333 }
334
335 void tst_QDeclarative1MouseArea::noOnClickedWithPressAndHold()
336 {
337     QDeclarativeView *canvas = createView();
338     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clickandhold.qml"));
339     canvas->show();
340     canvas->setFocus();
341     QVERIFY(canvas->rootObject() != 0);
342
343     QGraphicsScene *scene = canvas->scene();
344     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
345     pressEvent.setScenePos(QPointF(100, 100));
346     pressEvent.setButton(Qt::LeftButton);
347     pressEvent.setButtons(Qt::LeftButton);
348     QApplication::sendEvent(scene, &pressEvent);
349
350     QVERIFY(!canvas->rootObject()->property("clicked").toBool());
351     QVERIFY(!canvas->rootObject()->property("held").toBool());
352
353     QTest::qWait(1000);
354
355     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
356     releaseEvent.setScenePos(QPointF(100, 100));
357     releaseEvent.setButton(Qt::LeftButton);
358     releaseEvent.setButtons(Qt::LeftButton);
359     QApplication::sendEvent(scene, &releaseEvent);
360
361     QVERIFY(!canvas->rootObject()->property("clicked").toBool());
362     QVERIFY(canvas->rootObject()->property("held").toBool());
363
364     delete canvas;
365 }
366
367 void tst_QDeclarative1MouseArea::onMousePressRejected()
368 {
369     QDeclarativeView *canvas = createView();
370     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/rejectEvent.qml"));
371     canvas->show();
372     canvas->setFocus();
373     QVERIFY(canvas->rootObject() != 0);
374     QVERIFY(canvas->rootObject()->property("enabled").toBool());
375
376     QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool());
377     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
378     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
379     QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool());
380     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
381     QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool());
382
383     QGraphicsScene *scene = canvas->scene();
384     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
385     pressEvent.setScenePos(QPointF(100, 100));
386     pressEvent.setButton(Qt::LeftButton);
387     pressEvent.setButtons(Qt::LeftButton);
388     QApplication::sendEvent(scene, &pressEvent);
389
390     QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool());
391     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
392     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
393     QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool());
394     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
395     QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool());
396
397     QTest::qWait(200);
398
399     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
400     releaseEvent.setScenePos(QPointF(100, 100));
401     releaseEvent.setButton(Qt::LeftButton);
402     releaseEvent.setButtons(Qt::LeftButton);
403     QApplication::sendEvent(scene, &releaseEvent);
404
405     QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
406     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
407     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
408
409     delete canvas;
410 }
411
412 void tst_QDeclarative1MouseArea::doubleClick()
413 {
414     QDeclarativeView *canvas = createView();
415     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/doubleclick.qml"));
416     canvas->show();
417     canvas->setFocus();
418     QVERIFY(canvas->rootObject() != 0);
419
420     QGraphicsScene *scene = canvas->scene();
421     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
422     pressEvent.setScenePos(QPointF(100, 100));
423     pressEvent.setButton(Qt::LeftButton);
424     pressEvent.setButtons(Qt::LeftButton);
425     QApplication::sendEvent(scene, &pressEvent);
426
427     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
428     releaseEvent.setScenePos(QPointF(100, 100));
429     releaseEvent.setButton(Qt::LeftButton);
430     releaseEvent.setButtons(Qt::LeftButton);
431     QApplication::sendEvent(scene, &releaseEvent);
432
433     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
434
435     QGraphicsSceneMouseEvent dblClickEvent(QEvent::GraphicsSceneMouseDoubleClick);
436     dblClickEvent.setScenePos(QPointF(100, 100));
437     dblClickEvent.setButton(Qt::LeftButton);
438     dblClickEvent.setButtons(Qt::LeftButton);
439     QApplication::sendEvent(scene, &dblClickEvent);
440
441     QApplication::sendEvent(scene, &releaseEvent);
442
443     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
444     QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
445     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
446
447     delete canvas;
448 }
449
450 // QTBUG-14832
451 void tst_QDeclarative1MouseArea::clickTwice()
452 {
453     QDeclarativeView *canvas = createView();
454     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/clicktwice.qml"));
455     canvas->show();
456     canvas->setFocus();
457     QVERIFY(canvas->rootObject() != 0);
458
459     QGraphicsScene *scene = canvas->scene();
460     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
461     pressEvent.setScenePos(QPointF(100, 100));
462     pressEvent.setButton(Qt::LeftButton);
463     pressEvent.setButtons(Qt::LeftButton);
464     QApplication::sendEvent(scene, &pressEvent);
465
466     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
467     releaseEvent.setScenePos(QPointF(100, 100));
468     releaseEvent.setButton(Qt::LeftButton);
469     releaseEvent.setButtons(Qt::LeftButton);
470     QApplication::sendEvent(scene, &releaseEvent);
471
472     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1);
473     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
474     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
475
476     QGraphicsSceneMouseEvent dblClickEvent(QEvent::GraphicsSceneMouseDoubleClick);
477     dblClickEvent.setScenePos(QPointF(100, 100));
478     dblClickEvent.setButton(Qt::LeftButton);
479     dblClickEvent.setButtons(Qt::LeftButton);
480     QApplication::sendEvent(scene, &dblClickEvent);
481
482     QApplication::sendEvent(scene, &pressEvent);
483     QApplication::sendEvent(scene, &releaseEvent);
484
485     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
486     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
487     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
488
489     delete canvas;
490 }
491
492 void tst_QDeclarative1MouseArea::pressedOrdering()
493 {
494     QDeclarativeView *canvas = createView();
495     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pressedOrdering.qml"));
496     canvas->show();
497     canvas->setFocus();
498     QVERIFY(canvas->rootObject() != 0);
499
500     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base"));
501
502     QGraphicsScene *scene = canvas->scene();
503     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
504     pressEvent.setScenePos(QPointF(100, 100));
505     pressEvent.setButton(Qt::LeftButton);
506     pressEvent.setButtons(Qt::LeftButton);
507     QApplication::sendEvent(scene, &pressEvent);
508
509     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
510
511     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
512     releaseEvent.setScenePos(QPointF(100, 100));
513     releaseEvent.setButton(Qt::LeftButton);
514     releaseEvent.setButtons(Qt::LeftButton);
515     QApplication::sendEvent(scene, &releaseEvent);
516
517     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled"));
518
519     QApplication::sendEvent(scene, &pressEvent);
520
521     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
522
523     delete canvas;
524 }
525
526 void tst_QDeclarative1MouseArea::preventStealing()
527 {
528     QDeclarativeView *canvas = createView();
529
530     canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/preventstealing.qml"));
531     canvas->show();
532     canvas->setFocus();
533     QVERIFY(canvas->rootObject() != 0);
534
535     QDeclarative1Flickable *flickable = qobject_cast<QDeclarative1Flickable*>(canvas->rootObject());
536     QVERIFY(flickable != 0);
537
538     QDeclarative1MouseArea *mouseArea = canvas->rootObject()->findChild<QDeclarative1MouseArea*>("mousearea");
539     QVERIFY(mouseArea != 0);
540
541     QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QDeclarative1MouseEvent*)));
542
543     QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(80, 80)));
544
545     // Without preventStealing, mouse movement over MouseArea would
546     // cause the Flickable to steal mouse and trigger content movement.
547     QGraphicsScene *scene = canvas->scene();
548     QGraphicsSceneMouseEvent moveEvent(QEvent::GraphicsSceneMouseMove);
549     moveEvent.setScenePos(QPointF(70, 70));
550     moveEvent.setButton(Qt::LeftButton);
551     moveEvent.setButtons(Qt::LeftButton);
552     QApplication::sendEvent(scene, &moveEvent);
553
554     moveEvent.setScenePos(QPointF(60, 60));
555     moveEvent.setButton(Qt::LeftButton);
556     moveEvent.setButtons(Qt::LeftButton);
557     QApplication::sendEvent(scene, &moveEvent);
558
559     moveEvent.setScenePos(QPointF(50, 50));
560     moveEvent.setButton(Qt::LeftButton);
561     moveEvent.setButtons(Qt::LeftButton);
562     QApplication::sendEvent(scene, &moveEvent);
563
564     // We should have received all three move events
565     QCOMPARE(mousePositionSpy.count(), 3);
566     QVERIFY(mouseArea->pressed());
567
568     // Flickable content should not have moved.
569     QCOMPARE(flickable->contentX(), 0.);
570     QCOMPARE(flickable->contentY(), 0.);
571
572     QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50)));
573
574     // Now allow stealing and confirm Flickable does its thing.
575     canvas->rootObject()->setProperty("stealing", false);
576
577     QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(80, 80)));
578
579     // Without preventStealing, mouse movement over MouseArea would
580     // cause the Flickable to steal mouse and trigger content movement.
581     moveEvent.setScenePos(QPointF(70, 70));
582     QApplication::sendEvent(scene, &moveEvent);
583
584     moveEvent.setScenePos(QPointF(60, 60));
585     QApplication::sendEvent(scene, &moveEvent);
586
587     moveEvent.setScenePos(QPointF(50, 50));
588     QApplication::sendEvent(scene, &moveEvent);
589
590     // We should only have received the first move event
591     QCOMPARE(mousePositionSpy.count(), 4);
592     // Our press should be taken away
593     QVERIFY(!mouseArea->pressed());
594
595     // Flickable content should have moved.
596     QCOMPARE(flickable->contentX(), 10.);
597     QCOMPARE(flickable->contentY(), 10.);
598
599     QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(50, 50)));
600
601     delete canvas;
602 }
603
604 void tst_QDeclarative1MouseArea::testQtQuick11Attributes()
605 {
606     QFETCH(QString, code);
607     QFETCH(QString, warning);
608     QFETCH(QString, error);
609
610     QDeclarativeEngine engine;
611     QObject *obj;
612
613     QDeclarativeComponent valid(&engine);
614     valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl(""));
615     obj = valid.create();
616     QVERIFY(obj);
617     QVERIFY(valid.errorString().isEmpty());
618     delete obj;
619
620     QDeclarativeComponent invalid(&engine);
621     invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl(""));
622     QTest::ignoreMessage(QtWarningMsg, warning.toUtf8());
623     obj = invalid.create();
624     QCOMPARE(invalid.errorString(), error);
625     delete obj;
626 }
627
628 void tst_QDeclarative1MouseArea::testQtQuick11Attributes_data()
629 {
630     QTest::addColumn<QString>("code");
631     QTest::addColumn<QString>("warning");
632     QTest::addColumn<QString>("error");
633
634     QTest::newRow("preventStealing") << "preventStealing: true"
635         << "QDeclarativeComponent: Component is not ready"
636         << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n";
637 }
638
639 #ifndef QT_NO_CONTEXTMENU
640 class ContextMenuEventReceiver : public QDeclarativeItem
641 {
642     Q_OBJECT
643     Q_PROPERTY(int eventCount READ eventCount NOTIFY eventCountChanged);
644 public:
645     ContextMenuEventReceiver(QDeclarativeItem *parent = 0) : QDeclarativeItem(parent), m_eventCount(0) { }
646     int eventCount() const { return m_eventCount; }
647 signals:
648     void eventCountChanged(int);
649 protected:
650     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
651         if (event->reason() == QGraphicsSceneContextMenuEvent::Mouse) {
652             m_eventCount++;
653             emit eventCountChanged(m_eventCount);
654         }
655     }
656 private:
657     int m_eventCount;
658 };
659
660 void tst_QDeclarative1MouseArea::preventContextMenu()
661 {
662     // A MouseArea accepting Left, Middle and Right buttons should prevent context menu
663     // events with "Mouse" reason to hit the Item below.
664
665     qmlRegisterType<ContextMenuEventReceiver>("Test", 1, 0, "ContextMenuEventReceiver");
666
667     QDeclarativeView *view = createView();
668     view->setSource(QUrl::fromLocalFile(SRCDIR "/data/preventContextMenu.qml"));
669     view->show();
670     QVERIFY(view->rootObject() != 0);
671
672     QDeclarativeProperty mouseAreaEnabled(view->rootObject(), "mouseAreaEnabled");
673     QVERIFY(mouseAreaEnabled.read().toBool());
674
675     QDeclarativeProperty eventsReceived(view->rootObject(), "eventsReceived");
676     QCOMPARE(eventsReceived.read().toInt(), 0);
677
678     QPoint targetPoint = view->mapFromScene(QPoint(80, 80));
679
680     QContextMenuEvent fakeEvent1(QContextMenuEvent::Mouse, targetPoint);
681     QApplication::sendEvent(view->viewport(), &fakeEvent1);
682     QCOMPARE(eventsReceived.read().toInt(), 0);
683
684     mouseAreaEnabled.write(false);
685     QVERIFY(!mouseAreaEnabled.read().toBool());
686     QContextMenuEvent fakeEvent2(QContextMenuEvent::Mouse, targetPoint);
687     QApplication::sendEvent(view->viewport(), &fakeEvent2);
688     QCOMPARE(eventsReceived.read().toInt(), 1);
689
690     mouseAreaEnabled.write(true);
691     QVERIFY(mouseAreaEnabled.read().toBool());
692     QContextMenuEvent fakeEvent3(QContextMenuEvent::Mouse, targetPoint);
693     QApplication::sendEvent(view->viewport(), &fakeEvent3);
694     QCOMPARE(eventsReceived.read().toInt(), 1);
695 }
696 #endif // QT_NO_CONTEXTMENU
697
698 QTEST_MAIN(tst_QDeclarative1MouseArea)
699
700 #include "tst_qdeclarativemousearea.moc"