[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Wed Feb 12 07:22:56 PST 2014


 sc/inc/document.hxx              |    5 +++--
 sc/qa/unit/ucalc_formula.cxx     |   36 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/column2.cxx  |    4 ++--
 sc/source/core/data/documen7.cxx |    2 +-
 sc/source/core/data/document.cxx |    4 ++--
 sc/source/ui/docshell/docsh.cxx  |    2 +-
 sc/source/ui/docshell/docsh3.cxx |    2 +-
 sc/source/ui/view/gridwin4.cxx   |    2 +-
 8 files changed, 47 insertions(+), 10 deletions(-)

New commits:
commit 3f7a491c646a14fb03172d14b421a780e73508c9
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Feb 11 13:28:47 2014 -0500

    Ensure that vector array has a numeric array of NaN's for empty range.
    
    With this change, we ensure that mpNumArray is never NULL even when the
    range consists entirely of empty cells.  For an empty range, mpNumArray
    will be non-NULL and filled with NaN's while mpStrArray will be NULL.
    
    P.S. We need to backport this because without this, the existing OpenCL
    code could lead to a crash during OpenCL enabled calculations.
    
    (cherry picked from commit 2ec3127da35933fc6d5ac47ecedd0267f67c1d62)
    
    Change-Id: If5cead26ebe917af150cf7e39e17afe3f310beb7
    Reviewed-on: https://gerrit.libreoffice.org/8021
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 505746f..3ac1089 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -2035,9 +2035,10 @@ public:
     formula::VectorRefArray FetchVectorRefArray( const ScAddress& rPos, SCROW nLength );
 
     /**
-     * Called whenever the value of a cell inside the document is modified.
+     * Call this before any operations that might trigger one or more formula
+     * cells to get calculated.
      */
-    void CellContentModified();
+    void ClearFormulaContext();
 
     SvtBroadcaster* GetBroadcaster( const ScAddress& rPos );
     const SvtBroadcaster* GetBroadcaster( const ScAddress& rPos ) const;
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index b07fffc..c798cbb 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -470,6 +470,42 @@ void Test::testFetchVectorRefArray()
     CPPUNIT_ASSERT_MESSAGE("Array should NOT have a string array.", !aArray.mpStringArray);
     CPPUNIT_ASSERT_MESSAGE("Unexpected string cell.", equals(aArray, 0, 5.0));
 
+    // Clear everything and start over.
+    clearRange(m_pDoc, ScRange(0,0,0,MAXCOL,MAXROW,0));
+    m_pDoc->ClearFormulaContext();
+
+    // Totally empty range in a totally empty column (Column A).
+    aArray = m_pDoc->FetchVectorRefArray(ScAddress(0,0,0), 3); // A1:A3
+    CPPUNIT_ASSERT_MESSAGE("Array should have a numeric array.", aArray.mpNumericArray);
+    CPPUNIT_ASSERT_MESSAGE("Array should NOT have a string array.", !aArray.mpStringArray);
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[0]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[1]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[2]));
+
+    // Totally empty range in a non-empty column (Column B).
+    m_pDoc->SetString(ScAddress(1,10,0), "Some text"); // B11
+    aArray = m_pDoc->FetchVectorRefArray(ScAddress(1,0,0), 3); // B1:B3
+    CPPUNIT_ASSERT_MESSAGE("Array should have a numeric array.", aArray.mpNumericArray);
+    CPPUNIT_ASSERT_MESSAGE("Array should NOT have a string array.", !aArray.mpStringArray);
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[0]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[1]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[2]));
+
+    aArray = m_pDoc->FetchVectorRefArray(ScAddress(1,12,0), 3); // B13:B15
+    CPPUNIT_ASSERT_MESSAGE("Array should have a numeric array.", aArray.mpNumericArray);
+    CPPUNIT_ASSERT_MESSAGE("Array should NOT have a string array.", !aArray.mpStringArray);
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[0]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[1]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[2]));
+
+    // These values come from a cache because of the call above.
+    aArray = m_pDoc->FetchVectorRefArray(ScAddress(1,1,0), 3); // B2:B4
+    CPPUNIT_ASSERT_MESSAGE("Array should have a numeric array.", aArray.mpNumericArray);
+    CPPUNIT_ASSERT_MESSAGE("Array should NOT have a string array.", !aArray.mpStringArray);
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[0]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[1]));
+    CPPUNIT_ASSERT(rtl::math::isNan(aArray.mpNumericArray[2]));
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 4f4ee06..1d28780 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2730,7 +2730,7 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( SCROW nRow1, SCROW nRow2
     if (pColArray)
     {
         const double* pNum = NULL;
-        if (pColArray->mpNumArray && hasNonEmpty(*pColArray->mpNumArray, nRow1, nRow2))
+        if (pColArray->mpNumArray)
             pNum = &(*pColArray->mpNumArray)[nRow1];
 
         rtl_uString** pStr = NULL;
@@ -2871,7 +2871,7 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( SCROW nRow1, SCROW nRow2
             if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, itBlk, maCells.end()))
                 return formula::VectorRefArray();
 
-            if (pColArray->mpStrArray)
+            if (pColArray->mpStrArray && hasNonEmpty(*pColArray->mpStrArray, nRow1, nRow2))
                 return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1], &(*pColArray->mpStrArray)[nRow1]);
             else
                 return formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1]);
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 210d87b..ac3f3cf 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -106,7 +106,7 @@ void ScDocument::Broadcast( const ScHint& rHint )
 
 void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint )
 {
-    CellContentModified();
+    ClearFormulaContext();
 
     ScBulkBroadcast aBulkBroadcast(pBASM);
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 06ae530..5f59e0f 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2316,7 +2316,7 @@ ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
     mpDoc->pFormatExchangeList = NULL;
 }
 
-void ScDocument::CellContentModified()
+void ScDocument::ClearFormulaContext()
 {
     mpFormulaGroupCxt.reset();
 }
@@ -3629,6 +3629,7 @@ void ScDocument::AddTableOpFormulaCell( ScFormulaCell* pCell )
 
 void ScDocument::CalcAll()
 {
+    ClearFormulaContext();
     ClearLookupCaches();    // Ensure we don't deliver zombie data.
     sc::AutoCalcSwitch aSwitch(*this, true);
     TableContainer::iterator it = maTabs.begin();
@@ -3639,7 +3640,6 @@ void ScDocument::CalcAll()
         if (*it)
             (*it)->CalcAll();
     ClearFormulaTree();
-    mpFormulaGroupCxt.reset();
 }
 
 
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index b4cf615..a642092 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -3082,7 +3082,7 @@ ScDocShellModificator::~ScDocShellModificator()
 void ScDocShellModificator::SetDocumentModified()
 {
     ScDocument* pDoc = rDocShell.GetDocument();
-    pDoc->CellContentModified();
+    pDoc->ClearFormulaContext();
     if ( !pDoc->IsImportingXML() )
     {
         // AutoCalcShellDisabled temporaer restaurieren
diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx
index ad2806d..fcb2760f 100644
--- a/sc/source/ui/docshell/docsh3.cxx
+++ b/sc/source/ui/docshell/docsh3.cxx
@@ -87,7 +87,7 @@ void ScDocShell::PostDataChanged()
 {
     Broadcast( SfxSimpleHint( FID_DATACHANGED ) );
     SFX_APP()->Broadcast(SfxSimpleHint( FID_ANYDATACHANGED ));      // Navigator
-    aDocument.CellContentModified();
+    aDocument.ClearFormulaContext();
     //! Navigator direkt benachrichtigen!
 }
 
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 3786fad..38039ad 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -882,7 +882,7 @@ void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMod
 
     // Flag drawn formula cells "unchanged".
     pDoc->ResetChanged(ScRange(nX1,nY1,nTab,nX2,nY2,nTab));
-    pDoc->CellContentModified();
+    pDoc->ClearFormulaContext();
 }
 
 void ScGridWindow::CheckNeedsRepaint()


More information about the Libreoffice-commits mailing list