summaryrefslogtreecommitdiff
path: root/sc/source/core
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-07-07 01:45:41 +0200
committerAndras Timar <andras.timar@collabora.com>2015-08-03 17:51:08 +0200
commite24d775c0d8d355f9cd41f081991d2fe6f24017d (patch)
tree2488b740d34cd62eb7bea26bfd2d0fd77892e8e8 /sc/source/core
parent679651baff32e7971724ec0c1844a227f7f759a9 (diff)
always justify a referenced range in order, tdf#92468
(cherry picked from commit d24c6a0280b0287ee6c23ca89068323c6b7c3dd7) (re-)introduce ScComplexRefData::PutInOrder(), tdf#92468 (cherry picked from commit ad3d2b6c2e88d191d76f90eb5be927f7ca76c670) introduce ScTokenArray::AdjustReferenceOnCopy(), tdf#92468 (cherry picked from commit 369ee0b1faf79f1bd23c75ee04dd0dcc5bf283af) call ScTokenArray::AdjustReferenceOnCopy() in ScFormulaCell clone, tdf#92468 (cherry picked from commit 3ddaeaab37d585971e376de6ad7b0f06f55f2e1a) f551e02a77a416b95f74266de896391d1d72eb3c 0a7ac0d9d10e96223cd5f095a771aa6f9d271417 0dc0c3528b35bc6ea2525bafb94d72ee65e4791a Backported. Change-Id: Id69c58800d28f1733777f7931a20d8ee7bdf034f Reviewed-on: https://gerrit.libreoffice.org/16829 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc/source/core')
-rw-r--r--sc/source/core/data/formulacell.cxx3
-rw-r--r--sc/source/core/tool/interpr4.cxx1
-rw-r--r--sc/source/core/tool/refdata.cxx92
-rw-r--r--sc/source/core/tool/token.cxx27
4 files changed, 123 insertions, 0 deletions
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index efa393a04c99..0545f560cafd 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -850,6 +850,9 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
pCode->AdjustAbsoluteRefs( rCell.pDocument, rCell.aPos, aPos, false, bCopyBetweenDocs );
}
+ if (!pDocument->IsClipOrUndo())
+ pCode->AdjustReferenceOnCopy( aPos);
+
if ( nCloneFlags & SC_CLONECELL_ADJUST3DREL )
pCode->ReadjustRelative3DReferences( rCell.aPos, aPos );
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 504e87873fcf..f4158f05ec57 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1305,6 +1305,7 @@ void ScInterpreter::DoubleRefToRange( const ScComplexRefData & rCRef,
rRange.aStart.Set( nCol, nRow, nTab );
SingleRefToVars( rCRef.Ref2, nCol, nRow, nTab);
rRange.aEnd.Set( nCol, nRow, nTab );
+ rRange.Justify();
if (! pDok->aTableOpList.empty() && !bDontCheckForTableOp )
{
if ( IsTableOpInRange( rRange ) )
diff --git a/sc/source/core/tool/refdata.cxx b/sc/source/core/tool/refdata.cxx
index 97d419c03105..4a814dba1f3f 100644
--- a/sc/source/core/tool/refdata.cxx
+++ b/sc/source/core/tool/refdata.cxx
@@ -239,6 +239,93 @@ SCTAB ScSingleRefData::Tab() const
return mnTab;
}
+// static
+void ScSingleRefData::PutInOrder( ScSingleRefData& rRef1, ScSingleRefData& rRef2, const ScAddress& rPos )
+{
+ sal_uInt8 nRelState1 = rRef1.Flags.bRelName ?
+ ((rRef1.Flags.bTabRel ? 4 : 0) |
+ (rRef1.Flags.bRowRel ? 2 : 0) |
+ (rRef1.Flags.bColRel ? 1 : 0)) :
+ 0;
+
+ sal_uInt8 nRelState2 = rRef2.Flags.bRelName ?
+ ((rRef2.Flags.bTabRel ? 4 : 0) |
+ (rRef2.Flags.bRowRel ? 2 : 0) |
+ (rRef2.Flags.bColRel ? 1 : 0)) :
+ 0;
+
+ SCCOL nCol1 = rRef1.Flags.bColRel ? rPos.Col() + rRef1.mnCol : rRef1.mnCol;
+ SCCOL nCol2 = rRef2.Flags.bColRel ? rPos.Col() + rRef2.mnCol : rRef2.mnCol;
+ if (nCol2 < nCol1)
+ {
+ rRef1.mnCol = rRef2.Flags.bColRel ? nCol2 - rPos.Col() : nCol2;
+ rRef2.mnCol = rRef1.Flags.bColRel ? nCol1 - rPos.Col() : nCol1;
+ if (rRef1.Flags.bRelName && rRef1.Flags.bColRel)
+ nRelState2 |= 1;
+ else
+ nRelState2 &= ~1;
+ if (rRef2.Flags.bRelName && rRef2.Flags.bColRel)
+ nRelState1 |= 1;
+ else
+ nRelState1 &= ~1;
+ bool bTmp = rRef1.Flags.bColRel;
+ rRef1.Flags.bColRel = rRef2.Flags.bColRel;
+ rRef2.Flags.bColRel = bTmp;
+ bTmp = rRef1.Flags.bColDeleted;
+ rRef1.Flags.bColDeleted = rRef2.Flags.bColDeleted;
+ rRef2.Flags.bColDeleted = bTmp;
+ }
+
+ SCROW nRow1 = rRef1.Flags.bRowRel ? rPos.Row() + rRef1.mnRow : rRef1.mnRow;
+ SCROW nRow2 = rRef2.Flags.bRowRel ? rPos.Row() + rRef2.mnRow : rRef2.mnRow;
+ if (nRow2 < nRow1)
+ {
+ rRef1.mnRow = rRef2.Flags.bRowRel ? nRow2 - rPos.Row() : nRow2;
+ rRef2.mnRow = rRef1.Flags.bRowRel ? nRow1 - rPos.Row() : nRow1;
+ if (rRef1.Flags.bRelName && rRef1.Flags.bRowRel)
+ nRelState2 |= 2;
+ else
+ nRelState2 &= ~2;
+ if (rRef2.Flags.bRelName && rRef2.Flags.bRowRel)
+ nRelState1 |= 2;
+ else
+ nRelState1 &= ~2;
+ bool bTmp = rRef1.Flags.bRowRel;
+ rRef1.Flags.bRowRel = rRef2.Flags.bRowRel;
+ rRef2.Flags.bRowRel = bTmp;
+ bTmp = rRef1.Flags.bRowDeleted;
+ rRef1.Flags.bRowDeleted = rRef2.Flags.bRowDeleted;
+ rRef2.Flags.bRowDeleted = bTmp;
+ }
+
+ SCTAB nTab1 = rRef1.Flags.bTabRel ? rPos.Tab() + rRef1.mnTab : rRef1.mnTab;
+ SCTAB nTab2 = rRef2.Flags.bTabRel ? rPos.Tab() + rRef2.mnTab : rRef2.mnTab;
+ if (nTab2 < nTab1)
+ {
+ rRef1.mnTab = rRef2.Flags.bTabRel ? nTab2 - rPos.Tab() : nTab2;
+ rRef2.mnTab = rRef1.Flags.bTabRel ? nTab1 - rPos.Tab() : nTab1;
+ if (rRef1.Flags.bRelName && rRef1.Flags.bTabRel)
+ nRelState2 |= 4;
+ else
+ nRelState2 &= ~4;
+ if (rRef2.Flags.bRelName && rRef2.Flags.bTabRel)
+ nRelState1 |= 4;
+ else
+ nRelState1 &= ~4;
+ bool bTmp = rRef1.Flags.bTabRel;
+ rRef1.Flags.bTabRel = rRef2.Flags.bTabRel;
+ rRef2.Flags.bTabRel = bTmp;
+ bTmp = rRef1.Flags.bTabDeleted;
+ rRef1.Flags.bTabDeleted = rRef2.Flags.bTabDeleted;
+ rRef2.Flags.bTabDeleted = bTmp;
+ }
+
+ // bFlag3D stays the same on both references.
+
+ rRef1.Flags.bRelName = (nRelState1 != 0);
+ rRef2.Flags.bRelName = (nRelState2 != 0);
+}
+
bool ScSingleRefData::operator==( const ScSingleRefData& r ) const
{
return mnFlagValue == r.mnFlagValue && mnCol == r.mnCol && mnRow == r.mnRow && mnTab == r.mnTab;
@@ -382,6 +469,11 @@ void ScComplexRefData::SetRange( const ScRange& rRange, const ScAddress& rPos )
Ref2.SetAddress(rRange.aEnd, rPos);
}
+void ScComplexRefData::PutInOrder( const ScAddress& rPos )
+{
+ ScSingleRefData::PutInOrder( Ref1, Ref2, rPos);
+}
+
#if DEBUG_FORMULA_COMPILER
void ScComplexRefData::Dump( int nIndent ) const
{
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index b4d1dd02fc12..cfd286616152 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3624,6 +3624,33 @@ void ScTokenArray::AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rO
}
}
+void ScTokenArray::AdjustReferenceOnCopy( const ScAddress& rNewPos )
+{
+ TokenPointers aPtrs( pCode, nLen, pRPN, nRPN);
+ for (size_t j=0; j<2; ++j)
+ {
+ FormulaToken** pp = aPtrs.maPointerRange[j].mpStart;
+ FormulaToken** pEnd = aPtrs.maPointerRange[j].mpStop;
+ for (; pp != pEnd; ++pp)
+ {
+ if (TokenPointers::skipToken(j,pp))
+ continue;
+
+ switch ((*pp)->GetType())
+ {
+ case svDoubleRef:
+ {
+ ScComplexRefData& rRef = *(*pp)->GetDoubleRef();
+ rRef.PutInOrder( rNewPos);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+}
+
namespace {
void clearTabDeletedFlag( ScSingleRefData& rRef, const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )