diff options
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 80 | ||||
-rw-r--r-- | sc/source/filter/inc/pivotcachebuffer.hxx | 7 | ||||
-rw-r--r-- | sc/source/filter/inc/pivottablebuffer.hxx | 10 | ||||
-rw-r--r-- | sc/source/filter/oox/pivotcachebuffer.cxx | 5 | ||||
-rw-r--r-- | sc/source/filter/oox/pivottablebuffer.cxx | 77 | ||||
-rw-r--r-- | sc/source/ui/docshell/dbdocfun.cxx | 54 | ||||
-rw-r--r-- | sc/source/ui/unoobj/dapiuno.cxx | 2 |
7 files changed, 211 insertions, 24 deletions
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 |