Kaydet (Commit) ff5aad0a authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Speed up pasting of single row onto multiple destination rows.

This is an extension of the earlier paste optimization of a single cell
across multiple destination cells.

Change-Id: I3a60300d3d0e11420d997bea8f7f540e948f56cc
üst 136eed0f
...@@ -54,10 +54,12 @@ class CopyFromClipContext : public ClipContextBase ...@@ -54,10 +54,12 @@ class CopyFromClipContext : public ClipContextBase
ScDocument* mpClipDoc; ScDocument* mpClipDoc;
InsertDeleteFlags mnInsertFlag; InsertDeleteFlags mnInsertFlag;
InsertDeleteFlags mnDeleteFlag; InsertDeleteFlags mnDeleteFlag;
ScCellValue maSingleCell;
std::vector<ScCellValue> maSingleCells;
std::vector<const ScPatternAttr*> maSinglePatterns;
std::vector<const ScPostIt*> maSingleNotes;
ScConditionalFormatList* mpCondFormatList; ScConditionalFormatList* mpCondFormatList;
const ScPatternAttr* mpSinglePattern;
const ScPostIt* mpSingleNote;
bool mbAsLink:1; bool mbAsLink:1;
bool mbSkipAttrForEmptyCells:1; bool mbSkipAttrForEmptyCells:1;
bool mbCloneNotes:1; bool mbCloneNotes:1;
...@@ -96,16 +98,23 @@ public: ...@@ -96,16 +98,23 @@ public:
void setDeleteFlag( InsertDeleteFlags nFlag ); void setDeleteFlag( InsertDeleteFlags nFlag );
InsertDeleteFlags getDeleteFlag() const; InsertDeleteFlags getDeleteFlag() const;
ScCellValue& getSingleCell(); /**
* Set the column size of a "single cell" row, which is used when copying
* a single row of cells in a clip doc and pasting it into multiple
* rows by replicating it.
*/
void setSingleCellColumnSize( size_t nSize );
void setCondFormatList( ScConditionalFormatList* pCondFormatList ); ScCellValue& getSingleCell( size_t nColOffset );
ScConditionalFormatList* getCondFormatList();
const ScPatternAttr* getSingleCellPattern( size_t nColOffset ) const;
void setSingleCellPattern( size_t nColOffset, const ScPatternAttr* pAttr );
const ScPatternAttr* getSingleCellPattern() const; const ScPostIt* getSingleCellNote( size_t nColOffset ) const;
void setSingleCellPattern( const ScPatternAttr* pAttr ); void setSingleCellNote( size_t nColOffset, const ScPostIt* pNote );
const ScPostIt* getSingleCellNote() const; void setCondFormatList( ScConditionalFormatList* pCondFormatList );
void setSingleCellNote( const ScPostIt* pNote ); ScConditionalFormatList* getCondFormatList();
void setTableProtected( bool b ); void setTableProtected( bool b );
bool isTableProtected() const; bool isTableProtected() const;
......
...@@ -245,7 +245,7 @@ public: ...@@ -245,7 +245,7 @@ public:
bool InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const; bool InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const;
void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol ); void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol );
void CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2 ); void CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, size_t nColOffset );
void CopyFromClip( void CopyFromClip(
sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn ); sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn );
......
...@@ -36,7 +36,7 @@ CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc, ...@@ -36,7 +36,7 @@ CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc,
mnTabStart(-1), mnTabEnd(-1), mnTabStart(-1), mnTabEnd(-1),
mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc), mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc),
mnInsertFlag(nInsertFlag), mnDeleteFlag(IDF_NONE), mnInsertFlag(nInsertFlag), mnDeleteFlag(IDF_NONE),
mpCondFormatList(NULL), mpSinglePattern(NULL), mpSingleNote(NULL), mpCondFormatList(NULL),
mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells), mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES)), mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES)),
mbTableProtected(false) mbTableProtected(false)
...@@ -106,39 +106,51 @@ InsertDeleteFlags CopyFromClipContext::getDeleteFlag() const ...@@ -106,39 +106,51 @@ InsertDeleteFlags CopyFromClipContext::getDeleteFlag() const
return mnDeleteFlag; return mnDeleteFlag;
} }
ScCellValue& CopyFromClipContext::getSingleCell() void CopyFromClipContext::setSingleCellColumnSize( size_t nSize )
{ {
return maSingleCell; maSingleCells.resize(nSize);
maSinglePatterns.resize(nSize, NULL);
maSingleNotes.resize(nSize, NULL);
} }
void CopyFromClipContext::setCondFormatList( ScConditionalFormatList* pCondFormatList ) ScCellValue& CopyFromClipContext::getSingleCell( size_t nColOffset )
{ {
mpCondFormatList = pCondFormatList; assert(nColOffset < maSingleCells.size());
return maSingleCells[nColOffset];
} }
ScConditionalFormatList* CopyFromClipContext::getCondFormatList() const ScPatternAttr* CopyFromClipContext::getSingleCellPattern( size_t nColOffset ) const
{ {
return mpCondFormatList; assert(nColOffset < maSinglePatterns.size());
return maSinglePatterns[nColOffset];
} }
const ScPatternAttr* CopyFromClipContext::getSingleCellPattern() const void CopyFromClipContext::setSingleCellPattern( size_t nColOffset, const ScPatternAttr* pAttr )
{ {
return mpSinglePattern; assert(nColOffset < maSinglePatterns.size());
maSinglePatterns[nColOffset] = pAttr;
} }
void CopyFromClipContext::setSingleCellPattern( const ScPatternAttr* pAttr ) const ScPostIt* CopyFromClipContext::getSingleCellNote( size_t nColOffset ) const
{ {
mpSinglePattern = pAttr; assert(nColOffset < maSingleNotes.size());
return maSingleNotes[nColOffset];
} }
const ScPostIt* CopyFromClipContext::getSingleCellNote() const void CopyFromClipContext::setSingleCellNote( size_t nColOffset, const ScPostIt* pNote )
{ {
return mpSingleNote; assert(nColOffset < maSingleNotes.size());
maSingleNotes[nColOffset] = pNote;
} }
void CopyFromClipContext::setSingleCellNote( const ScPostIt* pNote ) void CopyFromClipContext::setCondFormatList( ScConditionalFormatList* pCondFormatList )
{ {
mpSingleNote = pNote; mpCondFormatList = pCondFormatList;
}
ScConditionalFormatList* CopyFromClipContext::getCondFormatList()
{
return mpCondFormatList;
} }
void CopyFromClipContext::setTableProtected( bool b ) void CopyFromClipContext::setTableProtected( bool b )
......
...@@ -138,7 +138,7 @@ void ScColumn::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const Sc ...@@ -138,7 +138,7 @@ void ScColumn::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const Sc
BroadcastCells(aDeletedRows, SC_HINT_DATACHANGED); BroadcastCells(aDeletedRows, SC_HINT_DATACHANGED);
} }
void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2 ) void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, size_t nColOffset )
{ {
assert(nRow1 <= nRow2); assert(nRow1 <= nRow2);
...@@ -147,7 +147,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, ...@@ -147,7 +147,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
if (!pBlockPos) if (!pBlockPos)
return; return;
ScCellValue& rSrcCell = rCxt.getSingleCell(); ScCellValue& rSrcCell = rCxt.getSingleCell(nColOffset);
InsertDeleteFlags nFlags = rCxt.getInsertFlag(); InsertDeleteFlags nFlags = rCxt.getInsertFlag();
...@@ -155,7 +155,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, ...@@ -155,7 +155,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
{ {
if (!rCxt.isSkipAttrForEmptyCells() || rSrcCell.meType != CELLTYPE_NONE) if (!rCxt.isSkipAttrForEmptyCells() || rSrcCell.meType != CELLTYPE_NONE)
{ {
const ScPatternAttr* pAttr = rCxt.getSingleCellPattern(); const ScPatternAttr* pAttr = rCxt.getSingleCellPattern(nColOffset);
pAttrArray->SetPatternArea(nRow1, nRow2, pAttr, true); pAttrArray->SetPatternArea(nRow1, nRow2, pAttr, true);
} }
} }
...@@ -221,7 +221,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, ...@@ -221,7 +221,7 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
} }
} }
const ScPostIt* pNote = rCxt.getSingleCellNote(); const ScPostIt* pNote = rCxt.getSingleCellNote(nColOffset);
if (pNote && (nFlags & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE) if (pNote && (nFlags & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE)
{ {
// Duplicate the cell note over the whole pasted range. // Duplicate the cell note over the whole pasted range.
......
...@@ -70,22 +70,41 @@ bool ScDocument::CopyOneCellFromClip( ...@@ -70,22 +70,41 @@ bool ScDocument::CopyOneCellFromClip(
return false; return false;
ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange(); ScRange aClipRange = pClipDoc->GetClipParam().getWholeRange();
if (aClipRange.aStart != aClipRange.aEnd) if (aClipRange.aStart.Row() != aClipRange.aEnd.Row())
// The source is not really a single cell. Bail out. // The source is not really a single row. Bail out.
return false;
SCCOL nSrcColSize = aClipRange.aEnd.Col() - aClipRange.aStart.Col() + 1;
SCCOL nDestColSize = nCol2 - nCol1 + 1;
if (nDestColSize < nSrcColSize)
return false; return false;
ScAddress aSrcPos = aClipRange.aStart; ScAddress aSrcPos = aClipRange.aStart;
if (pClipDoc->IsMerged(aSrcPos))
for (SCCOL nCol = aClipRange.aStart.Col(); nCol <= aClipRange.aEnd.Col(); ++nCol)
{
ScAddress aTestPos = aSrcPos;
aTestPos.SetCol(nCol);
if (pClipDoc->IsMerged(aTestPos))
// We don't handle merged source cell for this. // We don't handle merged source cell for this.
return false; return false;
}
ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab()); ScTable* pSrcTab = pClipDoc->FetchTable(aSrcPos.Tab());
if (!pSrcTab) if (!pSrcTab)
return false; return false;
ScCellValue& rSrcCell = rCxt.getSingleCell(); rCxt.setSingleCellColumnSize(nSrcColSize);
for (SCCOL nColOffset = 0; nColOffset < nSrcColSize; ++nColOffset, aSrcPos.IncCol())
{
const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos); const ScPatternAttr* pAttr = pClipDoc->GetPattern(aSrcPos);
rCxt.setSingleCellPattern(pAttr); rCxt.setSingleCellPattern(nColOffset, pAttr);
if ((rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE)
rCxt.setSingleCellNote(nColOffset, pClipDoc->GetNote(aSrcPos));
ScCellValue& rSrcCell = rCxt.getSingleCell(nColOffset);
if (rCxt.isAsLink()) if (rCxt.isAsLink())
{ {
ScSingleRefData aRef; ScSingleRefData aRef;
...@@ -98,7 +117,7 @@ bool ScDocument::CopyOneCellFromClip( ...@@ -98,7 +117,7 @@ bool ScDocument::CopyOneCellFromClip(
} }
else else
{ {
rSrcCell.set(pClipDoc->GetRefCellValue(aSrcPos)); rSrcCell.assign(*pClipDoc, aSrcPos);
// Check the paste flag to see whether we want to paste this cell. If the // Check the paste flag to see whether we want to paste this cell. If the
// flag says we don't want to paste this cell, we'll return with true. // flag says we don't want to paste this cell, we'll return with true.
...@@ -202,9 +221,7 @@ bool ScDocument::CopyOneCellFromClip( ...@@ -202,9 +221,7 @@ bool ScDocument::CopyOneCellFromClip(
rSrcCell.clear(); rSrcCell.clear();
} }
} }
}
if ((rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES)) != IDF_NONE)
rCxt.setSingleCellNote(pClipDoc->GetNote(aSrcPos));
// All good. Proceed with the pasting. // All good. Proceed with the pasting.
......
...@@ -55,8 +55,16 @@ void ScTable::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScT ...@@ -55,8 +55,16 @@ void ScTable::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScT
void ScTable::CopyOneCellFromClip( void ScTable::CopyOneCellFromClip(
sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
{ {
ScRange aSrcRange = rCxt.getClipDoc()->GetClipParam().getWholeRange();
SCCOL nSrcColSize = aSrcRange.aEnd.Col() - aSrcRange.aStart.Col() + 1;
for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
aCol[nCol].CopyOneCellFromClip(rCxt, nRow1, nRow2); {
SCCOL nColOffset = nCol - nCol1;
nColOffset = nColOffset % nSrcColSize;
assert(nColOffset >= 0);
aCol[nCol].CopyOneCellFromClip(rCxt, nRow1, nRow2, nColOffset);
}
} }
void ScTable::SetValues( SCCOL nCol, SCROW nRow, const std::vector<double>& rVals ) void ScTable::SetValues( SCCOL nCol, SCROW nRow, const std::vector<double>& rVals )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment