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

Kohei Yoshida kohei.yoshida at gmail.com
Thu Jul 25 10:33:26 PDT 2013


 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 <kohei.yoshida at gmail.com>
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 <fridrich at documentfoundation.org>
    Tested-by: Fridrich Strba <fridrich at documentfoundation.org>

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)
 {


More information about the Libreoffice-commits mailing list