CatalogueEventsWidget.cpp
316 lines
| 11.4 KiB
| text/x-c
|
CppLexer
r1095 | #include "Catalogue/CatalogueEventsWidget.h" | |||
#include "ui_CatalogueEventsWidget.h" | ||||
r1129 | #include <Catalogue/CatalogueController.h> | |||
r1149 | #include <Catalogue/CatalogueEventsModel.h> | |||
r1129 | #include <CatalogueDao.h> | |||
#include <DBCatalogue.h> | ||||
#include <SqpApplication.h> | ||||
r1136 | #include <Visualization/VisualizationTabWidget.h> | |||
#include <Visualization/VisualizationWidget.h> | ||||
r1138 | #include <Visualization/VisualizationZoneWidget.h> | |||
r1129 | ||||
r1135 | #include <QDialog> | |||
#include <QDialogButtonBox> | ||||
#include <QListWidget> | ||||
r1138 | Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget") | |||
r1129 | ||||
/// Format of the dates appearing in the label of a cursor | ||||
const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss"); | ||||
r1105 | ||||
r1101 | struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate { | |||
r1149 | CatalogueEventsModel *m_Model = nullptr; | |||
r1138 | QStringList m_ZonesForTimeMode; | |||
r1135 | QString m_ZoneForGraphMode; | |||
r1134 | ||||
r1136 | VisualizationWidget *m_VisualizationWidget = nullptr; | |||
r1149 | void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, QTreeView *treeView) | |||
r1134 | { | |||
r1149 | treeView->setSortingEnabled(false); | |||
r1134 | m_Model->setEvents(events); | |||
r1149 | treeView->setSortingEnabled(true); | |||
r1134 | } | |||
r1149 | void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView) | |||
r1134 | { | |||
r1149 | treeView->setSortingEnabled(false); | |||
r1134 | m_Model->addEvent(event); | |||
r1149 | treeView->setSortingEnabled(true); | |||
r1134 | } | |||
r1149 | void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView) | |||
r1134 | { | |||
r1149 | treeView->setSortingEnabled(false); | |||
r1134 | m_Model->removeEvent(event); | |||
r1149 | treeView->setSortingEnabled(true); | |||
r1134 | } | |||
r1101 | ||||
r1136 | QStringList getAvailableVisualizationZoneList() const | |||
{ | ||||
if (m_VisualizationWidget) { | ||||
if (auto tab = m_VisualizationWidget->currentTabWidget()) { | ||||
return tab->availableZoneWidgets(); | ||||
} | ||||
} | ||||
return QStringList{}; | ||||
} | ||||
QStringList selectZone(QWidget *parent, const QStringList &selectedZones, | ||||
bool allowMultiSelection, const QPoint &location) | ||||
r1135 | { | |||
r1136 | auto availableZones = getAvailableVisualizationZoneList(); | |||
if (availableZones.isEmpty()) { | ||||
return QStringList{}; | ||||
} | ||||
r1135 | QDialog d(parent, Qt::Tool); | |||
d.setWindowTitle("Choose a zone"); | ||||
auto layout = new QVBoxLayout{&d}; | ||||
layout->setContentsMargins(0, 0, 0, 0); | ||||
auto listWidget = new QListWidget{&d}; | ||||
layout->addWidget(listWidget); | ||||
QSet<QListWidgetItem *> checkedItems; | ||||
for (auto zone : availableZones) { | ||||
auto item = new QListWidgetItem{zone}; | ||||
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); | ||||
if (selectedZones.contains(zone)) { | ||||
item->setCheckState(Qt::Checked); | ||||
checkedItems << item; | ||||
} | ||||
else { | ||||
item->setCheckState(Qt::Unchecked); | ||||
} | ||||
listWidget->addItem(item); | ||||
} | ||||
auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d}; | ||||
layout->addWidget(buttonBox); | ||||
QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept); | ||||
QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject); | ||||
QObject::connect(listWidget, &QListWidget::itemChanged, | ||||
[&checkedItems, allowMultiSelection, listWidget](auto item) { | ||||
if (item->checkState() == Qt::Checked) { | ||||
if (!allowMultiSelection) { | ||||
for (auto checkedItem : checkedItems) { | ||||
listWidget->blockSignals(true); | ||||
checkedItem->setCheckState(Qt::Unchecked); | ||||
listWidget->blockSignals(false); | ||||
} | ||||
checkedItems.clear(); | ||||
} | ||||
checkedItems << item; | ||||
} | ||||
else { | ||||
checkedItems.remove(item); | ||||
} | ||||
}); | ||||
QStringList result; | ||||
d.setMinimumWidth(120); | ||||
d.resize(d.minimumSizeHint()); | ||||
d.move(location); | ||||
if (d.exec() == QDialog::Accepted) { | ||||
for (auto item : checkedItems) { | ||||
result += item->text(); | ||||
} | ||||
} | ||||
r1136 | else { | |||
result = selectedZones; | ||||
} | ||||
r1135 | ||||
return result; | ||||
} | ||||
r1138 | ||||
r1149 | void updateForTimeMode(QTreeView *treeView) | |||
r1138 | { | |||
r1149 | auto selectedRows = treeView->selectionModel()->selectedRows(); | |||
r1138 | ||||
if (selectedRows.count() == 1) { | ||||
r1150 | auto event = m_Model->getEvent(selectedRows.first()); | |||
r1152 | if (event) { | |||
if (m_VisualizationWidget) { | ||||
if (auto tab = m_VisualizationWidget->currentTabWidget()) { | ||||
for (auto zoneName : m_ZonesForTimeMode) { | ||||
if (auto zone = tab->getZoneWithName(zoneName)) { | ||||
SqpRange eventRange; | ||||
eventRange.m_TStart = event->getTStart(); | ||||
eventRange.m_TEnd = event->getTEnd(); | ||||
zone->setZoneRange(eventRange); | ||||
} | ||||
r1138 | } | |||
} | ||||
r1152 | else { | |||
qCWarning(LOG_CatalogueEventsWidget()) | ||||
<< "updateTimeZone: no tab found in the visualization"; | ||||
} | ||||
r1138 | } | |||
else { | ||||
qCWarning(LOG_CatalogueEventsWidget()) | ||||
r1152 | << "updateTimeZone: visualization widget not found"; | |||
r1138 | } | |||
} | ||||
} | ||||
else { | ||||
qCWarning(LOG_CatalogueEventsWidget()) | ||||
<< "updateTimeZone: not compatible with multiple events selected"; | ||||
} | ||||
} | ||||
r1149 | void updateForGraphMode(QTreeView *treeView) | |||
r1138 | { | |||
r1149 | auto selectedRows = treeView->selectionModel()->selectedRows(); | |||
r1138 | ||||
if (selectedRows.count() == 1) { | ||||
r1150 | auto event = m_Model->getEvent(selectedRows.first()); | |||
r1138 | if (m_VisualizationWidget) { | |||
if (auto tab = m_VisualizationWidget->currentTabWidget()) { | ||||
if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) { | ||||
// TODO | ||||
} | ||||
} | ||||
else { | ||||
qCWarning(LOG_CatalogueEventsWidget()) | ||||
<< "updateGraphMode: no tab found in the visualization"; | ||||
} | ||||
} | ||||
else { | ||||
qCWarning(LOG_CatalogueEventsWidget()) | ||||
<< "updateGraphMode: visualization widget not found"; | ||||
} | ||||
} | ||||
else { | ||||
qCWarning(LOG_CatalogueEventsWidget()) | ||||
<< "updateGraphMode: not compatible with multiple events selected"; | ||||
} | ||||
} | ||||
r1135 | }; | |||
r1101 | ||||
r1095 | CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent) | |||
r1101 | : QWidget(parent), | |||
ui(new Ui::CatalogueEventsWidget), | ||||
impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()} | ||||
r1095 | { | |||
ui->setupUi(this); | ||||
r1101 | ||||
r1149 | impl->m_Model = new CatalogueEventsModel{this}; | |||
ui->treeView->setModel(impl->m_Model); | ||||
r1130 | ||||
r1149 | ui->treeView->setSortingEnabled(true); | |||
ui->treeView->setDragDropMode(QAbstractItemView::DragDrop); | ||||
ui->treeView->setDragEnabled(true); | ||||
r1130 | ||||
r1101 | connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) { | |||
if (checked) { | ||||
ui->btnChart->setChecked(false); | ||||
r1138 | impl->m_ZonesForTimeMode | |||
= impl->selectZone(this, impl->m_ZonesForTimeMode, true, | ||||
this->mapToGlobal(ui->btnTime->frameGeometry().center())); | ||||
r1149 | impl->updateForTimeMode(ui->treeView); | |||
r1101 | } | |||
}); | ||||
connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) { | ||||
if (checked) { | ||||
ui->btnTime->setChecked(false); | ||||
r1135 | impl->m_ZoneForGraphMode | |||
r1136 | = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false, | |||
r1135 | this->mapToGlobal(ui->btnChart->frameGeometry().center())) | |||
.value(0); | ||||
r1138 | ||||
r1149 | impl->updateForGraphMode(ui->treeView); | |||
r1101 | } | |||
}); | ||||
r1132 | auto emitSelection = [this]() { | |||
r1143 | QVector<std::shared_ptr<DBEvent> > events; | |||
r1150 | QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts; | |||
r1149 | for (auto rowIndex : ui->treeView->selectionModel()->selectedRows()) { | |||
r1150 | ||||
auto itemType = impl->m_Model->itemTypeOf(rowIndex); | ||||
if (itemType == CatalogueEventsModel::ItemType::Event) { | ||||
events << impl->m_Model->getEvent(rowIndex); | ||||
} | ||||
else if (itemType == CatalogueEventsModel::ItemType::EventProduct) { | ||||
eventProducts << qMakePair(impl->m_Model->getParentEvent(rowIndex), | ||||
impl->m_Model->getEventProduct(rowIndex)); | ||||
} | ||||
r1131 | } | |||
r1150 | if (!events.isEmpty() && eventProducts.isEmpty()) { | |||
emit this->eventsSelected(events); | ||||
} | ||||
else if (events.isEmpty() && !eventProducts.isEmpty()) { | ||||
emit this->eventProductsSelected(eventProducts); | ||||
} | ||||
else { | ||||
emit this->selectionCleared(); | ||||
} | ||||
r1132 | }; | |||
r1105 | ||||
r1149 | connect(ui->treeView, &QTreeView::clicked, emitSelection); | |||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, emitSelection); | ||||
r1105 | ||||
r1149 | connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() { | |||
auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1; | ||||
r1106 | ui->btnChart->setEnabled(isNotMultiSelection); | |||
ui->btnTime->setEnabled(isNotMultiSelection); | ||||
r1138 | ||||
if (isNotMultiSelection && ui->btnTime->isChecked()) { | ||||
r1149 | impl->updateForTimeMode(ui->treeView); | |||
r1138 | } | |||
else if (isNotMultiSelection && ui->btnChart->isChecked()) { | ||||
r1149 | impl->updateForGraphMode(ui->treeView); | |||
r1138 | } | |||
r1105 | }); | |||
r1103 | ||||
r1149 | ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); | |||
ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch); | ||||
ui->treeView->header()->setSortIndicatorShown(true); | ||||
r1095 | } | |||
CatalogueEventsWidget::~CatalogueEventsWidget() | ||||
{ | ||||
delete ui; | ||||
} | ||||
r1101 | ||||
r1136 | void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization) | |||
{ | ||||
impl->m_VisualizationWidget = visualization; | ||||
} | ||||
r1148 | void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges) | |||
{ | ||||
impl->m_Model->refreshEvent(event); | ||||
} | ||||
r1143 | void CatalogueEventsWidget::populateWithCatalogues( | |||
const QVector<std::shared_ptr<DBCatalogue> > &catalogues) | ||||
r1103 | { | |||
r1132 | QSet<QUuid> eventIds; | |||
r1143 | QVector<std::shared_ptr<DBEvent> > events; | |||
r1132 | ||||
for (auto catalogue : catalogues) { | ||||
r1143 | auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue); | |||
r1132 | for (auto event : catalogueEvents) { | |||
r1143 | if (!eventIds.contains(event->getUniqId())) { | |||
r1132 | events << event; | |||
r1143 | eventIds.insert(event->getUniqId()); | |||
r1132 | } | |||
} | ||||
r1129 | } | |||
r1103 | ||||
r1149 | impl->setEvents(events, ui->treeView); | |||
r1101 | } | |||