sc/inc/column.hxx                |    1 
 sc/inc/table.hxx                 |   20 ++++++++++++++-
 sc/source/core/data/column.cxx   |   30 ++++++++++++++++++++++-
 sc/source/core/data/document.cxx |   50 ++++++++++++++++++++++++++++++---------
 sc/source/core/data/table2.cxx   |    7 +++++
 5 files changed, 94 insertions(+), 14 deletions(-)

New commits:
commit fd340291c4ef579ee42850f9b7842d6afe98877d
Author: Kohei Yoshida <kohei.yosh...@gmail.com>
Date:   Tue Jul 23 16:02:37 2013 -0400

    Broadcast on formula cells containing COLUMN functions on column insertion.
    
    To ensure that the change gets propagated properly. This fixes
    testFuncCOLUMN() cppunit test.
    
    Change-Id: Ia1ffc2880b7dae530ceb11c617c3963f7bfaeb00

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 00b2a63..5ef6cce 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -431,6 +431,7 @@ public:
     void        StartAllListeners();
     void        StartNeededListeners(); // only for cells where 
NeedsListening()==true
     void        SetRelNameDirty();
+    void BroadcastRecalcOnRefMove();
 
     void        CompileDBFormula();
     void        CompileDBFormula( bool bCreateFormulaString );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 0e4305a..00cc7e5 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -862,6 +862,24 @@ public:
 
     void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, 
size_t nLen );
 
+    /**
+     * Have formula cells with NeedsListening() == true start listening to the
+     * document.
+     */
+    void StartNeededListeners();
+
+    /**
+     * Mark dirty those formula cells that has named ranges with relative
+     * references.
+     */
+    void SetRelNameDirty();
+
+    /**
+     * Broadcast dirty formula cells that contain functions such as CELL(),
+     * COLUMN() or ROW() which may change its value on move.
+     */
+    void BroadcastRecalcOnRefMove();
+
 #if DEBUG_COLUMN_STORAGE
     void DumpFormulaGroups( SCCOL nCol ) const;
 #endif
@@ -968,8 +986,6 @@ private:
     void StartListening( sc::StartListeningContext& rCxt, SCCOL nCol, SCROW 
nRow, SvtListener& rListener );
     void EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, 
SvtListener& rListener );
     void        StartAllListeners();
-    void        StartNeededListeners(); // only for cells where 
NeedsListening()==TRUE
-    void        SetRelNameDirty();
 
     void        SetLoadingMedium(bool bLoading);
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 23a740f..da3cb49 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2144,6 +2144,7 @@ void resetColumnPosition(sc::CellStoreType& rCells, SCCOL 
nCol)
 
 void ScColumn::SwapCol(ScColumn& rCol)
 {
+    maBroadcasters.swap(rCol.maBroadcasters);
     maCells.swap(rCol.maCells);
     maCellTextAttrs.swap(rCol.maCellTextAttrs);
 
@@ -2163,7 +2164,6 @@ void ScColumn::SwapCol(ScColumn& rCol)
 
     CellStorageModified();
     rCol.CellStorageModified();
-
 }
 
 void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
@@ -3004,6 +3004,26 @@ void ScColumn::SetDirtyAfterLoad()
     sc::ProcessFormula(maCells, aFunc);
 }
 
+namespace {
+
+class RecalcOnRefMoveCollector
+{
+    std::vector<SCROW> maDirtyRows;
+public:
+    void operator() (size_t nRow, ScFormulaCell* pCell)
+    {
+        if (pCell->GetDirty() && pCell->GetCode()->IsRecalcModeOnRefMove())
+            maDirtyRows.push_back(nRow);
+    }
+
+    const std::vector<SCROW>& getDirtyRows() const
+    {
+        return maDirtyRows;
+    }
+};
+
+}
+
 void ScColumn::SetRelNameDirty()
 {
     sc::AutoCalcSwitch aSwitch(*pDocument, false);
@@ -3011,6 +3031,14 @@ void ScColumn::SetRelNameDirty()
     sc::ProcessFormula(maCells, aFunc);
 }
 
+void ScColumn::BroadcastRecalcOnRefMove()
+{
+    sc::AutoCalcSwitch aSwitch(*pDocument, false);
+    RecalcOnRefMoveCollector aFunc;
+    sc::ProcessFormula(maCells, aFunc);
+    BroadcastCells(aFunc.getDirtyRows());
+}
+
 void ScColumn::CalcAll()
 {
     CalcAllHandler aFunc;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index dfc17cf..9cba374 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1334,6 +1334,36 @@ bool ScDocument::CanInsertCol( const ScRange& rRange ) 
const
     return bTest;
 }
 
+namespace {
+
+struct StartNeededListenersHandler : std::unary_function<ScTable*, void>
+{
+    void operator() (ScTable* p)
+    {
+        if (p)
+            p->StartNeededListeners();
+    }
+};
+
+struct SetRelNameDirtyHandler : std::unary_function<ScTable*, void>
+{
+    void operator() (ScTable* p)
+    {
+        if (p)
+            p->SetRelNameDirty();
+    }
+};
+
+struct BroadcastRecalcOnRefMoveHandler : std::unary_function<ScTable*, void>
+{
+    void operator() (ScTable* p)
+    {
+        if (p)
+            p->BroadcastRecalcOnRefMove();
+    }
+};
+
+}
 
 bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
                             SCROW nEndRow,   SCTAB nEndTab,
@@ -1394,17 +1424,15 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB 
nStartTab,
             StartAllListeners();
         }
         else
-        {// Listeners have been removed in UpdateReference
-            TableContainer::iterator it = maTabs.begin();
-            for (; it != maTabs.end(); ++it)
-                if (*it)
-                    (*it)->StartNeededListeners();
-            // at least all cells using range names pointing relative
-            // to the moved range must recalculate
-            it = maTabs.begin();
-            for (; it != maTabs.end(); ++it)
-                if (*it)
-                    (*it)->SetRelNameDirty();
+        {
+            // Listeners have been removed in UpdateReference
+            std::for_each(maTabs.begin(), maTabs.end(), 
StartNeededListenersHandler());
+            // at least all cells using range names pointing relative to the
+            // moved range must recalculate.
+            std::for_each(maTabs.begin(), maTabs.end(), 
SetRelNameDirtyHandler());
+            // Cells containing functions such as CELL, COLUMN or ROW may have
+            // changed their values on relocation. Broadcast them.
+            std::for_each(maTabs.begin(), maTabs.end(), 
BroadcastRecalcOnRefMoveHandler());
         }
         bRet = true;
     }
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 96839f1..5bbb6d3 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -48,6 +48,7 @@
 #include "editutil.hxx"
 #include "mtvcellfunc.hxx"
 #include "refupdatecontext.hxx"
+#include "scopetools.hxx"
 
 #include "scitems.hxx"
 #include <editeng/boxitem.hxx>
@@ -1705,6 +1706,12 @@ void ScTable::SetRelNameDirty()
     pDocument->SetAutoCalc( bOldAutoCalc );
 }
 
+void ScTable::BroadcastRecalcOnRefMove()
+{
+    sc::AutoCalcSwitch aSwitch(*pDocument, false);
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].BroadcastRecalcOnRefMove();
+}
 
 void ScTable::SetLoadingMedium(bool bLoading)
 {
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to