##// END OF EJS Templates
Manage drag&drop of empty graphs
trabillard -
r841:a582bf0b199a
parent child
Show More
@@ -1,72 +1,79
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
2 #define SCIQLOP_VISUALIZATIONTABWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <Common/spimpl.h>
6 #include <Common/spimpl.h>
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QWidget>
9 #include <QWidget>
10 #include <QMimeData>
10 #include <QMimeData>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationTabWidget)
13
13
14 class Variable;
14 class Variable;
15 class VisualizationZoneWidget;
15 class VisualizationZoneWidget;
16
16
17 namespace Ui {
17 namespace Ui {
18 class VisualizationTabWidget;
18 class VisualizationTabWidget;
19 } // namespace Ui
19 } // namespace Ui
20
20
21 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
21 class VisualizationTabWidget : public QWidget, public IVisualizationWidget {
22 Q_OBJECT
22 Q_OBJECT
23
23
24 public:
24 public:
25 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
25 explicit VisualizationTabWidget(const QString &name = {}, QWidget *parent = 0);
26 virtual ~VisualizationTabWidget();
26 virtual ~VisualizationTabWidget();
27
27
28 /// Add a zone widget
28 /// Add a zone widget
29 void addZone(VisualizationZoneWidget *zoneWidget);
29 void addZone(VisualizationZoneWidget *zoneWidget);
30
30
31 void insertZone(int index, VisualizationZoneWidget *zoneWidget);
31 void insertZone(int index, VisualizationZoneWidget *zoneWidget);
32
32
33 /**
33 /**
34 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
34 * Creates a zone using a variable. The variable will be displayed in a new graph of the new
35 * zone. The zone is added at the end.
35 * zone. The zone is added at the end.
36 * @param variable the variable for which to create the zone
36 * @param variable the variable for which to create the zone
37 * @return the pointer to the created zone
37 * @return the pointer to the created zone
38 */
38 */
39 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
39 VisualizationZoneWidget *createZone(std::shared_ptr<Variable> variable);
40
40
41 /**
41 /**
42 * Creates a zone using a list of variables. The variables will be displayed in a new graph of the new
42 * Creates a zone using a list of variables. The variables will be displayed in a new graph of the new
43 * zone. The zone is inserted at the specified index.
43 * zone. The zone is inserted at the specified index.
44 * @param variables the variables for which to create the zone
44 * @param variables the variables for which to create the zone
45 * @param index The index where the zone should be inserted in the layout
45 * @param index The index where the zone should be inserted in the layout
46 * @return the pointer to the created zone
46 * @return the pointer to the created zone
47 */
47 */
48 VisualizationZoneWidget *createZone(const QList<std::shared_ptr<Variable>>& variables, int index);
48 VisualizationZoneWidget *createZone(const QList<std::shared_ptr<Variable>>& variables, int index);
49
49
50 /**
51 * Creates a zone which is empty (no variables). The zone is inserted at the specified index.
52 * @param index The index where the zone should be inserted in the layout
53 * @return the pointer to the created zone
54 */
55 VisualizationZoneWidget *createEmptyZone(int index);
56
50 // IVisualizationWidget interface
57 // IVisualizationWidget interface
51 void accept(IVisualizationWidgetVisitor *visitor) override;
58 void accept(IVisualizationWidgetVisitor *visitor) override;
52 bool canDrop(const Variable &variable) const override;
59 bool canDrop(const Variable &variable) const override;
53 bool contains(const Variable &variable) const override;
60 bool contains(const Variable &variable) const override;
54 QString name() const override;
61 QString name() const override;
55
62
56 protected:
63 protected:
57 void closeEvent(QCloseEvent *event) override;
64 void closeEvent(QCloseEvent *event) override;
58
65
59 private:
66 private:
60 /// @return the layout of tab in which zones are added
67 /// @return the layout of tab in which zones are added
61 QLayout &tabLayout() const noexcept;
68 QLayout &tabLayout() const noexcept;
62
69
63 Ui::VisualizationTabWidget *ui;
70 Ui::VisualizationTabWidget *ui;
64
71
65 class VisualizationTabWidgetPrivate;
72 class VisualizationTabWidgetPrivate;
66 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
73 spimpl::unique_impl_ptr<VisualizationTabWidgetPrivate> impl;
67
74
68 private slots:
75 private slots:
69 void dropMimeData(int index, const QMimeData *mimeData);
76 void dropMimeData(int index, const QMimeData *mimeData);
70 };
77 };
71
78
72 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
79 #endif // SCIQLOP_VISUALIZATIONTABWIDGET_H
@@ -1,183 +1,212
1 #include "Visualization/VisualizationTabWidget.h"
1 #include "Visualization/VisualizationTabWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "ui_VisualizationTabWidget.h"
3 #include "ui_VisualizationTabWidget.h"
4
4
5 #include "Visualization/VisualizationZoneWidget.h"
5 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationGraphWidget.h"
6 #include "Visualization/VisualizationGraphWidget.h"
7
7
8 #include "Variable/VariableController.h"
9
8 #include "SqpApplication.h"
10 #include "SqpApplication.h"
9 #include "DragDropHelper.h"
11 #include "DragDropHelper.h"
10
12
11 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
13 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
12
14
13 namespace {
15 namespace {
14
16
15 /// Generates a default name for a new zone, according to the number of zones already displayed in
17 /// Generates a default name for a new zone, according to the number of zones already displayed in
16 /// the tab
18 /// the tab
17 QString defaultZoneName(const QLayout &layout)
19 QString defaultZoneName(const QLayout &layout)
18 {
20 {
19 auto count = 0;
21 auto count = 0;
20 for (auto i = 0; i < layout.count(); ++i) {
22 for (auto i = 0; i < layout.count(); ++i) {
21 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
23 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
22 count++;
24 count++;
23 }
25 }
24 }
26 }
25
27
26 return QObject::tr("Zone %1").arg(count + 1);
28 return QObject::tr("Zone %1").arg(count + 1);
27 }
29 }
28
30
29 /**
31 /**
30 * Applies a function to all zones of the tab represented by its layout
32 * Applies a function to all zones of the tab represented by its layout
31 * @param layout the layout that contains zones
33 * @param layout the layout that contains zones
32 * @param fun the function to apply to each zone
34 * @param fun the function to apply to each zone
33 */
35 */
34 template <typename Fun>
36 template <typename Fun>
35 void processZones(QLayout &layout, Fun fun)
37 void processZones(QLayout &layout, Fun fun)
36 {
38 {
37 for (auto i = 0; i < layout.count(); ++i) {
39 for (auto i = 0; i < layout.count(); ++i) {
38 if (auto item = layout.itemAt(i)) {
40 if (auto item = layout.itemAt(i)) {
39 if (auto visualizationZoneWidget
41 if (auto visualizationZoneWidget
40 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
42 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
41 fun(*visualizationZoneWidget);
43 fun(*visualizationZoneWidget);
42 }
44 }
43 }
45 }
44 }
46 }
45 }
47 }
46
48
47 } // namespace
49 } // namespace
48
50
49 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
51 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
50 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
52 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
51
53
52 QString m_Name;
54 QString m_Name;
53 };
55 };
54
56
55 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
57 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
56 : QWidget{parent},
58 : QWidget{parent},
57 ui{new Ui::VisualizationTabWidget},
59 ui{new Ui::VisualizationTabWidget},
58 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
60 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
59 {
61 {
60 ui->setupUi(this);
62 ui->setupUi(this);
61
63
62 ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH, DragDropHelper::MIME_TYPE_ZONE});
64 ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH, DragDropHelper::MIME_TYPE_ZONE});
63 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationTabWidget::dropMimeData);
65 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationTabWidget::dropMimeData);
64 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
66 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
65
67
66 // Widget is deleted when closed
68 // Widget is deleted when closed
67 setAttribute(Qt::WA_DeleteOnClose);
69 setAttribute(Qt::WA_DeleteOnClose);
68 }
70 }
69
71
70 VisualizationTabWidget::~VisualizationTabWidget()
72 VisualizationTabWidget::~VisualizationTabWidget()
71 {
73 {
72 sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea);
74 sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea);
73 delete ui;
75 delete ui;
74 }
76 }
75
77
76 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
78 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
77 {
79 {
78 ui->dragDropContainer->addDragWidget(zoneWidget);
80 ui->dragDropContainer->addDragWidget(zoneWidget);
79 }
81 }
80
82
81 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
83 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
82 {
84 {
83 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
85 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
84 }
86 }
85
87
86 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
88 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
87 {
89 {
88 return createZone({variable}, -1);
90 return createZone({variable}, -1);
89 }
91 }
90
92
91 VisualizationZoneWidget *VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
93 VisualizationZoneWidget *VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
92 {
94 {
93 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
95 auto zoneWidget = createEmptyZone(index);
94 this->insertZone(index, zoneWidget);
95
96
96 // Creates a new graph into the zone
97 // Creates a new graph into the zone
97 zoneWidget->createGraph(variables, index);
98 zoneWidget->createGraph(variables, index);
98
99
99 return zoneWidget;
100 return zoneWidget;
100 }
101 }
101
102
103 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
104 {
105 auto zoneWidget = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
106 this->insertZone(index, zoneWidget);
107
108 return zoneWidget;
109 }
110
102 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
111 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
103 {
112 {
104 if (visitor) {
113 if (visitor) {
105 visitor->visitEnter(this);
114 visitor->visitEnter(this);
106
115
107 // Apply visitor to zone children: widgets different from zones are not visited (no action)
116 // Apply visitor to zone children: widgets different from zones are not visited (no action)
108 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
117 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
109 zoneWidget.accept(visitor);
118 zoneWidget.accept(visitor);
110 });
119 });
111
120
112 visitor->visitLeave(this);
121 visitor->visitLeave(this);
113 }
122 }
114 else {
123 else {
115 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
124 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
116 }
125 }
117 }
126 }
118
127
119 bool VisualizationTabWidget::canDrop(const Variable &variable) const
128 bool VisualizationTabWidget::canDrop(const Variable &variable) const
120 {
129 {
121 // A tab can always accomodate a variable
130 // A tab can always accomodate a variable
122 Q_UNUSED(variable);
131 Q_UNUSED(variable);
123 return true;
132 return true;
124 }
133 }
125
134
126 bool VisualizationTabWidget::contains(const Variable &variable) const
135 bool VisualizationTabWidget::contains(const Variable &variable) const
127 {
136 {
128 Q_UNUSED(variable);
137 Q_UNUSED(variable);
129 return false;
138 return false;
130 }
139 }
131
140
132 QString VisualizationTabWidget::name() const
141 QString VisualizationTabWidget::name() const
133 {
142 {
134 return impl->m_Name;
143 return impl->m_Name;
135 }
144 }
136
145
137 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
146 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
138 {
147 {
139 // Closes zones in the tab
148 // Closes zones in the tab
140 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
149 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
141
150
142 QWidget::closeEvent(event);
151 QWidget::closeEvent(event);
143 }
152 }
144
153
145 QLayout &VisualizationTabWidget::tabLayout() const noexcept
154 QLayout &VisualizationTabWidget::tabLayout() const noexcept
146 {
155 {
147 return *ui->dragDropContainer->layout();
156 return *ui->dragDropContainer->layout();
148 }
157 }
149
158
150 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
159 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
151 {
160 {
152 auto& helper = sqpApp->dragDropHelper();
161 auto& helper = sqpApp->dragDropHelper();
153 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH))
162 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH))
154 {
163 {
155 auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
164 auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
156 auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
165 auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
157 Q_ASSERT(parentDragDropContainer);
166 Q_ASSERT(parentDragDropContainer);
158
167
159 auto nbGraph = parentDragDropContainer->countDragWidget();
168 auto nbGraph = parentDragDropContainer->countDragWidget();
160 if (nbGraph == 1)
169
170 const auto& variables = graphWidget->variables();
171
172 if (!variables.isEmpty())
161 {
173 {
162 //This is the only graph in the previous zone, close the zone
174 if (nbGraph == 1)
163 graphWidget->parentZoneWidget()->close();
175 {
176 //This is the only graph in the previous zone, close the zone
177 graphWidget->parentZoneWidget()->close();
178 }
179 else
180 {
181 //Close the graph
182 graphWidget->close();
183 }
184
185 createZone(variables, index);
164 }
186 }
165 else
187 else
166 {
188 {
167 //Close the graph
189 //The graph is empty, create an empty zone and move the graph inside
168 graphWidget->close();
169 }
170
190
171 const auto& variables = graphWidget->variables();
191 auto parentZoneWidget = graphWidget->parentZoneWidget();
172 createZone(variables, index);
192
193 parentDragDropContainer->layout()->removeWidget(graphWidget);
194
195 auto zoneWidget = createEmptyZone(index);
196 zoneWidget->addGraph(graphWidget);
197
198 //Close the old zone if it was the only graph inside
199 if (nbGraph == 1)
200 parentZoneWidget->close();
201 }
173 }
202 }
174 else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE))
203 else if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_ZONE))
175 {
204 {
176 //Simple move of the zone, no variable operation associated
205 //Simple move of the zone, no variable operation associated
177 auto zoneWidget = static_cast<VisualizationZoneWidget*>(helper.getCurrentDragWidget());
206 auto zoneWidget = static_cast<VisualizationZoneWidget*>(helper.getCurrentDragWidget());
178 auto parentDragDropContainer = zoneWidget->parentWidget();
207 auto parentDragDropContainer = zoneWidget->parentWidget();
179 parentDragDropContainer->layout()->removeWidget(zoneWidget);
208 parentDragDropContainer->layout()->removeWidget(zoneWidget);
180
209
181 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
210 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
182 }
211 }
183 }
212 }
@@ -1,394 +1,406
1 #include "Visualization/VisualizationZoneWidget.h"
1 #include "Visualization/VisualizationZoneWidget.h"
2
2
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 "ui_VisualizationZoneWidget.h"
6 #include "ui_VisualizationZoneWidget.h"
7
7
8 #include <Data/SqpRange.h>
8 #include <Data/SqpRange.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <QUuid>
12 #include <QUuid>
13 #include <SqpApplication.h>
13 #include <SqpApplication.h>
14 #include <DragDropHelper.h>
14 #include <DragDropHelper.h>
15 #include <cmath>
15 #include <cmath>
16
16
17 #include <QLayout>
17 #include <QLayout>
18
18
19 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
19 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
20
20
21 namespace {
21 namespace {
22
22
23 /// Minimum height for graph added in zones (in pixels)
23 /// Minimum height for graph added in zones (in pixels)
24 const auto GRAPH_MINIMUM_HEIGHT = 300;
24 const auto GRAPH_MINIMUM_HEIGHT = 300;
25
25
26 /// Generates a default name for a new graph, according to the number of graphs already displayed in
26 /// Generates a default name for a new graph, according to the number of graphs already displayed in
27 /// the zone
27 /// the zone
28 QString defaultGraphName(const QLayout &layout)
28 QString defaultGraphName(const QLayout &layout)
29 {
29 {
30 auto count = 0;
30 auto count = 0;
31 for (auto i = 0; i < layout.count(); ++i) {
31 for (auto i = 0; i < layout.count(); ++i) {
32 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
32 if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
33 count++;
33 count++;
34 }
34 }
35 }
35 }
36
36
37 return QObject::tr("Graph %1").arg(count + 1);
37 return QObject::tr("Graph %1").arg(count + 1);
38 }
38 }
39
39
40 /**
40 /**
41 * Applies a function to all graphs of the zone represented by its layout
41 * Applies a function to all graphs of the zone represented by its layout
42 * @param layout the layout that contains graphs
42 * @param layout the layout that contains graphs
43 * @param fun the function to apply to each graph
43 * @param fun the function to apply to each graph
44 */
44 */
45 template <typename Fun>
45 template <typename Fun>
46 void processGraphs(QLayout &layout, Fun fun)
46 void processGraphs(QLayout &layout, Fun fun)
47 {
47 {
48 for (auto i = 0; i < layout.count(); ++i) {
48 for (auto i = 0; i < layout.count(); ++i) {
49 if (auto item = layout.itemAt(i)) {
49 if (auto item = layout.itemAt(i)) {
50 if (auto visualizationGraphWidget
50 if (auto visualizationGraphWidget
51 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
51 = dynamic_cast<VisualizationGraphWidget *>(item->widget())) {
52 fun(*visualizationGraphWidget);
52 fun(*visualizationGraphWidget);
53 }
53 }
54 }
54 }
55 }
55 }
56 }
56 }
57
57
58 } // namespace
58 } // namespace
59
59
60 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
60 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
61
61
62 explicit VisualizationZoneWidgetPrivate()
62 explicit VisualizationZoneWidgetPrivate()
63 : m_SynchronisationGroupId{QUuid::createUuid()},
63 : m_SynchronisationGroupId{QUuid::createUuid()},
64 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
64 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
65 {
65 {
66 }
66 }
67 QUuid m_SynchronisationGroupId;
67 QUuid m_SynchronisationGroupId;
68 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
68 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
69 };
69 };
70
70
71 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
71 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
72 : VisualizationDragWidget{parent},
72 : VisualizationDragWidget{parent},
73 ui{new Ui::VisualizationZoneWidget},
73 ui{new Ui::VisualizationZoneWidget},
74 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
74 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
75 {
75 {
76 ui->setupUi(this);
76 ui->setupUi(this);
77
77
78 ui->zoneNameLabel->setText(name);
78 ui->zoneNameLabel->setText(name);
79
79
80 ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH});
80 ui->dragDropContainer->setAcceptedMimeTypes({DragDropHelper::MIME_TYPE_GRAPH});
81 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationZoneWidget::dropMimeData);
81 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccured, this, &VisualizationZoneWidget::dropMimeData);
82
82
83 // 'Close' options : widget is deleted when closed
83 // 'Close' options : widget is deleted when closed
84 setAttribute(Qt::WA_DeleteOnClose);
84 setAttribute(Qt::WA_DeleteOnClose);
85 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
85 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
86 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
86 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
87
87
88 // Synchronisation id
88 // Synchronisation id
89 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
89 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
90 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
90 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
91 }
91 }
92
92
93 VisualizationZoneWidget::~VisualizationZoneWidget()
93 VisualizationZoneWidget::~VisualizationZoneWidget()
94 {
94 {
95 delete ui;
95 delete ui;
96 }
96 }
97
97
98 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
98 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
99 {
99 {
100 // Synchronize new graph with others in the zone
100 // Synchronize new graph with others in the zone
101 impl->m_Synchronizer->addGraph(*graphWidget);
101 impl->m_Synchronizer->addGraph(*graphWidget);
102
102
103 ui->dragDropContainer->addDragWidget(graphWidget);
103 ui->dragDropContainer->addDragWidget(graphWidget);
104 }
104 }
105
105
106 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
106 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
107 {
107 {
108 // Synchronize new graph with others in the zone
108 // Synchronize new graph with others in the zone
109 impl->m_Synchronizer->addGraph(*graphWidget);
109 impl->m_Synchronizer->addGraph(*graphWidget);
110
110
111 ui->dragDropContainer->insertDragWidget(index, graphWidget);
111 ui->dragDropContainer->insertDragWidget(index, graphWidget);
112 }
112 }
113
113
114 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
114 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
115 {
115 {
116 return createGraph(variable, -1);
116 return createGraph(variable, -1);
117 }
117 }
118
118
119 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable, int index)
119 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable, int index)
120 {
120 {
121 auto graphWidget = new VisualizationGraphWidget{
121 auto graphWidget = new VisualizationGraphWidget{
122 defaultGraphName(*ui->dragDropContainer->layout()), this};
122 defaultGraphName(*ui->dragDropContainer->layout()), this};
123
123
124
124
125 // Set graph properties
125 // Set graph properties
126 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
126 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
127 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
127 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
128
128
129
129
130 // Lambda to synchronize zone widget
130 // Lambda to synchronize zone widget
131 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
131 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
132 const SqpRange &oldGraphRange) {
132 const SqpRange &oldGraphRange) {
133
133
134 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
134 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
135 auto frameLayout = ui->dragDropContainer->layout();
135 auto frameLayout = ui->dragDropContainer->layout();
136 for (auto i = 0; i < frameLayout->count(); ++i) {
136 for (auto i = 0; i < frameLayout->count(); ++i) {
137 auto graphChild
137 auto graphChild
138 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
138 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
139 if (graphChild && (graphChild != graphWidget)) {
139 if (graphChild && (graphChild != graphWidget)) {
140
140
141 auto graphChildRange = graphChild->graphRange();
141 auto graphChildRange = graphChild->graphRange();
142 switch (zoomType) {
142 switch (zoomType) {
143 case AcquisitionZoomType::ZoomIn: {
143 case AcquisitionZoomType::ZoomIn: {
144 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
144 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
145 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
145 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
146 graphChildRange.m_TStart += deltaLeft;
146 graphChildRange.m_TStart += deltaLeft;
147 graphChildRange.m_TEnd -= deltaRight;
147 graphChildRange.m_TEnd -= deltaRight;
148 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
148 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
149 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
149 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
150 << deltaLeft;
150 << deltaLeft;
151 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
151 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
152 << deltaRight;
152 << deltaRight;
153 qCDebug(LOG_VisualizationZoneWidget())
153 qCDebug(LOG_VisualizationZoneWidget())
154 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
154 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
155
155
156 break;
156 break;
157 }
157 }
158
158
159 case AcquisitionZoomType::ZoomOut: {
159 case AcquisitionZoomType::ZoomOut: {
160 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
160 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
161 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
161 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
162 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
162 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
163 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
163 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
164 << deltaLeft;
164 << deltaLeft;
165 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
165 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
166 << deltaRight;
166 << deltaRight;
167 qCDebug(LOG_VisualizationZoneWidget())
167 qCDebug(LOG_VisualizationZoneWidget())
168 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
168 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
169 graphChildRange.m_TStart -= deltaLeft;
169 graphChildRange.m_TStart -= deltaLeft;
170 graphChildRange.m_TEnd += deltaRight;
170 graphChildRange.m_TEnd += deltaRight;
171 break;
171 break;
172 }
172 }
173 case AcquisitionZoomType::PanRight: {
173 case AcquisitionZoomType::PanRight: {
174 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
174 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
175 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
175 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
176 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
176 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
177 graphChildRange.m_TStart += deltaLeft;
177 graphChildRange.m_TStart += deltaLeft;
178 graphChildRange.m_TEnd += deltaRight;
178 graphChildRange.m_TEnd += deltaRight;
179 qCDebug(LOG_VisualizationZoneWidget())
179 qCDebug(LOG_VisualizationZoneWidget())
180 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
180 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
181 break;
181 break;
182 }
182 }
183 case AcquisitionZoomType::PanLeft: {
183 case AcquisitionZoomType::PanLeft: {
184 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
184 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
185 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
185 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
186 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
186 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
187 graphChildRange.m_TStart -= deltaLeft;
187 graphChildRange.m_TStart -= deltaLeft;
188 graphChildRange.m_TEnd -= deltaRight;
188 graphChildRange.m_TEnd -= deltaRight;
189 break;
189 break;
190 }
190 }
191 case AcquisitionZoomType::Unknown: {
191 case AcquisitionZoomType::Unknown: {
192 qCDebug(LOG_VisualizationZoneWidget())
192 qCDebug(LOG_VisualizationZoneWidget())
193 << tr("Impossible to synchronize: zoom type unknown");
193 << tr("Impossible to synchronize: zoom type unknown");
194 break;
194 break;
195 }
195 }
196 default:
196 default:
197 qCCritical(LOG_VisualizationZoneWidget())
197 qCCritical(LOG_VisualizationZoneWidget())
198 << tr("Impossible to synchronize: zoom type not take into account");
198 << tr("Impossible to synchronize: zoom type not take into account");
199 // No action
199 // No action
200 break;
200 break;
201 }
201 }
202 graphChild->enableAcquisition(false);
202 graphChild->enableAcquisition(false);
203 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
203 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
204 << graphChild->graphRange();
204 << graphChild->graphRange();
205 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
205 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
206 << graphChildRange;
206 << graphChildRange;
207 qCDebug(LOG_VisualizationZoneWidget())
207 qCDebug(LOG_VisualizationZoneWidget())
208 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
208 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
209 graphChild->setGraphRange(graphChildRange);
209 graphChild->setGraphRange(graphChildRange);
210 graphChild->enableAcquisition(true);
210 graphChild->enableAcquisition(true);
211 }
211 }
212 }
212 }
213 };
213 };
214
214
215 // connection for synchronization
215 // connection for synchronization
216 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
216 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
217 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
217 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
218 &VisualizationZoneWidget::onVariableAdded);
218 &VisualizationZoneWidget::onVariableAdded);
219 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
219 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
220 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
220 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
221
221
222 auto range = SqpRange{};
222 auto range = SqpRange{};
223
223
224 // Apply visitor to graph children
224 // Apply visitor to graph children
225 auto layout = ui->dragDropContainer->layout();
225 auto layout = ui->dragDropContainer->layout();
226 if (layout->count() > 0) {
226 if (layout->count() > 0) {
227 // Case of a new graph in a existant zone
227 // Case of a new graph in a existant zone
228 if (auto visualizationGraphWidget
228 if (auto visualizationGraphWidget
229 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
229 = dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
230 range = visualizationGraphWidget->graphRange();
230 range = visualizationGraphWidget->graphRange();
231 }
231 }
232 }
232 }
233 else {
233 else {
234 // Case of a new graph as the first of the zone
234 // Case of a new graph as the first of the zone
235 range = variable->range();
235 range = variable->range();
236 }
236 }
237
237
238 this->insertGraph(index, graphWidget);
238 this->insertGraph(index, graphWidget);
239
239
240 graphWidget->addVariable(variable, range);
240 graphWidget->addVariable(variable, range);
241
241
242 // get y using variable range
242 // get y using variable range
243 if (auto dataSeries = variable->dataSeries()) {
243 if (auto dataSeries = variable->dataSeries()) {
244 dataSeries->lockRead();
244 dataSeries->lockRead();
245 auto valuesBounds
245 auto valuesBounds
246 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
246 = dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
247 auto end = dataSeries->cend();
247 auto end = dataSeries->cend();
248 if (valuesBounds.first != end && valuesBounds.second != end) {
248 if (valuesBounds.first != end && valuesBounds.second != end) {
249 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
249 auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
250
250
251 auto minValue = rangeValue(valuesBounds.first->minValue());
251 auto minValue = rangeValue(valuesBounds.first->minValue());
252 auto maxValue = rangeValue(valuesBounds.second->maxValue());
252 auto maxValue = rangeValue(valuesBounds.second->maxValue());
253
253
254 graphWidget->setYRange(SqpRange{minValue, maxValue});
254 graphWidget->setYRange(SqpRange{minValue, maxValue});
255 }
255 }
256 dataSeries->unlock();
256 dataSeries->unlock();
257 }
257 }
258
258
259 return graphWidget;
259 return graphWidget;
260 }
260 }
261
261
262 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
262 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
263 {
263 {
264 if (variables.isEmpty())
264 if (variables.isEmpty())
265 return nullptr;
265 return nullptr;
266
266
267 auto graphWidget = createGraph(variables.first(), index);
267 auto graphWidget = createGraph(variables.first(), index);
268 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt)
268 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt)
269 {
269 {
270 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
270 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
271 }
271 }
272
272
273 return graphWidget;
273 return graphWidget;
274 }
274 }
275
275
276 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
276 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
277 {
277 {
278 if (visitor) {
278 if (visitor) {
279 visitor->visitEnter(this);
279 visitor->visitEnter(this);
280
280
281 // Apply visitor to graph children: widgets different from graphs are not visited (no
281 // Apply visitor to graph children: widgets different from graphs are not visited (no
282 // action)
282 // action)
283 processGraphs(
283 processGraphs(
284 *ui->dragDropContainer->layout(),
284 *ui->dragDropContainer->layout(),
285 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
285 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
286
286
287 visitor->visitLeave(this);
287 visitor->visitLeave(this);
288 }
288 }
289 else {
289 else {
290 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
290 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
291 }
291 }
292 }
292 }
293
293
294 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
294 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
295 {
295 {
296 // A tab can always accomodate a variable
296 // A tab can always accomodate a variable
297 Q_UNUSED(variable);
297 Q_UNUSED(variable);
298 return true;
298 return true;
299 }
299 }
300
300
301 bool VisualizationZoneWidget::contains(const Variable &variable) const
301 bool VisualizationZoneWidget::contains(const Variable &variable) const
302 {
302 {
303 Q_UNUSED(variable);
303 Q_UNUSED(variable);
304 return false;
304 return false;
305 }
305 }
306
306
307 QString VisualizationZoneWidget::name() const
307 QString VisualizationZoneWidget::name() const
308 {
308 {
309 return ui->zoneNameLabel->text();
309 return ui->zoneNameLabel->text();
310 }
310 }
311
311
312 QMimeData *VisualizationZoneWidget::mimeData() const
312 QMimeData *VisualizationZoneWidget::mimeData() const
313 {
313 {
314 auto *mimeData = new QMimeData;
314 auto *mimeData = new QMimeData;
315 mimeData->setData(DragDropHelper::MIME_TYPE_ZONE, QByteArray());
315 mimeData->setData(DragDropHelper::MIME_TYPE_ZONE, QByteArray());
316
316
317 return mimeData;
317 return mimeData;
318 }
318 }
319
319
320 bool VisualizationZoneWidget::isDragAllowed() const
320 bool VisualizationZoneWidget::isDragAllowed() const
321 {
321 {
322 return true;
322 return true;
323 }
323 }
324
324
325 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
325 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
326 {
326 {
327 // Closes graphs in the zone
327 // Closes graphs in the zone
328 processGraphs(*ui->dragDropContainer->layout(),
328 processGraphs(*ui->dragDropContainer->layout(),
329 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
329 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
330
330
331 // Delete synchronization group from variable controller
331 // Delete synchronization group from variable controller
332 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
332 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
333 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
333 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
334
334
335 QWidget::closeEvent(event);
335 QWidget::closeEvent(event);
336 }
336 }
337
337
338 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
338 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
339 {
339 {
340 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
340 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
341 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
341 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
342 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
342 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
343 }
343 }
344
344
345 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
345 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
346 {
346 {
347 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
347 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
348 Q_ARG(std::shared_ptr<Variable>, variable),
348 Q_ARG(std::shared_ptr<Variable>, variable),
349 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
349 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
350 }
350 }
351
351
352 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
352 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
353 {
353 {
354 auto& helper = sqpApp->dragDropHelper();
354 auto& helper = sqpApp->dragDropHelper();
355 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH))
355 if (mimeData->hasFormat(DragDropHelper::MIME_TYPE_GRAPH))
356 {
356 {
357 auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
357 auto graphWidget = static_cast<VisualizationGraphWidget*>(helper.getCurrentDragWidget());
358 auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
358 auto parentDragDropContainer = qobject_cast<VisualizationDragDropContainer*>(graphWidget->parentWidget());
359 Q_ASSERT(parentDragDropContainer);
359 Q_ASSERT(parentDragDropContainer);
360
360
361 const auto& variables = graphWidget->variables();
361 const auto& variables = graphWidget->variables();
362
362
363 if (!variables.empty())
363 if (parentDragDropContainer != ui->dragDropContainer && !variables.isEmpty())
364 {
364 {
365 if (parentDragDropContainer != ui->dragDropContainer)
365 //The drop didn't occur in the same zone
366 {
367 //The drop didn't occur in the same zone
368
366
369 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
367 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
370 auto nbGraph = parentDragDropContainer->countDragWidget();
368 auto nbGraph = parentDragDropContainer->countDragWidget();
371 if (nbGraph == 1)
369 if (nbGraph == 1)
372 {
370 {
373 //This is the only graph in the previous zone, close the zone
371 //This is the only graph in the previous zone, close the zone
374 previousParentZoneWidget->close();
372 previousParentZoneWidget->close();
375 }
376 else
377 {
378 //Close the graph
379 graphWidget->close();
380 }
381
382 //Creates the new graph in the zone
383 createGraph(variables, index);
384 }
373 }
385 else
374 else
386 {
375 {
387 //The drop occurred in the same zone
376 //Close the graph
388 //Simple move of the graph, no variable operation associated
377 graphWidget->close();
389 parentDragDropContainer->layout()->removeWidget(graphWidget);
390 ui->dragDropContainer->insertDragWidget(index, graphWidget);
391 }
378 }
379
380 //Creates the new graph in the zone
381 createGraph(variables, index);
382 }
383 else
384 {
385 //The drop occurred in the same zone or the graph is empty
386 //Simple move of the graph, no variable operation associated
387 parentDragDropContainer->layout()->removeWidget(graphWidget);
388
389 if (variables.isEmpty() && parentDragDropContainer != ui->dragDropContainer)
390 {
391 // The graph is empty and dropped in a different zone.
392 // Take the range of the first graph in the zone (if existing).
393 auto layout = ui->dragDropContainer->layout();
394 if (layout->count() > 0)
395 {
396 if (auto visualizationGraphWidget = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget()))
397 {
398 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
399 }
400 }
401 }
402
403 ui->dragDropContainer->insertDragWidget(index, graphWidget);
392 }
404 }
393 }
405 }
394 }
406 }
General Comments 0
You need to be logged in to leave comments. Login now