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

Reply via email to