diff options
author | Niklas Nebel <nn@openoffice.org> | 2011-03-14 11:40:44 +0100 |
---|---|---|
committer | Niklas Nebel <nn@openoffice.org> | 2011-03-14 11:40:44 +0100 |
commit | 754240ba32e835ce44097fb14cd449da21195195 (patch) | |
tree | d521ce9ab1022af7dbb78fe5a8263a74cf32ece8 /sc | |
parent | b9b552acefead988d14e0e9f4b21fe4480101398 (diff) |
calc66: #i117239# prevent nested GetTableData calls from GetPivotData
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/dpobject.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 45 |
2 files changed, 33 insertions, 15 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index e69f8e8c3a3f..f1ea36e9b81e 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -117,6 +117,7 @@ private: SC_DLLPRIVATE void CreateOutput(); sal_Bool bRefresh; long mnCacheId; + bool mbCreatingTableData; public: // Wang Xu Ming -- 2009-8-17 @@ -156,7 +157,7 @@ public: void SetHeaderLayout(bool bUseGrid); bool GetHeaderLayout() const; - void SetSheetDesc(const ScSheetSourceDesc& rDesc); + void SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate = false); void SetImportDesc(const ScImportSourceDesc& rDesc); void SetServiceData(const ScDPServiceDesc& rDesc); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 77dd1d67139d..b4fb351b9ba7 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -176,7 +176,8 @@ ScDPObject::ScDPObject( ScDocument* pD ) : nHeaderRows( 0 ), mbHeaderLayout(false), bRefresh( sal_False ), // Wang Xu Ming - DataPilot migration - mnCacheId( -1) // Wang Xu Ming - DataPilot migration + mnCacheId( -1 ), // Wang Xu Ming - DataPilot migration + mbCreatingTableData( false ) { } @@ -199,7 +200,8 @@ ScDPObject::ScDPObject(const ScDPObject& r) : nHeaderRows( r.nHeaderRows ), mbHeaderLayout( r.mbHeaderLayout ), bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration - mnCacheId ( r.mnCacheId ) // Wang Xu Ming - DataPilot migration + mnCacheId ( r.mnCacheId ), // Wang Xu Ming - DataPilot migration + mbCreatingTableData( false ) { if (r.pSaveData) pSaveData = new ScDPSaveData(*r.pSaveData); @@ -284,7 +286,7 @@ void ScDPObject::SetOutRange(const ScRange& rRange) pOutput->SetPosition( rRange.aStart ); } -void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) +void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc, bool bFromRefUpdate) { if ( pSheetDesc && rDesc == *pSheetDesc ) return; // nothing to do @@ -304,7 +306,8 @@ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) pSheetDesc->aQueryParam.bHasHeader = sal_True; InvalidateSource(); // new source must be created - SetCacheId( -1 ); // #i116504# don't use the same cache ID for a different range + if (!bFromRefUpdate) + SetCacheId( -1 ); // #i116504# don't use the same cache ID for a different range (except reference update) } void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc) @@ -430,8 +433,12 @@ void ScDPObject::CreateOutput() ScDPTableData* ScDPObject::GetTableData() { - if (!mpTableData) + if (!mpTableData && !mbCreatingTableData) { + // #i117239# While filling the cache, mpTableData is still null. + // Prevent nested calls from GetPivotData and similar functions. + mbCreatingTableData = true; + shared_ptr<ScDPTableData> pData; if ( pImpDesc ) { @@ -467,6 +474,8 @@ ScDPTableData* ScDPObject::GetTableData() // End Comments mpTableData = pData; // after SetCacheId + + mbCreatingTableData = false; } return mpTableData.get(); @@ -496,16 +505,19 @@ void ScDPObject::CreateObjects() DBG_ASSERT( !pServDesc, "DPSource could not be created" ); ScDPTableData* pData = GetTableData(); - ScDPSource* pSource = new ScDPSource( pData ); - xSource = pSource; - - if ( pSaveData && bRefresh ) + if ( pData ) // nested GetTableData calls may return NULL { - pSaveData->Refresh( xSource ); - bRefresh = sal_False; + ScDPSource* pSource = new ScDPSource( pData ); + xSource = pSource; + + if ( pSaveData && bRefresh ) + { + pSaveData->Refresh( xSource ); + bRefresh = sal_False; + } } } - if (pSaveData ) + if ( xSource.is() && pSaveData ) pSaveData->WriteToSource( xSource ); } else if (bSettingsChanged) @@ -753,7 +765,7 @@ void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode, if (aNewDesc.aQueryParam.GetEntry(i).bDoQuery) aNewDesc.aQueryParam.GetEntry(i).nField += nDiffX; - SetSheetDesc( aNewDesc ); // allocates new pSheetDesc + SetSheetDesc( aNewDesc, true ); // allocates new pSheetDesc } } } @@ -781,7 +793,7 @@ void ScDPObject::WriteRefsTo( ScDPObject& r ) const { r.SetOutRange( aOutRange ); if ( pSheetDesc ) - r.SetSheetDesc( *pSheetDesc ); + r.SetSheetDesc( *pSheetDesc, true ); } void ScDPObject::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData) @@ -1057,6 +1069,11 @@ void ScDPObject::GetHeaderPositionData(const ScAddress& rPos, DataPilotTableHead sal_Bool ScDPObject::GetPivotData( ScDPGetPivotDataField& rTarget, const std::vector< ScDPGetPivotDataField >& rFilters ) { + // #i117239# Exit with an error if called from creating the cache for this object + // (don't create an empty pOutput object) + if (mbCreatingTableData) + return sal_False; + CreateOutput(); // create xSource and pOutput if not already done return pOutput->GetPivotData( rTarget, rFilters ); |