diff options
author | Eike Rathke <erack@redhat.com> | 2015-09-10 15:52:21 +0200 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2015-09-11 09:50:49 +0000 |
commit | b6f31e1025d658f15ed8280225c4b5c032639629 (patch) | |
tree | 50501771f50039dfc21080efd237da128ef96540 | |
parent | c055dd615b17198b37e98ed3f832246ca8fbf5ee (diff) |
Resolves: tdf#92995 do not delete caption objects that are held by Undo
Drag&Drop Undo is a special case of ownership..
Change-Id: I2fe7769c4d84efe09d432335d5d8e72d506bf7a1
(cherry picked from commit 44f34c1163882c2e3086282374fee9cd55ee211f)
Reviewed-on: https://gerrit.libreoffice.org/18472
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/inc/global.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 21 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 2 | ||||
-rw-r--r-- | sc/source/ui/undo/undoblk.cxx | 9 |
6 files changed, 36 insertions, 6 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 9d9679308d49..fd27c107fafb 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -583,7 +583,7 @@ public: ScPostIt* GetCellNote( SCROW nRow ); const ScPostIt* GetCellNote( SCROW nRow ) const; const ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const; - void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 ); + void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership ); bool HasCellNotes() const; void SetCellNote( SCROW nRow, ScPostIt* pNote); bool IsNotesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const; diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index b95faf5cd305..397808ec6eb2 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -197,10 +197,11 @@ const InsertDeleteFlags IDF_OUTLINE = InsertDeleteFlags::fromInt(0x0800); // const InsertDeleteFlags IDF_NOCAPTIONS = InsertDeleteFlags::fromInt(0x0200); /// Internal use only (undo etc.): do not copy/delete caption objects of cell notes. const InsertDeleteFlags IDF_ADDNOTES = InsertDeleteFlags::fromInt(0x0400); /// Internal use only (copy from clip): do not delete existing cell contents when pasting notes. const InsertDeleteFlags IDF_SPECIAL_BOOLEAN = InsertDeleteFlags::fromInt(0x1000); +const InsertDeleteFlags IDF_FORGETCAPTIONS = InsertDeleteFlags::fromInt(0x2000); /// Internal use only (d&d undo): do not delete caption objects of cell notes. const InsertDeleteFlags IDF_ATTRIB = IDF_HARDATTR | IDF_STYLES; const InsertDeleteFlags IDF_CONTENTS = IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_NOTE | IDF_FORMULA | IDF_OUTLINE; const InsertDeleteFlags IDF_ALL = IDF_CONTENTS | IDF_ATTRIB | IDF_OBJECTS; -const InsertDeleteFlags IDF_ALL_USED_BITS = IDF_ALL | IDF_EDITATTR | IDF_NOCAPTIONS | IDF_ADDNOTES | IDF_SPECIAL_BOOLEAN; +const InsertDeleteFlags IDF_ALL_USED_BITS = IDF_ALL | IDF_EDITATTR | IDF_NOCAPTIONS | IDF_ADDNOTES | IDF_SPECIAL_BOOLEAN | IDF_FORGETCAPTIONS; inline InsertDeleteFlags operator~ (const InsertDeleteFlags& rhs) { diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index bb6a37da927b..8929ecd9f46e 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1816,8 +1816,27 @@ void ScColumn::SetCellNote(SCROW nRow, ScPostIt* pNote) maCellNotes.set(nRow, pNote); } -void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 ) +namespace { +class ForgetCellNoteCaptionsHandler +{ + +public: + ForgetCellNoteCaptionsHandler() {} + + void operator() ( size_t /*nRow*/, ScPostIt* p ) + { + p->ForgetCaption(); + } +}; +} + +void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership ) { + if (bForgetCaptionOwnership) + { + ForgetCellNoteCaptionsHandler aFunc; + sc::ParseNote(maCellNotes.begin(), maCellNotes, nRow1, nRow2, aFunc); + } rBlockPos.miCellNotePos = maCellNotes.set_empty(rBlockPos.miCellNotePos, nRow1, nRow2); } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 40ec240370ca..757c3e3de10f 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -684,7 +684,10 @@ void ScColumn::DeleteArea( } if (nDelFlag & IDF_NOTE) - DeleteCellNotes(aBlockPos, nStartRow, nEndRow); + { + bool bForgetCaptionOwnership = ((nDelFlag & IDF_FORGETCAPTIONS) != IDF_NONE); + DeleteCellNotes(aBlockPos, nStartRow, nEndRow, bForgetCaptionOwnership); + } if ( nDelFlag & IDF_EDITATTR ) { diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index 46b59c04b6a0..ac09eac472ce 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -114,7 +114,7 @@ void ScColumn::DeleteBeforeCopyFromClip( } if (nDelFlag & IDF_NOTE) - DeleteCellNotes(aBlockPos, nRow1, nRow2); + DeleteCellNotes(aBlockPos, nRow1, nRow2, false); if (nDelFlag & IDF_EDITATTR) RemoveEditAttribs(nRow1, nRow2); diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index 2154466e9732..9cecfa029045 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -1239,7 +1239,14 @@ void ScUndoDragDrop::DoUndo( ScRange aRange ) // do not undo objects and note captions, they are handled via drawing undo InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS; - rDoc.DeleteAreaTab( aRange, nUndoFlags ); + // Additionally discard/forget caption ownership during deletion, as + // Drag&Drop is a special case in that the Undo holds captions of the + // transfered target range, which would get deleted and + // SdrGroupUndo::Undo() would attempt to access invalidated captions and + // crash, tdf#92995 + InsertDeleteFlags nDelFlags = nUndoFlags | IDF_FORGETCAPTIONS; + + rDoc.DeleteAreaTab( aRange, nDelFlags ); pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc ); if ( rDoc.HasAttrib( aRange, HASATTR_MERGED ) ) rDoc.ExtendMerge( aRange, true ); |