summaryrefslogtreecommitdiffstats
path: root/sc/source/core/data/columniterator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/columniterator.cxx')
-rw-r--r--sc/source/core/data/columniterator.cxx209
1 files changed, 209 insertions, 0 deletions
diff --git a/sc/source/core/data/columniterator.cxx b/sc/source/core/data/columniterator.cxx
new file mode 100644
index 000000000..cec8f7a20
--- /dev/null
+++ b/sc/source/core/data/columniterator.cxx
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <columniterator.hxx>
+#include <column.hxx>
+#include <document.hxx>
+#include <table.hxx>
+
+#include <osl/diagnose.h>
+
+ScColumnTextWidthIterator::ScColumnTextWidthIterator(const ScDocument& rDoc, ScColumn& rCol, SCROW nStartRow, SCROW nEndRow) :
+ mnEnd(static_cast<size_t>(nEndRow)),
+ mnCurPos(0)
+{
+ miBlockCur = rCol.maCellTextAttrs.begin();
+ miBlockEnd = rCol.maCellTextAttrs.end();
+ init(rDoc, nStartRow, nEndRow);
+}
+
+ScColumnTextWidthIterator::ScColumnTextWidthIterator(const ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow) :
+ mnEnd(static_cast<size_t>(nEndRow)),
+ mnCurPos(0)
+{
+ auto & rCellTextAttrs = rDoc.maTabs[rStartPos.Tab()]->aCol[rStartPos.Col()].maCellTextAttrs;
+ miBlockCur = rCellTextAttrs.begin();
+ miBlockEnd = rCellTextAttrs.end();
+ init(rDoc, rStartPos.Row(), nEndRow);
+}
+
+void ScColumnTextWidthIterator::next()
+{
+ ++miDataCur;
+ ++mnCurPos;
+
+ if (miDataCur != miDataEnd)
+ {
+ // Still in the same block. We're good.
+ checkEndRow();
+ return;
+ }
+
+ // Move to the next block.
+ for (++miBlockCur; miBlockCur != miBlockEnd; ++miBlockCur)
+ {
+ if (miBlockCur->type != sc::element_type_celltextattr)
+ {
+ // We don't iterator over this block.
+ mnCurPos += miBlockCur->size;
+ continue;
+ }
+
+ getDataIterators(0);
+ checkEndRow();
+ return;
+ }
+
+ // Reached the end.
+ assert(miBlockCur == miBlockEnd);
+}
+
+bool ScColumnTextWidthIterator::hasCell() const
+{
+ return miBlockCur != miBlockEnd;
+}
+
+SCROW ScColumnTextWidthIterator::getPos() const
+{
+ assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
+ return static_cast<SCROW>(mnCurPos);
+}
+
+sal_uInt16 ScColumnTextWidthIterator::getValue() const
+{
+ assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
+ return miDataCur->mnTextWidth;
+}
+
+void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal)
+{
+ assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
+ miDataCur->mnTextWidth = nVal;
+}
+
+void ScColumnTextWidthIterator::init(const ScDocument& rDoc, SCROW nStartRow, SCROW nEndRow)
+{
+ if (!rDoc.ValidRow(nStartRow) || !rDoc.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 == sc::element_type_celltextattr)
+ {
+ // 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 != sc::element_type_celltextattr)
+ continue;
+
+ // Found!
+ mnCurPos = nBlockStart;
+ getDataIterators(0);
+ checkEndRow();
+ return;
+ }
+
+ // Not found.
+ assert(miBlockCur == miBlockEnd);
+}
+
+void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock)
+{
+ OSL_ENSURE(miBlockCur != miBlockEnd, "block is at end position");
+#if 0
+ // Does not compile
+ OSL_ENSURE(miBlockCur->type == sc::celltextattr_block,
+ "wrong block type - unsigned short block expected.");
+#endif
+ miDataCur = sc::celltextattr_block::begin(*miBlockCur->data);
+ miDataEnd = sc::celltextattr_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;
+}
+
+namespace sc {
+
+ColumnIterator::ColumnIterator( const CellStoreType& rCells, SCROW nRow1, SCROW nRow2 ) :
+ maPos(rCells.position(nRow1)),
+ maPosEnd(rCells.position(maPos.first, nRow2)),
+ mbComplete(false)
+{
+}
+
+void ColumnIterator::next()
+{
+ if ( maPos == maPosEnd)
+ mbComplete = true;
+ else
+ maPos = CellStoreType::next_position(maPos);
+}
+
+SCROW ColumnIterator::getRow() const
+{
+ return CellStoreType::logical_position(maPos);
+}
+
+bool ColumnIterator::hasCell() const
+{
+ return !mbComplete;
+}
+
+mdds::mtv::element_t ColumnIterator::getType() const
+{
+ return maPos.first->type;
+}
+
+ScRefCellValue ColumnIterator::getCell() const
+{
+ return toRefCell(maPos.first, maPos.second);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */