Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / sc / source / core / data / columniterator.cxx
blobcec8f7a2028e7532b9871f229d4a80b2fa4f3a93
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 #include <osl/diagnose.h>
17 ScColumnTextWidthIterator::ScColumnTextWidthIterator(const ScDocument& rDoc, ScColumn& rCol, SCROW nStartRow, SCROW nEndRow) :
18 mnEnd(static_cast<size_t>(nEndRow)),
19 mnCurPos(0)
21 miBlockCur = rCol.maCellTextAttrs.begin();
22 miBlockEnd = rCol.maCellTextAttrs.end();
23 init(rDoc, nStartRow, nEndRow);
26 ScColumnTextWidthIterator::ScColumnTextWidthIterator(const ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow) :
27 mnEnd(static_cast<size_t>(nEndRow)),
28 mnCurPos(0)
30 auto & rCellTextAttrs = rDoc.maTabs[rStartPos.Tab()]->aCol[rStartPos.Col()].maCellTextAttrs;
31 miBlockCur = rCellTextAttrs.begin();
32 miBlockEnd = rCellTextAttrs.end();
33 init(rDoc, rStartPos.Row(), nEndRow);
36 void ScColumnTextWidthIterator::next()
38 ++miDataCur;
39 ++mnCurPos;
41 if (miDataCur != miDataEnd)
43 // Still in the same block. We're good.
44 checkEndRow();
45 return;
48 // Move to the next block.
49 for (++miBlockCur; miBlockCur != miBlockEnd; ++miBlockCur)
51 if (miBlockCur->type != sc::element_type_celltextattr)
53 // We don't iterator over this block.
54 mnCurPos += miBlockCur->size;
55 continue;
58 getDataIterators(0);
59 checkEndRow();
60 return;
63 // Reached the end.
64 assert(miBlockCur == miBlockEnd);
67 bool ScColumnTextWidthIterator::hasCell() const
69 return miBlockCur != miBlockEnd;
72 SCROW ScColumnTextWidthIterator::getPos() const
74 assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
75 return static_cast<SCROW>(mnCurPos);
78 sal_uInt16 ScColumnTextWidthIterator::getValue() const
80 assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
81 return miDataCur->mnTextWidth;
84 void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal)
86 assert(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
87 miDataCur->mnTextWidth = nVal;
90 void ScColumnTextWidthIterator::init(const ScDocument& rDoc, SCROW nStartRow, SCROW nEndRow)
92 if (!rDoc.ValidRow(nStartRow) || !rDoc.ValidRow(nEndRow))
93 miBlockCur = miBlockEnd;
95 size_t nStart = static_cast<size_t>(nStartRow);
97 // Locate the start row position.
98 size_t nBlockStart = 0, nBlockEnd = 0;
99 for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
101 nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
102 if (nBlockStart <= nStart && nStart < nBlockEnd)
104 // Initial block is found!
105 break;
109 if (miBlockCur == miBlockEnd)
110 // Initial block not found for whatever reason... Bail out.
111 return;
113 // Locate the initial row position within this block.
114 if (miBlockCur->type == sc::element_type_celltextattr)
116 // This block stores text widths for non-empty cells.
117 size_t nOffsetInBlock = nStart - nBlockStart;
118 mnCurPos = nStart;
119 getDataIterators(nOffsetInBlock);
120 checkEndRow();
121 return;
124 // Current block is not of ushort type. Skip to the next block.
125 nBlockStart = nBlockEnd;
126 ++miBlockCur;
128 // Look for the first ushort block.
129 for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
131 nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
132 if (miBlockCur->type != sc::element_type_celltextattr)
133 continue;
135 // Found!
136 mnCurPos = nBlockStart;
137 getDataIterators(0);
138 checkEndRow();
139 return;
142 // Not found.
143 assert(miBlockCur == miBlockEnd);
146 void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock)
148 OSL_ENSURE(miBlockCur != miBlockEnd, "block is at end position");
149 #if 0
150 // Does not compile
151 OSL_ENSURE(miBlockCur->type == sc::celltextattr_block,
152 "wrong block type - unsigned short block expected.");
153 #endif
154 miDataCur = sc::celltextattr_block::begin(*miBlockCur->data);
155 miDataEnd = sc::celltextattr_block::end(*miBlockCur->data);
157 std::advance(miDataCur, nOffsetInBlock);
160 void ScColumnTextWidthIterator::checkEndRow()
162 if (mnCurPos <= mnEnd)
163 // We're still good.
164 return;
166 // We're below the end position. End the iteration.
167 miBlockCur = miBlockEnd;
170 namespace sc {
172 ColumnIterator::ColumnIterator( const CellStoreType& rCells, SCROW nRow1, SCROW nRow2 ) :
173 maPos(rCells.position(nRow1)),
174 maPosEnd(rCells.position(maPos.first, nRow2)),
175 mbComplete(false)
179 void ColumnIterator::next()
181 if ( maPos == maPosEnd)
182 mbComplete = true;
183 else
184 maPos = CellStoreType::next_position(maPos);
187 SCROW ColumnIterator::getRow() const
189 return CellStoreType::logical_position(maPos);
192 bool ColumnIterator::hasCell() const
194 return !mbComplete;
197 mdds::mtv::element_t ColumnIterator::getType() const
199 return maPos.first->type;
202 ScRefCellValue ColumnIterator::getCell() const
204 return toRefCell(maPos.first, maPos.second);
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */