[Libreoffice-commits] core.git: sc/inc sc/source

Noel Grandin noel.grandin at collabora.co.uk
Fri Aug 25 13:30:55 UTC 2017


 sc/inc/colcontainer.hxx          |    3 +++
 sc/inc/document.hxx              |    4 ++++
 sc/inc/table.hxx                 |   13 +++++++++++++
 sc/source/core/data/document.cxx |   17 +++++++++++++++--
 sc/source/core/data/drwlayer.cxx |   34 +++++++++++++++++++++++++++-------
 sc/source/core/data/table1.cxx   |   14 ++++++++++----
 sc/source/core/data/table2.cxx   |    9 ++++-----
 sc/source/core/data/table3.cxx   |   13 +++++++------
 sc/source/core/data/table5.cxx   |    4 ++--
 9 files changed, 85 insertions(+), 26 deletions(-)

New commits:
commit c47eb8afd1b941a4dca832cfad85ba750c76635d
Author: Noel Grandin <noel.grandin at collabora.co.uk>
Date:   Tue Aug 22 11:43:15 2017 +0200

    dynamic column container: more efficient loops over all cols
    
    Create an ScColumnsRange class that returns a pair of (start,end)
    iterators to go through the list of currently allocated columns.
    This is a fairly thing wrapper around the underlying std::vector,
    so it should be fairly efficient (two pointers, and pointer increment
    for iteration).
    
    If this style of iteration is acceptable, I'll go through the rest
    of the code that does:
    
        for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++)
    
    type stuff, and change it to use ScColumnsRange.
    
    Change-Id: I81501c69b7f5566c6204dde0d87a6fe0deb9743c
    Reviewed-on: https://gerrit.libreoffice.org/41413
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sc/inc/colcontainer.hxx b/sc/inc/colcontainer.hxx
index 3e97ed048f4d..bf2bd206850f 100644
--- a/sc/inc/colcontainer.hxx
+++ b/sc/inc/colcontainer.hxx
@@ -72,6 +72,9 @@ public:
         assert(aCols.size() > 0);
         return *aCols.back();
     }
+
+    ScColumnVector::const_iterator begin() const { return aCols.begin(); }
+    ScColumnVector::const_iterator end() const { return aCols.end(); }
 };
 
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 6650c2e111ee..bc1f4ea2f5cf 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -198,6 +198,7 @@ class SvtBroadcaster;
 enum class ScDBDataPortion;
 enum class ScSheetEventId;
 class BitmapEx;
+class ScColumnsRange;
 
 namespace sc {
 
@@ -295,6 +296,7 @@ friend class sc::ColumnSpanSet;
 friend class sc::EditTextIterator;
 friend class sc::FormulaGroupAreaListener;
 friend class sc::TableColumnBlockPositionSet;
+friend class ScDrawLayer;
 
     typedef std::vector<ScTable*> TableContainer;
 
@@ -2383,6 +2385,8 @@ private:
 
     void EndListeningGroups( const std::vector<ScAddress>& rPosArray );
     void SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray );
+
+    ScColumnsRange       GetColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const;
 };
 
 #endif
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index d64bc90b4f3b..d41d67d10a1c 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -117,6 +117,17 @@ class ScDBData;
 class ScDocumentImport;
 class ScHint;
 
+class ScColumnsRange final
+{
+    typedef std::vector<ScColumn*>::const_iterator const_iterator;
+    const const_iterator maBegin;
+    const const_iterator maEnd;
+public:
+    ScColumnsRange(const_iterator nBegin, const_iterator nEnd) : maBegin(nBegin), maEnd(nEnd) {}
+    const const_iterator & begin() { return maBegin; }
+    const const_iterator & end() { return maEnd; }
+};
+
 class ScTable
 {
 private:
@@ -1024,6 +1035,8 @@ public:
     */
     static void UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow );
 
+    ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const;
+
 private:
 
     void FillFormulaVertical(
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 5f1278f8c268..6bb050d6dcf0 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2518,6 +2518,17 @@ const ScTable* ScDocument::FetchTable( SCTAB nTab ) const
     return maTabs[nTab];
 }
 
+ScColumnsRange ScDocument::GetColumnsRange( SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const
+{
+    if (!TableExists(nTab))
+    {
+        std::vector<ScColumn*> aEmptyVector;
+        return ScColumnsRange(aEmptyVector.begin(), aEmptyVector.end());
+    }
+
+    return maTabs[nTab]->GetColumnsRange(nColBegin, nColEnd);
+}
+
 void ScDocument::MergeNumberFormatter(const ScDocument* pSrcDoc)
 {
     SvNumberFormatter* pThisFormatter = xPoolHelper->GetFormTable();
@@ -6580,8 +6591,9 @@ ScAddress ScDocument::GetNotePosition( size_t nIndex ) const
 {
     for (size_t nTab = 0; nTab < maTabs.size(); ++nTab)
     {
-        for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++)
+        for (const ScColumn* pCol : GetColumnsRange(nTab, 0, MAXCOL))
         {
+            SCCOL nCol = pCol->GetCol();
             size_t nColNoteCount = GetNoteCount(nTab, nCol);
             if (!nColNoteCount)
                 continue;
@@ -6607,8 +6619,9 @@ ScAddress ScDocument::GetNotePosition( size_t nIndex ) const
 
 ScAddress ScDocument::GetNotePosition( size_t nIndex, SCTAB nTab ) const
 {
-    for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++)
+    for (const ScColumn * pCol : GetColumnsRange(nTab, 0, MAXCOL))
     {
+        SCCOL nCol = pCol->GetCol();
         size_t nColNoteCount = GetNoteCount(nTab, nCol);
         if (!nColNoteCount)
             continue;
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 2242a6d53744..ddf2cf41dfb6 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -70,6 +70,7 @@
 #include "postit.hxx"
 #include "attrib.hxx"
 #include "charthelper.hxx"
+#include "table.hxx"
 #include <basegfx/matrix/b2dhommatrix.hxx>
 
 #include <vcl/field.hxx>
@@ -1064,17 +1065,36 @@ bool ScDrawLayer::GetPrintArea( ScRange& rRange, bool bSetHor, bool bSetVer ) co
             nStartX = HmmToTwips( nStartX );
             nEndX = HmmToTwips( nEndX );
             long nWidth;
-            SCCOL i;
 
             nWidth = 0;
-            for (i=0; i<=MAXCOL && nWidth<=nStartX; i++)
-                nWidth += pDoc->GetColWidth(i,nTab);
-            rRange.aStart.SetCol( i>0 ? (i-1) : 0 );
+            rRange.aStart.SetCol( 0 );
+            if (nWidth <= nStartX)
+            {
+                for (const ScColumn* pCol : pDoc->GetColumnsRange(nTab, 0, MAXCOL))
+                {
+                    nWidth += pDoc->GetColWidth(pCol->GetCol(),nTab);
+                    if (nWidth > nStartX)
+                    {
+                        rRange.aStart.SetCol( pCol->GetCol() );
+                        break;
+                    }
+                }
+            }
 
             nWidth = 0;
-            for (i=0; i<=MAXCOL && nWidth<=nEndX; i++)          //TODO: start at Start
-                nWidth += pDoc->GetColWidth(i,nTab);
-            rRange.aEnd.SetCol( i>0 ? (i-1) : 0 );
+            rRange.aEnd.SetCol( 0 );
+            if (nWidth <= nEndX)
+            {
+                for (const ScColumn* pCol : pDoc->GetColumnsRange(nTab, 0, MAXCOL)) //TODO: start at Start
+                {
+                    nWidth += pDoc->GetColWidth(pCol->GetCol(),nTab);
+                    if (nWidth > nEndX)
+                    {
+                        rRange.aEnd.SetCol( pCol->GetCol() );
+                        break;
+                    }
+                }
+            }
         }
 
         if (bSetVer)
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index ad1a50ee3828..c10100d4777b 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -1681,14 +1681,14 @@ void ScTable::UpdateReference(
 void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
                                     ScDocument* pUndoDoc )
 {
-    for ( SCCOL i=0; i<=MAXCOL; i++ )
-        aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
+    for (ScColumn* pCol : GetColumnsRange(0, MAXCOL))
+        pCol->UpdateTranspose( rSource, rDest, pUndoDoc );
 }
 
 void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
 {
-    for ( SCCOL i=0; i<=MAXCOL; i++ )
-        aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
+    for (ScColumn* pCol : GetColumnsRange(0, MAXCOL))
+        pCol->UpdateGrow( rArea, nGrowX, nGrowY );
 }
 
 void ScTable::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt )
@@ -2383,4 +2383,10 @@ const ScConditionalFormatList* ScTable::GetCondFormList() const
     return mpCondFormatList.get();
 }
 
+ScColumnsRange ScTable::GetColumnsRange(SCCOL nColBegin, SCCOL nColEnd) const
+{
+    // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range
+    return ScColumnsRange(aCol.begin() + nColBegin, nColEnd < nColBegin ? (aCol.begin() + nColBegin) : (aCol.begin() + nColEnd + 1));
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index b42959a46403..7871f04318fb 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1650,10 +1650,8 @@ CommentCaptionState ScTable::GetAllNoteCaptionsState(const ScRange& rRange, std:
 
 void ScTable::GetUnprotectedCells( ScRangeList& rRangeList ) const
 {
-    for (SCCOL nCol = 0; nCol < MAXCOL; ++nCol)
-    {
-        aCol[nCol].GetUnprotectedCells(0, MAXROW, rRangeList);
-    }
+    for (auto pCol : aCol)
+        pCol->GetUnprotectedCells(0, MAXROW, rRangeList);
 }
 
 bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const
@@ -2109,8 +2107,9 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC
     SCROW nY1 = pRowInfo[0].nRowNo;
     SCROW nY2 = pRowInfo[nArrCount-1].nRowNo;
 
-    for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
+    for (ScColumn* pCol : GetColumnsRange(0, MAXCOL))
     {
+        SCCOL nCol = pCol->GetCol();
         if (!ColHidden(nCol))
         {
             SCSIZE nArrY = 0;
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 39eff62a2d87..926301cd4582 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1849,15 +1849,16 @@ public:
         SCCOL nStartCol = mrParam.nCol1;
         SCCOL nEndCol = mrParam.nCol2;
 
-        for (SCCOL i = 0; i <= MAXCOL; ++i)
+        for (const ScColumn* pCol : mrTab.GetColumnsRange(0, nStartCol - 1))
         {
-            if (nStartCol <= i && i <= nEndCol)
-                continue;
-
-            if (mrTab.HasData(i, nRow))
+            if (mrTab.HasData(pCol->GetCol(), nRow))
+                return true;
+        }
+        for (const ScColumn* pCol : mrTab.GetColumnsRange(nEndCol + 1, MAXCOL))
+        {
+            if (mrTab.HasData(pCol->GetCol(), nRow))
                 return true;
         }
-
         return false;
     }
 };
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index d6c7a8527e4b..46f36b11bba0 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -290,8 +290,8 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
     if (nEndCol < MAXCOL)
     {
         SetColBreak(nEndCol+1, true, false);  // AREABREAK
-        for (nX=nEndCol+2; nX<=MAXCOL; nX++)
-            RemoveColBreak(nX, true, false);
+        for (const ScColumn* pCol : GetColumnsRange(nEndCol + 2, MAXCOL))
+            RemoveColBreak(pCol->GetCol(), true, false);
     }
     if (nEndRow < MAXROW)
     {


More information about the Libreoffice-commits mailing list