Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / data / cellvalue.cxx
blob12ef30272e62c545332bcf1085d80be60242bc84
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 "cellvalue.hxx"
11 #include "document.hxx"
12 #include "column.hxx"
13 #include "formulacell.hxx"
14 #include "editeng/editobj.hxx"
15 #include "editeng/editstat.hxx"
16 #include "stringutil.hxx"
17 #include "editutil.hxx"
18 #include "tokenarray.hxx"
19 #include "formula/token.hxx"
20 #include "svl/sharedstring.hxx"
22 namespace {
24 CellType adjustCellType( CellType eOrig )
26 switch (eOrig)
28 case CELLTYPE_EDIT:
29 return CELLTYPE_STRING;
30 default:
33 return eOrig;
36 template<typename _T>
37 OUString getString( const _T& rVal )
39 if (rVal.meType == CELLTYPE_STRING)
40 return rVal.mpString->getString();
42 if (rVal.meType == CELLTYPE_EDIT)
44 OUStringBuffer aRet;
45 sal_Int32 n = rVal.mpEditText->GetParagraphCount();
46 for (sal_Int32 i = 0; i < n; ++i)
48 if (i > 0)
49 aRet.append('\n');
50 aRet.append(rVal.mpEditText->GetText(i));
52 return aRet.makeStringAndClear();
55 return EMPTY_OUSTRING;
58 bool equalsFormulaCells( const ScFormulaCell* p1, const ScFormulaCell* p2 )
60 const ScTokenArray* pCode1 = p1->GetCode();
61 const ScTokenArray* pCode2 = p2->GetCode();
63 if (pCode1->GetLen() != pCode2->GetLen())
64 return false;
66 sal_uInt16 n = pCode1->GetLen();
67 formula::FormulaToken** ppToken1 = pCode1->GetArray();
68 formula::FormulaToken** ppToken2 = pCode2->GetArray();
69 for (sal_uInt16 i = 0; i < n; ++i)
71 if (!ppToken1[i]->TextEqual(*(ppToken2[i])))
72 return false;
75 return true;
78 template<typename _T>
79 bool equalsWithoutFormatImpl( const _T& left, const _T& right )
81 CellType eType1 = adjustCellType(left.meType);
82 CellType eType2 = adjustCellType(right.meType);
83 if (eType1 != eType2)
84 return false;
86 switch (eType1)
88 case CELLTYPE_NONE:
89 return true;
90 case CELLTYPE_VALUE:
91 return left.mfValue == right.mfValue;
92 case CELLTYPE_STRING:
94 OUString aStr1 = getString(left);
95 OUString aStr2 = getString(right);
96 return aStr1 == aStr2;
98 case CELLTYPE_FORMULA:
99 return equalsFormulaCells(left.mpFormula, right.mpFormula);
100 default:
103 return false;
106 template<typename _T>
107 void commitToColumn( const _T& rCell, ScColumn& rColumn, SCROW nRow )
109 switch (rCell.meType)
111 case CELLTYPE_STRING:
112 rColumn.SetRawString(nRow, *rCell.mpString);
113 break;
114 case CELLTYPE_EDIT:
115 rColumn.SetEditText(nRow, ScEditUtil::Clone(*rCell.mpEditText, rColumn.GetDoc()));
116 break;
117 case CELLTYPE_VALUE:
118 rColumn.SetValue(nRow, rCell.mfValue);
119 break;
120 case CELLTYPE_FORMULA:
122 ScAddress aDestPos(rColumn.GetCol(), nRow, rColumn.GetTab());
123 rColumn.SetFormulaCell(nRow, new ScFormulaCell(*rCell.mpFormula, rColumn.GetDoc(), aDestPos));
125 break;
126 default:
127 rColumn.Delete(nRow);
131 bool hasStringImpl( CellType eType, ScFormulaCell* pFormula )
133 switch (eType)
135 case CELLTYPE_STRING:
136 case CELLTYPE_EDIT:
137 return true;
138 case CELLTYPE_FORMULA:
139 return !pFormula->IsValue();
140 default:
141 return false;
145 bool hasNumericImpl( CellType eType, ScFormulaCell* pFormula )
147 switch (eType)
149 case CELLTYPE_VALUE:
150 return true;
151 case CELLTYPE_FORMULA:
152 return pFormula->IsValue();
153 default:
154 return false;
160 ScCellValue::ScCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
162 ScCellValue::ScCellValue( const ScRefCellValue& rCell ) : meType(rCell.meType), mfValue(rCell.mfValue)
164 switch (rCell.meType)
166 case CELLTYPE_STRING:
167 mpString = new svl::SharedString(*rCell.mpString);
168 break;
169 case CELLTYPE_EDIT:
170 mpEditText = rCell.mpEditText->Clone();
171 break;
172 case CELLTYPE_FORMULA:
173 mpFormula = rCell.mpFormula->Clone();
174 break;
175 default:
180 ScCellValue::ScCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
181 ScCellValue::ScCellValue( const svl::SharedString& rString ) : meType(CELLTYPE_STRING), mpString(new svl::SharedString(rString)) {}
182 ScCellValue::ScCellValue( const EditTextObject& rEditText ) : meType(CELLTYPE_EDIT), mpEditText(rEditText.Clone()) {}
183 ScCellValue::ScCellValue( const ScFormulaCell& rFormula ) : meType(CELLTYPE_FORMULA), mpFormula(rFormula.Clone()) {}
185 ScCellValue::ScCellValue( const ScCellValue& r ) : meType(r.meType), mfValue(r.mfValue)
187 switch (r.meType)
189 case CELLTYPE_STRING:
190 mpString = new svl::SharedString(*r.mpString);
191 break;
192 case CELLTYPE_EDIT:
193 mpEditText = r.mpEditText->Clone();
194 break;
195 case CELLTYPE_FORMULA:
196 mpFormula = r.mpFormula->Clone();
197 break;
198 default:
203 ScCellValue::~ScCellValue()
205 clear();
208 void ScCellValue::clear()
210 switch (meType)
212 case CELLTYPE_STRING:
213 delete mpString;
214 break;
215 case CELLTYPE_EDIT:
216 delete mpEditText;
217 break;
218 case CELLTYPE_FORMULA:
219 delete mpFormula;
220 break;
221 default:
225 // Reset to empty value.
226 meType = CELLTYPE_NONE;
227 mfValue = 0.0;
230 void ScCellValue::set( double fValue )
232 clear();
233 meType = CELLTYPE_VALUE;
234 mfValue = fValue;
237 void ScCellValue::set( const svl::SharedString& rStr )
239 clear();
240 meType = CELLTYPE_STRING;
241 mpString = new svl::SharedString(rStr);
244 void ScCellValue::set( const EditTextObject& rEditText )
246 clear();
247 meType = CELLTYPE_EDIT;
248 mpEditText = rEditText.Clone();
251 void ScCellValue::set( const ScFormulaCell& rFormula )
253 clear();
254 meType = CELLTYPE_FORMULA;
255 mpFormula = rFormula.Clone();
258 void ScCellValue::set( ScFormulaCell* pFormula )
260 clear();
261 meType = CELLTYPE_FORMULA;
262 mpFormula = pFormula;
265 void ScCellValue::assign( const ScDocument& rDoc, const ScAddress& rPos )
267 clear();
269 ScRefCellValue aRefVal;
270 aRefVal.assign(const_cast<ScDocument&>(rDoc), rPos);
272 meType = aRefVal.meType;
273 switch (meType)
275 case CELLTYPE_STRING:
276 mpString = new svl::SharedString(*aRefVal.mpString);
277 break;
278 case CELLTYPE_EDIT:
279 if (aRefVal.mpEditText)
280 mpEditText = aRefVal.mpEditText->Clone();
281 break;
282 case CELLTYPE_VALUE:
283 mfValue = aRefVal.mfValue;
284 break;
285 case CELLTYPE_FORMULA:
286 mpFormula = aRefVal.mpFormula->Clone();
287 break;
288 default:
289 meType = CELLTYPE_NONE; // reset to empty.
293 void ScCellValue::assign( const ScCellValue& rOther, ScDocument& rDestDoc, int nCloneFlags )
295 clear();
297 meType = rOther.meType;
298 switch (meType)
300 case CELLTYPE_STRING:
301 mpString = new svl::SharedString(*rOther.mpString);
302 break;
303 case CELLTYPE_EDIT:
305 // Switch to the pool of the destination document.
306 ScFieldEditEngine& rEngine = rDestDoc.GetEditEngine();
307 if (rOther.mpEditText->HasOnlineSpellErrors())
309 sal_uLong nControl = rEngine.GetControlWord();
310 const sal_uLong nSpellControl = EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS;
311 bool bNewControl = ((nControl & nSpellControl) != nSpellControl);
312 if (bNewControl)
313 rEngine.SetControlWord(nControl | nSpellControl);
314 rEngine.SetText(*rOther.mpEditText);
315 mpEditText = rEngine.CreateTextObject();
316 if (bNewControl)
317 rEngine.SetControlWord(nControl);
319 else
321 rEngine.SetText(*rOther.mpEditText);
322 mpEditText = rEngine.CreateTextObject();
325 break;
326 case CELLTYPE_VALUE:
327 mfValue = rOther.mfValue;
328 break;
329 case CELLTYPE_FORMULA:
330 // Switch to the destination document.
331 mpFormula = new ScFormulaCell(*rOther.mpFormula, rDestDoc, rOther.mpFormula->aPos, nCloneFlags);
332 break;
333 default:
334 meType = CELLTYPE_NONE; // reset to empty.
338 void ScCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
340 switch (meType)
342 case CELLTYPE_STRING:
344 ScSetStringParam aParam;
345 aParam.setTextInput();
346 rDoc.SetString(rPos, mpString->getString(), &aParam);
348 break;
349 case CELLTYPE_EDIT:
350 rDoc.SetEditText(rPos, mpEditText->Clone());
351 break;
352 case CELLTYPE_VALUE:
353 rDoc.SetValue(rPos, mfValue);
354 break;
355 case CELLTYPE_FORMULA:
356 rDoc.SetFormulaCell(rPos, mpFormula->Clone());
357 break;
358 default:
359 rDoc.SetEmptyCell(rPos);
363 void ScCellValue::commit( ScColumn& rColumn, SCROW nRow ) const
365 commitToColumn(*this, rColumn, nRow);
368 void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
370 switch (meType)
372 case CELLTYPE_STRING:
374 // Currently, string cannot be placed without copying.
375 ScSetStringParam aParam;
376 aParam.setTextInput();
377 rDoc.SetString(rPos, mpString->getString(), &aParam);
378 delete mpString;
380 break;
381 case CELLTYPE_EDIT:
382 // Cell takes the ownership of the text object.
383 rDoc.SetEditText(rPos, mpEditText);
384 break;
385 case CELLTYPE_VALUE:
386 rDoc.SetValue(rPos, mfValue);
387 break;
388 case CELLTYPE_FORMULA:
389 // This formula cell instance is directly placed in the document without copying.
390 rDoc.SetFormulaCell(rPos, mpFormula);
391 break;
392 default:
393 rDoc.SetEmptyCell(rPos);
396 meType = CELLTYPE_NONE;
397 mfValue = 0.0;
400 void ScCellValue::release( ScColumn& rColumn, SCROW nRow )
402 switch (meType)
404 case CELLTYPE_STRING:
406 // Currently, string cannot be placed without copying.
407 rColumn.SetRawString(nRow, *mpString);
408 delete mpString;
410 break;
411 case CELLTYPE_EDIT:
412 // Cell takes the ownership of the text object.
413 rColumn.SetEditText(nRow, mpEditText);
414 break;
415 case CELLTYPE_VALUE:
416 rColumn.SetValue(nRow, mfValue);
417 break;
418 case CELLTYPE_FORMULA:
419 // This formula cell instance is directly placed in the document without copying.
420 rColumn.SetFormulaCell(nRow, mpFormula);
421 break;
422 default:
423 rColumn.Delete(nRow);
426 meType = CELLTYPE_NONE;
427 mfValue = 0.0;
430 bool ScCellValue::hasString() const
432 return hasStringImpl(meType, mpFormula);
435 bool ScCellValue::hasNumeric() const
437 return hasNumericImpl(meType, mpFormula);
440 bool ScCellValue::isEmpty() const
442 return meType == CELLTYPE_NONE;
445 bool ScCellValue::equalsWithoutFormat( const ScCellValue& r ) const
447 return equalsWithoutFormatImpl(*this, r);
450 ScCellValue& ScCellValue::operator= ( const ScCellValue& r )
452 ScCellValue aTmp(r);
453 swap(aTmp);
454 return *this;
457 ScCellValue& ScCellValue::operator= ( const ScRefCellValue& r )
459 ScCellValue aTmp(r);
460 swap(aTmp);
461 return *this;
464 void ScCellValue::swap( ScCellValue& r )
466 std::swap(meType, r.meType);
468 // double is 8 bytes, whereas a pointer may be 4 or 8 bytes depending on
469 // the platform. Swap by double values.
470 std::swap(mfValue, r.mfValue);
473 ScRefCellValue::ScRefCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
474 ScRefCellValue::ScRefCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
475 ScRefCellValue::ScRefCellValue( const svl::SharedString* pString ) : meType(CELLTYPE_STRING), mpString(pString) {}
476 ScRefCellValue::ScRefCellValue( const EditTextObject* pEditText ) : meType(CELLTYPE_EDIT), mpEditText(pEditText) {}
477 ScRefCellValue::ScRefCellValue( ScFormulaCell* pFormula ) : meType(CELLTYPE_FORMULA), mpFormula(pFormula) {}
479 // It should be enough to copy the double value, which is at least as large
480 // as the pointer values.
481 ScRefCellValue::ScRefCellValue( const ScRefCellValue& r ) : meType(r.meType), mfValue(r.mfValue) {}
483 ScRefCellValue::~ScRefCellValue()
485 clear();
488 void ScRefCellValue::clear()
490 // Reset to empty value.
491 meType = CELLTYPE_NONE;
492 mfValue = 0.0;
495 void ScRefCellValue::assign( ScDocument& rDoc, const ScAddress& rPos )
497 *this = rDoc.GetRefCellValue(rPos);
500 void ScRefCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
502 switch (meType)
504 case CELLTYPE_STRING:
506 ScSetStringParam aParam;
507 aParam.setTextInput();
508 rDoc.SetString(rPos, mpString->getString(), &aParam);
510 break;
511 case CELLTYPE_EDIT:
512 rDoc.SetEditText(rPos, ScEditUtil::Clone(*mpEditText, rDoc));
513 break;
514 case CELLTYPE_VALUE:
515 rDoc.SetValue(rPos, mfValue);
516 break;
517 case CELLTYPE_FORMULA:
518 rDoc.SetFormulaCell(rPos, new ScFormulaCell(*mpFormula, rDoc, rPos));
519 break;
520 default:
521 rDoc.SetEmptyCell(rPos);
525 void ScRefCellValue::commit( ScColumn& rColumn, SCROW nRow ) const
527 commitToColumn(*this, rColumn, nRow);
530 bool ScRefCellValue::hasString() const
532 return hasStringImpl(meType, mpFormula);
535 bool ScRefCellValue::hasNumeric() const
537 return hasNumericImpl(meType, mpFormula);
540 double ScRefCellValue::getValue()
542 switch (meType)
544 case CELLTYPE_VALUE:
545 return mfValue;
546 case CELLTYPE_FORMULA:
547 return mpFormula->GetValue();
548 default:
551 return 0.0;
554 OUString ScRefCellValue::getString( const ScDocument* pDoc )
556 switch (meType)
558 case CELLTYPE_VALUE:
559 return OUString::number(mfValue);
560 case CELLTYPE_STRING:
561 return mpString->getString();
562 case CELLTYPE_EDIT:
563 if (mpEditText)
564 return ScEditUtil::GetString(*mpEditText, pDoc);
565 break;
566 case CELLTYPE_FORMULA:
567 return mpFormula->GetString().getString();
568 default:
571 return EMPTY_OUSTRING;
574 bool ScRefCellValue::isEmpty() const
576 return meType == CELLTYPE_NONE;
579 bool ScRefCellValue::hasEmptyValue()
581 if (isEmpty())
582 return true;
584 if (meType == CELLTYPE_FORMULA)
585 return mpFormula->IsEmpty();
587 return false;
590 bool ScRefCellValue::equalsWithoutFormat( const ScRefCellValue& r ) const
592 return equalsWithoutFormatImpl(*this, r);
595 ScRefCellValue& ScRefCellValue::operator= ( const ScRefCellValue& r )
597 ScRefCellValue aTmp(r);
598 swap(aTmp);
599 return *this;
602 void ScRefCellValue::swap( ScRefCellValue& r )
604 std::swap(meType, r.meType);
606 // double is 8 bytes, whereas a pointer may be 4 or 8 bytes depending on
607 // the platform. Swap by double values.
608 std::swap(mfValue, r.mfValue);
611 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */