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