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

Eike Rathke erack at redhat.com
Mon Jan 27 01:42:23 PST 2014


 sc/inc/column.hxx                   |    2 -
 sc/inc/formulacell.hxx              |    5 +++-
 sc/inc/table.hxx                    |    7 +++++-
 sc/source/core/data/column.cxx      |    4 +--
 sc/source/core/data/document.cxx    |   26 ++++++++++++-----------
 sc/source/core/data/formulacell.cxx |   40 ++++++++++++++++++++----------------
 sc/source/core/data/table2.cxx      |    4 +--
 7 files changed, 52 insertions(+), 36 deletions(-)

New commits:
commit b99a2691484e9b0533530ad4f02e15ad4031b74b
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Jan 23 22:40:16 2014 +0100

    resolved fdo#71598 postpone SetDirty during Insert/Delete
    
    ... until after all listeners are re-established.
    
    (cherry picked from commit 20b7476142f75b49d10a75e48429a94cff0cec32)
    
    Conflicts:
    	sc/inc/formulacell.hxx
    	sc/inc/table.hxx
    	sc/source/core/data/column.cxx
    	sc/source/core/data/document.cxx
    	sc/source/core/data/formulacell.cxx
    
    Backported.
    
    Change-Id: I9f6036d4bcc9206191959a88ed5439b9860ca268
    Reviewed-on: https://gerrit.libreoffice.org/7624
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    Tested-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1dd462d..83ccf09 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -446,7 +446,7 @@ public:
     void        MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow );
     void        StartAllListeners();
     void        StartNeededListeners(); // only for cells where NeedsListening()==true
-    void        SetRelNameDirty();
+    void        SetDirtyIfPostponed();
     void BroadcastRecalcOnRefMove();
 
     void        CompileDBFormula();
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 747d67f..fd4af05 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -90,6 +90,7 @@ private:
     bool            bTableOpDirty  : 1; // Dirty flag for TableOp
     bool            bNeedListening : 1; // Listeners need to be re-established after UpdateReference
     bool            mbNeedsNumberFormat : 1; // set the calculated number format as hard number format
+    bool            mbPostponedDirty : 1;   // if cell needs to be set dirty later
 
                     enum ScInterpretTailParameter
                     {
@@ -149,7 +150,7 @@ public:
     void            SetTableOpDirty();
     bool            IsDirtyOrInTableOpDirty() const;
     bool            GetDirty() const { return bDirty; }
-    void            ResetDirty() { bDirty = false; }
+    void            ResetDirty() { bDirty = bTableOpDirty = mbPostponedDirty = false; }
     bool            NeedsListening() const { return bNeedListening; }
     void            SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
     void            SetNeedNumberFormat( bool bVal ) { mbNeedsNumberFormat = bVal; }
@@ -304,6 +305,8 @@ public:
     void EndListeningTo(
         ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
     void EndListeningTo( sc::EndListeningContext& rCxt );
+
+    bool IsPostponedDirty() const { return mbPostponedDirty; }
 };
 
 #endif
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 20b0ed7..7f95d7f 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -854,6 +854,12 @@ public:
     bool HasBroadcaster( SCCOL nCol ) const;
 
     /**
+     * Mark formula cells dirty that have the mbPostponedDirty flag set or
+     * contain named ranges with relative references.
+     */
+    void SetDirtyIfPostponed();
+
+    /**
      * Broadcast dirty formula cells that contain functions such as CELL(),
      * COLUMN() or ROW() which may change its value on move.
      */
@@ -961,7 +967,6 @@ private:
     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 305eeb5..984633c 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2168,14 +2168,14 @@ void ScColumn::SetDirtyAfterLoad()
 }
 
 
-void ScColumn::SetRelNameDirty()
+void ScColumn::SetDirtyIfPostponed()
 {
     bool bOldAutoCalc = pDocument->GetAutoCalc();
     pDocument->SetAutoCalc( false );    // no multiple recalculation
     for (SCSIZE i=0; i<maItems.size(); i++)
     {
         ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
-        if( p->GetCellType() == CELLTYPE_FORMULA && p->HasRelNameReference() )
+        if( p->GetCellType() == CELLTYPE_FORMULA && (p->IsPostponedDirty() || p->HasRelNameReference()) )
             p->SetDirty();
     }
     pDocument->SetAutoCalc( bOldAutoCalc );
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 02d6e21..6369388 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1200,12 +1200,13 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
             for (; it != maTabs.end(); ++it)
                 if (*it)
                     (*it)->StartNeededListeners();
-            // at least all cells using range names pointing relative
-            // to the moved range must recalculate
+            // At least all cells using range names pointing relative to the
+            // moved range must be recalculated, and all cells marked postponed
+            // dirty.
             it = maTabs.begin();
             for (; it != maTabs.end(); ++it)
                 if (*it)
-                    (*it)->SetRelNameDirty();
+                    (*it)->SetDirtyIfPostponed();
 
             // Cells containing functions such as CELL, COLUMN or ROW may have
             // changed their values on relocation. Broadcast them.
@@ -1295,12 +1296,12 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
         for (; it != maTabs.end(); ++it)
             if (*it)
                 (*it)->StartNeededListeners();
-        // at least all cells using range names pointing relative
-        // to the moved range must recalculate
+        // At least all cells using range names pointing relative to the moved
+        // range must be recalculated, and all cells marked postponed dirty.
         it = maTabs.begin();
         for (; it != maTabs.end(); ++it)
             if (*it)
-                (*it)->SetRelNameDirty();
+                (*it)->SetDirtyIfPostponed();
 
         // Cells containing functions such as CELL, COLUMN or ROW may have
         // changed their values on relocation. Broadcast them.
@@ -1404,12 +1405,13 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
             for (; it != maTabs.end(); ++it)
                 if (*it)
                     (*it)->StartNeededListeners();
-            // at least all cells using range names pointing relative
-            // to the moved range must recalculate
+            // At least all cells using range names pointing relative to the
+            // moved range must be recalculated, and all cells marked postponed
+            // dirty.
             it = maTabs.begin();
             for (; it != maTabs.end(); ++it)
                 if (*it)
-                    (*it)->SetRelNameDirty();
+                    (*it)->SetDirtyIfPostponed();
 
             // Cells containing functions such as CELL, COLUMN or ROW may have
             // changed their values on relocation. Broadcast them.
@@ -1497,12 +1499,12 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA
         for (; it != maTabs.end(); ++it)
             if (*it)
                 (*it)->StartNeededListeners();
-        // at least all cells using range names pointing relative
-        // to the moved range must recalculate
+        // At least all cells using range names pointing relative to the moved
+        // range must be recalculated, and all cells marked postponed dirty.
         it = maTabs.begin();
         for (; it != maTabs.end(); ++it)
             if (*it)
-                (*it)->SetRelNameDirty();
+                (*it)->SetDirtyIfPostponed();
 
         // Cells containing functions such as CELL, COLUMN or ROW may have
         // changed their values on relocation. Broadcast them.
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index b75bdcc..5ebf9b3 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -414,6 +414,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
     bTableOpDirty( false ),
     bNeedListening( false ),
     mbNeedsNumberFormat( false ),
+    mbPostponedDirty(false),
     aPos( rPos )
 {
     Compile( rFormula, true, eGrammar );    // bNoListening, Insert does that
@@ -448,6 +449,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
     bTableOpDirty( false ),
     bNeedListening( false ),
     mbNeedsNumberFormat( false ),
+    mbPostponedDirty(false),
     aPos( rPos )
 {
     // UPN-Array generation
@@ -494,6 +496,7 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
     bTableOpDirty( false ),
     bNeedListening( false ),
     mbNeedsNumberFormat( false ),
+    mbPostponedDirty(false),
     aPos( rPos )
 {
     pCode = rCell.pCode->Clone();
@@ -1094,8 +1097,7 @@ void ScFormulaCell::Interpret()
                             // If one cell didn't converge, all cells of this
                             // circular dependency don't, no matter whether
                             // single cells did.
-                            pIterCell->bDirty = false;
-                            pIterCell->bTableOpDirty = false;
+                            pIterCell->ResetDirty();
                             pIterCell->aResult.SetResultError( errNoConvergence);
                             pIterCell->bChanged = true;
                             pDocument->SetTextWidth(pIterCell->aPos, TEXTWIDTH_DIRTY);
@@ -1251,8 +1253,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
 
         if( p->GetError() && p->GetError() != errCircularReference)
         {
-            bDirty = false;
-            bTableOpDirty = false;
+            ResetDirty();
             bChanged = true;
         }
         if (eTailParam == SCITP_FROM_ITERATION && IsDirtyOrInTableOpDirty())
@@ -1275,8 +1276,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
                 if (nSeenInIteration > 1 ||
                         pDocument->GetDocOptions().GetIterCount() == 1)
                 {
-                    bDirty = false;
-                    bTableOpDirty = false;
+                    ResetDirty();
                 }
             }
         }
@@ -1377,8 +1377,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
         }
         if (eTailParam == SCITP_NORMAL)
         {
-            bDirty = false;
-            bTableOpDirty = false;
+            ResetDirty();
         }
         if( aResult.GetMatrix() )
         {
@@ -1460,9 +1459,8 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
     else
     {
         // Cells with compiler errors should not be marked dirty forever
-        OSL_ENSURE( pCode->GetCodeError(), "no UPN-Code und no errors ?!?!" );
-        bDirty = false;
-        bTableOpDirty = false;
+        OSL_ENSURE( pCode->GetCodeError(), "no RPN code und no errors ?!?!" );
+        ResetDirty();
     }
 }
 
@@ -1546,7 +1544,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
             // by Scenario and Copy Block From Clip.
             // If unconditional required Formula tracking is set before SetDirty
             // bDirty = false, eg in CompileTokenArray
-            if ( !bDirty || !pDocument->IsInFormulaTree( this ) )
+            if ( !bDirty || mbPostponedDirty || !pDocument->IsInFormulaTree( this ) )
             {
                 if( bDirtyFlag )
                     SetDirtyVar();
@@ -1563,6 +1561,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
 void ScFormulaCell::SetDirtyVar()
 {
     bDirty = true;
+    mbPostponedDirty = false;
     // mark the sheet of this cell to be calculated
     //#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() );
 }
@@ -2293,11 +2292,18 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
         }
         if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
         {   // Cut off references, invalid or similar?
-            bool bOldAutoCalc = pDocument->GetAutoCalc();
-            // No Interpret in SubMinimalRecalc because of eventual wrong reference
-            pDocument->SetAutoCalc( false );
-            SetDirty();
-            pDocument->SetAutoCalc( bOldAutoCalc );
+            if (eUpdateRefMode == URM_INSDEL)
+            {
+                mbPostponedDirty = true;
+            }
+            else
+            {
+                bool bOldAutoCalc = pDocument->GetAutoCalc();
+                // No Interpret in SubMinimalRecalc because of eventual wrong reference
+                pDocument->SetAutoCalc( false );
+                SetDirty();
+                pDocument->SetAutoCalc( bOldAutoCalc );
+            }
         }
 
         delete pOld;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 6c530d3..821ab92 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1670,12 +1670,12 @@ void ScTable::SetDirtyAfterLoad()
 }
 
 
-void ScTable::SetRelNameDirty()
+void ScTable::SetDirtyIfPostponed()
 {
     bool bOldAutoCalc = pDocument->GetAutoCalc();
     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
     for (SCCOL i=0; i<=MAXCOL; i++)
-        aCol[i].SetRelNameDirty();
+        aCol[i].SetDirtyIfPostponed();
     pDocument->SetAutoCalc( bOldAutoCalc );
 }
 


More information about the Libreoffice-commits mailing list