diff options
author | László Németh <nemeth@numbertext.org> | 2020-12-21 21:09:44 +0100 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-12-22 15:25:10 +0100 |
commit | 207a709bcf1af2eee7fbac8d3c30de6f8d43a8a3 (patch) | |
tree | 065c0bb8439c2004238a1ce34d2bdb24bf43ca0a | |
parent | 45175d655ad3773df1c006182108cf25e87b1091 (diff) |
tdf#139120 tdf#139127 sw: fix empty redline related crash
and bad "$2" redline text in ChangesInMargin mode.
Also in the default "changes-in-text" mode, Undo didn't
remove this empty redline added for tdf#119571 in the
case of associated redline ExtraData (i.e. joining
paragraphs with different styles), see also
commit 66b39ca79b36da8d5e151deab17a0fb7690eebe6
(tdf#131147 don't store redline ExtraData during Undo).
Change-Id: I7faa7c3acd8f8a0312339087072453a15751dd81
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108126
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/extras/uiwriter/data2/tdf139127.fodt | 45 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 100 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentRedlineManager.cxx | 11 |
3 files changed, 156 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/data2/tdf139127.fodt b/sw/qa/extras/uiwriter/data2/tdf139127.fodt new file mode 100644 index 000000000000..1acd9dc24506 --- /dev/null +++ b/sw/qa/extras/uiwriter/data2/tdf139127.fodt @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:officeooo="http://openoffice.org/2009/office" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text" xmlns:dc="http://purl.org/dc/elements/1.1/"> + <office:styles> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:default-style style:family="paragraph"> + <style:text-properties fo:language="en" fo:country="US"/> + </style:default-style> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties officeooo:rsid="0012fa68" officeooo:paragraph-rsid="0012fa68"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard"> + <style:paragraph-properties fo:break-before="page"/> + <style:text-properties officeooo:rsid="0011ba97" officeooo:paragraph-rsid="0011ba97"/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:text-properties fo:font-weight="normal" style:font-weight-asian="normal" style:font-weight-complex="normal"/> + </style:style> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style/> + <style:footer-style/> + </style:page-layout> + <style:page-layout style:name="pm2"> + <style:page-layout-properties fo:page-width="29.7cm" fo:page-height="21.001cm" style:num-format="1" style:print-orientation="landscape" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm"> + <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/> + </style:page-layout-properties> + <style:header-style/> + <style:footer-style/> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1" style:next-style-name="Landscape"/> + <style:master-page style:name="Landscape" style:page-layout-name="pm2" style:next-style-name="Standard"/> + </office:master-styles> + <office:body> + <office:text> + <text:p text:style-name="P1">First <text:span text:style-name="T1">page</text:span></text:p> + <text:p text:style-name="P2">B</text:p> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 3ad15af8c0ac..50a41b548eff 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -2084,6 +2084,60 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137771) CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin()); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf139120) +{ + SwDoc* pDoc = createDoc("tdf54819.fodt"); + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + // switch on "Show changes in margin" mode + dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {}); + + SwWrtShell* const pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin()); + + // turn on red-lining and show changes + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert + | RedlineFlags::ShowDelete); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE( + "redlines should be visible", + IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + + // delete paragraph break + dispatchCommand(mxComponent, ".uno:GotoEndOfPara", {}); + for (int i = 0; i < 6; ++i) + { + dispatchCommand(mxComponent, ".uno:Delete", {}); + } + + CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum sit amet."), pTextDoc->getText()->getString()); + + for (int i = 0; i < 6; ++i) + { + dispatchCommand(mxComponent, ".uno:Undo", {}); + } + + CPPUNIT_ASSERT_EQUAL(OUString("Lorem ipsum"), getParagraph(1)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("dolor sit amet."), getParagraph(2)->getString()); + + // Dump the rendering of the first page as an XML file. + SwDocShell* pShell = pTextDoc->GetDocShell(); + std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile(); + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + CPPUNIT_ASSERT(pXmlDoc); + + // This was the 3, containing the text "$2" instead of nothing + assertXPath(pXmlDoc, "/metafile/push/push/push/textarray", 2); + + // switch off "Show changes in margin" mode + dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {}); + CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin()); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testJoinParaChangesInMargin) { load(DATA_DIRECTORY, "tdf54819.fodt"); @@ -2125,6 +2179,52 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testJoinParaChangesInMargin) CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin()); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf139127) +{ + load(DATA_DIRECTORY, "tdf139127.fodt"); + + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + // switch on "Show changes in margin" mode + dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {}); + + SwWrtShell* const pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin()); + + // turn on red-lining and show changes + SwDoc* pDoc = pWrtShell->GetDoc(); + pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | RedlineFlags::ShowInsert + | RedlineFlags::ShowDelete); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + CPPUNIT_ASSERT_MESSAGE( + "redlines should be visible", + IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + + // two pages + CPPUNIT_ASSERT_EQUAL(2, getPages()); + + // delete the last two characters with a page break at the end of the document + dispatchCommand(mxComponent, ".uno:GoToEndOfDoc", {}); + dispatchCommand(mxComponent, ".uno:SwBackspace", {}); + dispatchCommand(mxComponent, ".uno:SwBackspace", {}); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + CPPUNIT_ASSERT_EQUAL(OUString("First page"), pTextDoc->getText()->getString()); + + // Undo + dispatchCommand(mxComponent, ".uno:Undo", {}); + // this would crash due to bad redline range + dispatchCommand(mxComponent, ".uno:Undo", {}); + CPPUNIT_ASSERT_EQUAL(2, getPages()); + CPPUNIT_ASSERT_EQUAL(OUString("First page"), getParagraph(1)->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("B"), getParagraph(2)->getString()); + + // switch off "Show changes in margin" mode + dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {}); + CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin()); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138479) { SwDoc* const pDoc = createDoc(); diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 016151161dc5..889b725e8e3e 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -2486,6 +2486,17 @@ bool DocumentRedlineManager::DeleteRedline( const SwPaM& rRange, bool bSaveInUnd break; case SwComparePosition::CollideEnd: + // remove (not hidden) empty redlines created for fixing tdf#119571 + // (Note: hidden redlines are all empty, i.e. start and end are equal.) + if ( pRedl->HasMark() && *pRedl->GetMark() == *pRedl->GetPoint() ) + { + pRedl->InvalidateRange(SwRangeRedline::Invalidation::Remove); + mpRedlineTable->DeleteAndDestroy( n-- ); + bChg = true; + break; + } + [[fallthrough]]; + case SwComparePosition::Before: n = mpRedlineTable->size(); break; |