summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-04-28 22:42:14 +0200
committerEike Rathke <erack@redhat.com>2016-04-28 22:43:09 +0200
commit37b071c9330d28f08d5a9f7bf11e577040925684 (patch)
tree2c3e2fbb119fee3c47d9227de4f2f37db911f3c5 /sc
parent75d588556ebe7f542673de67e87a6cb570ef75d1 (diff)
move to ScDocument::CopyAdjustRangeName() and namespace
Change-Id: I1ec3c8cc1b8d3cb899d49192295b14ffac02849a
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/document.hxx34
-rw-r--r--sc/source/core/data/document10.cxx292
-rw-r--r--sc/source/core/data/formulacell.cxx309
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)