Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include "columniterator.hxx"
11 : #include "column.hxx"
12 : #include "document.hxx"
13 : #include "table.hxx"
14 :
15 0 : 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 0 : miBlockEnd(mrCellTextAttrs.end())
21 : {
22 0 : init(nStartRow, nEndRow);
23 0 : }
24 :
25 0 : ScColumnTextWidthIterator::ScColumnTextWidthIterator(ScDocument& rDoc, const ScAddress& rStartPos, SCROW nEndRow) :
26 0 : mrCellTextAttrs(rDoc.maTabs[rStartPos.Tab()]->aCol[rStartPos.Col()].maCellTextAttrs),
27 : mnEnd(static_cast<size_t>(nEndRow)),
28 : mnCurPos(0),
29 : miBlockCur(mrCellTextAttrs.begin()),
30 0 : miBlockEnd(mrCellTextAttrs.end())
31 : {
32 0 : init(rStartPos.Row(), nEndRow);
33 0 : }
34 :
35 0 : void ScColumnTextWidthIterator::next()
36 : {
37 0 : ++miDataCur;
38 0 : ++mnCurPos;
39 :
40 0 : if (miDataCur != miDataEnd)
41 : {
42 : // Stil in the same block. We're good.
43 0 : checkEndRow();
44 0 : return;
45 : }
46 :
47 : // Move to the next block.
48 0 : for (++miBlockCur; miBlockCur != miBlockEnd; ++miBlockCur)
49 : {
50 0 : if (miBlockCur->type != sc::element_type_celltextattr)
51 : {
52 : // We don't iterator over this block.
53 0 : mnCurPos += miBlockCur->size;
54 0 : continue;
55 : }
56 :
57 0 : getDataIterators(0);
58 0 : checkEndRow();
59 0 : return;
60 : }
61 :
62 : // Reached the end.
63 : OSL_ASSERT(miBlockCur == miBlockEnd);
64 : }
65 :
66 0 : bool ScColumnTextWidthIterator::hasCell() const
67 : {
68 0 : return miBlockCur != miBlockEnd;
69 : }
70 :
71 0 : SCROW ScColumnTextWidthIterator::getPos() const
72 : {
73 : OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
74 0 : return static_cast<SCROW>(mnCurPos);
75 : }
76 :
77 0 : sal_uInt16 ScColumnTextWidthIterator::getValue() const
78 : {
79 : OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
80 0 : return miDataCur->mnTextWidth;
81 : }
82 :
83 0 : void ScColumnTextWidthIterator::setValue(sal_uInt16 nVal)
84 : {
85 : OSL_ASSERT(miBlockCur != miBlockEnd && miDataCur != miDataEnd);
86 0 : miDataCur->mnTextWidth = nVal;
87 0 : }
88 :
89 0 : void ScColumnTextWidthIterator::init(SCROW nStartRow, SCROW nEndRow)
90 : {
91 0 : if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
92 0 : miBlockCur = miBlockEnd;
93 :
94 0 : size_t nStart = static_cast<size_t>(nStartRow);
95 :
96 : // Locate the start row position.
97 0 : size_t nBlockStart = 0, nBlockEnd = 0;
98 0 : for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
99 : {
100 0 : nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
101 0 : if (nBlockStart <= nStart && nStart < nBlockEnd)
102 : {
103 : // Initial block is found!
104 0 : break;
105 : }
106 : }
107 :
108 0 : if (miBlockCur == miBlockEnd)
109 : // Initial block not found for whatever reason... Bail out.
110 0 : return;
111 :
112 : // Locate the initial row position within this block.
113 0 : if (miBlockCur->type == sc::element_type_celltextattr)
114 : {
115 : // This block stores text widths for non-empty cells.
116 0 : size_t nOffsetInBlock = nStart - nBlockStart;
117 0 : mnCurPos = nStart;
118 0 : getDataIterators(nOffsetInBlock);
119 0 : checkEndRow();
120 0 : return;
121 : }
122 :
123 : // Current block is not of ushort type. Skip to the next block.
124 0 : nBlockStart = nBlockEnd;
125 0 : ++miBlockCur;
126 :
127 : // Look for the first ushort block.
128 0 : for (; miBlockCur != miBlockEnd; ++miBlockCur, nBlockStart = nBlockEnd)
129 : {
130 0 : nBlockEnd = nBlockStart + miBlockCur->size; // non-inclusive end point.
131 0 : if (miBlockCur->type != sc::element_type_celltextattr)
132 0 : continue;
133 :
134 : // Found!
135 0 : mnCurPos = nBlockStart;
136 0 : getDataIterators(0);
137 0 : checkEndRow();
138 0 : return;
139 : }
140 :
141 : // Not found.
142 : OSL_ASSERT(miBlockCur == miBlockEnd);
143 : }
144 :
145 0 : void ScColumnTextWidthIterator::getDataIterators(size_t nOffsetInBlock)
146 : {
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 0 : miDataCur = sc::celltextattr_block::begin(*miBlockCur->data);
154 0 : miDataEnd = sc::celltextattr_block::end(*miBlockCur->data);
155 :
156 0 : std::advance(miDataCur, nOffsetInBlock);
157 0 : }
158 :
159 0 : void ScColumnTextWidthIterator::checkEndRow()
160 : {
161 0 : if (mnCurPos <= mnEnd)
162 : // We're still good.
163 0 : return;
164 :
165 : // We're below the end position. End the iteration.
166 0 : miBlockCur = miBlockEnd;
167 0 : }
168 :
169 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|