From 679651baff32e7971724ec0c1844a227f7f759a9 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Tue, 7 Jul 2015 23:36:02 +0200 Subject: end/restart group listening in DeleteSelection(), similar to DeleteArea() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reproducer: * in A1 enter =SUM(B1:C4) * copy A1 to clipboard * paste to A2 and A3 * formula in A2 is =SUM(B2:C5) A3 is =SUM(B3:C6) * select A2:A3 * hit Del key to delete the two cells * enter any numeric value in B2 => formula result in A1 is not updated Shift+Ctrl+F9 hard recalc updates Change-Id: I55e55b8cfe69e9273170ceaea4e6c046b3d4f7b7 (cherry picked from commit a49b8af4cf03ae08cb7a28f66e24368a7b08ae3f) Reviewed-on: https://gerrit.libreoffice.org/16838 Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- sc/source/core/data/document.cxx | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'sc') diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 4a4f0004cb2d..59fef65ec391 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -5611,18 +5611,81 @@ void ScDocument::ClearSelectionItems( const sal_uInt16* pWhich, const ScMarkData void ScDocument::DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast ) { + sc::AutoCalcSwitch aACSwitch(*this, false); + + std::vector aGroupPos; + // Destroy and reconstruct listeners only if content is affected. + bool bDelContent = ((nDelFlag & ~IDF_CONTENTS) != nDelFlag); + if (bDelContent) + { + // Record the positions of top and/or bottom formula groups that + // intersect the area borders. + sc::EndListeningContext aCxt(*this); + ScRangeList aRangeList; + rMark.FillRangeListWithMarks( &aRangeList, false); + for (size_t i = 0; i < aRangeList.size(); ++i) + { + const ScRange* pRange = aRangeList[i]; + if (pRange) + EndListeningIntersectedGroups( aCxt, *pRange, &aGroupPos); + } + aCxt.purgeEmptyBroadcasters(); + } + SCTAB nMax = static_cast(maTabs.size()); ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end(); for (; itr != itrEnd && *itr < nMax; ++itr) if (maTabs[*itr]) maTabs[*itr]->DeleteSelection(nDelFlag, rMark, bBroadcast); + + if (bDelContent) + { + // Re-start listeners on those top bottom groups that have been split. + SetNeedsListeningGroups(aGroupPos); + StartNeededListeners(); + } } void ScDocument::DeleteSelectionTab( SCTAB nTab, InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast ) { if (ValidTab(nTab) && nTab < static_cast(maTabs.size()) && maTabs[nTab]) + { + sc::AutoCalcSwitch aACSwitch(*this, false); + + std::vector aGroupPos; + // Destroy and reconstruct listeners only if content is affected. + bool bDelContent = ((nDelFlag & ~IDF_CONTENTS) != nDelFlag); + if (bDelContent) + { + // Record the positions of top and/or bottom formula groups that + // intersect the area borders. + sc::EndListeningContext aCxt(*this); + ScRangeList aRangeList; + rMark.FillRangeListWithMarks( &aRangeList, false); + for (size_t i = 0; i < aRangeList.size(); ++i) + { + const ScRange* pRange = aRangeList[i]; + if (pRange && pRange->aStart.Tab() <= nTab && nTab <= pRange->aEnd.Tab()) + { + ScRange aRange( *pRange); + aRange.aStart.SetTab( nTab); + aRange.aEnd.SetTab( nTab); + EndListeningIntersectedGroups( aCxt, aRange, &aGroupPos); + } + } + aCxt.purgeEmptyBroadcasters(); + } + maTabs[nTab]->DeleteSelection(nDelFlag, rMark, bBroadcast); + + if (bDelContent) + { + // Re-start listeners on those top bottom groups that have been split. + SetNeedsListeningGroups(aGroupPos); + StartNeededListeners(); + } + } else { OSL_FAIL("wrong table"); -- cgit