summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-09-10 15:52:21 +0200
committerCaolán McNamara <caolanm@redhat.com>2015-09-11 09:42:00 +0000
commita07333a3f88ab39db554751146687fa6351d2ea0 (patch)
tree8d8e46120e5934b2dc5a3b38fe03cdfdcf71552b
parentd5220fcd4d2583ce7fdfaad4cc5ea2ca881f8c37 (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/18474 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/global.hxx3
-rw-r--r--sc/source/core/data/column2.cxx21
-rw-r--r--sc/source/core/data/column3.cxx5
-rw-r--r--sc/source/core/data/column4.cxx2
-rw-r--r--sc/source/ui/undo/undoblk.cxx9
6 files changed, 36 insertions, 6 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index bacafa5f0962..a89b170e282a 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -566,7 +566,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 143caf8a9c5d..1bb8d45af1e4 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -204,10 +204,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 93f61a6f2b75..3f22a7329b6d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1815,8 +1815,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 d50e4436222a..2b8bdac7332d 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 63534c3aeae3..4de41943eb57 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 15e0a90533c6..0cf3ce131c1f 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 );