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.mohrh...@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.mohrh...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits