Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


On 09/21/2012 01:30 PM, Kohei Yoshida wrote:
On 09/21/2012 08:12 AM, Markus Mohrhard wrote:

Please apply them in the following order:

http://cgit.freedesktop.org/libreoffice/core/commit/?id=7222a571d0d458810c1b23871f8b91491db4462d

http://cgit.freedesktop.org/libreoffice/core/commit/?id=a3c4ee1653166ee2ac1f1b9d65ff1065b6288ebc

http://cgit.freedesktop.org/libreoffice/core/commit/?id=4cf0759e7c6bd698c929a11c771d2ab03f1b9536

http://cgit.freedesktop.org/libreoffice/core/commit/?id=e6bca122176cdb2b6e822fc933f159dc3e3c8d46

http://cgit.freedesktop.org/libreoffice/core/commit/?id=7a182026fce922a9f69e8da76d46e87e7188a4e9

http://cgit.freedesktop.org/libreoffice/core/commit/?id=764e7e71038d5ae66061f44bc0cd51ce33ae96ed

http://cgit.freedesktop.org/libreoffice/core/commit/?id=1e3919f040ade5d0f7f9fa854b3ed23366080c0c

I've squashed all these plus

http://cgit.freedesktop.org/libreoffice/core/commit/?id=0e1e59057d005c9333a49ce7b2ae949a3121c55e

into a single commit. All these commits are from Markus, and I have signed-off on this, on the condition that we also backport my own change on top of it to fix several issues that I discovered and fixed during my review.

The attached 0001 patch is Markus' patch, and the 0002 patch is mine on top of it. Mine is basically a backport of

http://cgit.freedesktop.org/libreoffice/core/commit/?id=5551cd0209981f71ea5fb252b791391a6427066e

and

http://cgit.freedesktop.org/libreoffice/core/commit/?id=cb7ee824dc0b9dcc2fd466f190945de01a9d1fa5

minus the unit test piece which doesn't exist in the 3-6 branch.

Now, technically someone has to sign-off on my proposed change on top of Markus, so whoever signs off on it will have to first commit Markus' patch with my sign-off, and then commit mine.

Regards,

Kohei

--
Kohei Yoshida, LibreOffice hacker, Calc
From c431000216edad132702d5555903fb9410b7ec25 Mon Sep 17 00:00:00 2001
From: Markus Mohrhard <markus.mohrhard@googlemail.com>
Date: Fri, 31 Aug 2012 04:02:10 +0200
Subject: [PATCH 1/2] Backport various conditional formatting fixes from master.

Change-Id: I52987e957918853bcd1abd1460c6166b52454d62
Signed-off-by: Kohei Yoshida <kohei.yoshida@gmail.com>
---
 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 |  353 +++++++++++++++++++++++++++++++++++++-
 5 files changed, 385 insertions(+), 5 deletions(-)

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(
-- 
1.7.3.4

From fd5ecea20552b922f70764aec2ca6d6e77e16ed6 Mon Sep 17 00:00:00 2001
From: Kohei Yoshida <kohei.yoshida@gmail.com>
Date: Fri, 21 Sep 2012 20:39:40 -0400
Subject: [PATCH 2/2] Backported fixes for several bugs found in ScRangeList::DeleteArea().

Change-Id: I9875485008d021dd7a0605e4b7e350345d367a69
---
 sc/source/core/tool/rangelst.cxx |  444 +++++++++++++++++++++++++++-----------
 1 files changed, 318 insertions(+), 126 deletions(-)

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;
-- 
1.7.3.4


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.