fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / cellvalues.cxx
blob725c5b9fe5261296260486902cb5914fc64bb565
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 <cellvalues.hxx>
11 #include <column.hxx>
12 #include <cellvalue.hxx>
14 #include <cassert>
15 #include <boost/noncopyable.hpp>
16 #include <boost/ptr_container/ptr_vector.hpp>
18 namespace sc {
20 namespace {
22 struct BlockPos
24 size_t mnStart;
25 size_t mnEnd;
28 CellType toCellType( mdds::mtv::element_t eType )
30 switch (eType)
32 case element_type_numeric:
33 return CELLTYPE_VALUE;
34 case element_type_string:
35 return CELLTYPE_STRING;
36 case element_type_edittext:
37 return CELLTYPE_EDIT;
38 case element_type_formula:
39 return CELLTYPE_FORMULA;
40 default:
44 return CELLTYPE_NONE;
49 CellValueSpan::CellValueSpan( SCROW nRow1, SCROW nRow2, CellType eType ) :
50 mnRow1(nRow1), mnRow2(nRow2), meType(eType) {}
52 struct CellValuesImpl : boost::noncopyable
54 CellStoreType maCells;
55 CellTextAttrStoreType maCellTextAttrs;
56 CellStoreType::iterator miCellPos;
57 CellTextAttrStoreType::iterator miAttrPos;
60 CellValues::CellValues() :
61 mpImpl(new CellValuesImpl) {}
63 CellValues::~CellValues()
65 delete mpImpl;
68 void CellValues::transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen )
70 mpImpl->maCells.resize(nLen);
71 mpImpl->maCellTextAttrs.resize(nLen);
72 rCol.maCells.transfer(nRow, nRow+nLen-1, mpImpl->maCells, 0);
73 rCol.maCellTextAttrs.transfer(nRow, nRow+nLen-1, mpImpl->maCellTextAttrs, 0);
76 void CellValues::transferTo( ScColumn& rCol, SCROW nRow )
78 assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
80 size_t nLen = mpImpl->maCells.size();
81 mpImpl->maCells.transfer(0, nLen-1, rCol.maCells, nRow);
82 mpImpl->maCellTextAttrs.transfer(0, nLen-1, rCol.maCellTextAttrs, nRow);
85 void CellValues::copyTo( ScColumn& rCol, SCROW nRow ) const
87 copyCellsTo(rCol, nRow);
88 copyCellTextAttrsTo(rCol, nRow);
91 void CellValues::swapNonEmpty( ScColumn& rCol )
93 std::vector<BlockPos> aBlocksToSwap;
96 // Go through static value blocks and record their positions and sizes.
97 sc::CellStoreType::const_iterator it = mpImpl->maCells.begin(), itEnd = mpImpl->maCells.end();
98 for (; it != itEnd; ++it)
100 if (it->type == sc::element_type_empty)
101 continue;
103 BlockPos aPos;
104 aPos.mnStart = it->position;
105 aPos.mnEnd = aPos.mnStart + it->size - 1;
106 aBlocksToSwap.push_back(aPos);
110 // Do the swapping. The undo storage will store the replaced formula cells after this.
111 std::vector<BlockPos>::const_iterator it = aBlocksToSwap.begin(), itEnd = aBlocksToSwap.end();
112 for (; it != itEnd; ++it)
114 rCol.maCells.swap(it->mnStart, it->mnEnd, mpImpl->maCells, it->mnStart);
115 rCol.maCellTextAttrs.swap(it->mnStart, it->mnEnd, mpImpl->maCellTextAttrs, it->mnStart);
119 void CellValues::assign( const std::vector<double>& rVals )
121 mpImpl->maCells.resize(rVals.size());
122 mpImpl->maCells.set(0, rVals.begin(), rVals.end());
124 // Set default text attributes.
125 std::vector<CellTextAttr> aDefaults(rVals.size(), CellTextAttr());
126 mpImpl->maCellTextAttrs.resize(rVals.size());
127 mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
130 size_t CellValues::size() const
132 assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
133 return mpImpl->maCells.size();
136 void CellValues::reset( size_t nSize )
138 mpImpl->maCells.clear();
139 mpImpl->maCells.resize(nSize);
140 mpImpl->maCellTextAttrs.clear();
141 mpImpl->maCellTextAttrs.resize(nSize);
143 mpImpl->miCellPos = mpImpl->maCells.begin();
144 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.begin();
147 void CellValues::setValue( size_t nRow, double fVal )
149 mpImpl->miCellPos = mpImpl->maCells.set(mpImpl->miCellPos, nRow, fVal);
150 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.set(mpImpl->miAttrPos, nRow, sc::CellTextAttr());
153 void CellValues::setValue( size_t nRow, const svl::SharedString& rStr )
155 mpImpl->miCellPos = mpImpl->maCells.set(mpImpl->miCellPos, nRow, rStr);
156 mpImpl->miAttrPos = mpImpl->maCellTextAttrs.set(mpImpl->miAttrPos, nRow, sc::CellTextAttr());
159 void CellValues::swap( CellValues& r )
161 std::swap(mpImpl, r.mpImpl);
164 std::vector<CellValueSpan> CellValues::getNonEmptySpans() const
166 std::vector<CellValueSpan> aRet;
167 CellStoreType::const_iterator it = mpImpl->maCells.begin(), itEnd = mpImpl->maCells.end();
168 for (; it != itEnd; ++it)
170 if (it->type != element_type_empty)
172 // Record this span.
173 size_t nRow1 = it->position;
174 size_t nRow2 = nRow1 + it->size - 1;
175 aRet.push_back(CellValueSpan(nRow1, nRow2, toCellType(it->type)));
178 return aRet;
181 void CellValues::copyCellsTo( ScColumn& rCol, SCROW nRow ) const
183 CellStoreType& rDest = rCol.maCells;
184 const CellStoreType& rSrc = mpImpl->maCells;
186 // Caller must ensure the destination is long enough.
187 assert(rSrc.size() + static_cast<size_t>(nRow) < rDest.size());
189 SCROW nCurRow = nRow;
190 CellStoreType::iterator itPos = rDest.begin();
192 CellStoreType::const_iterator itBlk = rSrc.begin(), itBlkEnd = rSrc.end();
193 for (; itBlk != itBlkEnd; ++itBlk)
195 switch (itBlk->type)
197 case element_type_numeric:
199 numeric_block::const_iterator it = numeric_block::begin(*itBlk->data);
200 numeric_block::const_iterator itEnd = numeric_block::end(*itBlk->data);
201 itPos = rDest.set(itPos, nCurRow, it, itEnd);
203 break;
204 case element_type_string:
206 string_block::const_iterator it = string_block::begin(*itBlk->data);
207 string_block::const_iterator itEnd = string_block::end(*itBlk->data);
208 itPos = rDest.set(itPos, nCurRow, it, itEnd);
210 break;
211 case element_type_edittext:
213 edittext_block::const_iterator it = edittext_block::begin(*itBlk->data);
214 edittext_block::const_iterator itEnd = edittext_block::end(*itBlk->data);
215 std::vector<EditTextObject*> aVals;
216 aVals.reserve(itBlk->size);
217 for (; it != itEnd; ++it)
219 const EditTextObject* p = *it;
220 aVals.push_back(p->Clone());
222 itPos = rDest.set(itPos, nCurRow, aVals.begin(), aVals.end());
224 break;
225 case element_type_formula:
227 formula_block::const_iterator it = formula_block::begin(*itBlk->data);
228 formula_block::const_iterator itEnd = formula_block::end(*itBlk->data);
229 std::vector<ScFormulaCell*> aVals;
230 aVals.reserve(itBlk->size);
231 for (; it != itEnd; ++it)
233 const ScFormulaCell* p = *it;
234 aVals.push_back(p->Clone());
236 itPos = rDest.set(itPos, nCurRow, aVals.begin(), aVals.end());
238 break;
239 default:
240 itPos = rDest.set_empty(itPos, nCurRow, nCurRow+itBlk->size-1);
243 nCurRow += itBlk->size;
247 void CellValues::copyCellTextAttrsTo( ScColumn& rCol, SCROW nRow ) const
249 CellTextAttrStoreType& rDest = rCol.maCellTextAttrs;
250 const CellTextAttrStoreType& rSrc = mpImpl->maCellTextAttrs;
252 // Caller must ensure the destination is long enough.
253 assert(rSrc.size() + static_cast<size_t>(nRow) < rDest.size());
255 SCROW nCurRow = nRow;
256 CellTextAttrStoreType::iterator itPos = rDest.begin();
258 CellTextAttrStoreType::const_iterator itBlk = rSrc.begin(), itBlkEnd = rSrc.end();
259 for (; itBlk != itBlkEnd; ++itBlk)
261 switch (itBlk->type)
263 case element_type_celltextattr:
265 celltextattr_block::const_iterator it = celltextattr_block::begin(*itBlk->data);
266 celltextattr_block::const_iterator itEnd = celltextattr_block::end(*itBlk->data);
267 itPos = rDest.set(itPos, nCurRow, it, itEnd);
269 break;
270 default:
271 itPos = rDest.set_empty(itPos, nCurRow, nCurRow+itBlk->size-1);
274 nCurRow += itBlk->size;
278 typedef boost::ptr_vector<CellValues> TableType;
279 typedef boost::ptr_vector<TableType> TablesType;
281 struct TableValues::Impl
283 ScRange maRange;
284 TablesType maTables;
286 Impl( const ScRange& rRange ) : maRange(rRange)
288 size_t nTabs = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
289 size_t nCols = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
291 for (size_t nTab = 0; nTab < nTabs; ++nTab)
293 maTables.push_back(new TableType);
294 TableType& rTab = maTables.back();
295 for (size_t nCol = 0; nCol < nCols; ++nCol)
296 rTab.push_back(new CellValues);
300 CellValues* getCellValues( SCTAB nTab, SCCOL nCol )
302 if (nTab < maRange.aStart.Tab() || maRange.aEnd.Tab() < nTab)
303 // sheet index out of bound.
304 return NULL;
306 if (nCol < maRange.aStart.Col() || maRange.aEnd.Col() < nCol)
307 // column index out of bound.
308 return NULL;
310 size_t nTabOffset = nTab - maRange.aStart.Tab();
311 if (nTabOffset >= maTables.size())
312 return NULL;
314 TableType& rTab = maTables[nTab-maRange.aStart.Tab()];
316 size_t nColOffset = nCol - maRange.aStart.Col();
317 if (nColOffset >= rTab.size())
318 return NULL;
320 return &rTab[nColOffset];
324 TableValues::TableValues() :
325 mpImpl(new Impl(ScRange(ScAddress::INITIALIZE_INVALID))) {}
327 TableValues::TableValues( const ScRange& rRange ) :
328 mpImpl(new Impl(rRange)) {}
330 TableValues::~TableValues()
332 delete mpImpl;
335 const ScRange& TableValues::getRange() const
337 return mpImpl->maRange;
340 void TableValues::swap( SCTAB nTab, SCCOL nCol, CellValues& rColValue )
342 CellValues* pCol = mpImpl->getCellValues(nTab, nCol);
343 if (!pCol)
344 return;
346 pCol->swap(rColValue);
349 void TableValues::swapNonEmpty( SCTAB nTab, SCCOL nCol, ScColumn& rCol )
351 CellValues* pCol = mpImpl->getCellValues(nTab, nCol);
352 if (!pCol)
353 return;
355 pCol->swapNonEmpty(rCol);
358 std::vector<CellValueSpan> TableValues::getNonEmptySpans( SCTAB nTab, SCCOL nCol ) const
360 std::vector<CellValueSpan> aRet;
361 CellValues* pCol = mpImpl->getCellValues(nTab, nCol);
362 if (pCol)
363 aRet = pCol->getNonEmptySpans();
365 return aRet;
368 void TableValues::swap( TableValues& rOther )
370 std::swap(mpImpl, rOther.mpImpl);
375 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */