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

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now