1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <QtTest/QSignalSpy>
31#include <QtGui/qstylehints.h>
32#include <QtQuick/qquickitem.h>
33#include <QtQuick/qquickview.h>
34#include <QtQml/qqmlcontext.h>
35#include <QtQml/qqmlengine.h>
36#include <QtQml/qqmlexpression.h>
37
38#include <qpa/qplatformdrag.h>
39#include <qpa/qwindowsysteminterface.h>
40#include "../../shared/util.h"
41#include "../shared/viewtestutil.h"
42
43template <typename T> static T evaluate(QObject *scope, const QString &expression)
44{
45 QQmlExpression expr(qmlContext(scope), scope, expression);
46 QVariant result = expr.evaluate();
47 if (expr.hasError())
48 qWarning() << expr.error().toString();
49 return result.value<T>();
50}
51
52template <> void evaluate<void>(QObject *scope, const QString &expression)
53{
54 QQmlExpression expr(qmlContext(scope), scope, expression);
55 expr.evaluate();
56 if (expr.hasError())
57 qWarning() << expr.error().toString();
58}
59
60class tst_QQuickDropArea: public QQmlDataTest
61{
62 Q_OBJECT
63private slots:
64 void containsDrag_internal();
65 void containsDrag_external();
66 void keys_internal();
67 void keys_external();
68 void source_internal();
69// void source_external();
70 void position_internal();
71 void position_external();
72 void drop_internal();
73// void drop_external();
74 void competingDrags();
75 void simultaneousDrags();
76 void dropStuff();
77 void nestedDropAreas_data();
78 void nestedDropAreas();
79
80private:
81 QQmlEngine engine;
82};
83
84void tst_QQuickDropArea::containsDrag_internal()
85{
86 QQuickWindow window;
87 QQmlComponent component(&engine);
88 component.setData(
89 "import QtQuick 2.0\n"
90 "DropArea {\n"
91 "property bool hasDrag: containsDrag\n"
92 "property int enterEvents: 0\n"
93 "property int exitEvents: 0\n"
94 "width: 100; height: 100\n"
95 "onEntered: {++enterEvents}\n"
96 "onExited: {++exitEvents}\n"
97 "Item {\n"
98 "objectName: \"dragItem\"\n"
99 "x: 50; y: 50\n"
100 "width: 10; height: 10\n"
101 "}\n"
102 "}", baseUrl: QUrl());
103 QScopedPointer<QObject> object(component.create());
104 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
105 QVERIFY(dropArea);
106 dropArea->setParentItem(window.contentItem());
107
108 QQuickItem *dragItem = dropArea->findChild<QQuickItem *>(aName: "dragItem");
109 QVERIFY(dragItem);
110
111 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
112 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
113
114 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
115 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
116 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
117 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
118 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
119
120 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; exitEvents = 0 }");
121 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
122 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
123 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
124 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
125 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
126
127 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; exitEvents = 0 }");
128
129 dragItem->setPosition(QPointF(150, 50));
130 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
131 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
132 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
133 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
134 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
135
136 dragItem->setPosition(QPointF(50, 50));
137 QCoreApplication::processEvents();
138 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
139 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
140 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
141 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
142
143 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; exitEvents = 0 }");
144 dragItem->setPosition(QPointF(150, 50));
145 QCoreApplication::processEvents();
146
147 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
148 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
149 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
150 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
151
152 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
153}
154
155void tst_QQuickDropArea::containsDrag_external()
156{
157 QQuickWindow window;
158 QQmlComponent component(&engine);
159 component.setData(
160 "import QtQuick 2.0\n"
161 "DropArea {\n"
162 "property bool hasDrag: containsDrag\n"
163 "property int enterEvents: 0\n"
164 "property int exitEvents: 0\n"
165 "width: 100; height: 100\n"
166 "onEntered: {++enterEvents}\n"
167 "onExited: {++exitEvents}\n"
168 "}", baseUrl: QUrl());
169 QScopedPointer<QObject> object(component.create());
170 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
171 QVERIFY(dropArea);
172 dropArea->setParentItem(window.contentItem());
173
174 QMimeData data;
175 QQuickWindow alternateWindow;
176
177 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
178 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
179
180 const qreal dpr = window.devicePixelRatio();
181 const QPoint nativePos1 = QPoint(50, 50) * dpr;
182 const QPoint nativePos2 = QPoint(150, 50) * dpr;
183 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: nativePos1, supportedActions: Qt::CopyAction,
184 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
185 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
186 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
187 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
188 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
189
190 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; exitEvents = 0 }");
191 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: nativePos1, supportedActions: Qt::CopyAction,
192 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
193 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
194 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
195 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
196 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
197
198 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; exitEvents = 0 }");
199
200 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: nativePos2, supportedActions: Qt::CopyAction,
201 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
202 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
203 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
204 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
205 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
206
207 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: nativePos1, supportedActions: Qt::CopyAction,
208 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
209 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
210 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), true);
211 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
212 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 0);
213
214 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; exitEvents = 0 }");
215
216 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: nativePos2, supportedActions: Qt::CopyAction,
217 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
218 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
219 QCOMPARE(evaluate<bool>(dropArea, "hasDrag"), false);
220 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
221 QCOMPARE(evaluate<int>(dropArea, "exitEvents"), 1);
222
223 QWindowSystemInterface::handleDrop(window: &window, dropData: &data, p: nativePos2, supportedActions: Qt::CopyAction,
224 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
225}
226
227void tst_QQuickDropArea::keys_internal()
228{
229 QQuickWindow window;
230 QQmlComponent component(&engine);
231 component.setData(
232 "import QtQuick 2.0\n"
233 "DropArea {\n"
234 "property variant dragKeys\n"
235 "property variant dropKeys: keys\n"
236 "property int enterEvents: 0\n"
237 "width: 100; height: 100\n"
238 "onEntered: {++enterEvents; dragKeys = drag.keys }\n"
239 "Item {\n"
240 "objectName: \"dragItem\"\n"
241 "x: 50; y: 50\n"
242 "width: 10; height: 10\n"
243 "Drag.keys: [\"red\", \"blue\"]\n"
244 "}\n"
245 "}", baseUrl: QUrl());
246 QScopedPointer<QObject> object(component.create());
247 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
248 QVERIFY(dropArea);
249 dropArea->setParentItem(window.contentItem());
250
251 QQuickItem *dragItem = dropArea->findChild<QQuickItem *>(aName: "dragItem");
252 QVERIFY(dragItem);
253
254 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
255
256 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
257 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
258 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
259 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
260
261 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
262 evaluate<void>(scope: dropArea, expression: "keys = \"blue\"");
263 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "blue");
264 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "blue");
265 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
266 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
267 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
268 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
269 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
270
271 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
272 evaluate<void>(scope: dropArea, expression: "keys = \"red\"");
273 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red");
274 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red");
275 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
276 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
277 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
278 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
279 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
280
281 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
282 evaluate<void>(scope: dropArea, expression: "keys = \"green\"");
283 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "green");
284 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "green");
285 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
286 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
287 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
288 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
289
290 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
291 evaluate<void>(scope: dropArea, expression: "keys = [\"red\", \"green\"]");
292 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red" << "green");
293 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red" << "green");
294 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
295 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
296 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
297 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
298 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
299
300 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
301 evaluate<void>(scope: dragItem, expression: "Drag.keys = []");
302 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
303 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
304 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
305 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
306
307 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
308 evaluate<void>(scope: dropArea, expression: "keys = []");
309 QCOMPARE(dropArea->property("keys").toStringList(), QStringList());
310 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList());
311 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
312 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
313 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
314 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
315 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList());
316
317 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
318 evaluate<void>(scope: dropArea, expression: "keys = []");
319 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
320 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
321 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
322 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
323 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList());
324
325 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
326 evaluate<void>(scope: dragItem, expression: "Drag.keys = [\"red\", \"blue\"]");
327 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
328 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
329 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
330 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
331 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue");
332}
333
334void tst_QQuickDropArea::keys_external()
335{
336 QQuickWindow window;
337 QQmlComponent component(&engine);
338 component.setData(
339 "import QtQuick 2.0\n"
340 "DropArea {\n"
341 "property variant dragKeys\n"
342 "property variant dropKeys: keys\n"
343 "property int enterEvents: 0\n"
344 "width: 100; height: 100\n"
345 "onEntered: {++enterEvents; dragKeys = drag.keys }\n"
346 "}", baseUrl: QUrl());
347 QScopedPointer<QObject> object(component.create());
348 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
349 dropArea->setParentItem(window.contentItem());
350
351 QMimeData data;
352 QQuickWindow alternateWindow;
353
354 data.setData(mimetype: "text/x-red", data: "red");
355 data.setData(mimetype: "text/x-blue", data: "blue");
356
357 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
358
359 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
360 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
361 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
362 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
363 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
364
365 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
366 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
367 evaluate<void>(scope: dropArea, expression: "keys = \"text/x-blue\"");
368 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-blue");
369 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-blue");
370 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
371 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
372 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
373 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
374 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
375 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
376
377 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
378 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
379 evaluate<void>(scope: dropArea, expression: "keys = \"text/x-red\"");
380 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red");
381 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red");
382 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
383 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
384 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
385 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
386 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
387 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
388
389 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
390 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
391 evaluate<void>(scope: dropArea, expression: "keys = \"text/x-green\"");
392 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-green");
393 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-green");
394 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
395 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
396 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
397 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
398 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
399
400 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
401 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
402 evaluate<void>(scope: dropArea, expression: "keys = [\"text/x-red\", \"text/x-green\"]");
403 QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red" << "text/x-green");
404 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red" << "text/x-green");
405 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
406 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
407 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
408 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
409 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
410 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
411
412 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
413 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
414 data.removeFormat(mimetype: "text/x-red");
415 data.removeFormat(mimetype: "text/x-blue");
416 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
417 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
418 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
419 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), false);
420 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
421
422 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
423 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
424 evaluate<void>(scope: dropArea, expression: "keys = []");
425 QCOMPARE(dropArea->property("keys").toStringList(), QStringList());
426 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList());
427 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
428 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
429 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
430 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
431 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
432 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList());
433
434 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
435 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
436 data.setData(mimetype: "text/x-red", data: "red");
437 data.setData(mimetype: "text/x-blue", data: "blue");
438 QCOMPARE(dropArea->property("keys").toStringList(), QStringList());
439 QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList());
440 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; dragKeys = undefined }");
441 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
442 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
443 QCOMPARE(evaluate<bool>(dropArea, "containsDrag"), true);
444 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
445 QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue");
446
447 QWindowSystemInterface::handleDrop(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
448 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
449}
450
451void tst_QQuickDropArea::source_internal()
452{
453 QQuickWindow window;
454 QQmlComponent component(&engine);
455 component.setData(
456 "import QtQuick 2.0\n"
457 "DropArea {\n"
458 "property Item source: drag.source\n"
459 "property Item eventSource\n"
460 "width: 100; height: 100\n"
461 "onEntered: {eventSource = drag.source}\n"
462 "Item {\n"
463 "objectName: \"dragItem\"\n"
464 "x: 50; y: 50\n"
465 "width: 10; height: 10\n"
466 "}\n"
467 "Item { id: dragSource; objectName: \"dragSource\" }\n"
468 "}", baseUrl: QUrl());
469 QScopedPointer<QObject> object(component.create());
470 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
471 QVERIFY(dropArea);
472 dropArea->setParentItem(window.contentItem());
473
474 QQuickItem *dragItem = dropArea->findChild<QQuickItem *>(aName: "dragItem");
475 QVERIFY(dragItem);
476
477 QQuickItem *dragSource = dropArea->findChild<QQuickItem *>(aName: "dragSource");
478 QVERIFY(dragSource);
479
480 QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(nullptr));
481 QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(nullptr));
482
483 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
484 QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(dragItem));
485 QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(dragItem));
486 QCOMPARE(evaluate<QObject *>(dropArea, "eventSource"), static_cast<QObject *>(dragItem));
487
488 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
489 QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(nullptr));
490 QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(nullptr));
491
492
493 evaluate<void>(scope: dropArea, expression: "{ eventSource = null }");
494 evaluate<void>(scope: dragItem, expression: "Drag.source = dragSource");
495
496 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
497 QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(dragSource));
498 QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(dragSource));
499 QCOMPARE(evaluate<QObject *>(dropArea, "eventSource"), static_cast<QObject *>(dragSource));
500
501 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
502 QCOMPARE(evaluate<QObject *>(dropArea, "source"), static_cast<QObject *>(nullptr));
503 QCOMPARE(evaluate<QObject *>(dropArea, "drag.source"), static_cast<QObject *>(nullptr));
504}
505
506// Setting a source can't be emulated using the QWindowSystemInterface API.
507
508//void tst_QQuickDropArea::source_external()
509//{
510//}
511
512void tst_QQuickDropArea::position_internal()
513{
514 QQuickWindow window;
515 QQmlComponent component(&engine);
516 component.setData(
517 "import QtQuick 2.0\n"
518 "DropArea {\n"
519 "property real dragX: drag.x\n"
520 "property real dragY: drag.y\n"
521 "property real eventX\n"
522 "property real eventY\n"
523 "property int enterEvents: 0\n"
524 "property int moveEvents: 0\n"
525 "width: 100; height: 100\n"
526 "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n"
527 "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n"
528 "Item {\n"
529 "objectName: \"dragItem\"\n"
530 "x: 50; y: 50\n"
531 "width: 10; height: 10\n"
532 "}\n"
533 "}", baseUrl: QUrl());
534 QScopedPointer<QObject> object(component.create());
535 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
536 QVERIFY(dropArea);
537 dropArea->setParentItem(window.contentItem());
538
539 QQuickItem *dragItem = dropArea->findChild<QQuickItem *>(aName: "dragItem");
540 QVERIFY(dragItem);
541
542 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
543 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
544 QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 0);
545 QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50));
546 QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
547 QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(50));
548 QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
549 QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(50));
550 QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
551
552 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
553 dragItem->setPosition(QPointF(40, 50));
554 QCoreApplication::processEvents();
555 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
556 QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
557 QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40));
558 QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
559 QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(40));
560 QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
561 QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(40));
562 QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
563
564 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
565 dragItem->setPosition(QPointF(75, 25));
566 QCoreApplication::processEvents();
567 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
568 QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
569 QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75));
570 QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(25));
571 QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(75));
572 QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(25));
573 QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75));
574 QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25));
575
576 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
577}
578
579void tst_QQuickDropArea::position_external()
580{
581 QQuickWindow window;
582 QQmlComponent component(&engine);
583 component.setData(
584 "import QtQuick 2.0\n"
585 "DropArea {\n"
586 "property real dragX: drag.x\n"
587 "property real dragY: drag.y\n"
588 "property real eventX\n"
589 "property real eventY\n"
590 "property int enterEvents: 0\n"
591 "property int moveEvents: 0\n"
592 "width: 100; height: 100\n"
593 "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n"
594 "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n"
595 "}", baseUrl: QUrl());
596 QScopedPointer<QObject> object(component.create());
597 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
598 QVERIFY(dropArea);
599 dropArea->setParentItem(window.contentItem());
600
601 QMimeData data;
602
603 const qreal dpr = window.devicePixelRatio();
604 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50) * dpr, supportedActions: Qt::CopyAction,
605 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
606 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 1);
607 QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
608 QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(50));
609 QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
610 QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(50));
611 QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
612 QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(50));
613 QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
614
615 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
616 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(40, 50) * dpr, supportedActions: Qt::CopyAction,
617 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
618 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
619 QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
620 QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(40));
621 QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(50));
622 QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(40));
623 QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(50));
624 QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(40));
625 QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(50));
626
627 evaluate<void>(scope: dropArea, expression: "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }");
628 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(75, 25) * dpr, supportedActions: Qt::CopyAction,
629 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
630 QCOMPARE(evaluate<int>(dropArea, "enterEvents"), 0);
631 QCOMPARE(evaluate<int>(dropArea, "moveEvents"), 1);
632 QCOMPARE(evaluate<qreal>(dropArea, "drag.x"), qreal(75));
633 QCOMPARE(evaluate<qreal>(dropArea, "drag.y"), qreal(25));
634 QCOMPARE(evaluate<qreal>(dropArea, "dragX"), qreal(75));
635 QCOMPARE(evaluate<qreal>(dropArea, "dragY"), qreal(25));
636 QCOMPARE(evaluate<qreal>(dropArea, "eventX"), qreal(75));
637 QCOMPARE(evaluate<qreal>(dropArea, "eventY"), qreal(25));
638
639 QWindowSystemInterface::handleDrop(window: &window, dropData: &data, p: QPoint(75, 25) * dpr, supportedActions: Qt::CopyAction,
640 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
641}
642
643void tst_QQuickDropArea::drop_internal()
644{
645 QQuickWindow window;
646 QQmlComponent component(&engine);
647 component.setData(
648 "import QtQuick 2.0\n"
649 "DropArea {\n"
650 "property bool accept: false\n"
651 "property bool setAccepted: false\n"
652 "property bool acceptDropAction: false\n"
653 "property bool setDropAction: false\n"
654 "property int dropAction: Qt.IgnoreAction\n"
655 "property int proposedAction: Qt.IgnoreAction\n"
656 "property int supportedActions: Qt.IgnoreAction\n"
657 "property int dropEvents: 0\n"
658 "width: 100; height: 100\n"
659 "onDropped: {\n"
660 "++dropEvents\n"
661 "supportedActions = drop.supportedActions\n"
662 "proposedAction = drop.action\n"
663 "if (setDropAction)\n"
664 "drop.action = dropAction\n"
665 "if (acceptDropAction)\n"
666 "drop.accept(dropAction)\n"
667 "else if (setAccepted)\n"
668 "drop.accepted = accept\n"
669 "else if (accept)\n"
670 "drop.accept()\n"
671 "}\n"
672 "Item {\n"
673 "objectName: \"dragItem\"\n"
674 "x: 50; y: 50\n"
675 "width: 10; height: 10\n"
676 "}\n"
677 "}", baseUrl: QUrl());
678 QScopedPointer<QObject> object(component.create());
679 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
680 QVERIFY(dropArea);
681 dropArea->setParentItem(window.contentItem());
682
683 QQuickItem *dragItem = dropArea->findChild<QQuickItem *>(aName: "dragItem");
684 QVERIFY(dragItem);
685
686 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
687 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::IgnoreAction));
688 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
689 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
690 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
691
692 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
693 evaluate<void>(scope: dropArea, expression: "{ accept = true; setDropAction = true; dropAction = Qt.LinkAction }");
694 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
695 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
696 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
697 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
698 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
699
700 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
701 evaluate<void>(scope: dropArea, expression: "{ setAccepted = true; }");
702 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
703 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
704 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
705 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
706 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
707
708 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
709 evaluate<void>(scope: dropArea, expression: "{ accept = false; setAccepted = true; }");
710 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
711 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::IgnoreAction));
712 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
713 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
714 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
715
716 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
717 evaluate<void>(scope: dropArea, expression: "{ setAccepted = false; setDropAction = false; acceptDropAction = true; }");
718 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
719 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
720 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
721 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
722 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
723
724 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
725 evaluate<void>(scope: dropArea, expression: "{ acceptDropAction = false; dropAction = Qt.IgnoreAction; accept = true }");
726 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
727 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
728 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
729 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
730 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
731
732 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
733 evaluate<void>(scope: dropArea, expression: "{ setAccepted = true }");
734 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
735 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
736 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
737 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction));
738 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
739
740 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
741 evaluate<void>(scope: dropArea, expression: "{ setAccepted = false }");
742 evaluate<void>(scope: dragItem, expression: "Drag.supportedActions = Qt.LinkAction");
743 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
744 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
745 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
746 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
747 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
748
749 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
750 evaluate<void>(scope: dropArea, expression: "{ setAccepted = true }");
751 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
752 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::MoveAction));
753 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
754 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
755 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::MoveAction));
756
757 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
758 evaluate<void>(scope: dropArea, expression: "{ setAccepted = false }");
759 evaluate<void>(scope: dragItem, expression: "Drag.proposedAction = Qt.LinkAction");
760 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
761 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
762 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
763 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
764 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::LinkAction));
765
766 evaluate<void>(scope: dropArea, expression: "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }");
767 evaluate<void>(scope: dropArea, expression: "{ setAccepted = true }");
768 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
769 QCOMPARE(evaluate<int>(dragItem, "Drag.drop()"), int(Qt::LinkAction));
770 QCOMPARE(evaluate<int>(dropArea, "dropEvents"), 1);
771 QCOMPARE(evaluate<int>(dropArea, "supportedActions"), int(Qt::LinkAction));
772 QCOMPARE(evaluate<int>(dropArea, "proposedAction"), int(Qt::LinkAction));
773}
774
775// Setting the supportedActions can't be emulated using the QWindowSystemInterface API.
776
777//void tst_QQuickDropArea::drop_external()
778//{
779//}
780
781void tst_QQuickDropArea::competingDrags()
782{
783 QQuickWindow window;
784 QQmlComponent component(&engine);
785 component.setData(
786 "import QtQuick 2.0\n"
787 "DropArea {\n"
788 "width: 100; height: 100\n"
789 "objectName: \"dropArea1\"\n"
790 "property string statuslol\n"
791 "onEntered: { statuslol = 'parent' }\n"
792 "DropArea {\n"
793 "objectName: \"dropArea2\"\n"
794 "width: 100; height: 100\n"
795 "property bool acceptsEnters: true\n"
796 "onEntered: { parent.statuslol = 'son'; drag.accepted = acceptsEnters; }\n"
797 "}\n"
798 "Item {\n"
799 "objectName: \"dragItem\"\n"
800 "x: 50; y: 50\n"
801 "width: 10; height: 10\n"
802 "}\n"
803 "}\n", baseUrl: QUrl());
804
805 QScopedPointer<QObject> object(component.create());
806 QQuickItem *dropArea1 = qobject_cast<QQuickItem *>(object: object.data());
807 QVERIFY(dropArea1);
808 dropArea1->setParentItem(window.contentItem());
809
810 QQuickItem *dropArea2 = dropArea1->findChild<QQuickItem *>(aName: "dropArea2");
811 QVERIFY(dropArea2);
812
813 QQuickItem *dragItem = dropArea1->findChild<QQuickItem *>(aName: "dragItem");
814 QVERIFY(dragItem);
815
816 QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral(""));
817 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
818 QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral("son"));
819 evaluate<void>(scope: dragItem, expression: "Drag.active = false");
820 evaluate<void>(scope: dropArea2, expression: "acceptsEnters = false");
821 evaluate<void>(scope: dragItem, expression: "Drag.active = true");
822 QCOMPARE(evaluate<QString>(dropArea1, "statuslol"), QStringLiteral("parent"));
823}
824
825void tst_QQuickDropArea::simultaneousDrags()
826{
827 QQuickWindow window;
828 QQmlComponent component(&engine);
829 component.setData(
830 "import QtQuick 2.0\n"
831 "DropArea {\n"
832 "property int enterEvents: 0\n"
833 "property int exitEvents: 0\n"
834 "width: 100; height: 100\n"
835 "objectName: \"dropArea1\"\n"
836 "keys: [\"red\", \"text/x-red\"]\n"
837 "onEntered: {++enterEvents}\n"
838 "onExited: {++exitEvents}\n"
839 "DropArea {\n"
840 "objectName: \"dropArea2\"\n"
841 "property int enterEvents: 0\n"
842 "property int exitEvents: 0\n"
843 "width: 100; height: 100\n"
844 "keys: [\"blue\", \"text/x-blue\"]\n"
845 "onEntered: {++enterEvents}\n"
846 "onExited: {++exitEvents}\n"
847 "}\n"
848 "Item {\n"
849 "objectName: \"dragItem1\"\n"
850 "x: 50; y: 50\n"
851 "width: 10; height: 10\n"
852 "Drag.keys: [\"red\", \"blue\"]"
853 "}\n"
854 "Item {\n"
855 "objectName: \"dragItem2\"\n"
856 "x: 50; y: 50\n"
857 "width: 10; height: 10\n"
858 "Drag.keys: [\"red\", \"blue\"]"
859 "}\n"
860 "}", baseUrl: QUrl());
861
862 QScopedPointer<QObject> object(component.create());
863 QQuickItem *dropArea1 = qobject_cast<QQuickItem *>(object: object.data());
864 QVERIFY(dropArea1);
865 dropArea1->setParentItem(window.contentItem());
866
867 QQuickItem *dropArea2 = dropArea1->findChild<QQuickItem *>(aName: "dropArea2");
868 QVERIFY(dropArea2);
869
870 QQuickItem *dragItem1 = dropArea1->findChild<QQuickItem *>(aName: "dragItem1");
871 QVERIFY(dragItem1);
872
873 QQuickItem *dragItem2 = dropArea1->findChild<QQuickItem *>(aName: "dragItem2");
874 QVERIFY(dragItem2);
875
876 QMimeData data;
877 data.setData(mimetype: "text/x-red", data: "red");
878 data.setData(mimetype: "text/x-blue", data: "blue");
879
880 QQuickWindow alternateWindow;
881
882 // Mixed internal drags.
883 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
884 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
885 evaluate<void>(scope: dragItem1, expression: "Drag.active = true");
886 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
887 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
888 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
889 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
890 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
891 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
892
893 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
894 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
895 evaluate<void>(scope: dragItem2, expression: "Drag.active = true");
896 //DropArea discards events if already contains something being dragged in
897 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
898 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
899 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
900 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
901 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
902 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
903
904 evaluate<void>(scope: dragItem2, expression: "Drag.active = false");
905 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
906 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
907 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
908 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
909 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
910 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
911
912 evaluate<void>(scope: dragItem2, expression: "Drag.active = true");
913 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
914 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
915 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
916 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
917 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
918 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
919
920 evaluate<void>(scope: dragItem1, expression: "Drag.active = false");
921 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
922 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
923 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
924 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
925 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
926 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
927
928 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
929 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
930 evaluate<void>(scope: dragItem2, expression: "Drag.active = false");
931 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
932 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
933 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
934 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
935 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
936 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
937
938 // internal then external.
939 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
940 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
941 evaluate<void>(scope: dragItem1, expression: "Drag.active = true");
942 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
943 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
944 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
945 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
946 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
947 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
948
949 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
950 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
951 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
952 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
953 //Same as in the first case, dropArea2 already contains a drag, dropArea1 will get the event
954 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
955 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
956 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
957 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
958 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
959 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
960
961 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
962 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
963 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
964 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
965 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
966 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
967 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
968 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
969
970 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
971 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
972 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
973 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
974 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
975 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
976 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
977 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
978
979 evaluate<void>(scope: dragItem1, expression: "Drag.active = false");
980 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
981 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
982 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
983 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
984 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
985 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
986
987 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
988 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
989 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
990 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
991 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
992 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
993 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
994 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
995 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
996 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
997
998 // external then internal.
999 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1000 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1001 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1002 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1003 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1004 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1005 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1006 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1007 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
1008 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1009
1010 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1011 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1012 evaluate<void>(scope: dragItem2, expression: "Drag.active = true");
1013 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1014 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
1015 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1016 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1017 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1018 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1019
1020 evaluate<void>(scope: dragItem2, expression: "Drag.active = false");
1021 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1022 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
1023 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
1024 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1025 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1026 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1027
1028 evaluate<void>(scope: dragItem2, expression: "Drag.active = true");
1029 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1030 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
1031 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
1032 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1033 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1034 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1035
1036 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1037 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1038 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1039 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 2);
1040 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
1041 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1042 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1043 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
1044
1045 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1046 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1047 evaluate<void>(scope: dragItem2, expression: "Drag.active = false");
1048 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1049 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1050 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
1051 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1052 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1053 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1054
1055 // Different acceptance
1056 evaluate<void>(scope: dragItem1, expression: "Drag.keys = \"red\"");
1057 evaluate<void>(scope: dragItem2, expression: "Drag.keys = \"blue\"");
1058 data.removeFormat(mimetype: "text/x-red");
1059
1060 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1061 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1062 evaluate<void>(scope: dragItem1, expression: "Drag.active = true");
1063 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1064 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
1065 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1066 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1067 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1068 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1069
1070 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1071 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1072 evaluate<void>(scope: dragItem2, expression: "Drag.active = true");
1073 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1074 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1075 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1076 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1077 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
1078 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1079
1080 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1081 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1082 evaluate<void>(scope: dragItem2, expression: "Drag.active = false");
1083 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1084 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1085 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1086 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1087 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1088 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
1089
1090 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1091 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1092 evaluate<void>(scope: dragItem2, expression: "Drag.active = true");
1093 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1094 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1095 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1096 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1097 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
1098 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1099
1100 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1101 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1102 evaluate<void>(scope: dragItem1, expression: "Drag.active = false");
1103 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1104 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1105 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
1106 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1107 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1108 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1109
1110 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1111 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1112 evaluate<void>(scope: dragItem2, expression: "Drag.active = false");
1113 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1114 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1115 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1116 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1117 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1118 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
1119
1120 // internal then external
1121 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1122 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1123 evaluate<void>(scope: dragItem1, expression: "Drag.active = true");
1124 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1125 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 1);
1126 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1127 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1128 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1129 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1130
1131 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1132 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1133 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1134 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1135 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1136 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1137 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1138 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1139 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
1140 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1141
1142 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1143 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1144 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1145 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1146 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1147 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1148 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1149 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1150 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1151 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
1152
1153 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1154 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1155 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1156 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1157 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), true);
1158 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1159 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1160 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1161 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 1);
1162 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1163
1164 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1165 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1166 evaluate<void>(scope: dragItem1, expression: "Drag.active = false");
1167 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1168 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1169 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 1);
1170 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), true);
1171 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1172 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 0);
1173
1174 evaluate<void>(scope: dropArea1, expression: "{ enterEvents = 0; exitEvents = 0 }");
1175 evaluate<void>(scope: dropArea2, expression: "{ enterEvents = 0; exitEvents = 0 }");
1176 QWindowSystemInterface::handleDrag(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1177 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1178 QCOMPARE(evaluate<bool>(dropArea1, "containsDrag"), false);
1179 QCOMPARE(evaluate<int>(dropArea1, "enterEvents"), 0);
1180 QCOMPARE(evaluate<int>(dropArea1, "exitEvents"), 0);
1181 QCOMPARE(evaluate<bool>(dropArea2, "containsDrag"), false);
1182 QCOMPARE(evaluate<int>(dropArea2, "enterEvents"), 0);
1183 QCOMPARE(evaluate<int>(dropArea2, "exitEvents"), 1);
1184
1185 QWindowSystemInterface::handleDrop(window: &alternateWindow, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1186 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1187}
1188
1189void tst_QQuickDropArea::dropStuff()
1190{
1191 QQuickWindow window;
1192 QQmlComponent component(&engine);
1193 component.setData(
1194 "import QtQuick 2.3\n"
1195 "DropArea {\n"
1196 "width: 100; height: 100\n"
1197 "property var array\n"
1198 "onDropped: { array = drop.getDataAsArrayBuffer('text/x-red'); }\n"
1199 "}", baseUrl: QUrl());
1200
1201 QScopedPointer<QObject> object(component.create());
1202 QQuickItem *dropArea = qobject_cast<QQuickItem *>(object: object.data());
1203 QVERIFY(dropArea);
1204 dropArea->setParentItem(window.contentItem());
1205
1206 QMimeData data;
1207 data.setData(mimetype: "text/x-red", data: "red");
1208
1209 QCOMPARE(evaluate<QVariant>(dropArea, "array"), QVariant());
1210
1211 QWindowSystemInterface::handleDrag(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1212 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1213 QWindowSystemInterface::handleDrop(window: &window, dropData: &data, p: QPoint(50, 50), supportedActions: Qt::CopyAction,
1214 buttons: Qt::MouseButtons(), modifiers: Qt::KeyboardModifiers());
1215 QCOMPARE(evaluate<int>(dropArea, "array.byteLength"), 3);
1216 QCOMPARE(evaluate<QByteArray>(dropArea, "array"), QByteArray("red"));
1217}
1218
1219void tst_QQuickDropArea::nestedDropAreas_data()
1220{
1221 QTest::addColumn<QString>(name: "qmlFile");
1222
1223 QTest::newRow(dataTag: "dropRectDropRect") << "nested1.qml";
1224 QTest::newRow(dataTag: "rectDropRectDrop") << "nested2.qml";
1225}
1226
1227void tst_QQuickDropArea::nestedDropAreas()
1228{
1229 QFETCH(QString, qmlFile);
1230
1231 const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
1232 QQuickView window;
1233 QByteArray errorMessage;
1234 QVERIFY2(QQuickTest::initView(window, testFileUrl(qmlFile.toLatin1().data()), true, &errorMessage), errorMessage.constData());
1235
1236 window.show();
1237 QVERIFY(QTest::qWaitForWindowExposed(&window));
1238 QVERIFY(window.rootObject() != nullptr);
1239
1240 QQuickItem *dragArea = window.rootObject()->findChild<QQuickItem*>(aName: "dragArea");
1241 QVERIFY(dragArea);
1242 QQuickItem *outerDropArea = window.rootObject()->findChild<QQuickItem*>(aName: "outerDropArea");
1243 QVERIFY(outerDropArea);
1244 QQuickItem *innerDropArea = window.rootObject()->findChild<QQuickItem*>(aName: "innerDropArea");
1245 QVERIFY(innerDropArea);
1246
1247 QPoint p = QPoint(10,10);
1248 QTest::mousePress(window: &window, button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p);
1249
1250 // move the minimum distance to activate drag
1251 p += QPoint(dragThreshold + 1, dragThreshold + 1);
1252 QTest::mouseMove(window: &window, pos: p);
1253
1254 // drag the red rectangle into the inner DropArea
1255 p += QPoint(100, 100);
1256 QTest::mouseMove(window: &window, pos: p);
1257 QCOMPARE(window.rootObject()->property("outerEnterEvents"), 0);
1258 QCOMPARE(window.rootObject()->property("outerExitEvents"), 0);
1259 QCOMPARE(window.rootObject()->property("innerEnterEvents"), 1);
1260 QCOMPARE(window.rootObject()->property("innerExitEvents"), 0);
1261
1262 // drag the red rectangle into the outer DropArea
1263 p += QPoint(0, 50);
1264 QTest::mouseMove(window: &window, pos: p);
1265 QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
1266 QCOMPARE(window.rootObject()->property("outerExitEvents"), 0);
1267 QCOMPARE(window.rootObject()->property("innerEnterEvents"), 1);
1268 QCOMPARE(window.rootObject()->property("innerExitEvents"), 1);
1269
1270 // drag the red rectangle into the inner DropArea
1271 p -= QPoint(0, 50);
1272 QTest::mouseMove(window: &window, pos: p);
1273 QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
1274 QCOMPARE(window.rootObject()->property("outerExitEvents"), 1);
1275 QCOMPARE(window.rootObject()->property("innerEnterEvents"), 2);
1276 QCOMPARE(window.rootObject()->property("innerExitEvents"), 1);
1277
1278 // drag the red rectangle back out of both
1279 p -= QPoint(100, 100);
1280 QTest::mouseMove(window: &window, pos: p);
1281 QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
1282 QCOMPARE(window.rootObject()->property("outerExitEvents"), 1);
1283 QCOMPARE(window.rootObject()->property("innerEnterEvents"), 2);
1284 QCOMPARE(window.rootObject()->property("innerExitEvents"), 2);
1285}
1286
1287QTEST_MAIN(tst_QQuickDropArea)
1288
1289#include "tst_qquickdroparea.moc"
1290

source code of qtdeclarative/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp