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 ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScColumn
& rCol
, SCROW nStartRow
, SCROW nEndRow
) :
16 mrCellTextAttrs(rCol
.maCellTextAttrs
),
17 mnEnd(static_cast<size_t>(nEndRow
)),
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
)),
29 miBlockCur(mrCellTextAttrs
.begin()),
30 miBlockEnd(mrCellTextAttrs
.end())
32 init(rStartPos
.Row(), nEndRow
);
35 void ScColumnTextWidthIterator::next()
40 if (miDataCur
!= miDataEnd
)
42 // Stil in the same block. We're good.
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
;
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!
108 if (miBlockCur
== miBlockEnd
)
109 // Initial block not found for whatever reason... Bail out.
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
;
118 getDataIterators(nOffsetInBlock
);
123 // Current block is not of ushort type. Skip to the next block.
124 nBlockStart
= nBlockEnd
;
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
)
135 mnCurPos
= nBlockStart
;
142 OSL_ASSERT(miBlockCur
== miBlockEnd
);
145 void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock
)
147 OSL_ENSURE(miBlockCur
!= miBlockEnd
, "block is at end position");
150 OSL_ENSURE(miBlockCur
->type
== sc::celltextattr_block
,
151 "wrong block type - unsigned short block expected.");
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
)
165 // We're below the end position. End the iteration.
166 miBlockCur
= miBlockEnd
;
169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */