##// END OF EJS Templates
drop of variables in the visualization
trabillard -
r850:2e038915a77e
parent child
Show More
@@ -287,9 +287,11 QMimeData *VariableModel::mimeData(const QModelIndexList &indexes) const
287 QList<std::shared_ptr<Variable> > variableList;
287 QList<std::shared_ptr<Variable> > variableList;
288
288
289 for (const auto &index : indexes) {
289 for (const auto &index : indexes) {
290 auto variable = impl->m_Variables.at(index.row());
290 if (index.column() == 0) { // only the first column
291 if (variable.get() && index.isValid()) {
291 auto variable = impl->m_Variables.at(index.row());
292 variableList << variable;
292 if (variable.get() && index.isValid()) {
293 variableList << variable;
294 }
293 }
295 }
294 }
296 }
295
297
@@ -2,39 +2,23
2 #define SCIQLOP_DRAGDROPHELPER_H
2 #define SCIQLOP_DRAGDROPHELPER_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 #include <QWidget>
6 #include <QWidget>
6
7
7 class QVBoxLayout;
8 class QVBoxLayout;
8 class QScrollArea;
9 class QScrollArea;
9 class VisualizationDragWidget;
10 class VisualizationDragWidget;
11 class VisualizationDragDropContainer;
10 class QMimeData;
12 class QMimeData;
11
13
12 /**
14 Q_DECLARE_LOGGING_CATEGORY(LOG_DragDropHelper)
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 };
35
15
36 /**
16 /**
37 * @brief Helper class for drag&drop operations.
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 class DragDropHelper {
23 class DragDropHelper {
40 public:
24 public:
@@ -44,7 +28,15 public:
44 DragDropHelper();
28 DragDropHelper();
45 virtual ~DragDropHelper();
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 void setCurrentDragWidget(VisualizationDragWidget *dragWidget);
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 VisualizationDragWidget *getCurrentDragWidget() const;
40 VisualizationDragWidget *getCurrentDragWidget() const;
49
41
50 QWidget &placeHolder() const;
42 QWidget &placeHolder() const;
@@ -52,6 +44,10 public:
52 void removePlaceHolder();
44 void removePlaceHolder();
53 bool isPlaceHolderSet() const;
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 void addDragDropScrollArea(QScrollArea *scrollArea);
51 void addDragDropScrollArea(QScrollArea *scrollArea);
56 void removeDragDropScrollArea(QScrollArea *scrollArea);
52 void removeDragDropScrollArea(QScrollArea *scrollArea);
57
53
@@ -62,4 +58,28 private:
62 spimpl::unique_impl_ptr<DragDropHelperPrivate> impl;
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 #endif // SCIQLOP_DRAGDROPHELPER_H
85 #endif // SCIQLOP_DRAGDROPHELPER_H
@@ -45,7 +45,8 public:
45 VariableController &variableController() noexcept;
45 VariableController &variableController() noexcept;
46 VisualizationController &visualizationController() noexcept;
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 DragDropHelper &dragDropHelper() noexcept;
50 DragDropHelper &dragDropHelper() noexcept;
50
51
51 private:
52 private:
@@ -2,10 +2,15
2 #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
2 #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 #include <QMimeData>
6 #include <QMimeData>
6 #include <QVBoxLayout>
7 #include <QVBoxLayout>
7 #include <QWidget>
8 #include <QWidget>
8
9
10 #include <functional>
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer)
13
9 class VisualizationDragWidget;
14 class VisualizationDragWidget;
10
15
11 class VisualizationDragDropContainer : public QWidget {
16 class VisualizationDragDropContainer : public QWidget {
@@ -15,6 +20,8 signals:
15 void dropOccured(int dropIndex, const QMimeData *mimeData);
20 void dropOccured(int dropIndex, const QMimeData *mimeData);
16
21
17 public:
22 public:
23 using AcceptMimeDataFunction = std::function<bool(const QMimeData *mimeData)>;
24
18 VisualizationDragDropContainer(QWidget *parent = nullptr);
25 VisualizationDragDropContainer(QWidget *parent = nullptr);
19
26
20 void addDragWidget(VisualizationDragWidget *dragWidget);
27 void addDragWidget(VisualizationDragWidget *dragWidget);
@@ -25,6 +32,8 public:
25
32
26 int countDragWidget() const;
33 int countDragWidget() const;
27
34
35 void setAcceptMimeDataFunction(AcceptMimeDataFunction fun);
36
28 protected:
37 protected:
29 void dragEnterEvent(QDragEnterEvent *event);
38 void dragEnterEvent(QDragEnterEvent *event);
30 void dragLeaveEvent(QDragLeaveEvent *event);
39 void dragLeaveEvent(QDragLeaveEvent *event);
@@ -1,6 +1,14
1 #include "DragDropHelper.h"
1 #include "DragDropHelper.h"
2 #include "SqpApplication.h"
2 #include "SqpApplication.h"
3 #include "Visualization/VisualizationDragDropContainer.h"
3 #include "Visualization/VisualizationDragWidget.h"
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 #include <QDir>
13 #include <QDir>
6 #include <QDragEnterEvent>
14 #include <QDragEnterEvent>
@@ -13,6 +21,8
13 const int SCROLL_SPEED = 5;
21 const int SCROLL_SPEED = 5;
14 const int SCROLL_ZONE_SIZE = 50;
22 const int SCROLL_ZONE_SIZE = 50;
15
23
24 Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper")
25
16 struct DragDropScroller::DragDropScrollerPrivate {
26 struct DragDropScroller::DragDropScrollerPrivate {
17
27
18 QList<QScrollArea *> m_ScrollAreas;
28 QList<QScrollArea *> m_ScrollAreas;
@@ -156,7 +166,11 struct DragDropHelper::DragDropHelperPrivate {
156 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
166 m_PlaceHolder->setSizePolicy(m_CurrentDragWidget->sizePolicy());
157 }
167 }
158 else {
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 QFile::remove(impl->m_ImageTempUrl);
185 QFile::remove(impl->m_ImageTempUrl);
172 }
186 }
173
187
188 void DragDropHelper::resetDragAndDrop()
189 {
190 setCurrentDragWidget(nullptr);
191 }
192
174 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
193 void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget)
175 {
194 {
176 impl->m_CurrentDragWidget = dragWidget;
195 impl->m_CurrentDragWidget = dragWidget;
@@ -225,3 +244,46 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const
225 image.save(impl->m_ImageTempUrl);
244 image.save(impl->m_ImageTempUrl);
226 return QUrl::fromLocalFile(impl->m_ImageTempUrl);
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 #include <QStyledItemDelegate>
12 #include <QStyledItemDelegate>
13 #include <QWidgetAction>
13 #include <QWidgetAction>
14
14
15 #include <DragDropHelper.h>
15 #include <SqpApplication.h>
16 #include <SqpApplication.h>
16
17
17 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
18 Q_LOGGING_CATEGORY(LOG_VariableInspectorWidget, "VariableInspectorWidget")
@@ -151,6 +152,11 VariableInspectorWidget::VariableInspectorWidget(QWidget *parent)
151 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
152 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 connect(ui->tableView, &QTableView::customContextMenuRequested, this,
153 &VariableInspectorWidget::onTableMenuRequested);
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 VariableInspectorWidget::~VariableInspectorWidget()
162 VariableInspectorWidget::~VariableInspectorWidget()
@@ -10,11 +10,15
10 #include <cmath>
10 #include <cmath>
11 #include <memory>
11 #include <memory>
12
12
13 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
14
13 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
15 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
14
16
15 QVBoxLayout *m_Layout;
17 QVBoxLayout *m_Layout;
16 QStringList m_AcceptedMimeTypes;
18 QStringList m_AcceptedMimeTypes;
17 QStringList m_MergeAllowedMimeTypes;
19 QStringList m_MergeAllowedMimeTypes;
20 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
21 = [](auto mimeData) { return true; };
18
22
19 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
23 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
20 {
24 {
@@ -25,7 +29,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
25 bool acceptMimeData(const QMimeData *data) const
29 bool acceptMimeData(const QMimeData *data) const
26 {
30 {
27 for (const auto &type : m_AcceptedMimeTypes) {
31 for (const auto &type : m_AcceptedMimeTypes) {
28 if (data->hasFormat(type)) {
32 if (data->hasFormat(type) && m_AcceptMimeDataFun(data)) {
29 return true;
33 return true;
30 }
34 }
31 }
35 }
@@ -121,10 +125,17 int VisualizationDragDropContainer::countDragWidget() const
121 return nbGraph;
125 return nbGraph;
122 }
126 }
123
127
128 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
129 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
130 {
131 impl->m_AcceptMimeDataFun = fun;
132 }
133
124 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
134 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
125 const QPoint &dragPosition)
135 const QPoint &dragPosition)
126 {
136 {
127 auto &helper = sqpApp->dragDropHelper();
137 auto &helper = sqpApp->dragDropHelper();
138 helper.resetDragAndDrop();
128
139
129 // Note: The management of the drag object is done by Qt
140 // Note: The management of the drag object is done by Qt
130 auto drag = new QDrag{dragWidget};
141 auto drag = new QDrag{dragWidget};
@@ -149,10 +160,15 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidg
149 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex);
160 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex);
150 dragWidget->setVisible(false);
161 dragWidget->setVisible(false);
151 }
162 }
152 }
153
163
154 // Note: The exec() is blocking on windows but not on linux and macOS
164 // Note: The exec() is blocking on windows but not on linux and macOS
155 drag->exec(Qt::MoveAction | Qt::CopyAction);
165 drag->exec(Qt::MoveAction | Qt::CopyAction);
166 }
167 else {
168 qCWarning(LOG_VisualizationDragDropContainer())
169 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
170 "VisualizationDragWidget is not found in this container.");
171 }
156 }
172 }
157
173
158 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
174 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
@@ -164,20 +180,30 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
164
180
165 if (!impl->hasPlaceHolder()) {
181 if (!impl->hasPlaceHolder()) {
166 auto dragWidget = helper.getCurrentDragWidget();
182 auto dragWidget = helper.getCurrentDragWidget();
167 auto parentWidget
183
168 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
184 if (dragWidget) {
169 if (parentWidget) {
185 // If the drag&drop is internal to the visualization, entering the container hide
170 dragWidget->setVisible(false);
186 // the dragWidget which was hidden by the dragLeaveEvent
187 auto parentWidget
188 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
189 if (parentWidget) {
190 dragWidget->setVisible(false);
191 }
171 }
192 }
172
193
173 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
194 auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos());
174
195
175 if (dragWidgetHovered) {
196 if (dragWidgetHovered) {
176 auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered);
197 auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered);
177 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
198
178 if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) {
199 if (dragWidget) {
179 hoveredWidgetIndex
200 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
180 += 1; // Correction of the index if the drop occurs in the same container
201 if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) {
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 helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex);
209 helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex);
@@ -186,6 +212,9 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
186 helper.insertPlaceHolder(impl->m_Layout, 0);
212 helper.insertPlaceHolder(impl->m_Layout, 0);
187 }
213 }
188 }
214 }
215 else {
216 // do nothing
217 }
189 }
218 }
190 else {
219 else {
191 event->ignore();
220 event->ignore();
@@ -203,19 +232,23 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
203 if (!impl->cursorIsInContainer(this)) {
232 if (!impl->cursorIsInContainer(this)) {
204 helper.removePlaceHolder();
233 helper.removePlaceHolder();
205
234
206 bool isInternal = true;
235 auto dragWidget = helper.getCurrentDragWidget();
207 if (isInternal) {
236 if (dragWidget) {
208 // Only if the drag is started from the visualization
237 // dragWidget has a value only if the drag is started from the visualization
209 // Show the drag widget at its original place
238 // In that case, shows the drag widget at its original place
210 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
239 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
211 // drop zone (It is not possible to catch a drop event outside of the application)
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 if (dragWidget) {
242 if (dragWidget) {
215 dragWidget->setVisible(true);
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 QWidget::dragLeaveEvent(event);
253 QWidget::dragLeaveEvent(event);
221 }
254 }
@@ -244,10 +277,15 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
244 dropIndex += 1;
277 dropIndex += 1;
245 }
278 }
246
279
247 auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
280 if (helper.getCurrentDragWidget()) {
248 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
281 auto dragWidgetIndex
249 dropIndex += 1; // Correction of the index if the drop occurs in the same
282 = impl->m_Layout->indexOf(helper.getCurrentDragWidget());
250 // container
283 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
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 if (dropIndex != placeHolderIndex) {
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 else {
313 else {
@@ -274,18 +321,22 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
274 {
321 {
275 if (impl->acceptMimeData(event->mimeData())) {
322 if (impl->acceptMimeData(event->mimeData())) {
276 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
323 auto dragWidget = sqpApp->dragDropHelper().getCurrentDragWidget();
277 if (impl->hasPlaceHolder() && dragWidget) {
324 if (impl->hasPlaceHolder()) {
278 auto &helper = sqpApp->dragDropHelper();
325 auto &helper = sqpApp->dragDropHelper();
279
326
280 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
327 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
281
328
282 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
329 if (dragWidget) {
283 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
330 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
284 droppedIndex
331 if (dragWidgetIndex >= 0 && dragWidgetIndex < 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
286 }
333 // and if the drag is started from the visualization (in that case, the
334 // dragWidget is hidden)
335 droppedIndex -= 1;
336 }
287
337
288 dragWidget->setVisible(true);
338 dragWidget->setVisible(true);
339 }
289
340
290 event->acceptProposedAction();
341 event->acceptProposedAction();
291
342
@@ -293,6 +344,12 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
293
344
294 emit dropOccured(droppedIndex, event->mimeData());
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 else {
354 else {
298 event->ignore();
355 event->ignore();
@@ -54,6 +54,11 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
54 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
54 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
55
55
56 QString m_Name;
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 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
64 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
@@ -63,9 +68,14 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par
63 {
68 {
64 ui->setupUi(this);
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 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
73 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
68 &VisualizationTabWidget::dropMimeData);
74 &VisualizationTabWidget::dropMimeData);
75 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
76 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
77 ui->dragDropContainer);
78 });
69 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
79 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
70
80
71 // Widget is deleted when closed
81 // Widget is deleted when closed
@@ -163,58 +173,122 QLayout &VisualizationTabWidget::tabLayout() const noexcept
163
173
164 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
174 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
165 {
175 {
166 auto &helper = sqpApp->dragDropHelper();
167 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
176 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
168 auto graphWidget = static_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
177 impl->dropGraph(index, this);
169 auto parentDragDropContainer
178 }
170 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
179 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
171 Q_ASSERT(parentDragDropContainer);
180 impl->dropZone(index, this);
172
181 }
173 auto nbGraph = parentDragDropContainer->countDragWidget();
182 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
174
183 auto variables = sqpApp->variableController().variablesForMimeData(
175 const auto &variables = graphWidget->variables();
184 mimeData->data(MIME_TYPE_VARIABLE_LIST));
176
185 impl->dropVariables(variables, index, this);
177 if (!variables.isEmpty()) {
186 }
178 // Abort the requests for the variables (if any)
187 else {
179 // Commented, because it's not sure if it's needed or not
188 qCWarning(LOG_VisualizationZoneWidget())
180 // for (const auto& var : variables)
189 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
181 //{
190 }
182 // sqpApp->variableController().onAbortProgressRequested(var);
191 }
183 //}
192
184
193 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
185 if (nbGraph == 1) {
194 int index, VisualizationTabWidget *tabWidget)
186 // This is the only graph in the previous zone, close the zone
195 {
187 graphWidget->parentZoneWidget()->close();
196 auto &helper = sqpApp->dragDropHelper();
188 }
197
189 else {
198 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
190 // Close the graph
199 if (!graphWidget) {
191 graphWidget->close();
200 qCWarning(LOG_VisualizationZoneWidget())
192 }
201 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
202 "found or invalid.");
203 Q_ASSERT(false);
204 return;
205 }
206
207 auto parentDragDropContainer
208 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
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 }
216
217 auto nbGraph = parentDragDropContainer->countDragWidget();
193
218
194 createZone(variables, index);
219 const auto &variables = graphWidget->variables();
220
221 if (!variables.isEmpty()) {
222 // Abort the requests for the variables (if any)
223 // Commented, because it's not sure if it's needed or not
224 // for (const auto& var : variables)
225 //{
226 // sqpApp->variableController().onAbortProgressRequested(var);
227 //}
228
229 if (nbGraph == 1) {
230 // This is the only graph in the previous zone, close the zone
231 graphWidget->parentZoneWidget()->close();
195 }
232 }
196 else {
233 else {
197 // The graph is empty, create an empty zone and move the graph inside
234 // Close the graph
235 graphWidget->close();
236 }
198
237
199 auto parentZoneWidget = graphWidget->parentZoneWidget();
238 tabWidget->createZone(variables, index);
239 }
240 else {
241 // The graph is empty, create an empty zone and move the graph inside
200
242
201 parentDragDropContainer->layout()->removeWidget(graphWidget);
243 auto parentZoneWidget = graphWidget->parentZoneWidget();
202
244
203 auto zoneWidget = createEmptyZone(index);
245 parentDragDropContainer->layout()->removeWidget(graphWidget);
204 zoneWidget->addGraph(graphWidget);
205
246
206 // Close the old zone if it was the only graph inside
247 auto zoneWidget = tabWidget->createEmptyZone(index);
207 if (nbGraph == 1) {
248 zoneWidget->addGraph(graphWidget);
208 parentZoneWidget->close();
249
209 }
250 // Close the old zone if it was the only graph inside
251 if (nbGraph == 1) {
252 parentZoneWidget->close();
210 }
253 }
211 }
254 }
212 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
255 }
213 // Simple move of the zone, no variable operation associated
214 auto zoneWidget = static_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
215 auto parentDragDropContainer = zoneWidget->parentWidget();
216 parentDragDropContainer->layout()->removeWidget(zoneWidget);
217
256
218 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
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;
219 }
279 }
280
281 // Simple move of the zone, no variable operation associated
282 parentDragDropContainer->layout()->removeWidget(zoneWidget);
283 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
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 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/IVisualizationWidgetVisitor.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
4 #include "Visualization/QCustomPlotSynchronizer.h"
5 #include "Visualization/VisualizationGraphWidget.h"
5 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
7 #include "ui_VisualizationZoneWidget.h"
7
8
8 #include "Common/MimeTypesDef.h"
9 #include "Common/MimeTypesDef.h"
@@ -10,6 +11,8
10 #include <Variable/Variable.h>
11 #include <Variable/Variable.h>
11 #include <Variable/VariableController.h>
12 #include <Variable/VariableController.h>
12
13
14 #include <Visualization/operations/FindVariableOperation.h>
15
13 #include <DragDropHelper.h>
16 #include <DragDropHelper.h>
14 #include <QUuid>
17 #include <QUuid>
15 #include <SqpApplication.h>
18 #include <SqpApplication.h>
@@ -67,6 +70,10 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
67 }
70 }
68 QUuid m_SynchronisationGroupId;
71 QUuid m_SynchronisationGroupId;
69 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
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 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
79 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
@@ -78,7 +85,11 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
78
85
79 ui->zoneNameLabel->setText(name);
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 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
93 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this,
83 &VisualizationZoneWidget::dropMimeData);
94 &VisualizationZoneWidget::dropMimeData);
84
95
@@ -355,57 +366,119 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variabl
355
366
356 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
367 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
357 {
368 {
358 auto &helper = sqpApp->dragDropHelper();
359 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
369 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
360 auto graphWidget = static_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
370 impl->dropGraph(index, this);
361 auto parentDragDropContainer
371 }
362 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
372 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
363 Q_ASSERT(parentDragDropContainer);
373 auto variables = sqpApp->variableController().variablesForMimeData(
364
374 mimeData->data(MIME_TYPE_VARIABLE_LIST));
365 const auto &variables = graphWidget->variables();
375 impl->dropVariables(variables, index, this);
366
376 }
367 if (parentDragDropContainer != ui->dragDropContainer && !variables.isEmpty()) {
377 else {
368 // The drop didn't occur in the same zone
378 qCWarning(LOG_VisualizationZoneWidget())
369
379 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
370 // Abort the requests for the variables (if any)
380 }
371 // Commented, because it's not sure if it's needed or not
381 }
372 // for (const auto& var : variables)
382
373 //{
383 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
374 // sqpApp->variableController().onAbortProgressRequested(var);
384 int index, VisualizationZoneWidget *zoneWidget)
375 //}
385 {
376
386 auto &helper = sqpApp->dragDropHelper();
377 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
387
378 auto nbGraph = parentDragDropContainer->countDragWidget();
388 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
379 if (nbGraph == 1) {
389 if (!graphWidget) {
380 // This is the only graph in the previous zone, close the zone
390 qCWarning(LOG_VisualizationZoneWidget())
381 previousParentZoneWidget->close();
391 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
382 }
392 "found or invalid.");
383 else {
393 Q_ASSERT(false);
384 // Close the graph
394 return;
385 graphWidget->close();
395 }
386 }
396
397 auto parentDragDropContainer
398 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
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 }
406
407 const auto &variables = graphWidget->variables();
387
408
388 // Creates the new graph in the zone
409 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
389 createGraph(variables, index);
410 // The drop didn't occur in the same zone
411
412 // Abort the requests for the variables (if any)
413 // Commented, because it's not sure if it's needed or not
414 // for (const auto& var : variables)
415 //{
416 // sqpApp->variableController().onAbortProgressRequested(var);
417 //}
418
419 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
420 auto nbGraph = parentDragDropContainer->countDragWidget();
421 if (nbGraph == 1) {
422 // This is the only graph in the previous zone, close the zone
423 previousParentZoneWidget->close();
390 }
424 }
391 else {
425 else {
392 // The drop occurred in the same zone or the graph is empty
426 // Close the graph
393 // Simple move of the graph, no variable operation associated
427 graphWidget->close();
394 parentDragDropContainer->layout()->removeWidget(graphWidget);
428 }
395
429
396 if (variables.isEmpty() && parentDragDropContainer != ui->dragDropContainer) {
430 // Creates the new graph in the zone
397 // The graph is empty and dropped in a different zone.
431 zoneWidget->createGraph(variables, index);
398 // Take the range of the first graph in the zone (if existing).
432 }
399 auto layout = ui->dragDropContainer->layout();
433 else {
400 if (layout->count() > 0) {
434 // The drop occurred in the same zone or the graph is empty
401 if (auto visualizationGraphWidget
435 // Simple move of the graph, no variable operation associated
402 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
436 parentDragDropContainer->layout()->removeWidget(graphWidget);
403 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
437
404 }
438 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
439 // The graph is empty and dropped in a different zone.
440 // Take the range of the first graph in the zone (if existing).
441 auto layout = zoneWidget->ui->dragDropContainer->layout();
442 if (layout->count() > 0) {
443 if (auto visualizationGraphWidget
444 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
445 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
405 }
446 }
406 }
447 }
448 }
449
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);
407
473
408 ui->dragDropContainer->insertDragWidget(index, graphWidget);
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 0
You need to be logged in to leave comments. Login now