diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-03-13 21:13:14 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-03-14 15:35:54 -0400 |
commit | 8945bddcc9294dc839e046d2d8b6c6dabd8caeb9 (patch) | |
tree | f59e89ab3433144b8694503d2fbc8418b09c1866 /sc | |
parent | b086f0fa026a5bc794832e8457833379036e5440 (diff) |
First cut on column text width iterator implementation. Untested.
Change-Id: Ic615e5645f1a89a4b1a60dc519eb79ff921203a9
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/inc/columniterator.hxx | 29 | ||||
-rw-r--r-- | sc/source/core/data/columniterator.cxx | 138 | ||||
-rw-r--r-- | sc/source/core/data/documen8.cxx | 1 |
4 files changed, 164 insertions, 6 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index acaede3f7435..f1996f1b9bab 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -61,7 +61,7 @@ struct ScMergePatternState; class ScFlatBoolRowSegments; struct ScSetStringParam; struct ScColWidthParam; -struct ScColumnImpl; +class ScColumnTextWidthIterator; struct ScNeededSizeOptions { diff --git a/sc/inc/columniterator.hxx b/sc/inc/columniterator.hxx index b8f8f598ec39..a70567c56c0f 100644 --- a/sc/inc/columniterator.hxx +++ b/sc/inc/columniterator.hxx @@ -10,13 +10,36 @@ #ifndef __SC_COLUMNITERATOR_HXX__ #define __SC_COLUMNITERATOR_HXX__ +#include <boost/noncopyable.hpp> + +#include "column.hxx" + class ScColumn; -class ScColumnTextWidthIterator +class ScColumnTextWidthIterator : boost::noncopyable { - ScColumn& mrCol; + typedef ScColumn::TextWidthType TextWidthType; + + TextWidthType& mrTextWidths; + const size_t mnEnd; + size_t mnCurPos; + TextWidthType::iterator miBlockCur; + TextWidthType::iterator miBlockEnd; + mdds::mtv::ushort_element_block::iterator miDataCur; + mdds::mtv::ushort_element_block::iterator miDataEnd; + public: - ScColumnTextWidthIterator(ScColumn& rCol); + ScColumnTextWidthIterator(ScColumn& rCol, SCROW nStartRow, SCROW nEndRow); + + void next(); + bool hasCell() const; + SCROW getPos() const; + sal_uInt16 getValue() const; + void setValue(sal_uInt16 nVal); + +private: + void getDataIterators(size_t nOffsetInBlock); + void checkEndRow(); }; #endif diff --git a/sc/source/core/data/columniterator.cxx b/sc/source/core/data/columniterator.cxx index 289c1942456f..31298bc3592e 100644 --- a/sc/source/core/data/columniterator.cxx +++ b/sc/source/core/data/columniterator.cxx @@ -10,7 +10,141 @@ #include "columniterator.hxx" #include "column.hxx" -ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScColumn& rCol) : - mrCol(rCol) {} +ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScColumn& rCol, SCROW nStartRow, SCROW nEndRow) : + mrTextWidths(rCol.maTextWidths), + mnEnd(static_cast<size_t>(nEndRow)), + mnCurPos(0), + miBlockCur(mrTextWidths.begin()), + miBlockEnd(mrTextWidths.end()) +{ + if (!ValidRow(nStartRow) || !ValidRow(nEndRow)) + miBlockCur = miBlockEnd; + + size_t nStart = static_cast<size_t>(nStartRow); + + // Locate the start row position. + size_t nBlockStart = 0, nBlockEnd = 0; + for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd) + { + nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point. + if (nBlockStart <= nStart && nStart < nBlockEnd) + { + // Initial block is found! + break; + } + } + + if (miBlockCur == miBlockEnd) + // Initial block not found for whatever reason... Bail out. + return; + + // Locate the initial row position within this block. + if (miBlockCur->type == mdds::mtv::element_type_ushort) + { + // This block stores text widths for non-empty cells. + size_t nOffsetInBlock = nStart - nBlockStart; + mnCurPos = nStart; + getDataIterators(nOffsetInBlock); + checkEndRow(); + return; + } + + // Current block is not of ushort type. Skip to the next block. + nBlockStart = nBlockEnd; + ++miBlockCur; + + // Look for the first ushort block. + for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd) + { + nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point. + if (miBlockCur->type != mdds::mtv::element_type_ushort) + continue; + + // Found! + mnCurPos = nBlockStart; + getDataIterators(0); + checkEndRow(); + return; + } + + // Not found. + OSL_ASSERT(miBlockCur == miBlockEnd); +} + +void ScColumnTextWidthIterator::next() +{ + ++miDataCur; + ++mnCurPos; + + if (miDataCur != miDataEnd) + { + // Stil in the same block. We're good. + checkEndRow(); + return; + } + + // Move to the next block. + for (++miBlockCur; miBlockCur != miBlockEnd; ++miBlockCur) + { + if (miBlockCur->type != mdds::mtv::element_type_ushort) + { + // We don't iterator over this block. + mnCurPos += miBlockCur->size; + continue; + } + + getDataIterators(0); + checkEndRow(); + return; + } + + // Reached the end. + OSL_ASSERT(miBlockCur == miBlockEnd); +} + +bool ScColumnTextWidthIterator::hasCell() const +{ + return miBlockCur != miBlockEnd; +} + +SCROW ScColumnTextWidthIterator::getPos() const +{ + OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd); + return static_cast<SCROW>(mnCurPos); +} + +sal_uInt16 ScColumnTextWidthIterator::getValue() const +{ + OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd); + return *miDataCur; +} + +void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal) +{ + OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd); + *miDataCur = nVal; +} + +void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock) +{ + OSL_ENSURE(miBlockCur != miBlockEnd, "block is at end position"); + OSL_ENSURE(miBlockCur->type == mdds::mtv::element_type_ushort, + "wrong block type - unsigned short block expected."); + + miDataCur = mdds::mtv::ushort_element_block::begin(*miBlockCur->data); + miDataEnd = mdds::mtv::ushort_element_block::end(*miBlockCur->data); + + std::advance(miDataCur, nOffsetInBlock); +} + +void ScColumnTextWidthIterator::checkEndRow() +{ + if (mnCurPos <= mnEnd) + // We're still good. + return; + + // We're below the end position. End the iteration. + miBlockCur = miBlockEnd; +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx index bceb8c888bba..263dc743867a 100644 --- a/sc/source/core/data/documen8.cxx +++ b/sc/source/core/data/documen8.cxx @@ -85,6 +85,7 @@ #include "dpobject.hxx" #include "docuno.hxx" #include "scresid.hxx" +#include "columniterator.hxx" #include <memory> #include <boost/scoped_ptr.hpp> |