LibreOffice Module sc (master) 1
cellvalues.cxx
Go to the documentation of this file.
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 <memory>
11#include <cellvalues.hxx>
12#include <column.hxx>
13#include <formulacell.hxx>
14#include <editeng/editobj.hxx>
15
16#include <cassert>
17
18namespace sc {
19
20namespace {
21
22struct BlockPos
23{
24 size_t mnStart;
25 size_t mnEnd;
26};
27
28}
29
31 mnRow1(nRow1), mnRow2(nRow2) {}
32
34{
37 CellStoreType::iterator miCellPos;
38 CellTextAttrStoreType::iterator miAttrPos;
39
40 CellValuesImpl() = default;
41
43 const CellValuesImpl& operator=(const CellValuesImpl&) = delete;
44};
45
47 mpImpl(new CellValuesImpl) {}
48
50{
51}
52
53void CellValues::transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen )
54{
55 mpImpl->maCells.resize(nLen);
56 mpImpl->maCellTextAttrs.resize(nLen);
57 rCol.maCells.transfer(nRow, nRow+nLen-1, mpImpl->maCells, 0);
58 rCol.maCellTextAttrs.transfer(nRow, nRow+nLen-1, mpImpl->maCellTextAttrs, 0);
59}
60
61
62void CellValues::copyTo( ScColumn& rCol, SCROW nRow ) const
63{
64 copyCellsTo(rCol, nRow);
65 copyCellTextAttrsTo(rCol, nRow);
66}
67
69{
70 std::vector<BlockPos> aBlocksToSwap;
71
72 // Go through static value blocks and record their positions and sizes.
73 for (const auto& rCell : mpImpl->maCells)
74 {
75 if (rCell.type == sc::element_type_empty)
76 continue;
77
78 BlockPos aPos;
79 aPos.mnStart = rCell.position;
80 aPos.mnEnd = aPos.mnStart + rCell.size - 1;
81 aBlocksToSwap.push_back(aPos);
82 }
83
84 // Do the swapping. The undo storage will store the replaced formula cells after this.
85 for (const auto& rBlock : aBlocksToSwap)
86 {
87 rCol.maCells.swap(rBlock.mnStart, rBlock.mnEnd, mpImpl->maCells, rBlock.mnStart);
88 rCol.maCellTextAttrs.swap(rBlock.mnStart, rBlock.mnEnd, mpImpl->maCellTextAttrs, rBlock.mnStart);
89 }
90}
91
92void CellValues::assign( const std::vector<double>& rVals )
93{
94 mpImpl->maCells.resize(rVals.size());
95 mpImpl->maCells.set(0, rVals.begin(), rVals.end());
96
97 // Set default text attributes.
98 std::vector<CellTextAttr> aDefaults(rVals.size(), CellTextAttr());
99 mpImpl->maCellTextAttrs.resize(rVals.size());
100 mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
101}
102
103void CellValues::assign( const std::vector<ScFormulaCell*>& rVals )
104{
105 std::vector<ScFormulaCell*> aCopyVals(rVals.size());
106 size_t nIdx = 0;
107 for (const auto* pCell : rVals)
108 {
109 aCopyVals[nIdx] = pCell->Clone();
110 ++nIdx;
111 }
112
113 mpImpl->maCells.resize(aCopyVals.size());
114 mpImpl->maCells.set(0, aCopyVals.begin(), aCopyVals.end());
115
116 // Set default text attributes.
117 std::vector<CellTextAttr> aDefaults(rVals.size(), CellTextAttr());
118 mpImpl->maCellTextAttrs.resize(rVals.size());
119 mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
120}
121
122size_t CellValues::size() const
123{
124 assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
125 return mpImpl->maCells.size();
126}
127
128void CellValues::reset( size_t nSize )
129{
130 mpImpl->maCells.clear();
131 mpImpl->maCells.resize(nSize);
132 mpImpl->maCellTextAttrs.clear();
133 mpImpl->maCellTextAttrs.resize(nSize);
134
135 mpImpl->miCellPos = mpImpl->maCells.begin();
136 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.begin();
137}
138
139void CellValues::setValue( size_t nRow, double fVal )
140{
141 mpImpl->miCellPos = mpImpl->maCells.set(mpImpl->miCellPos, nRow, fVal);
142 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.set(mpImpl->miAttrPos, nRow, sc::CellTextAttr());
143}
144
145void CellValues::setValue( size_t nRow, const svl::SharedString& rStr )
146{
147 mpImpl->miCellPos = mpImpl->maCells.set(mpImpl->miCellPos, nRow, rStr);
148 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.set(mpImpl->miAttrPos, nRow, sc::CellTextAttr());
149}
150
151void CellValues::setValue( size_t nRow, std::unique_ptr<EditTextObject> pEditText )
152{
153 mpImpl->miCellPos = mpImpl->maCells.set(mpImpl->miCellPos, nRow, pEditText.release());
154 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.set(mpImpl->miAttrPos, nRow, sc::CellTextAttr());
155}
156
158{
159 std::swap(mpImpl, r.mpImpl);
160}
161
162std::vector<CellValueSpan> CellValues::getNonEmptySpans() const
163{
164 std::vector<CellValueSpan> aRet;
165 for (const auto& rCell : mpImpl->maCells)
166 {
167 if (rCell.type != element_type_empty)
168 {
169 // Record this span.
170 size_t nRow1 = rCell.position;
171 size_t nRow2 = nRow1 + rCell.size - 1;
172 aRet.emplace_back(nRow1, nRow2);
173 }
174 }
175 return aRet;
176}
177
178void CellValues::copyCellsTo( ScColumn& rCol, SCROW nRow ) const
179{
180 CellStoreType& rDest = rCol.maCells;
181 const CellStoreType& rSrc = mpImpl->maCells;
182
183 // Caller must ensure the destination is long enough.
184 assert(rSrc.size() + static_cast<size_t>(nRow) <= rDest.size());
185
186 SCROW nCurRow = nRow;
187 CellStoreType::iterator itPos = rDest.begin();
188
189 for (const auto& rBlk : rSrc)
190 {
191 switch (rBlk.type)
192 {
194 {
195 numeric_block::const_iterator it = numeric_block::begin(*rBlk.data);
196 numeric_block::const_iterator itEnd = numeric_block::end(*rBlk.data);
197 itPos = rDest.set(itPos, nCurRow, it, itEnd);
198 }
199 break;
201 {
202 string_block::const_iterator it = string_block::begin(*rBlk.data);
203 string_block::const_iterator itEnd = string_block::end(*rBlk.data);
204 itPos = rDest.set(itPos, nCurRow, it, itEnd);
205 }
206 break;
208 {
209 edittext_block::const_iterator it = edittext_block::begin(*rBlk.data);
210 edittext_block::const_iterator itEnd = edittext_block::end(*rBlk.data);
211 std::vector<EditTextObject*> aVals;
212 aVals.reserve(rBlk.size);
213 for (; it != itEnd; ++it)
214 {
215 const EditTextObject* p = *it;
216 aVals.push_back(p->Clone().release());
217 }
218 itPos = rDest.set(itPos, nCurRow, aVals.begin(), aVals.end());
219 }
220 break;
222 {
223 formula_block::const_iterator it = formula_block::begin(*rBlk.data);
224 formula_block::const_iterator itEnd = formula_block::end(*rBlk.data);
225 std::vector<ScFormulaCell*> aVals;
226 aVals.reserve(rBlk.size);
227 for (; it != itEnd; ++it)
228 {
229 const ScFormulaCell* p = *it;
230 aVals.push_back(p->Clone());
231 }
232 itPos = rDest.set(itPos, nCurRow, aVals.begin(), aVals.end());
233 }
234 break;
235 default:
236 itPos = rDest.set_empty(itPos, nCurRow, nCurRow+rBlk.size-1);
237 }
238
239 nCurRow += rBlk.size;
240 }
241}
242
244{
246 const CellTextAttrStoreType& rSrc = mpImpl->maCellTextAttrs;
247
248 // Caller must ensure the destination is long enough.
249 assert(rSrc.size() + static_cast<size_t>(nRow) <= rDest.size());
250
251 SCROW nCurRow = nRow;
252 CellTextAttrStoreType::iterator itPos = rDest.begin();
253
254 for (const auto& rBlk : rSrc)
255 {
256 switch (rBlk.type)
257 {
259 {
260 celltextattr_block::const_iterator it = celltextattr_block::begin(*rBlk.data);
261 celltextattr_block::const_iterator itEnd = celltextattr_block::end(*rBlk.data);
262 itPos = rDest.set(itPos, nCurRow, it, itEnd);
263 }
264 break;
265 default:
266 itPos = rDest.set_empty(itPos, nCurRow, nCurRow+rBlk.size-1);
267 }
268
269 nCurRow += rBlk.size;
270 }
271}
272
273typedef std::vector<std::unique_ptr<CellValues>> TableType;
274typedef std::vector<std::unique_ptr<TableType>> TablesType;
275
277{
280
281 explicit Impl( const ScRange& rRange ) : maRange(rRange)
282 {
283 size_t nTabs = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
284 size_t nCols = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
285
286 for (size_t nTab = 0; nTab < nTabs; ++nTab)
287 {
288 m_Tables.push_back(std::make_unique<TableType>());
289 std::unique_ptr<TableType>& rTab2 = m_Tables.back();
290 for (size_t nCol = 0; nCol < nCols; ++nCol)
291 rTab2->push_back(std::make_unique<CellValues>());
292 }
293 }
294
296 {
297 if (nTab < maRange.aStart.Tab() || maRange.aEnd.Tab() < nTab)
298 // sheet index out of bound.
299 return nullptr;
300 if (nCol < maRange.aStart.Col() || maRange.aEnd.Col() < nCol)
301 // column index out of bound.
302 return nullptr;
303 size_t nTabOffset = nTab - maRange.aStart.Tab();
304 if (nTabOffset >= m_Tables.size())
305 return nullptr;
306 std::unique_ptr<TableType>& rTab2 = m_Tables[nTab-maRange.aStart.Tab()];
307 size_t nColOffset = nCol - maRange.aStart.Col();
308 if (nColOffset >= rTab2->size())
309 return nullptr;
310 return &rTab2.get()[0][nColOffset].get()[0];
311 }
312};
313
315 mpImpl(new Impl(ScRange(ScAddress::INITIALIZE_INVALID))) {}
316
318 mpImpl(new Impl(rRange)) {}
319
321{
322}
323
325{
326 return mpImpl->maRange;
327}
328
329void TableValues::swap( SCTAB nTab, SCCOL nCol, CellValues& rColValue )
330{
331 CellValues* pCol = mpImpl->getCellValues(nTab, nCol);
332 if (!pCol)
333 return;
334
335 pCol->swap(rColValue);
336}
337
339{
340 CellValues* pCol = mpImpl->getCellValues(nTab, nCol);
341 if (!pCol)
342 return;
343
344 pCol->swapNonEmpty(rCol);
345}
346
347std::vector<CellValueSpan> TableValues::getNonEmptySpans( SCTAB nTab, SCCOL nCol ) const
348{
349 std::vector<CellValueSpan> aRet;
350 CellValues* pCol = mpImpl->getCellValues(nTab, nCol);
351 if (pCol)
352 aRet = pCol->getNonEmptySpans();
353
354 return aRet;
355}
356
358{
359 std::swap(mpImpl, rOther.mpImpl);
360}
361
362}
363
364/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t mnEnd
Definition: cellvalues.cxx:25
size_t mnStart
Definition: cellvalues.cxx:24
SCTAB Tab() const
Definition: address.hxx:283
SCCOL Col() const
Definition: address.hxx:279
sc::CellTextAttrStoreType maCellTextAttrs
Definition: column.hxx:188
sc::CellStoreType maCells
Definition: column.hxx:197
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
Think of this as a mini-ScColumn like storage that only stores cell values in a column.
Definition: cellvalues.hxx:42
void assign(const std::vector< double > &rVals)
Definition: cellvalues.cxx:92
void copyCellTextAttrsTo(ScColumn &rCol, SCROW nRow) const
Definition: cellvalues.cxx:243
void transferFrom(ScColumn &rCol, SCROW nRow, size_t nLen)
Transfer values from specified column.
Definition: cellvalues.cxx:53
void reset(size_t nSize)
Definition: cellvalues.cxx:128
void copyCellsTo(ScColumn &rCol, SCROW nRow) const
Definition: cellvalues.cxx:178
std::unique_ptr< CellValuesImpl > mpImpl
Definition: cellvalues.hxx:43
std::vector< CellValueSpan > getNonEmptySpans() const
Definition: cellvalues.cxx:162
void swap(CellValues &r)
Definition: cellvalues.cxx:157
size_t size() const
Definition: cellvalues.cxx:122
void copyTo(ScColumn &rCol, SCROW nRow) const
Definition: cellvalues.cxx:62
void swapNonEmpty(ScColumn &rCol)
Definition: cellvalues.cxx:68
void setValue(size_t nRow, double fVal)
Definition: cellvalues.cxx:139
Stores cell values for multiple tables.
Definition: cellvalues.hxx:89
void swap(SCTAB nTab, SCCOL nCol, CellValues &rColValue)
Swap the entire column.
Definition: cellvalues.cxx:329
std::vector< CellValueSpan > getNonEmptySpans(SCTAB nTab, SCCOL nCol) const
Definition: cellvalues.cxx:347
const ScRange & getRange() const
Definition: cellvalues.cxx:324
void swapNonEmpty(SCTAB nTab, SCCOL nCol, ScColumn &rCol)
Swap non-empty blocks with the column storage.
Definition: cellvalues.cxx:338
std::unique_ptr< Impl > mpImpl
Definition: cellvalues.hxx:90
void * p
CAUTION! The following defines must be in the same namespace as the respective type.
Definition: broadcast.cxx:15
const mdds::mtv::element_t element_type_celltextattr
Definition: mtvelements.hxx:45
const mdds::mtv::element_t element_type_edittext
Definition: mtvelements.hxx:48
const mdds::mtv::element_t element_type_formula
Definition: mtvelements.hxx:49
std::vector< std::unique_ptr< CellValues > > TableType
Definition: cellvalues.cxx:273
mdds::mtv::soa::multi_type_vector< CellStoreTraits > CellStoreType
Cell container.
const mdds::mtv::element_t element_type_numeric
Mapped standard element types (for convenience).
Definition: mtvelements.hxx:55
mdds::mtv::soa::multi_type_vector< CellTextAttrTraits > CellTextAttrStoreType
Cell text attribute container.
const mdds::mtv::element_t element_type_string
Definition: mtvelements.hxx:47
const mdds::mtv::element_t element_type_empty
Definition: mtvelements.hxx:56
std::vector< std::unique_ptr< TableType > > TablesType
Definition: cellvalues.cxx:274
CellValueSpan(SCROW nRow1, SCROW nRow2)
Definition: cellvalues.cxx:30
CellValuesImpl()=default
CellTextAttrStoreType::iterator miAttrPos
Definition: cellvalues.cxx:38
CellStoreType maCells
Definition: cellvalues.cxx:35
CellValuesImpl(const CellValuesImpl &)=delete
const CellValuesImpl & operator=(const CellValuesImpl &)=delete
CellTextAttrStoreType maCellTextAttrs
Definition: cellvalues.cxx:36
CellStoreType::iterator miCellPos
Definition: cellvalues.cxx:37
CellValues * getCellValues(SCTAB nTab, SCCOL nCol)
Definition: cellvalues.cxx:295
Impl(const ScRange &rRange)
Definition: cellvalues.cxx:281
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17