diff options
-rw-r--r-- | sc/inc/dpobject.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 74 | ||||
-rw-r--r-- | sc/source/ui/docshell/dbdocfun.cxx | 54 |
3 files changed, 114 insertions, 16 deletions
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 92ceff14fa0a..747bcfbac18c 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -365,6 +365,7 @@ public: sal_uLong ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs); bool ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs); + bool GetReferenceGroups(const ScDPObject& rDPObj, const ScDPDimensionSaveData** pGroups) const; SC_DLLPUBLIC size_t GetCount() const; SC_DLLPUBLIC ScDPObject& operator[](size_t nIndex); @@ -389,6 +390,7 @@ public: void FreeTable(ScDPObject* pDPObj); SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj); + bool HasTable(ScDPObject* pDPObj) const; SC_DLLPUBLIC SheetCaches& GetSheetCaches(); SC_DLLPUBLIC const SheetCaches& GetSheetCaches() const; diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 4ba4398aae69..302eea5bcbfa 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -3545,6 +3545,68 @@ 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 (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()); @@ -3724,6 +3786,18 @@ bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj) return true; } +bool ScDPCollection::HasTable(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/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 2dfee907fb9e..3b7cdbfeb74c 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(); } } |