summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/dpobject.hxx2
-rw-r--r--sc/inc/dpsave.hxx2
-rw-r--r--sc/qa/unit/data/xlsx/pivot-table/shared-dategroup.xlsxbin0 -> 17540 bytes
-rw-r--r--sc/qa/unit/data/xlsx/pivot-table/shared-nested-dategroup.xlsxbin0 -> 19160 bytes
-rw-r--r--sc/qa/unit/data/xlsx/pivot-table/shared-numgroup.xlsxbin0 -> 17830 bytes
-rw-r--r--sc/qa/unit/data/xlsx/pivot-table/shared_group.xlsxbin0 -> 20180 bytes
-rw-r--r--sc/qa/unit/subsequent_filters-test.cxx150
-rw-r--r--sc/source/core/data/dpobject.cxx80
-rw-r--r--sc/source/filter/inc/pivotcachebuffer.hxx7
-rw-r--r--sc/source/filter/inc/pivottablebuffer.hxx10
-rw-r--r--sc/source/filter/oox/pivotcachebuffer.cxx5
-rw-r--r--sc/source/filter/oox/pivottablebuffer.cxx77
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx54
-rw-r--r--sc/source/ui/unoobj/dapiuno.cxx2
14 files changed, 364 insertions, 25 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 5876bd930dbc..ffafd2640eef 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -364,6 +364,7 @@ public:
sal_uLong ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs);
bool ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs);
+ SC_DLLPUBLIC bool GetReferenceGroups(const ScDPObject& rDPObj, const ScDPDimensionSaveData** pGroups) const;
SC_DLLPUBLIC size_t GetCount() const;
SC_DLLPUBLIC ScDPObject& operator[](size_t nIndex);
@@ -388,6 +389,7 @@ public:
void FreeTable(ScDPObject* pDPObj);
SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj);
+ SC_DLLPUBLIC bool HasTable(const ScDPObject* pDPObj) const;
SC_DLLPUBLIC SheetCaches& GetSheetCaches();
SC_DLLPUBLIC const SheetCaches& GetSheetCaches() const;
diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx
index 2deb35e5517d..bb1e8acb7098 100644
--- a/sc/inc/dpsave.hxx
+++ b/sc/inc/dpsave.hxx
@@ -352,7 +352,7 @@ public:
void RemoveAllGroupDimensions( const OUString& rSrcDimName, std::vector<OUString>* pDeletedNames = nullptr );
SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there
- void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
+ SC_DLLPUBLIC void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
void BuildAllDimensionMembers(ScDPTableData* pData);
void SyncAllDimensionMembers(ScDPTableData* pData);
diff --git a/sc/qa/unit/data/xlsx/pivot-table/shared-dategroup.xlsx b/sc/qa/unit/data/xlsx/pivot-table/shared-dategroup.xlsx
new file mode 100644
index 000000000000..60cbd66d8dcd
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/pivot-table/shared-dategroup.xlsx
Binary files differ
diff --git a/sc/qa/unit/data/xlsx/pivot-table/shared-nested-dategroup.xlsx b/sc/qa/unit/data/xlsx/pivot-table/shared-nested-dategroup.xlsx
new file mode 100644
index 000000000000..4dfb55d3cc5b
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/pivot-table/shared-nested-dategroup.xlsx
Binary files differ
diff --git a/sc/qa/unit/data/xlsx/pivot-table/shared-numgroup.xlsx b/sc/qa/unit/data/xlsx/pivot-table/shared-numgroup.xlsx
new file mode 100644
index 000000000000..36f36efb4567
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/pivot-table/shared-numgroup.xlsx
Binary files differ
diff --git a/sc/qa/unit/data/xlsx/pivot-table/shared_group.xlsx b/sc/qa/unit/data/xlsx/pivot-table/shared_group.xlsx
new file mode 100644
index 000000000000..2bc5cddfc870
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/pivot-table/shared_group.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 0c1428ec3c06..16545b98616f 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -183,6 +183,10 @@ public:
void testPivotTableNamedRangeSourceODS();
void testPivotTableSharedCacheGroupODS();
void testGetPivotDataXLS();
+ void testPivotTableSharedGroupXLSX();
+ void testPivotTableSharedDateGroupXLSX();
+ void testPivotTableSharedNestedDateGroupXLSX();
+ void testPivotTableSharedNumGroupXLSX();
void testFormulaDependency();
@@ -280,6 +284,10 @@ public:
CPPUNIT_TEST(testPivotTableNamedRangeSourceODS);
CPPUNIT_TEST(testPivotTableSharedCacheGroupODS);
CPPUNIT_TEST(testGetPivotDataXLS);
+ CPPUNIT_TEST(testPivotTableSharedGroupXLSX);
+ CPPUNIT_TEST(testPivotTableSharedDateGroupXLSX);
+ CPPUNIT_TEST(testPivotTableSharedNestedDateGroupXLSX);
+ CPPUNIT_TEST(testPivotTableSharedNumGroupXLSX);
CPPUNIT_TEST(testRowHeightODS);
CPPUNIT_TEST(testFormulaDependency);
CPPUNIT_TEST(testRichTextContentODS);
@@ -2035,6 +2043,148 @@ void ScFiltersTest::testGetPivotDataXLS()
xDocSh->DoClose();
}
+void ScFiltersTest::testPivotTableSharedGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared_group.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ rDoc.CalcAll();
+
+ // Check whether right group names are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), rDoc.GetString(ScAddress(0,2,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), rDoc.GetString(ScAddress(0,3,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), rDoc.GetString(ScAddress(0,4,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("16"), rDoc.GetString(ScAddress(0,5,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("17"), rDoc.GetString(ScAddress(0,6,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("18"), rDoc.GetString(ScAddress(0,7,0)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport1"), rDoc.GetString(ScAddress(0,12,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport2"), rDoc.GetString(ScAddress(0,13,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Csoport3"), rDoc.GetString(ScAddress(0,14,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("16"), rDoc.GetString(ScAddress(0,15,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("17"), rDoc.GetString(ScAddress(0,16,0)));
+ CPPUNIT_ASSERT_EQUAL(OUString("18"), rDoc.GetString(ScAddress(0,17,0)));
+
+ xDocSh->DoClose();
+}
+
+void ScFiltersTest::testPivotTableSharedDateGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-dategroup.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right date labels are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(0,7,1)));
+ // TODO: check why this fails with 2005
+ // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,8,1)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(5,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(5,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(5,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(5,7,1)));
+ // TODO: check why this fails with 2005
+ // CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(5,8,1)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,0,9,24,0));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:J25 on the first sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(10), pCache->GetFieldCount());
+
+ xDocSh->DoClose();
+}
+
+void ScFiltersTest::testPivotTableSharedNestedDateGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-nested-dategroup.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right date groups are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("Years"), rDoc.GetString(ScAddress(0,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(0,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(0,11,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(0,18,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(0,21,1)));
+ // TODO: check why this fails with the empty string
+ //CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(0,32,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Quarters"), rDoc.GetString(ScAddress(1,3,1)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("Years"), rDoc.GetString(ScAddress(6,3,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1965"), rDoc.GetString(ScAddress(6,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("1989"), rDoc.GetString(ScAddress(6,11,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2000"), rDoc.GetString(ScAddress(6,18,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("2004"), rDoc.GetString(ScAddress(6,21,1)));
+ // TODO: check why this fails with the empty string
+ //CPPUNIT_ASSERT_EQUAL(OUString("2007"), rDoc.GetString(ScAddress(6,31,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("Quarters"), rDoc.GetString(ScAddress(7,3,1)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,0,9,24,0));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:J25 on the first sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(10), pCache->GetFieldCount());
+ // Two new group field is created
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pCache->GetGroupFieldCount());
+
+ xDocSh->DoClose();
+}
+
+void ScFiltersTest::testPivotTableSharedNumGroupXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("pivot-table/shared-numgroup.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+
+ // Check whether right number groups are imported for both tables
+ // First table
+ CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), rDoc.GetString(ScAddress(0,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), rDoc.GetString(ScAddress(0,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), rDoc.GetString(ScAddress(0,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), rDoc.GetString(ScAddress(0,7,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), rDoc.GetString(ScAddress(0,8,1)));
+
+ // Second table
+ CPPUNIT_ASSERT_EQUAL(OUString("32674-47673"), rDoc.GetString(ScAddress(5,4,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("47674-62673"), rDoc.GetString(ScAddress(5,5,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("62674-77673"), rDoc.GetString(ScAddress(5,6,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("77674-92673"), rDoc.GetString(ScAddress(5,7,1)));
+ CPPUNIT_ASSERT_EQUAL(OUString("92674-107673"), rDoc.GetString(ScAddress(5,8,1)));
+
+ // There should be exactly 2 pivot tables and 1 cache.
+ ScDPCollection* pDPs = rDoc.GetDPCollection();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pDPs->GetCount());
+
+ ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
+
+ const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0,0,0,9,24,0));
+ CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:J25 on the first sheet.", pCache);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(10), pCache->GetFieldCount());
+
+ xDocSh->DoClose();
+}
+
void ScFiltersTest::testRowHeightODS()
{
ScDocShellRef xDocSh = loadDoc("row-height-import.", FORMAT_ODS);
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 531ab8176a0b..db529fbdff4c 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2847,7 +2847,10 @@ const ScDPCache* ScDPCollection::SheetCaches::getCache(const ScRange& rRange, co
}
if (pDimData)
+ {
+ (itCache->second)->ClearGroupFields();
pDimData->WriteToCache(*itCache->second);
+ }
return itCache->second.get();
}
@@ -3440,6 +3443,71 @@ bool ScDPCollection::ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject
return true;
}
+bool ScDPCollection::GetReferenceGroups(const ScDPObject& rDPObj, const ScDPDimensionSaveData** pGroups) const
+{
+ for (const std::unique_ptr<ScDPObject>& aTable : maTables)
+ {
+ const ScDPObject& rRefObj = *aTable.get();
+
+ if (&rRefObj == &rDPObj)
+ continue;
+
+ if (rDPObj.IsSheetData()){
+ if(!rRefObj.IsSheetData())
+ continue;
+
+ const ScSheetSourceDesc* pDesc = rDPObj.GetSheetDesc();
+ const ScSheetSourceDesc* pRefDesc = rRefObj.GetSheetDesc();
+ if (pDesc == nullptr || pRefDesc == nullptr)
+ continue;
+
+ if (pDesc->HasRangeName())
+ {
+ if (!pRefDesc->HasRangeName())
+ continue;
+
+ if (pDesc->GetRangeName() == pRefDesc->GetRangeName())
+ {
+ *pGroups = rRefObj.GetSaveData()->GetExistingDimensionData();
+ return true;
+ }
+ }
+ else
+ {
+ if (pRefDesc->HasRangeName())
+ continue;
+
+ if (pDesc->GetSourceRange() == pRefDesc->GetSourceRange())
+ {
+ *pGroups = rRefObj.GetSaveData()->GetExistingDimensionData();
+ return true;
+ }
+ }
+ }
+ else if (rDPObj.IsImportData())
+ {
+ if (!rRefObj.IsImportData ())
+ continue;
+
+ const ScImportSourceDesc* pDesc = rDPObj.GetImportSourceDesc();
+ const ScImportSourceDesc* pRefDesc = rRefObj.GetImportSourceDesc();
+ if (pDesc == nullptr || pRefDesc == nullptr)
+ continue;
+
+ if (pDesc->aDBName.equals(pRefDesc->aDBName) &&
+ pDesc->aObject.equals(pRefDesc->aObject) &&
+ pDesc->GetCommandType() == pRefDesc->GetCommandType())
+ {
+ *pGroups = rRefObj.GetSaveData()->GetExistingDimensionData();
+ return true;
+ }
+
+ }
+ }
+ return false;
+}
+
+
void ScDPCollection::DeleteOnTab( SCTAB nTab )
{
maTables.erase( std::remove_if(maTables.begin(), maTables.end(), MatchByTable(nTab)), maTables.end());
@@ -3619,6 +3687,18 @@ bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
return true;
}
+bool ScDPCollection::HasTable(const ScDPObject* pDPObj) const
+{
+ for (const std::unique_ptr<ScDPObject>& aTable : maTables)
+ {
+ if (aTable.get() == pDPObj)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
ScDPCollection::SheetCaches& ScDPCollection::GetSheetCaches()
{
return maSheetCaches;
diff --git a/sc/source/filter/inc/pivotcachebuffer.hxx b/sc/source/filter/inc/pivotcachebuffer.hxx
index 3bf5406c62f3..80e2f45972e7 100644
--- a/sc/source/filter/inc/pivotcachebuffer.hxx
+++ b/sc/source/filter/inc/pivotcachebuffer.hxx
@@ -186,6 +186,8 @@ struct PCFieldGroupModel
bool mbDateGroup; /// True = items are grouped by date ranges or by item names.
bool mbAutoStart; /// True = start value for range groups is calculated from source data.
bool mbAutoEnd; /// True = end value for range groups is calculated from source data.
+ OUString msFinalGroupName ; /// Finalized group name of this field used in internal pivot table collaction.
+
explicit PCFieldGroupModel();
@@ -269,6 +271,10 @@ public:
inline sal_Int32 getParentGroupField() const { return maFieldGroupModel.mnParentField; }
/** Returns the index of the base field grouping is based on. */
inline sal_Int32 getGroupBaseField() const { return maFieldGroupModel.mnBaseField; }
+ /** Returns the finalized group name of this field. */
+ inline const OUString& getFinalGroupName() const { return maFieldGroupModel.msFinalGroupName; }
+ /** Set the finalized group name of this field. */
+ inline void setFinalGroupName(const OUString& rFinalGroupName) { maFieldGroupModel.msFinalGroupName = rFinalGroupName; }
/** Returns the shared or group item with the specified index. */
const PivotCacheItem* getCacheItem( sal_Int32 nItemIdx ) const;
@@ -405,6 +411,7 @@ public:
/** Returns the number of pivot cache fields. */
sal_Int32 getCacheFieldCount() const;
/** Returns the cache field with the specified index. */
+ PivotCacheField* getCacheField( sal_Int32 nFieldIdx );
const PivotCacheField* getCacheField( sal_Int32 nFieldIdx ) const;
/** Returns the source column index of the field with the passed index. */
sal_Int32 getCacheDatabaseIndex( sal_Int32 nFieldIdx ) const;
diff --git a/sc/source/filter/inc/pivottablebuffer.hxx b/sc/source/filter/inc/pivottablebuffer.hxx
index 37ee04edf586..1838c539fb5d 100644
--- a/sc/source/filter/inc/pivottablebuffer.hxx
+++ b/sc/source/filter/inc/pivottablebuffer.hxx
@@ -149,6 +149,8 @@ public:
const css::uno::Reference< css::sheet::XDataPilotField >& rxBaseDPField,
const PivotCacheField& rBaseCacheField,
PivotCacheGroupItemVector& orItemNames );
+ void finalizeImportBasedOnCache(
+ const css::uno::Reference< css::sheet::XDataPilotDescriptor >& rxDPDesc);
/** Returns the name of the DataPilot field in the fields collection. */
inline const OUString& getDPFieldName() const { return maDPFieldName; }
@@ -175,7 +177,7 @@ private:
PivotTable& mrPivotTable; /// The parent pivot table object.
ItemModelVector maItems; /// All items of this field.
PTFieldModel maModel; /// Pivot field settings.
- OUString maDPFieldName; /// Name of the field in DataPilot field collection.
+ OUString maDPFieldName; /// Name of the field in DataPilot field collection.
sal_Int32 mnFieldIndex; /// Zero-based index of this field.
};
@@ -317,6 +319,8 @@ public:
PivotTableFilter& createTableFilter();
/** Inserts the pivot table into the sheet. */
void finalizeImport();
+ /** Finalizes all fields, finds field names and creates grouping fields. */
+ void finalizeFieldsImport();
/** Creates all date group fields for the specified cache field after import. */
void finalizeDateGroupingImport(
const css::uno::Reference< css::sheet::XDataPilotField >& rxBaseDPField,
@@ -338,6 +342,7 @@ public:
getDataLayoutField() const;
/** Returns the cache field with the specified index. */
+ PivotCacheField* getCacheField( sal_Int32 nFieldIdx );
const PivotCacheField* getCacheField( sal_Int32 nFieldIdx ) const;
/** Returns the base cache field of the data field item with the specified index. */
const PivotCacheField* getCacheFieldOfDataField( sal_Int32 nDataItemIdx ) const;
@@ -373,9 +378,10 @@ private:
PivotTableFilterVector maFilters; /// All field filters.
PTDefinitionModel maDefModel; /// Global pivot table settings.
PTLocationModel maLocationModel; /// Location settings of the pivot table.
- const PivotCache* mpPivotCache; /// The pivot cache this table is based on.
+ PivotCache* mpPivotCache; /// The pivot cache this table is based on.
css::uno::Reference< css::sheet::XDataPilotDescriptor >
mxDPDescriptor; /// Descriptor of the DataPilot object.
+
};
class PivotTableBuffer : public WorkbookHelper
diff --git a/sc/source/filter/oox/pivotcachebuffer.cxx b/sc/source/filter/oox/pivotcachebuffer.cxx
index c7b75e3b3a5c..687a47d976e7 100644
--- a/sc/source/filter/oox/pivotcachebuffer.cxx
+++ b/sc/source/filter/oox/pivotcachebuffer.cxx
@@ -1250,6 +1250,11 @@ sal_Int32 PivotCache::getCacheFieldCount() const
return static_cast< sal_Int32 >( maFields.size() );
}
+PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx )
+{
+ return maFields.get( nFieldIdx ).get();
+}
+
const PivotCacheField* PivotCache::getCacheField( sal_Int32 nFieldIdx ) const
{
return maFields.get( nFieldIdx ).get();
diff --git a/sc/source/filter/oox/pivottablebuffer.cxx b/sc/source/filter/oox/pivottablebuffer.cxx
index bc3c05ce8c82..04a432ae8d92 100644
--- a/sc/source/filter/oox/pivottablebuffer.cxx
+++ b/sc/source/filter/oox/pivottablebuffer.cxx
@@ -49,6 +49,9 @@
#include "dapiuno.hxx"
#include "dpobject.hxx"
#include "dpsave.hxx"
+#include "dpdimsave.hxx"
+#include "document.hxx"
+#include "documentimport.hxx"
namespace oox {
namespace xls {
@@ -424,11 +427,12 @@ void PivotTableField::finalizeDateGroupingImport( const Reference< XDataPilotFie
{
if( maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken
{
- if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ if( PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
{
if( !pCacheField->isDatabaseField() && pCacheField->hasDateGrouping() && (pCacheField->getGroupBaseField() == nBaseFieldIdx) )
{
maDPFieldName = pCacheField->createDateGroupField( rxBaseDPField );
+ pCacheField->setFinalGroupName(maDPFieldName);
OSL_ENSURE( !maDPFieldName.isEmpty(), "PivotTableField::finalizeDateGroupingImport - cannot create date group field" );
}
}
@@ -439,7 +443,7 @@ void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotF
{
if( maDPFieldName.isEmpty() ) // prevent endless loops if file format is broken
{
- if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ if( PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
{
// data field can have user defined groupname captions, apply them
// if they do
@@ -449,10 +453,11 @@ void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotF
if ( aIt->mnType == XML_data && aIt->msCaption.getLength() )
captionList.push_back( IdCaptionPair( aIt->mnCacheItem, aIt->msCaption ) );
}
- // #FIXME find another way out of this const nightmare prison
if ( !captionList.empty() )
- const_cast<PivotCacheField*>( pCacheField )->applyItemCaptions( captionList );
+ pCacheField->applyItemCaptions( captionList );
+
maDPFieldName = pCacheField->createParentGroupField( rxBaseDPField, rBaseCacheField, orItemNames );
+ pCacheField->setFinalGroupName(maDPFieldName);
// on success, try to create nested group fields
Reference< XDataPilotField > xDPField = mrPivotTable.getDataPilotField( maDPFieldName );
if( xDPField.is() )
@@ -461,6 +466,33 @@ void PivotTableField::finalizeParentGroupingImport( const Reference< XDataPilotF
}
}
+void PivotTableField::finalizeImportBasedOnCache( const Reference< XDataPilotDescriptor >& rxDPDesc)
+{
+ /* Process all fields based on source data, other fields (e.g. group
+ fields) are processed based on cache fields.*/
+ Reference< XDataPilotField > xDPField;
+ sal_Int32 nDatabaseIdx = mrPivotTable.getCacheDatabaseIndex( mnFieldIndex );
+ if( (nDatabaseIdx >= 0) && rxDPDesc.is() ) try
+ {
+ // Try to get the source field and its name from passed DataPilot descriptor
+ Reference< XIndexAccess > xDPFieldsIA( rxDPDesc->getDataPilotFields(), UNO_SET_THROW );
+ xDPField.set( xDPFieldsIA->getByIndex( nDatabaseIdx ), UNO_QUERY_THROW );
+ Reference< XNamed > xDPFieldName( xDPField, UNO_QUERY_THROW );
+ maDPFieldName = xDPFieldName->getName();
+ SAL_WARN_IF( maDPFieldName.isEmpty(), "sc.filter", "PivotTableField::finalizeImportBasedOnCache - no field name in source data found" );
+ }
+ catch( Exception& )
+ {
+ }
+
+ // Use group names already generated for another table using the same group field.
+ if( const PivotCacheField* pCacheField = mrPivotTable.getCacheField( mnFieldIndex ) )
+ {
+ if(!pCacheField->getFinalGroupName().isEmpty())
+ maDPFieldName = pCacheField->getFinalGroupName();
+ }
+}
+
void PivotTableField::convertRowField()
{
convertRowColPageField( XML_axisRow );
@@ -1190,7 +1222,7 @@ void PivotTable::finalizeImport()
aDescProp.setProperty( PROP_DrillDownOnDoubleClick, maDefModel.mbEnableDrill );
// finalize all fields, this finds field names and creates grouping fields
- maFields.forEachMem(&PivotTableField::finalizeImport, ::std::cref(mxDPDescriptor));
+ finalizeFieldsImport();
// all row fields
for( IndexVector::iterator aIt = maRowFields.begin(), aEnd = maRowFields.end(); aIt != aEnd; ++aIt )
@@ -1250,6 +1282,36 @@ void PivotTable::finalizeImport()
}
}
+void PivotTable::finalizeFieldsImport()
+{
+ if (maFields.empty())
+ return;
+
+ /* Check whether group fields are already imported for an other table
+ sharing the same groups. */
+ ScDPObject* pDPObj = getDPObject();
+ const ScDocument& rDoc = getDocImport().getDoc();
+ if (rDoc.HasPivotTable())
+ {
+ const ScDPCollection* pDPCollection = rDoc.GetDPCollection();
+ assert(pDPCollection != nullptr);
+ const ScDPDimensionSaveData* pGroups = nullptr;
+ bool bRefFound = pDPCollection->GetReferenceGroups(*pDPObj, &pGroups);
+ // Apply reference groups on this table.
+ if (bRefFound && pGroups && pGroups->HasGroupDimensions()) {
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (pSaveData) {
+ pSaveData->SetDimensionData(pGroups);
+ pDPObj->ReloadGroupTableData();
+ maFields.forEachMem(&PivotTableField::finalizeImportBasedOnCache, ::std::cref(mxDPDescriptor));
+ return;
+ }
+
+ }
+ }
+ maFields.forEachMem(&PivotTableField::finalizeImport, ::std::cref(mxDPDescriptor));
+}
+
void PivotTable::finalizeDateGroupingImport( const Reference< XDataPilotField >& rxBaseDPField, sal_Int32 nBaseFieldIdx )
{
// process all fields, there is no chaining information in the cache fields
@@ -1300,6 +1362,11 @@ Reference< XDataPilotField > PivotTable::getDataLayoutField() const
return xDPField;
}
+PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx )
+{
+ return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : nullptr;
+}
+
const PivotCacheField* PivotTable::getCacheField( sal_Int32 nFieldIdx ) const
{
return mpPivotCache ? mpPivotCache->getCacheField( nFieldIdx ) : nullptr;
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 983f29d431b0..acbace69428a 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -1386,6 +1386,19 @@ bool ScDBDocFunc::CreatePivotTable(const ScDPObject& rDPObj, bool bRecord, bool
if (rDoc.GetDPCollection()->GetByName(rDestObj.GetName()))
rDestObj.SetName(OUString()); // ignore the invalid name, create a new name below
+ // Syncronize groups between linked tables
+ {
+ bool bRefFound = false;
+ const ScDPDimensionSaveData* pGroups = nullptr;
+ bRefFound = rDoc.GetDPCollection()->GetReferenceGroups(rDestObj, &pGroups);
+ if (bRefFound)
+ {
+ ScDPSaveData* pSaveData = rDestObj.GetSaveData();
+ if (pSaveData)
+ pSaveData->SetDimensionData(pGroups);
+ }
+ }
+
if (!rDoc.GetDPCollection()->InsertNewTable(pDestObj.release()))
// Insertion into collection failed.
return false;
@@ -1567,25 +1580,34 @@ void ScDBDocFunc::RefreshPivotTableGroups(ScDPObject* pDPObj)
if (!pSaveData)
return;
- std::set<ScDPObject*> aRefs;
- if (!pDPs->ReloadGroupsInCache(pDPObj, aRefs))
- return;
-
- // We allow pDimData being NULL.
- const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData();
- std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end();
- for (; it != itEnd; ++it)
+ // Update all linked tables, if this table is part of the cache (ScDPCollection)
+ if (pDPs->HasTable(pDPObj))
{
- ScDPObject* pObj = *it;
- if (pObj != pDPObj)
+ std::set<ScDPObject*> aRefs;
+ if (!pDPs->ReloadGroupsInCache(pDPObj, aRefs))
+ return;
+
+ // We allow pDimData being NULL.
+ const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData();
+ std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end();
+ for (; it != itEnd; ++it)
{
- pSaveData = pObj->GetSaveData();
- if (pSaveData)
- pSaveData->SetDimensionData(pDimData);
- }
+ ScDPObject* pObj = *it;
+ if (pObj != pDPObj)
+ {
+ pSaveData = pObj->GetSaveData();
+ if (pSaveData)
+ pSaveData->SetDimensionData(pDimData);
+ }
- // This action is intentionally not undoable since it modifies cache.
- UpdatePivotTable(*pObj, false, false);
+ // This action is intentionally not undoable since it modifies cache.
+ UpdatePivotTable(*pObj, false, false);
+ }
+ }
+ else // Otherwise update only this single table
+ {
+ // This table is under construction so no need for a whole update (UpdatePivotTable()).
+ pDPObj->ReloadGroupTableData();
}
}
diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx
index 32f43a3784c1..97c35e97f4e1 100644
--- a/sc/source/ui/unoobj/dapiuno.cxx
+++ b/sc/source/ui/unoobj/dapiuno.cxx
@@ -2790,7 +2790,7 @@ Reference < XDataPilotField > SAL_CALL ScDataPilotFieldObj::createDateGroup( con
// apply changes
pDPObj->SetSaveData( aSaveData );
- SetDPObject( pDPObj );
+ ScDBDocFunc(*GetDocShell()).RefreshPivotTableGroups(pDPObj);
}
// return the UNO object of the new dimension, after writing back saved data