[Libreoffice-commits] core.git: sc/inc sc/source

Dennis Francis (via logerrit) logerrit at kemper.freedesktop.org
Mon May 20 13:44:32 UTC 2019


 sc/inc/cellvalues.hxx                                             |    2 
 sc/source/core/data/cellvalues.cxx                                |   24 ++++
 sc/source/ui/StatisticsDialogs/MovingAverageDialog.cxx            |    8 -
 sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx |   22 ++++
 sc/source/ui/docshell/docfunc.cxx                                 |   55 ++++++++++
 sc/source/ui/inc/TableFillingAndNavigationTools.hxx               |    1 
 sc/source/ui/inc/docfunc.hxx                                      |    3 
 sc/source/ui/inc/undocell.hxx                                     |    2 
 sc/source/ui/undo/undocell2.cxx                                   |    6 +
 9 files changed, 117 insertions(+), 6 deletions(-)

New commits:
commit 1bfbe2a44021ca4ae6716caa39fc8a375914be5c
Author:     Dennis Francis <dennis.francis at collabora.com>
AuthorDate: Sat May 4 21:49:44 2019 +0530
Commit:     Eike Rathke <erack at redhat.com>
CommitDate: Mon May 20 15:43:41 2019 +0200

    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 at redhat.com>

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: */


More information about the Libreoffice-commits mailing list