Kaydet (Commit) 1bfbe2a4 authored tarafından Dennis Francis's avatar Dennis Francis Kaydeden (comit) Eike Rathke

tdf#99938 : Allow batch of formula-cells to be written...

using a single undo document from ScMovingAverageDialog
rather than write tons of formula-cells to the document
one by one thus creating that many number of undo docs
unnecessarily.

Change-Id: I2528e0ab47f83e0c5ea40c73d00db5af14f656e0
Reviewed-on: https://gerrit.libreoffice.org/71823
Tested-by: Jenkins
Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
üst 6b2cff82
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <vector> #include <vector>
class ScColumn; class ScColumn;
class ScFormulaCell;
namespace svl { namespace svl {
...@@ -63,6 +64,7 @@ public: ...@@ -63,6 +64,7 @@ public:
void swapNonEmpty( ScColumn& rCol ); void swapNonEmpty( ScColumn& rCol );
void assign( const std::vector<double>& rVals ); void assign( const std::vector<double>& rVals );
void assign( const std::vector<ScFormulaCell*>& rVals );
size_t size() const; size_t size() const;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <memory> #include <memory>
#include <cellvalues.hxx> #include <cellvalues.hxx>
#include <column.hxx> #include <column.hxx>
#include <formulacell.hxx>
#include <cassert> #include <cassert>
...@@ -98,6 +99,25 @@ void CellValues::assign( const std::vector<double>& rVals ) ...@@ -98,6 +99,25 @@ void CellValues::assign( const std::vector<double>& rVals )
mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end()); mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
} }
void CellValues::assign( const std::vector<ScFormulaCell*>& rVals )
{
std::vector<ScFormulaCell*> aCopyVals(rVals.size());
size_t nIdx = 0;
for (const auto* pCell : rVals)
{
aCopyVals[nIdx] = pCell->Clone();
++nIdx;
}
mpImpl->maCells.resize(aCopyVals.size());
mpImpl->maCells.set(0, aCopyVals.begin(), aCopyVals.end());
// Set default text attributes.
std::vector<CellTextAttr> aDefaults(rVals.size(), CellTextAttr());
mpImpl->maCellTextAttrs.resize(rVals.size());
mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
}
size_t CellValues::size() const size_t CellValues::size() const
{ {
assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size()); assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
...@@ -154,7 +174,7 @@ void CellValues::copyCellsTo( ScColumn& rCol, SCROW nRow ) const ...@@ -154,7 +174,7 @@ void CellValues::copyCellsTo( ScColumn& rCol, SCROW nRow ) const
const CellStoreType& rSrc = mpImpl->maCells; const CellStoreType& rSrc = mpImpl->maCells;
// Caller must ensure the destination is long enough. // Caller must ensure the destination is long enough.
assert(rSrc.size() + static_cast<size_t>(nRow) < rDest.size()); assert(rSrc.size() + static_cast<size_t>(nRow) <= rDest.size());
SCROW nCurRow = nRow; SCROW nCurRow = nRow;
CellStoreType::iterator itPos = rDest.begin(); CellStoreType::iterator itPos = rDest.begin();
...@@ -219,7 +239,7 @@ void CellValues::copyCellTextAttrsTo( ScColumn& rCol, SCROW nRow ) const ...@@ -219,7 +239,7 @@ void CellValues::copyCellTextAttrsTo( ScColumn& rCol, SCROW nRow ) const
const CellTextAttrStoreType& rSrc = mpImpl->maCellTextAttrs; const CellTextAttrStoreType& rSrc = mpImpl->maCellTextAttrs;
// Caller must ensure the destination is long enough. // Caller must ensure the destination is long enough.
assert(rSrc.size() + static_cast<size_t>(nRow) < rDest.size()); assert(rSrc.size() + static_cast<size_t>(nRow) <= rDest.size());
SCROW nCurRow = nRow; SCROW nCurRow = nRow;
CellTextAttrStoreType::iterator itPos = rDest.begin(); CellTextAttrStoreType::iterator itPos = rDest.begin();
......
...@@ -75,6 +75,7 @@ ScRange ScMovingAverageDialog::ApplyOutput(ScDocShell* pDocShell) ...@@ -75,6 +75,7 @@ ScRange ScMovingAverageDialog::ApplyOutput(ScDocShell* pDocShell)
output.nextRow(); output.nextRow();
DataCellIterator aDataCellIterator = pIterator->iterateCells(); DataCellIterator aDataCellIterator = pIterator->iterateCells();
std::vector<OUString> aFormulas;
for (; aDataCellIterator.hasNext(); aDataCellIterator.next()) for (; aDataCellIterator.hasNext(); aDataCellIterator.next())
{ {
...@@ -98,14 +99,15 @@ ScRange ScMovingAverageDialog::ApplyOutput(ScDocShell* pDocShell) ...@@ -98,14 +99,15 @@ ScRange ScMovingAverageDialog::ApplyOutput(ScDocShell* pDocShell)
{ {
aTemplate.setTemplate("=AVERAGE(%RANGE%)"); aTemplate.setTemplate("=AVERAGE(%RANGE%)");
aTemplate.applyRange("%RANGE%", ScRange(aIntervalStart, aIntervalEnd)); aTemplate.applyRange("%RANGE%", ScRange(aIntervalStart, aIntervalEnd));
output.writeFormula(aTemplate.getTemplate()); aFormulas.push_back(aTemplate.getTemplate());
} }
else else
{ {
output.writeFormula("=#N/A"); aFormulas.push_back("=#N/A");
} }
output.nextRow();
} }
output.writeFormulas(aFormulas);
output.nextColumn(); output.nextColumn();
} }
return ScRange(output.mMinimumAddress, output.mMaximumAddress); return ScRange(output.mMinimumAddress, output.mMaximumAddress);
......
...@@ -163,6 +163,28 @@ void AddressWalkerWriter::writeFormula(const OUString& aFormula) ...@@ -163,6 +163,28 @@ void AddressWalkerWriter::writeFormula(const OUString& aFormula)
new ScFormulaCell(mpDocument, mCurrentAddress, aFormula, meGrammar), true); new ScFormulaCell(mpDocument, mCurrentAddress, aFormula, meGrammar), true);
} }
void AddressWalkerWriter::writeFormulas(const std::vector<OUString>& rFormulas)
{
size_t nLength = rFormulas.size();
if (!nLength)
return;
const size_t nMaxLen = MAXROW - mCurrentAddress.Row() + 1;
// If not done already, trim the length to fit.
if (nLength > nMaxLen)
nLength = nMaxLen;
std::vector<ScFormulaCell*> aFormulaCells(nLength);
ScAddress aAddr(mCurrentAddress);
for (size_t nIdx = 0; nIdx < nLength; ++nIdx)
{
aFormulaCells[nIdx] = new ScFormulaCell(mpDocument, aAddr, rFormulas[nIdx], meGrammar);
aAddr.IncRow(1);
}
mpDocShell->GetDocFunc().SetFormulaCells(mCurrentAddress, aFormulaCells, true);
}
void AddressWalkerWriter::writeMatrixFormula(const OUString& aFormula, SCCOL nCols, SCROW nRows) void AddressWalkerWriter::writeMatrixFormula(const OUString& aFormula, SCCOL nCols, SCROW nRows)
{ {
ScRange aRange; ScRange aRange;
......
...@@ -1023,6 +1023,61 @@ bool ScDocFunc::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, boo ...@@ -1023,6 +1023,61 @@ bool ScDocFunc::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, boo
return true; return true;
} }
bool ScDocFunc::SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells, bool bInteraction )
{
const size_t nLength = rCells.size();
if (rPos.Row() + nLength - 1 > MAXROW)
// out of bound
return false;
ScRange aRange(rPos);
aRange.aEnd.IncRow(nLength - 1);
ScDocShellModificator aModificator( rDocShell );
ScDocument& rDoc = rDocShell.GetDocument();
bool bUndo = rDoc.IsUndoEnabled();
std::unique_ptr<sc::UndoSetCells> pUndoObj;
if (bUndo)
{
pUndoObj.reset(new sc::UndoSetCells(&rDocShell, rPos));
rDoc.TransferCellValuesTo(rPos, nLength, pUndoObj->GetOldValues());
}
rDoc.SetFormulaCells(rPos, rCells);
// For performance reasons API calls may disable calculation while
// operating and recalculate once when done. If through user interaction
// and AutoCalc is disabled, calculate the formula (without its
// dependencies) once so the result matches the current document's content.
if (bInteraction && !rDoc.GetAutoCalc())
{
for (auto* pCell : rCells)
{
// calculate just the cell once and set Dirty again
pCell->Interpret();
pCell->SetDirtyVar();
rDoc.PutInFormulaTree( pCell);
}
}
if (bUndo)
{
pUndoObj->SetNewValues(rCells);
SfxUndoManager* pUndoMgr = rDocShell.GetUndoManager();
pUndoMgr->AddUndoAction(std::move(pUndoObj));
}
rDocShell.PostPaint(aRange, PaintPartFlags::Grid);
aModificator.SetDocumentModified();
// #103934#; notify editline and cell in edit mode
if (!bInteraction)
NotifyInputHandler( rPos );
return true;
}
void ScDocFunc::NotifyInputHandler( const ScAddress& rPos ) void ScDocFunc::NotifyInputHandler( const ScAddress& rPos )
{ {
ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
......
...@@ -80,6 +80,7 @@ public: ...@@ -80,6 +80,7 @@ public:
formula::FormulaGrammar::Grammar eGrammar ); formula::FormulaGrammar::Grammar eGrammar );
void writeFormula(const OUString& aFormula); void writeFormula(const OUString& aFormula);
void writeFormulas(const std::vector<OUString>& rFormulas);
void writeMatrixFormula(const OUString& aFormula, SCCOL nCols = 1, SCROW nRows = 1); void writeMatrixFormula(const OUString& aFormula, SCCOL nCols = 1, SCROW nRows = 1);
void writeString(const OUString& aString); void writeString(const OUString& aString);
void writeString(const char* aCharArray); void writeString(const char* aCharArray);
......
...@@ -104,10 +104,11 @@ public: ...@@ -104,10 +104,11 @@ public:
bool SetStringOrEditCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction ); bool SetStringOrEditCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction );
/** /**
* This method takes ownership of the formula cell instance. The caller * Below two methods take ownership of the formula cell instance(s). The caller
* must not delete it after passing it to this call. * must not delete it after passing it to this call.
*/ */
bool SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction ); bool SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction );
bool SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells, bool bInteraction );
void PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi ); void PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi );
bool SetCellText( bool SetCellText(
const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi, const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
class ScDocShell; class ScDocShell;
class ScPatternAttr; class ScPatternAttr;
class ScRangeName; class ScRangeName;
class ScFormulaCell;
class ScUndoCursorAttr: public ScSimpleUndo class ScUndoCursorAttr: public ScSimpleUndo
{ {
...@@ -361,6 +362,7 @@ public: ...@@ -361,6 +362,7 @@ public:
CellValues& GetOldValues() { return maOldValues;} CellValues& GetOldValues() { return maOldValues;}
void SetNewValues( const std::vector<double>& rVals ); void SetNewValues( const std::vector<double>& rVals );
void SetNewValues( const std::vector<ScFormulaCell*>& rVals );
}; };
} // namespace sc } // namespace sc
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <globstr.hrc> #include <globstr.hrc>
#include <scresid.hxx> #include <scresid.hxx>
#include <cellvalues.hxx> #include <cellvalues.hxx>
#include <formulacell.hxx>
namespace sc { namespace sc {
...@@ -60,6 +61,11 @@ void UndoSetCells::SetNewValues( const std::vector<double>& rVals ) ...@@ -60,6 +61,11 @@ void UndoSetCells::SetNewValues( const std::vector<double>& rVals )
maNewValues.assign(rVals); maNewValues.assign(rVals);
} }
void UndoSetCells::SetNewValues( const std::vector<ScFormulaCell*>& rVals )
{
maNewValues.assign(rVals);
}
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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