[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 6 commits - sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Wed Mar 13 20:31:36 PDT 2013


 sc/inc/cell.hxx                  |    5 --
 sc/inc/column.hxx                |    2 
 sc/inc/document.hxx              |    2 
 sc/source/core/data/cell.cxx     |   10 +---
 sc/source/core/data/column.cxx   |   17 +++++++
 sc/source/core/data/documen8.cxx |   26 +++++-----
 sc/source/core/data/document.cxx |    7 ++
 sc/source/core/data/table1.cxx   |    5 +-
 sc/source/core/data/table5.cxx   |   94 +++++++++++++++++++++------------------
 9 files changed, 100 insertions(+), 68 deletions(-)

New commits:
commit 8ef7228dcf51b83a03ef780675c3baa0bdc642e7
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 23:30:32 2013 -0400

    We should exit the idle calc when the sheet changes.
    
    Otherwise the code would end up in an undefined state.
    
    Change-Id: I47f58698ac1eb94bf92ab7278bb7521d892ba340

diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 6684d32..9b9fecc 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -664,7 +664,10 @@ bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder vers
                     pColIter.reset(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
                 }
                 else
+                {
                     aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set.
+                    return false;
+                }
             }
         }
 
commit 2f850532e8cf56c4f076523120c5a12d8f9d5ffb
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 23:26:27 2013 -0400

    ScBaseCell::nTextWidth is no more.
    
    Change-Id: I32368d39a21d44bef8ab7fe265077cd147a50024

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index c84e985..5fbfb0b 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -101,10 +101,6 @@ public:
         Returns false for formula cells returning nothing, use HasEmptyData() for that. */
     bool            IsBlank() const;
 
-// for idle-calculations
-    inline sal_uInt16   GetTextWidth() const { return nTextWidth; }
-    inline void     SetTextWidth( sal_uInt16 nNew ) { nTextWidth = nNew; }
-
     inline sal_uInt8     GetScriptType() const { return nScriptType; }
     inline void     SetScriptType( sal_uInt8 nNew ) { nScriptType = nNew; }
 
@@ -148,7 +144,6 @@ private:
     SvtBroadcaster* mpBroadcaster;  /// Broadcaster for changed values. Cell takes ownership!
 
 protected:
-    sal_uInt16          nTextWidth;
     sal_uInt8            eCellType;      // enum CellType - sal_uInt8 spart Speicher
     sal_uInt8            nScriptType;
 };
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 8c3fac2..2f59ef1 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1844,6 +1844,8 @@ public:
     void RemoveSubTotalCell(ScFormulaCell* pCell);
     void SetSubTotalCellsDirty(const ScRange& rDirtyRange);
 
+    void SetTextWidth( const ScAddress& rPos, sal_uInt16 nWidth );
+
 private: // CLOOK-Impl-methods
 
     /**
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 5ffd85e..bc6367c 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -69,7 +69,6 @@ IMPL_FIXEDMEMPOOL_NEWDEL( ScNoteCell )
 
 ScBaseCell::ScBaseCell( CellType eNewType ) :
     mpBroadcaster( 0 ),
-    nTextWidth( TEXTWIDTH_DIRTY ),
     eCellType( sal::static_int_cast<sal_uInt8>(eNewType) ),
     nScriptType( SC_SCRIPTTYPE_UNKNOWN )
 {
@@ -77,7 +76,6 @@ ScBaseCell::ScBaseCell( CellType eNewType ) :
 
 ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
     mpBroadcaster( 0 ),
-    nTextWidth( rCell.nTextWidth ),
     eCellType( rCell.eCellType ),
     nScriptType( SC_SCRIPTTYPE_UNKNOWN )
 {
@@ -1002,7 +1000,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
     else
     {
         bChanged = true;
-        SetTextWidth( TEXTWIDTH_DIRTY );
+        pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
         SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
     }
     if ( bWasInFormulaTree )
@@ -1096,7 +1094,7 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
     else
     {
         bChanged = true;
-        SetTextWidth( TEXTWIDTH_DIRTY );
+        pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
         SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
     }
 
@@ -1367,7 +1365,7 @@ void ScFormulaCell::Interpret()
                             pIterCell->bTableOpDirty = false;
                             pIterCell->aResult.SetResultError( errNoConvergence);
                             pIterCell->bChanged = true;
-                            pIterCell->SetTextWidth( TEXTWIDTH_DIRTY);
+                            pDocument->SetTextWidth(pIterCell->aPos, TEXTWIDTH_DIRTY);
                             pIterCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN);
                         }
                     }
@@ -1662,7 +1660,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
         }
         if( bChanged )
         {
-            SetTextWidth( TEXTWIDTH_DIRTY );
+            pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
             SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
         }
         if (bContentChanged && pDocument->IsStreamValid(aPos.Tab()))
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 8cfc787..acce598 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5695,6 +5695,13 @@ void ScDocument::SetSubTotalCellsDirty(const ScRange& rDirtyRange)
     maSubTotalCells.swap(aNewSet); // update the list.
 }
 
+void ScDocument::SetTextWidth( const ScAddress& rPos, sal_uInt16 nWidth )
+{
+    SCTAB nTab = rPos.Tab();
+    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
+        maTabs[nTab]->SetTextWidth(rPos.Col(), rPos.Row(), nWidth);
+}
+
 void ScDocument::EnableUndo( bool bVal )
 {
     // The undo manager increases lock count every time undo is disabled.
commit c086bc89feee8aebff6c2d3086c56995db3ce8d7
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 23:04:20 2013 -0400

    MaybeAddExtraColumn() too.  This one is trivial.
    
    Change-Id: I0cd33c90bdb3c6b7cf48677140e3c66fa78caaba

diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index caf858f..be34e51 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1751,7 +1751,7 @@ void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, d
         return;
 
     bool bFormula = false;  //! ueberge
-    long nPixel = pCell->GetTextWidth();
+    long nPixel = aCol[rCol].GetTextWidth(nRow);
 
     // Breite bereits im Idle-Handler berechnet?
     if ( TEXTWIDTH_DIRTY == nPixel )
@@ -1764,7 +1764,8 @@ void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, d
         Fraction aZoom(1,1);
         nPixel = aCol[rCol].GetNeededSize(
             nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions );
-        pCell->SetTextWidth( (sal_uInt16)nPixel );
+
+        aCol[rCol].SetTextWidth(nRow, static_cast<sal_uInt16>(nPixel));
     }
 
     long nTwips = (long) (nPixel / nPPTX);
commit d355cf9f5d2cdd68fa45fe91a838f2161e45f001
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 22:59:38 2013 -0400

    InvalidateTextWidth() now uses the new iterator.
    
    No more SetTextWidth() directly to the cells.
    
    Change-Id: I0a2aba63685ea1461b763e8d628052ecd4c71c25

diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 74af647..355d2f1 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -36,6 +36,8 @@
 #include "tabprotection.hxx"
 #include "globstr.hrc"
 #include "segmenttree.hxx"
+#include "columniterator.hxx"
+
 #include <com/sun/star/sheet/TablePageBreakData.hpp>
 
 #include <algorithm>
@@ -1145,20 +1147,64 @@ void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* p
 {
     if ( pAdrFrom && !pAdrTo )
     {
-        ScBaseCell* pCell = aCol[pAdrFrom->Col()].GetCell( pAdrFrom->Row() );
-        if ( pCell )
+        // Special case: only process the "from" cell.
+        SCCOL nCol = pAdrFrom->Col();
+        SCROW nRow = pAdrFrom->Row();
+        ScColumn& rCol = aCol[nCol];
+        ScBaseCell* pCell = rCol.GetCell(nRow);
+        if (!pCell)
+            return;
+
+        rCol.SetTextWidth(nRow, TEXTWIDTH_DIRTY);
+
+        if ( bNumFormatChanged )
+            pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+
+        if ( bBroadcast )
+        {   // nur bei CalcAsShown
+            switch ( pCell->GetCellType() )
+            {
+                case CELLTYPE_VALUE :
+                    pDocument->Broadcast(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab), pCell);
+                    break;
+                case CELLTYPE_FORMULA :
+                    ((ScFormulaCell*)pCell)->SetDirty();
+                    break;
+                default:
+                {
+                    // added to avoid warnings
+                }
+            }
+        }
+
+        return;
+    }
+
+    const SCCOL nCol1 = pAdrFrom ? pAdrFrom->Col() : 0;
+    const SCROW nRow1 = pAdrFrom ? pAdrFrom->Row() : 0;
+    const SCCOL nCol2 = pAdrTo   ? pAdrTo->Col()   : MAXCOL;
+    const SCROW nRow2 = pAdrTo   ? pAdrTo->Row()   : MAXROW;
+
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+    {
+        ScColumnTextWidthIterator aIter(aCol[nCol], nRow1, nRow2);
+
+        for (; aIter.hasCell(); aIter.next())
         {
-            pCell->SetTextWidth( TEXTWIDTH_DIRTY );
+            SCROW nRow = aIter.getPos();
+            aIter.setValue(TEXTWIDTH_DIRTY);
+            ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+
             if ( bNumFormatChanged )
                 pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+
             if ( bBroadcast )
             {   // nur bei CalcAsShown
                 switch ( pCell->GetCellType() )
                 {
                     case CELLTYPE_VALUE :
                         pDocument->Broadcast( SC_HINT_DATACHANGED,
-                            ScAddress( pAdrFrom->Col(), pAdrFrom->Row(), nTab ),
-                            pCell );
+                            ScAddress( nCol, nRow, nTab ), pCell );
                         break;
                     case CELLTYPE_FORMULA :
                         ((ScFormulaCell*)pCell)->SetDirty();
@@ -1171,44 +1217,6 @@ void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* p
             }
         }
     }
-    else
-    {
-        const SCCOL nColStart = pAdrFrom ? pAdrFrom->Col() : 0;
-        const SCROW nRowStart = pAdrFrom ? pAdrFrom->Row() : 0;
-        const SCCOL nColEnd   = pAdrTo   ? pAdrTo->Col()   : MAXCOL;
-        const SCROW nRowEnd   = pAdrTo   ? pAdrTo->Row()   : MAXROW;
-
-        for ( SCCOL nCol=nColStart; nCol<=nColEnd; nCol++ )
-        {
-            ScColumnIterator aIter( &aCol[nCol], nRowStart, nRowEnd );
-            ScBaseCell*      pCell = NULL;
-            SCROW            nRow  = nRowStart;
-
-            while ( aIter.Next( nRow, pCell ) )
-            {
-                pCell->SetTextWidth( TEXTWIDTH_DIRTY );
-                if ( bNumFormatChanged )
-                    pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
-                if ( bBroadcast )
-                {   // nur bei CalcAsShown
-                    switch ( pCell->GetCellType() )
-                    {
-                        case CELLTYPE_VALUE :
-                            pDocument->Broadcast( SC_HINT_DATACHANGED,
-                                ScAddress( nCol, nRow, nTab ), pCell );
-                            break;
-                        case CELLTYPE_FORMULA :
-                            ((ScFormulaCell*)pCell)->SetDirty();
-                            break;
-                        default:
-                        {
-                            // added to avoid warnings
-                        }
-                    }
-                }
-            }
-        }
-    }
 }
 
 
commit 8830cb63522f208e897de256f6e30db06b0a9a5e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 22:54:14 2013 -0400

    Forgot to increment the iterator.
    
    Change-Id: Ica8c9be8a383879a509d90c6da6309d2eee4fe8c

diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index e9bf545..6684d32 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -604,6 +604,7 @@ bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder vers
                 pColIter->setValue(nNewWidth);
                 aScope.setNeedMore(true);
             }
+            pColIter->next();
         }
         else
         {
commit 7f331c66c8e68b6f6b54a221fecca51fca66c144
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 22:34:23 2013 -0400

    IdleCalcTextWidth() now sets cell text widths to the new container.
    
    No more direct access to ScBaseCell's nTextWidth.
    
    Change-Id: I5a0a5fd24555d9fa8e1de895f0f9d8b710cc8094

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index f1996f1..0a699d3 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -244,6 +244,8 @@ public:
     bool    HasValueData( SCROW nRow ) const;
     bool    HasStringCells( SCROW nStartRow, SCROW nEndRow ) const;
 
+    bool IsFormulaDirty( SCROW nRow ) const;
+
     void        SetDirty();
     void        SetDirty( const ScRange& );
     void        SetDirtyVar();
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index e81456d..6082ed6 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2008,6 +2008,23 @@ void ScColumn::SetDirtyVar()
     }
 }
 
+bool ScColumn::IsFormulaDirty( SCROW nRow ) const
+{
+    if (!ValidRow(nRow))
+        return false;
+
+    SCSIZE nIndex;
+    if (!Search(nRow, nIndex))
+        // No cell at this row position.
+        return false;
+
+    const ScBaseCell* pCell = maItems[nIndex].pCell;
+    if (pCell->GetCellType() != CELLTYPE_FORMULA)
+        // Not even a formula cell.
+        return false;
+
+    return static_cast<const ScFormulaCell*>(pCell)->GetDirty();
+}
 
 void ScColumn::SetDirty()
 {
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 263dc74..e9bf545 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -495,6 +495,8 @@ public:
     SCCOL Col() const { return mrCalcPos.Col(); }
     SCROW Row() const { return mrCalcPos.Row(); }
 
+    const ScAddress& Pos() const { return mrCalcPos; }
+
     void setTab(SCTAB nTab) { mrCalcPos.SetTab(nTab); }
     void setCol(SCCOL nCol) { mrCalcPos.SetCol(nCol); }
     void setRow(SCROW nRow) { mrCalcPos.SetRow(nRow); }
@@ -563,21 +565,20 @@ bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder vers
 
     // Start at specified cell position (nCol, nRow, nTab).
     ScColumn* pCol  = &pTab->aCol[aScope.Col()];
-    boost::scoped_ptr<ScColumnIterator> pColIter(new ScColumnIterator(pCol, aScope.Row(), MAXROW));
+    boost::scoped_ptr<ScColumnTextWidthIterator> pColIter(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
 
     OutputDevice* pDev = NULL;
     sal_uInt16 nRestart = 0;
     sal_uInt16 nCount = 0;
     while ( (nZoom > 0) && (nCount < CALCMAX) && (nRestart < 2) )
     {
-        SCROW nRow;
-        ScBaseCell* pCell = NULL;
-        if ( pColIter->Next(nRow, pCell) )
+        if (pColIter->hasCell())
         {
             // More cell in this column.
+            SCROW nRow = pColIter->getPos();
             aScope.setRow(nRow);
 
-            if ( TEXTWIDTH_DIRTY == pCell->GetTextWidth() )
+            if (pColIter->getValue() == TEXTWIDTH_DIRTY)
             {
                 // Calculate text width for this cell.
                 double nPPTX = 0.0;
@@ -593,17 +594,14 @@ bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder vers
                     nPPTY = aPix1000.Y() / 1000.0;
                 }
 
-                if (!aScope.hasProgressBar() && pCell->GetCellType() == CELLTYPE_FORMULA
-                    && ((ScFormulaCell*)pCell)->GetDirty())
-                {
+                if (!aScope.hasProgressBar() && pCol->IsFormulaDirty(nRow))
                     aScope.createProgressBar();
-                }
 
                 sal_uInt16 nNewWidth = (sal_uInt16)GetNeededSize(
                     aScope.Col(), aScope.Row(), aScope.Tab(),
                     pDev, nPPTX, nPPTY, aZoomFract,aZoomFract, true, true);   // bTotalSize
 
-                pCell->SetTextWidth( nNewWidth );
+                pColIter->setValue(nNewWidth);
                 aScope.setNeedMore(true);
             }
         }
@@ -662,14 +660,14 @@ bool ScDocument::IdleCalcTextWidth()            // true = demnaechst wieder vers
                 if ( nZoom > 0 )
                 {
                     pCol  = &pTab->aCol[aScope.Col()];
-                    pColIter.reset(new ScColumnIterator(pCol, aScope.Row(), MAXROW));
+                    pColIter.reset(new ScColumnTextWidthIterator(*pCol, aScope.Row(), MAXROW));
                 }
                 else
                     aScope.incTab(); // Move to the next sheet as the current one has scale-to-pages set.
             }
         }
 
-        nCount++;
+        ++nCount;
 
         // Quit if either 1) its duration exceeds 50 ms, or 2) there is any
         // pending event after processing 32 cells.


More information about the Libreoffice-commits mailing list