##// END OF EJS Templates
Fixes data loss in some cases of data recovery from the CosiunusProvider
Fixes data loss in some cases of data recovery from the CosiunusProvider

File last commit:

r739:0435199fe310
r764:6fa5f5facdaa
Show More
VisualizationZoneWidget.cpp
302 lines | 11.9 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationZoneWidget.cpp
mv visualization -> Visualization...
r95 #include "Visualization/VisualizationZoneWidget.h"
Add synchronization that keep delta
r444
Alexandre Leroux
Updates visitor interface...
r207 #include "Visualization/IVisualizationWidgetVisitor.h"
Alexandre Leroux
Sets sames margin sides for graphs in a same zone
r730 #include "Visualization/QCustomPlotSynchronizer.h"
Add synchronization that keep delta
r444 #include "Visualization/VisualizationGraphWidget.h"
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 #include "ui_VisualizationZoneWidget.h"
Implementation of V5 acquisition
r539 #include <Data/SqpRange.h>
Initialisation of the graph range at creation in a new graphe, or inside...
r548 #include <Variable/Variable.h>
Implementation of V5 acquisition
r539 #include <Variable/VariableController.h>
Add the visualization gui classes
r118
Implementation of V5 acquisition
r539 #include <QUuid>
Alexandre Leroux
Adds a close button to a zone widget + calls close() method when clicked
r265 #include <SqpApplication.h>
Change cmath include order from clang format
r621 #include <cmath>
Alexandre Leroux
Adds a close button to a zone widget + calls close() method when clicked
r265
Alexandre Leroux
Adds logs for null visitors
r219 Q_LOGGING_CATEGORY(LOG_VisualizationZoneWidget, "VisualizationZoneWidget")
Alexandre Leroux
Completes the method of creating a zone from a variable
r200 namespace {
Alexandre Leroux
Adds scrollbar to tabs
r307 /// Minimum height for graph added in zones (in pixels)
const auto GRAPH_MINIMUM_HEIGHT = 300;
Alexandre Leroux
Completes the method of creating a zone from a variable
r200 /// Generates a default name for a new graph, according to the number of graphs already displayed in
/// the zone
QString defaultGraphName(const QLayout &layout)
{
auto count = 0;
for (auto i = 0; i < layout.count(); ++i) {
if (dynamic_cast<VisualizationGraphWidget *>(layout.itemAt(i)->widget())) {
count++;
}
}
return QObject::tr("Graph %1").arg(count + 1);
}
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (2)...
r738 /**
* 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 <typename Fun>
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<VisualizationGraphWidget *>(item->widget())) {
fun(*visualizationGraphWidget);
}
}
}
}
Alexandre Leroux
Completes the method of creating a zone from a variable
r200 } // namespace
Implementation of V5 acquisition
r539 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
Alexandre Leroux
Sets sames margin sides for graphs in a same zone
r730 explicit VisualizationZoneWidgetPrivate()
: m_SynchronisationGroupId{QUuid::createUuid()},
m_Synchronizer{std::make_unique<QCustomPlotSynchronizer>()}
{
}
Implementation of V5 acquisition
r539 QUuid m_SynchronisationGroupId;
Alexandre Leroux
Sets sames margin sides for graphs in a same zone
r730 std::unique_ptr<IGraphSynchronizer> m_Synchronizer;
Implementation of V5 acquisition
r539 };
Alexandre Leroux
Adds a name for a zone...
r197 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
Implementation of V5 acquisition
r539 : QWidget{parent},
ui{new Ui::VisualizationZoneWidget},
impl{spimpl::make_unique_impl<VisualizationZoneWidgetPrivate>()}
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 {
ui->setupUi(this);
Alexandre Leroux
Adds a name for a zone...
r197
ui->zoneNameLabel->setText(name);
Alexandre Leroux
Adds a close button to a zone widget + calls close() method when clicked
r265
// 'Close' options : widget is deleted when closed
setAttribute(Qt::WA_DeleteOnClose);
connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationZoneWidget::close);
ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
Implementation of V5 acquisition
r539
// Synchronisation id
QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronizationGroupId",
Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 }
VisualizationZoneWidget::~VisualizationZoneWidget()
{
delete ui;
}
Add the visualization gui classes
r118
void VisualizationZoneWidget::addGraph(VisualizationGraphWidget *graphWidget)
{
Alexandre Leroux
Sets sames margin sides for graphs in a same zone
r730 // Synchronize new graph with others in the zone
impl->m_Synchronizer->addGraph(*graphWidget);
Add the visualization gui classes
r118 ui->visualizationZoneFrame->layout()->addWidget(graphWidget);
}
Alexandre Leroux
Completes the method of creating a zone from a variable
r200 VisualizationGraphWidget *VisualizationZoneWidget::createGraph(std::shared_ptr<Variable> variable)
Add the visualization gui classes
r118 {
Alexandre Leroux
Completes the method of creating a zone from a variable
r200 auto graphWidget = new VisualizationGraphWidget{
defaultGraphName(*ui->visualizationZoneFrame->layout()), this};
Alexandre Leroux
Adds scrollbar to tabs
r307
Add synchronization that keep delta
r444
Alexandre Leroux
Adds scrollbar to tabs
r307 // Set graph properties
graphWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
graphWidget->setMinimumHeight(GRAPH_MINIMUM_HEIGHT);
Alexandre Leroux
Completes the method of creating a zone from a variable
r200
Add synchronization that keep delta
r444 // Lambda to synchronize zone widget
change grapheRange to graphRange
r545 auto synchronizeZoneWidget = [this, graphWidget](const SqpRange &graphRange,
Implementation of V5 acquisition
r539 const SqpRange &oldGraphRange) {
change grapheRange to graphRange
r545 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
Add synchronization that keep delta
r444 auto frameLayout = ui->visualizationZoneFrame->layout();
for (auto i = 0; i < frameLayout->count(); ++i) {
auto graphChild
= dynamic_cast<VisualizationGraphWidget *>(frameLayout->itemAt(i)->widget());
if (graphChild && (graphChild != graphWidget)) {
auto graphChildRange = graphChild->graphRange();
switch (zoomType) {
Implementation of V5 acquisition
r539 case AcquisitionZoomType::ZoomIn: {
change grapheRange to graphRange
r545 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
Add synchronization that keep delta
r444 graphChildRange.m_TStart += deltaLeft;
graphChildRange.m_TEnd -= deltaRight;
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomIn");
qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
<< deltaLeft;
qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
<< deltaRight;
qCDebug(LOG_VisualizationZoneWidget())
change grapheRange to graphRange
r545 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
Implementation of the calibration for the synchronization...
r445
Add synchronization that keep delta
r444 break;
}
Implementation of V5 acquisition
r539 case AcquisitionZoomType::ZoomOut: {
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: ZoomOut");
change grapheRange to graphRange
r545 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaLeft")
<< deltaLeft;
qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: deltaRight")
<< deltaRight;
qCDebug(LOG_VisualizationZoneWidget())
change grapheRange to graphRange
r545 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
Add synchronization that keep delta
r444 graphChildRange.m_TStart -= deltaLeft;
graphChildRange.m_TEnd += deltaRight;
break;
}
Implementation of V5 acquisition
r539 case AcquisitionZoomType::PanRight: {
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanRight");
change grapheRange to graphRange
r545 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
Add synchronization that keep delta
r444 graphChildRange.m_TStart += deltaRight;
graphChildRange.m_TEnd += deltaRight;
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget())
change grapheRange to graphRange
r545 << tr("TORM: dt") << graphRange.m_TEnd - graphRange.m_TStart;
Add synchronization that keep delta
r444 break;
}
Implementation of V5 acquisition
r539 case AcquisitionZoomType::PanLeft: {
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: PanLeft");
change grapheRange to graphRange
r545 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
Add synchronization that keep delta
r444 graphChildRange.m_TStart -= deltaLeft;
graphChildRange.m_TEnd -= deltaLeft;
break;
}
Implementation of V5 acquisition
r539 case AcquisitionZoomType::Unknown: {
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget())
Add synchronization that keep delta
r444 << tr("Impossible to synchronize: zoom type unknown");
break;
}
default:
qCCritical(LOG_VisualizationZoneWidget())
<< tr("Impossible to synchronize: zoom type not take into account");
// No action
break;
}
Implementation of V5 acquisition
r539 graphChild->enableAcquisition(false);
Next range of a variable synchronized is now computed using:...
r627 qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range before: ")
<< graphChild->graphRange();
qCDebug(LOG_VisualizationZoneWidget()) << tr("TORM: Range after : ")
<< graphChildRange;
qCDebug(LOG_VisualizationZoneWidget())
Implementation of the calibration for the synchronization...
r445 << tr("TORM: child dt") << graphChildRange.m_TEnd - graphChildRange.m_TStart;
graphChild->setGraphRange(graphChildRange);
Implementation of V5 acquisition
r539 graphChild->enableAcquisition(true);
Add synchronization that keep delta
r444 }
}
};
// connection for synchronization
connect(graphWidget, &VisualizationGraphWidget::synchronize, synchronizeZoneWidget);
Add synchronization part of v5 acquisition
r540 connect(graphWidget, &VisualizationGraphWidget::variableAdded, this,
&VisualizationZoneWidget::onVariableAdded);
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (1)...
r737 connect(graphWidget, &VisualizationGraphWidget::variableAboutToBeRemoved, this,
&VisualizationZoneWidget::onVariableAboutToBeRemoved);
Add synchronization part of v5 acquisition
r540
Initialisation of the graph range at creation in a new graphe, or inside...
r548 auto range = SqpRange{};
// Apply visitor to graph children
auto layout = ui->visualizationZoneFrame->layout();
if (layout->count() > 0) {
// Case of a new graph in a existant zone
if (auto visualizationGraphWidget
= dynamic_cast<VisualizationGraphWidget *>(layout->itemAt(0)->widget())) {
range = visualizationGraphWidget->graphRange();
}
}
else {
// Case of a new graph as the first of the zone
range = variable->range();
}
Add synchronization part of v5 acquisition
r540 this->addGraph(graphWidget);
Initialisation of the graph range at creation in a new graphe, or inside...
r548 graphWidget->addVariable(variable, range);
Alexandre Leroux
Uses variable range in graph
r615
// get y using variable range
if (auto dataSeries = variable->dataSeries()) {
Add thread protection for DataSeries...
r636 dataSeries->lockRead();
Add clang format from linux
r637 auto valuesBounds
= dataSeries->valuesBounds(variable->range().m_TStart, variable->range().m_TEnd);
Alexandre Leroux
Uses variable range in graph
r615 auto end = dataSeries->cend();
if (valuesBounds.first != end && valuesBounds.second != end) {
auto rangeValue = [](const auto &value) { return std::isnan(value) ? 0. : value; };
auto minValue = rangeValue(valuesBounds.first->minValue());
auto maxValue = rangeValue(valuesBounds.second->maxValue());
graphWidget->setYRange(SqpRange{minValue, maxValue});
}
Add thread protection for DataSeries...
r636 dataSeries->unlock();
Alexandre Leroux
Uses variable range in graph
r615 }
Add synchronization that keep delta
r444
Add the visualization gui classes
r118 return graphWidget;
}
Alexandre Leroux
Updates visitor interface...
r207 void VisualizationZoneWidget::accept(IVisualizationWidgetVisitor *visitor)
Add the visualization gui classes
r118 {
Alexandre Leroux
Implements accept() method of visualization widgets
r208 if (visitor) {
visitor->visitEnter(this);
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (2)...
r738 // Apply visitor to graph children: widgets different from graphs are not visited (no
// action)
processGraphs(
*ui->visualizationZoneFrame->layout(),
[visitor](VisualizationGraphWidget &graphWidget) { graphWidget.accept(visitor); });
Alexandre Leroux
Implements accept() method of visualization widgets
r208
visitor->visitLeave(this);
}
Alexandre Leroux
Adds logs for null visitors
r219 else {
qCCritical(LOG_VisualizationZoneWidget()) << tr("Can't visit widget : the visitor is null");
}
Add the visualization gui classes
r118 }
Alexandre Leroux
Creates a interface that defines a variable container...
r209 bool VisualizationZoneWidget::canDrop(const Variable &variable) const
{
// A tab can always accomodate a variable
Q_UNUSED(variable);
return true;
}
Alexandre Leroux
Unplot menu (5): adds contains() method to an IVariableContainer...
r327 bool VisualizationZoneWidget::contains(const Variable &variable) const
{
Q_UNUSED(variable);
return false;
}
Add const and override
r119 QString VisualizationZoneWidget::name() const
Add the visualization gui classes
r118 {
Alexandre Leroux
Adds a name for a zone...
r197 return ui->zoneNameLabel->text();
Add the visualization gui classes
r118 }
Add synchronization part of v5 acquisition
r540
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (2)...
r738 void VisualizationZoneWidget::closeEvent(QCloseEvent *event)
{
// Closes graphs in the zone
processGraphs(*ui->visualizationZoneFrame->layout(),
[](VisualizationGraphWidget &graphWidget) { graphWidget.close(); });
Alexandre Leroux
Removes synchronisation group from Variable controller when a zone is being closed
r739 // Delete synchronization group from variable controller
QMetaObject::invokeMethod(&sqpApp->variableController(), "onRemoveSynchronizationGroupId",
Qt::QueuedConnection, Q_ARG(QUuid, impl->m_SynchronisationGroupId));
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (2)...
r738 QWidget::closeEvent(event);
}
Add synchronization part of v5 acquisition
r540 void VisualizationZoneWidget::onVariableAdded(std::shared_ptr<Variable> variable)
{
QMetaObject::invokeMethod(&sqpApp->variableController(), "onAddSynchronized",
Qt::QueuedConnection, Q_ARG(std::shared_ptr<Variable>, variable),
Q_ARG(QUuid, impl->m_SynchronisationGroupId));
}
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (1)...
r737
void VisualizationZoneWidget::onVariableAboutToBeRemoved(std::shared_ptr<Variable> variable)
{
QMetaObject::invokeMethod(&sqpApp->variableController(), "desynchronize", Qt::QueuedConnection,
Q_ARG(std::shared_ptr<Variable>, variable),
Q_ARG(QUuid, impl->m_SynchronisationGroupId));
}