[Libreoffice-commits] core.git: sc/source

Eike Rathke erack at redhat.com
Wed May 18 22:30:40 UTC 2016


 sc/source/core/tool/token.cxx |   38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

New commits:
commit a2e591e26549294cdb07eb685d4069343404d898
Author: Eike Rathke <erack at redhat.com>
Date:   Wed May 18 23:32:00 2016 +0200

    Resolves: tdf#86502 split formula groups referring bounds shifted into
    
    So references can be updated or invalidated individually when deleting
    cells with shifting cells up or left.
    
    Change-Id: I03a57e94cf0fa9bb0716ffec21960e85ad5c7094

diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 642e3af..a9894c0 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -4365,18 +4365,18 @@ namespace {
 
 void checkBounds(
     const ScAddress& rPos, SCROW nGroupLen, const ScRange& rCheckRange,
-    const ScSingleRefData& rRef, std::vector<SCROW>& rBounds )
+    const ScSingleRefData& rRef, std::vector<SCROW>& rBounds, const ScRange* pDeletedRange )
 {
     if (!rRef.IsRowRel())
         return;
 
     ScRange aAbs(rRef.toAbs(rPos));
     aAbs.aEnd.IncRow(nGroupLen-1);
-    if (!rCheckRange.Intersects(aAbs))
+    if (!rCheckRange.Intersects(aAbs) && (!pDeletedRange || !pDeletedRange->Intersects(aAbs)))
         return;
 
     // Get the boundary row positions.
-    if (aAbs.aEnd.Row() < rCheckRange.aStart.Row())
+    if (aAbs.aEnd.Row() < rCheckRange.aStart.Row() && (!pDeletedRange || aAbs.aEnd.Row() < pDeletedRange->aStart.Row()))
         // No intersections.
         return;
 
@@ -4393,6 +4393,12 @@ void checkBounds(
         SCROW nOffset = rCheckRange.aStart.Row() - aAbs.aStart.Row();
         rBounds.push_back(rPos.Row()+nOffset);
     }
+    // Same for deleted range.
+    if (pDeletedRange && aAbs.aStart.Row() <= pDeletedRange->aStart.Row())
+    {
+        SCROW nOffset = pDeletedRange->aStart.Row() - aAbs.aStart.Row();
+        rBounds.push_back(rPos.Row()+nOffset);
+    }
 
     if (aAbs.aEnd.Row() >= rCheckRange.aEnd.Row())
     {
@@ -4409,6 +4415,12 @@ void checkBounds(
         SCROW nOffset = rCheckRange.aEnd.Row() + 1 - aAbs.aStart.Row();
         rBounds.push_back(rPos.Row()+nOffset);
     }
+    // Same for deleted range.
+    if (pDeletedRange && aAbs.aEnd.Row() >= pDeletedRange->aEnd.Row())
+    {
+        SCROW nOffset = pDeletedRange->aEnd.Row() + 1 - aAbs.aStart.Row();
+        rBounds.push_back(rPos.Row()+nOffset);
+    }
 }
 
 void checkBounds(
@@ -4418,6 +4430,9 @@ void checkBounds(
     if (!rRef.IsRowRel())
         return;
 
+    ScRange aDeletedRange( ScAddress::UNINITIALIZED );
+    const ScRange* pDeletedRange = nullptr;
+
     ScRange aCheckRange = rCxt.maRange;
     if (rCxt.meMode == URM_MOVE)
     {
@@ -4428,8 +4443,17 @@ void checkBounds(
             assert(!"can't move");
         }
     }
+    else if (rCxt.meMode == URM_INSDEL &&
+            ((rCxt.mnColDelta < 0 && rCxt.maRange.aStart.Col() > 0) ||
+             (rCxt.mnRowDelta < 0 && rCxt.maRange.aStart.Row() > 0)))
+    {
+        // Check bounds also against deleted range where cells are shifted
+        // into and references need to be invalidated.
+        aDeletedRange = getSelectedRange( rCxt);
+        pDeletedRange = &aDeletedRange;
+    }
 
-    checkBounds(rPos, nGroupLen, aCheckRange, rRef, rBounds);
+    checkBounds(rPos, nGroupLen, aCheckRange, rRef, rBounds, pDeletedRange);
 }
 
 }
@@ -4488,14 +4512,14 @@ void ScTokenArray::CheckRelativeReferenceBounds(
                 case svSingleRef:
                     {
                         const ScSingleRefData& rRef = *p->GetSingleRef();
-                        checkBounds(rPos, nGroupLen, rRange, rRef, rBounds);
+                        checkBounds(rPos, nGroupLen, rRange, rRef, rBounds, nullptr);
                     }
                     break;
                 case svDoubleRef:
                     {
                         const ScComplexRefData& rRef = *p->GetDoubleRef();
-                        checkBounds(rPos, nGroupLen, rRange, rRef.Ref1, rBounds);
-                        checkBounds(rPos, nGroupLen, rRange, rRef.Ref2, rBounds);
+                        checkBounds(rPos, nGroupLen, rRange, rRef.Ref1, rBounds, nullptr);
+                        checkBounds(rPos, nGroupLen, rRange, rRef.Ref2, rBounds, nullptr);
                     }
                     break;
                 default:


More information about the Libreoffice-commits mailing list