Kaydet (Commit) da80a5ff authored tarafından Eike Rathke's avatar Eike Rathke Kaydeden (comit) Andras Timar

always justify a referenced range in order, tdf#92468

(cherry picked from commit d24c6a02)

(re-)introduce ScComplexRefData::PutInOrder(), tdf#92468

(cherry picked from commit ad3d2b6c)

introduce ScTokenArray::AdjustReferenceOnCopy(), tdf#92468

(cherry picked from commit 369ee0b1)

call ScTokenArray::AdjustReferenceOnCopy() in ScFormulaCell clone, tdf#92468

(cherry picked from commit 3ddaeaab)

f551e02a77a416b95f74266de896391d1d72eb3c
0a7ac0d9d10e96223cd5f095a771aa6f9d271417
0dc0c3528b35bc6ea2525bafb94d72ee65e4791a

Change-Id: Id69c58800d28f1733777f7931a20d8ee7bdf034f
Reviewed-on: https://gerrit.libreoffice.org/16815Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst bf8ba3fd
......@@ -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;
......@@ -161,8 +164,14 @@ struct ScComplexRefData
}
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.
......
......@@ -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
......
......@@ -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 );
......
......@@ -1309,6 +1309,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 ) )
......
......@@ -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
{
......
......@@ -3951,6 +3951,34 @@ void ScTokenArray::AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rO
}
}
void ScTokenArray::AdjustReferenceOnCopy( const ScAddress& rNewPos )
{
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();
rRef.PutInOrder( rNewPos);
}
break;
default:
;
}
}
}
}
namespace {
void clearTabDeletedFlag( ScSingleRefData& rRef, const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment