From 908d1b6e632922a6fa59385c49828be3c3eeb969 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Mon, 20 Oct 2014 14:56:32 +0200 Subject: chart2: fix memory leak due to cyclic reference in VAxisBase The VAxisBase::m_xNumberFormatsSupplier refers to the ChartModel itself, and apparently that is a cyclic reference. Naively using the ChartModel's m_xNumberFormatsSupplier in ChartView::impl_createDiagramAndContent() because it will later be passed to AxisHelper::getExplicitNumberFormatKeyForAxis(), which expects to be able to convert it to a ChartModel. Since passing around the ChartModel as an XNumberFormattingSupplier is sort of un-intuitive anyway, refactor some methods to use XChartDocument instead, and only create the VPolarAxis / VCartesianAxis with the ChartModel's m_xNumberFormatsSupplier. The drawback is that if ChartModel::attachNumberFormatsSupplier() is called after ChartView::update() has created the axes, it may not have an effect on them; not sure if that is a real or hypothetical problem. Change-Id: Ib5f0d5882b85adaf44f80e086f19178b3e64882f --- .../source/controller/chartapiwrapper/Chart2ModelContact.cxx | 2 +- chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx | 6 +++--- chart2/source/inc/AxisHelper.hxx | 2 +- chart2/source/inc/chartview/ExplicitValueProvider.hxx | 2 +- chart2/source/tools/AxisHelper.cxx | 6 +++--- chart2/source/tools/ExplicitCategoriesProvider.cxx | 2 +- chart2/source/view/axes/VCartesianCoordinateSystem.cxx | 9 +++++++-- chart2/source/view/axes/VCartesianCoordinateSystem.hxx | 2 +- chart2/source/view/axes/VCoordinateSystem.cxx | 6 +++--- chart2/source/view/axes/VPolarCoordinateSystem.cxx | 9 +++++++-- chart2/source/view/axes/VPolarCoordinateSystem.hxx | 2 +- chart2/source/view/inc/VCoordinateSystem.hxx | 4 ++-- chart2/source/view/main/ChartView.cxx | 10 ++++++---- 13 files changed, 37 insertions(+), 25 deletions(-) diff --git a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx index 1588a2fbdd4b..afdebd1db5ae 100644 --- a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx +++ b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx @@ -158,7 +158,7 @@ sal_Int32 Chart2ModelContact::getExplicitNumberFormatKeyForAxis( xAxis, ChartModelHelper::findDiagram( m_xChartModel ) ) ); return ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( xAxis, xCooSys - , Reference< util::XNumberFormatsSupplier >( m_xChartModel.get(), uno::UNO_QUERY ) ); + , getChart2Document()); } sal_Int32 Chart2ModelContact::getExplicitNumberFormatKeyForSeries( diff --git a/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx b/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx index e2cd620f8340..76f7d6846501 100644 --- a/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx +++ b/chart2/source/controller/itemsetwrapper/AxisItemConverter.cxx @@ -363,7 +363,7 @@ void AxisItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet & rOutI Reference< chart2::XAxis > xCrossingMainAxis( AxisHelper::getCrossingMainAxis( m_xAxis, xCooSys ) ); sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( - xCrossingMainAxis, xCooSys, Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ) ); + xCrossingMainAxis, xCooSys, m_xChartDoc); rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey )); } @@ -407,7 +407,7 @@ void AxisItemConverter::FillSpecialItem( sal_uInt16 nWhichId, SfxItemSet & rOutI m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( - m_xAxis, xCooSys, Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ) ); + m_xAxis, xCooSys, m_xChartDoc); rOutItemSet.Put( SfxUInt32Item( nWhichId, nFormatKey )); } @@ -948,7 +948,7 @@ bool AxisItemConverter::ApplySpecialItem( sal_uInt16 nWhichId, const SfxItemSet m_xAxis, ChartModelHelper::findDiagram( m_xChartDoc ) ) ); sal_Int32 nFormatKey = ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( - m_xAxis, xCooSys, Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ) ); + m_xAxis, xCooSys, m_xChartDoc); aValue <<= nFormatKey; } diff --git a/chart2/source/inc/AxisHelper.hxx b/chart2/source/inc/AxisHelper.hxx index 3aff9dd6f6a7..803532ce0445 100644 --- a/chart2/source/inc/AxisHelper.hxx +++ b/chart2/source/inc/AxisHelper.hxx @@ -57,7 +57,7 @@ public: static sal_Int32 getExplicitNumberFormatKeyForAxis( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem >& xCorrespondingCoordinateSystem - , const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier + , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument>& xChartDoc , bool bSearchForParallelAxisIfNothingIsFound ); static ::com::sun::star::uno::Reference< diff --git a/chart2/source/inc/chartview/ExplicitValueProvider.hxx b/chart2/source/inc/chartview/ExplicitValueProvider.hxx index b18381c3378e..934f22fcc481 100644 --- a/chart2/source/inc/chartview/ExplicitValueProvider.hxx +++ b/chart2/source/inc/chartview/ExplicitValueProvider.hxx @@ -86,7 +86,7 @@ public: static sal_Int32 getExplicitNumberFormatKeyForAxis( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem - , const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier ); + , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument>& xChartDoc); static sal_Int32 getExplicitNumberFormatKeyForDataLabel( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSeriesOrPointProp diff --git a/chart2/source/tools/AxisHelper.cxx b/chart2/source/tools/AxisHelper.cxx index acc757071ff6..d60b0311c07c 100644 --- a/chart2/source/tools/AxisHelper.cxx +++ b/chart2/source/tools/AxisHelper.cxx @@ -132,7 +132,7 @@ void AxisHelper::checkDateAxis( chart2::ScaleData& rScale, ExplicitCategoriesPro sal_Int32 AxisHelper::getExplicitNumberFormatKeyForAxis( const Reference< chart2::XAxis >& xAxis , const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem - , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier + , const Reference& xChartDoc , bool bSearchForParallelAxisIfNothingIsFound ) { sal_Int32 nNumberFormatKey(0); @@ -140,7 +140,7 @@ sal_Int32 AxisHelper::getExplicitNumberFormatKeyForAxis( sal_Int32 nAxisIndex = 0; sal_Int32 nDimensionIndex = 1; AxisHelper::getIndicesForAxis( xAxis, xCorrespondingCoordinateSystem, nDimensionIndex, nAxisIndex ); - Reference< chart2::XChartDocument > xChartDoc( xNumberFormatsSupplier, uno::UNO_QUERY ); + Reference const xNumberFormatsSupplier(xChartDoc, uno::UNO_QUERY); Reference< beans::XPropertySet > xProp( xAxis, uno::UNO_QUERY ); if (!xProp.is()) @@ -321,7 +321,7 @@ sal_Int32 AxisHelper::getExplicitNumberFormatKeyForAxis( { sal_Int32 nParallelAxisIndex = (nAxisIndex==1) ?0 :1; Reference< XAxis > xParallelAxis( AxisHelper::getAxis( 1, nParallelAxisIndex, xCorrespondingCoordinateSystem ) ); - nNumberFormatKey = AxisHelper::getExplicitNumberFormatKeyForAxis( xParallelAxis, xCorrespondingCoordinateSystem, xNumberFormatsSupplier, false ); + nNumberFormatKey = AxisHelper::getExplicitNumberFormatKeyForAxis(xParallelAxis, xCorrespondingCoordinateSystem, xChartDoc, false); } } } diff --git a/chart2/source/tools/ExplicitCategoriesProvider.cxx b/chart2/source/tools/ExplicitCategoriesProvider.cxx index 51ee17ea10c5..a57607178d75 100644 --- a/chart2/source/tools/ExplicitCategoriesProvider.cxx +++ b/chart2/source/tools/ExplicitCategoriesProvider.cxx @@ -183,7 +183,7 @@ void ExplicitCategoriesProvider::convertCategoryAnysToText( uno::Sequence< OUStr { Reference< chart2::XAxis > xAxis( xCooSysModel->getAxisByDimension(0,0) ); nAxisNumberFormat = AxisHelper::getExplicitNumberFormatKeyForAxis( - xAxis, xCooSysModel, uno::Reference< util::XNumberFormatsSupplier> (static_cast< ::cppu::OWeakObject* >( &rModel ), uno::UNO_QUERY), false ); + xAxis, xCooSysModel, uno::Reference(static_cast< ::cppu::OWeakObject* >(&rModel), uno::UNO_QUERY), false ); } sal_Int32 nLabelColor; diff --git a/chart2/source/view/axes/VCartesianCoordinateSystem.cxx b/chart2/source/view/axes/VCartesianCoordinateSystem.cxx index 79005bf4195b..9ca6286bb4b9 100644 --- a/chart2/source/view/axes/VCartesianCoordinateSystem.cxx +++ b/chart2/source/view/axes/VCartesianCoordinateSystem.cxx @@ -94,11 +94,16 @@ void VCartesianCoordinateSystem::createGridShapes() } void VCartesianCoordinateSystem::createVAxisList( - const uno::Reference< util::XNumberFormatsSupplier > & xNumberFormatsSupplier + const uno::Reference & xChartDoc , const awt::Size& rFontReferenceSize , const awt::Rectangle& rMaximumSpaceForLabels ) { + // note: using xChartDoc itself as XNumberFormatsSupplier would cause + // a leak from VCartesianAxis due to cyclic reference + uno::Reference const xNumberFormatsSupplier( + dynamic_cast(xChartDoc.get())->getNumberFormatsSupplier()); + m_aAxisMap.clear(); sal_Int32 nDimensionCount = m_xCooSysModel->getDimension(); @@ -144,7 +149,7 @@ void VCartesianCoordinateSystem::createVAxisList( } aAxisProperties.init(true); if(aAxisProperties.m_bDisplayLabels) - aAxisProperties.m_nNumberFormatKey = this->getNumberFormatKeyForAxis( xAxis, xNumberFormatsSupplier ); + aAxisProperties.m_nNumberFormatKey = this->getNumberFormatKeyForAxis(xAxis, xChartDoc); ::boost::shared_ptr< VAxisBase > apVAxis( new VCartesianAxis(aAxisProperties,xNumberFormatsSupplier,nDimensionIndex,nDimensionCount) ); tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex ); diff --git a/chart2/source/view/axes/VCartesianCoordinateSystem.hxx b/chart2/source/view/axes/VCartesianCoordinateSystem.hxx index 71bdbf45c813..b5a5cc4f5904 100644 --- a/chart2/source/view/axes/VCartesianCoordinateSystem.hxx +++ b/chart2/source/view/axes/VCartesianCoordinateSystem.hxx @@ -34,7 +34,7 @@ public: virtual ~VCartesianCoordinateSystem(); virtual void createVAxisList( - const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier + const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument> &ChartDoc , const ::com::sun::star::awt::Size& rFontReferenceSize , const ::com::sun::star::awt::Rectangle& rMaximumSpaceForLabels ) SAL_OVERRIDE; diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx b/chart2/source/view/axes/VCoordinateSystem.cxx index 7e880977990d..3e8dd8b34d97 100644 --- a/chart2/source/view/axes/VCoordinateSystem.cxx +++ b/chart2/source/view/axes/VCoordinateSystem.cxx @@ -342,7 +342,7 @@ sal_Int32 VCoordinateSystem::getMaximumAxisIndexByDimension( sal_Int32 nDimensio } void VCoordinateSystem::createVAxisList( - const uno::Reference< util::XNumberFormatsSupplier > & /* xNumberFormatsSupplier */ + const uno::Reference & /* xChartDoc */ , const awt::Size& /* rFontReferenceSize */ , const awt::Rectangle& /* rMaximumSpaceForLabels */ ) @@ -573,10 +573,10 @@ void VCoordinateSystem::setSeriesNamesForAxis( const Sequence< OUString >& rSeri sal_Int32 VCoordinateSystem::getNumberFormatKeyForAxis( const Reference< chart2::XAxis >& xAxis - , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier ) + , const Reference& xChartDoc) { return ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( - xAxis, m_xCooSysModel, xNumberFormatsSupplier ); + xAxis, m_xCooSysModel, xChartDoc); } } //namespace chart diff --git a/chart2/source/view/axes/VPolarCoordinateSystem.cxx b/chart2/source/view/axes/VPolarCoordinateSystem.cxx index 50a8ce538633..fe5caa467bd7 100644 --- a/chart2/source/view/axes/VPolarCoordinateSystem.cxx +++ b/chart2/source/view/axes/VPolarCoordinateSystem.cxx @@ -62,11 +62,16 @@ uno::Sequence< sal_Int32 > VPolarCoordinateSystem::getCoordinateSystemResolution } void VPolarCoordinateSystem::createVAxisList( - const uno::Reference< util::XNumberFormatsSupplier > & xNumberFormatsSupplier + const uno::Reference & xChartDoc , const awt::Size& rFontReferenceSize , const awt::Rectangle& rMaximumSpaceForLabels ) { + // note: using xChartDoc itself as XNumberFormatsSupplier would cause + // a leak from VPolarAxis due to cyclic reference + uno::Reference const xNumberFormatsSupplier( + dynamic_cast(xChartDoc.get())->getNumberFormatsSupplier()); + m_aAxisMap.clear(); sal_Int32 nDimensionCount = m_xCooSysModel->getDimension(); sal_Int32 nDimensionIndex = 0; @@ -83,7 +88,7 @@ void VPolarCoordinateSystem::createVAxisList( AxisProperties aAxisProperties(xAxis,this->getExplicitCategoriesProvider()); aAxisProperties.init(); if(aAxisProperties.m_bDisplayLabels) - aAxisProperties.m_nNumberFormatKey = this->getNumberFormatKeyForAxis( xAxis, xNumberFormatsSupplier ); + aAxisProperties.m_nNumberFormatKey = this->getNumberFormatKeyForAxis(xAxis, xChartDoc); ::boost::shared_ptr< VAxisBase > apVAxis( VPolarAxis::createAxis( aAxisProperties,xNumberFormatsSupplier,nDimensionIndex,nDimensionCount) ); tFullAxisIndex aFullAxisIndex( nDimensionIndex, nAxisIndex ); diff --git a/chart2/source/view/axes/VPolarCoordinateSystem.hxx b/chart2/source/view/axes/VPolarCoordinateSystem.hxx index b5c5b858bdab..135c3c19bb50 100644 --- a/chart2/source/view/axes/VPolarCoordinateSystem.hxx +++ b/chart2/source/view/axes/VPolarCoordinateSystem.hxx @@ -38,7 +38,7 @@ public: , const ::com::sun::star::awt::Size& rPageResolution ) SAL_OVERRIDE; virtual void createVAxisList( - const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier + const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument> & xChartDoc , const ::com::sun::star::awt::Size& rFontReferenceSize , const ::com::sun::star::awt::Rectangle& rMaximumSpaceForLabels ) SAL_OVERRIDE; diff --git a/chart2/source/view/inc/VCoordinateSystem.hxx b/chart2/source/view/inc/VCoordinateSystem.hxx index cde8c1b26cee..8408f6661a30 100644 --- a/chart2/source/view/inc/VCoordinateSystem.hxx +++ b/chart2/source/view/inc/VCoordinateSystem.hxx @@ -102,7 +102,7 @@ public: * Create "view" axis obejcts 'VAxis' from the coordinate system model. */ virtual void createVAxisList( - const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xNumberFormatsSupplier + const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument> & xChartDoc , const ::com::sun::star::awt::Size& rFontReferenceSize , const ::com::sun::star::awt::Rectangle& rMaximumSpaceForLabels ); @@ -144,7 +144,7 @@ protected: //methods sal_Int32 getNumberFormatKeyForAxis( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis , const ::com::sun::star::uno::Reference< - ::com::sun::star::util::XNumberFormatsSupplier >& xNumberFormatsSupplier ); + ::com::sun::star::chart2::XChartDocument>& xChartDoc); private: //methods void impl_adjustDimension( sal_Int32& rDimensionIndex ) const; diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index 4ba924b88654..63ba12abda30 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -1515,7 +1515,9 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D SeriesPlottersType& rSeriesPlotterList = rParam.mpSeriesPlotterContainer->getSeriesPlotterList(); //create VAxis, so they can give necessary information for automatic scaling - uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( static_cast< ::cppu::OWeakObject* >( &mrChartModel ), uno::UNO_QUERY ); + uno::Reference const xChartDoc(&mrChartModel); + uno::Reference const xNumberFormatsSupplier( + mrChartModel.getNumberFormatsSupplier()); size_t nC = 0; for( nC=0; nC < rVCooSysList.size(); nC++) { @@ -1529,7 +1531,7 @@ awt::Rectangle ChartView::impl_createDiagramAndContent( const CreateShapeParam2D pVCooSys->set3DWallPositions( eLeftWallPos, eBackWallPos, eBottomPos ); } - pVCooSys->createVAxisList(xNumberFormatsSupplier, rPageSize, rParam.maRemainingSpace); + pVCooSys->createVAxisList(xChartDoc, rPageSize, rParam.maRemainingSpace); } // - prepare list of all axis and how they are used @@ -1946,9 +1948,9 @@ bool lcl_getPropertySwapXAndYAxis( const uno::Reference< XDiagram >& xDiagram ) sal_Int32 ExplicitValueProvider::getExplicitNumberFormatKeyForAxis( const Reference< chart2::XAxis >& xAxis , const Reference< chart2::XCoordinateSystem > & xCorrespondingCoordinateSystem - , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier ) + , const Reference& xChartDoc) { - return AxisHelper::getExplicitNumberFormatKeyForAxis( xAxis, xCorrespondingCoordinateSystem, xNumberFormatsSupplier + return AxisHelper::getExplicitNumberFormatKeyForAxis( xAxis, xCorrespondingCoordinateSystem, xChartDoc , true /*bSearchForParallelAxisIfNothingIsFound*/ ); } -- cgit