diff options
author | Eike Rathke <erack@redhat.com> | 2015-07-07 01:45:41 +0200 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-07-08 11:45:10 +0000 |
commit | 9bb4b60fd6deb348af37d9a51860e4d554ffbc35 (patch) | |
tree | 1a0a9e3f87f225f570714915c1cdaaf0e29a3d36 | |
parent | b85ddf6ef577e7f38394a398818420fe9f367a66 (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>
-rw-r--r-- | sc/inc/refdata.hxx | 9 | ||||
-rw-r--r-- | sc/inc/tokenarray.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/refdata.cxx | 92 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 27 |
6 files changed, 138 insertions, 0 deletions
diff --git a/sc/inc/refdata.hxx b/sc/inc/refdata.hxx index e0d9b807a78b..75c94a1d89cf 100644 --- a/sc/inc/refdata.hxx +++ b/sc/inc/refdata.hxx @@ -104,6 +104,9 @@ public: SCCOL Col() const; SCTAB Tab() const; + /** Adjust ordering (front-top-left/rear-bottom-right) to a new position. */ + static void PutInOrder( ScSingleRefData& rRef1, ScSingleRefData& rRef2, const ScAddress& rPos ); + bool operator==( const ScSingleRefData& ) const; bool operator!=( const ScSingleRefData& ) const; @@ -147,8 +150,14 @@ struct ScComplexRefData bool ValidExternal() const; SC_DLLPUBLIC ScRange toAbs( const ScAddress& rPos ) const; + + /** Set a new range, assuming that the ordering of the range matches the + ordering of the reference data flags already set. */ void SetRange( const ScRange& rRange, const ScAddress& rPos ); + /** Adjust ordering (front-top-left/rear-bottom-right) to a new position. */ + void PutInOrder( const ScAddress& rPos ); + inline bool operator==( const ScComplexRefData& r ) const { return Ref1 == r.Ref1 && Ref2 == r.Ref2; } /** Enlarge range if reference passed is not within existing range. diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index cd32952c47eb..01d7a52fbd1c 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -216,6 +216,12 @@ public: void AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rOldPos, const ScAddress& rNewPos ); /** + * Adjust internal range references on base position change to justify / + * put in order the relative references. + */ + void AdjustReferenceOnCopy( const ScAddress& rNewPos ); + + /** * Clear sheet deleted flag from internal reference tokens if the sheet * index falls within specified range. Note that when a reference is on a * sheet that's been deleted, its referenced sheet index retains the diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index d456911eb53c..71b30d025154 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -844,6 +844,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 ) |