[Libreoffice-commits] .: sc/source

Eike Rathke erack at kemper.freedesktop.org
Mon Aug 15 15:45:55 PDT 2011


 sc/source/core/data/column3.cxx |   79 +++++++++++++++++++++-------------------
 1 file changed, 43 insertions(+), 36 deletions(-)

New commits:
commit ed1ecfc0c23e27db04685e39ca5f5ddb2b680017
Author: Eike Rathke <erack at erack.de>
Date:   Mon Aug 15 15:43:02 2011 +0200

    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

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 8c3b373..384f98f 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;
         }
     }
 


More information about the Libreoffice-commits mailing list