[Libreoffice-commits] core.git: 2 commits - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Fri Jan 31 12:41:46 PST 2014
sc/inc/column.hxx | 5 +
sc/inc/table.hxx | 8 +
sc/source/core/data/column4.cxx | 112 ++++++++++++++++++---------
sc/source/core/data/table4.cxx | 161 +++++++++++++++++++++++++++++-----------
4 files changed, 206 insertions(+), 80 deletions(-)
New commits:
commit 571070074671bd0102422dd8a0ac1c3be6358f80
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Jan 31 15:44:00 2014 -0500
Speed up simple fill of formula cells. Vertical direction only.
Other cells could be optimized in a similar fashion, but they aren't
that slow even with the current code.
Change-Id: I0b71bf271fab68c9fba0b39463dfe3ef46dacfb0
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 69ba1af..7fefa04 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -57,6 +57,7 @@ class EditTextIterator;
struct NoteEntry;
class DocumentStreamAccess;
class CellValues;
+struct RowSpan;
}
@@ -218,6 +219,8 @@ public:
void DeleteRow( SCROW nStartRow, SCSIZE nSize );
void DeleteArea(
SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag, bool bBroadcast = true );
+ void DeleteRanges( const std::vector<sc::RowSpan>& rRanges, sal_uInt16 nDelFlag, bool bBroadcast );
+
void CopyToClip(
sc::CopyToClipContext& rCxt, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const;
void CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol);
@@ -289,6 +292,8 @@ public:
ScFormulaCell* SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
+ void CloneFormulaCell( const ScFormulaCell& rSrc, const std::vector<sc::RowSpan>& rRanges );
+
svl::SharedString GetSharedString( SCROW nRow ) const;
void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true );
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 661c38d..7a5998c 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -14,6 +14,8 @@
#include <attarray.hxx>
#include <document.hxx>
#include <cellvalues.hxx>
+#include <columnspanset.hxx>
+#include <listenercontext.hxx>
#include <svl/sharedstring.hxx>
@@ -49,6 +51,8 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
if ((nFlags & IDF_CONTENTS) != 0)
{
+ std::vector<sc::CellTextAttr> aTextAttrs(nDestSize);
+
switch (rSrcCell.meType)
{
case CELLTYPE_VALUE:
@@ -56,13 +60,18 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
std::vector<double> aVals(nDestSize, rSrcCell.mfValue);
pBlockPos->miCellPos =
maCells.set(pBlockPos->miCellPos, nRow1, aVals.begin(), aVals.end());
+ pBlockPos->miCellTextAttrPos =
+ maCellTextAttrs.set(pBlockPos->miCellTextAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
CellStorageModified();
}
break;
case CELLTYPE_STRING:
{
std::vector<svl::SharedString> aStrs(nDestSize, *rSrcCell.mpString);
- maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+ pBlockPos->miCellPos =
+ maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+ pBlockPos->miCellTextAttrPos =
+ maCellTextAttrs.set(pBlockPos->miCellTextAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
CellStorageModified();
}
break;
@@ -75,46 +84,17 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
pBlockPos->miCellPos =
maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+ pBlockPos->miCellTextAttrPos =
+ maCellTextAttrs.set(pBlockPos->miCellTextAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
CellStorageModified();
}
break;
case CELLTYPE_FORMULA:
{
- std::vector<ScFormulaCell*> aFormulas;
- ScAddress aPos(nCol, nRow1, nTab);
- aFormulas.reserve(nDestSize);
- ScFormulaCellGroupRef xGroup(new ScFormulaCellGroup);
- xGroup->setCode(*rSrcCell.mpFormula->GetCode());
- xGroup->compileCode(*pDocument, aPos, pDocument->GetGrammar());
- for (size_t i = 0; i < nDestSize; ++i)
- {
- ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, xGroup);
- if (i == 0)
- {
- xGroup->mpTopCell = pCell;
- xGroup->mnLength = nDestSize;
- }
- aFormulas.push_back(pCell);
- aPos.IncRow();
- }
-
- pBlockPos->miCellPos =
- maCells.set(pBlockPos->miCellPos, nRow1, aFormulas.begin(), aFormulas.end());
-
- // Join the top and bottom of the pasted formula cells as needed.
- sc::CellStoreType::position_type aPosObj =
- maCells.position(pBlockPos->miCellPos, nRow1);
-
- assert(aPosObj.first->type == sc::element_type_formula);
- ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
- JoinNewFormulaCell(aPosObj, *pCell);
-
- aPosObj = maCells.position(aPosObj.first, nRow2);
- assert(aPosObj.first->type == sc::element_type_formula);
- pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
- JoinNewFormulaCell(aPosObj, *pCell);
-
- CellStorageModified();
+ std::vector<sc::RowSpan> aRanges;
+ aRanges.reserve(1);
+ aRanges.push_back(sc::RowSpan(nRow1, nRow2));
+ CloneFormulaCell(*rSrcCell.mpFormula, aRanges);
}
break;
default:
@@ -228,4 +208,64 @@ void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
BroadcastCells(aRows, SC_HINT_DATACHANGED);
}
+void ScColumn::DeleteRanges( const std::vector<sc::RowSpan>& rRanges, sal_uInt16 nDelFlag, bool bBroadcast )
+{
+ std::vector<sc::RowSpan>::const_iterator itSpan = rRanges.begin(), itSpanEnd = rRanges.end();
+ for (; itSpan != itSpanEnd; ++itSpan)
+ DeleteArea(itSpan->mnRow1, itSpan->mnRow2, nDelFlag, bBroadcast);
+}
+
+void ScColumn::CloneFormulaCell( const ScFormulaCell& rSrc, const std::vector<sc::RowSpan>& rRanges )
+{
+ sc::CellStoreType::iterator itPos = maCells.begin();
+ sc::CellTextAttrStoreType::iterator itAttrPos = maCellTextAttrs.begin();
+ sc::StartListeningContext aCxt(*pDocument);
+
+ std::vector<ScFormulaCell*> aFormulas;
+ std::vector<sc::RowSpan>::const_iterator itSpan = rRanges.begin(), itSpanEnd = rRanges.end();
+ for (; itSpan != itSpanEnd; ++itSpan)
+ {
+ SCROW nRow1 = itSpan->mnRow1, nRow2 = itSpan->mnRow2;
+ size_t nLen = nRow2 - nRow1 + 1;
+ aFormulas.clear();
+ aFormulas.reserve(nLen);
+
+ ScAddress aPos(nCol, nRow1, nTab);
+ ScFormulaCellGroupRef xGroup(new ScFormulaCellGroup);
+ xGroup->setCode(*rSrc.GetCode());
+ xGroup->compileCode(*pDocument, aPos, pDocument->GetGrammar());
+ for (size_t i = 0; i < nLen; ++i, aPos.IncRow())
+ {
+ ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, xGroup);
+ if (i == 0)
+ {
+ xGroup->mpTopCell = pCell;
+ xGroup->mnLength = nLen;
+ }
+ pCell->StartListeningTo(aCxt);
+ pCell->SetDirty();
+ aFormulas.push_back(pCell);
+ }
+
+ itPos = maCells.set(itPos, nRow1, aFormulas.begin(), aFormulas.end());
+
+ // Join the top and bottom of the pasted formula cells as needed.
+ sc::CellStoreType::position_type aPosObj = maCells.position(itPos, nRow1);
+
+ assert(aPosObj.first->type == sc::element_type_formula);
+ ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
+ JoinNewFormulaCell(aPosObj, *pCell);
+
+ aPosObj = maCells.position(aPosObj.first, nRow2);
+ assert(aPosObj.first->type == sc::element_type_formula);
+ pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
+ JoinNewFormulaCell(aPosObj, *pCell);
+
+ std::vector<sc::CellTextAttr> aTextAttrs(nLen);
+ itAttrPos = maCellTextAttrs.set(itAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
+ }
+
+ CellStorageModified();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 6a21cef..3f586f5 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -60,6 +60,7 @@
#include "segmenttree.hxx"
#include "conditio.hxx"
#include "editutil.hxx"
+#include <columnspanset.hxx>
#include <math.h>
#include <boost/scoped_ptr.hpp>
@@ -1287,42 +1288,110 @@ void ScTable::FillSimple(
SCCOLROW& rCol, SCCOLROW& rRow, bool bVertical, ScProgress* pProgress, sal_uLong& rProgress )
{
bool bHidden = false;
- SCCOLROW nHiddenValid = -1;
+ SCCOLROW nHiddenLast = -1;
- switch (rSrcCell.meType)
+ if (bVertical)
{
- case CELLTYPE_FORMULA:
+ switch (rSrcCell.meType)
{
- for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ case CELLTYPE_FORMULA:
{
- if (rInner > nHiddenValid)
- bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+ SCCOLROW nRowStart = -1, nRowEnd = -1;
+ std::vector<sc::RowSpan> aSpans;
+ for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ {
+ if (rInner > nHiddenLast)
+ bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
+
+ if (bHidden)
+ {
+ if (nRowStart >= 0)
+ {
+ nRowEnd = rInner - 1;
+ aSpans.push_back(sc::RowSpan(nRowStart, nRowEnd));
+ nRowStart = -1;
+ }
+ rInner = nHiddenLast;
+ continue;
+ }
- if (bHidden)
- continue;
+ if (nRowStart < 0)
+ nRowStart = rInner;
+ }
- FillFormula(rSrcCell.mpFormula, rCol, rRow, (rInner == nIMax));
+ if (nRowStart >= 0)
+ {
+ nRowEnd = rInner - 1;
+ aSpans.push_back(sc::RowSpan(nRowStart, nRowEnd));
+ }
+
+ aCol[rCol].DeleteRanges(aSpans, IDF_CONTENTS, false);
+ aCol[rCol].CloneFormulaCell(*rSrcCell.mpFormula, aSpans);
+
+ rProgress += nIMax - nIMin + 1;
if (pProgress)
- pProgress->SetStateOnPercent(++rProgress);
+ pProgress->SetStateOnPercent(rProgress);
+ }
+ break;
+ default:
+ {
+ for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ {
+ if (rInner > nHiddenLast)
+ bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
+
+ if (bHidden)
+ {
+ rInner = nHiddenLast;
+ continue;
+ }
+
+ ScAddress aDestPos(rCol, rRow, nTab);
+ rSrcCell.commit(aCol[rCol], aDestPos.Row());
+ }
+ rProgress += nIMax - nIMin + 1;
+ if (pProgress)
+ pProgress->SetStateOnPercent(rProgress);
}
}
- break;
- default:
+ }
+ else
+ {
+ switch (rSrcCell.meType)
{
- for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ case CELLTYPE_FORMULA:
+ {
+ for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ {
+ if (rInner > nHiddenLast)
+ bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
+
+ if (bHidden)
+ continue;
+
+ FillFormula(rSrcCell.mpFormula, rCol, rRow, (rInner == nIMax));
+ if (pProgress)
+ pProgress->SetStateOnPercent(++rProgress);
+ }
+ }
+ break;
+ default:
{
- if (rInner > nHiddenValid)
- bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+ for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ {
+ if (rInner > nHiddenLast)
+ bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
- if (bHidden)
- continue;
+ if (bHidden)
+ continue;
- ScAddress aDestPos(rCol, rRow, nTab);
- rSrcCell.commit(aCol[rCol], aDestPos.Row());
+ ScAddress aDestPos(rCol, rRow, nTab);
+ rSrcCell.commit(aCol[rCol], aDestPos.Row());
+ }
+ rProgress += nIMax - nIMin + 1;
+ if (pProgress)
+ pProgress->SetStateOnPercent(rProgress);
}
- rProgress += nIMax - nIMin + 1;
- if (pProgress)
- pProgress->SetStateOnPercent(rProgress);
}
}
}
commit 777e3930a1e85b9bc97c1852b09802fc389c5e2d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Jan 31 12:34:26 2014 -0500
Move the code for "fill simple" to its own method.
Change-Id: I317f20eb4e8b6e41f12b7da872d158b859579861
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 260a736..658b4c1 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -915,6 +915,10 @@ public:
static void UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow );
private:
+ void FillSimple(
+ ScCellValue& rSrcCell, SCCOLROW& rInner, SCCOLROW nIMin, SCCOLROW nIMax,
+ SCCOLROW& rCol, SCCOLROW& rRow, bool bVertical, ScProgress* pProgress, sal_uLong& rProgress );
+
void FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd,
FillDateCmd eFillDateCmd,
@@ -990,8 +994,8 @@ private:
bool IsEmptyLine(SCROW nRow, SCCOL nStartCol, SCCOL nEndCol) const;
void IncDate(double& rVal, sal_uInt16& nDayOfMonth, double nStep, FillDateCmd eCmd);
- void FillFormula(sal_uLong& nFormulaCounter, bool bFirst, ScFormulaCell* pSrcCell,
- SCCOL nDestCol, SCROW nDestRow, bool bLast );
+ void FillFormula(
+ ScFormulaCell* pSrcCell, SCCOL nDestCol, SCROW nDestRow, bool bLast );
void UpdateInsertTabAbs(SCTAB nNewPos);
bool GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, bool bInSel,
const ScMarkData& rMark) const;
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index ca89428..6a21cef 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -427,8 +427,8 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
}
}
-void ScTable::FillFormula(sal_uLong& /* nFormulaCounter */, bool /* bFirst */, ScFormulaCell* pSrcCell,
- SCCOL nDestCol, SCROW nDestRow, bool bLast )
+void ScTable::FillFormula(
+ ScFormulaCell* pSrcCell, SCCOL nDestCol, SCROW nDestRow, bool bLast )
{
pDocument->SetNoListening( true ); // still the wrong reference
@@ -753,7 +753,6 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
nDelta = -1.0;
double nVal = 0.0;
sal_uLong nFormulaCounter = nActFormCnt;
- bool bFirst = true;
bool bGetCell = true;
sal_uInt16 nCellDigits = 0;
short nHeadNoneTail = 0;
@@ -843,7 +842,8 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
break;
case CELLTYPE_FORMULA :
- FillFormula( nFormulaCounter, bFirst, aSrcCell.mpFormula,
+ FillFormula(
+ aSrcCell.mpFormula,
static_cast<SCCOL>(nCol),
static_cast<SCROW>(nRow), (rInner == nIEnd) );
if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
@@ -870,7 +870,6 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
nDelta -= 1.0;
}
nFormulaCounter = nActFormCnt;
- bFirst = false;
}
else if (bPositive)
{
@@ -1283,6 +1282,51 @@ bool HiddenRowColumn(ScTable* pTable, SCCOLROW nRowColumn, bool bVertical, SCCOL
}
+void ScTable::FillSimple(
+ ScCellValue& rSrcCell, SCCOLROW& rInner, SCCOLROW nIMin, SCCOLROW nIMax,
+ SCCOLROW& rCol, SCCOLROW& rRow, bool bVertical, ScProgress* pProgress, sal_uLong& rProgress )
+{
+ bool bHidden = false;
+ SCCOLROW nHiddenValid = -1;
+
+ switch (rSrcCell.meType)
+ {
+ case CELLTYPE_FORMULA:
+ {
+ for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ {
+ if (rInner > nHiddenValid)
+ bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+
+ if (bHidden)
+ continue;
+
+ FillFormula(rSrcCell.mpFormula, rCol, rRow, (rInner == nIMax));
+ if (pProgress)
+ pProgress->SetStateOnPercent(++rProgress);
+ }
+ }
+ break;
+ default:
+ {
+ for (rInner = nIMin; rInner <= nIMax; ++rInner)
+ {
+ if (rInner > nHiddenValid)
+ bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+
+ if (bHidden)
+ continue;
+
+ ScAddress aDestPos(rCol, rRow, nTab);
+ rSrcCell.commit(aCol[rCol], aDestPos.Row());
+ }
+ rProgress += nIMax - nIMin + 1;
+ if (pProgress)
+ pProgress->SetStateOnPercent(rProgress);
+ }
+ }
+}
+
void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
double nStepValue, double nMaxValue, sal_uInt16 nArgMinDigits,
@@ -1449,43 +1493,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
if (eFillCmd == FILL_SIMPLE) // copy
{
- bool bHidden = false;
- SCCOLROW nHiddenValid = -1;
-
- if (eCellType == CELLTYPE_FORMULA)
- {
- bool bFirst = true;
- for (rInner = nIMin; rInner <= nIMax; rInner++)
- {
- if (rInner > nHiddenValid)
- bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
-
- if (bHidden)
- continue;
- sal_uLong nInd = nActFormCnt;
- FillFormula(nInd, bFirst, aSrcCell.mpFormula,
- static_cast<SCCOL>(nCol), nRow, (rInner == nIEnd) );
- bFirst = false;
- if(pProgress)
- pProgress->SetStateOnPercent( ++nProgress );
- }
- }
- else
- {
- for (rInner = nIMin; rInner <= nIMax; rInner++)
- {
- if (rInner > nHiddenValid)
- bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
-
- if (bHidden)
- continue;
- ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
- aSrcCell.commit(aCol[nCol], aDestPos.Row());
- }
- nProgress += nIMax - nIMin + 1;
- if(pProgress)
- pProgress->SetStateOnPercent( nProgress );
- }
+ FillSimple(aSrcCell, rInner, nIMin, nIMax, nCol, nRow, bVertical, pProgress, nProgress);
}
else if (eCellType == CELLTYPE_VALUE || eCellType == CELLTYPE_FORMULA)
{
More information about the Libreoffice-commits
mailing list