From c4820366710fcbcc198a5471ad1f4a29f71d2019 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Tue, 15 Nov 2016 23:50:49 +0100 Subject: tdf#96475 PutFormulaCell: any other cell than formula is utter nonsense This is called only if a cell has the table:formula attribute and that *is* a formula cell and nothing else. In fact in ODFF the initial leading '=' is not mandatory, so attempting to set a different cell type if it is not present is wrong. Commit 62ec7f9e824ed1c17f01beaf8f4cec3b76b3aae9 introduced that, which at that time may have been necessary, but doubtful.. Additionally, ScFormulaCell::CompileXML() that tries to group formulas had to be adpated to not rely on the presence of a leading '='. Luckily there was an assert.. These changes enable loading of "error cell" formulas that were stored without a leading '=' if they originated from a paste special with only values, which maintains an error result as error formula. Change-Id: I43394de108066a24b792eec958b19f51f990403b --- sc/source/core/data/formulacell.cxx | 7 +++--- sc/source/filter/xml/xmlcelli.cxx | 45 ++++++++++--------------------------- 2 files changed, 16 insertions(+), 36 deletions(-) diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 400671830c8f..5750aa3409e4 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1308,10 +1308,11 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr OUStringBuffer aShouldBeBuf; aBackComp.CreateStringFromTokenArray( aShouldBeBuf ); - assert( aFormula[0] == '=' ); + // The initial '=' is optional in ODFF. + const sal_Int32 nLeadingEqual = (aFormula.getLength() > 0 && aFormula[0] == '=') ? 1 : 0; OUString aShouldBe = aShouldBeBuf.makeStringAndClear(); - if( aFormula.getLength() == aShouldBe.getLength() + 1 && - aFormula.match( aShouldBe, 1 ) ) // initial '=' + if (aFormula.getLength() == aShouldBe.getLength() + nLeadingEqual && + aFormula.match( aShouldBe, nLeadingEqual)) { // Put them in the same formula group. ScFormulaCellGroupRef xGroup = pPreviousCell->GetCellGroup(); diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx index abc69871804e..f224852edbc6 100644 --- a/sc/source/filter/xml/xmlcelli.cxx +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -1360,42 +1360,21 @@ void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos ) if ( !aText.isEmpty() ) { - if ( aText[0] == '=' && aText.getLength() > 1 ) - { - // temporary formula string as string tokens - ScTokenArray *pCode = new ScTokenArray(); + // temporary formula string as string tokens + ScTokenArray *pCode = new ScTokenArray(); - OUString aFormulaNmsp = maFormula->second; - if( eGrammar != formula::FormulaGrammar::GRAM_EXTERNAL ) - aFormulaNmsp.clear(); - pCode->AssignXMLString( aText, aFormulaNmsp ); + OUString aFormulaNmsp = maFormula->second; + if( eGrammar != formula::FormulaGrammar::GRAM_EXTERNAL ) + aFormulaNmsp.clear(); + pCode->AssignXMLString( aText, aFormulaNmsp ); - rDoc.getDoc().IncXMLImportedFormulaCount( aText.getLength() ); - ScFormulaCell* pNewCell = new ScFormulaCell(pDoc, rCellPos, pCode, eGrammar, MM_NONE); - SetFormulaCell(pNewCell); - rDoc.setFormulaCell(rCellPos, pNewCell); + rDoc.getDoc().IncXMLImportedFormulaCount( aText.getLength() ); + ScFormulaCell* pNewCell = new ScFormulaCell(pDoc, rCellPos, pCode, eGrammar, MM_NONE); + SetFormulaCell(pNewCell); + rDoc.setFormulaCell(rCellPos, pNewCell); - // Re-calculate to get number format only when style is not set. - pNewCell->SetNeedNumberFormat(!mbHasStyle); - } - else if ( aText[0] == '\'' && aText.getLength() > 1 ) - { - // for bEnglish, "'" at the beginning is always interpreted as text - // marker and stripped - rDoc.setStringCell(rCellPos, aText.copy(1)); - } - else - { - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); - double fVal; - if ( pFormatter->IsNumberFormat( aText, nEnglish, fVal ) ) - rDoc.setNumericCell(rCellPos, fVal); - //the (english) number format will not be set - //search matching local format and apply it - else - rDoc.setStringCell(rCellPos, aText); - } + // Re-calculate to get number format only when style is not set. + pNewCell->SetNeedNumberFormat(!mbHasStyle); } } -- cgit