[Libreoffice-commits] .: Branch 'libreoffice-3-6' - 3 commits - sc/inc sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Sep 24 08:35:27 PDT 2012


 sc/inc/conditio.hxx              |    2 
 sc/inc/rangelst.hxx              |    8 
 sc/source/core/data/conditio.cxx |   22 +
 sc/source/core/data/table2.cxx   |    5 
 sc/source/core/tool/rangelst.cxx |  545 ++++++++++++++++++++++++++++++++++++++-
 5 files changed, 577 insertions(+), 5 deletions(-)

New commits:
commit ae584d265c59c54608c63697559c0ed911601aeb
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sat Sep 22 04:44:35 2012 +0200

    some more fixes for ScRangeList::DeleteArea
    
    Change-Id: I7f4cf6b053d7cff85e46ecf51cbf8a327530de67
    Signed-off-by: Kohei Yoshida <kohei.yoshida at gmail.com>

diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx
index f33659d..8214c50 100644
--- a/sc/source/core/tool/rangelst.cxx
+++ b/sc/source/core/tool/rangelst.cxx
@@ -608,7 +608,7 @@ bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRan
     {
         // column deleted :     |-------|
         // column original: |-------|
-        if (nRow1 < nDeleteRow1 && nDeleteRow1 < nRow2 && nRow2 <= nDeleteRow2)
+        if (nRow1 < nDeleteRow1 && nDeleteRow1 <= nRow2 && nRow2 <= nDeleteRow2)
         {
             // row deleted:     |------|
             // row original: |------|
@@ -627,7 +627,7 @@ bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRan
             p->aEnd.SetRow(nDeleteRow1-1); // 1
             return true;
         }
-        else if (nRow1 < nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
+        else if (nRow1 <= nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
         {
             // row deleted:  |------|
             // row original:    |------|
@@ -651,7 +651,7 @@ bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRan
     {
         // column deleted : |-------|
         // column original:     |-------|
-        if (nRow1 < nDeleteRow1 && nDeleteRow1 < nRow2 && nRow2 <= nDeleteRow2)
+        if (nRow1 < nDeleteRow1 && nDeleteRow1 <= nRow2 && nRow2 <= nDeleteRow2)
         {
             // row deleted:     |------|
             // row original: |------|
@@ -671,7 +671,7 @@ bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRan
             p->aEnd.SetRow(nDeleteRow1-1); // 1
             return true;
         }
-        else if (nRow1 < nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
+        else if (nRow1 <= nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
         {
             // row deleted:  |-------|
             // row original:     |--------|
@@ -755,10 +755,10 @@ template<typename X, typename Y>
 bool checkForThreeRanges(
    X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
 {
-    if (nX1 < nDeleteX1 && nX2 <= nDeleteX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
+    if (nX1 <= nDeleteX1 && nX2 <= nDeleteX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
         return true;
 
-    if (nDeleteX1 <= nX1 && nDeleteX2 < nX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
+    if (nDeleteX1 <= nX1 && nDeleteX2 <= nX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
         return true;
 
     return false;
commit 34fa2a6763a6f17ffa4f38984d5beac13805515e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Sep 21 20:39:40 2012 -0400

    Backported fixes for several bugs found in ScRangeList::DeleteArea().
    
    Change-Id: I9875485008d021dd7a0605e4b7e350345d367a69
    Signed-off-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx
index edf2d69..f33659d 100644
--- a/sc/source/core/tool/rangelst.cxx
+++ b/sc/source/core/tool/rangelst.cxx
@@ -464,16 +464,31 @@ bool ScRangeList::UpdateReference(
 }
 
 namespace {
-    //
-        // r.aStart.X() <= p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
-        // && ( r.aStart.Y() <= p.aStart.Y() || r.aEnd.Y() >= r.aEnd.Y() )
 
+/**
+ * Check if the deleting range cuts the test range exactly into a single
+ * piece.
+ *
+ * X = column ; Y = row
+ * +------+    +------+
+ * |xxxxxx|    |      |
+ * +------+ or +------+
+ * |      |    |xxxxxx|
+ * +------+    +------+
+ *
+ * X = row; Y = column
+ * +--+--+    +--+--+
+ * |xx|  |    |  |xx|
+ * |xx|  | or |  |xx|
+ * |xx|  |    |  |xx|
+ * +--+--+    +--+--+
+ * where xxx is the deleted region.
+ */
 template<typename X, typename Y>
-bool checkForOneRange( X rStartX, X rEndX, Y rStartY, Y rEndY,
-                    X pStartX, X pEndX, Y pStartY, Y pEndY )
+bool checkForOneRange(
+   X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
 {
-    if( rStartX <= pStartX && rEndX >= pEndX
-            && ( rStartY <= pStartY || rEndY >= pEndY ) )
+    if (nDeleteX1 <= nX1 && nX2 <= nDeleteX2 && (nDeleteY1 <= nY1 || nY2 <= nDeleteY2))
         return true;
 
     return false;
@@ -481,142 +496,269 @@ bool checkForOneRange( X rStartX, X rEndX, Y rStartY, Y rEndY,
 
 bool handleOneRange( const ScRange& rDeleteRange, ScRange* p )
 {
-    ScAddress rDelStart = rDeleteRange.aStart;
-    ScAddress rDelEnd = rDeleteRange.aEnd;
-    ScAddress rPStart = p->aStart;
-    ScAddress rPEnd = p->aEnd;
-    if(checkForOneRange(rDelStart.Col(), rDelEnd.Col(), rDelStart.Row(), rDelEnd.Row(),
-                rPStart.Col(), rPEnd.Col(), rPStart.Row(), rPEnd.Row()))
+    const ScAddress& rDelStart = rDeleteRange.aStart;
+    const ScAddress& rDelEnd = rDeleteRange.aEnd;
+    ScAddress aPStart = p->aStart;
+    ScAddress aPEnd = p->aEnd;
+    SCCOL nDeleteCol1 = rDelStart.Col();
+    SCCOL nDeleteCol2 = rDelEnd.Col();
+    SCROW nDeleteRow1 = rDelStart.Row();
+    SCROW nDeleteRow2 = rDelEnd.Row();
+    SCCOL nCol1 = aPStart.Col();
+    SCCOL nCol2 = aPEnd.Col();
+    SCROW nRow1 = aPStart.Row();
+    SCROW nRow2 = aPEnd.Row();
+
+    if (checkForOneRange(nDeleteCol1, nDeleteCol2, nDeleteRow1, nDeleteRow2, nCol1, nCol2, nRow1, nRow2))
     {
-        // X = Col
-        // Y = Row
-        if(rDelStart.Row() <= rPStart.Row())
+        // Deleting range fully overlaps the column range.  Adjust the row span.
+        if (nDeleteRow1 <= nRow1)
         {
-            p->aStart.SetRow(rDelEnd.Row()+1);
+            // +------+
+            // |xxxxxx|
+            // +------+
+            // |      |
+            // +------+ (xxx) = deleted region
+
+            p->aStart.SetRow(nDeleteRow1+1);
+            return true;
         }
-        else if(rDelEnd.Row() >= rPEnd.Row())
+        else if (nRow2 <= nDeleteRow2)
         {
-            p->aEnd.SetRow(rDelStart.Row()-1);
-        }
+            // +------+
+            // |      |
+            // +------+
+            // |xxxxxx|
+            // +------+ (xxx) = deleted region
 
-        return true;
+            p->aEnd.SetRow(nDeleteRow1-1);
+            return true;
+        }
     }
-    else if(checkForOneRange(rDelStart.Row(), rDelEnd.Row(), rDelStart.Col(), rDelEnd.Col(),
-                rPStart.Row(), rPEnd.Row(), rPStart.Col(), rPEnd.Col()))
+    else if (checkForOneRange(nDeleteRow1, nDeleteRow2, nDeleteCol1, nDeleteCol2, nRow1, nRow2, nCol1, nCol2))
     {
-        // X = Row
-        // Y = Col
-        if(rDelStart.Col() <= rPStart.Col())
-            p->aStart.SetCol(rDelEnd.Col()+1);
-        else if(rDelEnd.Col() >= rPEnd.Col())
-            p->aEnd.SetCol(rDelStart.Col()-1);
+        // Deleting range fully overlaps the row range.  Adjust the column span.
+        if (nDeleteCol1 <= nCol1)
+        {
+            // +--+--+
+            // |xx|  |
+            // |xx|  |
+            // |xx|  |
+            // +--+--+ (xxx) = deleted region
 
-        return true;
+            p->aStart.SetCol(nDeleteCol2+1);
+            return true;
+        }
+        else if (nCol2 <= nDeleteCol2)
+        {
+            // +--+--+
+            // |  |xx|
+            // |  |xx|
+            // |  |xx|
+            // +--+--+ (xxx) = deleted region
+
+            p->aEnd.SetCol(nDeleteCol1-1);
+            return true;
+        }
     }
     return false;
 }
 
+/**
+ * Check if the deleting range cuts the test range in the middle, to
+ * separate it into exactly two pieces.
+ *
+ * Either
+ * +--------+    +--+-+--+
+ * |        |    |  |x|  |
+ * +--------+    |  |x|  |
+ * |xxxxxxxx| or |  |x|  |
+ * +--------+    |  |x|  |
+ * |        |    |  |x|  |
+ * +--------+    +--+-+--+
+ * where xxx is the deleted region.
+ */
 template<typename X, typename Y>
-bool checkForTwoRangesCase2( X rStartX, X rEndX, Y rStartY, Y rEndY,
-                    X pStartX, X pEndX, Y pStartY, Y pEndY )
+bool checkForTwoRangesCase2(
+   X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
 {
-    if(rStartY > pStartY && rStartX <= pStartX
-            && rEndY < pEndY && rEndX >= pEndX)
+    if (nY1 < nDeleteY1 && nDeleteY2 < nY2 && nDeleteX1 <= nX1 && nX2 <= nDeleteX2)
         return true;
 
     return false;
 }
 
-
 bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRange>& rNewRanges )
 {
-    ScAddress rDelStart = rDeleteRange.aStart;
-    ScAddress rDelEnd = rDeleteRange.aEnd;
-    ScAddress rPStart = p->aStart;
-    ScAddress rPEnd = p->aEnd;
-    SCCOL rStartCol = rDelStart.Col();
-    SCCOL rEndCol = rDelEnd.Col();
-    SCCOL pStartCol = rPStart.Col();
-    SCCOL pEndCol = rPEnd.Col();
-    SCROW rStartRow = rDelStart.Row();
-    SCROW rEndRow = rDelEnd.Row();
-    SCROW pStartRow = rPStart.Row();
-    SCROW pEndRow = rPEnd.Row();
-    SCTAB nTab = rPStart.Tab();
-    if(rStartCol > pStartCol && rStartCol < pEndCol && rEndCol >= pEndCol)
+    const ScAddress& rDelStart = rDeleteRange.aStart;
+    const ScAddress& rDelEnd = rDeleteRange.aEnd;
+    ScAddress aPStart = p->aStart;
+    ScAddress aPEnd = p->aEnd;
+    SCCOL nDeleteCol1 = rDelStart.Col();
+    SCCOL nDeleteCol2 = rDelEnd.Col();
+    SCROW nDeleteRow1 = rDelStart.Row();
+    SCROW nDeleteRow2 = rDelEnd.Row();
+    SCCOL nCol1 = aPStart.Col();
+    SCCOL nCol2 = aPEnd.Col();
+    SCROW nRow1 = aPStart.Row();
+    SCROW nRow2 = aPEnd.Row();
+    SCTAB nTab = aPStart.Tab();
+
+    if (nCol1 < nDeleteCol1 && nDeleteCol1 <= nCol2 && nCol2 <= nDeleteCol2)
     {
-        if(rStartRow > pStartRow && rStartRow < pEndRow && rEndRow >= pEndRow)
+        // column deleted :     |-------|
+        // column original: |-------|
+        if (nRow1 < nDeleteRow1 && nDeleteRow1 < nRow2 && nRow2 <= nDeleteRow2)
         {
-            ScRange aNewRange( pStartCol, rStartRow, nTab, rStartCol-1, pEndRow, nTab );
+            // row deleted:     |------|
+            // row original: |------|
+            //
+            // +-------+
+            // |   1   |
+            // +---+---+---+
+            // | 2 |xxxxxxx|
+            // +---+xxxxxxx|
+            //     |xxxxxxx|
+            //     +-------+ (xxx) deleted region
+
+            ScRange aNewRange( nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nRow2, nTab ); // 2
             rNewRanges.push_back(aNewRange);
 
-            p->aEnd.SetRow(rStartRow -1);
+            p->aEnd.SetRow(nDeleteRow1-1); // 1
             return true;
         }
-        else if(rEndRow > pStartRow && rEndRow < pEndRow && rStartRow <= pStartRow)
+        else if (nRow1 < nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
         {
-            ScRange aNewRange( rPStart, ScAddress( pStartCol -1, pEndRow, nTab ) );
+            // row deleted:  |------|
+            // row original:    |------|
+            //
+            //     +-------+
+            //     |xxxxxxx|
+            // +---+xxxxxxx|
+            // | 1 |xxxxxxx|
+            // +---+---+---+
+            // |   2   |    (xxx) deleted region
+            // +-------+
+
+            ScRange aNewRange( aPStart, ScAddress(nDeleteCol1-1, nRow2, nTab) ); // 1
             rNewRanges.push_back(aNewRange);
 
-            p->aStart.SetRow(rEndRow+1);
+            p->aStart.SetRow(nDeleteRow2+1); // 2
             return true;
         }
     }
-    else if(rEndCol > pStartCol && rEndCol < pEndCol && rStartCol <= pStartCol)
+    else if (nCol1 <= nDeleteCol2 && nDeleteCol2 < nCol2 && nDeleteCol1 <= nCol1)
     {
-        if(rStartRow > pStartRow && rStartRow < pEndRow)
+        // column deleted : |-------|
+        // column original:     |-------|
+        if (nRow1 < nDeleteRow1 && nDeleteRow1 < nRow2 && nRow2 <= nDeleteRow2)
         {
-            ScRange aNewRange( ScAddress( rEndCol +1, rStartRow, nTab ), rPEnd );
+            // row deleted:     |------|
+            // row original: |------|
+            //
+            //     +-------+
+            //     |   1   |
+            // +-------+---+
+            // |xxxxxxx| 2 |
+            // |xxxxxxx+---+
+            // |xxxxxxx|
+            // +-------+
+            //  (xxx) deleted region
+
+            ScRange aNewRange( ScAddress( nDeleteCol2+1, nDeleteRow1, nTab ), aPEnd ); // 2
             rNewRanges.push_back(aNewRange);
 
-            p->aEnd.SetRow(rStartRow-1);
+            p->aEnd.SetRow(nDeleteRow1-1); // 1
             return true;
         }
-        else if(rEndRow > pStartRow && rEndRow < pEndRow)
+        else if (nRow1 < nDeleteRow2 && nDeleteRow2 < nRow2 && nDeleteRow1 <= nRow1)
         {
-            ScRange aNewRange( rEndCol +1, pStartRow, nTab, rEndCol, rEndRow, nTab );
+            // row deleted:  |-------|
+            // row original:     |--------|
+            //
+            // +-------+
+            // |xxxxxxx|
+            // |xxxxxxx+---+
+            // |xxxxxxx| 1 |
+            // +-------+---+
+            //     |   2   |
+            //     +-------+ (xxx) deleted region
+
+            ScRange aNewRange(nDeleteCol2+1, nRow1, nTab, nCol2, nDeleteRow2, nTab); // 1
             rNewRanges.push_back(aNewRange);
 
-            p->aStart.SetRow(rEndRow+1);
+            p->aStart.SetRow(nDeleteRow2+1); // 2
             return true;
         }
     }
-    else if(checkForTwoRangesCase2(rDelStart.Col(), rDelEnd.Col(), rDelStart.Row(), rDelEnd.Row(),
-                rPStart.Col(), rPEnd.Col(), rPStart.Row(), rPEnd.Row()))
+    else if (nRow1 < nDeleteRow1 && nDeleteRow2 < nRow2 && nDeleteCol1 <= nCol1 && nCol2 <= nDeleteCol2)
     {
-        ScRange aNewRange( rPStart, ScAddress( rPEnd.Col(), rDelStart.Row() -1, nTab ) );
+        // +--------+
+        // |   1    |
+        // +--------+
+        // |xxxxxxxx| (xxx) deleted region
+        // +--------+
+        // |   2    |
+        // +--------+
+
+        ScRange aNewRange( aPStart, ScAddress(nCol2, nDeleteRow1-1, nTab) ); // 1
         rNewRanges.push_back(aNewRange);
 
-        p->aStart.SetRow(rEndRow+1);
+        p->aStart.SetRow(nDeleteRow2+1); // 2
         return true;
     }
-    else if(checkForTwoRangesCase2(rDelStart.Row(), rDelEnd.Row(), rDelStart.Col(), rDelEnd.Col(),
-                rPStart.Row(), rPEnd.Row(), rPStart.Col(), rPEnd.Col()))
+    else if (nCol1 < nDeleteCol1 && nDeleteCol2 < nCol2 && nDeleteRow1 <= nRow1 && nRow2 <= nDeleteRow2)
     {
-        ScRange aNewRange( rPStart, ScAddress( rDelStart.Col() -1, rPEnd.Row(), nTab ) );
+        // +---+-+---+
+        // |   |x|   |
+        // |   |x|   |
+        // | 1 |x| 2 | (xxx) deleted region
+        // |   |x|   |
+        // |   |x|   |
+        // +---+-+---+
+
+        ScRange aNewRange( aPStart, ScAddress(nDeleteCol1-1, nRow2, nTab) ); // 1
         rNewRanges.push_back(aNewRange);
 
-        p->aStart.SetCol(rEndCol+1);
+        p->aStart.SetCol(nDeleteCol2+1); // 2
         return true;
     }
 
     return false;
 }
 
-        // r.aStart.X() > p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
-        // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
-        // or
-        // r.aStart.X() <= p.aStart.X() && r.aEnd.X() < p.aEnd.X()
-        // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
+/**
+ * Check if any of the followings applies:
+ *
+ * X = column; Y = row
+ * +----------+           +----------+
+ * |          |           |          |
+ * |  +-------+---+    +--+-------+  |
+ * |  |xxxxxxxxxxx| or |xxxxxxxxxx|  |
+ * |  +-------+---+    +--+-------+  |
+ * |          |           |          |
+ * +----------+           +----------+
+ *
+ * X = row; Y = column
+ *     +--+
+ *     |xx|
+ * +---+xx+---+    +----------+
+ * |   |xx|   |    |          |
+ * |   |xx|   | or |   +--+   |
+ * |   +--+   |    |   |xx|   |
+ * |          |    |   |xx|   |
+ * +----------+    +---+xx+---+
+ *                     |xx|
+ *                     +--+     (xxx) deleted region
+ */
 template<typename X, typename Y>
-bool checkForThreeRanges( X rStartX, X rEndX, Y rStartY, Y rEndY,
-                                X pStartX, X pEndX, Y pStartY, Y pEndY )
+bool checkForThreeRanges(
+   X nDeleteX1, X nDeleteX2, Y nDeleteY1, Y nDeleteY2, X nX1, X nX2, Y nY1, Y nY2)
 {
-    if(rStartX > pStartX && rEndX >= pEndX
-            && rStartY > pStartY && rEndY < pEndY )
+    if (nX1 < nDeleteX1 && nX2 <= nDeleteX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
         return true;
-    else if( rStartX <= pStartX && rEndX < pEndX
-            && rStartY > pStartY && rEndY < pEndY )
+
+    if (nDeleteX1 <= nX1 && nDeleteX2 < nX2 && nY1 < nDeleteY1 && nDeleteY2 < nY2)
         return true;
 
     return false;
@@ -624,66 +766,100 @@ bool checkForThreeRanges( X rStartX, X rEndX, Y rStartY, Y rEndY,
 
 bool handleThreeRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRange>& rNewRanges )
 {
-    ScAddress rDelStart = rDeleteRange.aStart;
-    ScAddress rDelEnd = rDeleteRange.aEnd;
-    ScAddress rPStart = p->aStart;
-    ScAddress rPEnd = p->aEnd;
-    SCTAB nTab = rDelStart.Tab();
-    if(checkForThreeRanges(rDelStart.Col(), rDelEnd.Col(), rDelStart.Row(), rDelEnd.Row(),
-                rPStart.Col(), rPEnd.Col(), rPStart.Row(), rPEnd.Row()))
+    const ScAddress& rDelStart = rDeleteRange.aStart;
+    const ScAddress& rDelEnd = rDeleteRange.aEnd;
+    ScAddress aPStart = p->aStart;
+    ScAddress aPEnd = p->aEnd;
+    SCCOL nDeleteCol1 = rDelStart.Col();
+    SCCOL nDeleteCol2 = rDelEnd.Col();
+    SCROW nDeleteRow1 = rDelStart.Row();
+    SCROW nDeleteRow2 = rDelEnd.Row();
+    SCCOL nCol1 = aPStart.Col();
+    SCCOL nCol2 = aPEnd.Col();
+    SCROW nRow1 = aPStart.Row();
+    SCROW nRow2 = aPEnd.Row();
+    SCTAB nTab = aPStart.Tab();
+
+    if (checkForThreeRanges(nDeleteCol1, nDeleteCol2, nDeleteRow1, nDeleteRow2, nCol1, nCol2, nRow1, nRow2))
     {
-        if(rDelStart.Col() > rPStart.Col())
+        if (nCol1 < nDeleteCol1)
         {
-            SCCOL nCol1 = rDelStart.Col();
-
-            ScRange aNewRange( nCol1, rPStart.Row(), nTab, rPEnd.Col(), rDelStart.Row()-1, nTab);
+            // +---+------+
+            // |   |  2   |
+            // |   +------+---+
+            // | 1 |xxxxxxxxxx|
+            // |   +------+---+
+            // |   |  3   |
+            // +---+------+
+
+            ScRange aNewRange(nDeleteCol1, nRow1, nTab, nCol2, nDeleteRow1-1, nTab); // 2
             rNewRanges.push_back(aNewRange);
 
-            aNewRange = ScRange( ScAddress(nCol1, rDelEnd.Row()+1, nTab), rPEnd);
+            aNewRange = ScRange(ScAddress(nDeleteCol1, nDeleteRow2+1, nTab), aPEnd); // 3
             rNewRanges.push_back(aNewRange);
 
-            p->aEnd.SetCol(nCol1-1);
+            p->aEnd.SetCol(nDeleteCol1-1); // 1
         }
         else
         {
-            SCCOL nCol1 = rDelEnd.Col();
-
-            ScRange aNewRange( rPStart, ScAddress( nCol1 - 1, rDelStart.Row() -1, nTab ) );
+            //     +------+---+
+            //     |  1   |   |
+            // +---+------+   |
+            // |xxxxxxxxxx| 2 |
+            // +---+------+   |
+            //     |  3   |   |
+            //     +------+---+
+
+            ScRange aNewRange(aPStart, ScAddress(nDeleteCol2, nDeleteRow1-1, nTab)); // 1
             rNewRanges.push_back(aNewRange);
 
-            aNewRange = ScRange( rPStart.Col(), rDelEnd.Row() + 1, nTab, rDelEnd.Col() +1, rPEnd.Row(), nTab );
+            aNewRange = ScRange(nCol1, nDeleteRow2+1, nTab, nDeleteCol2, nRow2, nTab); // 3
             rNewRanges.push_back(aNewRange);
 
-            p->aStart.SetCol(nCol1+1);
+            p->aStart.SetCol(nDeleteCol2+1); // 2
         }
         return true;
     }
-    else if(checkForThreeRanges(rDelStart.Row(), rDelEnd.Row(), rDelStart.Col(), rDelEnd.Col(),
-                rPStart.Row(), rPEnd.Row(), rPStart.Col(), rPEnd.Col()))
+    else if (checkForThreeRanges(nDeleteRow1, nDeleteRow2, nDeleteCol1, nDeleteCol2, nRow1, nRow2, nCol1, nCol2))
     {
-        if(rDelStart.Row() > rPStart.Row())
+        if (nRow1 < nDeleteRow1)
         {
-            SCROW nRow1 = rDelStart.Row();
-
-            ScRange aNewRange( rPStart.Col(), nRow1, nTab, rDelStart.Col() -1, rPEnd.Row(), nTab );
+            // +----------+
+            // |    1     |
+            // +---+--+---+
+            // |   |xx|   |
+            // | 2 |xx| 3 |
+            // |   |xx|   |
+            // +---+xx+---+
+            //     |xx|
+            //     +--+
+
+            ScRange aNewRange(nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nRow2, nTab); // 2
             rNewRanges.push_back( aNewRange );
 
-            aNewRange = ScRange( ScAddress(rDelEnd.Col() +1, nRow1, nTab), rPEnd );
+            aNewRange = ScRange(ScAddress(nDeleteCol2+1, nDeleteRow1, nTab), aPEnd); // 3
             rNewRanges.push_back( aNewRange );
 
-            p->aEnd.SetRow(nRow1-1);
+            p->aEnd.SetRow(nDeleteRow1-1); // 1
         }
         else
         {
-            SCROW nRow1 = rDelEnd.Row();
-
-            ScRange aNewRange( rPStart, ScAddress( rDelStart.Col() -1, nRow1, nTab ) );
+            //     +--+
+            //     |xx|
+            // +---+xx+---+
+            // | 1 |xx| 2 |
+            // |   |xx|   |
+            // +---+--+---+
+            // |    3     |
+            // +----------+
+
+            ScRange aNewRange(aPStart, ScAddress(nDeleteCol1-1, nDeleteRow2, nTab)); // 1
             rNewRanges.push_back(aNewRange);
 
-            aNewRange = ScRange( rDelEnd.Col() +1, rPStart.Col(), nTab, rPEnd.Col(), nRow1, nTab );
+            aNewRange = ScRange(nDeleteCol2+1, nRow1, nTab, nCol2, nDeleteRow2, nTab); // 2
             rNewRanges.push_back( aNewRange );
 
-            p->aStart.SetRow(nRow1+1);
+            p->aStart.SetRow(nDeleteRow2+1); // 3
         }
         return true;
     }
@@ -693,26 +869,42 @@ bool handleThreeRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScR
 
 bool handleFourRanges( const ScRange& rDelRange, ScRange* p, std::vector<ScRange>& rNewRanges )
 {
-    ScAddress rDelStart = rDelRange.aStart;
-    ScAddress rDelEnd = rDelRange.aEnd;
-    ScAddress rPStart = p->aStart;
-    ScAddress rPEnd = p->aEnd;
-    if( rDelRange.aStart.Col() > p->aStart.Col() && rDelRange.aEnd.Col() < p->aEnd.Col()
-            && rDelRange.aStart.Row() > p->aStart.Row() && rDelRange.aEnd.Row() < p->aEnd.Row() )
+    const ScAddress& rDelStart = rDelRange.aStart;
+    const ScAddress& rDelEnd = rDelRange.aEnd;
+    ScAddress aPStart = p->aStart;
+    ScAddress aPEnd = p->aEnd;
+    SCCOL nDeleteCol1 = rDelStart.Col();
+    SCCOL nDeleteCol2 = rDelEnd.Col();
+    SCROW nDeleteRow1 = rDelStart.Row();
+    SCROW nDeleteRow2 = rDelEnd.Row();
+    SCCOL nCol1 = aPStart.Col();
+    SCCOL nCol2 = aPEnd.Col();
+    SCROW nRow1 = aPStart.Row();
+    SCROW nRow2 = aPEnd.Row();
+    SCTAB nTab = aPStart.Tab();
+
+    if (nCol1 < nDeleteCol1 && nDeleteCol2 < nCol2 && nRow1 < nDeleteRow1 && nDeleteRow2 < nRow2)
     {
-        SCTAB nTab = rDelStart.Tab();
-
-        ScRange aNewRange( ScAddress( rPStart.Col(), rDelEnd.Row()+1, nTab ), rPEnd );
+        // +---------------+
+        // |       1       |
+        // +---+-------+---+
+        // |   |xxxxxxx|   |
+        // | 2 |xxxxxxx| 3 |
+        // |   |xxxxxxx|   |
+        // +---+-------+---+
+        // |       4       |
+        // +---------------+
+
+        ScRange aNewRange(ScAddress(nCol1, nDeleteRow2+1, nTab), aPEnd); // 4
         rNewRanges.push_back( aNewRange );
 
-        aNewRange = ScRange( rPStart.Col(), rDelStart.Row(), nTab, rDelStart.Col() -1, rDelEnd.Row(), nTab );
+        aNewRange = ScRange(nCol1, nDeleteRow1, nTab, nDeleteCol1-1, nDeleteRow2, nTab); // 2
         rNewRanges.push_back( aNewRange );
 
-        aNewRange = ScRange( rDelEnd.Col() +1, rDelStart.Row(), nTab, rPEnd.Col(), rDelEnd.Row(), nTab );
+        aNewRange = ScRange(nDeleteCol2+1, nDeleteRow1, nTab, nCol2, nDeleteRow2, nTab); // 3
         rNewRanges.push_back( aNewRange );
 
-        rPEnd.SetRow(rDelStart.Row()-1);
-        p->aEnd = rPEnd;
+        p->aEnd.SetRow(nDeleteRow1-1); // 1
 
         return true;
     }
@@ -728,7 +920,7 @@ void ScRangeList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
     ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     for(size_t i = 0; i < maRanges.size();)
     {
-        if(FindRangeIn(aRange)(maRanges[i]))
+        if(FindRangeIn<ScRange>(aRange)(maRanges[i]))
         {
             ScRange* pRange = Remove(i);
             delete pRange;
commit fbf78dac0fd616b85969fa77f00a4597b49ab3b4
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Aug 31 04:02:10 2012 +0200

    Backport various conditional formatting fixes from master.
    
    Change-Id: I52987e957918853bcd1abd1460c6166b52454d62
    Signed-off-by: Kohei Yoshida <kohei.yoshida at gmail.com>

diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index 49cfaa0..80a8e62 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -289,6 +289,7 @@ public:
     void            CompileXML();
     void            UpdateReference( UpdateRefMode eUpdateRefMode,
                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
+    void            DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
     void            UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
     void            RenameCellStyle( const String& rOld, const String& rNew );
 
@@ -344,6 +345,7 @@ public:
                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
     void    RenameCellStyle( const String& rOld, const String& rNew );
     void    UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos );
+    void    DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
 
     void    SourceChanged( const ScAddress& rAddr );
 
diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx
index 0c51506..74bb7be 100644
--- a/sc/inc/rangelst.hxx
+++ b/sc/inc/rangelst.hxx
@@ -68,6 +68,12 @@ public:
                                      SCsTAB nDz
                                    );
 
+    /** For now this method assumes that nTab1 == nTab2
+     * The algorithm will be much more complicated if nTab1 != nTab2
+     */
+    void            DeleteArea( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2,
+                                    SCROW nRow2, SCTAB nTab2 );
+
     const ScRange*  Find( const ScAddress& ) const;
     ScRange*        Find( const ScAddress& );
     bool            operator==( const ScRangeList& ) const;
@@ -93,6 +99,8 @@ public:
 
 private:
     ::std::vector<ScRange*> maRanges;
+    typedef std::vector<ScRange*>::iterator iterator;
+    typedef std::vector<ScRange*>::const_iterator const_iterator;
 };
 SV_DECL_IMPL_REF( ScRangeList );
 
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index feb3f76..ea6657a 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -1552,6 +1552,12 @@ void ScConditionalFormat::UpdateReference( UpdateRefMode eUpdateRefMode,
         itr->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz);
 }
 
+void ScConditionalFormat::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+    SCTAB nTab = maRanges[0]->aStart.Tab();
+    maRanges.DeleteArea( nCol1, nRow1, nTab, nCol2, nRow2, nTab );
+}
+
 void ScConditionalFormat::RenameCellStyle(const String& rOld, const String& rNew)
 {
     for(CondFormatContainer::iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
@@ -1707,6 +1713,22 @@ void ScConditionalFormatList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
         itr->UpdateMoveTab( nOldPos, nNewPos );
 }
 
+void ScConditionalFormatList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+    for( iterator itr = begin(); itr != end(); ++itr)
+        itr->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
+
+    // need to check which must be deleted
+    iterator itr = begin();
+    while(itr != end())
+    {
+        if(itr->GetRange().empty())
+            maConditionalFormats.erase(itr++);
+        else
+            ++itr;
+    }
+}
+
 void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
 {
     for( iterator itr = begin(); itr != end(); ++itr)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 21d9307..4230cbd 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -536,6 +536,8 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal
             aPattern.GetItemSet().Put( ScProtectionAttr( false ) );
             ApplyPatternArea( nCol1, nRow1, nCol2, nRow2, aPattern );
         }
+
+        mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 );
     }
 
     if (nDelFlag & IDF_NOTE)
@@ -564,6 +566,9 @@ void ScTable::DeleteSelection( sal_uInt16 nDelFlag, const ScMarkData& rMark )
         ScRange* pRange = aRangeList[i];
         if (nDelFlag & IDF_NOTE && pRange)
             maNotes.erase(pRange->aStart.Col(), pRange->aStart.Row(), pRange->aEnd.Col(), pRange->aEnd.Row(), true);
+
+        if(pRange && pRange->aStart.Tab() == nTab)
+            mpCondFormatList->DeleteArea( pRange->aStart.Col(), pRange->aStart.Row(), pRange->aEnd.Col(), pRange->aEnd.Row() );
     }
 
         //
diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx
index 88f9727..edf2d69 100644
--- a/sc/source/core/tool/rangelst.cxx
+++ b/sc/source/core/tool/rangelst.cxx
@@ -66,6 +66,20 @@ private:
 };
 
 template<typename T>
+class FindRangeIn : public ::std::unary_function<bool, ScRange*>
+{
+public:
+    FindRangeIn(const T& rTest) : mrTest(rTest) {}
+    FindRangeIn(const FindRangeIn& r) : mrTest(r.mrTest) {}
+    bool operator() (const ScRange* pRange) const
+    {
+        return mrTest.In(*pRange);
+    }
+private:
+    const T& mrTest;
+};
+
+template<typename T>
 class FindIntersectingRange : public ::std::unary_function<bool, ScRange*>
 {
 public:
@@ -407,12 +421,21 @@ bool ScRangeList::UpdateReference(
     SCTAB nTab2;
     rWhere.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
 
-    // delete all entries that are fully deleted
-    if( eUpdateRefMode == URM_INSDEL && (nDx < 0 || nDy < 0) )
+    if(eUpdateRefMode == URM_INSDEL)
     {
-        vector<ScRange*>::iterator itr = std::remove_if(maRanges.begin(), maRanges.end(), FindDeletedRange(nDx, nDy));
-        for_each(itr, maRanges.end(), ScDeleteObjectByPtr<ScRange>());
-        maRanges.erase(itr, maRanges.end());
+        // right now this only works for nTab1 == nTab2
+        if(nTab1 == nTab2)
+        {
+            if(nDx < 0)
+            {
+                DeleteArea(nCol1+nDx, nRow1, nTab1, nCol1-1, nRow2, nTab2);
+            }
+            if(nDy < 0)
+            {
+                DeleteArea(nCol1, nRow1+nDy, nTab1, nCol2, nRow1-1, nTab2);
+            }
+            SAL_WARN_IF(nDx < 0 && nDy < 0, "sc", "nDx and nDy are negative, check why");
+        }
     }
 
     vector<ScRange*>::iterator itr = maRanges.begin(), itrEnd = maRanges.end();
@@ -440,6 +463,326 @@ bool ScRangeList::UpdateReference(
     return bChanged;
 }
 
+namespace {
+    //
+        // r.aStart.X() <= p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
+        // && ( r.aStart.Y() <= p.aStart.Y() || r.aEnd.Y() >= r.aEnd.Y() )
+
+template<typename X, typename Y>
+bool checkForOneRange( X rStartX, X rEndX, Y rStartY, Y rEndY,
+                    X pStartX, X pEndX, Y pStartY, Y pEndY )
+{
+    if( rStartX <= pStartX && rEndX >= pEndX
+            && ( rStartY <= pStartY || rEndY >= pEndY ) )
+        return true;
+
+    return false;
+}
+
+bool handleOneRange( const ScRange& rDeleteRange, ScRange* p )
+{
+    ScAddress rDelStart = rDeleteRange.aStart;
+    ScAddress rDelEnd = rDeleteRange.aEnd;
+    ScAddress rPStart = p->aStart;
+    ScAddress rPEnd = p->aEnd;
+    if(checkForOneRange(rDelStart.Col(), rDelEnd.Col(), rDelStart.Row(), rDelEnd.Row(),
+                rPStart.Col(), rPEnd.Col(), rPStart.Row(), rPEnd.Row()))
+    {
+        // X = Col
+        // Y = Row
+        if(rDelStart.Row() <= rPStart.Row())
+        {
+            p->aStart.SetRow(rDelEnd.Row()+1);
+        }
+        else if(rDelEnd.Row() >= rPEnd.Row())
+        {
+            p->aEnd.SetRow(rDelStart.Row()-1);
+        }
+
+        return true;
+    }
+    else if(checkForOneRange(rDelStart.Row(), rDelEnd.Row(), rDelStart.Col(), rDelEnd.Col(),
+                rPStart.Row(), rPEnd.Row(), rPStart.Col(), rPEnd.Col()))
+    {
+        // X = Row
+        // Y = Col
+        if(rDelStart.Col() <= rPStart.Col())
+            p->aStart.SetCol(rDelEnd.Col()+1);
+        else if(rDelEnd.Col() >= rPEnd.Col())
+            p->aEnd.SetCol(rDelStart.Col()-1);
+
+        return true;
+    }
+    return false;
+}
+
+template<typename X, typename Y>
+bool checkForTwoRangesCase2( X rStartX, X rEndX, Y rStartY, Y rEndY,
+                    X pStartX, X pEndX, Y pStartY, Y pEndY )
+{
+    if(rStartY > pStartY && rStartX <= pStartX
+            && rEndY < pEndY && rEndX >= pEndX)
+        return true;
+
+    return false;
+}
+
+
+bool handleTwoRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRange>& rNewRanges )
+{
+    ScAddress rDelStart = rDeleteRange.aStart;
+    ScAddress rDelEnd = rDeleteRange.aEnd;
+    ScAddress rPStart = p->aStart;
+    ScAddress rPEnd = p->aEnd;
+    SCCOL rStartCol = rDelStart.Col();
+    SCCOL rEndCol = rDelEnd.Col();
+    SCCOL pStartCol = rPStart.Col();
+    SCCOL pEndCol = rPEnd.Col();
+    SCROW rStartRow = rDelStart.Row();
+    SCROW rEndRow = rDelEnd.Row();
+    SCROW pStartRow = rPStart.Row();
+    SCROW pEndRow = rPEnd.Row();
+    SCTAB nTab = rPStart.Tab();
+    if(rStartCol > pStartCol && rStartCol < pEndCol && rEndCol >= pEndCol)
+    {
+        if(rStartRow > pStartRow && rStartRow < pEndRow && rEndRow >= pEndRow)
+        {
+            ScRange aNewRange( pStartCol, rStartRow, nTab, rStartCol-1, pEndRow, nTab );
+            rNewRanges.push_back(aNewRange);
+
+            p->aEnd.SetRow(rStartRow -1);
+            return true;
+        }
+        else if(rEndRow > pStartRow && rEndRow < pEndRow && rStartRow <= pStartRow)
+        {
+            ScRange aNewRange( rPStart, ScAddress( pStartCol -1, pEndRow, nTab ) );
+            rNewRanges.push_back(aNewRange);
+
+            p->aStart.SetRow(rEndRow+1);
+            return true;
+        }
+    }
+    else if(rEndCol > pStartCol && rEndCol < pEndCol && rStartCol <= pStartCol)
+    {
+        if(rStartRow > pStartRow && rStartRow < pEndRow)
+        {
+            ScRange aNewRange( ScAddress( rEndCol +1, rStartRow, nTab ), rPEnd );
+            rNewRanges.push_back(aNewRange);
+
+            p->aEnd.SetRow(rStartRow-1);
+            return true;
+        }
+        else if(rEndRow > pStartRow && rEndRow < pEndRow)
+        {
+            ScRange aNewRange( rEndCol +1, pStartRow, nTab, rEndCol, rEndRow, nTab );
+            rNewRanges.push_back(aNewRange);
+
+            p->aStart.SetRow(rEndRow+1);
+            return true;
+        }
+    }
+    else if(checkForTwoRangesCase2(rDelStart.Col(), rDelEnd.Col(), rDelStart.Row(), rDelEnd.Row(),
+                rPStart.Col(), rPEnd.Col(), rPStart.Row(), rPEnd.Row()))
+    {
+        ScRange aNewRange( rPStart, ScAddress( rPEnd.Col(), rDelStart.Row() -1, nTab ) );
+        rNewRanges.push_back(aNewRange);
+
+        p->aStart.SetRow(rEndRow+1);
+        return true;
+    }
+    else if(checkForTwoRangesCase2(rDelStart.Row(), rDelEnd.Row(), rDelStart.Col(), rDelEnd.Col(),
+                rPStart.Row(), rPEnd.Row(), rPStart.Col(), rPEnd.Col()))
+    {
+        ScRange aNewRange( rPStart, ScAddress( rDelStart.Col() -1, rPEnd.Row(), nTab ) );
+        rNewRanges.push_back(aNewRange);
+
+        p->aStart.SetCol(rEndCol+1);
+        return true;
+    }
+
+    return false;
+}
+
+        // r.aStart.X() > p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
+        // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
+        // or
+        // r.aStart.X() <= p.aStart.X() && r.aEnd.X() < p.aEnd.X()
+        // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
+template<typename X, typename Y>
+bool checkForThreeRanges( X rStartX, X rEndX, Y rStartY, Y rEndY,
+                                X pStartX, X pEndX, Y pStartY, Y pEndY )
+{
+    if(rStartX > pStartX && rEndX >= pEndX
+            && rStartY > pStartY && rEndY < pEndY )
+        return true;
+    else if( rStartX <= pStartX && rEndX < pEndX
+            && rStartY > pStartY && rEndY < pEndY )
+        return true;
+
+    return false;
+}
+
+bool handleThreeRanges( const ScRange& rDeleteRange, ScRange* p, std::vector<ScRange>& rNewRanges )
+{
+    ScAddress rDelStart = rDeleteRange.aStart;
+    ScAddress rDelEnd = rDeleteRange.aEnd;
+    ScAddress rPStart = p->aStart;
+    ScAddress rPEnd = p->aEnd;
+    SCTAB nTab = rDelStart.Tab();
+    if(checkForThreeRanges(rDelStart.Col(), rDelEnd.Col(), rDelStart.Row(), rDelEnd.Row(),
+                rPStart.Col(), rPEnd.Col(), rPStart.Row(), rPEnd.Row()))
+    {
+        if(rDelStart.Col() > rPStart.Col())
+        {
+            SCCOL nCol1 = rDelStart.Col();
+
+            ScRange aNewRange( nCol1, rPStart.Row(), nTab, rPEnd.Col(), rDelStart.Row()-1, nTab);
+            rNewRanges.push_back(aNewRange);
+
+            aNewRange = ScRange( ScAddress(nCol1, rDelEnd.Row()+1, nTab), rPEnd);
+            rNewRanges.push_back(aNewRange);
+
+            p->aEnd.SetCol(nCol1-1);
+        }
+        else
+        {
+            SCCOL nCol1 = rDelEnd.Col();
+
+            ScRange aNewRange( rPStart, ScAddress( nCol1 - 1, rDelStart.Row() -1, nTab ) );
+            rNewRanges.push_back(aNewRange);
+
+            aNewRange = ScRange( rPStart.Col(), rDelEnd.Row() + 1, nTab, rDelEnd.Col() +1, rPEnd.Row(), nTab );
+            rNewRanges.push_back(aNewRange);
+
+            p->aStart.SetCol(nCol1+1);
+        }
+        return true;
+    }
+    else if(checkForThreeRanges(rDelStart.Row(), rDelEnd.Row(), rDelStart.Col(), rDelEnd.Col(),
+                rPStart.Row(), rPEnd.Row(), rPStart.Col(), rPEnd.Col()))
+    {
+        if(rDelStart.Row() > rPStart.Row())
+        {
+            SCROW nRow1 = rDelStart.Row();
+
+            ScRange aNewRange( rPStart.Col(), nRow1, nTab, rDelStart.Col() -1, rPEnd.Row(), nTab );
+            rNewRanges.push_back( aNewRange );
+
+            aNewRange = ScRange( ScAddress(rDelEnd.Col() +1, nRow1, nTab), rPEnd );
+            rNewRanges.push_back( aNewRange );
+
+            p->aEnd.SetRow(nRow1-1);
+        }
+        else
+        {
+            SCROW nRow1 = rDelEnd.Row();
+
+            ScRange aNewRange( rPStart, ScAddress( rDelStart.Col() -1, nRow1, nTab ) );
+            rNewRanges.push_back(aNewRange);
+
+            aNewRange = ScRange( rDelEnd.Col() +1, rPStart.Col(), nTab, rPEnd.Col(), nRow1, nTab );
+            rNewRanges.push_back( aNewRange );
+
+            p->aStart.SetRow(nRow1+1);
+        }
+        return true;
+    }
+
+    return false;
+}
+
+bool handleFourRanges( const ScRange& rDelRange, ScRange* p, std::vector<ScRange>& rNewRanges )
+{
+    ScAddress rDelStart = rDelRange.aStart;
+    ScAddress rDelEnd = rDelRange.aEnd;
+    ScAddress rPStart = p->aStart;
+    ScAddress rPEnd = p->aEnd;
+    if( rDelRange.aStart.Col() > p->aStart.Col() && rDelRange.aEnd.Col() < p->aEnd.Col()
+            && rDelRange.aStart.Row() > p->aStart.Row() && rDelRange.aEnd.Row() < p->aEnd.Row() )
+    {
+        SCTAB nTab = rDelStart.Tab();
+
+        ScRange aNewRange( ScAddress( rPStart.Col(), rDelEnd.Row()+1, nTab ), rPEnd );
+        rNewRanges.push_back( aNewRange );
+
+        aNewRange = ScRange( rPStart.Col(), rDelStart.Row(), nTab, rDelStart.Col() -1, rDelEnd.Row(), nTab );
+        rNewRanges.push_back( aNewRange );
+
+        aNewRange = ScRange( rDelEnd.Col() +1, rDelStart.Row(), nTab, rPEnd.Col(), rDelEnd.Row(), nTab );
+        rNewRanges.push_back( aNewRange );
+
+        rPEnd.SetRow(rDelStart.Row()-1);
+        p->aEnd = rPEnd;
+
+        return true;
+    }
+
+    return false;
+}
+
+}
+
+void ScRangeList::DeleteArea( SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+                                SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
+{
+    ScRange aRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+    for(size_t i = 0; i < maRanges.size();)
+    {
+        if(FindRangeIn(aRange)(maRanges[i]))
+        {
+            ScRange* pRange = Remove(i);
+            delete pRange;
+        }
+        else
+            ++i;
+    }
+
+    std::vector<ScRange> aNewRanges;
+
+    for(iterator itr = maRanges.begin(); itr != maRanges.end(); ++itr)
+    {
+        // we have two basic cases here:
+        // 1. Delete area and pRange intersect
+        // 2. Delete area and pRange are not intersecting
+        // checking for 2 and if true skip this range
+        if(!(*itr)->Intersects(aRange))
+            continue;
+
+        // We get between 1 and 4 ranges from the difference of the first with the second
+
+        // X either Col or Row and Y then the opposite
+        // r = deleteRange, p = entry from ScRangeList
+
+        // getting exactly one range is the simple case
+        // r.aStart.X() <= p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
+        // && ( r.aStart.Y() <= p.aStart.Y() || r.aEnd.Y() >= r.aEnd.Y() )
+        if(handleOneRange( aRange, *itr ))
+            continue;
+
+        // getting two ranges
+        // r.aStart.X()
+        else if(handleTwoRanges( aRange, *itr, aNewRanges ))
+            continue;
+
+        // getting 3 ranges
+        // r.aStart.X() > p.aStart.X() && r.aEnd.X() >= p.aEnd.X()
+        // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
+        // or
+        // r.aStart.X() <= p.aStart.X() && r.aEnd.X() < p.aEnd.X()
+        // && r.aStart.Y() > p.aStart.Y() && r.aEnd.Y() < p.aEnd.Y()
+        else if(handleThreeRanges( aRange, *itr, aNewRanges ))
+            continue;
+
+        // getting 4 ranges
+        // r.aStart.X() > p.aStart.X() && r.aEnd().X() < p.aEnd.X()
+        // && r.aStart.Y() > p.aStart.Y() && r.aEnd().Y() < p.aEnd.Y()
+        else if(handleFourRanges( aRange, *itr, aNewRanges ))
+            continue;
+    }
+    for(vector<ScRange>::iterator itr = aNewRanges.begin(); itr != aNewRanges.end(); ++itr)
+        Join( *itr, false);
+}
+
 const ScRange* ScRangeList::Find( const ScAddress& rAdr ) const
 {
     vector<ScRange*>::const_iterator itr = find_if(


More information about the Libreoffice-commits mailing list