[Libreoffice-commits] .: sc/inc sc/qa sc/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Wed Dec 5 09:57:15 PST 2012
sc/inc/dpsave.hxx | 2 +
sc/qa/unit/ucalc.cxx | 29 ++++++++++++++++++++++++++
sc/source/core/data/dpobject.cxx | 12 +++++++++-
sc/source/core/data/dpsave.cxx | 37 +++++++++++++++++++++++++++++++++
sc/source/ui/view/dbfunc3.cxx | 43 ++++++---------------------------------
5 files changed, 86 insertions(+), 37 deletions(-)
New commits:
commit 56bb08e75c12cb85041607f7f34451018b09414f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Dec 5 12:53:03 2012 -0500
fdo#57497: Remove group table data when all group dimensions are gone.
Otherwise ungrouping date grouped dimension may crash, or produce
incorrect results.
Change-Id: I3634e3c0bf8336fc1221f5d234cb7e01eb1f07c6
diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx
index 5a97b54..948117b 100644
--- a/sc/inc/dpsave.hxx
+++ b/sc/inc/dpsave.hxx
@@ -336,6 +336,8 @@ public:
const ScDPDimensionSaveData* GetExistingDimensionData() const
{ return pDimensionData; }
+ void RemoveAllGroupDimensions( const rtl::OUString& rSrcDimName, std::vector<rtl::OUString>* pDeletedNames = NULL );
+
SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there
void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
void BuildAllDimensionMembers(ScDPTableData* pData);
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index e3de176..2509400 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2964,6 +2964,35 @@ void Test::testPivotTableDateGrouping()
CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
}
+ // Remove all date grouping. The source dimension "Date" has two
+ // external dimensions ("Years" and "Quarters") and one internal ("Date"
+ // the same name but different hierarchy). Remove all of them.
+ pSaveData = pDPObj->GetSaveData();
+ pSaveData->RemoveAllGroupDimensions(aBaseDimName);
+ pDPObj->SetSaveData(*pSaveData);
+ pDPObj->ReloadGroupTableData();
+ pDPObj->InvalidateData();
+
+ aOutRange = refresh(pDPObj);
+ {
+ // Expected output table content. 0 = empty cell
+ const char* aOutputCheck[][2] = {
+ { "Date", 0 },
+ { "2011-01-01", "1" },
+ { "2011-03-02", "2" },
+ { "2011-09-03", "7" },
+ { "2012-01-04", "3" },
+ { "2012-02-23", "4" },
+ { "2012-02-24", "5" },
+ { "2012-03-15", "6" },
+ { "2012-12-25", "8" },
+ { "Total Result", "36" }
+ };
+
+ bSuccess = checkDPTableOutput<2>(m_pDoc, aOutRange, aOutputCheck, "Remove all date grouping.");
+ CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
+ }
+
pDPs->FreeTable(pDPObj);
CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no more tables.", pDPs->GetCount(), static_cast<size_t>(0));
CPPUNIT_ASSERT_EQUAL_MESSAGE("There shouldn't be any more cache stored.",
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 529de6b..9b78336 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -710,8 +710,18 @@ void ScDPObject::ReloadGroupTableData()
const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData();
if (!pDimData || !pDimData->HasGroupDimensions())
- // No group dimensions exist.
+ {
+ // No group dimensions exist. Check if it currently has group
+ // dimensions, and if so, remove all of them.
+ ScDPGroupTableData* pData = dynamic_cast<ScDPGroupTableData*>(mpTableData.get());
+ if (pData)
+ {
+ // Replace the existing group table data with the source data.
+ shared_ptr<ScDPTableData> pSource = pData->GetSourceTableData();
+ mpTableData = pSource;
+ }
return;
+ }
ScDPGroupTableData* pData = dynamic_cast<ScDPGroupTableData*>(mpTableData.get());
if (pData)
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 3a9f174..5fcd8d7 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -1209,6 +1209,43 @@ bool ScDPSaveData::IsEmpty() const
return true; // no entries that are not hidden
}
+void ScDPSaveData::RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames )
+{
+ if (!pDimensionData)
+ // No group dimensions exist. Nothing to do.
+ return;
+
+ // Remove numeric group dimension (exists once at most). No need to delete
+ // anything in save data (grouping was done inplace in an existing base
+ // dimension).
+ pDimensionData->RemoveNumGroupDimension(rSrcDimName);
+
+ // Remove named group dimension(s). Dimensions have to be removed from
+ // dimension save data and from save data too.
+ const ScDPSaveGroupDimension* pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
+ while ( pExistingGroup )
+ {
+ rtl::OUString aGroupDimName = pExistingGroup->GetGroupDimName();
+ pDimensionData->RemoveGroupDimension(aGroupDimName); // pExistingGroup is deleted
+
+ // also remove SaveData settings for the dimension that no longer exists
+ RemoveDimensionByName(aGroupDimName);
+
+ if (pDeletedNames)
+ pDeletedNames->push_back(aGroupDimName);
+
+ // see if there are more group dimensions
+ pExistingGroup = pDimensionData->GetGroupDimForBase(rSrcDimName);
+
+ if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
+ {
+ // still get the same group dimension?
+ OSL_FAIL("couldn't remove group dimension");
+ pExistingGroup = NULL; // avoid endless loop
+ }
+ }
+}
+
ScDPDimensionSaveData* ScDPSaveData::GetDimensionData()
{
if (!pDimensionData)
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 5f58d70..5925e3f 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -946,52 +946,23 @@ void ScDBFunc::DateGroupDataPilot( const ScDPNumGroupInfo& rInfo, sal_Int32 nPar
if (aEntries.empty())
return;
+ std::vector<rtl::OUString> aDeletedNames;
bool bIsDataLayout;
OUString aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout );
ScDPSaveData aData( *pDPObj->GetSaveData() );
ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there
- // find original base
+ // find the source dimension name.
rtl::OUString aBaseDimName = aDimName;
if( const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName ) )
aBaseDimName = pBaseGroupDim->GetSourceDimName();
- // remove all existing parts (the grouping is built completely new)
-
- /* Remove numeric group dimension (exists once at most). No need
- to delete anything in save data (grouping was done inplace in
- an existing base dimension). */
- pDimData->RemoveNumGroupDimension( aBaseDimName );
-
- /* Remove named group dimension(s). Collect deleted dimension
- names which may be reused while recreating the groups.
- Dimensions have to be removed from dimension save data and from
- save data too. */
- std::vector<rtl::OUString> aDeletedNames;
- const ScDPSaveGroupDimension* pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName );
- while ( pExistingGroup )
- {
- rtl::OUString aGroupDimName = pExistingGroup->GetGroupDimName();
- pDimData->RemoveGroupDimension( aGroupDimName ); // pExistingGroup is deleted
-
- // also remove SaveData settings for the dimension that no longer exists
- aData.RemoveDimensionByName( aGroupDimName );
-
- /* The name can be used for the new group dimensions, although
- it is still in use with the DataPilotSource. */
- aDeletedNames.push_back( aGroupDimName );
-
- // see if there are more group dimensions
- pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName );
-
- if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName )
- {
- // still get the same group dimension?
- OSL_FAIL("couldn't remove group dimension");
- pExistingGroup = NULL; // avoid endless loop
- }
- }
+ // Remove all group dimensions associated with this source dimension. For
+ // date grouping, we need to remove all existing groups for the affected
+ // source dimension and build new one(s) from scratch. Keep the deleted
+ // names so that they can be reused during re-construction.
+ aData.RemoveAllGroupDimensions(aBaseDimName, &aDeletedNames);
if ( nParts )
{
More information about the Libreoffice-commits
mailing list