Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickdroparea.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:interprocess-communication
4
6#include "qquickdrag_p.h"
7#include "qquickitem_p.h"
8
9#include <private/qv4arraybuffer_p.h>
10
11#include <QtCore/qpointer.h>
12#include <QtCore/qregularexpression.h>
13
15
16QQuickDropAreaDrag::QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent)
18 , d(d)
19{
20}
21
25
27{
28 Q_DECLARE_PUBLIC(QQuickDropArea)
29
30public:
33
34 bool hasMatchingKey(const QStringList &keys) const;
35
36 QStringList getKeys(const QMimeData *mimeData) const;
37
44};
45
46QQuickDropAreaPrivate::QQuickDropAreaPrivate()
47 : drag(nullptr)
48 , containsDrag(false)
49{
50}
51
56
57/*!
58 \qmltype DropArea
59 \nativetype QQuickDropArea
60 \inherits Item
61 \inqmlmodule QtQuick
62 \ingroup qtquick-input
63 \brief For specifying drag and drop handling in an area.
64
65 A DropArea is an invisible item which receives events when other items are
66 dragged over it.
67
68 The \l Drag attached property can be used to notify the DropArea when an Item is
69 dragged over it.
70
71 The \l keys property can be used to filter drag events which don't include
72 a matching key.
73
74 The \l drag.source property is communicated to the source of a drag event as
75 the recipient of a drop on the drag target.
76
77 \sa {Qt Quick Examples - Drag and Drop}
78*/
79
80QQuickDropArea::QQuickDropArea(QQuickItem *parent)
81 : QQuickItem(*new QQuickDropAreaPrivate, parent)
82{
83 setFlags(ItemAcceptsDrops);
84}
85
86QQuickDropArea::~QQuickDropArea()
87{
88}
89
90/*!
91 \qmlproperty bool QtQuick::DropArea::containsDrag
92
93 This property identifies whether the DropArea currently contains any
94 dragged items.
95*/
96
97bool QQuickDropArea::containsDrag() const
98{
99 Q_D(const QQuickDropArea);
100 return d->containsDrag;
101}
102
103/*!
104 \qmlproperty stringlist QtQuick::DropArea::keys
105
106 This property holds a list of drag keys a DropArea will accept.
107
108 If no keys are listed the DropArea will accept events from any drag source,
109 otherwise the drag source must have at least one compatible key.
110
111 \sa QtQuick::Drag::keys
112*/
113
114QStringList QQuickDropArea::keys() const
115{
116 Q_D(const QQuickDropArea);
117 return d->keys;
118}
119
120void QQuickDropArea::setKeys(const QStringList &keys)
121{
122 Q_D(QQuickDropArea);
123 if (d->keys != keys) {
124 d->keys = keys;
125
126 if (keys.isEmpty()) {
127 d->keyRegExp = QRegularExpression();
128 } else {
129 QString pattern = QLatin1Char('(') + QRegularExpression::escape(keys.first());
130 for (int i = 1; i < keys.size(); ++i)
131 pattern += QLatin1Char('|') + QRegularExpression::escape(keys.at(i));
132 pattern += QLatin1Char(')');
133 d->keyRegExp = QRegularExpression(
134 QRegularExpression::anchoredPattern(pattern.replace(QLatin1String("\\*"),
135 QLatin1String(".+"))));
136 }
137 emit keysChanged();
138 }
139}
140
141QQuickDropAreaDrag *QQuickDropArea::drag()
142{
143 Q_D(QQuickDropArea);
144 if (!d->drag)
145 d->drag = new QQuickDropAreaDrag(d);
146 return d->drag;
147}
148
149/*!
150 \qmlproperty QtObject QtQuick::DropArea::drag.source
151
152 This property holds the source of a drag.
153*/
154
156{
157 return d->source;
158}
159
160/*!
161 \qmlpropertygroup QtQuick::DropArea::drag
162 \qmlproperty real QtQuick::DropArea::drag.x
163 \qmlproperty real QtQuick::DropArea::drag.y
164
165 These properties hold the coordinates of the last drag event.
166*/
167
169{
170 return d->dragPosition.x();
171}
172
174{
175 return d->dragPosition.y();
176}
177
178/*!
179 \qmlsignal QtQuick::DropArea::positionChanged(DragEvent drag)
180
181 This signal is emitted when the position of a \a drag has changed.
182*/
183
184void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
185{
186 Q_D(QQuickDropArea);
187 if (!d->containsDrag)
188 return;
189
190 d->dragPosition = event->position().toPoint();
191 if (d->drag)
192 emit d->drag->positionChanged();
193
194 event->accept();
195 QQuickDragEvent dragTargetEvent(d, event);
196 emit positionChanged(&dragTargetEvent);
197}
198
199bool QQuickDropAreaPrivate::hasMatchingKey(const QStringList &keys) const
200{
201 if (keyRegExp.pattern().isEmpty())
202 return true;
203
204 for (const QString &key : keys) {
205 if (key.contains(keyRegExp))
206 return true;
207 }
208 return false;
209}
210
211QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
212{
213 if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(mimeData))
214 return dragMime->keys();
215 return mimeData->formats();
216}
217
218/*!
219 \qmlsignal QtQuick::DropArea::entered(DragEvent drag)
220
221 This signal is emitted when a \a drag enters the bounds of a DropArea.
222*/
223
224void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
225{
226 Q_D(QQuickDropArea);
227 const QMimeData *mimeData = event->mimeData();
228 if (!d->effectiveEnable || d->containsDrag || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData)))
229 return;
230
231 const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(mimeData);
232 auto dragSource = dragMime ? dragMime->source() : event->source();
233
234 // if the source of the drag is an ancestor of the drop area, then dragging
235 // also drags the drop area; see QTBUG-64128
236 if (QQuickItem *dragSourceItem = qobject_cast<QQuickItem *>(dragSource)) {
237 if (dragSourceItem->isAncestorOf(this))
238 return;
239 }
240
241 d->dragPosition = event->position().toPoint();
242
243 event->accept();
244
245 QQuickDragEvent dragTargetEvent(d, event);
246 emit entered(&dragTargetEvent);
247 if (!event->isAccepted())
248 return;
249
250 d->containsDrag = true;
251 d->source = dragSource;
252 d->dragPosition = event->position().toPoint();
253 if (d->drag) {
254 emit d->drag->positionChanged();
255 emit d->drag->sourceChanged();
256 }
257 emit containsDragChanged();
258}
259
260/*!
261 \qmlsignal QtQuick::DropArea::exited()
262
263 This signal is emitted when a drag exits the bounds of a DropArea.
264*/
265
266void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
267{
268 Q_D(QQuickDropArea);
269 if (!d->containsDrag)
270 return;
271
272 emit exited();
273
274 d->containsDrag = false;
275 d->source = nullptr;
276 emit containsDragChanged();
277 if (d->drag)
278 emit d->drag->sourceChanged();
279}
280
281/*!
282 \qmlsignal QtQuick::DropArea::dropped(DragEvent drop)
283
284 This signal is emitted when a \a drop event occurs within the bounds of
285 a DropArea.
286*/
287
288void QQuickDropArea::dropEvent(QDropEvent *event)
289{
290 Q_D(QQuickDropArea);
291 if (!d->containsDrag)
292 return;
293
294 QQuickDragEvent dragTargetEvent(d, event);
295 emit dropped(&dragTargetEvent);
296
297 d->containsDrag = false;
298 d->source = nullptr;
299 emit containsDragChanged();
300 if (d->drag)
301 emit d->drag->sourceChanged();
302}
303
304/*!
305 \qmltype DragEvent
306 \nativetype QQuickDragEvent
307 \inqmlmodule QtQuick
308 \ingroup qtquick-input-events
309 \brief Provides information about a drag event.
310
311 The position of the drag event can be obtained from the \l x and \l y
312 properties, and the \l keys property identifies the drag keys of the event
313 \l {drag.source}{source}.
314
315 The existence of specific drag types can be determined using the \l hasColor,
316 \l hasHtml, \l hasText, and \l hasUrls properties.
317
318 The list of all supplied formats can be determined using the \l formats property.
319
320 Specific drag types can be obtained using the \l colorData, \l html, \l text,
321 and \l urls properties.
322
323 A string version of any available mimeType can be obtained using \l getDataAsString.
324*/
325
326/*!
327 \qmlproperty real QtQuick::DragEvent::x
328
329 This property holds the x coordinate of a drag event.
330*/
331
332/*!
333 \qmlproperty real QtQuick::DragEvent::y
334
335 This property holds the y coordinate of a drag event.
336*/
337
338/*!
339 \qmlproperty QtObject QtQuick::DragEvent::drag.source
340
341 This property holds the source of a drag event.
342*/
343
344/*!
345 \qmlproperty stringlist QtQuick::DragEvent::keys
346
347 This property holds a list of keys identifying the data type or source of a
348 drag event.
349*/
350
351/*!
352 \qmlproperty enumeration QtQuick::DragEvent::action
353
354 This property holds the action that the \l {drag.source}{source} is to perform on an accepted drop.
355
356 The drop action may be one of:
357
358 \value Qt.CopyAction Copy the data to the target.
359 \value Qt.MoveAction Move the data from the source to the target.
360 \value Qt.LinkAction Create a link from the source to the target.
361 \value Qt.IgnoreAction Ignore the action (do nothing with the data).
362*/
363
364/*!
365 \qmlproperty flags QtQuick::DragEvent::supportedActions
366
367 This property holds the set of \l {action}{actions} supported by the
368 drag source.
369*/
370
371/*!
372 \qmlproperty flags QtQuick::DragEvent::proposedAction
373 \since 5.2
374
375 This property holds the set of \l {action}{actions} proposed by the
376 drag source.
377*/
378
379/*!
380 \qmlproperty bool QtQuick::DragEvent::accepted
381
382 This property holds whether the drag event was accepted by a handler.
383
384 The default value is true.
385*/
386
387/*!
388 \qmlmethod QtQuick::DragEvent::accept()
389 \qmlmethod QtQuick::DragEvent::accept(enumeration action)
390
391 Accepts the drag event.
392
393 If an \a action is specified it will overwrite the value of the \l action property.
394*/
395
396/*!
397 \qmlmethod QtQuick::DragEvent::acceptProposedAction()
398 \since 5.2
399
400 Accepts the drag event with the \l proposedAction.
401*/
402
403/*!
404 \qmlproperty bool QtQuick::DragEvent::hasColor
405 \since 5.2
406
407 This property holds whether the drag event contains a color item.
408*/
409
410/*!
411 \qmlproperty bool QtQuick::DragEvent::hasHtml
412 \since 5.2
413
414 This property holds whether the drag event contains a html item.
415*/
416
417/*!
418 \qmlproperty bool QtQuick::DragEvent::hasText
419 \since 5.2
420
421 This property holds whether the drag event contains a text item.
422*/
423
424/*!
425 \qmlproperty bool QtQuick::DragEvent::hasUrls
426 \since 5.2
427
428 This property holds whether the drag event contains one or more url items.
429*/
430
431/*!
432 \qmlproperty color QtQuick::DragEvent::colorData
433 \since 5.2
434
435 This property holds color data, if any.
436*/
437
438/*!
439 \qmlproperty string QtQuick::DragEvent::html
440 \since 5.2
441
442 This property holds html data, if any.
443*/
444
445/*!
446 \qmlproperty string QtQuick::DragEvent::text
447 \since 5.2
448
449 This property holds text data, if any.
450*/
451
452/*!
453 \qmlproperty urllist QtQuick::DragEvent::urls
454 \since 5.2
455
456 This property holds a list of urls, if any.
457*/
458
459/*!
460 \qmlproperty stringlist QtQuick::DragEvent::formats
461 \since 5.2
462
463 This property holds a list of mime type formats contained in the drag data.
464*/
465
466/*!
467 \qmlmethod string QtQuick::DragEvent::getDataAsString(string format)
468 \since 5.2
469
470 Returns the data for the given \a format converted to a string. \a format should be one contained in the \l formats property.
471*/
472
473/*!
474 \qmlmethod string QtQuick::DragEvent::getDataAsArrayBuffer(string format)
475 \since 5.5
476
477 Returns the data for the given \a format into an ArrayBuffer, which can
478 easily be translated into a QByteArray. \a format should be one contained in the \l formats property.
479*/
480
481QObject *QQuickDragEvent::source() const
482{
483 if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(event->mimeData()))
484 return dragMime->source();
485 else
486 return event->source();
487}
488
489QStringList QQuickDragEvent::keys() const
490{
491 return d->getKeys(event->mimeData());
492}
493
494bool QQuickDragEvent::hasColor() const
495{
496 return event->mimeData()->hasColor();
497}
498
499bool QQuickDragEvent::hasHtml() const
500{
501 return event->mimeData()->hasHtml();
502}
503
504bool QQuickDragEvent::hasText() const
505{
506 return event->mimeData()->hasText();
507}
508
509bool QQuickDragEvent::hasUrls() const
510{
511 return event->mimeData()->hasUrls();
512}
513
514QVariant QQuickDragEvent::colorData() const
515{
516 return event->mimeData()->colorData();
517}
518
519QString QQuickDragEvent::html() const
520{
521 return event->mimeData()->html();
522}
523
524QString QQuickDragEvent::text() const
525{
526 return event->mimeData()->text();
527}
528
529QList<QUrl> QQuickDragEvent::urls() const
530{
531 return event->mimeData()->urls();
532}
533
534QStringList QQuickDragEvent::formats() const
535{
536 return event->mimeData()->formats();
537}
538
539QString QQuickDragEvent::getDataAsString(const QString &format) const
540{
541 return QString::fromUtf8(event->mimeData()->data(format));
542}
543
544QByteArray QQuickDragEvent::getDataAsArrayBuffer(const QString &format) const
545{
546 return event->mimeData()->data(format);
547}
548
549void QQuickDragEvent::acceptProposedAction()
550{
551 event->acceptProposedAction();
552}
553
554void QQuickDragEvent::accept()
555{
556 Qt::DropAction action = event->dropAction();
557 event->setDropAction(action);
558 event->accept();
559}
560
561void QQuickDragEvent::accept(Qt::DropAction action)
562{
563 // get action from arguments.
564 event->setDropAction(action);
565 event->accept();
566}
567
568
569QT_END_NAMESPACE
570
571#include "moc_qquickdroparea_p.cpp"
QObject * parent
Definition qobject.h:73
qreal x() const
\qmlpropertygroup QtQuick::DropArea::drag \qmlproperty real QtQuick::DropArea::drag....
QObject * source() const
\qmlproperty QtObject QtQuick::DropArea::drag.source
QPointer< QObject > source
QStringList getKeys(const QMimeData *mimeData) const
QRegularExpression keyRegExp
bool hasMatchingKey(const QStringList &keys) const
QQuickDropAreaDrag * drag