[Libreoffice-commits] core.git: Branch 'feature/perfwork5' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Thu Nov 13 17:18:40 PST 2014
sc/inc/column.hxx | 10 +++--
sc/inc/document.hxx | 15 +++++--
sc/inc/table.hxx | 9 +++-
sc/source/core/data/column.cxx | 23 +++++++++++
sc/source/core/data/column3.cxx | 17 +++++---
sc/source/core/data/document.cxx | 77 ++++++++++++++++++++++++++++++---------
sc/source/core/data/table2.cxx | 12 +++---
7 files changed, 125 insertions(+), 38 deletions(-)
New commits:
commit 32624ea130d2ad066c187dace9a884e48c885423
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Thu Nov 13 20:14:27 2014 -0500
Reduce duplicate broadcasting done when pasting a range of cells from clip.
We do pasting from clip in 2 steps: 1) delete the destination range, then
2) paste the content onto the destination range. The old code would broadcast
both during 1) and 2). This change consolidates them and do broadcasting
only once at the end, and also avoids broadcasting the same cell twice,
which the old code sometimes did.
Change-Id: Ic524c2b70888ce158619d99cbfb55dea85870497
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d1ec1de..4e8bb00 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -230,8 +230,11 @@ public:
bool TestInsertRow( SCROW nStartRow, SCSIZE nSize ) const;
void InsertRow( SCROW nStartRow, SCSIZE nSize );
void DeleteRow( SCROW nStartRow, SCSIZE nSize );
+
void DeleteArea(
- SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag, bool bBroadcast = true );
+ SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag,
+ bool bBroadcast = true, sc::ColumnSpanSet* pBroadcastSpans = NULL );
+
void DeleteRanges( const std::vector<sc::RowSpan>& rRanges, InsertDeleteFlags nDelFlag, bool bBroadcast );
void CopyToClip(
@@ -347,7 +350,8 @@ public:
bool IsFormulaDirty( SCROW nRow ) const;
void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
- void SetDirty( SCROW nRow1, SCROW nRow2 );
+ void BroadcastInArea( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans );
+ void SetDirty( SCROW nRow1, SCROW nRow2 );
void SetDirtyVar();
void SetDirtyAfterLoad();
void SetTableOpDirty( const ScRange& );
@@ -644,7 +648,7 @@ private:
void DeleteCells(
sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nDelFlag,
- std::vector<SCROW>& rDeleted );
+ std::vector<SCROW>& rDeleted, sc::ColumnSpanSet* pDeletedSpans = NULL );
/**
* Get all non-grouped formula cells and formula cell groups in the whole
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 3974b47..9f6ab2c 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1204,8 +1204,11 @@ public:
const ScMarkData& rMark );
void DeleteObjectsInSelection( const ScMarkData& rMark );
- void DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
- const ScMarkData& rMark, InsertDeleteFlags nDelFlag);
+ void DeleteArea(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
+ InsertDeleteFlags nDelFlag, bool bBroadcast = true,
+ sc::ColumnSpanSet* pBroadcastSpans = NULL );
+
SC_DLLPUBLIC void DeleteAreaTab(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCTAB nTab, InsertDeleteFlags nDelFlag);
void DeleteAreaTab(const ScRange& rRange, InsertDeleteFlags nDelFlag);
@@ -1253,9 +1256,11 @@ public:
void StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
SCCOL nCol2, SCROW nRow2,
const ScMarkData& rMark, InsertDeleteFlags nInsFlag );
- void BroadcastFromClip( SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2,
- const ScMarkData& rMark, InsertDeleteFlags nInsFlag );
+
+ void BroadcastFromClip(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
+ InsertDeleteFlags nInsFlag, sc::ColumnSpanSet& rBroadcastSpans );
+
/** If pDestRanges is given it overrides rDestRange, rDestRange in this
case is the overall encompassing range. */
void CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMark,
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 0b5adfa..5a6f015 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -411,7 +411,10 @@ public:
void DeleteCol(
const sc::ColumnSet& rRegroupCols, SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE nSize, bool* pUndoOutline = NULL );
- void DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag);
+ void DeleteArea(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag,
+ bool bBroadcast = true, sc::ColumnSpanSet* pBroadcastSpans = NULL );
+
void CopyToClip( sc::CopyToClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable* pTable );
void CopyToClip( sc::CopyToClipContext& rCxt, const ScRangeList& rRanges, ScTable* pTable );
@@ -435,8 +438,8 @@ public:
void StartListeningInArea(
sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
- void BroadcastInArea( SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2 );
+ void BroadcastInArea(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans );
void CopyToTable(
sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 9aa3532..9eb2358 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2660,6 +2660,18 @@ public:
maValueRanges.getRows(aRows);
mrColumn.BroadcastCells(aRows, SC_HINT_DATACHANGED);
}
+
+ void fillBroadcastSpans( sc::ColumnSpanSet& rBroadcastSpans ) const
+ {
+ SCCOL nCol = mrColumn.GetCol();
+ SCTAB nTab = mrColumn.GetTab();
+ sc::SingleColumnSpanSet::SpansType aSpans;
+ maValueRanges.getSpans(aSpans);
+
+ sc::SingleColumnSpanSet::SpansType::const_iterator it = aSpans.begin(), itEnd = aSpans.end();
+ for (; it != itEnd; ++it)
+ rBroadcastSpans.set(nTab, nCol, it->mnRow1, it->mnRow2, true);
+ }
};
class SetTableOpDirtyOnRangeHandler
@@ -3032,6 +3044,17 @@ void ScColumn::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
sc::ProcessFormula(maCells, aFunc);
}
+void ScColumn::BroadcastInArea( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans )
+{
+ // Set all formula cells in the range dirty, and pick up all non-formula
+ // cells for later broadcasting. We don't broadcast here.
+ sc::AutoCalcSwitch aSwitch(*pDocument, false);
+
+ SetDirtyOnRangeHandler aHdl(*this);
+ sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl, aHdl);
+ aHdl.fillBroadcastSpans(rBroadcastSpans);
+}
+
void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2 )
{
// broadcasts everything within the range, with FormulaTracking
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index f3c7a5a..73c0311 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -559,6 +559,7 @@ class EmptyCells
{
ScColumn& mrColumn;
sc::ColumnBlockPosition& mrPos;
+ sc::ColumnSpanSet* mpCellSpans;
void splitFormulaGrouping(const sc::CellStoreType::position_type& rPos)
{
@@ -570,8 +571,8 @@ class EmptyCells
}
public:
- EmptyCells(sc::ColumnBlockPosition& rPos, ScColumn& rColumn) :
- mrColumn(rColumn), mrPos(rPos) {}
+ EmptyCells( sc::ColumnBlockPosition& rPos, ScColumn& rColumn, sc::ColumnSpanSet* pCellSpans ) :
+ mrColumn(rColumn), mrPos(rPos), mpCellSpans(pCellSpans) {}
void operator() (const sc::RowSpan& rSpan)
{
@@ -586,6 +587,9 @@ public:
mrPos.miCellPos = rCells.set_empty(mrPos.miCellPos, rSpan.mnRow1, rSpan.mnRow2);
mrPos.miCellTextAttrPos = mrColumn.GetCellAttrStore().set_empty(mrPos.miCellTextAttrPos, rSpan.mnRow1, rSpan.mnRow2);
+
+ if (mpCellSpans)
+ mpCellSpans->set(mrColumn.GetTab(), mrColumn.GetCol(), rSpan.mnRow1, rSpan.mnRow2, true);
}
};
@@ -593,7 +597,7 @@ public:
void ScColumn::DeleteCells(
sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nDelFlag,
- std::vector<SCROW>& rDeleted )
+ std::vector<SCROW>& rDeleted, sc::ColumnSpanSet* pDeletedSpans )
{
// Determine which cells to delete based on the deletion flags.
DeleteAreaHandler aFunc(*pDocument, nDelFlag);
@@ -610,12 +614,13 @@ void ScColumn::DeleteCells(
aFunc.getSpans().getSpans(aSpans);
// Delete the cells for real.
- std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(rBlockPos, *this));
+ std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(rBlockPos, *this, pDeletedSpans));
CellStorageModified();
}
void ScColumn::DeleteArea(
- SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag, bool bBroadcast )
+ SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag, bool bBroadcast,
+ sc::ColumnSpanSet* pBroadcastSpans )
{
InsertDeleteFlags nContMask = IDF_CONTENTS;
// IDF_NOCAPTIONS needs to be passed too, if IDF_NOTE is set
@@ -629,7 +634,7 @@ void ScColumn::DeleteArea(
InitBlockPosition(aBlockPos);
if (!IsEmptyData() && nContFlag)
- DeleteCells(aBlockPos, nStartRow, nEndRow, nDelFlag, aDeletedRows);
+ DeleteCells(aBlockPos, nStartRow, nEndRow, nDelFlag, aDeletedRows, pBroadcastSpans);
if (nDelFlag & IDF_NOTE)
DeleteCellNotes(aBlockPos, nStartRow, nEndRow);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index b3a3fc1..57d2b26 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1761,19 +1761,19 @@ void ScDocument::FitBlock( const ScRange& rOld, const ScRange& rNew, bool bClear
}
}
-void ScDocument::DeleteArea(SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2,
- const ScMarkData& rMark, InsertDeleteFlags nDelFlag)
+void ScDocument::DeleteArea(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
+ InsertDeleteFlags nDelFlag, bool bBroadcast, sc::ColumnSpanSet* pBroadcastSpans )
{
+ sc::AutoCalcSwitch aACSwitch(*this, false);
+
PutInOrder( nCol1, nCol2 );
PutInOrder( nRow1, nRow2 );
- bool bOldAutoCalc = GetAutoCalc();
- SetAutoCalc( false ); // avoid multiple calculations
for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); i++)
if (maTabs[i])
if ( rMark.GetTableSelect(i) || bIsUndo )
- maTabs[i]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag);
- SetAutoCalc( bOldAutoCalc );
+ maTabs[i]->DeleteArea(nCol1, nRow1, nCol2, nRow2, nDelFlag, bBroadcast, pBroadcastSpans);
+
}
void ScDocument::DeleteAreaTab(SCCOL nCol1, SCROW nRow1,
@@ -2429,9 +2429,9 @@ void ScDocument::StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
}
}
-void ScDocument::BroadcastFromClip( SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2,
- const ScMarkData& rMark, InsertDeleteFlags nInsFlag )
+void ScDocument::BroadcastFromClip(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
+ InsertDeleteFlags nInsFlag, sc::ColumnSpanSet& rBroadcastSpans )
{
if (nInsFlag & IDF_CONTENTS)
{
@@ -2440,7 +2440,7 @@ void ScDocument::BroadcastFromClip( SCCOL nCol1, SCROW nRow1,
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd && *itr < nMax; ++itr)
if (maTabs[*itr])
- maTabs[*itr]->BroadcastInArea( nCol1, nRow1, nCol2, nRow2 );
+ maTabs[*itr]->BroadcastInArea(nCol1, nRow1, nCol2, nRow2, rBroadcastSpans);
}
}
@@ -2584,6 +2584,39 @@ void ScDocument::CopyNonFilteredFromClip(
rClipStartRow = nSourceRow;
}
+namespace {
+
+class BroadcastAction : public sc::ColumnSpanSet::ColumnAction
+{
+ ScDocument& mrDoc;
+ ScColumn* mpCol;
+ std::vector<SCROW> maRows;
+
+public:
+ BroadcastAction( ScDocument& rDoc ) : mrDoc(rDoc), mpCol(NULL) {}
+
+ virtual void startColumn( ScColumn* pCol ) SAL_OVERRIDE
+ {
+ mpCol = pCol;
+ }
+
+ virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal ) SAL_OVERRIDE
+ {
+ if (!bVal)
+ return;
+
+ assert(mpCol);
+ maRows.clear();
+ maRows.reserve(nRow2-nRow1+1);
+ for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+ maRows.push_back(nRow);
+
+ mpCol->BroadcastCells(maRows, SC_HINT_DATACHANGED);
+ };
+};
+
+}
+
void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMark,
InsertDeleteFlags nInsFlag,
ScDocument* pRefUndoDoc, ScDocument* pClipDoc, bool bResetCut,
@@ -2667,6 +2700,8 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
bInsertingFromOtherDoc = true; // kein Broadcast/Listener aufbauen bei Insert
+ sc::ColumnSpanSet aBroadcastSpans(false);
+
SCCOL nClipStartCol = aClipRange.aStart.Col();
SCROW nClipStartRow = aClipRange.aStart.Row();
SCROW nClipEndRow = aClipRange.aEnd.Row();
@@ -2685,7 +2720,7 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
DeleteBeforeCopyFromClip(aCxt, rMark);
}
else
- DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag);
+ DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag, false, &aBroadcastSpans);
if (CopyOneCellFromClip(aCxt, nCol1, nRow1, nCol2, nRow2))
continue;
@@ -2785,7 +2820,14 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
// Listener aufbauen nachdem alles inserted wurde
StartListeningFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
// nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
- BroadcastFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag );
+ BroadcastFromClip(nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag, aBroadcastSpans);
+
+ {
+ ScBulkBroadcast aBulkBroadcast( GetBASM());
+ BroadcastAction aAction(*this);
+ aBroadcastSpans.executeColumnAction(*this, aAction);
+ }
+
if (bResetCut)
pClipDoc->GetClipParam().mbCutMode = false;
}
@@ -2815,6 +2857,8 @@ void ScDocument::CopyMultiRangeFromClip(
SCROW nRow1 = rDestPos.Row();
ScClipParam& rClipParam = pClipDoc->GetClipParam();
+ sc::ColumnSpanSet aBroadcastSpans(false);
+
if (!bSkipAttrForEmpty)
{
// Do the deletion first.
@@ -2822,7 +2866,7 @@ void ScDocument::CopyMultiRangeFromClip(
SCCOL nColSize = rClipParam.getPasteColSize();
SCROW nRowSize = rClipParam.getPasteRowSize();
- DeleteArea(nCol1, nRow1, nCol1+nColSize-1, nRow1+nRowSize-1, rMark, nDelFlag);
+ DeleteArea(nCol1, nRow1, nCol1+nColSize-1, nRow1+nRowSize-1, rMark, nDelFlag, false, &aBroadcastSpans);
}
sc::CopyFromClipContext aCxt(*this, NULL, pClipDoc, nInsFlag, bAsLink, bSkipAttrForEmpty);
@@ -2861,8 +2905,9 @@ void ScDocument::CopyMultiRangeFromClip(
StartListeningFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
// nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden
- BroadcastFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(),
- aDestRange.aEnd.Col(), aDestRange.aEnd.Row(), rMark, nInsFlag );
+ BroadcastFromClip(
+ aDestRange.aStart.Col(), aDestRange.aStart.Row(), aDestRange.aEnd.Col(), aDestRange.aEnd.Row(),
+ rMark, nInsFlag, aBroadcastSpans);
if (bResetCut)
pClipDoc->GetClipParam().mbCutMode = false;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 381d32b..1d3bad4 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -410,7 +410,9 @@ void ScTable::DeleteCol(
SetStreamValid(false);
}
-void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag)
+void ScTable::DeleteArea(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, InsertDeleteFlags nDelFlag,
+ bool bBroadcast, sc::ColumnSpanSet* pBroadcastSpans )
{
if (nCol2 > MAXCOL) nCol2 = MAXCOL;
if (nRow2 > MAXROW) nRow2 = MAXROW;
@@ -419,7 +421,7 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, Ins
{ // scope for bulk broadcast
ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM());
for (SCCOL i = nCol1; i <= nCol2; i++)
- aCol[i].DeleteArea(nRow1, nRow2, nDelFlag);
+ aCol[i].DeleteArea(nRow1, nRow2, nDelFlag, bBroadcast, pBroadcastSpans);
}
// Zellschutz auf geschuetzter Tabelle nicht setzen
@@ -1047,14 +1049,14 @@ void ScTable::StartNeededListeners()
aCol[i].StartNeededListeners();
}
-void ScTable::BroadcastInArea( SCCOL nCol1, SCROW nRow1,
- SCCOL nCol2, SCROW nRow2 )
+void ScTable::BroadcastInArea(
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans )
{
if (nCol2 > MAXCOL) nCol2 = MAXCOL;
if (nRow2 > MAXROW) nRow2 = MAXROW;
if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
for (SCCOL i = nCol1; i <= nCol2; i++)
- aCol[i].SetDirty(nRow1, nRow2);
+ aCol[i].BroadcastInArea(nRow1, nRow2, rBroadcastSpans);
}
void ScTable::StartListeningInArea(
More information about the Libreoffice-commits
mailing list