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

Markus Mohrhard markus.mohrhard at googlemail.com
Wed Nov 27 15:33:13 PST 2013


 sc/inc/column.hxx                |    1 
 sc/inc/document.hxx              |    2 +
 sc/inc/table.hxx                 |    2 +
 sc/source/core/data/column2.cxx  |   33 +++++++++++++++++++++++---
 sc/source/core/data/document.cxx |   28 ++++++++++++++++++++++
 sc/source/core/data/table2.cxx   |   24 +++++++++++++++++++
 sc/source/ui/view/cellsh.cxx     |   49 ++++++++-------------------------------
 7 files changed, 98 insertions(+), 41 deletions(-)

New commits:
commit 839eccc8ae5aa5dde055f84471246f2a3ef04929
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Thu Nov 28 00:29:59 2013 +0100

    iterating through all cells is not a good idea, fdo#71934
    
    Change-Id: I370f641f0fffed8835a32c577c2f2e841ba419aa

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index c08236b..ba16644 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -506,6 +506,7 @@ public:
     size_t GetNoteCount() const;
     SCROW GetNotePosition( size_t nIndex ) const;
     void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
+    void GetNotesInRange( SCROW nStartRow, SCROW nEndRow, std::vector<sc::NoteEntry>& rNotes ) const;
 
     SCROW GetCellNotesMaxRow() const;
     SCROW GetCellNotesMinRow() const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index b9e3dc3..0546ef0 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -909,6 +909,7 @@ public:
     SCROW GetNotePosition( SCTAB nTab, SCCOL nCol, size_t nIndex ) const;
 
     SC_DLLPUBLIC void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
+    void GetNotesInRange( const ScRangeList& rRange, std::vector<sc::NoteEntry>& rNotes ) const;
     bool ContainsNotesInRange( const ScRangeList& rRange ) const;
 
     SC_DLLPUBLIC void            SetDrawPageSize(SCTAB nTab);
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 5938dcb..e273da8 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -382,6 +382,7 @@ public:
     SCROW GetNotePosition( SCCOL nCol, size_t nIndex ) const;
 
     void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
+    void GetNotesInRange( const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes ) const;
     bool ContainsNotesInRange( const ScRange& rRange ) const;
 
     bool TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) const;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 24cd615..8759c51 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1262,9 +1262,13 @@ class NoteEntryCollector
     std::vector<sc::NoteEntry>& mrNotes;
     SCTAB mnTab;
     SCCOL mnCol;
+    SCROW mnStartRow;
+    SCROW mnEndRow;
 public:
-    NoteEntryCollector( std::vector<sc::NoteEntry>& rNotes, SCTAB nTab, SCCOL nCol ) :
-        mrNotes(rNotes), mnTab(nTab), mnCol(nCol) {}
+    NoteEntryCollector( std::vector<sc::NoteEntry>& rNotes, SCTAB nTab, SCCOL nCol,
+            SCROW nStartRow = 0, SCROW nEndRow = MAXROW) :
+        mrNotes(rNotes), mnTab(nTab), mnCol(nCol),
+        mnStartRow(nStartRow), mnEndRow(nEndRow) {}
 
     void operator() (const sc::CellNoteStoreType::value_type& node) const
     {
@@ -1275,7 +1279,14 @@ public:
         sc::cellnote_block::const_iterator it = sc::cellnote_block::begin(*node.data);
         sc::cellnote_block::const_iterator itEnd = sc::cellnote_block::end(*node.data);
         size_t nOffset = 0;
-        for (; it != itEnd; ++it, ++nOffset)
+        if(nTopRow < size_t(mnStartRow))
+        {
+            std::advance(it, mnStartRow - nTopRow);
+            nOffset = mnStartRow - nTopRow;
+        }
+
+        for (; it != itEnd && nTopRow + nOffset <= size_t(mnEndRow);
+                ++it, ++nOffset)
         {
             ScAddress aPos(mnCol, nTopRow + nOffset, mnTab);
             mrNotes.push_back(sc::NoteEntry(aPos, *it));
@@ -1290,6 +1301,22 @@ void ScColumn::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
     std::for_each(maCellNotes.begin(), maCellNotes.end(), NoteEntryCollector(rNotes, nTab, nCol));
 }
 
+void ScColumn::GetNotesInRange(SCROW nStartRow, SCROW nEndRow,
+        std::vector<sc::NoteEntry>& rNotes ) const
+{
+    std::pair<sc::CellNoteStoreType::const_iterator,size_t> aPos = maCellNotes.position(nStartRow);
+    sc::CellNoteStoreType::const_iterator it = aPos.first;
+    if (it == maCellNotes.end())
+        // Invalid row number.
+        return;
+
+    std::pair<sc::CellNoteStoreType::const_iterator,size_t> aEndPos =
+        maCellNotes.position(nEndRow);
+    sc::CellNoteStoreType::const_iterator itEnd = aEndPos.first;
+
+    std::for_each(it, itEnd, NoteEntryCollector(rNotes, nTab, nCol, nStartRow, nEndRow));
+}
+
 SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const
 {
     // Given a range of rows, find a top or bottom empty segment.
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 708300e..931994a 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6226,6 +6226,18 @@ void ScDocument::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
     }
 }
 
+void ScDocument::GetNotesInRange( const ScRangeList& rRange, std::vector<sc::NoteEntry>& rNotes ) const
+{
+    for( size_t i = 0; i < rRange.size(); ++i)
+    {
+        const ScRange* pRange = rRange[i];
+        for( SCTAB nTab = pRange->aStart.Tab(); nTab < pRange->aEnd.Tab(); ++nTab )
+        {
+            maTabs[nTab]->GetNotesInRange( *pRange, rNotes );
+        }
+    }
+}
+
 bool ScDocument::ContainsNotesInRange( const ScRangeList& rRange ) const
 {
     for( size_t i = 0; i < rRange.size(); ++i)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index c0d41d1..d7fca4f 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1516,6 +1516,16 @@ void ScTable::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
         aCol[nCol].GetAllNoteEntries(rNotes);
 }
 
+void ScTable::GetNotesInRange( const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes ) const
+{
+    SCROW nStartRow = rRange.aStart.Row();
+    SCROW nEndRow = rRange.aEnd.Row();
+    for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
+    {
+        aCol[nCol].GetNotesInRange(nStartRow, nEndRow, rNotes);
+    }
+}
+
 bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const
 {
     SCROW nStartRow = rRange.aStart.Row();
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 8895f96..ec69f05 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -935,34 +935,22 @@ void ScCellShell::GetState(SfxItemSet &rSet)
                         ScRangeListRef aRangesRef;
                         pData->GetMultiArea(aRangesRef);
                         ScRangeList aRanges = *aRangesRef;
-                        size_t nRangeSize = aRanges.size();
-
-                        for ( size_t i = 0; i < nRangeSize && !bEnable; ++i )
+                        std::vector<sc::NoteEntry> aNotes;
+                        pDoc->GetNotesInRange(aRanges, aNotes);
+                        for(std::vector<sc::NoteEntry>::const_iterator itr = aNotes.begin(),
+                                itrEnd = aNotes.end(); itr != itrEnd; ++itr)
                         {
-                            const ScRange * pRange = aRanges[i];
-                            const SCROW nRow0 = pRange->aStart.Row();
-                            const SCROW nRow1 = pRange->aEnd.Row();
-                            const SCCOL nCol0 = pRange->aStart.Col();
-                            const SCCOL nCol1 = pRange->aEnd.Col();
-                            const SCTAB nRangeTab = pRange->aStart.Tab();
-                            // Check by each cell
-                            // nCellNumber < pDoc->CountNotes() with const size_t nCellNumber = ( nRow1 - nRow0 ) * ( nCol1 - nCol0 );
-                            for ( SCROW nRow = nRow0; nRow <= nRow1 && !bEnable; ++nRow )
+                            const ScAddress& rAdr = itr->maPos;
+                            if( pDoc->IsBlockEditable( rAdr.Tab(), rAdr.Col(), rAdr.Row(), rAdr.Col(), rAdr.Row() ))
                             {
-                                for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol )
+                                if (itr->mpNote->IsCaptionShown() != bSearchForHidden)
                                 {
-                                    const ScPostIt* pNote = pDoc->GetNote(nCol, nRow, nRangeTab);
-                                    if ( pNote && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) )
-                                    {
-                                        if ( pNote->IsCaptionShown() != bSearchForHidden)
-                                        {
-                                            bEnable = true;
-                                            break;
-                                        }
-                                    }
+                                    bEnable = true;
+                                    break;
                                 }
                             }
                         }
+
                     }
                     if ( !bEnable )
                         rSet.DisableItem( nWhich );
commit 12aa3151ab993fff1ae312ae7b1d5bbcfc379b07
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Sun Nov 24 21:22:20 2013 +0100

    checking every cell on a sheet is expensive, related fdo#71934
    
    This is only the first of two places that does this.
    
    Change-Id: I57fe1eb07630ecd86b112e88b7ad32c16e9f793a

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 49fd571..b9e3dc3 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -909,6 +909,7 @@ public:
     SCROW GetNotePosition( SCTAB nTab, SCCOL nCol, size_t nIndex ) const;
 
     SC_DLLPUBLIC void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
+    bool ContainsNotesInRange( const ScRangeList& rRange ) const;
 
     SC_DLLPUBLIC void            SetDrawPageSize(SCTAB nTab);
 
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 8eb75be..5938dcb 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -382,6 +382,7 @@ public:
     SCROW GetNotePosition( SCCOL nCol, size_t nIndex ) const;
 
     void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
+    bool ContainsNotesInRange( const ScRange& rRange ) const;
 
     bool TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) const;
     void        InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize );
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 80696e4..708300e 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6226,6 +6226,22 @@ void ScDocument::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
     }
 }
 
+bool ScDocument::ContainsNotesInRange( const ScRangeList& rRange ) const
+{
+    for( size_t i = 0; i < rRange.size(); ++i)
+    {
+        const ScRange* pRange = rRange[i];
+        for( SCTAB nTab = pRange->aStart.Tab(); nTab < pRange->aEnd.Tab(); ++nTab )
+        {
+            bool bContainsNote = maTabs[nTab]->ContainsNotesInRange( *pRange );
+            if(bContainsNote)
+                return true;
+        }
+    }
+
+    return false;
+}
+
 void ScDocument::SetAutoNameCache(  ScAutoNameCache* pCache )
 {
     delete pAutoNameCache;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 29e10c9..c0d41d1 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1516,6 +1516,20 @@ void ScTable::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
         aCol[nCol].GetAllNoteEntries(rNotes);
 }
 
+bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const
+{
+    SCROW nStartRow = rRange.aStart.Row();
+    SCROW nEndRow = rRange.aEnd.Row();
+    for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
+    {
+        bool bContainsNote = !aCol[nCol].IsNotesEmptyBlock(nStartRow, nEndRow);
+        if(bContainsNote)
+            return true;
+    }
+
+    return false;
+}
+
 CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const
 {
     if (ValidColRow( nCol, nRow ))
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 943379f..8895f96 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -979,22 +979,7 @@ void ScCellShell::GetState(SfxItemSet &rSet)
                             // look for at least one note in selection
                             ScRangeList aRanges;
                             rMark.FillRangeListWithMarks( &aRanges, false );
-                            size_t nCount = aRanges.size();
-                            for (size_t nPos = 0; nPos < nCount && !bEnable; ++nPos)
-                            {
-                                SCTAB aTab = aRanges[nPos]->aStart.Tab();
-                                for (SCCOL aCol=aRanges[nPos]->aStart.Col(); aCol <= aRanges[nPos]->aEnd.Col() && !bEnable; aCol++)
-                                {
-                                    for (SCROW aRow=aRanges[nPos]->aStart.Row(); aRow <= aRanges[nPos]->aEnd.Row(); aRow++)
-                                    {
-                                        if (pDoc->HasNote(aCol, aRow, aTab))
-                                        {
-                                            bEnable = true;
-                                            break;
-                                        }
-                                    }
-                                }
-                            }
+                            bEnable = pDoc->ContainsNotesInRange( aRanges );
                         }
                     }
                     else


More information about the Libreoffice-commits mailing list