##// END OF EJS Templates
fix some wrong drag&drop behavior appearing on mac
trabillard -
r938:a300a0876631
parent child
Show More
@@ -1,470 +1,472
1 #include "Visualization/VisualizationDragDropContainer.h"
1 #include "Visualization/VisualizationDragDropContainer.h"
2 #include "DragAndDrop/DragDropHelper.h"
2 #include "DragAndDrop/DragDropHelper.h"
3 #include "SqpApplication.h"
3 #include "SqpApplication.h"
4 #include "Visualization/VisualizationDragWidget.h"
4 #include "Visualization/VisualizationDragWidget.h"
5
5
6 #include "Common/VisualizationDef.h"
6 #include "Common/VisualizationDef.h"
7
7
8 #include <QDrag>
8 #include <QDrag>
9 #include <QDragEnterEvent>
9 #include <QDragEnterEvent>
10 #include <QVBoxLayout>
10 #include <QVBoxLayout>
11
11
12 #include <cmath>
12 #include <cmath>
13 #include <memory>
13 #include <memory>
14
14
15 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
15 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
16
16
17 auto DRAGGED_MINIATURE_WIDTH = 200; // in pixels
17 auto DRAGGED_MINIATURE_WIDTH = 200; // in pixels
18
18
19 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
19 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
20
20
21 QVBoxLayout *m_Layout;
21 QVBoxLayout *m_Layout;
22 QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes;
22 QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes;
23 QString m_PlaceHolderText;
23 QString m_PlaceHolderText;
24 DragDropHelper::PlaceHolderType m_PlaceHolderType = DragDropHelper::PlaceHolderType::Graph;
24 DragDropHelper::PlaceHolderType m_PlaceHolderType = DragDropHelper::PlaceHolderType::Graph;
25
25
26 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
26 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
27 = [](auto mimeData) { return true; };
27 = [](auto mimeData) { return true; };
28
28
29 int m_MinContainerHeight = 0;
29 int m_MinContainerHeight = 0;
30
30
31 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
31 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
32 {
32 {
33 m_Layout = new QVBoxLayout(widget);
33 m_Layout = new QVBoxLayout(widget);
34 m_Layout->setContentsMargins(0, 0, 0, 0);
34 m_Layout->setContentsMargins(0, 0, 0, 0);
35 }
35 }
36
36
37 bool acceptMimeData(const QMimeData *data) const
37 bool acceptMimeData(const QMimeData *data) const
38 {
38 {
39 auto accepted = false;
39 auto accepted = false;
40 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
40 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
41 ++it) {
41 ++it) {
42 const auto &type = it.key();
42 const auto &type = it.key();
43 const auto &behavior = it.value();
43 const auto &behavior = it.value();
44
44
45 if (data->hasFormat(type)) {
45 if (data->hasFormat(type)) {
46 if (behavior != DropBehavior::Forbidden) {
46 if (behavior != DropBehavior::Forbidden) {
47 accepted = true;
47 accepted = true;
48 }
48 }
49 else {
49 else {
50 accepted = false;
50 accepted = false;
51 break;
51 break;
52 }
52 }
53 }
53 }
54 }
54 }
55
55
56 if (accepted) {
56 if (accepted) {
57 accepted = m_AcceptMimeDataFun(data);
57 accepted = m_AcceptMimeDataFun(data);
58 }
58 }
59
59
60 return accepted;
60 return accepted;
61 }
61 }
62
62
63 bool allowMergeForMimeData(const QMimeData *data) const
63 bool allowMergeForMimeData(const QMimeData *data) const
64 {
64 {
65 bool result = false;
65 bool result = false;
66 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
66 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
67 ++it) {
67 ++it) {
68
68
69 if (data->hasFormat(it.key())
69 if (data->hasFormat(it.key())
70 && (it.value() == VisualizationDragDropContainer::DropBehavior::Merged
70 && (it.value() == VisualizationDragDropContainer::DropBehavior::Merged
71 || it.value()
71 || it.value()
72 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
72 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
73 result = true;
73 result = true;
74 }
74 }
75 else if (data->hasFormat(it.key())
75 else if (data->hasFormat(it.key())
76 && it.value() == VisualizationDragDropContainer::DropBehavior::Inserted) {
76 && it.value() == VisualizationDragDropContainer::DropBehavior::Inserted) {
77 // Merge is forbidden if the mime data contain an acceptable type which cannot be
77 // Merge is forbidden if the mime data contain an acceptable type which cannot be
78 // merged
78 // merged
79 result = false;
79 result = false;
80 break;
80 break;
81 }
81 }
82 }
82 }
83
83
84 return result;
84 return result;
85 }
85 }
86
86
87 bool allowInsertForMimeData(const QMimeData *data) const
87 bool allowInsertForMimeData(const QMimeData *data) const
88 {
88 {
89 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
89 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
90 ++it) {
90 ++it) {
91 if (data->hasFormat(it.key())
91 if (data->hasFormat(it.key())
92 && (it.value() == VisualizationDragDropContainer::DropBehavior::Inserted
92 && (it.value() == VisualizationDragDropContainer::DropBehavior::Inserted
93 || it.value()
93 || it.value()
94 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
94 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
95 return true;
95 return true;
96 }
96 }
97 }
97 }
98
98
99 return false;
99 return false;
100 }
100 }
101
101
102 bool hasPlaceHolder() const
102 bool hasPlaceHolder() const
103 {
103 {
104 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
104 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
105 }
105 }
106
106
107 VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const
107 VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const
108 {
108 {
109 VisualizationDragWidget *dragWidget = nullptr;
109 VisualizationDragWidget *dragWidget = nullptr;
110
110
111 for (auto child : parent->children()) {
111 for (auto child : parent->children()) {
112 auto widget = qobject_cast<VisualizationDragWidget *>(child);
112 auto widget = qobject_cast<VisualizationDragWidget *>(child);
113 if (widget && widget->isVisible()) {
113 if (widget && widget->isVisible()) {
114 if (widget->frameGeometry().contains(pos)) {
114 if (widget->frameGeometry().contains(pos)) {
115 dragWidget = widget;
115 dragWidget = widget;
116 break;
116 break;
117 }
117 }
118 }
118 }
119 }
119 }
120
120
121 return dragWidget;
121 return dragWidget;
122 }
122 }
123
123
124 bool cursorIsInContainer(QWidget *container) const
124 bool cursorIsInContainer(QWidget *container) const
125 {
125 {
126 return container->isAncestorOf(sqpApp->widgetAt(QCursor::pos()));
126 auto widgetUnderMouse = sqpApp->widgetAt(QCursor::pos());
127 return container->isAncestorOf(widgetUnderMouse) && widgetUnderMouse != container
128 && sqpApp->dragDropHelper().placeHolder().isAncestorOf(widgetUnderMouse);
127 }
129 }
128
130
129 int countDragWidget(const QWidget *parent, bool onlyVisible = false) const
131 int countDragWidget(const QWidget *parent, bool onlyVisible = false) const
130 {
132 {
131 auto nbGraph = 0;
133 auto nbGraph = 0;
132 for (auto child : parent->children()) {
134 for (auto child : parent->children()) {
133 if (qobject_cast<VisualizationDragWidget *>(child)) {
135 if (qobject_cast<VisualizationDragWidget *>(child)) {
134 if (!onlyVisible || qobject_cast<VisualizationDragWidget *>(child)->isVisible()) {
136 if (!onlyVisible || qobject_cast<VisualizationDragWidget *>(child)->isVisible()) {
135 nbGraph += 1;
137 nbGraph += 1;
136 }
138 }
137 }
139 }
138 }
140 }
139
141
140 return nbGraph;
142 return nbGraph;
141 }
143 }
142
144
143 void findPlaceHolderPosition(const QPoint &pos, bool canInsert, bool canMerge,
145 void findPlaceHolderPosition(const QPoint &pos, bool canInsert, bool canMerge,
144 const VisualizationDragDropContainer *container);
146 const VisualizationDragDropContainer *container);
145 };
147 };
146
148
147 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
149 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
148 : QFrame{parent},
150 : QFrame{parent},
149 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
151 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
150 {
152 {
151 setAcceptDrops(true);
153 setAcceptDrops(true);
152 }
154 }
153
155
154 void VisualizationDragDropContainer::addDragWidget(VisualizationDragWidget *dragWidget)
156 void VisualizationDragDropContainer::addDragWidget(VisualizationDragWidget *dragWidget)
155 {
157 {
156 impl->m_Layout->addWidget(dragWidget);
158 impl->m_Layout->addWidget(dragWidget);
157 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
159 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
158 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
160 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
159 &VisualizationDragDropContainer::startDrag);
161 &VisualizationDragDropContainer::startDrag);
160 }
162 }
161
163
162 void VisualizationDragDropContainer::insertDragWidget(int index,
164 void VisualizationDragDropContainer::insertDragWidget(int index,
163 VisualizationDragWidget *dragWidget)
165 VisualizationDragWidget *dragWidget)
164 {
166 {
165 impl->m_Layout->insertWidget(index, dragWidget);
167 impl->m_Layout->insertWidget(index, dragWidget);
166 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
168 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
167 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
169 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
168 &VisualizationDragDropContainer::startDrag);
170 &VisualizationDragDropContainer::startDrag);
169 }
171 }
170
172
171 void VisualizationDragDropContainer::setMimeType(
173 void VisualizationDragDropContainer::setMimeType(
172 const QString &mimeType, VisualizationDragDropContainer::DropBehavior behavior)
174 const QString &mimeType, VisualizationDragDropContainer::DropBehavior behavior)
173 {
175 {
174 impl->m_AcceptedMimeTypes[mimeType] = behavior;
176 impl->m_AcceptedMimeTypes[mimeType] = behavior;
175 }
177 }
176
178
177 int VisualizationDragDropContainer::countDragWidget() const
179 int VisualizationDragDropContainer::countDragWidget() const
178 {
180 {
179 return impl->countDragWidget(this);
181 return impl->countDragWidget(this);
180 }
182 }
181
183
182 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
184 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
183 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
185 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
184 {
186 {
185 impl->m_AcceptMimeDataFun = fun;
187 impl->m_AcceptMimeDataFun = fun;
186 }
188 }
187
189
188 void VisualizationDragDropContainer::setPlaceHolderType(DragDropHelper::PlaceHolderType type,
190 void VisualizationDragDropContainer::setPlaceHolderType(DragDropHelper::PlaceHolderType type,
189 const QString &placeHolderText)
191 const QString &placeHolderText)
190 {
192 {
191 impl->m_PlaceHolderType = type;
193 impl->m_PlaceHolderType = type;
192 impl->m_PlaceHolderText = placeHolderText;
194 impl->m_PlaceHolderText = placeHolderText;
193 }
195 }
194
196
195 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
197 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
196 const QPoint &dragPosition)
198 const QPoint &dragPosition)
197 {
199 {
198 auto &helper = sqpApp->dragDropHelper();
200 auto &helper = sqpApp->dragDropHelper();
199 helper.resetDragAndDrop();
201 helper.resetDragAndDrop();
200
202
201 // Note: The management of the drag object is done by Qt
203 // Note: The management of the drag object is done by Qt
202 auto drag = new QDrag{dragWidget};
204 auto drag = new QDrag{dragWidget};
203
205
204 auto mimeData = dragWidget->mimeData();
206 auto mimeData = dragWidget->mimeData();
205 drag->setMimeData(mimeData);
207 drag->setMimeData(mimeData);
206
208
207 auto pixmap = QPixmap(dragWidget->size());
209 auto pixmap = QPixmap(dragWidget->size());
208 dragWidget->render(&pixmap);
210 dragWidget->render(&pixmap);
209 drag->setPixmap(pixmap.scaled(DRAGGED_MINIATURE_WIDTH, DRAGGED_MINIATURE_WIDTH,
211 drag->setPixmap(pixmap.scaled(DRAGGED_MINIATURE_WIDTH, DRAGGED_MINIATURE_WIDTH,
210 Qt::KeepAspectRatio, Qt::SmoothTransformation));
212 Qt::KeepAspectRatio, Qt::SmoothTransformation));
211
213
212 auto image = pixmap.toImage();
214 auto image = pixmap.toImage();
213 mimeData->setImageData(image);
215 mimeData->setImageData(image);
214 mimeData->setUrls({helper.imageTemporaryUrl(image)});
216 mimeData->setUrls({helper.imageTemporaryUrl(image)});
215
217
216 if (impl->m_Layout->indexOf(dragWidget) >= 0) {
218 if (impl->m_Layout->indexOf(dragWidget) >= 0) {
217 helper.setCurrentDragWidget(dragWidget);
219 helper.setCurrentDragWidget(dragWidget);
218
220
219 if (impl->cursorIsInContainer(this)) {
221 if (impl->cursorIsInContainer(this)) {
220 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
222 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
221 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex, impl->m_PlaceHolderType,
223 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex, impl->m_PlaceHolderType,
222 impl->m_PlaceHolderText);
224 impl->m_PlaceHolderText);
223 dragWidget->setVisible(false);
225 dragWidget->setVisible(false);
224 }
226 }
225 else {
227 else {
226 // The drag starts directly outside the drop zone
228 // The drag starts directly outside the drop zone
227 // do not add the placeHolder
229 // do not add the placeHolder
228 }
230 }
229
231
230 drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
232 drag->exec(Qt::MoveAction | Qt::CopyAction, Qt::MoveAction);
231
233
232 helper.doCloseWidgets();
234 helper.doCloseWidgets();
233 }
235 }
234 else {
236 else {
235 qCWarning(LOG_VisualizationDragDropContainer())
237 qCWarning(LOG_VisualizationDragDropContainer())
236 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
238 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
237 "VisualizationDragWidget is not found in this container.");
239 "VisualizationDragWidget is not found in this container.");
238 }
240 }
239 }
241 }
240
242
241 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
243 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
242 {
244 {
243 if (impl->acceptMimeData(event->mimeData())) {
245 if (impl->acceptMimeData(event->mimeData())) {
244 event->acceptProposedAction();
246 event->acceptProposedAction();
245
247
246 auto &helper = sqpApp->dragDropHelper();
248 auto &helper = sqpApp->dragDropHelper();
247
249
248 if (!impl->hasPlaceHolder()) {
250 if (!impl->hasPlaceHolder()) {
249 auto dragWidget = helper.getCurrentDragWidget();
251 auto dragWidget = helper.getCurrentDragWidget();
250
252
251 if (dragWidget) {
253 if (dragWidget) {
252 // If the drag&drop is internal to the visualization, entering the container hide
254 // If the drag&drop is internal to the visualization, entering the container hide
253 // the dragWidget which was made visible by the dragLeaveEvent
255 // the dragWidget which was made visible by the dragLeaveEvent
254 auto parentWidget
256 auto parentWidget
255 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
257 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
256 if (parentWidget) {
258 if (parentWidget) {
257 dragWidget->setVisible(false);
259 dragWidget->setVisible(false);
258 }
260 }
259 }
261 }
260
262
261 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
263 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
262 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
264 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
263 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
265 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
264 }
266 }
265 else {
267 else {
266 // do nothing
268 // do nothing
267 }
269 }
268 }
270 }
269 else {
271 else {
270 event->ignore();
272 event->ignore();
271 }
273 }
272
274
273 QWidget::dragEnterEvent(event);
275 QWidget::dragEnterEvent(event);
274 }
276 }
275
277
276 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
278 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
277 {
279 {
278 Q_UNUSED(event);
280 Q_UNUSED(event);
279
281
280 auto &helper = sqpApp->dragDropHelper();
282 auto &helper = sqpApp->dragDropHelper();
281
283
282 if (!impl->cursorIsInContainer(this)) {
284 if (!impl->cursorIsInContainer(this)) {
283 helper.removePlaceHolder();
285 helper.removePlaceHolder();
284 helper.setHightlightedDragWidget(nullptr);
286 helper.setHightlightedDragWidget(nullptr);
285 impl->m_MinContainerHeight = 0;
287 impl->m_MinContainerHeight = 0;
286
288
287 auto dragWidget = helper.getCurrentDragWidget();
289 auto dragWidget = helper.getCurrentDragWidget();
288 if (dragWidget) {
290 if (dragWidget) {
289 // dragWidget has a value only if the drag is started from the visualization
291 // dragWidget has a value only if the drag is started from the visualization
290 // In that case, shows the drag widget at its original place
292 // In that case, shows the drag widget at its original place
291 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
293 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
292 // drop zone (It is not possible to catch a drop event outside of the application)
294 // drop zone (It is not possible to catch a drop event outside of the application)
293
295
294 if (dragWidget) {
296 if (dragWidget) {
295 dragWidget->setVisible(true);
297 dragWidget->setVisible(true);
296 }
298 }
297 }
299 }
298 }
300 }
299 else {
301 else {
300 // Leave event probably received for a child widget.
302 // Leave event probably received for a child widget.
301 // Do nothing.
303 // Do nothing.
302 // Note: The DragLeave event, doesn't have any mean to determine who sent it.
304 // Note: The DragLeave event, doesn't have any mean to determine who sent it.
303 }
305 }
304
306
305 QWidget::dragLeaveEvent(event);
307 QWidget::dragLeaveEvent(event);
306 }
308 }
307
309
308 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
310 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
309 {
311 {
310 if (impl->acceptMimeData(event->mimeData())) {
312 if (impl->acceptMimeData(event->mimeData())) {
311 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
313 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
312 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
314 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
313 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
315 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
314 }
316 }
315 else {
317 else {
316 event->ignore();
318 event->ignore();
317 }
319 }
318
320
319 QWidget::dragMoveEvent(event);
321 QWidget::dragMoveEvent(event);
320 }
322 }
321
323
322 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
324 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
323 {
325 {
324 auto &helper = sqpApp->dragDropHelper();
326 auto &helper = sqpApp->dragDropHelper();
325
327
326 if (impl->acceptMimeData(event->mimeData())) {
328 if (impl->acceptMimeData(event->mimeData())) {
327 auto dragWidget = helper.getCurrentDragWidget();
329 auto dragWidget = helper.getCurrentDragWidget();
328 if (impl->hasPlaceHolder()) {
330 if (impl->hasPlaceHolder()) {
329 // drop where the placeHolder is located
331 // drop where the placeHolder is located
330
332
331 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
333 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
332 if (canInsert) {
334 if (canInsert) {
333 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
335 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
334
336
335 if (dragWidget) {
337 if (dragWidget) {
336 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
338 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
337 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
339 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
338 // Correction of the index if the drop occurs in the same container
340 // Correction of the index if the drop occurs in the same container
339 // and if the drag is started from the visualization (in that case, the
341 // and if the drag is started from the visualization (in that case, the
340 // dragWidget is hidden)
342 // dragWidget is hidden)
341 droppedIndex -= 1;
343 droppedIndex -= 1;
342 }
344 }
343
345
344 dragWidget->setVisible(true);
346 dragWidget->setVisible(true);
345 }
347 }
346
348
347 event->acceptProposedAction();
349 event->acceptProposedAction();
348
350
349 helper.removePlaceHolder();
351 helper.removePlaceHolder();
350
352
351 emit dropOccuredInContainer(droppedIndex, event->mimeData());
353 emit dropOccuredInContainer(droppedIndex, event->mimeData());
352 }
354 }
353 else {
355 else {
354 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
356 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
355 "VisualizationDragDropContainer::dropEvent, dropping on the placeHolder, but "
357 "VisualizationDragDropContainer::dropEvent, dropping on the placeHolder, but "
356 "the insertion is forbidden.");
358 "the insertion is forbidden.");
357 Q_ASSERT(false);
359 Q_ASSERT(false);
358 }
360 }
359 }
361 }
360 else if (helper.getHightlightedDragWidget()) {
362 else if (helper.getHightlightedDragWidget()) {
361 // drop on the highlighted widget
363 // drop on the highlighted widget
362
364
363 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
365 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
364 if (canMerge) {
366 if (canMerge) {
365 event->acceptProposedAction();
367 event->acceptProposedAction();
366 emit dropOccuredOnWidget(helper.getHightlightedDragWidget(), event->mimeData());
368 emit dropOccuredOnWidget(helper.getHightlightedDragWidget(), event->mimeData());
367 }
369 }
368 else {
370 else {
369 qCWarning(LOG_VisualizationDragDropContainer())
371 qCWarning(LOG_VisualizationDragDropContainer())
370 << tr("VisualizationDragDropContainer::dropEvent, dropping on a widget, but "
372 << tr("VisualizationDragDropContainer::dropEvent, dropping on a widget, but "
371 "the merge is forbidden.");
373 "the merge is forbidden.");
372 Q_ASSERT(false);
374 Q_ASSERT(false);
373 }
375 }
374 }
376 }
375 }
377 }
376 else {
378 else {
377 event->ignore();
379 event->ignore();
378 }
380 }
379
381
380 sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr);
382 sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr);
381 impl->m_MinContainerHeight = 0;
383 impl->m_MinContainerHeight = 0;
382
384
383 QWidget::dropEvent(event);
385 QWidget::dropEvent(event);
384 }
386 }
385
387
386
388
387 void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition(
389 void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition(
388 const QPoint &pos, bool canInsert, bool canMerge,
390 const QPoint &pos, bool canInsert, bool canMerge,
389 const VisualizationDragDropContainer *container)
391 const VisualizationDragDropContainer *container)
390 {
392 {
391 auto &helper = sqpApp->dragDropHelper();
393 auto &helper = sqpApp->dragDropHelper();
392
394
393 auto absPos = container->mapToGlobal(pos);
395 auto absPos = container->mapToGlobal(pos);
394 auto isOnPlaceHolder = sqpApp->widgetAt(absPos) == &(helper.placeHolder());
396 auto isOnPlaceHolder = helper.placeHolder().isAncestorOf(sqpApp->widgetAt(absPos));
395
397
396 if (countDragWidget(container, true) == 0) {
398 if (countDragWidget(container, true) == 0) {
397 // Drop on an empty container, just add the placeHolder at the top
399 // Drop on an empty container, just add the placeHolder at the top
398 helper.insertPlaceHolder(m_Layout, 0, m_PlaceHolderType, m_PlaceHolderText);
400 helper.insertPlaceHolder(m_Layout, 0, m_PlaceHolderType, m_PlaceHolderText);
399 }
401 }
400 else if (!isOnPlaceHolder) {
402 else if (!isOnPlaceHolder) {
401 auto nbDragWidget = countDragWidget(container);
403 auto nbDragWidget = countDragWidget(container);
402 if (nbDragWidget > 0) {
404 if (nbDragWidget > 0) {
403
405
404 if (m_MinContainerHeight == 0) {
406 if (m_MinContainerHeight == 0) {
405 m_MinContainerHeight = container->size().height();
407 m_MinContainerHeight = container->size().height();
406 }
408 }
407
409
408 m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height());
410 m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height());
409 auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
411 auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
410
412
411 auto posY = pos.y();
413 auto posY = pos.y();
412 auto dropIndex = floor(posY / graphHeight);
414 auto dropIndex = floor(posY / graphHeight);
413 auto zoneSize = qMin(graphHeight / 4.0, 75.0);
415 auto zoneSize = qMin(graphHeight / 4.0, 75.0);
414
416
415
417
416 auto isOnTop = posY < dropIndex * graphHeight + zoneSize;
418 auto isOnTop = posY < dropIndex * graphHeight + zoneSize;
417 auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize;
419 auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize;
418
420
419 auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder()));
421 auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder()));
420
422
421 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
423 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
422
424
423 if (canInsert && (isOnTop || isOnBottom || !canMerge)) {
425 if (canInsert && (isOnTop || isOnBottom || !canMerge)) {
424 if (isOnBottom) {
426 if (isOnBottom) {
425 dropIndex += 1;
427 dropIndex += 1;
426 }
428 }
427
429
428 if (helper.getCurrentDragWidget()) {
430 if (helper.getCurrentDragWidget()) {
429 auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget());
431 auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget());
430 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
432 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
431 // Correction of the index if the drop occurs in the same container
433 // Correction of the index if the drop occurs in the same container
432 // and if the drag is started from the visualization (in that case, the
434 // and if the drag is started from the visualization (in that case, the
433 // dragWidget is hidden)
435 // dragWidget is hidden)
434 dropIndex += 1;
436 dropIndex += 1;
435 }
437 }
436 }
438 }
437
439
438 if (dropIndex != placeHolderIndex) {
440 if (dropIndex != placeHolderIndex) {
439 helper.insertPlaceHolder(m_Layout, dropIndex, m_PlaceHolderType,
441 helper.insertPlaceHolder(m_Layout, dropIndex, m_PlaceHolderType,
440 m_PlaceHolderText);
442 m_PlaceHolderText);
441 }
443 }
442
444
443 helper.setHightlightedDragWidget(nullptr);
445 helper.setHightlightedDragWidget(nullptr);
444 }
446 }
445 else if (canMerge && dragWidgetHovered) {
447 else if (canMerge && dragWidgetHovered) {
446 // drop on the middle -> merge
448 // drop on the middle -> merge
447 if (hasPlaceHolder()) {
449 if (hasPlaceHolder()) {
448 helper.removePlaceHolder();
450 helper.removePlaceHolder();
449 }
451 }
450
452
451 helper.setHightlightedDragWidget(dragWidgetHovered);
453 helper.setHightlightedDragWidget(dragWidgetHovered);
452 }
454 }
453 else {
455 else {
454 qCWarning(LOG_VisualizationDragDropContainer())
456 qCWarning(LOG_VisualizationDragDropContainer())
455 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
457 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
456 "action.");
458 "action.");
457 }
459 }
458 }
460 }
459 else {
461 else {
460 qCWarning(LOG_VisualizationDragDropContainer())
462 qCWarning(LOG_VisualizationDragDropContainer())
461 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget "
463 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget "
462 "found in the "
464 "found in the "
463 "container");
465 "container");
464 }
466 }
465 }
467 }
466 else {
468 else {
467 // the mouse is hover the placeHolder
469 // the mouse is hover the placeHolder
468 // Do nothing
470 // Do nothing
469 }
471 }
470 }
472 }
General Comments 0
You need to be logged in to leave comments. Login now