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

Kohei Yoshida kohei.yoshida at gmail.com
Fri May 17 09:38:49 PDT 2013


 sc/inc/clipcontext.hxx              |    7 ++++++
 sc/inc/column.hxx                   |    3 +-
 sc/inc/table.hxx                    |   10 +++++----
 sc/source/core/data/clipcontext.cxx |    3 ++
 sc/source/core/data/column.cxx      |   36 ++++++++++++++++++++++++----------
 sc/source/core/data/documen2.cxx    |    9 ++++++--
 sc/source/core/data/document.cxx    |   38 ++++++++++++++++++++++++++----------
 sc/source/core/data/table2.cxx      |   18 ++++++++++-------
 8 files changed, 90 insertions(+), 34 deletions(-)

New commits:
commit 0b6304c54973df70f4c18117ed83c6f8da02d6c9
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri May 17 12:40:17 2013 -0400

    Do the same thing for CopyToDocument.
    
    This removes O(n^2) slowness from undo and redo of a large array of
    cells with empty cells in between.
    
    Change-Id: Id87c8ac8986c97ddf305f849a4752f0f92cc5899

diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx
index 0df627c..4d9224f 100644
--- a/sc/inc/clipcontext.hxx
+++ b/sc/inc/clipcontext.hxx
@@ -83,6 +83,13 @@ public:
     bool isCloneNotes() const;
 };
 
+class CopyToDocContext : public ClipContextBase
+{
+public:
+    CopyToDocContext(ScDocument& rDoc);
+    virtual ~CopyToDocContext();
+};
+
 }
 
 #endif
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 4e5688c..1165ee3 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -40,6 +40,7 @@ namespace sc {
     class EndListeningContext;
     class CopyFromClipContext;
     class CopyToClipContext;
+    class CopyToDocContext;
     struct ColumnBlockPosition;
 }
 
@@ -252,7 +253,7 @@ public:
         ScFunctionData& rData, ScFlatBoolRowSegments& rHiddenRows, SCROW nStartRow, SCROW nEndRow) const;
 
     void CopyToColumn(
-        SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked,
+        sc::CopyToDocContext& rCxt, SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked,
         ScColumn& rColumn, const ScMarkData* pMarkData = NULL, bool bAsLink = false) const;
 
     void UndoToColumn(
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 9b0d4d2..c40e5ec 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -52,6 +52,7 @@ namespace sc {
     class EndListeningContext;
     class CopyFromClipContext;
     class CopyToClipContext;
+    class CopyToDocContext;
     struct ColumnBlockPosition;
 }
 
@@ -396,10 +397,11 @@ public:
     void        BroadcastInArea( SCCOL nCol1, SCROW nRow1,
                                     SCCOL nCol2, SCROW nRow2 );
 
-    void        CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
-                            sal_uInt16 nFlags, bool bMarked, ScTable* pDestTab,
-                            const ScMarkData* pMarkData = NULL,
-                            bool bAsLink = false, bool bColRowFlags = true);
+    void CopyToTable(
+        sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+        sal_uInt16 nFlags, bool bMarked, ScTable* pDestTab,
+        const ScMarkData* pMarkData = NULL, bool bAsLink = false, bool bColRowFlags = true );
+
     void        UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                             sal_uInt16 nFlags, bool bMarked, ScTable* pDestTab,
                             const ScMarkData* pMarkData = NULL);
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 8a02cea..8777aa3 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -117,6 +117,9 @@ bool CopyToClipContext::isCloneNotes() const
     return mbCloneNotes;
 }
 
+CopyToDocContext::CopyToDocContext(ScDocument& rDoc) : ClipContextBase(rDoc) {}
+CopyToDocContext::~CopyToDocContext() {}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 9fb6406..d196223 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1368,6 +1368,7 @@ void ScColumn::CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDes
 }
 
 void ScColumn::CopyToColumn(
+    sc::CopyToDocContext& rCxt,
     SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked, ScColumn& rColumn,
     const ScMarkData* pMarkData, bool bAsLink) const
 {
@@ -1381,7 +1382,7 @@ void ScColumn::CopyToColumn(
             while ( aIter.Next( nStart, nEnd ) && nStart <= nRow2 )
             {
                 if ( nEnd >= nRow1 )
-                    CopyToColumn( std::max(nRow1,nStart), std::min(nRow2,nEnd),
+                    CopyToColumn(rCxt, std::max(nRow1,nStart), std::min(nRow2,nEnd),
                                     nFlags, false, rColumn, pMarkData, bAsLink );
             }
         }
@@ -1443,6 +1444,7 @@ void ScColumn::CopyToColumn(
                     // Special case to allow removing of cell instances.  A
                     // string cell with empty content is used to indicate an
                     // empty cell.
+                    sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
                     if (pNew->GetCellType() == CELLTYPE_STRING)
                     {
                         OUString aStr = static_cast<ScStringCell*>(pNew)->GetString();
@@ -1450,11 +1452,21 @@ void ScColumn::CopyToColumn(
                             // A string cell with empty string.  Delete the cell itself.
                             rColumn.Delete(maItems[i].nRow);
                         else
+                        {
                             // non-empty string cell
-                            rColumn.Insert(maItems[i].nRow, pNew);
+                            if (p)
+                                rColumn.Insert(*p, maItems[i].nRow, pNew);
+                            else
+                                rColumn.Insert(maItems[i].nRow, pNew);
+                        }
                     }
                     else
-                        rColumn.Insert(maItems[i].nRow, pNew);
+                    {
+                        if (p)
+                            rColumn.Insert(*p, maItems[i].nRow, pNew);
+                        else
+                            rColumn.Insert(maItems[i].nRow, pNew);
+                    }
                 }
             }
         }
@@ -1466,13 +1478,15 @@ void ScColumn::UndoToColumn(
     SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked, ScColumn& rColumn,
     const ScMarkData* pMarkData) const
 {
+    sc::CopyToDocContext aCxt(*rColumn.pDocument);
+    aCxt.setTabRange(rColumn.nTab, rColumn.nTab);
     if (nRow1 > 0)
-        CopyToColumn( 0, nRow1-1, IDF_FORMULA, false, rColumn );
+        CopyToColumn(aCxt, 0, nRow1-1, IDF_FORMULA, false, rColumn);
 
-    CopyToColumn( nRow1, nRow2, nFlags, bMarked, rColumn, pMarkData );      //! bMarked ????
+    CopyToColumn(aCxt, nRow1, nRow2, nFlags, bMarked, rColumn, pMarkData);      //! bMarked ????
 
     if (nRow2 < MAXROW)
-        CopyToColumn( nRow2+1, MAXROW, IDF_FORMULA, false, rColumn );
+        CopyToColumn(aCxt, nRow2+1, MAXROW, IDF_FORMULA, false, rColumn);
 }
 
 
@@ -1501,7 +1515,8 @@ void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
 void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
 {
     //  This is the scenario table, the data is copied into it
-
+    sc::CopyToDocContext aCxt(*pDocument);
+    aCxt.setTabRange(nTab, nTab);
     ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
     SCROW nStart = -1, nEnd = -1;
     const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
@@ -1511,7 +1526,7 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
         {
             DeleteArea( nStart, nEnd, IDF_CONTENTS );
             ((ScColumn&)rSrcCol).
-                CopyToColumn( nStart, nEnd, IDF_CONTENTS, false, *this );
+                CopyToColumn(aCxt, nStart, nEnd, IDF_CONTENTS, false, *this);
 
             //  UpdateUsed not needed, already done in TestCopyScenario (obsolete comment ?)
 
@@ -1532,7 +1547,8 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol )
 void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
 {
     //  This is the scenario table, the data is copied to the other
-
+    sc::CopyToDocContext aCxt(*rDestCol.pDocument);
+    aCxt.setTabRange(rDestCol.nTab, rDestCol.nTab);
     ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW );
     SCROW nStart = -1, nEnd = -1;
     const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd );
@@ -1542,7 +1558,7 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const
         {
             rDestCol.DeleteArea( nStart, nEnd, IDF_CONTENTS );
             ((ScColumn*)this)->
-                CopyToColumn( nStart, nEnd, IDF_CONTENTS, false, rDestCol );
+                CopyToColumn(aCxt, nStart, nEnd, IDF_CONTENTS, false, rDestCol);
 
             //  UpdateUsed not needed, is already done in TestCopyScenario (obsolete comment ?)
 
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 5a45fda..0229c52 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -86,6 +86,7 @@
 #include "macromgr.hxx"
 #include "cell.hxx"
 #include "formulacell.hxx"
+#include "clipcontext.hxx"
 
 using namespace com::sun::star;
 
@@ -855,8 +856,10 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
     }
     if (bValid)
     {
+        sc::CopyToDocContext aCxt(*this);
+        aCxt.setTabRange(nNewPos, nNewPos);
         SetNoListening( true );     // noch nicht bei CopyToTable/Insert
-        maTabs[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
+        maTabs[nOldPos]->CopyToTable(aCxt, 0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL),
                                         maTabs[nNewPos], pOnlyMarked );
         maTabs[nNewPos]->SetTabBgColor(maTabs[nOldPos]->GetTabBgColor());
 
@@ -961,10 +964,12 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
         {
             NumFmtMergeHandler aNumFmtMergeHdl(this, pSrcDoc);
 
+            sc::CopyToDocContext aCxt(*this);
+            aCxt.setTabRange(nDestPos, nDestPos);
             nDestPos = std::min(nDestPos, (SCTAB)(GetTableCount() - 1));
             {   // scope for bulk broadcast
                 ScBulkBroadcast aBulkBroadcast( pBASM);
-                pSrcDoc->maTabs[nSrcPos]->CopyToTable(0, 0, MAXCOL, MAXROW,
+                pSrcDoc->maTabs[nSrcPos]->CopyToTable(aCxt, 0, 0, MAXCOL, MAXROW,
                         ( bResultsOnly ? IDF_ALL & ~IDF_FORMULA : IDF_ALL),
                         false, maTabs[nDestPos] );
                 maTabs[nDestPos]->CopyConditionalFormat(0, 0, MAXCOL, MAXROW,
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index cd4a3bf..44668ac 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1841,12 +1841,14 @@ void ScDocument::CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
         pDestDoc->aDocName = aDocName;
     if (ValidTab(nTab1) && ValidTab(nTab2))
     {
+        sc::CopyToDocContext aCxt(*pDestDoc);
+        aCxt.setTabRange(nTab1, nTab2);
         bool bOldAutoCalc = pDestDoc->GetAutoCalc();
         pDestDoc->SetAutoCalc( false );     // avoid multiple calculations
         for (SCTAB i = nTab1; i <= nTab2 && i < static_cast<SCTAB>(maTabs.size()); i++)
         {
             if (maTabs[i] && i < static_cast<SCTAB>(pDestDoc->maTabs.size()) && pDestDoc->maTabs[i])
-                maTabs[i]->CopyToTable( nCol1, nRow1, nCol2, nRow2, nFlags,
+                maTabs[i]->CopyToTable(aCxt, nCol1, nRow1, nCol2, nRow2, nFlags,
                                       bOnlyMarked, pDestDoc->maTabs[i], pMarks,
                                       false, bColRowFlags );
         }
@@ -1896,12 +1898,19 @@ void ScDocument::CopyToDocument(const ScRange& rRange,
         pDestDoc->aDocName = aDocName;
     bool bOldAutoCalc = pDestDoc->GetAutoCalc();
     pDestDoc->SetAutoCalc( false );     // avoid multiple calculations
+
+    sc::CopyToDocContext aCxt(*pDestDoc);
+    aCxt.setTabRange(aNewRange.aStart.Tab(), aNewRange.aEnd.Tab());
     for (SCTAB i = aNewRange.aStart.Tab(); i <= aNewRange.aEnd.Tab() && i < static_cast<SCTAB>(maTabs.size()); i++)
-        if (maTabs[i] && i < static_cast<SCTAB>(pDestDoc->maTabs.size()) && pDestDoc->maTabs[i])
-            maTabs[i]->CopyToTable(aNewRange.aStart.Col(), aNewRange.aStart.Row(),
-                                 aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
-                                 nFlags, bOnlyMarked, pDestDoc->maTabs[i],
-                                 pMarks, false, bColRowFlags);
+    {
+        if (!TableExists(i) || !pDestDoc->TableExists(i))
+            continue;
+
+        maTabs[i]->CopyToTable(aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(),
+                               aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
+                               nFlags, bOnlyMarked, pDestDoc->maTabs[i],
+                               pMarks, false, bColRowFlags);
+    }
     pDestDoc->SetAutoCalc( bOldAutoCalc );
 }
 
@@ -2862,6 +2871,8 @@ void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
         bool bOldAutoCalc = GetAutoCalc();
         SetAutoCalc( false );                   // avoid multiple calculations
 
+        sc::CopyToDocContext aCxt(*this);
+        aCxt.setTabRange(rMark.GetFirstSelected(), rMark.GetLastSelected());
         SCTAB nCount = static_cast<SCTAB>(maTabs.size());
         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
         for (; itr != itrEnd && *itr < nCount; ++itr)
@@ -2877,11 +2888,13 @@ void ScDocument::FillTab( const ScRange& rSrcArea, const ScMarkData& rMark,
                     }
                     else
                         pMixDoc->AddUndoTab( i, i );
-                    maTabs[i]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+                    sc::CopyToDocContext aMixCxt(*pMixDoc);
+                    aMixCxt.setTabRange(i, i);
+                    maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
                                             IDF_CONTENTS, false, pMixDoc->maTabs[i] );
                 }
                 maTabs[i]->DeleteArea( nStartCol,nStartRow, nEndCol,nEndRow, nDelFlags);
-                maTabs[nSrcTab]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+                maTabs[nSrcTab]->CopyToTable(aCxt, nStartCol,nStartRow, nEndCol,nEndRow,
                                                  nFlags, false, maTabs[i], NULL, bAsLink );
 
                 if (bDoMix)
@@ -2923,6 +2936,8 @@ void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
         SCCOL nEndCol = aArea.aEnd.Col();
         SCROW nEndRow = aArea.aEnd.Row();
 
+        sc::CopyToDocContext aCxt(*this);
+        aCxt.setTabRange(rMark.GetFirstSelected(), rMark.GetLastSelected());
         SCTAB nCount = static_cast<SCTAB>(maTabs.size());
         ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
         for (; itr != itrEnd && *itr < nCount; ++itr)
@@ -2938,12 +2953,15 @@ void ScDocument::FillTabMarked( SCTAB nSrcTab, const ScMarkData& rMark,
                     }
                     else
                         pMixDoc->AddUndoTab( i, i );
-                    maTabs[i]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+
+                    sc::CopyToDocContext aMixCxt(*pMixDoc);
+                    aMixCxt.setTabRange(i, i);
+                    maTabs[i]->CopyToTable(aMixCxt, nStartCol,nStartRow, nEndCol,nEndRow,
                                             IDF_CONTENTS, true, pMixDoc->maTabs[i], &rMark );
                 }
 
                 maTabs[i]->DeleteSelection( nDelFlags, rMark );
-                maTabs[nSrcTab]->CopyToTable( nStartCol,nStartRow, nEndCol,nEndRow,
+                maTabs[nSrcTab]->CopyToTable(aCxt, nStartCol,nStartRow, nEndCol,nEndRow,
                                              nFlags, true, maTabs[i], &rMark, bAsLink );
 
                 if (bDoMix)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index d1605c7..1a59fca 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -406,9 +406,11 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE
         nWhichArray[1] = ATTR_CONDITIONAL;
         nWhichArray[2] = 0;
 
+        sc::CopyToDocContext aCxt(*pDocument);
+        aCxt.setTabRange(nTab, nTab);
         for (SCSIZE i=0; i<nSize; i++)
         {
-            aCol[nStartCol-1].CopyToColumn( nStartRow, nEndRow, IDF_ATTRIB,
+            aCol[nStartCol-1].CopyToColumn(aCxt, nStartRow, nEndRow, IDF_ATTRIB,
                                                 false, aCol[nStartCol+i] );
             aCol[nStartCol+i].RemoveFlags( nStartRow, nEndRow,
                                                 SC_MF_HOR | SC_MF_VER | SC_MF_AUTO );
@@ -1018,17 +1020,17 @@ void ScTable::StartListeningInArea( SCCOL nCol1, SCROW nRow1,
 }
 
 
-void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
-                            sal_uInt16 nFlags, bool bMarked, ScTable* pDestTab,
-                            const ScMarkData* pMarkData,
-                            bool bAsLink, bool bColRowFlags)
+void ScTable::CopyToTable(
+    sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+    sal_uInt16 nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData,
+    bool bAsLink, bool bColRowFlags )
 {
     if (!ValidColRow(nCol1, nRow1) || !ValidColRow(nCol2, nRow2))
         return;
 
     if (nFlags)
         for (SCCOL i = nCol1; i <= nCol2; i++)
-            aCol[i].CopyToColumn(nRow1, nRow2, nFlags, bMarked,
+            aCol[i].CopyToColumn(rCxt, nRow1, nRow2, nFlags, bMarked,
                                 pDestTab->aCol[i], pMarkData, bAsLink);
 
     if (!bColRowFlags)      // Spaltenbreiten/Zeilenhoehen/Flags
@@ -1158,13 +1160,15 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         bool bWidth  = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth);
         bool bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights);
 
+        sc::CopyToDocContext aCopyCxt(*pDestTab->pDocument);
+        aCopyCxt.setTabRange(pDestTab->nTab, pDestTab->nTab);
         for ( SCCOL i = 0; i <= MAXCOL; i++)
         {
             if ( i >= nCol1 && i <= nCol2 )
                 aCol[i].UndoToColumn(nRow1, nRow2, nFlags, bMarked, pDestTab->aCol[i],
                                         pMarkData);
             else
-                aCol[i].CopyToColumn(0, MAXROW, IDF_FORMULA, false, pDestTab->aCol[i]);
+                aCol[i].CopyToColumn(aCopyCxt, 0, MAXROW, IDF_FORMULA, false, pDestTab->aCol[i]);
         }
 
         //remove old notes


More information about the Libreoffice-commits mailing list