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
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 4006718..5750aa3 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 abc6987..f224852 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);
}
}