diff --git a/gui/include/Catalogue/CatalogueEventsWidget.h b/gui/include/Catalogue/CatalogueEventsWidget.h index 0dee481..b40dfca 100644 --- a/gui/include/Catalogue/CatalogueEventsWidget.h +++ b/gui/include/Catalogue/CatalogueEventsWidget.h @@ -9,6 +9,7 @@ class DBCatalogue; class DBEvent; class DBEventProduct; class VisualizationWidget; +class VisualizationSelectionZoneItem; namespace Ui { class CatalogueEventsWidget; @@ -21,10 +22,13 @@ class CatalogueEventsWidget : public QWidget { signals: void eventsSelected(const QVector > &event); + void eventsRemoved(const QVector > &event); void eventProductsSelected( const QVector, std::shared_ptr > > &eventproducts); void selectionCleared(); + void selectionZoneAdded(const std::shared_ptr &event, const QString &productId, + VisualizationSelectionZoneItem *selectionZone); public: explicit CatalogueEventsWidget(QWidget *parent = 0); @@ -39,6 +43,8 @@ public: bool isAllEventsDisplayed() const; bool isEventDisplayed(const std::shared_ptr &event) const; + void refreshEvent(const std::shared_ptr &event); + public slots: void populateWithCatalogues(const QVector > &catalogues); void populateWithAllEvents(); diff --git a/gui/include/Catalogue/CatalogueInspectorWidget.h b/gui/include/Catalogue/CatalogueInspectorWidget.h index 51c42b9..1bef099 100644 --- a/gui/include/Catalogue/CatalogueInspectorWidget.h +++ b/gui/include/Catalogue/CatalogueInspectorWidget.h @@ -36,6 +36,8 @@ public: const std::shared_ptr &eventProduct); void setCatalogue(const std::shared_ptr &catalogue); + void refresh(); + public slots: void showPage(Page page); diff --git a/gui/include/Visualization/VisualizationGraphWidget.h b/gui/include/Visualization/VisualizationGraphWidget.h index 8ce15f1..c48e045 100644 --- a/gui/include/Visualization/VisualizationGraphWidget.h +++ b/gui/include/Visualization/VisualizationGraphWidget.h @@ -77,6 +77,8 @@ public: QVector selectionZoneRanges() const; /// Adds new selection zones in the graph void addSelectionZones(const QVector &ranges); + /// Adds a new selection zone in the graph + VisualizationSelectionZoneItem *addSelectionZone(const QString &name, const SqpRange &range); /// Removes the specified selection zone void removeSelectionZone(VisualizationSelectionZoneItem *selectionZone); diff --git a/gui/include/Visualization/VisualizationSelectionZoneItem.h b/gui/include/Visualization/VisualizationSelectionZoneItem.h index d7b6e58..675981e 100644 --- a/gui/include/Visualization/VisualizationSelectionZoneItem.h +++ b/gui/include/Visualization/VisualizationSelectionZoneItem.h @@ -8,6 +8,11 @@ class VisualizationGraphWidget; class VisualizationSelectionZoneItem : public QCPItemRect { + Q_OBJECT + +signals: + /// Signal emitted when the zone range is edited manually + void rangeEdited(const SqpRange &range); public: VisualizationSelectionZoneItem(QCustomPlot *plot); diff --git a/gui/meson.build b/gui/meson.build index add3dca..1a81c55 100644 --- a/gui/meson.build +++ b/gui/meson.build @@ -20,6 +20,7 @@ gui_moc_headers = [ 'include/Visualization/VisualizationDragDropContainer.h', 'include/Visualization/VisualizationDragWidget.h', 'include/Visualization/ColorScaleEditor.h', + 'include/Visualization/VisualizationSelectionZoneItem.h', 'include/Actions/SelectionZoneAction.h', 'include/Visualization/VisualizationMultiZoneSelectionDialog.h', 'include/Catalogue/CatalogueExplorer.h', diff --git a/gui/src/Catalogue/CatalogueEventsWidget.cpp b/gui/src/Catalogue/CatalogueEventsWidget.cpp index 3c01c4f..882d212 100644 --- a/gui/src/Catalogue/CatalogueEventsWidget.cpp +++ b/gui/src/Catalogue/CatalogueEventsWidget.cpp @@ -224,9 +224,9 @@ struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate { return correctedGraphRanges; } - void updateForGraphMode(QTreeView *treeView) + void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget) { - auto selectedRows = treeView->selectionModel()->selectedRows(); + auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows(); if (selectedRows.count() != 1) { qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: not compatible with multiple events selected"; @@ -285,17 +285,21 @@ struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate { productRange.m_TStart = eventProduct.getTStart(); productRange.m_TEnd = eventProduct.getTEnd(); - auto context = new QObject{treeView}; + auto context = new QObject{catalogueEventWidget}; QObject::connect( &sqpApp->variableController(), &VariableController::variableAdded, context, - [this, zone, context, range, productRange, productId](auto variable) { + [this, catalogueEventWidget, zone, context, event, range, productRange, + productId](auto variable) { if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString() == productId) { auto graph = zone->createGraph(variable); graph->setAutoRangeOnVariableInitialization(false); - graph->addSelectionZones({productRange}); + auto selectionZone + = graph->addSelectionZone(event->getName(), productRange); + emit catalogueEventWidget->selectionZoneAdded(event, productId, + selectionZone); m_CustomGraphs << graph; graph->setGraphRange(range, true); @@ -365,7 +369,7 @@ CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent) this->mapToGlobal(ui->btnChart->frameGeometry().center())) .value(0); - impl->updateForGraphMode(ui->treeView); + impl->updateForGraphMode(this); } }); @@ -386,6 +390,8 @@ CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent) sqpApp->catalogueController().removeEvent(event); impl->removeEvent(event, ui->treeView); } + + emit this->eventsRemoved(events); } } }); @@ -404,7 +410,7 @@ CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent) impl->updateForTimeMode(ui->treeView); } else if (isNotMultiSelection && ui->btnChart->isChecked()) { - impl->updateForGraphMode(ui->treeView); + impl->updateForGraphMode(this); } QVector > events; @@ -507,6 +513,11 @@ bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr &eve return impl->m_Model->indexOf(event).isValid(); } +void CatalogueEventsWidget::refreshEvent(const std::shared_ptr &event) +{ + impl->m_Model->refreshEvent(event, true); +} + void CatalogueEventsWidget::populateWithCatalogues( const QVector > &catalogues) { diff --git a/gui/src/Catalogue/CatalogueExplorer.cpp b/gui/src/Catalogue/CatalogueExplorer.cpp index e730041..d90e973 100644 --- a/gui/src/Catalogue/CatalogueExplorer.cpp +++ b/gui/src/Catalogue/CatalogueExplorer.cpp @@ -4,13 +4,20 @@ #include #include #include +#include +#include #include #include #include +#include + +#include struct CatalogueExplorer::CatalogueExplorerPrivate { CatalogueActionManager m_ActionManager; + std::unordered_map, QVector > + m_SelectionZonesPerEvents; CatalogueExplorerPrivate(CatalogueExplorer *catalogueExplorer) : m_ActionManager(catalogueExplorer) @@ -27,6 +34,7 @@ CatalogueExplorer::CatalogueExplorer(QWidget *parent) impl->m_ActionManager.installSelectionZoneActions(); + // Updates events and inspector when something is selected in the catalogue widget connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSelected, [this](auto catalogues) { if (catalogues.count() == 1) { ui->inspector->setCatalogue(catalogues.first()); @@ -66,6 +74,7 @@ CatalogueExplorer::CatalogueExplorer(QWidget *parent) ui->events->clear(); }); + // Updates the inspectot when something is selected in the events connect(ui->events, &CatalogueEventsWidget::eventsSelected, [this](auto events) { if (events.count() == 1) { ui->inspector->setEvent(events.first()); @@ -88,6 +97,42 @@ CatalogueExplorer::CatalogueExplorer(QWidget *parent) connect(ui->events, &CatalogueEventsWidget::selectionCleared, [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); }); + // Manage Selection Zones associated to events + connect(ui->events, &CatalogueEventsWidget::selectionZoneAdded, + [this](auto event, auto productId, auto zone) { + impl->m_SelectionZonesPerEvents[event] << zone; + connect(zone, &VisualizationSelectionZoneItem::rangeEdited, + [event, productId, this](auto range) { + auto productList = event->getEventProducts(); + for (auto &product : productList) { + if (product.getProductId() == productId) { + product.setTStart(range.m_TStart); + product.setTEnd(range.m_TEnd); + } + } + event->setEventProducts(productList); + sqpApp->catalogueController().updateEvent(event); + ui->events->refreshEvent(event); + ui->events->setEventChanges(event, true); + ui->inspector->refresh(); + }); + }); + + connect(ui->events, &CatalogueEventsWidget::eventsRemoved, [this](auto events) { + for (auto event : events) { + auto associatedSelectionZonesIt = impl->m_SelectionZonesPerEvents.find(event); + if (associatedSelectionZonesIt != impl->m_SelectionZonesPerEvents.cend()) { + for (auto selectionZone : associatedSelectionZonesIt->second) { + auto parentGraph = selectionZone->parentGraphWidget(); + parentGraph->removeSelectionZone(selectionZone); + } + + impl->m_SelectionZonesPerEvents.erase(event); + } + } + }); + + // Updates changes from the inspector connect(ui->inspector, &CatalogueInspectorWidget::catalogueUpdated, [this](auto catalogue) { sqpApp->catalogueController().updateCatalogue(catalogue); ui->catalogues->setCatalogueChanges(catalogue, true); diff --git a/gui/src/Catalogue/CatalogueInspectorWidget.cpp b/gui/src/Catalogue/CatalogueInspectorWidget.cpp index 6ab4aa8..02c8616 100644 --- a/gui/src/Catalogue/CatalogueInspectorWidget.cpp +++ b/gui/src/Catalogue/CatalogueInspectorWidget.cpp @@ -209,3 +209,19 @@ void CatalogueInspectorWidget::setCatalogue(const std::shared_ptr & blockSignals(false); } + +void CatalogueInspectorWidget::refresh() +{ + switch (static_cast(ui->stackedWidget->currentIndex())) { + case Page::CatalogueProperties: + setCatalogue(impl->m_DisplayedCatalogue); + break; + case Page::EventProperties: { + auto isEventShowed = ui->leEventName->isEnabled(); + setEvent(impl->m_DisplayedEvent); + if (!isEventShowed && impl->m_DisplayedEvent) { + setEventProduct(impl->m_DisplayedEvent, impl->m_DisplayedEventProduct); + } + } + } +} diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index 1b7bbe8..204224e 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -438,6 +438,20 @@ void VisualizationGraphWidget::addSelectionZones(const QVector &ranges plot().replot(QCustomPlot::rpQueuedReplot); } +VisualizationSelectionZoneItem *VisualizationGraphWidget::addSelectionZone(const QString &name, + const SqpRange &range) +{ + // note: ownership is transfered to QCustomPlot + auto zone = new VisualizationSelectionZoneItem(&plot()); + zone->setName(name); + zone->setRange(range.m_TStart, range.m_TEnd); + impl->addSelectionZone(zone); + + plot().replot(QCustomPlot::rpQueuedReplot); + + return zone; +} + void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem *selectionZone) { parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false); diff --git a/gui/src/Visualization/VisualizationSelectionZoneItem.cpp b/gui/src/Visualization/VisualizationSelectionZoneItem.cpp index 2e5c5b2..4e51bd9 100644 --- a/gui/src/Visualization/VisualizationSelectionZoneItem.cpp +++ b/gui/src/Visualization/VisualizationSelectionZoneItem.cpp @@ -388,8 +388,11 @@ void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QP break; } + emit rangeEdited(range()); + for (auto associatedZone : impl->m_AssociatedEditedZones) { associatedZone->parentPlot()->replot(); + emit associatedZone->rangeEdited(associatedZone->range()); } } else {