[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - sw/CppunitTest_sw_core_docnode.mk sw/Module_sw.mk sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Nov 9 08:59:08 UTC 2020


 sw/CppunitTest_sw_core_docnode.mk                    |   73 +++++++++++++++++++
 sw/Module_sw.mk                                      |    1 
 sw/qa/core/docnode/data/redline-ends-before-toc.docx |binary
 sw/qa/core/docnode/docnode.cxx                       |   50 +++++++++++++
 sw/source/core/docnode/ndsect.cxx                    |   23 +++++
 5 files changed, 147 insertions(+)

New commits:
commit a0359bd07b2f4063378f5d052994b2dcbe4aaae2
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Nov 6 16:33:10 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Nov 9 09:58:32 2020 +0100

    DOCX import: fix assertion failure when redline ends right before a ToC
    
    This was always a problem, but now more visible since commit
    8b3c861c46ae12d21b7b3a550e2daa21d2006b77 (tdf#89991 DOCX: import Show
    changes from older formats, 2019-06-13), as it now affects more
    documents: tracked changes can be hidden by the time the initial layout
    is created.
    
    With that aside, the immediate problem is an assertion failure in
    InsertCnt_(), because it assumes that an end node for a section has to
    have a matching pActualSection, created by start node of the same
    section. This will fail in case the start node is hidden, but not the
    end node.
    
    The deeper problem is that redlines are not supposed to cross section
    boundaries: if e.g. multiple cells are selected in a table and the user
    deletes while tracking changes, then the UI creates multiple redlines
    instead.  The problem here is similar: a delete redline ends right
    before the section start, so when SwNodes::InsertTextSection() inserts a
    section node, the end of that redline is automatically moved to the
    start of the section content (its index increases, the actual SwNode
    doesn't change).
    
    Fix the problem by explicitly checking for a redline end at ToX start and
    moving it back to the end of last content node. This matches the doc
    model produced by the WW8 import.
    
    (cherry picked from commit 69edfcf789db1920273191d93fae0bc03f385b81)
    
    Conflicts:
            sw/source/core/docnode/ndsect.cxx
    
    Change-Id: Ic7b279185a20d2a32abd054d3fc6be530ddde12a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105473
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/CppunitTest_sw_core_docnode.mk b/sw/CppunitTest_sw_core_docnode.mk
new file mode 100644
index 000000000000..daa9666a99d4
--- /dev/null
+++ b/sw/CppunitTest_sw_core_docnode.mk
@@ -0,0 +1,73 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_core_docnode))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_docnode))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_core_docnode, \
+    sw/qa/core/docnode/docnode \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_core_docnode, \
+    comphelper \
+    cppu \
+    cppuhelper \
+    editeng \
+    sal \
+    sfx \
+    sw \
+    test \
+    unotest \
+    utl \
+    vcl \
+    svt \
+    tl \
+    svl \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_core_docnode,\
+    boost_headers \
+    libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sw_core_docnode,\
+    -I$(SRCDIR)/sw/inc \
+    -I$(SRCDIR)/sw/source/core/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
+    -I$(SRCDIR)/sw/qa/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sw_core_docnode,\
+    udkapi \
+    offapi \
+    oovbaapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_core_docnode))
+$(eval $(call gb_CppunitTest_use_vcl,sw_core_docnode))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_core_docnode,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_core_docnode,\
+    officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_core_docnode))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,sw_core_docnode, \
+    modules/swriter \
+))
+
+$(eval $(call gb_CppunitTest_use_more_fonts,sw_core_docnode))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index a3958d4c4b65..280d7f25627c 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -107,6 +107,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
     CppunitTest_sw_unowriter \
     CppunitTest_sw_core_text \
     CppunitTest_sw_core_doc \
+    CppunitTest_sw_core_docnode \
     CppunitTest_sw_uibase_shells \
     CppunitTest_sw_uibase_dochdl \
     CppunitTest_sw_core_frmedt \
diff --git a/sw/qa/core/docnode/data/redline-ends-before-toc.docx b/sw/qa/core/docnode/data/redline-ends-before-toc.docx
new file mode 100644
index 000000000000..7696b3532e6e
Binary files /dev/null and b/sw/qa/core/docnode/data/redline-ends-before-toc.docx differ
diff --git a/sw/qa/core/docnode/docnode.cxx b/sw/qa/core/docnode/docnode.cxx
new file mode 100644
index 000000000000..6ed3f8ec01f6
--- /dev/null
+++ b/sw/qa/core/docnode/docnode.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <IDocumentRedlineAccess.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+
+char const DATA_DIRECTORY[] = "/sw/qa/core/docnode/data/";
+
+/// Covers sw/source/core/docnode/ fixes.
+class Test : public SwModelTestBase
+{
+public:
+    SwDoc* createDoc(const char* pName = nullptr);
+};
+
+SwDoc* Test::createDoc(const char* pName)
+{
+    if (!pName)
+        loadURL("private:factory/swriter", nullptr);
+    else
+        load(DATA_DIRECTORY, pName);
+
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+    return pTextDoc->GetDocShell()->GetDoc();
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRedlineEndsBeforeToC)
+{
+    // Load a document where a delete redline ends right before a ToC, then redlines are hidden at a
+    // layout level.
+    SwDoc* pDoc = createDoc("redline-ends-before-toc.docx");
+    const SwRedlineTable& rTable = pDoc->getIDocumentRedlineAccess().GetRedlineTable();
+    // Without the accompanying fix in place, this test would have resulted in an assertion failure
+    // in InsertCnt_(), because the start of the section was hidden, but not its end.
+    CPPUNIT_ASSERT_EQUAL(static_cast<SwRedlineTable::size_type>(2), rTable.size());
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/docnode/ndsect.cxx b/sw/source/core/docnode/ndsect.cxx
index 8c2efee0eb7e..f53ae5d4e5cd 100644
--- a/sw/source/core/docnode/ndsect.cxx
+++ b/sw/source/core/docnode/ndsect.cxx
@@ -822,6 +822,29 @@ SwSectionNode* SwNodes::InsertTextSection(SwNodeIndex const& rNdIdx,
 
     SwSectionNode *const pSectNd =
             new SwSectionNode(aInsPos, rSectionFormat, pTOXBase);
+
+    if (lcl_IsTOXSection(rSectionData))
+    {
+        // We're inserting a ToX. Make sure that if a redline ends right before the ToX start, then
+        // that end now doesn't cross a section start node.
+        SwRedlineTable& rRedlines = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+        for (SwRedlineTable::size_type nIndex = 0; nIndex < rRedlines.size(); ++nIndex)
+        {
+            SwRangeRedline* pRedline = rRedlines[nIndex];
+            if (!pRedline->HasMark() || pRedline->GetMark()->nNode != aInsPos)
+            {
+                continue;
+            }
+
+            // The redline ends at the new section content start, so it originally ended before the
+            // section start: move it back.
+            SwPaM aRedlineEnd(*pRedline->GetMark());
+            aRedlineEnd.Move(fnMoveBackward);
+            *pRedline->GetMark() = *aRedlineEnd.GetPoint();
+            break;
+        }
+    }
+
     if( pEnde )
     {
         // Special case for the Reader/Writer


More information about the Libreoffice-commits mailing list