sc/inc/cellvalue.hxx | 5 ++ sc/source/core/data/cellvalue.cxx | 77 ++++++++++++++++++++++++++++---------- sc/source/core/data/table4.cxx | 23 ++--------- 3 files changed, 68 insertions(+), 37 deletions(-)
New commits: commit 0ad0d04928da99a3a9b8f1bdd44382388240f8d1 Author: Kohei Yoshida <[email protected]> Date: Wed Jun 19 15:19:31 2013 -0400 Same fix for fill series & some cleanup. Change-Id: I2f741305ac64c221c5af8ab99f3ddff0ce56f458 diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 02f9c7d..c605a97 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -766,7 +766,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, short nHeadNoneTail = 0; sal_Int32 nStringValue = 0; String aValue; - ScRefCellValue aSrcCell; + ScCellValue aSrcCell; CellType eCellType = CELLTYPE_NONE; bool bIsOrdinalSuffix = false; @@ -846,21 +846,8 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, } } else - { - ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab ); - switch ( eCellType ) - { - case CELLTYPE_STRING: - aCol[nCol].SetRawString(aDestPos.Row(), *aSrcCell.mpString); - case CELLTYPE_EDIT: - aCol[nCol].SetEditText(aDestPos.Row(), aSrcCell.mpEditText->Clone()); - break; - default: - { - // added to avoid warnings - } - } - } + aSrcCell.commit(aCol[nCol], nRow); + break; case CELLTYPE_FORMULA : FillFormula( nFormulaCounter, bFirst, aSrcCell.mpFormula, commit 709f5504c4545f240ec78284c8f812d74af24a26 Author: Kohei Yoshida <[email protected]> Date: Wed Jun 19 14:58:35 2013 -0400 We need to clone the source cell value to prevent crash. If we don't clone this, the original string value would become invalid after the first insertion, which may cause a reallocation of the array that stores the cell. Change-Id: I5b1bb5f378ed5503169fce75fcbc7aeb85c5ed6e diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx index b1be68d..43e7a05 100644 --- a/sc/inc/cellvalue.hxx +++ b/sc/inc/cellvalue.hxx @@ -17,6 +17,7 @@ class ScDocument; class ScFormulaCell; class EditTextObject; class ScColumn; +struct ScRefCellValue; /** * Store arbitrary cell value of any kind. It only stores cell value and @@ -34,6 +35,7 @@ struct SC_DLLPUBLIC ScCellValue }; ScCellValue(); + ScCellValue( const ScRefCellValue& rCell ); ScCellValue( double fValue ); ScCellValue( const OUString& rString ); ScCellValue( const EditTextObject& rEditText ); @@ -61,6 +63,8 @@ struct SC_DLLPUBLIC ScCellValue */ void commit( ScDocument& rDoc, const ScAddress& rPos ) const; + void commit( ScColumn& rColumn, SCROW nRow ) const; + /** * Set cell value at specified position in specified document. But unlike * commit(), this method sets the original value to the document without @@ -79,6 +83,7 @@ struct SC_DLLPUBLIC ScCellValue bool equalsWithoutFormat( const ScCellValue& r ) const; ScCellValue& operator= ( const ScCellValue& r ); + ScCellValue& operator= ( const ScRefCellValue& r ); void swap( ScCellValue& r ); }; diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx index f9575d5..617eb29 100644 --- a/sc/source/core/data/cellvalue.cxx +++ b/sc/source/core/data/cellvalue.cxx @@ -102,6 +102,31 @@ bool equalsWithoutFormatImpl( const _T& left, const _T& right ) return false; } +template<typename _T> +void commitToColumn( const _T& rCell, ScColumn& rColumn, SCROW nRow ) +{ + switch (rCell.meType) + { + case CELLTYPE_STRING: + rColumn.SetRawString(nRow, *rCell.mpString); + break; + case CELLTYPE_EDIT: + rColumn.SetEditText(nRow, ScEditUtil::Clone(*rCell.mpEditText, rColumn.GetDoc())); + break; + case CELLTYPE_VALUE: + rColumn.SetValue(nRow, rCell.mfValue); + break; + case CELLTYPE_FORMULA: + { + ScAddress aDestPos(rColumn.GetCol(), nRow, rColumn.GetTab()); + rColumn.SetFormulaCell(nRow, new ScFormulaCell(*rCell.mpFormula, rColumn.GetDoc(), aDestPos)); + } + break; + default: + rColumn.Delete(nRow); + } +} + bool hasStringImpl( CellType eType, ScFormulaCell* pFormula ) { switch (eType) @@ -132,6 +157,25 @@ bool hasNumericImpl( CellType eType, ScFormulaCell* pFormula ) } ScCellValue::ScCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {} + +ScCellValue::ScCellValue( const ScRefCellValue& rCell ) : meType(rCell.meType), mfValue(rCell.mfValue) +{ + switch (rCell.meType) + { + case CELLTYPE_STRING: + mpString = new OUString(*rCell.mpString); + break; + case CELLTYPE_EDIT: + mpEditText = rCell.mpEditText->Clone(); + break; + case CELLTYPE_FORMULA: + mpFormula = rCell.mpFormula->Clone(); + break; + default: + ; + } +} + ScCellValue::ScCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {} ScCellValue::ScCellValue( const OUString& rString ) : meType(CELLTYPE_STRING), mpString(new OUString(rString)) {} ScCellValue::ScCellValue( const EditTextObject& rEditText ) : meType(CELLTYPE_EDIT), mpEditText(rEditText.Clone()) {} @@ -315,6 +359,11 @@ void ScCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const } } +void ScCellValue::commit( ScColumn& rColumn, SCROW nRow ) const +{ + commitToColumn(*this, rColumn, nRow); +} + void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos ) { switch (meType) @@ -404,6 +453,13 @@ ScCellValue& ScCellValue::operator= ( const ScCellValue& r ) return *this; } +ScCellValue& ScCellValue::operator= ( const ScRefCellValue& r ) +{ + ScCellValue aTmp(r); + swap(aTmp); + return *this; +} + void ScCellValue::swap( ScCellValue& r ) { std::swap(meType, r.meType); @@ -496,26 +552,7 @@ void ScRefCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const void ScRefCellValue::commit( ScColumn& rColumn, SCROW nRow ) const { - switch (meType) - { - case CELLTYPE_STRING: - rColumn.SetRawString(nRow, *mpString); - break; - case CELLTYPE_EDIT: - rColumn.SetEditText(nRow, ScEditUtil::Clone(*mpEditText, rColumn.GetDoc())); - break; - case CELLTYPE_VALUE: - rColumn.SetValue(nRow, mfValue); - break; - case CELLTYPE_FORMULA: - { - ScAddress aDestPos(rColumn.GetCol(), nRow, rColumn.GetTab()); - rColumn.SetFormulaCell(nRow, new ScFormulaCell(*mpFormula, rColumn.GetDoc(), aDestPos)); - } - break; - default: - rColumn.Delete(nRow); - } + commitToColumn(*this, rColumn, nRow); } bool ScRefCellValue::hasString() const diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 4c835b2..02f9c7d 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -1390,7 +1390,9 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, for (rOuter = nOStart; rOuter <= nOEnd; rOuter++) { rInner = nISource; - ScRefCellValue aSrcCell = aCol[nCol].GetCellValue(static_cast<SCROW>(nRow)); + + // Source cell value. We need to clone the value since it may be inserted repeatedly. + ScCellValue aSrcCell = aCol[nCol].GetCellValue(static_cast<SCROW>(nRow)); if (bAttribs) { _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
