summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2017-03-22 21:21:31 -0400
committerEike Rathke <erack@redhat.com>2017-04-06 13:53:21 +0000
commit97ce2a4eb0b2b479d48afe28299ad0ff1d3a264d (patch)
tree0d63272902d24ffa6f363f3eaeaee77d58e25da6
parent16e2701d02e777673c957ff77bcc0a66e24f9d81 (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.hxx2
-rw-r--r--sc/source/core/tool/interpr4.cxx19
-rw-r--r--sc/source/core/tool/interpr6.cxx6
-rw-r--r--sc/source/core/tool/refdata.cxx5
-rw-r--r--sc/source/core/tool/token.cxx19
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))