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