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.mohrh...@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.yosh...@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.yosh...@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
_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice