From 4a2867e9f7b8929a73a0b6c89d73bb3de2c21f97 Mon Sep 17 00:00:00 2001 From: Markus Mohrhard Date: Sat, 28 Mar 2015 05:43:33 +0100 Subject: 3D refs with more than one sheet should not set sheets deleted, tdf#90001 correct 3D reference update on sheet deletion, tdf#90001 follow-up be1b3daeeb64a44e577510561d02147b87db72c2 missed a few cases * a deleted reference start was shifted by two sheets instead of one if the formula was on a sheet before the deleted one * a deleted reference end was not correct if the formula was on a sheet behind the deleted one and used relative sheet reference * #REF! wasn't set when the entire referenced range was deleted (cherry picked from commit 20e4ccc6ba366cd70c9218e016ccff4025e3d816) b9c7492a651a8429fa1c411c8e447593e366e09d Change-Id: I501ad421c283ec6a1f2629aa424f4d4c32228516 Reviewed-on: https://gerrit.libreoffice.org/15043 Reviewed-by: Eike Rathke Tested-by: Eike Rathke --- sc/source/core/tool/token.cxx | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'sc/source/core/tool/token.cxx') diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 1462a8be309f..a96936c9d961 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3348,6 +3348,42 @@ bool adjustSingleRefOnInsertedTab( ScSingleRefData& rRef, SCTAB nInsPos, SCTAB n return false; } +bool adjustDoubleRefOnDeleteTab(ScComplexRefData& rRef, SCTAB nDelPos, SCTAB nSheets, const ScAddress& rOldPos, const ScAddress& rNewPos) +{ + ScSingleRefData& rRef1 = rRef.Ref1; + ScSingleRefData& rRef2 = rRef.Ref2; + ScAddress aStartPos = rRef1.toAbs(rOldPos); + ScAddress aEndPos = rRef2.toAbs(rOldPos); + bool bMoreThanOneTab = aStartPos.Tab() != aEndPos.Tab(); + bool bModified = false; + if (bMoreThanOneTab && aStartPos.Tab() == nDelPos && nDelPos + nSheets <= aEndPos.Tab()) + { + if (rRef1.IsTabRel() && aStartPos.Tab() < rOldPos.Tab()) + { + rRef1.IncTab(nSheets); + bModified = true; + } + } + else + { + bModified = adjustSingleRefOnDeletedTab(rRef1, nDelPos, nSheets, rOldPos, rNewPos); + } + + if (bMoreThanOneTab && aEndPos.Tab() == nDelPos && aStartPos.Tab() <= nDelPos - nSheets) + { + if (!rRef2.IsTabRel() || rOldPos.Tab() < aEndPos.Tab()) + { + rRef2.IncTab(-nSheets); + bModified = true; + } + } + else + { + bModified |= adjustSingleRefOnDeletedTab(rRef2, nDelPos, nSheets, rOldPos, rNewPos); + } + return bModified; +} + } sc::RefUpdateResult ScTokenArray::AdjustReferenceOnDeletedTab( sc::RefUpdateDeleteTabContext& rCxt, const ScAddress& rOldPos ) @@ -3375,10 +3411,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnDeletedTab( sc::RefUpdateDele { formula::FormulaToken* pToken = *p; ScComplexRefData& rRef = *pToken->GetDoubleRef(); - if (adjustSingleRefOnDeletedTab(rRef.Ref1, rCxt.mnDeletePos, rCxt.mnSheets, rOldPos, aNewPos)) - aRes.mbReferenceModified = true; - if (adjustSingleRefOnDeletedTab(rRef.Ref2, rCxt.mnDeletePos, rCxt.mnSheets, rOldPos, aNewPos)) - aRes.mbReferenceModified = true; + aRes.mbReferenceModified |= adjustDoubleRefOnDeleteTab(rRef, rCxt.mnDeletePos, rCxt.mnSheets, rOldPos, aNewPos); } break; case svIndex: -- cgit v1.2.3