##// END OF EJS Templates
Fix creation of first event
trabillard -
r1311:d6548be72d76
parent child
Show More
@@ -1,460 +1,464
1 1 #include "Catalogue/CatalogueEventsWidget.h"
2 2 #include "ui_CatalogueEventsWidget.h"
3 3
4 4 #include <Catalogue/CatalogueController.h>
5 5 #include <Catalogue/CatalogueEventsModel.h>
6 6 #include <Catalogue/CatalogueExplorerHelper.h>
7 7 #include <CatalogueDao.h>
8 8 #include <DBCatalogue.h>
9 9 #include <SqpApplication.h>
10 10 #include <Visualization/VisualizationTabWidget.h>
11 11 #include <Visualization/VisualizationWidget.h>
12 12 #include <Visualization/VisualizationZoneWidget.h>
13 13
14 14 #include <QDialog>
15 15 #include <QDialogButtonBox>
16 16 #include <QListWidget>
17 17 #include <QMessageBox>
18 18
19 19 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
20 20
21 21 /// Fixed size of the validation column
22 22 const auto VALIDATION_COLUMN_SIZE = 35;
23 23
24 24 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
25 25
26 26 CatalogueEventsModel *m_Model = nullptr;
27 27 QStringList m_ZonesForTimeMode;
28 28 QString m_ZoneForGraphMode;
29 29 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
30 bool m_AllEventDisplayed = false;
30 31
31 32 VisualizationWidget *m_VisualizationWidget = nullptr;
32 33
33 34 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
34 35 {
35 36 widget->ui->treeView->setSortingEnabled(false);
36 37 m_Model->setEvents(events);
37 38 widget->ui->treeView->setSortingEnabled(true);
38 39
39 40 for (auto event : events) {
40 41 if (sqpApp->catalogueController().eventHasChanges(event)) {
41 42 auto index = m_Model->indexOf(event);
42 43 widget->setEventChanges(event, true);
43 44 }
44 45 }
45 46 }
46 47
47 48 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
48 49 {
49 50 treeView->setSortingEnabled(false);
50 51 m_Model->addEvent(event);
51 52 treeView->setSortingEnabled(true);
52 53 }
53 54
54 55 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
55 56 {
56 57 treeView->setSortingEnabled(false);
57 58 m_Model->removeEvent(event);
58 59 treeView->setSortingEnabled(true);
59 60 }
60 61
61 62 QStringList getAvailableVisualizationZoneList() const
62 63 {
63 64 if (m_VisualizationWidget) {
64 65 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
65 66 return tab->availableZoneWidgets();
66 67 }
67 68 }
68 69
69 70 return QStringList{};
70 71 }
71 72
72 73 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
73 74 bool allowMultiSelection, const QPoint &location)
74 75 {
75 76 auto availableZones = getAvailableVisualizationZoneList();
76 77 if (availableZones.isEmpty()) {
77 78 return QStringList{};
78 79 }
79 80
80 81 QDialog d(parent, Qt::Tool);
81 82 d.setWindowTitle("Choose a zone");
82 83 auto layout = new QVBoxLayout{&d};
83 84 layout->setContentsMargins(0, 0, 0, 0);
84 85 auto listWidget = new QListWidget{&d};
85 86 layout->addWidget(listWidget);
86 87
87 88 QSet<QListWidgetItem *> checkedItems;
88 89 for (auto zone : availableZones) {
89 90 auto item = new QListWidgetItem{zone};
90 91 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
91 92 if (selectedZones.contains(zone)) {
92 93 item->setCheckState(Qt::Checked);
93 94 checkedItems << item;
94 95 }
95 96 else {
96 97 item->setCheckState(Qt::Unchecked);
97 98 }
98 99
99 100 listWidget->addItem(item);
100 101 }
101 102
102 103 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
103 104 layout->addWidget(buttonBox);
104 105
105 106 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
106 107 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
107 108
108 109 QObject::connect(listWidget, &QListWidget::itemChanged,
109 110 [&checkedItems, allowMultiSelection, listWidget](auto item) {
110 111 if (item->checkState() == Qt::Checked) {
111 112 if (!allowMultiSelection) {
112 113 for (auto checkedItem : checkedItems) {
113 114 listWidget->blockSignals(true);
114 115 checkedItem->setCheckState(Qt::Unchecked);
115 116 listWidget->blockSignals(false);
116 117 }
117 118
118 119 checkedItems.clear();
119 120 }
120 121 checkedItems << item;
121 122 }
122 123 else {
123 124 checkedItems.remove(item);
124 125 }
125 126 });
126 127
127 128 QStringList result;
128 129
129 130 d.setMinimumWidth(120);
130 131 d.resize(d.minimumSizeHint());
131 132 d.move(location);
132 133 if (d.exec() == QDialog::Accepted) {
133 134 for (auto item : checkedItems) {
134 135 result += item->text();
135 136 }
136 137 }
137 138 else {
138 139 result = selectedZones;
139 140 }
140 141
141 142 return result;
142 143 }
143 144
144 145 void updateForTimeMode(QTreeView *treeView)
145 146 {
146 147 auto selectedRows = treeView->selectionModel()->selectedRows();
147 148
148 149 if (selectedRows.count() == 1) {
149 150 auto event = m_Model->getEvent(selectedRows.first());
150 151 if (event) {
151 152 if (m_VisualizationWidget) {
152 153 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
153 154
154 155 for (auto zoneName : m_ZonesForTimeMode) {
155 156 if (auto zone = tab->getZoneWithName(zoneName)) {
156 157 SqpRange eventRange;
157 158 eventRange.m_TStart = event->getTStart();
158 159 eventRange.m_TEnd = event->getTEnd();
159 160 zone->setZoneRange(eventRange);
160 161 }
161 162 }
162 163 }
163 164 else {
164 165 qCWarning(LOG_CatalogueEventsWidget())
165 166 << "updateTimeZone: no tab found in the visualization";
166 167 }
167 168 }
168 169 else {
169 170 qCWarning(LOG_CatalogueEventsWidget())
170 171 << "updateTimeZone: visualization widget not found";
171 172 }
172 173 }
173 174 }
174 175 else {
175 176 qCWarning(LOG_CatalogueEventsWidget())
176 177 << "updateTimeZone: not compatible with multiple events selected";
177 178 }
178 179 }
179 180
180 181 void updateForGraphMode(QTreeView *treeView)
181 182 {
182 183 auto selectedRows = treeView->selectionModel()->selectedRows();
183 184
184 185 if (selectedRows.count() == 1) {
185 186 auto event = m_Model->getEvent(selectedRows.first());
186 187 if (m_VisualizationWidget) {
187 188 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
188 189 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
189 190 // TODO
190 191 }
191 192 }
192 193 else {
193 194 qCWarning(LOG_CatalogueEventsWidget())
194 195 << "updateGraphMode: no tab found in the visualization";
195 196 }
196 197 }
197 198 else {
198 199 qCWarning(LOG_CatalogueEventsWidget())
199 200 << "updateGraphMode: visualization widget not found";
200 201 }
201 202 }
202 203 else {
203 204 qCWarning(LOG_CatalogueEventsWidget())
204 205 << "updateGraphMode: not compatible with multiple events selected";
205 206 }
206 207 }
207 208
208 209 void getSelectedItems(
209 210 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
210 211 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
211 212 {
212 213 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
213 214 auto itemType = m_Model->itemTypeOf(rowIndex);
214 215 if (itemType == CatalogueEventsModel::ItemType::Event) {
215 216 events << m_Model->getEvent(rowIndex);
216 217 }
217 218 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
218 219 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
219 220 m_Model->getEventProduct(rowIndex));
220 221 }
221 222 }
222 223 }
223 224 };
224 225
225 226 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
226 227 : QWidget(parent),
227 228 ui(new Ui::CatalogueEventsWidget),
228 229 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
229 230 {
230 231 ui->setupUi(this);
231 232
232 233 impl->m_Model = new CatalogueEventsModel{this};
233 234 ui->treeView->setModel(impl->m_Model);
234 235
235 236 ui->treeView->setSortingEnabled(true);
236 237 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
237 238 ui->treeView->setDragEnabled(true);
238 239
239 240 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
240 241 if (checked) {
241 242 ui->btnChart->setChecked(false);
242 243 impl->m_ZonesForTimeMode
243 244 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
244 245 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
245 246
246 247 impl->updateForTimeMode(ui->treeView);
247 248 }
248 249 });
249 250
250 251 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
251 252 if (checked) {
252 253 ui->btnTime->setChecked(false);
253 254 impl->m_ZoneForGraphMode
254 255 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
255 256 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
256 257 .value(0);
257 258
258 259 impl->updateForGraphMode(ui->treeView);
259 260 }
260 261 });
261 262
262 263 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
263 264 QVector<std::shared_ptr<DBEvent> > events;
264 265 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
265 266 impl->getSelectedItems(ui->treeView, events, eventProducts);
266 267
267 268 if (!events.isEmpty() && eventProducts.isEmpty()) {
268 269
269 270 if (QMessageBox::warning(this, tr("Remove Event(s)"),
270 271 tr("The selected event(s) will be completly removed "
271 272 "from the repository!\nAre you sure you want to continue?"),
272 273 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
273 274 == QMessageBox::Yes) {
274 275
275 276 for (auto event : events) {
276 277 sqpApp->catalogueController().removeEvent(event);
277 278 impl->removeEvent(event, ui->treeView);
278 279 }
279 280 }
280 281 }
281 282 });
282 283
283 284 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
284 285 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
285 286 &CatalogueEventsWidget::emitSelection);
286 287
287 288 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
288 289 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
289 290 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
290 291 ui->btnChart->setEnabled(isNotMultiSelection);
291 292 ui->btnTime->setEnabled(isNotMultiSelection);
292 293
293 294 if (isNotMultiSelection && ui->btnTime->isChecked()) {
294 295 impl->updateForTimeMode(ui->treeView);
295 296 }
296 297 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
297 298 impl->updateForGraphMode(ui->treeView);
298 299 }
299 300
300 301 QVector<std::shared_ptr<DBEvent> > events;
301 302 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
302 303 impl->getSelectedItems(ui->treeView, events, eventProducts);
303 304 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
304 305 });
305 306
306 307 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
307 308 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
308 309 QHeaderView::Stretch);
309 310 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
310 311 QHeaderView::Fixed);
311 312 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
312 313 QHeaderView::Interactive);
313 314 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
314 315 VALIDATION_COLUMN_SIZE);
315 316 ui->treeView->header()->setSortIndicatorShown(true);
316 317
317 318 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
318 319 auto allEvents = impl->m_Model->events();
319 320 for (auto event : allEvents) {
320 321 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
321 322 }
322 323 });
323 324
324 325 populateWithAllEvents();
325 326 }
326 327
327 328 CatalogueEventsWidget::~CatalogueEventsWidget()
328 329 {
329 330 delete ui;
330 331 }
331 332
332 333 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
333 334 {
334 335 impl->m_VisualizationWidget = visualization;
335 336 }
336 337
337 338 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
338 339 {
339 340 impl->addEvent(event, ui->treeView);
340 341 }
341 342
342 343 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
343 344 {
344 345 impl->m_Model->refreshEvent(event);
345 346
346 347 auto eventIndex = impl->m_Model->indexOf(event);
347 348 auto validationIndex
348 349 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
349 350
350 351 if (validationIndex.isValid()) {
351 352 if (hasChanges) {
352 353 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
353 354 auto widget = CatalogueExplorerHelper::buildValidationWidget(
354 355 ui->treeView,
355 356 [this, event]() {
356 357 sqpApp->catalogueController().saveEvent(event);
357 358 setEventChanges(event, false);
358 359 },
359 360 [this, event]() {
360 361 sqpApp->catalogueController().discardEvent(event);
361 362 setEventChanges(event, false);
362 363 impl->m_Model->refreshEvent(event, true);
363 364 emitSelection();
364 365 });
365 366 ui->treeView->setIndexWidget(validationIndex, widget);
366 367 }
367 368 }
368 369 else {
369 370 // Note: the widget is destroyed
370 371 ui->treeView->setIndexWidget(validationIndex, nullptr);
371 372 }
372 373 }
373 374 else {
374 375 qCWarning(LOG_CatalogueEventsWidget())
375 376 << "setEventChanges: the event is not displayed in the model.";
376 377 }
377 378 }
378 379
379 380 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
380 381 {
381 382 return impl->m_DisplayedCatalogues;
382 383 }
383 384
384 385 bool CatalogueEventsWidget::isAllEventsDisplayed() const
385 386 {
386 return impl->m_DisplayedCatalogues.isEmpty() && !impl->m_Model->events().isEmpty();
387 return impl->m_AllEventDisplayed;
387 388 }
388 389
389 390 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
390 391 {
391 392 return impl->m_Model->indexOf(event).isValid();
392 393 }
393 394
394 395 void CatalogueEventsWidget::populateWithCatalogues(
395 396 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
396 397 {
397 398 impl->m_DisplayedCatalogues = catalogues;
399 impl->m_AllEventDisplayed = false;
398 400
399 401 QSet<QUuid> eventIds;
400 402 QVector<std::shared_ptr<DBEvent> > events;
401 403
402 404 for (auto catalogue : catalogues) {
403 405 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
404 406 for (auto event : catalogueEvents) {
405 407 if (!eventIds.contains(event->getUniqId())) {
406 408 events << event;
407 409 eventIds.insert(event->getUniqId());
408 410 }
409 411 }
410 412 }
411 413
412 414 impl->setEvents(events, this);
413 415 }
414 416
415 417 void CatalogueEventsWidget::populateWithAllEvents()
416 418 {
417 419 impl->m_DisplayedCatalogues.clear();
420 impl->m_AllEventDisplayed = true;
418 421
419 422 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
420 423
421 424 QVector<std::shared_ptr<DBEvent> > events;
422 425 for (auto event : allEvents) {
423 426 events << event;
424 427 }
425 428
426 429 impl->setEvents(events, this);
427 430 }
428 431
429 432 void CatalogueEventsWidget::clear()
430 433 {
431 434 impl->m_DisplayedCatalogues.clear();
435 impl->m_AllEventDisplayed = false;
432 436 impl->setEvents({}, this);
433 437 }
434 438
435 439 void CatalogueEventsWidget::refresh()
436 440 {
437 if (impl->m_DisplayedCatalogues.isEmpty()) {
441 if (isAllEventsDisplayed()) {
438 442 populateWithAllEvents();
439 443 }
440 else {
444 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
441 445 populateWithCatalogues(impl->m_DisplayedCatalogues);
442 446 }
443 447 }
444 448
445 449 void CatalogueEventsWidget::emitSelection()
446 450 {
447 451 QVector<std::shared_ptr<DBEvent> > events;
448 452 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
449 453 impl->getSelectedItems(ui->treeView, events, eventProducts);
450 454
451 455 if (!events.isEmpty() && eventProducts.isEmpty()) {
452 456 emit eventsSelected(events);
453 457 }
454 458 else if (events.isEmpty() && !eventProducts.isEmpty()) {
455 459 emit eventProductsSelected(eventProducts);
456 460 }
457 461 else {
458 462 emit selectionCleared();
459 463 }
460 464 }
General Comments 0
You need to be logged in to leave comments. Login now