summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp26
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea_p.h3
-rw-r--r--tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml22
-rw-r--r--tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp63
4 files changed, 114 insertions, 0 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index d4e7f7b..6633256 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -660,6 +660,32 @@ void QDeclarativeMouseArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
setHovered(false);
}
+#ifndef QT_NO_CONTEXTMENU
+void QDeclarativeMouseArea::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
+{
+ bool acceptsContextMenuButton;
+#if defined(Q_OS_SYMBIAN)
+ // In Symbian a Long Tap on the screen will trigger. See QSymbianControl::HandleLongTapEventL().
+ acceptsContextMenuButton = acceptedButtons() & Qt::LeftButton;
+#elif defined(Q_WS_WINCE)
+ // ### WinCE can trigger context menu event with a gesture in the left button or a
+ // click with the right button. Since we have no way here to differentiate them when
+ // event happens, accepting either of the them will block the event.
+ acceptsContextMenuButton = acceptedButtons() & (Qt::LeftButton | Qt::RightButton);
+#else
+ acceptsContextMenuButton = acceptedButtons() & Qt::RightButton;
+#endif
+
+ if (isEnabled() && event->reason() == QGraphicsSceneContextMenuEvent::Mouse
+ && acceptsContextMenuButton) {
+ // Do not let the context menu event propagate to items behind.
+ return;
+ }
+
+ QDeclarativeItem::contextMenuEvent(event);
+}
+#endif // QT_NO_CONTEXTMENU
+
bool QDeclarativeMouseArea::sceneEvent(QEvent *event)
{
bool rv = QDeclarativeItem::sceneEvent(event);
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h
index 351d4de..0fe8c6a 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h
+++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h
@@ -190,6 +190,9 @@ protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+#ifndef QT_NO_CONTEXTMENU
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+#endif // QT_NO_CONTEXTMENU
bool sceneEvent(QEvent *);
bool sendMouseEvent(QGraphicsSceneMouseEvent *event);
bool sceneEventFilter(QGraphicsItem *i, QEvent *e);
diff --git a/tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml b/tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml
new file mode 100644
index 0000000..dcbb5d7
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml
@@ -0,0 +1,22 @@
+import QtQuick 1.1
+import Test 1.0
+
+Item {
+ width: 200
+ height: 200
+
+ property alias mouseAreaEnabled: mouseArea.enabled
+ property alias eventsReceived: receiver.eventCount
+
+ ContextMenuEventReceiver {
+ id: receiver
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
+ enabled: true
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
index e1c34fc..fea7865 100644
--- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
+++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp
@@ -47,6 +47,7 @@
#include <QtDeclarative/qdeclarativeview.h>
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeproperty.h>
#ifdef Q_OS_SYMBIAN
// In Symbian OS test data is located in applications private dir
@@ -70,6 +71,9 @@ private slots:
void preventStealing();
void testQtQuick11Attributes();
void testQtQuick11Attributes_data();
+#ifndef QT_NO_CONTEXTMENU
+ void preventContextMenu();
+#endif // QT_NO_CONTEXTMENU
private:
QDeclarativeView *createView();
@@ -637,6 +641,65 @@ void tst_QDeclarativeMouseArea::testQtQuick11Attributes_data()
<< ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n";
}
+#ifndef QT_NO_CONTEXTMENU
+class ContextMenuEventReceiver : public QDeclarativeItem
+{
+ Q_OBJECT
+ Q_PROPERTY(int eventCount READ eventCount NOTIFY eventCountChanged);
+public:
+ ContextMenuEventReceiver(QDeclarativeItem *parent = 0) : QDeclarativeItem(parent), m_eventCount(0) { }
+ int eventCount() const { return m_eventCount; }
+signals:
+ void eventCountChanged(int);
+protected:
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) {
+ if (event->reason() == QGraphicsSceneContextMenuEvent::Mouse) {
+ m_eventCount++;
+ emit eventCountChanged(m_eventCount);
+ }
+ }
+private:
+ int m_eventCount;
+};
+
+void tst_QDeclarativeMouseArea::preventContextMenu()
+{
+ // A MouseArea accepting Left, Middle and Right buttons should prevent context menu
+ // events with "Mouse" reason to hit the Item below.
+
+ qmlRegisterType<ContextMenuEventReceiver>("Test", 1, 0, "ContextMenuEventReceiver");
+
+ QDeclarativeView *view = createView();
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/preventContextMenu.qml"));
+ view->show();
+ QVERIFY(view->rootObject() != 0);
+
+ QDeclarativeProperty mouseAreaEnabled(view->rootObject(), "mouseAreaEnabled");
+ QVERIFY(mouseAreaEnabled.read().toBool());
+
+ QDeclarativeProperty eventsReceived(view->rootObject(), "eventsReceived");
+ QCOMPARE(eventsReceived.read().toInt(), 0);
+
+ QPoint targetPoint = view->mapFromScene(QPoint(80, 80));
+
+ QContextMenuEvent fakeEvent1(QContextMenuEvent::Mouse, targetPoint);
+ QApplication::sendEvent(view->viewport(), &fakeEvent1);
+ QCOMPARE(eventsReceived.read().toInt(), 0);
+
+ mouseAreaEnabled.write(false);
+ QVERIFY(!mouseAreaEnabled.read().toBool());
+ QContextMenuEvent fakeEvent2(QContextMenuEvent::Mouse, targetPoint);
+ QApplication::sendEvent(view->viewport(), &fakeEvent2);
+ QCOMPARE(eventsReceived.read().toInt(), 1);
+
+ mouseAreaEnabled.write(true);
+ QVERIFY(mouseAreaEnabled.read().toBool());
+ QContextMenuEvent fakeEvent3(QContextMenuEvent::Mouse, targetPoint);
+ QApplication::sendEvent(view->viewport(), &fakeEvent3);
+ QCOMPARE(eventsReceived.read().toInt(), 1);
+}
+#endif // QT_NO_CONTEXTMENU
+
QTEST_MAIN(tst_QDeclarativeMouseArea)
#include "tst_qdeclarativemousearea.moc"