diff options
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 34 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 292 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 309 |
3 files changed, 327 insertions, 308 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index bb46e2d1a42a..a38279f66037 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -600,6 +600,40 @@ public: SCTAB nGlobalRefTab, SCTAB nLocalRefTab, SCTAB nOldTokenTab, SCTAB nOldTokenTabReplacement, bool bSameDoc, int nRecursion ) const; + /** If necessary (name references sheet rOldPos.Tab()) copy and adjust + named expression/range from sheet-local to sheet-local, or global to + sheet-local if bGlobalNamesToLocal==true. + + Also copies nested names and adjusts the ocName tokens of the calling name. + + @param rSheet + On entry, the original sheet of the named expression/range, <0 global. + On return TRUE, the new sheet. Else unchanged. + + @param rIndex + On entry, the original index of the named expression/range. + On return TRUE, the new index, or 0 if a new copied name couldn't be inserted. Else unchanged. + + @param rpRangeData + On entry, the pointer to the original named expression/range. + On return TRUE, the pointer to the new copied name, or nullptr if hit shappened. + + @param rNewPos + New position of formula cell if called for that, else new base + position of a to be created new name adjusted for Tab. + rNewPos.nTab MUST point to the new sheet copied to. + + @param rOldPos + Old position of formula cell if called for that, else base + position of the existing name adjusted for Tab. + rOldPos.nTab MUST point to the old sheet copied from. + + @return TRUE if copied and caller may need to evaluate rpRangeData and rSheet and rIndex. + FALSE if nothing to be done. + */ + bool CopyAdjustRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRangeData*& rpRangeData, ScDocument& rNewDoc, + const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal) const; + /** * Call this immediately before updating all named ranges. */ diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index 80375b86d789..f7ed6e89b80c 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -513,4 +513,296 @@ bool ScDocument::FindRangeNamesReferencingSheet( sc::UpdatedRangeNames& rIndexes return bRef; } +namespace { + +enum MightReferenceSheet +{ + UNKNOWN, + NONE, + CODE, + NAME +}; + +MightReferenceSheet mightRangeNameReferenceSheet( ScRangeData* pData, SCTAB nRefTab) +{ + ScTokenArray* pCode = pData->GetCode(); + if (!pCode) + return MightReferenceSheet::NONE; + + for (const formula::FormulaToken* p = pCode->First(); p; p = pCode->Next()) + { + if (p->GetOpCode() == ocName) + return MightReferenceSheet::NAME; + } + + return pCode->ReferencesSheet( nRefTab, pData->GetPos().Tab()) ? + MightReferenceSheet::CODE : MightReferenceSheet::NONE; +} + +ScRangeData* copyRangeName( const ScRangeData* pOldRangeData, ScDocument& rNewDoc, const ScDocument* pOldDoc, + const ScAddress& rNewPos, const ScAddress& rOldPos, bool bGlobalNamesToLocal, + SCTAB nOldSheet, const SCTAB nNewSheet, bool bSameDoc) +{ + ScAddress aRangePos( pOldRangeData->GetPos()); + if (nNewSheet >= 0) + aRangePos.SetTab( nNewSheet); + ScRangeData* pRangeData = new ScRangeData(*pOldRangeData, &rNewDoc, &aRangePos); + pRangeData->SetIndex(0); // needed for insert to assign a new index + ScTokenArray* pRangeNameToken = pRangeData->GetCode(); + if (bSameDoc && nNewSheet >= 0) + { + if (bGlobalNamesToLocal && nOldSheet < 0) + { + nOldSheet = rOldPos.Tab(); + if (rNewPos.Tab() <= nOldSheet) + // Sheet was inserted before and references already updated. + ++nOldSheet; + } + pRangeNameToken->AdjustSheetLocalNameReferences( nOldSheet, nNewSheet); + } + if (!bSameDoc) + { + pRangeNameToken->ReadjustAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos(), true); + pRangeNameToken->AdjustAbsoluteRefs(pOldDoc, rOldPos, rNewPos, true); + } + + bool bInserted; + if (nNewSheet < 0) + bInserted = rNewDoc.GetRangeName()->insert(pRangeData); + else + bInserted = rNewDoc.GetRangeName(nNewSheet)->insert(pRangeData); + + return bInserted ? pRangeData : nullptr; +} + +struct SheetIndex +{ + SCTAB mnSheet; + sal_uInt16 mnIndex; + + SheetIndex( SCTAB nSheet, sal_uInt16 nIndex ) : mnSheet(nSheet < -1 ? -1 : nSheet), mnIndex(nIndex) {} + bool operator<( const SheetIndex& r ) const + { + // Ascending order sheet, index + if (mnSheet < r.mnSheet) + return true; + if (mnSheet == r.mnSheet) + return mnIndex < r.mnIndex; + return false; + } +}; +typedef std::map< SheetIndex, SheetIndex > SheetIndexMap; + +ScRangeData* copyRangeNames( SheetIndexMap& rSheetIndexMap, std::vector<ScRangeData*>& rRangeDataVec, + const sc::UpdatedRangeNames& rReferencingNames, SCTAB nTab, + const ScRangeData* pOldRangeData, ScDocument& rNewDoc, const ScDocument* pOldDoc, + const ScAddress& rNewPos, const ScAddress& rOldPos, bool bGlobalNamesToLocal, + const SCTAB nOldSheet, const SCTAB nNewSheet, bool bSameDoc) +{ + ScRangeData* pRangeData = nullptr; + const ScRangeName* pOldRangeName = (nTab < 0 ? pOldDoc->GetRangeName() : pOldDoc->GetRangeName(nTab)); + if (pOldRangeName) + { + const ScRangeName* pNewRangeName = (nNewSheet < 0 ? rNewDoc.GetRangeName() : rNewDoc.GetRangeName(nNewSheet)); + sc::UpdatedRangeNames::NameIndicesType aSet( rReferencingNames.getUpdatedNames(nTab)); + for (auto const & rIndex : aSet) + { + const ScRangeData* pCopyData = pOldRangeName->findByIndex(rIndex); + if (pCopyData) + { + // Match the original pOldRangeData to adapt the current + // token's values later. For that no check for an already + // copied name is needed as we only enter here if there was + // none. + if (pCopyData == pOldRangeData) + { + pRangeData = copyRangeName( pCopyData, rNewDoc, pOldDoc, rNewPos, rOldPos, + bGlobalNamesToLocal, nOldSheet, nNewSheet, bSameDoc); + if (pRangeData) + { + rRangeDataVec.push_back(pRangeData); + rSheetIndexMap.insert( std::make_pair( SheetIndex( nOldSheet, pCopyData->GetIndex()), + SheetIndex( nNewSheet, pRangeData->GetIndex()))); + } + } + else + { + // First check if the name is already available as copy. + const ScRangeData* pFoundData = pNewRangeName->findByUpperName( pCopyData->GetUpperName()); + if (pFoundData) + { + // Just add the resulting sheet/index mapping. + rSheetIndexMap.insert( std::make_pair( SheetIndex( nOldSheet, pCopyData->GetIndex()), + SheetIndex( nNewSheet, pFoundData->GetIndex()))); + } + else + { + ScRangeData* pTmpData = copyRangeName( pCopyData, rNewDoc, pOldDoc, rNewPos, rOldPos, + bGlobalNamesToLocal, nOldSheet, nNewSheet, bSameDoc); + if (pTmpData) + { + rRangeDataVec.push_back(pTmpData); + rSheetIndexMap.insert( std::make_pair( SheetIndex( nOldSheet, pCopyData->GetIndex()), + SheetIndex( nNewSheet, pTmpData->GetIndex()))); + } + } + } + } + } + } + return pRangeData; +} + +} // namespace + +bool ScDocument::CopyAdjustRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRangeData*& rpRangeData, + ScDocument& rNewDoc, const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal) const +{ + const bool bSameDoc = (rNewDoc.GetPool() == const_cast<ScDocument*>(this)->GetPool()); + if (bSameDoc && ((rSheet < 0 && !bGlobalNamesToLocal) || (rSheet >= 0 && rSheet != rOldPos.Tab()))) + // Same doc and global name, if not copied to local name, or + // sheet-local name on other sheet stays the same. + return false; + + // Ensure we don't fiddle with the references until exit. + const SCTAB nOldSheet = rSheet; + const sal_uInt16 nOldIndex = rIndex; + + SAL_WARN_IF( !bSameDoc && nOldSheet >= 0 && nOldSheet != rOldPos.Tab(), + "sc.core", "adjustCopyRangeName - sheet-local name was on other sheet in other document"); + /* TODO: can we do something about that? e.g. loop over sheets? */ + + OUString aRangeName; + ScRangeData* pOldRangeData = nullptr; + + // XXX bGlobalNamesToLocal is also a synonym for copied sheet. + bool bInsertingBefore = (bGlobalNamesToLocal && bSameDoc && rNewPos.Tab() <= rOldPos.Tab()); + + // The Tab where an old local name is to be found or that a global name + // references. May differ below from nOldSheet if a sheet was inserted + // before the old position. Global names and local names other than on the + // old sheet or new sheet are already updated, local names on the old sheet + // or inserted sheet will be updated later. Confusing stuff. Watch out. + SCTAB nOldTab = (nOldSheet < 0 ? rOldPos.Tab() : nOldSheet); + if (bInsertingBefore) + // Sheet was already inserted before old position. + ++nOldTab; + + // Search the name of the RangeName. + if (nOldSheet >= 0) + { + const ScRangeName* pNames = GetRangeName(nOldTab); + pOldRangeData = pNames ? pNames->findByIndex(nOldIndex) : nullptr; + if (!pOldRangeData) + return false; // might be an error in the formula array + aRangeName = pOldRangeData->GetUpperName(); + } + else + { + pOldRangeData = GetRangeName()->findByIndex(nOldIndex); + if (!pOldRangeData) + return false; // might be an error in the formula array + aRangeName = pOldRangeData->GetUpperName(); + } + + // Find corresponding range name in new document. + // First search for local range name then global range names. + SCTAB nNewSheet = rNewPos.Tab(); + ScRangeName* pNewNames = rNewDoc.GetRangeName(nNewSheet); + // Search local range names. + if (pNewNames) + { + rpRangeData = pNewNames->findByUpperName(aRangeName); + } + // Search global range names. + if (!rpRangeData && !bGlobalNamesToLocal) + { + nNewSheet = -1; + pNewNames = rNewDoc.GetRangeName(); + if (pNewNames) + rpRangeData = pNewNames->findByUpperName(aRangeName); + } + // If no range name was found copy it. + if (!rpRangeData) + { + bool bEarlyBailOut = (nOldSheet < 0 && bSameDoc); + MightReferenceSheet eMightReference = mightRangeNameReferenceSheet( pOldRangeData, nOldTab); + if (bEarlyBailOut && eMightReference == MightReferenceSheet::NONE) + return false; + + if (eMightReference == MightReferenceSheet::NAME) + { + // Name these to clarify what is passed where. + const SCTAB nGlobalRefTab = nOldTab; + const SCTAB nLocalRefTab = (bInsertingBefore ? nOldTab-1 : nOldTab); + const SCTAB nOldTokenTab = (nOldSheet < 0 ? (bInsertingBefore ? nOldTab-1 : nOldTab) : nOldSheet); + const SCTAB nOldTokenTabReplacement = nOldTab; + sc::UpdatedRangeNames aReferencingNames; + FindRangeNamesReferencingSheet( aReferencingNames, nOldSheet, nOldIndex, + nGlobalRefTab, nLocalRefTab, nOldTokenTab, nOldTokenTabReplacement, bSameDoc, 0); + if (bEarlyBailOut && aReferencingNames.isEmpty(-1) && aReferencingNames.isEmpty(nOldTokenTabReplacement)) + return false; + + SheetIndexMap aSheetIndexMap; + std::vector<ScRangeData*> aRangeDataVec; + if (!aReferencingNames.isEmpty(nOldTokenTabReplacement)) + { + const SCTAB nTmpOldSheet = (nOldSheet < 0 ? nOldTab : nOldSheet); + nNewSheet = rNewPos.Tab(); + rpRangeData = copyRangeNames( aSheetIndexMap, aRangeDataVec, aReferencingNames, nOldTab, + pOldRangeData, rNewDoc, this, rNewPos, rOldPos, + bGlobalNamesToLocal, nTmpOldSheet, nNewSheet, bSameDoc); + } + if ((bGlobalNamesToLocal || !bSameDoc) && !aReferencingNames.isEmpty(-1)) + { + const SCTAB nTmpOldSheet = -1; + const SCTAB nTmpNewSheet = (bGlobalNamesToLocal ? rNewPos.Tab() : -1); + ScRangeData* pTmpData = copyRangeNames( aSheetIndexMap, aRangeDataVec, aReferencingNames, -1, + pOldRangeData, rNewDoc, this, rNewPos, rOldPos, + bGlobalNamesToLocal, nTmpOldSheet, nTmpNewSheet, bSameDoc); + if (!rpRangeData) + { + rpRangeData = pTmpData; + nNewSheet = nTmpNewSheet; + } + } + + // Adjust copied nested names to new sheet/index. + for (auto & iRD : aRangeDataVec) + { + ScTokenArray* pCode = iRD->GetCode(); + if (pCode) + { + for (formula::FormulaToken* p = pCode->First(); p; p = pCode->Next()) + { + if (p->GetOpCode() == ocName) + { + auto it = aSheetIndexMap.find( SheetIndex( p->GetSheet(), p->GetIndex())); + if (it != aSheetIndexMap.end()) + { + p->SetSheet( it->second.mnSheet); + p->SetIndex( it->second.mnIndex); + } + else if (!bSameDoc) + { + SAL_WARN("sc.core","adjustCopyRangeName - mapping to new name in other doc missing"); + p->SetIndex(0); // #NAME? error instead of arbitrary name. + } + } + } + } + } + } + else + { + nNewSheet = ((nOldSheet < 0 && !bGlobalNamesToLocal) ? -1 : rNewPos.Tab()); + rpRangeData = copyRangeName( pOldRangeData, rNewDoc, this, rNewPos, rOldPos, bGlobalNamesToLocal, + nOldSheet, nNewSheet, bSameDoc); + } + } + rSheet = nNewSheet; + rIndex = rpRangeData ? rpRangeData->GetIndex() : 0; // 0 means not inserted + return true; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index f2a56ddc4ac6..b61d89c3dcf5 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -424,320 +424,13 @@ bool lcl_isReference(const FormulaToken& rToken) rToken.GetType() == svDoubleRef; } -enum MightReferenceSheet -{ - UNKNOWN, - NONE, - CODE, - NAME -}; - -MightReferenceSheet mightRangeNameReferenceSheet( ScRangeData* pData, SCTAB nRefTab) -{ - ScTokenArray* pCode = pData->GetCode(); - if (!pCode) - return MightReferenceSheet::NONE; - - for (const FormulaToken* p = pCode->First(); p; p = pCode->Next()) - { - if (p->GetOpCode() == ocName) - return MightReferenceSheet::NAME; - } - - return pCode->ReferencesSheet( nRefTab, pData->GetPos().Tab()) ? - MightReferenceSheet::CODE : MightReferenceSheet::NONE; -} - -ScRangeData* copyRangeName( const ScRangeData* pOldRangeData, ScDocument& rNewDoc, const ScDocument* pOldDoc, - const ScAddress& rNewPos, const ScAddress& rOldPos, bool bGlobalNamesToLocal, - SCTAB nOldSheet, const SCTAB nNewSheet, bool bSameDoc) -{ - ScAddress aRangePos( pOldRangeData->GetPos()); - if (nNewSheet >= 0) - aRangePos.SetTab( nNewSheet); - ScRangeData* pRangeData = new ScRangeData(*pOldRangeData, &rNewDoc, &aRangePos); - pRangeData->SetIndex(0); // needed for insert to assign a new index - ScTokenArray* pRangeNameToken = pRangeData->GetCode(); - if (bSameDoc && nNewSheet >= 0) - { - if (bGlobalNamesToLocal && nOldSheet < 0) - { - nOldSheet = rOldPos.Tab(); - if (rNewPos.Tab() <= nOldSheet) - // Sheet was inserted before and references already updated. - ++nOldSheet; - } - pRangeNameToken->AdjustSheetLocalNameReferences( nOldSheet, nNewSheet); - } - if (!bSameDoc) - { - pRangeNameToken->ReadjustAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos(), true); - pRangeNameToken->AdjustAbsoluteRefs(pOldDoc, rOldPos, rNewPos, true); - } - - bool bInserted; - if (nNewSheet < 0) - bInserted = rNewDoc.GetRangeName()->insert(pRangeData); - else - bInserted = rNewDoc.GetRangeName(nNewSheet)->insert(pRangeData); - - return bInserted ? pRangeData : nullptr; -} - -struct SheetIndex -{ - SCTAB mnSheet; - sal_uInt16 mnIndex; - - SheetIndex( SCTAB nSheet, sal_uInt16 nIndex ) : mnSheet(nSheet < -1 ? -1 : nSheet), mnIndex(nIndex) {} - bool operator<( const SheetIndex& r ) const - { - // Ascending order sheet, index - if (mnSheet < r.mnSheet) - return true; - if (mnSheet == r.mnSheet) - return mnIndex < r.mnIndex; - return false; - } -}; -typedef std::map< SheetIndex, SheetIndex > SheetIndexMap; - -ScRangeData* copyRangeNames( SheetIndexMap& rSheetIndexMap, std::vector<ScRangeData*>& rRangeDataVec, - const sc::UpdatedRangeNames& rReferencingNames, SCTAB nTab, - const ScRangeData* pOldRangeData, ScDocument& rNewDoc, const ScDocument* pOldDoc, - const ScAddress& rNewPos, const ScAddress& rOldPos, bool bGlobalNamesToLocal, - const SCTAB nOldSheet, const SCTAB nNewSheet, bool bSameDoc) -{ - ScRangeData* pRangeData = nullptr; - const ScRangeName* pOldRangeName = (nTab < 0 ? pOldDoc->GetRangeName() : pOldDoc->GetRangeName(nTab)); - if (pOldRangeName) - { - const ScRangeName* pNewRangeName = (nNewSheet < 0 ? rNewDoc.GetRangeName() : rNewDoc.GetRangeName(nNewSheet)); - sc::UpdatedRangeNames::NameIndicesType aSet( rReferencingNames.getUpdatedNames(nTab)); - for (auto const & rIndex : aSet) - { - const ScRangeData* pCopyData = pOldRangeName->findByIndex(rIndex); - if (pCopyData) - { - // Match the original pOldRangeData to adapt the current - // token's values later. For that no check for an already - // copied name is needed as we only enter here if there was - // none. - if (pCopyData == pOldRangeData) - { - pRangeData = copyRangeName( pCopyData, rNewDoc, pOldDoc, rNewPos, rOldPos, - bGlobalNamesToLocal, nOldSheet, nNewSheet, bSameDoc); - if (pRangeData) - { - rRangeDataVec.push_back(pRangeData); - rSheetIndexMap.insert( std::make_pair( SheetIndex( nOldSheet, pCopyData->GetIndex()), - SheetIndex( nNewSheet, pRangeData->GetIndex()))); - } - } - else - { - // First check if the name is already available as copy. - const ScRangeData* pFoundData = pNewRangeName->findByUpperName( pCopyData->GetUpperName()); - if (pFoundData) - { - // Just add the resulting sheet/index mapping. - rSheetIndexMap.insert( std::make_pair( SheetIndex( nOldSheet, pCopyData->GetIndex()), - SheetIndex( nNewSheet, pFoundData->GetIndex()))); - } - else - { - ScRangeData* pTmpData = copyRangeName( pCopyData, rNewDoc, pOldDoc, rNewPos, rOldPos, - bGlobalNamesToLocal, nOldSheet, nNewSheet, bSameDoc); - if (pTmpData) - { - rRangeDataVec.push_back(pTmpData); - rSheetIndexMap.insert( std::make_pair( SheetIndex( nOldSheet, pCopyData->GetIndex()), - SheetIndex( nNewSheet, pTmpData->GetIndex()))); - } - } - } - } - } - } - return pRangeData; -} - -/** Adjust or copy name from sheet-local to sheet-local, or global to - sheet-local if bGlobalNamesToLocal==true. - - @param rSheet - On entry, the original sheet of the named expression/range, <0 global. - On return TRUE, the new sheet. Else unchanged. - - @param rIndex - On entry, the original index of the named expression/range. - On return TRUE, the new index, or 0 if a new copied name couldn't be inserted. Else unchanged. - - @param rpRangeData - On entry, the pointer to the original named expression/range. - On return TRUE, the pointer to the new copied name, or nullptr if hit shappened. - - @return TRUE if copied and caller may need to evaluate rpRangeData and rSheet and rIndex. - FALSE if nothing to be done. - */ -bool adjustCopyRangeName( SCTAB& rSheet, sal_uInt16& rIndex, ScRangeData*& rpRangeData, - ScDocument& rNewDoc, const ScDocument* pOldDoc, - const ScAddress& rNewPos, const ScAddress& rOldPos, const bool bGlobalNamesToLocal) -{ - const bool bSameDoc = (rNewDoc.GetPool() == const_cast<ScDocument*>(pOldDoc)->GetPool()); - if (bSameDoc && ((rSheet < 0 && !bGlobalNamesToLocal) || (rSheet >= 0 && rSheet != rOldPos.Tab()))) - // Same doc and global name, if not copied to local name, or - // sheet-local name on other sheet stays the same. - return false; - - // Ensure we don't fiddle with the references until exit. - const SCTAB nOldSheet = rSheet; - const sal_uInt16 nOldIndex = rIndex; - - SAL_WARN_IF( !bSameDoc && nOldSheet >= 0 && nOldSheet != rOldPos.Tab(), - "sc.core", "adjustCopyRangeName - sheet-local name was on other sheet in other document"); - /* TODO: can we do something about that? e.g. loop over sheets? */ - - OUString aRangeName; - ScRangeData* pOldRangeData = nullptr; - - // XXX bGlobalNamesToLocal is also a synonym for copied sheet. - bool bInsertingBefore = (bGlobalNamesToLocal && bSameDoc && rNewPos.Tab() <= rOldPos.Tab()); - - // The Tab where an old local name is to be found or that a global name - // references. May differ below from nOldSheet if a sheet was inserted - // before the old position. Global names and local names other than on the - // old sheet or new sheet are already updated, local names on the old sheet - // or inserted sheet will be updated later. Confusing stuff. Watch out. - SCTAB nOldTab = (nOldSheet < 0 ? rOldPos.Tab() : nOldSheet); - if (bInsertingBefore) - // Sheet was already inserted before old position. - ++nOldTab; - - // Search the name of the RangeName. - if (nOldSheet >= 0) - { - const ScRangeName* pRangeName = pOldDoc->GetRangeName(nOldTab); - pOldRangeData = pRangeName ? pRangeName->findByIndex(nOldIndex) : nullptr; - if (!pOldRangeData) - return false; // might be an error in the formula array - aRangeName = pOldRangeData->GetUpperName(); - } - else - { - pOldRangeData = pOldDoc->GetRangeName()->findByIndex(nOldIndex); - if (!pOldRangeData) - return false; // might be an error in the formula array - aRangeName = pOldRangeData->GetUpperName(); - } - - // Find corresponding range name in new document. - // First search for local range name then global range names. - SCTAB nNewSheet = rNewPos.Tab(); - ScRangeName* pRangeName = rNewDoc.GetRangeName(nNewSheet); - // Search local range names. - if (pRangeName) - { - rpRangeData = pRangeName->findByUpperName(aRangeName); - } - // Search global range names. - if (!rpRangeData && !bGlobalNamesToLocal) - { - nNewSheet = -1; - pRangeName = rNewDoc.GetRangeName(); - if (pRangeName) - rpRangeData = pRangeName->findByUpperName(aRangeName); - } - // If no range name was found copy it. - if (!rpRangeData) - { - bool bEarlyBailOut = (nOldSheet < 0 && bSameDoc); - MightReferenceSheet eMightReference = mightRangeNameReferenceSheet( pOldRangeData, nOldTab); - if (bEarlyBailOut && eMightReference == MightReferenceSheet::NONE) - return false; - - if (eMightReference == MightReferenceSheet::NAME) - { - // Name these to clarify what is passed where. - const SCTAB nGlobalRefTab = nOldTab; - const SCTAB nLocalRefTab = (bInsertingBefore ? nOldTab-1 : nOldTab); - const SCTAB nOldTokenTab = (nOldSheet < 0 ? (bInsertingBefore ? nOldTab-1 : nOldTab) : nOldSheet); - const SCTAB nOldTokenTabReplacement = nOldTab; - sc::UpdatedRangeNames aReferencingNames; - pOldDoc->FindRangeNamesReferencingSheet( aReferencingNames, nOldSheet, nOldIndex, - nGlobalRefTab, nLocalRefTab, nOldTokenTab, nOldTokenTabReplacement, bSameDoc, 0); - if (bEarlyBailOut && aReferencingNames.isEmpty(-1) && aReferencingNames.isEmpty(nOldTokenTabReplacement)) - return false; - - SheetIndexMap aSheetIndexMap; - std::vector<ScRangeData*> aRangeDataVec; - if (!aReferencingNames.isEmpty(nOldTokenTabReplacement)) - { - const SCTAB nTmpOldSheet = (nOldSheet < 0 ? nOldTab : nOldSheet); - nNewSheet = rNewPos.Tab(); - rpRangeData = copyRangeNames( aSheetIndexMap, aRangeDataVec, aReferencingNames, nOldTab, - pOldRangeData, rNewDoc, pOldDoc, rNewPos, rOldPos, - bGlobalNamesToLocal, nTmpOldSheet, nNewSheet, bSameDoc); - } - if ((bGlobalNamesToLocal || !bSameDoc) && !aReferencingNames.isEmpty(-1)) - { - const SCTAB nTmpOldSheet = -1; - const SCTAB nTmpNewSheet = (bGlobalNamesToLocal ? rNewPos.Tab() : -1); - ScRangeData* pTmpData = copyRangeNames( aSheetIndexMap, aRangeDataVec, aReferencingNames, -1, - pOldRangeData, rNewDoc, pOldDoc, rNewPos, rOldPos, - bGlobalNamesToLocal, nTmpOldSheet, nTmpNewSheet, bSameDoc); - if (!rpRangeData) - { - rpRangeData = pTmpData; - nNewSheet = nTmpNewSheet; - } - } - - // Adjust copied nested names to new sheet/index. - for (auto & iRD : aRangeDataVec) - { - ScTokenArray* pCode = iRD->GetCode(); - if (pCode) - { - for (FormulaToken* p = pCode->First(); p; p = pCode->Next()) - { - if (p->GetOpCode() == ocName) - { - auto it = aSheetIndexMap.find( SheetIndex( p->GetSheet(), p->GetIndex())); - if (it != aSheetIndexMap.end()) - { - p->SetSheet( it->second.mnSheet); - p->SetIndex( it->second.mnIndex); - } - else if (!bSameDoc) - { - SAL_WARN("sc.core","adjustCopyRangeName - mapping to new name in other doc missing"); - p->SetIndex(0); // #NAME? error instead of arbitrary name. - } - } - } - } - } - } - else - { - nNewSheet = ((nOldSheet < 0 && !bGlobalNamesToLocal) ? -1 : rNewPos.Tab()); - rpRangeData = copyRangeName( pOldRangeData, rNewDoc, pOldDoc, rNewPos, rOldPos, bGlobalNamesToLocal, - nOldSheet, nNewSheet, bSameDoc); - } - } - rSheet = nNewSheet; - rIndex = rpRangeData ? rpRangeData->GetIndex() : 0; // 0 means not inserted - return true; -} - void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const ScDocument* pOldDoc, const ScAddress& rNewPos, const ScAddress& rOldPos, bool bGlobalNamesToLocal) { ScRangeData* pRangeData = nullptr; SCTAB nSheet = pToken->GetSheet(); sal_uInt16 nIndex = pToken->GetIndex(); - if (!adjustCopyRangeName( nSheet, nIndex, pRangeData, rNewDoc, pOldDoc, rNewPos, rOldPos, bGlobalNamesToLocal)) + if (!pOldDoc->CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, rNewPos, rOldPos, bGlobalNamesToLocal)) return; // nothing to do if (!pRangeData) |