[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Wed Mar 13 18:14:06 PDT 2013


 sc/inc/column.hxx                      |    2 
 sc/inc/columniterator.hxx              |   29 ++++++
 sc/source/core/data/columniterator.cxx |  138 ++++++++++++++++++++++++++++++++-
 sc/source/core/data/documen8.cxx       |    1 
 4 files changed, 164 insertions(+), 6 deletions(-)

New commits:
commit d2ff2f681cb401f5354c12d2e8345d4f67c47fab
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Mar 13 21:13:14 2013 -0400

    First cut on column text width iterator implementation. Untested.
    
    Change-Id: Ic615e5645f1a89a4b1a60dc519eb79ff921203a9

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index acaede3..f1996f1 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 b8f8f59..a70567c56 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 289c194..31298bc 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 bceb8c8..263dc74 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>


More information about the Libreoffice-commits mailing list