1/*
2 SPDX-FileCopyrightText: 2010 BetterInbox <contact@betterinbox.com>
3 SPDX-FileContributor: Gregory Schlomoff <greg@betterinbox.com>
4
5 SPDX-License-Identifier: MIT
6*/
7
8#include "DeclarativeDropArea.h"
9#include "DeclarativeDragDropEvent.h"
10
11DeclarativeDropArea::DeclarativeDropArea(QQuickItem *parent)
12 : QQuickItem(parent)
13 , m_enabled(true)
14 , m_preventStealing(false)
15 , m_temporaryInhibition(false)
16 , m_containsDrag(false)
17{
18 setFlag(flag: ItemAcceptsDrops, enabled: m_enabled);
19}
20
21void DeclarativeDropArea::temporaryInhibitParent(bool inhibit)
22{
23 QQuickItem *candidate = parentItem();
24
25 while (candidate) {
26 if (DeclarativeDropArea *da = qobject_cast<DeclarativeDropArea *>(object: candidate)) {
27 da->m_temporaryInhibition = inhibit;
28 if (inhibit) {
29 Q_EMIT da->dragLeaveEvent(event: nullptr);
30 }
31 }
32 candidate = candidate->parentItem();
33 }
34}
35
36void DeclarativeDropArea::dragEnterEvent(QDragEnterEvent *event)
37{
38 if (!m_enabled || m_temporaryInhibition) {
39 return;
40 }
41
42 DeclarativeDragDropEvent dde(event, this);
43 event->accept();
44
45 Q_EMIT dragEnter(event: &dde);
46
47 if (!event->isAccepted()) {
48 return;
49 }
50
51 if (m_preventStealing) {
52 temporaryInhibitParent(inhibit: true);
53 }
54
55 m_oldDragMovePos = event->position().toPoint();
56 setContainsDrag(true);
57}
58
59void DeclarativeDropArea::dragLeaveEvent(QDragLeaveEvent *event)
60{
61 // do it anyways, in the unlikely case m_preventStealing
62 // was changed while drag
63 temporaryInhibitParent(inhibit: false);
64
65 m_oldDragMovePos = QPoint(-1, -1);
66 DeclarativeDragDropEvent dde(event, this);
67 Q_EMIT dragLeave(event: &dde);
68 setContainsDrag(false);
69}
70
71void DeclarativeDropArea::dragMoveEvent(QDragMoveEvent *event)
72{
73 if (!m_enabled || m_temporaryInhibition) {
74 event->ignore();
75 return;
76 }
77 event->accept();
78 // if the position we export didn't change, don't generate the move event
79 if (event->position() == m_oldDragMovePos) {
80 return;
81 }
82
83 m_oldDragMovePos = event->position().toPoint();
84 DeclarativeDragDropEvent dde(event, this);
85 Q_EMIT dragMove(event: &dde);
86}
87
88void DeclarativeDropArea::dropEvent(QDropEvent *event)
89{
90 // do it anyways, in the unlikely case m_preventStealing
91 // was changed while drag, do it after a loop,
92 // so the parent dropevent doesn't get delivered
93 metaObject()->invokeMethod(obj: this, member: "temporaryInhibitParent", c: Qt::QueuedConnection, Q_ARG(bool, false));
94
95 m_oldDragMovePos = QPoint(-1, -1);
96
97 if (!m_enabled || m_temporaryInhibition) {
98 return;
99 }
100
101 DeclarativeDragDropEvent dde(event, this);
102 Q_EMIT drop(event: &dde);
103 setContainsDrag(false);
104}
105
106bool DeclarativeDropArea::isEnabled() const
107{
108 return m_enabled;
109}
110
111void DeclarativeDropArea::setEnabled(bool enabled)
112{
113 if (enabled == m_enabled) {
114 return;
115 }
116
117 m_enabled = enabled;
118 setFlag(flag: ItemAcceptsDrops, enabled: m_enabled);
119 Q_EMIT enabledChanged();
120}
121
122bool DeclarativeDropArea::preventStealing() const
123{
124 return m_preventStealing;
125}
126
127void DeclarativeDropArea::setPreventStealing(bool prevent)
128{
129 if (prevent == m_preventStealing) {
130 return;
131 }
132
133 m_preventStealing = prevent;
134 Q_EMIT preventStealingChanged();
135}
136
137void DeclarativeDropArea::setContainsDrag(bool dragging)
138{
139 if (m_containsDrag != dragging) {
140 m_containsDrag = dragging;
141 Q_EMIT containsDragChanged(contained: m_containsDrag);
142 }
143}
144
145bool DeclarativeDropArea::containsDrag() const
146{
147 return m_containsDrag;
148}
149
150#include "moc_DeclarativeDropArea.cpp"
151

source code of kdeclarative/src/qmlcontrols/draganddrop/DeclarativeDropArea.cpp