diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-02-11 13:28:47 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-02-11 15:12:21 -0500 |
commit | 2ec3127da35933fc6d5ac47ecedd0267f67c1d62 (patch) | |
tree | 49f3b061b3f3964bb9b3e797c9ff011e1e2c6cfd /sc | |
parent | b51acfb4c0c7dec0cdc3de5890ebb1c051bab509 (diff) |
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.
Change-Id: If5cead26ebe917af150cf7e39e17afe3f310beb7
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 5 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_formula.cxx | 36 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/documen7.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh3.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin4.cxx | 2 |
8 files changed, 47 insertions, 10 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 032675b891fa..129450389b80 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -2047,9 +2047,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 a4b628953859..75553aebc3cd 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -490,6 +490,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 e601540fd355..2c3e58aab2ae 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -2591,7 +2591,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; @@ -2732,7 +2732,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 210d87bd64d7..ac3f3cf2ed69 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 0f24c234c827..f825a794c663 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(); } @@ -3683,6 +3683,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(); @@ -3693,7 +3694,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 101332d1807a..7ceff2b963ab 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -3091,7 +3091,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 0a18ba8f97bb..125ac0f523dd 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 729073b23d96..56f227de8b16 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() |