##// END OF EJS Templates
graph mode with a "New Zone"
trabillard -
r1377:13ac2b0ff0d5
parent child
Show More
@@ -1,599 +1,617
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 <QActionGroup>
20 #include <QActionGroup>
21 #include <QDialog>
21 #include <QDialog>
22 #include <QDialogButtonBox>
22 #include <QDialogButtonBox>
23 #include <QKeyEvent>
23 #include <QKeyEvent>
24 #include <QListWidget>
24 #include <QListWidget>
25 #include <QMenu>
25 #include <QMenu>
26 #include <QMessageBox>
26 #include <QMessageBox>
27
27
28 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
28 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
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 const QString NEW_ZONE_TEXT = QStringLiteral("New Zone");
34
33 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
35 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
34
36
35 CatalogueEventsModel *m_Model = nullptr;
37 CatalogueEventsModel *m_Model = nullptr;
36 QStringList m_ZonesForTimeMode;
38 QStringList m_ZonesForTimeMode;
37 QString m_ZoneForGraphMode;
39 QString m_ZoneForGraphMode;
38 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
40 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
39 bool m_AllEventDisplayed = false;
41 bool m_AllEventDisplayed = false;
40 QVector<VisualizationGraphWidget *> m_CustomGraphs;
42 QVector<VisualizationGraphWidget *> m_CustomGraphs;
41
43
42 VisualizationWidget *m_VisualizationWidget = nullptr;
44 VisualizationWidget *m_VisualizationWidget = nullptr;
43
45
44 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
46 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
45 {
47 {
46 widget->ui->treeView->setSortingEnabled(false);
48 widget->ui->treeView->setSortingEnabled(false);
47 m_Model->setSourceCatalogues(m_DisplayedCatalogues);
49 m_Model->setSourceCatalogues(m_DisplayedCatalogues);
48 m_Model->setEvents(events);
50 m_Model->setEvents(events);
49 widget->ui->treeView->setSortingEnabled(true);
51 widget->ui->treeView->setSortingEnabled(true);
50
52
51 for (auto event : events) {
53 for (auto event : events) {
52 if (sqpApp->catalogueController().eventHasChanges(event)) {
54 if (sqpApp->catalogueController().eventHasChanges(event)) {
53 auto index = m_Model->indexOf(event);
55 auto index = m_Model->indexOf(event);
54 widget->setEventChanges(event, true);
56 widget->setEventChanges(event, true);
55 }
57 }
56 }
58 }
57 }
59 }
58
60
59 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
61 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
60 {
62 {
61 treeView->setSortingEnabled(false);
63 treeView->setSortingEnabled(false);
62 m_Model->addEvent(event);
64 m_Model->addEvent(event);
63 treeView->setSortingEnabled(true);
65 treeView->setSortingEnabled(true);
64 }
66 }
65
67
66 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
68 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
67 {
69 {
68 treeView->setSortingEnabled(false);
70 treeView->setSortingEnabled(false);
69 m_Model->removeEvent(event);
71 m_Model->removeEvent(event);
70 treeView->setSortingEnabled(true);
72 treeView->setSortingEnabled(true);
71 }
73 }
72
74
73 QStringList getAvailableVisualizationZoneList() const
75 QStringList getAvailableVisualizationZoneList() const
74 {
76 {
75 if (m_VisualizationWidget) {
77 if (m_VisualizationWidget) {
76 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
78 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
77 return tab->availableZoneWidgets();
79 return tab->availableZoneWidgets();
78 }
80 }
79 }
81 }
80
82
81 return QStringList{};
83 return QStringList{};
82 }
84 }
83
85
84 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
86 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
85 bool allowMultiSelection, const QPoint &location)
87 bool allowMultiSelection, bool addNewZoneOption, const QPoint &location)
86 {
88 {
87 auto availableZones = getAvailableVisualizationZoneList();
89 auto availableZones = getAvailableVisualizationZoneList();
88 if (availableZones.isEmpty()) {
90 if (!addNewZoneOption && availableZones.isEmpty()) {
89 return QStringList{};
91 return QStringList{};
90 }
92 }
91
93
92 QActionGroup actionGroup{parent};
94 QActionGroup actionGroup{parent};
93 actionGroup.setExclusive(!allowMultiSelection);
95 actionGroup.setExclusive(!allowMultiSelection);
94
96
97 QVector<QAction *> zoneActions;
98
95 QMenu selectionMenu{parent};
99 QMenu selectionMenu{parent};
100
101 if (addNewZoneOption) {
102 availableZones.prepend(NEW_ZONE_TEXT);
103 }
104
96 selectionMenu.addSeparator();
105 selectionMenu.addSeparator();
97 QVector<QAction *> zoneActions;
98 for (auto zone : availableZones) {
106 for (auto zone : availableZones) {
99 auto zoneAction = selectionMenu.addAction(zone);
107 auto zoneAction = selectionMenu.addAction(zone);
100 zoneAction->setCheckable(true);
108 zoneAction->setCheckable(true);
101 zoneAction->setChecked(selectedZones.contains(zone));
109 zoneAction->setChecked(selectedZones.contains(zone));
102 actionGroup.addAction(zoneAction);
110 actionGroup.addAction(zoneAction);
103 zoneActions << zoneAction;
111 zoneActions << zoneAction;
104 }
112 }
105
113
106 auto action = selectionMenu.exec(QCursor::pos());
114 auto resultAction = selectionMenu.exec(QCursor::pos());
107
115
108 QStringList result;
116 QStringList result;
109
117
110 if (action == nullptr) {
118 if (resultAction == nullptr) {
111 result = selectedZones;
119 result = selectedZones;
112 }
120 }
113 else {
121 else {
114 for (auto zoneAction : zoneActions) {
122 for (auto zoneAction : zoneActions) {
115 if (zoneAction->isChecked()) {
123 if (zoneAction->isChecked()) {
116 result << zoneAction->text();
124 result << zoneAction->text();
117 }
125 }
118 }
126 }
119 }
127 }
120
128
121 return result;
129 return result;
122 }
130 }
123
131
124 void updateForTimeMode(QTreeView *treeView)
132 void updateForTimeMode(QTreeView *treeView)
125 {
133 {
126 auto selectedRows = treeView->selectionModel()->selectedRows();
134 auto selectedRows = treeView->selectionModel()->selectedRows();
127
135
128 if (selectedRows.count() == 1) {
136 if (selectedRows.count() == 1) {
129 auto event = m_Model->getEvent(selectedRows.first());
137 auto event = m_Model->getEvent(selectedRows.first());
130 if (event) {
138 if (event) {
131 if (m_VisualizationWidget) {
139 if (m_VisualizationWidget) {
132 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
140 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
133
141
134 for (auto zoneName : m_ZonesForTimeMode) {
142 for (auto zoneName : m_ZonesForTimeMode) {
135 if (auto zone = tab->getZoneWithName(zoneName)) {
143 if (auto zone = tab->getZoneWithName(zoneName)) {
136 SqpRange eventRange;
144 SqpRange eventRange;
137 eventRange.m_TStart = event->getTStart();
145 eventRange.m_TStart = event->getTStart();
138 eventRange.m_TEnd = event->getTEnd();
146 eventRange.m_TEnd = event->getTEnd();
139 zone->setZoneRange(eventRange);
147 zone->setZoneRange(eventRange);
140 }
148 }
141 }
149 }
142 }
150 }
143 else {
151 else {
144 qCWarning(LOG_CatalogueEventsWidget())
152 qCWarning(LOG_CatalogueEventsWidget())
145 << "updateTimeZone: no tab found in the visualization";
153 << "updateTimeZone: no tab found in the visualization";
146 }
154 }
147 }
155 }
148 else {
156 else {
149 qCWarning(LOG_CatalogueEventsWidget())
157 qCWarning(LOG_CatalogueEventsWidget())
150 << "updateTimeZone: visualization widget not found";
158 << "updateTimeZone: visualization widget not found";
151 }
159 }
152 }
160 }
153 }
161 }
154 else {
162 else {
155 qCWarning(LOG_CatalogueEventsWidget())
163 qCWarning(LOG_CatalogueEventsWidget())
156 << "updateTimeZone: not compatible with multiple events selected";
164 << "updateTimeZone: not compatible with multiple events selected";
157 }
165 }
158 }
166 }
159
167
160 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
168 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
161 {
169 {
162 // Retrieves the range of each product and the maximum size
170 // Retrieves the range of each product and the maximum size
163 QVector<SqpRange> graphRanges;
171 QVector<SqpRange> graphRanges;
164 double maxDt = 0;
172 double maxDt = 0;
165 for (auto eventProduct : event->getEventProducts()) {
173 for (auto eventProduct : event->getEventProducts()) {
166 SqpRange eventRange;
174 SqpRange eventRange;
167 eventRange.m_TStart = eventProduct.getTStart();
175 eventRange.m_TStart = eventProduct.getTStart();
168 eventRange.m_TEnd = eventProduct.getTEnd();
176 eventRange.m_TEnd = eventProduct.getTEnd();
169 graphRanges << eventRange;
177 graphRanges << eventRange;
170
178
171 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
179 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
172 if (dt > maxDt) {
180 if (dt > maxDt) {
173 maxDt = dt;
181 maxDt = dt;
174 }
182 }
175 }
183 }
176
184
177 // Adds the marge
185 // Adds the marge
178 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
186 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
179
187
180 // Corrects the graph ranges so that they all have the same size
188 // Corrects the graph ranges so that they all have the same size
181 QVector<SqpRange> correctedGraphRanges;
189 QVector<SqpRange> correctedGraphRanges;
182 for (auto range : graphRanges) {
190 for (auto range : graphRanges) {
183 auto dt = range.m_TEnd - range.m_TStart;
191 auto dt = range.m_TEnd - range.m_TStart;
184 auto diff = qAbs((maxDt - dt) / 2.0);
192 auto diff = qAbs((maxDt - dt) / 2.0);
185
193
186 SqpRange correctedRange;
194 SqpRange correctedRange;
187 correctedRange.m_TStart = range.m_TStart - diff;
195 correctedRange.m_TStart = range.m_TStart - diff;
188 correctedRange.m_TEnd = range.m_TEnd + diff;
196 correctedRange.m_TEnd = range.m_TEnd + diff;
189
197
190 correctedGraphRanges << correctedRange;
198 correctedGraphRanges << correctedRange;
191 }
199 }
192
200
193 return correctedGraphRanges;
201 return correctedGraphRanges;
194 }
202 }
195
203
196 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
204 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
197 {
205 {
198 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
206 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
199 if (selectedRows.count() != 1) {
207 if (selectedRows.count() != 1) {
200 qCWarning(LOG_CatalogueEventsWidget())
208 qCWarning(LOG_CatalogueEventsWidget())
201 << "updateGraphMode: not compatible with multiple events selected";
209 << "updateGraphMode: not compatible with multiple events selected";
202 return;
210 return;
203 }
211 }
204
212
205 if (!m_VisualizationWidget) {
213 if (!m_VisualizationWidget) {
206 qCWarning(LOG_CatalogueEventsWidget())
214 qCWarning(LOG_CatalogueEventsWidget())
207 << "updateGraphMode: visualization widget not found";
215 << "updateGraphMode: visualization widget not found";
208 return;
216 return;
209 }
217 }
210
218
211 auto event = m_Model->getEvent(selectedRows.first());
219 auto event = m_Model->getEvent(selectedRows.first());
212 if (!event) {
220 if (!event) {
213 // A event product is probably selected
221 // A event product is probably selected
214 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
222 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
215 return;
223 return;
216 }
224 }
217
225
218 auto tab = m_VisualizationWidget->currentTabWidget();
226 auto tab = m_VisualizationWidget->currentTabWidget();
219 if (!tab) {
227 if (!tab) {
220 qCWarning(LOG_CatalogueEventsWidget())
228 qCWarning(LOG_CatalogueEventsWidget())
221 << "updateGraphMode: no tab found in the visualization";
229 << "updateGraphMode: no tab found in the visualization";
222 return;
230 return;
223 }
231 }
224
232
233 auto isNewZone = m_ZoneForGraphMode == NEW_ZONE_TEXT;
225 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
234 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
226 if (!zone) {
235 if (!isNewZone && !zone) {
227 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
236 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
228 return;
237 return;
229 }
238 }
230
239
231 // Closes the previous graph and delete the asociated variables
240 // Closes the previous graph and delete the asociated variables
232 for (auto graph : m_CustomGraphs) {
241 for (auto graph : m_CustomGraphs) {
233 graph->close();
242 graph->close();
234 auto variables = graph->variables().toVector();
243 auto variables = graph->variables().toVector();
235
244
236 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
245 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
237 Qt::QueuedConnection,
246 Qt::QueuedConnection,
238 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
247 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
239 }
248 }
240 m_CustomGraphs.clear();
249 m_CustomGraphs.clear();
241
250
242 // Closes the remaining graphs inside the zone
251 // Closes the remaining graphs inside the zone
243 zone->closeAllGraphs();
252 if (zone) {
253 zone->closeAllGraphs();
254 }
255
256 // Creates the zone if needed
257 if (isNewZone) {
258 zone = tab->createEmptyZone(0);
259 m_ZoneForGraphMode = zone->name();
260 }
244
261
245 // Calculates the range of each graph which will be created
262 // Calculates the range of each graph which will be created
246 auto graphRange = getGraphRanges(event);
263 auto graphRange = getGraphRanges(event);
247
264
248 // Loops through the event products and create the graph
265 // Loops through the event products and create the graph
249 auto itRange = graphRange.cbegin();
266 auto itRange = graphRange.cbegin();
250 for (auto eventProduct : event->getEventProducts()) {
267 for (auto eventProduct : event->getEventProducts()) {
251 auto productId = eventProduct.getProductId();
268 auto productId = eventProduct.getProductId();
252
269
253 auto range = *itRange;
270 auto range = *itRange;
254 ++itRange;
271 ++itRange;
255
272
256 SqpRange productRange;
273 SqpRange productRange;
257 productRange.m_TStart = eventProduct.getTStart();
274 productRange.m_TStart = eventProduct.getTStart();
258 productRange.m_TEnd = eventProduct.getTEnd();
275 productRange.m_TEnd = eventProduct.getTEnd();
259
276
260 auto context = new QObject{catalogueEventWidget};
277 auto context = new QObject{catalogueEventWidget};
261 QObject::connect(
278 QObject::connect(
262 &sqpApp->variableController(), &VariableController::variableAdded, context,
279 &sqpApp->variableController(), &VariableController::variableAdded, context,
263 [this, catalogueEventWidget, zone, context, event, range, productRange,
280 [this, catalogueEventWidget, zone, context, event, range, productRange,
264 productId](auto variable) {
281 productId](auto variable) {
265
282
266 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
283 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
267 == productId) {
284 == productId) {
268 auto graph = zone->createGraph(variable);
285 auto graph = zone->createGraph(variable);
269 graph->setAutoRangeOnVariableInitialization(false);
286 graph->setAutoRangeOnVariableInitialization(false);
270
287
271 auto selectionZone
288 auto selectionZone
272 = graph->addSelectionZone(event->getName(), productRange);
289 = graph->addSelectionZone(event->getName(), productRange);
273 emit catalogueEventWidget->selectionZoneAdded(event, productId,
290 emit catalogueEventWidget->selectionZoneAdded(event, productId,
274 selectionZone);
291 selectionZone);
275 m_CustomGraphs << graph;
292 m_CustomGraphs << graph;
276
293
277 graph->setGraphRange(range, true);
294 graph->setGraphRange(range, true);
278
295
279 // Removes the graph from the graph list if it is closed manually
296 // Removes the graph from the graph list if it is closed manually
280 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
297 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
281 [this, graph]() { m_CustomGraphs.removeAll(graph); });
298 [this, graph]() { m_CustomGraphs.removeAll(graph); });
282
299
283 delete context; // removes the connection
300 delete context; // removes the connection
284 }
301 }
285 },
302 },
286 Qt::QueuedConnection);
303 Qt::QueuedConnection);
287
304
288 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
305 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
289 "requestVariableFromProductIdKey", Qt::QueuedConnection,
306 "requestVariableFromProductIdKey", Qt::QueuedConnection,
290 Q_ARG(QString, productId));
307 Q_ARG(QString, productId));
291 }
308 }
292 }
309 }
293
310
294 void getSelectedItems(
311 void getSelectedItems(
295 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
312 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
296 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
313 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
297 {
314 {
298 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
315 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
299 auto itemType = m_Model->itemTypeOf(rowIndex);
316 auto itemType = m_Model->itemTypeOf(rowIndex);
300 if (itemType == CatalogueEventsModel::ItemType::Event) {
317 if (itemType == CatalogueEventsModel::ItemType::Event) {
301 events << m_Model->getEvent(rowIndex);
318 events << m_Model->getEvent(rowIndex);
302 }
319 }
303 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
320 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
304 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
321 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
305 m_Model->getEventProduct(rowIndex));
322 m_Model->getEventProduct(rowIndex));
306 }
323 }
307 }
324 }
308 }
325 }
309 };
326 };
310
327
311 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
328 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
312 : QWidget(parent),
329 : QWidget(parent),
313 ui(new Ui::CatalogueEventsWidget),
330 ui(new Ui::CatalogueEventsWidget),
314 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
331 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
315 {
332 {
316 ui->setupUi(this);
333 ui->setupUi(this);
317
334
318 impl->m_Model = new CatalogueEventsModel{this};
335 impl->m_Model = new CatalogueEventsModel{this};
319 ui->treeView->setModel(impl->m_Model);
336 ui->treeView->setModel(impl->m_Model);
320
337
321 ui->treeView->setSortingEnabled(true);
338 ui->treeView->setSortingEnabled(true);
322 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
339 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
323 ui->treeView->setDragEnabled(true);
340 ui->treeView->setDragEnabled(true);
324
341
325
342
326 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
343 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
327 if (checked) {
344 if (checked) {
328 ui->btnChart->setChecked(false);
345 ui->btnChart->setChecked(false);
329 impl->m_ZonesForTimeMode
346 impl->m_ZonesForTimeMode
330 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
347 = impl->selectZone(this, impl->m_ZonesForTimeMode, true, false,
331 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
348 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
332
349
333 impl->updateForTimeMode(ui->treeView);
350 impl->updateForTimeMode(ui->treeView);
334 }
351 }
335 });
352 });
336
353
337 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
354 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
338 if (checked) {
355 if (checked) {
339 ui->btnTime->setChecked(false);
356 ui->btnTime->setChecked(false);
357
340 impl->m_ZoneForGraphMode
358 impl->m_ZoneForGraphMode
341 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
359 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false, true,
342 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
360 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
343 .value(0);
361 .value(0);
344
362
345 impl->updateForGraphMode(this);
363 impl->updateForGraphMode(this);
346 }
364 }
347 });
365 });
348
366
349 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
367 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
350 QVector<std::shared_ptr<DBEvent> > events;
368 QVector<std::shared_ptr<DBEvent> > events;
351 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
369 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
352 impl->getSelectedItems(ui->treeView, events, eventProducts);
370 impl->getSelectedItems(ui->treeView, events, eventProducts);
353
371
354 if (!events.isEmpty() && eventProducts.isEmpty()) {
372 if (!events.isEmpty() && eventProducts.isEmpty()) {
355
373
356 auto canRemoveEvent
374 auto canRemoveEvent
357 = !this->isAllEventsDisplayed()
375 = !this->isAllEventsDisplayed()
358 || (QMessageBox::warning(
376 || (QMessageBox::warning(
359 this, tr("Remove Event(s)"),
377 this, tr("Remove Event(s)"),
360 tr("The selected event(s) will be permanently removed "
378 tr("The selected event(s) will be permanently removed "
361 "from the repository!\nAre you sure you want to continue?"),
379 "from the repository!\nAre you sure you want to continue?"),
362 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
380 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
363 == QMessageBox::Yes);
381 == QMessageBox::Yes);
364
382
365 if (canRemoveEvent) {
383 if (canRemoveEvent) {
366 for (auto event : events) {
384 for (auto event : events) {
367 if (this->isAllEventsDisplayed()) {
385 if (this->isAllEventsDisplayed()) {
368 sqpApp->catalogueController().removeEvent(event);
386 sqpApp->catalogueController().removeEvent(event);
369 impl->removeEvent(event, ui->treeView);
387 impl->removeEvent(event, ui->treeView);
370 }
388 }
371 else {
389 else {
372 QVector<std::shared_ptr<DBCatalogue> > modifiedCatalogues;
390 QVector<std::shared_ptr<DBCatalogue> > modifiedCatalogues;
373 for (auto catalogue : this->displayedCatalogues()) {
391 for (auto catalogue : this->displayedCatalogues()) {
374 if (catalogue->removeEvent(event->getUniqId())) {
392 if (catalogue->removeEvent(event->getUniqId())) {
375 sqpApp->catalogueController().updateCatalogue(catalogue);
393 sqpApp->catalogueController().updateCatalogue(catalogue);
376 modifiedCatalogues << catalogue;
394 modifiedCatalogues << catalogue;
377 }
395 }
378 }
396 }
379 if (!modifiedCatalogues.empty()) {
397 if (!modifiedCatalogues.empty()) {
380 emit eventCataloguesModified(modifiedCatalogues);
398 emit eventCataloguesModified(modifiedCatalogues);
381 }
399 }
382 }
400 }
383 impl->m_Model->removeEvent(event);
401 impl->m_Model->removeEvent(event);
384 }
402 }
385
403
386
404
387 emit this->eventsRemoved(events);
405 emit this->eventsRemoved(events);
388 }
406 }
389 }
407 }
390 });
408 });
391
409
392 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
410 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
393 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
411 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
394 &CatalogueEventsWidget::emitSelection);
412 &CatalogueEventsWidget::emitSelection);
395
413
396 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
414 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
397 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
415 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
398 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
416 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
399 ui->btnChart->setEnabled(isNotMultiSelection);
417 ui->btnChart->setEnabled(isNotMultiSelection);
400 ui->btnTime->setEnabled(isNotMultiSelection);
418 ui->btnTime->setEnabled(isNotMultiSelection);
401
419
402 if (isNotMultiSelection && ui->btnTime->isChecked()) {
420 if (isNotMultiSelection && ui->btnTime->isChecked()) {
403 impl->updateForTimeMode(ui->treeView);
421 impl->updateForTimeMode(ui->treeView);
404 }
422 }
405 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
423 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
406 impl->updateForGraphMode(this);
424 impl->updateForGraphMode(this);
407 }
425 }
408
426
409 QVector<std::shared_ptr<DBEvent> > events;
427 QVector<std::shared_ptr<DBEvent> > events;
410 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
428 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
411 impl->getSelectedItems(ui->treeView, events, eventProducts);
429 impl->getSelectedItems(ui->treeView, events, eventProducts);
412 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
430 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
413 });
431 });
414
432
415 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
433 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
416 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
434 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
417 QHeaderView::Stretch);
435 QHeaderView::Stretch);
418 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
436 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
419 QHeaderView::ResizeToContents);
437 QHeaderView::ResizeToContents);
420 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
438 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
421 QHeaderView::Interactive);
439 QHeaderView::Interactive);
422 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::TStart,
440 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::TStart,
423 QHeaderView::ResizeToContents);
441 QHeaderView::ResizeToContents);
424 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::TEnd,
442 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::TEnd,
425 QHeaderView::ResizeToContents);
443 QHeaderView::ResizeToContents);
426 ui->treeView->header()->setSortIndicatorShown(true);
444 ui->treeView->header()->setSortIndicatorShown(true);
427
445
428 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
446 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
429 auto allEvents = impl->m_Model->events();
447 auto allEvents = impl->m_Model->events();
430 for (auto event : allEvents) {
448 for (auto event : allEvents) {
431 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
449 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
432 }
450 }
433 });
451 });
434
452
435 populateWithAllEvents();
453 populateWithAllEvents();
436 }
454 }
437
455
438 CatalogueEventsWidget::~CatalogueEventsWidget()
456 CatalogueEventsWidget::~CatalogueEventsWidget()
439 {
457 {
440 delete ui;
458 delete ui;
441 }
459 }
442
460
443 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
461 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
444 {
462 {
445 impl->m_VisualizationWidget = visualization;
463 impl->m_VisualizationWidget = visualization;
446 }
464 }
447
465
448 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
466 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
449 {
467 {
450 impl->addEvent(event, ui->treeView);
468 impl->addEvent(event, ui->treeView);
451 }
469 }
452
470
453 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
471 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
454 {
472 {
455 impl->m_Model->refreshEvent(event);
473 impl->m_Model->refreshEvent(event);
456
474
457 auto eventIndex = impl->m_Model->indexOf(event);
475 auto eventIndex = impl->m_Model->indexOf(event);
458 auto validationIndex
476 auto validationIndex
459 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
477 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
460
478
461 if (validationIndex.isValid()) {
479 if (validationIndex.isValid()) {
462 if (hasChanges) {
480 if (hasChanges) {
463 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
481 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
464 auto widget = CatalogueExplorerHelper::buildValidationWidget(
482 auto widget = CatalogueExplorerHelper::buildValidationWidget(
465 ui->treeView,
483 ui->treeView,
466 [this, event]() {
484 [this, event]() {
467 sqpApp->catalogueController().saveEvent(event);
485 sqpApp->catalogueController().saveEvent(event);
468 setEventChanges(event, false);
486 setEventChanges(event, false);
469 },
487 },
470 [this, event]() {
488 [this, event]() {
471 bool removed = false;
489 bool removed = false;
472 sqpApp->catalogueController().discardEvent(event, removed);
490 sqpApp->catalogueController().discardEvent(event, removed);
473 if (removed) {
491 if (removed) {
474 impl->m_Model->removeEvent(event);
492 impl->m_Model->removeEvent(event);
475 }
493 }
476 else {
494 else {
477 setEventChanges(event, false);
495 setEventChanges(event, false);
478 impl->m_Model->refreshEvent(event, true);
496 impl->m_Model->refreshEvent(event, true);
479 }
497 }
480 emitSelection();
498 emitSelection();
481 });
499 });
482 ui->treeView->setIndexWidget(validationIndex, widget);
500 ui->treeView->setIndexWidget(validationIndex, widget);
483 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
501 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
484 QHeaderView::ResizeToContents);
502 QHeaderView::ResizeToContents);
485 }
503 }
486 }
504 }
487 else {
505 else {
488 // Note: the widget is destroyed
506 // Note: the widget is destroyed
489 ui->treeView->setIndexWidget(validationIndex, nullptr);
507 ui->treeView->setIndexWidget(validationIndex, nullptr);
490 }
508 }
491 }
509 }
492 else {
510 else {
493 qCWarning(LOG_CatalogueEventsWidget())
511 qCWarning(LOG_CatalogueEventsWidget())
494 << "setEventChanges: the event is not displayed in the model.";
512 << "setEventChanges: the event is not displayed in the model.";
495 }
513 }
496 }
514 }
497
515
498 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
516 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
499 {
517 {
500 return impl->m_DisplayedCatalogues;
518 return impl->m_DisplayedCatalogues;
501 }
519 }
502
520
503 bool CatalogueEventsWidget::isAllEventsDisplayed() const
521 bool CatalogueEventsWidget::isAllEventsDisplayed() const
504 {
522 {
505 return impl->m_AllEventDisplayed;
523 return impl->m_AllEventDisplayed;
506 }
524 }
507
525
508 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
526 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
509 {
527 {
510 return impl->m_Model->indexOf(event).isValid();
528 return impl->m_Model->indexOf(event).isValid();
511 }
529 }
512
530
513 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
531 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
514 {
532 {
515 impl->m_Model->refreshEvent(event, true);
533 impl->m_Model->refreshEvent(event, true);
516 }
534 }
517
535
518 void CatalogueEventsWidget::populateWithCatalogues(
536 void CatalogueEventsWidget::populateWithCatalogues(
519 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
537 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
520 {
538 {
521 impl->m_DisplayedCatalogues = catalogues;
539 impl->m_DisplayedCatalogues = catalogues;
522 impl->m_AllEventDisplayed = false;
540 impl->m_AllEventDisplayed = false;
523
541
524 QSet<QUuid> eventIds;
542 QSet<QUuid> eventIds;
525 QVector<std::shared_ptr<DBEvent> > events;
543 QVector<std::shared_ptr<DBEvent> > events;
526
544
527 for (auto catalogue : catalogues) {
545 for (auto catalogue : catalogues) {
528 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
546 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
529 for (auto event : catalogueEvents) {
547 for (auto event : catalogueEvents) {
530 if (!eventIds.contains(event->getUniqId())) {
548 if (!eventIds.contains(event->getUniqId())) {
531 events << event;
549 events << event;
532 eventIds.insert(event->getUniqId());
550 eventIds.insert(event->getUniqId());
533 }
551 }
534 }
552 }
535 }
553 }
536
554
537 impl->setEvents(events, this);
555 impl->setEvents(events, this);
538 }
556 }
539
557
540 void CatalogueEventsWidget::populateWithAllEvents()
558 void CatalogueEventsWidget::populateWithAllEvents()
541 {
559 {
542 impl->m_DisplayedCatalogues.clear();
560 impl->m_DisplayedCatalogues.clear();
543 impl->m_AllEventDisplayed = true;
561 impl->m_AllEventDisplayed = true;
544
562
545 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
563 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
546
564
547 QVector<std::shared_ptr<DBEvent> > events;
565 QVector<std::shared_ptr<DBEvent> > events;
548 for (auto event : allEvents) {
566 for (auto event : allEvents) {
549 events << event;
567 events << event;
550 }
568 }
551
569
552 impl->setEvents(events, this);
570 impl->setEvents(events, this);
553 }
571 }
554
572
555 void CatalogueEventsWidget::clear()
573 void CatalogueEventsWidget::clear()
556 {
574 {
557 impl->m_DisplayedCatalogues.clear();
575 impl->m_DisplayedCatalogues.clear();
558 impl->m_AllEventDisplayed = false;
576 impl->m_AllEventDisplayed = false;
559 impl->setEvents({}, this);
577 impl->setEvents({}, this);
560 }
578 }
561
579
562 void CatalogueEventsWidget::refresh()
580 void CatalogueEventsWidget::refresh()
563 {
581 {
564 if (isAllEventsDisplayed()) {
582 if (isAllEventsDisplayed()) {
565 populateWithAllEvents();
583 populateWithAllEvents();
566 }
584 }
567 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
585 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
568 populateWithCatalogues(impl->m_DisplayedCatalogues);
586 populateWithCatalogues(impl->m_DisplayedCatalogues);
569 }
587 }
570 }
588 }
571
589
572 void CatalogueEventsWidget::emitSelection()
590 void CatalogueEventsWidget::emitSelection()
573 {
591 {
574 QVector<std::shared_ptr<DBEvent> > events;
592 QVector<std::shared_ptr<DBEvent> > events;
575 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
593 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
576 impl->getSelectedItems(ui->treeView, events, eventProducts);
594 impl->getSelectedItems(ui->treeView, events, eventProducts);
577
595
578 if (!events.isEmpty() && eventProducts.isEmpty()) {
596 if (!events.isEmpty() && eventProducts.isEmpty()) {
579 emit eventsSelected(events);
597 emit eventsSelected(events);
580 }
598 }
581 else if (events.isEmpty() && !eventProducts.isEmpty()) {
599 else if (events.isEmpty() && !eventProducts.isEmpty()) {
582 emit eventProductsSelected(eventProducts);
600 emit eventProductsSelected(eventProducts);
583 }
601 }
584 else {
602 else {
585 emit selectionCleared();
603 emit selectionCleared();
586 }
604 }
587 }
605 }
588
606
589
607
590 void CatalogueEventsWidget::keyPressEvent(QKeyEvent *event)
608 void CatalogueEventsWidget::keyPressEvent(QKeyEvent *event)
591 {
609 {
592 switch (event->key()) {
610 switch (event->key()) {
593 case Qt::Key_Delete: {
611 case Qt::Key_Delete: {
594 ui->btnRemove->click();
612 ui->btnRemove->click();
595 }
613 }
596 default:
614 default:
597 break;
615 break;
598 }
616 }
599 }
617 }
General Comments 0
You need to be logged in to leave comments. Login now