diff --git a/gui/include/Visualization/VisualizationGraphWidget.h b/gui/include/Visualization/VisualizationGraphWidget.h index ad413f1..5b7b250 100644 --- a/gui/include/Visualization/VisualizationGraphWidget.h +++ b/gui/include/Visualization/VisualizationGraphWidget.h @@ -62,6 +62,7 @@ signals: void variableAdded(std::shared_ptr var); protected: + void closeEvent(QCloseEvent *event) override; void enterEvent(QEvent *event) override; void leaveEvent(QEvent *event) override; diff --git a/gui/include/Visualization/VisualizationTabWidget.h b/gui/include/Visualization/VisualizationTabWidget.h index ca9b4c8..c3623e2 100644 --- a/gui/include/Visualization/VisualizationTabWidget.h +++ b/gui/include/Visualization/VisualizationTabWidget.h @@ -41,6 +41,9 @@ public: bool contains(const Variable &variable) const override; QString name() const override; +protected: + void closeEvent(QCloseEvent *event) override; + private: /// @return the layout of tab in which zones are added QLayout &tabLayout() const noexcept; diff --git a/gui/include/Visualization/VisualizationWidget.h b/gui/include/Visualization/VisualizationWidget.h index 2d89820..3310990 100644 --- a/gui/include/Visualization/VisualizationWidget.h +++ b/gui/include/Visualization/VisualizationWidget.h @@ -44,6 +44,9 @@ public slots: void onRangeChanged(std::shared_ptr variable, const SqpRange &range) noexcept; +protected: + void closeEvent(QCloseEvent *event) override; + private: Ui::VisualizationWidget *ui; }; diff --git a/gui/include/Visualization/VisualizationZoneWidget.h b/gui/include/Visualization/VisualizationZoneWidget.h index 00389af..02aa6ba 100644 --- a/gui/include/Visualization/VisualizationZoneWidget.h +++ b/gui/include/Visualization/VisualizationZoneWidget.h @@ -42,6 +42,9 @@ public: bool contains(const Variable &variable) const override; QString name() const override; +protected: + void closeEvent(QCloseEvent *event) override; + private: Ui::VisualizationZoneWidget *ui; diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index c277fda..fc99f91 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -220,6 +220,16 @@ QString VisualizationGraphWidget::name() const return impl->m_Name; } +void VisualizationGraphWidget::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event); + + // Prevents that all variables will be removed from graph when it will be closed + for (auto &variableEntry : impl->m_VariableToPlotMultiMap) { + emit variableAboutToBeRemoved(variableEntry.first); + } +} + void VisualizationGraphWidget::enterEvent(QEvent *event) { Q_UNUSED(event); diff --git a/gui/src/Visualization/VisualizationTabWidget.cpp b/gui/src/Visualization/VisualizationTabWidget.cpp index f516cbb..84751e9 100644 --- a/gui/src/Visualization/VisualizationTabWidget.cpp +++ b/gui/src/Visualization/VisualizationTabWidget.cpp @@ -22,6 +22,24 @@ QString defaultZoneName(const QLayout &layout) return QObject::tr("Zone %1").arg(count + 1); } +/** + * Applies a function to all zones of the tab represented by its layout + * @param layout the layout that contains zones + * @param fun the function to apply to each zone + */ +template +void processZones(QLayout &layout, Fun fun) +{ + for (auto i = 0; i < layout.count(); ++i) { + if (auto item = layout.itemAt(i)) { + if (auto visualizationZoneWidget + = dynamic_cast(item->widget())) { + fun(*visualizationZoneWidget); + } + } + } +} + } // namespace struct VisualizationTabWidget::VisualizationTabWidgetPrivate { @@ -67,17 +85,10 @@ void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor) if (visitor) { visitor->visitEnter(this); - // Apply visitor to zone children - auto &layout = tabLayout(); - for (auto i = 0; i < layout.count(); ++i) { - if (auto item = layout.itemAt(i)) { - // Widgets different from zones are not visited (no action) - if (auto visualizationZoneWidget - = dynamic_cast(item->widget())) { - visualizationZoneWidget->accept(visitor); - } - } - } + // Apply visitor to zone children: widgets different from zones are not visited (no action) + processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) { + zoneWidget.accept(visitor); + }); visitor->visitLeave(this); } @@ -104,6 +115,14 @@ QString VisualizationTabWidget::name() const return impl->m_Name; } +void VisualizationTabWidget::closeEvent(QCloseEvent *event) +{ + // Closes zones in the tab + processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); }); + + QWidget::closeEvent(event); +} + QLayout &VisualizationTabWidget::tabLayout() const noexcept { return *ui->scrollAreaWidgetContents->layout(); diff --git a/gui/src/Visualization/VisualizationWidget.cpp b/gui/src/Visualization/VisualizationWidget.cpp index 061bdfe..b215461 100644 --- a/gui/src/Visualization/VisualizationWidget.cpp +++ b/gui/src/Visualization/VisualizationWidget.cpp @@ -157,3 +157,16 @@ void VisualizationWidget::onRangeChanged(std::shared_ptr variable, auto rescaleVariableOperation = RescaleAxeOperation{variable, range}; accept(&rescaleVariableOperation); } + +void VisualizationWidget::closeEvent(QCloseEvent *event) +{ + // Closes tabs in the widget + for (auto i = 0; i < ui->tabWidget->count(); ++i) { + if (auto visualizationTabWidget + = dynamic_cast(ui->tabWidget->widget(i))) { + visualizationTabWidget->close(); + } + } + + QWidget::closeEvent(event); +} diff --git a/gui/src/Visualization/VisualizationZoneWidget.cpp b/gui/src/Visualization/VisualizationZoneWidget.cpp index 88c96f4..943e2fc 100644 --- a/gui/src/Visualization/VisualizationZoneWidget.cpp +++ b/gui/src/Visualization/VisualizationZoneWidget.cpp @@ -34,6 +34,24 @@ QString defaultGraphName(const QLayout &layout) return QObject::tr("Graph %1").arg(count + 1); } +/** + * Applies a function to all graphs of the zone represented by its layout + * @param layout the layout that contains graphs + * @param fun the function to apply to each graph + */ +template +void processGraphs(QLayout &layout, Fun fun) +{ + for (auto i = 0; i < layout.count(); ++i) { + if (auto item = layout.itemAt(i)) { + if (auto visualizationGraphWidget + = dynamic_cast(item->widget())) { + fun(*visualizationGraphWidget); + } + } + } +} + } // namespace struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate { @@ -225,17 +243,11 @@ void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor) if (visitor) { visitor->visitEnter(this); - // Apply visitor to graph children - auto layout = ui->visualizationZoneFrame->layout(); - for (auto i = 0; i < layout->count(); ++i) { - if (auto item = layout->itemAt(i)) { - // Widgets different from graphs are not visited (no action) - if (auto visualizationGraphWidget - = dynamic_cast(item->widget())) { - visualizationGraphWidget->accept(visitor); - } - } - } + // Apply visitor to graph children: widgets different from graphs are not visited (no + // action) + processGraphs( + *ui->visualizationZoneFrame->layout(), + [visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); }); visitor->visitLeave(this); } @@ -262,6 +274,15 @@ QString VisualizationZoneWidget::name() const return ui->zoneNameLabel->text(); } +void VisualizationZoneWidget::closeEvent(QCloseEvent *event) +{ + // Closes graphs in the zone + processGraphs(*ui->visualizationZoneFrame->layout(), + [](VisualizationGraphWidget &graphWidget) { graphWidget.close(); }); + + QWidget::closeEvent(event); +} + void VisualizationZoneWidget::onVariableAdded(std::shared_ptr variable) { QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",