diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-06-19 16:48:32 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-06-24 16:51:36 -0400 |
commit | e3b91687590f08438b5a5d4eec72e634b11a8589 (patch) | |
tree | 96354be594954e1c53d35cbb82c144431a688896 /sc | |
parent | 2a5ea9ee0ba2b38d1810828a9fdf884d9b0fd198 (diff) |
Fix the horizontal cell iterator.
I got its logic totally wrong. Now it works.
Change-Id: I79e556da19c7c0b0d8cecbb4875d6d21d5ec4208
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/dociter.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/dociter.cxx | 83 |
2 files changed, 61 insertions, 24 deletions
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx index 87d17b261f90..2452a6083d93 100644 --- a/sc/inc/dociter.hxx +++ b/sc/inc/dociter.hxx @@ -410,8 +410,6 @@ public: class ScHorizontalCellIterator // walk through all non empty cells in an area { // row by row - typedef std::pair<sc::CellStoreType::const_iterator,size_t> PositionType; - struct ColParam { sc::CellStoreType::const_iterator maPos; diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index f357fe38caf4..fb9eb62dc297 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -1672,7 +1672,7 @@ bool ScQueryCellIterator::BinarySearch() ScHorizontalCellIterator::ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) : - maColPositions(nCol2-nCol2+1), + maColPositions(nCol2-nCol1+1), pDoc( pDocument ), mnTab( nTable ), nStartCol( nCol1 ), @@ -1768,35 +1768,74 @@ void ScHorizontalCellIterator::Advance() } // Move to the next row that has at least one non-empty cell. - size_t nMinRow = MAXROW+1; - size_t nMinRowCol = maColPositions.size(); - for (size_t i = 0, n = maColPositions.size(); i < n; ++i) + ++mnRow; + while (mnRow <= nEndRow) { - ColParam& r = maColPositions[i]; - if (r.maPos == r.maEnd) - // This column has ended. - continue; + size_t nRow = static_cast<size_t>(mnRow); + size_t nNextRow = MAXROW+1; + size_t nNextRowPos = 0; + for (size_t i = nNextRowPos, n = maColPositions.size(); i < n; ++i) + { + ColParam& r = maColPositions[i]; + if (r.maPos == r.maEnd) + // This column has ended. + continue; - // Move to the next block. - ++r.maPos; + if (nRow < r.maPos->position) + { + // This block is ahread of the current row position. Skip it. + if (r.maPos->position < nNextRow) + { + nNextRow = r.maPos->position; + nNextRowPos = i; + } + continue; + } + + if (r.maPos->position + r.maPos->size <= nRow) + { + // This block is behind the current row position. Advance the block. + for (++r.maPos; r.maPos != r.maEnd; ++r.maPos) + { + if (nRow < r.maPos->position + r.maPos->size) + break; + } - if (r.maPos != r.maEnd && r.maPos->position < nMinRow) + if (r.maPos == r.maEnd) + // This column has ended. + continue; + } + + if (r.maPos->type == sc::element_type_empty) + { + // Empty block. Move to the next block and try next column. + ++r.maPos; + if (r.maPos->position < nNextRow) + { + nNextRow = r.maPos->position; + nNextRowPos = i; + } + continue; + } + + // Found a non-empty cell block! + mnCol = i + nStartCol; + mnRow = nRow; + bMore = true; + return; + } + + if (nNextRow > MAXROW) { - nMinRow = r.maPos->position; - nMinRowCol = i; + // No more blocks to search. + bMore = false; + return; } - } - if (nMinRowCol == maColPositions.size() || static_cast<SCROW>(nMinRow) > nEndRow) - { - // No more cells found. - bMore = false; - return; + mnRow = nNextRow; // move to the next non-empty row. } - mnCol = nMinRowCol + nStartCol; - mnRow = nMinRow; - bMore = true; + bMore = false; } //------------------------------------------------------------------------ |