summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2013-11-28 00:29:59 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2013-11-28 00:32:44 +0100
commit839eccc8ae5aa5dde055f84471246f2a3ef04929 (patch)
tree566d0aa7e9c7036c012826d33b05aaaf7b09d9da
parent12aa3151ab993fff1ae312ae7b1d5bbcfc379b07 (diff)
iterating through all cells is not a good idea, fdo#71934
Change-Id: I370f641f0fffed8835a32c577c2f2e841ba419aa
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/document.hxx1
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/source/core/data/column2.cxx33
-rw-r--r--sc/source/core/data/document.cxx12
-rw-r--r--sc/source/core/data/table2.cxx10
-rw-r--r--sc/source/ui/view/cellsh.cxx32
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 );