summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-03-19 00:22:40 +0100
committerEike Rathke <erack@redhat.com>2016-03-19 01:47:05 +0100
commitb86b97e54590872fc0ea85fbea22c2d00d241181 (patch)
treea4f150c1fd604f66ea88f4ed871a540c00bcc871 /sc/source
parenta4d300f559c4c5704133c01efa6fbcd9193a16c8 (diff)
adjust sheet references when copying sheet-local named expressions
... so references to the local sheet point to the new scope's local sheet and not to the originating sheet. Change-Id: I7f33f4e9b379ec01d6c2587e92ffe851892fc32d
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/formulacell.cxx12
-rw-r--r--sc/source/core/tool/rangenam.cxx4
-rw-r--r--sc/source/core/tool/token.cxx48
3 files changed, 61 insertions, 3 deletions
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 9ef82e4834b1..f91dc213a1f2 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -475,13 +475,23 @@ void adjustRangeName(formula::FormulaToken* pToken, ScDocument& rNewDoc, const S
//if no range name was found copy it
if (!pRangeData)
{
+ ScAddress aRangePos( pOldRangeData->GetPos());
if (nOldSheet < 0)
+ {
nNewSheet = -1;
+ }
else
+ {
nNewSheet = aNewPos.Tab();
- pRangeData = new ScRangeData(*pOldRangeData, &rNewDoc);
+ aRangePos.SetTab( nNewSheet);
+ }
+ 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)
+ {
+ pRangeNameToken->AdjustSheetLocalNameReferences( nOldSheet, nNewSheet);
+ }
if (!bSameDoc)
{
pRangeNameToken->ReadjustAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos(), true);
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 830980c9ca66..15b7f6b17383 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -126,11 +126,11 @@ ScRangeData::ScRangeData( ScDocument* pDok,
eType |= RT_ABSPOS;
}
-ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument) :
+ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument, const ScAddress* pPos) :
aName (rScRangeData.aName),
aUpperName (rScRangeData.aUpperName),
pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()), // make real copy (not copy-ctor)
- aPos (rScRangeData.aPos),
+ aPos (pPos ? *pPos : rScRangeData.aPos),
eType (rScRangeData.eType),
pDoc (pDocument ? pDocument : rScRangeData.pDoc),
eTempGrammar(rScRangeData.eTempGrammar),
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 3d82694c3a9e..7a47d69b1424 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2480,6 +2480,54 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddres
}
}
+void ScTokenArray::AdjustSheetLocalNameReferences( SCTAB nOldTab, SCTAB nNewTab )
+{
+ TokenPointers aPtrs( pCode, nLen, pRPN, nRPN, false);
+ for (size_t j=0; j<2; ++j)
+ {
+ FormulaToken** pp = aPtrs.maPointerRange[j].mpStart;
+ FormulaToken** pEnd = aPtrs.maPointerRange[j].mpStop;
+ for (; pp != pEnd; ++pp)
+ {
+ FormulaToken* p = aPtrs.getHandledToken(j,pp);
+ if (!p)
+ continue;
+
+ switch ( p->GetType() )
+ {
+ case svDoubleRef :
+ {
+ ScComplexRefData& rRef = *p->GetDoubleRef();
+ ScSingleRefData& rRef2 = rRef.Ref2;
+ ScSingleRefData& rRef1 = rRef.Ref1;
+
+ if (!rRef1.IsTabRel() && rRef1.Tab() == nOldTab)
+ rRef1.SetAbsTab( nNewTab);
+ if (!rRef2.IsTabRel() && rRef2.Tab() == nOldTab)
+ rRef2.SetAbsTab( nNewTab);
+ if (!rRef1.IsTabRel() && !rRef2.IsTabRel() && rRef1.Tab() > rRef2.Tab())
+ {
+ SCTAB nTab = rRef1.Tab();
+ rRef1.SetAbsTab( rRef2.Tab());
+ rRef2.SetAbsTab( nTab);
+ }
+ }
+ break;
+ case svSingleRef :
+ {
+ ScSingleRefData& rRef = *p->GetSingleRef();
+
+ if (!rRef.IsTabRel() && rRef.Tab() == nOldTab)
+ rRef.SetAbsTab( nNewTab);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+}
+
namespace {
ScRange getSelectedRange( const sc::RefUpdateContext& rCxt )