diff options
author | Eike Rathke <erack@redhat.com> | 2015-07-07 23:36:02 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2015-08-03 17:51:08 +0200 |
commit | 679651baff32e7971724ec0c1844a227f7f759a9 (patch) | |
tree | 12ce761f256e7c61b6dc030e3cd349fc395eaa27 /sc | |
parent | a7852df35553dbc4e4508fc742f17a3582aebc5f (diff) |
end/restart group listening in DeleteSelection(), similar to DeleteArea()
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 <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/core/data/document.cxx | 63 |
1 files changed, 63 insertions, 0 deletions
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<ScAddress> 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<SCTAB>(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<SCTAB>(maTabs.size()) && maTabs[nTab]) + { + sc::AutoCalcSwitch aACSwitch(*this, false); + + std::vector<ScAddress> 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"); |