summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDennis Francis <dennis.francis@collabora.com>2019-05-04 21:49:44 +0530
committerEike Rathke <erack@redhat.com>2019-05-20 15:43:41 +0200
commit1bfbe2a44021ca4ae6716caa39fc8a375914be5c (patch)
treea6a633e7a4f19c437442492e378002bd545f8a67
parentUpdate git submodules (diff)
downloadcore-1bfbe2a44021ca4ae6716caa39fc8a375914be5c.tar.gz
core-1bfbe2a44021ca4ae6716caa39fc8a375914be5c.zip
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>
-rw-r--r--sc/inc/cellvalues.hxx2
-rw-r--r--sc/source/core/data/cellvalues.cxx24
-rw-r--r--sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx8
-rw-r--r--sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx22
-rw-r--r--sc/source/ui/docshell/docfunc.cxx55
-rw-r--r--sc/source/ui/inc/TableFillingAndNavigationTools.hxx1
-rw-r--r--sc/source/ui/inc/docfunc.hxx3
-rw-r--r--sc/source/ui/inc/undocell.hxx2
-rw-r--r--sc/source/ui/undo/undocell2.cxx6
9 files changed, 117 insertions, 6 deletions
diff --git a/sc/inc/cellvalues.hxx b/sc/inc/cellvalues.hxx
index 431239835271..4b877c661a1e 100644
--- a/sc/inc/cellvalues.hxx
+++ b/sc/inc/cellvalues.hxx
@@ -15,6 +15,7 @@
#include <vector>
class ScColumn;
+class ScFormulaCell;
namespace svl {
@@ -63,6 +64,7 @@ public:
void swapNonEmpty( ScColumn& rCol );
void assign( const std::vector<double>& rVals );
+ void assign( const std::vector<ScFormulaCell*>& rVals );
size_t size() const;
diff --git a/sc/source/core/data/cellvalues.cxx b/sc/source/core/data/cellvalues.cxx
index 83c01a9080ca..290dc0d091a9 100644
--- a/sc/source/core/data/cellvalues.cxx
+++ b/sc/source/core/data/cellvalues.cxx
@@ -10,6 +10,7 @@
#include <memory>
#include <cellvalues.hxx>
#include <column.hxx>
+#include <formulacell.hxx>
#include <cassert>
@@ -98,6 +99,25 @@ void CellValues::assign( const std::vector<double>& rVals )
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
{
assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
@@ -154,7 +174,7 @@ void CellValues::copyCellsTo( ScColumn& rCol, SCROW nRow ) const
const CellStoreType& rSrc = mpImpl->maCells;
// 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;
CellStoreType::iterator itPos = rDest.begin();
@@ -219,7 +239,7 @@ void CellValues::copyCellTextAttrsTo( ScColumn& rCol, SCROW nRow ) const
const CellTextAttrStoreType& rSrc = mpImpl->maCellTextAttrs;
// 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;
CellTextAttrStoreType::iterator itPos = rDest.begin();
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: */