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