From bc504b5adfaeeac0b910b89b0c98ae564f1ff5b8 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 5 Feb 2014 22:59:04 -0500 Subject: fdo#74556: Correctly handle note captions life cycles. When copying notes to clipboard, we don't clone captions but leave them pointing to the original captions objects. Also, during undo and redo, we need to clear all caption pointers to prevent them from being deleted when the ScPostIt objects get deleted. The undo and redo of caption objects are handled in the drawing layer afterwards. Change-Id: I2b9cf0858dba5b3cac26db3ef501ea09779a795a --- sc/inc/column.hxx | 1 + sc/inc/document.hxx | 1 + sc/inc/mtvcellfunc.hxx | 10 ++++++++++ sc/inc/table.hxx | 1 + sc/source/core/data/column.cxx | 2 +- sc/source/core/data/column2.cxx | 18 ++++++++++++++++++ sc/source/core/data/document.cxx | 18 ++++++++++++++++++ sc/source/core/data/table2.cxx | 9 +++++++++ sc/source/ui/undo/undoblk.cxx | 1 + 9 files changed, 60 insertions(+), 1 deletion(-) diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 23a2a824f50c..7f91d9050949 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -518,6 +518,7 @@ public: ScPostIt* ReleaseNote( SCROW nRow ); size_t GetNoteCount() const; void CreateAllNoteCaptions(); + void ForgetNoteCaptions( SCROW nRow1, SCROW nRow2 ); SCROW GetNotePosition( size_t nIndex ) const; void GetAllNoteEntries( std::vector& rNotes ) const; void GetNotesInRange( SCROW nStartRow, SCROW nEndRow, std::vector& rNotes ) const; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index e214a321c30a..64212ed2bf23 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -919,6 +919,7 @@ public: * code uses sdr objects to export note data. */ void CreateAllNoteCaptions(); + void ForgetNoteCaptions( const ScRangeList& rRanges ); ScAddress GetNotePosition( size_t nIndex ) const; SCROW GetNotePosition( SCTAB nTab, SCCOL nCol, size_t nIndex ) const; diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx index 793f2dbc1872..fc6d2dcd74b0 100644 --- a/sc/inc/mtvcellfunc.hxx +++ b/sc/inc/mtvcellfunc.hxx @@ -166,6 +166,16 @@ void ProcessNote(CellNoteStoreType& rStore, _Func& rFunc) ProcessElements1 >(rStore, rFunc, aElse); } +template +typename CellNoteStoreType::iterator +ProcessNote( + const CellNoteStoreType::iterator& it, CellNoteStoreType& rStore, SCROW nRow1, SCROW nRow2, _FuncElem& rFuncElem) +{ + FuncElseNoOp aElse; + return ProcessElements1< + CellNoteStoreType, cellnote_block, _FuncElem, FuncElseNoOp >(it, rStore, nRow1, nRow2, rFuncElem, aElse); +} + } #endif diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 0ac441cbf610..1e8764b7f12c 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -393,6 +393,7 @@ public: size_t GetNoteCount( SCCOL nCol ) const; SCROW GetNotePosition( SCCOL nCol, size_t nIndex ) const; void CreateAllNoteCaptions(); + void ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ); void GetAllNoteEntries( std::vector& rNotes ) const; void GetNotesInRange( const ScRange& rRange, std::vector& rNotes ) const; diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index ff8ed6bb1549..52eb27eb9a7e 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1278,7 +1278,7 @@ class CopyToClipHandler void duplicateNotes(SCROW nStartRow, size_t nDataSize ) { - mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestPos); + mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestPos, false); } public: diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index f6c7cd9fd8fb..af06f1bb5182 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1252,6 +1252,14 @@ public: } }; +struct NoteCaptionCleaner +{ + void operator() ( size_t /*nRow*/, ScPostIt* p ) + { + p->ForgetCaption(); + } +}; + } void ScColumn::CreateAllNoteCaptions() @@ -1260,6 +1268,16 @@ void ScColumn::CreateAllNoteCaptions() sc::ProcessNote(maCellNotes, aFunc); } +void ScColumn::ForgetNoteCaptions( SCROW nRow1, SCROW nRow2 ) +{ + if (!ValidRow(nRow1) || !ValidRow(nRow2)) + return; + + NoteCaptionCleaner aFunc; + sc::CellNoteStoreType::iterator it = maCellNotes.begin(); + sc::ProcessNote(it, maCellNotes, nRow1, nRow2, aFunc); +} + SCROW ScColumn::GetNotePosition( size_t nIndex ) const { // Return the row position of the nth note in the column. diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 3194f78bf5c1..3f08fd621cec 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6245,6 +6245,24 @@ void ScDocument::CreateAllNoteCaptions() } } +void ScDocument::ForgetNoteCaptions( const ScRangeList& rRanges ) +{ + for (size_t i = 0, n = rRanges.size(); i < n; ++i) + { + const ScRange* p = rRanges[i]; + const ScAddress& s = p->aStart; + const ScAddress& e = p->aEnd; + for (SCTAB nTab = s.Tab(); nTab <= s.Tab(); ++nTab) + { + ScTable* pTab = FetchTable(nTab); + if (!pTab) + continue; + + pTab->ForgetNoteCaptions(s.Col(), s.Row(), e.Col(), e.Row()); + } + } +} + ScAddress ScDocument::GetNotePosition( size_t nIndex ) const { for (size_t nTab = 0; nTab < maTabs.size(); ++nTab) diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 41f5e0d18287..88ffc1fcd333 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1551,6 +1551,15 @@ void ScTable::CreateAllNoteCaptions() aCol[i].CreateAllNoteCaptions(); } +void ScTable::ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) +{ + if (!ValidCol(nCol1) || !ValidCol(nCol2)) + return; + + for (SCCOL i = nCol1; i <= nCol2; ++i) + aCol[i].ForgetNoteCaptions(nRow1, nRow2); +} + void ScTable::GetAllNoteEntries( std::vector& rNotes ) const { for (SCCOL nCol = 0; nCol < MAXCOLCOUNT; ++nCol) diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index a6222582b23f..2b30fed702f8 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -946,6 +946,7 @@ void ScUndoPaste::DoChange(bool bUndo) sal_uInt16 nExtFlags = 0; pDocShell->UpdatePaintExt(nExtFlags, maBlockRanges.Combine()); + pDoc->ForgetNoteCaptions(maBlockRanges); aMarkData.MarkToMulti(); pDoc->DeleteSelection(nUndoFlags, aMarkData, false); // no broadcasting here for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i) -- cgit v1.2.3