##// END OF EJS Templates
drop of variables in the visualization
trabillard -
r852:2e038915a77e
parent child
Show More
@@ -287,11 +287,13 QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
287 287 QList<std::shared_ptr<Variable> > variableList;
288 288
289 289 for (const auto &index : indexes) {
290 if (index.column() == 0) { // only the first column
290 291 auto variable = impl->m_Variables.at(index.row());
291 292 if (variable.get() && index.isValid()) {
292 293 variableList << variable;
293 294 }
294 295 }
296 }
295 297
296 298 auto encodedData = impl->m_VariableController->mimeDataForVariables(variableList);
297 299 mimeData->setData(MIME_TYPE_VARIABLE_LIST, encodedData);
@@ -2,39 +2,23
2 2 #define SCIQLOP_DRAGDROPHELPER_H
3 3
4 4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 6 #include <QWidget>
6 7
7 8 class QVBoxLayout;
8 9 class QScrollArea;
9 10 class VisualizationDragWidget;
11 class VisualizationDragDropContainer;
10 12 class QMimeData;
11 13
12 /**
13 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
14 * @note A QScrollArea inside an other QScrollArea is not fully supported.
15 */
16 class DragDropScroller : public QObject {
17 Q_OBJECT
18
19 public:
20 DragDropScroller(QObject *parent = nullptr);
21
22 void addScrollArea(QScrollArea *scrollArea);
23 void removeScrollArea(QScrollArea *scrollArea);
24
25 protected:
26 bool eventFilter(QObject *obj, QEvent *event);
27
28 private:
29 class DragDropScrollerPrivate;
30 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
31
32 private slots:
33 void onTimer();
34 };
14 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper)
35 15
36 16 /**
37 17 * @brief Helper class for drag&drop operations.
18 * @note The helper is accessible from the sqpApp singleton and has the same life as the whole
19 * application (like a controller). But contrary to a controller, it doesn't live in a thread and
20 * can interect with the gui.
21 * @see SqpApplication
38 22 */
39 23 class DragDropHelper {
40 24 public:
@@ -44,7 +28,15 public:
44 28 DragDropHelper();
45 29 virtual ~DragDropHelper();
46 30
31 /// Resets some internal variables. Must be called before any new drag&drop operation.
32 void resetDragAndDrop();
33
34 /// Sets the visualization widget currently being drag on the visualization.
47 35 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
36
37 /// Returns the visualization widget currently being drag on the visualization.
38 /// Can be null if a new visualization widget is intended to be created by the drag&drop
39 /// operation.
48 40 VisualizationDragWidget *getCurrentDragWidget() const;
49 41
50 42 QWidget &placeHolder() const;
@@ -52,6 +44,10 public:
52 44 void removePlaceHolder();
53 45 bool isPlaceHolderSet() const;
54 46
47 /// Checks if the specified mime data is valid for a drop in the visualization
48 bool checkMimeDataForVisualization(const QMimeData *mimeData,
49 VisualizationDragDropContainer *dropContainer);
50
55 51 void addDragDropScrollArea(QScrollArea *scrollArea);
56 52 void removeDragDropScrollArea(QScrollArea *scrollArea);
57 53
@@ -62,4 +58,28 private:
62 58 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
63 59 };
64 60
61 /**
62 * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation.
63 * @note A QScrollArea inside an other QScrollArea is not fully supported.
64 */
65 class DragDropScroller : public QObject {
66 Q_OBJECT
67
68 public:
69 DragDropScroller(QObject *parent = nullptr);
70
71 void addScrollArea(QScrollArea *scrollArea);
72 void removeScrollArea(QScrollArea *scrollArea);
73
74 protected:
75 bool eventFilter(QObject *obj, QEvent *event);
76
77 private:
78 class DragDropScrollerPrivate;
79 spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl;
80
81 private slots:
82 void onTimer();
83 };
84
65 85 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -45,7 +45,8 public:
45 45 VariableController &variableController() noexcept;
46 46 VisualizationController &visualizationController() noexcept;
47 47
48 /// Accessors for the differents sciqlop helpers
48 /// Accessors for the differents sciqlop helpers, these helpers classes are like controllers but
49 /// doesn't live in a thread and access gui
49 50 DragDropHelper &dragDropHelper() noexcept;
50 51
51 52 private:
@@ -2,10 +2,15
2 2 #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
3 3
4 4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 6 #include <QMimeData>
6 7 #include <QVBoxLayout>
7 8 #include <QWidget>
8 9
10 #include <functional>
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer)
13
9 14 class VisualizationDragWidget;
10 15
11 16 class VisualizationDragDropContainer : public QWidget {
@@ -15,6 +20,8 signals:
15 20 void dropOccured(int dropIndex, const QMimeData *mimeData);
16 21
17 22 public:
23 using AcceptMimeDataFunction = std::function<bool(const QMimeData *mimeData)>;
24
18 25 VisualizationDragDropContainer(QWidget *parent = nullptr);
19 26
20 27 void addDragWidget(VisualizationDragWidget *dragWidget);
@@ -25,6 +32,8 public:
25 32
26 33 int countDragWidget() const;
27 34
35 void setAcceptMimeDataFunction(AcceptMimeDataFunction fun);
36
28 37 protected:
29 38 void dragEnterEvent(QDragEnterEvent *event);
30 39 void dragLeaveEvent(QDragLeaveEvent *event);
@@ -1,6 +1,14
1 1 #include "DragDropHelper.h"
2 2 #include "SqpApplication.h"
3 #include "Visualization/VisualizationDragDropContainer.h"
3 4 #include "Visualization/VisualizationDragWidget.h"
5 #include "Visualization/VisualizationWidget.h"
6 #include "Visualization/operations/FindVariableOperation.h"
7
8 #include "Variable/VariableController.h"
9
10 #include "Common/MimeTypesDef.h"
11 #include "Common/VisualizationDef.h"
4 12
5 13 #include <QDir>
6 14 #include <QDragEnterEvent>
@@ -13,6 +21,8
13 21 const int SCROLL_SPEED = 5;
14 22 const int SCROLL_ZONE_SIZE = 50;
15 23
24 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
25
16 26 struct DragDropScroller::DragDropScrollerPrivate {
17 27
18 28 QList<QScrollArea *> m_ScrollAreas;
@@ -156,7 +166,11 struct DragDropHelper::DragDropHelperPrivate {
156 166 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
157 167 }
158 168 else {
159 m_PlaceHolder->setMinimumSize(200, 200);
169 // Configuration of the placeHolder when there is no dragWidget
170 // (for instance with a drag from a variable)
171
172 m_PlaceHolder->setMinimumSize(400, 300);
173 m_PlaceHolder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
160 174 }
161 175 }
162 176 };
@@ -171,6 +185,11 DragDropHelper::~DragDropHelper()
171 185 QFile::remove(impl->m_ImageTempUrl);
172 186 }
173 187
188 void DragDropHelper::resetDragAndDrop()
189 {
190 setCurrentDragWidget(nullptr);
191 }
192
174 193 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
175 194 {
176 195 impl->m_CurrentDragWidget = dragWidget;
@@ -225,3 +244,46 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
225 244 image.save(impl->m_ImageTempUrl);
226 245 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
227 246 }
247
248 bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData,
249 VisualizationDragDropContainer *dropContainer)
250 {
251 auto result = true;
252
253 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
254 auto variables = sqpApp->variableController().variablesForMimeData(
255 mimeData->data(MIME_TYPE_VARIABLE_LIST));
256
257 if (variables.count() == 1) {
258 // Check that the viariable is not already in a graph
259
260 // Search for the top level VisualizationWidget
261 auto parent = dropContainer->parentWidget();
262 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
263 parent = parent->parentWidget();
264 }
265
266 if (parent) {
267 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
268
269 FindVariableOperation findVariableOperation{variables.first()};
270 visualizationWidget->accept(&findVariableOperation);
271 auto variableContainers = findVariableOperation.result();
272 if (!variableContainers.empty()) {
273 result = false;
274 }
275 }
276 else {
277 qCWarning(LOG_DragDropHelper()) << QObject::tr(
278 "DragDropHelper::checkMimeDataForVisualization, the parent "
279 "VisualizationWidget cannot be found.");
280 result = false;
281 }
282 }
283 else {
284 result = false;
285 }
286 }
287
288 return result;
289 }
@@ -12,6 +12,7
12 12 #include <QStyledItemDelegate>
13 13 #include <QWidgetAction>
14 14
15 #include <DragDropHelper.h>
15 16 #include <SqpApplication.h>
16 17
17 18 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
@@ -151,6 +152,11 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
151 152 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 153 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 154 &VariableInspectorWidget::onTableMenuRequested);
155
156 // Resets the drag&drop operation on a left-click (the drag&drop is also started by a left
157 // click).
158 connect(ui->tableView, &QTableView::clicked,
159 [](const auto &modelIndex) { sqpApp->dragDropHelper().resetDragAndDrop(); });
154 160 }
155 161
156 162 VariableInspectorWidget::~VariableInspectorWidget()
@@ -10,11 +10,15
10 10 #include <cmath>
11 11 #include <memory>
12 12
13 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
14
13 15 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
14 16
15 17 QVBoxLayout *m_Layout;
16 18 QStringList m_AcceptedMimeTypes;
17 19 QStringList m_MergeAllowedMimeTypes;
20 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
21 = [](auto mimeData) { return true; };
18 22
19 23 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
20 24 {
@@ -25,7 +29,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
25 29 bool acceptMimeData(const QMimeData *data) const
26 30 {
27 31 for (const auto &type : m_AcceptedMimeTypes) {
28 if (data->hasFormat(type)) {
32 if (data->hasFormat(type) && m_AcceptMimeDataFun(data)) {
29 33 return true;
30 34 }
31 35 }
@@ -121,10 +125,17 int VisualizationDragDropContainer::countDragWidget() const
121 125 return nbGraph;
122 126 }
123 127
128 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
129 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
130 {
131 impl->m_AcceptMimeDataFun = fun;
132 }
133
124 134 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
125 135 const QPoint &dragPosition)
126 136 {
127 137 auto &helper = sqpApp->dragDropHelper();
138 helper.resetDragAndDrop();
128 139
129 140 // Note: The management of the drag object is done by Qt
130 141 auto drag = new QDrag{dragWidget};
@@ -149,11 +160,16 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg
149 160 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex);
150 161 dragWidget->setVisible(false);
151 162 }
152 }
153 163
154 164 // Note: The exec() is blocking on windows but not on linux and macOS
155 165 drag->exec(Qt::MoveAction | Qt::CopyAction);
156 166 }
167 else {
168 qCWarning(LOG_VisualizationDragDropContainer())
169 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
170 "VisualizationDragWidget is not found in this container.");
171 }
172 }
157 173
158 174 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
159 175 {
@@ -164,20 +180,30 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
164 180
165 181 if (!impl->hasPlaceHolder()) {
166 182 auto dragWidget = helper.getCurrentDragWidget();
183
184 if (dragWidget) {
185 // If the drag&drop is internal to the visualization, entering the container hide
186 // the dragWidget which was hidden by the dragLeaveEvent
167 187 auto parentWidget
168 188 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
169 189 if (parentWidget) {
170 190 dragWidget->setVisible(false);
171 191 }
192 }
172 193
173 194 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
174 195
175 196 if (dragWidgetHovered) {
176 197 auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered);
198
199 if (dragWidget) {
177 200 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
178 201 if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) {
179 hoveredWidgetIndex
180 += 1; // Correction of the index if the drop occurs in the same container
202 // Correction of the index if the drop occurs in the same container
203 // and if the drag is started from the visualization (in that case, the
204 // dragWidget is hidden)
205 hoveredWidgetIndex += 1;
206 }
181 207 }
182 208
183 209 helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex);
@@ -186,6 +212,9 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
186 212 helper.insertPlaceHolder(impl->m_Layout, 0);
187 213 }
188 214 }
215 else {
216 // do nothing
217 }
189 218 }
190 219 else {
191 220 event->ignore();
@@ -203,19 +232,23 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
203 232 if (!impl->cursorIsInContainer(this)) {
204 233 helper.removePlaceHolder();
205 234
206 bool isInternal = true;
207 if (isInternal) {
208 // Only if the drag is started from the visualization
209 // Show the drag widget at its original place
235 auto dragWidget = helper.getCurrentDragWidget();
236 if (dragWidget) {
237 // dragWidget has a value only if the drag is started from the visualization
238 // In that case, shows the drag widget at its original place
210 239 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
211 240 // drop zone (It is not possible to catch a drop event outside of the application)
212 241
213 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
214 242 if (dragWidget) {
215 243 dragWidget->setVisible(true);
216 244 }
217 245 }
218 246 }
247 else {
248 // Leave event probably received for a child widget.
249 // Do nothing.
250 // Note: The DragLeave event, doesn't have any mean to determine who sent it.
251 }
219 252
220 253 QWidget::dragLeaveEvent(event);
221 254 }
@@ -244,10 +277,15 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
244 277 dropIndex += 1;
245 278 }
246 279
247 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
280 if (helper.getCurrentDragWidget()) {
281 auto dragWidgetIndex
282 = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
248 283 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
249 dropIndex += 1; // Correction of the index if the drop occurs in the same
250 // container
284 // Correction of the index if the drop occurs in the same container
285 // and if the drag is started from the visualization (in that case, the
286 // dragWidget is hidden)
287 dropIndex += 1;
288 }
251 289 }
252 290
253 291 if (dropIndex != placeHolderIndex) {
@@ -261,6 +299,15 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
261 299 }
262 300 }
263 301 }
302 else {
303 qCWarning(LOG_VisualizationDragDropContainer())
304 << tr("VisualizationDragDropContainer::dragMoveEvent, no widget found in the "
305 "container");
306 }
307 }
308 else {
309 // No hovered drag widget, the mouse is probably hover the placeHolder
310 // Do nothing
264 311 }
265 312 }
266 313 else {
@@ -274,18 +321,22 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
274 321 {
275 322 if (impl->acceptMimeData(event->mimeData())) {
276 323 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
277 if (impl->hasPlaceHolder() && dragWidget) {
324 if (impl->hasPlaceHolder()) {
278 325 auto &helper = sqpApp->dragDropHelper();
279 326
280 327 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
281 328
329 if (dragWidget) {
282 330 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
283 331 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
284 droppedIndex
285 -= 1; // Correction of the index if the drop occurs in the same container
332 // Correction of the index if the drop occurs in the same container
333 // and if the drag is started from the visualization (in that case, the
334 // dragWidget is hidden)
335 droppedIndex -= 1;
286 336 }
287 337
288 338 dragWidget->setVisible(true);
339 }
289 340
290 341 event->acceptProposedAction();
291 342
@@ -293,6 +344,12 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
293 344
294 345 emit dropOccured(droppedIndex, event->mimeData());
295 346 }
347 else {
348 qCWarning(LOG_VisualizationDragDropContainer())
349 << tr("VisualizationDragDropContainer::dropEvent, couldn't drop because the "
350 "placeHolder is not found.");
351 Q_ASSERT(false);
352 }
296 353 }
297 354 else {
298 355 event->ignore();
@@ -54,6 +54,11 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
54 54 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
55 55
56 56 QString m_Name;
57
58 void dropGraph(int index, VisualizationTabWidget *tabWidget);
59 void dropZone(int index, VisualizationTabWidget *tabWidget);
60 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
61 VisualizationTabWidget *tabWidget);
57 62 };
58 63
59 64 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
@@ -63,9 +68,14 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par
63 68 {
64 69 ui->setupUi(this);
65 70
66 ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH, MIME_TYPE_ZONE});
71 ui->dragDropContainer->setAcceptedMimeTypes(
72 {MIME_TYPE_GRAPH, MIME_TYPE_ZONE, MIME_TYPE_VARIABLE_LIST});
67 73 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
68 74 &VisualizationTabWidget::dropMimeData);
75 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
76 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
77 ui->dragDropContainer);
78 });
69 79 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
70 80
71 81 // Widget is deleted when closed
@@ -163,12 +173,46 QLayout &VisualizationTabWidget::tabLayout() const noexcept
163 173
164 174 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
165 175 {
166 auto &helper = sqpApp->dragDropHelper();
167 176 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
168 auto graphWidget = static_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
177 impl->dropGraph(index, this);
178 }
179 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
180 impl->dropZone(index, this);
181 }
182 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
183 auto variables = sqpApp->variableController().variablesForMimeData(
184 mimeData->data(MIME_TYPE_VARIABLE_LIST));
185 impl->dropVariables(variables, index, this);
186 }
187 else {
188 qCWarning(LOG_VisualizationZoneWidget())
189 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
190 }
191 }
192
193 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
194 int index, VisualizationTabWidget *tabWidget)
195 {
196 auto &helper = sqpApp->dragDropHelper();
197
198 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
199 if (!graphWidget) {
200 qCWarning(LOG_VisualizationZoneWidget())
201 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
202 "found or invalid.");
203 Q_ASSERT(false);
204 return;
205 }
206
169 207 auto parentDragDropContainer
170 208 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
171 Q_ASSERT(parentDragDropContainer);
209 if (!parentDragDropContainer) {
210 qCWarning(LOG_VisualizationZoneWidget())
211 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
212 "the dropped graph is not found.");
213 Q_ASSERT(false);
214 return;
215 }
172 216
173 217 auto nbGraph = parentDragDropContainer->countDragWidget();
174 218
@@ -191,7 +235,7 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
191 235 graphWidget->close();
192 236 }
193 237
194 createZone(variables, index);
238 tabWidget->createZone(variables, index);
195 239 }
196 240 else {
197 241 // The graph is empty, create an empty zone and move the graph inside
@@ -200,7 +244,7 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
200 244
201 245 parentDragDropContainer->layout()->removeWidget(graphWidget);
202 246
203 auto zoneWidget = createEmptyZone(index);
247 auto zoneWidget = tabWidget->createEmptyZone(index);
204 248 zoneWidget->addGraph(graphWidget);
205 249
206 250 // Close the old zone if it was the only graph inside
@@ -209,12 +253,42 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
209 253 }
210 254 }
211 255 }
212 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
256
257 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
258 int index, VisualizationTabWidget *tabWidget)
259 {
260 auto &helper = sqpApp->dragDropHelper();
261
262 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
263 if (!zoneWidget) {
264 qCWarning(LOG_VisualizationZoneWidget())
265 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
266 "found or invalid.");
267 Q_ASSERT(false);
268 return;
269 }
270
271 auto parentDragDropContainer
272 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
273 if (!parentDragDropContainer) {
274 qCWarning(LOG_VisualizationZoneWidget())
275 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
276 "the dropped zone is not found.");
277 Q_ASSERT(false);
278 return;
279 }
280
213 281 // Simple move of the zone, no variable operation associated
214 auto zoneWidget = static_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
215 auto parentDragDropContainer = zoneWidget->parentWidget();
216 282 parentDragDropContainer->layout()->removeWidget(zoneWidget);
217
218 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
283 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
219 284 }
285
286 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
287 const QList<std::shared_ptr<Variable> > &variables, int index,
288 VisualizationTabWidget *tabWidget)
289 {
290 // Note: we are sure that there is a single and compatible variable here
291 // because the AcceptMimeDataFunction, set on the drop container, makes the check before the
292 // drop can occur.
293 tabWidget->createZone(variables, index);
220 294 }
@@ -3,6 +3,7
3 3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 4 #include "Visualization/QCustomPlotSynchronizer.h"
5 5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationWidget.h"
6 7 #include "ui_VisualizationZoneWidget.h"
7 8
8 9 #include "Common/MimeTypesDef.h"
@@ -10,6 +11,8
10 11 #include <Variable/Variable.h>
11 12 #include <Variable/VariableController.h>
12 13
14 #include <Visualization/operations/FindVariableOperation.h>
15
13 16 #include <DragDropHelper.h>
14 17 #include <QUuid>
15 18 #include <SqpApplication.h>
@@ -67,6 +70,10 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
67 70 }
68 71 QUuid m_SynchronisationGroupId;
69 72 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
73
74 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
75 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
76 VisualizationZoneWidget *zoneWidget);
70 77 };
71 78
72 79 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
@@ -78,7 +85,11 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
78 85
79 86 ui->zoneNameLabel->setText(name);
80 87
81 ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH});
88 ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH, MIME_TYPE_VARIABLE_LIST});
89 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
90 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
91 ui->dragDropContainer);
92 });
82 93 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
83 94 &VisualizationZoneWidget::dropMimeData);
84 95
@@ -355,16 +366,47 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variabl
355 366
356 367 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
357 368 {
358 auto &helper = sqpApp->dragDropHelper();
359 369 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
360 auto graphWidget = static_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
370 impl->dropGraph(index, this);
371 }
372 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
373 auto variables = sqpApp->variableController().variablesForMimeData(
374 mimeData->data(MIME_TYPE_VARIABLE_LIST));
375 impl->dropVariables(variables, index, this);
376 }
377 else {
378 qCWarning(LOG_VisualizationZoneWidget())
379 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
380 }
381 }
382
383 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
384 int index, VisualizationZoneWidget *zoneWidget)
385 {
386 auto &helper = sqpApp->dragDropHelper();
387
388 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
389 if (!graphWidget) {
390 qCWarning(LOG_VisualizationZoneWidget())
391 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
392 "found or invalid.");
393 Q_ASSERT(false);
394 return;
395 }
396
361 397 auto parentDragDropContainer
362 398 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
363 Q_ASSERT(parentDragDropContainer);
399 if (!parentDragDropContainer) {
400 qCWarning(LOG_VisualizationZoneWidget())
401 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
402 "the dropped graph is not found.");
403 Q_ASSERT(false);
404 return;
405 }
364 406
365 407 const auto &variables = graphWidget->variables();
366 408
367 if (parentDragDropContainer != ui->dragDropContainer && !variables.isEmpty()) {
409 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
368 410 // The drop didn't occur in the same zone
369 411
370 412 // Abort the requests for the variables (if any)
@@ -386,17 +428,17 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
386 428 }
387 429
388 430 // Creates the new graph in the zone
389 createGraph(variables, index);
431 zoneWidget->createGraph(variables, index);
390 432 }
391 433 else {
392 434 // The drop occurred in the same zone or the graph is empty
393 435 // Simple move of the graph, no variable operation associated
394 436 parentDragDropContainer->layout()->removeWidget(graphWidget);
395 437
396 if (variables.isEmpty() && parentDragDropContainer != ui->dragDropContainer) {
438 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
397 439 // The graph is empty and dropped in a different zone.
398 440 // Take the range of the first graph in the zone (if existing).
399 auto layout = ui->dragDropContainer->layout();
441 auto layout = zoneWidget->ui->dragDropContainer->layout();
400 442 if (layout->count() > 0) {
401 443 if (auto visualizationGraphWidget
402 444 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
@@ -405,7 +447,38 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
405 447 }
406 448 }
407 449
408 ui->dragDropContainer->insertDragWidget(index, graphWidget);
450 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
451 }
452 }
453
454 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
455 const QList<std::shared_ptr<Variable> > &variables, int index,
456 VisualizationZoneWidget *zoneWidget)
457 {
458 // Search for the top level VisualizationWidget
459 auto parent = zoneWidget->parentWidget();
460 while (parent && qobject_cast<VisualizationWidget *>(parent) == nullptr) {
461 parent = parent->parentWidget();
462 }
463
464 if (!parent) {
465 qCWarning(LOG_VisualizationZoneWidget())
466 << tr("VisualizationZoneWidget::dropVariables, drop aborted, the parent "
467 "VisualizationWidget cannot be found.");
468 Q_ASSERT(false);
469 return;
470 }
471
472 auto visualizationWidget = static_cast<VisualizationWidget *>(parent);
473
474 // Search for the first variable which can be dropped
475 for (auto variable : variables) {
476 FindVariableOperation findVariableOperation{variable};
477 visualizationWidget->accept(&findVariableOperation);
478 auto variableContainers = findVariableOperation.result();
479 if (variableContainers.empty()) {
480 zoneWidget->createGraph(variable, index);
481 break;
409 482 }
410 483 }
411 484 }
General Comments 1
Under Review
author

Auto status change to "Under Review"

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