From e3b91687590f08438b5a5d4eec72e634b11a8589 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 19 Jun 2013 16:48:32 -0400 Subject: Fix the horizontal cell iterator. I got its logic totally wrong. Now it works. Change-Id: I79e556da19c7c0b0d8cecbb4875d6d21d5ec4208 --- sc/inc/dociter.hxx | 2 - sc/source/core/data/dociter.cxx | 83 ++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 24 deletions(-) (limited to 'sc') 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 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(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(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; } //------------------------------------------------------------------------ -- cgit