[Libreoffice-commits] core.git: 2 commits - sc/source

Eike Rathke erack at redhat.com
Tue Nov 15 22:52:21 UTC 2016


 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 <erack at 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 <erack at 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();


More information about the Libreoffice-commits mailing list