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