Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / columniterator.cxx
blob6b5c1a47176bd2d7f36956a69c478dc4a92dedf1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "columniterator.hxx"
11 #include "column.hxx"
12 #include "document.hxx"
13 #include "table.hxx"
15 ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScColumn& rCol, SCROW nStartRow, SCROW nEndRow) :
16 mrCellTextAttrs(rCol.maCellTextAttrs),
17 mnEnd(static_cast<size_t>(nEndRow)),
18 mnCurPos(0),
19 miBlockCur(mrCellTextAttrs.begin()),
20 miBlockEnd(mrCellTextAttrs.end())
22 init(nStartRow, nEndRow);
25 ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow) :
26 mrCellTextAttrs(rDoc.maTabs[rStartPos.Tab()]->aCol[rStartPos.Col()].maCellTextAttrs),
27 mnEnd(static_cast<size_t>(nEndRow)),
28 mnCurPos(0),
29 miBlockCur(mrCellTextAttrs.begin()),
30 miBlockEnd(mrCellTextAttrs.end())
32 init(rStartPos.Row(), nEndRow);
35 void ScColumnTextWidthIterator::next()
37 ++miDataCur;
38 ++mnCurPos;
40 if (miDataCur != miDataEnd)
42 // Stil in the same block. We're good.
43 checkEndRow();
44 return;
47 // Move to the next block.
48 for (++miBlockCur; miBlockCur != miBlockEnd; ++miBlockCur)
50 if (miBlockCur->type != sc::element_type_celltextattr)
52 // We don't iterator over this block.
53 mnCurPos += miBlockCur->size;
54 continue;
57 getDataIterators(0);
58 checkEndRow();
59 return;
62 // Reached the end.
63 OSL_ASSERT(miBlockCur == miBlockEnd);
66 bool ScColumnTextWidthIterator::hasCell() const
68 return miBlockCur != miBlockEnd;
71 SCROW ScColumnTextWidthIterator::getPos() const
73 OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
74 return static_cast<SCROW>(mnCurPos);
77 sal_uInt16 ScColumnTextWidthIterator::getValue() const
79 OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
80 return miDataCur->mnTextWidth;
83 void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal)
85 OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
86 miDataCur->mnTextWidth = nVal;
89 void ScColumnTextWidthIterator::init(SCROW nStartRow, SCROW nEndRow)
91 if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
92 miBlockCur = miBlockEnd;
94 size_t nStart = static_cast<size_t>(nStartRow);
96 // Locate the start row position.
97 size_t nBlockStart = 0, nBlockEnd = 0;
98 for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
100 nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
101 if (nBlockStart <= nStart && nStart < nBlockEnd)
103 // Initial block is found!
104 break;
108 if (miBlockCur == miBlockEnd)
109 // Initial block not found for whatever reason... Bail out.
110 return;
112 // Locate the initial row position within this block.
113 if (miBlockCur->type == sc::element_type_celltextattr)
115 // This block stores text widths for non-empty cells.
116 size_t nOffsetInBlock = nStart - nBlockStart;
117 mnCurPos = nStart;
118 getDataIterators(nOffsetInBlock);
119 checkEndRow();
120 return;
123 // Current block is not of ushort type. Skip to the next block.
124 nBlockStart = nBlockEnd;
125 ++miBlockCur;
127 // Look for the first ushort block.
128 for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
130 nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
131 if (miBlockCur->type != sc::element_type_celltextattr)
132 continue;
134 // Found!
135 mnCurPos = nBlockStart;
136 getDataIterators(0);
137 checkEndRow();
138 return;
141 // Not found.
142 OSL_ASSERT(miBlockCur == miBlockEnd);
145 void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock)
147 OSL_ENSURE(miBlockCur != miBlockEnd, "block is at end position");
148 #if 0
149 // Does not compile
150 OSL_ENSURE(miBlockCur->type == sc::celltextattr_block,
151 "wrong block type - unsigned short block expected.");
152 #endif
153 miDataCur = sc::celltextattr_block::begin(*miBlockCur->data);
154 miDataEnd = sc::celltextattr_block::end(*miBlockCur->data);
156 std::advance(miDataCur, nOffsetInBlock);
159 void ScColumnTextWidthIterator::checkEndRow()
161 if (mnCurPos <= mnEnd)
162 // We're still good.
163 return;
165 // We're below the end position. End the iteration.
166 miBlockCur = miBlockEnd;
169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */