diff options
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/declarative/declarative.pro | 2 | ||||
-rw-r--r-- | tests/auto/declarative/qsgdrag/qsgdrag.pro | 11 | ||||
-rw-r--r-- | tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp | 768 | ||||
-rw-r--r-- | tests/auto/declarative/qsgdroparea/qsgdroparea.pro | 11 | ||||
-rw-r--r-- | tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp | 1063 |
5 files changed, 1855 insertions, 0 deletions
diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 324880120b..c9b54b2908 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -64,6 +64,8 @@ SGTESTS = \ qsganimatedimage \ qsgborderimage \ qsgcanvas \ + qsgdrag \ + qsgdroparea \ qsgflickable \ qsgflipable \ qsgfocusscope \ diff --git a/tests/auto/declarative/qsgdrag/qsgdrag.pro b/tests/auto/declarative/qsgdrag/qsgdrag.pro new file mode 100644 index 0000000000..213385cd1f --- /dev/null +++ b/tests/auto/declarative/qsgdrag/qsgdrag.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui network +macx:CONFIG -= app_bundle + +SOURCES += tst_qsgdrag.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private diff --git a/tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp b/tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp new file mode 100644 index 0000000000..5d5da9a931 --- /dev/null +++ b/tests/auto/declarative/qsgdrag/tst_qsgdrag.cpp @@ -0,0 +1,768 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtTest/QSignalSpy> +#include <QtDeclarative/qsgitem.h> +#include <QtDeclarative/qsgview.h> +#include <QtDeclarative/qdeclarativecontext.h> +#include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeexpression.h> +#include "../../../shared/util.h" + +template <typename T> static T evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + QVariant result = expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); + return result.value<T>(); +} + +template <> void evaluate<void>(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); +} + +Q_DECLARE_METATYPE(Qt::DropActions) + +class TestDropTarget : public QSGItem +{ + Q_OBJECT +public: + TestDropTarget(QSGItem *parent = 0) + : QSGItem(parent) + , enterEvents(0) + , moveEvents(0) + , leaveEvents(0) + , dropEvents(0) + , acceptAction(Qt::MoveAction) + , defaultAction(Qt::IgnoreAction) + , proposedAction(Qt::IgnoreAction) + , accept(true) + { + setFlags(ItemAcceptsDrops); + } + + void reset() + { + enterEvents = 0; + moveEvents = 0; + leaveEvents = 0; + dropEvents = 0; + defaultAction = Qt::IgnoreAction; + proposedAction = Qt::IgnoreAction; + supportedActions = Qt::IgnoreAction; + } + + void dragEnterEvent(QDragEnterEvent *event) + { + ++enterEvents; + position = event->pos(); + defaultAction = event->dropAction(); + proposedAction = event->proposedAction(); + supportedActions = event->possibleActions(); + event->setAccepted(accept); + } + + void dragMoveEvent(QDragMoveEvent *event) + { + ++moveEvents; + position = event->pos(); + defaultAction = event->dropAction(); + proposedAction = event->proposedAction(); + supportedActions = event->possibleActions(); + event->setAccepted(accept); + } + + void dragLeaveEvent(QDragLeaveEvent *event) + { + ++leaveEvents; + event->setAccepted(accept); + } + + void dropEvent(QDropEvent *event) + { + ++dropEvents; + position = event->pos(); + defaultAction = event->dropAction(); + proposedAction = event->proposedAction(); + supportedActions = event->possibleActions(); + event->setDropAction(acceptAction); + event->setAccepted(accept); + } + + int enterEvents; + int moveEvents; + int leaveEvents; + int dropEvents; + Qt::DropAction acceptAction; + Qt::DropAction defaultAction; + Qt::DropAction proposedAction; + Qt::DropActions supportedActions; + QPointF position; + bool accept; +}; + +class tst_QSGDrag: public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + + void active(); + void drop(); + void move(); + void hotSpot(); + void supportedActions(); + void proposedAction(); + void keys(); + void source(); + +private: + QDeclarativeEngine engine; +}; + +void tst_QSGDrag::initTestCase() +{ + +} + +void tst_QSGDrag::cleanupTestCase() +{ + +} + +void tst_QSGDrag::active() +{ + QSGCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property bool dragActive: Drag.active\n" + "property Item dragTarget: Drag.target\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = false"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + dropTarget.reset(); + evaluate<void>(item, "Drag.cancel()"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate<void>(item, "Drag.start()"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + // Start while a drag is active, cancels the previous drag and starts a new one. + dropTarget.reset(); + evaluate<void>(item, "Drag.start()"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 1); + + dropTarget.reset(); + evaluate<void>(item, "Drag.cancel()"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + // Enter events aren't sent to items without the QSGItem::ItemAcceptsDrops flag. + dropTarget.setFlags(QSGItem::Flags()); + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = false"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.setFlags(QSGItem::ItemAcceptsDrops); + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.setFlags(QSGItem::Flags()); + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = false"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + // Follow up events aren't sent to items if the enter event isn't accepted. + dropTarget.setFlags(QSGItem::ItemAcceptsDrops); + dropTarget.accept = false; + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = false"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.accept = true; + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.accept = false; + + dropTarget.reset(); + evaluate<void>(item, "Drag.active = false"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); +} + +void tst_QSGDrag::drop() +{ + QSGCanvas canvas; + TestDropTarget outerTarget(canvas.rootItem()); + outerTarget.setSize(QSizeF(100, 100)); + outerTarget.acceptAction = Qt::CopyAction; + TestDropTarget innerTarget(&outerTarget); + innerTarget.setSize(QSizeF(100, 100)); + innerTarget.acceptAction = Qt::MoveAction; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property bool dragActive: Drag.active\n" + "property Item dragTarget: Drag.target\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + item->setParentItem(&outerTarget); + + innerTarget.reset(); outerTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1); + + innerTarget.reset(); outerTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&innerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&innerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + // Inner target declines the drop so it is propagated to the outer target. + innerTarget.accept = false; + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.CopyAction"), true); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1); + + + // Inner target doesn't accept enter so drop goes directly to outer. + innerTarget.accept = true; + innerTarget.setFlags(QSGItem::Flags()); + + innerTarget.reset(); outerTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.CopyAction"), true); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + // Neither target accepts drop so Qt::IgnoreAction is returned. + innerTarget.reset(); outerTarget.reset(); + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + outerTarget.accept = false; + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate<bool>(item, "Drag.drop() == Qt.IgnoreAction"), true); + QCOMPARE(evaluate<bool>(item, "Drag.active"), false); + QCOMPARE(evaluate<bool>(item, "dragActive"), false); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); +} + +void tst_QSGDrag::move() +{ + QSGCanvas canvas; + TestDropTarget outerTarget(canvas.rootItem()); + outerTarget.setSize(QSizeF(100, 100)); + TestDropTarget leftTarget(&outerTarget); + leftTarget.setPos(QPointF(0, 35)); + leftTarget.setSize(QSizeF(30, 30)); + TestDropTarget rightTarget(&outerTarget); + rightTarget.setPos(QPointF(70, 35)); + rightTarget.setSize(QSizeF(30, 30)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property bool dragActive: Drag.active\n" + "property Item dragTarget: Drag.target\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + item->setParentItem(&outerTarget); + + evaluate<void>(item, "Drag.active = true"); + QCOMPARE(evaluate<bool>(item, "Drag.active"), true); + QCOMPARE(evaluate<bool>(item, "dragActive"), true); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(50)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Move within the outer target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(60, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Move into the right target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(75, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&rightTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&rightTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(75)); QCOMPARE(outerTarget.position.y(), qreal(50)); + QCOMPARE(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15)); + + // Move into the left target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(25, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 1); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 1); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50)); + QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(15)); + + // Move within the left target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(25, 40)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 1); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(40)); + QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(5)); + + // Move out of all targets. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(110, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(0)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 1); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + + // Stop the right target accepting drag events and move into it. + rightTarget.accept = false; + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(80, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(80)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Stop the outer target accepting drag events after it has accepted an enter event. + outerTarget.accept = false; + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(60, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Clear the QSGItem::ItemAcceptsDrops flag from the outer target after it accepted an enter event. + outerTarget.setFlags(QSGItem::Flags()); + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(40, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(40)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Clear the QSGItem::ItemAcceptsDrops flag from the left target before it accepts an enter event. + leftTarget.setFlags(QSGItem::Flags()); + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(25, 50)); + QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50)); +} + + +void tst_QSGDrag::hotSpot() +{ + QSGCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property real hotSpotX: Drag.hotSpot.x\n" + "property real hotSpotY: Drag.hotSpot.y\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.x"), qreal(0)); + QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.y"), qreal(0)); + QCOMPARE(evaluate<qreal>(item, "hotSpotX"), qreal(0)); + QCOMPARE(evaluate<qreal>(item, "hotSpotY"), qreal(0)); + + evaluate<void>(item, "{ Drag.start(); Drag.cancel() }"); + QCOMPARE(dropTarget.position.x(), qreal(50)); + QCOMPARE(dropTarget.position.y(), qreal(50)); + + evaluate<void>(item, "{ Drag.hotSpot.x = 5, Drag.hotSpot.y = 5 }"); + QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.x"), qreal(5)); + QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.y"), qreal(5)); + QCOMPARE(evaluate<qreal>(item, "hotSpotX"), qreal(5)); + QCOMPARE(evaluate<qreal>(item, "hotSpotY"), qreal(5)); + + evaluate<void>(item, "Drag.start()"); + QCOMPARE(dropTarget.position.x(), qreal(55)); + QCOMPARE(dropTarget.position.y(), qreal(55)); + + item->setPos(QPointF(30, 20)); + QCOMPARE(dropTarget.position.x(), qreal(35)); + QCOMPARE(dropTarget.position.y(), qreal(25)); + + evaluate<void>(item, "{ Drag.hotSpot.x = 10; Drag.hotSpot.y = 10 }"); + QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.x"), qreal(10)); + QCOMPARE(evaluate<qreal>(item, "Drag.hotSpot.y"), qreal(10)); + QCOMPARE(evaluate<qreal>(item, "hotSpotX"), qreal(10)); + QCOMPARE(evaluate<qreal>(item, "hotSpotY"), qreal(10)); + // Changing the hotSpot won't generate a move event so the position is unchanged. Should it? + QCOMPARE(dropTarget.position.x(), qreal(35)); + QCOMPARE(dropTarget.position.y(), qreal(25)); + + item->setPos(QPointF(10, 20)); + QCOMPARE(dropTarget.position.x(), qreal(20)); + QCOMPARE(dropTarget.position.y(), qreal(30)); +} + +void tst_QSGDrag::supportedActions() +{ + QSGCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property int supportedActions: Drag.supportedActions\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true); + QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true); + evaluate<void>(item, "{ Drag.start(); Drag.cancel() }"); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction | Qt::LinkAction); + + evaluate<void>(item, "Drag.supportedActions = Qt.CopyAction | Qt.MoveAction"); + QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.CopyAction | Qt.MoveAction"), true); + evaluate<void>(item, "Drag.start()"); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction); + + // Once a drag is started the proposed actions are locked in for future events. + evaluate<void>(item, "Drag.supportedActions = Qt.MoveAction"); + QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.MoveAction"), true); + item->setPos(QPointF(60, 60)); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction); + + // Calling start with proposed actions will override the current actions for the next sequence. + evaluate<void>(item, "Drag.start(Qt.CopyAction)"); + QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.MoveAction"), true); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction); + + evaluate<void>(item, "Drag.start()"); + QCOMPARE(evaluate<bool>(item, "Drag.supportedActions == Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "supportedActions == Qt.MoveAction"), true); + QCOMPARE(dropTarget.supportedActions, Qt::MoveAction); +} + +void tst_QSGDrag::proposedAction() +{ + QSGCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property int proposedAction: Drag.proposedAction\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.MoveAction"), true); + evaluate<void>(item, "{ Drag.start(); Drag.cancel() }"); + QCOMPARE(dropTarget.defaultAction, Qt::MoveAction); + QCOMPARE(dropTarget.proposedAction, Qt::MoveAction); + + evaluate<void>(item, "Drag.proposedAction = Qt.CopyAction"); + QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.CopyAction"), true); + QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.CopyAction"), true); + evaluate<void>(item, "Drag.start()"); + QCOMPARE(dropTarget.defaultAction, Qt::CopyAction); + QCOMPARE(dropTarget.proposedAction, Qt::CopyAction); + + // The proposed action can change during a drag. + evaluate<void>(item, "Drag.proposedAction = Qt.MoveAction"); + QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.MoveAction"), true); + QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.MoveAction"), true); + item->setPos(QPointF(60, 60)); + QCOMPARE(dropTarget.defaultAction, Qt::MoveAction); + QCOMPARE(dropTarget.proposedAction, Qt::MoveAction); + + evaluate<void>(item, "Drag.proposedAction = Qt.LinkAction"); + QCOMPARE(evaluate<bool>(item, "Drag.proposedAction == Qt.LinkAction"), true); + QCOMPARE(evaluate<bool>(item, "proposedAction == Qt.LinkAction"), true); + evaluate<void>(item, "Drag.drop()"); + QCOMPARE(dropTarget.defaultAction, Qt::LinkAction); + QCOMPARE(dropTarget.proposedAction, Qt::LinkAction); +} + +void tst_QSGDrag::keys() +{ + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property variant keys: Drag.keys\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + +// QCOMPARE(evaluate<QStringList>(item, "Drag.keys"), QStringList()); +// QCOMPARE(evaluate<QStringList>(item, "keys"), QStringList()); + QCOMPARE(item->property("keys").toStringList(), QStringList()); + + evaluate<void>(item, "Drag.keys = [\"red\", \"blue\"]"); +// QCOMPARE(evaluate<QStringList>(item, "Drag.keys"), QStringList() << "red" << "blue"); +// QCOMPARE(evaluate<QStringList>(item, "keys"), QStringList() << "red" << "blue"); + QCOMPARE(item->property("keys").toStringList(), QStringList() << "red" << "blue"); +} + +void tst_QSGDrag::source() +{ + + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property Item source: Drag.source\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Item { id: proxySource; objectName: \"proxySource\" }\n" + "}", QUrl()); + QSGItem *item = qobject_cast<QSGItem *>(component.create()); + QVERIFY(item); + + QCOMPARE(evaluate<QObject *>(item, "Drag.source"), static_cast<QObject *>(item)); + QCOMPARE(evaluate<QObject *>(item, "source"), static_cast<QObject *>(item)); + + QSGItem *proxySource = item->findChild<QSGItem *>("proxySource"); + QVERIFY(proxySource); + + evaluate<void>(item, "Drag.source = proxySource"); + QCOMPARE(evaluate<QObject *>(item, "Drag.source"), static_cast<QObject *>(proxySource)); + QCOMPARE(evaluate<QObject *>(item, "source"), static_cast<QObject *>(proxySource)); +} + +QTEST_MAIN(tst_QSGDrag) + +#include "tst_qsgdrag.moc" diff --git a/tests/auto/declarative/qsgdroparea/qsgdroparea.pro b/tests/auto/declarative/qsgdroparea/qsgdroparea.pro new file mode 100644 index 0000000000..2f4be247b0 --- /dev/null +++ b/tests/auto/declarative/qsgdroparea/qsgdroparea.pro @@ -0,0 +1,11 @@ +load(qttest_p4) +contains(QT_CONFIG,declarative): QT += declarative gui network +macx:CONFIG -= app_bundle + +SOURCES += tst_qsgdroparea.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private diff --git a/tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp b/tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp new file mode 100644 index 0000000000..4fa6704611 --- /dev/null +++ b/tests/auto/declarative/qsgdroparea/tst_qsgdroparea.cpp @@ -0,0 +1,1063 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtTest/QSignalSpy> +#include <QtDeclarative/qsgitem.h> +#include <QtDeclarative/qsgview.h> +#include <QtDeclarative/qdeclarativecontext.h> +#include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeexpression.h> +#include "../../../shared/util.h" + +#include <QtGui/qwindowsysteminterface_qpa.h> + +template <typename T> static T evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + QVariant result = expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); + return result.value<T>(); +} + +template <> void evaluate<void>(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); +} + +class tst_QSGDropArea: public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + + void containsDrag_internal(); + void containsDrag_external(); + void keys_internal(); + void keys_external(); + void source_internal(); +// void source_external(); + void position_internal(); + void position_external(); + void drop_internal(); +// void drop_external(); + void simultaneousDrags(); + +private: + QDeclarativeEngine engine; +}; + +void tst_QSGDropArea::initTestCase() +{ + +} + +void tst_QSGDropArea::cleanupTestCase() +{ + +} + +void tst_QSGDropArea::containsDrag_internal() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property bool hasDrag: containsDrag\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem"); + QVERIFY(dragItem); + + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); + + evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1); + + evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + + dragItem->setPos(QPointF(150, 50)); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); + + dragItem->setPos(QPointF(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); + + evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + dragItem->setPos(QPointF(150, 50)); + + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1); + + evaluate<void>(dragItem, "Drag.active = false"); +} + +void tst_QSGDropArea::containsDrag_external() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property bool hasDrag: containsDrag\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QMimeData data; + QSGCanvas alternateCanvas; + + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); + + evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1); + + evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0); + + evaluate<void>(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1); + + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(150, 50)); +} + +void tst_QSGDropArea::keys_internal() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property variant dragKeys\n" + "property variant dropKeys: keys\n" + "property int enterEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; dragKeys = drag.keys }\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Drag.keys: [\"red\", \"blue\"]\n" + "}\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem"); + QVERIFY(dragItem); + + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate<void>(dragItem, "Drag.active = false"); + evaluate<void>(dropArea, "keys = \"blue\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "blue"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "blue"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate<void>(dragItem, "Drag.active = false"); + evaluate<void>(dropArea, "keys = \"red\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate<void>(dragItem, "Drag.active = false"); + evaluate<void>(dropArea, "keys = \"green\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "green"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + + evaluate<void>(dragItem, "Drag.active = false"); + evaluate<void>(dropArea, "keys = [\"red\", \"green\"]"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red" << "green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red" << "green"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate<void>(dragItem, "Drag.active = false"); + evaluate<void>(dragItem, "Drag.keys = []"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); +} + +void tst_QSGDropArea::keys_external() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property variant dragKeys\n" + "property variant dropKeys: keys\n" + "property int enterEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; dragKeys = drag.keys }\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QMimeData data; + QSGCanvas alternateCanvas; + + data.setData("text/x-red", "red"); + data.setData("text/x-blue", "blue"); + + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate<void>(dropArea, "keys = \"text/x-blue\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-blue"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-blue"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate<void>(dropArea, "keys = \"text/x-red\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate<void>(dropArea, "keys = \"text/x-green\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-green"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate<void>(dropArea, "keys = [\"text/x-red\", \"text/x-green\"]"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + data.removeFormat("text/x-red"); + data.removeFormat("text/x-blue"); + evaluate<void>(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(50, 50)); +} + +void tst_QSGDropArea::source_internal() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property Item source: drag.source\n" + "property Item eventSource\n" + "width: 100; height: 100\n" + "onEntered: {eventSource = drag.source}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "Item { id: dragSource; objectName: \"dragSource\" }\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem"); + QVERIFY(dragItem); + + QSGItem *dragSource = dropArea->findChild<QSGItem *>("dragSource"); + QVERIFY(dragSource); + + QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(0)); + + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(dragItem)); + QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(dragItem)); + QCOMPARE(evaluate<QObject *>(dropArea, "eventSource"), static_cast<QObject *>(dragItem)); + + evaluate<void>(dragItem, "Drag.active = false"); + QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(0)); + + + evaluate<void>(dropArea, "{ eventSource = null }"); + evaluate<void>(dragItem, "Drag.source = dragSource"); + + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(dragSource)); + QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(dragSource)); + QCOMPARE(evaluate<QObject *>(dropArea, "eventSource"), static_cast<QObject *>(dragSource)); + + evaluate<void>(dragItem, "Drag.active = false"); + QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(0)); + QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(0)); +} + +// Setting a source can't be emulated using the QWindowSystemInterface API. + +//void tst_QSGDropArea::source_external() +//{ +//} + +void tst_QSGDropArea::position_internal() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property real dragX: drag.x\n" + "property real dragY: drag.y\n" + "property real eventX\n" + "property real eventY\n" + "property int enterEvents: 0\n" + "property int moveEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n" + "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem"); + QVERIFY(dragItem); + + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 0); + QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50)); + + evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + dragItem->setPos(QPointF(40, 50)); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40)); + QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(40)); + QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(40)); + QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50)); + + evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + dragItem->setPos(QPointF(75, 25)); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75)); + QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(25)); + QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(75)); + QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(25)); + QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75)); + QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25)); + + evaluate<void>(dragItem, "Drag.active = false"); +} + +void tst_QSGDropArea::position_external() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property real dragX: drag.x\n" + "property real dragY: drag.y\n" + "property real eventX\n" + "property real eventY\n" + "property int enterEvents: 0\n" + "property int moveEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n" + "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QMimeData data; + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50)); + + evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(40, 50)); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40)); + QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(40)); + QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(40)); + QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50)); + + evaluate<void>(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(75, 25)); + QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75)); + QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(25)); + QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(75)); + QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(25)); + QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75)); + QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25)); + + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(75, 25)); +} + +void tst_QSGDropArea::drop_internal() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property bool accept: false\n" + "property bool setAccepted: false\n" + "property bool acceptDropAction: false\n" + "property bool setDropAction: false\n" + "property int dropAction: Qt.IgnoreAction\n" + "property int proposedAction: Qt.IgnoreAction\n" + "property int supportedActions: Qt.IgnoreAction\n" + "property int dropEvents: 0\n" + "width: 100; height: 100\n" + "onDropped: {\n" + "++dropEvents\n" + "supportedActions = drop.supportedActions\n" + "proposedAction = drop.action\n" + "if (setDropAction)\n" + "drop.action = dropAction\n" + "if (acceptDropAction)\n" + "drop.accept(dropAction)\n" + "else if (setAccepted)\n" + "drop.accepted = accept\n" + "else if (accept)\n" + "drop.accept()\n" + "}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "}", QUrl()); + QSGItem *dropArea = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QSGItem *dragItem = dropArea->findChild<QSGItem *>("dragItem"); + QVERIFY(dragItem); + + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::IgnoreAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ accept = true; setDropAction = true; dropAction = Qt.LinkAction }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = true; }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ accept = false; setAccepted = true; }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::IgnoreAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = false; setDropAction = false; acceptDropAction = true; }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ acceptDropAction = false; dropAction = Qt.IgnoreAction; accept = true }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = true }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = false }"); + evaluate<void>(dragItem, "Drag.supportedActions = Qt.LinkAction"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = true }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = false }"); + evaluate<void>(dragItem, "Drag.proposedAction = Qt.LinkAction"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::LinkAction)); + + evaluate<void>(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate<void>(dropArea, "{ setAccepted = true }"); + evaluate<void>(dragItem, "Drag.active = true"); + QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::LinkAction)); +} + +// Setting the supportedActions can't be emulated using the QWindowSystemInterface API. + +//void tst_QSGDropArea::drop_external() +//{ +//} + +void tst_QSGDropArea::simultaneousDrags() +{ + QSGCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "keys: [\"red\", \"text/x-red\"]\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "DropArea {\n" + "objectName: \"dropArea2\"\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "keys: [\"blue\", \"text/x-blue\"]\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "}\n" + "Item {\n" + "objectName: \"dragItem1\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Drag.keys: [\"red\", \"blue\"]" + "}\n" + "Item {\n" + "objectName: \"dragItem2\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Drag.keys: [\"red\", \"blue\"]" + "}\n" + "}", QUrl()); + + QSGItem *dropArea1 = qobject_cast<QSGItem *>(component.create()); + QVERIFY(dropArea1); + dropArea1->setParentItem(canvas.rootItem()); + + QSGItem *dropArea2 = dropArea1->findChild<QSGItem *>("dropArea2"); + QVERIFY(dropArea2); + + QSGItem *dragItem1 = dropArea1->findChild<QSGItem *>("dragItem1"); + QVERIFY(dragItem1); + + QSGItem *dragItem2 = dropArea1->findChild<QSGItem *>("dragItem2"); + QVERIFY(dragItem2); + + QMimeData data; + data.setData("text/x-red", "red"); + data.setData("text/x-blue", "blue"); + + QSGCanvas alternateCanvas; + + // Mixed internal drags. + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + // internal then external. + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + // external then internal. + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + // Different acceptance + evaluate<void>(dragItem1, "Drag.keys = \"red\""); + evaluate<void>(dragItem2, "Drag.keys = \"blue\""); + data.removeFormat("text/x-red"); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + // internal then external + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0); + + evaluate<void>(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate<void>(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1); + + QWindowSystemInterface::handleDrop(&alternateCanvas, &data, QPoint(50, 50)); +} + +QTEST_MAIN(tst_QSGDropArea) + +#include "tst_qsgdroparea.moc" |