diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-05-03 00:50:46 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-05-03 00:55:41 -0400 |
commit | af7df25bcc8bc95462e2b3bf8c003d035111a479 (patch) | |
tree | bf7bdeba603cdaeec0e371081cfc6b10ceb2a8ee /sc/source/ui | |
parent | 41062189f78990f7aa42949484b58de64b0dce79 (diff) |
fdo#78062: Broadcast only on non-empty cells within deleted range.
We don't want to broadcast over the whole selected range, which may be
the whole sheet which is well over 1 billion cells !
Change-Id: I7c139ce5efe09312cf824e35f0efe551184032eb
Diffstat (limited to 'sc/source/ui')
-rw-r--r-- | sc/source/ui/inc/undobase.hxx | 13 | ||||
-rw-r--r-- | sc/source/ui/inc/undoblk.hxx | 5 | ||||
-rw-r--r-- | sc/source/ui/undo/undobase.cxx | 44 | ||||
-rw-r--r-- | sc/source/ui/undo/undoblk3.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/view/viewfunc.cxx | 32 |
5 files changed, 100 insertions, 6 deletions
diff --git a/sc/source/ui/inc/undobase.hxx b/sc/source/ui/inc/undobase.hxx index 6a2cd94a883c..85726c8a2b1e 100644 --- a/sc/source/ui/inc/undobase.hxx +++ b/sc/source/ui/inc/undobase.hxx @@ -24,6 +24,9 @@ #include "global.hxx" #include "address.hxx" #include "docsh.hxx" +#include <columnspanset.hxx> + +#include <boost/ptr_container/ptr_map.hpp> class ScDocument; class ScDocShell; @@ -36,6 +39,8 @@ class ScSimpleUndo: public SfxUndoAction ScSimpleUndo(const ScSimpleUndo&); // disabled public: + typedef boost::ptr_map<SCTAB,sc::ColumnSpanSet> DataSpansType; + TYPEINFO_OVERRIDE(); ScSimpleUndo( ScDocShell* pDocSh ); virtual ~ScSimpleUndo(); @@ -57,6 +62,14 @@ protected: void BroadcastChanges( const ScRange& rRange ); + /** + * Broadcast changes on specified spans. + * + * @param rSpans container that specifies all spans whose changes need to + * be broadcasted. + */ + void BroadcastChanges( const DataSpansType& rSpans ); + static void ShowTable( SCTAB nTab ); static void ShowTable( const ScRange& rRange ); }; diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx index 40af6cc415b4..257c470e5615 100644 --- a/sc/source/ui/inc/undoblk.hxx +++ b/sc/source/ui/inc/undoblk.hxx @@ -25,7 +25,6 @@ #include "spellparam.hxx" #include "cellmergeoption.hxx" #include "paramisc.hxx" -#include <columnspanset.hxx> #include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> @@ -274,7 +273,11 @@ public: virtual OUString GetComment() const SAL_OVERRIDE; + void SetDataSpans( const boost::shared_ptr<DataSpansType>& pSpans ); + private: + boost::shared_ptr<DataSpansType> mpDataSpans; // Spans of non-empty cells. + ScRange aRange; ScMarkData aMarkData; ScDocument* pUndoDoc; // Block mark and deleted data diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx index 28daae102aad..8d7cff26203b 100644 --- a/sc/source/ui/undo/undobase.cxx +++ b/sc/source/ui/undo/undobase.cxx @@ -32,8 +32,8 @@ #include "bcaslot.hxx" #include "globstr.hrc" #include <rowheightcontext.hxx> +#include <column.hxx> -// STATIC DATA ----------------------------------------------------------- TYPEINIT1(ScSimpleUndo, SfxUndoAction); TYPEINIT1(ScBlockUndo, ScSimpleUndo); @@ -150,6 +150,48 @@ void ScSimpleUndo::BroadcastChanges( const ScRange& rRange ) pDoc->BroadcastCells(rRange, SC_HINT_DATACHANGED); } +namespace { + +class SpanBroadcaster : public sc::ColumnSpanSet::ColumnAction +{ + ScDocument& mrDoc; + SCTAB mnCurTab; + SCCOL mnCurCol; + +public: + SpanBroadcaster( ScDocument& rDoc ) : mrDoc(rDoc), mnCurTab(-1), mnCurCol(-1) {} + + virtual void startColumn( ScColumn* pCol ) + { + mnCurTab = pCol->GetTab(); + mnCurCol = pCol->GetCol(); + } + + virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal ) + { + if (!bVal) + return; + + ScRange aRange(mnCurTab, mnCurCol, nRow1, mnCurTab, mnCurCol, nRow2); + mrDoc.BroadcastCells(aRange, SC_HINT_DATACHANGED); + }; +}; + +} + +void ScSimpleUndo::BroadcastChanges( const DataSpansType& rSpans ) +{ + ScDocument* pDoc = pDocShell->GetDocument(); + SpanBroadcaster aBroadcaster(*pDoc); + + DataSpansType::const_iterator it = rSpans.begin(), itEnd = rSpans.end(); + for (; it != itEnd; ++it) + { + const sc::ColumnSpanSet& rSet = *it->second; + rSet.executeColumnAction(*pDoc, aBroadcaster); + } +} + void ScSimpleUndo::ShowTable( SCTAB nTab ) { ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell(); diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx index 437a9e189594..03edabff1fba 100644 --- a/sc/source/ui/undo/undoblk3.cxx +++ b/sc/source/ui/undo/undoblk3.cxx @@ -106,6 +106,11 @@ OUString ScUndoDeleteContents::GetComment() const return ScGlobal::GetRscString( STR_UNDO_DELETECONTENTS ); // "Delete" } +void ScUndoDeleteContents::SetDataSpans( const boost::shared_ptr<DataSpansType>& pSpans ) +{ + mpDataSpans = pSpans; +} + void ScUndoDeleteContents::SetChangeTrack() { ScChangeTrack* pChangeTrack = pDocShell->GetDocument()->GetChangeTrack(); @@ -184,8 +189,13 @@ void ScUndoDeleteContents::Undo() EndUndo(); if (nFlags & IDF_CONTENTS) + { // Broadcast only when the content changes. fdo#74687 - BroadcastChanges(aRange); + if (mpDataSpans) + BroadcastChanges(*mpDataSpans); + else + BroadcastChanges(aRange); + } HelperNotifyChanges::NotifyIfChangesListeners(*pDocShell, aRange); } diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index b1c3fc408217..7c66d9c9044d 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -1846,6 +1846,9 @@ void ScViewFunc::DeleteContents( sal_uInt16 nFlags, bool bRecord ) aFuncMark ); } + // To keep track of all non-empty cells within the deleted area. + boost::shared_ptr<ScSimpleUndo::DataSpansType> pDataSpans; + if ( bRecord ) { pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); @@ -1872,6 +1875,26 @@ void ScViewFunc::DeleteContents( sal_uInt16 nFlags, bool bRecord ) // do not copy note captions to undo document nUndoDocFlags |= IDF_NOCAPTIONS; pDoc->CopyToDocument( aCopyRange, nUndoDocFlags, bMulti, pUndoDoc, &aFuncMark ); + + pDataSpans.reset(new ScSimpleUndo::DataSpansType); + + for (itr = aFuncMark.begin(); itr != itrEnd; ++itr) + { + nTab = *itr; + + SCCOL nCol1 = aCopyRange.aStart.Col(), nCol2 = aCopyRange.aEnd.Col(); + SCROW nRow1 = aCopyRange.aStart.Row(), nRow2 = aCopyRange.aEnd.Row(); + + std::pair<ScSimpleUndo::DataSpansType::iterator,bool> r = + pDataSpans->insert(nTab, new sc::ColumnSpanSet(false)); + + if (r.second) + { + ScSimpleUndo::DataSpansType::iterator it = r.first; + sc::ColumnSpanSet* pSet = it->second; + pSet->scan(*pDoc, nTab, nCol1, nRow1, nCol2, nRow2, true); + } + } } HideAllCursors(); // for if summary is cancelled @@ -1886,9 +1909,12 @@ void ScViewFunc::DeleteContents( sal_uInt16 nFlags, bool bRecord ) if ( bRecord ) { - pDocSh->GetUndoManager()->AddUndoAction( - new ScUndoDeleteContents( pDocSh, aFuncMark, aExtendedRange, - pUndoDoc, bMulti, nFlags, bDrawUndo ) ); + ScUndoDeleteContents* pUndo = + new ScUndoDeleteContents( + pDocSh, aFuncMark, aExtendedRange, pUndoDoc, bMulti, nFlags, bDrawUndo); + pUndo->SetDataSpans(pDataSpans); + + pDocSh->GetUndoManager()->AddUndoAction(pUndo); } if (!AdjustRowHeight( aExtendedRange.aStart.Row(), aExtendedRange.aEnd.Row() )) |