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

Kohei Yoshida kohei.yoshida at collabora.com
Thu Jan 30 08:52:19 PST 2014


 sc/Library_sc.mk                                               |    2 
 sc/inc/cellvalues.hxx                                          |   44 +++
 sc/inc/column.hxx                                              |    6 
 sc/inc/document.hxx                                            |   13 +
 sc/inc/table.hxx                                               |    5 
 sc/source/core/data/cellvalues.cxx                             |  116 ++++++++++
 sc/source/core/data/column4.cxx                                |   84 +++++++
 sc/source/core/data/document10.cxx                             |   27 ++
 sc/source/core/data/table7.cxx                                 |   24 ++
 sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx |   18 +
 sc/source/ui/collab/sendfunc.cxx                               |    7 
 sc/source/ui/collab/sendfunc.hxx                               |    1 
 sc/source/ui/docshell/docfunc.cxx                              |   35 +++
 sc/source/ui/inc/docfunc.hxx                                   |    1 
 sc/source/ui/inc/undocell.hxx                                  |   31 ++
 sc/source/ui/undo/undocell2.cxx                                |   69 +++++
 16 files changed, 477 insertions(+), 6 deletions(-)

New commits:
commit a0bd814fb5c2ed1d8a1583eb59c783290c7c3dc9
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Jan 29 23:35:34 2014 -0500

    Speed up filling of random number generation over entire column.
    
    Because nobody wants to wait forever...
    
    Change-Id: Ie52bff944893b7e3fe9e7908be19d27c692fc1ea

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 1ed89c6..dcced7f 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -100,6 +100,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/core/data/bcaslot \
     sc/source/core/data/bigrange \
     sc/source/core/data/cellvalue \
+    sc/source/core/data/cellvalues \
     sc/source/core/data/clipcontext \
     sc/source/core/data/clipparam \
     sc/source/core/data/column \
@@ -512,6 +513,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/ui/undo/undoblk2 \
     sc/source/ui/undo/undoblk3 \
     sc/source/ui/undo/undocell \
+    sc/source/ui/undo/undocell2 \
     sc/source/ui/undo/undodat \
     sc/source/ui/undo/undodraw \
     sc/source/ui/undo/undoolk \
diff --git a/sc/inc/cellvalues.hxx b/sc/inc/cellvalues.hxx
new file mode 100644
index 0000000..8b249b4
--- /dev/null
+++ b/sc/inc/cellvalues.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SC_CELLVALUES_HXX
+#define SC_CELLVALUES_HXX
+
+#include <address.hxx>
+
+class ScColumn;
+
+namespace sc {
+
+struct CellValuesImpl;
+
+class CellValues
+{
+    CellValuesImpl* mpImpl;
+
+    CellValues( const CellValues& ); // disabled
+    CellValues& operator= ( const CellValues& ); // disabled
+
+public:
+    CellValues();
+    ~CellValues();
+
+    void transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen );
+    void copyTo( ScColumn& rCol, SCROW nRow ) const;
+
+    void assign( const std::vector<double>& rVals );
+
+    size_t size() const;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1ac1e3f..69ba1af 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -56,6 +56,7 @@ struct RefUpdateMoveTabContext;
 class EditTextIterator;
 struct NoteEntry;
 class DocumentStreamAccess;
+class CellValues;
 
 }
 
@@ -143,6 +144,7 @@ friend class sc::DocumentStreamAccess;
 friend class sc::SingleColumnSpanSet;
 friend class sc::ColumnSpanSet;
 friend class sc::EditTextIterator;
+friend class sc::CellValues;
 
     ScColumn(const ScColumn&); // disabled
     ScColumn& operator= (const ScColumn&); // disabled
@@ -294,6 +296,7 @@ public:
     void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const OUString& rStr, bool bBroadcast = true );
     void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const svl::SharedString& rStr, bool bBroadcast = true );
     void SetValue( SCROW nRow, double fVal );
+    void SetValues( SCROW nRow, const std::vector<double>& rVals );
     void SetValue( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, double fVal, bool bBroadcast = true );
     void        SetError( SCROW nRow, const sal_uInt16 nError);
 
@@ -539,6 +542,9 @@ public:
      */
     void RegroupFormulaCells();
 
+    void TransferCellValuesTo( SCROW nRow, size_t nLen, sc::CellValues& rDest );
+    void CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc );
+
 #if DEBUG_COLUMN_STORAGE
     void DumpFormulaGroups() const;
 #endif
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d39cb09..b241859 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -71,6 +71,7 @@ struct NoteEntry;
 struct FormulaGroupContext;
 class DocumentStreamAccess;
 class DocumentLinkManager;
+class CellValues;
 
 }
 
@@ -810,6 +811,9 @@ public:
 
     SC_DLLPUBLIC void SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal );
     SC_DLLPUBLIC void SetValue( const ScAddress& rPos, double fVal );
+
+    void SetValues( const ScAddress& rPos, const std::vector<double>& rVals );
+
     void SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError);
 
     SC_DLLPUBLIC void SetFormula(
@@ -1771,6 +1775,15 @@ public:
 
     void SC_DLLPUBLIC SetFormulaResults( const ScAddress& rTopPos, const formula::FormulaTokenRef* pResults, size_t nLen );
 
+    /**
+     * Transfer a series of contiguous cell values from specified position to
+     * the passed container. The specified segment will become empty after the
+     * transfer.
+     */
+    void TransferCellValuesTo( const ScAddress& rTopPos, size_t nLen, sc::CellValues& rDest );
+
+    void CopyCellValuesFrom( const ScAddress& rTopPos, const sc::CellValues& rSrc );
+
 private:
     ScDocument(const ScDocument& r); // disabled with no definition
 
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index bc10089..260a736 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -68,6 +68,7 @@ struct RefUpdateDeleteTabContext;
 struct RefUpdateMoveTabContext;
 struct NoteEntry;
 class DocumentStreamAccess;
+class CellValues;
 
 }
 
@@ -345,6 +346,7 @@ public:
     svl::SharedString GetSharedString( SCCOL nCol, SCROW nRow ) const;
 
     void        SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
+    void SetValues( SCCOL nCol, SCROW nRow, const std::vector<double>& rVals );
     void        SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError);
     SCSIZE      GetPatternCount( SCCOL nCol ) const;
     SCSIZE      GetPatternCount( SCCOL nCol, SCROW nRow1, SCROW nRow2 ) const;
@@ -897,6 +899,9 @@ public:
      */
     void BroadcastRecalcOnRefMove();
 
+    void TransferCellValuesTo( SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest );
+    void CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc );
+
 #if DEBUG_COLUMN_STORAGE
     void DumpFormulaGroups( SCCOL nCol ) const;
 #endif
diff --git a/sc/source/core/data/cellvalues.cxx b/sc/source/core/data/cellvalues.cxx
new file mode 100644
index 0000000..5f7802e
--- /dev/null
+++ b/sc/source/core/data/cellvalues.cxx
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cellvalues.hxx>
+#include <column.hxx>
+
+#include <cassert>
+#include <boost/noncopyable.hpp>
+
+namespace sc {
+
+struct CellValuesImpl : boost::noncopyable
+{
+    CellStoreType maCells;
+};
+
+CellValues::CellValues() :
+    mpImpl(new CellValuesImpl) {}
+
+CellValues::~CellValues()
+{
+    delete mpImpl;
+}
+
+void CellValues::transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen )
+{
+    mpImpl->maCells.resize(nLen);
+    rCol.maCells.transfer(nRow, nRow+nLen-1, mpImpl->maCells, 0);
+}
+
+void CellValues::copyTo( ScColumn& rCol, SCROW nRow ) const
+{
+    CellStoreType& rDest = rCol.maCells;
+    const CellStoreType& rSrc = mpImpl->maCells;
+
+    // Caller must ensure the destination is long enough.
+    assert(rSrc.size() + static_cast<size_t>(nRow) < rDest.size());
+
+    SCROW nCurRow = nRow;
+    CellStoreType::iterator itPos = rDest.begin();
+
+    CellStoreType::const_iterator itBlk = rSrc.begin(), itBlkEnd = rSrc.end();
+    for (; itBlk != itBlkEnd; ++itBlk)
+    {
+        switch (itBlk->type)
+        {
+            case element_type_numeric:
+            {
+                numeric_block::const_iterator it = numeric_block::begin(*itBlk->data);
+                numeric_block::const_iterator itEnd = numeric_block::end(*itBlk->data);
+                itPos = rDest.set(itPos, nCurRow, it, itEnd);
+            }
+            break;
+            case element_type_string:
+            {
+                string_block::const_iterator it = string_block::begin(*itBlk->data);
+                string_block::const_iterator itEnd = string_block::end(*itBlk->data);
+                itPos = rDest.set(itPos, nCurRow, it, itEnd);
+            }
+            break;
+            case element_type_edittext:
+            {
+                edittext_block::const_iterator it = edittext_block::begin(*itBlk->data);
+                edittext_block::const_iterator itEnd = edittext_block::end(*itBlk->data);
+                std::vector<EditTextObject*> aVals;
+                aVals.reserve(itBlk->size);
+                for (; it != itEnd; ++it)
+                {
+                    const EditTextObject* p = *it;
+                    aVals.push_back(p->Clone());
+                }
+                itPos = rDest.set(itPos, nCurRow, aVals.begin(), aVals.end());
+            }
+            break;
+            case element_type_formula:
+            {
+                formula_block::const_iterator it = formula_block::begin(*itBlk->data);
+                formula_block::const_iterator itEnd = formula_block::end(*itBlk->data);
+                std::vector<ScFormulaCell*> aVals;
+                aVals.reserve(itBlk->size);
+                for (; it != itEnd; ++it)
+                {
+                    const ScFormulaCell* p = *it;
+                    aVals.push_back(p->Clone());
+                }
+                itPos = rDest.set(itPos, nCurRow, aVals.begin(), aVals.end());
+            }
+            break;
+            default:
+                itPos = rDest.set_empty(itPos, nCurRow, nCurRow+itBlk->size-1);
+        }
+
+        nCurRow += itBlk->size;
+    }
+}
+
+void CellValues::assign( const std::vector<double>& rVals )
+{
+    mpImpl->maCells.resize(rVals.size());
+    mpImpl->maCells.set(0, rVals.begin(), rVals.end());
+}
+
+size_t CellValues::size() const
+{
+    return mpImpl->maCells.size();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index b70e52d..661c38d 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -13,6 +13,7 @@
 #include <cellvalue.hxx>
 #include <attarray.hxx>
 #include <document.hxx>
+#include <cellvalues.hxx>
 
 #include <svl/sharedstring.hxx>
 
@@ -144,4 +145,87 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
     }
 }
 
+void ScColumn::SetValues( SCROW nRow, const std::vector<double>& rVals )
+{
+    if (!ValidRow(nRow))
+        return;
+
+    SCROW nLastRow = nRow + rVals.size() - 1;
+    if (nLastRow > MAXROW)
+        // Out of bound. Do nothing.
+        return;
+
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    DetachFormulaCells(aPos, rVals.size());
+
+    maCells.set(nRow, rVals.begin(), rVals.end());
+    std::vector<sc::CellTextAttr> aDefaults(rVals.size());
+    maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
+
+    CellStorageModified();
+
+    std::vector<SCROW> aRows;
+    aRows.reserve(rVals.size());
+    for (SCROW i = nRow; i <= nLastRow; ++i)
+        aRows.push_back(i);
+
+    BroadcastCells(aRows, SC_HINT_DATACHANGED);
+}
+
+void ScColumn::TransferCellValuesTo( SCROW nRow, size_t nLen, sc::CellValues& rDest )
+{
+    if (!ValidRow(nRow))
+        return;
+
+    SCROW nLastRow = nRow + nLen - 1;
+    if (nLastRow > MAXROW)
+        // Out of bound. Do nothing.
+        return;
+
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    DetachFormulaCells(aPos, nLen);
+
+    rDest.transferFrom(*this, nRow, nLen);
+
+    std::vector<sc::CellTextAttr> aDefaults(nLen);
+    maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
+
+    CellStorageModified();
+
+    std::vector<SCROW> aRows;
+    aRows.reserve(nLen);
+    for (SCROW i = nRow; i <= nLastRow; ++i)
+        aRows.push_back(i);
+
+    BroadcastCells(aRows, SC_HINT_DATACHANGED);
+}
+
+void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
+{
+    if (!ValidRow(nRow))
+        return;
+
+    SCROW nLastRow = nRow + rSrc.size() - 1;
+    if (nLastRow > MAXROW)
+        // Out of bound. Do nothing
+        return;
+
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    DetachFormulaCells(aPos, rSrc.size());
+
+    rSrc.copyTo(*this, nRow);
+
+    std::vector<sc::CellTextAttr> aDefaults(rSrc.size());
+    maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
+
+    CellStorageModified();
+
+    std::vector<SCROW> aRows;
+    aRows.reserve(rSrc.size());
+    for (SCROW i = nRow; i <= nLastRow; ++i)
+        aRows.push_back(i);
+
+    BroadcastCells(aRows, SC_HINT_DATACHANGED);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index ee3e35d..bd1e385 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -170,4 +170,31 @@ bool ScDocument::CopyOneCellFromClip(
     return true;
 }
 
+void ScDocument::SetValues( const ScAddress& rPos, const std::vector<double>& rVals )
+{
+    ScTable* pTab = FetchTable(rPos.Tab());
+    if (!pTab)
+        return;
+
+    pTab->SetValues(rPos.Col(), rPos.Row(), rVals);
+}
+
+void ScDocument::TransferCellValuesTo( const ScAddress& rTopPos, size_t nLen, sc::CellValues& rDest )
+{
+    ScTable* pTab = FetchTable(rTopPos.Tab());
+    if (!pTab)
+        return;
+
+    pTab->TransferCellValuesTo(rTopPos.Col(), rTopPos.Row(), nLen, rDest);
+}
+
+void ScDocument::CopyCellValuesFrom( const ScAddress& rTopPos, const sc::CellValues& rSrc )
+{
+    ScTable* pTab = FetchTable(rTopPos.Tab());
+    if (!pTab)
+        return;
+
+    pTab->CopyCellValuesFrom(rTopPos.Col(), rTopPos.Row(), rSrc);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index ac036aa..8a7391c 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -24,4 +24,28 @@ void ScTable::CopyOneCellFromClip(
         aCol[nCol].CopyOneCellFromClip(rCxt, nRow1, nRow2);
 }
 
+void ScTable::SetValues( SCCOL nCol, SCROW nRow, const std::vector<double>& rVals )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].SetValues(nRow, rVals);
+}
+
+void ScTable::TransferCellValuesTo( SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].TransferCellValuesTo(nRow, nLen, rDest);
+}
+
+void ScTable::CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].CopyCellValuesFrom(nRow, rSrc);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx b/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx
index 0c47c5b..86fa779 100644
--- a/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx
+++ b/sc/source/ui/StatisticsDialogs/RandomNumberGeneratorDialog.cxx
@@ -266,14 +266,20 @@ void ScRandomNumberGeneratorDialog::GenerateNumbers(RNG randomGenerator, OUStrin
     SCTAB nTabStart = maInputRange.aStart.Tab();
     SCTAB nTabEnd   = maInputRange.aEnd.Tab();
 
-    for (SCROW nTab = nTabStart; nTab <= nTabEnd; nTab++)
+    std::vector<double> aVals;
+    aVals.reserve(nRowEnd-nRowStart+1);
+
+    for (SCROW nTab = nTabStart; nTab <= nTabEnd; ++nTab)
     {
-        for (SCROW nRow = nRowStart; nRow <= nRowEnd; nRow++)
+        for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
         {
-            for (SCCOL nCol = nColStart; nCol <= nColEnd; nCol++)
-            {
-                pDocShell->GetDocFunc().SetValueCell(ScAddress(nCol, nRow, nTab), randomGenerator(), true);
-            }
+            aVals.clear();
+
+            ScAddress aPos(nCol, nRowStart, nTab);
+            for (SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
+                aVals.push_back(randomGenerator());
+
+            pDocShell->GetDocFunc().SetValueCells(aPos, aVals, true);
         }
     }
 
diff --git a/sc/source/ui/collab/sendfunc.cxx b/sc/source/ui/collab/sendfunc.cxx
index fb45e9d..7e18ee8 100644
--- a/sc/source/ui/collab/sendfunc.cxx
+++ b/sc/source/ui/collab/sendfunc.cxx
@@ -350,6 +350,13 @@ bool ScDocFuncSend::SetValueCell( const ScAddress& rPos, double fVal, bool bInte
     return true; // needs some code auditing action
 }
 
+bool ScDocFuncSend::SetValueCells(
+    const ScAddress& /*rPos*/, const std::vector<double>& /*aVals*/, bool /*bInteraction*/ )
+{
+    // TODO : Implement this.
+    return true;
+}
+
 bool ScDocFuncSend::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
 {
     ScChangeOpWriter aOp("setStringCell");
diff --git a/sc/source/ui/collab/sendfunc.hxx b/sc/source/ui/collab/sendfunc.hxx
index 5dad421..4b5ef34 100644
--- a/sc/source/ui/collab/sendfunc.hxx
+++ b/sc/source/ui/collab/sendfunc.hxx
@@ -35,6 +35,7 @@ public:
 
     virtual sal_Bool    SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const OUString& rText, sal_Bool bApi );
     virtual bool SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction );
+    virtual bool SetValueCells( const ScAddress& rPos, const std::vector<double>& aVals, bool bInteraction );
     virtual bool SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction );
     virtual bool SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction );
     virtual bool SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction );
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 7f364f1..f0ad671 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -843,6 +843,41 @@ bool ScDocFunc::SetValueCell( const ScAddress& rPos, double fVal, bool bInteract
     return true;
 }
 
+bool ScDocFunc::SetValueCells( const ScAddress& rPos, const std::vector<double>& aVals, bool bInteraction )
+{
+    // Check for invalid range.
+    SCROW nLastRow = rPos.Row() + aVals.size() - 1;
+    if (nLastRow > MAXROW)
+        // out of bound.
+        return false;
+
+    ScRange aRange(rPos);
+    aRange.aEnd.SetRow(nLastRow);
+
+    ScDocShellModificator aModificator(rDocShell);
+    ScDocument* pDoc = rDocShell.GetDocument();
+
+    if (pDoc->IsUndoEnabled())
+    {
+        sc::UndoSetCells* pUndoObj = new sc::UndoSetCells(&rDocShell, rPos);
+        pDoc->TransferCellValuesTo(rPos, aVals.size(), pUndoObj->GetOldValues());
+        pUndoObj->SetNewValues(aVals);
+        svl::IUndoManager* pUndoMgr = rDocShell.GetUndoManager();
+        pUndoMgr->AddUndoAction(pUndoObj);
+    }
+
+    pDoc->SetValues(rPos, aVals);
+
+    rDocShell.PostPaint(aRange, PAINT_GRID);
+    aModificator.SetDocumentModified();
+
+    // #103934#; notify editline and cell in edit mode
+    if (!bInteraction)
+        NotifyInputHandler(rPos);
+
+    return true;
+}
+
 bool ScDocFunc::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
 {
     ScDocShellModificator aModificator( rDocShell );
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index c17e43b..75442fd 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -89,6 +89,7 @@ public:
 
     virtual sal_Bool        SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const OUString& rText, sal_Bool bApi );
     virtual bool SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction );
+    virtual bool SetValueCells( const ScAddress& rPos, const std::vector<double>& aVals, bool bInteraction );
     virtual bool SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction );
     virtual bool SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction );
 
diff --git a/sc/source/ui/inc/undocell.hxx b/sc/source/ui/inc/undocell.hxx
index 8183d2a..0b039b77 100644
--- a/sc/source/ui/inc/undocell.hxx
+++ b/sc/source/ui/inc/undocell.hxx
@@ -23,6 +23,7 @@
 #include "undobase.hxx"
 #include "postit.hxx"
 #include "cellvalue.hxx"
+#include <cellvalues.hxx>
 
 #include <boost/shared_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
@@ -36,6 +37,12 @@ class ScDetOpData;
 class ScRangeName;
 class ScDocument;
 
+namespace sc {
+
+class CellValues;
+
+}
+
 class ScUndoCursorAttr: public ScSimpleUndo
 {
 public:
@@ -367,7 +374,31 @@ private:
     void            DoChange( sal_Bool bUndo );
 };
 
+namespace sc {
+
+class UndoSetCells : public ScSimpleUndo
+{
+    ScAddress maTopPos;
+    CellValues maOldValues;
+    CellValues maNewValues;
+
+    void DoChange( const CellValues& rValues );
+
+public:
+    UndoSetCells( ScDocShell* pDocSh, const ScAddress& rTopPos );
+    virtual ~UndoSetCells();
+
+    virtual void Undo();
+    virtual void Redo();
+
+    virtual bool CanRepeat( SfxRepeatTarget& ) const;
+    virtual OUString GetComment() const;
+
+    CellValues& GetOldValues();
+    void SetNewValues( const std::vector<double>& rVals );
+};
 
+} // namespace sc
 
 #endif
 
diff --git a/sc/source/ui/undo/undocell2.cxx b/sc/source/ui/undo/undocell2.cxx
new file mode 100644
index 0000000..f4b5d93
--- /dev/null
+++ b/sc/source/ui/undo/undocell2.cxx
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <undocell.hxx>
+#include <globstr.hrc>
+#include <cellvalues.hxx>
+
+namespace sc {
+
+UndoSetCells::UndoSetCells( ScDocShell* pDocSh, const ScAddress& rTopPos ) :
+    ScSimpleUndo(pDocSh), maTopPos(rTopPos) {}
+
+UndoSetCells::~UndoSetCells() {}
+
+void UndoSetCells::DoChange( const CellValues& rValues )
+{
+    ScDocument* pDoc = pDocShell->GetDocument();
+    pDoc->CopyCellValuesFrom(maTopPos, rValues);
+
+    ScRange aRange(maTopPos);
+    aRange.aEnd.IncRow(rValues.size());
+    BroadcastChanges(aRange);
+    pDocShell->PostPaintGridAll();
+}
+
+void UndoSetCells::Undo()
+{
+    BeginUndo();
+    DoChange(maOldValues);
+    EndUndo();
+}
+
+void UndoSetCells::Redo()
+{
+    BeginRedo();
+    DoChange(maNewValues);
+    EndRedo();
+}
+
+bool UndoSetCells::CanRepeat( SfxRepeatTarget& ) const
+{
+    return false;
+}
+
+OUString UndoSetCells::GetComment() const
+{
+    // "Input"
+    return ScGlobal::GetRscString(STR_UNDO_ENTERDATA);
+}
+
+CellValues& UndoSetCells::GetOldValues()
+{
+    return maOldValues;
+}
+
+void UndoSetCells::SetNewValues( const std::vector<double>& rVals )
+{
+    maNewValues.assign(rVals);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list