fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / cellvalue.cxx
blobe03870c274e535f83a8d758bccb1121f44bf98aa
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 static void commitToColumn( const ScCellValue& rCell, ScColumn& rColumn, SCROW nRow )
108 switch (rCell.meType)
110 case CELLTYPE_STRING:
111 rColumn.SetRawString(nRow, *rCell.mpString);
112 break;
113 case CELLTYPE_EDIT:
114 rColumn.SetEditText(nRow, ScEditUtil::Clone(*rCell.mpEditText, rColumn.GetDoc()));
115 break;
116 case CELLTYPE_VALUE:
117 rColumn.SetValue(nRow, rCell.mfValue);
118 break;
119 case CELLTYPE_FORMULA:
121 ScAddress aDestPos(rColumn.GetCol(), nRow, rColumn.GetTab());
122 rColumn.SetFormulaCell(nRow, new ScFormulaCell(*rCell.mpFormula, rColumn.GetDoc(), aDestPos));
124 break;
125 default:
126 rColumn.DeleteContent(nRow);
130 bool hasStringImpl( CellType eType, ScFormulaCell* pFormula )
132 switch (eType)
134 case CELLTYPE_STRING:
135 case CELLTYPE_EDIT:
136 return true;
137 case CELLTYPE_FORMULA:
138 return !pFormula->IsValue();
139 default:
140 return false;
144 bool hasNumericImpl( CellType eType, ScFormulaCell* pFormula )
146 switch (eType)
148 case CELLTYPE_VALUE:
149 return true;
150 case CELLTYPE_FORMULA:
151 return pFormula->IsValue();
152 default:
153 return false;
157 template<typename _CellT>
158 OUString getStringImpl( const _CellT& rCell, const ScDocument* pDoc )
160 switch (rCell.meType)
162 case CELLTYPE_VALUE:
163 return OUString::number(rCell.mfValue);
164 case CELLTYPE_STRING:
165 return rCell.mpString->getString();
166 case CELLTYPE_EDIT:
167 if (rCell.mpEditText)
168 return ScEditUtil::GetString(*rCell.mpEditText, pDoc);
169 break;
170 case CELLTYPE_FORMULA:
171 return rCell.mpFormula->GetString().getString();
172 default:
175 return EMPTY_OUSTRING;
180 ScCellValue::ScCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
182 ScCellValue::ScCellValue( const ScRefCellValue& rCell ) : meType(rCell.meType), mfValue(rCell.mfValue)
184 switch (rCell.meType)
186 case CELLTYPE_STRING:
187 mpString = new svl::SharedString(*rCell.mpString);
188 break;
189 case CELLTYPE_EDIT:
190 mpEditText = rCell.mpEditText->Clone();
191 break;
192 case CELLTYPE_FORMULA:
193 mpFormula = rCell.mpFormula->Clone();
194 break;
195 default:
200 ScCellValue::ScCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
202 ScCellValue::ScCellValue( const svl::SharedString& rString ) : meType(CELLTYPE_STRING), mpString(new svl::SharedString(rString)) {}
204 ScCellValue::ScCellValue( const ScCellValue& r ) : meType(r.meType), mfValue(r.mfValue)
206 switch (r.meType)
208 case CELLTYPE_STRING:
209 mpString = new svl::SharedString(*r.mpString);
210 break;
211 case CELLTYPE_EDIT:
212 mpEditText = r.mpEditText->Clone();
213 break;
214 case CELLTYPE_FORMULA:
215 mpFormula = r.mpFormula->Clone();
216 break;
217 default:
222 ScCellValue::~ScCellValue()
224 clear();
227 void ScCellValue::clear()
229 switch (meType)
231 case CELLTYPE_STRING:
232 delete mpString;
233 break;
234 case CELLTYPE_EDIT:
235 delete mpEditText;
236 break;
237 case CELLTYPE_FORMULA:
238 delete mpFormula;
239 break;
240 default:
244 // Reset to empty value.
245 meType = CELLTYPE_NONE;
246 mfValue = 0.0;
249 void ScCellValue::set( const ScRefCellValue& rCell )
251 clear();
253 meType = rCell.meType;
254 switch (meType)
256 case CELLTYPE_VALUE:
257 mfValue = rCell.mfValue;
258 break;
259 case CELLTYPE_STRING:
260 mpString = new svl::SharedString(*rCell.mpString);
261 break;
262 case CELLTYPE_EDIT:
263 mpEditText = rCell.mpEditText->Clone();
264 break;
265 case CELLTYPE_FORMULA:
266 mpFormula = rCell.mpFormula->Clone();
267 break;
268 default:
273 void ScCellValue::set( double fValue )
275 clear();
276 meType = CELLTYPE_VALUE;
277 mfValue = fValue;
280 void ScCellValue::set( const svl::SharedString& rStr )
282 clear();
283 meType = CELLTYPE_STRING;
284 mpString = new svl::SharedString(rStr);
287 void ScCellValue::set( const EditTextObject& rEditText )
289 clear();
290 meType = CELLTYPE_EDIT;
291 mpEditText = rEditText.Clone();
294 void ScCellValue::set( EditTextObject* pEditText )
296 clear();
297 meType = CELLTYPE_EDIT;
298 mpEditText = pEditText;
301 void ScCellValue::set( ScFormulaCell* pFormula )
303 clear();
304 meType = CELLTYPE_FORMULA;
305 mpFormula = pFormula;
308 void ScCellValue::assign( const ScDocument& rDoc, const ScAddress& rPos )
310 clear();
312 ScRefCellValue aRefVal;
313 aRefVal.assign(const_cast<ScDocument&>(rDoc), rPos);
315 meType = aRefVal.meType;
316 switch (meType)
318 case CELLTYPE_STRING:
319 mpString = new svl::SharedString(*aRefVal.mpString);
320 break;
321 case CELLTYPE_EDIT:
322 if (aRefVal.mpEditText)
323 mpEditText = aRefVal.mpEditText->Clone();
324 break;
325 case CELLTYPE_VALUE:
326 mfValue = aRefVal.mfValue;
327 break;
328 case CELLTYPE_FORMULA:
329 mpFormula = aRefVal.mpFormula->Clone();
330 break;
331 default:
332 meType = CELLTYPE_NONE; // reset to empty.
336 void ScCellValue::assign( const ScCellValue& rOther, ScDocument& rDestDoc, int nCloneFlags )
338 clear();
340 meType = rOther.meType;
341 switch (meType)
343 case CELLTYPE_STRING:
344 mpString = new svl::SharedString(*rOther.mpString);
345 break;
346 case CELLTYPE_EDIT:
348 // Switch to the pool of the destination document.
349 ScFieldEditEngine& rEngine = rDestDoc.GetEditEngine();
350 if (rOther.mpEditText->HasOnlineSpellErrors())
352 EEControlBits nControl = rEngine.GetControlWord();
353 const EEControlBits nSpellControl = EEControlBits::ONLINESPELLING | EEControlBits::ALLOWBIGOBJS;
354 bool bNewControl = ((nControl & nSpellControl) != nSpellControl);
355 if (bNewControl)
356 rEngine.SetControlWord(nControl | nSpellControl);
357 rEngine.SetText(*rOther.mpEditText);
358 mpEditText = rEngine.CreateTextObject();
359 if (bNewControl)
360 rEngine.SetControlWord(nControl);
362 else
364 rEngine.SetText(*rOther.mpEditText);
365 mpEditText = rEngine.CreateTextObject();
368 break;
369 case CELLTYPE_VALUE:
370 mfValue = rOther.mfValue;
371 break;
372 case CELLTYPE_FORMULA:
373 // Switch to the destination document.
374 mpFormula = new ScFormulaCell(*rOther.mpFormula, rDestDoc, rOther.mpFormula->aPos, nCloneFlags);
375 break;
376 default:
377 meType = CELLTYPE_NONE; // reset to empty.
381 void ScCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
383 switch (meType)
385 case CELLTYPE_STRING:
387 ScSetStringParam aParam;
388 aParam.setTextInput();
389 rDoc.SetString(rPos, mpString->getString(), &aParam);
391 break;
392 case CELLTYPE_EDIT:
393 rDoc.SetEditText(rPos, mpEditText->Clone());
394 break;
395 case CELLTYPE_VALUE:
396 rDoc.SetValue(rPos, mfValue);
397 break;
398 case CELLTYPE_FORMULA:
399 rDoc.SetFormulaCell(rPos, mpFormula->Clone());
400 break;
401 default:
402 rDoc.SetEmptyCell(rPos);
406 void ScCellValue::commit( ScColumn& rColumn, SCROW nRow ) const
408 commitToColumn(*this, rColumn, nRow);
411 void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
413 switch (meType)
415 case CELLTYPE_STRING:
417 // Currently, string cannot be placed without copying.
418 ScSetStringParam aParam;
419 aParam.setTextInput();
420 rDoc.SetString(rPos, mpString->getString(), &aParam);
421 delete mpString;
423 break;
424 case CELLTYPE_EDIT:
425 // Cell takes the ownership of the text object.
426 rDoc.SetEditText(rPos, mpEditText);
427 break;
428 case CELLTYPE_VALUE:
429 rDoc.SetValue(rPos, mfValue);
430 break;
431 case CELLTYPE_FORMULA:
432 // This formula cell instance is directly placed in the document without copying.
433 rDoc.SetFormulaCell(rPos, mpFormula);
434 break;
435 default:
436 rDoc.SetEmptyCell(rPos);
439 meType = CELLTYPE_NONE;
440 mfValue = 0.0;
443 void ScCellValue::release( ScColumn& rColumn, SCROW nRow, sc::StartListeningType eListenType )
445 switch (meType)
447 case CELLTYPE_STRING:
449 // Currently, string cannot be placed without copying.
450 rColumn.SetRawString(nRow, *mpString);
451 delete mpString;
453 break;
454 case CELLTYPE_EDIT:
455 // Cell takes the ownership of the text object.
456 rColumn.SetEditText(nRow, mpEditText);
457 break;
458 case CELLTYPE_VALUE:
459 rColumn.SetValue(nRow, mfValue);
460 break;
461 case CELLTYPE_FORMULA:
462 // This formula cell instance is directly placed in the document without copying.
463 rColumn.SetFormulaCell(nRow, mpFormula, eListenType);
464 break;
465 default:
466 rColumn.DeleteContent(nRow);
469 meType = CELLTYPE_NONE;
470 mfValue = 0.0;
473 OUString ScCellValue::getString( const ScDocument* pDoc )
475 return getStringImpl(*this, pDoc);
478 bool ScCellValue::isEmpty() const
480 return meType == CELLTYPE_NONE;
483 bool ScCellValue::equalsWithoutFormat( const ScCellValue& r ) const
485 return equalsWithoutFormatImpl(*this, r);
488 ScCellValue& ScCellValue::operator= ( const ScCellValue& r )
490 ScCellValue aTmp(r);
491 swap(aTmp);
492 return *this;
495 ScCellValue& ScCellValue::operator= ( const ScRefCellValue& r )
497 ScCellValue aTmp(r);
498 swap(aTmp);
499 return *this;
502 void ScCellValue::swap( ScCellValue& r )
504 std::swap(meType, r.meType);
506 // double is 8 bytes, whereas a pointer may be 4 or 8 bytes depending on
507 // the platform. Swap by double values.
508 std::swap(mfValue, r.mfValue);
511 ScRefCellValue::ScRefCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
512 ScRefCellValue::ScRefCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
513 ScRefCellValue::ScRefCellValue( const svl::SharedString* pString ) : meType(CELLTYPE_STRING), mpString(pString) {}
514 ScRefCellValue::ScRefCellValue( const EditTextObject* pEditText ) : meType(CELLTYPE_EDIT), mpEditText(pEditText) {}
515 ScRefCellValue::ScRefCellValue( ScFormulaCell* pFormula ) : meType(CELLTYPE_FORMULA), mpFormula(pFormula) {}
517 // It should be enough to copy the double value, which is at least as large
518 // as the pointer values.
519 ScRefCellValue::ScRefCellValue( const ScRefCellValue& r ) : meType(r.meType), mfValue(r.mfValue) {}
521 ScRefCellValue::~ScRefCellValue()
523 clear();
526 void ScRefCellValue::clear()
528 // Reset to empty value.
529 meType = CELLTYPE_NONE;
530 mfValue = 0.0;
533 void ScRefCellValue::assign( ScDocument& rDoc, const ScAddress& rPos )
535 *this = rDoc.GetRefCellValue(rPos);
538 void ScRefCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
540 switch (meType)
542 case CELLTYPE_STRING:
544 ScSetStringParam aParam;
545 aParam.setTextInput();
546 rDoc.SetString(rPos, mpString->getString(), &aParam);
548 break;
549 case CELLTYPE_EDIT:
550 rDoc.SetEditText(rPos, ScEditUtil::Clone(*mpEditText, rDoc));
551 break;
552 case CELLTYPE_VALUE:
553 rDoc.SetValue(rPos, mfValue);
554 break;
555 case CELLTYPE_FORMULA:
556 rDoc.SetFormulaCell(rPos, new ScFormulaCell(*mpFormula, rDoc, rPos));
557 break;
558 default:
559 rDoc.SetEmptyCell(rPos);
563 bool ScRefCellValue::hasString() const
565 return hasStringImpl(meType, mpFormula);
568 bool ScRefCellValue::hasNumeric() const
570 return hasNumericImpl(meType, mpFormula);
573 double ScRefCellValue::getValue()
575 switch (meType)
577 case CELLTYPE_VALUE:
578 return mfValue;
579 case CELLTYPE_FORMULA:
580 return mpFormula->GetValue();
581 default:
584 return 0.0;
587 OUString ScRefCellValue::getString( const ScDocument* pDoc )
589 return getStringImpl(*this, pDoc);
592 bool ScRefCellValue::isEmpty() const
594 return meType == CELLTYPE_NONE;
597 bool ScRefCellValue::hasEmptyValue()
599 if (isEmpty())
600 return true;
602 if (meType == CELLTYPE_FORMULA)
603 return mpFormula->IsEmpty();
605 return false;
608 bool ScRefCellValue::equalsWithoutFormat( const ScRefCellValue& r ) const
610 return equalsWithoutFormatImpl(*this, r);
613 ScRefCellValue& ScRefCellValue::operator= ( const ScRefCellValue& r )
615 ScRefCellValue aTmp(r);
616 swap(aTmp);
617 return *this;
620 void ScRefCellValue::swap( ScRefCellValue& r )
622 std::swap(meType, r.meType);
624 // double is 8 bytes, whereas a pointer may be 4 or 8 bytes depending on
625 // the platform. Swap by double values.
626 std::swap(mfValue, r.mfValue);
629 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */