summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2015-04-10 11:54:03 +0200
committerCaolán McNamara <caolanm@redhat.com>2015-04-14 20:03:57 +0000
commit2d66204f9676e5a3361de0b6dcc5fcc5a4a625e2 (patch)
treee6d9cec688b72c3a6c310c8ade03874117011780
parent78ca28fb175f8b08b83b40050e41fe30f1bf6237 (diff)
tdf#90230 SwDoc::AppendDoc: take care of marks when inserting page break
SwDoc::AppendDoc() inserts nodes from an other document, and before doing that, it inserts a page break at the end of the document. In case there are marks at the end of the last paragraph, the insertion of the page break moves them to the next page. This is a rare situation, but happens e.g. when the source document is an empty one: then MM puts a mark at the first paragraph of each inserted MM part, and then the first paragraph == the last paragraph, so the mark of the only paragraph in the document gets moved to the next page. This is a problem on its own, but is detected by the SwIndexReg dtor when that empty paragraph gets deleted later in SwNodes::Delete() called by SwDoc::AppendDoc(), resulting in an assertion failure. Triggered by commit a305a2c91420652db450b7f8edd140e1d69f42cf (use bookmarks to mark mailmerge parts in a mailmerge document (fdo#80823), 2014-10-20), these not adjusted bookmarks were not detected before. (cherry picked from commit 2819ee71da631116662401f14f8a0fb78c2a7f3a) Conflicts: sw/qa/extras/mailmerge/mailmerge.cxx Change-Id: I89775b477a2fd3182b2bc87144aed2bfe7912aff Reviewed-on: https://gerrit.libreoffice.org/15310 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sw/qa/extras/mailmerge/data/empty.odtbin0 -> 7241 bytes
-rw-r--r--sw/qa/extras/mailmerge/mailmerge.cxx5
-rw-r--r--sw/source/core/doc/docnew.cxx26
3 files changed, 31 insertions, 0 deletions
diff --git a/sw/qa/extras/mailmerge/data/empty.odt b/sw/qa/extras/mailmerge/data/empty.odt
new file mode 100644
index 000000000000..311cb06e575e
--- /dev/null
+++ b/sw/qa/extras/mailmerge/data/empty.odt
Binary files differ
diff --git a/sw/qa/extras/mailmerge/mailmerge.cxx b/sw/qa/extras/mailmerge/mailmerge.cxx
index 3ac972406c40..37bbed4a2df0 100644
--- a/sw/qa/extras/mailmerge/mailmerge.cxx
+++ b/sw/qa/extras/mailmerge/mailmerge.cxx
@@ -346,6 +346,11 @@ DECLARE_SHELL_MAILMERGE_TEST(testTdf89214, "tdf89214.odt", "10-testing-addresses
CPPUNIT_ASSERT(!getProperty<OUString>(xParagraph, "ListId").isEmpty());
}
+DECLARE_SHELL_MAILMERGE_TEST(testTdf90230, "empty.odt", "10-testing-addresses.ods", "testing-addresses")
+{
+ // MM of an empty document caused an assertion in the SwIndexReg dtor.
+ executeMailMerge();
+}
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index c6d353bd3b10..95a3ded11f8d 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -985,6 +985,32 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, sal_uInt16 const nStartPageNu
if ( pTargetPageDesc ) {
OUString name = pTargetPageDesc->GetName();
pTargetShell->InsertPageBreak( &name, nStartPageNumber );
+
+ // There is now a new empty text node on the new page. If it has
+ // any marks, those are from the previous page: move them back
+ // there, otherwise later we can't delete that empty text node.
+ SwNodeIndex aNodeIndex(GetNodes().GetEndOfContent(), -1);
+ if (SwTxtNode* pTxtNode = aNodeIndex.GetNode().GetTxtNode())
+ {
+ // Position of the last paragraph on the previous page.
+ --aNodeIndex;
+ SwPaM aPaM(aNodeIndex);
+ // Collect the marks starting or ending at this text node.
+ std::set<sw::mark::IMark*> aSeenMarks;
+ IDocumentMarkAccess* pMarkAccess = getIDocumentMarkAccess();
+ for (const SwIndex* pIndex = pTxtNode->GetFirstIndex(); pIndex; pIndex = pIndex->GetNext())
+ {
+ sw::mark::IMark* pMark = const_cast<sw::mark::IMark*>(pIndex->GetMark());
+ if (!pMark)
+ continue;
+ if (aSeenMarks.find(pMark) != aSeenMarks.end())
+ continue;
+ aSeenMarks.insert(pMark);
+ }
+ // And move them back.
+ for (sw::mark::IMark* pMark : aSeenMarks)
+ pMarkAccess->repositionMark(pMark, aPaM);
+ }
}
}
#ifdef DBG_UTIL