summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2017-01-18 22:49:08 +0100
committerEike Rathke <erack@redhat.com>2017-01-18 22:49:42 +0100
commitb8b657123cc508c906622d20669507628c93e104 (patch)
tree88326f89d12cd26944c97c010da765cfe98a675a
parent6884550c20f95a635357ad848799a1aae555968a (diff)
tdf#104967 preserve isolated notes data in clipboard when closing document
Change-Id: I0e263583e27c5103c0bb90e8fe00562e46a52d98
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/postit.hxx10
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/source/core/data/column4.cxx12
-rw-r--r--sc/source/core/data/documen2.cxx8
-rw-r--r--sc/source/core/data/document.cxx4
-rw-r--r--sc/source/core/data/postit.cxx40
-rw-r--r--sc/source/core/data/table2.cxx4
-rw-r--r--sc/source/ui/undo/undoblk.cxx2
10 files changed, 60 insertions, 26 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 0568aa91dbb2..ae911e688c88 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -598,7 +598,7 @@ public:
ScPostIt* ReleaseNote( SCROW nRow );
size_t GetNoteCount() const;
void CreateAllNoteCaptions();
- void ForgetNoteCaptions( SCROW nRow1, SCROW nRow2 );
+ void ForgetNoteCaptions( SCROW nRow1, SCROW nRow2, bool bPreserveData );
SCROW GetNotePosition( size_t nIndex ) const;
void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
void GetNotesInRange( SCROW nStartRow, SCROW nEndRow, std::vector<sc::NoteEntry>& rNotes ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 2603cd632a65..7ceb1212dd1d 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1110,7 +1110,7 @@ public:
* code uses sdr objects to export note data.
*/
void CreateAllNoteCaptions();
- void ForgetNoteCaptions( const ScRangeList& rRanges );
+ void ForgetNoteCaptions( const ScRangeList& rRanges, bool bPreserveData );
ScAddress GetNotePosition( size_t nIndex ) const;
ScAddress GetNotePosition( size_t nIndex, SCTAB nTab ) const;
diff --git a/sc/inc/postit.hxx b/sc/inc/postit.hxx
index 8835deaee972..87553f3f5c3e 100644
--- a/sc/inc/postit.hxx
+++ b/sc/inc/postit.hxx
@@ -129,8 +129,14 @@ public:
/** Returns the caption object of this note. Creates the caption object, if
the note contains initial caption data instead of the caption. */
SdrCaptionObj* GetOrCreateCaption( const ScAddress& rPos ) const;
- /** Forgets the pointer to the note caption object. */
- void ForgetCaption();
+
+ /** Forgets the pointer to the note caption object.
+
+ @param bPreserveData
+ If true then the note text is remembered in maNoteData to be able
+ to later reconstruct a caption from it.
+ */
+ void ForgetCaption( bool bPreserveData = false );
/** Shows or hides the note caption object. */
void ShowCaption( const ScAddress& rPos, bool bShow );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index da69ea9a0571..34f6e3fd992a 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -400,7 +400,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 ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bPreserveData );
void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
void GetNotesInRange( const ScRange& rRange, std::vector<sc::NoteEntry>& rNotes ) const;
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index ddf18d68f1a0..b19f33069d89 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -598,11 +598,15 @@ public:
}
};
-struct NoteCaptionCleaner
+class NoteCaptionCleaner
{
+ bool mbPreserveData;
+public:
+ explicit NoteCaptionCleaner( bool bPreserveData ) : mbPreserveData(bPreserveData) {}
+
void operator() ( size_t /*nRow*/, ScPostIt* p )
{
- p->ForgetCaption();
+ p->ForgetCaption(mbPreserveData);
}
};
@@ -614,12 +618,12 @@ void ScColumn::CreateAllNoteCaptions()
sc::ProcessNote(maCellNotes, aFunc);
}
-void ScColumn::ForgetNoteCaptions( SCROW nRow1, SCROW nRow2 )
+void ScColumn::ForgetNoteCaptions( SCROW nRow1, SCROW nRow2, bool bPreserveData )
{
if (!ValidRow(nRow1) || !ValidRow(nRow2))
return;
- NoteCaptionCleaner aFunc;
+ NoteCaptionCleaner aFunc(bPreserveData);
sc::CellNoteStoreType::iterator it = maCellNotes.begin();
sc::ProcessNote(it, maCellNotes, nRow1, nRow2, aFunc);
}
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index cd3f2d715362..a5bf84093710 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -379,13 +379,11 @@ ScDocument::~ScDocument()
// copied from this document, forget it as it references this
// document's drawing layer pages and what not, which otherwise when
// pasting to another document after this document was destructed would
- // attempt to access non-existing data.
- /* XXX this is only a workaround to prevent a crash, the actual note
- * content is lost, only a standard empty note caption will be pasted.
- * TODO: come up with a solution. */
+ // attempt to access non-existing data. Preserve the text data though.
ScDocument* pClipDoc = ScModule::GetClipDoc();
if (pClipDoc)
- pClipDoc->ForgetNoteCaptions( ScRangeList( ScRange( 0,0,0, MAXCOL, MAXROW, pClipDoc->GetTableCount()-1)));
+ pClipDoc->ForgetNoteCaptions(
+ ScRangeList( ScRange( 0,0,0, MAXCOL, MAXROW, pClipDoc->GetTableCount()-1)), true);
}
mxFormulaParserPool.reset();
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f02c8a39b273..a9f5a875a0f2 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6484,7 +6484,7 @@ void ScDocument::CreateAllNoteCaptions()
}
}
-void ScDocument::ForgetNoteCaptions( const ScRangeList& rRanges )
+void ScDocument::ForgetNoteCaptions( const ScRangeList& rRanges, bool bPreserveData )
{
for (size_t i = 0, n = rRanges.size(); i < n; ++i)
{
@@ -6497,7 +6497,7 @@ void ScDocument::ForgetNoteCaptions( const ScRangeList& rRanges )
if (!pTab)
continue;
- pTab->ForgetNoteCaptions(s.Col(), s.Row(), e.Col(), e.Row());
+ pTab->ForgetNoteCaptions(s.Col(), s.Row(), e.Col(), e.Row(), bPreserveData);
}
}
}
diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
index 27dfb65113be..83c6111823fa 100644
--- a/sc/source/core/data/postit.cxx
+++ b/sc/source/core/data/postit.cxx
@@ -584,12 +584,32 @@ SdrCaptionObj* ScPostIt::GetOrCreateCaption( const ScAddress& rPos ) const
return maNoteData.mpCaption;
}
-void ScPostIt::ForgetCaption()
+void ScPostIt::ForgetCaption( bool bPreserveData )
{
- /* This function is used in undo actions to give up the responsibility for
- the caption object which is handled by separate drawing undo actions. */
- maNoteData.mpCaption = nullptr;
- maNoteData.mxInitData.reset();
+ if (bPreserveData)
+ {
+ // Used in clipboard when the originating document is destructed to be
+ // able to paste into another document. Caption size and relative
+ // position are not preserved but default created when pasted. Also the
+ // MergedItemSet can not be carried over or it had to be adapted to
+ // defaults and pool. At least preserve the text and outline object if
+ // possible.
+ ScCaptionInitData* pInitData = new ScCaptionInitData;
+ const OutlinerParaObject* pOPO = GetOutlinerObject();
+ if (pOPO)
+ pInitData->mxOutlinerObj.reset( new OutlinerParaObject(*pOPO));
+ pInitData->maSimpleText = GetText();
+
+ maNoteData.mxInitData.reset(pInitData);
+ maNoteData.mpCaption = nullptr;
+ }
+ else
+ {
+ /* This function is used in undo actions to give up the responsibility for
+ the caption object which is handled by separate drawing undo actions. */
+ maNoteData.mpCaption = nullptr;
+ maNoteData.mxInitData.reset();
+ }
}
void ScPostIt::ShowCaption( const ScAddress& rPos, bool bShow )
@@ -629,13 +649,19 @@ void ScPostIt::CreateCaptionFromInitData( const ScAddress& rPos ) const
to the clipboard/undo document, and when copying cells from the
clipboard/undo document. The former should always be called first,
so if called in an clipboard/undo document, the caption should have
- been created already. */
- OSL_ENSURE( !mrDoc.IsUndo() && !mrDoc.IsClipboard(), "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
+ been created already. Hovever, for clipboard in case the
+ originating document was destructed a new caption has to be
+ created. */
+ OSL_ENSURE( !mrDoc.IsUndo() && (!mrDoc.IsClipboard() || !maNoteData.mpCaption),
+ "ScPostIt::CreateCaptionFromInitData - note caption should not be created in undo/clip documents" );
/* #i104915# Never try to create notes in Undo document, leads to
crash due to missing document members (e.g. row height array). */
if( !maNoteData.mpCaption && !mrDoc.IsUndo() )
{
+ if (mrDoc.IsClipboard())
+ mrDoc.InitDrawLayer(); // ensure there is a drawing layer
+
// ScNoteCaptionCreator c'tor creates the caption and inserts it into the document and maNoteData
ScNoteCaptionCreator aCreator( mrDoc, rPos, maNoteData );
if( maNoteData.mpCaption )
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 9814b659daff..c98f97431bdf 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1587,13 +1587,13 @@ void ScTable::CreateAllNoteCaptions()
aCol[i].CreateAllNoteCaptions();
}
-void ScTable::ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+void ScTable::ForgetNoteCaptions( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bPreserveData )
{
if (!ValidCol(nCol1) || !ValidCol(nCol2))
return;
for (SCCOL i = nCol1; i <= nCol2; ++i)
- aCol[i].ForgetNoteCaptions(nRow1, nRow2);
+ aCol[i].ForgetNoteCaptions(nRow1, nRow2, bPreserveData);
}
void ScTable::GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 4a693e4a2c45..45c3ffb34b2b 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -939,7 +939,7 @@ void ScUndoPaste::DoChange(bool bUndo)
sal_uInt16 nExtFlags = 0;
pDocShell->UpdatePaintExt(nExtFlags, maBlockRanges.Combine());
- rDoc.ForgetNoteCaptions(maBlockRanges);
+ rDoc.ForgetNoteCaptions(maBlockRanges, false);
aMarkData.MarkToMulti();
rDoc.DeleteSelection(nUndoFlags, aMarkData, false); // no broadcasting here
for (size_t i = 0, n = maBlockRanges.size(); i < n; ++i)