summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@erack.de>2011-08-15 15:43:02 +0200
committerEike Rathke <erack@erack.de>2011-08-16 00:45:34 +0200
commited1ecfc0c23e27db04685e39ca5f5ddb2b680017 (patch)
treef2cabcc8af530b6c18d6b6b5b0f2302170c19a15 /sc
parentfbba74ca98c1e4e2256a11139786f18c0543591e (diff)
fix ScColumns::DeleteRange() responsible for all sorts of trouble
* mark correct segments as removed / not removed * move remaining segments with the correct number of entries * preserve broadcasters and don't delete/overwrite cell entries in that case * fixes also undo/redo where cells didn't appear after redo * fixes also weird or invisible values after input on deleted cells
Diffstat (limited to 'sc')
-rw-r--r--sc/source/core/data/column3.cxx79
1 files changed, 43 insertions, 36 deletions
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 8c3b37310695..384f98fa9d5b 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -387,7 +387,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
aDelCells.reserve( nEndIndex - nStartIndex + 1 );
typedef mdds::flat_segment_tree<SCSIZE, bool> RemovedSegments_t;
- RemovedSegments_t aRemovedSegments(nStartIndex, nEndIndex + 1, false);
+ RemovedSegments_t aRemovedSegments(nStartIndex, nCount, false);
SCSIZE nFirst(nStartIndex);
// dummy replacement for old cells, to prevent that interpreter uses old cell
@@ -395,8 +395,8 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
for ( SCSIZE nIdx = nStartIndex; nIdx <= nEndIndex; ++nIdx )
{
- // all contents is deleted and cell do not contain broadcaster
- if (((nDelFlag & IDF_CONTENTS) == IDF_CONTENTS) && pItems[ nIdx ].pCell->GetBroadcaster())
+ // all content is deleted and cell does not contain broadcaster
+ if (((nDelFlag & IDF_CONTENTS) == IDF_CONTENTS) && !pItems[ nIdx ].pCell->GetBroadcaster())
{
ScBaseCell* pOldCell = pItems[ nIdx ].pCell;
if (pOldCell->GetCellType() == CELLTYPE_FORMULA)
@@ -414,46 +414,54 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
pOldCell->Delete();
}
}
- // delete some contents of the cells
+ // delete some contents of the cells, or cells with broadcaster
else
{
- // decide whether to delete the cell object according to passed flags
bool bDelete = false;
ScBaseCell* pOldCell = pItems[nIdx].pCell;
CellType eCellType = pOldCell->GetCellType();
- switch ( eCellType )
+ if ((nDelFlag & IDF_CONTENTS) == IDF_CONTENTS)
+ bDelete = true;
+ else
{
- case CELLTYPE_VALUE:
+ // decide whether to delete the cell object according to passed
+ // flags
+ switch ( eCellType )
{
- sal_uInt16 nValFlags = nDelFlag & (IDF_DATETIME|IDF_VALUE);
- // delete values and dates?
- bDelete = nValFlags == (IDF_DATETIME|IDF_VALUE);
- // if not, decide according to cell number format
- if( !bDelete && (nValFlags != 0) )
- {
- sal_uLong nIndex = (sal_uLong)((SfxUInt32Item*)GetAttr( pItems[nIdx].nRow, ATTR_VALUE_FORMAT ))->GetValue();
- short nType = pDocument->GetFormatTable()->GetType(nIndex);
- bool bIsDate = (nType == NUMBERFORMAT_DATE) || (nType == NUMBERFORMAT_TIME) || (nType == NUMBERFORMAT_DATETIME);
- bDelete = nValFlags == (bIsDate ? IDF_DATETIME : IDF_VALUE);
- }
- }
- break;
+ case CELLTYPE_VALUE:
+ {
+ sal_uInt16 nValFlags = nDelFlag & (IDF_DATETIME|IDF_VALUE);
+ // delete values and dates?
+ bDelete = nValFlags == (IDF_DATETIME|IDF_VALUE);
+ // if not, decide according to cell number format
+ if( !bDelete && (nValFlags != 0) )
+ {
+ sal_uLong nIndex = (sal_uLong)((SfxUInt32Item*)GetAttr(
+ pItems[nIdx].nRow, ATTR_VALUE_FORMAT ))->GetValue();
+ short nType = pDocument->GetFormatTable()->GetType(nIndex);
+ bool bIsDate = (nType == NUMBERFORMAT_DATE) ||
+ (nType == NUMBERFORMAT_TIME) || (nType == NUMBERFORMAT_DATETIME);
+ bDelete = nValFlags == (bIsDate ? IDF_DATETIME : IDF_VALUE);
+ }
+ }
+ break;
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- bDelete = (nDelFlag & IDF_STRING) != 0;
- break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ bDelete = (nDelFlag & IDF_STRING) != 0;
+ break;
- case CELLTYPE_FORMULA:
- bDelete = (nDelFlag & IDF_FORMULA) != 0;
- break;
+ case CELLTYPE_FORMULA:
+ bDelete = (nDelFlag & IDF_FORMULA) != 0;
+ break;
- case CELLTYPE_NOTE:
- // do note delete note cell with broadcaster
- bDelete = bDeleteNote && !pOldCell->GetBroadcaster();
- break;
+ case CELLTYPE_NOTE:
+ // do note delete note cell with broadcaster
+ bDelete = bDeleteNote && !pOldCell->GetBroadcaster();
+ break;
- default:; // added to avoid warnings
+ default:; // added to avoid warnings
+ }
}
if (bDelete)
@@ -516,7 +524,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
}
}
// there is a segment of deleted cells at the end
- if (nFirst < nEndIndex)
+ if (nFirst <= nEndIndex)
aRemovedSegments.insert_back(nFirst, nEndIndex + 1, true);
{
@@ -541,14 +549,13 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
&pItems[nStartSegment - nShift],
&pItems[nEndSegment - nShift],
(nCount - nEndSegment) * sizeof(ColEntry));
- SCSIZE const nNewShift(nEndSegment - nStartSegment);
- nShift += nNewShift;
- nCount -= nNewShift;
+ nShift += nEndSegment - nStartSegment;
}
nStartSegment = nEndSegment;
bMoveSegment = aIt->second;
++aIt;
} while (aIt != aEnd);
+ nCount -= nShift;
}
}