sc/inc/document.hxx | 2 + sc/inc/refhint.hxx | 7 +++ sc/inc/tokenarray.hxx | 5 -- sc/inc/types.hxx | 6 +++ sc/qa/unit/ucalc.hxx | 2 + sc/qa/unit/ucalc_sharedformula.cxx | 68 ++++++++++++++++++++++++++++++++++ sc/source/core/data/bcaslot.cxx | 17 ++++++-- sc/source/core/data/documen7.cxx | 2 - sc/source/core/data/document10.cxx | 13 ++++++ sc/source/core/data/formulacell.cxx | 16 +++++++- sc/source/core/inc/bcaslot.hxx | 6 ++- sc/source/core/tool/refhint.cxx | 9 +++- sc/source/core/tool/token.cxx | 24 +++++++++--- sc/source/ui/docshell/docfunc.cxx | 6 +-- sc/source/ui/undo/undoblk.cxx | 71 ++++++++++++++++++++++++++++++------ 15 files changed, 218 insertions(+), 36 deletions(-)
New commits: commit 27182231acd3a0c9898a8dba78b76dc8a827b4c0 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Wed Jul 30 13:51:28 2014 -0400 fdo#78555: Retain formula results when moving a range of cells. * No need to re-compile RPN token array on reference change alone. We do that when the formula contains one or more names that have been updated. * Adjust undo code to get it to work without relying on ref undo document, which would cause the token arrays to be unnecessarily recompiled. * Whatever else need to be changed in order to pass all unit tests. Change-Id: I99e86d23320aca8900fef011da23a9d34e42751e diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 0dc3239..6bfb138 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1876,6 +1876,8 @@ public: void EndListeningCell( sc::EndListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener ); void EndListeningFormulaCells( std::vector<ScFormulaCell*>& rCells ); + void CollectAllAreaListeners( + std::vector<SvtListener*>& rListeners, const ScRange& rRange, sc::AreaOverlapType eType ); void PutInFormulaTree( ScFormulaCell* pCell ); void RemoveFromFormulaTree( ScFormulaCell* pCell ); diff --git a/sc/inc/refhint.hxx b/sc/inc/refhint.hxx index 1eff906..0f65aae 100644 --- a/sc/inc/refhint.hxx +++ b/sc/inc/refhint.hxx @@ -15,6 +15,8 @@ namespace sc { +struct RefUpdateContext; + class RefHint : public SfxSimpleHint { public: @@ -42,10 +44,11 @@ class RefMovedHint : public RefHint { ScRange maRange; ScAddress maMoveDelta; + const sc::RefUpdateContext& mrCxt; public: - RefMovedHint( const ScRange& rRange, const ScAddress& rMove ); + RefMovedHint( const ScRange& rRange, const ScAddress& rMove, const sc::RefUpdateContext& rCxt ); virtual ~RefMovedHint(); /** @@ -57,6 +60,8 @@ public: * Get the movement vector. */ const ScAddress& getDelta() const; + + const sc::RefUpdateContext& getContext() const; }; class RefColReorderHint : public RefHint diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index 8ae6145..9762364 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -152,11 +152,8 @@ public: * Move reference positions that are within specified moved range. * * @param rPos position of this formula cell - * @param rMovedRange range that has been moved. - * @param rDelta movement vector. */ - void MoveReference( - const ScAddress& rPos, const ScRange& rMovedRange, const ScAddress& rDelta ); + sc::RefUpdateResult MoveReference( const ScAddress& rPos, const sc::RefUpdateContext& rCxt ); /** * Move reference positions in response to column reordering. A range diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index 37784dc..8dc8f18 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -100,6 +100,12 @@ struct RangeMatrix typedef boost::unordered_map<SCCOLROW,SCCOLROW> ColRowReorderMapType; +enum AreaOverlapType +{ + AreaInside, + AreaPartialOverlap +}; + } #endif diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index 701e530..ea70ffb 100644 --- a/sc/source/core/data/bcaslot.cxx +++ b/sc/source/core/data/bcaslot.cxx @@ -432,7 +432,8 @@ void ScBroadcastAreaSlot::EraseArea( ScBroadcastAreas::iterator& rIter ) } } -void ScBroadcastAreaSlot::GetAllListeners( const ScRange& rRange, std::vector<sc::AreaListener>& rListeners ) +void ScBroadcastAreaSlot::GetAllListeners( + const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, sc::AreaOverlapType eType ) { for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin()), aIterEnd( aBroadcastAreaTbl.end()); aIter != aIterEnd; ++aIter ) @@ -442,7 +443,14 @@ void ScBroadcastAreaSlot::GetAllListeners( const ScRange& rRange, std::vector<sc ScBroadcastArea* pArea = (*aIter).mpArea; const ScRange& rAreaRange = pArea->GetRange(); - if (!rRange.In(rAreaRange)) + + if (eType == sc::AreaInside && !rRange.In(rAreaRange)) + // The range needs to be fully inside specified range. + continue; + + if (eType == sc::AreaPartialOverlap && + (!rRange.Intersects(rAreaRange) || rRange.In(rAreaRange))) + // The range needs to be only partially overlapping. continue; SvtBroadcaster::ListenersType& rLst = pArea->GetBroadcaster().GetAllListeners(); @@ -967,7 +975,8 @@ void ScBroadcastAreaSlotMachine::FinallyEraseAreas( ScBroadcastAreaSlot* pSlot ) maAreasToBeErased.swap( aCopy); } -std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( const ScRange& rRange ) +std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( + const ScRange& rRange, sc::AreaOverlapType eType ) { std::vector<sc::AreaListener> aRet; @@ -984,7 +993,7 @@ std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( const while ( nOff <= nEnd ) { ScBroadcastAreaSlot* p = *pp; - p->GetAllListeners(rRange, aRet); + p->GetAllListeners(rRange, aRet, eType); ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx index 5a4df60f1..1682332 100644 --- a/sc/source/core/data/documen7.cxx +++ b/sc/source/core/data/documen7.cxx @@ -152,7 +152,7 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint ) const ScAddress& rDelta = rHint.getDelta(); // Get all area listeners that listens on the old range, and end their listening. - std::vector<sc::AreaListener> aAreaListeners = pBASM->GetAllListeners(rSrcRange); + std::vector<sc::AreaListener> aAreaListeners = pBASM->GetAllListeners(rSrcRange, sc::AreaInside); { std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end(); for (; it != itEnd; ++it) diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index eb9a742..49db92e 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -17,6 +17,7 @@ #include <listenercontext.hxx> #include <tokenstringcontext.hxx> #include <poolhelp.hxx> +#include <bcaslot.hxx> // Add totally brand-new methods to this source file. @@ -319,4 +320,16 @@ void ScDocument::RegroupFormulaCells( SCTAB nTab, SCCOL nCol ) pTab->RegroupFormulaCells(nCol); } +void ScDocument::CollectAllAreaListeners( + std::vector<SvtListener*>& rListener, const ScRange& rRange, sc::AreaOverlapType eType ) +{ + if (!pBASM) + return; + + std::vector<sc::AreaListener> aAL = pBASM->GetAllListeners(rRange, eType); + std::vector<sc::AreaListener>::iterator it = aAL.begin(), itEnd = aAL.end(); + for (; it != itEnd; ++it) + rListener.push_back(it->mpListener); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 3c506ae..d846501 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1932,7 +1932,16 @@ void ScFormulaCell::Notify( const SfxHint& rHint ) const sc::RefMovedHint& rRefMoved = static_cast<const sc::RefMovedHint&>(rRefHint); if (!IsShared() || IsSharedTop()) - pCode->MoveReference(aPos, rRefMoved.getRange(), rRefMoved.getDelta()); + { + sc::RefUpdateResult aRes = pCode->MoveReference(aPos, rRefMoved.getContext()); + if (aRes.mbNameModified) + { + // RPN token needs to be re-generated. + bCompile = true; + CompileTokenArray(); + SetDirtyVar(); + } + } } break; case sc::RefHint::ColumnReordered: @@ -2883,6 +2892,9 @@ bool ScFormulaCell::UpdateReferenceOnMove( sc::RefUpdateResult aRes = pCode->AdjustReferenceOnMove(rCxt, aOldPos, aPos); bRefModified = aRes.mbReferenceModified || aRes.mbNameModified; bValChanged = aRes.mbValueChanged; + if (aRes.mbNameModified) + // Re-compile to get the RPN token regenerated to reflect updated names. + bCompile = true; } if (bValChanged || bRefModified) @@ -2933,7 +2945,7 @@ bool ScFormulaCell::UpdateReferenceOnMove( bValChanged = false; - bCompile = (bCompile || bValChanged || bRefModified || bColRowNameCompile); + bCompile = (bCompile || bValChanged || bColRowNameCompile); if ( bCompile ) { CompileTokenArray( bNewListening ); // no Listening diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx index 2980875..59812af 100644 --- a/sc/source/core/inc/bcaslot.hxx +++ b/sc/source/core/inc/bcaslot.hxx @@ -214,7 +214,8 @@ public: */ void EraseArea( ScBroadcastAreas::iterator& rIter ); - void GetAllListeners( const ScRange& rRange, std::vector<sc::AreaListener>& rListeners ); + void GetAllListeners( + const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, sc::AreaOverlapType eType ); }; /** @@ -309,7 +310,8 @@ public: // only for ScBroadcastAreaSlot void FinallyEraseAreas( ScBroadcastAreaSlot* pSlot ); - std::vector<sc::AreaListener> GetAllListeners( const ScRange& rRange ); + std::vector<sc::AreaListener> GetAllListeners( + const ScRange& rRange, sc::AreaOverlapType eType ); }; class ScBulkBroadcast diff --git a/sc/source/core/tool/refhint.cxx b/sc/source/core/tool/refhint.cxx index 533a41b..f76489c 100644 --- a/sc/source/core/tool/refhint.cxx +++ b/sc/source/core/tool/refhint.cxx @@ -19,8 +19,8 @@ RefHint::Type RefHint::getType() const return meType; } -RefMovedHint::RefMovedHint( const ScRange& rRange, const ScAddress& rMove ) : - RefHint(Moved), maRange(rRange), maMoveDelta(rMove) {} +RefMovedHint::RefMovedHint( const ScRange& rRange, const ScAddress& rMove, const sc::RefUpdateContext& rCxt ) : + RefHint(Moved), maRange(rRange), maMoveDelta(rMove), mrCxt(rCxt) {} RefMovedHint::~RefMovedHint() {} @@ -34,6 +34,11 @@ const ScAddress& RefMovedHint::getDelta() const return maMoveDelta; } +const sc::RefUpdateContext& RefMovedHint::getContext() const +{ + return mrCxt; +} + RefColReorderHint::RefColReorderHint( const sc::ColRowReorderMapType& rColMap, SCTAB nTab, SCROW nRow1, SCROW nRow2 ) : RefHint(ColumnReordered), mrColMap(rColMap), mnTab(nTab), mnRow1(nRow1), mnRow2(nRow2) {} diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 569834a..080e958 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2865,9 +2865,13 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove( return aRes; } -void ScTokenArray::MoveReference( - const ScAddress& rPos, const ScRange& rMovedRange, const ScAddress& rDelta ) +sc::RefUpdateResult ScTokenArray::MoveReference( const ScAddress& rPos, const sc::RefUpdateContext& rCxt ) { + sc::RefUpdateResult aRes; + + ScRange aOldRange = rCxt.maRange; + aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta); + FormulaToken** p = pCode; FormulaToken** pEnd = p + static_cast<size_t>(nLen); for (; p != pEnd; ++p) @@ -2879,9 +2883,9 @@ void ScTokenArray::MoveReference( ScToken* pToken = static_cast<ScToken*>(*p); ScSingleRefData& rRef = pToken->GetSingleRef(); ScAddress aAbs = rRef.toAbs(rPos); - if (rMovedRange.In(aAbs)) + if (aOldRange.In(aAbs)) { - aAbs.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab()); + aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta); rRef.SetAddress(aAbs, rPos); } } @@ -2891,17 +2895,25 @@ void ScTokenArray::MoveReference( ScToken* pToken = static_cast<ScToken*>(*p); ScComplexRefData& rRef = pToken->GetDoubleRef(); ScRange aAbs = rRef.toAbs(rPos); - if (rMovedRange.In(aAbs)) + if (aOldRange.In(aAbs)) { - aAbs.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab()); + aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta); rRef.SetRange(aAbs, rPos); } } break; + case svIndex: + { + if (isNameModified(rCxt.maUpdatedNames, aOldRange.aStart.Tab(), **p)) + aRes.mbNameModified = true; + } + break; default: ; } } + + return aRes; } void ScTokenArray::MoveReferenceColReorder( diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index d41caee..ff27635 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -2679,8 +2679,8 @@ bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, { rDoc.CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab, nUndoFlags, false, pUndoDoc ); - pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO ); - pRefUndoDoc->InitUndo( &rDoc, 0, nTabCount-1, false, false ); +// pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO ); +// pRefUndoDoc->InitUndo( &rDoc, 0, nTabCount-1, false, false ); } if ( nDestTab != nStartTab ) @@ -2689,7 +2689,7 @@ bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, nDestEndCol, nDestEndRow, nDestEndTab, nUndoFlags, false, pUndoDoc ); - pUndoData = new ScRefUndoData( &rDoc ); +// pUndoData = new ScRefUndoData( &rDoc ); rDoc.BeginDrawUndo(); } diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index 982925d..be6895f 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -52,6 +52,7 @@ #include <refupdatecontext.hxx> #include <validat.hxx> #include <gridwin.hxx> +#include <svl/listener.hxx> #include <set> #include <boost/scoped_ptr.hpp> @@ -1249,6 +1250,22 @@ void ScUndoDragDrop::DoUndo( ScRange aRange ) maPaintRanges.Join(aPaintRange); } +namespace { + +class DataChangeNotifier : std::unary_function<SvtListener*, void> +{ + ScHint maHint; +public: + DataChangeNotifier() : maHint(SC_HINT_DATACHANGED, ScAddress()) {} + + void operator() ( SvtListener* p ) + { + p->Notify(maHint); + } +}; + +} + void ScUndoDragDrop::Undo() { mnPaintExtFlags = 0; @@ -1258,32 +1275,64 @@ void ScUndoDragDrop::Undo() if (bCut) { - // Notify all listeners of the destination range, and have them update their references. + // During undo, we move cells from aDestRange to aSrcRange. + ScDocument& rDoc = pDocShell->GetDocument(); + SCCOL nColDelta = aSrcRange.aStart.Col() - aDestRange.aStart.Col(); SCROW nRowDelta = aSrcRange.aStart.Row() - aDestRange.aStart.Row(); SCTAB nTabDelta = aSrcRange.aStart.Tab() - aDestRange.aStart.Tab(); - sc::RefMovedHint aHint(aDestRange, ScAddress(nColDelta, nRowDelta, nTabDelta)); + + sc::RefUpdateContext aCxt(rDoc); + aCxt.meMode = URM_MOVE; + aCxt.maRange = aSrcRange; + aCxt.mnColDelta = nColDelta; + aCxt.mnRowDelta = nRowDelta; + aCxt.mnTabDelta = nTabDelta; + + // Global range names. + ScRangeName* pName = rDoc.GetRangeName(); + if (pName) + pName->UpdateReference(aCxt); + + SCTAB nTabCount = rDoc.GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; ++nTab) + { + // Sheet-local range names. + pName = rDoc.GetRangeName(nTab); + if (pName) + pName->UpdateReference(aCxt, nTab); + } + + // Notify all listeners of the destination range, and have them update their references. + sc::RefMovedHint aHint(aDestRange, ScAddress(nColDelta, nRowDelta, nTabDelta), aCxt); rDoc.BroadcastRefMoved(aHint); ScValidationDataList* pValidList = rDoc.GetValidationList(); if (pValidList) { // Update the references of validation entries. - sc::RefUpdateContext aCxt(rDoc); - aCxt.meMode = URM_MOVE; - aCxt.maRange = aSrcRange; - aCxt.mnColDelta = nColDelta; - aCxt.mnRowDelta = nRowDelta; - aCxt.mnTabDelta = nTabDelta; pValidList->UpdateReference(aCxt); } - } - DoUndo(aDestRange); - if (bCut) + DoUndo(aDestRange); DoUndo(aSrcRange); + // Notify all area listeners whose listened areas are partially moved, to + // recalculate. + std::vector<SvtListener*> aListeners; + rDoc.CollectAllAreaListeners(aListeners, aSrcRange, sc::AreaPartialOverlap); + + // Remove any duplicate listener entries. We must ensure that we notify + // each unique listener only once. + std::sort(aListeners.begin(), aListeners.end()); + aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end()); + + std::for_each(aListeners.begin(), aListeners.end(), DataChangeNotifier()); + } + else + DoUndo(aDestRange); + for (size_t i = 0; i < maPaintRanges.size(); ++i) { const ScRange* p = maPaintRanges[i]; commit 85f8f8f8589af3c404339c0f78021a7fe21cdfcd Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Wed Jul 30 12:35:26 2014 -0400 fdo#78555: Write test for this first. Change-Id: I01f7ca80d8d2ac4c3b5f262625cc54a27cf4327a diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index b067a22..e4a6b8c 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -290,6 +290,7 @@ public: void testSharedFormulas(); void testSharedFormulasRefUpdate(); void testSharedFormulasRefUpdateMove(); + void testSharedFormulasRefUpdateMove2(); void testSharedFormulasRefUpdateRange(); void testSharedFormulasRefUpdateExternal(); void testSharedFormulasInsertRow(); @@ -499,6 +500,7 @@ public: CPPUNIT_TEST(testSharedFormulas); CPPUNIT_TEST(testSharedFormulasRefUpdate); CPPUNIT_TEST(testSharedFormulasRefUpdateMove); + CPPUNIT_TEST(testSharedFormulasRefUpdateMove2); CPPUNIT_TEST(testSharedFormulasRefUpdateRange); CPPUNIT_TEST(testSharedFormulasRefUpdateExternal); CPPUNIT_TEST(testSharedFormulasInsertRow); diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx index 5fa1dfa..8c49076 100644 --- a/sc/qa/unit/ucalc_sharedformula.cxx +++ b/sc/qa/unit/ucalc_sharedformula.cxx @@ -459,6 +459,74 @@ void Test::testSharedFormulasRefUpdateMove() m_pDoc->DeleteTab(0); } +void Test::testSharedFormulasRefUpdateMove2() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, false); // turn auto calc off this time. + FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1); + + m_pDoc->InsertTab(0, "Test"); + + // Set values in B2:B3, and E2:E3. + for (SCROW i = 1; i <= 2; ++i) + { + m_pDoc->SetValue(ScAddress(1,i,0), i); + m_pDoc->SetValue(ScAddress(4,i,0), i); + } + + // Make sure the values are really there. + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(1,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(1,2,0))); + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(4,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(4,2,0))); + + // Set formulas in C2:C3 that reference B2:B4 individually, and F2:F3 to E2:E3. + for (SCROW i = 1; i <= 2; ++i) + { + m_pDoc->SetString(ScAddress(2,i,0), "=RC[-1]"); + m_pDoc->SetString(ScAddress(5,i,0), "=RC[-1]"); + } + + m_pDoc->CalcFormulaTree(); // calculate manually. + + // Check the formula results. + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(2,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,2,0))); + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(5,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(5,2,0))); + + // Move B2:C3 to C3:D4. + bool bMoved = getDocShell().GetDocFunc().MoveBlock( + ScRange(1,1,0,2,2,0), ScAddress(2,2,0), true, true, false, true); + CPPUNIT_ASSERT(bMoved); + + // Make sure the range has been moved. + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(2,2,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,3,0))); + + // The formula cells should retain their results even with auto calc off + // and without recalculation. + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(3,2,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(3,3,0))); + + // And these formulas in F2:F3 are unaffected, therefore should not change. + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(5,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(5,2,0))); + + SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager(); + CPPUNIT_ASSERT(pUndoMgr); + + // Undo the move. + pUndoMgr->Undo(); + + // Check the formula results. The results should still be intact. + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(2,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,2,0))); + CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(5,1,0))); + CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(5,2,0))); + + m_pDoc->DeleteTab(0); +} + void Test::testSharedFormulasRefUpdateRange() { m_pDoc->InsertTab(0, "Test"); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits