[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue Mar 25 03:19:42 PDT 2014


 sc/inc/column.hxx                |    3 +
 sc/inc/document.hxx              |    2 +
 sc/inc/table.hxx                 |    2 +
 sc/source/core/data/column.cxx   |   21 +++++++++--
 sc/source/core/data/column3.cxx  |   69 +++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/documen2.cxx |   12 ++++++
 sc/source/core/data/table2.cxx   |    8 ++++
 7 files changed, 113 insertions(+), 4 deletions(-)

New commits:
commit 572fdb94ecf3dfea6a6f787398efa4e4c54b4718
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Mar 22 09:47:11 2014 -0400

    fdo#76470: Avoid joining new formula cells individually.
    
    Instead, insert the formula cells in the group first, then only try to join
    the top and bottom cells afterward. Otherwise the grouping would get messed
    up and a problem would ensue.
    
    (cherry picked from commit 474b2ea601f7fa2f1fbeae0f169ff5b8abc965be)
    
    Conflicts:
    	sc/inc/column.hxx
    
    Change-Id: I4fdd5326c029032a636d8225b5fb16cbde427c7d
    Reviewed-on: https://gerrit.libreoffice.org/8716
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index e6a69e1..33a1bf7 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -291,6 +291,8 @@ public:
     ScFormulaCell* SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
     ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
 
+    bool SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells );
+
     svl::SharedString GetSharedString( SCROW nRow ) const;
 
     void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true );
@@ -555,6 +557,7 @@ private:
     sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
     void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell, bool bJoin = true );
     void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell, bool bJoin = true );
+    void AttachNewFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength );
     void BroadcastNewCell( SCROW nRow );
     bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow, sc::CellStoreType::iterator& itr );
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 04ffa47..809689b 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -839,6 +839,8 @@ public:
      */
     SC_DLLPUBLIC ScFormulaCell* SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell );
 
+    bool SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells );
+
     SC_DLLPUBLIC void InsertMatrixFormula(SCCOL nCol1, SCROW nRow1,
                                         SCCOL nCol2, SCROW nRow2,
                                         const ScMarkData& rMark,
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index eda54721..77e5996 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -345,6 +345,8 @@ public:
      */
     ScFormulaCell* SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* pCell );
 
+    bool SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells );
+
     svl::SharedString GetSharedString( SCCOL nCol, SCROW nRow ) const;
 
     void        SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 7914fdf..7a448fd 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -43,6 +43,7 @@
 #include "refupdatecontext.hxx"
 #include <listenercontext.hxx>
 #include <refhint.hxx>
+#include <stlalgorithm.hxx>
 
 #include <svl/poolcach.hxx>
 #include <svl/zforlist.hxx>
@@ -2553,21 +2554,33 @@ class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void>
 
     void fillUndoDoc( const ScAddress& rOldPos, SCROW nLength, const ScTokenArray& rOldCode )
     {
-        if (!mpUndoDoc)
+        if (!mpUndoDoc || nLength <= 0)
             return;
 
         // Insert the old formula group into the undo document.
         ScAddress aUndoPos = rOldPos;
         ScFormulaCell* pFC = new ScFormulaCell(mpUndoDoc, aUndoPos, rOldCode.Clone());
-        ScFormulaCellGroupRef xGroup = pFC->CreateCellGroup(nLength, false);
 
-        mpUndoDoc->SetFormulaCell(aUndoPos, pFC);
+        if (nLength == 1)
+        {
+            mpUndoDoc->SetFormulaCell(aUndoPos, pFC);
+            return;
+        }
+
+        std::vector<ScFormulaCell*> aCells;
+        aCells.reserve(nLength);
+        ScFormulaCellGroupRef xGroup = pFC->CreateCellGroup(nLength, false);
+        aCells.push_back(pFC);
         aUndoPos.IncRow();
         for (SCROW i = 1; i < nLength; ++i, aUndoPos.IncRow())
         {
             pFC = new ScFormulaCell(mpUndoDoc, aUndoPos, xGroup);
-            mpUndoDoc->SetFormulaCell(aUndoPos, pFC);
+            aCells.push_back(pFC);
         }
+
+        if (!mpUndoDoc->SetFormulaCells(rOldPos, aCells))
+            // Insertion failed.  Delete all formula cells.
+            std::for_each(aCells.begin(), aCells.end(), ScDeleteObjectByPtr<ScFormulaCell>());
     }
 
 public:
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 75ad544..d47893f 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -46,6 +46,7 @@
 #include "scopetools.hxx"
 #include "editutil.hxx"
 #include "sharedformula.hxx"
+#include <listenercontext.hxx>
 
 #include <com/sun/star/i18n/LocaleDataItem.hpp>
 
@@ -413,6 +414,40 @@ void ScColumn::ActivateNewFormulaCell(
     }
 }
 
+void ScColumn::AttachNewFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength )
+{
+    // Make sure the whole length consists of formula cells.
+    if (aPos.first->type != sc::element_type_formula)
+        return;
+
+    if (aPos.first->size < aPos.second + nLength)
+        // Block is shorter than specified length.
+        return;
+
+    // Join the top and bottom cells only.
+    ScFormulaCell* pCell = sc::formula_block::at(*aPos.first->data, aPos.second);
+    JoinNewFormulaCell(aPos, *pCell);
+
+    sc::CellStoreType::position_type aPosLast = aPos;
+    aPosLast.second += nLength - 1;
+    pCell = sc::formula_block::at(*aPosLast.first->data, aPosLast.second);
+    JoinNewFormulaCell(aPosLast, *pCell);
+
+    if (!pDocument->IsClipOrUndo() && !pDocument->IsInsertingFromOtherDoc())
+    {
+        sc::StartListeningContext aCxt(*pDocument);
+        ScFormulaCell** pp = &sc::formula_block::at(*aPos.first->data, aPos.second);
+        ScFormulaCell** ppEnd = pp + nLength;
+        for (; pp != ppEnd; ++pp)
+        {
+            pCell = *pp;
+            pCell->StartListeningTo(aCxt);
+            if (!pDocument->IsCalcingAfterLoad())
+                pCell->SetDirty();
+        }
+    }
+}
+
 void ScColumn::BroadcastNewCell( SCROW nRow )
 {
     // When we insert from the Clipboard we still have wrong (old) References!
@@ -1805,6 +1840,40 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR
     return pCell;
 }
 
+bool ScColumn::SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells )
+{
+    if (!ValidRow(nRow))
+        return false;
+
+    SCROW nEndRow = nRow + rCells.size() - 1;
+    if (!ValidRow(nEndRow))
+        return false;
+
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+
+    // Detach all formula cells that will be overwritten.
+    DetachFormulaCells(aPos, rCells.size());
+
+    for (size_t i = 0, n = rCells.size(); i < n; ++i)
+    {
+        SCROW nThisRow = nRow + i;
+        sal_uInt32 nFmt = GetNumberFormat(nThisRow);
+        if ((nFmt % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+            rCells[i]->SetNeedNumberFormat(true);
+    }
+
+    std::vector<sc::CellTextAttr> aDefaults(rCells.size(), sc::CellTextAttr());
+    maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
+
+    sc::CellStoreType::iterator it = maCells.set(aPos.first, nRow, rCells.begin(), rCells.end());
+
+    CellStorageModified();
+
+    AttachNewFormulaCells(aPos, rCells.size());
+
+    return true;
+}
+
 svl::SharedString ScColumn::GetSharedString( SCROW nRow ) const
 {
     sc::CellStoreType::const_position_type aPos = maCells.position(nRow);
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 1a57cc8..daa4e2a 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -1118,6 +1118,18 @@ ScFormulaCell* ScDocument::SetFormulaCell( const ScAddress& rPos, ScFormulaCell*
     return maTabs[rPos.Tab()]->SetFormulaCell(rPos.Col(), rPos.Row(), pCell);
 }
 
+bool ScDocument::SetFormulaCells( const ScAddress& rPos, std::vector<ScFormulaCell*>& rCells )
+{
+    if (rCells.empty())
+        return false;
+
+    ScTable* pTab = FetchTable(rPos.Tab());
+    if (!pTab)
+        return false;
+
+    return pTab->SetFormulaCells(rPos.Col(), rPos.Row(), rCells);
+}
+
 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam* pData )
 {
     delete pConsolidateDlgData;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index b0fba9c..2835496 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1384,6 +1384,14 @@ ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* p
     return aCol[nCol].SetFormulaCell(nRow, pCell);
 }
 
+bool ScTable::SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells )
+{
+    if (!ValidCol(nCol))
+        return false;
+
+    return aCol[nCol].SetFormulaCells(nRow, rCells);
+}
+
 svl::SharedString ScTable::GetSharedString( SCCOL nCol, SCROW nRow ) const
 {
     if (!ValidColRow(nCol, nRow))


More information about the Libreoffice-commits mailing list