summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2020-12-21 21:09:44 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2020-12-23 19:08:31 +0100
commit8dd2e9900d4f00dbc7ce289d9ce9a9c6739b4851 (patch)
tree31605a2eee628e680a3bb70bb814f9935a3a55cb
parente98c4be2c87ba5b3f4aedc31388014b320588d4b (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> (cherry picked from commit 207a709bcf1af2eee7fbac8d3c30de6f8d43a8a3) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108177 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--sw/qa/extras/uiwriter/data2/tdf139127.fodt45
-rw-r--r--sw/qa/extras/uiwriter/uiwriter2.cxx100
-rw-r--r--sw/source/core/doc/DocumentRedlineManager.cxx11
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 496b9b8602bc..64ad80da0f3b 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 466ffa0464a0..4a63d5e443ac 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -2488,6 +2488,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;