diff options
author | Eike Rathke <erack@erack.de> | 2011-08-15 15:43:02 +0200 |
---|---|---|
committer | Eike Rathke <erack@erack.de> | 2011-08-16 00:45:34 +0200 |
commit | ed1ecfc0c23e27db04685e39ca5f5ddb2b680017 (patch) | |
tree | f2cabcc8af530b6c18d6b6b5b0f2302170c19a15 /sc | |
parent | fbba74ca98c1e4e2256a11139786f18c0543591e (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.cxx | 79 |
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; } } |