diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2019-05-04 21:49:44 +0530 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2019-05-20 15:43:41 +0200 |
commit | 1bfbe2a44021ca4ae6716caa39fc8a375914be5c (patch) | |
tree | a6a633e7a4f19c437442492e378002bd545f8a67 /sc/source/ui | |
parent | 6b2cff82957e8b2c2ca729f076e6d798a74830e6 (diff) |
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: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc/source/ui')
-rw-r--r-- | sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx | 8 | ||||
-rw-r--r-- | sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx | 22 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 55 | ||||
-rw-r--r-- | sc/source/ui/inc/TableFillingAndNavigationTools.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/docfunc.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/inc/undocell.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/undo/undocell2.cxx | 6 |
7 files changed, 93 insertions, 4 deletions
diff --git a/sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx b/sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx index 4f4d5960e199..4d59e28336c7 100644 --- a/sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx +++ b/sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx @@ -75,6 +75,7 @@ ScRange ScMovingAverageDialog::ApplyOutput(ScDocShell* pDocShell) output.nextRow(); DataCellIterator aDataCellIterator = pIterator->iterateCells(); + std::vector<OUString> aFormulas; for (; aDataCellIterator.hasNext(); aDataCellIterator.next()) { @@ -98,14 +99,15 @@ ScRange ScMovingAverageDialog::ApplyOutput(ScDocShell* pDocShell) { aTemplate.setTemplate("=AVERAGE(%RANGE%)"); aTemplate.applyRange("%RANGE%", ScRange(aIntervalStart, aIntervalEnd)); - output.writeFormula(aTemplate.getTemplate()); + aFormulas.push_back(aTemplate.getTemplate()); } else { - output.writeFormula("=#N/A"); + aFormulas.push_back("=#N/A"); } - output.nextRow(); } + + output.writeFormulas(aFormulas); output.nextColumn(); } return ScRange(output.mMinimumAddress, output.mMaximumAddress); diff --git a/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx b/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx index 15936bc2d518..f793417f04a7 100644 --- a/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx +++ b/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx @@ -163,6 +163,28 @@ void AddressWalkerWriter::writeFormula(const OUString& aFormula) 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) { ScRange aRange; diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 1df41fa5903c..a5a61830f0fc 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -1023,6 +1023,61 @@ bool ScDocFunc::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, boo 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 ) { ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell(); diff --git a/sc/source/ui/inc/TableFillingAndNavigationTools.hxx b/sc/source/ui/inc/TableFillingAndNavigationTools.hxx index dd5cdcae1e51..d1d75d248c94 100644 --- a/sc/source/ui/inc/TableFillingAndNavigationTools.hxx +++ b/sc/source/ui/inc/TableFillingAndNavigationTools.hxx @@ -80,6 +80,7 @@ public: formula::FormulaGrammar::Grammar eGrammar ); void writeFormula(const OUString& aFormula); + void writeFormulas(const std::vector<OUString>& rFormulas); void writeMatrixFormula(const OUString& aFormula, SCCOL nCols = 1, SCROW nRows = 1); void writeString(const OUString& aString); void writeString(const char* aCharArray); diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index 28da723907a3..bf07e230cea8 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -104,10 +104,11 @@ public: 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. */ 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 ); bool SetCellText( const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi, diff --git a/sc/source/ui/inc/undocell.hxx b/sc/source/ui/inc/undocell.hxx index 6eb30ee3ff40..c62ea7205304 100644 --- a/sc/source/ui/inc/undocell.hxx +++ b/sc/source/ui/inc/undocell.hxx @@ -32,6 +32,7 @@ class ScDocShell; class ScPatternAttr; class ScRangeName; +class ScFormulaCell; class ScUndoCursorAttr: public ScSimpleUndo { @@ -361,6 +362,7 @@ public: CellValues& GetOldValues() { return maOldValues;} void SetNewValues( const std::vector<double>& rVals ); + void SetNewValues( const std::vector<ScFormulaCell*>& rVals ); }; } // namespace sc diff --git a/sc/source/ui/undo/undocell2.cxx b/sc/source/ui/undo/undocell2.cxx index da7c2ddaa0f1..2222afa4224c 100644 --- a/sc/source/ui/undo/undocell2.cxx +++ b/sc/source/ui/undo/undocell2.cxx @@ -11,6 +11,7 @@ #include <globstr.hrc> #include <scresid.hxx> #include <cellvalues.hxx> +#include <formulacell.hxx> namespace sc { @@ -60,6 +61,11 @@ void UndoSetCells::SetNewValues( const std::vector<double>& rVals ) maNewValues.assign(rVals); } +void UndoSetCells::SetNewValues( const std::vector<ScFormulaCell*>& rVals ) +{ + maNewValues.assign(rVals); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |