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