##// END OF EJS Templates
Closes all graphs of the selected zone in graph mode
trabillard -
r1307:47a361805173
parent child
Show More
@@ -1,103 +1,106
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
2 #define SCIQLOP_VISUALIZATIONZONEWIDGET_H
3
3
4 #include "Data/SqpRange.h"
4 #include "Data/SqpRange.h"
5 #include "Visualization/IVisualizationWidget.h"
5 #include "Visualization/IVisualizationWidget.h"
6 #include "Visualization/VisualizationDragWidget.h"
6 #include "Visualization/VisualizationDragWidget.h"
7
7
8 #include <QLoggingCategory>
8 #include <QLoggingCategory>
9 #include <QWidget>
9 #include <QWidget>
10
10
11 #include <memory>
11 #include <memory>
12
12
13 #include <Common/spimpl.h>
13 #include <Common/spimpl.h>
14
14
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
15 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationZoneWidget)
16
16
17 namespace Ui {
17 namespace Ui {
18 class VisualizationZoneWidget;
18 class VisualizationZoneWidget;
19 } // namespace Ui
19 } // namespace Ui
20
20
21 class Variable;
21 class Variable;
22 class VisualizationGraphWidget;
22 class VisualizationGraphWidget;
23
23
24 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget {
24 class VisualizationZoneWidget : public VisualizationDragWidget, public IVisualizationWidget {
25 Q_OBJECT
25 Q_OBJECT
26
26
27 public:
27 public:
28 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
28 explicit VisualizationZoneWidget(const QString &name = {}, QWidget *parent = 0);
29 virtual ~VisualizationZoneWidget();
29 virtual ~VisualizationZoneWidget();
30
30
31 /// Sets the range of the zone, only works if there is at least one graph in the zone
31 /// Sets the range of the zone, only works if there is at least one graph in the zone
32 /// Note: calibrations between graphs are lost.
32 /// Note: calibrations between graphs are lost.
33 void setZoneRange(const SqpRange &range);
33 void setZoneRange(const SqpRange &range);
34
34
35 /// Adds a graph widget
35 /// Adds a graph widget
36 void addGraph(VisualizationGraphWidget *graphWidget);
36 void addGraph(VisualizationGraphWidget *graphWidget);
37
37
38 /// Inserts a graph widget
38 /// Inserts a graph widget
39 void insertGraph(int index, VisualizationGraphWidget *graphWidget);
39 void insertGraph(int index, VisualizationGraphWidget *graphWidget);
40
40
41 /**
41 /**
42 * Creates a graph using a variable. The variable will be displayed in the new graph.
42 * Creates a graph using a variable. The variable will be displayed in the new graph.
43 * The graph is added at the end.
43 * The graph is added at the end.
44 * @param variable the variable for which to create the graph
44 * @param variable the variable for which to create the graph
45 * @return the pointer to the created graph
45 * @return the pointer to the created graph
46 */
46 */
47 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
47 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable);
48
48
49 /**
49 /**
50 * Creates a graph using a variable. The variable will be displayed in the new graph.
50 * Creates a graph using a variable. The variable will be displayed in the new graph.
51 * The graph is inserted at the specified index.
51 * The graph is inserted at the specified index.
52 * @param variable the variable for which to create the graph
52 * @param variable the variable for which to create the graph
53 * @param index The index where the graph should be inserted in the layout
53 * @param index The index where the graph should be inserted in the layout
54 * @return the pointer to the created graph
54 * @return the pointer to the created graph
55 */
55 */
56 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable, int index);
56 VisualizationGraphWidget *createGraph(std::shared_ptr<Variable> variable, int index);
57
57
58 /**
58 /**
59 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
59 * Creates a graph using a list of variables. The variables will be displayed in the new graph.
60 * The graph is inserted at the specified index.
60 * The graph is inserted at the specified index.
61 * @param variables List of variables to be added to the graph
61 * @param variables List of variables to be added to the graph
62 * @param index The index where the graph should be inserted in the layout
62 * @param index The index where the graph should be inserted in the layout
63 * @return the pointer to the created graph
63 * @return the pointer to the created graph
64 */
64 */
65 VisualizationGraphWidget *createGraph(const QList<std::shared_ptr<Variable> > variables,
65 VisualizationGraphWidget *createGraph(const QList<std::shared_ptr<Variable> > variables,
66 int index);
66 int index);
67
67
68 /// Returns the first graph in the zone or nullptr if there is no graph inside
68 /// Returns the first graph in the zone or nullptr if there is no graph inside
69 VisualizationGraphWidget *firstGraph() const;
69 VisualizationGraphWidget *firstGraph() const;
70
70
71 /// Closes all graphes inside the zone
72 void closeAllGraphs();
73
71 // IVisualizationWidget interface
74 // IVisualizationWidget interface
72 void accept(IVisualizationWidgetVisitor *visitor) override;
75 void accept(IVisualizationWidgetVisitor *visitor) override;
73 bool canDrop(const Variable &variable) const override;
76 bool canDrop(const Variable &variable) const override;
74 bool contains(const Variable &variable) const override;
77 bool contains(const Variable &variable) const override;
75 QString name() const override;
78 QString name() const override;
76
79
77 // VisualisationDragWidget
80 // VisualisationDragWidget
78 QMimeData *mimeData(const QPoint &position) const override;
81 QMimeData *mimeData(const QPoint &position) const override;
79 bool isDragAllowed() const override;
82 bool isDragAllowed() const override;
80
83
81 void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition,
84 void notifyMouseMoveInGraph(const QPointF &graphPosition, const QPointF &plotPosition,
82 VisualizationGraphWidget *graphWidget);
85 VisualizationGraphWidget *graphWidget);
83 void notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget);
86 void notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget);
84
87
85 protected:
88 protected:
86 void closeEvent(QCloseEvent *event) override;
89 void closeEvent(QCloseEvent *event) override;
87
90
88 private:
91 private:
89 Ui::VisualizationZoneWidget *ui;
92 Ui::VisualizationZoneWidget *ui;
90
93
91 class VisualizationZoneWidgetPrivate;
94 class VisualizationZoneWidgetPrivate;
92 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
95 spimpl::unique_impl_ptr<VisualizationZoneWidgetPrivate> impl;
93
96
94 private slots:
97 private slots:
95 void onVariableAdded(std::shared_ptr<Variable> variable);
98 void onVariableAdded(std::shared_ptr<Variable> variable);
96 /// Slot called when a variable is about to be removed from a graph contained in the zone
99 /// Slot called when a variable is about to be removed from a graph contained in the zone
97 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
100 void onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable);
98
101
99 void dropMimeData(int index, const QMimeData *mimeData);
102 void dropMimeData(int index, const QMimeData *mimeData);
100 void dropMimeDataOnGraph(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
103 void dropMimeDataOnGraph(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
101 };
104 };
102
105
103 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
106 #endif // SCIQLOP_VISUALIZATIONZONEWIDGET_H
@@ -1,590 +1,593
1 #include "Catalogue/CatalogueEventsWidget.h"
1 #include "Catalogue/CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
3
3
4 #include <Catalogue/CatalogueController.h>
4 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueEventsModel.h>
5 #include <Catalogue/CatalogueEventsModel.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
7 #include <CatalogueDao.h>
7 #include <CatalogueDao.h>
8 #include <DBCatalogue.h>
8 #include <DBCatalogue.h>
9 #include <DBEventProduct.h>
9 #include <DBEventProduct.h>
10 #include <DataSource/DataSourceController.h>
10 #include <DataSource/DataSourceController.h>
11 #include <DataSource/DataSourceItem.h>
11 #include <DataSource/DataSourceItem.h>
12 #include <SqpApplication.h>
12 #include <SqpApplication.h>
13 #include <Variable/Variable.h>
13 #include <Variable/Variable.h>
14 #include <Variable/VariableController.h>
14 #include <Variable/VariableController.h>
15 #include <Visualization/VisualizationGraphWidget.h>
15 #include <Visualization/VisualizationGraphWidget.h>
16 #include <Visualization/VisualizationTabWidget.h>
16 #include <Visualization/VisualizationTabWidget.h>
17 #include <Visualization/VisualizationWidget.h>
17 #include <Visualization/VisualizationWidget.h>
18 #include <Visualization/VisualizationZoneWidget.h>
18 #include <Visualization/VisualizationZoneWidget.h>
19
19
20 #include <QDialog>
20 #include <QDialog>
21 #include <QDialogButtonBox>
21 #include <QDialogButtonBox>
22 #include <QListWidget>
22 #include <QListWidget>
23 #include <QMessageBox>
23 #include <QMessageBox>
24
24
25 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
25 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
26
26
27 /// Fixed size of the validation column
27 /// Fixed size of the validation column
28 const auto VALIDATION_COLUMN_SIZE = 35;
28 const auto VALIDATION_COLUMN_SIZE = 35;
29
29
30 /// Percentage added to the range of a event when it is displayed
30 /// Percentage added to the range of a event when it is displayed
31 const auto EVENT_RANGE_MARGE = 30; // in %
31 const auto EVENT_RANGE_MARGE = 30; // in %
32
32
33 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
33 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
34
34
35 CatalogueEventsModel *m_Model = nullptr;
35 CatalogueEventsModel *m_Model = nullptr;
36 QStringList m_ZonesForTimeMode;
36 QStringList m_ZonesForTimeMode;
37 QString m_ZoneForGraphMode;
37 QString m_ZoneForGraphMode;
38 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
38 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
39 bool m_AllEventDisplayed = false;
39 bool m_AllEventDisplayed = false;
40 QVector<VisualizationGraphWidget *> m_CustomGraphs;
40 QVector<VisualizationGraphWidget *> m_CustomGraphs;
41
41
42 VisualizationWidget *m_VisualizationWidget = nullptr;
42 VisualizationWidget *m_VisualizationWidget = nullptr;
43
43
44 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
44 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
45 {
45 {
46 widget->ui->treeView->setSortingEnabled(false);
46 widget->ui->treeView->setSortingEnabled(false);
47 m_Model->setEvents(events);
47 m_Model->setEvents(events);
48 widget->ui->treeView->setSortingEnabled(true);
48 widget->ui->treeView->setSortingEnabled(true);
49
49
50 for (auto event : events) {
50 for (auto event : events) {
51 if (sqpApp->catalogueController().eventHasChanges(event)) {
51 if (sqpApp->catalogueController().eventHasChanges(event)) {
52 auto index = m_Model->indexOf(event);
52 auto index = m_Model->indexOf(event);
53 widget->setEventChanges(event, true);
53 widget->setEventChanges(event, true);
54 }
54 }
55 }
55 }
56 }
56 }
57
57
58 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
58 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
59 {
59 {
60 treeView->setSortingEnabled(false);
60 treeView->setSortingEnabled(false);
61 m_Model->addEvent(event);
61 m_Model->addEvent(event);
62 treeView->setSortingEnabled(true);
62 treeView->setSortingEnabled(true);
63 }
63 }
64
64
65 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
65 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
66 {
66 {
67 treeView->setSortingEnabled(false);
67 treeView->setSortingEnabled(false);
68 m_Model->removeEvent(event);
68 m_Model->removeEvent(event);
69 treeView->setSortingEnabled(true);
69 treeView->setSortingEnabled(true);
70 }
70 }
71
71
72 QStringList getAvailableVisualizationZoneList() const
72 QStringList getAvailableVisualizationZoneList() const
73 {
73 {
74 if (m_VisualizationWidget) {
74 if (m_VisualizationWidget) {
75 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
75 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
76 return tab->availableZoneWidgets();
76 return tab->availableZoneWidgets();
77 }
77 }
78 }
78 }
79
79
80 return QStringList{};
80 return QStringList{};
81 }
81 }
82
82
83 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
83 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
84 bool allowMultiSelection, const QPoint &location)
84 bool allowMultiSelection, const QPoint &location)
85 {
85 {
86 auto availableZones = getAvailableVisualizationZoneList();
86 auto availableZones = getAvailableVisualizationZoneList();
87 if (availableZones.isEmpty()) {
87 if (availableZones.isEmpty()) {
88 return QStringList{};
88 return QStringList{};
89 }
89 }
90
90
91 QDialog d(parent, Qt::Tool);
91 QDialog d(parent, Qt::Tool);
92 d.setWindowTitle("Choose a zone");
92 d.setWindowTitle("Choose a zone");
93 auto layout = new QVBoxLayout{&d};
93 auto layout = new QVBoxLayout{&d};
94 layout->setContentsMargins(0, 0, 0, 0);
94 layout->setContentsMargins(0, 0, 0, 0);
95 auto listWidget = new QListWidget{&d};
95 auto listWidget = new QListWidget{&d};
96 layout->addWidget(listWidget);
96 layout->addWidget(listWidget);
97
97
98 QSet<QListWidgetItem *> checkedItems;
98 QSet<QListWidgetItem *> checkedItems;
99 for (auto zone : availableZones) {
99 for (auto zone : availableZones) {
100 auto item = new QListWidgetItem{zone};
100 auto item = new QListWidgetItem{zone};
101 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
101 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
102 if (selectedZones.contains(zone)) {
102 if (selectedZones.contains(zone)) {
103 item->setCheckState(Qt::Checked);
103 item->setCheckState(Qt::Checked);
104 checkedItems << item;
104 checkedItems << item;
105 }
105 }
106 else {
106 else {
107 item->setCheckState(Qt::Unchecked);
107 item->setCheckState(Qt::Unchecked);
108 }
108 }
109
109
110 listWidget->addItem(item);
110 listWidget->addItem(item);
111 }
111 }
112
112
113 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
113 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
114 layout->addWidget(buttonBox);
114 layout->addWidget(buttonBox);
115
115
116 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
116 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
117 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
117 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
118
118
119 QObject::connect(listWidget, &QListWidget::itemChanged,
119 QObject::connect(listWidget, &QListWidget::itemChanged,
120 [&checkedItems, allowMultiSelection, listWidget](auto item) {
120 [&checkedItems, allowMultiSelection, listWidget](auto item) {
121 if (item->checkState() == Qt::Checked) {
121 if (item->checkState() == Qt::Checked) {
122 if (!allowMultiSelection) {
122 if (!allowMultiSelection) {
123 for (auto checkedItem : checkedItems) {
123 for (auto checkedItem : checkedItems) {
124 listWidget->blockSignals(true);
124 listWidget->blockSignals(true);
125 checkedItem->setCheckState(Qt::Unchecked);
125 checkedItem->setCheckState(Qt::Unchecked);
126 listWidget->blockSignals(false);
126 listWidget->blockSignals(false);
127 }
127 }
128
128
129 checkedItems.clear();
129 checkedItems.clear();
130 }
130 }
131 checkedItems << item;
131 checkedItems << item;
132 }
132 }
133 else {
133 else {
134 checkedItems.remove(item);
134 checkedItems.remove(item);
135 }
135 }
136 });
136 });
137
137
138 QStringList result;
138 QStringList result;
139
139
140 d.setMinimumWidth(120);
140 d.setMinimumWidth(120);
141 d.resize(d.minimumSizeHint());
141 d.resize(d.minimumSizeHint());
142 d.move(location);
142 d.move(location);
143 if (d.exec() == QDialog::Accepted) {
143 if (d.exec() == QDialog::Accepted) {
144 for (auto item : checkedItems) {
144 for (auto item : checkedItems) {
145 result += item->text();
145 result += item->text();
146 }
146 }
147 }
147 }
148 else {
148 else {
149 result = selectedZones;
149 result = selectedZones;
150 }
150 }
151
151
152 return result;
152 return result;
153 }
153 }
154
154
155 void updateForTimeMode(QTreeView *treeView)
155 void updateForTimeMode(QTreeView *treeView)
156 {
156 {
157 auto selectedRows = treeView->selectionModel()->selectedRows();
157 auto selectedRows = treeView->selectionModel()->selectedRows();
158
158
159 if (selectedRows.count() == 1) {
159 if (selectedRows.count() == 1) {
160 auto event = m_Model->getEvent(selectedRows.first());
160 auto event = m_Model->getEvent(selectedRows.first());
161 if (event) {
161 if (event) {
162 if (m_VisualizationWidget) {
162 if (m_VisualizationWidget) {
163 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
163 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
164
164
165 for (auto zoneName : m_ZonesForTimeMode) {
165 for (auto zoneName : m_ZonesForTimeMode) {
166 if (auto zone = tab->getZoneWithName(zoneName)) {
166 if (auto zone = tab->getZoneWithName(zoneName)) {
167 SqpRange eventRange;
167 SqpRange eventRange;
168 eventRange.m_TStart = event->getTStart();
168 eventRange.m_TStart = event->getTStart();
169 eventRange.m_TEnd = event->getTEnd();
169 eventRange.m_TEnd = event->getTEnd();
170 zone->setZoneRange(eventRange);
170 zone->setZoneRange(eventRange);
171 }
171 }
172 }
172 }
173 }
173 }
174 else {
174 else {
175 qCWarning(LOG_CatalogueEventsWidget())
175 qCWarning(LOG_CatalogueEventsWidget())
176 << "updateTimeZone: no tab found in the visualization";
176 << "updateTimeZone: no tab found in the visualization";
177 }
177 }
178 }
178 }
179 else {
179 else {
180 qCWarning(LOG_CatalogueEventsWidget())
180 qCWarning(LOG_CatalogueEventsWidget())
181 << "updateTimeZone: visualization widget not found";
181 << "updateTimeZone: visualization widget not found";
182 }
182 }
183 }
183 }
184 }
184 }
185 else {
185 else {
186 qCWarning(LOG_CatalogueEventsWidget())
186 qCWarning(LOG_CatalogueEventsWidget())
187 << "updateTimeZone: not compatible with multiple events selected";
187 << "updateTimeZone: not compatible with multiple events selected";
188 }
188 }
189 }
189 }
190
190
191 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
191 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
192 {
192 {
193 // Retrieves the range of each product and the maximum size
193 // Retrieves the range of each product and the maximum size
194 QVector<SqpRange> graphRanges;
194 QVector<SqpRange> graphRanges;
195 double maxDt = 0;
195 double maxDt = 0;
196 for (auto eventProduct : event->getEventProducts()) {
196 for (auto eventProduct : event->getEventProducts()) {
197 SqpRange eventRange;
197 SqpRange eventRange;
198 eventRange.m_TStart = eventProduct.getTStart();
198 eventRange.m_TStart = eventProduct.getTStart();
199 eventRange.m_TEnd = eventProduct.getTEnd();
199 eventRange.m_TEnd = eventProduct.getTEnd();
200 graphRanges << eventRange;
200 graphRanges << eventRange;
201
201
202 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
202 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
203 if (dt > maxDt) {
203 if (dt > maxDt) {
204 maxDt = dt;
204 maxDt = dt;
205 }
205 }
206 }
206 }
207
207
208 // Adds the marge
208 // Adds the marge
209 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
209 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
210
210
211 // Corrects the graph ranges so that they all have the same size
211 // Corrects the graph ranges so that they all have the same size
212 QVector<SqpRange> correctedGraphRanges;
212 QVector<SqpRange> correctedGraphRanges;
213 for (auto range : graphRanges) {
213 for (auto range : graphRanges) {
214 auto dt = range.m_TEnd - range.m_TStart;
214 auto dt = range.m_TEnd - range.m_TStart;
215 auto diff = qAbs((maxDt - dt) / 2.0);
215 auto diff = qAbs((maxDt - dt) / 2.0);
216
216
217 SqpRange correctedRange;
217 SqpRange correctedRange;
218 correctedRange.m_TStart = range.m_TStart - diff;
218 correctedRange.m_TStart = range.m_TStart - diff;
219 correctedRange.m_TEnd = range.m_TEnd + diff;
219 correctedRange.m_TEnd = range.m_TEnd + diff;
220
220
221 correctedGraphRanges << correctedRange;
221 correctedGraphRanges << correctedRange;
222 }
222 }
223
223
224 return correctedGraphRanges;
224 return correctedGraphRanges;
225 }
225 }
226
226
227 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
227 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
228 {
228 {
229 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
229 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
230 if (selectedRows.count() != 1) {
230 if (selectedRows.count() != 1) {
231 qCWarning(LOG_CatalogueEventsWidget())
231 qCWarning(LOG_CatalogueEventsWidget())
232 << "updateGraphMode: not compatible with multiple events selected";
232 << "updateGraphMode: not compatible with multiple events selected";
233 return;
233 return;
234 }
234 }
235
235
236 if (!m_VisualizationWidget) {
236 if (!m_VisualizationWidget) {
237 qCWarning(LOG_CatalogueEventsWidget())
237 qCWarning(LOG_CatalogueEventsWidget())
238 << "updateGraphMode: visualization widget not found";
238 << "updateGraphMode: visualization widget not found";
239 return;
239 return;
240 }
240 }
241
241
242 auto event = m_Model->getEvent(selectedRows.first());
242 auto event = m_Model->getEvent(selectedRows.first());
243 if (!event) {
243 if (!event) {
244 // A event product is probably selected
244 // A event product is probably selected
245 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
245 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
246 return;
246 return;
247 }
247 }
248
248
249 auto tab = m_VisualizationWidget->currentTabWidget();
249 auto tab = m_VisualizationWidget->currentTabWidget();
250 if (!tab) {
250 if (!tab) {
251 qCWarning(LOG_CatalogueEventsWidget())
251 qCWarning(LOG_CatalogueEventsWidget())
252 << "updateGraphMode: no tab found in the visualization";
252 << "updateGraphMode: no tab found in the visualization";
253 return;
253 return;
254 }
254 }
255
255
256 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
256 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
257 if (!zone) {
257 if (!zone) {
258 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
258 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
259 return;
259 return;
260 }
260 }
261
261
262 // Close the previous graph and delete the asociated variables
262 // Closes the previous graph and delete the asociated variables
263 for (auto graph : m_CustomGraphs) {
263 for (auto graph : m_CustomGraphs) {
264 graph->close();
264 graph->close();
265 auto variables = graph->variables().toVector();
265 auto variables = graph->variables().toVector();
266
266
267 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
267 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
268 Qt::QueuedConnection,
268 Qt::QueuedConnection,
269 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
269 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
270 }
270 }
271 m_CustomGraphs.clear();
271 m_CustomGraphs.clear();
272
272
273 // Closes the remaining graphs inside the zone
274 zone->closeAllGraphs();
275
273 // Calculates the range of each graph which will be created
276 // Calculates the range of each graph which will be created
274 auto graphRange = getGraphRanges(event);
277 auto graphRange = getGraphRanges(event);
275
278
276 // Loops through the event products and create the graph
279 // Loops through the event products and create the graph
277 auto itRange = graphRange.cbegin();
280 auto itRange = graphRange.cbegin();
278 for (auto eventProduct : event->getEventProducts()) {
281 for (auto eventProduct : event->getEventProducts()) {
279 auto productId = eventProduct.getProductId();
282 auto productId = eventProduct.getProductId();
280
283
281 auto range = *itRange;
284 auto range = *itRange;
282 ++itRange;
285 ++itRange;
283
286
284 SqpRange productRange;
287 SqpRange productRange;
285 productRange.m_TStart = eventProduct.getTStart();
288 productRange.m_TStart = eventProduct.getTStart();
286 productRange.m_TEnd = eventProduct.getTEnd();
289 productRange.m_TEnd = eventProduct.getTEnd();
287
290
288 auto context = new QObject{catalogueEventWidget};
291 auto context = new QObject{catalogueEventWidget};
289 QObject::connect(
292 QObject::connect(
290 &sqpApp->variableController(), &VariableController::variableAdded, context,
293 &sqpApp->variableController(), &VariableController::variableAdded, context,
291 [this, catalogueEventWidget, zone, context, event, range, productRange,
294 [this, catalogueEventWidget, zone, context, event, range, productRange,
292 productId](auto variable) {
295 productId](auto variable) {
293
296
294 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
297 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
295 == productId) {
298 == productId) {
296 auto graph = zone->createGraph(variable);
299 auto graph = zone->createGraph(variable);
297 graph->setAutoRangeOnVariableInitialization(false);
300 graph->setAutoRangeOnVariableInitialization(false);
298
301
299 auto selectionZone
302 auto selectionZone
300 = graph->addSelectionZone(event->getName(), productRange);
303 = graph->addSelectionZone(event->getName(), productRange);
301 emit catalogueEventWidget->selectionZoneAdded(event, productId,
304 emit catalogueEventWidget->selectionZoneAdded(event, productId,
302 selectionZone);
305 selectionZone);
303 m_CustomGraphs << graph;
306 m_CustomGraphs << graph;
304
307
305 graph->setGraphRange(range, true);
308 graph->setGraphRange(range, true);
306
309
307 // Removes the graph from the graph list if it is closed manually
310 // Removes the graph from the graph list if it is closed manually
308 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
311 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
309 [this, graph]() { m_CustomGraphs.removeAll(graph); });
312 [this, graph]() { m_CustomGraphs.removeAll(graph); });
310
313
311 delete context; // removes the connection
314 delete context; // removes the connection
312 }
315 }
313 },
316 },
314 Qt::QueuedConnection);
317 Qt::QueuedConnection);
315
318
316 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
319 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
317 "requestVariableFromProductIdKey", Qt::QueuedConnection,
320 "requestVariableFromProductIdKey", Qt::QueuedConnection,
318 Q_ARG(QString, productId));
321 Q_ARG(QString, productId));
319 }
322 }
320 }
323 }
321
324
322 void getSelectedItems(
325 void getSelectedItems(
323 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
326 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
324 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
327 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
325 {
328 {
326 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
329 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
327 auto itemType = m_Model->itemTypeOf(rowIndex);
330 auto itemType = m_Model->itemTypeOf(rowIndex);
328 if (itemType == CatalogueEventsModel::ItemType::Event) {
331 if (itemType == CatalogueEventsModel::ItemType::Event) {
329 events << m_Model->getEvent(rowIndex);
332 events << m_Model->getEvent(rowIndex);
330 }
333 }
331 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
334 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
332 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
335 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
333 m_Model->getEventProduct(rowIndex));
336 m_Model->getEventProduct(rowIndex));
334 }
337 }
335 }
338 }
336 }
339 }
337 };
340 };
338
341
339 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
342 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
340 : QWidget(parent),
343 : QWidget(parent),
341 ui(new Ui::CatalogueEventsWidget),
344 ui(new Ui::CatalogueEventsWidget),
342 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
345 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
343 {
346 {
344 ui->setupUi(this);
347 ui->setupUi(this);
345
348
346 impl->m_Model = new CatalogueEventsModel{this};
349 impl->m_Model = new CatalogueEventsModel{this};
347 ui->treeView->setModel(impl->m_Model);
350 ui->treeView->setModel(impl->m_Model);
348
351
349 ui->treeView->setSortingEnabled(true);
352 ui->treeView->setSortingEnabled(true);
350 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
353 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
351 ui->treeView->setDragEnabled(true);
354 ui->treeView->setDragEnabled(true);
352
355
353 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
356 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
354 if (checked) {
357 if (checked) {
355 ui->btnChart->setChecked(false);
358 ui->btnChart->setChecked(false);
356 impl->m_ZonesForTimeMode
359 impl->m_ZonesForTimeMode
357 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
360 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
358 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
361 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
359
362
360 impl->updateForTimeMode(ui->treeView);
363 impl->updateForTimeMode(ui->treeView);
361 }
364 }
362 });
365 });
363
366
364 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
367 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
365 if (checked) {
368 if (checked) {
366 ui->btnTime->setChecked(false);
369 ui->btnTime->setChecked(false);
367 impl->m_ZoneForGraphMode
370 impl->m_ZoneForGraphMode
368 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
371 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
369 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
372 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
370 .value(0);
373 .value(0);
371
374
372 impl->updateForGraphMode(this);
375 impl->updateForGraphMode(this);
373 }
376 }
374 });
377 });
375
378
376 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
379 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
377 QVector<std::shared_ptr<DBEvent> > events;
380 QVector<std::shared_ptr<DBEvent> > events;
378 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
381 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
379 impl->getSelectedItems(ui->treeView, events, eventProducts);
382 impl->getSelectedItems(ui->treeView, events, eventProducts);
380
383
381 if (!events.isEmpty() && eventProducts.isEmpty()) {
384 if (!events.isEmpty() && eventProducts.isEmpty()) {
382
385
383 if (QMessageBox::warning(this, tr("Remove Event(s)"),
386 if (QMessageBox::warning(this, tr("Remove Event(s)"),
384 tr("The selected event(s) will be permanently removed "
387 tr("The selected event(s) will be permanently removed "
385 "from the repository!\nAre you sure you want to continue?"),
388 "from the repository!\nAre you sure you want to continue?"),
386 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
389 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
387 == QMessageBox::Yes) {
390 == QMessageBox::Yes) {
388
391
389 for (auto event : events) {
392 for (auto event : events) {
390 sqpApp->catalogueController().removeEvent(event);
393 sqpApp->catalogueController().removeEvent(event);
391 impl->removeEvent(event, ui->treeView);
394 impl->removeEvent(event, ui->treeView);
392 }
395 }
393
396
394 emit this->eventsRemoved(events);
397 emit this->eventsRemoved(events);
395 }
398 }
396 }
399 }
397 });
400 });
398
401
399 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
402 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
400 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
403 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
401 &CatalogueEventsWidget::emitSelection);
404 &CatalogueEventsWidget::emitSelection);
402
405
403 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
406 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
404 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
407 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
405 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
408 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
406 ui->btnChart->setEnabled(isNotMultiSelection);
409 ui->btnChart->setEnabled(isNotMultiSelection);
407 ui->btnTime->setEnabled(isNotMultiSelection);
410 ui->btnTime->setEnabled(isNotMultiSelection);
408
411
409 if (isNotMultiSelection && ui->btnTime->isChecked()) {
412 if (isNotMultiSelection && ui->btnTime->isChecked()) {
410 impl->updateForTimeMode(ui->treeView);
413 impl->updateForTimeMode(ui->treeView);
411 }
414 }
412 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
415 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
413 impl->updateForGraphMode(this);
416 impl->updateForGraphMode(this);
414 }
417 }
415
418
416 QVector<std::shared_ptr<DBEvent> > events;
419 QVector<std::shared_ptr<DBEvent> > events;
417 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
420 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
418 impl->getSelectedItems(ui->treeView, events, eventProducts);
421 impl->getSelectedItems(ui->treeView, events, eventProducts);
419 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
422 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
420 });
423 });
421
424
422 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
425 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
423 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
426 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
424 QHeaderView::Stretch);
427 QHeaderView::Stretch);
425 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
428 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
426 QHeaderView::Fixed);
429 QHeaderView::Fixed);
427 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
430 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
428 QHeaderView::Interactive);
431 QHeaderView::Interactive);
429 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
432 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
430 VALIDATION_COLUMN_SIZE);
433 VALIDATION_COLUMN_SIZE);
431 ui->treeView->header()->setSortIndicatorShown(true);
434 ui->treeView->header()->setSortIndicatorShown(true);
432
435
433 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
436 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
434 auto allEvents = impl->m_Model->events();
437 auto allEvents = impl->m_Model->events();
435 for (auto event : allEvents) {
438 for (auto event : allEvents) {
436 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
439 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
437 }
440 }
438 });
441 });
439
442
440 populateWithAllEvents();
443 populateWithAllEvents();
441 }
444 }
442
445
443 CatalogueEventsWidget::~CatalogueEventsWidget()
446 CatalogueEventsWidget::~CatalogueEventsWidget()
444 {
447 {
445 delete ui;
448 delete ui;
446 }
449 }
447
450
448 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
451 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
449 {
452 {
450 impl->m_VisualizationWidget = visualization;
453 impl->m_VisualizationWidget = visualization;
451 }
454 }
452
455
453 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
456 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
454 {
457 {
455 impl->addEvent(event, ui->treeView);
458 impl->addEvent(event, ui->treeView);
456 }
459 }
457
460
458 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
461 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
459 {
462 {
460 impl->m_Model->refreshEvent(event);
463 impl->m_Model->refreshEvent(event);
461
464
462 auto eventIndex = impl->m_Model->indexOf(event);
465 auto eventIndex = impl->m_Model->indexOf(event);
463 auto validationIndex
466 auto validationIndex
464 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
467 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
465
468
466 if (validationIndex.isValid()) {
469 if (validationIndex.isValid()) {
467 if (hasChanges) {
470 if (hasChanges) {
468 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
471 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
469 auto widget = CatalogueExplorerHelper::buildValidationWidget(
472 auto widget = CatalogueExplorerHelper::buildValidationWidget(
470 ui->treeView,
473 ui->treeView,
471 [this, event]() {
474 [this, event]() {
472 sqpApp->catalogueController().saveEvent(event);
475 sqpApp->catalogueController().saveEvent(event);
473 setEventChanges(event, false);
476 setEventChanges(event, false);
474 },
477 },
475 [this, event]() {
478 [this, event]() {
476 bool removed = false;
479 bool removed = false;
477 sqpApp->catalogueController().discardEvent(event, removed);
480 sqpApp->catalogueController().discardEvent(event, removed);
478 if (removed) {
481 if (removed) {
479 impl->m_Model->removeEvent(event);
482 impl->m_Model->removeEvent(event);
480 }
483 }
481 else {
484 else {
482 setEventChanges(event, false);
485 setEventChanges(event, false);
483 impl->m_Model->refreshEvent(event, true);
486 impl->m_Model->refreshEvent(event, true);
484 }
487 }
485 emitSelection();
488 emitSelection();
486 });
489 });
487 ui->treeView->setIndexWidget(validationIndex, widget);
490 ui->treeView->setIndexWidget(validationIndex, widget);
488 }
491 }
489 }
492 }
490 else {
493 else {
491 // Note: the widget is destroyed
494 // Note: the widget is destroyed
492 ui->treeView->setIndexWidget(validationIndex, nullptr);
495 ui->treeView->setIndexWidget(validationIndex, nullptr);
493 }
496 }
494 }
497 }
495 else {
498 else {
496 qCWarning(LOG_CatalogueEventsWidget())
499 qCWarning(LOG_CatalogueEventsWidget())
497 << "setEventChanges: the event is not displayed in the model.";
500 << "setEventChanges: the event is not displayed in the model.";
498 }
501 }
499 }
502 }
500
503
501 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
504 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
502 {
505 {
503 return impl->m_DisplayedCatalogues;
506 return impl->m_DisplayedCatalogues;
504 }
507 }
505
508
506 bool CatalogueEventsWidget::isAllEventsDisplayed() const
509 bool CatalogueEventsWidget::isAllEventsDisplayed() const
507 {
510 {
508 return impl->m_AllEventDisplayed;
511 return impl->m_AllEventDisplayed;
509 }
512 }
510
513
511 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
514 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
512 {
515 {
513 return impl->m_Model->indexOf(event).isValid();
516 return impl->m_Model->indexOf(event).isValid();
514 }
517 }
515
518
516 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
519 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
517 {
520 {
518 impl->m_Model->refreshEvent(event, true);
521 impl->m_Model->refreshEvent(event, true);
519 }
522 }
520
523
521 void CatalogueEventsWidget::populateWithCatalogues(
524 void CatalogueEventsWidget::populateWithCatalogues(
522 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
525 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
523 {
526 {
524 impl->m_DisplayedCatalogues = catalogues;
527 impl->m_DisplayedCatalogues = catalogues;
525 impl->m_AllEventDisplayed = false;
528 impl->m_AllEventDisplayed = false;
526
529
527 QSet<QUuid> eventIds;
530 QSet<QUuid> eventIds;
528 QVector<std::shared_ptr<DBEvent> > events;
531 QVector<std::shared_ptr<DBEvent> > events;
529
532
530 for (auto catalogue : catalogues) {
533 for (auto catalogue : catalogues) {
531 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
534 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
532 for (auto event : catalogueEvents) {
535 for (auto event : catalogueEvents) {
533 if (!eventIds.contains(event->getUniqId())) {
536 if (!eventIds.contains(event->getUniqId())) {
534 events << event;
537 events << event;
535 eventIds.insert(event->getUniqId());
538 eventIds.insert(event->getUniqId());
536 }
539 }
537 }
540 }
538 }
541 }
539
542
540 impl->setEvents(events, this);
543 impl->setEvents(events, this);
541 }
544 }
542
545
543 void CatalogueEventsWidget::populateWithAllEvents()
546 void CatalogueEventsWidget::populateWithAllEvents()
544 {
547 {
545 impl->m_DisplayedCatalogues.clear();
548 impl->m_DisplayedCatalogues.clear();
546 impl->m_AllEventDisplayed = true;
549 impl->m_AllEventDisplayed = true;
547
550
548 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
551 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
549
552
550 QVector<std::shared_ptr<DBEvent> > events;
553 QVector<std::shared_ptr<DBEvent> > events;
551 for (auto event : allEvents) {
554 for (auto event : allEvents) {
552 events << event;
555 events << event;
553 }
556 }
554
557
555 impl->setEvents(events, this);
558 impl->setEvents(events, this);
556 }
559 }
557
560
558 void CatalogueEventsWidget::clear()
561 void CatalogueEventsWidget::clear()
559 {
562 {
560 impl->m_DisplayedCatalogues.clear();
563 impl->m_DisplayedCatalogues.clear();
561 impl->m_AllEventDisplayed = false;
564 impl->m_AllEventDisplayed = false;
562 impl->setEvents({}, this);
565 impl->setEvents({}, this);
563 }
566 }
564
567
565 void CatalogueEventsWidget::refresh()
568 void CatalogueEventsWidget::refresh()
566 {
569 {
567 if (isAllEventsDisplayed()) {
570 if (isAllEventsDisplayed()) {
568 populateWithAllEvents();
571 populateWithAllEvents();
569 }
572 }
570 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
573 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
571 populateWithCatalogues(impl->m_DisplayedCatalogues);
574 populateWithCatalogues(impl->m_DisplayedCatalogues);
572 }
575 }
573 }
576 }
574
577
575 void CatalogueEventsWidget::emitSelection()
578 void CatalogueEventsWidget::emitSelection()
576 {
579 {
577 QVector<std::shared_ptr<DBEvent> > events;
580 QVector<std::shared_ptr<DBEvent> > events;
578 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
581 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
579 impl->getSelectedItems(ui->treeView, events, eventProducts);
582 impl->getSelectedItems(ui->treeView, events, eventProducts);
580
583
581 if (!events.isEmpty() && eventProducts.isEmpty()) {
584 if (!events.isEmpty() && eventProducts.isEmpty()) {
582 emit eventsSelected(events);
585 emit eventsSelected(events);
583 }
586 }
584 else if (events.isEmpty() && !eventProducts.isEmpty()) {
587 else if (events.isEmpty() && !eventProducts.isEmpty()) {
585 emit eventProductsSelected(eventProducts);
588 emit eventProductsSelected(eventProducts);
586 }
589 }
587 else {
590 else {
588 emit selectionCleared();
591 emit selectionCleared();
589 }
592 }
590 }
593 }
@@ -1,652 +1,658
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 <DataSource/DataSourceController.h>
13 #include <DataSource/DataSourceController.h>
14 #include <Time/TimeController.h>
14 #include <Time/TimeController.h>
15 #include <Variable/Variable.h>
15 #include <Variable/Variable.h>
16 #include <Variable/VariableController.h>
16 #include <Variable/VariableController.h>
17
17
18 #include <Visualization/operations/FindVariableOperation.h>
18 #include <Visualization/operations/FindVariableOperation.h>
19
19
20 #include <DragAndDrop/DragDropGuiController.h>
20 #include <DragAndDrop/DragDropGuiController.h>
21 #include <QUuid>
21 #include <QUuid>
22 #include <SqpApplication.h>
22 #include <SqpApplication.h>
23 #include <cmath>
23 #include <cmath>
24
24
25 #include <QLayout>
25 #include <QLayout>
26
26
27 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
27 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
28
28
29 namespace {
29 namespace {
30
30
31 /**
31 /**
32 * Applies a function to all graphs of the zone represented by its layout
32 * Applies a function to all graphs of the zone represented by its layout
33 * @param layout the layout that contains graphs
33 * @param layout the layout that contains graphs
34 * @param fun the function to apply to each graph
34 * @param fun the function to apply to each graph
35 */
35 */
36 template <typename Fun>
36 template <typename Fun>
37 void processGraphs(QLayout &layout, Fun fun)
37 void processGraphs(QLayout &layout, Fun fun)
38 {
38 {
39 for (auto i = 0; i < layout.count(); ++i) {
39 for (auto i = 0; i < layout.count(); ++i) {
40 if (auto item = layout.itemAt(i)) {
40 if (auto item = layout.itemAt(i)) {
41 if (auto visualizationGraphWidget
41 if (auto visualizationGraphWidget
42 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
42 = qobject_cast<VisualizationGraphWidget *>(item->widget())) {
43 fun(*visualizationGraphWidget);
43 fun(*visualizationGraphWidget);
44 }
44 }
45 }
45 }
46 }
46 }
47 }
47 }
48
48
49 /// Generates a default name for a new graph, according to the number of graphs already displayed in
49 /// Generates a default name for a new graph, according to the number of graphs already displayed in
50 /// the zone
50 /// the zone
51 QString defaultGraphName(QLayout &layout)
51 QString defaultGraphName(QLayout &layout)
52 {
52 {
53 QSet<QString> existingNames;
53 QSet<QString> existingNames;
54 processGraphs(
54 processGraphs(
55 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
55 layout, [&existingNames](auto &graphWidget) { existingNames.insert(graphWidget.name()); });
56
56
57 int zoneNum = 1;
57 int zoneNum = 1;
58 QString name;
58 QString name;
59 do {
59 do {
60 name = QObject::tr("Graph ").append(QString::number(zoneNum));
60 name = QObject::tr("Graph ").append(QString::number(zoneNum));
61 ++zoneNum;
61 ++zoneNum;
62 } while (existingNames.contains(name));
62 } while (existingNames.contains(name));
63
63
64 return name;
64 return name;
65 }
65 }
66
66
67 } // namespace
67 } // namespace
68
68
69 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
69 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
70
70
71 explicit VisualizationZoneWidgetPrivate()
71 explicit VisualizationZoneWidgetPrivate()
72 : m_SynchronisationGroupId{QUuid::createUuid()},
72 : m_SynchronisationGroupId{QUuid::createUuid()},
73 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
73 m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
74 {
74 {
75 }
75 }
76 QUuid m_SynchronisationGroupId;
76 QUuid m_SynchronisationGroupId;
77 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
77 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
78
78
79 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
79 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
80 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
80 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
81 VisualizationZoneWidget *zoneWidget);
81 VisualizationZoneWidget *zoneWidget);
82 void dropProducts(const QVariantList &productsData, int index,
82 void dropProducts(const QVariantList &productsData, int index,
83 VisualizationZoneWidget *zoneWidget);
83 VisualizationZoneWidget *zoneWidget);
84 };
84 };
85
85
86 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
86 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
87 : VisualizationDragWidget{parent},
87 : VisualizationDragWidget{parent},
88 ui{new Ui::VisualizationZoneWidget},
88 ui{new Ui::VisualizationZoneWidget},
89 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
89 impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
90 {
90 {
91 ui->setupUi(this);
91 ui->setupUi(this);
92
92
93 ui->zoneNameLabel->setText(name);
93 ui->zoneNameLabel->setText(name);
94
94
95 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
95 ui->dragDropContainer->setPlaceHolderType(DragDropGuiController::PlaceHolderType::Graph);
96 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
96 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
97 VisualizationDragDropContainer::DropBehavior::Inserted);
97 VisualizationDragDropContainer::DropBehavior::Inserted);
98 ui->dragDropContainer->setMimeType(
98 ui->dragDropContainer->setMimeType(
99 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
99 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
100 ui->dragDropContainer->setMimeType(
100 ui->dragDropContainer->setMimeType(
101 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
101 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
102 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
102 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
103 VisualizationDragDropContainer::DropBehavior::Merged);
103 VisualizationDragDropContainer::DropBehavior::Merged);
104 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
104 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
105 VisualizationDragDropContainer::DropBehavior::Forbidden);
105 VisualizationDragDropContainer::DropBehavior::Forbidden);
106 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
106 ui->dragDropContainer->setMimeType(MIME_TYPE_SELECTION_ZONE,
107 VisualizationDragDropContainer::DropBehavior::Forbidden);
107 VisualizationDragDropContainer::DropBehavior::Forbidden);
108 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
108 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
109 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
109 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
110 ui->dragDropContainer);
110 ui->dragDropContainer);
111 });
111 });
112
112
113 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
113 auto acceptDragWidgetFun = [](auto dragWidget, auto mimeData) {
114 if (!mimeData) {
114 if (!mimeData) {
115 return false;
115 return false;
116 }
116 }
117
117
118 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
118 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
119 auto variables = sqpApp->variableController().variablesForMimeData(
119 auto variables = sqpApp->variableController().variablesForMimeData(
120 mimeData->data(MIME_TYPE_VARIABLE_LIST));
120 mimeData->data(MIME_TYPE_VARIABLE_LIST));
121
121
122 if (variables.count() != 1) {
122 if (variables.count() != 1) {
123 return false;
123 return false;
124 }
124 }
125 auto variable = variables.first();
125 auto variable = variables.first();
126
126
127 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
127 if (auto graphWidget = dynamic_cast<const VisualizationGraphWidget *>(dragWidget)) {
128 return graphWidget->canDrop(*variable);
128 return graphWidget->canDrop(*variable);
129 }
129 }
130 }
130 }
131
131
132 return true;
132 return true;
133 };
133 };
134 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
134 ui->dragDropContainer->setAcceptDragWidgetFunction(acceptDragWidgetFun);
135
135
136 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
136 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
137 &VisualizationZoneWidget::dropMimeData);
137 &VisualizationZoneWidget::dropMimeData);
138 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
138 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredOnWidget, this,
139 &VisualizationZoneWidget::dropMimeDataOnGraph);
139 &VisualizationZoneWidget::dropMimeDataOnGraph);
140
140
141 // 'Close' options : widget is deleted when closed
141 // 'Close' options : widget is deleted when closed
142 setAttribute(Qt::WA_DeleteOnClose);
142 setAttribute(Qt::WA_DeleteOnClose);
143 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
143 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
144 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
144 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
145
145
146 // Synchronisation id
146 // Synchronisation id
147 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
147 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
148 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
148 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
149 }
149 }
150
150
151 VisualizationZoneWidget::~VisualizationZoneWidget()
151 VisualizationZoneWidget::~VisualizationZoneWidget()
152 {
152 {
153 delete ui;
153 delete ui;
154 }
154 }
155
155
156 void VisualizationZoneWidget::setZoneRange(const SqpRange &range)
156 void VisualizationZoneWidget::setZoneRange(const SqpRange &range)
157 {
157 {
158 if (auto graph = firstGraph()) {
158 if (auto graph = firstGraph()) {
159 graph->setGraphRange(range);
159 graph->setGraphRange(range);
160 }
160 }
161 else {
161 else {
162 qCWarning(LOG_VisualizationZoneWidget())
162 qCWarning(LOG_VisualizationZoneWidget())
163 << tr("setZoneRange:Cannot set the range of an empty zone.");
163 << tr("setZoneRange:Cannot set the range of an empty zone.");
164 }
164 }
165 }
165 }
166
166
167 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
167 void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
168 {
168 {
169 // Synchronize new graph with others in the zone
169 // Synchronize new graph with others in the zone
170 impl->m_Synchronizer->addGraph(*graphWidget);
170 impl->m_Synchronizer->addGraph(*graphWidget);
171
171
172 ui->dragDropContainer->addDragWidget(graphWidget);
172 ui->dragDropContainer->addDragWidget(graphWidget);
173 }
173 }
174
174
175 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
175 void VisualizationZoneWidget::insertGraph(int index, VisualizationGraphWidget *graphWidget)
176 {
176 {
177 // Synchronize new graph with others in the zone
177 // Synchronize new graph with others in the zone
178 impl->m_Synchronizer->addGraph(*graphWidget);
178 impl->m_Synchronizer->addGraph(*graphWidget);
179
179
180 ui->dragDropContainer->insertDragWidget(index, graphWidget);
180 ui->dragDropContainer->insertDragWidget(index, graphWidget);
181 }
181 }
182
182
183 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
183 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
184 {
184 {
185 return createGraph(variable, -1);
185 return createGraph(variable, -1);
186 }
186 }
187
187
188 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
188 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable,
189 int index)
189 int index)
190 {
190 {
191 auto graphWidget
191 auto graphWidget
192 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
192 = new VisualizationGraphWidget{defaultGraphName(*ui->dragDropContainer->layout()), this};
193
193
194
194
195 // Set graph properties
195 // Set graph properties
196 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
196 graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
197 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
197 graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
198
198
199
199
200 // Lambda to synchronize zone widget
200 // Lambda to synchronize zone widget
201 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
201 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
202 const SqpRange &oldGraphRange) {
202 const SqpRange &oldGraphRange) {
203
203
204 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
204 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
205 auto frameLayout = ui->dragDropContainer->layout();
205 auto frameLayout = ui->dragDropContainer->layout();
206 for (auto i = 0; i < frameLayout->count(); ++i) {
206 for (auto i = 0; i < frameLayout->count(); ++i) {
207 auto graphChild
207 auto graphChild
208 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
208 = dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
209 if (graphChild && (graphChild != graphWidget)) {
209 if (graphChild && (graphChild != graphWidget)) {
210
210
211 auto graphChildRange = graphChild->graphRange();
211 auto graphChildRange = graphChild->graphRange();
212 switch (zoomType) {
212 switch (zoomType) {
213 case AcquisitionZoomType::ZoomIn: {
213 case AcquisitionZoomType::ZoomIn: {
214 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
214 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
215 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
215 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
216 graphChildRange.m_TStart += deltaLeft;
216 graphChildRange.m_TStart += deltaLeft;
217 graphChildRange.m_TEnd -= deltaRight;
217 graphChildRange.m_TEnd -= deltaRight;
218 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
218 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
219 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
219 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
220 << deltaLeft;
220 << deltaLeft;
221 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
221 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
222 << deltaRight;
222 << deltaRight;
223 qCDebug(LOG_VisualizationZoneWidget())
223 qCDebug(LOG_VisualizationZoneWidget())
224 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
224 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
225
225
226 break;
226 break;
227 }
227 }
228
228
229 case AcquisitionZoomType::ZoomOut: {
229 case AcquisitionZoomType::ZoomOut: {
230 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
230 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
231 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
231 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
232 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
232 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
233 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
233 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
234 << deltaLeft;
234 << deltaLeft;
235 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
235 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
236 << deltaRight;
236 << deltaRight;
237 qCDebug(LOG_VisualizationZoneWidget())
237 qCDebug(LOG_VisualizationZoneWidget())
238 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
238 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
239 graphChildRange.m_TStart -= deltaLeft;
239 graphChildRange.m_TStart -= deltaLeft;
240 graphChildRange.m_TEnd += deltaRight;
240 graphChildRange.m_TEnd += deltaRight;
241 break;
241 break;
242 }
242 }
243 case AcquisitionZoomType::PanRight: {
243 case AcquisitionZoomType::PanRight: {
244 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
244 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
245 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
245 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
246 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
246 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
247 graphChildRange.m_TStart += deltaLeft;
247 graphChildRange.m_TStart += deltaLeft;
248 graphChildRange.m_TEnd += deltaRight;
248 graphChildRange.m_TEnd += deltaRight;
249 qCDebug(LOG_VisualizationZoneWidget())
249 qCDebug(LOG_VisualizationZoneWidget())
250 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
250 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
251 break;
251 break;
252 }
252 }
253 case AcquisitionZoomType::PanLeft: {
253 case AcquisitionZoomType::PanLeft: {
254 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
254 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
255 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
255 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
256 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
256 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
257 graphChildRange.m_TStart -= deltaLeft;
257 graphChildRange.m_TStart -= deltaLeft;
258 graphChildRange.m_TEnd -= deltaRight;
258 graphChildRange.m_TEnd -= deltaRight;
259 break;
259 break;
260 }
260 }
261 case AcquisitionZoomType::Unknown: {
261 case AcquisitionZoomType::Unknown: {
262 qCDebug(LOG_VisualizationZoneWidget())
262 qCDebug(LOG_VisualizationZoneWidget())
263 << tr("Impossible to synchronize: zoom type unknown");
263 << tr("Impossible to synchronize: zoom type unknown");
264 break;
264 break;
265 }
265 }
266 default:
266 default:
267 qCCritical(LOG_VisualizationZoneWidget())
267 qCCritical(LOG_VisualizationZoneWidget())
268 << tr("Impossible to synchronize: zoom type not take into account");
268 << tr("Impossible to synchronize: zoom type not take into account");
269 // No action
269 // No action
270 break;
270 break;
271 }
271 }
272 graphChild->setFlags(GraphFlag::DisableAll);
272 graphChild->setFlags(GraphFlag::DisableAll);
273 qCDebug(LOG_VisualizationZoneWidget())
273 qCDebug(LOG_VisualizationZoneWidget())
274 << tr("TORM: Range before: ") << graphChild->graphRange();
274 << tr("TORM: Range before: ") << graphChild->graphRange();
275 qCDebug(LOG_VisualizationZoneWidget())
275 qCDebug(LOG_VisualizationZoneWidget())
276 << tr("TORM: Range after : ") << graphChildRange;
276 << tr("TORM: Range after : ") << graphChildRange;
277 qCDebug(LOG_VisualizationZoneWidget())
277 qCDebug(LOG_VisualizationZoneWidget())
278 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
278 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
279 graphChild->setGraphRange(graphChildRange);
279 graphChild->setGraphRange(graphChildRange);
280 graphChild->setFlags(GraphFlag::EnableAll);
280 graphChild->setFlags(GraphFlag::EnableAll);
281 }
281 }
282 }
282 }
283 };
283 };
284
284
285 // connection for synchronization
285 // connection for synchronization
286 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
286 connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
287 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
287 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
288 &VisualizationZoneWidget::onVariableAdded);
288 &VisualizationZoneWidget::onVariableAdded);
289 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
289 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
290 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
290 &VisualizationZoneWidget::onVariableAboutToBeRemoved);
291
291
292 auto range = SqpRange{};
292 auto range = SqpRange{};
293 if (auto firstGraph = this->firstGraph()) {
293 if (auto firstGraph = this->firstGraph()) {
294 // Case of a new graph in a existant zone
294 // Case of a new graph in a existant zone
295 range = firstGraph->graphRange();
295 range = firstGraph->graphRange();
296 }
296 }
297 else {
297 else {
298 // Case of a new graph as the first of the zone
298 // Case of a new graph as the first of the zone
299 range = variable->range();
299 range = variable->range();
300 }
300 }
301
301
302 this->insertGraph(index, graphWidget);
302 this->insertGraph(index, graphWidget);
303
303
304 graphWidget->addVariable(variable, range);
304 graphWidget->addVariable(variable, range);
305 graphWidget->setYRange(variable);
305 graphWidget->setYRange(variable);
306
306
307 return graphWidget;
307 return graphWidget;
308 }
308 }
309
309
310 VisualizationGraphWidget *
310 VisualizationGraphWidget *
311 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
311 VisualizationZoneWidget::createGraph(const QList<std::shared_ptr<Variable> > variables, int index)
312 {
312 {
313 if (variables.isEmpty()) {
313 if (variables.isEmpty()) {
314 return nullptr;
314 return nullptr;
315 }
315 }
316
316
317 auto graphWidget = createGraph(variables.first(), index);
317 auto graphWidget = createGraph(variables.first(), index);
318 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
318 for (auto variableIt = variables.cbegin() + 1; variableIt != variables.cend(); ++variableIt) {
319 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
319 graphWidget->addVariable(*variableIt, graphWidget->graphRange());
320 }
320 }
321
321
322 return graphWidget;
322 return graphWidget;
323 }
323 }
324
324
325 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
325 VisualizationGraphWidget *VisualizationZoneWidget::firstGraph() const
326 {
326 {
327 VisualizationGraphWidget *firstGraph = nullptr;
327 VisualizationGraphWidget *firstGraph = nullptr;
328 auto layout = ui->dragDropContainer->layout();
328 auto layout = ui->dragDropContainer->layout();
329 if (layout->count() > 0) {
329 if (layout->count() > 0) {
330 if (auto visualizationGraphWidget
330 if (auto visualizationGraphWidget
331 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
331 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
332 firstGraph = visualizationGraphWidget;
332 firstGraph = visualizationGraphWidget;
333 }
333 }
334 }
334 }
335
335
336 return firstGraph;
336 return firstGraph;
337 }
337 }
338
338
339 void VisualizationZoneWidget::closeAllGraphs()
340 {
341 processGraphs(*ui->dragDropContainer->layout(),
342 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
343 }
344
339 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
345 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
340 {
346 {
341 if (visitor) {
347 if (visitor) {
342 visitor->visitEnter(this);
348 visitor->visitEnter(this);
343
349
344 // Apply visitor to graph children: widgets different from graphs are not visited (no
350 // Apply visitor to graph children: widgets different from graphs are not visited (no
345 // action)
351 // action)
346 processGraphs(
352 processGraphs(
347 *ui->dragDropContainer->layout(),
353 *ui->dragDropContainer->layout(),
348 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
354 [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
349
355
350 visitor->visitLeave(this);
356 visitor->visitLeave(this);
351 }
357 }
352 else {
358 else {
353 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
359 qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
354 }
360 }
355 }
361 }
356
362
357 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
363 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
358 {
364 {
359 // A tab can always accomodate a variable
365 // A tab can always accomodate a variable
360 Q_UNUSED(variable);
366 Q_UNUSED(variable);
361 return true;
367 return true;
362 }
368 }
363
369
364 bool VisualizationZoneWidget::contains(const Variable &variable) const
370 bool VisualizationZoneWidget::contains(const Variable &variable) const
365 {
371 {
366 Q_UNUSED(variable);
372 Q_UNUSED(variable);
367 return false;
373 return false;
368 }
374 }
369
375
370 QString VisualizationZoneWidget::name() const
376 QString VisualizationZoneWidget::name() const
371 {
377 {
372 return ui->zoneNameLabel->text();
378 return ui->zoneNameLabel->text();
373 }
379 }
374
380
375 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
381 QMimeData *VisualizationZoneWidget::mimeData(const QPoint &position) const
376 {
382 {
377 Q_UNUSED(position);
383 Q_UNUSED(position);
378
384
379 auto mimeData = new QMimeData;
385 auto mimeData = new QMimeData;
380 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
386 mimeData->setData(MIME_TYPE_ZONE, QByteArray{});
381
387
382 if (auto firstGraph = this->firstGraph()) {
388 if (auto firstGraph = this->firstGraph()) {
383 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
389 auto timeRangeData = TimeController::mimeDataForTimeRange(firstGraph->graphRange());
384 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
390 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
385 }
391 }
386
392
387 return mimeData;
393 return mimeData;
388 }
394 }
389
395
390 bool VisualizationZoneWidget::isDragAllowed() const
396 bool VisualizationZoneWidget::isDragAllowed() const
391 {
397 {
392 return true;
398 return true;
393 }
399 }
394
400
395 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
401 void VisualizationZoneWidget::notifyMouseMoveInGraph(const QPointF &graphPosition,
396 const QPointF &plotPosition,
402 const QPointF &plotPosition,
397 VisualizationGraphWidget *graphWidget)
403 VisualizationGraphWidget *graphWidget)
398 {
404 {
399 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
405 processGraphs(*ui->dragDropContainer->layout(), [&graphPosition, &plotPosition, &graphWidget](
400 VisualizationGraphWidget &processedGraph) {
406 VisualizationGraphWidget &processedGraph) {
401
407
402 switch (sqpApp->plotsCursorMode()) {
408 switch (sqpApp->plotsCursorMode()) {
403 case SqpApplication::PlotsCursorMode::Vertical:
409 case SqpApplication::PlotsCursorMode::Vertical:
404 processedGraph.removeHorizontalCursor();
410 processedGraph.removeHorizontalCursor();
405 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
411 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
406 break;
412 break;
407 case SqpApplication::PlotsCursorMode::Temporal:
413 case SqpApplication::PlotsCursorMode::Temporal:
408 processedGraph.addVerticalCursor(plotPosition.x());
414 processedGraph.addVerticalCursor(plotPosition.x());
409 processedGraph.removeHorizontalCursor();
415 processedGraph.removeHorizontalCursor();
410 break;
416 break;
411 case SqpApplication::PlotsCursorMode::Horizontal:
417 case SqpApplication::PlotsCursorMode::Horizontal:
412 processedGraph.removeVerticalCursor();
418 processedGraph.removeVerticalCursor();
413 if (&processedGraph == graphWidget) {
419 if (&processedGraph == graphWidget) {
414 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
420 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
415 }
421 }
416 else {
422 else {
417 processedGraph.removeHorizontalCursor();
423 processedGraph.removeHorizontalCursor();
418 }
424 }
419 break;
425 break;
420 case SqpApplication::PlotsCursorMode::Cross:
426 case SqpApplication::PlotsCursorMode::Cross:
421 if (&processedGraph == graphWidget) {
427 if (&processedGraph == graphWidget) {
422 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
428 processedGraph.addVerticalCursorAtViewportPosition(graphPosition.x());
423 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
429 processedGraph.addHorizontalCursorAtViewportPosition(graphPosition.y());
424 }
430 }
425 else {
431 else {
426 processedGraph.removeHorizontalCursor();
432 processedGraph.removeHorizontalCursor();
427 processedGraph.removeVerticalCursor();
433 processedGraph.removeVerticalCursor();
428 }
434 }
429 break;
435 break;
430 case SqpApplication::PlotsCursorMode::NoCursor:
436 case SqpApplication::PlotsCursorMode::NoCursor:
431 processedGraph.removeHorizontalCursor();
437 processedGraph.removeHorizontalCursor();
432 processedGraph.removeVerticalCursor();
438 processedGraph.removeVerticalCursor();
433 break;
439 break;
434 }
440 }
435
441
436
442
437 });
443 });
438 }
444 }
439
445
440 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
446 void VisualizationZoneWidget::notifyMouseLeaveGraph(VisualizationGraphWidget *graphWidget)
441 {
447 {
442 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
448 processGraphs(*ui->dragDropContainer->layout(), [](VisualizationGraphWidget &processedGraph) {
443 processedGraph.removeHorizontalCursor();
449 processedGraph.removeHorizontalCursor();
444 processedGraph.removeVerticalCursor();
450 processedGraph.removeVerticalCursor();
445 });
451 });
446 }
452 }
447
453
448 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
454 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
449 {
455 {
450 // Closes graphs in the zone
456 // Closes graphs in the zone
451 processGraphs(*ui->dragDropContainer->layout(),
457 processGraphs(*ui->dragDropContainer->layout(),
452 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
458 [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
453
459
454 // Delete synchronization group from variable controller
460 // Delete synchronization group from variable controller
455 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
461 QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
456 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
462 Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
457
463
458 QWidget::closeEvent(event);
464 QWidget::closeEvent(event);
459 }
465 }
460
466
461 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
467 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
462 {
468 {
463 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
469 QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
464 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
470 Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
465 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
471 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
466 }
472 }
467
473
468 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
474 void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
469 {
475 {
470 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
476 QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
471 Q_ARG(std::shared_ptr<Variable>, variable),
477 Q_ARG(std::shared_ptr<Variable>, variable),
472 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
478 Q_ARG(QUuid, impl->m_SynchronisationGroupId));
473 }
479 }
474
480
475 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
481 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
476 {
482 {
477 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
483 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
478 impl->dropGraph(index, this);
484 impl->dropGraph(index, this);
479 }
485 }
480 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
486 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
481 auto variables = sqpApp->variableController().variablesForMimeData(
487 auto variables = sqpApp->variableController().variablesForMimeData(
482 mimeData->data(MIME_TYPE_VARIABLE_LIST));
488 mimeData->data(MIME_TYPE_VARIABLE_LIST));
483 impl->dropVariables(variables, index, this);
489 impl->dropVariables(variables, index, this);
484 }
490 }
485 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
491 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
486 auto products = sqpApp->dataSourceController().productsDataForMimeData(
492 auto products = sqpApp->dataSourceController().productsDataForMimeData(
487 mimeData->data(MIME_TYPE_PRODUCT_LIST));
493 mimeData->data(MIME_TYPE_PRODUCT_LIST));
488 impl->dropProducts(products, index, this);
494 impl->dropProducts(products, index, this);
489 }
495 }
490 else {
496 else {
491 qCWarning(LOG_VisualizationZoneWidget())
497 qCWarning(LOG_VisualizationZoneWidget())
492 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
498 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
493 }
499 }
494 }
500 }
495
501
496 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
502 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragWidget,
497 const QMimeData *mimeData)
503 const QMimeData *mimeData)
498 {
504 {
499 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
505 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(dragWidget);
500 if (!graphWidget) {
506 if (!graphWidget) {
501 qCWarning(LOG_VisualizationZoneWidget())
507 qCWarning(LOG_VisualizationZoneWidget())
502 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
508 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, dropping in an unknown widget, "
503 "drop aborted");
509 "drop aborted");
504 Q_ASSERT(false);
510 Q_ASSERT(false);
505 return;
511 return;
506 }
512 }
507
513
508 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
514 if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
509 auto variables = sqpApp->variableController().variablesForMimeData(
515 auto variables = sqpApp->variableController().variablesForMimeData(
510 mimeData->data(MIME_TYPE_VARIABLE_LIST));
516 mimeData->data(MIME_TYPE_VARIABLE_LIST));
511 for (const auto &var : variables) {
517 for (const auto &var : variables) {
512 graphWidget->addVariable(var, graphWidget->graphRange());
518 graphWidget->addVariable(var, graphWidget->graphRange());
513 }
519 }
514 }
520 }
515 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
521 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
516 auto products = sqpApp->dataSourceController().productsDataForMimeData(
522 auto products = sqpApp->dataSourceController().productsDataForMimeData(
517 mimeData->data(MIME_TYPE_PRODUCT_LIST));
523 mimeData->data(MIME_TYPE_PRODUCT_LIST));
518
524
519 auto context = new QObject{this};
525 auto context = new QObject{this};
520 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
526 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
521 [this, graphWidget, context](auto variable) {
527 [this, graphWidget, context](auto variable) {
522 graphWidget->addVariable(variable, graphWidget->graphRange());
528 graphWidget->addVariable(variable, graphWidget->graphRange());
523 delete context; // removes the connection
529 delete context; // removes the connection
524 },
530 },
525 Qt::QueuedConnection);
531 Qt::QueuedConnection);
526
532
527 auto productData = products.first().toHash();
533 auto productData = products.first().toHash();
528 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
534 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
529 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
535 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
530 }
536 }
531 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
537 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
532 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
538 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
533 graphWidget->setGraphRange(range);
539 graphWidget->setGraphRange(range);
534 }
540 }
535 else {
541 else {
536 qCWarning(LOG_VisualizationZoneWidget())
542 qCWarning(LOG_VisualizationZoneWidget())
537 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
543 << tr("VisualizationZoneWidget::dropMimeDataOnGraph, unknown MIME data received.");
538 }
544 }
539 }
545 }
540
546
541 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
547 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropGraph(
542 int index, VisualizationZoneWidget *zoneWidget)
548 int index, VisualizationZoneWidget *zoneWidget)
543 {
549 {
544 auto &helper = sqpApp->dragDropGuiController();
550 auto &helper = sqpApp->dragDropGuiController();
545
551
546 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
552 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
547 if (!graphWidget) {
553 if (!graphWidget) {
548 qCWarning(LOG_VisualizationZoneWidget())
554 qCWarning(LOG_VisualizationZoneWidget())
549 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
555 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the dropped graph is not "
550 "found or invalid.");
556 "found or invalid.");
551 Q_ASSERT(false);
557 Q_ASSERT(false);
552 return;
558 return;
553 }
559 }
554
560
555 auto parentDragDropContainer
561 auto parentDragDropContainer
556 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
562 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
557 if (!parentDragDropContainer) {
563 if (!parentDragDropContainer) {
558 qCWarning(LOG_VisualizationZoneWidget())
564 qCWarning(LOG_VisualizationZoneWidget())
559 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
565 << tr("VisualizationZoneWidget::dropGraph, drop aborted, the parent container of "
560 "the dropped graph is not found.");
566 "the dropped graph is not found.");
561 Q_ASSERT(false);
567 Q_ASSERT(false);
562 return;
568 return;
563 }
569 }
564
570
565 const auto &variables = graphWidget->variables();
571 const auto &variables = graphWidget->variables();
566
572
567 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
573 if (parentDragDropContainer != zoneWidget->ui->dragDropContainer && !variables.isEmpty()) {
568 // The drop didn't occur in the same zone
574 // The drop didn't occur in the same zone
569
575
570 // Abort the requests for the variables (if any)
576 // Abort the requests for the variables (if any)
571 // Commented, because it's not sure if it's needed or not
577 // Commented, because it's not sure if it's needed or not
572 // for (const auto& var : variables)
578 // for (const auto& var : variables)
573 //{
579 //{
574 // sqpApp->variableController().onAbortProgressRequested(var);
580 // sqpApp->variableController().onAbortProgressRequested(var);
575 //}
581 //}
576
582
577 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
583 auto previousParentZoneWidget = graphWidget->parentZoneWidget();
578 auto nbGraph = parentDragDropContainer->countDragWidget();
584 auto nbGraph = parentDragDropContainer->countDragWidget();
579 if (nbGraph == 1) {
585 if (nbGraph == 1) {
580 // This is the only graph in the previous zone, close the zone
586 // This is the only graph in the previous zone, close the zone
581 helper.delayedCloseWidget(previousParentZoneWidget);
587 helper.delayedCloseWidget(previousParentZoneWidget);
582 }
588 }
583 else {
589 else {
584 // Close the graph
590 // Close the graph
585 helper.delayedCloseWidget(graphWidget);
591 helper.delayedCloseWidget(graphWidget);
586 }
592 }
587
593
588 // Creates the new graph in the zone
594 // Creates the new graph in the zone
589 auto newGraphWidget = zoneWidget->createGraph(variables, index);
595 auto newGraphWidget = zoneWidget->createGraph(variables, index);
590 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
596 newGraphWidget->addSelectionZones(graphWidget->selectionZoneRanges());
591 }
597 }
592 else {
598 else {
593 // The drop occurred in the same zone or the graph is empty
599 // The drop occurred in the same zone or the graph is empty
594 // Simple move of the graph, no variable operation associated
600 // Simple move of the graph, no variable operation associated
595 parentDragDropContainer->layout()->removeWidget(graphWidget);
601 parentDragDropContainer->layout()->removeWidget(graphWidget);
596
602
597 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
603 if (variables.isEmpty() && parentDragDropContainer != zoneWidget->ui->dragDropContainer) {
598 // The graph is empty and dropped in a different zone.
604 // The graph is empty and dropped in a different zone.
599 // Take the range of the first graph in the zone (if existing).
605 // Take the range of the first graph in the zone (if existing).
600 auto layout = zoneWidget->ui->dragDropContainer->layout();
606 auto layout = zoneWidget->ui->dragDropContainer->layout();
601 if (layout->count() > 0) {
607 if (layout->count() > 0) {
602 if (auto visualizationGraphWidget
608 if (auto visualizationGraphWidget
603 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
609 = qobject_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
604 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
610 graphWidget->setGraphRange(visualizationGraphWidget->graphRange());
605 }
611 }
606 }
612 }
607 }
613 }
608
614
609 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
615 zoneWidget->ui->dragDropContainer->insertDragWidget(index, graphWidget);
610 }
616 }
611 }
617 }
612
618
613 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
619 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
614 const QList<std::shared_ptr<Variable> > &variables, int index,
620 const QList<std::shared_ptr<Variable> > &variables, int index,
615 VisualizationZoneWidget *zoneWidget)
621 VisualizationZoneWidget *zoneWidget)
616 {
622 {
617 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
623 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
618 // compatible variable here
624 // compatible variable here
619 if (variables.count() > 1) {
625 if (variables.count() > 1) {
620 qCWarning(LOG_VisualizationZoneWidget())
626 qCWarning(LOG_VisualizationZoneWidget())
621 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
627 << tr("VisualizationZoneWidget::dropVariables, dropping multiple variables, operation "
622 "aborted.");
628 "aborted.");
623 return;
629 return;
624 }
630 }
625
631
626 zoneWidget->createGraph(variables, index);
632 zoneWidget->createGraph(variables, index);
627 }
633 }
628
634
629 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
635 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
630 const QVariantList &productsData, int index, VisualizationZoneWidget *zoneWidget)
636 const QVariantList &productsData, int index, VisualizationZoneWidget *zoneWidget)
631 {
637 {
632 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
638 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
633 // compatible variable here
639 // compatible variable here
634 if (productsData.count() != 1) {
640 if (productsData.count() != 1) {
635 qCWarning(LOG_VisualizationZoneWidget())
641 qCWarning(LOG_VisualizationZoneWidget())
636 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
642 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
637 "aborted.");
643 "aborted.");
638 return;
644 return;
639 }
645 }
640
646
641 auto context = new QObject{zoneWidget};
647 auto context = new QObject{zoneWidget};
642 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
648 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
643 [this, index, zoneWidget, context](auto variable) {
649 [this, index, zoneWidget, context](auto variable) {
644 zoneWidget->createGraph(variable, index);
650 zoneWidget->createGraph(variable, index);
645 delete context; // removes the connection
651 delete context; // removes the connection
646 },
652 },
647 Qt::QueuedConnection);
653 Qt::QueuedConnection);
648
654
649 auto productData = productsData.first().toHash();
655 auto productData = productsData.first().toHash();
650 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
656 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
651 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
657 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
652 }
658 }
General Comments 0
You need to be logged in to leave comments. Login now