diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-05-15 16:09:40 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-05-20 20:13:08 -0400 |
commit | f3f0ae12f90af06f92b66017449ed4d7892a8ced (patch) | |
tree | a3ae1f32dfea00ef7f59afec77ee341d8b094d74 /sc/source/core/data/column2.cxx | |
parent | f8ed5c3ffea38b75df0a6dc44f5ee3d6da68c5ff (diff) |
Keep track of current block position when pasting a range of cells.
This avoids re-starting the search for insertion position in the cell
text attribute array, on every single cell insertion. Instead of always
searching from the first position, it starts the seaarch from the previous
insertion position.
This reduces the paste time from the previous 3.5 seconds to 1.7 seconds
on my machine.
Here is the scenario.
1) Put =A1 in B1, and leave B2 empty.
2) Select B1:B2 and copy it via Ctrl-C.
3) Select B3:B50000, and paste via Ctrl-V.
Because of the empty cells interspersing the destination range, this makes
the data array highly partitioned, which makes the position lookup very
very expensive without the position hint.
Still, I was hoping the duration would become a fraction of a second. 1.7
seconds still seems a bit too slow...
Change-Id: I7742ce7e22935b6d0e082e4569d53dbd2072c4e5
Diffstat (limited to 'sc/source/core/data/column2.cxx')
-rw-r--r-- | sc/source/core/data/column2.cxx | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 4269774d7516..7ad37625a2fc 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1474,7 +1474,43 @@ void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& r } } -void ScColumn::SetCell(SCROW nRow, ScBaseCell* pNewCell) +void ScColumn::SetCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScBaseCell* pNewCell ) +{ + bool bIsAppended = false; + if ( !maItems.empty() ) + { + if (maItems.back().nRow < nRow) + { + Append(rBlockPos, nRow, pNewCell); + bIsAppended = true; + } + } + if (!bIsAppended) + { + SCSIZE nIndex; + if (Search(nRow, nIndex)) + { + ScBaseCell* pOldCell = maItems[nIndex].pCell; + if ( pOldCell->GetCellType() == CELLTYPE_FORMULA && !pDocument->IsClipOrUndo() ) + static_cast<ScFormulaCell*>(pOldCell)->EndListeningTo( pDocument ); + pOldCell->Delete(); + maItems[nIndex].pCell = pNewCell; + } + else + { + maItems.insert(maItems.begin() + nIndex, ColEntry()); + maItems[nIndex].pCell = pNewCell; + maItems[nIndex].nRow = nRow; + } + + rBlockPos.miCellTextAttrPos = + maCellTextAttrs.set(rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + + CellStorageModified(); + } +} + +void ScColumn::SetCell( SCROW nRow, ScBaseCell* pNewCell ) { bool bIsAppended = false; if ( !maItems.empty() ) @@ -1508,6 +1544,30 @@ void ScColumn::SetCell(SCROW nRow, ScBaseCell* pNewCell) } } +void ScColumn::PostSetCell( SCROW nRow, ScBaseCell* pNewCell ) +{ + // When we insert from the Clipboard we still have wrong (old) References! + // First they are rewired in CopyBlockFromClip via UpdateReference and the + // we call StartListeningFromClip and BroadcastFromClip. + // If we insert into the Clipboard/andoDoc, we do not use a Broadcast. + // After Import we call CalcAfterLoad and in there Listening. + if ( !(pDocument->IsClipOrUndo() || pDocument->IsInsertingFromOtherDoc()) ) + { + CellType eCellType = pNewCell->GetCellType(); + if (eCellType == CELLTYPE_FORMULA) + static_cast<ScFormulaCell*>(pNewCell)->StartListeningTo(pDocument); + + if (!pDocument->IsCalcingAfterLoad()) + { + if ( eCellType == CELLTYPE_FORMULA ) + ((ScFormulaCell*)pNewCell)->SetDirty(); + else + pDocument->Broadcast( + ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab))); + } + } +} + SvtBroadcaster* ScColumn::GetBroadcaster(SCROW nRow) { return maBroadcasters.get<SvtBroadcaster*>(nRow); |