From 5ff9f36448735b89cc5386a132e30fbfe7febd94 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Thu, 20 Jan 2022 12:52:36 +0100 Subject: [PATCH] Merge pull request #8461 from OPM/8460-plot-curve-fixes Guard access to QtCharts objects that might be null Fix visibility of items in legend based on state in parent plot --- .../ProjectDataModel/RimPlotCurve.cpp | 6 ++- .../Summary/RimSummaryCurve.cpp | 10 +++-- .../Summary/RimSummaryCurveCollection.cpp | 2 +- .../Summary/RimSummaryPlot.cpp | 9 +++- .../UserInterface/RiuQtChartsPlotCurve.cpp | 43 +++++++++++++++++-- .../UserInterface/RiuQtChartsPlotCurve.h | 4 +- 6 files changed, 62 insertions(+), 12 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp index 4a51cbe128..2daad80109 100644 --- a/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimPlotCurve.cpp @@ -982,11 +982,13 @@ void RimPlotCurve::setParentPlotNoReplot( RiuPlotWidget* plotWidget ) if ( !plotWidget ) return; m_parentPlot = plotWidget; - if ( !m_plotCurve ) + if ( m_plotCurve ) { - m_plotCurve = m_parentPlot->createPlotCurve( this, "", RiaColorTools::toQColor( m_curveAppearance->color() ) ); + m_plotCurve->attachToPlot( plotWidget ); + return; } + m_plotCurve = m_parentPlot->createPlotCurve( this, "", RiaColorTools::toQColor( m_curveAppearance->color() ) ); m_plotCurve->attachToPlot( plotWidget ); } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 9a2b728fa0..871c343e6e 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -500,10 +500,12 @@ QString RimSummaryCurve::createCurveAutoName() std::vector nameHelpers; { RimSummaryPlot* plot = nullptr; - firstAncestorOrThisOfTypeAsserted( plot ); - auto nameHelper = plot->plotTitleHelper(); - - if ( nameHelper ) nameHelpers.push_back( nameHelper ); + firstAncestorOrThisOfType( plot ); + if ( plot ) + { + auto nameHelper = plot->plotTitleHelper(); + if ( nameHelper ) nameHelpers.push_back( nameHelper ); + } } { RimSummaryMultiPlot* summaryMultiPlot = nullptr; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp index f5e1b4d672..75fb86cf7c 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp @@ -151,7 +151,7 @@ void RimSummaryCurveCollection::reattachPlotCurves() { for ( RimSummaryCurve* curve : m_curves ) { - curve->reattach(); + if ( curve->isCurveVisible() ) curve->reattach(); } } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index 7923819e2f..957125130a 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -761,6 +761,11 @@ void RimSummaryPlot::updateLegend() if ( plotWidget() ) { plotWidget()->setInternalLegendVisible( m_showPlotLegends && !isSubPlot() ); + + for ( auto c : summaryCurves() ) + { + c->updateLegendEntryVisibilityNoPlotUpdate(); + } } reattachAllCurves(); @@ -1525,6 +1530,8 @@ void RimSummaryPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField, } } + if ( changedField == &m_showPlotLegends ) updateLegend(); + #ifdef USE_QTCHARTS if ( changedField == &m_useQtChartsPlot ) { @@ -2172,7 +2179,7 @@ void RimSummaryPlot::updateCurveNames() { for ( auto c : summaryCurves() ) { - c->updateCurveNameNoLegendUpdate(); + if ( c->isCurveVisible() ) c->updateCurveNameNoLegendUpdate(); } } diff --git a/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.cpp b/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.cpp index a12684eb25..5f497e0869 100644 --- a/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.cpp +++ b/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.cpp @@ -69,6 +69,8 @@ RiuQtChartsPlotCurve::~RiuQtChartsPlotCurve() //-------------------------------------------------------------------------------------------------- void RiuQtChartsPlotCurve::setTitle( const QString& title ) { + if ( !isQtChartObjectsPresent() ) return; + lineSeries()->setName( title ); scatterSeries()->setName( title ); } @@ -82,6 +84,8 @@ void RiuQtChartsPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum const QColor& curveColor, const QBrush& fillBrush /* = QBrush( Qt::NoBrush )*/ ) { + if ( !isQtChartObjectsPresent() ) return; + Qt::PenStyle penStyle = RiuQwtPlotCurveDefines::convertToPenStyle( lineStyle ); QPen curvePen( curveColor ); @@ -97,6 +101,8 @@ void RiuQtChartsPlotCurve::setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum //-------------------------------------------------------------------------------------------------- void RiuQtChartsPlotCurve::setBrush( const QBrush& brush ) { + if ( !isQtChartObjectsPresent() ) return; + lineSeries()->setBrush( brush ); } @@ -116,7 +122,10 @@ void RiuQtChartsPlotCurve::attachToPlot( RiuPlotWidget* plotWidget ) } else { - m_plotWidget->attach( this, lineSeries(), scatterSeries(), m_axisX, m_axisY ); + if ( !m_lineSeries ) m_lineSeries = new QtCharts::QLineSeries(); + if ( !m_scatterSeries ) m_scatterSeries = new QtCharts::QScatterSeries(); + + m_plotWidget->attach( this, m_lineSeries, m_scatterSeries, m_axisX, m_axisY ); // Plot widget takes ownership. m_lineSeries = nullptr; m_scatterSeries = nullptr; @@ -175,6 +184,8 @@ void RiuQtChartsPlotCurve::setSamplesInPlot( const std::vector& xValues, const std::vector& yValues, int numValues ) { + if ( !isQtChartObjectsPresent() ) return; + CAF_ASSERT( xValues.size() == yValues.size() ); CAF_ASSERT( numValues <= static_cast( xValues.size() ) ); CAF_ASSERT( numValues >= 0 ); @@ -191,6 +202,16 @@ void RiuQtChartsPlotCurve::setSamplesInPlot( const std::vector& xValues, } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuQtChartsPlotCurve::isQtChartObjectsPresent() const +{ + if ( !lineSeries() ) return false; + + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -243,6 +264,8 @@ void RiuQtChartsPlotCurve::setYAxis( RiaDefines::PlotAxis axis ) //-------------------------------------------------------------------------------------------------- int RiuQtChartsPlotCurve::numSamples() const { + if ( !lineSeries() ) return 0; + return lineSeries()->count(); } @@ -298,13 +321,27 @@ void RiuQtChartsPlotCurve::setVisibleInLegend( bool isVisibleInLegend ) CAF_ASSERT( m_plotWidget->qtChart() ); CAF_ASSERT( m_plotWidget->qtChart()->legend() ); + // The markers can be set visible independent to the visibility state of the containing legend. Use the visibility + // state of the legend to override the visibility flag + if ( !m_plotWidget->qtChart()->legend()->isAttachedToChart() ) isVisibleInLegend = false; + if ( !m_plotWidget->qtChart()->legend()->isVisible() ) isVisibleInLegend = false; + + bool showScatterMarker = isVisibleInLegend; + if ( !m_symbol ) showScatterMarker = false; + if ( scatterSeries() ) { auto markers = m_plotWidget->qtChart()->legend()->markers( scatterSeries() ); - if ( !markers.isEmpty() ) markers[0]->setVisible( isVisibleInLegend ); + if ( !markers.isEmpty() ) markers[0]->setVisible( showScatterMarker ); + } + bool showLineMarker = isVisibleInLegend; + if ( showScatterMarker ) showLineMarker = false; + + if ( lineSeries() ) + { auto lineSeriesMarkers = m_plotWidget->qtChart()->legend()->markers( lineSeries() ); - if ( !lineSeriesMarkers.isEmpty() ) lineSeriesMarkers[0]->setVisible( false ); + if ( !lineSeriesMarkers.isEmpty() ) lineSeriesMarkers[0]->setVisible( showLineMarker ); } } diff --git a/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.h b/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.h index 07c7bac9ea..634739e02c 100644 --- a/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.h +++ b/ApplicationLibCode/UserInterface/RiuQtChartsPlotCurve.h @@ -77,14 +77,16 @@ public: RiuPlotCurveSymbol* createSymbol( RiuPlotCurveSymbol::PointSymbolEnum symbol ) const override; -protected: +private: void setSamplesInPlot( const std::vector&, const std::vector&, int ) override; + bool isQtChartObjectsPresent() const; QtCharts::QLineSeries* lineSeries() const; QtCharts::QScatterSeries* scatterSeries() const; cvf::BoundingBox computeBoundingBox() const; +private: QtCharts::QLineSeries* m_lineSeries; QtCharts::QScatterSeries* m_scatterSeries; std::shared_ptr m_symbol;