1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <columniterator.hxx>
12 #include <document.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
)),
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
)),
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()
41 if (miDataCur
!= miDataEnd
)
43 // Still in the same block. We're good.
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
;
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!
109 if (miBlockCur
== miBlockEnd
)
110 // Initial block not found for whatever reason... Bail out.
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
;
119 getDataIterators(nOffsetInBlock
);
124 // Current block is not of ushort type. Skip to the next block.
125 nBlockStart
= nBlockEnd
;
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
)
136 mnCurPos
= nBlockStart
;
143 assert(miBlockCur
== miBlockEnd
);
146 void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock
)
148 OSL_ENSURE(miBlockCur
!= miBlockEnd
, "block is at end position");
151 OSL_ENSURE(miBlockCur
->type
== sc::celltextattr_block
,
152 "wrong block type - unsigned short block expected.");
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
)
166 // We're below the end position. End the iteration.
167 miBlockCur
= miBlockEnd
;
172 ColumnIterator::ColumnIterator( const CellStoreType
& rCells
, SCROW nRow1
, SCROW nRow2
) :
173 maPos(rCells
.position(nRow1
)),
174 maPosEnd(rCells
.position(maPos
.first
, nRow2
)),
179 void ColumnIterator::next()
181 if ( maPos
== maPosEnd
)
184 maPos
= CellStoreType::next_position(maPos
);
187 SCROW
ColumnIterator::getRow() const
189 return CellStoreType::logical_position(maPos
);
192 bool ColumnIterator::hasCell() const
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: */