diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2013-11-28 00:29:59 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2013-11-28 00:32:44 +0100 |
commit | 839eccc8ae5aa5dde055f84471246f2a3ef04929 (patch) | |
tree | 566d0aa7e9c7036c012826d33b05aaaf7b09d9da | |
parent | 12aa3151ab993fff1ae312ae7b1d5bbcfc379b07 (diff) |
iterating through all cells is not a good idea, fdo#71934
Change-Id: I370f641f0fffed8835a32c577c2f2e841ba419aa
-rw-r--r-- | sc/inc/column.hxx | 1 | ||||
-rw-r--r-- | sc/inc/document.hxx | 1 | ||||
-rw-r--r-- | sc/inc/table.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 33 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 12 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh.cxx | 32 |
7 files changed, 65 insertions, 25 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index c08236b220d0..ba16644492d4 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 b9e3dc3b6d38..0546ef0d376e 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 5938dcb2277c..e273da83e4c3 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 24cd6155865e..8759c513210c 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 708300e72a88..931994a0a3fd 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 c0d41d1ae6cf..d7fca4f9eb69 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 8895f963d192..ec69f05a0c3a 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 ); |