diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2017-03-22 21:21:31 -0400 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2017-04-06 13:53:21 +0000 |
commit | 97ce2a4eb0b2b479d48afe28299ad0ff1d3a264d (patch) | |
tree | 0d63272902d24ffa6f363f3eaeaee77d58e25da6 | |
parent | 16e2701d02e777673c957ff77bcc0a66e24f9d81 (diff) |
tdf#105908: restore previously deleted range references upon undo.
Change-Id: If1932a5eb10da4c50fbcc3329af75f2e7a0a5137
Reviewed-on: https://gerrit.libreoffice.org/35607
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
(cherry picked from commit 749405af4fc38e0c16dc7e860d23a13dfceb4e40)
Reviewed-on: https://gerrit.libreoffice.org/35672
Reviewed-by: Eike Rathke <erack@redhat.com>
-rw-r--r-- | sc/inc/refdata.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 19 | ||||
-rw-r--r-- | sc/source/core/tool/interpr6.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/refdata.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 19 |
5 files changed, 49 insertions, 2 deletions
diff --git a/sc/inc/refdata.hxx b/sc/inc/refdata.hxx index 5f3e7626940a..098f24de28fd 100644 --- a/sc/inc/refdata.hxx +++ b/sc/inc/refdata.hxx @@ -190,6 +190,8 @@ struct ScComplexRefData @return TRUE if changed. */ bool IncEndRowSticky( SCROW nDelta, const ScAddress& rPos ); + bool IsDeleted() const; + #if DEBUG_FORMULA_COMPILER void Dump( int nIndent = 0 ) const; #endif diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 7a0b08b06c96..13ab48391fb3 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -975,10 +975,17 @@ void ScInterpreter::PopSingleRef( ScAddress& rAdr ) break; case svSingleRef: { + const ScSingleRefData* pRefData = p->GetSingleRef(); + if (pRefData->IsDeleted()) + { + SetError( FormulaError::NoRef); + break; + } + SCCOL nCol; SCROW nRow; SCTAB nTab; - SingleRefToVars( *p->GetSingleRef(), nCol, nRow, nTab); + SingleRefToVars( *pRefData, nCol, nRow, nTab); rAdr.Set( nCol, nRow, nTab ); if (!pDok->m_TableOpList.empty()) ReplaceCell( rAdr ); @@ -1100,9 +1107,17 @@ void ScInterpreter::PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRe nGlobalError = pToken->GetError(); break; case svDoubleRef: + { --sp; - DoubleRefToRange( *pToken->GetDoubleRef(), rRange); + const ScComplexRefData* pRefData = pToken->GetDoubleRef(); + if (pRefData->IsDeleted()) + { + SetError( FormulaError::NoRef); + break; + } + DoubleRefToRange( *pRefData, rRange); break; + } case svRefList: { const ScRefList* pList = pToken->GetRefList(); diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx index 368ee2a157ee..c42f0f4545d3 100644 --- a/sc/source/core/tool/interpr6.cxx +++ b/sc/source/core/tool/interpr6.cxx @@ -613,6 +613,9 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) case svSingleRef : { PopSingleRef( aAdr ); + if (nGlobalError == FormulaError::NoRef) + return 0.0; + if ( nGlobalError != FormulaError::NONE && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT || ( mnSubTotalFlags & SubtotalFlags::IgnoreErrVal ) ) ) { @@ -676,6 +679,9 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero ) case svRefList : { PopDoubleRef( aRange, nParamCount, nRefInList); + if (nGlobalError == FormulaError::NoRef) + return 0.0; + if ( nGlobalError != FormulaError::NONE && ( eFunc == ifCOUNT2 || eFunc == ifCOUNT || ( mnSubTotalFlags & SubtotalFlags::IgnoreErrVal ) ) ) { diff --git a/sc/source/core/tool/refdata.cxx b/sc/source/core/tool/refdata.cxx index d97289345ae5..5d7d0f320f68 100644 --- a/sc/source/core/tool/refdata.cxx +++ b/sc/source/core/tool/refdata.cxx @@ -553,6 +553,11 @@ bool ScComplexRefData::IncEndRowSticky( SCROW nDelta, const ScAddress& rPos ) return true; } +bool ScComplexRefData::IsDeleted() const +{ + return Ref1.IsDeleted() || Ref2.IsDeleted(); +} + #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 77f5c36eef4d..23f986981784 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2624,6 +2624,12 @@ void setRefDeleted( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt ) } } +void restoreDeletedRef( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt ) +{ + restoreDeletedRef(rRef.Ref1, rCxt); + restoreDeletedRef(rRef.Ref2, rCxt); +} + bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange, const ScComplexRefData& rRef ) { @@ -2999,6 +3005,19 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon } } + if (!rCxt.isDeleted() && rRef.IsDeleted()) + { + // Check if the token has reference to previously deleted region. + ScRange aCheckRange = rRef.toAbs(aNewPos); + if (aSelectedRange.In(aCheckRange)) + { + // This reference was previously in the deleted region. Restore it. + restoreDeletedRef(rRef, rCxt); + aRes.mbValueChanged = true; + break; + } + } + if (rCxt.isInserted()) { if (expandRange(rCxt, aAbs, aSelectedRange, rRef)) |