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

Eike Rathke erack at redhat.com
Fri Nov 20 15:04:28 PST 2015


 sc/qa/unit/ucalc.cxx                |   25 +++++++++++++++++++
 sc/qa/unit/ucalc.hxx                |    2 +
 sc/source/core/data/formulacell.cxx |   47 ++++++++++++++++++++++++++++++------
 3 files changed, 67 insertions(+), 7 deletions(-)

New commits:
commit 01de2fc790b50c04f13907026f1a7782009fea61
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Nov 20 22:49:36 2015 +0100

    unit test testMatrixConditionalBooleanResult
    
    Change-Id: I6531a79b510da18b6799edd32d40cfce7dd2975a

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 66890c9..3fc85a6 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2033,6 +2033,31 @@ void Test::testMatrixComparisonWithErrors()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testMatrixConditionalBooleanResult()
+{
+    m_pDoc->InsertTab(0, "foo");
+
+    // Create matrix formulas in A1:B1,A2:B2,A3:B3,A4:B4 producing mixed
+    // boolean and numeric results in an unformatted area.
+    ScMarkData aMark;
+    aMark.SelectOneTable(0);
+    m_pDoc->InsertMatrixFormula( 0,0, 1,0, aMark, "=IF({1,0};TRUE();42)");  // {TRUE,42}
+    m_pDoc->InsertMatrixFormula( 0,1, 1,1, aMark, "=IF({0,1};TRUE();42)");  // {42,1} aim for {42,TRUE}
+    m_pDoc->InsertMatrixFormula( 0,2, 1,2, aMark, "=IF({1,0};42;FALSE())"); // {42,0} aim for {42,FALSE}
+    m_pDoc->InsertMatrixFormula( 0,3, 1,3, aMark, "=IF({0,1};42;FALSE())"); // {FALSE,42}
+
+    CPPUNIT_ASSERT_EQUAL( OUString("TRUE"),  m_pDoc->GetString(0,0,0));
+    CPPUNIT_ASSERT_EQUAL( OUString("42"),    m_pDoc->GetString(1,0,0));
+    CPPUNIT_ASSERT_EQUAL( OUString("42"),    m_pDoc->GetString(0,1,0));
+    //CPPUNIT_ASSERT_EQUAL( OUString("TRUE"),  m_pDoc->GetString(1,1,0));   // not yet
+    CPPUNIT_ASSERT_EQUAL( OUString("42"),    m_pDoc->GetString(0,2,0));
+    //CPPUNIT_ASSERT_EQUAL( OUString("FALSE"), m_pDoc->GetString(1,2,0));   // not yet
+    CPPUNIT_ASSERT_EQUAL( OUString("FALSE"), m_pDoc->GetString(0,3,0));
+    CPPUNIT_ASSERT_EQUAL( OUString("42"),    m_pDoc->GetString(1,3,0));
+
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testEnterMixedMatrix()
 {
     m_pDoc->InsertTab(0, "foo");
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 9ea7f4b..fc90f81 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -236,6 +236,7 @@ public:
     void testCSV();
     void testMatrix();
     void testMatrixComparisonWithErrors();
+    void testMatrixConditionalBooleanResult();
     void testEnterMixedMatrix();
     void testMatrixEditable();
 
@@ -559,6 +560,7 @@ public:
     CPPUNIT_TEST(testCSV);
     CPPUNIT_TEST(testMatrix);
     CPPUNIT_TEST(testMatrixComparisonWithErrors);
+    CPPUNIT_TEST(testMatrixConditionalBooleanResult);
     CPPUNIT_TEST(testEnterMixedMatrix);
     CPPUNIT_TEST(testMatrixEditable);
     CPPUNIT_TEST(testPivotTable);
commit fd8c802533e962b8cd13f8aecc6a2a8aa487bba1
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Nov 20 22:10:38 2015 +0100

    solve 6/8 cases of the dreaded conditional logical format in matrix results
    
    So we now have
    =IF({1,0},TRUE(),42)  => {TRUE,42}
    =IF({0,1},TRUE(),42)  => {42,1}
    =IF({1,0},42,FALSE()) => {42,0}
    =IF({0,1},42,FALSE()) => {FALSE,42}
    
    instead of before
    =IF({1,0},TRUE(),42)  => {TRUE,TRUE}
    =IF({0,1},TRUE(),42)  => {TRUE,TRUE}
    =IF({1,0},42,FALSE()) => {TRUE,FALSE}
    =IF({0,1},42,FALSE()) => {FALSE,TRUE}
    
    Not perfect but better..
    
    Change-Id: Ib4970f3c4c1bea87130730b956a0a6754879c6e6

diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index d429c89..a405ebe 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1859,15 +1859,50 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
                 bContentChanged = true;
         }
 
+        ScFormulaResult aNewResult( p->GetResultToken().get());
+
         if( mbNeedsNumberFormat )
         {
+            bool bSetFormat = true;
+            const short nOldFormatType = nFormatType;
             nFormatType = p->GetRetFormatType();
             sal_Int32 nFormatIndex = p->GetRetFormatIndex();
 
-            // don't set text format as hard format
-            if(nFormatType == css::util::NumberFormat::TEXT)
-                nFormatIndex = 0;
-            else if((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+            if (nFormatType == css::util::NumberFormat::TEXT)
+            {
+                // Don't set text format as hard format.
+                bSetFormat = false;
+            }
+            else if (nFormatType == css::util::NumberFormat::LOGICAL && cMatrixFlag != MM_NONE)
+            {
+                // In a matrix range do not set an (inherited) logical format
+                // as hard format if the value does not represent a strict TRUE
+                // or FALSE value. But do set for a top left error value so
+                // following matrix cells can inherit for non-error values.
+                // This solves a problem with IF() expressions in array context
+                // where incidentally the top left element results in logical
+                // type but some others don't. It still doesn't solve the
+                // reverse case though, where top left is not logical type but
+                // some other elements should be. We'd need to transport type
+                // or format information on arrays.
+                StackVar eNewCellResultType = aNewResult.GetCellResultType();
+                if (eNewCellResultType != svError || cMatrixFlag == MM_REFERENCE)
+                {
+                    double fVal;
+                    if (eNewCellResultType != svDouble)
+                    {
+                        bSetFormat = false;
+                        nFormatType = nOldFormatType;   // that? or number?
+                    }
+                    else if ((fVal = aNewResult.GetDouble()) != 1.0 && fVal != 0.0)
+                    {
+                        bSetFormat = false;
+                        nFormatType = css::util::NumberFormat::NUMBER;
+                    }
+                }
+            }
+
+            if (bSetFormat && (nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
                 nFormatIndex = ScGlobal::GetStandardFormat(*pDocument->GetFormatTable(),
                         nFormatIndex, nFormatType);
 
@@ -1879,7 +1914,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
             // XXX if mbNeedsNumberFormat was set even if the current format
             // was not General then we'd have to obtain the current format here
             // and check at least the types.
-            if ((nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
+            if (bSetFormat && (nFormatIndex % SV_COUNTRY_LANGUAGE_OFFSET) != 0)
             {
                 // set number format explicitly
                 pDocument->SetNumberFormat( aPos, nFormatIndex );
@@ -1897,7 +1932,6 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
             // Also handle special cases of initial results after loading.
             if ( !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
             {
-                ScFormulaResult aNewResult( p->GetResultToken().get());
                 StackVar eOld = aResult.GetCellResultType();
                 StackVar eNew = aNewResult.GetCellResultType();
                 if ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) )
@@ -1921,7 +1955,6 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
         }
         else
         {
-            ScFormulaResult aNewResult( p->GetResultToken().get());
             StackVar eOld = aResult.GetCellResultType();
             StackVar eNew = aNewResult.GetCellResultType();
             bChanged = (eOld != eNew ||


More information about the Libreoffice-commits mailing list