summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@erack.de>2011-08-23 23:50:08 +0200
committerEike Rathke <erack@erack.de>2011-08-24 00:01:23 +0200
commitde247b8805d3e60d2181ac6369b07f0a494cd1b6 (patch)
tree9eb440f0ab80054185597c815759cf407300c607 /sc
parent61aff182ab78af4cdd4e3d4d2b5e1b0872cb27f9 (diff)
adapt to unused memory correctly
* ScColumn::DeleteRange() still failed in a case when cells of the very last part of memory were removed that did not encompass the entire range passed and nCount wasn't decremented as a result. Refactored that loop over RemovedSegments.
Diffstat (limited to 'sc')
-rw-r--r--sc/source/core/data/column3.cxx48
1 files changed, 29 insertions, 19 deletions
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 384f98fa9d5b..8e8037a5914c 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -530,33 +530,43 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
{
RemovedSegments_t::const_iterator aIt(aRemovedSegments.begin());
RemovedSegments_t::const_iterator aEnd(aRemovedSegments.end());
- if (aIt != aEnd)
+ // The indexes in aRemovedSegments denote cell positions in the
+ // original array. But as we are shifting it from the left, we have
+ // to compensate for already performed shifts for latter segments.
+ // TODO: use reverse iterators instead
+ SCSIZE nShift(0);
+ SCSIZE nStartSegment(nStartIndex);
+ bool bRemoved = false;
+ while (aIt != aEnd)
{
- SCSIZE nStartSegment(aIt->first);
- bool bMoveSegment(aIt->second);
- // The indexes in aRemovedSegments denote cell positions in the
- // original array. But as we are shifting it from the left, we have
- // to compensate for already performed shifts for latter segments.
- // TODO: use reverse iterators instead
- SCSIZE nShift(0);
- ++aIt;
- do
- {
- SCSIZE const nEndSegment(aIt->first);
- if (bMoveSegment)
- {
+ if (aIt->second)
+ { // this segment removed
+ if (!bRemoved)
+ nStartSegment = aIt->first;
+ // The first of removes in a row sets start (they should be
+ // alternating removed/notremoved anyway).
+ bRemoved = true;
+ }
+ else
+ { // this segment not removed
+ if (bRemoved)
+ { // previous segment(s) removed, move tail
+ SCSIZE const nEndSegment(aIt->first);
memmove(
&pItems[nStartSegment - nShift],
&pItems[nEndSegment - nShift],
(nCount - nEndSegment) * sizeof(ColEntry));
nShift += nEndSegment - nStartSegment;
+ bRemoved = false;
}
- nStartSegment = nEndSegment;
- bMoveSegment = aIt->second;
- ++aIt;
- } while (aIt != aEnd);
- nCount -= nShift;
+ }
+ ++aIt;
}
+ // The last removed segment up to nCount is discarded, there's nothing
+ // following to be moved.
+ if (bRemoved)
+ nShift += nCount - nStartSegment;
+ nCount -= nShift;
}
// *** delete all formula cells ***