sc/inc/column.hxx                |    1 +
 sc/inc/table.hxx                 |    6 ++++++
 sc/source/core/data/column.cxx   |   21 +++++++++++++++++++++
 sc/source/core/data/document.cxx |   28 ++++++++++++++++++++++++++++
 sc/source/core/data/table2.cxx   |    8 ++++++++
 5 files changed, 64 insertions(+)

New commits:
commit 7299db371e38d1a3ecd51eb3811344ee5bb3a086
Author: Kohei Yoshida <[email protected]>
Date:   Thu Jul 25 12:24:01 2013 -0400

    Propagate change on COLUMN() and ROW() functions on position change.
    
    1) Insert =COLUMN() or =ROW() in arbitrary cell.
    2) Have another cell reference that cell.
    3) Insert or delete column or row to change the cell that contains
       COLUMN or ROW function. This will change the result of that cell.
    4) Check the result of the 2nd cell that references the first.  The
       value change is not propagated.
    
    This commit fixes that.
    
    NB: master has a similar but different fix. Due to the difference in
    cell storage between master and 4.1, I had to devise a different fix
    for the 4.1 branch.
    
    Change-Id: Ib1b730e7a4a70a11b967b88730a68362e061a8a0
    Reviewed-on: https://gerrit.libreoffice.org/5113
    Reviewed-by: Fridrich Strba <[email protected]>
    Tested-by: Fridrich Strba <[email protected]>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index dfc46b0..935c07e 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -440,6 +440,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 b62fa1e..20b0ed7 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -853,6 +853,12 @@ public:
     void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, 
SCROW nRow1, SCROW nRow2 );
     bool HasBroadcaster( SCCOL nCol ) const;
 
+    /**
+     * Broadcast dirty formula cells that contain functions such as CELL(),
+     * COLUMN() or ROW() which may change its value on move.
+     */
+    void BroadcastRecalcOnRefMove();
+
     /** Replace behaves differently to the Search; adjust the rCol and rRow 
accordingly.
 
         'Replace' replaces at the 'current' position, but in order to achieve
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 88cb65d..b687489 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2175,6 +2175,27 @@ void ScColumn::SetRelNameDirty()
     pDocument->SetAutoCalc( bOldAutoCalc );
 }
 
+void ScColumn::BroadcastRecalcOnRefMove()
+{
+    bool bOldAutoCalc = pDocument->GetAutoCalc();
+    pDocument->SetAutoCalc( false );    // no multiple recalculation
+
+    ScHint aHint(SC_HINT_DATACHANGED, ScAddress(nCol, 0, nTab));
+    for (SCSIZE i=0; i<maItems.size(); i++)
+    {
+        if (maItems[i].pCell->GetCellType() != CELLTYPE_FORMULA)
+            continue;
+
+        ScFormulaCell* p = static_cast<ScFormulaCell*>(maItems[i].pCell);
+        if (p->GetDirty() && p->GetCode()->IsRecalcModeOnRefMove())
+        {
+            aHint.GetAddress().SetRow(maItems[i].nRow);
+            pDocument->Broadcast(aHint);
+        }
+
+    }
+    pDocument->SetAutoCalc( bOldAutoCalc );
+}
 
 void ScColumn::CalcAll()
 {
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 4933e5d..02d6e21 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1115,6 +1115,18 @@ bool ScDocument::CanInsertRow( const ScRange& rRange ) 
const
     return bTest;
 }
 
+namespace {
+
+struct BroadcastRecalcOnRefMoveHandler : std::unary_function<ScTable*, void>
+{
+    void operator() (ScTable* p)
+    {
+        if (p)
+            p->BroadcastRecalcOnRefMove();
+    }
+};
+
+}
 
 bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
                             SCCOL nEndCol,   SCTAB nEndTab,
@@ -1194,6 +1206,10 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB 
nStartTab,
             for (; it != maTabs.end(); ++it)
                 if (*it)
                     (*it)->SetRelNameDirty();
+
+            // 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;
     }
@@ -1285,6 +1301,10 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB 
nStartTab,
         for (; it != maTabs.end(); ++it)
             if (*it)
                 (*it)->SetRelNameDirty();
+
+        // 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());
     }
 
     SetAutoCalc( bOldAutoCalc );
@@ -1390,6 +1410,10 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB 
nStartTab,
             for (; it != maTabs.end(); ++it)
                 if (*it)
                     (*it)->SetRelNameDirty();
+
+            // 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;
     }
@@ -1479,6 +1503,10 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB 
nStartTab, SCROW nEndRow, SCTA
         for (; it != maTabs.end(); ++it)
             if (*it)
                 (*it)->SetRelNameDirty();
+
+        // 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());
     }
 
     SetAutoCalc( bOldAutoCalc );
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index a44c602..4786d30 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1664,6 +1664,14 @@ void ScTable::SetRelNameDirty()
     pDocument->SetAutoCalc( bOldAutoCalc );
 }
 
+void ScTable::BroadcastRecalcOnRefMove()
+{
+    bool bOldAutoCalc = pDocument->GetAutoCalc();
+    pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
+    for (SCCOL i = 0; i <= MAXCOL; ++i)
+        aCol[i].BroadcastRecalcOnRefMove();
+    pDocument->SetAutoCalc( bOldAutoCalc );
+}
 
 void ScTable::SetLoadingMedium(bool bLoading)
 {
_______________________________________________
Libreoffice-commits mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to