QQuickCanvas renames
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickdroparea.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickdroparea_p.h"
43 #include "qquickdrag_p.h"
44 #include "qquickitem_p.h"
45 #include "qquickwindow.h"
46
47 #include <private/qqmlengine_p.h>
48
49 #ifndef QT_NO_DRAGANDDROP
50
51 QT_BEGIN_NAMESPACE
52
53 QQuickDropAreaDrag::QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent)
54     : QObject(parent)
55     , d(d)
56 {
57 }
58
59 QQuickDropAreaDrag::~QQuickDropAreaDrag()
60 {
61 }
62
63 class QQuickDropAreaPrivate : public QQuickItemPrivate
64 {
65     Q_DECLARE_PUBLIC(QQuickDropArea)
66
67 public:
68     QQuickDropAreaPrivate();
69     ~QQuickDropAreaPrivate();
70
71     bool hasMatchingKey(const QStringList &keys) const;
72
73     QStringList getKeys(const QMimeData *mimeData) const;
74
75     QStringList keys;
76     QRegExp keyRegExp;
77     QPointF dragPosition;
78     QQuickDropAreaDrag *drag;
79     QQmlGuard<QObject> source;
80     QQmlGuard<QMimeData> mimeData;
81 };
82
83 QQuickDropAreaPrivate::QQuickDropAreaPrivate()
84     : drag(0)
85 {
86 }
87
88 QQuickDropAreaPrivate::~QQuickDropAreaPrivate()
89 {
90     delete drag;
91 }
92
93 /*!
94     \qmlclass DropArea QQuickDropArea
95     \inqmlmodule QtQuick 2
96     \ingroup qtquick-input
97     \brief For specifying drag and drop handling in an area
98
99     A DropArea is an invisible item which receives events when other items are
100     dragged over it.
101
102     The Drag attached property can be used to notify the DropArea when an Item is
103     dragged over it.
104
105     The \l keys property can be used to filter drag events which don't include
106     a matching key.
107
108     The \l dropItem property is communicated to the source of a drag event as
109     the recipient of a drop on the drag target.
110
111     The \l delegate property provides a means to specify a component to be
112     instantiated for each active drag over a drag target.
113 */
114
115 QQuickDropArea::QQuickDropArea(QQuickItem *parent)
116     : QQuickItem(*new QQuickDropAreaPrivate, parent)
117 {
118     setFlags(ItemAcceptsDrops);
119 }
120
121 QQuickDropArea::~QQuickDropArea()
122 {
123 }
124
125 /*!
126     \qmlproperty bool QtQuick2::DropArea::containsDrag
127
128     This property identifies whether the DropArea currently contains any
129     dragged items.
130 */
131
132 bool QQuickDropArea::containsDrag() const
133 {
134     Q_D(const QQuickDropArea);
135     return d->mimeData;
136 }
137
138 /*!
139     \qmlproperty stringlist QtQuick2::DropArea::keys
140
141     This property holds a list of drag keys a DropArea will accept.
142
143     If no keys are listed the DropArea will accept events from any drag source,
144     otherwise the drag source must have at least one compatible key.
145
146     \sa QtQuick2::Drag::keys
147 */
148
149 QStringList QQuickDropArea::keys() const
150 {
151     Q_D(const QQuickDropArea);
152     return d->keys;
153 }
154
155 void QQuickDropArea::setKeys(const QStringList &keys)
156 {
157     Q_D(QQuickDropArea);
158     if (d->keys != keys) {
159         d->keys = keys;
160
161         if (keys.isEmpty()) {
162             d->keyRegExp = QRegExp();
163         } else {
164             QString pattern = QLatin1Char('(') + QRegExp::escape(keys.first());
165             for (int i = 1; i < keys.count(); ++i)
166                 pattern += QLatin1Char('|') + QRegExp::escape(keys.at(i));
167             pattern += QLatin1Char(')');
168             d->keyRegExp = QRegExp(pattern.replace(QLatin1String("\\*"), QLatin1String(".+")));
169         }
170         emit keysChanged();
171     }
172 }
173
174 QQuickDropAreaDrag *QQuickDropArea::drag()
175 {
176     Q_D(QQuickDropArea);
177     if (!d->drag)
178         d->drag = new QQuickDropAreaDrag(d);
179     return d->drag;
180 }
181
182 /*!
183     \qmlproperty Object QtQuick2::DropArea::drag.source
184
185     This property holds the source of a drag.
186 */
187
188 QObject *QQuickDropAreaDrag::source() const
189 {
190     return d->source;
191 }
192
193 /*!
194     \qmlproperty qreal QtQuick2::DropArea::drag.x
195     \qmlproperty qreal QtQuick2::DropArea::drag.y
196
197     These properties hold the coordinates of the last drag event.
198 */
199
200 qreal QQuickDropAreaDrag::x() const
201 {
202     return d->dragPosition.x();
203 }
204
205 qreal QQuickDropAreaDrag::y() const
206 {
207     return d->dragPosition.y();
208 }
209
210 /*!
211     \qmlsignal QtQuick2::DropArea::onPositionChanged(DragEvent drag)
212
213     This handler is called when the position of a drag has changed.
214 */
215
216 void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
217 {
218     Q_D(QQuickDropArea);
219     if (!d->mimeData)
220         return;
221
222     d->dragPosition = event->pos();
223     if (d->drag)
224         emit d->drag->positionChanged();
225
226     event->accept();
227     QQuickDropEvent dragTargetEvent(d, event);
228     emit positionChanged(&dragTargetEvent);
229 }
230
231 bool QQuickDropAreaPrivate::hasMatchingKey(const QStringList &keys) const
232 {
233     if (keyRegExp.isEmpty())
234         return true;
235
236     QRegExp copy = keyRegExp;
237     foreach (const QString &key, keys) {
238         if (copy.exactMatch(key))
239             return true;
240     }
241     return false;
242 }
243
244 QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
245 {
246     if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(mimeData))
247         return dragMime->keys();
248     return mimeData->formats();
249 }
250
251 /*!
252     \qmlsignal QtQuick2::DropArea::onEntered(DragEvent drag)
253
254     This handler is called when a \a drag enters the bounds of a DropArea.
255 */
256
257 void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
258 {
259     Q_D(QQuickDropArea);
260     const QMimeData *mimeData = event->mimeData();
261     if (!d->effectiveEnable || d->mimeData || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData)))
262         return;
263
264     d->dragPosition = event->pos();
265
266     event->accept();
267     QQuickDropEvent dragTargetEvent(d, event);
268     emit entered(&dragTargetEvent);
269
270     if (event->isAccepted()) {
271         d->mimeData = const_cast<QMimeData *>(mimeData);
272         if (QQuickDragMimeData *dragMime = qobject_cast<QQuickDragMimeData *>(d->mimeData))
273             d->source = dragMime->source();
274         else
275             d->source = event->source();
276         d->dragPosition = event->pos();
277         if (d->drag) {
278             emit d->drag->positionChanged();
279             emit d->drag->sourceChanged();
280         }
281         emit containsDragChanged();
282     }
283 }
284
285 /*!
286     \qmlsignal QtQuick2::DropArea::onExited()
287
288     This handler is called when a drag exits the bounds of a DropArea.
289 */
290
291 void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
292 {
293     Q_D(QQuickDropArea);
294     if (!d->mimeData)
295         return;
296
297     emit exited();
298
299     d->mimeData = 0;
300     d->source = 0;
301     emit containsDragChanged();
302     if (d->drag)
303         emit d->drag->sourceChanged();
304 }
305
306 /*!
307     \qmlsignal QtQuick2::DropArea::onDropped(DragEvent drop)
308
309     This handler is called when a drop event occurs within the bounds of a
310     a DropArea.
311 */
312
313 void QQuickDropArea::dropEvent(QDropEvent *event)
314 {
315     Q_D(QQuickDropArea);
316     if (!d->mimeData)
317         return;
318
319     QQuickDropEvent dragTargetEvent(d, event);
320     emit dropped(&dragTargetEvent);
321
322     d->mimeData = 0;
323     d->source = 0;
324     emit containsDragChanged();
325     if (d->drag)
326         emit d->drag->sourceChanged();
327 }
328
329 /*!
330     \qmlclass DragEvent QQuickDragEvent
331     \inqmlmodule QtQuick 2
332     \ingroup qtquick-input-events
333     \brief Provides information about a drag event
334
335     The position of the drag event can be obtained from the \l x and \l y
336     properties, and the \l keys property identifies the drag keys of the event
337     \l source.
338 */
339
340 /*!
341     \qmlproperty real QtQuick2::DragEvent::x
342
343     This property holds the x coordinate of a drag event.
344 */
345
346 /*!
347     \qmlproperty real QtQuick2::DragEvent::y
348
349     This property holds the y coordinate of a drag event.
350 */
351
352 /*!
353     \qmlproperty Object QtQuick2::DragEvent::drag.source
354
355     This property holds the source of a drag event.
356 */
357
358 QObject *QQuickDropEvent::source()
359 {
360     if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(event->mimeData()))
361         return dragMime->source();
362     else
363         return event->source();
364 }
365
366 /*!
367     \qmlproperty stringlist QtQuick2::DragEvent::keys
368
369     This property holds a list of keys identifying the data type or source of a
370     drag event.
371 */
372
373 QStringList QQuickDropEvent::keys() const
374 {
375     return d->getKeys(event->mimeData());
376 }
377
378 /*!
379     \qmlproperty enumeration QtQuick2::DragEvent::action
380
381     This property holds the action that the \l source is to perform on an accepted drop.
382
383     The drop action may be one of:
384
385     \list
386     \li Qt.CopyAction Copy the data to the target
387     \li Qt.MoveAction Move the data from the source to the target
388     \li Qt.LinkAction Create a link from the source to the target.
389     \li Qt.IgnoreAction Ignore the action (do nothing with the data).
390     \endlist
391 */
392
393 /*!
394     \qmlproperty flags QtQuick2::DragEvent::supportedActions
395
396     This property holds the set of \l {action}{actions} supported by the
397     drag source.
398 */
399
400 /*!
401     \qmlproperty real QtQuick2::DragEvent::accepted
402
403     This property holds whether the drag event was accepted by a handler.
404
405     The default value is true.
406 */
407
408 /*!
409     \qmlmethod void QtQuick2::DragEvent::accept()
410     \qmlmethod void QtQuick2::DragEvent::accept(enumeration action)
411
412     Accepts the drag event.
413
414     If an \a action is specified it will overwrite the value of the \l action property.
415 */
416
417 void QQuickDropEvent::accept(QQmlV8Function *args)
418 {
419     Qt::DropAction action = event->dropAction();
420
421     if (args->Length() >= 1) {
422         v8::Local<v8::Value> v = (*args)[0];
423         if (v->IsInt32())
424             action = Qt::DropAction(v->Int32Value());
425     }
426     // get action from arguments.
427     event->setDropAction(action);
428     event->accept();
429 }
430
431
432 QT_END_NAMESPACE
433
434 #endif // QT_NO_DRAGANDDROP