[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Thu Apr 6 13:53:51 UTC 2017


 sc/inc/refdata.hxx               |    2 ++
 sc/source/core/tool/interpr4.cxx |   19 +++++++++++++++++--
 sc/source/core/tool/interpr6.cxx |    6 ++++++
 sc/source/core/tool/refdata.cxx  |    5 +++++
 sc/source/core/tool/token.cxx    |   19 +++++++++++++++++++
 5 files changed, 49 insertions(+), 2 deletions(-)

New commits:
commit 97ce2a4eb0b2b479d48afe28299ad0ff1d3a264d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Mar 22 21:21:31 2017 -0400

    tdf#105908: restore previously deleted range references upon undo.
    
    Change-Id: If1932a5eb10da4c50fbcc3329af75f2e7a0a5137
    Reviewed-on: https://gerrit.libreoffice.org/35607
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    (cherry picked from commit 749405af4fc38e0c16dc7e860d23a13dfceb4e40)
    Reviewed-on: https://gerrit.libreoffice.org/35672
    Reviewed-by: Eike Rathke <erack at redhat.com>

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))


More information about the Libreoffice-commits mailing list