sw/qa/extras/uiwriter/data/tdf144058.fodt     |  134 ++++++++++++++++++++++++++
 sw/qa/extras/uiwriter/uiwriter2.cxx           |   36 ++++++
 sw/source/core/doc/DocumentRedlineManager.cxx |   43 ++++++--
 3 files changed, 206 insertions(+), 7 deletions(-)

New commits:
commit f3bec764ddbf3fd3ae986f034c89626bf22940e0
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Thu Sep 2 14:21:22 2021 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Fri Sep 3 09:27:14 2021 +0200

    tdf144058 sw track changes: fix table deletion at paragraph join
    
    Tracked paragraph join by table deletion left empty
    table in the text after accepting the changes, caused
    by the non-continuous redline range over the table,
    related to the copying of the formatting of the first
    paragraph to the (wholly or partially) removed paragraphs.
    Fixed by skipping paragraph format copying in the case
    of table paragraphs.
    
    Note: this is not enough for tables with inner redlines,
    where tracked paragraph join with deletion of such a table
    still leaves an empty table at the place of the table
    (a problem inherited from OOo).
    
    Regression from commit 1bbbe57dfc0b43d6b5444798d77dcdf5e4e76e49
    "tdf#119571 change tracking: show layout changes at paragraph join".
    
    Change-Id: Ib3ff79c766b5e6faced796b9546d332bab4e0d94
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121510
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/qa/extras/uiwriter/data/tdf144058.fodt 
b/sw/qa/extras/uiwriter/data/tdf144058.fodt
new file mode 100644
index 000000000000..6c311cbbc84f
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf144058.fodt
@@ -0,0 +1,134 @@
+<?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:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:config="urn:oas
 is:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:rpt="http://openoffice.org/2005/report"; 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:xhtml="http://www.w3.org/1999/xhtml"; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#"; 
xmlns:officeooo="http://openoffice.org/2009/office"; 
xmlns:tableooo="http://openoffice.org/2009/table"; 
xmlns:drawooo="http://openoffice.org/2010/draw"; 
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:formx="urn:openoffice:names:
 experimental:ooxml-odf-interop:xmlns:form:1.0" 
xmlns:css3t="http://www.w3.org/TR/css3-text/"; office:version="1.2" 
office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="Table1" style:family="table">
+   <style:table-properties style:width="17cm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table1.A" style:family="table-column">
+   <style:table-column-properties style:column-width="4.249cm" 
style:rel-column-width="16383*"/>
+  </style:style>
+  <style:style style:name="Table1.D" style:family="table-column">
+   <style:table-column-properties style:column-width="4.251cm" 
style:rel-column-width="16386*"/>
+  </style:style>
+  <style:style style:name="Table1.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt 
solid #000000" fo:border-right="none" fo:border-top="0.05pt solid #000000" 
fo:border-bottom="0.05pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table1.D1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid 
#000000"/>
+  </style:style>
+  <style:style style:name="Table1.A2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt 
solid #000000" fo:border-right="none" fo:border-top="none" 
fo:border-bottom="0.05pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table1.D2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt 
solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" 
fo:border-bottom="0.05pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2" style:family="table">
+   <style:table-properties style:width="17cm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table2.A" style:family="table-column">
+   <style:table-column-properties style:column-width="17cm" 
style:rel-column-width="65535*"/>
+  </style:style>
+  <style:style style:name="Table2.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid 
#000000"/>
+  </style:style>
+  <style:style style:name="Table2.A2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt 
solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" 
fo:border-bottom="0.05pt solid #000000"/>
+  </style:style>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties officeooo:rsid="000d0e98" 
officeooo:paragraph-rsid="000d0e98"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" 
style:parent-style-name="Table_20_Contents">
+   <style:text-properties officeooo:rsid="000d0e98" 
officeooo:paragraph-rsid="000ebd4f"/>
+  </style:style>
+  <style:style style:name="P3" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties officeooo:paragraph-rsid="000d0e98"/>
+  </style:style>
+  <style:style style:name="P4" style:family="paragraph" 
style:parent-style-name="Table_20_Contents">
+   <style:text-properties officeooo:rsid="000ebd4f" 
officeooo:paragraph-rsid="000ebd4f"/>
+  </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" loext:margin-gutter="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:style style:name="dp1" style:family="drawing-page">
+   <style:drawing-page-properties draw:background-size="full"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:h text:outline-level="1">Lorem ipsum</text:h>
+   <text:p text:style-name="P1">dolor sit amet, consectetur adipiscing 
elit.</text:p>
+   <table:table table:name="Table1" table:style-name="Table1">
+    <table:table-column table:style-name="Table1.A" 
table:number-columns-repeated="3"/>
+    <table:table-column table:style-name="Table1.D"/>
+    <table:table-row table:style-name="TableLine94153531010224">
+     <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P4">x</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.D1" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row table:style-name="TableLine94153591510960">
+     <table:table-cell table:style-name="Table1.A2" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.A2" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.A2" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.D2" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+    </table:table-row>
+   </table:table>
+   <table:table table:name="Table2" table:style-name="Table2">
+    <table:table-column table:style-name="Table2.A"/>
+    <table:table-row table:style-name="TableLine94153607741600">
+     <table:table-cell table:style-name="Table2.A1" office:value-type="string">
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+      <text:p text:style-name="P2">x</text:p>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row table:style-name="TableLine94153608696784">
+     <table:table-cell table:style-name="Table2.A2" office:value-type="string">
+      <text:p text:style-name="P4">x</text:p>
+      <text:p text:style-name="P4">x</text:p>
+      <text:p text:style-name="P4">x</text:p>
+     </table:table-cell>
+    </table:table-row>
+   </table:table>
+   <text:p text:style-name="P1">Integer sodales tincidunt tristique.</text:p>
+   <text:p text:style-name="P1">Aliquam velit massa, laoreet vel leo nec, 
volutpat facilisis eros.</text:p>
+   <text:p text:style-name="P3"/>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index a1603ab50f30..1b1a1f73be92 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1437,6 +1437,42 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119571)
                          getProperty<OUString>(getParagraph(2), 
"ParaStyleName"));
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf144058)
+{
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf144058.fodt");
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"),
+                         getProperty<OUString>(getParagraph(1), 
"ParaStyleName"));
+
+    //turn on red-lining and show changes
+    pDoc->getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::On | 
RedlineFlags::ShowDelete
+                                                      | 
RedlineFlags::ShowInsert);
+    CPPUNIT_ASSERT_MESSAGE("redlining should be on",
+                           pDoc->getIDocumentRedlineAccess().IsRedlineOn());
+    CPPUNIT_ASSERT_MESSAGE(
+        "redlines should be visible",
+        
IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
+
+    // join first and last but one paragraphs by removing the end of the first 
paragraph
+    // with paragraph break, and by removing two tables of the selected range 
completely
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/false, 1, 
/*bBasicCall=*/false);
+    pWrtShell->Down(/*bSelect=*/true);
+    pWrtShell->Down(/*bSelect=*/true);
+    pWrtShell->Down(/*bSelect=*/true);
+    rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
+    pTransfer->Cut();
+
+    // accept all: tables are deleted
+    dispatchCommand(mxComponent, ".uno:AcceptAllTrackedChanges", {});
+
+    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> 
xTables(xTextTablesSupplier->getTextTables(),
+                                                    uno::UNO_QUERY);
+    // This was 2 (remaining empty tables)
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf119019)
 {
     // check handling of overlapping redlines
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index aaf24054db5e..cf68ce329ae5 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -2190,19 +2190,17 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* 
pNewRedl, bool const bCall
                     // in "Show changes" mode, too. All removed paragraphs
                     // get the style of the first (partially deleted) paragraph
                     // to avoid text insertion with bad style in the deleted
-                    // area later.
+                    // area later (except paragraphs of the removed tables).
 
                     SwContentNode* pDelNd = 
pStt->nNode.GetNode().GetContentNode();
+                    // start copying the style of the first paragraph from the 
end of the range
                     SwContentNode* pTextNd = 
pEnd->nNode.GetNode().GetContentNode();
-                    SwTextNode* pDelNode = pStt->nNode.GetNode().GetTextNode();
-                    SwTextNode* pTextNode;
                     SwNodeIndex aIdx( pEnd->nNode.GetNode() );
                     bool bFirst = true;
 
-                    while (pDelNode != nullptr && pTextNd != nullptr && 
pDelNd->GetIndex() < pTextNd->GetIndex())
+                    while (pTextNd != nullptr && pDelNd->GetIndex() < 
pTextNd->GetIndex())
                     {
-                        pTextNode = pTextNd->GetTextNode();
-                        if (pTextNode && pDelNode != pTextNode )
+                        if( pTextNd->IsTextNode() )
                         {
                             SwPosition aPos(aIdx);
 
@@ -2237,10 +2235,41 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* 
pNewRedl, bool const bCall
                             // modify paragraph formatting
                             lcl_CopyStyle(*pStt, aPos);
                         }
-                        pTextNd = SwNodes::GoPrevious( &aIdx );
 
                         if (bFirst)
                             bFirst = false;
+
+                        // Jump to the previous paragraph and if needed, skip 
paragraphs of
+                        // the removed table(s) in the range to avoid leaving 
empty tables
+                        // because of the non-continuous redline range over 
the table.
+                        // FIXME: this is not enough for tables with inner 
redlines, where
+                        // tracked deletion of the text containing such a 
table leaves an
+                        // empty table at the place of the table (a problem 
inherited from OOo).
+                        pTextNd = nullptr;
+                        while( --aIdx && pDelNd->GetIndex() < aIdx.GetIndex() 
&&
+                                !aIdx.GetNode().IsContentNode() )
+                        {
+                            // possible table end
+                            if( aIdx.GetNode().IsEndNode() && 
aIdx.GetNode().FindTableNode() )
+                            {
+                                SwNodeIndex aIdx2 = aIdx;
+                                // search table start and skip table paragraphs
+                                while ( pDelNd->GetIndex() < aIdx2.GetIndex() )
+                                {
+                                    SwTableNode* pTable = 
aIdx2.GetNode().GetTableNode();
+                                    if( pTable &&
+                                        pTable->EndOfSectionNode()->GetIndex() 
== aIdx.GetIndex() )
+                                    {
+                                       aIdx = aIdx2;
+                                       break;
+                                    }
+                                    --aIdx2;
+                                }
+                            }
+                        }
+
+                        if (aIdx.GetNode().IsContentNode())
+                            pTextNd = aIdx.GetNode().GetContentNode();
                     }
                 }
             }

Reply via email to