sc/source/core/data/formulacell.cxx | 7 ++-- sc/source/core/data/table3.cxx | 61 +++++++++++++++++++++++++++++++----- sc/source/filter/xml/xmlcelli.cxx | 45 +++++++------------------- 3 files changed, 69 insertions(+), 44 deletions(-)
New commits: commit c4820366710fcbcc198a5471ad1f4a29f71d2019 Author: Eike Rathke <er...@redhat.com> Date: Tue Nov 15 23:50:49 2016 +0100 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); } } commit c802fb24368ac9866940f2d987d46357b0e577f3 Author: Eike Rathke <er...@redhat.com> Date: Tue Nov 15 20:55:01 2016 +0100 tdf#96475 sort error result between text and empty cell Error results weren't handled at all and sorted same as numeric 0, which due to "stable sort" resulted in arbitrary looking sort order if 0 values or results where included. Change-Id: Ib7c516b57ea92bc5b813f448d9c2bb5491e43940 diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 1336e04..cace309 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -1483,12 +1483,35 @@ short ScTable::CompareCell( { if (!rCell2.isEmpty()) { + bool bErr1 = false; bool bStr1 = ( eType1 != CELLTYPE_VALUE ); - if (eType1 == CELLTYPE_FORMULA && rCell1.mpFormula->IsValue()) - bStr1 = false; + if (eType1 == CELLTYPE_FORMULA) + { + if (rCell1.mpFormula->GetErrCode() != FormulaError::NONE) + { + bErr1 = true; + bStr1 = false; + } + else if (rCell1.mpFormula->IsValue()) + { + bStr1 = false; + } + } + + bool bErr2 = false; bool bStr2 = ( eType2 != CELLTYPE_VALUE ); - if (eType2 == CELLTYPE_FORMULA && rCell2.mpFormula->IsValue()) - bStr2 = false; + if (eType2 == CELLTYPE_FORMULA) + { + if (rCell2.mpFormula->GetErrCode() != FormulaError::NONE) + { + bErr2 = true; + bStr2 = false; + } + else if (rCell2.mpFormula->IsValue()) + { + bStr2 = false; + } + } if ( bStr1 && bStr2 ) // only compare strings as strings! { @@ -1531,10 +1554,32 @@ short ScTable::CompareCell( nRes = static_cast<short>( pSortCollator->compareString( aStr1, aStr2 ) ); } } - else if ( bStr1 ) // String <-> Number - nRes = 1; // Number in front - else if ( bStr2 ) // Number <-> String - nRes = -1; // Number in front + else if ( bStr1 ) // String <-> Number or Error + { + if (bErr2) + nRes = -1; // String in front of Error + else + nRes = 1; // Number in front of String + } + else if ( bStr2 ) // Number or Error <-> String + { + if (bErr1) + nRes = 1; // String in front of Error + else + nRes = -1; // Number in front of String + } + else if (bErr1 && bErr2) + { + // nothing, two Errors are equal + } + else if (bErr1) // Error <-> Number + { + nRes = 1; // Number in front of Error + } + else if (bErr2) // Number <-> Error + { + nRes = -1; // Number in front of Error + } else // Mixed numbers { double nVal1 = rCell1.getValue(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits