summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorNiklas Nebel <nn@openoffice.org>2011-03-14 11:40:44 +0100
committerNiklas Nebel <nn@openoffice.org>2011-03-14 11:40:44 +0100
commit754240ba32e835ce44097fb14cd449da21195195 (patch)
treed521ce9ab1022af7dbb78fe5a8263a74cf32ece8 /sc
parentb9b552acefead988d14e0e9f4b21fe4480101398 (diff)
calc66: #i117239# prevent nested GetTableData calls from GetPivotData
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/dpobject.hxx3
-rw-r--r--sc/source/core/data/dpobject.cxx45
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 );